From 59e73403b562dcb87b51efea452531eb4e73eb43 Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Mon, 10 Aug 2026 10:18:24 +0800 Subject: [PATCH 01/24] feat(agentos): add first-class PocketJS app runtime --- ARCHITECTURE.md | 169 +- Cargo.lock | 143 +- Cargo.toml | 22 +- README.md | 5 +- apps/README.md | 19 + apps/_shared/text.ts | 88 + apps/_shared/ui.tsx | 67 + apps/exa/agent-app.json | 12 + apps/exa/app.tsx | 141 ++ apps/exa/data-action.ts | 184 ++ apps/exa/dist/app.js | 15 + apps/exa/dist/app.pak | Bin 0 -> 317776 bytes apps/exa/dist/data-action.js | 37 + apps/exa/pocket.json | 10 + apps/pi-agent/agent-app.json | 7 + apps/pi-agent/app.tsx | 599 ++++++ apps/pi-agent/dist/agent.js | 399 ++++ apps/pi-agent/dist/app.js | 16 + apps/pi-agent/dist/app.pak | Bin 0 -> 431376 bytes apps/pi-agent/pocket.json | 19 + apps/robinhood/agent-app.json | 21 + apps/robinhood/app.tsx | 562 ++++++ apps/robinhood/data-action.ts | 463 +++++ apps/robinhood/dist/app.js | 22 + apps/robinhood/dist/app.pak | Bin 0 -> 294656 bytes apps/robinhood/dist/data-action.js | 111 ++ apps/robinhood/pocket.json | 10 + crates/pocket-pi-agentos/Cargo.toml | 23 + crates/pocket-pi-agentos/src/lib.rs | 1723 +++++++++++++++++ crates/pocket-pi-device-ui/Cargo.toml | 11 - .../assets/fonts/INTER-LICENSE.txt | 92 - .../assets/fonts/SOURCE_PROVENANCE.md | 17 - .../assets/fonts/inter-18-bold.pfa | Bin 43894 -> 0 bytes .../assets/fonts/inter-18-regular.pfa | Bin 41628 -> 0 bytes .../assets/fonts/inter-24-bold.pfa | Bin 75515 -> 0 bytes .../assets/fonts/inter-36-regular.pfa | Bin 163992 -> 0 bytes crates/pocket-pi-device-ui/src/lib.rs | 5 - crates/pocket-pi-device-ui/src/model.rs | 68 - crates/pocket-pi-device-ui/src/screen/font.rs | 165 -- crates/pocket-pi-device-ui/src/screen/mod.rs | 1649 ---------------- .../src/screen/workspace_browser.rs | 325 ---- crates/pocket-pi-embedded/Cargo.toml | 1 + crates/pocket-pi-embedded/js/env.d.ts | 6 +- .../pocket-pi-embedded/js/pi-agent.bundle.js | 21 +- crates/pocket-pi-embedded/js/src/entry.ts | 229 ++- crates/pocket-pi-embedded/src/lib.rs | 472 +++-- docs/agentos-architecture.md | 1068 ++++++++++ docs/esp32-p4-port.md | 21 +- docs/pocket-pi-design-system.md | 54 + firmware/esp32-p4/.cargo/config.toml | 1 + firmware/esp32-p4/Cargo.lock | 180 +- firmware/esp32-p4/Cargo.toml | 18 +- .../pi_p4_touch_bridge.c | 47 - .../components/pocketjs_ppa/CMakeLists.txt | 17 + .../esp32-p4/components/pocketjs_ppa/LICENSE | 21 + .../components/pocketjs_ppa/README.md | 8 + .../pocketjs_ppa/SOURCE_PROVENANCE.md | 8 + .../components/pocketjs_ppa/idf_component.yml | 11 + .../pocketjs_ppa/include/pocketjs_ppa.h | 89 + .../pocketjs_ppa/src/pocketjs_ppa.c | 468 +++++ firmware/esp32-p4/components_esp32p4.lock | 2 +- firmware/esp32-p4/sdkconfig.defaults | 4 +- firmware/esp32-p4/shim/sys/ioctl.h | 1 + firmware/esp32-p4/src/agentos_main.rs | 731 +++++++ firmware/esp32-p4/src/app_services.rs | 708 +++++++ firmware/esp32-p4/src/backend/uart.rs | 11 +- firmware/esp32-p4/src/backend/wireless.rs | 11 +- firmware/esp32-p4/src/bin/sqlite_probe.rs | 253 +++ firmware/esp32-p4/src/device_state.rs | 23 + firmware/esp32-p4/src/main.rs | 808 ++------ .../esp32-p4/src/transport/provisioning.rs | 10 + firmware/esp32-p4/src/waveshare_bindings.h | 1 - firmware/esp32-p4/tools/esp32p4-cc | 2 +- hosts/esp32-p4-sim/Cargo.toml | 8 +- hosts/esp32-p4-sim/src/main.rs | 987 ++++++---- tools/uart-model-bridge.py | 138 +- tools/xtask/src/main.rs | 82 +- 77 files changed, 9923 insertions(+), 3816 deletions(-) create mode 100644 apps/README.md create mode 100644 apps/_shared/text.ts create mode 100644 apps/_shared/ui.tsx create mode 100644 apps/exa/agent-app.json create mode 100644 apps/exa/app.tsx create mode 100644 apps/exa/data-action.ts create mode 100644 apps/exa/dist/app.js create mode 100644 apps/exa/dist/app.pak create mode 100644 apps/exa/dist/data-action.js create mode 100644 apps/exa/pocket.json create mode 100644 apps/pi-agent/agent-app.json create mode 100644 apps/pi-agent/app.tsx create mode 100644 apps/pi-agent/dist/agent.js create mode 100644 apps/pi-agent/dist/app.js create mode 100644 apps/pi-agent/dist/app.pak create mode 100644 apps/pi-agent/pocket.json create mode 100644 apps/robinhood/agent-app.json create mode 100644 apps/robinhood/app.tsx create mode 100644 apps/robinhood/data-action.ts create mode 100644 apps/robinhood/dist/app.js create mode 100644 apps/robinhood/dist/app.pak create mode 100644 apps/robinhood/dist/data-action.js create mode 100644 apps/robinhood/pocket.json create mode 100644 crates/pocket-pi-agentos/Cargo.toml create mode 100644 crates/pocket-pi-agentos/src/lib.rs delete mode 100644 crates/pocket-pi-device-ui/Cargo.toml delete mode 100644 crates/pocket-pi-device-ui/assets/fonts/INTER-LICENSE.txt delete mode 100644 crates/pocket-pi-device-ui/assets/fonts/SOURCE_PROVENANCE.md delete mode 100644 crates/pocket-pi-device-ui/assets/fonts/inter-18-bold.pfa delete mode 100644 crates/pocket-pi-device-ui/assets/fonts/inter-18-regular.pfa delete mode 100644 crates/pocket-pi-device-ui/assets/fonts/inter-24-bold.pfa delete mode 100644 crates/pocket-pi-device-ui/assets/fonts/inter-36-regular.pfa delete mode 100644 crates/pocket-pi-device-ui/src/lib.rs delete mode 100644 crates/pocket-pi-device-ui/src/model.rs delete mode 100644 crates/pocket-pi-device-ui/src/screen/font.rs delete mode 100644 crates/pocket-pi-device-ui/src/screen/mod.rs delete mode 100644 crates/pocket-pi-device-ui/src/screen/workspace_browser.rs create mode 100644 docs/agentos-architecture.md create mode 100644 docs/pocket-pi-design-system.md create mode 100644 firmware/esp32-p4/components/pocketjs_ppa/CMakeLists.txt create mode 100644 firmware/esp32-p4/components/pocketjs_ppa/LICENSE create mode 100644 firmware/esp32-p4/components/pocketjs_ppa/README.md create mode 100644 firmware/esp32-p4/components/pocketjs_ppa/SOURCE_PROVENANCE.md create mode 100644 firmware/esp32-p4/components/pocketjs_ppa/idf_component.yml create mode 100644 firmware/esp32-p4/components/pocketjs_ppa/include/pocketjs_ppa.h create mode 100644 firmware/esp32-p4/components/pocketjs_ppa/src/pocketjs_ppa.c create mode 100644 firmware/esp32-p4/shim/sys/ioctl.h create mode 100644 firmware/esp32-p4/src/agentos_main.rs create mode 100644 firmware/esp32-p4/src/app_services.rs create mode 100644 firmware/esp32-p4/src/bin/sqlite_probe.rs create mode 100644 firmware/esp32-p4/src/device_state.rs diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 4770cbb..a2757a5 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -1,143 +1,72 @@ # Pocket Pi architecture -Pocket Pi is one runtime family with two agent profiles and three hosts. +Pocket Pi is one AgentOS runtime family with three host profiles: -| Run mode | Host | Pocket Pi profile | Purpose | -|---|---|---|---| -| Native Mac | `hosts/macos` | full `pi-coding-agent` | Normal desktop Pocket Pi | -| ESP32 simulator on Mac | `hosts/esp32-p4-sim` | embedded `pi-agent-core` + device UI/tools | Fast development of embedded contracts and product flows | -| Physical ESP32-P4 | `firmware/esp32-p4` | embedded `pi-agent-core` + device UI/tools | Real PocketJS/QuickJS Agent on the board | +| Run mode | Host | Agent profile | +| --- | --- | --- | +| Native Mac | `hosts/macos` | full `pi-coding-agent` | +| ESP32 simulator | `hosts/esp32-p4-sim` | embedded `pi-agent-core` System App | +| ESP32-P4 | `firmware/esp32-p4` | embedded `pi-agent-core` System App | -These are not three products. They are three compositions of Pocket Pi. The -simulator and physical firmware share the embedded runtime, UI, tool contracts -and interaction semantics. The simulator may use simpler host implementations; -physical hardware remains the final acceptance target. - -```text - full desktop profile embedded product profile - crates/pocket-pi crates/pocket-pi-embedded - │ │ - hosts/macos crates/pocket-pi-device-ui - │ - ┌────────────┴────────────┐ - │ │ - firmware/esp32-p4 hosts/esp32-p4-sim -``` +The authoritative detailed design is +[`docs/agentos-architecture.md`](docs/agentos-architecture.md). ## Ownership -- `crates/pocket-pi` runs the full, unmodified `pi-coding-agent` with its - desktop Node/Web compatibility layer. -- `crates/pocket-pi-embedded` runs the bounded upstream `pi-agent-core` loop. - Native host traits provide model and tool capabilities. -- `crates/pocket-pi-device-ui` is the single source for the 720x1280 PocketJS - draw list, fonts, touch hit map, Chat, Workspace browser, keyboard, message - reader, device Settings and system status. The host supplies the mounted - workspace root. +- `crates/pocket-pi-agentos` owns App catalog, runtime lifecycle, foreground + selection, schedules, App Tool routing, and App-scoped FS/SQLite mounts. +- `crates/pocket-pi-embedded` provides the bounded JavaScript Agent Loop bridge. + In AgentOS hosts, the loop is loaded from the Pi Agent System App release into + the same PocketJS Guest as its Root View. +- `apps/pi-agent` owns the Root View and Agent Loop release artifacts. +- `apps/robinhood` and `apps/exa` own their Tools, Tasks, SQLite schemas, and + PocketJS Views. +- `crates/pocket-pi-tools` owns portable native workspace, bounded shell, time, + device, and Agent schedule Tools. - `crates/pocket-pi-protocols` owns model/provider transport protocols. -- `crates/pocket-pi-tools` owns the portable native ESP tool registry: - filesystem tools, bounded bash, workspace context, time and schedules. -- Each host is a composition root. It connects the embedded Agent, shared UI, - filesystem, input, display and model adapter. - -Dependencies point inward: hosts depend on the runtime, UI and protocols. The -runtime and UI do not depend on a host. External products can populate a UI -projection or register a native tool without putting provider clients in core. - -## Repository map - -```text -crates/pocket-pi/ full desktop pi-coding-agent runtime -crates/pocket-pi-embedded/ bounded pi-agent-core guest + native host traits -crates/pocket-pi-tools/ portable native workspace, shell, time and schedule tools -crates/pocket-pi-protocols/ provider request/response and streaming codecs -crates/pocket-pi-device-ui/ shared PocketJS embedded UI and interaction state -hosts/macos/ desktop composition root -hosts/esp32-p4-sim/ macOS implementation of the embedded host adapters -firmware/esp32-p4/ ESP-IDF hardware composition root and adapters -tools/uart_bridge/ Mac Codex/Claude streaming adapters -tools/uart-model-bridge.py thin UART framing and provisioning CLI -``` - -The split follows ownership, not product features. A native tool is implemented -once in `pocket-pi-tools`; a provider codec belongs in `pocket-pi-protocols`; -hardware access stays in a host. Optional applications such as Exa or -Robinhood should be separate tool/plugin adapters and must not become -dependencies of the embedded runtime or shared UI. - -## ESP32 and simulator parity - -The physical ESP32-P4 firmware and macOS simulator compile the same: +- Hosts own hardware, transport, credentials, and rendering adapters. -- `pocket-pi-embedded` Agent runtime; -- `pocket-pi-device-ui` Rust source and exact font atlases; -- `ScreenState::handle_tap` coordinate hit map; -- 720x1280 PocketJS draw-list viewport. +There is no legacy Rust product UI. Simulator and ESP32 render the same +PocketJS App bundles at a 720x1280 logical viewport. Rust firmware supplies the +display/touch driver and renders the selected App's DrawList. -The simulator maps a mouse pointer into the same 720x1280 coordinates used by -the touch controller and calls the same `handle_tap` method. It substitutes -macOS filesystem, wgpu display and model adapters; it does not emulate the -ESP32 CPU or peripherals. +## Runtime lifecycle -Both embedded hosts construct the same `CoreToolHost`. The simulator executes -filesystem and schedule operations against its Mac workspace directory using -the exact ESP constraints. Only `device.status`, `wifi status` and -`reboot` cross a small `PlatformTools` adapter. +The Pi Agent is a first-class, always-resident System App. Its Agent Loop, +context, Tool Registry, and Root View share one Guest and one App lifecycle. +Opening Robinhood or Exa changes only the foreground View; it does not restart +or replace the Agent. Model and native Tool transport complete asynchronously +and return events to that persistent Guest. -Parity is contract-level, not peripheral emulation. The simulator must support -the real embedded Pi Agent, core tool registry, workspace flows and schedules. -It may use macOS storage, networking, deterministic fixtures and simplified -telemetry to do so. CPU load, LittleFS capacity, Wi-Fi/NVS behavior, touch, LCD -scanout and other ESP-IDF details are implemented and accepted only on physical -hardware. +Ordinary Apps receive capability-scoped data roots. Pi Agent alone owns the +top-level `/workspace` and cross-App Tool Registry. -The full macOS host does not link the device UI. Embedded products enable Chat, -Files and Settings. External applications such as Exa or Robinhood belong in -separate plugin/tool and UI adapter crates; Pocket Pi core contains none of -their domain models, clients, credentials or tools. - -Settings follows the same host boundary as the rest of the device UI. PocketJS -emits `SettingsCommand` values and renders `SettingsProjection`; only the ESP -host calls ESP-IDF Wi-Fi/NVS/restart APIs. The simulator handles the same -commands with deterministic hardware projections. Password input is transient, -masked, cleared after submit, and never enters the Agent workspace or context. - -The physical model boundary has two implementations: - -- `UartBackend` sends framed model decisions to the Mac bridge, which can use a - logged-in Codex or Claude Code CLI. -- `WirelessBackend` sends direct HTTPS requests over board Wi-Fi to OpenAI, - OpenRouter, or Anthropic. - -Provider JSON and streaming decoders live in `pocket-pi-protocols`; ESP-IDF and -desktop HTTP transports stay in their hosts. - -The UART development path is deliberately layered. The ESP firmware owns only -line framing and `UartBackend`; `tools/uart-model-bridge.py` routes those frames; -`tools/uart_bridge` adapts a logged-in Codex app-server or Claude Code stream. -Only decoded top-level `text` is forwarded as UI deltas, while tool-decision -JSON remains private to the Pi Harness. Because ESP logs share UART0, the -firmware disables ESP-IDF logging after the Pi Harness ready handshake so logs -cannot corrupt model frames. - -Device time follows the same dual-adapter rule. A standalone Wi-Fi device uses -SNTP. The UART development bridge may seed Unix time at boot, after which the -same persistent `schedule.*` tools and wake loop run unchanged. - -## Runtime separation - -Agent work runs on a worker thread. UI and touch remain responsive while model -deltas are projected into `ChatProjection`. The UI never owns network access, -model credentials or broker credentials. +## Repository map -## Build entry point +```text +apps/ PocketJS System/ordinary App sources and bundles +crates/pocket-pi/ full desktop pi-coding-agent runtime +crates/pocket-pi-agentos/ App Supervisor and AgentOS contracts +crates/pocket-pi-embedded/ embedded pi-agent-core bridge and host traits +crates/pocket-pi-tools/ native workspace/shell/time/schedule Tools +crates/pocket-pi-protocols/ provider codecs +hosts/macos/ native desktop composition root +hosts/esp32-p4-sim/ embedded AgentOS simulator +firmware/esp32-p4/ ESP-IDF hardware composition root +tools/uart_bridge/ Mac Codex/Claude streaming adapters +tools/uart-model-bridge.py UART framing and provisioning CLI +``` -`cargo xtask` is the orchestration layer: +## Build entry points ```sh +cargo xtask build agentos-apps cargo xtask build macos cargo xtask build esp32-p4 cargo xtask build esp32-p4-sim cargo xtask run esp32-p4-sim cargo xtask snapshot esp32-p4-sim ``` + +Simulator proof, firmware compilation, and physical-board proof are separate +evidence tiers. Physical ESP32-P4 remains the final hardware acceptance target. diff --git a/Cargo.lock b/Cargo.lock index faedc92..ebb0c80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -204,6 +204,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "base64-simd" version = "0.8.0" @@ -750,6 +756,18 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fastrand" version = "2.5.0" @@ -1083,6 +1101,15 @@ dependencies = [ "foldhash 0.1.5", ] +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "foldhash 0.2.0", +] + [[package]] name = "hashbrown" version = "0.17.1" @@ -1094,6 +1121,15 @@ dependencies = [ "foldhash 0.2.0", ] +[[package]] +name = "hashlink" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32069d97bb81e38fa67eab65e3393bf804bb85969f2bc06bf13f64aef5aba248" +dependencies = [ + "hashbrown 0.17.1", +] + [[package]] name = "heck" version = "0.5.0" @@ -1490,6 +1526,17 @@ dependencies = [ "redox_syscall 0.9.1", ] +[[package]] +name = "libsqlite3-sys" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6c19a05435c21ac299d71b6a9c13db3e3f47c520517d58990a462a1397a61db" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -2481,10 +2528,35 @@ dependencies = [ "miniz_oxide 0.8.9", ] +[[package]] +name = "pocket-db" +version = "0.1.0" +source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +dependencies = [ + "anyhow", + "base64 0.23.1", + "pocket-mod", + "pocketjs-core", + "rusqlite", + "serde_json", +] + +[[package]] +name = "pocket-fs" +version = "0.1.0" +source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +dependencies = [ + "anyhow", + "base64 0.23.1", + "pocket-mod", + "pocketjs-core", + "serde_json", +] + [[package]] name = "pocket-mod" version = "0.1.0" -source = "git+https://github.com/pocket-stack/pocketjs.git?rev=4c5dc9ef1dd26e6f49b036c210931d399f2b52b2#4c5dc9ef1dd26e6f49b036c210931d399f2b52b2" +source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" dependencies = [ "anyhow", "log", @@ -2512,17 +2584,27 @@ dependencies = [ ] [[package]] -name = "pocket-pi-device-ui" +name = "pocket-pi-agentos" version = "0.1.0" dependencies = [ - "pocket-pi-protocols", + "anyhow", + "log", + "pocket-db", + "pocket-fs", + "pocket-mod", + "pocket-pi-embedded", + "pocket-ui-surface", "pocketjs-core", + "serde", + "serde_json", + "tempfile", ] [[package]] name = "pocket-pi-embedded" version = "0.1.0" dependencies = [ + "pocket-mod", "rquickjs", "serde_json", ] @@ -2534,7 +2616,7 @@ dependencies = [ "anyhow", "env_logger", "log", - "pocket-pi-device-ui", + "pocket-pi-agentos", "pocket-pi-embedded", "pocket-pi-protocols", "pocket-pi-tools", @@ -2579,7 +2661,7 @@ dependencies = [ [[package]] name = "pocket-ui-surface" version = "0.1.0" -source = "git+https://github.com/pocket-stack/pocketjs.git?rev=4c5dc9ef1dd26e6f49b036c210931d399f2b52b2#4c5dc9ef1dd26e6f49b036c210931d399f2b52b2" +source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" dependencies = [ "anyhow", "log", @@ -2590,7 +2672,7 @@ dependencies = [ [[package]] name = "pocket-ui-wgpu" version = "0.1.0" -source = "git+https://github.com/pocket-stack/pocketjs.git?rev=4c5dc9ef1dd26e6f49b036c210931d399f2b52b2#4c5dc9ef1dd26e6f49b036c210931d399f2b52b2" +source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" dependencies = [ "anyhow", "bytemuck", @@ -2603,7 +2685,7 @@ dependencies = [ [[package]] name = "pocket3d" version = "0.1.0" -source = "git+https://github.com/pocket-stack/pocketjs.git?rev=4c5dc9ef1dd26e6f49b036c210931d399f2b52b2#4c5dc9ef1dd26e6f49b036c210931d399f2b52b2" +source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" dependencies = [ "anyhow", "bytemuck", @@ -2622,7 +2704,7 @@ dependencies = [ [[package]] name = "pocket3d-bsp" version = "0.1.0" -source = "git+https://github.com/pocket-stack/pocketjs.git?rev=4c5dc9ef1dd26e6f49b036c210931d399f2b52b2#4c5dc9ef1dd26e6f49b036c210931d399f2b52b2" +source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" dependencies = [ "anyhow", "glam", @@ -2632,7 +2714,7 @@ dependencies = [ [[package]] name = "pocketjs-core" version = "0.1.0" -source = "git+https://github.com/pocket-stack/pocketjs.git?rev=4c5dc9ef1dd26e6f49b036c210931d399f2b52b2#4c5dc9ef1dd26e6f49b036c210931d399f2b52b2" +source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" dependencies = [ "taffy", ] @@ -2934,6 +3016,31 @@ dependencies = [ "cc", ] +[[package]] +name = "rsqlite-vfs" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51c9ae4df8a7fba42103df5c621fa3c37eccf3a3c650879e90fc48b11cc192c" +dependencies = [ + "hashbrown 0.16.1", + "thiserror 2.0.19", +] + +[[package]] +name = "rusqlite" +version = "0.40.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11438310b19e3109b6446c33d1ed5e889428cf2e278407bc7896bc4aaea43323" +dependencies = [ + "bitflags 2.13.1", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", + "sqlite-wasm-rs", +] + [[package]] name = "rustc-hash" version = "1.1.0" @@ -3236,6 +3343,18 @@ dependencies = [ "bitflags 2.13.1", ] +[[package]] +name = "sqlite-wasm-rs" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc3efc0da82635d7e1ced0053bbbfa8c7ab9645d0bf36ceb4f7127bb85315d75" +dependencies = [ + "cc", + "js-sys", + "rsqlite-vfs", + "wasm-bindgen", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -3577,6 +3696,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" diff --git a/Cargo.toml b/Cargo.toml index 9f7d3ba..fac91fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,8 +2,8 @@ resolver = "2" members = [ "crates/pocket-pi", + "crates/pocket-pi-agentos", "crates/pocket-pi-embedded", - "crates/pocket-pi-device-ui", "crates/pocket-pi-protocols", "crates/pocket-pi-tools", "hosts/macos", @@ -25,5 +25,25 @@ log = "0.4" serde = { version = "1", default-features = false, features = ["derive", "alloc"] } serde_json = { version = "1", default-features = false, features = ["alloc"] } +[workspace.dependencies.pocketjs-core] +git = "https://github.com/siwei-yuan/pocketjs.git" +rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" + +[workspace.dependencies.pocket-mod] +git = "https://github.com/siwei-yuan/pocketjs.git" +rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" + +[workspace.dependencies.pocket-ui-surface] +git = "https://github.com/siwei-yuan/pocketjs.git" +rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" + +[workspace.dependencies.pocket-db] +git = "https://github.com/siwei-yuan/pocketjs.git" +rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" + +[workspace.dependencies.pocket-fs] +git = "https://github.com/siwei-yuan/pocketjs.git" +rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" + [profile.release] opt-level = 2 diff --git a/README.md b/README.md index 01e7d3b..e6bb200 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,7 @@ cargo xtask build esp32-p4 DEVICE_PORT=/dev/cu.usbmodem... espflash flash --baud 921600 --port "$DEVICE_PORT" \ + --partition-table firmware/esp32-p4/partitions.csv \ firmware/esp32-p4/target/riscv32imafc-esp-espidf/release/pocket-pi-p4 ``` @@ -196,7 +197,7 @@ The shared PocketJS device UI includes: - Chat with streamed replies, recent-turn history and a full-message reader; - Files with workspace metadata, file viewing and scrolling; - Settings with Wi-Fi scanning, selection and password entry; -- touch keyboard, system telemetry and next-schedule status. +- touch keyboard and next-schedule status. Settings is an embedded-device feature and is not linked into native macOS Pocket Pi. This repository does not include Robinhood or Exa UI, clients, @@ -235,7 +236,7 @@ crates/pocket-pi/ full desktop pi-coding-agent runtime crates/pocket-pi-embedded/ embedded pi-agent-core guest and host traits crates/pocket-pi-tools/ portable workspace, shell, time and schedule tools crates/pocket-pi-protocols/ model request, response and streaming codecs -crates/pocket-pi-device-ui/ shared PocketJS device UI and interaction state +crates/pocket-pi-agentos/ App Supervisor, System App lifecycle and App contracts hosts/macos/ native desktop composition root hosts/esp32-p4-sim/ macOS adapters for the embedded product firmware/esp32-p4/ ESP-IDF hardware composition root and adapters diff --git a/apps/README.md b/apps/README.md new file mode 100644 index 0000000..ba66db0 --- /dev/null +++ b/apps/README.md @@ -0,0 +1,19 @@ +# Pocket Pi built-in Apps + +Each directory is one independently versioned PocketJS App source. The checked +in `dist/app.js` and `dist/app.pak` files are target artifacts embedded into the +firmware as the recovery release, then seeded into `/workspace` on boot. + +- `pi-agent`: the privileged Root View; its filesystem mount is `/workspace`. +- `robinhood`: curated MCP tools, `refreshPortfolio` AppTask, SQLite and View. +- `exa`: Exa search/fetch tools, SQLite search history and View. + +Build all three from the pinned FS/DB branch checkout: + +```sh +POCKETJS_ROOT=/path/to/pocketjs-feat-fs-surface cargo xtask build agentos-apps +``` + +The task refuses a checkout other than revision +`afc8d4e8e877dac7f9b0c01b5c0d667642009fc0`, so generated recovery bundles +cannot silently drift from the runtime modules linked into the firmware. diff --git a/apps/_shared/text.ts b/apps/_shared/text.ts new file mode 100644 index 0000000..868684a --- /dev/null +++ b/apps/_shared/text.ts @@ -0,0 +1,88 @@ +import { getOps } from "@pocketjs/framework"; + +// Dynamic App text is not visible to PocketJS's bundle-time font subsetter. +// Keep common English prose punctuation in every bundle that imports this +// module so model/provider text does not fall back to missing-glyph boxes. +export const DYNAMIC_TEXT_GLYPHS = "‘’“”–—…•"; + +const widthCache = new Map(); +const wrapCache = new Map(); + +function width(text: string, fontSlot: number): number { + if (!text) return 0; + const key = fontSlot + "|" + text; + const cached = widthCache.get(key); + if (cached !== undefined) return cached; + const measured = getOps().measureText(text, fontSlot); + widthCache.set(key, measured); + return measured; +} + +function breakToken(token: string, fontSlot: number, maxWidth: number): string[] { + const chunks: string[] = []; + let chunk = ""; + let chunkWidth = 0; + for (const character of token) { + const characterWidth = width(character, fontSlot); + if (chunk && chunkWidth + characterWidth > maxWidth) { + chunks.push(chunk); + chunk = ""; + chunkWidth = 0; + } + chunk += character; + chunkWidth += characterWidth; + } + if (chunk) chunks.push(chunk); + return chunks; +} + +// PocketJS Text only breaks on explicit newlines. Measure once per unique +// string and insert those newlines before the DrawList reaches native UI. +export function wrapLines(text: string, fontSlot: number, maxWidth: number): string[] { + void DYNAMIC_TEXT_GLYPHS; + const key = fontSlot + "|" + maxWidth + "|" + text; + const cached = wrapCache.get(key); + if (cached) return cached; + + const lines: string[] = []; + const spaceWidth = width(" ", fontSlot); + for (const paragraph of text.split("\n")) { + const words = paragraph.split(" ").flatMap((token) => + token && width(token, fontSlot) > maxWidth + ? breakToken(token, fontSlot, maxWidth) + : [token], + ); + let line = ""; + let lineWidth = 0; + for (const word of words) { + const wordWidth = width(word, fontSlot); + if (!line) { + line = word; + lineWidth = wordWidth; + } else if (lineWidth + spaceWidth + wordWidth <= maxWidth) { + line += " " + word; + lineWidth += spaceWidth + wordWidth; + } else { + lines.push(line); + line = word; + lineWidth = wordWidth; + } + } + lines.push(line); + } + wrapCache.set(key, lines); + return lines; +} + +export function wrapPreview( + text: string, + fontSlot: number, + maxWidth: number, + maxLines: number, +): string { + const lines = wrapLines(text, fontSlot, maxWidth); + if (lines.length <= maxLines) return lines.join("\n"); + const visible = lines.slice(0, maxLines); + visible[maxLines - 1] = visible[maxLines - 1].replace(/[\s.]+$/, "") + "…"; + return visible.join("\n"); +} diff --git a/apps/_shared/ui.tsx b/apps/_shared/ui.tsx new file mode 100644 index 0000000..65c8d51 --- /dev/null +++ b/apps/_shared/ui.tsx @@ -0,0 +1,67 @@ +import { Text, View } from "@pocketjs/framework/components"; + +// Pocket Pi Design System v0.1. Keep this layer deliberately small: shared +// typography, spacing and foundational surfaces only. Product-specific +// components such as charts, account pickers and file rows stay in each App. +export const type = { + title: "text-2xl text-white font-bold", + section: "text-sm text-slate-600 font-bold", + body: "text-base text-slate-900", + bodyStrong: "text-base text-slate-900 font-bold", + caption: "text-sm text-slate-500", +} as const; + +export const space = { + screenX: "px-6", + card: "px-6 py-5", + stack: "gap-4", +} as const; + +type HeaderProps = { + title: string; + back?: boolean; + accent?: "ready" | "busy" | "danger" | "none"; + metaTop?: string; + metaBottom?: string; +}; + +export function PocketHeader(props: HeaderProps) { + const accent = () => props.accent === "busy" ? "w-[34] h-[34] rounded-lg bg-amber-400" + : props.accent === "danger" ? "w-[34] h-[34] rounded-lg bg-red-500" + : props.accent === "none" ? "w-[34] h-[34] rounded-lg bg-slate-800" + : "w-[34] h-[34] rounded-lg bg-emerald-500"; + return ( + + + {props.back + ? + : } + {props.title} + + + {props.metaTop ?? ""} + {props.metaBottom ?? ""} + + + ); +} + +export function SectionHeading(props: { title: string; detail?: string; action?: boolean }) { + const trailing = () => props.action + ? (props.detail ? props.detail + " · VIEW ALL ›" : "VIEW ALL ›") + : props.detail ?? ""; + return ( + + {props.title} + {trailing()} + + ); +} + +export function ActionButton(props: { label: string; disabled?: boolean }) { + return ( + + {props.label} + + ); +} diff --git a/apps/exa/agent-app.json b/apps/exa/agent-app.json new file mode 100644 index 0000000..2b35709 --- /dev/null +++ b/apps/exa/agent-app.json @@ -0,0 +1,12 @@ +{ + "id": "exa", + "version": "1.0.0", + "dataVersion": 3, + "tools": [ + {"name":"research.search","description":"Search the web through Exa, return bounded source-linked highlights, and save the search to local history.","parameters":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":2000},"numResults":{"type":"integer","minimum":1,"maximum":8},"searchType":{"type":"string","enum":["auto","fast","instant"]},"includeDomains":{"type":"array","items":{"type":"string"},"maxItems":8},"excludeDomains":{"type":"array","items":{"type":"string"},"maxItems":8}},"required":["query"],"additionalProperties":false}}, + {"name":"research.fetch","description":"Fetch a bounded research document through Exa and save it as the latest opened document.","parameters":{"type":"object","properties":{"url":{"type":"string","maxLength":2048},"maxCharacters":{"type":"integer","minimum":200,"maximum":12000}},"required":["url"],"additionalProperties":false}}, + {"name":"research.storage_status","description":"Inspect this App's local SQLite schema, row counts, and bounded recent row summaries without contacting Exa.","parameters":{"type":"object","properties":{},"additionalProperties":false}} + ], + "tasks": [], + "schedules": [] +} diff --git a/apps/exa/app.tsx b/apps/exa/app.tsx new file mode 100644 index 0000000..01133b4 --- /dev/null +++ b/apps/exa/app.tsx @@ -0,0 +1,141 @@ +import { createSignal, For, Show } from "solid-js"; +import { Text, View } from "@pocketjs/framework/components"; +import { mount } from "@pocketjs/framework"; +import { Database } from "@pocketjs/framework/db"; + +const DB_SCHEMA_VERSION = 3; +const db = new Database("exa"); + +type SearchRow = { id: number; query: string; searched_at: number; status: string; result_count: number; top_title: string | null; top_url: string | null; error: string | null }; +const [history, setHistory] = createSignal([]); +const [status, setStatus] = createSignal("SEARCH HISTORY IS LOCAL"); +let loadedRevision = -1; + +function parse(value: string): any { try { return JSON.parse(value); } catch { return null; } } + +function searchTime(seconds: number): string { + const value = new Date(seconds * 1000).toISOString(); + return value.slice(0, 10) + " · " + value.slice(11, 16) + " UTC"; +} + +function loadView(revision: number) { + if (loadedRevision === revision) return; + try { + const schema = db.query("PRAGMA user_version").get() as unknown as { user_version?: number } | null; + if (Number(schema?.user_version ?? 0) !== DB_SCHEMA_VERSION) { + setHistory([]); + setStatus("SEARCH HISTORY IS LOCAL"); + return; + } + const next = db.query(` + SELECT search.id,search.query,search.searched_at,search.status,search.result_count, + result.title AS top_title,result.url AS top_url,search.error + FROM searches search + LEFT JOIN search_results result ON result.search_id=search.id AND result.rank=0 + ORDER BY search.id DESC LIMIT 8 + `).all() as unknown as SearchRow[]; + setHistory(next); + setStatus(next[0]?.status === "error" ? String(next[0].error || "EXA SEARCH FAILED").slice(0, 80) + : next.length ? "SEARCH HISTORY UPDATED FROM SQLITE" : "SEARCH HISTORY IS LOCAL"); + loadedRevision = revision; + } catch { + setHistory([]); + setStatus("SEARCH HISTORY IS LOCAL"); + } +} + +function storageStatus(): any { + const tables = db.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all() as unknown as Array<{ name: string; sql: string }>; + const names = new Set(tables.map((table) => table.name)); + const tableSummary = tables.map((table) => { + const rowCount = (db.query("SELECT COUNT(*) AS count FROM " + table.name).get() as unknown as { count: number }).count; + return { name: table.name, rowCount, schema: table.sql }; + }); + const latestSearches = names.has("searches") ? db.query(` + SELECT search.id,search.query,search.searched_at,search.status,search.result_count, + result.title AS top_title,result.url AS top_url,search.error + FROM searches search + LEFT JOIN search_results result ON result.search_id=search.id AND result.rank=0 + ORDER BY search.id DESC LIMIT 8 + `).all() : []; + const latestDocuments = names.has("documents") + ? db.query("SELECT fetched_at,url,title,LENGTH(text) AS text_bytes FROM documents ORDER BY fetched_at DESC LIMIT 5").all() : []; + return { + database: "exa.sqlite", + schemaVersion: DB_SCHEMA_VERSION, + tables: tableSummary, + latestSearches, + latestDocuments, + }; +} + +function Exa() { + return ( + + + + + POCKET APPExa Research + + SQLITE HISTORY + + + AGENT RESEARCH MEMORY + Search history + Every research.search call is saved here automatically. + + + + + E + No searches yet + {"Ask Pi Agent to research a topic.\nThe search and its results will appear here."} + + + {(item) => ( + + + {item.query.slice(0, 72)} + {(item.top_title || item.error || "No result title").slice(0, 92)} + {searchTime(item.searched_at)} + + + {item.status === "ok" ? item.result_count + " RESULTS" : "FAILED"} + + + )} + + {status()} + + ); +} + +loadView(0); +mount(() => ); + +(globalThis as any).PocketPiApp = { + tick() { return ""; }, + update() { return ""; }, + dataChanged(eventsLine: string) { + const events = parse(eventsLine); + const revision = Array.isArray(events) + ? events.reduce((latest: number, event: any) => Math.max(latest, Number(event?.revision ?? 0)), loadedRevision) + : loadedRevision; + loadView(revision); + return ""; + }, + invokeTool(name: string) { + try { + const value = name === "research.storage_status" ? storageStatus() + : (() => { throw new Error("Data-writing tools run in the background App Data Action"); })(); + return JSON.stringify({ text: JSON.stringify(value), details: value, isError: false }); + } catch (error) { + return JSON.stringify({ text: error instanceof Error ? error.message : String(error), isError: true }); + } + }, + invokeTask(name: string) { return JSON.stringify({ text: "Unknown Exa task: " + name, isError: true }); }, + tap(x: number, y: number) { + if (y < 112 && x < 100) return JSON.stringify({ type: "navigate", app: "pi-agent" }); + return ""; + }, +}; diff --git a/apps/exa/data-action.ts b/apps/exa/data-action.ts new file mode 100644 index 0000000..042cdd0 --- /dev/null +++ b/apps/exa/data-action.ts @@ -0,0 +1,184 @@ +// Headless Exa data plane. Search and document responses are normalized into +// App-owned domain rows before one transaction invalidates the View cache. +const nativeDb = (globalThis as any).db; +const handle = nativeDb.open("exa"); +if (handle < 0) throw new Error("open exa.sqlite"); + +const SCHEMA_VERSION = 3; + +function dbError(): string { return String(nativeDb.lastError(handle) || "SQLite operation failed"); } +function exec(sql: string): void { if (nativeDb.exec(handle, sql) !== 0) throw new Error(dbError()); } +function query(sql: string, args: any[] = []): any { + const result = JSON.parse(nativeDb.query(handle, sql, JSON.stringify(args))); + if (result.error) throw new Error(String(result.error)); + return result; +} +function run(sql: string, args: any[] = []): any { return query(sql, args); } + +const version = query("PRAGMA user_version") as { user_version?: number } | null; +if (Number(version?.user_version ?? 0) !== SCHEMA_VERSION) { + exec(` + CREATE TABLE IF NOT EXISTS searches ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + query TEXT NOT NULL, + searched_at INTEGER NOT NULL, + status TEXT NOT NULL, + result_count INTEGER NOT NULL DEFAULT 0, + error TEXT + ); + CREATE INDEX IF NOT EXISTS searches_recent ON searches(id DESC); + CREATE TABLE IF NOT EXISTS search_results ( + search_id INTEGER NOT NULL, + rank INTEGER NOT NULL, + title TEXT, + url TEXT NOT NULL, + published_at TEXT, + author TEXT, + score TEXT, + highlight TEXT, + PRIMARY KEY(search_id, rank) + ); + CREATE INDEX IF NOT EXISTS search_results_url ON search_results(url); + CREATE TABLE IF NOT EXISTS documents ( + url TEXT PRIMARY KEY, + fetched_at INTEGER NOT NULL, + title TEXT, + published_at TEXT, + author TEXT, + text TEXT NOT NULL + ); + CREATE INDEX IF NOT EXISTS documents_recent ON documents(fetched_at DESC); + PRAGMA user_version=3; + `); +} + +function now(): number { return Math.floor(Date.now() / 1000); } +function text(value: unknown): string | null { + return value === null || value === undefined || typeof value === "object" ? null : String(value); +} +function firstText(value: any, names: string[]): string | null { + if (!value || typeof value !== "object") return null; + for (const name of names) { + const found = text(value[name]); + if (found !== null) return found; + } + return null; +} +function highlight(value: any): string | null { + if (Array.isArray(value?.highlights)) return value.highlights.map(String).join("\n").slice(0, 1200); + return firstText(value, ["highlight", "summary", "text"])?.slice(0, 1200) ?? null; +} + +function post(path: string, body: any): any { + const envelope = JSON.parse((globalThis as any).services.call( + "net.http", + "post", + JSON.stringify({ connection: "exa", path, body }), + )); + if (!envelope.ok) throw new Error(envelope.error || "Exa service failed"); + return envelope.value; +} + +function transaction(action: () => void): void { + exec("BEGIN IMMEDIATE"); + try { + action(); + exec("COMMIT"); + } catch (error) { + try { exec("ROLLBACK"); } catch {} + throw error; + } + (globalThis as any).app.commit(); +} + +function search(args: any): any { + const searchQuery = String(args.query ?? "").trim(); + if (!searchQuery) throw new Error("query is required"); + const searchedAt = now(); + try { + const body: any = { + query: searchQuery, + type: args.searchType ?? "auto", + numResults: Math.max(1, Math.min(8, Number(args.numResults ?? 5))), + contents: { highlights: { maxCharacters: 800 } }, + }; + for (const key of ["includeDomains", "excludeDomains", "startPublishedDate", "endPublishedDate"]) { + if (args[key] !== undefined) body[key] = args[key]; + } + const value = post("/search", body); + const results = Array.isArray(value?.results) ? value.results.slice(0, 8) : []; + transaction(() => { + const inserted = run( + "INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,?,NULL)", + [searchQuery, searchedAt, "ok", results.length], + ); + const searchId = Number(inserted.lastInsertRowid || 0); + results.forEach((item: any, rank: number) => { + const url = firstText(item, ["url", "id"]); + if (!url) return; + run( + `INSERT INTO search_results(search_id,rank,title,url,published_at,author,score,highlight) + VALUES(?,?,?,?,?,?,?,?)`, + [searchId, rank, firstText(item, ["title"]), url, firstText(item, ["publishedDate", "published_at", "date"]), firstText(item, ["author"]), firstText(item, ["score"]), highlight(item)], + ); + }); + }); + return value; + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + transaction(() => run( + "INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,0,?)", + [searchQuery, searchedAt, "error", message], + )); + throw error; + } +} + +function fetchDocument(args: any): any { + const requestedUrl = String(args.url ?? "").trim(); + if (!requestedUrl) throw new Error("url is required"); + const response = post("/contents", { + urls: [requestedUrl], + text: { + maxCharacters: Math.max(200, Math.min(12000, Number(args.maxCharacters ?? 6000))), + includeHtmlTags: false, + }, + }); + const document = Array.isArray(response?.results) ? response.results[0] : response; + if (!document) throw new Error("Exa returned no document"); + const url = firstText(document, ["url", "id"]) || requestedUrl; + const body = firstText(document, ["text", "content", "summary"]) || ""; + transaction(() => run( + `INSERT INTO documents(url,fetched_at,title,published_at,author,text) VALUES(?,?,?,?,?,?) + ON CONFLICT(url) DO UPDATE SET fetched_at=excluded.fetched_at,title=excluded.title, + published_at=excluded.published_at,author=excluded.author,text=excluded.text`, + [url, now(), firstText(document, ["title"]), firstText(document, ["publishedDate", "published_at", "date"]), firstText(document, ["author"]), body], + )); + return { + status: "ok", + provider: "exa", + requestId: response?.requestId, + document, + costDollars: response?.costDollars, + }; +} + +(globalThis as any).PocketPiData = { + invokeTask(name: string) { + return JSON.stringify({ text: "Unknown Exa Data Action: " + name, isError: true }); + }, + invokeTool(name: string, argsLine: string) { + try { + const args = JSON.parse(argsLine); + const value = name === "research.search" ? search(args) + : name === "research.fetch" ? fetchDocument(args) + : (() => { throw new Error("Unknown Exa tool: " + name); })(); + return JSON.stringify({ text: JSON.stringify(value), details: value, isError: false }); + } catch (error) { + return JSON.stringify({ + text: error instanceof Error ? error.message : String(error), + isError: true, + }); + } + }, +}; diff --git a/apps/exa/dist/app.js b/apps/exa/dist/app.js new file mode 100644 index 0000000..99fbb69 --- /dev/null +++ b/apps/exa/dist/app.js @@ -0,0 +1,15 @@ +(()=>{var FJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return m0(this.context.count)},getNextContextId(){return m0(this.context.count++)}};function m0(J){let Q=String(J),$=Q.length-1;return FJ.context.id+($?String.fromCharCode(96+$):"")+Q}function v0(J){FJ.context=J}function U4(){return{...FJ.context,id:FJ.getNextContextId(),count:0}}var V4=!1,P4=(J,Q)=>J===Q,W0=Symbol("solid-proxy"),R4=typeof Proxy==="function",w4=Symbol("solid-track"),q2=Symbol("solid-dev-component"),gJ={equals:P4},u0=null,D4=a0,E=1,LJ=2,l0={owned:null,cleanups:null,context:null,owner:null},L=null,B=null,IJ=null,KJ=null,I=null,S=null,f=null,TJ=0;function EJ(J,Q){let $=I,Z=L,X=J.length===0,W=Q===void 0?Z:Q,q=X?l0:{owned:null,cleanups:null,context:W?W.context:null,owner:W},G=X?J:()=>J(()=>a(()=>r(q)));L=q,I=null;try{return i(G,!0)}finally{I=$,L=Z}}function kJ(J,Q){Q=Q?Object.assign({},gJ,Q):gJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return i0($,X)};return[c0.bind($),Z]}function s(J,Q,$){let Z=s0(J,Q,!1,E);if(IJ&&B&&B.running)S.push(Z);else NJ(Z)}function MJ(J,Q,$){$=$?Object.assign({},gJ,$):gJ;let Z=s0(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,IJ&&B&&B.running)Z.tState=E,S.push(Z);else NJ(Z);return c0.bind(Z)}function a(J){if(!KJ&&I===null)return J();let Q=I;I=null;try{if(KJ)return KJ.untrack(J);return J()}finally{I=Q}}function Y0(J){if(L===null);else if(L.cleanups===null)L.cleanups=[J];else L.cleanups.push(J);return J}function O4(J){if(B&&B.running)return J(),B.done;let Q=I,$=L;return Promise.resolve().then(()=>{I=Q,L=$;let Z;if(IJ||C4)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return i(J,!1),I=L=null,Z?Z.done:void 0})}var[z2,p0]=kJ(!1),C4;function c0(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===E)NJ(this);else{let Q=S;S=null,i(()=>mJ(this),!1),S=Q}if(I){let Q=this.observers;if(!Q||Q[Q.length-1]!==I){let $=Q?Q.length:0;if(!I.sources)I.sources=[this],I.sourceSlots=[$];else I.sources.push(this),I.sourceSlots.push($);if(!Q)this.observers=[I],this.observerSlots=[I.sources.length-1];else Q.push(I),this.observerSlots.push(I.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function i0(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)i(()=>{for(let X=0;X1e6)throw S=[],Error()},!1)}return Q}function NJ(J){if(!J.fn)return;r(J);let Q=TJ;if(d0(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{i(()=>{B&&(B.running=!0),I=L=J,d0(J,J.tValue,Q),I=L=null},!1)})}function d0(J,Q,$){let Z,X=L,W=I;I=L=J;try{Z=J.fn(Q)}catch(q){if(J.pure)if(B&&B.running)J.tState=E,J.tOwned&&J.tOwned.forEach(r),J.tOwned=void 0;else J.state=E,J.owned&&J.owned.forEach(r),J.owned=null;return J.updatedAt=$+1,z0(q)}finally{I=W,L=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)i0(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function s0(J,Q,$,Z=E,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:L,context:L?L.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(L===null);else if(L!==l0)if(B&&B.running&&L.pure)if(!L.tOwned)L.tOwned=[W];else L.tOwned.push(W);else if(!L.owned)L.owned=[W];else L.owned.push(W);if(KJ&&W.fn){let q=W.fn,[G,M]=kJ(void 0,{equals:!1}),V=KJ.factory(q,M);Y0(()=>V.dispose());let R,H=()=>O4(M).then(()=>{if(R)R.dispose(),R=void 0});W.fn=(k)=>{if(G(),B&&B.running){if(!R)R=KJ.factory(q,H);return R.track(k)}return V.track(k)}}return W}function q0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===LJ)return mJ(J);if(J.suspense&&a(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===E)NJ(J);else if((Q?J.tState:J.state)===LJ){let X=S;S=null,i(()=>mJ(J,$[0]),!1),S=X}}}function i(J,Q){if(S)return J();let $=!1;if(!Q)S=[];if(f)$=!0;else f=[];TJ++;try{let Z=J();return L4($),Z}catch(Z){if(!$)f=null;S=null,z0(Z)}}function L4(J){if(S){if(IJ&&B&&B.running)I4(S);else a0(S);S=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;f.push.apply(f,B.effects),Q=B.resolve;for(let W of f)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,i(()=>{for(let W of X)r(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let q=0,G=W.owned.length;qD4($),!1);if(Q)Q()}function a0(J){for(let Q=0;Q{Z.delete($),i(()=>{B.running=!0,q0($)},!1),B&&(B.running=!1)})}}function mJ(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)r(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)o0(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)r(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function o0(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return Y0(()=>t0(W)),()=>{let M=J()||[],V=M.length,R,H;return M[w4],a(()=>{let _,h,p,$J,HJ,F,j,z,U;if(V===0){if(q!==0)t0(W),W=[],Z=[],X=[],q=0,G&&(G=[]);if($.fallback)Z=[A4],X[0]=EJ((D)=>{return W[0]=D,$.fallback()}),q=1}else if(q===0){X=Array(V);for(H=0;H=F&&z>=F&&Z[j]===M[z];j--,z--)p[z]=X[j],$J[z]=W[j],G&&(HJ[z]=G[j]);_=new Map,h=Array(z+1);for(H=z;H>=F;H--)U=M[H],R=_.get(U),h[H]=R===void 0?-1:R,_.set(U,H);for(R=F;R<=j;R++)if(U=Z[R],H=_.get(U),H!==void 0&&H!==-1)p[H]=X[R],$J[H]=W[R],G&&(HJ[H]=G[R]),H=h[H],_.set(U,H);else W[R]();for(H=F;HJ(Q||{}));return v0($),Z}}return a(()=>J(Q||{}))}function vJ(){return!0}var h4={get(J,Q,$){if(Q===W0)return $;return J.get(Q)},has(J,Q){if(Q===W0)return!0;return J.has(Q)},set:vJ,deleteProperty:vJ,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:vJ,deleteProperty:vJ}},ownKeys(J){return J.keys()}};function G0(J){return!(J=typeof J==="function"?J():J)?{}:J}function x4(){for(let J=0,Q=this.length;J=0;G--){let M=G0(J[G])[q];if(M!==void 0)return M}},has(q){for(let G=J.length-1;G>=0;G--)if(q in G0(J[G]))return!0;return!1},keys(){let q=[];for(let G=0;G=0;q--){let G=J[q];if(!G)continue;let M=Object.getOwnPropertyNames(G);for(let V=M.length-1;V>=0;V--){let R=M[V];if(R==="__proto__"||R==="constructor")continue;let H=Object.getOwnPropertyDescriptor(G,R);if(!Z[R])Z[R]=H.get?{enumerable:!0,configurable:!0,get:x4.bind($[R]=[H.get.bind(G)])}:H.value!==void 0?H:void 0;else{let k=$[R];if(k){if(H.get)k.push(H.get.bind(G));else if(H.value!==void 0)k.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let q=W.length-1;q>=0;q--){let G=W[q],M=Z[G];if(M&&M.get)Object.defineProperty(X,G,M);else X[G]=M?M.value:void 0}return X}var f4=(J)=>`Stale read from <${J}>.`;function b4(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return MJ(S4(()=>J.each,J.children,Q||void 0))}function g4(J){let Q=J.keyed,$=MJ(()=>J.when,void 0,void 0),Z=Q?$:MJ($,void 0,{equals:(X,W)=>!X===!W});return MJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?a(()=>W(Q?X:()=>{if(!a(Z))throw f4("Show");return $()})):W}return J.fallback},void 0,void 0)}var T4=(J)=>MJ(()=>J());function E4({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:q,getParentNode:G,getFirstChild:M,getNextSibling:V}){function R(F,j,z,U){if(z!==void 0&&!U)U=[];if(typeof j!=="function")return H(F,j,U,z);s((D)=>H(F,j(),D,z),U)}function H(F,j,z,U,D){while(typeof z==="function")z=z();if(j===z)return z;let C=typeof j,w=U!==void 0;if(C==="string"||C==="number"){if(C==="number")j=j.toString();if(w){let P=z[0];if(P&&$(P))Z(P,j);else P=Q(j);z=h(F,z,U,P)}else if(z!==""&&typeof z==="string")Z(M(F),z=j);else h(F,z,U,Q(j)),z=j}else if(j==null||C==="boolean")z=h(F,z,U);else if(C==="function")return s(()=>{let P=j();while(typeof P==="function")P=P();z=H(F,P,z,U)}),()=>z;else if(Array.isArray(j)){let P=[];if(k(P,j,D))return s(()=>z=H(F,P,z,U,!0)),()=>z;if(P.length===0){let CJ=h(F,z,U);if(w)return z=CJ}else if(Array.isArray(z))if(z.length===0)p(F,P,U);else _(F,z,P);else if(z==null||z==="")p(F,P);else _(F,w&&z||[M(F)],P);z=P}else{if(Array.isArray(z)){if(w)return z=h(F,z,U,j);h(F,z,null,j)}else if(z==null||z===""||!M(F))X(F,j);else $J(F,j,M(F));z=j}return z}function k(F,j,z){let U=!1;for(let D=0,C=j.length;Dc-P){let Y2=j[w];while(P=0;w--){let P=j[w];if(D!==P){let CJ=G(P)===F;if(!C&&!w)CJ?$J(F,D,P):X(F,D,z);else CJ&&W(F,P)}else C=!0}}else X(F,D,z);return[D]}function p(F,j,z){for(let U=0,D=j.length;Uz.children=H(F,j.children,z.children));return s(()=>j.ref&&j.ref(F)),s(()=>{for(let D in j){if(D==="children"||D==="ref")continue;let C=j[D];if(C===z[D])continue;q(F,D,C,z[D]),z[D]=C}}),z}return{render(F,j){let z;return EJ((U)=>{z=U,R(j,F())}),z},insert:R,spread(F,j,z){if(typeof j==="function")s((U)=>HJ(F,j(),U,z));else HJ(F,j,void 0,z)},createElement:J,createTextNode:Q,insertNode:X,setProp(F,j,z,U){return q(F,j,z,U),z},mergeProps:e0,effect:s,memo:T4,createComponent:y4,use(F,j,z){return a(()=>F(j,z))}}}function N4(J){let Q=E4(J);return Q.mergeProps=e0,Q}var J1=480,Q1=272,ZJ={view:0,text:1,image:2},m4=1,v4=-1,u4={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},K={f32:0,color:1,int:2},l4={width:K.f32,height:K.f32,minW:K.f32,minH:K.f32,maxW:K.f32,maxH:K.f32,paddingT:K.f32,paddingR:K.f32,paddingB:K.f32,paddingL:K.f32,marginT:K.f32,marginR:K.f32,marginB:K.f32,marginL:K.f32,gap:K.f32,flexDir:K.int,justify:K.int,align:K.int,grow:K.f32,shrink:K.f32,basis:K.f32,flexWrap:K.int,posType:K.int,insetT:K.f32,insetR:K.f32,insetB:K.f32,insetL:K.f32,display:K.int,overflow:K.int,zIndex:K.int,hitPass:K.int,bgColor:K.color,gradFrom:K.color,gradTo:K.color,gradDir:K.int,radius:K.f32,opacity:K.f32,borderColor:K.color,borderWidth:K.f32,shadow:K.int,bevelOuterLight:K.color,bevelOuterDark:K.color,bevelInnerLight:K.color,bevelInnerDark:K.color,bevelWidth:K.f32,textColor:K.color,fontSlot:K.int,textAlign:K.int,lineHeight:K.f32,tracking:K.f32,translateX:K.f32,translateY:K.f32,scale:K.f32,rotate:K.f32,scaleX:K.f32,scaleY:K.f32,originX:K.f32,originY:K.f32,rotateX:K.f32,rotateY:K.f32,translateZ:K.f32,perspective:K.f32,arcStart:K.f32,arcSweep:K.f32,arcWidth:K.f32},N={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},p4={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},c4=1,G2=2,H2=1,j2=2,B2=131072,F2=1,K2=262144,M2=1,U2=1,V2=1,P2=2,R2=4,w2=8,D2=16,O2=1,C2=2;function $1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var L2=1,i4=1263551300,d4=1,s4=32,a4=24,v={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},XJ=32896,I2=0.016666666666666666;function Z1(J){return J.__viewport??null}var H0=null;function r4(){return null}function X1(J,Q=r4()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function o4(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return X1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return X1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function n4(J){H0=J}function UJ(){if(!H0)throw Error("PocketJS: host not installed — call render() first");return H0}function y(){return UJ().ops}function t4(J){globalThis.frame=J}function e4(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function J6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return $1($>>>16&255,$>>>8&255,$&255,255);return $1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function Q6(J,Q){let $=l4[J];if(typeof Q==="string"){if($===K.color)return J6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===K.color||$===K.int)return Q>>>0;return Q}var uJ=60,W1=[1,2,3,4,5,6,10,12,15,20,30,60],j0=uJ,o=-1,$6=0,AJ=[];function Z6(J){if(!Number.isFinite(J)||J<=0)return uJ;let Q=W1[0];for(let $ of W1)if(Math.abs($-J)Q.at<=o).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;AJ=AJ.filter((Q)=>Q.at>o);for(let Q of J)Q.cb()}var B0=0.12,lJ=XJ;function q6(J){lJ=J===void 0?XJ:J&65535}function z6(){lJ=XJ}function z1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function H6(){return z1(lJ&255)}var G1=new Set,j6=0;function B6(){G1.clear(),j6=0,z6()}function F6(J){for(let Q of[...G1])Q(J)}var WJ=null,H1=null;function K6(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function j1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function SJ(J){F0();let Q=WJ?WJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return H1.slice(Q.off,Q.off+Q.len)}var _J=null,A=null,YJ=null,pJ=0,qJ=[],M0=[],U0=[];function F1(J){if(_J=J,A=null,YJ=null,pJ=0,qJ.length=0,M0.length=0,U0.length=0,m){if(m.pressTarget=null,m.target=null,m.spriteDirty=!0,m.fresh=!0,m.vw=0,m.tex>=0){let Q=y();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(m.tex),m.tex=-1}}}function U6(J,Q){J.onPress=Q??void 0}function V6(J,Q){if(J.focusable=Q,P1(),!Q&&A===J)g(null)}function g(J){if(YJ&&YJ!==J)zJ(null);A=J,y().setFocus(J?J.id:0)}function zJ(J){if(YJ===J)return;let Q=y();if(YJ)Q.setActive?.(YJ.id,0);if(YJ=J,J)Q.setActive?.(J.id,1)}function V0(){return qJ.length>0?qJ[qJ.length-1]:_J}function P0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;g($[X])}function w6(){if(!A)return null;let J=V0();if(J&&!u(A,J))return null;for(let Q=M0.length-1;Q>=0;Q--){let $=M0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function D6(J){let Q=w6();if(!Q)return!1;let $=[];if(P0(Q.node,$),$.length===0){if(A)g(null);return!0}let Z=Q.columns,X=A?$.indexOf(A):-1;if(X<0)return g(K1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)g($[W]);return!0}function O6(){if(!A)return null;let J=V0();if(J&&!u(A,J))return null;for(let Q=U0.length-1;Q>=0;Q--){let $=U0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function cJ(J){let Q=O6();if(Q&&Q.move(J))return;if(D6(J))return;R6(J)}function M1(){U1(A)}function U1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function iJ(J){zJ(J)}function C6(J){g(J),U1(J)}function u(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function R0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=R0(Q.children[X]);if(W){g(W);return}}let Z=Q;while(Z){if(Z.focusable){g(Z);return}Z=Z.parent}}g(null)}var m=null,V1=0;function P1(){V1++}var I6=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],k6=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function A6(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=I6[Q]>>$&1,X=k6[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,q=X?255:0;J[W]=q,J[W+1]=q,J[W+2]=q,J[W+3]=255}return J}function S6(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=SJ($.image)}catch(q){if(UJ().strict)throw q;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):_6(Q,W),X<0&&UJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(A6(),16,16,p4.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function _6(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&c4)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function dJ(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=dJ($[Z],Q);if(X)return X}return null}var sJ=null;function R1(J){sJ=J}function w1(J){let Q=qJ.length>0?qJ[qJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||u($,Q)))return $;$=$.parent}return null}function D1(J,Q,$){return w1(O1(J,Q,$))}function O1(J,Q,$){if($!==void 0)return $===0?null:dJ(sJ??_J,$);let Z=y(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return dJ(sJ??_J,X(J,Q))}function y6(J,Q,$){let Z=m,X=y();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=Z1(X);if(Z.vw=H?H.w:J1,Z.vh=H?H.h:Q1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)S6(Z,X);let W=G6()*Z.speed,q=H6()*Z.speed;if(Z.dpadSpeed>0&&W===0&&q===0){if(J&v.LEFT)W=-Z.dpadSpeed;if(J&v.RIGHT)W=Z.dpadSpeed;if(J&v.UP)q=-Z.dpadSpeed;if(J&v.DOWN)q=Z.dpadSpeed}let G=Z.fresh;if(W!==0||q!==0){let H=X6()/60,k=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),_=Math.min(Math.max(Z.y+q*H,0),Z.vh-1);if(k!==Z.x||_!==Z.y)Z.x=k,Z.y=_,G=!0}if(G)X.setCursorPos(Z.x,Z.y);let M=(Q|$)&Z.button,V=V1;if(G||M!==0||V!==Z.gen)Z.gen=V,Z.fresh=!1,Z.target=w1(dJ(sJ??_J,X.hitTest(Z.x,Z.y)));let R=Z.target;if(R!==A)g(R);if(Q&Z.button&&R)Z.pressTarget=R;if(Z.pressTarget){if(zJ(R===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=R===Z.pressTarget;if(Z.pressTarget=null,zJ(null),H)M1()}}else if($&Z.button)zJ(null);return!0}function h6(J){let Q=J&~pJ,$=pJ&~J;if(pJ=J,m&&y6(J,Q,$))return;if($&v.CIRCLE)zJ(null);if(Q===0)return;if(Q&v.DOWN)cJ("down");if(Q&v.RIGHT)cJ("right");if(Q&v.UP)cJ("up");if(Q&v.LEFT)cJ("left");if(Q&v.CIRCLE)zJ(A),M1()}var w0=null;function C1(J){w0=J}function VJ(){if(P1(),w0)w0()}function x6(J,Q){J.debugName=Q||void 0,VJ()}var n={id:m4,type:ZJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},L1=Symbol.for("pocketjs.native-node"),D0=1,yJ=3,d=8,f6=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function aJ(J){return J.domAttrs??={}}function I1(J,Q){let $=J.domNodeType??(hJ(J)?yJ:D0),Z=$===yJ?rJ(J.text??""):$===d?T6(J.domData??""):x1(J.domTag??nJ(J));for(let X of Object.keys(J.domAttrs??{}))O0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)t(Z,I1(X,!0));return Z}function O0(J,Q,$){if(f6.has(Q)){RJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete aJ(J)[Q];else aJ(J)[Q]=$}function C0(J){if(J[L1]===!0)return J;return Object.defineProperty(J,L1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(hJ(J)?yJ:D0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else oJ(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else oJ(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===d)return J.domData??"";if(hJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===d)J.domData=Z;else if(hJ(J))oJ(J,Z);else if(p6(J),Z)t(J,rJ(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return b1(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??nJ(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===yJ)return"#text";if(J.domNodeType===d)return"#comment";return(J.domTag??nJ(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){RJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===n)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return t(J,$),$},insertBefore($,Z){return t(J,$,Z??null),$},removeChild($){return xJ(J,$),$},replaceChild($,Z){return t(J,$,Z),xJ(J,Z),Z},cloneNode($=!1){return I1(J,!!$)},remove(){if(J.parent)xJ(J.parent,J)},setAttribute($,Z){O0(J,$,Z)},removeAttribute($){O0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}C0(n);var L0=null;function b6(J){L0=J}var I0={unknownClass:0,unknownTexture:0},k1=new Map;function A1(J,Q){k1.set(J,Q)}var S1=new Map;function _1(J,Q){S1.set(J,Q)}var PJ=new Set,g6=new Set;function y1(J){if(!J)return!1;if(g6.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return C0({id:y().createNode(Q),type:Q,parent:null,children:[],domNodeType:D0,domTag:J})}function rJ(J){let Q=y(),$=Q.createNode(ZJ.text);return Q.setText($,J),C0({id:$,type:ZJ.text,parent:null,children:[],text:J,domNodeType:yJ,domTag:"#text"})}function T6(J=""){let Q=rJ("");return Q.domNodeType=d,Q.domTag="#comment",Q.domData=J,Q}function oJ(J,Q){y().replaceText(J.id,Q),J.text=Q,VJ()}function hJ(J){return J.type===ZJ.text}function f1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function t(J,Q,$){let Z=y();if(f1(Q),PJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,VJ()}function xJ(J,Q){if(!Q)return;L6(Q),y().removeChild(J.id,Q.id),f1(Q),PJ.add(Q),VJ()}function E6(J){return J.parent??void 0}function N6(J){return J.children[0]}function b1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function m6(J,Q){let $=y();if(VJ(),Q==null||Q===""){$.setStyle(J.id,v4);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=L0?L0(Q):void 0;if(Z===void 0){if(UJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);I0.unknownClass++;return}$.setStyle(J.id,Z)}function v6(J,Q){let $=y();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=k1.get(Q);if(Z===void 0){if(UJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);I0.unknownTexture++;return}$.setImage(J.id,Z)}function u6(J,Q){let $=y();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=S1.get(Q);if(Z===void 0){if(UJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);I0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function l6(J,Q,$){let Z=y(),X=Q??{},W=$??{},q=!1;for(let G in X){let M=X[G];if(W[G]===M)continue;let V=u4[G];if(V===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,V,Q6(G,M)),q=!0}if(q)VJ()}function RJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete aJ(J)[Q];else aJ(J)[Q]=$;switch(Q){case"class":return m6(J,$),$;case"onPress":case"on:press":return U6(J,$),$;case"src":return v6(J,$),$;case"sprite":return u6(J,$),$;case"style":return l6(J,$,Z),$;case"focusable":return V6(J,!!$),$;case"debugName":return x6(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${nJ(J)}>`)}function p6(J){for(let Q of[...J.children])xJ(J,Q)}function nJ(J){for(let Q of Object.keys(ZJ))if(ZJ[Q]===J.type)return Q;return String(J.type)}function c6(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}RJ(J,Q,$,Z)}var i6=N4({createElement:x1,createTextNode:rJ,replaceText:oJ,isTextNode:hJ,setProperty:c6,insertNode(J,Q,$){t(J,Q,$)},removeNode(J,Q){xJ(J,Q)},getParentNode:E6,getFirstChild:N6,getNextSibling:b1}),{render:d6,effect:k2,memo:s6,createComponent:O,createElement:g1,insert:A2,spread:a6,mergeProps:S2,use:_2}=i6,y2={linear:N.Easing.Linear,in:N.Easing.EaseIn,out:N.Easing.EaseOut,"in-out":N.Easing.EaseInOut,"out-back":N.Easing.OutBack,spring:N.Easing.Spring,"spring-bouncy":N.Easing.SpringBouncy},r6=null;function T1(J){r6=J}function o6(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function E1(J,Q){let $=g1(J);return a6($,Q,!1),o6(Q.nodeRef,$),$}function T(J){return E1("view",J)}function x(J){return E1("text",J)}var h2=new WeakMap,x2=new WeakMap,n6={}!==null?Object.freeze({...{}}):Object.freeze({}),f2=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:n6}),b2=new Map,e=36000,k0=30,t6=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(e),tapeAnalog:new Uint16Array(e),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-k0,saidHello:!1,hostCalls:0};function e6(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-k0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)C1(()=>{Y.treeDirty=!0}),q8();else C1(null);globalThis.__pocketDevtools=G8}function J8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)$8(),W8();let W=Q,q=$===void 0?XJ:$&65535,G=Z,M=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(e).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==XJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function v1(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,q]of J)Z.fill(W,X,Math.min(X+q,$)),X+=q;return Z}function u1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return v1(J.masks,0,Q)}function l1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return v1(J.analog??[],XJ,Q)}function p1(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,b({t:"hello",app:Y.app,host:z8(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` +`))if(X.trim())Z8(X)}}function Z8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)b({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),A0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),A0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":c1();break;case"eval":{let Z=!0,X;try{X=tJ((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}b({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":b({t:"tape",tape:m1()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}b({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())b({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else b({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=u1(Z),Y.replayAnalog=Z.analog?l1(Z):null,Y.replayTouch=Z.touch?p1(Z):null,Y.replayAt=0;break}default:break}}function X8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=k0)c1();if(Y.frame%t6===0)A0()}function W8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,b({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,b({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function A0(){b({t:"stats",frame:Y.frame,nodes:s1(n),tapeLen:Y.tapeLen,paused:Y.paused})}function c1(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,b({t:"tree",frame:Y.frame,root:d1(n)})}function Y8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function S0(J,Q){if(Array.isArray(J)){for(let $ of J)S0($,Q);return}if(Y8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)S0($,Q)}}function i1(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)S0(Z,Q)}function d1(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(i1(J,(X)=>{if(X.domNodeType===8)return;Z.push(d1(X))}),Z.length)Q.k=Z;return Q}function s1(J){let Q=1;return i1(J,($)=>{Q+=s1($)}),Q}function q8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{b({t:"log",level:$,args:X.map((W)=>tJ(W))}),Z?.apply(Q,X)}}}function tJ(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?a1(W):JSON.stringify(a1(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((q)=>tJ(q,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,q])=>`${W}: ${tJ(q,Q+1)}`).join(", ")}}`}function a1(J){return J.length>200?J.slice(0,199)+"…":J}function z8(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var G8={get frame(){return Y.frame},dumpTape:()=>m1(),replay:(J)=>{Y.replayMasks=u1(J),Y.replayAnalog=J.analog?l1(J):null,Y.replayTouch=J.touch?p1(J):null,Y.replayAt=0}},r1=new Map,_0=new Map;function o1(J){return J.trim().replace(/\s+/g," ")}function n1(J){return J.split(" ").sort().join(" ")}var t1=-1;function H8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=o1(Q);r1.set(Z,$);let X=n1(Z),W=_0.get(X);_0.set(X,W!==void 0&&W!==$?t1:$)}}function j8(J){let Q=o1(J),$=r1.get(Q);if($!==void 0)return $;let Z=_0.get(n1(Q));return Z===t1?void 0:Z}var y0=9,B8=(1<{let X=($&K8)!==0,W=X?h0:y0,q=X?M8:B8;return Object.freeze({id:$>>>(X?U8:F8)&255,x:$&q,y:$>>>W&q,hit:Q?.[Z]})}))}function P8(){return eJ}function R8(){eJ=x0}var e1=8,JJ=8,w8=3,D8=8,O8=6,C8=0.5,l=1,fJ=2,f0=4,GJ=8,wJ=[],J4=0,J0=0,QJ=Array.from({length:e1},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(JJ),histY:new Int16Array(JJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function L8(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function I8(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=O1(Q,$,Z.fact);let G=Z.hit;if(G)return L8(G,W)}let q=X.rect?.();if(!q)return!1;return Q>=q.x&&Q=q.y&&$=0;q--){let G=wJ[q];if(G.disposed)continue;if(J4>0&&!G.opts.allowWhenBlocked)continue;if(!I8(G,$,Z,W))continue;G.flags[J.slot]=l,J.owners.push(G)}for(let q of J.owners)q.opts.onDown?.(J)}function S8(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%JJ,J.histLenq||Z>q))X.flags[J.slot]|=fJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&l)||W&(fJ|f0))continue;if(!X.opts.onLongPress)continue;let q=Math.max(1,Math.round((X.opts.longPressSeconds??C8)*Y1()));if(J.frames=0)wJ.splice($,1)},cancel(){if(!Q.disposed)Z4(Q)},get panning(){for(let $ of QJ)if($.used&&Q.flags[$.slot]&GJ)return!0;return!1}}}function f8(J){let Q=x8(J);return Y0(()=>Q.dispose()),Q}function X4(){wJ.length=0,J4=0,J0=0;for(let J of QJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function b8(){return f8({onDown:(J)=>{let Q=D1(J.x,J.y,J.hit);if(Q)iJ(Q)},onTap:(J)=>{iJ(null);let Q=D1(J.x,J.y,J.hit);if(Q)C6(Q)},onUp:()=>iJ(null),onCancel:()=>iJ(null)})}var g8=1,b0=new Map,Q0=[];function T8(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function E8(){g8=1,b0.clear(),Q0=[]}function N8(){if(Q0.length===0)return;let J=Q0;Q0=[];for(let{id:Q,result:$}of J){let Z=b0.get(Q);if(!Z)continue;b0.delete(Q),T8()?.({t:"delivery",frame:q1(),id:Q,kind:Z.kind}),Z.onResult($)}}var m8={"flex-col w-full h-full bg-slate-50":0,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":1,"flex-row items-center gap-4":2,"text-2xl text-white":3,"flex-col":4,"text-sm text-indigo-300 tracking-wide":5,"text-2xl text-white font-bold":6,"px-3 py-2 bg-indigo-900":7,"text-sm text-indigo-200":8,"p-6 flex-col gap-3":9,"text-sm text-indigo-700 font-bold":10,"text-2xl text-slate-950 font-bold":11,"text-base text-slate-600":12,"grow px-6 pt-4 flex-col gap-3":13,"h-[430] px-12 flex-col items-center justify-center bg-white":14,"w-[88] h-[88] items-center justify-center bg-indigo-100":15,"text-2xl text-indigo-700 font-bold":16,"pt-7 text-xl text-slate-900 font-bold":17,"pt-4 text-base text-slate-500":18,"h-[118] px-5 flex-row items-center justify-between bg-white":19,"w-[500] flex-col gap-2":20,"text-base text-slate-900 font-bold":21,"text-sm text-slate-500":22,"text-sm text-indigo-600 font-bold":23,"px-3 py-2 bg-emerald-100":24,"px-3 py-2 bg-red-100":25,"text-sm text-emerald-700":26,"text-sm text-red-500":27,"h-[96] px-6 flex-row items-center bg-slate-950":28,"text-sm text-slate-300":29,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":30,"absolute inset-0 z-50 flex-col items-center justify-center":31,"absolute inset-0 bg-slate-950":32,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":33,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":34,"flex-row flex-wrap":35,grow:36};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var v8="ui:styles",u8="ui:font.",W4="ui:img.",Y4="ui:sprite.";function l8(){return globalThis.ui}function p8(J){if(J.__textures)return;for(let Q of K0(W4)){let $=SJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)A1(Q.slice(W4.length),Z)}}function c8(J){if(J.__sprites)return;for(let Q of K0(Y4)){let $=SJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),q=$[4],G=Z.getUint16(6,!0),M=Z.getUint16(8,!0),V=Z.getUint16(10,!0),R=J.uploadTexture($.subarray(16),X,W,q);if(R>=0)_1(Q.slice(Y4.length),{handle:R,frames:G,cols:M,step:V})}}function q4(J){let Q=g1("view");return RJ(Q,"style",J,void 0),Q}var $0=null,Z0=null;function i8(J,Q){if(!$0||!Z0)return;RJ($0,"style",{width:J,height:Q,overflow:N.Overflow.Hidden},void 0),RJ(Z0,"style",{width:J,height:Q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=y();$.__viewport={w:J,h:Q}}function d8(J,Q={}){let $=o4(Q.ops);if(n4($),b6(j8),Q.styles)H8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let k in Z)A1(k,Z[k]);let H=$.ops.__sprites;if(H)for(let k in H)_1(k,H[k])}if($.kind==="injected"||Z===void 0){if(Q.pak)B1(Q.pak);if(M6()){for(let H of K0())if(H===v8)$.ops.loadStyles?.(SJ(H));else if(H.startsWith(u8))$.ops.loadFontAtlas?.(SJ(H))}}let X=Z1($.ops),W=X?.w??J1,q=X?.h??Q1,G=q4({width:W,height:q,overflow:N.Overflow.Hidden}),M=q4({width:W,height:q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});t(n,G),t(n,M),T1(M),$0=G,Z0=M,F1(G),R1(n),B6(),X4(),b8(),W6(),E8(),e6($.ops),t4(J8((H,k,_,h)=>{Y6(),q6(k),V8(_,h),N8(),h8(),F6(H),h6(H),h1()}));let V=d6(J,G),R=e4(i8);return()=>{R(),R8(),X4(),V(),F1(null),R1(null),T1(null),$0=null,Z0=null;for(let H of n.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);h1()}}function s8(J,Q={}){let $=Q.ops??l8();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)B1(Q.pak);return p8($),c8($),d8(J,{ops:$,styles:Q.styles??m8,pak:Q.pak})}var z4="$b",a8=9007199254740991,r8=":memory:",DJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function o8(J){let Q="";for(let $=0;$>2]+DJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2>16,Z<$.length)$[Z++]=W>>8&255;if(Z<$.length)$[Z++]=W&255}return $}function t8(){let J=globalThis.db;if(!J||typeof J!=="object")return null;return typeof J.open==="function"?J:null}function G4(J){if(J instanceof Uint8Array)return{[z4]:o8(J)};if(typeof J==="number"&&!Number.isFinite(J))throw Error("db: cannot bind a non-finite number");if(typeof J==="number"&&Number.isInteger(J)&&Math.abs(J)>a8)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function e8(J){if(J!==null&&typeof J==="object")return n8(J[z4]);return J}function J2(J){if(Array.isArray(J))return JSON.stringify(J.map(G4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=G4(Z);return JSON.stringify(Q)}class g0{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,J2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=H4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(e8))}run(...J){let Q=this.execute(H4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function H4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class j4{statements=new Map;txDepth=0;constructor(J=r8){let Q=t8();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new g0(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new g0(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let q=J(...Q);return this.txDepth--,this.exec(X),q}catch(q){throw this.txDepth--,this.exec(W),q}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var B4=3,OJ=new j4("exa"),[F4,T0]=kJ([]),[Q2,E0]=kJ("SEARCH HISTORY IS LOCAL"),X0=-1;function $2(J){try{return JSON.parse(J)}catch{return null}}function Z2(J){let Q=new Date(J*1000).toISOString();return Q.slice(0,10)+" · "+Q.slice(11,16)+" UTC"}function K4(J){if(X0===J)return;try{let Q=OJ.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==B4){T0([]),E0("SEARCH HISTORY IS LOCAL");return}let $=OJ.query(` + SELECT search.id,search.query,search.searched_at,search.status,search.result_count, + result.title AS top_title,result.url AS top_url,search.error + FROM searches search + LEFT JOIN search_results result ON result.search_id=search.id AND result.rank=0 + ORDER BY search.id DESC LIMIT 8 + `).all();T0($),E0($[0]?.status==="error"?String($[0].error||"EXA SEARCH FAILED").slice(0,80):$.length?"SEARCH HISTORY UPDATED FROM SQLITE":"SEARCH HISTORY IS LOCAL"),X0=J}catch{T0([]),E0("SEARCH HISTORY IS LOCAL")}}function X2(){let J=OJ.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((W)=>W.name)),$=J.map((W)=>{let q=OJ.query("SELECT COUNT(*) AS count FROM "+W.name).get().count;return{name:W.name,rowCount:q,schema:W.sql}}),Z=Q.has("searches")?OJ.query(` + SELECT search.id,search.query,search.searched_at,search.status,search.result_count, + result.title AS top_title,result.url AS top_url,search.error + FROM searches search + LEFT JOIN search_results result ON result.search_id=search.id AND result.rank=0 + ORDER BY search.id DESC LIMIT 8 + `).all():[],X=Q.has("documents")?OJ.query("SELECT fetched_at,url,title,LENGTH(text) AS text_bytes FROM documents ORDER BY fetched_at DESC LIMIT 5").all():[];return{database:"exa.sqlite",schemaVersion:B4,tables:$,latestSearches:Z,latestDocuments:X}}function W2(){return O(T,{class:"flex-col w-full h-full bg-slate-50",get children(){return[O(T,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[O(T,{class:"flex-row items-center gap-4",get children(){return[O(x,{class:"text-2xl text-white",children:"‹"}),O(T,{class:"flex-col",get children(){return[O(x,{class:"text-sm text-indigo-300 tracking-wide",children:"POCKET APP"}),O(x,{class:"text-2xl text-white font-bold",children:"Exa Research"})]}})]}}),O(T,{class:"px-3 py-2 bg-indigo-900",get children(){return O(x,{class:"text-sm text-indigo-200",children:"SQLITE HISTORY"})}})]}}),O(T,{class:"p-6 flex-col gap-3",get children(){return[O(x,{class:"text-sm text-indigo-700 font-bold",children:"AGENT RESEARCH MEMORY"}),O(x,{class:"text-2xl text-slate-950 font-bold",children:"Search history"}),O(x,{class:"text-base text-slate-600",children:"Every research.search call is saved here automatically."})]}}),O(T,{class:"grow px-6 pt-4 flex-col gap-3",get children(){return[O(g4,{get when(){return F4().length===0},get children(){return O(T,{class:"h-[430] px-12 flex-col items-center justify-center bg-white",get children(){return[O(T,{class:"w-[88] h-[88] items-center justify-center bg-indigo-100",get children(){return O(x,{class:"text-2xl text-indigo-700 font-bold",children:"E"})}}),O(x,{class:"pt-7 text-xl text-slate-900 font-bold",children:"No searches yet"}),O(x,{class:"pt-4 text-base text-slate-500",children:`Ask Pi Agent to research a topic. +The search and its results will appear here.`})]}})}}),O(b4,{get each(){return F4()},children:(J)=>O(T,{class:"h-[118] px-5 flex-row items-center justify-between bg-white",get children(){return[O(T,{class:"w-[500] flex-col gap-2",get children(){return[O(x,{class:"text-base text-slate-900 font-bold",get children(){return J.query.slice(0,72)}}),O(x,{class:"text-sm text-slate-500",get children(){return(J.top_title||J.error||"No result title").slice(0,92)}}),O(x,{class:"text-sm text-indigo-600 font-bold",get children(){return Z2(J.searched_at)}})]}}),O(T,{get["class"](){return J.status==="ok"?"px-3 py-2 bg-emerald-100":"px-3 py-2 bg-red-100"},get children(){return O(x,{get["class"](){return J.status==="ok"?"text-sm text-emerald-700":"text-sm text-red-500"},get children(){return s6(()=>J.status==="ok")()?J.result_count+" RESULTS":"FAILED"}})}})]}})})]}}),O(T,{class:"h-[96] px-6 flex-row items-center bg-slate-950",get children(){return O(x,{class:"text-sm text-slate-300",get children(){return Q2()}})}})]}})}K4(0),s8(()=>O(W2,{})),globalThis.PocketPiApp={tick(){return""},update(){return""},dataChanged(J){let Q=$2(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),X0):X0;return K4($),""},invokeTool(J){try{let Q=J==="research.storage_status"?X2():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Unknown Exa task: "+J,isError:!0})},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});return""}}})(); diff --git a/apps/exa/dist/app.pak b/apps/exa/dist/app.pak new file mode 100644 index 0000000000000000000000000000000000000000..b8e89aec43818bda46473aa8500e2382f1a24749 GIT binary patch literal 317776 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 Ni2p~Cf+ev&{~t6+zOVoQ literal 0 HcmV?d00001 diff --git a/apps/exa/dist/data-action.js b/apps/exa/dist/data-action.js new file mode 100644 index 0000000..705e838 --- /dev/null +++ b/apps/exa/dist/data-action.js @@ -0,0 +1,37 @@ +(()=>{var h=globalThis.db,E=h.open("exa");if(E<0)throw Error("open exa.sqlite");var I=3;function O(){return String(h.lastError(E)||"SQLite operation failed")}function c(r){if(h.exec(E,r)!==0)throw Error(O())}function N(r,n=[]){let e=JSON.parse(h.query(E,r,JSON.stringify(n)));if(e.error)throw Error(String(e.error));return e}function l(r,n=[]){return N(r,n)}var m=N("PRAGMA user_version");if(Number(m?.user_version??0)!==I)c(` + CREATE TABLE IF NOT EXISTS searches ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + query TEXT NOT NULL, + searched_at INTEGER NOT NULL, + status TEXT NOT NULL, + result_count INTEGER NOT NULL DEFAULT 0, + error TEXT + ); + CREATE INDEX IF NOT EXISTS searches_recent ON searches(id DESC); + CREATE TABLE IF NOT EXISTS search_results ( + search_id INTEGER NOT NULL, + rank INTEGER NOT NULL, + title TEXT, + url TEXT NOT NULL, + published_at TEXT, + author TEXT, + score TEXT, + highlight TEXT, + PRIMARY KEY(search_id, rank) + ); + CREATE INDEX IF NOT EXISTS search_results_url ON search_results(url); + CREATE TABLE IF NOT EXISTS documents ( + url TEXT PRIMARY KEY, + fetched_at INTEGER NOT NULL, + title TEXT, + published_at TEXT, + author TEXT, + text TEXT NOT NULL + ); + CREATE INDEX IF NOT EXISTS documents_recent ON documents(fetched_at DESC); + PRAGMA user_version=3; + `);function f(){return Math.floor(Date.now()/1000)}function A(r){return r===null||r===void 0||typeof r==="object"?null:String(r)}function s(r,n){if(!r||typeof r!=="object")return null;for(let e of n){let t=A(r[e]);if(t!==null)return t}return null}function x(r){if(Array.isArray(r?.highlights))return r.highlights.map(String).join(` +`).slice(0,1200);return s(r,["highlight","summary","text"])?.slice(0,1200)??null}function y(r,n){let e=JSON.parse(globalThis.services.call("net.http","post",JSON.stringify({connection:"exa",path:r,body:n})));if(!e.ok)throw Error(e.error||"Exa service failed");return e.value}function T(r){c("BEGIN IMMEDIATE");try{r(),c("COMMIT")}catch(n){try{c("ROLLBACK")}catch{}throw n}globalThis.app.commit()}function _(r){let n=String(r.query??"").trim();if(!n)throw Error("query is required");let e=f();try{let t={query:n,type:r.searchType??"auto",numResults:Math.max(1,Math.min(8,Number(r.numResults??5))),contents:{highlights:{maxCharacters:800}}};for(let i of["includeDomains","excludeDomains","startPublishedDate","endPublishedDate"])if(r[i]!==void 0)t[i]=r[i];let o=y("/search",t),u=Array.isArray(o?.results)?o.results.slice(0,8):[];return T(()=>{let i=l("INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,?,NULL)",[n,e,"ok",u.length]),g=Number(i.lastInsertRowid||0);u.forEach((a,S)=>{let d=s(a,["url","id"]);if(!d)return;l(`INSERT INTO search_results(search_id,rank,title,url,published_at,author,score,highlight) + VALUES(?,?,?,?,?,?,?,?)`,[g,S,s(a,["title"]),d,s(a,["publishedDate","published_at","date"]),s(a,["author"]),s(a,["score"]),x(a)])})}),o}catch(t){let o=t instanceof Error?t.message:String(t);throw T(()=>l("INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,0,?)",[n,e,"error",o])),t}}function p(r){let n=String(r.url??"").trim();if(!n)throw Error("url is required");let e=y("/contents",{urls:[n],text:{maxCharacters:Math.max(200,Math.min(12000,Number(r.maxCharacters??6000))),includeHtmlTags:!1}}),t=Array.isArray(e?.results)?e.results[0]:e;if(!t)throw Error("Exa returned no document");let o=s(t,["url","id"])||n,u=s(t,["text","content","summary"])||"";return T(()=>l(`INSERT INTO documents(url,fetched_at,title,published_at,author,text) VALUES(?,?,?,?,?,?) + ON CONFLICT(url) DO UPDATE SET fetched_at=excluded.fetched_at,title=excluded.title, + published_at=excluded.published_at,author=excluded.author,text=excluded.text`,[o,f(),s(t,["title"]),s(t,["publishedDate","published_at","date"]),s(t,["author"]),u])),{status:"ok",provider:"exa",requestId:e?.requestId,document:t,costDollars:e?.costDollars}}globalThis.PocketPiData={invokeTask(r){return JSON.stringify({text:"Unknown Exa Data Action: "+r,isError:!0})},invokeTool(r,n){try{let e=JSON.parse(n),t=r==="research.search"?_(e):r==="research.fetch"?p(e):(()=>{throw Error("Unknown Exa tool: "+r)})();return JSON.stringify({text:JSON.stringify(t),details:t,isError:!1})}catch(e){return JSON.stringify({text:e instanceof Error?e.message:String(e),isError:!0})}}};})(); diff --git a/apps/exa/pocket.json b/apps/exa/pocket.json new file mode 100644 index 0000000..dd51fa8 --- /dev/null +++ b/apps/exa/pocket.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://pocketjs.dev/schema/pocket-2.json", + "pocket": 2, + "id": "dev.pocket-stack.exa", + "name": "exa", + "title": "Exa Research", + "version": "1.0.0", + "engine": {"capabilities":{"requires":["data.fs","data.sqlite"]}}, + "app": {"entry":"app.tsx","output":"app","framework":"solid","viewport":{"logical":[720,1280],"presentation":"fit"}} +} diff --git a/apps/pi-agent/agent-app.json b/apps/pi-agent/agent-app.json new file mode 100644 index 0000000..5c43d51 --- /dev/null +++ b/apps/pi-agent/agent-app.json @@ -0,0 +1,7 @@ +{ + "id": "pi-agent", + "version": "1.0.0", + "tools": [], + "tasks": [], + "schedules": [] +} diff --git a/apps/pi-agent/app.tsx b/apps/pi-agent/app.tsx new file mode 100644 index 0000000..4504605 --- /dev/null +++ b/apps/pi-agent/app.tsx @@ -0,0 +1,599 @@ +import { batch, createSignal, For, Show } from "solid-js"; +import { Text, View } from "@pocketjs/framework/components"; +import { mount } from "@pocketjs/framework"; +import { readFileSync, readdirSync, type DirEntry } from "@pocketjs/framework/fs"; +import { ActionButton, PocketHeader } from "../_shared/ui"; +import { wrapLines, wrapPreview } from "../_shared/text"; + +const FONT_BODY = 2; +const FONT_CAPTION = 1; +const CHAT_TEXT_WIDTH = 536; +const READER_TEXT_WIDTH = 544; +const READER_PAGE_LINES = 46; + +type Message = { role: string; text: string }; +type Network = { ssid: string; rssiDbm: number; secured: boolean }; +type Projection = { + agent?: string; + model?: string; + messages?: Message[]; + schedule?: { name?: string | null; prompt?: string; next?: string; everyMinutes?: number | null }; + settings?: { + wifi?: { + connectedSsid?: string | null; + ipAddress?: string | null; + rssiDbm?: number | null; + scanning?: boolean; + networks?: Network[]; + status?: string; + }; + firmwareVersion?: string; + workspaceFree?: string; + }; +}; + +type Tab = "chat" | "files" | "apps" | "settings"; +type Screen = Tab | "keyboard" | "viewer" | "reader"; +type KeyboardPurpose = { type: "prompt" } | { type: "wifi"; ssid: string }; +type FileEntry = { name: string; kind: "file" | "dir"; size: number }; +type Reader = { author: "YOU" | "PI"; text: string }; + +const [projection, setProjection] = createSignal({ + agent: "STARTING", + model: "CODEX / UART / MAC", + messages: [{ role: "assistant", text: "BOOTING PI AGENT..." }], +}); +const [screen, setScreen] = createSignal("chat"); +const [activeTab, setActiveTab] = createSignal("chat"); +const [chatScroll, setChatScroll] = createSignal(0); +const [filePath, setFilePath] = createSignal(""); +const [fileOffset, setFileOffset] = createSignal(0); +const [files, setFiles] = createSignal([]); +const [fileError, setFileError] = createSignal(""); +const [viewer, setViewer] = createSignal<{ path: string; text: string; lineOffset: number } | null>(null); +const [reader, setReader] = createSignal(null); +const [readerOffset, setReaderOffset] = createSignal(0); +const [input, setInput] = createSignal(""); +const [keyboardMode, setKeyboardMode] = createSignal<"letters" | "numbers">("letters"); +const [uppercase, setUppercase] = createSignal(false); +const [keyboardPurpose, setKeyboardPurpose] = createSignal({ type: "prompt" }); +const [wifiOffset, setWifiOffset] = createSignal(0); +const fileCache = new Map(); + +const letterRows = ["qwertyuiop", "asdfghjkl", "zxcvbnm"]; +const numberRows = ["1234567890", "-/:;()$&@", ".,?!'\"+"]; +const tabNames: Tab[] = ["chat", "files", "apps", "settings"]; + +function formatSize(size: number): string { + if (size < 1024) return size + " B"; + if (size < 1024 * 1024) return (size / 1024).toFixed(1) + " KB"; + return (size / (1024 * 1024)).toFixed(1) + " MB"; +} + +function joinPath(parent: string, name: string): string { + return parent ? parent + "/" + name : name; +} + +function refreshFiles(path = filePath(), force = false) { + const cached = fileCache.get(path); + if (!force && cached) { + setFiles(cached); + setFileError(""); + setFileOffset((value) => Math.min(value, Math.max(0, cached.length - 8))); + return; + } + try { + const next = (readdirSync(path, { withFileTypes: true }) as DirEntry[]).map((entry) => ({ + name: entry.name, + kind: entry.isDirectory() ? "dir" as const : "file" as const, + size: entry.size, + })); + fileCache.set(path, next); + setFiles(next); + setFileError(""); + setFileOffset((value) => Math.min(value, Math.max(0, next.length - 8))); + } catch (error) { + setFiles([]); + setFileError(error instanceof Error ? error.message : String(error)); + } +} + +function chatTurns(): Array<{ user: string; assistant: string }> { + const out: Array<{ user: string; assistant: string }> = []; + for (const message of projection().messages ?? []) { + if (message.role === "user") { + out.push({ user: message.text, assistant: "THINKING..." }); + } else if (out.length === 0) { + out.push({ user: "TYPE A MESSAGE", assistant: message.text || "THINKING..." }); + } else { + out[out.length - 1].assistant = message.text || "THINKING..."; + } + } + return out.length ? out : [{ user: "TYPE A MESSAGE", assistant: "BOOTING PI AGENT..." }]; +} + +function visibleTurns() { + const all = chatTurns(); + const max = Math.max(0, all.length - 2); + const scroll = Math.min(chatScroll(), max); + const end = all.length - scroll; + return all.slice(Math.max(0, end - 2), end); +} + +function Header(props: { title: string }) { + return ( + + ); +} + +function ScrollButtons(props: { top: string; bottom: string }) { + return ( + <> + UP + DN + + ); +} + +function BottomBar() { + return ( + + {(name) => ( + + {name.toUpperCase()} + + )} + + ); +} + +function ChatScreen() { + const schedule = () => projection().schedule; + return ( + +
+ + {(turn) => ( + + + + YOU + + {wrapPreview(turn.user, FONT_BODY, CHAT_TEXT_WIDTH, 3)} + + + + PI + + {wrapPreview(turn.assistant, FONT_BODY, CHAT_TEXT_WIDTH, 3)} + + )} + + + + NEXT WAKE + {"NO WAKE SCHEDULED\n\nASK PI TO CREATE ONE WITH SCHEDULE.SET"} + }> + + {String(schedule()?.name) + " " + String(schedule()?.next ?? "") + "\n\n" + String(schedule()?.prompt ?? "")} + + + + + + + + + ); +} + +function FilesScreen() { + const visible = () => files().slice(fileOffset(), fileOffset() + 8); + return ( + +
+ + + {"/workspace" + (filePath() ? "/" + filePath() : "")} + + + {(entry) => ( + + + {entry.kind === "dir" ? "D" : "F"} + + + {(entry.name + (entry.kind === "dir" ? "/" : "")).slice(0, 60)} + {entry.kind === "dir" ? "FOLDER" : formatSize(entry.size)} + + + )} + + + {fileError() || "THIS DIRECTORY IS EMPTY"} + + 8}> + + + + ); +} + +function AppsScreen() { + return ( + +
+ + 2 INSTALLED APPS + + + R + RobinhoodPortfolio and positionsUPDATES EVERY 5 MINUTES + + + + + + E + Exa ResearchAgent search historySTORED LOCALLY IN SQLITE + + + + + {"APP DATA STAYS ISOLATED.\nPI AGENT CAN USE EACH APP'S TOOLS."} + + + + + ); +} + +function SettingsScreen() { + const settings = () => projection().settings ?? {}; + const wifi = () => settings().wifi ?? {}; + const networks = () => (wifi().networks ?? []).slice(wifiOffset(), wifiOffset() + 5); + const detail = () => wifi().ipAddress + ? "IP " + wifi().ipAddress + " RSSI " + String(wifi().rssiDbm ?? "--") + " DBM" + : wifi().status || "SCAN AND SELECT A NETWORK"; + return ( + +
+ + + WI-FI + {wifi().connectedSsid || "NOT CONNECTED"} + {detail()} + + {wifi().scanning ? "SCANNING" : "SCAN"} + + + AVAILABLE NETWORKS + + 0} fallback={ + {"NO NETWORK LIST YET\n\nTAP SCAN TO FIND WI-FI"} + }> + {(network) => ( + + {network.ssid} + {String(network.rssiDbm) + " DBM " + (network.secured ? "LOCK" : "OPEN")} + + )} + + 5}> + + + MODEL BACKEND + {projection().model ?? "UNKNOWN"} + {"FIRMWARE " + String(settings().firmwareVersion ?? "0.1.0") + " · WORKSPACE FREE " + String(settings().workspaceFree ?? "--")} + + + FORGET WI-FI + RESTART DEVICE + + + + + ); +} + +function KeyboardScreen() { + const purpose = () => keyboardPurpose(); + const rows = () => keyboardMode() === "letters" ? letterRows : numberRows; + const display = () => purpose().type === "wifi" ? "*".repeat(input().length) : input(); + return ( + +
+ + + {display() || (purpose().type === "wifi" ? "ENTER NETWORK PASSWORD..." : "TYPE YOUR MESSAGE...")} + + {String(input().length) + " / " + (purpose().type === "wifi" ? "63" : "256") + " CHARACTERS"}CLEAR + {(row, rowIndex) => ( + + {(key) => ( + {uppercase() ? key.toUpperCase() : key} + )} + DEL + + )} + + {keyboardMode() === "letters" ? "123" : "ABC"} + SPACE + {keyboardMode() === "letters" ? "SHIFT" : ". ?"} + {purpose().type === "wifi" ? "JOIN" : "SEND"} + + + CLOSE KEYBOARD + + ); +} + +function ViewerScreen() { + const current = () => viewer(); + const lines = () => (current()?.text ?? "").split("\n"); + const offset = () => current()?.lineOffset ?? 0; + return ( + +
+ + {current()?.path ?? "NO FILE OPEN"} + + {lines().slice(offset(), offset() + 39).join("\n")} + + {"LINES " + String(offset() + 1) + "-" + String(Math.min(offset() + 39, lines().length)) + " / " + String(lines().length)} + + + + ); +} + +function ReaderScreen() { + const current = () => reader(); + const lines = () => wrapLines(current()?.text ?? "", FONT_CAPTION, READER_TEXT_WIDTH); + return ( + +
+ + {current()?.author ?? "PI"} + {lines().slice(readerOffset(), readerOffset() + READER_PAGE_LINES).join("\n")} + + + + ); +} + +function Root() { + return ( + + {screen() === "chat" ? + : screen() === "files" ? + : screen() === "apps" ? + : screen() === "settings" ? + : screen() === "keyboard" ? + : screen() === "viewer" ? + : } + + ); +} + +function openTab(tab: Tab) { + batch(() => { + setActiveTab(tab); + setScreen(tab); + if (tab === "files") refreshFiles(); + }); +} + +function keyboardCharacterAt(x: number, y: number): string | null { + const rows = keyboardMode() === "letters" ? letterRows : numberRows; + const ys = [488, 628, 768]; + for (let row = 0; row < 3; row++) { + if (y < ys[row] || y >= ys[row] + 120) continue; + const chars = rows[row]; + const available = row === 2 ? 560 : 672; + const width = available / chars.length; + const index = Math.floor((x - 24) / width); + if (index >= 0 && index < chars.length) return chars[index]; + } + return null; +} + +function handleKeyboardTap(x: number, y: number): string { + if (y >= 1164) { + setInput(""); + setScreen(activeTab()); + return ""; + } + if (x >= 548 && y >= 402 && y <= 482) { + setInput(""); + return ""; + } + const key = keyboardCharacterAt(x, y); + if (key) { + const next = keyboardMode() === "letters" && uppercase() ? key.toUpperCase() : key; + const limit = keyboardPurpose().type === "wifi" ? 63 : 256; + if (input().length < limit) setInput(input() + next); + return ""; + } + if (x >= 592 && y >= 768 && y <= 888) { + setInput(input().slice(0, -1)); + return ""; + } + if (y >= 908 && y <= 1064) { + if (x <= 116) { + setKeyboardMode(keyboardMode() === "letters" ? "numbers" : "letters"); + setUppercase(false); + } else if (x <= 424) { + if (input()) setInput(input() + " "); + } else if (x <= 576) { + if (keyboardMode() === "letters") setUppercase(!uppercase()); + else setInput(input() + (x <= 500 ? "." : "?")); + } else if (input().trim()) { + const value = input().trim(); + const purpose = keyboardPurpose(); + setInput(""); + setKeyboardMode("letters"); + setUppercase(false); + setScreen(activeTab()); + if (purpose.type === "wifi") return JSON.stringify({ type: "settings", command: "connect", ssid: purpose.ssid, password: value }); + return JSON.stringify({ type: "submitPrompt", prompt: value }); + } + } + return ""; +} + +mount(() => ); +queueMicrotask(() => refreshFiles("", true)); + +(globalThis as any).PocketPiApp = { + tick() { + return ""; + }, + update(line: string) { + setProjection(JSON.parse(line)); + return ""; + }, + dataChanged() { + fileCache.delete(filePath()); + if (activeTab() === "files") refreshFiles(filePath(), true); + return ""; + }, + invokeTool() { + return JSON.stringify({ text: "Pi Agent has no App tools", isError: true }); + }, + invokeTask() { + return JSON.stringify({ text: "Pi Agent has no App tasks", isError: true }); + }, + tap(x: number, y: number) { + if (screen() === "keyboard") return handleKeyboardTap(x, y); + if (screen() === "viewer") { + const current = viewer(); + if (x < 104 && y < 112) { + setViewer(null); + setScreen("files"); + } else if (current && x >= 620 && y >= 170 && y <= 340) { + setViewer({ ...current, lineOffset: Math.max(0, current.lineOffset - 18) }); + } else if (current && x >= 620 && y >= 920 && y <= 1100) { + setViewer({ ...current, lineOffset: Math.min(Math.max(0, current.text.split("\n").length - 39), current.lineOffset + 18) }); + } + return ""; + } + if (screen() === "reader") { + if (x < 104 && y < 112) { + setReader(null); + setReaderOffset(0); + setScreen("chat"); + } else if (x >= 620 && y >= 170 && y <= 340) { + setReaderOffset(Math.max(0, readerOffset() - 18)); + } else if (x >= 620 && y >= 920 && y <= 1100) { + const lineCount = wrapLines(reader()?.text ?? "", FONT_CAPTION, READER_TEXT_WIDTH).length; + setReaderOffset(Math.min(Math.max(0, lineCount - READER_PAGE_LINES), readerOffset() + 18)); + } + return ""; + } + if (y >= 1172) { + openTab(tabNames[Math.min(3, Math.floor(x / 180))]); + return ""; + } + if (screen() === "chat") { + if (x >= 620 && y >= 140 && y <= 272) setChatScroll(chatScroll() + 2); + else if (x >= 620 && y >= 624 && y <= 756) setChatScroll(Math.max(0, chatScroll() - 2)); + else if (x < 610 && y >= 140 && y < 738) { + const row = Math.floor((y - 140) / 320); + const turn = visibleTurns()[row]; + if (turn) { + const isPi = y >= 140 + row * 320 + 150; + setReader({ author: isPi ? "PI" : "YOU", text: isPi ? turn.assistant : turn.user }); + setReaderOffset(0); + setScreen("reader"); + } + } else if (y >= 1070 && y <= 1150) { + setKeyboardPurpose({ type: "prompt" }); + setInput(""); + setScreen("keyboard"); + } + return ""; + } + if (screen() === "files") { + if (x < 104 && y < 112 && filePath()) { + const parts = filePath().split("/"); + parts.pop(); + const next = parts.join("/"); + setFilePath(next); + setFileOffset(0); + refreshFiles(next); + } else if (x >= 620 && y >= 170 && y <= 340) { + setFileOffset(Math.max(0, fileOffset() - 4)); + } else if (x >= 620 && y >= 920 && y <= 1100) { + setFileOffset(Math.min(Math.max(0, files().length - 8), fileOffset() + 4)); + } else if (x < 610 && y >= 190) { + const row = Math.floor((y - 190) / 104); + const entry = files()[fileOffset() + row]; + if (entry) { + const path = joinPath(filePath(), entry.name); + if (entry.kind === "dir") { + setFilePath(path); + setFileOffset(0); + refreshFiles(path); + } else { + try { + setViewer({ path: "/workspace/" + path, text: readFileSync(path, "utf8"), lineOffset: 0 }); + setScreen("viewer"); + } catch (error) { + setFileError(error instanceof Error ? error.message : String(error)); + } + } + } + } + return ""; + } + if (screen() === "apps") { + if (y >= 162 && y < 324) { + return JSON.stringify({ type: "navigate", app: "robinhood" }); + } + if (y >= 324 && y < 490) { + return JSON.stringify({ type: "navigate", app: "exa" }); + } + return ""; + } + if (screen() === "settings") { + const networks = projection().settings?.wifi?.networks ?? []; + if (x >= 480 && y >= 126 && y <= 218) return JSON.stringify({ type: "settings", command: "scan" }); + if (x >= 620 && y >= 330 && y <= 462) setWifiOffset(Math.max(0, wifiOffset() - 4)); + else if (x >= 620 && y >= 650 && y <= 782) setWifiOffset(Math.min(Math.max(0, networks.length - 5), wifiOffset() + 4)); + else if (x < 610 && y >= 330 && y < 790) { + const row = Math.floor((y - 330) / 92); + const network = networks[wifiOffset() + row]; + if (network) { + if (!network.secured) return JSON.stringify({ type: "settings", command: "connect", ssid: network.ssid, password: "" }); + setKeyboardPurpose({ type: "wifi", ssid: network.ssid }); + setInput(""); + setScreen("keyboard"); + } + } else if (x <= 340 && y >= 1010 && y <= 1090) return JSON.stringify({ type: "settings", command: "forget" }); + else if (x >= 356 && y >= 1010 && y <= 1090) return JSON.stringify({ type: "settings", command: "restart" }); + } + return ""; + }, +}; diff --git a/apps/pi-agent/dist/agent.js b/apps/pi-agent/dist/agent.js new file mode 100644 index 0000000..ffd4260 --- /dev/null +++ b/apps/pi-agent/dist/agent.js @@ -0,0 +1,399 @@ +"use strict";(()=>{var __defProp=Object.defineProperty;var __defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:true,configurable:true,writable:true,value}):obj[key]=value;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __publicField=(obj,key,value)=>__defNormalProp(obj,typeof key!=="symbol"?key+"":key,value);var memory_exports={};__export(memory_exports,{Assign:()=>Assign,Clone:()=>Clone,Create:()=>Create,Discard:()=>Discard,Metrics:()=>Metrics,Update:()=>Update});var Metrics={assign:0,create:0,clone:0,discard:0,update:0};function Assign(left,right){Metrics.assign+=1;return{...left,...right}}var emit_exports={};__export(emit_exports,{And:()=>And,ArrayLiteral:()=>ArrayLiteral,ArrowFunction:()=>ArrowFunction,Call:()=>Call,ConstDeclaration:()=>ConstDeclaration,Constant:()=>Constant,Entries:()=>Entries2,Every:()=>Every2,HasPropertyKey:()=>HasPropertyKey2,If:()=>If,IsArray:()=>IsArray2,IsAsyncIterator:()=>IsAsyncIterator2,IsBigInt:()=>IsBigInt2,IsBoolean:()=>IsBoolean2,IsConstructor:()=>IsConstructor2,IsDeepEqual:()=>IsDeepEqual2,IsEqual:()=>IsEqual2,IsFunction:()=>IsFunction2,IsGreaterEqualThan:()=>IsGreaterEqualThan2, +IsGreaterThan:()=>IsGreaterThan2,IsInteger:()=>IsInteger2,IsIterator:()=>IsIterator2,IsLessEqualThan:()=>IsLessEqualThan2,IsLessThan:()=>IsLessThan2,IsMaxLength:()=>IsMaxLength3,IsMinLength:()=>IsMinLength3,IsNull:()=>IsNull2,IsNumber:()=>IsNumber2,IsObject:()=>IsObject2,IsObjectNotArray:()=>IsObjectNotArray2,IsString:()=>IsString2,IsSymbol:()=>IsSymbol2,IsUndefined:()=>IsUndefined2,Keys:()=>Keys2,Member:()=>Member,MultipleOf:()=>MultipleOf,New:()=>New,Not:()=>Not,Or:()=>Or,PrefixIncrement:()=>PrefixIncrement, +ReduceAnd:()=>ReduceAnd,ReduceOr:()=>ReduceOr,Return:()=>Return,Statements:()=>Statements,Ternary:()=>Ternary});var guard_exports={};__export(guard_exports,{Entries:()=>Entries,EntriesRegExp:()=>EntriesRegExp,Every:()=>Every,EveryAll:()=>EveryAll,GraphemeCount:()=>GraphemeCount2,HasPropertyKey:()=>HasPropertyKey,IsArray:()=>IsArray,IsAsyncIterator:()=>IsAsyncIterator,IsBigInt:()=>IsBigInt,IsBoolean:()=>IsBoolean,IsClassInstance:()=>IsClassInstance,IsConstructor:()=>IsConstructor,IsDeepEqual:()=>IsDeepEqual,IsEqual:()=>IsEqual,IsFunction:()=>IsFunction,IsGreaterEqualThan:()=>IsGreaterEqualThan,IsGreaterThan:()=>IsGreaterThan, +IsInteger:()=>IsInteger,IsIterator:()=>IsIterator,IsLessEqualThan:()=>IsLessEqualThan,IsLessThan:()=>IsLessThan,IsMaxLength:()=>IsMaxLength2,IsMinLength:()=>IsMinLength2,IsMultipleOf:()=>IsMultipleOf,IsNull:()=>IsNull,IsNumber:()=>IsNumber,IsObject:()=>IsObject,IsObjectNotArray:()=>IsObjectNotArray,IsString:()=>IsString,IsSymbol:()=>IsSymbol,IsUndefined:()=>IsUndefined,IsUnsafePropertyKey:()=>IsUnsafePropertyKey,IsValueLike:()=>IsValueLike,Keys:()=>Keys,Symbols:()=>Symbols,TakeLeft:()=>TakeLeft, +Values:()=>Values});function IsBetween(value,min,max){return value>=min&&value<=max}function IsRegionalIndicator(value){return IsBetween(value,127462,127487)}function IsVariationSelector(value){return IsBetween(value,65024,65039)}function IsCombiningMark(value){return IsBetween(value,768,879)||IsBetween(value,6832,6911)||IsBetween(value,7616,7679)||IsBetween(value,65056,65071)}function CodePointLength(value){return value>65535?2:1}function ConsumeModifiers(value,index2){while(index2=minLength)return true}return false}function IsMaxLength(value,maxLength){let count=0;let index2=0;while(index2maxLength)return false}return true}function IsMinLengthFast(value,minLength){if(minLength===0)return true;let index2=0;while(index2=minLength)return true}return false}function IsMaxLengthFast(value,maxLength){let index2=0;while(index2maxLength)return false}return true}function IsArray(value){return Array.isArray(value)}function IsAsyncIterator(value){return IsObject(value)&&Symbol.asyncIterator in value}function IsBigInt(value){return IsEqual(typeof value,"bigint")}function IsBoolean(value){return IsEqual(typeof value,"boolean")}function IsConstructor(value){if(IsUndefined(value)||!IsFunction(value))return false;const result=Function.prototype.toString.call(value);if(/^class\s/.test(result))return true;if(/\[native code\]/.test(result))return true;return false} +function IsFunction(value){return IsEqual(typeof value,"function")}function IsInteger(value){return Number.isInteger(value)}function IsIterator(value){return IsObject(value)&&Symbol.iterator in value}function IsNull(value){return IsEqual(value,null)}function IsNumber(value){return Number.isFinite(value)}function IsObjectNotArray(value){return IsObject(value)&&!IsArray(value)}function IsObject(value){return IsEqual(typeof value,"object")&&!IsNull(value)}function IsString(value){return IsEqual(typeof value, +"string")}function IsSymbol(value){return IsEqual(typeof value,"symbol")}function IsUndefined(value){return IsEqual(value,void 0)}function IsEqual(left,right){return left===right}function IsGreaterThan(left,right){return left>right}function IsLessThan(left,right){return left=right}function IsMultipleOf(dividend,divisor){if(IsBigInt(dividend)||IsBigInt(divisor)){return BigInt(dividend)% +BigInt(divisor)===0n}const tolerance=1e-10;if(!IsNumber(dividend))return true;if(IsInteger(dividend)&&1/divisor%1===0)return true;const mod=dividend%divisor;return Math.min(Math.abs(mod),Math.abs(mod-divisor))[new RegExp(`^${key}$`),value[key]])}function Entries(value){return Object.entries(value)}function Keys(value){return Object.getOwnPropertyNames(value)}function Symbols(value){return Object.getOwnPropertySymbols(value)}function Values(value){return Object.values(value)}function DeepEqualObject(left,right){if(!IsObject(right))return false;const keys=Keys(left);return IsEqual(keys.length,Keys(right).length)&&keys.every( +key=>IsDeepEqual(left[key],right[key]))}function DeepEqualArray(left,right){return IsArray(right)&&IsEqual(left.length,right.length)&&left.every((_,index2)=>IsDeepEqual(left[index2],right[index2]))}function IsDeepEqual(left,right){return IsArray(left)?DeepEqualArray(left,right):IsObject(left)?DeepEqualObject(left,right):IsEqual(left,right)}var identifierRegExp=/^[\p{ID_Start}_$][\p{ID_Continue}_$\u200C\u200D]*$/u;function IsIdentifier(value){return identifierRegExp.test(value)}function And(left,right){return`(${left} && ${right})`}function Or(left,right){return`(${left} || ${right})`}function Not(expr){return`!(${expr})`}function IsArray2(value){return`Array.isArray(${value})`}function IsAsyncIterator2(value){return`Guard.IsAsyncIterator(${value})`}function IsBigInt2(value){return`typeof ${value} === "bigint"`}function IsBoolean2(value){ +return`typeof ${value} === "boolean"`}function IsInteger2(value){return`Number.isInteger(${value})`}function IsIterator2(value){return`Guard.IsIterator(${value})`}function IsNull2(value){return`${value} === null`}function IsNumber2(value){return`Number.isFinite(${value})`}function IsObjectNotArray2(value){return And(IsObject2(value),Not(IsArray2(value)))}function IsObject2(value){return`typeof ${value} === "object" && ${value} !== null`}function IsString2(value){return`typeof ${value} === "strin\ +g"`}function IsSymbol2(value){return`typeof ${value} === "symbol"`}function IsUndefined2(value){return`${value} === undefined`}function IsFunction2(value){return`typeof ${value} === "function"`}function IsConstructor2(value){return`Guard.IsConstructor(${value})`}function IsEqual2(left,right){return`${left} === ${right}`}function IsGreaterThan2(left,right){return`${left} > ${right}`}function IsLessThan2(left,right){return`${left} < ${right}`}function IsLessEqualThan2(left,right){return`${left} <=\ + ${right}`}function IsGreaterEqualThan2(left,right){return`${left} >= ${right}`}function IsMinLength3(value,length){return`Guard.IsMinLength(${value}, ${length})`}function IsMaxLength3(value,length){return`Guard.IsMaxLength(${value}, ${length})`}function Every2(value,offset,params,expression){return IsEqual(offset,"0")?`${value}.every((${params[0]}, ${params[1]}) => ${expression})`:`((value, callback) => { for(let index = ${offset}; index < value.length; index++) if (!callback(value[index], inde\ +x)) return false; return true })(${value}, (${params[0]}, ${params[1]}) => ${expression})`}function Entries2(value){return`Object.entries(${value})`}function Keys2(value){return`Object.getOwnPropertyNames(${value})`}function HasPropertyKey2(value,key){const isProtoField=IsEqual(key,'"__proto__"')||IsEqual(key,'"constructor"');return isProtoField?`Object.prototype.hasOwnProperty.call(${value}, ${key})`:`${key} in ${value}`}function IsDeepEqual2(left,right){return`Guard.IsDeepEqual(${left}, ${right}\ +)`}function ArrayLiteral(elements){return`[${elements.join(", ")}]`}function ArrowFunction(parameters,body){return`((${parameters.join(", ")}) => ${body})`}function Call(value,arguments_){return`${value}(${arguments_.join(", ")})`}function New(value,arguments_){return`new ${value}(${arguments_.join(", ")})`}function Member(left,right){return`${left}${IsIdentifier(right)?`.${right}`:`[${Constant(right)}]`}`}function Constant(value){return IsString(value)?JSON.stringify(value):`${value}`}function Ternary(condition,true_,false_){ +return`(${condition} ? ${true_} : ${false_})`}function Statements(statements){return`{ ${statements.join("; ")}; }`}function ConstDeclaration(identifier,expression){return`const ${identifier} = ${expression}`}function If(condition,then){return`if(${condition}) { ${then} }`}function Return(expression){return`return ${expression}`}function ReduceAnd(operands){return IsEqual(operands.length,0)?"true":operands.reduce((left,right)=>And(left,right))}function ReduceOr(operands){return IsEqual(operands. +length,0)?"false":operands.reduce((left,right)=>Or(left,right))}function PrefixIncrement(expression){return`++${expression}`}function MultipleOf(dividend,divisor){return`Guard.IsMultipleOf(${dividend}, ${divisor})`}var globals_exports={};__export(globals_exports,{IsBigInt64Array:()=>IsBigInt64Array,IsBigUint64Array:()=>IsBigUint64Array,IsBoolean:()=>IsBoolean3,IsDate:()=>IsDate,IsFloat32Array:()=>IsFloat32Array,IsFloat64Array:()=>IsFloat64Array,IsInt16Array:()=>IsInt16Array,IsInt32Array:()=>IsInt32Array,IsInt8Array:()=>IsInt8Array,IsMap:()=>IsMap,IsNumber:()=>IsNumber3,IsRegExp:()=>IsRegExp,IsSet:()=>IsSet,IsString:()=>IsString3,IsTypeArray:()=>IsTypeArray,IsUint16Array:()=>IsUint16Array,IsUint32Array:()=>IsUint32Array, +IsUint8Array:()=>IsUint8Array,IsUint8ClampedArray:()=>IsUint8ClampedArray});function IsBoolean3(value){return value instanceof Boolean}function IsNumber3(value){return value instanceof Number}function IsString3(value){return value instanceof String}function IsTypeArray(value){return globalThis.ArrayBuffer.isView(value)}function IsInt8Array(value){return value instanceof globalThis.Int8Array}function IsUint8Array(value){return value instanceof globalThis.Uint8Array}function IsUint8ClampedArray(value){ +return value instanceof globalThis.Uint8ClampedArray}function IsInt16Array(value){return value instanceof globalThis.Int16Array}function IsUint16Array(value){return value instanceof globalThis.Uint16Array}function IsInt32Array(value){return value instanceof globalThis.Int32Array}function IsUint32Array(value){return value instanceof globalThis.Uint32Array}function IsFloat32Array(value){return value instanceof globalThis.Float32Array}function IsFloat64Array(value){return value instanceof globalThis. +Float64Array}function IsBigInt64Array(value){return value instanceof globalThis.BigInt64Array}function IsBigUint64Array(value){return value instanceof globalThis.BigUint64Array}function IsRegExp(value){return value instanceof globalThis.RegExp}function IsDate(value){return value instanceof globalThis.Date}function IsSet(value){return value instanceof globalThis.Set}function IsMap(value){return value instanceof globalThis.Map}function IsGuard(value){return guard_exports.IsObject(value)&&guard_exports.HasPropertyKey(value,"~guard")}function FromGuard(value){return value}function FromArray(value){return value.map(value2=>FromValue(value2))}function FromObject(value){const result={};const descriptors=Object.getOwnPropertyDescriptors(value);for(const key of Object.keys(descriptors)){const descriptor=descriptors[key];if(guard_exports.HasPropertyKey(descriptor,"value")){Object.defineProperty(result,key,{...descriptor,value:FromValue( +descriptor.value)})}}return result}function FromRegExp(value){return new RegExp(value.source,value.flags)}function FromUnknown(value){return value}function FromValue(value){return value instanceof RegExp?FromRegExp(value):IsGuard(value)?FromGuard(value):guard_exports.IsArray(value)?FromArray(value):guard_exports.IsObject(value)?FromObject(value):FromUnknown(value)}function Clone(value){Metrics.clone+=1;return FromValue(value)}var settings_exports={};__export(settings_exports,{Get:()=>Get,Reset:()=>Reset,Set:()=>Set2});var settings={immutableTypes:false,maxErrors:8,useAcceleration:true,exactOptionalPropertyTypes:false,enumerableKind:false,correctiveParse:false};function Reset(){settings.immutableTypes=false;settings.maxErrors=8;settings.useAcceleration=true;settings.exactOptionalPropertyTypes=false;settings.enumerableKind=false;settings.correctiveParse=false}function Set2(options){for(const key of guard_exports.Keys(options)){const value=options[key];if(value!==void 0){Object.defineProperty(settings,key,{value})}}} +function Get(){return settings}function MergeHidden(left,right){for(const key of Object.keys(right)){Object.defineProperty(left,key,{configurable:true,writable:true,enumerable:false,value:right[key]})}return left}function Merge(left,right){return{...left,...right}}function Create(hidden,enumerable,options={}){Metrics.create+=1;const settings2=settings_exports.Get();const withOptions=Merge(enumerable,options);const withHidden=settings2.enumerableKind?Merge(withOptions,hidden):MergeHidden(withOptions,hidden);return settings2.immutableTypes? +Object.freeze(withHidden):withHidden}function Discard(value,propertyKeys){Metrics.discard+=1;const result={};const descriptors=Object.getOwnPropertyDescriptors(Clone(value));const keysToDiscard=new Set(propertyKeys);for(const key of Object.keys(descriptors)){if(keysToDiscard.has(key))continue;Object.defineProperty(result,key,descriptors[key])}return result}function Update(current,hidden,enumerable){Metrics.update+=1;const settings2=settings_exports.Get();const result=Clone(current);for(const key of Object.keys(hidden)){Object.defineProperty(result,key,{configurable:true,writable:true,enumerable:settings2.enumerableKind,value:hidden[key]})}for(const key of Object.keys(enumerable)){Object.defineProperty(result,key,{configurable:true,enumerable:true,writable:true,value:enumerable[key]})}return result}function IsKind(value,kind){return guard_exports.IsObject(value)&&guard_exports.HasPropertyKey(value,"~kind")&&guard_exports.IsEqual(value["~kind"],kind)}function IsSchema(value){return guard_exports.IsObject(value)}function IsOptionalAddAction(value){return guard_exports.IsObject(value)&&guard_exports.HasPropertyKey(value,"~kind")&&guard_exports.HasPropertyKey(value,"type")&&guard_exports.IsEqual(value["~kind"],"OptionalAddAction")&&IsSchema(value.type)}function IsOptionalRemoveAction(value){return guard_exports.IsObject(value)&&guard_exports.HasPropertyKey(value,"~kind")&&guard_exports.HasPropertyKey(value,"type")&&guard_exports.IsEqual(value["~kind"],"OptionalRemoveAction")&&IsSchema(value.type)}function IsReadonlyAddAction(value){return guard_exports.IsObject(value)&&guard_exports.HasPropertyKey(value,"~kind")&&guard_exports.HasPropertyKey(value,"type")&&guard_exports.IsEqual(value["~kind"],"ReadonlyAddAction")&&IsSchema(value.type)}function IsReadonlyRemoveAction(value){return guard_exports.IsObject(value)&&guard_exports.HasPropertyKey(value,"~kind")&&guard_exports.HasPropertyKey(value,"type")&&guard_exports.IsEqual(value["~kind"],"ReadonlyRemoveAction")&&IsSchema(value.type)}function Deferred(action,parameters,options){return memory_exports.Create({"~kind":"Deferred"},{action,parameters,options},{})}function IsDeferred(value){return IsKind(value,"Deferred")}function _Promise_(item,options){return memory_exports.Create({["~kind"]:"Promise"},{type:"promise",item},options)}function IsPromise(value){return IsKind(value,"Promise")}function PromiseOptions(type){return memory_exports.Discard(type,["~kind","type","item"])}function ImmutableAdd(type){return memory_exports.Update(type,{"~immutable":true},{})}function Immutable(type){return ImmutableAdd(type)}function IsImmutable(value){return IsSchema(value)&&guard_exports.HasPropertyKey(value,"~immutable")}function OptionalRemove(type){const result=memory_exports.Discard(type,["~optional"]);return result}function OptionalAdd(type){return memory_exports.Update(type,{"~optional":true},{})}function Optional(type){return OptionalAdd(type)}function IsOptional(value){return IsSchema(value)&&guard_exports.HasPropertyKey(value,"~optional")}function ReadonlyRemove(type){return memory_exports.Discard(type,["~readonly"])}function ReadonlyAdd(type){return memory_exports.Update(type,{"~readonly":true},{})}function Readonly(type){return ReadonlyAdd(type)}function IsReadonly(value){return IsSchema(value)&&guard_exports.HasPropertyKey(value,"~readonly")}function BaseProperty(value){return{enumerable:settings_exports.Get().enumerableKind,writable:false,configurable:false,value}}var Base=class{constructor(){globalThis.Object.defineProperty(this,"~kind",BaseProperty("Base"));globalThis.Object.defineProperty(this,"~guard",BaseProperty({check:value=>this.Check(value),errors:value=>this.Errors(value)}))}Check(_value){return true}Errors(_value){return[]}Convert(value){return value}Clean(value){return value}Default(value){return value}Create(){throw new Error( +"Create not implemented")}Clone(){throw Error("Clone not implemented")}};function IsBase(value){return IsKind(value,"Base")}function _Array_(items,options){return memory_exports.Create({"~kind":"Array"},{type:"array",items},options)}function IsArray3(value){return IsKind(value,"Array")}function ArrayOptions(type){return memory_exports.Discard(type,["~kind","type","items"])}function AsyncIterator(iteratorItems,options){return memory_exports.Create({"~kind":"AsyncIterator"},{type:"asyncIterator",iteratorItems},options)}function IsAsyncIterator3(value){return IsKind(value,"AsyncIterator")}function AsyncIteratorOptions(type){return memory_exports.Discard(type,["~kind","type","iteratorItems"])}function Constructor(parameters,instanceType,options={}){return memory_exports.Create({"~kind":"Constructor"},{type:"constructor",parameters,instanceType},options)}function IsConstructor3(value){return IsKind(value,"Constructor")}function ConstructorOptions(type){return memory_exports.Discard(type,["~kind","type","parameters","instanceType"])}function _Function_(parameters,returnType,options={}){return memory_exports.Create({["~kind"]:"Function"},{type:"function",parameters,returnType},options)}function IsFunction3(value){return IsKind(value,"Function")}function FunctionOptions(type){return memory_exports.Discard(type,["~kind","type","parameters","returnType"])}function Ref(ref,options){return memory_exports.Create({["~kind"]:"Ref"},{$ref:ref},options)}function IsRef(value){return IsKind(value,"Ref")}function Generic(parameters,expression){return memory_exports.Create({"~kind":"Generic"},{type:"generic",parameters,expression})}function IsGeneric(value){return IsKind(value,"Generic")}function Any(options){return memory_exports.Create({["~kind"]:"Any"},{},options)}function IsAny(value){return IsKind(value,"Any")}var NeverPattern="(?!)";function Never(options){return memory_exports.Create({"~kind":"Never"},{not:{}},options)}function IsNever(value){return IsKind(value,"Never")}function RequiredArray(properties){return guard_exports.Keys(properties).filter(key=>!IsOptional(properties[key]))}function PropertyKeys(properties){return guard_exports.Keys(properties)}function PropertyValues(properties){return guard_exports.Values(properties)}function _Object_(properties,options={}){const requiredKeys=RequiredArray(properties);const required=requiredKeys.length>0?{required:requiredKeys}:{};return memory_exports.Create({"~kind":"Object"},{type:"object",...required,properties},options)}function IsObject3(value){return IsKind(value,"Object")}function ObjectOptions(type){return memory_exports.Discard(type,["~kind","type","properties","required"])}function Union(anyOf,options={}){return memory_exports.Create({"~kind":"Union"},{anyOf},options)}function IsUnion(value){return IsKind(value,"Union")}function UnionOptions(type){return memory_exports.Discard(type,["~kind","anyOf"])}function Unknown(options){return memory_exports.Create({["~kind"]:"Unknown"},{},options)}function IsUnknown(value){return IsKind(value,"Unknown")}function Cyclic($defs,$ref,options){const defs=guard_exports.Keys($defs).reduce((result,key)=>{return{...result,[key]:memory_exports.Update($defs[key],{},{$id:key})}},{});return memory_exports.Create({["~kind"]:"Cyclic"},{$defs:defs,$ref},options)}function IsCyclic(value){return IsKind(value,"Cyclic")}function IsUnsafe(value){return guard_exports.IsObjectNotArray(value)&&guard_exports.HasPropertyKey(value,"~unsafe")&&guard_exports.IsNull(value["~unsafe"])}var arguments_exports={};__export(arguments_exports,{Match:()=>Match});function Match(args,match){return match[args.length]?.(...args)??(()=>{throw Error("Invalid Arguments")})()}function IsInfer(value){return IsKind(value,"Infer")}function IsEnum(value){return IsKind(value,"Enum")}function Intersect(types,options={}){return memory_exports.Create({"~kind":"Intersect"},{allOf:types},options)}function IsIntersect(value){return IsKind(value,"Intersect")}function IntersectOptions(type){return memory_exports.Discard(type,["~kind","allOf"])}var environment_exports={};__export(environment_exports,{CanEvaluate:()=>CanEvaluate,Evaluate:()=>Evaluate});var supported=void 0;function TryEvaluate(){try{Evaluate("null")();return true}catch{return false}}function CanEvaluate(){if(guard_exports.IsUndefined(supported))supported=TryEvaluate();return supported&&settings_exports.Get().useAcceleration}function Evaluate(...args){return new globalThis.Function(...args)}var hash_exports={};__export(hash_exports,{Hash:()=>Hash,HashCode:()=>HashCode});function Unreachable(){throw new Error("Unreachable")}function InstanceKeys(value){const propertyKeys=new Set;let current=value;while(current&¤t!==Object.prototype){for(const key of Reflect.ownKeys(current)){if(key!=="constructor"&&typeof key!=="symbol")propertyKeys.add(key)}current=Object.getPrototypeOf(current)}return[...propertyKeys]}function IsIEEE754(value){return typeof value==="number"}var ByteMarker;(function(ByteMarker2){ByteMarker2[ByteMarker2["Array"]=0]="Array";ByteMarker2[ByteMarker2["BigInt"]=1]="BigInt";ByteMarker2[ByteMarker2["\ +Boolean"]=2]="Boolean";ByteMarker2[ByteMarker2["Date"]=3]="Date";ByteMarker2[ByteMarker2["Constructor"]=4]="Constructor";ByteMarker2[ByteMarker2["Function"]=5]="Function";ByteMarker2[ByteMarker2["Null"]=6]="Null";ByteMarker2[ByteMarker2["Number"]=7]="Number";ByteMarker2[ByteMarker2["Object"]=8]="Object";ByteMarker2[ByteMarker2["RegExp"]=9]="RegExp";ByteMarker2[ByteMarker2["String"]=10]="String";ByteMarker2[ByteMarker2["Symbol"]=11]="Symbol";ByteMarker2[ByteMarker2["TypeArray"]=12]="TypeArray";ByteMarker2[ByteMarker2["\ +Undefined"]=13]="Undefined"})(ByteMarker||(ByteMarker={}));var Accumulator=BigInt("14695981039346656037");var[Prime,Size]=[BigInt("1099511628211"),BigInt("18446744073709551616")];var Bytes=Array.from({length:256}).map((_,i)=>BigInt(i));var F64=new Float64Array(1);var F64In=new DataView(F64.buffer);var F64Out=new Uint8Array(F64.buffer);function FNV1A64_OP(byte){Accumulator=Accumulator^Bytes[byte];Accumulator=Accumulator*Prime%Size}function FromArray2(value){FNV1A64_OP(ByteMarker.Array);for(const item of value){ +FromValue2(item)}}function FromBigInt(value){FNV1A64_OP(ByteMarker.BigInt);F64In.setBigInt64(0,value);for(const byte of F64Out){FNV1A64_OP(byte)}}function FromBoolean(value){FNV1A64_OP(ByteMarker.Boolean);FNV1A64_OP(value?1:0)}function FromConstructor(value){FNV1A64_OP(ByteMarker.Constructor);FromValue2(value.toString())}function FromDate(value){FNV1A64_OP(ByteMarker.Date);FromValue2(value.getTime())}function FromFunction(value){FNV1A64_OP(ByteMarker.Function);FromValue2(value.toString())}function FromNull(_value){ +FNV1A64_OP(ByteMarker.Null)}function FromNumber(value){FNV1A64_OP(ByteMarker.Number);F64In.setFloat64(0,value,true);for(const byte of F64Out){FNV1A64_OP(byte)}}function FromObject2(value){FNV1A64_OP(ByteMarker.Object);for(const key of InstanceKeys(value).sort()){FromValue2(key);FromValue2(value[key])}}function FromRegExp2(value){FNV1A64_OP(ByteMarker.RegExp);FromString(value.toString())}var encoder=new TextEncoder;function FromString(value){FNV1A64_OP(ByteMarker.String);for(const byte of encoder. +encode(value)){FNV1A64_OP(byte)}}function FromSymbol(value){FNV1A64_OP(ByteMarker.Symbol);FromValue2(value.toString())}function FromTypeArray(value){FNV1A64_OP(ByteMarker.TypeArray);const buffer=new Uint8Array(value.buffer);for(let i=0;iIsRefinement(value2))}var BigIntPattern="-?(?:0|[1-9][0-9]*)n";function BigInt2(options){return memory_exports.Create({"~kind":"BigInt"},{type:"bigint"},options)}function IsBigInt3(value){return IsKind(value,"BigInt")}function IsBoolean4(value){return IsKind(value,"Boolean")}var IntegerPattern="-?(?:0|[1-9][0-9]*)";function Integer(options){return memory_exports.Create({"~kind":"Integer"},{type:"integer"},options)}function IsInteger3(value){return IsKind(value,"Integer")}function Iterator(iteratorItems,options){return memory_exports.Create({"~kind":"Iterator"},{type:"iterator",iteratorItems},options)}function IsIterator3(value){return IsKind(value,"Iterator")}function IteratorOptions(type){return memory_exports.Discard(type,["~kind","type","iteratorItems"])}var InvalidLiteralValue=class extends Error{constructor(value){super(`Invalid Literal value`);Object.defineProperty(this,"cause",{value:{value},writable:false,configurable:false,enumerable:false})}};function LiteralTypeName(value){return guard_exports.IsBigInt(value)?"bigint":guard_exports.IsBoolean(value)?"boolean":guard_exports.IsNumber(value)?"number":guard_exports.IsString(value)?"string":(()=>{throw new InvalidLiteralValue(value)})()}function Literal(value,options){return memory_exports.Create( +{"~kind":"Literal"},{type:LiteralTypeName(value),const:value},options)}function IsLiteralValue(value){return guard_exports.IsBigInt(value)||guard_exports.IsBoolean(value)||guard_exports.IsNumber(value)||guard_exports.IsString(value)}function IsLiteralBigInt(value){return IsLiteral(value)&&guard_exports.IsBigInt(value.const)}function IsLiteralBoolean(value){return IsLiteral(value)&&guard_exports.IsBoolean(value.const)}function IsLiteralNumber(value){return IsLiteral(value)&&guard_exports.IsNumber( +value.const)}function IsLiteralString(value){return IsLiteral(value)&&guard_exports.IsString(value.const)}function IsLiteral(value){return IsKind(value,"Literal")}function Null(options){return memory_exports.Create({"~kind":"Null"},{type:"null"},options)}function IsNull3(value){return IsKind(value,"Null")}var NumberPattern="-?(?:0|[1-9][0-9]*)(?:.[0-9]+)?";function Number2(options){return memory_exports.Create({"~kind":"Number"},{type:"number"},options)}function IsNumber4(value){return IsKind(value,"Number")}function Symbol2(options){return memory_exports.Create({"~kind":"Symbol"},{type:"symbol"},options)}function IsSymbol3(value){return IsKind(value,"Symbol")}var StringPattern=".*";function String2(options){return memory_exports.Create({"~kind":"String"},{type:"string"},options)}function IsString4(value){return IsKind(value,"String")}function ParsePatternIntoTypes(pattern){const parsed=Pattern(pattern);const result=guard_exports.IsEqual(parsed.length,2)?parsed[0]:[];return result}function FromLiteral(_value){return true}function FromTypesReduce(types){return guard_exports.TakeLeft(types,(left,right)=>FromType(left)?FromTypesReduce(right):false,()=>true)}function FromTypes(types){const result=guard_exports.IsEqual(types.length,0)?false:FromTypesReduce(types);return result}function FromType(type){return IsUnion(type)?FromTypes(type.anyOf):IsLiteral(type)?FromLiteral(type.const):false}function IsTemplateLiteralFinite(types){const result=FromTypes(types);return result}function TemplateLiteralCreate(pattern){return memory_exports.Create({["~kind"]:"TemplateLiteral"},{type:"string",pattern},{})}function FromLiteralPush(variants,value,result=[]){return guard_exports.TakeLeft(variants,(left,right)=>FromLiteralPush(right,value,[...result,`${left}${value}`]),()=>result)}function FromLiteral2(variants,value){return guard_exports.IsEqual(variants.length,0)?[`${value}`]:FromLiteralPush(variants,value)}function FromUnion(variants,types,result=[]){return guard_exports.TakeLeft(types,(left,right)=>FromUnion(variants,right,[...result,...FromType2(variants,left)]),()=>result)}function FromType2(variants,type){ +const result=IsUnion(type)?FromUnion(variants,type.anyOf):IsLiteral(type)?FromLiteral2(variants,type.const):Unreachable();return result}function DecodeFromSpan(variants,types){return guard_exports.TakeLeft(types,(left,right)=>DecodeFromSpan(FromType2(variants,left),right),()=>variants)}function VariantsToLiterals(variants){return variants.map(variant=>Literal(variant))}function DecodeTypesAsUnion(types){const variants=DecodeFromSpan([],types);const literals=VariantsToLiterals(variants);const result=Union( +literals);return result}function DecodeTypes(types){return guard_exports.IsEqual(types.length,0)?Unreachable():guard_exports.IsEqual(types.length,1)&&IsLiteral(types[0])?types[0]:DecodeTypesAsUnion(types)}function TemplateLiteralDecodeUnsafe(pattern){const types=ParsePatternIntoTypes(pattern);const result=guard_exports.IsEqual(types.length,0)?String2():IsTemplateLiteralFinite(types)?DecodeTypes(types):TemplateLiteralCreate(pattern);return result}function TemplateLiteralDecode(pattern){const decoded=TemplateLiteralDecodeUnsafe( +pattern);const result=IsTemplateLiteral(decoded)?String2():decoded;return result}function CreateRecord(key,value){const type="object";const patternProperties={[key]:value};return memory_exports.Create({["~kind"]:"Record"},{type,patternProperties})}function FromAnyKey(value){return CreateRecord(StringKey,value)}function FromBooleanKey(value){return _Object_({true:value,false:value})}function FromEnumValue(value){return guard_exports.IsString(value)||guard_exports.IsNumber(value)?Literal(value):guard_exports.IsNull(value)?Null():Never()}function EnumValuesToVariants(values){const result=values.map(value=>FromEnumValue(value));return result}function EnumValuesToUnion(values){const variants=EnumValuesToVariants(values);const result=Union(variants);return result}function EnumToUnion(type){const result=EnumValuesToUnion(type.enum);return result}function FromEnumKey(values,value){const unionKey=EnumValuesToUnion(values);const result=FromKey(unionKey,value);return result}function FromIntegerKey(_key,value){const result=CreateRecord(IntegerKey,value);return result}function Tuple(types,options={}){const[items,minItems,additionalItems]=[types,types.length,false];return memory_exports.Create({["~kind"]:"Tuple"},{type:"array",additionalItems,items,minItems},options)}function IsTuple(value){return IsKind(value,"Tuple")}function TupleOptions(type){return memory_exports.Discard(type,["~kind","type","items","minItems","additionalItems"])}function TupleElementsToProperties(types){const result=types.reduceRight((result2,right,index2)=>{return{[index2]:right,...result2}},{});return result}function TupleToObject(type){const properties=TupleElementsToProperties(type.items);const result=_Object_(properties);return result}function IsReadonlyProperty(left,right){return IsReadonly(left)?IsReadonly(right)?true:false:false}function IsOptionalProperty(left,right){return IsOptional(left)?IsOptional(right)?true:false:false}function CompositeProperty(left,right){const isReadonly=IsReadonlyProperty(left,right);const isOptional=IsOptionalProperty(left,right);const evaluated=EvaluateIntersect([left,right]);const property=ReadonlyRemove(OptionalRemove(evaluated));return isReadonly&&isOptional?ReadonlyAdd(OptionalAdd(property)): +isReadonly&&!isOptional?ReadonlyAdd(property):!isReadonly&&isOptional?OptionalAdd(property):property}function CompositePropertyKey(left,right,key){return key in left?key in right?CompositeProperty(left[key],right[key]):left[key]:key in right?right[key]:Never()}function CompositeProperties(left,right){const keys=new Set([...guard_exports.Keys(right),...guard_exports.Keys(left)]);return[...keys].reduce((result,key)=>{return{...result,[key]:CompositePropertyKey(left,right,key)}},{})}function GetProperties(type){ +const result=IsObject3(type)?type.properties:IsTuple(type)?TupleElementsToProperties(type.items):Unreachable();return result}function Composite(left,right){const leftProperties=GetProperties(left);const rightProperties=GetProperties(right);const properties=CompositeProperties(leftProperties,rightProperties);return _Object_(properties)}function Narrow(left,right){const result=Compare(left,right);return guard_exports.IsEqual(result,ResultLeftInside)?left:guard_exports.IsEqual(result,ResultRightInside)?right:guard_exports.IsEqual(result,ResultEqual)?right:Never()}function IsObjectLike(type){return IsObject3(type)||IsTuple(type)}function IsUnionOperand(left,right){const isUnionLeft=IsUnion(left);const isUnionRight=IsUnion(right);const result=isUnionLeft||isUnionRight;return result}function DistributeOperation(left,right){const evaluatedLeft=EvaluateType(left);const evaluatedRight=EvaluateType(right);const isUnionOperand=IsUnionOperand(evaluatedLeft,evaluatedRight);const isObjectLeft=IsObjectLike(evaluatedLeft);const IsObjectRight=IsObjectLike(evaluatedRight); +const result=isUnionOperand?EvaluateIntersect([evaluatedLeft,evaluatedRight]):isObjectLeft&&IsObjectRight?Composite(evaluatedLeft,evaluatedRight):isObjectLeft&&!IsObjectRight?evaluatedLeft:!isObjectLeft&&IsObjectRight?evaluatedRight:Narrow(evaluatedLeft,evaluatedRight);return result}function DistributeType(type,types,result=[]){return guard_exports.TakeLeft(types,(left,right)=>DistributeType(type,right,[...result,DistributeOperation(type,left)]),()=>guard_exports.IsEqual(result.length,0)?[type]: +result)}function DistributeUnion(types,distribution,result=[]){return guard_exports.TakeLeft(types,(left,right)=>DistributeUnion(right,distribution,[...result,...Distribute([left],distribution)]),()=>result)}function Distribute(types,result=[]){return guard_exports.TakeLeft(types,(left,right)=>IsUnion(left)?Distribute(right,DistributeUnion(left.anyOf,result)):Distribute(right,DistributeType(left,result)),()=>result)}function EvaluateIntersect(types){const distribution=Distribute(types);const result=Broaden(distribution);return result}function EvaluateUnion(types){const result=Broaden(types);return result}function EvaluateType(type){return IsIntersect(type)?EvaluateIntersect(type.allOf):IsUnion(type)?EvaluateUnion(type.anyOf):type}function EvaluateUnionFast(types){const result=guard_exports.IsEqual(types.length,1)?types[0]:guard_exports.IsEqual(types.length,0)?Never():Union(types);return result}function FromIntersectKey(types,value){const evaluatedKey=EvaluateIntersect(types);const result=FromKey(evaluatedKey,value);return result}function FromLiteralKey(key,value){return guard_exports.IsString(key)||guard_exports.IsNumber(key)?_Object_({[key]:value}):guard_exports.IsEqual(key,false)?_Object_({false:value}):guard_exports.IsEqual(key,true)?_Object_({true:value}):_Object_({})}function FromNumberKey(_key,value){const result=CreateRecord(NumberKey,value);return result}function FromStringKey(key,value){return guard_exports.HasPropertyKey(key,"pattern")&&(guard_exports.IsString(key.pattern)||key.pattern instanceof RegExp)?CreateRecord(key.pattern.toString(),value):CreateRecord(StringKey,value)}function FromTemplateKey(pattern,value){const types=ParsePatternIntoTypes(pattern);const finite=IsTemplateLiteralFinite(types);const result=finite?FromKey(TemplateLiteralDecode(pattern),value):CreateRecord(pattern,value);return result}function FlattenType(type){const result=IsUnion(type)?Flatten(type.anyOf):[type];return result}function Flatten(types){return types.reduce((result,type)=>{return[...result,...FlattenType(type)]},[])}function StringOrNumberCheck(types){return types.some(type=>IsString4(type)||IsNumber4(type)||IsInteger3(type))}function TryBuildRecord(types,value){return guard_exports.IsEqual(StringOrNumberCheck(types),true)?CreateRecord(StringKey,value):void 0}function CreateProperties(types,value){return types.reduce((result,left)=>{return IsLiteral(left)&&(guard_exports.IsString(left.const)||guard_exports.IsNumber(left.const))?{...result,[left.const]:value}:result},{})}function CreateObject(types,value){const properties=CreateProperties( +types,value);const result=_Object_(properties);return result}function FromUnionKey(types,value){const flattened=Flatten(types);const record=TryBuildRecord(flattened,value);return IsSchema(record)?record:CreateObject(flattened,value)}function FromKey(key,value){const result=IsAny(key)?FromAnyKey(value):IsBoolean4(key)?FromBooleanKey(value):IsEnum(key)?FromEnumKey(key.enum,value):IsInteger3(key)?FromIntegerKey(key,value):IsIntersect(key)?FromIntersectKey(key.allOf,value):IsLiteral(key)?FromLiteralKey(key.const,value):IsNumber4(key)?FromNumberKey(key,value):IsUnion(key)?FromUnionKey(key.anyOf,value):IsString4(key)?FromStringKey(key,value):IsTemplateLiteral(key)?FromTemplateKey(key.pattern,value):_Object_({});return result}function RecordAction(key,value,options){const result=CanInstantiate([key])?memory_exports.Update(FromKey(key,value),{},options):RecordDeferred(key,value,options);return result}function RecordInstantiate(context,state2,key,value,options){const instantiatedKey=InstantiateType(context,state2,key);const instantiatedValue=InstantiateType(context,state2,value);return RecordAction(instantiatedKey,instantiatedValue,options)}var IntegerKey=`^${IntegerPattern}$`;var NumberKey=`^${NumberPattern}$`;var StringKey=`^${StringPattern}$`;function RecordDeferred(key,value,options={}){return Deferred("Record",[key,value],options)}function Record(key,value,options={}){return RecordAction(key,value,options)}function RecordFromPattern(key,value){return CreateRecord(key,value)}function RecordPattern(type){return guard_exports.Keys(type.patternProperties)[0]}function RecordKey(type){const pattern=RecordPattern(type);const result=guard_exports. +IsEqual(pattern,StringKey)?String2():guard_exports.IsEqual(pattern,IntegerKey)?Integer():guard_exports.IsEqual(pattern,NumberKey)?Number2():TemplateLiteralDecodeUnsafe(pattern);return result}function RecordValue(type){return type.patternProperties[RecordPattern(type)]}function IsRecord(value){return IsKind(value,"Record")}function Rest(type){return memory_exports.Create({"~kind":"Rest"},{type:"rest",items:type},{})}function IsRest(value){return IsKind(value,"Rest")}function IsThis(value){return IsKind(value,"This")}function Undefined(options){return memory_exports.Create({"~kind":"Undefined"},{type:"undefined"},options)}function IsUndefined3(value){return IsKind(value,"Undefined")}function IsVoid(value){return IsKind(value,"Void")}function PatternBigIntMapping(input){return BigInt2()}function PatternStringMapping(input){return String2()}function PatternNumberMapping(input){return Number2()}function PatternIntegerMapping(input){return Integer()}function PatternNeverMapping(input){return Never()}function PatternTextMapping(input){return Literal(input)}function PatternBaseMapping(input){return input}function PatternGroupMapping(input){return Union(input[1])}function PatternUnionMapping(input){return input.length===3?[...input[0], +...input[2]]:input.length===1?[...input[0]]:[]}function PatternTermMapping(input){return[input[0],...input[1]]}function PatternBodyMapping(input){return input}function PatternMapping(input){return input[1]}function IsMatch(value){return IsEqual(value.length,2)}function Match2(input,ok,fail){return IsMatch(input)?ok(input[0],input[1]):fail()}function TakeVariant(variant,input){return IsEqual(input.indexOf(variant),0)?[variant,input.slice(variant.length)]:[]}function Take(variants,input){for(let i=0;iString.fromCharCode(start+i))}var Alpha=[...Range(97,122),...Range(65,90)];var Zero="0";var NonZero=Range(49,57);var Digit=[Zero,...NonZero];var WhiteSpace=" ";var NewLine="\n";var UnderScore="_";var DollarSign="$";var LineComment="//";var OpenComment="/*";var CloseComment="*/";function DiscardMultilineComment(input){const index2=input.indexOf(CloseComment);const result=IsEqual(index2,-1)?"":input.slice(index2+2);return result}function DiscardLineComment(input){const index2=input.indexOf(NewLine);const result=IsEqual(index2,-1)?"":input.slice(index2);return result}function TrimStartUntilNewline(input){return input.replace(/^[ \t\r\f\v]+/,"")}function TrimWhitespace(input){const trimmed=TrimStartUntilNewline( +input);return trimmed.startsWith(OpenComment)?TrimWhitespace(DiscardMultilineComment(trimmed.slice(2))):trimmed.startsWith(LineComment)?TrimWhitespace(DiscardLineComment(trimmed.slice(2))):trimmed}function Trim(input){const trimmed=input.trimStart();return trimmed.startsWith(OpenComment)?Trim(DiscardMultilineComment(trimmed.slice(2))):trimmed.startsWith(LineComment)?Trim(DiscardLineComment(trimmed.slice(2))):trimmed}var AllowedDigits=[...Digit,UnderScore];function TakeConst(const_,input){return Take([const_],input)}function Const(const_,input){return IsEqual(const_,"")?["",input]:const_.startsWith(NewLine)?TakeConst(const_,TrimWhitespace(input)):const_.startsWith(WhiteSpace)?TakeConst(const_,input):TakeConst(const_,Trim(input))}var Initial=[...Alpha,UnderScore,DollarSign];var Remaining=[...Initial,...Digit];var AllowedDigits2=[...Digit,UnderScore];function TakeOne(input){const result=IsEqual(input,"")?[]:[input.slice(0,1),input.slice(1)];return result}function IsInputMatchSentinal(end,input){return TakeLeft(end,(left,right)=>input.startsWith(left)?true:IsInputMatchSentinal(right,input),()=>false)}function Until(end,input,result=""){return Match2(TakeOne(input),(One,Rest2)=>IsInputMatchSentinal(end,input)?[result,input]:Until(end,Rest2,`${result}${One}`),()=>[])}function Until_1(end,input){return Match2(Until(end,input),(Until2,UntilRest)=>IsEqual(Until2,"")?[]:[Until2,UntilRest],()=>[])}var If2=(result,left,right=()=>[])=>result.length===2?left(result):right();var PatternBigInt=input=>If2(Const("-?(?:0|[1-9][0-9]*)n",input),([_0,input2])=>[PatternBigIntMapping(_0),input2]);var PatternString=input=>If2(Const(".*",input),([_0,input2])=>[PatternStringMapping(_0),input2]);var PatternNumber=input=>If2(Const("-?(?:0|[1-9][0-9]*)(?:.[0-9]+)?",input),([_0,input2])=>[PatternNumberMapping(_0),input2]);var PatternInteger=input=>If2(Const("-?(?:0|[1-9][0-9]*)",input),([_0,input2])=>[PatternIntegerMapping(_0),input2]);var PatternNever=input=>If2(Const("(?!)",input), +([_0,input2])=>[PatternNeverMapping(_0),input2]);var PatternText=input=>If2(Until_1(["-?(?:0|[1-9][0-9]*)n",".*","-?(?:0|[1-9][0-9]*)(?:.[0-9]+)?","-?(?:0|[1-9][0-9]*)","(?!)","(",")","$","|"],input),([_0,input2])=>[PatternTextMapping(_0),input2]);var PatternBase=input=>If2(If2(PatternBigInt(input),([_0,input2])=>[_0,input2],()=>If2(PatternString(input),([_0,input2])=>[_0,input2],()=>If2(PatternNumber(input),([_0,input2])=>[_0,input2],()=>If2(PatternInteger(input),([_0,input2])=>[_0,input2],()=>If2( +PatternNever(input),([_0,input2])=>[_0,input2],()=>If2(PatternGroup(input),([_0,input2])=>[_0,input2],()=>If2(PatternText(input),([_0,input2])=>[_0,input2],()=>[]))))))),([_0,input2])=>[PatternBaseMapping(_0),input2]);var PatternGroup=input=>If2(If2(Const("(",input),([_0,input2])=>If2(PatternBody(input2),([_1,input3])=>If2(Const(")",input3),([_2,input4])=>[[_0,_1,_2],input4]))),([_0,input2])=>[PatternGroupMapping(_0),input2]);var PatternUnion=input=>If2(If2(If2(PatternTerm(input),([_0,input2])=>If2( +Const("|",input2),([_1,input3])=>If2(PatternUnion(input3),([_2,input4])=>[[_0,_1,_2],input4]))),([_0,input2])=>[_0,input2],()=>If2(If2(PatternTerm(input),([_0,input2])=>[[_0],input2]),([_0,input2])=>[_0,input2],()=>If2([[],input],([_0,input2])=>[_0,input2],()=>[]))),([_0,input2])=>[PatternUnionMapping(_0),input2]);var PatternTerm=input=>If2(If2(PatternBase(input),([_0,input2])=>If2(PatternBody(input2),([_1,input3])=>[[_0,_1],input3])),([_0,input2])=>[PatternTermMapping(_0),input2]);var PatternBody=input=>If2( +If2(PatternUnion(input),([_0,input2])=>[_0,input2],()=>If2(PatternTerm(input),([_0,input2])=>[_0,input2],()=>[])),([_0,input2])=>[PatternBodyMapping(_0),input2]);var Pattern=input=>If2(If2(Const("^",input),([_0,input2])=>If2(PatternBody(input2),([_1,input3])=>If2(Const("$",input3),([_2,input4])=>[[_0,_1,_2],input4]))),([_0,input2])=>[PatternMapping(_0),input2]);function JoinString(input){return input.join("|")}function UnwrapTemplateLiteralPattern(pattern){return pattern.slice(1,pattern.length-1)}function EncodeLiteral(value,right,pattern){return EncodeTypes(right,`${pattern}${value}`)}function EncodeBigInt(right,pattern){return EncodeTypes(right,`${pattern}${BigIntPattern}`)}function EncodeInteger(right,pattern){return EncodeTypes(right,`${pattern}${IntegerPattern}`)}function EncodeNumber(right,pattern){return EncodeTypes(right,`${pattern}${NumberPattern}`)} +function EncodeBoolean(right,pattern){return EncodeType(Union([Literal("false"),Literal("true")]),right,pattern)}function EncodeString(right,pattern){return EncodeTypes(right,`${pattern}${StringPattern}`)}function EncodeTemplateLiteral(templatePattern,right,pattern){return EncodeTypes(right,`${pattern}${UnwrapTemplateLiteralPattern(templatePattern)}`)}function EncodeTemplateLiteralDeferred(types,right,pattern){const templateLiteral=TemplateLiteralAction(types,{});const result=EncodeType(templateLiteral, +right,pattern);return result}function EncodeEnum(types,right,pattern){const variants=EnumValuesToVariants(types);return EncodeUnion(variants,right,pattern)}function EncodeUnion(types,right,pattern,result=[]){return guard_exports.TakeLeft(types,(head,tail)=>EncodeUnion(tail,right,pattern,[...result,EncodeType(head,[],"")]),()=>EncodeTypes(right,`${pattern}(${JoinString(result)})`))}function EncodeType(type,right,pattern){return IsEnum(type)?EncodeEnum(type.enum,right,pattern):IsInteger3(type)?EncodeInteger( +right,pattern):IsLiteral(type)?EncodeLiteral(type.const,right,pattern):IsBigInt3(type)?EncodeBigInt(right,pattern):IsBoolean4(type)?EncodeBoolean(right,pattern):IsNumber4(type)?EncodeNumber(right,pattern):IsString4(type)?EncodeString(right,pattern):IsTemplateLiteral(type)?EncodeTemplateLiteral(type.pattern,right,pattern):IsTemplateLiteralDeferred(type)?EncodeTemplateLiteralDeferred(type.parameters[0],right,pattern):IsUnion(type)?EncodeUnion(type.anyOf,right,pattern):NeverPattern}function EncodeTypes(types,pattern){ +return guard_exports.TakeLeft(types,(left,right)=>EncodeType(left,right,pattern),()=>pattern)}function EncodePattern(types){const encoded=EncodeTypes(types,"");const result=`^${encoded}$`;return result}function TemplateLiteralEncode(types){const pattern=EncodePattern(types);const result=TemplateLiteralCreate(pattern);return result}function TemplateLiteralAction(types,options){const result=CanInstantiate(types)?memory_exports.Update(TemplateLiteralEncode(types),{},options):TemplateLiteralDeferred(types,options);return result}function TemplateLiteralInstantiate(context,state2,types,options){const instantiatedTypes=InstantiateTypes(context,state2,types);return TemplateLiteralAction(instantiatedTypes,options)}function TemplateLiteralDeferred(types,options={}){return Deferred("TemplateLiteral",[types],options)}function IsTemplateLiteralDeferred(value){return IsSchema(value)&&guard_exports.HasPropertyKey(value,"action")&&guard_exports.IsEqual(value.action,"TemplateLiteral")}function IsTemplateLiteral(value){return IsKind(value,"TemplateLiteral")}var result_exports={};__export(result_exports,{ExtendsFalse:()=>ExtendsFalse,ExtendsTrue:()=>ExtendsTrue,ExtendsUnion:()=>ExtendsUnion,IsExtendsFalse:()=>IsExtendsFalse,IsExtendsTrue:()=>IsExtendsTrue,IsExtendsTrueLike:()=>IsExtendsTrueLike,IsExtendsUnion:()=>IsExtendsUnion,Match:()=>Match3});function ExtendsUnion(inferred){return memory_exports.Create({["~kind"]:"ExtendsUnion"},{inferred})}function IsExtendsUnion(value){return guard_exports.IsObject(value)&&guard_exports.HasPropertyKey(value,"~kind")&&guard_exports.HasPropertyKey(value,"inferred")&&guard_exports.IsEqual(value["~kind"],"ExtendsUnion")&&guard_exports.IsObject(value.inferred)}function ExtendsTrue(inferred){return memory_exports.Create({["~kind"]:"ExtendsTrue"},{inferred})}function IsExtendsTrue(value){return guard_exports. +IsObject(value)&&guard_exports.HasPropertyKey(value,"~kind")&&guard_exports.HasPropertyKey(value,"inferred")&&guard_exports.IsEqual(value["~kind"],"ExtendsTrue")&&guard_exports.IsObject(value.inferred)}function ExtendsFalse(){return memory_exports.Create({["~kind"]:"ExtendsFalse"},{})}function IsExtendsFalse(value){return guard_exports.IsObject(value)&&guard_exports.HasPropertyKey(value,"~kind")&&guard_exports.IsEqual(value["~kind"],"ExtendsFalse")}function IsExtendsTrueLike(value){return IsExtendsUnion( +value)||IsExtendsTrue(value)}function Match3(result,true_,false_){return IsExtendsTrueLike(result)?true_(result.inferred):false_()}function ExtendsRightInfer(inferred,name,left,right){return Match3(ExtendsLeft(inferred,left,right),checkInferred=>ExtendsTrue(memory_exports.Assign(memory_exports.Assign(inferred,checkInferred),{[name]:left})),()=>ExtendsFalse())}function ExtendsRightAny(inferred,_left){return ExtendsTrue(inferred)}function ExtendsRightEnum(inferred,left,right){const union=EnumValuesToUnion(right);return ExtendsLeft(inferred,left,union)}function ExtendsRightIntersect(inferred,left,right){return guard_exports.TakeLeft( +right,(head,tail)=>Match3(ExtendsLeft(inferred,left,head),inferred2=>ExtendsRightIntersect(inferred2,left,tail),()=>ExtendsFalse()),()=>ExtendsTrue(inferred))}function ExtendsRightTemplateLiteral(inferred,left,right){const decoded=TemplateLiteralDecode(right);return ExtendsLeft(inferred,left,decoded)}function ExtendsRightUnion(inferred,left,right){return guard_exports.TakeLeft(right,(head,tail)=>Match3(ExtendsLeft(inferred,left,head),inferred2=>ExtendsTrue(inferred2),()=>ExtendsRightUnion(inferred, +left,tail)),()=>ExtendsFalse())}function ExtendsRight(inferred,left,right){return IsAny(right)?ExtendsRightAny(inferred,left):IsEnum(right)?ExtendsRightEnum(inferred,left,right.enum):IsInfer(right)?ExtendsRightInfer(inferred,right.name,left,right.extends):IsIntersect(right)?ExtendsRightIntersect(inferred,left,right.allOf):IsTemplateLiteral(right)?ExtendsRightTemplateLiteral(inferred,left,right.pattern):IsUnion(right)?ExtendsRightUnion(inferred,left,right.anyOf):IsUnknown(right)?ExtendsTrue(inferred): +ExtendsFalse()}function ExtendsAny(inferred,left,right){return IsInfer(right)?ExtendsRight(inferred,left,right):IsAny(right)?ExtendsTrue(inferred):IsUnknown(right)?ExtendsTrue(inferred):ExtendsUnion(inferred)}function ExtendsImmutable(left,right){const isImmutableLeft=IsImmutable(left);const isImmutableRight=IsImmutable(right);return isImmutableLeft&&isImmutableRight?true:!isImmutableLeft&&isImmutableRight?true:isImmutableLeft&&!isImmutableRight?false:true}function ExtendsArray(inferred,arrayLeft,left,right){return IsArray3(right)?ExtendsImmutable(arrayLeft,right)?ExtendsLeft(inferred,left,right.items):ExtendsFalse():ExtendsRight(inferred,arrayLeft,right)}function ExtendsAsyncIterator(inferred,left,right){return IsAsyncIterator3(right)?ExtendsLeft(inferred,left,right.iteratorItems):ExtendsRight(inferred,AsyncIterator(left),right)}function ExtendsBigInt(inferred,left,right){return IsBigInt3(right)?ExtendsTrue(inferred):ExtendsRight(inferred,left,right)}function ExtendsBoolean(inferred,left,right){return IsBoolean4(right)?ExtendsTrue(inferred):ExtendsRight(inferred,left,right)}function ParameterCompare(inferred,left,leftRest,right,rightRest){const checkLeft=IsInfer(right)?left:right;const checkRight=IsInfer(right)?right:left;const isLeftOptional=IsOptional(left);const isRightOptional=IsOptional(right);return!isLeftOptional&&isRightOptional?ExtendsFalse():Match3(ExtendsLeft(inferred,checkLeft,checkRight),inferred2=>ExtendsParameters(inferred2,leftRest,rightRest),()=>ExtendsFalse())}function ParameterRight(inferred,left,leftRest,rightRest){return guard_exports.TakeLeft( +rightRest,(head,tail)=>ParameterCompare(inferred,left,leftRest,head,tail),()=>IsOptional(left)?ExtendsTrue(inferred):ExtendsFalse())}function ParametersLeft(inferred,left,rightRest){return guard_exports.TakeLeft(left,(head,tail)=>ParameterRight(inferred,head,tail,rightRest),()=>ExtendsTrue(inferred))}function ExtendsParameters(inferred,left,right){return ParametersLeft(inferred,left,right)}function ExtendsReturnType(inferred,left,right){return IsVoid(right)?ExtendsTrue(inferred):ExtendsLeft(inferred,left,right)}function ExtendsConstructor(inferred,parameters,returnType,right){return IsAny(right)?ExtendsTrue(inferred):IsUnknown(right)?ExtendsTrue(inferred):IsConstructor3(right)?Match3(ExtendsParameters(inferred,parameters,right["parameters"]),inferred2=>ExtendsReturnType(inferred2,returnType,right["instanceType"]),()=>ExtendsFalse()):ExtendsFalse()}function ExtendsEnum(inferred,left,right){return ExtendsLeft(inferred,EnumToUnion(left),right)}function ExtendsFunction(inferred,parameters,returnType,right){return IsAny(right)?ExtendsTrue(inferred):IsUnknown(right)?ExtendsTrue(inferred):IsFunction3(right)?Match3(ExtendsParameters(inferred,parameters,right["parameters"]),inferred2=>ExtendsReturnType(inferred2,returnType,right["returnType"]),()=>ExtendsFalse()):ExtendsFalse()}function ExtendsInteger(inferred,left,right){return IsInteger3(right)?ExtendsTrue(inferred):IsNumber4(right)?ExtendsTrue(inferred):ExtendsRight(inferred,left,right)}function ExtendsIntersect(inferred,left,right){const evaluated=EvaluateIntersect(left);return ExtendsLeft(inferred,evaluated,right)}function ExtendsIterator(inferred,left,right){return IsIterator3(right)?ExtendsLeft(inferred,left,right.iteratorItems):ExtendsRight(inferred,Iterator(left),right)}function ExtendsLiteralValue(inferred,left,right){return left===right?ExtendsTrue(inferred):ExtendsFalse()}function ExtendsLiteralBigInt(inferred,left,right){return IsLiteral(right)?ExtendsLiteralValue(inferred,left,right.const):IsBigInt3(right)?ExtendsTrue(inferred):ExtendsRight(inferred,Literal(left),right)}function ExtendsLiteralBoolean(inferred,left,right){return IsLiteral(right)?ExtendsLiteralValue(inferred,left,right.const):IsBoolean4(right)?ExtendsTrue(inferred):ExtendsRight(inferred,Literal( +left),right)}function ExtendsLiteralNumber(inferred,left,right){return IsLiteral(right)?ExtendsLiteralValue(inferred,left,right.const):IsNumber4(right)?ExtendsTrue(inferred):ExtendsRight(inferred,Literal(left),right)}function ExtendsLiteralString(inferred,left,right){return IsLiteral(right)?ExtendsLiteralValue(inferred,left,right.const):IsString4(right)?ExtendsTrue(inferred):ExtendsRight(inferred,Literal(left),right)}function ExtendsLiteral(inferred,left,right){return guard_exports.IsBigInt(left. +const)?ExtendsLiteralBigInt(inferred,left.const,right):guard_exports.IsBoolean(left.const)?ExtendsLiteralBoolean(inferred,left.const,right):guard_exports.IsNumber(left.const)?ExtendsLiteralNumber(inferred,left.const,right):guard_exports.IsString(left.const)?ExtendsLiteralString(inferred,left.const,right):Unreachable()}function ExtendsNever(inferred,left,right){return IsInfer(right)?ExtendsRight(inferred,left,right):ExtendsTrue(inferred)}function ExtendsNull(inferred,left,right){return IsNull3(right)?ExtendsTrue(inferred):ExtendsRight(inferred,left,right)}function ExtendsNumber(inferred,left,right){return IsNumber4(right)?ExtendsTrue(inferred):ExtendsRight(inferred,left,right)}function ExtendsPropertyOptional(inferred,left,right){return IsOptional(left)?IsOptional(right)?ExtendsTrue(inferred):ExtendsFalse():ExtendsTrue(inferred)}function ExtendsProperty(inferred,left,right){return IsInfer(right)&&IsNever(right.extends)?ExtendsFalse():Match3(ExtendsLeft(inferred,left,right),inferred2=>ExtendsPropertyOptional(inferred2,left,right),()=>ExtendsFalse())}function ExtractInferredProperties(keys,properties){return keys.reduce((result,key)=>{return key in properties?IsExtendsTrueLike( +properties[key])?{...result,...properties[key].inferred}:Unreachable():Unreachable()},{})}function ExtendsPropertiesComparer(inferred,left,right){const properties={};for(const rightKey of guard_exports.Keys(right)){properties[rightKey]=rightKey in left?ExtendsProperty({},left[rightKey],right[rightKey]):IsOptional(right[rightKey])?IsInfer(right[rightKey])?ExtendsTrue(memory_exports.Assign(inferred,{[right[rightKey].name]:right[rightKey].extends})):ExtendsTrue(inferred):ExtendsFalse()}const checked=guard_exports. +Values(properties).every(result=>IsExtendsTrueLike(result));const extracted=checked?ExtractInferredProperties(guard_exports.Keys(properties),properties):{};return checked?ExtendsTrue(extracted):ExtendsFalse()}function ExtendsProperties(inferred,left,right){const compared=ExtendsPropertiesComparer(inferred,left,right);return IsExtendsTrueLike(compared)?ExtendsTrue(memory_exports.Assign(inferred,compared.inferred)):ExtendsFalse()}function ExtendsObjectToObject(inferred,left,right){return ExtendsProperties( +inferred,left,right)}function ExtendsObject(inferred,left,right){return IsObject3(right)?ExtendsObjectToObject(inferred,left,right.properties):ExtendsRight(inferred,_Object_(left),right)}function ExtendsPromise(inferred,left,right){return IsPromise(right)?ExtendsLeft(inferred,left,right.item):ExtendsRight(inferred,_Promise_(left),right)}function ExtendsString(inferred,left,right){return IsString4(right)?ExtendsTrue(inferred):ExtendsRight(inferred,left,right)}function ExtendsSymbol(inferred,left,right){return IsSymbol3(right)?ExtendsTrue(inferred):ExtendsRight(inferred,left,right)}function ExtendsTemplateLiteral(inferred,left,right){const decoded=TemplateLiteralDecode(left);return ExtendsLeft(inferred,decoded,right)}function Inferrable(name,type){return memory_exports.Create({"~kind":"Inferrable"},{name,type},{})}function IsInferable(value){return guard_exports.IsObject(value)&&guard_exports.HasPropertyKey(value,"~kind")&&guard_exports.HasPropertyKey(value,"name")&&guard_exports.HasPropertyKey(value,"type")&&guard_exports.IsEqual(value["~kind"],"Inferrable")&&guard_exports.IsString(value.name)&&guard_exports.IsObject(value.type)}function TryRestInferable(type){return IsRest(type)?IsInfer(type.items)?IsArray3( +type.items.extends)?Inferrable(type.items.name,type.items.extends.items):IsUnknown(type.items.extends)?Inferrable(type.items.name,type.items.extends):void 0:Unreachable():void 0}function TryInferable(type){return IsInfer(type)?Inferrable(type.name,type.extends):void 0}function TryInferResults(rest,right,result=[]){return guard_exports.TakeLeft(rest,(head,tail)=>Match3(ExtendsLeft({},head,right),()=>TryInferResults(tail,right,[...result,head]),()=>void 0),()=>result)}function InferTupleResult(inferred,name,left,right){ +const results=TryInferResults(left,right);return guard_exports.IsArray(results)?ExtendsTrue(memory_exports.Assign(inferred,{[name]:Tuple(results)})):ExtendsFalse()}function InferUnionResult(inferred,name,left,right){const results=TryInferResults(left,right);return guard_exports.IsArray(results)?ExtendsTrue(memory_exports.Assign(inferred,{[name]:Union(results)})):ExtendsFalse()}function Reverse(types){return[...types].reverse()}function ApplyReverse(types,reversed){return reversed?Reverse(types):types}function Reversed(types){const first=types.length>0?types[0]:void 0;const inferrable=IsSchema(first)?TryRestInferable(first):void 0;return IsSchema(inferrable)}function ElementsCompare(inferred,reversed,left,leftRest,right,rightRest){return Match3(ExtendsLeft(inferred,left,right),checkInferred=>Elements(checkInferred,reversed,leftRest,rightRest),()=>ExtendsFalse())}function ElementsLeft(inferred,reversed,leftRest,right,rightRest){ +const inferable=TryRestInferable(right);return IsInferable(inferable)?InferTupleResult(inferred,inferable["name"],ApplyReverse(leftRest,reversed),inferable["type"]):guard_exports.TakeLeft(leftRest,(head,tail)=>ElementsCompare(inferred,reversed,head,tail,right,rightRest),()=>ExtendsFalse())}function ElementsRight(inferred,reversed,leftRest,rightRest){return guard_exports.TakeLeft(rightRest,(head,tail)=>ElementsLeft(inferred,reversed,leftRest,head,tail),()=>guard_exports.IsEqual(leftRest.length,0)? +ExtendsTrue(inferred):ExtendsFalse())}function Elements(inferred,reversed,leftRest,rightRest){return ElementsRight(inferred,reversed,leftRest,rightRest)}function ExtendsTupleToTuple(inferred,left,right){const instantiatedRight=InstantiateElements(inferred,{callstack:[]},right);const reversed=Reversed(instantiatedRight);return Elements(inferred,reversed,ApplyReverse(left,reversed),ApplyReverse(instantiatedRight,reversed))}function ExtendsTupleToArray(inferred,left,right){const inferrable=TryInferable( +right);return IsInferable(inferrable)?InferUnionResult(inferred,inferrable["name"],left,inferrable["type"]):guard_exports.TakeLeft(left,(head,tail)=>Match3(ExtendsLeft(inferred,head,right),inferred2=>ExtendsTupleToArray(inferred2,tail,right),()=>ExtendsFalse()),()=>ExtendsTrue(inferred))}function ExtendsTuple(inferred,left,right){const instantiatedLeft=InstantiateElements(inferred,{callstack:[]},left);return IsTuple(right)?ExtendsTupleToTuple(inferred,instantiatedLeft,right.items):IsArray3(right)? +ExtendsTupleToArray(inferred,instantiatedLeft,right.items):ExtendsRight(inferred,Tuple(instantiatedLeft),right)}function ExtendsUndefined(inferred,left,right){return IsVoid(right)?ExtendsTrue(inferred):IsUndefined3(right)?ExtendsTrue(inferred):ExtendsRight(inferred,left,right)}function ExtendsUnionSome(inferred,type,unionTypes){return guard_exports.TakeLeft(unionTypes,(head,tail)=>Match3(ExtendsLeft(inferred,type,head),inferred2=>ExtendsTrue(inferred2),()=>ExtendsUnionSome(inferred,type,tail)),()=>ExtendsFalse())}function ExtendsUnionLeft(inferred,left,right){return guard_exports.TakeLeft(left,(head,tail)=>Match3(ExtendsUnionSome(inferred,head,right),inferred2=>ExtendsUnionLeft(inferred2,tail,right),()=>ExtendsFalse()),()=>ExtendsTrue(inferred))}function ExtendsUnion2(inferred,left,right){ +const inferrable=TryInferable(right);return IsInferable(inferrable)?InferUnionResult(inferred,inferrable.name,left,inferrable.type):IsUnion(right)?ExtendsUnionLeft(inferred,left,right.anyOf):ExtendsUnionLeft(inferred,left,[right])}function ExtendsUnknown(inferred,left,right){return IsInfer(right)?ExtendsRight(inferred,left,right):IsAny(right)?ExtendsTrue(inferred):IsUnknown(right)?ExtendsTrue(inferred):ExtendsFalse()}function ExtendsVoid(inferred,left,right){return IsVoid(right)?ExtendsTrue(inferred):ExtendsRight(inferred,left,right)}function ExtendsLeft(inferred,left,right){return IsAny(left)?ExtendsAny(inferred,left,right):IsArray3(left)?ExtendsArray(inferred,left,left.items,right):IsAsyncIterator3(left)?ExtendsAsyncIterator(inferred,left.iteratorItems,right):IsBigInt3(left)?ExtendsBigInt(inferred,left,right):IsBoolean4(left)?ExtendsBoolean(inferred,left,right):IsConstructor3(left)?ExtendsConstructor(inferred,left.parameters,left.instanceType,right):IsEnum(left)?ExtendsEnum(inferred,left,right):IsFunction3(left)?ExtendsFunction( +inferred,left.parameters,left.returnType,right):IsInteger3(left)?ExtendsInteger(inferred,left,right):IsIntersect(left)?ExtendsIntersect(inferred,left.allOf,right):IsIterator3(left)?ExtendsIterator(inferred,left.iteratorItems,right):IsLiteral(left)?ExtendsLiteral(inferred,left,right):IsNever(left)?ExtendsNever(inferred,left,right):IsNull3(left)?ExtendsNull(inferred,left,right):IsNumber4(left)?ExtendsNumber(inferred,left,right):IsObject3(left)?ExtendsObject(inferred,left.properties,right):IsPromise( +left)?ExtendsPromise(inferred,left.item,right):IsString4(left)?ExtendsString(inferred,left,right):IsSymbol3(left)?ExtendsSymbol(inferred,left,right):IsTemplateLiteral(left)?ExtendsTemplateLiteral(inferred,left.pattern,right):IsTuple(left)?ExtendsTuple(inferred,left.items,right):IsUndefined3(left)?ExtendsUndefined(inferred,left,right):IsUnion(left)?ExtendsUnion2(inferred,left.anyOf,right):IsUnknown(left)?ExtendsUnknown(inferred,left,right):IsVoid(left)?ExtendsVoid(inferred,left,right):ExtendsFalse()}function InterfaceOperation(heritage,properties){const result=EvaluateIntersect([...heritage,_Object_(properties)]);return result}function InterfaceAction(heritage,properties,options){const result=CanInstantiate(heritage)?memory_exports.Update(InterfaceOperation(heritage,properties),{},options):InterfaceDeferred(heritage,properties,options);return result}function InterfaceInstantiate(context,state2,heritage,properties,options){const instantiatedHeritage=InstantiateTypes(context,state2,heritage); +const instantiatedProperties=InstantiateProperties(context,state2,properties);return InterfaceAction(instantiatedHeritage,instantiatedProperties,options)}function InterfaceDeferred(heritage,properties,options={}){return Deferred("Interface",[heritage,properties],options)}function IsInterfaceDeferred(value){return IsSchema(value)&&guard_exports.HasPropertyKey(value,"action")&&guard_exports.IsEqual(value.action,"Interface")}function FromRef(stack,context,ref){return stack.includes(ref)?true:FromType3([...stack,ref],context,context[ref])}function FromProperties(stack,context,properties){const types=PropertyValues(properties);return FromTypes2(stack,context,types)}function FromTypes2(stack,context,types){return guard_exports.TakeLeft(types,(left,right)=>FromType3(stack,context,left)?true:FromTypes2(stack,context,right),()=>false)}function FromType3(stack,context,type){return IsRef(type)?FromRef(stack,context,type.$ref): +IsArray3(type)?FromType3(stack,context,type.items):IsAsyncIterator3(type)?FromType3(stack,context,type.iteratorItems):IsConstructor3(type)?FromTypes2(stack,context,[...type.parameters,type.instanceType]):IsFunction3(type)?FromTypes2(stack,context,[...type.parameters,type.returnType]):IsInterfaceDeferred(type)?FromProperties(stack,context,type.parameters[1]):IsIntersect(type)?FromTypes2(stack,context,type.allOf):IsIterator3(type)?FromType3(stack,context,type.iteratorItems):IsObject3(type)?FromProperties( +stack,context,type.properties):IsPromise(type)?FromType3(stack,context,type.item):IsUnion(type)?FromTypes2(stack,context,type.anyOf):IsTuple(type)?FromTypes2(stack,context,type.items):IsRecord(type)?FromType3(stack,context,RecordValue(type)):false}function CyclicCheck(stack,context,type){const result=FromType3(stack,context,type);return result}function ResolveCandidateKeys(context,keys){return keys.reduce((result,left)=>{return left in context?CyclicCheck([left],context,context[left])?[...result,left]:result:Unreachable()},[])}function CyclicCandidates(context){const keys=PropertyKeys(context);const result=ResolveCandidateKeys(context,keys);return result}function FromRef2(context,ref,result){return result.includes(ref)?result:ref in context?FromType4(context,context[ref],[...result,ref]):Unreachable()}function FromProperties2(context,properties,result){const types=PropertyValues(properties);return FromTypes3(context,types,result)}function FromTypes3(context,types,result){return types.reduce((result2,left)=>{return FromType4(context,left,result2)},result)}function FromType4(context,type,result){return IsRef(type)?FromRef2(context,type.$ref,result): +IsArray3(type)?FromType4(context,type.items,result):IsAsyncIterator3(type)?FromType4(context,type.iteratorItems,result):IsConstructor3(type)?FromTypes3(context,[...type.parameters,type.instanceType],result):IsFunction3(type)?FromTypes3(context,[...type.parameters,type.returnType],result):IsInterfaceDeferred(type)?FromProperties2(context,type.parameters[1],result):IsIntersect(type)?FromTypes3(context,type.allOf,result):IsIterator3(type)?FromType4(context,type.iteratorItems,result):IsObject3(type)? +FromProperties2(context,type.properties,result):IsPromise(type)?FromType4(context,type.item,result):IsUnion(type)?FromTypes3(context,type.anyOf,result):IsTuple(type)?FromTypes3(context,type.items,result):IsRecord(type)?FromType4(context,RecordValue(type),result):result}function CyclicDependencies(context,key,type){const result=FromType4(context,type,[key]);return result}function FromRef3(_ref){return Any()}function FromProperties3(properties){return guard_exports.Keys(properties).reduce((result,key)=>{return{...result,[key]:FromType5(properties[key])}},{})}function FromTypes4(types){return types.reduce((result,left)=>{return[...result,FromType5(left)]},[])}function FromType5(type){return IsRef(type)?FromRef3(type.$ref):IsArray3(type)?_Array_(FromType5(type.items),ArrayOptions(type)):IsAsyncIterator3(type)?AsyncIterator(FromType5(type.iteratorItems)):IsConstructor3( +type)?Constructor(FromTypes4(type.parameters),FromType5(type.instanceType)):IsFunction3(type)?_Function_(FromTypes4(type.parameters),FromType5(type.returnType)):IsIntersect(type)?Intersect(FromTypes4(type.allOf)):IsIterator3(type)?Iterator(FromType5(type.iteratorItems)):IsObject3(type)?_Object_(FromProperties3(type.properties)):IsPromise(type)?_Promise_(FromType5(type.item)):IsRecord(type)?Record(RecordKey(type),FromType5(RecordValue(type))):IsUnion(type)?Union(FromTypes4(type.anyOf)):IsTuple(type)? +Tuple(FromTypes4(type.items)):type}function CyclicAnyFromParameters(defs,ref){return ref in defs?FromType5(defs[ref]):Unknown()}function CyclicExtends(type){return CyclicAnyFromParameters(type.$defs,type.$ref)}function CyclicInterface(context,heritage,properties){const instantiatedHeritage=InstantiateTypes(context,{callstack:[]},heritage);const instantiatedProperties=InstantiateProperties({},{callstack:[]},properties);const evaluatedInterface=EvaluateIntersect([...instantiatedHeritage,_Object_(instantiatedProperties)]);return evaluatedInterface}function CyclicDefinitions(context,dependencies){const keys=guard_exports.Keys(context).filter(key=>dependencies.includes(key));return keys.reduce((result,key)=>{ +const type=context[key];const instantiatedType=IsInterfaceDeferred(type)?CyclicInterface(context,type.parameters[0],type.parameters[1]):type;return{...result,[key]:instantiatedType}},{})}function InstantiateCyclic(context,ref,type){const dependencies=CyclicDependencies(context,ref,type);const definitions=CyclicDefinitions(context,dependencies);const result=Cyclic(definitions,ref);return result}function Resolve(defs,ref){return ref in defs?IsRef(defs[ref])?Resolve(defs,defs[ref].$ref):defs[ref]:Never()}function CyclicTarget(defs,ref){const result=Resolve(defs,ref);return result}function Canonical(type){return IsCyclic(type)?CyclicExtends(type):IsUnsafe(type)?Unknown():type}function Extends(inferred,left,right){const canonicalLeft=Canonical(left);const canonicalRight=Canonical(right);return ExtendsLeft(inferred,canonicalLeft,canonicalRight)}var ResultEqual="equal";var ResultDisjoint="disjoint";var ResultLeftInside="left-inside";var ResultRightInside="right-inside";function Compare(left,right){const extendsCheck=[IsUnknown(left)?result_exports.ExtendsFalse():Extends({},left,right),IsUnknown(left)?result_exports.ExtendsTrue({}):Extends({},right,left)];return result_exports.IsExtendsTrueLike(extendsCheck[0])&&result_exports.IsExtendsTrueLike(extendsCheck[1])?ResultEqual:result_exports.IsExtendsTrueLike(extendsCheck[0])&&result_exports. +IsExtendsFalse(extendsCheck[1])?ResultLeftInside:result_exports.IsExtendsFalse(extendsCheck[0])&&result_exports.IsExtendsTrueLike(extendsCheck[1])?ResultRightInside:ResultDisjoint}function BroadFilter(type,types){return types.filter(left=>{return Compare(type,left)===ResultRightInside?false:true})}function IsBroadestType(type,types){const result=types.some(left=>{const result2=Compare(type,left);return guard_exports.IsEqual(result2,ResultLeftInside)||guard_exports.IsEqual(result2,ResultEqual)});return guard_exports.IsEqual(result,false)}function BroadenType(type,types){const evaluated=EvaluateType(type);return IsAny(evaluated)?[evaluated]:IsBroadestType(evaluated,types)?[ +...BroadFilter(evaluated,types),evaluated]:types}function BroadenTypes(types){return types.reduce((result,left)=>{return IsObject3(left)?[...result,left]:IsNever(left)?result:BroadenType(left,result)},[])}function Broaden(types){const broadened=BroadenTypes(types);const flattened=Flatten(broadened);const result=flattened.length===0?Never():flattened.length===1?flattened[0]:Union(flattened);return result}function EvaluateAction(type,options){const result=memory_exports.Update(EvaluateType(type),{},options);return result}function EvaluateInstantiate(context,state2,type,options){const instantiatedType=InstantiateType(context,state2,type);return EvaluateAction(instantiatedType,options)}function CollectDistributionNames(expression,result=[]){return IsDeferred(expression)&&guard_exports.IsEqual(expression.action,"Conditional")?IsRef(expression.parameters[0])?CollectDistributionNames(expression.parameters[2],CollectDistributionNames(expression.parameters[3],[...result,expression.parameters[0]["$ref"]])):CollectDistributionNames(expression.parameters[2],CollectDistributionNames(expression.parameters[3],result)):IsDeferred(expression)&&guard_exports.IsEqual(expression.action,"Mappe\ +d")?IsDeferred(expression.parameters[1])&&guard_exports.IsEqual(expression.parameters[1].action,"KeyOf")&&IsRef(expression.parameters[1].parameters[0])?[...result,expression.parameters[1].parameters[0]["$ref"]]:result:result}function BuildDistributionArray(parameters,names){return parameters.reduce((result,left)=>[...result,names.includes(left.name)],[])}function ZipDistributionArray(arguments_,distributionArray,result=[]){return guard_exports.TakeLeft(arguments_,(argumentLeft,argumentRight)=>guard_exports. +TakeLeft(distributionArray,(booleanLeft,booleanRight)=>ZipDistributionArray(argumentRight,booleanRight,[...result,[booleanLeft,argumentLeft]]),()=>result),()=>result)}function Expand(type){return IsUnion(type)?[...type.anyOf]:[type]}function Append(current,type){return current.reduce((result,left)=>[...result,[...left,type]],[])}function Cross(current,variants){return variants.reduce((result,left)=>{return[...result,...Append(current,left)]},[])}function Distribute2(zipped){return zipped.reduce( +(result,left)=>{return guard_exports.IsEqual(left[0],true)?Cross(result,Expand(left[1])):Cross(result,[left[1]])},[[]])}function DistributeArguments(parameters,arguments_,expression){const distributionNames=CollectDistributionNames(expression);const distributionArray=BuildDistributionArray(parameters,distributionNames);const zippedArguments=ZipDistributionArray(arguments_,distributionArray);return IsDeferred(expression)&&guard_exports.IsEqual(expression.action,"Conditional")?Distribute2(zippedArguments): +IsDeferred(expression)&&guard_exports.IsEqual(expression.action,"Mapped")?Distribute2(zippedArguments):[arguments_]}function FromNotResolvable(){return["(not-resolvable)",Never()]}function FromNotGeneric(){return["(not-generic)",Never()]}function FromGeneric(name,parameters,expression){return[name,Generic(parameters,expression)]}function FromRef4(context,ref,arguments_){return ref in context?FromType6(context,ref,context[ref],arguments_):FromNotResolvable()}function FromType6(context,name,target,arguments_){return IsGeneric(target)?FromGeneric(name,target.parameters,target.expression):IsRef(target)?FromRef4(context, +target.$ref,arguments_):FromNotGeneric()}function ResolveTarget(context,target,arguments_){return FromType6(context,"(anonymous)",target,arguments_)}function AssertArgumentExtends(name,type,extends_){if(IsInfer(type)||IsCall(type)||result_exports.IsExtendsTrueLike(Extends({},type,extends_)))return;const cause={parameter:name,expect:extends_,actual:type};throw new Error(`Argument for parameter ${name} does not satisfy constraint`,{cause})}function BindArgument(context,state2,name,extends_,type){const instantiatedArgument=InstantiateType(context,state2,type);AssertArgumentExtends(name,instantiatedArgument,extends_);return memory_exports.Assign( +context,{[name]:instantiatedArgument})}function BindArguments(context,state2,parameterLeft,parameterRight,arguments_){const instantiatedExtends=InstantiateType(context,state2,parameterLeft.extends);const instantiatedEquals=InstantiateType(context,state2,parameterLeft.equals);return guard_exports.TakeLeft(arguments_,(left,right)=>BindParameters(BindArgument(context,state2,parameterLeft["name"],instantiatedExtends,left),state2,parameterRight,right),()=>BindParameters(BindArgument(context,state2,parameterLeft["\ +name"],instantiatedExtends,instantiatedEquals),state2,parameterRight,[]))}function BindParameters(context,state2,parameters,arguments_){return guard_exports.TakeLeft(parameters,(left,right)=>BindArguments(context,state2,left,right,arguments_),()=>context)}function ResolveArgumentsContext(context,state2,parameters,arguments_){return BindParameters(context,state2,parameters,arguments_)}function Peek(state2){const result=guard_exports.IsGreaterThan(state2.callstack.length,0)?state2.callstack[state2.callstack.length-1]:"";return result}function IsTailCall(state2,name){const result=guard_exports.IsEqual(Peek(state2),name);return result}function CallDispatch(context,state2,target,parameters,expression,arguments_){const argumentsContext=ResolveArgumentsContext(context,state2,parameters,arguments_);const returnType=InstantiateType(argumentsContext,{callstack:[...state2.callstack,target. +$ref]},expression);return InstantiateType(context,state2,returnType)}function CallDistributed(context,state2,target,parameters,expression,distributedArguments){return distributedArguments.reduce((result,arguments_)=>[...result,CallDispatch(context,state2,target,parameters,expression,arguments_)],[])}function CallImmediate(context,state2,target,parameters,expression,arguments_){const distributedArguments=DistributeArguments(parameters,arguments_,expression);const returnTypes=CallDistributed(context, +state2,target,parameters,expression,distributedArguments);const result=guard_exports.IsEqual(returnTypes.length,1)?returnTypes[0]:EvaluateUnion(returnTypes);return result}function CallInstantiate(context,state2,target,arguments_){const instantiatedArguments=InstantiateTypes(context,state2,arguments_);const resolved=ResolveTarget(context,target,arguments_);const name=resolved[0];const type=resolved[1];const result=IsGeneric(type)?IsTailCall(state2,name)?CallConstruct(Ref(name),instantiatedArguments): +CallImmediate(context,state2,Ref(name),type.parameters,type.expression,instantiatedArguments):CallConstruct(target,instantiatedArguments);return result}function CallConstruct(target,arguments_){return memory_exports.Create({["~kind"]:"Call"},{target,arguments:arguments_},{})}function IsCall(value){return IsKind(value,"Call")}function ApplyMapping(mapping,value){return mapping(value)}function FromLiteral3(mapping,value){return guard_exports.IsString(value)?Literal(ApplyMapping(mapping,value)):Literal(value)}function FromTemplateLiteral(mapping,pattern){const decoded=TemplateLiteralDecode(pattern);const result=FromType7(mapping,decoded);return result}function FromUnion2(mapping,types){const result=types.map(type=>FromType7(mapping,type));return Union(result)}function FromType7(mapping,type){return IsLiteral(type)?FromLiteral3(mapping,type.const):IsTemplateLiteral(type)?FromTemplateLiteral(mapping,type.pattern):IsUnion(type)?FromUnion2(mapping,type.anyOf):type}function CapitalizeDeferred(type,options={}){return Deferred("Capitalize",[type],options)}function LowercaseDeferred(type,options={}){return Deferred("Lowercase",[type],options)}function UncapitalizeDeferred(type,options={}){return Deferred("Uncapitalize",[type],options)}function UppercaseDeferred(type,options={}){return Deferred("Uppercase",[type],options)}var CapitalizeMapping=input=>input[0].toUpperCase()+input.slice(1);var LowercaseMapping=input=>input.toLowerCase();var UncapitalizeMapping=input=>input[0].toLowerCase()+input.slice(1);var UppercaseMapping=input=>input.toUpperCase();function CapitalizeAction(type,options){const result=CanInstantiate([type])?memory_exports.Update(FromType7(CapitalizeMapping,type),{},options):CapitalizeDeferred(type,options);return result}function LowercaseAction(type,options){const result=CanInstantiate([type])?memory_exports. +Update(FromType7(LowercaseMapping,type),{},options):LowercaseDeferred(type,options);return result}function UncapitalizeAction(type,options){const result=CanInstantiate([type])?memory_exports.Update(FromType7(UncapitalizeMapping,type),{},options):UncapitalizeDeferred(type,options);return result}function UppercaseAction(type,options){const result=CanInstantiate([type])?memory_exports.Update(FromType7(UppercaseMapping,type),{},options):UppercaseDeferred(type,options);return result}function CapitalizeInstantiate(context,state2,type,options){ +const instantiatedType=InstantiateType(context,state2,type);return CapitalizeAction(instantiatedType,options)}function LowercaseInstantiate(context,state2,type,options){const instantiatedType=InstantiateType(context,state2,type);return LowercaseAction(instantiatedType,options)}function UncapitalizeInstantiate(context,state2,type,options){const instantiatedType=InstantiateType(context,state2,type);return UncapitalizeAction(instantiatedType,options)}function UppercaseInstantiate(context,state2,type,options){ +const instantiatedType=InstantiateType(context,state2,type);return UppercaseAction(instantiatedType,options)}function ConditionalDeferred(left,right,true_,false_,options={}){return Deferred("Conditional",[left,right,true_,false_],options)}function ConditionalOperation(context,state2,left,right,true_,false_){const extendsResult=Extends(context,left,right);return result_exports.IsExtendsUnion(extendsResult)?Union([InstantiateType(extendsResult.inferred,state2,true_),InstantiateType(context,state2,false_)]):result_exports.IsExtendsTrue(extendsResult)?InstantiateType(extendsResult.inferred,state2,true_):InstantiateType(context,state2,false_)}function ConditionalAction(context,state2,left,right,true_,false_,options){const result=CanInstantiate( +[left,right])?memory_exports.Update(ConditionalOperation(context,state2,left,right,true_,false_),{},options):ConditionalDeferred(left,right,true_,false_,options);return result}function ConditionalInstantiate(context,state2,left,right,true_,false_,options){const instantiatedLeft=InstantiateType(context,state2,left);const instantiatedRight=InstantiateType(context,state2,right);return ConditionalAction(context,state2,instantiatedLeft,instantiatedRight,true_,false_,options)}function ConstructorParametersDeferred(type,options={}){return Deferred("ConstructorParameters",[type],options)}function ConstructorParametersOperation(type){const parameters=IsConstructor3(type)?type["parameters"]:[];const instantiatedParameters=InstantiateElements({},{callstack:[]},parameters);const result=Tuple(instantiatedParameters);return result}function ConstructorParametersAction(type,options){const result=CanInstantiate([type])?memory_exports.Update(ConstructorParametersOperation(type),{},options):ConstructorParametersDeferred(type,options);return result}function ConstructorParametersInstantiate(context,state2,type,options){ +const instantiatedType=InstantiateType(context,state2,type);return ConstructorParametersAction(instantiatedType,options)}function ExcludeDeferred(left,right,options={}){return Deferred("Exclude",[left,right],options)}function ExcludeUnionLeft(types,right){return types.reduce((result,head)=>{return[...result,...ExcludeTypeLeft(head,right)]},[])}function ExcludeTypeLeft(left,right){const check=Extends({},left,right);const result=result_exports.IsExtendsTrueLike(check)?[]:[left];return result}function ExcludeOperation(left,right){const remaining=IsEnum(left)?ExcludeUnionLeft(EnumValuesToVariants(left.enum),right):IsUnion(left)?ExcludeUnionLeft(Flatten(left.anyOf),right):ExcludeTypeLeft(left,right);const result=EvaluateUnion( +remaining);return result}function ExcludeAction(left,right,options){const result=CanInstantiate([left,right])?memory_exports.Update(ExcludeOperation(left,right),{},options):ExcludeDeferred(left,right,options);return result}function ExcludeInstantiate(context,state2,left,right,options){const instantiatedLeft=InstantiateType(context,state2,left);const instantiatedRight=InstantiateType(context,state2,right);return ExcludeAction(instantiatedLeft,instantiatedRight,options)}function ExtractDeferred(left,right,options={}){return Deferred("Extract",[left,right],options)}function ExtractUnionLeft(types,right){return types.reduce((result,head)=>{return[...result,...ExtractTypeLeft(head,right)]},[])}function ExtractTypeLeft(left,right){const check=Extends({},left,right);const result=result_exports.IsExtendsTrueLike(check)?[left]:[];return result}function ExtractOperation(left,right){const remaining=IsEnum(left)?ExtractUnionLeft(EnumValuesToVariants(left.enum),right):IsUnion(left)?ExtractUnionLeft(Flatten(left.anyOf),right):ExtractTypeLeft(left,right);const result=EvaluateUnion( +remaining);return result}function ExtractAction(left,right,options){const result=CanInstantiate([left,right])?memory_exports.Update(ExtractOperation(left,right),{},options):ExtractDeferred(left,right,options);return result}function ExtractInstantiate(context,state2,left,right,options){const instantiatedLeft=InstantiateType(context,state2,left);const instantiatedRight=InstantiateType(context,state2,right);return ExtractAction(instantiatedLeft,instantiatedRight,options)}function IndexDeferred(type,indexer,options={}){return Deferred("Index",[type,indexer],options)}function FromCyclic(defs,ref){const target=CyclicTarget(defs,ref);const result=FromType8(target);return result}function CollapseIntersectProperties(left,right){const leftKeys=guard_exports.Keys(left).filter(key=>!guard_exports.HasPropertyKey(right,key));const rightKeys=guard_exports.Keys(right).filter(key=>!guard_exports.HasPropertyKey(left,key));const sharedKeys=guard_exports.Keys(left).filter(key=>guard_exports.HasPropertyKey(right,key));const leftProperties=leftKeys.reduce((result,key)=>({...result,[key]:left[key]}),{});const rightProperties=rightKeys.reduce((result,key)=>({...result,[key]:right[key]}), +{});const sharedProperties=sharedKeys.reduce((result,key)=>({...result,[key]:EvaluateIntersect([left[key],right[key]])}),{});const unique=memory_exports.Assign(leftProperties,rightProperties);const shared=memory_exports.Assign(unique,sharedProperties);return shared}function FromIntersect(types){return types.reduce((result,left)=>{return CollapseIntersectProperties(result,FromType8(left))},{})}function FromObject3(properties){return properties}function FromTuple(types){const object=TupleToObject(Tuple(types));const result=FromType8(object);return result}function CollapseUnionProperties(left,right){const sharedKeys=guard_exports.Keys(left).filter(key=>key in right);const result=sharedKeys.reduce((result2,key)=>{return{...result2,[key]:EvaluateUnion([left[key],right[key]])}},{});return result}function ReduceVariants(types,result){return guard_exports.TakeLeft(types,(left,right)=>ReduceVariants(right,CollapseUnionProperties(result,FromType8(left))),()=>result)}function FromUnion3(types){return guard_exports.TakeLeft(types,(left,right)=>ReduceVariants( +right,FromType8(left)),()=>Unreachable())}function FromType8(type){return IsCyclic(type)?FromCyclic(type.$defs,type.$ref):IsIntersect(type)?FromIntersect(type.allOf):IsUnion(type)?FromUnion3(type.anyOf):IsTuple(type)?FromTuple(type.items):IsObject3(type)?FromObject3(type.properties):{}}function CollapseToObject(type){const properties=FromType8(type);const result=_Object_(properties);return result}var integerKeyPattern=new RegExp("^(?:0|[1-9][0-9]*)$");function ConvertToIntegerKey(value){const normal=`${value}`;return integerKeyPattern.test(normal)?parseInt(normal):value}function NormalizeLiteral(value){return Literal(ConvertToIntegerKey(value))}function NormalizeIndexerTypes(types){return types.map(type=>NormalizeIndexer(type))}function NormalizeIndexer(type){return IsIntersect(type)?Intersect(NormalizeIndexerTypes(type.allOf)):IsUnion(type)?Union(NormalizeIndexerTypes(type.anyOf)):IsLiteral(type)?NormalizeLiteral(type.const):type}function FromArray3(type,indexer){const normalizedIndexer=NormalizeIndexer(indexer);const check=Extends({},normalizedIndexer,Number2()); +const result=result_exports.IsExtendsTrueLike(check)?type:IsLiteral(indexer)&&guard_exports.IsEqual(indexer.const,"length")?Number2():Never();return result}function FromCyclic2(defs,ref){const target=CyclicTarget(defs,ref);const result=FromType9(target);return result}function FromUnion4(types){return types.reduce((result,left)=>{return[...result,...FromType9(left)]},[])}function FromEnum(values){const variants=EnumValuesToVariants(values);const result=FromUnion4(variants);return result}function FromIntersect2(types){const evaluated=EvaluateIntersect(types);const result=FromType9(evaluated);return result}function FromLiteral4(value){const result=[`${value}`];return result}function FromTemplateLiteral2(pattern){const decoded=TemplateLiteralDecode(pattern);const result=FromType9(decoded);return result}function FromType9(type){return IsCyclic(type)?FromCyclic2(type.$defs,type.$ref):IsEnum(type)?FromEnum(type.enum):IsIntersect(type)?FromIntersect2(type.allOf):IsLiteral(type)?FromLiteral4(type.const):IsTemplateLiteral(type)?FromTemplateLiteral2(type.pattern):IsUnion(type)?FromUnion4(type.anyOf):[]}function ToIndexableKeys(type){const result=FromType9(type);return result}function FromTypes5(properties,types){return types.map(type=>FromType10(properties,type))}function FromType10(properties,type){return IsArray3(type)?_Array_(FromType10(properties,type.items)):IsAsyncIterator3(type)?AsyncIterator(FromType10(properties,type.iteratorItems)):IsConstructor3(type)?Constructor(FromTypes5(properties,type.parameters),FromType10(properties,type.instanceType)):IsFunction3(type)?_Function_(FromTypes5(properties,type.parameters),FromType10(properties,type.returnType)):IsIterator3( +type)?Iterator(FromType10(properties,type.iteratorItems)):IsPromise(type)?_Promise_(FromType10(properties,type.item)):IsTuple(type)?Tuple(FromTypes5(properties,type.items)):IsUnion(type)?Union(FromTypes5(properties,type.anyOf)):IsIntersect(type)?Intersect(FromTypes5(properties,type.allOf)):IsThis(type)?_Object_(properties):type}function ExpandThis(properties,type){const result=FromType10(properties,type);return result}function IndexProperty(properties,key){const selectedType=key in properties?properties[key]:Never();const result=ExpandThis(properties,selectedType);return result}function IndexProperties(properties,keys){return keys.reduce((result,left)=>{return[...result,IndexProperty(properties,left)]},[])}function FromIndexer(properties,indexer){const keys=ToIndexableKeys(indexer);const variants=IndexProperties(properties,keys);const result=EvaluateUnion(variants);return result}var NumericKeyPattern=new RegExp( +IntegerKey);function NumericKeys(keys){const result=keys.filter(key=>NumericKeyPattern.test(key));return result}function FromIndexerNumber(properties){const keys=PropertyKeys(properties);const numericKeys=NumericKeys(keys);const variants=IndexProperties(properties,numericKeys);const result=EvaluateUnion(variants);return result}function FromObject4(properties,indexer){const result=IsNumber4(indexer)?FromIndexerNumber(properties):FromIndexer(properties,indexer);return result}function ConvertLiteral(value){return Literal(ConvertToIntegerKey(value))}function ArrayIndexerTypes(types){return types.map(type=>FormatArrayIndexer(type))}function FormatArrayIndexer(type){return IsIntersect(type)?Intersect(ArrayIndexerTypes(type.allOf)):IsUnion(type)?Union(ArrayIndexerTypes(type.anyOf)):IsLiteral(type)?ConvertLiteral(type.const):type}function IndexElementsWithIndexer(types,indexer){return types.reduceRight((result,right,index2)=>{const check=Extends({},Literal(index2),indexer);return result_exports.IsExtendsTrueLike(check)?[right,...result]:result},[])}function FromTupleWithIndexer(types,indexer){const formattedArrayIndexer=FormatArrayIndexer(indexer);const elements=IndexElementsWithIndexer(types,formattedArrayIndexer);return EvaluateUnionFast(elements)}function FromTupleWithoutIndexer(types){return EvaluateUnionFast(types)} +function FromTuple2(types,indexer){return IsLiteral(indexer)&&guard_exports.IsEqual(indexer.const,"length")?Literal(types.length):IsNumber4(indexer)||IsInteger3(indexer)?FromTupleWithoutIndexer(types):FromTupleWithIndexer(types,indexer)}function FromType11(type,indexer){return IsArray3(type)?FromArray3(type.items,indexer):IsObject3(type)?FromObject4(type.properties,indexer):IsTuple(type)?FromTuple2(type.items,indexer):Never()}function NormalizeType(type){const result=IsCyclic(type)||IsIntersect(type)||IsUnion(type)?CollapseToObject(type):type;return result}function IndexAction(type,indexer,options){const result=CanInstantiate([type,indexer])?memory_exports.Update(FromType11(NormalizeType(type),indexer),{},options):IndexDeferred(type,indexer,options);return result}function IndexInstantiate(context,state2,type,indexer,options){const instantiatedType=InstantiateType(context,state2,type);const instantiatedIndexer=InstantiateType( +context,state2,indexer);return IndexAction(instantiatedType,instantiatedIndexer,options)}function InstanceTypeDeferred(type,options={}){return Deferred("InstanceType",[type],options)}function InstanceTypeOperation(type){return IsConstructor3(type)?type["instanceType"]:Never()}function InstanceTypeAction(type,options){const result=CanInstantiate([type])?memory_exports.Update(InstanceTypeOperation(type),{},options):InstanceTypeDeferred(type,options);return result}function InstanceTypeInstantiate(context,state2,type,options={}){const instantiatedType=InstantiateType(context,state2,type);return InstanceTypeAction(instantiatedType,options)}function KeyOfDeferred(type,options={}){return Deferred("KeyOf",[type],options)}function FromAny(){return Union([Number2(),String2(),Symbol2()])}function FromArray4(_type){return Number2()}function FromPropertyKeys(keys){const result=keys.reduce((result2,left)=>{return IsLiteralValue(left)?[...result2,Literal(ConvertToIntegerKey(left))]:Unreachable()},[]);return result}function FromObject5(properties){const propertyKeys=guard_exports.Keys(properties);const variants=FromPropertyKeys(propertyKeys);const result=EvaluateUnionFast(variants);return result}function FromRecord(type){return RecordKey(type)}function FromTuple3(types){const result=types.map((_,index2)=>Literal(index2));return EvaluateUnionFast(result)}function FromType12(type){return IsAny(type)?FromAny():IsArray3(type)?FromArray4(type.items):IsObject3(type)?FromObject5(type.properties):IsRecord(type)?FromRecord(type):IsTuple(type)?FromTuple3(type.items):Never()}function NormalizeType2(type){const result=IsCyclic(type)||IsIntersect(type)||IsUnion(type)?CollapseToObject(type):type;return result}function KeyOfAction(type,options){return CanInstantiate([type])?memory_exports.Update(FromType12(NormalizeType2(type)),{},options):KeyOfDeferred(type,options)}function KeyOfInstantiate(context,state2,type,options){const instantiatedType=InstantiateType(context,state2,type);return KeyOfAction(instantiatedType,options)}function MappedDeferred(identifier,type,as,property,options={}){return Deferred("Mapped",[identifier,type,as,property],options)}function FromTemplateLiteral3(pattern){const decoded=TemplateLiteralDecode(pattern);const result=FromType13(decoded);return result}function FromUnion5(types){return types.reduce((result,left)=>{return[...result,...FromType13(left)]},[])}function FromLiteral5(value){const result=guard_exports.IsNumber(value)?[Literal(`${value}`)]:[Literal(value)];return result}function FromType13(type){const result=IsEnum(type)?FromUnion5(EnumValuesToVariants(type.enum)):IsLiteral(type)?FromLiteral5(type.const):IsTemplateLiteral( +type)?FromTemplateLiteral3(type.pattern):IsUnion(type)?FromUnion5(type.anyOf):[type];return result}function MappedVariants(type){const result=FromType13(type);return result}function CanonicalAs(instantiatedAs){const result=IsTemplateLiteral(instantiatedAs)?TemplateLiteralDecode(instantiatedAs.pattern):instantiatedAs;return result}function MappedVariant(context,state2,identifier,variant,as,property){const variantContext=memory_exports.Assign(context,{[identifier["name"]]:variant});const instantiatedAs=InstantiateType(variantContext,state2,as);const canonicalAs=CanonicalAs(instantiatedAs);const instantiatedProperty=InstantiateType(variantContext,state2,property);return IsLiteralNumber( +canonicalAs)||IsLiteralString(canonicalAs)?{[canonicalAs.const]:instantiatedProperty}:{}}function MappedProperties(context,state2,identifier,variants,as,property){return variants.reduce((result,left)=>{return[...result,MappedVariant(context,state2,identifier,left,as,property)]},[])}function MappedObjects(properties){return properties.reduce((result,left)=>{return[...result,_Object_(left)]},[])}function MappedOperation(context,state2,identifier,type,as,property){const variants=MappedVariants(type); +const mappedProperties=MappedProperties(context,state2,identifier,variants,as,property);const mappedObjects=MappedObjects(mappedProperties);const result=EvaluateIntersect(mappedObjects);return result}function MappedAction(context,state2,identifier,type,as,property,options){const result=CanInstantiate([type])?memory_exports.Update(MappedOperation(context,state2,identifier,type,as,property),{},options):MappedDeferred(identifier,type,as,property,options);return result}function MappedInstantiate(context,state2,identifier,type,as,property,options){const instantiatedType=InstantiateType(context,state2,type);return MappedAction(context,state2,identifier,instantiatedType,as,property,options)}function InstantiateCyclics(context,cyclicKeys){const keys=guard_exports.Keys(context).filter(key=>cyclicKeys.includes(key));return keys.reduce((result,key)=>{return{...result,[key]:InstantiateCyclic(context,key,context[key])}},{})}function InstantiateNonCyclics(context,cyclicKeys){const keys=guard_exports.Keys(context).filter(key=>!cyclicKeys.includes(key));return keys.reduce((result,key)=>{return{...result,[key]:InstantiateType(context,{callstack:[]},context[key])}},{})}function InstantiateModule(context,options){ +const cyclicCandidates=CyclicCandidates(context);const instantiatedCyclics=InstantiateCyclics(context,cyclicCandidates);const instantiatedNonCyclics=InstantiateNonCyclics(context,cyclicCandidates);const instantiatedModule={...instantiatedCyclics,...instantiatedNonCyclics};return memory_exports.Update(instantiatedModule,{},options)}function ModuleInstantiate(context,_state,properties,options){const moduleContext=memory_exports.Assign(context,properties);const instantiatedModule=InstantiateModule( +moduleContext,options);return instantiatedModule}function NonNullableDeferred(type,options={}){return Deferred("NonNullable",[type],options)}function NonNullableOperation(type){const excluded=Union([Null(),Undefined()]);return ExcludeAction(type,excluded,{})}function NonNullableAction(type,options){const result=CanInstantiate([type])?memory_exports.Update(NonNullableOperation(type),{},options):NonNullableDeferred(type,options);return result}function NonNullableInstantiate(context,state2,type,options){const instantiatedType=InstantiateType(context,state2,type);return NonNullableAction(instantiatedType,options)}function OmitDeferred(type,indexer,options={}){return Deferred("Omit",[type,indexer],options)}function ToIndexable(type){const collapsed=CollapseToObject(type);const result=IsObject3(collapsed)?collapsed.properties:Unreachable();return result}function FromKeys(properties,keys){const result=guard_exports.Keys(properties).reduce((result2,key)=>{return keys.includes(key)?result2:{...result2,[key]:properties[key]}},{});return result}function FromType14(type,indexer){const indexable=ToIndexable(type);const indexableKeys=ToIndexableKeys(indexer);const omitted=FromKeys(indexable,indexableKeys);const result=_Object_(omitted);return result}function OmitAction(type,indexer,options){const result=CanInstantiate([type,indexer])?memory_exports.Update(FromType14(type,indexer),{},options):OmitDeferred(type,indexer,options);return result}function OmitInstantiate(context,state2,type,indexer,options){const instantiatedType=InstantiateType(context,state2,type);const instantiatedIndexer=InstantiateType(context,state2,indexer);return OmitAction(instantiatedType,instantiatedIndexer,options)}function OptionsDeferred(type,options){return Deferred("Options",[type,options],{})}function Options(type,options){return OptionsAction(type,options)}function OptionsAction(type,options){const result=CanInstantiate([type])?memory_exports.Update(type,{},options):OptionsDeferred(type,options);return result}function OptionsInstantiate(context,state2,type,options){const instaniatedType=InstantiateType(context,state2,type);return OptionsAction(instaniatedType,options)}function ParametersDeferred(type,options={}){return Deferred("Parameters",[type],options)}function ParametersOperation(type){const parameters=IsFunction3(type)?type["parameters"]:[];const instantiatedParameters=InstantiateElements({},{callstack:[]},parameters);const result=Tuple(instantiatedParameters);return result}function ParametersAction(type,options){const result=CanInstantiate([type])?memory_exports.Update(ParametersOperation(type),{},options):ParametersDeferred(type,options);return result}function ParametersInstantiate(context,state2,type,options){const instantiatedType=InstantiateType( +context,state2,type);return ParametersAction(instantiatedType,options)}function PartialDeferred(type,options={}){return Deferred("Partial",[type],options)}function FromCyclic3(defs,ref){const target=CyclicTarget(defs,ref);const partial=FromType15(target);const result=Cyclic(memory_exports.Assign(defs,{[ref]:partial}),ref);return result}function FromIntersect3(types){const result=types.map(type=>FromType15(type));return EvaluateIntersect(result)}function FromUnion6(types){const result=types.map(type=>FromType15(type));return Union(result)}function FromObject6(properties){const mapped=guard_exports.Keys(properties).reduce((result2,left)=>{return{...result2,[left]:Optional(properties[left])}},{});const result=_Object_(mapped);return result}function FromType15(type){return IsCyclic(type)?FromCyclic3(type.$defs,type.$ref):IsIntersect(type)?FromIntersect3(type.allOf):IsUnion(type)?FromUnion6(type.anyOf):IsObject3(type)?FromObject6(type.properties):_Object_({})}function PartialAction(type,options){const result=CanInstantiate([type])?memory_exports.Update(FromType15(type),{},options):PartialDeferred(type,options);return result}function PartialInstantiate(context,state2,type,options){const instantiatedType=InstantiateType(context,state2,type);return PartialAction(instantiatedType,options)}function PickDeferred(type,indexer,options={}){return Deferred("Pick",[type,indexer],options)}function FromKeys2(properties,keys){const result=guard_exports.Keys(properties).reduce((result2,key)=>{return keys.includes(key)?memory_exports.Assign(result2,{[key]:properties[key]}):result2},{});return result}function FromType16(type,indexer){const indexable=ToIndexable(type);const keys=ToIndexableKeys(indexer);const applied=FromKeys2(indexable,keys);const result=_Object_(applied);return result}function PickAction(type,indexer,options){const result=CanInstantiate([type,indexer])?memory_exports.Update(FromType16(type,indexer),{},options):PickDeferred(type,indexer,options);return result}function PickInstantiate(context,state2,type,indexer,options){const instantiatedType=InstantiateType(context,state2,type);const instantiatedIndexer=InstantiateType(context,state2,indexer);return PickAction(instantiatedType,instantiatedIndexer,options)}function ReadonlyObjectDeferred(type,options={}){return Deferred("ReadonlyObject",[type],options)}function FromArray5(type){const result=Immutable(_Array_(type));return result}function FromCyclic4(defs,ref){const target=CyclicTarget(defs,ref);const partial=FromType17(target);const result=Cyclic(memory_exports.Assign(defs,{[ref]:partial}),ref);return result}function FromIntersect4(types){const result=types.map(type=>FromType17(type));return EvaluateIntersect(result)}function FromObject7(properties){const mapped=guard_exports.Keys(properties).reduce((result2,left)=>{return{...result2,[left]:Readonly(properties[left])}},{});const result=_Object_(mapped);return result}function FromTuple4(types){const result=Immutable(Tuple(types));return result}function FromUnion7(types){const result=types.map(type=>FromType17(type));return Union(result)}function FromType17(type){return IsArray3(type)?FromArray5(type.items):IsCyclic(type)?FromCyclic4(type.$defs,type.$ref):IsIntersect(type)?FromIntersect4(type.allOf):IsObject3(type)?FromObject7(type.properties):IsTuple(type)?FromTuple4(type.items):IsUnion(type)?FromUnion7(type.anyOf):type}function ReadonlyObjectAction(type,options){const result=CanInstantiate([type])?memory_exports.Update(FromType17(type),{},options):ReadonlyObjectDeferred(type);return result}function ReadonlyObjectInstantiate(context,state2,type,options){const instantiatedType=InstantiateType(context,state2,type);return ReadonlyObjectAction(instantiatedType,options)}function RefInstantiate(context,state2,type,ref){return ref in context?CyclicCheck([ref],context,context[ref])?type:InstantiateType(context,state2,context[ref]):type}function FromCyclic5(defs,ref){const target=CyclicTarget(defs,ref);const partial=FromType18(target);const result=Cyclic(memory_exports.Assign(defs,{[ref]:partial}),ref);return result}function FromIntersect5(types){const result=types.map(type=>FromType18(type));return EvaluateIntersect(result)}function FromUnion8(types){const result=types.map(type=>FromType18(type));return Union(result)}function FromObject8(properties){const mapped=guard_exports.Keys(properties).reduce((result2,left)=>{return{...result2,[left]:OptionalRemove(properties[left])}},{});const result=_Object_(mapped);return result}function FromType18(type){return IsCyclic(type)?FromCyclic5(type.$defs,type.$ref):IsIntersect(type)?FromIntersect5(type.allOf):IsUnion(type)?FromUnion8(type.anyOf):IsObject3(type)?FromObject8(type.properties):_Object_({})}function RequiredDeferred(type,options={}){return Deferred("Required",[type],options)}function RequiredAction(type,options){const result=CanInstantiate([type])?memory_exports.Update(FromType18(type),{},options):RequiredDeferred(type,options);return result}function RequiredInstantiate(context,state2,type,options){const instaniatedType=InstantiateType(context,state2,type);return RequiredAction(instaniatedType,options)}function ReturnTypeDeferred(type,options={}){return Deferred("ReturnType",[type],options)}function ReturnTypeOperation(type){return IsFunction3(type)?type["returnType"]:Never()}function ReturnTypeAction(type,options){const result=CanInstantiate([type])?memory_exports.Update(ReturnTypeOperation(type),{},options):ReturnTypeDeferred(type,options);return result}function ReturnTypeInstantiate(context,state2,type,options={}){const instantiatedType=InstantiateType(context,state2,type);return ReturnTypeAction(instantiatedType,options)}function SpreadElement(type){const result=IsRest(type)?IsTuple(type.items)?RestSpread(type.items.items):IsInfer(type.items)?[type]:IsRef(type.items)?[type]:[Never()]:[type];return result}function RestSpread(types){const result=types.reduce((result2,left)=>{return[...result2,...SpreadElement(left)]},[]);return result}function CanInstantiate(types){return guard_exports.TakeLeft(types,(left,right)=>IsRef(left)?false:CanInstantiate(right),()=>true)}function ModifierActions(type,readonly,optional){return IsReadonlyRemoveAction(type)?ModifierActions(type.type,"remove",optional):IsOptionalRemoveAction(type)?ModifierActions(type.type,readonly,"remove"):IsReadonlyAddAction(type)?ModifierActions(type.type,"add",optional):IsOptionalAddAction(type)?ModifierActions(type.type,readonly,"add"):[type,readonly,optional]}function ApplyReadonly(action,type){ +return guard_exports.IsEqual(action,"remove")?ReadonlyRemove(type):guard_exports.IsEqual(action,"add")?ReadonlyAdd(type):type}function ApplyOptional(action,type){return guard_exports.IsEqual(action,"remove")?OptionalRemove(type):guard_exports.IsEqual(action,"add")?OptionalAdd(type):type}function InstantiateProperties(context,state2,properties){return guard_exports.Keys(properties).reduce((result,key)=>{return{...result,[key]:InstantiateType(context,state2,properties[key])}},{})}function InstantiateElements(context,state2,types){ +const elements=InstantiateTypes(context,state2,types);const result=RestSpread(elements);return result}function InstantiateTypes(context,state2,types){return types.map(type=>InstantiateType(context,state2,type))}function InstantiateDeferred(context,state2,action,parameters,options){return guard_exports.IsEqual(action,"Awaited")?AwaitedInstantiate(context,state2,parameters[0],options):guard_exports.IsEqual(action,"Capitalize")?CapitalizeInstantiate(context,state2,parameters[0],options):guard_exports. +IsEqual(action,"Conditional")?ConditionalInstantiate(context,state2,parameters[0],parameters[1],parameters[2],parameters[3],options):guard_exports.IsEqual(action,"ConstructorParameters")?ConstructorParametersInstantiate(context,state2,parameters[0],options):guard_exports.IsEqual(action,"Evaluate")?EvaluateInstantiate(context,state2,parameters[0],options):guard_exports.IsEqual(action,"Exclude")?ExcludeInstantiate(context,state2,parameters[0],parameters[1],options):guard_exports.IsEqual(action,"Ex\ +tract")?ExtractInstantiate(context,state2,parameters[0],parameters[1],options):guard_exports.IsEqual(action,"Index")?IndexInstantiate(context,state2,parameters[0],parameters[1],options):guard_exports.IsEqual(action,"InstanceType")?InstanceTypeInstantiate(context,state2,parameters[0],options):guard_exports.IsEqual(action,"Interface")?InterfaceInstantiate(context,state2,parameters[0],parameters[1],options):guard_exports.IsEqual(action,"KeyOf")?KeyOfInstantiate(context,state2,parameters[0],options): +guard_exports.IsEqual(action,"Lowercase")?LowercaseInstantiate(context,state2,parameters[0],options):guard_exports.IsEqual(action,"Mapped")?MappedInstantiate(context,state2,parameters[0],parameters[1],parameters[2],parameters[3],options):guard_exports.IsEqual(action,"Module")?ModuleInstantiate(context,state2,parameters[0],options):guard_exports.IsEqual(action,"NonNullable")?NonNullableInstantiate(context,state2,parameters[0],options):guard_exports.IsEqual(action,"Pick")?PickInstantiate(context,state2, +parameters[0],parameters[1],options):guard_exports.IsEqual(action,"Options")?OptionsInstantiate(context,state2,parameters[0],parameters[1]):guard_exports.IsEqual(action,"Parameters")?ParametersInstantiate(context,state2,parameters[0],options):guard_exports.IsEqual(action,"Partial")?PartialInstantiate(context,state2,parameters[0],options):guard_exports.IsEqual(action,"Omit")?OmitInstantiate(context,state2,parameters[0],parameters[1],options):guard_exports.IsEqual(action,"ReadonlyObject")?ReadonlyObjectInstantiate( +context,state2,parameters[0],options):guard_exports.IsEqual(action,"Record")?RecordInstantiate(context,state2,parameters[0],parameters[1],options):guard_exports.IsEqual(action,"Required")?RequiredInstantiate(context,state2,parameters[0],options):guard_exports.IsEqual(action,"ReturnType")?ReturnTypeInstantiate(context,state2,parameters[0],options):guard_exports.IsEqual(action,"TemplateLiteral")?TemplateLiteralInstantiate(context,state2,parameters[0],options):guard_exports.IsEqual(action,"Uncapita\ +lize")?UncapitalizeInstantiate(context,state2,parameters[0],options):guard_exports.IsEqual(action,"Uppercase")?UppercaseInstantiate(context,state2,parameters[0],options):Deferred(action,parameters,options)}function InstantiateType(context,state2,input){const immutable=IsImmutable(input);const modifiers=ModifierActions(input,IsReadonly(input)?"add":"none",IsOptional(input)?"add":"none");const type=IsBase(modifiers[0])?modifiers[0].Clone():modifiers[0];const instantiated=IsRef(type)?RefInstantiate( +context,state2,type,type.$ref):IsArray3(type)?_Array_(InstantiateType(context,state2,type.items),ArrayOptions(type)):IsAsyncIterator3(type)?AsyncIterator(InstantiateType(context,state2,type.iteratorItems),AsyncIteratorOptions(type)):IsCall(type)?CallInstantiate(context,state2,type.target,type.arguments):IsConstructor3(type)?Constructor(InstantiateTypes(context,state2,type.parameters),InstantiateType(context,state2,type.instanceType),ConstructorOptions(type)):IsDeferred(type)?InstantiateDeferred( +context,state2,type.action,type.parameters,type.options):IsFunction3(type)?_Function_(InstantiateTypes(context,state2,type.parameters),InstantiateType(context,state2,type.returnType),FunctionOptions(type)):IsIntersect(type)?Intersect(InstantiateTypes(context,state2,type.allOf),IntersectOptions(type)):IsIterator3(type)?Iterator(InstantiateType(context,state2,type.iteratorItems),IteratorOptions(type)):IsObject3(type)?_Object_(InstantiateProperties(context,state2,type.properties),ObjectOptions(type)): +IsPromise(type)?_Promise_(InstantiateType(context,state2,type.item),PromiseOptions(type)):IsRecord(type)?RecordFromPattern(RecordPattern(type),InstantiateType(context,state2,RecordValue(type))):IsRest(type)?Rest(InstantiateType(context,state2,type.items)):IsTuple(type)?Tuple(InstantiateElements(context,state2,type.items),TupleOptions(type)):IsUnion(type)?Union(InstantiateTypes(context,state2,type.anyOf),UnionOptions(type)):type;const withImmutable=immutable?Immutable(instantiated):instantiated;const withModifiers=ApplyReadonly( +modifiers[1],ApplyOptional(modifiers[2],withImmutable));return withModifiers}function Instantiate(context,type){return InstantiateType(context,{callstack:[]},type)}function AwaitedOperation(type){return IsPromise(type)?AwaitedOperation(type.item):type}function AwaitedAction(type,options){const result=CanInstantiate([type])?memory_exports.Update(AwaitedOperation(type),{},options):AwaitedDeferred(type,options);return result}function AwaitedInstantiate(context,state2,type,options){const instantiatedType=InstantiateType(context,state2,type);return AwaitedAction(instantiatedType,options)}function AwaitedDeferred(type,options={}){return Deferred("Awaited",[type],options)}function Evaluate2(type,options={}){return EvaluateAction(type,options)}var EventStream=class{constructor(isComplete,extractResult){__publicField(this,"queue",[]);__publicField(this,"waiting",[]);__publicField(this,"done",false);__publicField(this,"finalResultPromise");__publicField(this,"resolveFinalResult");__publicField(this,"isComplete");__publicField(this,"extractResult");this.isComplete=isComplete;this.extractResult=extractResult;this.finalResultPromise=new Promise(resolve=>{this.resolveFinalResult=resolve})}push(event){if(this.done)return;if(this.isComplete(event)){ +this.done=true;this.resolveFinalResult(this.extractResult(event))}const waiter=this.waiting.shift();if(waiter){waiter({value:event,done:false})}else{this.queue.push(event)}}end(result){this.done=true;if(result!==void 0){this.resolveFinalResult(result)}while(this.waiting.length>0){const waiter=this.waiting.shift();waiter({value:void 0,done:true})}}async*[Symbol.asyncIterator](){while(true){if(this.queue.length>0){yield this.queue.shift()}else if(this.done){return}else{const result=await new Promise( +resolve=>this.waiting.push(resolve));if(result.done)return;yield result.value}}}result(){return this.finalResultPromise}};var AssistantMessageEventStream=class extends EventStream{constructor(){super(event=>event.type==="done"||event.type==="error",event=>{if(event.type==="done"){return event.message}else if(event.type==="error"){return event.error}throw new Error("Unexpected event type for final result")})}};function IsGuardInterface(value){return guard_exports.IsObject(value)&&guard_exports.HasPropertyKey(value,"check")&&guard_exports.HasPropertyKey(value,"errors")&&guard_exports.IsFunction(value.check)&&guard_exports.IsFunction(value.errors)}function IsGuard2(value){return guard_exports.HasPropertyKey(value,"~guard")&&IsGuardInterface(value["~guard"])}function IsRefine2(value){return guard_exports.HasPropertyKey(value,"~refine")&&guard_exports.IsArray(value["~refine"])&&guard_exports.Every(value["~refine"],0,value2=>guard_exports.IsObject(value2)&&guard_exports.HasPropertyKey(value2,"check")&&guard_exports.HasPropertyKey(value2,"error")&&guard_exports.IsFunction(value2.check)&&guard_exports.IsFunction(value2.error))}function IsSchemaObject(value){return guard_exports.IsObject(value)&&!guard_exports.IsArray(value)}function IsBooleanSchema(value){return guard_exports.IsBoolean(value)}function IsSchema2(value){return IsSchemaObject(value)||IsBooleanSchema(value)}function IsAdditionalItems(schema){return guard_exports.HasPropertyKey(schema,"additionalItems")&&IsSchema2(schema.additionalItems)}function IsAdditionalProperties(schema){return guard_exports.HasPropertyKey(schema,"additionalProperties")&&IsSchema2(schema.additionalProperties)}function IsAllOf(schema){return guard_exports.HasPropertyKey(schema,"allOf")&&guard_exports.IsArray(schema.allOf)&&schema.allOf.every(value=>IsSchema2(value))}function IsAnchor(schema){return guard_exports.HasPropertyKey(schema,"$anchor")&&guard_exports.IsString(schema.$anchor)}function IsAnyOf(schema){return guard_exports.HasPropertyKey(schema,"anyOf")&&guard_exports.IsArray(schema.anyOf)&&schema.anyOf.every(value=>IsSchema2(value))}function IsConst(value){return guard_exports.HasPropertyKey(value,"const")}function IsContains(schema){return guard_exports.HasPropertyKey(schema,"contains")&&IsSchema2(schema.contains)}function IsDefault(schema){return guard_exports.HasPropertyKey(schema,"default")}function IsDependencies(schema){return guard_exports.HasPropertyKey(schema,"dependencies")&&guard_exports.IsObject(schema.dependencies)&&Object.values(schema.dependencies).every(value=>IsSchema2(value)||guard_exports.IsArray(value)&&value.every(value2=>guard_exports.IsString(value2)))}function IsDependentRequired(schema){return guard_exports.HasPropertyKey(schema,"dependentRequired")&&guard_exports.IsObject(schema.dependentRequired)&&Object.values(schema.dependentRequired).every(value=>guard_exports.IsArray(value)&&value.every(value2=>guard_exports.IsString(value2)))}function IsDependentSchemas(schema){return guard_exports.HasPropertyKey(schema,"dependentSchemas")&&guard_exports.IsObject(schema.dependentSchemas)&&Object.values(schema.dependentSchemas).every(value=>IsSchema2(value))}function IsDynamicAnchor(schema){return guard_exports.HasPropertyKey(schema,"$dynamicAnchor")&&guard_exports.IsString(schema.$dynamicAnchor)}function IsDynamicRef(schema){return guard_exports.HasPropertyKey(schema,"$dynamicRef")&&guard_exports.IsString(schema.$dynamicRef)}function IsElse(schema){return guard_exports.HasPropertyKey(schema,"else")&&IsSchema2(schema.else)}function IsEnum2(schema){return guard_exports.HasPropertyKey(schema,"enum")&&guard_exports.IsArray(schema.enum)}function IsExclusiveMaximum(schema){return guard_exports.HasPropertyKey(schema,"exclusiveMaximum")&&(guard_exports.IsNumber(schema.exclusiveMaximum)||guard_exports.IsBigInt(schema.exclusiveMaximum))}function IsExclusiveMinimum(schema){return guard_exports.HasPropertyKey(schema,"exclusiveMinimum")&&(guard_exports.IsNumber(schema.exclusiveMinimum)||guard_exports.IsBigInt(schema.exclusiveMinimum))}function IsFormat(schema){return guard_exports.HasPropertyKey(schema,"format")&&guard_exports.IsString(schema.format)}function IsId(schema){return guard_exports.HasPropertyKey(schema,"$id")&&guard_exports.IsString(schema.$id)}function IsIf(schema){return guard_exports.HasPropertyKey(schema,"if")&&IsSchema2(schema.if)}function IsItems(schema){return guard_exports.HasPropertyKey(schema,"items")&&(IsSchema2(schema.items)||guard_exports.IsArray(schema.items)&&schema.items.every(value=>{return IsSchema2(value)}))}function IsItemsSized(schema){return IsItems(schema)&&guard_exports.IsArray(schema.items)}function IsMaximum(schema){return guard_exports.HasPropertyKey(schema,"maximum")&&(guard_exports.IsNumber(schema.maximum)||guard_exports.IsBigInt(schema.maximum))}function IsMaxContains(schema){return guard_exports.HasPropertyKey(schema,"maxContains")&&guard_exports.IsNumber(schema.maxContains)}function IsMaxItems(schema){return guard_exports.HasPropertyKey(schema,"maxItems")&&guard_exports.IsNumber(schema.maxItems)}function IsMaxLength4(schema){return guard_exports.HasPropertyKey(schema,"maxLength")&&guard_exports.IsNumber(schema.maxLength)}function IsMaxProperties(schema){return guard_exports.HasPropertyKey(schema,"maxProperties")&&guard_exports.IsNumber(schema.maxProperties)}function IsMinimum(schema){return guard_exports.HasPropertyKey(schema,"minimum")&&(guard_exports.IsNumber(schema.minimum)||guard_exports.IsBigInt(schema.minimum))}function IsMinContains(schema){return guard_exports.HasPropertyKey(schema,"minContains")&&guard_exports.IsNumber(schema.minContains)}function IsMinItems(schema){return guard_exports.HasPropertyKey(schema,"minItems")&&guard_exports.IsNumber(schema.minItems)}function IsMinLength4(schema){return guard_exports.HasPropertyKey(schema,"minLength")&&guard_exports.IsNumber(schema.minLength)}function IsMinProperties(schema){return guard_exports.HasPropertyKey(schema,"minProperties")&&guard_exports.IsNumber(schema.minProperties)}function IsMultipleOf2(schema){return guard_exports.HasPropertyKey(schema,"multipleOf")&&(guard_exports.IsNumber(schema.multipleOf)||guard_exports.IsBigInt(schema.multipleOf))}function IsNot(schema){return guard_exports.HasPropertyKey(schema,"not")&&IsSchema2(schema.not)}function IsOneOf(schema){return guard_exports.HasPropertyKey(schema,"oneOf")&&guard_exports.IsArray(schema.oneOf)&&schema.oneOf.every(value=>IsSchema2(value))}function IsPattern(schema){return guard_exports.HasPropertyKey(schema,"pattern")&&(guard_exports.IsString(schema.pattern)||schema.pattern instanceof RegExp)}function IsPatternProperties(schema){return guard_exports.HasPropertyKey(schema,"patternProperties")&&guard_exports.IsObject(schema.patternProperties)&&Object.values(schema.patternProperties).every(value=>IsSchema2(value))}function IsPrefixItems(schema){return guard_exports.HasPropertyKey(schema,"prefixItems")&&guard_exports.IsArray(schema.prefixItems)&&schema.prefixItems.every(schema2=>IsSchema2(schema2))}function IsProperties(schema){return guard_exports.HasPropertyKey(schema,"properties")&&guard_exports.IsObject(schema.properties)&&Object.values(schema.properties).every(value=>IsSchema2(value))}function IsPropertyNames(schema){return guard_exports.HasPropertyKey(schema,"propertyNames")&&(guard_exports.IsObject(schema.propertyNames)||IsSchema2(schema.propertyNames))}function IsRecursiveAnchor(schema){return guard_exports.HasPropertyKey(schema,"$recursiveAnchor")&&guard_exports.IsBoolean(schema.$recursiveAnchor)}function IsRecursiveAnchorTrue(schema){return IsRecursiveAnchor(schema)&&guard_exports.IsEqual(schema.$recursiveAnchor,true)}function IsRecursiveRef(schema){return guard_exports.HasPropertyKey(schema,"$recursiveRef")&&guard_exports.IsString(schema.$recursiveRef)}function IsRef2(schema){return guard_exports.HasPropertyKey(schema,"$ref")&&guard_exports.IsString(schema.$ref)}function IsRequired(schema){return guard_exports.HasPropertyKey(schema,"required")&&guard_exports.IsArray(schema.required)&&schema.required.every(value=>guard_exports.IsString(value))}function IsThen(schema){return guard_exports.HasPropertyKey(schema,"then")&&IsSchema2(schema.then)}function IsType(schema){return guard_exports.HasPropertyKey(schema,"type")&&(guard_exports.IsString(schema.type)||guard_exports.IsArray(schema.type)&&schema.type.every(value=>guard_exports.IsString(value)))}function IsUniqueItems(schema){return guard_exports.HasPropertyKey(schema,"uniqueItems")&&guard_exports.IsBoolean(schema.uniqueItems)}function IsUnevaluatedItems(schema){return guard_exports.HasPropertyKey(schema,"unevaluatedItems")&&IsSchema2(schema.unevaluatedItems)}function IsUnevaluatedProperties(schema){return guard_exports.HasPropertyKey(schema,"unevaluatedProperties")&&IsSchema2(schema.unevaluatedProperties)}function HasUnevaluatedFromObject(value){return IsUnevaluatedItems(value)||IsUnevaluatedProperties(value)||guard_exports.Keys(value).some(key=>HasUnevaluatedFromUnknown(value[key]))}function HasUnevaluatedFromArray(value){return value.some(value2=>HasUnevaluatedFromUnknown(value2))}function HasUnevaluatedFromUnknown(value){return guard_exports.IsArray(value)?HasUnevaluatedFromArray(value):guard_exports.IsObject(value)?HasUnevaluatedFromObject(value):false}function HasUnevaluated(context,schema){ +return HasUnevaluatedFromUnknown(schema)||guard_exports.Keys(context).some(key=>HasUnevaluatedFromUnknown(context[key]))}var BuildContext=class{constructor(hasUnevaluated){this.hasUnevaluated=hasUnevaluated}UseUnevaluated(){return this.hasUnevaluated}Push(){return emit_exports.Call(emit_exports.Member("context","Push"),[])}Pop(){return emit_exports.Call(emit_exports.Member("context","Pop"),[])}AddIndex(index2){return emit_exports.Call(emit_exports.Member("context","AddIndex"),[index2])}AddKey(key){ +return emit_exports.Call(emit_exports.Member("context","AddKey"),[key])}Merge(results){return emit_exports.Call(emit_exports.Member("context","Merge"),[results])}};var CheckContext=class{constructor(){const indices=new Set;const keys=new Set;this.stack=[{indices,keys}]}Push(){const indices=new Set;const keys=new Set;this.stack.push({indices,keys});return true}Pop(){this.stack.pop();return true}AddIndex(index2){this.GetIndices().add(index2);return true}AddKey(key){this.GetKeys().add(key);return true}GetIndices(){ +const top=this.stack[this.stack.length-1];return top.indices}GetKeys(){const top=this.stack[this.stack.length-1];return top.keys}Merge(results){for(const context of results){context.GetIndices().forEach(value=>this.GetIndices().add(value));context.GetKeys().forEach(value=>this.GetKeys().add(value))}return true}};var ErrorContext=class extends CheckContext{constructor(callback){super();this.callback=callback}AddError(error){this.callback(error);return false}};var AccumulatedErrorContext=class extends ErrorContext{constructor(){ +super(error=>this.errors.push(error));this.errors=[]}AddError(error){this.errors.push(error);return false}GetErrors(){return this.errors}};var state={identifier:"External",variables:[]};function CreateVariable(value){const call=`External[${state.variables.length}]`;state.variables.push(value);return call}function ResetExternal(){state.variables=[]}function GetExternal(){return{...state}}function BuildGuard(_stack,_context,schema,value){return emit_exports.Call(emit_exports.Member(emit_exports.Member(CreateVariable(schema),"~guard"),"check"),[value])}function CheckGuard(_stack,_context,schema,value){return schema["~guard"].check(value)}function ErrorGuard(_stack,context,schemaPath,instancePath,schema,value){return schema["~guard"].check(value)||context.AddError({keyword:"~guard",schemaPath,instancePath,params:{errors:schema["~guard"].errors(value)}})}function BuildRefine(_stack,_context,schema,value){const refinements=CreateVariable(schema["~refine"].map(refinement=>refinement));return emit_exports.Every(refinements,emit_exports.Constant(0),["refinement","_"],emit_exports.Call(emit_exports.Member("refinement","check"),[value]))}function CheckRefine(_stack,_context,schema,value){return guard_exports.Every(schema["~refine"],0,(refinement,_)=>refinement.check(value))}function ErrorRefine(_stack,context,schemaPath,instancePath,schema,value){return guard_exports. +EveryAll(schema["~refine"],0,(refinement,index2)=>{return refinement.check(value)||context.AddError({keyword:"~refine",schemaPath,instancePath,params:{index:index2,message:refinement.error(value)}})})}var index=0;function Unique(){return`var_${index++}`}function IsValid(schema){return IsItems(schema)&&guard_exports.IsArray(schema.items)}function BuildAdditionalItems(stack,context,schema,value){if(!IsValid(schema))return emit_exports.Constant(true);const[item,index2]=[Unique(),Unique()];const isSchema=BuildSchemaPushStack(stack,context,schema.additionalItems,item);const isLength=emit_exports.IsLessThan(index2,emit_exports.Constant(schema.items.length));const addIndex=context.AddIndex(index2);const guarded=context.UseUnevaluated()?emit_exports.Or( +isLength,emit_exports.And(isSchema,addIndex)):emit_exports.Or(isLength,isSchema);return emit_exports.Call(emit_exports.Member(value,"every"),[emit_exports.ArrowFunction([item,index2],guarded)])}function CheckAdditionalItems(stack,context,schema,value){if(!IsValid(schema))return true;const isAdditionalItems=value.every((item,index2)=>{return guard_exports.IsLessThan(index2,schema.items.length)||CheckSchemaPushStack(stack,context,schema.additionalItems,item)&&context.AddIndex(index2)});return isAdditionalItems} +function ErrorAdditionalItems(stack,context,schemaPath,instancePath,schema,value){if(!IsValid(schema))return true;const isAdditionalItems=value.every((item,index2)=>{const nextSchemaPath=`${schemaPath}/additionalItems`;const nextInstancePath=`${instancePath}/${index2}`;return guard_exports.IsLessThan(index2,schema.items.length)||ErrorSchemaPushStack(stack,context,nextSchemaPath,nextInstancePath,schema.additionalItems,item)&&context.AddIndex(index2)});return isAdditionalItems}function GetPropertyKeyAsPattern(key){const escaped=key.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return`^${escaped}$`}function GetPropertiesPattern(schema){const patterns=[];if(IsPatternProperties(schema))patterns.push(...guard_exports.Keys(schema.patternProperties));if(IsProperties(schema))patterns.push(...guard_exports.Keys(schema.properties).map(GetPropertyKeyAsPattern));return guard_exports.IsEqual(patterns.length,0)?"(?!)":`(${patterns.join("|")})`}function CanAdditionalPropertiesFast(_context,schema,_value){ +return IsRequired(schema)&&IsProperties(schema)&&!IsPatternProperties(schema)&&guard_exports.IsEqual(schema.additionalProperties,false)&&guard_exports.IsEqual(guard_exports.Keys(schema.properties).length,schema.required.length)}function BuildAdditionalPropertiesFast(_context,schema,value){return emit_exports.IsEqual(emit_exports.Member(emit_exports.Call(emit_exports.Member("Object","getOwnPropertyNames"),[value]),"length"),emit_exports.Constant(schema.required.length))}function BuildAdditionalPropertiesStandard(stack,context,schema,value){ +const[key,_index]=[Unique(),Unique()];const regexp=CreateVariable(new RegExp(GetPropertiesPattern(schema)));const isSchema=BuildSchemaPushStack(stack,context,schema.additionalProperties,`${value}[${key}]`);const isKey=emit_exports.Call(emit_exports.Member(regexp,"test"),[key]);const addKey=context.AddKey(key);const guarded=context.UseUnevaluated()?emit_exports.Or(isKey,emit_exports.And(isSchema,addKey)):emit_exports.Or(isKey,isSchema);const result=emit_exports.Every(emit_exports.Keys(value),emit_exports. +Constant(0),[key,_index],guarded);return result}function BuildAdditionalProperties(stack,context,schema,value){return CanAdditionalPropertiesFast(context,schema,value)?BuildAdditionalPropertiesFast(context,schema,value):BuildAdditionalPropertiesStandard(stack,context,schema,value)}function CheckAdditionalProperties(stack,context,schema,value){const regexp=new RegExp(GetPropertiesPattern(schema));const isAdditionalProperties=guard_exports.Every(guard_exports.Keys(value),0,(key,_index)=>{return regexp. +test(key)||CheckSchemaPushStack(stack,context,schema.additionalProperties,value[key])&&context.AddKey(key)});return isAdditionalProperties}function ErrorAdditionalProperties(stack,context,schemaPath,instancePath,schema,value){const regexp=new RegExp(GetPropertiesPattern(schema));const additionalProperties=[];const isAdditionalProperties=guard_exports.EveryAll(guard_exports.Keys(value),0,(key,_index)=>{const nextSchemaPath=`${schemaPath}/additionalProperties`;const nextInstancePath=`${instancePath}\ +/${key}`;const nextContext=new AccumulatedErrorContext;const isAdditionalProperty=regexp.test(key)||ErrorSchemaPushStack(stack,nextContext,nextSchemaPath,nextInstancePath,schema.additionalProperties,value[key])&&context.AddKey(key);if(!isAdditionalProperty)additionalProperties.push(key);return isAdditionalProperty});return isAdditionalProperties||context.AddError({keyword:"additionalProperties",schemaPath,instancePath,params:{additionalProperties}})}function Reducer(stack,context,schemas,value,check){const results=emit_exports.ConstDeclaration("results","[]");const context_n=schemas.map((_schema,index2)=>emit_exports.ConstDeclaration(`context_${index2}`,emit_exports.New("CheckContext",[])));const condition_n=schemas.map((schema,index2)=>emit_exports.ConstDeclaration(`condition_${index2}`,emit_exports.Call(emit_exports.ArrowFunction(["context"],BuildSchema(stack,context,schema,value)),[`context_${index2}`])));const checks=schemas.map((_schema,index2)=>emit_exports. +If(`condition_${index2}`,emit_exports.Call(emit_exports.Member("results","push"),[`context_${index2}`])));const returns=emit_exports.Return(emit_exports.And(check,context.Merge("results")));return emit_exports.Call(emit_exports.ArrowFunction([],emit_exports.Statements([results,...context_n,...condition_n,...checks,returns])),[])}function BuildAllOfStandard(stack,context,schema,value){return Reducer(stack,context,schema.allOf,value,emit_exports.IsEqual(emit_exports.Member("results","length"),emit_exports.Constant(schema.allOf.length)))}function BuildAllOfFast(stack,context,schema,value){return emit_exports.ReduceAnd(schema.allOf.map(schema2=>BuildSchema(stack,context,schema2,value)))}function BuildAllOf(stack,context,schema,value){return context.UseUnevaluated()?BuildAllOfStandard(stack,context,schema,value):BuildAllOfFast( +stack,context,schema,value)}function CheckAllOf(stack,context,schema,value){const results=schema.allOf.reduce((result,schema2)=>{const nextContext=new CheckContext;return CheckSchema(stack,nextContext,schema2,value)?[...result,nextContext]:result},[]);return guard_exports.IsEqual(results.length,schema.allOf.length)&&context.Merge(results)}function ErrorAllOf(stack,context,schemaPath,instancePath,schema,value){const failedContexts=[];const results=schema.allOf.reduce((result,schema2,index2)=>{const nextSchemaPath=`${schemaPath}\ +/allOf/${index2}`;const nextContext=new AccumulatedErrorContext;const isSchema=ErrorSchema(stack,nextContext,nextSchemaPath,instancePath,schema2,value);if(!isSchema)failedContexts.push(nextContext);return isSchema?[...result,nextContext]:result},[]);const isAllOf=guard_exports.IsEqual(results.length,schema.allOf.length)&&context.Merge(results);if(!isAllOf)failedContexts.forEach(failed=>failed.GetErrors().forEach(error=>context.AddError(error)));return isAllOf}function BuildAnyOfStandard(stack,context,schema,value){return Reducer(stack,context,schema.anyOf,value,emit_exports.IsGreaterThan(emit_exports.Member("results","length"),emit_exports.Constant(0)))}function BuildAnyOfFast(stack,context,schema,value){return emit_exports.ReduceOr(schema.anyOf.map(schema2=>BuildSchema(stack,context,schema2,value)))}function BuildAnyOf(stack,context,schema,value){return context.UseUnevaluated()?BuildAnyOfStandard(stack,context,schema,value):BuildAnyOfFast(stack,context, +schema,value)}function CheckAnyOf(stack,context,schema,value){const results=schema.anyOf.reduce((result,schema2)=>{const nextContext=new CheckContext;return CheckSchema(stack,nextContext,schema2,value)?[...result,nextContext]:result},[]);return guard_exports.IsGreaterThan(results.length,0)&&context.Merge(results)}function ErrorAnyOf(stack,context,schemaPath,instancePath,schema,value){const failedContexts=[];const results=schema.anyOf.reduce((result,schema2,index2)=>{const nextContext=new AccumulatedErrorContext; +const nextSchemaPath=`${schemaPath}/anyOf/${index2}`;const isSchema=ErrorSchema(stack,nextContext,nextSchemaPath,instancePath,schema2,value);if(!isSchema)failedContexts.push(nextContext);return isSchema?[...result,nextContext]:result},[]);const isAnyOf=guard_exports.IsGreaterThan(results.length,0)&&context.Merge(results);if(!isAnyOf)failedContexts.forEach(failed=>failed.GetErrors().forEach(error=>context.AddError(error)));return isAnyOf||context.AddError({keyword:"anyOf",schemaPath,instancePath, +params:{}})}function BuildBooleanSchema(_stack,_context,schema,_value){return schema?emit_exports.Constant(true):emit_exports.Constant(false)}function CheckBooleanSchema(_stack,_context,schema,_value){return schema}function ErrorBooleanSchema(stack,context,schemaPath,instancePath,schema,value){return CheckBooleanSchema(stack,context,schema,value)||context.AddError({keyword:"boolean",schemaPath,instancePath,params:{}})}function BuildConst(_stack,_context,schema,value){return guard_exports.IsValueLike(schema.const)?emit_exports.IsEqual(value,emit_exports.Constant(schema.const)):emit_exports.IsDeepEqual(value,CreateVariable(schema.const))}function CheckConst(_stack,_context,schema,value){return guard_exports.IsValueLike(schema.const)?guard_exports.IsEqual(value,schema.const):guard_exports.IsDeepEqual(value,schema.const)}function ErrorConst(stack,context,schemaPath,instancePath,schema,value){return CheckConst(stack, +context,schema,value)||context.AddError({keyword:"const",schemaPath,instancePath,params:{allowedValue:schema.const}})}function IsValid2(schema){return!(IsMinContains(schema)&&guard_exports.IsEqual(schema.minContains,0))}function BuildContains(stack,context,schema,value){if(!IsValid2(schema))return emit_exports.Constant(true);const item=Unique();const isLength=emit_exports.Not(emit_exports.IsEqual(emit_exports.Member(value,"length"),emit_exports.Constant(0)));const isSome=emit_exports.Call(emit_exports.Member(value,"some"),[emit_exports.ArrowFunction([item],BuildSchema(stack,context,schema.contains,item))]);return emit_exports. +And(isLength,isSome)}function CheckContains(stack,context,schema,value){if(!IsValid2(schema))return true;return!guard_exports.IsEqual(value.length,0)&&value.some(item=>CheckSchema(stack,context,schema.contains,item))}function ErrorContains(stack,context,schemaPath,instancePath,schema,value){return CheckContains(stack,context,schema,value)||context.AddError({keyword:"contains",schemaPath,instancePath,params:{minContains:1}})}function BuildDependencies(stack,context,schema,value){const isLength=emit_exports.IsEqual(emit_exports.Member(emit_exports.Keys(value),"length"),emit_exports.Constant(0));const isEveryDependency=emit_exports.ReduceAnd(guard_exports.Entries(schema.dependencies).map(([key,schema2])=>{const notKey=emit_exports.Not(emit_exports.HasPropertyKey(value,emit_exports.Constant(key)));const isSchema=BuildSchema(stack,context,schema2,value);const isEveryKey=schema3=>emit_exports.ReduceAnd(schema3.map(key2=>emit_exports. +HasPropertyKey(value,emit_exports.Constant(key2))));return emit_exports.Or(notKey,guard_exports.IsArray(schema2)?isEveryKey(schema2):isSchema)}));return emit_exports.Or(isLength,isEveryDependency)}function CheckDependencies(stack,context,schema,value){const isLength=guard_exports.IsEqual(guard_exports.Keys(value).length,0);const isEvery=guard_exports.Every(guard_exports.Entries(schema.dependencies),0,([key,schema2])=>{return!guard_exports.HasPropertyKey(value,key)||(guard_exports.IsArray(schema2)? +schema2.every(key2=>guard_exports.HasPropertyKey(value,key2)):CheckSchema(stack,context,schema2,value))});return isLength||isEvery}function ErrorDependencies(stack,context,schemaPath,instancePath,schema,value){const isLength=guard_exports.IsEqual(guard_exports.Keys(value).length,0);const isEvery=guard_exports.EveryAll(guard_exports.Entries(schema.dependencies),0,([key,schema2])=>{const nextSchemaPath=`${schemaPath}/dependencies/${key}`;return!guard_exports.HasPropertyKey(value,key)||(guard_exports. +IsArray(schema2)?schema2.every(dependency=>guard_exports.HasPropertyKey(value,dependency)||context.AddError({keyword:"dependencies",schemaPath,instancePath,params:{property:key,dependencies:schema2}})):ErrorSchema(stack,context,nextSchemaPath,instancePath,schema2,value))});return isLength||isEvery}function BuildDependentRequired(_stack,_context,schema,value){const isLength=emit_exports.IsEqual(emit_exports.Member(emit_exports.Keys(value),"length"),emit_exports.Constant(0));const isEvery=emit_exports.ReduceAnd(guard_exports.Entries(schema.dependentRequired).map(([key,keys])=>{const notKey=emit_exports.Not(emit_exports.HasPropertyKey(value,emit_exports.Constant(key)));const everyKey=emit_exports.ReduceAnd(keys.map(key2=>emit_exports.HasPropertyKey(value,emit_exports.Constant(key2))));return emit_exports. +Or(notKey,everyKey)}));return emit_exports.Or(isLength,isEvery)}function CheckDependentRequired(_stack,_context,schema,value){const isLength=guard_exports.IsEqual(guard_exports.Keys(value).length,0);const isEvery=guard_exports.Every(guard_exports.Entries(schema.dependentRequired),0,([key,keys])=>{return!guard_exports.HasPropertyKey(value,key)||keys.every(key2=>guard_exports.HasPropertyKey(value,key2))});return isLength||isEvery}function ErrorDependentRequired(_stack,context,schemaPath,instancePath,schema,value){ +const isLength=guard_exports.IsEqual(guard_exports.Keys(value).length,0);const isEveryEntry=guard_exports.EveryAll(guard_exports.Entries(schema.dependentRequired),0,([key,keys])=>{return!guard_exports.HasPropertyKey(value,key)||guard_exports.EveryAll(keys,0,dependency=>guard_exports.HasPropertyKey(value,dependency)||context.AddError({keyword:"dependentRequired",schemaPath,instancePath,params:{property:key,dependencies:keys}}))});return isLength||isEveryEntry}function BuildDependentSchemas(stack,context,schema,value){const isLength=emit_exports.IsEqual(emit_exports.Member(emit_exports.Keys(value),"length"),emit_exports.Constant(0));const isEvery=emit_exports.ReduceAnd(guard_exports.Entries(schema.dependentSchemas).map(([key,schema2])=>{const notKey=emit_exports.Not(emit_exports.HasPropertyKey(value,emit_exports.Constant(key)));const isSchema=BuildSchema(stack,context,schema2,value);return emit_exports.Or(notKey,isSchema)}));return emit_exports.Or(isLength, +isEvery)}function CheckDependentSchemas(stack,context,schema,value){const isLength=guard_exports.IsEqual(guard_exports.Keys(value).length,0);const isEvery=guard_exports.Every(guard_exports.Entries(schema.dependentSchemas),0,([key,schema2])=>{return!guard_exports.HasPropertyKey(value,key)||CheckSchema(stack,context,schema2,value)});return isLength||isEvery}function ErrorDependentSchemas(stack,context,schemaPath,instancePath,schema,value){const isLength=guard_exports.IsEqual(guard_exports.Keys(value). +length,0);const isEvery=guard_exports.EveryAll(guard_exports.Entries(schema.dependentSchemas),0,([key,schema2])=>{const nextSchemaPath=`${schemaPath}/dependentSchemas/${key}`;return!guard_exports.HasPropertyKey(value,key)||ErrorSchema(stack,context,nextSchemaPath,instancePath,schema2,value)});return isLength||isEvery}function BuildDynamicRef(stack,context,schema,value){const target=stack.DynamicRef(schema)??false;return CreateFunction(stack,context,target,value)}function CheckDynamicRef(stack,context,schema,value){const target=stack.DynamicRef(schema)??false;return IsSchema2(target)&&CheckSchema(stack,context,target,value)}function ErrorDynamicRef(stack,context,_schemaPath,instancePath,schema,value){const target=stack.DynamicRef(schema)??false;return IsSchema2(target)&&ErrorSchema(stack,context,"#",instancePath, +target,value)}function BuildEnum(_stack,_context,schema,value){return emit_exports.ReduceOr(schema.enum.map(option=>{if(guard_exports.IsValueLike(option))return emit_exports.IsEqual(value,emit_exports.Constant(option));const variable=CreateVariable(option);return emit_exports.IsDeepEqual(value,variable)}))}function CheckEnum(_stack,_context,schema,value){return schema.enum.some(option=>guard_exports.IsValueLike(option)?guard_exports.IsEqual(value,option):guard_exports.IsDeepEqual(value,option))}function ErrorEnum(stack,context,schemaPath,instancePath,schema,value){ +return CheckEnum(stack,context,schema,value)||context.AddError({keyword:"enum",schemaPath,instancePath,params:{allowedValues:schema.enum}})}function BuildExclusiveMaximum(_stack,_context,schema,value){return emit_exports.IsLessThan(value,emit_exports.Constant(schema.exclusiveMaximum))}function CheckExclusiveMaximum(_stack,_context,schema,value){return guard_exports.IsLessThan(value,schema.exclusiveMaximum)}function ErrorExclusiveMaximum(stack,context,schemaPath,instancePath,schema,value){return CheckExclusiveMaximum(stack,context,schema,value)||context.AddError({keyword:"exclusiveMaximum",schemaPath,instancePath,params:{comparison:"\ +<",limit:schema.exclusiveMaximum}})}function BuildExclusiveMinimum(_stack,_context,schema,value){return emit_exports.IsGreaterThan(value,emit_exports.Constant(schema.exclusiveMinimum))}function CheckExclusiveMinimum(_stack,_context,schema,value){return guard_exports.IsGreaterThan(value,schema.exclusiveMinimum)}function ErrorExclusiveMinimum(stack,context,schemaPath,instancePath,schema,value){return CheckExclusiveMinimum(stack,context,schema,value)||context.AddError({keyword:"exclusiveMinimum",schemaPath,instancePath,params:{comparison:"\ +>",limit:schema.exclusiveMinimum}})}var format_exports={};__export(format_exports,{Clear:()=>Clear,Entries:()=>Entries3,Get:()=>Get3,Has:()=>Has,IsDate:()=>IsDate2,IsDateTime:()=>IsDateTime,IsDuration:()=>IsDuration,IsEmail:()=>IsEmail,IsHostname:()=>IsHostname,IsIPv4:()=>IsIPv4,IsIPv6:()=>IsIPv6,IsIdnEmail:()=>IsIdnEmail,IsIdnHostname:()=>IsIdnHostname,IsIri:()=>IsIri,IsIriReference:()=>IsIriReference,IsJsonPointer:()=>IsJsonPointer,IsJsonPointerUriFragment:()=>IsJsonPointerUriFragment,IsRegex:()=>IsRegex,IsRelativeJsonPointer:()=>IsRelativeJsonPointer, +IsTime:()=>IsTime,IsUri:()=>IsUri,IsUriReference:()=>IsUriReference,IsUriTemplate:()=>IsUriTemplate,IsUrl:()=>IsUrl,IsUuid:()=>IsUuid,Reset:()=>Reset2,Set:()=>Set3,Test:()=>Test});var DAYS=[0,31,28,31,30,31,30,31,31,30,31,30,31];var DATE=/^(\d\d\d\d)-(\d\d)-(\d\d)$/;function IsLeapYear(year){return year%4===0&&(year%100!==0||year%400===0)}function IsDate2(value){const matches=DATE.exec(value);if(!matches)return false;const year=+matches[1];const month=+matches[2];const day=+matches[3];return month>=1&&month<=12&&day>=1&&day<=(month===2&&IsLeapYear(year)?29:DAYS[month])}var TIME=/^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(?:Z|([+-])(\d\d):(\d\d))?$/i;function IsTime(value,strictTimeZone=true){const matches=TIME.exec(value);if(!matches)return false;const hr=+matches[1];const min=+matches[2];const sec=+matches[3];const tzSign=matches[4]==="-"?-1:1;const tzH=+(matches[5]||0);const tzM=+(matches[6]||0);if(tzH>23||tzM>59)return false;if(strictTimeZone&&!matches[4]&&value.toLowerCase().indexOf("z")===-1){return false}if(hr<=23&&min<=59&&sec<60)return true;const utcMin=min-tzM*tzSign; +const utcHr=hr-tzH*tzSign-(utcMin<0?1:0);return(utcHr===23||utcHr===-1)&&(utcMin===59||utcMin===-1)&&sec<61}function IsDateTime(value,strictTimeZone=true){const dateTime=value.split(/T/i);return dateTime.length===2&&IsDate2(dateTime[0])&&IsTime(dateTime[1],strictTimeZone)}var Duration=/^P((\d+Y(\d+M(\d+D)?)?|\d+M(\d+D)?|\d+D)(T(\d+H(\d+M(\d+S)?)?|\d+M(\d+S)?|\d+S))?|T(\d+H(\d+M(\d+S)?)?|\d+M(\d+S)?|\d+S)|\d+W)$/;function IsDuration(value){return Duration.test(value)}var Email=/^(?!.*\.\.)[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i;function IsEmail(value){return Email.test(value)}var PUNYCODE_BASE=36;var PUNYCODE_TMIN=1;var PUNYCODE_TMAX=26;var PUNYCODE_SKEW=38;var PUNYCODE_DAMP=700;var PUNYCODE_INITIAL_BIAS=72;var PUNYCODE_INITIAL_N=128;function Adapt(delta,numPoints,firstTime){delta=firstTime?Math.floor(delta/PUNYCODE_DAMP):delta>>1;delta+=Math.floor(delta/numPoints);let k=0;while(delta>(PUNYCODE_BASE-PUNYCODE_TMIN)*PUNYCODE_TMAX>>1){delta=Math.floor(delta/(PUNYCODE_BASE-PUNYCODE_TMIN));k+=PUNYCODE_BASE}return k+Math.floor((PUNYCODE_BASE-PUNYCODE_TMIN+1)*delta/(delta+PUNYCODE_SKEW))} +function Decode(value){const output=[];let n=PUNYCODE_INITIAL_N;let i=0;let bias=PUNYCODE_INITIAL_BIAS;const delimIdx=value.lastIndexOf("-");if(delimIdx>0){for(let j=0;j=128)throw new Error("Invalid punycode: non-basic before delimiter");output.push(cp)}}let inIdx=delimIdx<0?0:delimIdx+1;while(inIdx=value.length)throw new Error("Invalid punycode: unexpected end of input"); +const ch=value.charCodeAt(inIdx++);let digit;if(ch>=97&&ch<=122)digit=ch-97;else if(ch>=48&&ch<=57)digit=ch-48+26;else if(ch>=65&&ch<=90)digit=ch-65;else throw new Error("Invalid punycode: bad digit character");i+=digit*w;const t=k<=bias?PUNYCODE_TMIN:k>=bias+PUNYCODE_TMAX?PUNYCODE_TMAX:k-bias;if(digit=1632&&cp<=1641}function IsExtendedArabicIndicDigit(cp){return cp>=1776&&cp<=1785}function IsVirama(cp){return VIRAMA_CPS.has(cp)}function IsUnicodeLabel(value){if(value.length===0)return false;const cps=[...value].map(c=>c.codePointAt(0));const len=cps.length;if(cps[0]===45||cps[len-1]===45)return false;if(len>=4&&cps[2]===45&&cps[3]===45)return false;if(IsCombiningMark2(cps[0]))return false;let hasJapanese=false;let hasArabicIndic=false; +let hasExtendedArabicIndic=false;for(let i=0;i=4&&value.charCodeAt(2)===45&&value.charCodeAt(3)===45)return false;for(let i=0;i=97&&ch<=122||ch>=65&&ch<=90|| +ch>=48&&ch<=57||ch===45))return false}return true}function IsPuny(value){return value.toLowerCase().startsWith("xn--")}function IsPunyLabel(value){try{return IsUnicodeLabel(Decode(value.slice(4)))}catch{return false}}function IsIdnLabel(value){if(value.length===0||value.length>63)return false;return IsPuny(value)?IsPunyLabel(value):IsUnicodeLabel(value)}function IsLabel(value){if(value.length===0||value.length>63)return false;return IsPuny(value)?IsPunyLabel(value):IsAsciiLabel(value)}function IsHostname(value){if(value.length===0||value.length>253)return false;if(value.charCodeAt(value.length-1)===46)return false;for(const label of value.split(".")){if(!IsLabel(label))return false}return true}var IdnEmail=/^(?!.*\.\.)[\p{L}\p{N}!#$%&'*+/=?^_`{|}~-]+(?:\.[\p{L}\p{N}!#$%&'*+/=?^_`{|}~-]+)*@[\p{L}\p{N}](?:[\p{L}\p{N}-]{0,61}[\p{L}\p{N}])?(?:\.[\p{L}\p{N}](?:[\p{L}\p{N}-]{0,61}[\p{L}\p{N}])?)*$/iu;function IsIdnEmail(value){return IdnEmail.test(value)}function IsIdnHostname(value){if(value.length===0||value.includes(" "))return false;const canonical=value.normalize("NFC").replace(/[\u002E\u3002\uFF0E\uFF61]/g,".");if(canonical.length>253)return false;for(const label of canonical.split(".")){if(!IsIdnLabel(label))return false}return true}function IsIPv4Internal(value,start,end){let dots=0;let num=0;let digits=0;let leading=0;for(let i=start;i255||leading===48&&digits>1)return false;dots++;num=0;digits=0;leading=0}else if(ch>=48&&ch<=57){if(digits===0)leading=ch;num=num*10+(ch-48);digits++}else{return false}}return dots===3&&digits>0&&num<=255&&!(leading===48&&digits>1)}function IsIPv4(value){return IsIPv4Internal(value,0,value.length)}function InRange(ch){return ch>=48&&ch<=57||ch>=65&&ch<=70||ch>=97&&ch<=102}function IsIPv6(value){const length=value.length;if(length===0)return false;let groups=0;let compressed=false;let i=0;if(value.charCodeAt(0)===58&&value.charCodeAt(1)===58){if(length===2)return true;compressed=true;i=2}while(i4)return false;groups++;if(i===length)break;if(next!==58)return false;i++;if(value.charCodeAt(i)===58){if(compressed)return false;if(value.charCodeAt(i+1)===58)return false;compressed=true;i++;if(i===length)break}}return compressed?groups<=7:groups===8}function TryUrl(value){try{new URL(value,"http://example.com");return true}catch{return false}}function IsIriReference(value){if(value.includes(" ")){return false}if(value.includes("\\")){return false}if(/[\x00-\x1F\x7F]/.test(value)){return false}if(/%(?![0-9a-fA-F]{2})/.test(value)){return false}if(value===""){return true}const colonIndex=value.indexOf(":");const hasValidSchemePrefix=colonIndex>0&&/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(value.substring(0,colonIndex));if(hasValidSchemePrefix){return TryUrl( +value)}else{const looksLikeMalformedSchemeAndAuthority=value.match(/^([a-zA-Z][a-zA-Z0-9+\-.]*)(\/\/)/);if(looksLikeMalformedSchemeAndAuthority&&colonIndex===-1){return false}return TryUrl(value)}}function IsIri(value){try{new URL(value);return true}catch{return false}}var JsonPointerUriFragment=/^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i;function IsJsonPointerUriFragment(value){return JsonPointerUriFragment.test(value)}var JsonPointer=/^(?:\/(?:[^~/]|~0|~1)*)*$/;function IsJsonPointer(value){return JsonPointer.test(value)}function IsRegex(value){if(value.length===0){return false}try{new RegExp(value);return true}catch{return false}}var RelativeJsonPointer=/^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/;function IsRelativeJsonPointer(value){return RelativeJsonPointer.test(value)}var UriReference=/^(?!.*[^\x00-\x7F])(?!.*\\)(?:(?:[a-z][a-z0-9+\-.]*:)?(?:\/\/[^\s[\]{}<>^`|]*)?|[^\s[\]{}<>^`|]*)(?:\?[^\s[\]{}<>^`|]*)?(?:#[^\s[\]{}<>^`|]*)?$/i;function IsUriReference(value){return UriReference.test(value)}var UriTemplate=/^(?:(?:[^\x00-\x20"'<>%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i;function IsUriTemplate(value){return UriTemplate.test(value)}function IsAlpha(ch){return ch>=97&&ch<=122||ch>=65&&ch<=90}function IsAlphaNumeric(ch){return IsAlpha(ch)||ch>=48&&ch<=57}function IsHex(ch){return ch>=48&&ch<=57||ch>=65&&ch<=70||ch>=97&&ch<=102}function IsSchemeChar(ch){return IsAlphaNumeric(ch)||ch===43||ch===45||ch===46}function IsUnreserved(ch){return IsAlphaNumeric(ch)||ch===45||ch===46||ch===95||ch===126}function IsSubDelim(ch){return ch===33||ch===36||ch===38||ch===39||ch===40||ch===41||ch===42||ch===43||ch===44||ch===59||ch===61}function IsPchar(ch){ +return IsUnreserved(ch)||IsSubDelim(ch)||ch===58||ch===64}function IsUri(value){const length=value.length;if(length===0)return false;if(!IsAlpha(value.charCodeAt(0)))return false;let i=1;while(i=atPos||!IsHex(value.charCodeAt(j+1))||!IsHex(value.charCodeAt(j+2)))return false;j+=2}else if(!IsUnreserved(ch)&&!IsSubDelim(ch)&&ch!==58)return false}i=atPos+1}if(value.charCodeAt(i)===91){i++;while(i57)return false;i++}}}while(i=length||!IsHex(value.charCodeAt(i+1))||!IsHex(value.charCodeAt(i+2)))return false;i+=2}else if(ch>127){return false}else if(!(IsPchar(ch)||ch===47||ch===63||ch===35)){return false} +i++}return true}var Url=/^(?:https?|ftp):\/\/(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u{00a1}-\u{ffff}]+-)*[a-z0-9\u{00a1}-\u{ffff}]+)(?:\.(?:[a-z0-9\u{00a1}-\u{ffff}]+-)*[a-z0-9\u{00a1}-\u{ffff}]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu;function IsUrl(value){return Url. +test(value)}var Uuid=/^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i;function IsUuid(value){return Uuid.test(value)}var formats=new Map;function Clear(){formats.clear()}function Entries3(){return[...formats.entries()]}function Set3(format,check){formats.set(format,check)}function Has(format){return formats.has(format)}function Get3(format){return formats.get(format)}function Test(format,value){return formats.get(format)?.(value)??true}function Reset2(){Clear();formats.set("date-time",IsDateTime);formats.set("date",IsDate2);formats.set("duration",IsDuration);formats.set("email",IsEmail);formats.set("hostname", +IsHostname);formats.set("idn-email",IsIdnEmail);formats.set("idn-hostname",IsIdnHostname);formats.set("ipv4",IsIPv4);formats.set("ipv6",IsIPv6);formats.set("iri-reference",IsIriReference);formats.set("iri",IsIri);formats.set("json-pointer-uri-fragment",IsJsonPointerUriFragment);formats.set("json-pointer",IsJsonPointer);formats.set("regex",IsRegex);formats.set("relative-json-pointer",IsRelativeJsonPointer);formats.set("time",IsTime);formats.set("uri-reference",IsUriReference);formats.set("uri-tem\ +plate",IsUriTemplate);formats.set("uri",IsUri);formats.set("url",IsUrl);formats.set("uuid",IsUuid)}Reset2();function BuildFormat(_stack,_context,schema,value){return emit_exports.Call(emit_exports.Member("Format","Test"),[emit_exports.Constant(schema.format),value])}function CheckFormat(_stack,_context,schema,value){return format_exports.Test(schema.format,value)}function ErrorFormat(stack,context,schemaPath,instancePath,schema,value){return CheckFormat(stack,context,schema,value)||context.AddError({keyword:"format",schemaPath,instancePath,params:{format:schema.format}})}function BuildIf(stack,context,schema,value){const thenSchema=IsThen(schema)?schema.then:true;const elseSchema=IsElse(schema)?schema.else:true;return emit_exports.Ternary(BuildSchema(stack,context,schema.if,value),BuildSchema(stack,context,thenSchema,value),BuildSchema(stack,context,elseSchema,value))}function CheckIf(stack,context,schema,value){const thenSchema=IsThen(schema)?schema.then:true;const elseSchema=IsElse(schema)?schema.else:true;return CheckSchema(stack,context,schema.if,value)?CheckSchema( +stack,context,thenSchema,value):CheckSchema(stack,context,elseSchema,value)}function ErrorIf(stack,context,schemaPath,instancePath,schema,value){const thenSchema=IsThen(schema)?schema.then:true;const elseSchema=IsElse(schema)?schema.else:true;const trueContext=new AccumulatedErrorContext;const isIf=ErrorSchema(stack,trueContext,`${schemaPath}/if`,instancePath,schema.if,value)?ErrorSchema(stack,trueContext,`${schemaPath}/then`,instancePath,thenSchema,value)||context.AddError({keyword:"if",schemaPath, +instancePath,params:{failingKeyword:"then"}}):ErrorSchema(stack,context,`${schemaPath}/else`,instancePath,elseSchema,value)||context.AddError({keyword:"if",schemaPath,instancePath,params:{failingKeyword:"else"}});if(isIf)context.Merge([trueContext]);return isIf}function BuildItemsSized(stack,context,schema,value){return emit_exports.ReduceAnd(schema.items.map((schema2,index2)=>{const isLength=emit_exports.IsLessEqualThan(emit_exports.Member(value,"length"),emit_exports.Constant(index2));const isSchema=BuildSchemaPushStack(stack,context,schema2,`${value}[${index2}]`);const addIndex=context.AddIndex(emit_exports.Constant(index2));const guarded=context.UseUnevaluated()?emit_exports.And(isSchema,addIndex):isSchema;return emit_exports.Or(isLength,guarded)}))} +function CheckItemsSized(stack,context,schema,value){return guard_exports.Every(schema.items,0,(schema2,index2)=>{return guard_exports.IsLessEqualThan(value.length,index2)||CheckSchemaPushStack(stack,context,schema2,value[index2])&&context.AddIndex(index2)})}function ErrorItemsSized(stack,context,schemaPath,instancePath,schema,value){return guard_exports.EveryAll(schema.items,0,(schema2,index2)=>{const nextSchemaPath=`${schemaPath}/items/${index2}`;const nextInstancePath=`${instancePath}/${index2}`; +return guard_exports.IsLessEqualThan(value.length,index2)||ErrorSchemaPushStack(stack,context,nextSchemaPath,nextInstancePath,schema2,value[index2])&&context.AddIndex(index2)})}function BuildItemsUnsized(stack,context,schema,value){const offset=IsPrefixItems(schema)?schema.prefixItems.length:0;const isSchema=BuildSchemaPushStack(stack,context,schema.items,"element");const addIndex=context.AddIndex("index");const guarded=context.UseUnevaluated()?emit_exports.And(isSchema,addIndex):isSchema;return emit_exports. +Every(value,emit_exports.Constant(offset),["element","index"],guarded)}function CheckItemsUnsized(stack,context,schema,value){const offset=IsPrefixItems(schema)?schema.prefixItems.length:0;return guard_exports.Every(value,offset,(element,index2)=>{return CheckSchemaPushStack(stack,context,schema.items,element)&&context.AddIndex(index2)})}function ErrorItemsUnsized(stack,context,schemaPath,instancePath,schema,value){const offset=IsPrefixItems(schema)?schema.prefixItems.length:0;return guard_exports. +EveryAll(value,offset,(element,index2)=>{const nextSchemaPath=`${schemaPath}/items`;const nextInstancePath=`${instancePath}/${index2}`;return ErrorSchemaPushStack(stack,context,nextSchemaPath,nextInstancePath,schema.items,element)&&context.AddIndex(index2)})}function BuildItems(stack,context,schema,value){return IsItemsSized(schema)?BuildItemsSized(stack,context,schema,value):BuildItemsUnsized(stack,context,schema,value)}function CheckItems(stack,context,schema,value){return IsItemsSized(schema)? +CheckItemsSized(stack,context,schema,value):CheckItemsUnsized(stack,context,schema,value)}function ErrorItems(stack,context,schemaPath,instancePath,schema,value){return IsItemsSized(schema)?ErrorItemsSized(stack,context,schemaPath,instancePath,schema,value):ErrorItemsUnsized(stack,context,schemaPath,instancePath,schema,value)}function IsValid3(schema){return IsContains(schema)}function BuildMaxContains(stack,context,schema,value){if(!IsValid3(schema))return emit_exports.Constant(true);const[result,item]=[Unique(),Unique()];const count=emit_exports.Call(emit_exports.Member(value,"reduce"),[emit_exports.ArrowFunction([result,item],emit_exports.Ternary(BuildSchema(stack,context,schema.contains,item),emit_exports.PrefixIncrement(result),result)),emit_exports.Constant(0)]);return emit_exports.IsLessEqualThan(count,emit_exports. +Constant(schema.maxContains))}function CheckMaxContains(stack,context,schema,value){if(!IsValid3(schema))return true;const count=value.reduce((result,item)=>CheckSchema(stack,context,schema.contains,item)?++result:result,0);return guard_exports.IsLessEqualThan(count,schema.maxContains)}function ErrorMaxContains(stack,context,schemaPath,instancePath,schema,value){const minContains=IsMinContains(schema)?schema.minContains:1;return CheckMaxContains(stack,context,schema,value)||context.AddError({keyword:"\ +contains",schemaPath,instancePath,params:{minContains,maxContains:schema.maxContains}})}function BuildMaximum(_stack,_context,schema,value){return emit_exports.IsLessEqualThan(value,emit_exports.Constant(schema.maximum))}function CheckMaximum(_stack,_context,schema,value){return guard_exports.IsLessEqualThan(value,schema.maximum)}function ErrorMaximum(stack,context,schemaPath,instancePath,schema,value){return CheckMaximum(stack,context,schema,value)||context.AddError({keyword:"maximum",schemaPath,instancePath,params:{comparison:"<=",limit:schema.maximum}})}function BuildMaxItems(_stack,_context,schema,value){return emit_exports.IsLessEqualThan(emit_exports.Member(value,"length"),emit_exports.Constant(schema.maxItems))}function CheckMaxItems(_stack,_context,schema,value){return guard_exports.IsLessEqualThan(value.length,schema.maxItems)}function ErrorMaxItems(stack,context,schemaPath,instancePath,schema,value){return CheckMaxItems(stack,context,schema,value)||context.AddError({keyword:"maxItems",schemaPath,instancePath,params:{limit:schema.maxItems}})}function BuildMaxLength(_stack,_context,schema,value){return emit_exports.IsMaxLength(value,emit_exports.Constant(schema.maxLength))}function CheckMaxLength(_stack,_context,schema,value){return guard_exports.IsMaxLength(value,schema.maxLength)}function ErrorMaxLength(stack,context,schemaPath,instancePath,schema,value){return CheckMaxLength(stack,context,schema,value)||context.AddError({keyword:"maxLength",schemaPath,instancePath,params:{limit:schema.maxLength}})}function BuildMaxProperties(_stack,_context,schema,value){return emit_exports.IsLessEqualThan(emit_exports.Member(emit_exports.Keys(value),"length"),emit_exports.Constant(schema.maxProperties))}function CheckMaxProperties(_stack,_context,schema,value){return guard_exports.IsLessEqualThan(guard_exports.Keys(value).length,schema.maxProperties)}function ErrorMaxProperties(stack,context,schemaPath,instancePath,schema,value){return CheckMaxProperties(stack,context,schema,value)||context.AddError({keyword:"\ +maxProperties",schemaPath,instancePath,params:{limit:schema.maxProperties}})}function IsValid4(schema){return IsContains(schema)}function BuildMinContains(stack,context,schema,value){if(!IsValid4(schema))return emit_exports.Constant(true);const[result,item]=[Unique(),Unique()];const count=emit_exports.Call(emit_exports.Member(value,"reduce"),[emit_exports.ArrowFunction([result,item],emit_exports.Ternary(BuildSchema(stack,context,schema.contains,item),emit_exports.PrefixIncrement(result),result)),emit_exports.Constant(0)]);return emit_exports.IsGreaterEqualThan(count,emit_exports. +Constant(schema.minContains))}function CheckMinContains(stack,context,schema,value){if(!IsValid4(schema))return true;const count=value.reduce((result,item)=>CheckSchema(stack,context,schema.contains,item)?++result:result,0);return guard_exports.IsGreaterEqualThan(count,schema.minContains)}function ErrorMinContains(stack,context,schemaPath,instancePath,schema,value){return CheckMinContains(stack,context,schema,value)||context.AddError({keyword:"contains",schemaPath,instancePath,params:{minContains:schema. +minContains}})}function BuildMinimum(_stack,_context,schema,value){return emit_exports.IsGreaterEqualThan(value,emit_exports.Constant(schema.minimum))}function CheckMinimum(_stack,_context,schema,value){return guard_exports.IsGreaterEqualThan(value,schema.minimum)}function ErrorMinimum(stack,context,schemaPath,instancePath,schema,value){return CheckMinimum(stack,context,schema,value)||context.AddError({keyword:"minimum",schemaPath,instancePath,params:{comparison:">=",limit:schema.minimum}})}function BuildMinItems(_stack,_context,schema,value){return emit_exports.IsGreaterEqualThan(emit_exports.Member(value,"length"),emit_exports.Constant(schema.minItems))}function CheckMinItems(_stack,_context,schema,value){return guard_exports.IsGreaterEqualThan(value.length,schema.minItems)}function ErrorMinItems(stack,context,schemaPath,instancePath,schema,value){return CheckMinItems(stack,context,schema,value)||context.AddError({keyword:"minItems",schemaPath,instancePath,params:{limit:schema.minItems}})}function BuildMinLength(_stack,_context,schema,value){return emit_exports.IsMinLength(value,emit_exports.Constant(schema.minLength))}function CheckMinLength(_stack,_context,schema,value){return guard_exports.IsMinLength(value,schema.minLength)}function ErrorMinLength(stack,context,schemaPath,instancePath,schema,value){return CheckMinLength(stack,context,schema,value)||context.AddError({keyword:"minLength",schemaPath,instancePath,params:{limit:schema.minLength}})}function BuildMinProperties(_stack,_context,schema,value){return emit_exports.IsGreaterEqualThan(emit_exports.Member(emit_exports.Keys(value),"length"),emit_exports.Constant(schema.minProperties))}function CheckMinProperties(_stack,_context,schema,value){return guard_exports.IsGreaterEqualThan(guard_exports.Keys(value).length,schema.minProperties)}function ErrorMinProperties(stack,context,schemaPath,instancePath,schema,value){return CheckMinProperties(stack,context,schema,value)||context.AddError( +{keyword:"minProperties",schemaPath,instancePath,params:{limit:schema.minProperties}})}function BuildMultipleOf(_stack,_context,schema,value){return emit_exports.MultipleOf(value,emit_exports.Constant(schema.multipleOf))}function CheckMultipleOf(_stack,_context,schema,value){return guard_exports.IsMultipleOf(value,schema.multipleOf)}function ErrorMultipleOf(stack,context,schemaPath,instancePath,schema,value){return CheckMultipleOf(stack,context,schema,value)||context.AddError({keyword:"multipleOf",schemaPath,instancePath,params:{multipleOf:schema.multipleOf}})}function BuildNotUnevaluated(stack,context,schema,value){return Reducer(stack,context,[schema.not],value,emit_exports.Not(emit_exports.IsEqual(emit_exports.Member("results","length"),emit_exports.Constant(1))))}function BuildNotFast(stack,context,schema,value){return emit_exports.Not(BuildSchema(stack,context,schema.not,value))}function BuildNot(stack,context,schema,value){return context.UseUnevaluated()?BuildNotUnevaluated(stack,context,schema,value):BuildNotFast(stack,context,schema,value)}function CheckNot(stack,context,schema,value){ +const nextContext=new CheckContext;const isSchema=!CheckSchema(stack,nextContext,schema.not,value);const isNot=isSchema&&context.Merge([nextContext]);return isNot}function ErrorNot(stack,context,schemaPath,instancePath,schema,value){return CheckNot(stack,context,schema,value)||context.AddError({keyword:"not",schemaPath,instancePath,params:{}})}function BuildOneOfUnevaluated(stack,context,schema,value){return Reducer(stack,context,schema.oneOf,value,emit_exports.IsEqual(emit_exports.Member("results","length"),emit_exports.Constant(1)))}function BuildOneOfFast(stack,context,schema,value){const results=emit_exports.ArrayLiteral(schema.oneOf.map(schema2=>BuildSchema(stack,context,schema2,value)));const count=emit_exports.Call(emit_exports.Member(results,"reduce"),[emit_exports.ArrowFunction(["count","result"],emit_exports.Ternary(emit_exports. +IsEqual("result",emit_exports.Constant(true)),emit_exports.PrefixIncrement("count"),"count")),emit_exports.Constant(0)]);return emit_exports.IsEqual(count,emit_exports.Constant(1))}function BuildOneOf(stack,context,schema,value){return context.UseUnevaluated()?BuildOneOfUnevaluated(stack,context,schema,value):BuildOneOfFast(stack,context,schema,value)}function CheckOneOf(stack,context,schema,value){const passedContexts=schema.oneOf.reduce((result,schema2)=>{const nextContext=new CheckContext;return CheckSchema( +stack,nextContext,schema2,value)?[...result,nextContext]:result},[]);return guard_exports.IsEqual(passedContexts.length,1)&&context.Merge(passedContexts)}function ErrorOneOf(stack,context,schemaPath,instancePath,schema,value){const failedContexts=[];const passingSchemas=[];const passedContexts=schema.oneOf.reduce((result,schema2,index2)=>{const nextContext=new AccumulatedErrorContext;const nextSchemaPath=`${schemaPath}/oneOf/${index2}`;const isSchema=ErrorSchema(stack,nextContext,nextSchemaPath, +instancePath,schema2,value);if(isSchema)passingSchemas.push(index2);if(!isSchema)failedContexts.push(nextContext);return isSchema?[...result,nextContext]:result},[]);const isOneOf=guard_exports.IsEqual(passedContexts.length,1)&&context.Merge(passedContexts);if(!isOneOf&&guard_exports.IsEqual(passingSchemas.length,0))failedContexts.forEach(failed=>failed.GetErrors().forEach(error=>context.AddError(error)));return isOneOf||context.AddError({keyword:"oneOf",schemaPath,instancePath,params:{passingSchemas}})}function BuildPattern(_stack,_context,schema,value){const regexp=CreateVariable(guard_exports.IsString(schema.pattern)?new RegExp(schema.pattern,"u"):schema.pattern);return emit_exports.Call(emit_exports.Member(regexp,"test"),[value])}function CheckPattern(_stack,_context,schema,value){const regexp=guard_exports.IsString(schema.pattern)?new RegExp(schema.pattern,"u"):schema.pattern;return regexp.test(value)}function ErrorPattern(stack,context,schemaPath,instancePath,schema,value){return CheckPattern( +stack,context,schema,value)||context.AddError({keyword:"pattern",schemaPath,instancePath,params:{pattern:schema.pattern}})}function BuildPatternProperties(stack,context,schema,value){return emit_exports.ReduceAnd(guard_exports.Entries(schema.patternProperties).map(([pattern,schema2])=>{const[key,prop]=[Unique(),Unique()];const regexp=CreateVariable(new RegExp(pattern,"u"));const notKey=emit_exports.Not(emit_exports.Call(emit_exports.Member(regexp,"test"),[key]));const isSchema=BuildSchemaPushStack(stack,context,schema2,prop);const addKey=context.AddKey(key);const guarded=context.UseUnevaluated()?emit_exports.Or(notKey, +emit_exports.And(isSchema,addKey)):emit_exports.Or(notKey,isSchema);return emit_exports.Every(emit_exports.Entries(value),emit_exports.Constant(0),[`[${key}, ${prop}]`,"_"],guarded)}))}function CheckPatternProperties(stack,context,schema,value){return guard_exports.Every(guard_exports.Entries(schema.patternProperties),0,([pattern,schema2])=>{const regexp=new RegExp(pattern,"u");return guard_exports.Every(guard_exports.Entries(value),0,([key,prop])=>{return!regexp.test(key)||CheckSchemaPushStack( +stack,context,schema2,prop)&&context.AddKey(key)})})}function ErrorPatternProperties(stack,context,schemaPath,instancePath,schema,value){return guard_exports.EveryAll(guard_exports.Entries(schema.patternProperties),0,([pattern,schema2])=>{const nextSchemaPath=`${schemaPath}/patternProperties/${pattern}`;const regexp=new RegExp(pattern,"u");return guard_exports.EveryAll(guard_exports.Entries(value),0,([key,value2])=>{const nextInstancePath=`${instancePath}/${key}`;const notKey=!regexp.test(key);return notKey|| +ErrorSchemaPushStack(stack,context,nextSchemaPath,nextInstancePath,schema2,value2)&&context.AddKey(key)})})}function BuildPrefixItems(stack,context,schema,value){return emit_exports.ReduceAnd(schema.prefixItems.map((schema2,index2)=>{const isLength=emit_exports.IsLessEqualThan(emit_exports.Member(value,"length"),emit_exports.Constant(index2));const isSchema=BuildSchemaPushStack(stack,context,schema2,`${value}[${index2}]`);const addIndex=context.AddIndex(emit_exports.Constant(index2));const guarded=context.UseUnevaluated()?emit_exports.And(isSchema,addIndex):isSchema;return emit_exports.Or(isLength,guarded)}))} +function CheckPrefixItems(stack,context,schema,value){return guard_exports.IsEqual(value.length,0)||guard_exports.Every(schema.prefixItems,0,(schema2,index2)=>{return guard_exports.IsLessEqualThan(value.length,index2)||CheckSchemaPushStack(stack,context,schema2,value[index2])&&context.AddIndex(index2)})}function ErrorPrefixItems(stack,context,schemaPath,instancePath,schema,value){return guard_exports.IsEqual(value.length,0)||guard_exports.EveryAll(schema.prefixItems,0,(schema2,index2)=>{const nextSchemaPath=`${schemaPath}\ +/prefixItems/${index2}`;const nextInstancePath=`${instancePath}/${index2}`;return guard_exports.IsLessEqualThan(value.length,index2)||ErrorSchemaPushStack(stack,context,nextSchemaPath,nextInstancePath,schema2,value[index2])&&context.AddIndex(index2)})}function IsExactOptional(required,key){return required.includes(key)||settings_exports.Get().exactOptionalPropertyTypes}function InexactOptionalBuild(value,key){return emit_exports.IsUndefined(emit_exports.Member(value,key))}function InexactOptionalCheck(value,key){return guard_exports.IsUndefined(value[key])}function BuildProperties(stack,context,schema,value){const required=IsRequired(schema)?schema.required:[];const everyKey=guard_exports.Entries(schema.properties).map(([key,schema2])=>{const notKey=emit_exports.Not(emit_exports.HasPropertyKey(value,emit_exports.Constant(key)));const isSchema=BuildSchemaPushStack(stack,context,schema2,emit_exports.Member(value,key));const addKey=context.AddKey(emit_exports.Constant(key));const guarded=context.UseUnevaluated()?emit_exports.And(isSchema,addKey):isSchema; +const isProperty=required.includes(key)?guarded:emit_exports.Or(notKey,guarded);return IsExactOptional(required,key)?isProperty:emit_exports.Or(InexactOptionalBuild(value,key),isProperty)});return emit_exports.ReduceAnd(everyKey)}function CheckProperties(stack,context,schema,value){const required=IsRequired(schema)?schema.required:[];const isProperties=guard_exports.Every(guard_exports.Entries(schema.properties),0,([key,schema2])=>{const isProperty=!guard_exports.HasPropertyKey(value,key)||CheckSchemaPushStack( +stack,context,schema2,value[key])&&context.AddKey(key);return IsExactOptional(required,key)?isProperty:InexactOptionalCheck(value,key)||isProperty});return isProperties}function ErrorProperties(stack,context,schemaPath,instancePath,schema,value){const required=IsRequired(schema)?schema.required:[];const isProperties=guard_exports.EveryAll(guard_exports.Entries(schema.properties),0,([key,schema2])=>{const nextSchemaPath=`${schemaPath}/properties/${key}`;const nextInstancePath=`${instancePath}/${key}`; +const isProperty=()=>!guard_exports.HasPropertyKey(value,key)||ErrorSchemaPushStack(stack,context,nextSchemaPath,nextInstancePath,schema2,value[key])&&context.AddKey(key);return IsExactOptional(required,key)?isProperty():InexactOptionalCheck(value,key)||isProperty()});return isProperties}function BuildPropertyNames(stack,context,schema,value){const[key,_index]=[Unique(),Unique()];return emit_exports.Every(emit_exports.Keys(value),emit_exports.Constant(0),[key,_index],BuildSchema(stack,context,schema.propertyNames,key))}function CheckPropertyNames(stack,context,schema,value){return guard_exports.Every(guard_exports.Keys(value),0,(key,_index)=>CheckSchema(stack,context,schema.propertyNames,key))}function ErrorPropertyNames(stack,context,schemaPath,instancePath,schema,value){const propertyNames=[]; +const isPropertyNames=guard_exports.EveryAll(guard_exports.Keys(value),0,(key,_index)=>{const nextInstancePath=`${instancePath}/${key}`;const nextSchemaPath=`${schemaPath}/propertyNames`;const nextContext=new AccumulatedErrorContext;const isPropertyName=ErrorSchema(stack,nextContext,nextSchemaPath,nextInstancePath,schema.propertyNames,key);if(!isPropertyName)propertyNames.push(key);return isPropertyName});return isPropertyNames||context.AddError({keyword:"propertyNames",schemaPath,instancePath,params:{ +propertyNames}})}function BuildRecursiveRef(stack,context,schema,value){const target=stack.RecursiveRef(schema)??false;return CreateFunction(stack,context,target,value)}function CheckRecursiveRef(stack,context,schema,value){const target=stack.RecursiveRef(schema)??false;return IsSchema2(target)&&CheckSchema(stack,context,target,value)}function ErrorRecursiveRef(stack,context,_schemaPath,instancePath,schema,value){const target=stack.RecursiveRef(schema)??false;return IsSchema2(target)&&ErrorSchema(stack,context,"\ +#",instancePath,target,value)}function BuildRefStandard(stack,context,target,value){const interior=emit_exports.ArrowFunction(["context","value"],CreateFunction(stack,context,target,"value"));const exterior=emit_exports.ArrowFunction(["context","value"],emit_exports.Statements([emit_exports.ConstDeclaration("nextContext",emit_exports.New("CheckContext",[])),emit_exports.ConstDeclaration("result",emit_exports.Call(interior,["nextContext","value"])),emit_exports.If("result",context.Merge("[nextContext]")),emit_exports.Return("\ +result")]));return emit_exports.Call(exterior,["context",value])}function BuildRefFast(stack,context,target,value){return CreateFunction(stack,context,target,value)}function BuildRef(stack,context,schema,value){const target=stack.Ref(schema)??false;return context.UseUnevaluated()?BuildRefStandard(stack,context,target,value):BuildRefFast(stack,context,target,value)}function CheckRef(stack,context,schema,value){const target=stack.Ref(schema)??false;const nextContext=new CheckContext;const result=IsSchema2( +target)&&CheckSchema(stack,nextContext,target,value);if(result)context.Merge([nextContext]);return result}function ErrorRef(stack,context,_schemaPath,instancePath,schema,value){const target=stack.Ref(schema)??false;const nextContext=new AccumulatedErrorContext;const result=IsSchema2(target)&&ErrorSchema(stack,nextContext,"#",instancePath,target,value);if(result)context.Merge([nextContext]);if(!result)nextContext.GetErrors().forEach(error=>context.AddError(error));return result}function BuildRequired(_stack,_context,schema,value){return emit_exports.ReduceAnd(schema.required.map(key=>emit_exports.HasPropertyKey(value,emit_exports.Constant(key))))}function CheckRequired(_stack,_context,schema,value){return guard_exports.Every(schema.required,0,key=>guard_exports.HasPropertyKey(value,key))}function ErrorRequired(_stack,context,schemaPath,instancePath,schema,value){const requiredProperties=[];const isRequired=guard_exports.EveryAll(schema.required,0,key=>{const hasKey=guard_exports. +HasPropertyKey(value,key);if(!hasKey)requiredProperties.push(key);return hasKey});return isRequired||context.AddError({keyword:"required",schemaPath,instancePath,params:{requiredProperties}})}function BuildTypeName(_stack,_context,type,value){return guard_exports.IsEqual(type,"object")?emit_exports.IsObjectNotArray(value):guard_exports.IsEqual(type,"array")?emit_exports.IsArray(value):guard_exports.IsEqual(type,"boolean")?emit_exports.IsBoolean(value):guard_exports.IsEqual(type,"integer")?emit_exports.IsInteger(value):guard_exports.IsEqual(type,"number")?emit_exports.IsNumber(value):guard_exports.IsEqual(type,"null")?emit_exports.IsNull(value):guard_exports.IsEqual(type,"string")?emit_exports. +IsString(value):guard_exports.IsEqual(type,"asyncIterator")?emit_exports.IsAsyncIterator(value):guard_exports.IsEqual(type,"bigint")?emit_exports.IsBigInt(value):guard_exports.IsEqual(type,"constructor")?emit_exports.IsConstructor(value):guard_exports.IsEqual(type,"function")?emit_exports.IsFunction(value):guard_exports.IsEqual(type,"iterator")?emit_exports.IsIterator(value):guard_exports.IsEqual(type,"symbol")?emit_exports.IsSymbol(value):guard_exports.IsEqual(type,"undefined")?emit_exports.IsUndefined( +value):guard_exports.IsEqual(type,"void")?emit_exports.IsUndefined(value):emit_exports.Constant(true)}function CheckTypeName(_stack,_context,type,_schema,value){return guard_exports.IsEqual(type,"object")?guard_exports.IsObjectNotArray(value):guard_exports.IsEqual(type,"array")?guard_exports.IsArray(value):guard_exports.IsEqual(type,"boolean")?guard_exports.IsBoolean(value):guard_exports.IsEqual(type,"integer")?guard_exports.IsInteger(value):guard_exports.IsEqual(type,"number")?guard_exports.IsNumber( +value):guard_exports.IsEqual(type,"null")?guard_exports.IsNull(value):guard_exports.IsEqual(type,"string")?guard_exports.IsString(value):guard_exports.IsEqual(type,"asyncIterator")?guard_exports.IsAsyncIterator(value):guard_exports.IsEqual(type,"bigint")?guard_exports.IsBigInt(value):guard_exports.IsEqual(type,"constructor")?guard_exports.IsConstructor(value):guard_exports.IsEqual(type,"function")?guard_exports.IsFunction(value):guard_exports.IsEqual(type,"iterator")?guard_exports.IsIterator(value): +guard_exports.IsEqual(type,"symbol")?guard_exports.IsSymbol(value):guard_exports.IsEqual(type,"undefined")?guard_exports.IsUndefined(value):guard_exports.IsEqual(type,"void")?guard_exports.IsUndefined(value):true}function BuildTypeNames(stack,context,typenames,value){return emit_exports.ReduceOr(typenames.map(type=>BuildTypeName(stack,context,type,value)))}function CheckTypeNames(stack,context,types,schema,value){return types.some(type=>CheckTypeName(stack,context,type,schema,value))}function BuildType(stack,context,schema,value){ +return guard_exports.IsArray(schema.type)?BuildTypeNames(stack,context,schema.type,value):BuildTypeName(stack,context,schema.type,value)}function CheckType(stack,context,schema,value){return guard_exports.IsArray(schema.type)?CheckTypeNames(stack,context,schema.type,schema,value):CheckTypeName(stack,context,schema.type,schema,value)}function ErrorType(stack,context,schemaPath,instancePath,schema,value){const isType=guard_exports.IsArray(schema.type)?CheckTypeNames(stack,context,schema.type,schema, +value):CheckTypeName(stack,context,schema.type,schema,value);return isType||context.AddError({keyword:"type",schemaPath,instancePath,params:{type:schema.type}})}function BuildUnevaluatedItems(stack,context,schema,value){const[index2,item]=[Unique(),Unique()];const indices=emit_exports.Call(emit_exports.Member("context","GetIndices"),[]);const hasIndex=emit_exports.Call(emit_exports.Member("indices","has"),[index2]);const isSchema=BuildSchema(stack,context,schema.unevaluatedItems,item);const addIndex=emit_exports.Call(emit_exports.Member("context","AddIndex"),[index2]);const isEvery=emit_exports.Every(value,emit_exports.Constant(0),[item,index2],emit_exports. +And(emit_exports.Or(hasIndex,isSchema),addIndex));return emit_exports.Call(emit_exports.ArrowFunction(["context"],emit_exports.Statements([emit_exports.ConstDeclaration("indices",indices),emit_exports.Return(isEvery)])),["context"])}function CheckUnevaluatedItems(stack,context,schema,value){const indices=context.GetIndices();return guard_exports.Every(value,0,(item,index2)=>{return(indices.has(index2)||CheckSchema(stack,context,schema.unevaluatedItems,item))&&context.AddIndex(index2)})}function ErrorUnevaluatedItems(stack,context,schemaPath,instancePath,schema,value){ +const indices=context.GetIndices();const unevaluatedItems=[];const isUnevaluatedItems=guard_exports.EveryAll(value,0,(item,index2)=>{const nextContext=new AccumulatedErrorContext;const isEvaluatedItem=(indices.has(index2)||ErrorSchema(stack,nextContext,schemaPath,instancePath,schema.unevaluatedItems,item))&&context.AddIndex(index2);if(!isEvaluatedItem)unevaluatedItems.push(index2);return isEvaluatedItem});return isUnevaluatedItems||context.AddError({keyword:"unevaluatedItems",schemaPath,instancePath, +params:{unevaluatedItems}})}function BuildUnevaluatedProperties(stack,context,schema,value){const[key,prop]=[Unique(),Unique()];const keys=emit_exports.Call(emit_exports.Member("context","GetKeys"),[]);const hasKey=emit_exports.Call(emit_exports.Member("keys","has"),[key]);const addKey=emit_exports.Call(emit_exports.Member("context","AddKey"),[key]);const isSchema=BuildSchema(stack,context,schema.unevaluatedProperties,prop);const isEvery=emit_exports.Every(emit_exports.Entries(value),emit_exports.Constant(0),[`[${key}, ${prop}\ +]`,"_"],emit_exports.Or(hasKey,emit_exports.And(isSchema,addKey)));return emit_exports.Call(emit_exports.ArrowFunction(["context"],emit_exports.Statements([emit_exports.ConstDeclaration("keys",keys),emit_exports.Return(isEvery)])),["context"])}function CheckUnevaluatedProperties(stack,context,schema,value){const keys=context.GetKeys();return guard_exports.Every(guard_exports.Entries(value),0,([key,prop])=>{return keys.has(key)||CheckSchema(stack,context,schema.unevaluatedProperties,prop)&&context. +AddKey(key)})}function ErrorUnevaluatedProperties(stack,context,schemaPath,instancePath,schema,value){const keys=context.GetKeys();const unevaluatedProperties=[];const isUnevaluatedProperties=guard_exports.EveryAll(guard_exports.Entries(value),0,([key,prop])=>{const nextContext=new AccumulatedErrorContext;const isEvaluatedProperty=keys.has(key)||ErrorSchema(stack,nextContext,schemaPath,instancePath,schema.unevaluatedProperties,prop)&&context.AddKey(key);if(!isEvaluatedProperty)unevaluatedProperties. +push(key);return isEvaluatedProperty});return isUnevaluatedProperties||context.AddError({keyword:"unevaluatedProperties",schemaPath,instancePath,params:{unevaluatedProperties}})}function IsValid5(schema){return!guard_exports.IsEqual(schema.uniqueItems,false)}function BuildUniqueItems(_stack,_context,schema,value){if(!IsValid5(schema))return emit_exports.Constant(true);const set=emit_exports.Member(emit_exports.New("Set",[emit_exports.Call(emit_exports.Member(value,"map"),[emit_exports.Member("Hashing","Hash")])]),"size");const isLength=emit_exports.Member(value,"length");return emit_exports.IsEqual(set,isLength)}function CheckUniqueItems(_stack,_context,schema,value){if(!IsValid5( +schema))return true;const set=new Set(value.map(hash_exports.Hash)).size;const isLength=value.length;return guard_exports.IsEqual(set,isLength)}function ErrorUniqueItems(_stack,context,schemaPath,instancePath,schema,value){if(!IsValid5(schema))return true;const set=new Set;const duplicateItems=value.reduce((result,value2,index2)=>{const hash=hash_exports.Hash(value2);if(set.has(hash))return[...result,index2];set.add(hash);return result},[]);const isUniqueItems=guard_exports.IsEqual(duplicateItems. +length,0);return isUniqueItems||context.AddError({keyword:"uniqueItems",schemaPath,instancePath,params:{duplicateItems}})}function HasTypeName(schema,typename){return IsType(schema)&&(guard_exports.IsArray(schema.type)&&schema.type.includes(typename)||guard_exports.IsEqual(schema.type,typename))}function HasObjectType(schema){return HasTypeName(schema,"object")}function HasObjectKeywords(schema){return IsSchemaObject(schema)&&(IsAdditionalProperties(schema)||IsDependencies(schema)||IsDependentRequired(schema)||IsDependentSchemas(schema)||IsProperties(schema)||IsPatternProperties(schema)||IsPropertyNames(schema)||IsMinProperties( +schema)||IsMaxProperties(schema)||IsRequired(schema)||IsUnevaluatedProperties(schema))}function HasArrayType(schema){return HasTypeName(schema,"array")}function HasArrayKeywords(schema){return IsSchemaObject(schema)&&(IsAdditionalItems(schema)||IsItems(schema)||IsContains(schema)||IsMaxContains(schema)||IsMaxItems(schema)||IsMinContains(schema)||IsMinItems(schema)||IsPrefixItems(schema)||IsUnevaluatedItems(schema)||IsUniqueItems(schema))}function HasStringType(schema){return HasTypeName(schema,"\ +string")}function HasStringKeywords(schema){return IsSchemaObject(schema)&&(IsMinLength4(schema)||IsMaxLength4(schema)||IsFormat(schema)||IsPattern(schema))}function HasNumberType(schema){return HasTypeName(schema,"number")||HasTypeName(schema,"bigint")}function HasNumberKeywords(schema){return IsSchemaObject(schema)&&(IsMinimum(schema)||IsMaximum(schema)||IsExclusiveMaximum(schema)||IsExclusiveMinimum(schema)||IsMultipleOf2(schema))}function BuildSchemaPushStack(stack,context,schema,value){return context. +UseUnevaluated()?emit_exports.And(emit_exports.And(context.Push(),BuildSchema(stack,context,schema,value)),context.Pop()):BuildSchema(stack,context,schema,value)}function BuildSchema(stack,context,schema,value){stack.Push(schema);const conditions=[];if(IsBooleanSchema(schema))return BuildBooleanSchema(stack,context,schema,value);if(IsType(schema))conditions.push(BuildType(stack,context,schema,value));if(HasObjectKeywords(schema)){const constraints=[];if(IsRequired(schema))constraints.push(BuildRequired( +stack,context,schema,value));if(IsAdditionalProperties(schema))constraints.push(BuildAdditionalProperties(stack,context,schema,value));if(IsDependencies(schema))constraints.push(BuildDependencies(stack,context,schema,value));if(IsDependentRequired(schema))constraints.push(BuildDependentRequired(stack,context,schema,value));if(IsDependentSchemas(schema))constraints.push(BuildDependentSchemas(stack,context,schema,value));if(IsPatternProperties(schema))constraints.push(BuildPatternProperties(stack, +context,schema,value));if(IsProperties(schema))constraints.push(BuildProperties(stack,context,schema,value));if(IsPropertyNames(schema))constraints.push(BuildPropertyNames(stack,context,schema,value));if(IsMinProperties(schema))constraints.push(BuildMinProperties(stack,context,schema,value));if(IsMaxProperties(schema))constraints.push(BuildMaxProperties(stack,context,schema,value));const reduced=emit_exports.ReduceAnd(constraints);const guarded=emit_exports.Or(emit_exports.Not(emit_exports.IsObjectNotArray( +value)),reduced);conditions.push(HasObjectType(schema)?reduced:guarded)}if(HasArrayKeywords(schema)){const constraints=[];if(IsAdditionalItems(schema))constraints.push(BuildAdditionalItems(stack,context,schema,value));if(IsContains(schema))constraints.push(BuildContains(stack,context,schema,value));if(IsItems(schema))constraints.push(BuildItems(stack,context,schema,value));if(IsMaxContains(schema))constraints.push(BuildMaxContains(stack,context,schema,value));if(IsMaxItems(schema))constraints.push( +BuildMaxItems(stack,context,schema,value));if(IsMinContains(schema))constraints.push(BuildMinContains(stack,context,schema,value));if(IsMinItems(schema))constraints.push(BuildMinItems(stack,context,schema,value));if(IsPrefixItems(schema))constraints.push(BuildPrefixItems(stack,context,schema,value));if(IsUniqueItems(schema))constraints.push(BuildUniqueItems(stack,context,schema,value));const reduced=emit_exports.ReduceAnd(constraints);const guarded=emit_exports.Or(emit_exports.Not(emit_exports.IsArray( +value)),reduced);conditions.push(HasArrayType(schema)?reduced:guarded)}if(HasStringKeywords(schema)){const constraints=[];if(IsMaxLength4(schema))constraints.push(BuildMaxLength(stack,context,schema,value));if(IsMinLength4(schema))constraints.push(BuildMinLength(stack,context,schema,value));if(IsFormat(schema))constraints.push(BuildFormat(stack,context,schema,value));if(IsPattern(schema))constraints.push(BuildPattern(stack,context,schema,value));const reduced=emit_exports.ReduceAnd(constraints); +const guarded=emit_exports.Or(emit_exports.Not(emit_exports.IsString(value)),reduced);conditions.push(HasStringType(schema)?reduced:guarded)}if(HasNumberKeywords(schema)){const constraints=[];if(IsExclusiveMaximum(schema))constraints.push(BuildExclusiveMaximum(stack,context,schema,value));if(IsExclusiveMinimum(schema))constraints.push(BuildExclusiveMinimum(stack,context,schema,value));if(IsMaximum(schema))constraints.push(BuildMaximum(stack,context,schema,value));if(IsMinimum(schema))constraints. +push(BuildMinimum(stack,context,schema,value));if(IsMultipleOf2(schema))constraints.push(BuildMultipleOf(stack,context,schema,value));const reduced=emit_exports.ReduceAnd(constraints);const guarded=emit_exports.Or(emit_exports.Not(emit_exports.Or(emit_exports.IsNumber(value),emit_exports.IsBigInt(value))),reduced);conditions.push(HasNumberType(schema)?reduced:guarded)}if(IsRef2(schema))conditions.push(BuildRef(stack,context,schema,value));if(IsRecursiveRef(schema))conditions.push(BuildRecursiveRef( +stack,context,schema,value));if(IsDynamicRef(schema))conditions.push(BuildDynamicRef(stack,context,schema,value));if(IsGuard2(schema))conditions.push(BuildGuard(stack,context,schema,value));if(IsConst(schema))conditions.push(BuildConst(stack,context,schema,value));if(IsEnum2(schema))conditions.push(BuildEnum(stack,context,schema,value));if(IsIf(schema))conditions.push(BuildIf(stack,context,schema,value));if(IsNot(schema))conditions.push(BuildNot(stack,context,schema,value));if(IsAllOf(schema))conditions. +push(BuildAllOf(stack,context,schema,value));if(IsAnyOf(schema))conditions.push(BuildAnyOf(stack,context,schema,value));if(IsOneOf(schema))conditions.push(BuildOneOf(stack,context,schema,value));if(IsUnevaluatedItems(schema))conditions.push(emit_exports.Or(emit_exports.Not(emit_exports.IsArray(value)),BuildUnevaluatedItems(stack,context,schema,value)));if(IsUnevaluatedProperties(schema))conditions.push(emit_exports.Or(emit_exports.Not(emit_exports.IsObject(value)),BuildUnevaluatedProperties(stack, +context,schema,value)));if(IsRefine2(schema))conditions.push(BuildRefine(stack,context,schema,value));const result=emit_exports.ReduceAnd(conditions);stack.Pop(schema);return result}function CheckSchemaPushStack(stack,context,schema,value){return context.Push()&&CheckSchema(stack,context,schema,value)&&context.Pop()}function CheckSchema(stack,context,schema,value){stack.Push(schema);const result=IsBooleanSchema(schema)?CheckBooleanSchema(stack,context,schema,value):(!IsType(schema)||CheckType(stack, +context,schema,value))&&(!(guard_exports.IsObject(value)&&!guard_exports.IsArray(value))||(!IsRequired(schema)||CheckRequired(stack,context,schema,value))&&(!IsAdditionalProperties(schema)||CheckAdditionalProperties(stack,context,schema,value))&&(!IsDependencies(schema)||CheckDependencies(stack,context,schema,value))&&(!IsDependentRequired(schema)||CheckDependentRequired(stack,context,schema,value))&&(!IsDependentSchemas(schema)||CheckDependentSchemas(stack,context,schema,value))&&(!IsPatternProperties( +schema)||CheckPatternProperties(stack,context,schema,value))&&(!IsProperties(schema)||CheckProperties(stack,context,schema,value))&&(!IsPropertyNames(schema)||CheckPropertyNames(stack,context,schema,value))&&(!IsMinProperties(schema)||CheckMinProperties(stack,context,schema,value))&&(!IsMaxProperties(schema)||CheckMaxProperties(stack,context,schema,value)))&&(!guard_exports.IsArray(value)||(!IsAdditionalItems(schema)||CheckAdditionalItems(stack,context,schema,value))&&(!IsContains(schema)||CheckContains( +stack,context,schema,value))&&(!IsItems(schema)||CheckItems(stack,context,schema,value))&&(!IsMaxContains(schema)||CheckMaxContains(stack,context,schema,value))&&(!IsMaxItems(schema)||CheckMaxItems(stack,context,schema,value))&&(!IsMinContains(schema)||CheckMinContains(stack,context,schema,value))&&(!IsMinItems(schema)||CheckMinItems(stack,context,schema,value))&&(!IsPrefixItems(schema)||CheckPrefixItems(stack,context,schema,value))&&(!IsUniqueItems(schema)||CheckUniqueItems(stack,context,schema, +value)))&&(!guard_exports.IsString(value)||(!IsMaxLength4(schema)||CheckMaxLength(stack,context,schema,value))&&(!IsMinLength4(schema)||CheckMinLength(stack,context,schema,value))&&(!IsFormat(schema)||CheckFormat(stack,context,schema,value))&&(!IsPattern(schema)||CheckPattern(stack,context,schema,value)))&&(!(guard_exports.IsNumber(value)||guard_exports.IsBigInt(value))||(!IsExclusiveMaximum(schema)||CheckExclusiveMaximum(stack,context,schema,value))&&(!IsExclusiveMinimum(schema)||CheckExclusiveMinimum( +stack,context,schema,value))&&(!IsMaximum(schema)||CheckMaximum(stack,context,schema,value))&&(!IsMinimum(schema)||CheckMinimum(stack,context,schema,value))&&(!IsMultipleOf2(schema)||CheckMultipleOf(stack,context,schema,value)))&&(!IsRef2(schema)||CheckRef(stack,context,schema,value))&&(!IsRecursiveRef(schema)||CheckRecursiveRef(stack,context,schema,value))&&(!IsDynamicRef(schema)||CheckDynamicRef(stack,context,schema,value))&&(!IsGuard2(schema)||CheckGuard(stack,context,schema,value))&&(!IsConst( +schema)||CheckConst(stack,context,schema,value))&&(!IsEnum2(schema)||CheckEnum(stack,context,schema,value))&&(!IsIf(schema)||CheckIf(stack,context,schema,value))&&(!IsNot(schema)||CheckNot(stack,context,schema,value))&&(!IsAllOf(schema)||CheckAllOf(stack,context,schema,value))&&(!IsAnyOf(schema)||CheckAnyOf(stack,context,schema,value))&&(!IsOneOf(schema)||CheckOneOf(stack,context,schema,value))&&(!IsUnevaluatedItems(schema)||(!guard_exports.IsArray(value)||CheckUnevaluatedItems(stack,context,schema, +value)))&&(!IsUnevaluatedProperties(schema)||(!guard_exports.IsObject(value)||CheckUnevaluatedProperties(stack,context,schema,value)))&&(!IsRefine2(schema)||CheckRefine(stack,context,schema,value));stack.Pop(schema);return result}function ErrorSchemaPushStack(stack,context,schemaPath,instancePath,schema,value){return context.Push()&&ErrorSchema(stack,context,schemaPath,instancePath,schema,value)&&context.Pop()}function ErrorSchema(stack,context,schemaPath,instancePath,schema,value){stack.Push(schema); +const result=IsBooleanSchema(schema)?ErrorBooleanSchema(stack,context,schemaPath,instancePath,schema,value):!!(+(!IsType(schema)||ErrorType(stack,context,schemaPath,instancePath,schema,value))&+(!(guard_exports.IsObject(value)&&!guard_exports.IsArray(value))||!!(+(!IsRequired(schema)||ErrorRequired(stack,context,schemaPath,instancePath,schema,value))&+(!IsAdditionalProperties(schema)||ErrorAdditionalProperties(stack,context,schemaPath,instancePath,schema,value))&+(!IsDependencies(schema)||ErrorDependencies( +stack,context,schemaPath,instancePath,schema,value))&+(!IsDependentRequired(schema)||ErrorDependentRequired(stack,context,schemaPath,instancePath,schema,value))&+(!IsDependentSchemas(schema)||ErrorDependentSchemas(stack,context,schemaPath,instancePath,schema,value))&+(!IsPatternProperties(schema)||ErrorPatternProperties(stack,context,schemaPath,instancePath,schema,value))&+(!IsProperties(schema)||ErrorProperties(stack,context,schemaPath,instancePath,schema,value))&+(!IsPropertyNames(schema)||ErrorPropertyNames( +stack,context,schemaPath,instancePath,schema,value))&+(!IsMinProperties(schema)||ErrorMinProperties(stack,context,schemaPath,instancePath,schema,value))&+(!IsMaxProperties(schema)||ErrorMaxProperties(stack,context,schemaPath,instancePath,schema,value))))&+(!guard_exports.IsArray(value)||!!(+(!IsAdditionalItems(schema)||ErrorAdditionalItems(stack,context,schemaPath,instancePath,schema,value))&+(!IsContains(schema)||ErrorContains(stack,context,schemaPath,instancePath,schema,value))&+(!IsItems(schema)|| +ErrorItems(stack,context,schemaPath,instancePath,schema,value))&+(!IsMaxContains(schema)||ErrorMaxContains(stack,context,schemaPath,instancePath,schema,value))&+(!IsMaxItems(schema)||ErrorMaxItems(stack,context,schemaPath,instancePath,schema,value))&+(!IsMinContains(schema)||ErrorMinContains(stack,context,schemaPath,instancePath,schema,value))&+(!IsMinItems(schema)||ErrorMinItems(stack,context,schemaPath,instancePath,schema,value))&+(!IsPrefixItems(schema)||ErrorPrefixItems(stack,context,schemaPath, +instancePath,schema,value))&+(!IsUniqueItems(schema)||ErrorUniqueItems(stack,context,schemaPath,instancePath,schema,value))))&+(!guard_exports.IsString(value)||!!(+(!IsMaxLength4(schema)||ErrorMaxLength(stack,context,schemaPath,instancePath,schema,value))&+(!IsMinLength4(schema)||ErrorMinLength(stack,context,schemaPath,instancePath,schema,value))&+(!IsFormat(schema)||ErrorFormat(stack,context,schemaPath,instancePath,schema,value))&+(!IsPattern(schema)||ErrorPattern(stack,context,schemaPath,instancePath, +schema,value))))&+(!(guard_exports.IsNumber(value)||guard_exports.IsBigInt(value))||!!(+(!IsExclusiveMaximum(schema)||ErrorExclusiveMaximum(stack,context,schemaPath,instancePath,schema,value))&+(!IsExclusiveMinimum(schema)||ErrorExclusiveMinimum(stack,context,schemaPath,instancePath,schema,value))&+(!IsMaximum(schema)||ErrorMaximum(stack,context,schemaPath,instancePath,schema,value))&+(!IsMinimum(schema)||ErrorMinimum(stack,context,schemaPath,instancePath,schema,value))&+(!IsMultipleOf2(schema)|| +ErrorMultipleOf(stack,context,schemaPath,instancePath,schema,value))))&+(!IsRef2(schema)||ErrorRef(stack,context,schemaPath,instancePath,schema,value))&+(!IsRecursiveRef(schema)||ErrorRecursiveRef(stack,context,schemaPath,instancePath,schema,value))&+(!IsDynamicRef(schema)||ErrorDynamicRef(stack,context,schemaPath,instancePath,schema,value))&+(!IsGuard2(schema)||ErrorGuard(stack,context,schemaPath,instancePath,schema,value))&+(!IsConst(schema)||ErrorConst(stack,context,schemaPath,instancePath,schema, +value))&+(!IsEnum2(schema)||ErrorEnum(stack,context,schemaPath,instancePath,schema,value))&+(!IsIf(schema)||ErrorIf(stack,context,schemaPath,instancePath,schema,value))&+(!IsNot(schema)||ErrorNot(stack,context,schemaPath,instancePath,schema,value))&+(!IsAllOf(schema)||ErrorAllOf(stack,context,schemaPath,instancePath,schema,value))&+(!IsAnyOf(schema)||ErrorAnyOf(stack,context,schemaPath,instancePath,schema,value))&+(!IsOneOf(schema)||ErrorOneOf(stack,context,schemaPath,instancePath,schema,value))& ++(!IsUnevaluatedItems(schema)||(!guard_exports.IsArray(value)||ErrorUnevaluatedItems(stack,context,schemaPath,instancePath,schema,value)))&+(!IsUnevaluatedProperties(schema)||(!guard_exports.IsObject(value)||ErrorUnevaluatedProperties(stack,context,schemaPath,instancePath,schema,value))))&&(!IsRefine2(schema)||ErrorRefine(stack,context,schemaPath,instancePath,schema,value));stack.Pop(schema);return result}var functions=new Map;function CreateCallExpression(context,_schema,hash,value){return context.UseUnevaluated()?emit_exports.Call(`check_${hash}`,["context",value]):emit_exports.Call(`check_${hash}`,[value])}function CreateFunctionExpression(stack,context,schema,hash){const expression=BuildSchema(stack,context,schema,"value");return context.UseUnevaluated()?emit_exports.ConstDeclaration(`check_${hash}`,emit_exports.ArrowFunction(["context","value"],expression)):emit_exports.ConstDeclaration(`che\ +ck_${hash}`,emit_exports.ArrowFunction(["value"],expression))}function ResetFunctions(){functions.clear()}function GetFunctions(){return[...functions.values()]}function CreateFunction(stack,context,schema,value){const hash=IsSchemaObject(schema)?hash_exports.Hash({__baseURL:stack.BaseURL().href,...schema}):hash_exports.Hash(schema);const call=CreateCallExpression(context,schema,hash,value);if(functions.has(hash))return call;functions.set(hash,"");functions.set(hash,CreateFunctionExpression(stack, +context,schema,hash));return call}var resolve_exports={};__export(resolve_exports,{DynamicRef:()=>DynamicRef,Ref:()=>Ref2});var pointer_exports={};__export(pointer_exports,{Delete:()=>Delete,Get:()=>Get4,Has:()=>Has2,Indices:()=>Indices,Set:()=>Set4});function AssertNotRoot(indices){if(indices.length===0)throw Error("Cannot set root")}function AssertCanSet(value){if(!guard_exports.IsObject(value))throw Error("Cannot set value")}function AssertIndex(index2){if(guard_exports.IsUnsafePropertyKey(index2))throw Error("Pointer contains unsafe property key")}function AssertIndices(indices){for(const index2 of indices)AssertIndex(index2)}function IsNumericIndex(index2){return/^(0|[1-9]\d*)$/.test(index2)}function TakeIndexRight(indices){return[indices. +slice(0,indices.length-1),indices.slice(indices.length-1)[0]]}function HasIndex(index2,value){return guard_exports.IsObject(value)&&guard_exports.HasPropertyKey(value,index2)}function GetIndex(index2,value){return guard_exports.IsObject(value)&&!guard_exports.IsUnsafePropertyKey(index2)?value[index2]:void 0}function GetIndices(indices,value){return indices.reduce((value2,index2)=>GetIndex(index2,value2),value)}function Indices(pointer){if(guard_exports.IsEqual(pointer.length,0))return[];const indices=pointer. +split("/").map(index2=>index2.replace(/~1/g,"/").replace(/~0/g,"~"));return indices.length>0&&indices[0]===""?indices.slice(1):indices}function Has2(value,pointer){let current=value;return Indices(pointer).every(index2=>{if(!HasIndex(index2,current))return false;current=current[index2];return true})}function Get4(value,pointer){const indices=Indices(pointer);return GetIndices(indices,value)}function Set4(value,pointer,next){const indices=Indices(pointer);AssertNotRoot(indices);AssertIndices(indices); +const[head,index2]=TakeIndexRight(indices);const parent=GetIndices(head,value);AssertCanSet(parent);parent[index2]=next;return value}function Delete(value,pointer){const indices=Indices(pointer);AssertNotRoot(indices);AssertIndices(indices);const[head,index2]=TakeIndexRight(indices);const parent=GetIndices(head,value);AssertCanSet(parent);if(guard_exports.IsArray(parent)&&IsNumericIndex(index2)){parent.splice(+index2,1)}else{delete parent[index2]}return value}function MatchId(schema,base,ref){if(schema.$id===ref.hash)return schema;const absoluteId=new URL(schema.$id,base.href);const absoluteRef=new URL(ref.href,base.href);if(guard_exports.IsEqual(absoluteId.pathname,absoluteRef.pathname)){return ref.hash.startsWith("#")?MatchHash(schema,base,ref):schema}return void 0}function MatchAnchor(schema,base,ref){const absoluteAnchor=new URL(`#${schema.$anchor}`,base.href);const absoluteRef=new URL(ref.href,base.href);return guard_exports.IsEqual(absoluteAnchor. +href,absoluteRef.href)?schema:void 0}function MatchDynamicAnchor(schema,base,ref){const absoluteAnchor=new URL(`#${schema.$dynamicAnchor}`,base.href);const absoluteRef=new URL(ref.href,base.href);return guard_exports.IsEqual(absoluteAnchor.href,absoluteRef.href)?schema:void 0}function MatchHash(schema,_base,ref){if(ref.href.endsWith("#"))return schema;if(!ref.hash.startsWith("#"))return void 0;const fragment=decodeURIComponent(ref.hash.slice(1));if(!fragment.startsWith("/"))return void 0;return pointer_exports. +Get(schema,fragment)}function Match4(schema,base,ref){if(IsId(schema)){const result=MatchId(schema,base,ref);if(!guard_exports.IsUndefined(result))return result}if(IsAnchor(schema)){const result=MatchAnchor(schema,base,ref);if(!guard_exports.IsUndefined(result))return result}if(IsDynamicAnchor(schema)){const result=MatchDynamicAnchor(schema,base,ref);if(!guard_exports.IsUndefined(result))return result}return MatchHash(schema,base,ref)}function FromArray6(schema,base,ref){return schema.reduce((result,item)=>{ +const match=FromValue3(item,base,ref);return!guard_exports.IsUndefined(match)?match:result},void 0)}function FromObject9(schema,base,ref){return guard_exports.Keys(schema).reduce((result,key)=>{const match=FromValue3(schema[key],base,ref);return!guard_exports.IsUndefined(match)?match:result},void 0)}function FromValue3(schema,base,ref){const nextBase=IsSchemaObject(schema)&&IsId(schema)?new URL(schema.$id,base.href):base;if(IsSchemaObject(schema)){const result=Match4(schema,nextBase,ref);if(!guard_exports. +IsUndefined(result))return result}if(guard_exports.IsArray(schema))return FromArray6(schema,nextBase,ref);if(guard_exports.IsObject(schema))return FromObject9(schema,nextBase,ref);return void 0}function Ref2(schema,ref){const defaultBase=new URL("http://unknown/");const initialBase=IsId(schema)?new URL(schema.$id,defaultBase.href):defaultBase;const initialRef=new URL(ref,initialBase.href);return FromValue3(schema,initialBase,initialRef)}function DynamicRef(root,base,dynamicRef,dynamicAnchors){const fragmentTarget=dynamicRef. +$dynamicRef.startsWith("#")?Ref2(base,dynamicRef.$dynamicRef):Ref2(root,dynamicRef.$dynamicRef);if(guard_exports.IsUndefined(fragmentTarget))return void 0;if(!IsSchemaObject(fragmentTarget)||!IsDynamicAnchor(fragmentTarget))return fragmentTarget;const fragment=new URL(dynamicRef.$dynamicRef,"http://unknown/").hash;if(fragment.startsWith("#/"))return fragmentTarget;const anchorTarget=dynamicAnchors.find(anchor=>anchor.$dynamicAnchor===fragmentTarget.$dynamicAnchor);return anchorTarget??fragmentTarget}var __classPrivateFieldGet=function(receiver,state2,kind,f){if(kind==="a"&&!f)throw new TypeError("Private accessor was defined without a getter");if(typeof state2==="function"?receiver!==state2||!f:!state2.has(receiver))throw new TypeError("Cannot read private member from an object whose class did not declare it");return kind==="m"?f:kind==="a"?f.call(receiver):f?f.value:state2.get(receiver)};var _Stack_instances;var _Stack_PushResourceAnchors;var _Stack_PopResourceAnchors;var _Stack_FromContext; +var _Stack_FromRef;var Stack=class{constructor(context,schema){_Stack_instances.add(this);this.context=context;this.schema=schema;this.ids=[];this.anchors=[];this.recursiveAnchors=[];this.dynamicAnchors=[]}BaseURL(){return this.ids.reduce((result,schema)=>new URL(schema.$id,result),new URL("http://unknown"))}Base(){return this.ids[this.ids.length-1]??this.schema}Push(schema){if(!IsSchemaObject(schema))return;if(IsId(schema)){this.ids.push(schema);__classPrivateFieldGet(this,_Stack_instances,"m", +_Stack_PushResourceAnchors).call(this,schema)}if(IsAnchor(schema))this.anchors.push(schema);if(IsRecursiveAnchorTrue(schema))this.recursiveAnchors.push(schema);if(IsDynamicAnchor(schema))this.dynamicAnchors.push(schema)}Pop(schema){if(!IsSchemaObject(schema))return;if(IsId(schema)){this.ids.pop();__classPrivateFieldGet(this,_Stack_instances,"m",_Stack_PopResourceAnchors).call(this,schema)}if(IsAnchor(schema))this.anchors.pop();if(IsRecursiveAnchorTrue(schema))this.recursiveAnchors.pop();if(IsDynamicAnchor( +schema))this.dynamicAnchors.pop()}Ref(ref){return __classPrivateFieldGet(this,_Stack_instances,"m",_Stack_FromContext).call(this,ref)??__classPrivateFieldGet(this,_Stack_instances,"m",_Stack_FromRef).call(this,ref)}RecursiveRef(recursiveRef){return IsRecursiveAnchorTrue(this.Base())?resolve_exports.Ref(this.recursiveAnchors[0],recursiveRef.$recursiveRef):resolve_exports.Ref(this.Base(),recursiveRef.$recursiveRef)}DynamicRef(dynamicRef){const root=this.schema;return resolve_exports.DynamicRef(root, +this.Base(),dynamicRef,this.dynamicAnchors)}};_Stack_instances=new WeakSet,_Stack_PushResourceAnchors=function _Stack_PushResourceAnchors2(schema,isRoot=true){if(!IsSchemaObject(schema))return;const current=schema;if(!isRoot&&IsId(current))return;if(!isRoot&&IsDynamicAnchor(current))this.dynamicAnchors.push(current);for(const key of guard_exports.Keys(current))__classPrivateFieldGet(this,_Stack_instances,"m",_Stack_PushResourceAnchors2).call(this,current[key],false)},_Stack_PopResourceAnchors=function _Stack_PopResourceAnchors2(schema,isRoot=true){ +if(!IsSchemaObject(schema))return;const current=schema;if(!isRoot&&IsId(current))return;if(!isRoot&&IsDynamicAnchor(current))this.dynamicAnchors.pop();for(const key of guard_exports.Keys(current))__classPrivateFieldGet(this,_Stack_instances,"m",_Stack_PopResourceAnchors2).call(this,current[key],false)},_Stack_FromContext=function _Stack_FromContext2(ref){return guard_exports.HasPropertyKey(this.context,ref.$ref)?this.context[ref.$ref]:void 0},_Stack_FromRef=function _Stack_FromRef2(ref){const root=this. +schema;return!ref.$ref.startsWith("#")?resolve_exports.Ref(root,ref.$ref):resolve_exports.Ref(this.Base(),ref.$ref)};function CreateCode(build){const functions2=build.Functions().join(";\n");const statements=build.UseUnevaluated()?["const context = new CheckContext({}, {})",`return ${build.Entry()}`]:[`return ${build.Entry()}`];return`${functions2}; return (value) => { ${statements.join("; ")} }`}function CreateEvaluatedCheck(build,code){const factory=environment_exports.Evaluate("CheckContext","Guard","Format","Hashing",build.External().identifier,code);return factory(CheckContext,guard_exports,format_exports, +hash_exports,build.External().variables)}function CreateDynamicCheck(build){const stack=new Stack(build.Context(),build.Schema());const context=new CheckContext;return value=>CheckSchema(stack,context,build.Schema(),value)}function CreateCheck(build,code){return environment_exports.CanEvaluate()?CreateEvaluatedCheck(build,code):CreateDynamicCheck(build)}var EvaluateResult=class{constructor(isAccelerated,code,check){this.isAccelerated=isAccelerated;this.code=code;this.check=check}IsAccelerated(){ +return this.isAccelerated}Code(){return this.code}Check(value){return this.check(value)}};var BuildResult=class{constructor(context,schema,external,functions2,entry,useUnevaluated){this.context=context;this.schema=schema;this.external=external;this.functions=functions2;this.entry=entry;this.useUnevaluated=useUnevaluated}Context(){return this.context}Schema(){return this.schema}UseUnevaluated(){return this.useUnevaluated}External(){return this.external}Functions(){return this.functions}Entry(){return this. +entry}Evaluate(){const code=CreateCode(this);const check=CreateCheck(this,code);return new EvaluateResult(environment_exports.CanEvaluate(),code,check)}};function Build(...args){const[context,schema]=arguments_exports.Match(args,{2:(context2,schema2)=>[context2,schema2],1:schema2=>[{},schema2]});ResetExternal();ResetFunctions();const stack=new Stack(context,schema);const build=new BuildContext(HasUnevaluated(context,schema));const call=CreateFunction(stack,build,schema,"value");const functions2=GetFunctions(); +const externals=GetExternal();return new BuildResult(context,schema,externals,functions2,call,build.UseUnevaluated())}function Errors(...args){const[context,schema,value]=arguments_exports.Match(args,{3:(context2,schema2,value2)=>[context2,schema2,value2],2:(schema2,value2)=>[{},schema2,value2]});const settings2=settings_exports.Get();const locale2=Get2();const errors=[];const stack=new Stack(context,schema);const errorContext=new ErrorContext(error=>{if(guard_exports.IsGreaterEqualThan(errors.length,settings2.maxErrors))return;return errors.push({...error,message:locale2(error)})});const result=ErrorSchema(stack, +errorContext,"#","",schema,value);return[result,errors]}function Check(...args){const[context,schema,value]=arguments_exports.Match(args,{3:(context2,schema2,value2)=>[context2,schema2,value2],2:(schema2,value2)=>[{},schema2,value2]});const stack=new Stack(context,schema);const checkContext=new CheckContext;return CheckSchema(stack,checkContext,schema,value)}function Check2(...args){const[context,type,value]=arguments_exports.Match(args,{3:(context2,type2,value2)=>[context2,type2,value2],2:(type2,value2)=>[{},type2,value2]});return Check(context,type,value)}function Errors2(...args){const[context,type,value]=arguments_exports.Match(args,{3:(context2,type2,value2)=>[context2,type2,value2],2:(type2,value2)=>[{},type2,value2]});const[_,errors]=Errors(context,type,value);return errors}var AssertError=class extends Error{constructor(source,value,errors){super(source);Object.defineProperty(this,"cause",{value:{source,errors,value},writable:false,configurable:false,enumerable:false})}};function Assert(...args){const[context,type,value]=arguments_exports.Match(args,{3:(context2,type2,value2)=>[context2,type2,value2],2:(type2,value2)=>[{},type2,value2]});const check=Check2(context,type,value);if(!check)throw new AssertError("Assert",value,Errors2(context,type,value))}function FromArray7(context,type,value){if(!guard_exports.IsArray(value))return value;return value.map(value2=>FromType19(context,type.items,value2))}function FromBase(_context,type,value){return type.Clean(value)}function FromCyclic6(context,type,value){return FromType19({...context,...type.$defs},Ref(type.$ref),value)}function EvaluateIntersection(context,type){const additionalProperties=guard_exports.HasPropertyKey(type,"unevaluatedProperties")?{additionalProperties:type.unevaluatedProperties}:{};const instantiated=Instantiate(context,type);const evaluated=Evaluate2(instantiated);return IsObject3(evaluated)?Options(evaluated,additionalProperties):evaluated}function FromIntersect6(context,type,value){const evaluated=EvaluateIntersection(context,type);return FromType19(context,evaluated,value)}function GetAdditionalProperties(type){const additionalProperties=guard_exports.HasPropertyKey(type,"additionalProperties")?type.additionalProperties:void 0;return additionalProperties}function FromObject10(context,type,value){if(!guard_exports.IsObject(value)||guard_exports.IsArray(value))return value;const additionalProperties=GetAdditionalProperties(type);for(const key of guard_exports.Keys(value)){if(guard_exports.HasPropertyKey(type.properties,key)){value[key]=FromType19(context,type.properties[key],value[key]);continue}const unknownCheck=guard_exports.IsBoolean(additionalProperties)&&guard_exports.IsEqual(additionalProperties,true)||IsSchema(additionalProperties)&&Check2( +context,additionalProperties,value[key]);if(unknownCheck){value[key]=FromType19(context,additionalProperties,value[key]);continue}delete value[key]}return value}function FromRecord2(context,type,value){if(!guard_exports.IsObject(value))return value;const additionalProperties=GetAdditionalProperties(type);const[recordPattern,recordValue]=[new RegExp(RecordPattern(type)),RecordValue(type)];for(const key of guard_exports.Keys(value)){if(recordPattern.test(key)){value[key]=FromType19(context,recordValue,value[key]);continue}const unknownCheck=guard_exports.IsBoolean(additionalProperties)&&guard_exports.IsEqual(additionalProperties,true)||IsSchema(additionalProperties)&& +Check2(context,additionalProperties,value[key]);if(unknownCheck){value[key]=FromType19(context,additionalProperties,value[key]);continue}delete value[key]}return value}function FromRef5(context,type,value){return guard_exports.HasPropertyKey(context,type.$ref)?FromType19(context,context[type.$ref],value):value}function FromTuple5(context,schema,value){if(!guard_exports.IsArray(value))return value;const length=Math.min(value.length,schema.items.length);for(let index2=0;index2Clone2( +element))}function FromTypedArray(value){return value.slice()}function FromMap(value){return new Map(Clone2([...value.entries()]))}function FromSet(value){return new Set(Clone2([...value.values()]))}function FromValue4(value){return value}function Clone2(value){return globals_exports.IsTypeArray(value)?FromTypedArray(value):globals_exports.IsMap(value)?FromMap(value):globals_exports.IsSet(value)?FromSet(value):guard_exports.IsArray(value)?FromArray8(value):guard_exports.IsObject(value)?FromObject11( +value):FromValue4(value)}function DeterministicCompare(left,right){return JSON.stringify(left).localeCompare(JSON.stringify(right))}function UnionPrioritySort(types,order=1){return types.sort((left,right)=>{const result=Compare(left,right);return(guard_exports.IsEqual(result,"disjoint")?DeterministicCompare(left,right):guard_exports.IsEqual(result,"right-inside")?1:guard_exports.IsEqual(result,"left-inside")?-1:DeterministicCompare(left,right))*order})}function FromUnion9(context,type,value){for(const schema of UnionPrioritySort(type.anyOf)){const clean=FromType19(context,schema,Clone2(value));if(Check2(context,schema,clean))return clean}return value}function FromType19(context,type,value){return IsArray3(type)?FromArray7(context,type,value):IsBase(type)?FromBase(context,type,value):IsCyclic(type)?FromCyclic6(context,type,value):IsIntersect(type)?FromIntersect6(context,type,value):IsObject3(type)?FromObject10(context,type,value):IsRecord(type)?FromRecord2(context,type,value):IsRef(type)?FromRef5(context,type,value):IsTuple(type)?FromTuple5(context,type,value):IsUnion(type)?FromUnion9(context,type,value):value}function Clean(...args){const[context,type,value]=arguments_exports.Match(args,{3:(context2,type2,value2)=>[context2,type2,value2],2:(type2,value2)=>[{},type2,value2]});return FromType19(context,type,value)}var try_exports={};__export(try_exports,{Fail:()=>Fail,IsOk:()=>IsOk,Ok:()=>Ok,TryArray:()=>TryArray,TryBigInt:()=>TryBigInt,TryBoolean:()=>TryBoolean,TryNull:()=>TryNull,TryNumber:()=>TryNumber,TryString:()=>TryString,TryUndefined:()=>TryUndefined});function IsOk(value){return guard_exports.IsObject(value)&&guard_exports.HasPropertyKey(value,"value")}function Ok(value){return{value}}function Fail(){return void 0}function TryArray(value){return guard_exports.IsArray(value)?Ok(value):Ok([value])}function FromBoolean2(value){return guard_exports.IsEqual(value,true)?Ok(BigInt(1)):Ok(BigInt(0))}var bigintPattern=/^-?(0|[1-9]\d*)n$/;var decimalPattern=/^-?(0|[1-9]\d*)\.\d+$/;var integerPattern=/^-?(0|[1-9]\d*)$/;function IsStringBigIntLike(value){return bigintPattern.test(value)}function IsStringDecimalLike(value){return decimalPattern.test(value)}function IsStringIntegerLike(value){return integerPattern.test(value)}function FromString2(value){const lowercase=value.toLowerCase();return IsStringBigIntLike( +value)?Ok(BigInt(value.slice(0,value.length-1))):IsStringDecimalLike(value)?Ok(BigInt(value.split(".")[0])):IsStringIntegerLike(value)?Ok(BigInt(value)):guard_exports.IsEqual(lowercase,"false")?Ok(BigInt(0)):guard_exports.IsEqual(lowercase,"true")?Ok(BigInt(1)):Fail()}function TryBigInt(value){return guard_exports.IsBigInt(value)?Ok(value):guard_exports.IsBoolean(value)?FromBoolean2(value):guard_exports.IsNumber(value)?Ok(BigInt(Math.trunc(value))):guard_exports.IsNull(value)?Ok(BigInt(0)):guard_exports. +IsString(value)?FromString2(value):guard_exports.IsUndefined(value)?Ok(BigInt(0)):Fail()}function FromBigInt2(value){return guard_exports.IsEqual(value,BigInt(0))?Ok(false):guard_exports.IsEqual(value,BigInt(1))?Ok(true):Fail()}function FromNumber2(value){return guard_exports.IsEqual(value,0)?Ok(false):guard_exports.IsEqual(value,1)?Ok(true):Fail()}function FromString3(value){return guard_exports.IsEqual(value.toLowerCase(),"false")?Ok(false):guard_exports.IsEqual(value.toLowerCase(),"true")?Ok(true):guard_exports.IsEqual(value,"0")?Ok(false):guard_exports.IsEqual(value,"1")?Ok(true): +Fail()}function TryBoolean(value){return guard_exports.IsBigInt(value)?FromBigInt2(value):guard_exports.IsBoolean(value)?Ok(value):guard_exports.IsNumber(value)?FromNumber2(value):guard_exports.IsNull(value)?Ok(false):guard_exports.IsString(value)?FromString3(value):guard_exports.IsUndefined(value)?Ok(false):Fail()}function FromBigInt3(value){return guard_exports.IsEqual(value,BigInt(0))?Ok(null):Fail()}function FromBoolean3(value){return guard_exports.IsEqual(value,false)?Ok(null):Fail()}function FromNumber3(value){return guard_exports.IsEqual(value,0)?Ok(null):Fail()}function FromString4(value){const lowercase=value.toLowerCase();const predicate=guard_exports.IsEqual(lowercase,"undefined")||guard_exports.IsEqual(lowercase,"null")||guard_exports.IsEqual(value,"")||guard_exports.IsEqual(value,"0");return predicate? +Ok(null):Fail()}function TryNull(value){return guard_exports.IsBigInt(value)?FromBigInt3(value):guard_exports.IsBoolean(value)?FromBoolean3(value):guard_exports.IsNumber(value)?FromNumber3(value):guard_exports.IsNull(value)?Ok(null):guard_exports.IsString(value)?FromString4(value):guard_exports.IsUndefined(value)?Ok(null):Fail()}var maxBigInt=BigInt(Number.MAX_SAFE_INTEGER);var minBigInt=BigInt(Number.MIN_SAFE_INTEGER);function FromBigInt4(value){return value<=maxBigInt&&value>=minBigInt?Ok(Number(value)):Fail()}function FromBoolean4(value){return Ok(value?1:0)}function FromString5(value){const coerced=+value;if(guard_exports.IsNumber(coerced))return Ok(coerced);const lowercase=value.toLowerCase();if(guard_exports.IsEqual(lowercase,"false"))return Ok(0);if(guard_exports.IsEqual(lowercase,"true"))return Ok(1);const result=TryBigInt( +value);if(IsOk(result))return result.value<=maxBigInt&&result.value>=minBigInt?Ok(Number(result.value)):Fail();return Fail()}function TryNumber(value){return guard_exports.IsBigInt(value)?FromBigInt4(value):guard_exports.IsBoolean(value)?FromBoolean4(value):guard_exports.IsNumber(value)?Ok(value):guard_exports.IsNull(value)?Ok(0):guard_exports.IsString(value)?FromString5(value):guard_exports.IsUndefined(value)?Ok(0):Fail()}function TryString(value){return guard_exports.IsBigInt(value)?Ok(value.toString()):guard_exports.IsBoolean(value)?Ok(value.toString()):guard_exports.IsNumber(value)?Ok(value.toString()):guard_exports.IsNull(value)?Ok("null"):guard_exports.IsString(value)?Ok(value):guard_exports.IsUndefined(value)?Ok(""):Fail()}function FromBigInt5(value){return guard_exports.IsEqual(value,BigInt(0))?Ok(void 0):Fail()}function FromBoolean5(value){return guard_exports.IsEqual(value,false)?Ok(void 0):Fail()}function FromNumber4(value){return guard_exports.IsEqual(value,0)?Ok(void 0):Fail()}function FromString6(value){const lowercase=value.toLowerCase();const predicate=guard_exports.IsEqual(lowercase,"undefined")||guard_exports.IsEqual(lowercase,"null")||guard_exports.IsEqual(value,"")||guard_exports.IsEqual(value,"0");return predicate? +Ok(void 0):Fail()}function TryUndefined(value){return guard_exports.IsBigInt(value)?FromBigInt5(value):guard_exports.IsBoolean(value)?FromBoolean5(value):guard_exports.IsNumber(value)?FromNumber4(value):guard_exports.IsNull(value)?Ok(void 0):guard_exports.IsString(value)?FromString6(value):guard_exports.IsUndefined(value)?Ok(value):Fail()}function FromArray9(context,type,value){const result=try_exports.TryArray(value);return result.value.map(value2=>FromType20(context,type.items,value2))}function FromBase2(_context,type,value){return type.Convert(value)}function FromBigInt6(_context,_type,value){const result=try_exports.TryBigInt(value);return try_exports.IsOk(result)?result.value:value}function FromBoolean6(_context,_type,value){const result=try_exports.TryBoolean(value);return try_exports.IsOk(result)?result.value:value}function FromCyclic7(context,type,value){return FromType20({...context,...type.$defs},Ref(type.$ref),value)}function FromUnion10(context,type,value){const matched=type.anyOf.some(type2=>Check2(context,type2,value));if(matched)return value;const candidates=type.anyOf.map(type2=>FromType20(context,type2,Clone2(value)));const selected=candidates.find(value2=>Check2(context,type,value2));return guard_exports.IsUndefined(selected)?value:selected}function FromEnum2(context,type,value){const union=EnumToUnion(type);return FromUnion10(context,union,value)}function FromInteger(_context,_type,value){const result=try_exports.TryNumber(value);return try_exports.IsOk(result)?Math.trunc(result.value):value}function FromIntersect7(context,type,value){const instantiated=Instantiate(context,type);const evaluated=Evaluate2(instantiated);return FromType20(context,evaluated,value)}function FromLiteralBigInt(_context,type,value){const result=try_exports.TryBigInt(value);return try_exports.IsOk(result)&&guard_exports.IsEqual(type.const,result.value)?result.value:value}function FromLiteralBoolean(_context,type,value){const result=try_exports.TryBoolean(value);return try_exports.IsOk(result)&&guard_exports.IsEqual(type.const,result.value)?result.value:value}function FromLiteralNumber(_context,type,value){const result=try_exports.TryNumber(value);return try_exports.IsOk(result)&& +guard_exports.IsEqual(type.const,result.value)?result.value:value}function FromLiteralString(_context,type,value){const result=try_exports.TryString(value);return try_exports.IsOk(result)&&guard_exports.IsEqual(type.const,result.value)?result.value:value}function FromLiteral6(context,type,value){if(guard_exports.IsEqual(type.const,value))return value;return IsLiteralBigInt(type)?FromLiteralBigInt(context,type,value):IsLiteralBoolean(type)?FromLiteralBoolean(context,type,value):IsLiteralNumber(type)? +FromLiteralNumber(context,type,value):IsLiteralString(type)?FromLiteralString(context,type,value):Unreachable()}function FromNull2(_context,_type,value){const result=try_exports.TryNull(value);return try_exports.IsOk(result)?result.value:value}function FromNumber5(_context,_type,value){const result=try_exports.TryNumber(value);return try_exports.IsOk(result)?result.value:value}function FromAdditionalProperties(context,entries,additionalProperties,value){const keys=guard_exports.Keys(value);for(const[regexp,_]of entries){for(const key of keys){if(!regexp.test(key)){value[key]=FromType20(context,additionalProperties,value[key])}}}return value}function IsOptionalUndefined(property,key,value){return IsOptional(property)&&guard_exports.IsUndefined(value[key])}function FromProperties4(context,type,value){const entries=guard_exports.EntriesRegExp(type.properties);const keys=guard_exports.Keys(value);for(const[regexp,property]of entries){for(const key of keys){if(!regexp.test(key)||IsOptionalUndefined(property,key,value))continue;value[key]=FromType20(context,property,value[key])}}return guard_exports.HasPropertyKey(type,"additionalProperties")&&guard_exports.IsObject(type.additionalProperties)?FromAdditionalProperties(context,entries,type.additionalProperties, +value):value}function FromObject12(context,type,value){return guard_exports.IsObjectNotArray(value)?FromProperties4(context,type,value):value}function FromPatternProperties(context,type,value){const entries=guard_exports.EntriesRegExp(type.patternProperties);const keys=guard_exports.Keys(value);for(const[regexp,schema]of entries){for(const key of keys){if(regexp.test(key)){value[key]=FromType20(context,schema,value[key])}}}return guard_exports.HasPropertyKey(type,"additionalProperties")&&guard_exports.IsObject(type.additionalProperties)?FromAdditionalProperties(context,entries,type.additionalProperties,value):value}function FromRecord3(context,type,value){ +return guard_exports.IsObjectNotArray(value)?FromPatternProperties(context,type,value):value}function FromRef6(context,type,value){return guard_exports.HasPropertyKey(context,type.$ref)?FromType20(context,context[type.$ref],value):value}function FromString7(_context,_type,value){const result=try_exports.TryString(value);return try_exports.IsOk(result)?result.value:value}function FromTemplateLiteral4(context,type,value){const decoded=TemplateLiteralDecode(type.pattern);return FromType20(context,decoded,value)}function FromTuple6(context,type,value){if(!guard_exports.IsArray(value))return value;for(let index2=0;index2[context2,type2,value2],2:(type2,value2)=>[{},type2,value2]});return FromType20(context,type,value)}function FromArray10(context,type,value){if(!guard_exports.IsArray(value))return value;for(let i=0;i[context2,type2,value2],2:(type2,value2)=>[{},type2,value2]});return FromType21(context,type,value)}function Pipeline(pipeline){return(...args)=>{const[context,type,value]=arguments_exports.Match(args,{3:(context2,type2,value2)=>[context2,type2,value2],2:(type2,value2)=>[{},type2,value2]});return pipeline.reduce((result,func)=>func(context,type,result),value)}}function Decode2(_context,type,value){return type["~codec"].decode(value)}function Encode(_context,type,value){return type["~codec"].encode(value)}function Callback(direction,context,type,value){if(!IsCodec(type))return value;return guard_exports.IsEqual(direction,"Decode")?Decode2(context,type,value):Encode(context,type,value)}function Decode3(direction,context,type,value){if(!guard_exports.IsArray(value))return Unreachable();for(let i=0;i({...results,...interior}),{})}function NonMatchingInterior(value,interiors){for(const interior of interiors)if(!guard_exports.IsDeepEqual(value,interior))return interior;return value}function Decode4(direction,context,type,value){if(guard_exports.IsEqual(type.allOf.length,0))return Callback(direction,context,type,value);const interiors=type.allOf.map(schema=>FromType22(direction,context,schema,Clean(schema,Clone2(value)))); +const structural=interiors.every(result=>guard_exports.IsObject(result));const exterior=structural?MergeInteriors(interiors):NonMatchingInterior(value,interiors);return Callback(direction,context,type,exterior)}function Encode3(direction,context,type,value){if(guard_exports.IsEqual(type.allOf.length,0))return Callback(direction,context,type,value);const exterior=Callback(direction,context,type,value);const interiors=type.allOf.map(schema=>FromType22(direction,context,schema,Clean(schema,Clone2(exterior)))); +const structural=interiors.every(result=>guard_exports.IsObject(result));if(structural)return MergeInteriors(interiors);return NonMatchingInterior(exterior,interiors)}function FromIntersect9(direction,context,type,value){return guard_exports.IsEqual(direction,"Decode")?Decode4(direction,context,type,value):Encode3(direction,context,type,value)}function Decode5(direction,context,type,value){if(!guard_exports.IsObjectNotArray(value))return Unreachable();for(const key of guard_exports.Keys(type.properties)){if(!guard_exports.HasPropertyKey(value,key)||IsOptionalUndefined(type.properties[key],key,value))continue;value[key]=FromType22(direction,context,type.properties[key],value[key])}return Callback(direction,context,type,value)}function Encode4(direction,context,type,value){const exterior=Callback(direction,context,type,value);if(!guard_exports. +IsObjectNotArray(exterior))return exterior;for(const key of guard_exports.Keys(type.properties)){if(!guard_exports.HasPropertyKey(exterior,key)||IsOptionalUndefined(type.properties[key],key,exterior))continue;exterior[key]=FromType22(direction,context,type.properties[key],exterior[key])}return exterior}function FromObject14(direction,context,type,value){return guard_exports.IsEqual(direction,"Decode")?Decode5(direction,context,type,value):Encode4(direction,context,type,value)}function Decode6(direction,context,type,value){if(!guard_exports.IsObjectNotArray(value))return Unreachable();const regexp=new RegExp(RecordPattern(type));for(const key of guard_exports.Keys(value)){if(!regexp.test(key))Unreachable();value[key]=FromType22(direction,context,RecordValue(type),value[key])}return Callback(direction,context,type,value)}function Encode5(direction,context,type,value){const exterior=Callback(direction,context,type,value);if(!guard_exports.IsObjectNotArray(exterior))return exterior; +const regexp=new RegExp(RecordPattern(type));for(const key of guard_exports.Keys(exterior)){if(!regexp.test(key))continue;exterior[key]=FromType22(direction,context,RecordValue(type),exterior[key])}return exterior}function FromRecord5(direction,context,type,value){return guard_exports.IsEqual(direction,"Decode")?Decode6(direction,context,type,value):Encode5(direction,context,type,value)}function ResolveRef(direction,context,type,value){return guard_exports.HasPropertyKey(context,type.$ref)?FromType22(direction,context,context[type.$ref],value):value}function FromRef8(direction,context,type,value){return guard_exports.IsEqual(direction,"Decode")?Callback(direction,context,type,ResolveRef(direction,context,type,value)):ResolveRef(direction,context,type,Callback(direction,context,type,value))}function Decode7(direction,context,type,value){if(!guard_exports.IsArray(value))return Unreachable();for(let i=0;iClone2(value),(context,type,value)=>Default(context,type,value),(context,type,value)=>Convert(context,type,value),(context,type,value)=>Clean( +context,type,value),(context,type,value)=>Assert2(context,type,value),(context,type,value)=>DecodeUnsafe(context,type,value)]);function Decode9(...args){const[context,type,value]=arguments_exports.Match(args,{3:(context2,type2,value2)=>[context2,type2,value2],2:(type2,value2)=>[{},type2,value2]});return Decoder(context,type,value)}var EncodeError=class extends AssertError{constructor(value,errors){super("Encode",value,errors)}};function Assert3(context,type,value){if(!Check2(context,type,value))throw new EncodeError(value,Errors2(context,type,value));return value}function EncodeUnsafe(context,type,value){return FromType22("Encode",context,type,value)}var Encoder=Pipeline([(_context,_type,value)=>Clone2(value),(context,type,value)=>EncodeUnsafe(context,type,value),(context,type,value)=>Default(context,type,value),(context,type,value)=>Convert( +context,type,value),(context,type,value)=>Clean(context,type,value),(context,type,value)=>Assert3(context,type,value)]);function Encode8(...args){const[context,type,value]=arguments_exports.Match(args,{3:(context2,type2,value2)=>[context2,type2,value2],2:(type2,value2)=>[{},type2,value2]});return Encoder(context,type,value)}function FromArray12(context,type){return IsCodec(type)||FromType23(context,type.items)}function FromCyclic10(context,type){return IsCodec(type)||FromRef9({...context,...type.$defs},Ref(type.$ref))}function FromIntersect10(context,type){return IsCodec(type)||type.allOf.some(type2=>FromType23(context,type2))}function FromObject15(context,type){return IsCodec(type)||guard_exports.Keys(type.properties).some(key=>{return FromType23(context,type.properties[key])})}function FromRecord6(context,type){return IsCodec( +type)||FromType23(context,RecordValue(type))}function FromRef9(context,type){if(visited.has(type.$ref))return false;visited.add(type.$ref);return IsCodec(type)||guard_exports.HasPropertyKey(context,type.$ref)&&FromType23(context,context[type.$ref])}function FromTuple9(context,type){return IsCodec(type)||type.items.some(type2=>FromType23(context,type2))}function FromUnion13(context,type){return IsCodec(type)||type.anyOf.some(type2=>FromType23(context,type2))}function FromType23(context,type){return IsArray3( +type)?FromArray12(context,type):IsCyclic(type)?FromCyclic10(context,type):IsIntersect(type)?FromIntersect10(context,type):IsObject3(type)?FromObject15(context,type):IsRecord(type)?FromRecord6(context,type):IsRef(type)?FromRef9(context,type):IsTuple(type)?FromTuple9(context,type):IsUnion(type)?FromUnion13(context,type):IsCodec(type)}var visited=new Set;function HasCodec(...args){const[context,type]=arguments_exports.Match(args,{2:(context2,type2)=>[context2,type2],1:type2=>[{},type2]});visited.clear(); +return FromType23(context,type)}var CreateError=class extends Error{constructor(type,message){super(message);this.type=type}};function FromDefault2(_context,schema){return guard_exports.IsFunction(schema.default)?schema.default(schema):guard_exports.IsObject(schema.default)?Clone2(schema.default):schema.default}function FromArray13(context,type){if(IsUniqueItems(type)&&!IsDefault(type))throw new CreateError(type,"Arrays with uniqueItems constraints must specify a default annotation");const length=IsMinItems(type)?type.minItems:0;return Array.from({length},()=>FromType24(context,type.items))}async function*CreateAsyncIterator(){}function FromAsyncIterator(_context,_type){return CreateAsyncIterator()}function FromBase4(_context,type){return type.Create()}function FromBigInt7(_context,type){return IsExclusiveMinimum(type)?BigInt(type.exclusiveMinimum)+BigInt(1):IsMinimum(type)?BigInt(type.minimum):BigInt(0)}function FromBoolean7(_context,_type){return false}function FromConstructor2(context,type){const instanceType=FromType24(context,type.instanceType);return class{constructor(){Object.assign(this,instanceType)}}}function FromCyclic11(context,type){return FromType24({...context,...type.$defs},Ref(type.$ref))}function FromEnum3(context,type){return FromType24(context,EnumToUnion(type))}function FromFunction2(context,type){const returnType=FromType24(context,type.returnType);return()=>returnType}function FromInteger2(_context,type){return IsExclusiveMinimum(type)&&guard_exports.IsNumber(type.exclusiveMinimum)?type.exclusiveMinimum+1:IsMinimum(type)?type.minimum:0}function FromIntersect11(context,type){const instantiated=Instantiate(context,type);const evaluated=Evaluate2(instantiated);return FromType24(context,evaluated)}function*CreateIterator(){}function FromIterator(_context,_type){return CreateIterator()}function FromLiteral7(_context,type){return type.const}function FromNever(_context,type){throw new CreateError(type,"Cannot create TNever types")}function FromNull3(_context,_type){return null}function FromNumber6(_context,type){return IsExclusiveMinimum(type)&&guard_exports.IsNumber(type.exclusiveMinimum)?type.exclusiveMinimum+1:IsMinimum(type)?type.minimum:0}function FromObject16(context,type){const required=guard_exports.IsUndefined(type.required)?[]:type.required;return required.reduce((result,key)=>{return{...result,[key]:FromType24(context,type.properties[key])}},{})}function FromPromise(context,type){return Promise.resolve(FromType24(context,type.item))}function FromRecord7(_context,type){if(IsMinProperties(type)&&!IsDefault(type))throw new CreateError(type,"Record with the minProperties constraint must have a default annotation");return{}}function FromRef10(context,type){return guard_exports.HasPropertyKey(context,type.$ref)?FromType24(context,context[type.$ref]):(()=>{throw new CreateError(type,"Unable to deref Ref")})()}function FromString8(_context,type){const needsDefault=(IsPattern(type)||IsFormat(type))&&!IsDefault(type);if(needsDefault)throw Error("Strings with format or pattern constraints must specify default");const minLength=IsMinLength4(type)?type.minLength:0;return"".padEnd(minLength)}function FromSymbol2(_context,_type){return Symbol()}function FromTemplateLiteral5(context,type){const decoded=TemplateLiteralDecode(type.pattern);if(IsString4(decoded))throw new CreateError(type,"Unable to create TemplateLiteral due to infinite type expansion");return FromType24(context,decoded)}function FromTuple10(context,type){return Array.from({length:type.minItems},(_,i)=>FromType24(context,type.items[i]))}function FromUndefined3(_context,_type){return void 0}function FromUnion14(context,type){if(guard_exports.IsEqual(type.anyOf.length,0)){throw Error("Unable to create Union with no variants")}return FromType24(context,type.anyOf[0])}function FromVoid2(_context,_type){return void 0}function FromType24(context,type){return IsDefault(type)?FromDefault2(context,type):IsArray3(type)?FromArray13(context,type):IsAsyncIterator3(type)?FromAsyncIterator(context,type):IsBase(type)?FromBase4(context,type):IsBigInt3(type)?FromBigInt7(context,type):IsBoolean4(type)?FromBoolean7(context,type):IsConstructor3(type)?FromConstructor2(context,type):IsCyclic(type)?FromCyclic11(context,type):IsEnum(type)?FromEnum3(context,type):IsFunction3(type)?FromFunction2(context,type):IsInteger3(type)?FromInteger2( +context,type):IsIntersect(type)?FromIntersect11(context,type):IsIterator3(type)?FromIterator(context,type):IsLiteral(type)?FromLiteral7(context,type):IsNever(type)?FromNever(context,type):IsNull3(type)?FromNull3(context,type):IsNumber4(type)?FromNumber6(context,type):IsObject3(type)?FromObject16(context,type):IsPromise(type)?FromPromise(context,type):IsRecord(type)?FromRecord7(context,type):IsRef(type)?FromRef10(context,type):IsString4(type)?FromString8(context,type):IsSymbol3(type)?FromSymbol2( +context,type):IsTemplateLiteral(type)?FromTemplateLiteral5(context,type):IsTuple(type)?FromTuple10(context,type):IsUndefined3(type)?FromUndefined3(context,type):IsUnion(type)?FromUnion14(context,type):IsVoid(type)?FromVoid2(context,type):void 0}function Create2(...args){const[context,type]=arguments_exports.Match(args,{2:(context2,type2)=>[context2,type2],1:type2=>[{},type2]});return FromType24(context,type)}function Equal(left,right){return guard_exports.IsDeepEqual(left,right)}function Hash2(value){return hash_exports.Hash(value)}var MutateError=class extends Error{constructor(message){super(message)}};function FromArray14(root,path,current,next){if(!guard_exports.IsArray(current)){pointer_exports.Set(root,path,Clone2(next))}else{for(let index2=0;index2Clone2(value),(context,type,value)=>Default(context,type,value),(context,type,value)=>Convert(context,type,value),(context,type,value)=>Clean(context,type,value),(context,type,value)=>Assert4(context,type,value)]);function Parse(...args){ +const[context,type,value]=arguments_exports.Match(args,{3:(context2,type2,value2)=>[context2,type2,value2],2:(type2,value2)=>[{},type2,value2]});const checked=Check2(context,type,value);if(checked)return value;if(settings_exports.Get().correctiveParse)return Parser(context,type,value);throw new ParseError2(value,Errors2(context,type,value))}function CreateUpdate(path,value){return{type:"update",path,value}}function CreateInsert(path,value){return{type:"insert",path,value}}function CreateDelete(path){return{type:"delete",path}}function AssertCanDiffObject(value){if(guard_exports.IsObject(value)&&guard_exports.IsEqual(guard_exports.Symbols(value).length,0))return;throw new Error("Cannot create diffs for objects with symbols keys")}function*FromObject18(path,left,right){if(!guard_exports.IsObject(right)||guard_exports.IsArray(right))return yield CreateUpdate( +path,right);AssertCanDiffObject(left);AssertCanDiffObject(right);const leftKeys=guard_exports.Keys(left);const rightKeys=guard_exports.Keys(right);for(const key of rightKeys){if(guard_exports.HasPropertyKey(left,key))continue;if(guard_exports.IsUnsafePropertyKey(key))continue;yield CreateInsert(`${path}/${key}`,right[key])}for(const key of leftKeys){if(!guard_exports.HasPropertyKey(right,key))continue;if(guard_exports.IsUnsafePropertyKey(key))continue;if(Equal(left,right))continue;yield*FromValue6( +`${path}/${key}`,left[key],right[key])}for(const key of leftKeys){if(guard_exports.HasPropertyKey(right,key))continue;if(guard_exports.IsUnsafePropertyKey(key))continue;yield CreateDelete(`${path}/${key}`)}}function*FromArray15(path,left,right){if(!guard_exports.IsArray(right))return yield CreateUpdate(path,right);for(let i=0;i=0;i--){if(i0&&edits[0].path===""&&edits[0].type==="update"}function IsEmpty(edits){return edits.length===0}function Patch(current,edits){if(IsRoot(edits))return Clone2(edits[0].value);if(IsEmpty(edits))return Clone2(current);const clone=Clone2(current);for(const edit of edits){switch(edit.type){case"insert":{pointer_exports.Set(clone,edit.path,edit.value);break}case"update":{pointer_exports.Set(clone,edit.path,edit.value);break}case"delete":{pointer_exports.Delete( +clone,edit.path);break}}}return clone}var RepairError=class extends Error{constructor(context,type,value,message){super(message);this.context=context;this.type=type;this.value=value}};function MakeUnique(values){const[hashes,result]=[new Set,[]];for(const value of values){const hash=Hash2(value);if(hashes.has(hash))continue;hashes.add(hash);result.push(value)}return result}function FromArray16(context,type,value){if(Check2(context,type,value))return value;const created=guard_exports.IsArray(value)?value:Create2(context,type);const minimum=IsMinItems(type)&&created.lengthCreate2(context,type))]: +created;const maximum=IsMaxItems(type)&&minimum.length>type.maxItems?minimum.slice(0,type.maxItems):minimum;const repaired=maximum.map(value2=>FromType25(context,type.items,value2));if(!IsUniqueItems(type)||IsUniqueItems(type)&&!guard_exports.IsEqual(type.uniqueItems,true))return repaired;const unique=MakeUnique(repaired);if(!Check2(context,type,unique))throw new RepairError(context,type,value,"Failed to repair Array due to uniqueItems constraint");return unique}function FromUnknown4(context,type,value){if(Check2(context,type,value))return value;const converted=Convert(context,type,value);if(Check2(context,type,converted))return converted;return Create2(context,type)}function FromBase5(context,type,value){return FromUnknown4(context,type,value)}function FromEnum4(context,type,value){const union=EnumToUnion(type);return FromType25(context,union,value)}function FromIntersect12(context,type,value){const instantiated=Instantiate(context,type);const evaluated=Evaluate2(instantiated);return FromType25(context,evaluated,value)}function FromObject19(context,type,value){if(Check2(context,type,value))return value;if(!guard_exports.IsObjectNotArray(value))return Create2(context,type);const required=new Set(guard_exports.IsUndefined(type.required)?[]:type.required);const result={};for(const[key,schema]of guard_exports.Entries(type.properties)){if(!required.has(key)&&guard_exports.IsUndefined(value[key]))continue;result[key]=key in value?FromType25(context,schema,value[key]):Create2(context,schema)}const evaluatedKeys=guard_exports. +Keys(type.properties);if(IsAdditionalProperties(type)&&guard_exports.IsObject(type.additionalProperties)){for(const key of guard_exports.Keys(value)){if(evaluatedKeys.includes(key))continue;result[key]=FromType25(context,type.additionalProperties,value[key])}}return result}function FromRecord8(context,type,value){if(Check2(context,type,value))return value;if(guard_exports.IsNull(value)||!guard_exports.IsObject(value)||guard_exports.IsArray(value))return Create2(context,type);const recordKey=new RegExp(RecordPattern(type));const recordValue=RecordValue(type);const evaluatedKeys=new Set;const result={};for(const[key,value_]of guard_exports.Entries(value)){if(!recordKey.test(key))continue;result[key]=FromType25(context,recordValue,value_);evaluatedKeys.add(key)}if(IsAdditionalProperties( +type)){for(const key of guard_exports.Keys(value)){if(evaluatedKeys.has(key))continue;result[key]=FromType25(context,type.additionalProperties,value[key])}}return result}function FromRef11(context,type,value){return guard_exports.HasPropertyKey(context,type.$ref)?FromType25(context,context[type.$ref],value):(()=>{throw new RepairError(context,type,value,"Unable to de-reference target type")})()}function FromTemplateLiteral6(context,type,value){const decoded=TemplateLiteralDecode(type.pattern);return FromType25(context,decoded,value)}function FromTuple11(context,schema,value){if(Check2(context,schema,value))return value;if(!guard_exports.IsArray(value))return Create2(context,schema);return schema.items.map((schema2,index2)=>FromType25(context,schema2,value[index2]))}function Deref(context,type,value){return IsRef(type)?guard_exports.HasPropertyKey(context,type.$ref)?Deref(context,context[type.$ref],value):(()=>{throw new Error("Unable to Deref target")})():type}function ScoreVariant(context,type,value){if(!(IsObject3(type)&&guard_exports.IsObject(value)))return 0;const keys=guard_exports.Keys(value);const entries=guard_exports.Entries(type.properties);return entries.reduce((result,[key,schema])=>{const literal=IsLiteral(schema)&&guard_exports.IsEqual(schema. +const,value[key])?100:0;const checks=Check2(context,schema,value[key])?10:0;const exists=keys.includes(key)?1:0;return result+(literal+checks+exists)},0)}function UnionScoreSelect(context,type,value){const schemas=type.anyOf.map(schema=>Deref(context,schema,value));let[select,best]=[schemas[0],0];for(const schema of schemas){const score=ScoreVariant(context,schema,value);if(score>best){select=schema;best=score}}return select}function RepairUnion(context,type,value){const union=Union(Flatten(type.anyOf));const schema=UnionScoreSelect(context,union,value);return FromType25(context,schema,value)}function FromUnion15(context,type,value){if(Check2(context,type,value))return Clone2(value);if(IsDefault(type))return Create2(context,type);return RepairUnion(context,type,value)}function AssertRepairableValue(context,type,value){const unsupported=globals_exports.IsDate(value)||globals_exports.IsMap(value)||globals_exports.IsSet(value)||globals_exports.IsTypeArray(value)||guard_exports.IsConstructor(value)||guard_exports.IsFunction(value);if(unsupported){throw new RepairError(context,type,value,"Value is not repairable")}}function AssertRepairableType(context,type,value){const unsupported=IsAsyncIterator3(type)||IsIterator3(type)||IsConstructor3(type)||IsFunction3(type)|| +IsNever(type)||IsPromise(type);if(unsupported){throw new RepairError(context,type,value,"Type is not repairable")}}function FinalizeRepair(context,type,repaired){return IsRefine(type)?Check2(context,type,repaired)?repaired:Create2(context,type):repaired}function FromType25(context,type,value){if(IsBase(type)){const repaired2=FromBase5(context,type,value);return FinalizeRepair(context,type,repaired2)}AssertRepairableValue(context,type,value);AssertRepairableType(context,type,value);const repaired=IsArray3( +type)?FromArray16(context,type,value):IsEnum(type)?FromEnum4(context,type,value):IsIntersect(type)?FromIntersect12(context,type,value):IsObject3(type)?FromObject19(context,type,value):IsRecord(type)?FromRecord8(context,type,value):IsRef(type)?FromRef11(context,type,value):IsTemplateLiteral(type)?FromTemplateLiteral6(context,type,value):IsTuple(type)?FromTuple11(context,type,value):IsUnion(type)?FromUnion15(context,type,value):FromUnknown4(context,type,value);return FinalizeRepair(context,type,repaired)}function Repair(...args){const[context,type,value]=arguments_exports.Match(args,{3:(context2,type2,value2)=>[context2,type2,value2],2:(type2,value2)=>[{},type2,value2]});const repaired=FromType25(context,type,value);Assert(context,type,repaired);return repaired}var value_exports={};__export(value_exports,{Assert:()=>Assert,Check:()=>Check2,Clean:()=>Clean,Clone:()=>Clone2,Convert:()=>Convert,Create:()=>Create2,Decode:()=>Decode9,Default:()=>Default,Diff:()=>Diff,Encode:()=>Encode8,Equal:()=>Equal,Errors:()=>Errors2,HasCodec:()=>HasCodec,Hash:()=>Hash2,Mutate:()=>Mutate,Parse:()=>Parse,Patch:()=>Patch,Pointer:()=>pointer_exports,Repair:()=>Repair});var Validator=class _Validator extends Base{constructor(...args){super();const matched=arguments_exports.Match(args,{3:(hasCodec,buildResult,evaluateResult)=>[hasCodec,buildResult,evaluateResult],2:(context,type)=>[context,type]});if(matched.length===3&&matched[1]instanceof BuildResult&&matched[2]instanceof EvaluateResult){const[hasCodec,buildResult,evaluateResult]=matched;this.hasCodec=hasCodec;this.buildResult=buildResult;this.evaluateResult=evaluateResult}else{const[context,type]=matched;this. +hasCodec=HasCodec(context,type);this.buildResult=Build(context,type);this.evaluateResult=this.buildResult.Evaluate()}}IsAccelerated(){return this.evaluateResult.IsAccelerated()}Context(){return this.buildResult.Context()}Type(){return this.buildResult.Schema()}Code(){return this.evaluateResult.Code()}Check(value){return this.evaluateResult.Check(value)}Parse(value){const checked=this.Check(value);if(checked)return value;if(settings_exports.Get().correctiveParse)return Parser(this.Context(),this. +Type(),value);throw new ParseError2(value,this.Errors(value))}Errors(value){if(this.IsAccelerated()&&this.Check(value))return[];return Errors2(this.Context(),this.Type(),value)}Clean(value){return Clean(this.Context(),this.Type(),value)}Convert(value){return Convert(this.Context(),this.Type(),value)}Create(){return Create2(this.Context(),this.Type())}Default(value){return Default(this.Context(),this.Type(),value)}Decode(value){const result=this.hasCodec?Decode9(this.Context(),this.Type(),value): +this.Parse(value);return result}Encode(value){const result=this.hasCodec?Encode8(this.Context(),this.Type(),value):this.Parse(value);return result}Clone(){return new _Validator(this.hasCodec,this.buildResult,this.evaluateResult)}};function Compile(...args){const[context,type]=arguments_exports.Match(args,{2:(context2,type2)=>[context2,type2],1:type2=>[{},type2]});return new Validator(context,type)}var validatorCache=new WeakMap;var TYPEBOX_KIND=Symbol.for("TypeBox.Kind");function getSchemaTypes(schema){if(typeof schema.type==="string"){return[schema.type]}if(Array.isArray(schema.type)){return schema.type.filter(type=>typeof type==="string")}return[]}function matchesJsonType(value,type){switch(type){case"number":return typeof value==="number";case"integer":return typeof value==="number"&&Number.isInteger(value);case"boolean":return typeof value==="boolean";case"string":return typeof value=== +"string";case"null":return value===null;case"array":return Array.isArray(value);case"object":return typeof value==="object"&&value!==null&&!Array.isArray(value);default:return false}}function getSubSchemaValidator(schema){try{return getValidator(schema)}catch{return void 0}}function coercePrimitiveByType(value,type){switch(type){case"number":{if(value===null){return 0}if(typeof value==="string"&&value.trim()!==""){const parsed=Number(value);if(Number.isFinite(parsed)){return parsed}}if(typeof value=== +"boolean"){return value?1:0}return value}case"integer":{if(value===null){return 0}if(typeof value==="string"&&value.trim()!==""){const parsed=Number(value);if(Number.isInteger(parsed)){return parsed}}if(typeof value==="boolean"){return value?1:0}return value}case"boolean":{if(value===null){return false}if(typeof value==="string"){if(value==="true"){return true}if(value==="false"){return false}}if(typeof value==="number"){if(value===1){return true}if(value===0){return false}}return value}case"str\ +ing":{if(value===null){return""}if(typeof value==="number"||typeof value==="boolean"){return String(value)}return value}case"null":{if(value===""||value===0||value===false){return null}return value}default:return value}}function applySchemaObjectCoercion(value,schema){const properties=schema.properties;const definedKeys=new Set(properties?Object.keys(properties):[]);if(properties){for(const[key,propertySchema]of Object.entries(properties)){if(!(key in value)){continue}value[key]=coerceWithJsonSchema( +value[key],propertySchema)}}if(schema.additionalProperties&&typeof schema.additionalProperties==="object"){for(const[key,propertyValue]of Object.entries(value)){if(definedKeys.has(key)){continue}value[key]=coerceWithJsonSchema(propertyValue,schema.additionalProperties)}}}function applySchemaArrayCoercion(value,schema){if(Array.isArray(schema.items)){for(let index2=0;index21&&schemaTypes.some(schemaType=>matchesJsonType(nextValue,schemaType));if(schemaTypes.length>0&&!matchesUnionMember){for(const schemaType of schemaTypes){ +const candidate=coercePrimitiveByType(nextValue,schemaType);if(candidate!==nextValue){nextValue=candidate;break}}}if(schemaTypes.includes("object")&&typeof nextValue==="object"&&nextValue!==null&&!Array.isArray(nextValue)){applySchemaObjectCoercion(nextValue,schema)}if(schemaTypes.includes("array")&&Array.isArray(nextValue)){applySchemaArrayCoercion(nextValue,schema)}return nextValue}function getValidator(schema){const key=schema;const cached=validatorCache.get(key);if(cached){return cached}const validator=Compile( +schema);validatorCache.set(key,validator);return validator}function formatValidationPath(error){if(error.keyword==="required"){const requiredProperties=error.params.requiredProperties;const requiredProperty=requiredProperties?.[0];if(requiredProperty){const basePath=error.instancePath.replace(/^\//,"").replace(/\//g,".");return basePath?`${basePath}.${requiredProperty}`:requiredProperty}}const path=error.instancePath.replace(/^\//,"").replace(/\//g,".");return path||"root"}function validateToolArguments(tool,toolCall){const args=structuredClone(toolCall.arguments);value_exports.Convert(tool.parameters,args);const validator=getValidator(tool.parameters);if(!Object.getOwnPropertySymbols(tool.parameters).includes(TYPEBOX_KIND)){const coerced=coerceWithJsonSchema(args,tool.parameters);if(coerced!==args){if(typeof args==="object"&&args!==null&&typeof coerced==="object"&&coerced!==null){for(const key of Object.keys(args)){delete args[key]}Object.assign(args,coerced)}else{ +return validator.Check(coerced)?coerced:args}}}if(validator.Check(args)){return args}const errors=validator.Errors(args).map(error=>` - ${formatValidationPath(error)}: ${error.message}`).join("\n")||"Unknown validation error";const errorMessage=`Validation failed for tool "${toolCall.name}": +${errors} + +Received arguments: +${JSON.stringify(toolCall.arguments,null,2)}`;throw new Error(errorMessage)}var defaultStreamFn;function getDefaultStreamFn(){if(!defaultStreamFn){throw new Error("No default stream function configured. Pass streamFn explicitly or call setDefaultStreamFn().")}return defaultStreamFn}async function runAgentLoop(prompts,context,config,emit,signal,streamFn){const newMessages=[...prompts];const currentContext={...context,messages:[...context.messages,...prompts]};await emit({type:"agent_start"});await emit({type:"turn_start"});for(const prompt2 of prompts){await emit({type:"message_start",message:prompt2});await emit({type:"message_end",message:prompt2})}await runLoop(currentContext,newMessages,config,signal,emit,streamFn??getDefaultStreamFn());return newMessages}async function runAgentLoopContinue(context,config,emit,signal,streamFn){ +if(context.messages.length===0){throw new Error("Cannot continue: no messages in context")}if(context.messages[context.messages.length-1].role==="assistant"){throw new Error("Cannot continue from message role: assistant")}const newMessages=[];const currentContext={...context};await emit({type:"agent_start"});await emit({type:"turn_start"});await runLoop(currentContext,newMessages,config,signal,emit,streamFn??getDefaultStreamFn());return newMessages}async function runLoop(initialContext,newMessages,initialConfig,signal,emit,streamFunction){let currentContext=initialContext;let config=initialConfig;let firstTurn=true;let pendingMessages=await config.getSteeringMessages?.()||[];while(true){let hasMoreToolCalls=true;while(hasMoreToolCalls||pendingMessages.length>0){if(!firstTurn){await emit({type:"turn_start"})}else{firstTurn=false}if(pendingMessages.length>0){for(const message2 of pendingMessages){await emit({type:"message_start",message:message2}); +await emit({type:"message_end",message:message2});currentContext.messages.push(message2);newMessages.push(message2)}pendingMessages=[]}const message=await streamAssistantResponse(currentContext,config,signal,emit,streamFunction);newMessages.push(message);if(message.stopReason==="error"||message.stopReason==="aborted"){await emit({type:"turn_end",message,toolResults:[]});await emit({type:"agent_end",messages:newMessages});return}const toolCalls=message.content.filter(c=>c.type==="toolCall");const toolResults=[]; +hasMoreToolCalls=false;if(toolCalls.length>0){const executedToolBatch=message.stopReason==="length"?await failToolCallsFromTruncatedMessage(toolCalls,emit):await executeToolCalls(currentContext,message,config,signal,emit);toolResults.push(...executedToolBatch.messages);hasMoreToolCalls=!executedToolBatch.terminate;for(const result of toolResults){currentContext.messages.push(result);newMessages.push(result)}}await emit({type:"turn_end",message,toolResults});const nextTurnContext={message,toolResults, +context:currentContext,newMessages};const nextTurnSnapshot=await config.prepareNextTurn?.(nextTurnContext);if(nextTurnSnapshot){currentContext=nextTurnSnapshot.context??currentContext;config={...config,model:nextTurnSnapshot.model??config.model,reasoning:nextTurnSnapshot.thinkingLevel===void 0?config.reasoning:nextTurnSnapshot.thinkingLevel==="off"?void 0:nextTurnSnapshot.thinkingLevel}}if(await config.shouldStopAfterTurn?.({message,toolResults,context:currentContext,newMessages})){await emit({type:"\ +agent_end",messages:newMessages});return}pendingMessages=await config.getSteeringMessages?.()||[]}const followUpMessages=await config.getFollowUpMessages?.()||[];if(followUpMessages.length>0){pendingMessages=followUpMessages;continue}break}await emit({type:"agent_end",messages:newMessages})}async function streamAssistantResponse(context,config,signal,emit,streamFunction){let messages=context.messages;if(config.transformContext){messages=await config.transformContext(messages,signal)}const llmMessages=await config. +convertToLlm(messages);const llmContext={systemPrompt:context.systemPrompt,messages:llmMessages,tools:context.tools};const resolvedApiKey=(config.getApiKey?await config.getApiKey(config.model.provider):void 0)||config.apiKey;const response=await streamFunction(config.model,llmContext,{...config,apiKey:resolvedApiKey,signal});let partialMessage=null;let addedPartial=false;for await(const event of response){switch(event.type){case"start":partialMessage=event.partial;context.messages.push(partialMessage); +addedPartial=true;await emit({type:"message_start",message:{...partialMessage}});break;case"text_start":case"text_delta":case"text_end":case"thinking_start":case"thinking_delta":case"thinking_end":case"toolcall_start":case"toolcall_delta":case"toolcall_end":if(partialMessage){partialMessage=event.partial;context.messages[context.messages.length-1]=partialMessage;await emit({type:"message_update",assistantMessageEvent:event,message:{...partialMessage}})}break;case"done":case"error":{const finalMessage2=await response. +result();if(addedPartial){context.messages[context.messages.length-1]=finalMessage2}else{context.messages.push(finalMessage2)}if(!addedPartial){await emit({type:"message_start",message:{...finalMessage2}})}await emit({type:"message_end",message:finalMessage2});return finalMessage2}}}const finalMessage=await response.result();if(addedPartial){context.messages[context.messages.length-1]=finalMessage}else{context.messages.push(finalMessage);await emit({type:"message_start",message:{...finalMessage}})} +await emit({type:"message_end",message:finalMessage});return finalMessage}async function failToolCallsFromTruncatedMessage(toolCalls,emit){const messages=[];for(const toolCall of toolCalls){await emit({type:"tool_execution_start",toolCallId:toolCall.id,toolName:toolCall.name,args:toolCall.arguments});const finalized={toolCall,result:createErrorToolResult(`Tool call "${toolCall.name}" was not executed: the response hit the output token limit, so its arguments may be truncated. Re-issue the tool c\ +all with complete arguments.`),isError:true};await emitToolExecutionEnd(finalized,emit);const toolResultMessage=createToolResultMessage(finalized);await emitToolResultMessage(toolResultMessage,emit);messages.push(toolResultMessage)}return{messages,terminate:false}}async function executeToolCalls(currentContext,assistantMessage,config,signal,emit){const toolCalls=assistantMessage.content.filter(c=>c.type==="toolCall");const hasSequentialToolCall=toolCalls.some(tc=>currentContext.tools?.find(t=>t. +name===tc.name)?.executionMode==="sequential");if(config.toolExecution==="sequential"||hasSequentialToolCall){return executeToolCallsSequential(currentContext,assistantMessage,toolCalls,config,signal,emit)}return executeToolCallsParallel(currentContext,assistantMessage,toolCalls,config,signal,emit)}async function executeToolCallsSequential(currentContext,assistantMessage,toolCalls,config,signal,emit){const finalizedCalls=[];const messages=[];for(const toolCall of toolCalls){await emit({type:"too\ +l_execution_start",toolCallId:toolCall.id,toolName:toolCall.name,args:toolCall.arguments});const preparation=await prepareToolCall(currentContext,assistantMessage,toolCall,config,signal);let finalized;if(preparation.kind==="immediate"){finalized={toolCall,result:preparation.result,isError:preparation.isError}}else{const executed=await executePreparedToolCall(preparation,signal,emit);finalized=await finalizeExecutedToolCall(currentContext,assistantMessage,preparation,executed,config,signal)}await emitToolExecutionEnd( +finalized,emit);const toolResultMessage=createToolResultMessage(finalized);await emitToolResultMessage(toolResultMessage,emit);finalizedCalls.push(finalized);messages.push(toolResultMessage);if(signal?.aborted){break}}return{messages,terminate:shouldTerminateToolBatch(finalizedCalls)}}async function executeToolCallsParallel(currentContext,assistantMessage,toolCalls,config,signal,emit){const finalizedCalls=[];for(const toolCall of toolCalls){await emit({type:"tool_execution_start",toolCallId:toolCall. +id,toolName:toolCall.name,args:toolCall.arguments});const preparation=await prepareToolCall(currentContext,assistantMessage,toolCall,config,signal);if(preparation.kind==="immediate"){const finalized={toolCall,result:preparation.result,isError:preparation.isError};await emitToolExecutionEnd(finalized,emit);finalizedCalls.push(finalized);if(signal?.aborted){break}continue}finalizedCalls.push(async()=>{const executed=await executePreparedToolCall(preparation,signal,emit);const finalized=await finalizeExecutedToolCall( +currentContext,assistantMessage,preparation,executed,config,signal);await emitToolExecutionEnd(finalized,emit);return finalized});if(signal?.aborted){break}}const orderedFinalizedCalls=await Promise.all(finalizedCalls.map(entry=>typeof entry==="function"?entry():Promise.resolve(entry)));const messages=[];for(const finalized of orderedFinalizedCalls){const toolResultMessage=createToolResultMessage(finalized);await emitToolResultMessage(toolResultMessage,emit);messages.push(toolResultMessage)}return{ +messages,terminate:shouldTerminateToolBatch(orderedFinalizedCalls)}}function shouldTerminateToolBatch(finalizedCalls){return finalizedCalls.length>0&&finalizedCalls.every(finalized=>finalized.result.terminate===true)}function prepareToolCallArguments(tool,toolCall){if(!tool.prepareArguments){return toolCall}const preparedArguments=tool.prepareArguments(toolCall.arguments);if(preparedArguments===toolCall.arguments){return toolCall}return{...toolCall,arguments:preparedArguments}}async function prepareToolCall(currentContext,assistantMessage,toolCall,config,signal){ +const tool=currentContext.tools?.find(t=>t.name===toolCall.name);if(!tool){return{kind:"immediate",result:createErrorToolResult(`Tool ${toolCall.name} not found`),isError:true}}try{const preparedToolCall=prepareToolCallArguments(tool,toolCall);const validatedArgs=validateToolArguments(tool,preparedToolCall);if(config.beforeToolCall){const beforeResult=await config.beforeToolCall({assistantMessage,toolCall,args:validatedArgs,context:currentContext},signal);if(signal?.aborted){return{kind:"immedia\ +te",result:createErrorToolResult("Operation aborted"),isError:true}}if(beforeResult?.block){return{kind:"immediate",result:createErrorToolResult(beforeResult.reason||"Tool execution was blocked"),isError:true}}}if(signal?.aborted){return{kind:"immediate",result:createErrorToolResult("Operation aborted"),isError:true}}return{kind:"prepared",toolCall,tool,args:validatedArgs}}catch(error){return{kind:"immediate",result:createErrorToolResult(error instanceof Error?error.message:String(error)),isError:true}}} +async function executePreparedToolCall(prepared,signal,emit){const updateEvents=[];let acceptingUpdates=true;try{const result=await prepared.tool.execute(prepared.toolCall.id,prepared.args,signal,partialResult=>{if(!acceptingUpdates)return;updateEvents.push(Promise.resolve(emit({type:"tool_execution_update",toolCallId:prepared.toolCall.id,toolName:prepared.toolCall.name,args:prepared.toolCall.arguments,partialResult})))});acceptingUpdates=false;await Promise.all(updateEvents);return{result,isError:false}}catch(error){ +acceptingUpdates=false;await Promise.all(updateEvents);return{result:createErrorToolResult(error instanceof Error?error.message:String(error)),isError:true}}finally{acceptingUpdates=false}}async function finalizeExecutedToolCall(currentContext,assistantMessage,prepared,executed,config,signal){let result=executed.result;let isError=executed.isError;if(config.afterToolCall){try{const afterResult=await config.afterToolCall({assistantMessage,toolCall:prepared.toolCall,args:prepared.args,result,isError, +context:currentContext},signal);if(afterResult){result={...result,content:afterResult.content??result.content,details:afterResult.details??result.details,usage:afterResult.usage??result.usage,terminate:afterResult.terminate??result.terminate};isError=afterResult.isError??isError}}catch(error){result=createErrorToolResult(error instanceof Error?error.message:String(error));isError=true}}return{toolCall:prepared.toolCall,result,isError}}function createErrorToolResult(message){return{content:[{type:"\ +text",text:message}],details:{}}}async function emitToolExecutionEnd(finalized,emit){await emit({type:"tool_execution_end",toolCallId:finalized.toolCall.id,toolName:finalized.toolCall.name,result:finalized.result,isError:finalized.isError})}function createToolResultMessage(finalized){return{role:"toolResult",toolCallId:finalized.toolCall.id,toolName:finalized.toolCall.name,content:finalized.result.content??[],details:finalized.result.details,usage:finalized.result.usage,...finalized.result.addedToolNames?. +length?{addedToolNames:finalized.result.addedToolNames}:{},isError:finalized.isError,timestamp:Date.now()}}async function emitToolResultMessage(toolResultMessage,emit){await emit({type:"message_start",message:toolResultMessage});await emit({type:"message_end",message:toolResultMessage})}function defaultConvertToLlm(messages){return messages.filter(message=>message.role==="user"||message.role==="assistant"||message.role==="toolResult")}var EMPTY_USAGE={input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}};var DEFAULT_MODEL={id:"unknown",name:"unknown",api:"unknown",provider:"unknown",baseUrl:"",reasoning:false,input:[],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:0,maxTokens:0};function createMutableAgentState(initialState){ +let tools=initialState?.tools?.slice()??[];let messages=initialState?.messages?.slice()??[];return{systemPrompt:initialState?.systemPrompt??"",model:initialState?.model??DEFAULT_MODEL,thinkingLevel:initialState?.thinkingLevel??"off",get tools(){return tools},set tools(nextTools){tools=nextTools.slice()},get messages(){return messages},set messages(nextMessages){messages=nextMessages.slice()},isStreaming:false,streamingMessage:void 0,pendingToolCalls:new Set,errorMessage:void 0}}var PendingMessageQueue=class{constructor(mode){ +__publicField(this,"messages",[]);__publicField(this,"mode");this.mode=mode}enqueue(message){this.messages.push(message)}hasItems(){return this.messages.length>0}drain(){if(this.mode==="all"){const drained=this.messages.slice();this.messages=[];return drained}const first=this.messages[0];if(!first){return[]}this.messages=this.messages.slice(1);return[first]}clear(){this.messages=[]}};var Agent=class{constructor(options){__publicField(this,"_state");__publicField(this,"listeners",new Set);__publicField( +this,"steeringQueue");__publicField(this,"followUpQueue");__publicField(this,"convertToLlm");__publicField(this,"transformContext");__publicField(this,"streamFunction");__publicField(this,"getApiKey");__publicField(this,"onPayload");__publicField(this,"onResponse");__publicField(this,"beforeToolCall");__publicField(this,"afterToolCall");__publicField(this,"prepareNextTurn");__publicField(this,"prepareNextTurnWithContext");__publicField(this,"activeRun");__publicField(this,"sessionId");__publicField( +this,"thinkingBudgets");__publicField(this,"transport");__publicField(this,"maxRetryDelayMs");__publicField(this,"toolExecution");const runtimeOptions=options??{};this._state=createMutableAgentState(runtimeOptions.initialState);this.convertToLlm=runtimeOptions.convertToLlm??defaultConvertToLlm;this.transformContext=runtimeOptions.transformContext;this.streamFunction=runtimeOptions.streamFn??getDefaultStreamFn();this.getApiKey=runtimeOptions.getApiKey;this.onPayload=runtimeOptions.onPayload;this. +onResponse=runtimeOptions.onResponse;this.beforeToolCall=runtimeOptions.beforeToolCall;this.afterToolCall=runtimeOptions.afterToolCall;this.prepareNextTurn=runtimeOptions.prepareNextTurn;this.prepareNextTurnWithContext=runtimeOptions.prepareNextTurnWithContext;this.steeringQueue=new PendingMessageQueue(runtimeOptions.steeringMode??"one-at-a-time");this.followUpQueue=new PendingMessageQueue(runtimeOptions.followUpMode??"one-at-a-time");this.sessionId=runtimeOptions.sessionId;this.thinkingBudgets= +runtimeOptions.thinkingBudgets;this.transport=runtimeOptions.transport??"auto";this.maxRetryDelayMs=runtimeOptions.maxRetryDelayMs;this.toolExecution=runtimeOptions.toolExecution??"parallel"}subscribe(listener){this.listeners.add(listener);return()=>this.listeners.delete(listener)}get state(){return this._state}set steeringMode(mode){this.steeringQueue.mode=mode}get steeringMode(){return this.steeringQueue.mode}set followUpMode(mode){this.followUpQueue.mode=mode}get followUpMode(){return this.followUpQueue. +mode}steer(message){this.steeringQueue.enqueue(message)}followUp(message){this.followUpQueue.enqueue(message)}clearSteeringQueue(){this.steeringQueue.clear()}clearFollowUpQueue(){this.followUpQueue.clear()}clearAllQueues(){this.clearSteeringQueue();this.clearFollowUpQueue()}hasQueuedMessages(){return this.steeringQueue.hasItems()||this.followUpQueue.hasItems()}get signal(){return this.activeRun?.abortController.signal}abort(){this.activeRun?.abortController.abort()}waitForIdle(){return this.activeRun?. +promise??Promise.resolve()}reset(){this._state.messages=[];this._state.isStreaming=false;this._state.streamingMessage=void 0;this._state.pendingToolCalls=new Set;this._state.errorMessage=void 0;this.clearFollowUpQueue();this.clearSteeringQueue()}async prompt(input,images){if(this.activeRun){throw new Error("Agent is already processing a prompt. Use steer() or followUp() to queue messages, or wait for completion.")}const messages=this.normalizePromptInput(input,images);await this.runPromptMessages( +messages)}async continue(){if(this.activeRun){throw new Error("Agent is already processing. Wait for completion before continuing.")}const lastMessage=this._state.messages[this._state.messages.length-1];if(!lastMessage){throw new Error("No messages to continue from")}if(lastMessage.role==="assistant"){const queuedSteering=this.steeringQueue.drain();if(queuedSteering.length>0){await this.runPromptMessages(queuedSteering,{skipInitialSteeringPoll:true});return}const queuedFollowUps=this.followUpQueue. +drain();if(queuedFollowUps.length>0){await this.runPromptMessages(queuedFollowUps);return}throw new Error("Cannot continue from message role: assistant")}await this.runContinuation()}normalizePromptInput(input,images){if(Array.isArray(input)){return input}if(typeof input!=="string"){return[input]}const content=[{type:"text",text:input}];if(images&&images.length>0){content.push(...images)}return[{role:"user",content,timestamp:Date.now()}]}async runPromptMessages(messages,options={}){await this.runWithLifecycle( +async signal=>{await runAgentLoop(messages,this.createContextSnapshot(),this.createLoopConfig(options),event=>this.processEvents(event),signal,this.streamFunction)})}async runContinuation(){await this.runWithLifecycle(async signal=>{await runAgentLoopContinue(this.createContextSnapshot(),this.createLoopConfig(),event=>this.processEvents(event),signal,this.streamFunction)})}createContextSnapshot(){return{systemPrompt:this._state.systemPrompt,messages:this._state.messages.slice(),tools:this._state. +tools.slice()}}createLoopConfig(options={}){let skipInitialSteeringPoll=options.skipInitialSteeringPoll===true;return{model:this._state.model,reasoning:this._state.thinkingLevel==="off"?void 0:this._state.thinkingLevel,sessionId:this.sessionId,onPayload:this.onPayload,onResponse:this.onResponse,transport:this.transport,thinkingBudgets:this.thinkingBudgets,maxRetryDelayMs:this.maxRetryDelayMs,toolExecution:this.toolExecution,beforeToolCall:this.beforeToolCall,afterToolCall:this.afterToolCall,prepareNextTurn:this. +prepareNextTurnWithContext||this.prepareNextTurn?async context=>{if(this.prepareNextTurnWithContext){return await this.prepareNextTurnWithContext(context,this.signal)}return await this.prepareNextTurn?.(this.signal)}:void 0,convertToLlm:this.convertToLlm,transformContext:this.transformContext,getApiKey:this.getApiKey,getSteeringMessages:async()=>{if(skipInitialSteeringPoll){skipInitialSteeringPoll=false;return[]}return this.steeringQueue.drain()},getFollowUpMessages:async()=>this.followUpQueue.drain()}}async runWithLifecycle(executor){ +if(this.activeRun){throw new Error("Agent is already processing.")}const abortController=new AbortController;let resolvePromise=()=>{};const promise=new Promise(resolve=>{resolvePromise=resolve});this.activeRun={promise,resolve:resolvePromise,abortController};this._state.isStreaming=true;this._state.streamingMessage=void 0;this._state.errorMessage=void 0;try{await executor(abortController.signal)}catch(error){await this.handleRunFailure(error,abortController.signal.aborted)}finally{this.finishRun()}}async handleRunFailure(error,aborted){ +const failureMessage={role:"assistant",content:[{type:"text",text:""}],api:this._state.model.api,provider:this._state.model.provider,model:this._state.model.id,usage:EMPTY_USAGE,stopReason:aborted?"aborted":"error",errorMessage:error instanceof Error?error.message:String(error),timestamp:Date.now()};await this.processEvents({type:"message_start",message:failureMessage});await this.processEvents({type:"message_end",message:failureMessage});await this.processEvents({type:"turn_end",message:failureMessage, +toolResults:[]});await this.processEvents({type:"agent_end",messages:[failureMessage]})}finishRun(){this._state.isStreaming=false;this._state.streamingMessage=void 0;this._state.pendingToolCalls=new Set;this.activeRun?.resolve();this.activeRun=void 0}async processEvents(event){switch(event.type){case"message_start":this._state.streamingMessage=event.message;break;case"message_update":this._state.streamingMessage=event.message;break;case"message_end":this._state.streamingMessage=void 0;this._state. +messages.push(event.message);break;case"tool_execution_start":{const pendingToolCalls=new Set(this._state.pendingToolCalls);pendingToolCalls.add(event.toolCallId);this._state.pendingToolCalls=pendingToolCalls;break}case"tool_execution_end":{const pendingToolCalls=new Set(this._state.pendingToolCalls);pendingToolCalls.delete(event.toolCallId);this._state.pendingToolCalls=pendingToolCalls;break}case"turn_end":if(event.message.role==="assistant"&&event.message.errorMessage){this._state.errorMessage= +event.message.errorMessage}break;case"agent_end":this._state.streamingMessage=void 0;break}const signal=this.activeRun?.abortController.signal;if(!signal){throw new Error("Agent listener invoked outside active run")}for(const listener of this.listeners){await listener(event,signal)}}};var events=[];var pendingModels=new Map;var pendingTools=new Map;var agent=null;var emptyUsage=()=>({input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}});function modelFor(config){const provider=config.provider||"openai";return{id:config.model||"gpt-5-mini",name:config.model||"gpt-5-mini",provider,api:provider==="anthropic"?"anthropic-messages":"openai-responses",baseUrl:provider==="anthropic"?"https://api.anthropic.com":"https://api.\ +openai.com/v1",reasoning:false,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:128e3,maxTokens:1024}}function hostStream(model,context){const stream=new AssistantMessageEventStream;const partial={role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,usage:emptyUsage(),stopReason:"stop",timestamp:Date.now()};try{if(!globalThis.host)throw new Error("Pocket Pi Agent host is unavailable");const id=globalThis.host.startModel(JSON.stringify({model, +context}));pendingModels.set(id,{stream,model,partial,started:false,textStarted:false,text:""})}catch(error){pushModelError(stream,model,String(error))}return stream}function ensureModelStarted(pending){if(pending.started)return;pending.started=true;pending.stream.push({type:"start",partial:{...pending.partial}})}function pushModelDelta(pending,delta){ensureModelStarted(pending);if(!pending.textStarted){pending.textStarted=true;pending.stream.push({type:"text_start",contentIndex:0,partial:{...pending. +partial}})}pending.text+=delta;pending.partial.content=[{type:"text",text:pending.text}];pending.stream.push({type:"text_delta",contentIndex:0,delta,partial:{...pending.partial}})}function finishModel(pending,result){ensureModelStarted(pending);pending.partial.stopReason=result.stopReason||"stop";if(result.toolCall){const toolCall={type:"toolCall",id:result.toolCall.id||`tool_${Date.now()}`,name:result.toolCall.name,arguments:result.toolCall.arguments||{}};pending.partial.content=[toolCall];pending. +partial.stopReason="toolUse";pending.stream.push({type:"toolcall_start",contentIndex:0,partial:{...pending.partial}});pending.stream.push({type:"toolcall_end",contentIndex:0,toolCall,partial:{...pending.partial}});pending.stream.push({type:"done",reason:"toolUse",message:{...pending.partial}});return}const finalText=String(result.text||pending.text);if(!pending.textStarted||finalText!==pending.text){const delta=finalText.startsWith(pending.text)?finalText.slice(pending.text.length):finalText;if(delta) +pushModelDelta(pending,delta)}if(!pending.textStarted)pushModelDelta(pending,"");pending.text=finalText;pending.partial.content=[{type:"text",text:finalText}];pending.stream.push({type:"text_end",contentIndex:0,content:finalText,partial:{...pending.partial}});pending.stream.push({type:"done",reason:pending.partial.stopReason,message:{...pending.partial}})}function pushModelError(stream,model,message){stream.push({type:"error",reason:"error",error:{role:"assistant",content:[],api:model.api,provider:model. +provider,model:model.id,usage:emptyUsage(),stopReason:"error",errorMessage:message,timestamp:Date.now()}})}function boot(configJson){const config=JSON.parse(configJson);const model=modelFor(config);const tools=(config.tools||[]).map(tool=>({name:tool.name,label:tool.label||tool.name,description:tool.description||"",parameters:tool.parameters||{type:"object",properties:{}},executionMode:"sequential",execute:(id,args)=>new Promise((resolve,reject)=>{try{if(!globalThis.host)throw new Error("Pocket \ +Pi Agent host is unavailable");const requestId=globalThis.host.startTool(id,tool.name,JSON.stringify(args||{}));pendingTools.set(requestId,{resolve,reject})}catch(error){reject(error instanceof Error?error:new Error(String(error)))}})}));agent=new Agent({initialState:{systemPrompt:config.systemPrompt||"You are Pocket Pi running on an embedded device.",model,thinkingLevel:"off",tools},streamFn:hostStream,toolExecution:"sequential"});agent.subscribe(event=>{const compact={type:event.type};if(event. +type==="message_update"){compact.kind=event.assistantMessageEvent?.type;compact.delta=event.assistantMessageEvent?.delta}else if(event.type==="message_end"){compact.role=event.message?.role;compact.stopReason=event.message?.stopReason}else if(event.type==="tool_execution_start"||event.type==="tool_execution_end"){compact.name=event.toolName;compact.toolCallId=event.toolCallId;compact.isError=Boolean(event.isError)}events.push(compact)});events.push({type:"agent_ready"})}function prompt(text){if(!agent) +throw new Error("prompt before boot");void agent.prompt(text).catch(error=>events.push({type:"agent_error",message:String(error)}))}function abort(){agent?.abort()}function tick(){const batch=JSON.parse(globalThis.host?.poll()||"[]");for(const event of batch){if(event.type==="model_delta"){const pending=pendingModels.get(event.id);if(pending)pushModelDelta(pending,String(event.delta||""))}else if(event.type==="model_done"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels. +delete(event.id);try{finishModel(pending,JSON.parse(event.result||"{}"))}catch(error){pushModelError(pending.stream,pending.model,String(error))}}else if(event.type==="model_error"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);pushModelError(pending.stream,pending.model,event.error)}else if(event.type==="tool_done"){const pending=pendingTools.get(event.id);if(!pending)continue;pendingTools.delete(event.id);try{const result=JSON.parse(event.result|| +"{}");if(result.isError)throw new Error(String(result.text||"App tool failed"));pending.resolve({content:[{type:"text",text:String(result.text||"")}],details:result.details,terminate:Boolean(result.terminate)})}catch(error){pending.reject(error instanceof Error?error:new Error(String(error)))}}}}function drain(){return JSON.stringify({phase:agent?.state.isStreaming?"thinking":agent?"ready":"idle",messages:agent?.state.messages.length||0,events:events.splice(0,events.length)})}globalThis.PocketPiEmbedded= +{boot,prompt,abort,tick,drain};})(); diff --git a/apps/pi-agent/dist/app.js b/apps/pi-agent/dist/app.js new file mode 100644 index 0000000..adc6f0c --- /dev/null +++ b/apps/pi-agent/dist/app.js @@ -0,0 +1,16 @@ +(()=>{var IJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return H1(this.context.count)},getNextContextId(){return H1(this.context.count++)}};function H1(J){let Q=String(J),$=Q.length-1;return IJ.context.id+($?String.fromCharCode(96+$):"")+Q}function B1(J){IJ.context=J}function $6(){return{...IJ.context,id:IJ.getNextContextId(),count:0}}var Z6=!1,q6=(J,Q)=>J===Q,k0=Symbol("solid-proxy"),X6=typeof Proxy==="function",Y6=Symbol("solid-track"),WQ=Symbol("solid-dev-component"),oJ={equals:q6},j1=null,z6=D1,m=1,yJ=2,K1={owned:null,cleanups:null,context:null,owner:null},S=null,K=null,TJ=null,AJ=null,b=null,w=null,y=null,nJ=0;function tJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?K1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>QJ(()=>$J(z)));S=z,b=null;try{return c(G,!0)}finally{b=$,S=Z}}function C(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return U1($,q)};return[M1.bind($),Z]}function JJ(J,Q,$){let Z=P1(J,Q,!1,m);if(TJ&&K&&K.running)w.push(Z);else eJ(Z)}function _J(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=P1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,TJ&&K&&K.running)Z.tState=m,w.push(Z);else eJ(Z);return M1.bind(Z)}function W6(J){return c(J,!1)}function QJ(J){if(!AJ&&b===null)return J();let Q=b;b=null;try{if(AJ)return AJ.untrack(J);return J()}finally{b=Q}}function S0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function G6(J){if(K&&K.running)return J(),K.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(TJ||H6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[GQ,F1]=C(!1),H6;function M1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)eJ(this);else{let Q=w;w=null,c(()=>J0(this),!1),w=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function U1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw w=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;$J(J);let Q=nJ;if(R1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{c(()=>{K&&(K.running=!0),b=S=J,R1(J,J.tValue,Q),b=S=null},!1)})}function R1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=m,J.tOwned&&J.tOwned.forEach($J),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach($J),J.owned=null;return J.updatedAt=$+1,g0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)U1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function P1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(S===null);else if(S!==K1)if(K&&K.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(AJ&&X.fn){let z=X.fn,[G,P]=C(void 0,{equals:!1}),D=AJ.factory(z,P);S0(()=>D.dispose());let V,B=()=>G6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),K&&K.running){if(!V)V=AJ.factory(z,B);return V.track(_)}return D.track(_)}}return X}function b0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===yJ)return J0(J);if(J.suspense&&QJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===m)eJ(J);else if((Q?J.tState:J.state)===yJ){let q=w;w=null,c(()=>J0(J,$[0]),!1),w=q}}}function c(J,Q){if(w)return J();let $=!1;if(!Q)w=[];if(y)$=!0;else y=[];nJ++;try{let Z=J();return B6($),Z}catch(Z){if(!$)y=null;w=null,g0(Z)}}function B6(J){if(w){if(TJ&&K&&K.running)j6(w);else D1(w);w=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;y.push.apply(y,K.effects),Q=K.resolve;for(let X of y)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,c(()=>{for(let X of q)$J(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zz6($),!1);if(Q)Q()}function D1(J){for(let Q=0;Q{Z.delete($),c(()=>{K.running=!0,b0($)},!1),K&&(K.running=!1)})}}function J0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)$J(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)L1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)$J(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function L1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return S0(()=>I1(X)),()=>{let P=J()||[],D=P.length,V,B;return P[Y6],QJ(()=>{let N,h,a,GJ,VJ,M,j,H,L;if(D===0){if(z!==0)I1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[F6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=M&&H>=M&&Z[j]===P[H];j--,H--)a[H]=q[j],GJ[H]=X[j],G&&(VJ[H]=G[j]);N=new Map,h=Array(H+1);for(B=H;B>=M;B--)L=P[B],V=N.get(L),h[B]=V===void 0?-1:V,N.set(L,B);for(V=M;V<=j;V++)if(L=Z[V],B=N.get(L),B!==void 0&&B!==-1)a[B]=q[V],GJ[B]=X[V],G&&(VJ[B]=G[V]),B=h[B],N.set(L,B);else X[V]();for(B=M;BJ(Q||{}));return B1($),Z}}return QJ(()=>J(Q||{}))}function Q0(){return!0}var P6={get(J,Q,$){if(Q===k0)return $;return J.get(Q)},has(J,Q){if(Q===k0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function w0(J){return!(J=typeof J==="function"?J():J)?{}:J}function D6(){for(let J=0,Q=this.length;J=0;G--){let P=w0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in w0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:D6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var V6=(J)=>`Stale read from <${J}>.`;function kJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return _J(M6(()=>J.each,J.children,Q||void 0))}function SJ(J){let Q=J.keyed,$=_J(()=>J.when,void 0,void 0),Z=Q?$:_J($,void 0,{equals:(q,X)=>!q===!X});return _J(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?QJ(()=>X(Q?q:()=>{if(!QJ(Z))throw V6("Show");return $()})):X}return J.fallback},void 0,void 0)}var L6=(J)=>_J(()=>J());function O6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(M,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(M,j,L,H);JJ((A)=>B(M,j(),A,H),L)}function B(M,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=h(M,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(M),H=j);else h(M,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=h(M,H,L);else if(k==="function")return JJ(()=>{let O=j();while(typeof O==="function")O=O();H=B(M,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return JJ(()=>H=B(M,O,H,L,!0)),()=>H;if(O.length===0){let hJ=h(M,H,L);if(I)return H=hJ}else if(Array.isArray(H))if(H.length===0)a(M,O,L);else N(M,H,O);else if(H==null||H==="")a(M,O);else N(M,I&&H||[P(M)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(M,H,L,j);h(M,H,null,j)}else if(H==null||H===""||!P(M))q(M,j);else GJ(M,j,P(M));H=j}return H}function _(M,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let zQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let hJ=G(O)===M;if(!k&&!I)hJ?GJ(M,A,O):q(M,A,H);else hJ&&X(M,O)}else k=!0}}else q(M,A,H);return[A]}function a(M,j,H){for(let L=0,A=j.length;LH.children=B(M,j.children,H.children));return JJ(()=>j.ref&&j.ref(M)),JJ(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(M,A,k,H[A]),H[A]=k}}),H}return{render(M,j){let H;return tJ((L)=>{H=L,V(j,M())}),H},insert:V,spread(M,j,H){if(typeof j==="function")JJ((L)=>VJ(M,j(),L,H));else VJ(M,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(M,j,H,L){return z(M,j,H,L),H},mergeProps:A1,effect:JJ,memo:L6,createComponent:R6,use(M,j,H){return QJ(()=>M(j,H))}}}function I6(J){let Q=O6(J);return Q.mergeProps=A1,Q}var _1=480,k1=272,HJ={view:0,text:1,image:2},A6=1,_6=-1,k6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},S6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},b6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},g6=1,HQ=2,BQ=1,jQ=2,KQ=131072,FQ=1,MQ=262144,UQ=1,RQ=1,PQ=1,DQ=2,VQ=4,LQ=8,OQ=16,IQ=1,AQ=2;function S1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var _Q=1,w6=1263551300,C6=1,E6=32,N6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},BJ=32896,kQ=0.016666666666666666;function b1(J){return J.__viewport??null}var C0=null;function h6(){return null}function g1(J,Q=h6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function y6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return g1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return g1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function T6(J){C0=J}function bJ(){if(!C0)throw Error("PocketJS: host not installed — call render() first");return C0}function E(){return bJ().ops}function x6(J){globalThis.frame=J}function f6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function v6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return S1($>>>16&255,$>>>8&255,$&255,255);return S1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function m6(J,Q){let $=S6[J];if(typeof Q==="string"){if($===U.color)return v6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var $0=60,w1=[1,2,3,4,5,6,10,12,15,20,30,60],E0=$0,ZJ=-1,u6=0,xJ=[];function l6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=w1[0];for(let $ of w1)if(Math.abs($-J)Q.at<=ZJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>ZJ);for(let Q of J)Q.cb()}var N0=0.12,Z0=BJ;function i6(J){Z0=J===void 0?BJ:J&65535}function s6(){Z0=BJ}function N1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function r6(){return N1(Z0&255)}var h1=new Set,o6=0;function n6(){h1.clear(),o6=0,s6()}function t6(J){for(let Q of[...h1])Q(J)}var jJ=null,y1=null;function e6(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function T1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function fJ(J){h0();let Q=jJ?jJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return y1.slice(Q.off,Q.off+Q.len)}var vJ=null,g=null,KJ=null,q0=0,FJ=[],T0=[],x0=[];function f1(J){if(vJ=J,g=null,KJ=null,q0=0,FJ.length=0,T0.length=0,x0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function Q8(J,Q){J.onPress=Q??void 0}function $8(J,Q){if(J.focusable=Q,p1(),!Q&&g===J)x(null)}function x(J){if(KJ&&KJ!==J)MJ(null);g=J,E().setFocus(J?J.id:0)}function MJ(J){if(KJ===J)return;let Q=E();if(KJ)Q.setActive?.(KJ.id,0);if(KJ=J,J)Q.setActive?.(J.id,1)}function f0(){return FJ.length>0?FJ[FJ.length-1]:vJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function X8(){if(!g)return null;let J=f0();if(J&&!i(g,J))return null;for(let Q=T0.length-1;Q>=0;Q--){let $=T0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(g,$.node))return $}return null}function Y8(J){let Q=X8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(g)x(null);return!0}let Z=Q.columns,q=g?$.indexOf(g):-1;if(q<0)return x(v1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function z8(){if(!g)return null;let J=f0();if(J&&!i(g,J))return null;for(let Q=x0.length-1;Q>=0;Q--){let $=x0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(g,$.node))return $}return null}function X0(J){let Q=z8();if(Q&&Q.move(J))return;if(Y8(J))return;q8(J)}function m1(){u1(g)}function u1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){MJ(J)}function W8(J){x(J),u1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=m0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,l1=0;function p1(){l1++}var H8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],B8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function j8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=H8[Q]>>$&1,q=B8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function K8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=fJ($.image)}catch(z){if(bJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):F8(Q,X),q<0&&bJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(j8(),16,16,b6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function F8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&g6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var W0=null;function c1(J){W0=J}function d1(J){let Q=FJ.length>0?FJ[FJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function i1(J,Q,$){return d1(s1(J,Q,$))}function s1(J,Q,$){if($!==void 0)return $===0?null:z0(W0??vJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(W0??vJ,q(J,Q))}function M8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=b1(q);if(Z.vw=B?B.w:_1,Z.vh=B?B.h:k1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)K8(Z,q);let X=a6()*Z.speed,z=r6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=p6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=l1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=d1(z0(W0??vJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==g)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(MJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,MJ(null),B)m1()}}else if($&Z.button)MJ(null);return!0}function U8(J){let Q=J&~q0,$=q0&~J;if(q0=J,l&&M8(J,Q,$))return;if($&d.CIRCLE)MJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)MJ(g),m1()}var u0=null;function a1(J){u0=J}function gJ(){if(p1(),u0)u0()}function R8(J,Q){J.debugName=Q||void 0,gJ()}var qJ={id:A6,type:HJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},r1=Symbol.for("pocketjs.native-node"),l0=1,mJ=3,o=8,P8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function G0(J){return J.domAttrs??={}}function o1(J,Q){let $=J.domNodeType??(uJ(J)?mJ:l0),Z=$===mJ?H0(J.text??""):$===o?L8(J.domData??""):Z4(J.domTag??j0(J));for(let q of Object.keys(J.domAttrs??{}))p0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)XJ(Z,o1(q,!0));return Z}function p0(J,Q,$){if(P8.has(Q)){CJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete G0(J)[Q];else G0(J)[Q]=$}function c0(J){if(J[r1]===!0)return J;return Object.defineProperty(J,r1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?mJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(uJ(J))B0(J,Z);else if(b8(J),Z)XJ(J,H0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return X4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??j0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===mJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??j0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){CJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===qJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return XJ(J,$),$},insertBefore($,Z){return XJ(J,$,Z??null),$},removeChild($){return lJ(J,$),$},replaceChild($,Z){return XJ(J,$,Z),lJ(J,Z),Z},cloneNode($=!1){return o1(J,!!$)},remove(){if(J.parent)lJ(J.parent,J)},setAttribute($,Z){p0(J,$,Z)},removeAttribute($){p0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(qJ);var d0=null;function D8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},n1=new Map;function t1(J,Q){n1.set(J,Q)}var e1=new Map;function J4(J,Q){e1.set(J,Q)}var wJ=new Set,V8=new Set;function Q4(J){if(!J)return!1;if(V8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function H0(J){let Q=E(),$=Q.createNode(HJ.text);return Q.setText($,J),c0({id:$,type:HJ.text,parent:null,children:[],text:J,domNodeType:mJ,domTag:"#text"})}function L8(J=""){let Q=H0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){E().replaceText(J.id,Q),J.text=Q,gJ()}function uJ(J){return J.type===HJ.text}function q4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function XJ(J,Q,$){let Z=E();if(q4(Q),wJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,gJ()}function lJ(J,Q){if(!Q)return;G8(Q),E().removeChild(J.id,Q.id),q4(Q),wJ.add(Q),gJ()}function O8(J){return J.parent??void 0}function I8(J){return J.children[0]}function X4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function A8(J,Q){let $=E();if(gJ(),Q==null||Q===""){$.setStyle(J.id,_6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(bJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function _8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=n1.get(Q);if(Z===void 0){if(bJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function k8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=e1.get(Q);if(Z===void 0){if(bJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function S8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=k6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,m6(G,P)),z=!0}if(z)gJ()}function CJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete G0(J)[Q];else G0(J)[Q]=$;switch(Q){case"class":return A8(J,$),$;case"onPress":case"on:press":return Q8(J,$),$;case"src":return _8(J,$),$;case"sprite":return k8(J,$),$;case"style":return S8(J,$,Z),$;case"focusable":return $8(J,!!$),$;case"debugName":return R8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${j0(J)}>`)}function b8(J){for(let Q of[...J.children])lJ(J,Q)}function j0(J){for(let Q of Object.keys(HJ))if(HJ[Q]===J.type)return Q;return String(J.type)}function g8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}CJ(J,Q,$,Z)}var w8=I6({createElement:Z4,createTextNode:H0,replaceText:B0,isTextNode:uJ,setProperty:g8,insertNode(J,Q,$){XJ(J,Q,$)},removeNode(J,Q){lJ(J,Q)},getParentNode:O8,getFirstChild:I8,getNextSibling:X4}),{render:C8,effect:SQ,memo:p,createComponent:Y,createElement:Y4,insert:bQ,spread:E8,mergeProps:gQ,use:wQ}=w8,CQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},N8=null;function z4(J){N8=J}function h8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function W4(J,Q){let $=Y4(J);return E8($,Q,!1),h8(Q.nodeRef,$),$}function F(J){return W4("view",J)}function R(J){return W4("text",J)}var EQ=new WeakMap,NQ=new WeakMap,y8={}!==null?Object.freeze({...{}}):Object.freeze({}),hQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:y8}),yQ=new Map,YJ=36000,s0=30,T8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(YJ),tapeAnalog:new Uint16Array(YJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function x8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-s0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)a1(()=>{W.treeDirty=!0}),d8();else a1(null);globalThis.__pocketDevtools=s8}function f8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)m8(),p8();let X=Q,z=$===void 0?BJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(YJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==BJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function B4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function j4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.masks,0,Q)}function K4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.analog??[],BJ,Q)}function F4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,T({t:"hello",app:W.app,host:i8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` +`))if(q.trim())u8(q)}}function u8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),a0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":M4();break;case"eval":{let Z=!0,q;try{q=K0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}T({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":T({t:"tape",tape:H4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}T({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=j4(Z),W.replayAnalog=Z.analog?K4(Z):null,W.replayTouch=Z.touch?F4(Z):null,W.replayAt=0;break}default:break}}function l8(){if(W.treeDirty&&W.frame-W.treeSentAt>=s0)M4();if(W.frame%T8===0)a0()}function p8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){T({t:"stats",frame:W.frame,nodes:P4(qJ),tapeLen:W.tapeLen,paused:W.paused})}function M4(){W.treeDirty=!1,W.treeSentAt=W.frame,T({t:"tree",frame:W.frame,root:R4(qJ)})}function c8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(c8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function U4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function R4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(U4(J,(q)=>{if(q.domNodeType===8)return;Z.push(R4(q))}),Z.length)Q.k=Z;return Q}function P4(J){let Q=1;return U4(J,($)=>{Q+=P4($)}),Q}function d8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{T({t:"log",level:$,args:q.map((X)=>K0(X))}),Z?.apply(Q,q)}}}function K0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?D4(X):JSON.stringify(D4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>K0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${K0(z,Q+1)}`).join(", ")}}`}function D4(J){return J.length>200?J.slice(0,199)+"…":J}function i8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var s8={get frame(){return W.frame},dumpTape:()=>H4(),replay:(J)=>{W.replayMasks=j4(J),W.replayAnalog=J.analog?K4(J):null,W.replayTouch=J.touch?F4(J):null,W.replayAt=0}},V4=new Map,o0=new Map;function L4(J){return J.trim().replace(/\s+/g," ")}function O4(J){return J.split(" ").sort().join(" ")}var I4=-1;function a8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=L4(Q);V4.set(Z,$);let q=O4(Z),X=o0.get(q);o0.set(q,X!==void 0&&X!==$?I4:$)}}function r8(J){let Q=L4(J),$=V4.get(Q);if($!==void 0)return $;let Z=o0.get(O4(Q));return Z===I4?void 0:Z}var n0=9,o8=(1<{let q=($&t8)!==0,X=q?t0:n0,z=q?e8:o8;return Object.freeze({id:$>>>(q?J2:n8)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function $2(){return F0}function Z2(){F0=e0}var A4=8,zJ=8,q2=3,X2=8,Y2=6,z2=0.5,s=1,pJ=2,J1=4,UJ=8,EJ=[],_4=0,M0=0,WJ=Array.from({length:A4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(zJ),histY:new Int16Array(zJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function W2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function G2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=s1(Q,$,Z.fact);let G=Z.hit;if(G)return W2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=EJ[z];if(G.disposed)continue;if(_4>0&&!G.opts.allowWhenBlocked)continue;if(!G2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function j2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%zJ,J.histLenz||Z>z))q.flags[J.slot]|=pJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(pJ|J1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??z2)*C1()));if(J.frames=0)EJ.splice($,1)},cancel(){if(!Q.disposed)b4(Q)},get panning(){for(let $ of WJ)if($.used&&Q.flags[$.slot]&UJ)return!0;return!1}}}function R2(J){let Q=U2(J);return S0(()=>Q.dispose()),Q}function g4(){EJ.length=0,_4=0,M0=0;for(let J of WJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function P2(){return R2({onDown:(J)=>{let Q=i1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=i1(J.x,J.y,J.hit);if(Q)W8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var D2=1,Q1=new Map,U0=[];function V2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function L2(){D2=1,Q1.clear(),U0=[]}function O2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),V2()?.({t:"delivery",frame:E1(),id:Q,kind:Z.kind}),Z.onResult($)}}var I2={"text-lg text-orange-600 font-bold":0,"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":1,"w-[165] h-[76] items-center justify-center bg-orange-600":2,"w-[165] h-[76] items-center justify-center bg-slate-900":3,"text-sm text-white font-bold":4,"flex-col w-full h-full bg-slate-50":5,"h-[686] px-6 pt-7 flex-col gap-[22]":6,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":7,"h-[28] flex-row items-center gap-3":8,"w-[10] h-[10] rounded bg-orange-500":9,"text-sm text-orange-600 font-bold":10,"h-[76] pt-3 text-base text-slate-900":11,"h-[2] mx-1 my-4 bg-slate-100":12,"w-[10] h-[10] rounded bg-emerald-500":13,"text-sm text-emerald-700 font-bold":14,"h-[84] pt-3 text-base text-slate-900":15,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":16,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":17,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":18,"text-sm text-slate-600 font-bold":19,"pt-6 text-base text-slate-500":20,"pt-6 text-base text-slate-900 font-bold":21,"h-[146] px-6 pt-7 flex-col bg-slate-50":22,"h-[80]":23,"h-[1060] px-6 pt-5 flex-col":24,"h-[48] px-4 justify-center bg-slate-100":25,"text-sm text-slate-600":26,"pt-[10] flex-col gap-[12]":27,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":28,"w-[48] h-[48] items-center justify-center bg-blue-100":29,"w-[48] h-[48] items-center justify-center bg-emerald-100":30,"text-base text-blue-700 font-bold":31,"text-base text-emerald-700 font-bold":32,"w-[474] flex-col gap-2":33,"text-base text-slate-900 font-bold":34,"text-sm text-slate-500":35,"pt-20 pl-10 text-base text-slate-500":36,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":37,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":38,"h-[1060] px-6 pt-7 flex-col gap-4":39,"text-sm text-slate-500 font-bold":40,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":41,"flex-row items-center gap-5":42,"w-[68] h-[68] items-center justify-center bg-emerald-100":43,"text-xl text-emerald-700 font-bold":44,"flex-col gap-2":45,"text-lg text-slate-900 font-bold":46,"text-base text-slate-600":47,"text-2xl text-orange-600":48,"w-[68] h-[68] items-center justify-center bg-indigo-100":49,"text-xl text-indigo-700 font-bold":50,"mt-4 h-[112] px-6 justify-center bg-slate-100":51,"relative h-[154] px-5 pt-5 flex-col bg-white":52,"pt-3 text-base text-orange-600 font-bold":53,"pt-3 text-sm text-slate-500":54,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":55,"text-base text-white font-bold":56,"h-[40] pt-3 text-sm text-slate-500":57,"h-[470] flex-col gap-2":58,"h-[214] px-7 items-center justify-center bg-slate-100":59,"text-base text-slate-500 font-bold":60,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":61,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":62,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":63,"h-[160] px-5 pt-5 flex-col bg-white":64,"pt-3 text-base text-slate-900 font-bold":65,"pt-3 text-sm text-slate-600":66,"h-[108] pt-7 flex-row gap-4":67,"w-[316] h-[80] items-center justify-center bg-slate-100":68,"w-[340] h-[80] items-center justify-center bg-red-100":69,"text-base text-red-500 font-bold":70,"h-[1052] px-6 pt-5 flex-col":71,"h-[270] px-[22] pt-6 bg-white":72,"text-lg text-slate-900":73,"text-lg text-slate-400":74,"h-[86] px-1 flex-row items-center justify-between":75,"w-[132] h-[58] items-center justify-center bg-slate-100":76,"text-sm text-slate-900 font-bold":77,"h-[140] flex-row gap-2":78,"grow h-[120] items-center justify-center bg-white":79,"text-xl text-slate-900 font-bold":80,"w-[104] h-[120] items-center justify-center bg-slate-100":81,"h-[176] flex-row gap-2":82,"w-[92] h-[156] items-center justify-center bg-slate-100":83,"w-[300] h-[156] items-center justify-center bg-slate-100":84,"w-[144] h-[156] items-center justify-center bg-slate-100":85,"w-[112] h-[156] items-center justify-center bg-emerald-500":86,"text-sm text-slate-950 font-bold":87,"h-[108] px-6 py-3 flex-col bg-slate-50":88,"h-[84] items-center justify-center bg-slate-100":89,"h-[1168] px-6 pt-5 flex-col":90,"h-[82] px-4 justify-center bg-white":91,"w-[584] h-[900] px-5 pt-5 bg-slate-950":92,"text-sm text-slate-200":93,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":94,"text-base text-orange-600 font-bold":95,"w-[584] h-[900] px-5 pt-5 bg-white":96,"text-sm text-slate-900":97,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":98,"absolute inset-0 z-50 flex-col items-center justify-center":99,"absolute inset-0 bg-slate-950":100,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":101,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":102,"flex-row flex-wrap":103,grow:104,"text-2xl text-white font-bold":105,"text-base text-slate-900":106,"px-6":107,"px-6 py-5":108,"gap-4":109,"w-[34] h-[34] rounded-lg bg-amber-400":110,"w-[34] h-[34] rounded-lg bg-red-500":111,"w-[34] h-[34] rounded-lg bg-slate-800":112,"w-[34] h-[34] rounded-lg bg-emerald-500":113,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":114,"flex-row items-center gap-4":115,"w-[34] text-2xl text-white font-bold":116,"w-[332] flex-col items-end gap-2":117,"text-sm text-slate-300 font-bold":118,"text-sm text-slate-400":119,"h-[40] px-1 flex-row items-center justify-between":120,"w-full h-full items-center justify-center rounded-xl bg-slate-200":121,"w-full h-full items-center justify-center rounded-xl bg-orange-600":122};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var A2="ui:styles",_2="ui:font.",w4="ui:img.",C4="ui:sprite.";function k2(){return globalThis.ui}function S2(J){if(J.__textures)return;for(let Q of y0(w4)){let $=fJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)t1(Q.slice(w4.length),Z)}}function b2(J){if(J.__sprites)return;for(let Q of y0(C4)){let $=fJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)J4(Q.slice(C4.length),{handle:V,frames:G,cols:P,step:D})}}function E4(J){let Q=Y4("view");return CJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function g2(J,Q){if(!R0||!P0)return;CJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),CJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function w2(J,Q={}){let $=y6(Q.ops);if(T6($),D8(r8),Q.styles)a8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)t1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)J4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)x1(Q.pak);if(J8()){for(let B of y0())if(B===A2)$.ops.loadStyles?.(fJ(B));else if(B.startsWith(_2))$.ops.loadFontAtlas?.(fJ(B))}}let q=b1($.ops),X=q?.w??_1,z=q?.h??k1,G=E4({width:X,height:z,overflow:u.Overflow.Hidden}),P=E4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});XJ(qJ,G),XJ(qJ,P),z4(P),R0=G,P0=P,f1(G),c1(qJ),n6(),g4(),P2(),c6(),L2(),x8($.ops),x6(f8((B,_,N,h)=>{d6(),i6(_),Q2(N,h),O2(),M2(),t6(B),U8(B),$4()}));let D=C8(J,G),V=f6(g2);return()=>{V(),Z2(),g4(),D(),f1(null),c1(null),z4(null),R0=null,P0=null;for(let B of qJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);$4()}}function C2(J,Q={}){let $=Q.ops??k2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)x1(Q.pak);return S2($),b2($),w2(J,{ops:$,styles:Q.styles??I2,pak:Q.pak})}var E2="$b",N2=65536,N4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",cJ={};for(let J=0;J>16,Z<$.length)$[Z++]=X>>8&255;if(Z<$.length)$[Z++]=X&255}return $}function y2(J){let Q="",$=0;while($J.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function T2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function h4(){let J=T2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function x2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,N2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=h2(z.data[E2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function f2(J,Q){let $=x2(h4(),J);return Q==="utf8"||Q==="utf-8"?y2($):$}function v2(J,Q){let $=h4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var m2={title:"text-2xl text-white font-bold",section:"text-sm text-slate-600 font-bold",body:"text-base text-slate-900",bodyStrong:"text-base text-slate-900 font-bold",caption:"text-sm text-slate-500"};function u2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(F,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(F,{class:"flex-row items-center gap-4",get children(){return[p(()=>p(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(F,{get["class"](){return Q()}})),Y(R,{get["class"](){return m2.title},get children(){return J.title}})]}}),Y(F,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-sm text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-sm text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function l2(J){return Y(F,{get["class"](){return J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":"w-full h-full items-center justify-center rounded-xl bg-orange-600"},get children(){return Y(R,{get["class"](){return J.disabled?"text-base text-slate-500 font-bold":"text-base text-white font-bold"},get children(){return J.label}})}})}var TQ="‘’“”–—…•",y4=new Map,T4=new Map;function D0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=y4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return y4.set($,q),q}function p2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=D0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function $1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=T4.get(Z);if(q)return q;let X=[],z=D0(" ",Q);for(let G of J.split(` +`)){let P=G.split(" ").flatMap((B)=>B&&D0(B,Q)>$?p2(B,Q,$):[B]),D="",V=0;for(let B of P){let _=D0(B,Q);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return T4.set(Z,X),X}function x4(J,Q,$,Z){let q=$1(J,Q,$);if(q.length<=Z)return q.join(` +`);let X=q.slice(0,Z);return X[Z-1]=X[Z-1].replace(/[\s.]+$/,"")+"…",X.join(` +`)}var f4=2,v4=1,m4=536,u4=544,l4=46,[RJ,c2]=C({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[f,n]=C("chat"),[V0,d2]=C("chat"),[Z1,p4]=C(0),[t,c4]=C(""),[dJ,NJ]=C(0),[iJ,q1]=C([]),[i2,L0]=C(""),[d4,O0]=C(null),[i4,s4]=C(null),[I0,A0]=C(0),[v,e]=C(""),[PJ,a4]=C("letters"),[X1,Y1]=C(!1),[z1,r4]=C({type:"prompt"}),[sJ,o4]=C(0),W1=new Map,n4=["qwertyuiop","asdfghjkl","zxcvbnm"],t4=["1234567890","-/:;()$&@",`.,?!'"+`],e4=["chat","files","apps","settings"];function s2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function a2(J,Q){return J?J+"/"+Q:Q}function aJ(J=t(),Q=!1){let $=W1.get(J);if(!Q&&$){q1($),L0(""),NJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=v2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));W1.set(J,Z),q1(Z),L0(""),NJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){q1([]),L0(Z instanceof Error?Z.message:String(Z))}}function r2(){let J=[];for(let Q of RJ().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function J6(){let J=r2(),Q=Math.max(0,J.length-2),$=Math.min(Z1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function DJ(J){return Y(u2,{get title(){return J.title},get accent(){return p(()=>RJ().agent==="FAULTED")()?"danger":RJ().agent==="THINKING"?"busy":"ready"}})}function rJ(J){return[Y(F,{get["class"](){return J.top},get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",children:"UP"})}}),Y(F,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",children:"DN"})}})]}function _0(){return Y(F,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(kJ,{each:e4,children:(J)=>Y(F,{get["class"](){return V0()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-sm text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function o2(){let J=()=>RJ().schedule;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"ESP32 PI AGENT"}),Y(F,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(kJ,{get each(){return J6()},children:(Q)=>Y(F,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-sm text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-base text-slate-900",get children(){return x4(Q.user,f4,m4,3)}}),Y(F,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-sm text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-base text-slate-900",get children(){return x4(Q.assistant,f4,m4,3)}})]}})}),Y(rJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(F,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-sm text-slate-600 font-bold",children:"NEXT WAKE"}),Y(SJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-base text-slate-500",children:`NO WAKE SCHEDULED + +ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(R,{class:"pt-6 text-base text-slate-900 font-bold",get children(){return String(J()?.name)+" "+String(J()?.next??"")+` + +`+String(J()?.prompt??"")}})}})]}}),Y(F,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(F,{class:"h-[80]",get children(){return Y(l2,{label:"TYPE A MESSAGE"})}})}}),Y(_0,{})]}})}function n2(){let J=()=>iJ().slice(dJ(),dJ()+8);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{get title(){return t()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-600",get children(){return"/workspace"+(t()?"/"+t():"")}})}}),Y(F,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(kJ,{get each(){return J()},children:(Q)=>Y(F,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(F,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-base text-blue-700 font-bold":"text-base text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(F,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,60)}}),Y(R,{class:"text-sm text-slate-500",get children(){return p(()=>Q.kind==="dir")()?"FOLDER":s2(Q.size)}})]}})]}})})}}),Y(SJ,{get when(){return iJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-base text-slate-500",get children(){return i2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(SJ,{get when(){return iJ().length>8},get children(){return Y(rJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(_0,{})]}})}function t2(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"APPS"}),Y(F,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-sm text-slate-500 font-bold",children:"2 INSTALLED APPS"}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-emerald-100",get children(){return Y(R,{class:"text-xl text-emerald-700 font-bold",children:"R"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"Robinhood"}),Y(R,{class:"text-base text-slate-600",children:"Portfolio and positions"}),Y(R,{class:"text-sm text-slate-500",children:"UPDATES EVERY 5 MINUTES"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-indigo-100",get children(){return Y(R,{class:"text-xl text-indigo-700 font-bold",children:"E"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"Exa Research"}),Y(R,{class:"text-base text-slate-600",children:"Agent search history"}),Y(R,{class:"text-sm text-slate-500",children:"STORED LOCALLY IN SQLITE"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-600",children:`APP DATA STAYS ISOLATED. +PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(_0,{})]}})}function e2(){let J=()=>RJ().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(sJ(),sJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"SETTINGS"}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-base text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-sm text-slate-500",get children(){return Z()}}),Y(F,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-sm text-slate-500",children:"AVAILABLE NETWORKS"}),Y(F,{class:"h-[470] flex-col gap-2",get children(){return[Y(SJ,{get when(){return $().length>0},get fallback(){return Y(F,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-500 font-bold",children:`NO NETWORK LIST YET + +TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(kJ,{get each(){return $()},children:(q)=>Y(F,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-sm text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(SJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(rJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(F,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-sm text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-base text-slate-900 font-bold",get children(){return RJ().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-sm text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(F,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(F,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(F,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-base text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(_0,{})]}})}function JQ(){let J=()=>z1(),Q=()=>PJ()==="letters"?n4:t4,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(F,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(F,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-sm text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(F,{class:"w-[132] h-[58] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(kJ,{get each(){return Q()},children:(Z,q)=>Y(F,{class:"h-[140] flex-row gap-2",get children(){return[Y(kJ,{get each(){return Z.split("")},children:(X)=>Y(F,{class:"grow h-[120] items-center justify-center bg-white",get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return p(()=>!!X1())()?X.toUpperCase():X}})}})}),Y(SJ,{get when(){return q()===2},get children(){return Y(F,{class:"w-[104] h-[120] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(F,{class:"h-[176] flex-row gap-2",get children(){return[Y(F,{class:"w-[92] h-[156] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",get children(){return PJ()==="letters"?"123":"ABC"}})}}),Y(F,{class:"w-[300] h-[156] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"SPACE"})}}),Y(F,{class:"w-[144] h-[156] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",get children(){return PJ()==="letters"?"SHIFT":". ?"}})}}),Y(F,{class:"w-[112] h-[156] items-center justify-center bg-emerald-500",get children(){return Y(R,{class:"text-sm text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(F,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(F,{class:"h-[84] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function QQ(){let J=()=>d4(),Q=()=>(J()?.text??"").split(` +`),$=()=>J()?.lineOffset??0;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"< FILE VIEWER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(R,{class:"text-sm text-slate-200",get children(){return Q().slice($(),$()+39).join(` +`)}})}}),Y(R,{class:"pt-3 text-sm text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(rJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function $Q(){let J=()=>i4(),Q=()=>$1(J()?.text??"",v4,u4);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"< MESSAGE READER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-base text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-sm text-slate-900",get children(){return Q().slice(I0(),I0()+l4).join(` +`)}})}}),Y(rJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function ZQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return p(()=>f()==="chat")()?Y(o2,{}):p(()=>f()==="files")()?Y(n2,{}):p(()=>f()==="apps")()?Y(t2,{}):p(()=>f()==="settings")()?Y(e2,{}):p(()=>f()==="keyboard")()?Y(JQ,{}):p(()=>f()==="viewer")()?Y(QQ,{}):Y($Q,{})}})}function qQ(J){W6(()=>{if(d2(J),n(J),J==="files")aJ()})}function XQ(J,Q){let $=PJ()==="letters"?n4:t4,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return e(""),n(V0()),"";if(J>=548&&Q>=402&&Q<=482)return e(""),"";let $=XQ(J,Q);if($){let Z=PJ()==="letters"&&X1()?$.toUpperCase():$,q=z1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return e(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)a4(PJ()==="letters"?"numbers":"letters"),Y1(!1);else if(J<=424){if(v())e(v()+" ")}else if(J<=576)if(PJ()==="letters")Y1(!X1());else e(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=z1();if(e(""),a4("letters"),Y1(!1),n(V0()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}C2(()=>Y(ZQ,{})),queueMicrotask(()=>aJ("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return c2(JSON.parse(J)),""},dataChanged(){if(W1.delete(t()),V0()==="files")aJ(t(),!0);return""},invokeTool(){return JSON.stringify({text:"Pi Agent has no App tools",isError:!0})},invokeTask(){return JSON.stringify({text:"Pi Agent has no App tasks",isError:!0})},tap(J,Q){if(f()==="keyboard")return YQ(J,Q);if(f()==="viewer"){let $=d4();if(J<104&&Q<112)O0(null),n("files");else if($&&J>=620&&Q>=170&&Q<=340)O0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)O0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` +`).length-39),$.lineOffset+18)});return""}if(f()==="reader"){if(J<104&&Q<112)s4(null),A0(0),n("chat");else if(J>=620&&Q>=170&&Q<=340)A0(Math.max(0,I0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=$1(i4()?.text??"",v4,u4).length;A0(Math.min(Math.max(0,$-l4),I0()+18))}return""}if(Q>=1172)return qQ(e4[Math.min(3,Math.floor(J/180))]),"";if(f()==="chat"){if(J>=620&&Q>=140&&Q<=272)p4(Z1()+2);else if(J>=620&&Q>=624&&Q<=756)p4(Math.max(0,Z1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=J6()[$];if(Z){let q=Q>=140+$*320+150;s4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),A0(0),n("reader")}}else if(Q>=1070&&Q<=1150)r4({type:"prompt"}),e(""),n("keyboard");return""}if(f()==="files"){if(J<104&&Q<112&&t()){let $=t().split("/");$.pop();let Z=$.join("/");c4(Z),NJ(0),aJ(Z)}else if(J>=620&&Q>=170&&Q<=340)NJ(Math.max(0,dJ()-4));else if(J>=620&&Q>=920&&Q<=1100)NJ(Math.min(Math.max(0,iJ().length-8),dJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=iJ()[dJ()+$];if(Z){let q=a2(t(),Z.name);if(Z.kind==="dir")c4(q),NJ(0),aJ(q);else try{O0({path:"/workspace/"+q,text:f2(q,"utf8"),lineOffset:0}),n("viewer")}catch(X){L0(X instanceof Error?X.message:String(X))}}}return""}if(f()==="apps"){if(Q>=162&&Q<324)return JSON.stringify({type:"navigate",app:"robinhood"});if(Q>=324&&Q<490)return JSON.stringify({type:"navigate",app:"exa"});return""}if(f()==="settings"){let $=RJ().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)o4(Math.max(0,sJ()-4));else if(J>=620&&Q>=650&&Q<=782)o4(Math.min(Math.max(0,$.length-5),sJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[sJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});r4({type:"wifi",ssid:q.ssid}),e(""),n("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); diff --git a/apps/pi-agent/dist/app.pak b/apps/pi-agent/dist/app.pak new file mode 100644 index 0000000000000000000000000000000000000000..59847a83fdcd8c1ae6e25dad35cbda2ecbf22d95 GIT binary patch literal 431376 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 literal 0 HcmV?d00001 diff --git a/apps/pi-agent/pocket.json b/apps/pi-agent/pocket.json new file mode 100644 index 0000000..0e24172 --- /dev/null +++ b/apps/pi-agent/pocket.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://pocketjs.dev/schema/pocket-2.json", + "pocket": 2, + "id": "dev.pocket-stack.pi-agent", + "name": "pi-agent", + "title": "Pi Agent", + "version": "1.0.0", + "engine": { + "capabilities": { + "requires": ["data.fs", "data.sqlite"] + } + }, + "app": { + "entry": "app.tsx", + "output": "app", + "framework": "solid", + "viewport": { "logical": [720, 1280], "presentation": "fit" } + } +} diff --git a/apps/robinhood/agent-app.json b/apps/robinhood/agent-app.json new file mode 100644 index 0000000..ceeaa19 --- /dev/null +++ b/apps/robinhood/agent-app.json @@ -0,0 +1,21 @@ +{ + "id": "robinhood", + "version": "1.0.0", + "dataVersion": 4, + "tools": [ + {"name":"robinhood.get_accounts","description":"List Robinhood brokerage accounts. Read-only.","parameters":{"type":"object","properties":{},"additionalProperties":true}}, + {"name":"robinhood.get_portfolio","description":"Read the latest portfolio for an account and save it to the App database.","parameters":{"type":"object","properties":{"account_number":{"type":"string"}},"additionalProperties":true}}, + {"name":"robinhood.get_equity_positions","description":"Read equity positions and save them to the App database.","parameters":{"type":"object","properties":{"account_number":{"type":"string"}},"additionalProperties":true}}, + {"name":"robinhood.get_equity_orders","description":"Read equity orders and save them to the App database.","parameters":{"type":"object","properties":{"account_number":{"type":"string"}},"additionalProperties":true}}, + {"name":"robinhood.get_equity_historicals","description":"Read equity historicals and save them to the App database.","parameters":{"type":"object","properties":{"account_number":{"type":"string"}},"additionalProperties":true}}, + {"name":"robinhood.get_realized_pnl","description":"Read realized P&L and save it to the App database.","parameters":{"type":"object","properties":{"account_number":{"type":"string"}},"additionalProperties":true}}, + {"name":"robinhood.get_pnl_trade_history","description":"Read chronological realized P&L trade history.","parameters":{"type":"object","properties":{"account_number":{"type":"string"}},"additionalProperties":true}}, + {"name":"robinhood.review_equity_order","description":"Review an equity order without submitting it.","parameters":{"type":"object","additionalProperties":true}}, + {"name":"robinhood.refresh_portfolio","description":"Refresh accounts, portfolio, positions, orders and P&L into local SQLite.","parameters":{"type":"object","properties":{},"additionalProperties":false}}, + {"name":"robinhood.storage_status","description":"Inspect this App's local SQLite schema, row counts, and bounded recent row summaries without contacting Robinhood.","parameters":{"type":"object","properties":{},"additionalProperties":false}} + ], + "tasks": ["refreshPortfolio"], + "schedules": [ + {"id":"portfolio-refresh","everyMinutes":5,"task":"refreshPortfolio","args":{}} + ] +} diff --git a/apps/robinhood/app.tsx b/apps/robinhood/app.tsx new file mode 100644 index 0000000..e376db7 --- /dev/null +++ b/apps/robinhood/app.tsx @@ -0,0 +1,562 @@ +import { batch, createMemo, createSignal, For, Show } from "solid-js"; +import { Text, View } from "@pocketjs/framework/components"; +import { mount } from "@pocketjs/framework"; +import { Database } from "@pocketjs/framework/db"; +import { ActionButton, PocketHeader, SectionHeading } from "../_shared/ui"; + +const DB_SCHEMA_VERSION = 4; +const db = new Database("robinhood"); + +type Screen = "dashboard" | "accounts" | "activity" | "positions"; +type Span = "day" | "week"; +type Account = { number: string; label: string; suffix: string; status: string }; +type Position = { symbol: string; quantity: string; averagePrice: string; marketValue: string }; +type Activity = { title: string; timestamp: string; detail: string; state: string; amount: string; side: string }; +type Dashboard = { + account: Account; + totalValue: string | null; + cash: string | null; + buyingPower: string | null; + pnlDay: string | null; + pnlWeek: string | null; + positions: Position[]; + activity: Activity[]; + positionsAvailable: boolean; + activityAvailable: boolean; + observedAt: number | null; +}; +type ChartPoint = { x: number; y: number }; +type ChartSegment = { x: number; y: number; width: number; angle: number }; +type ChartProjection = { points: ChartPoint[]; segments: ChartSegment[]; labels: string[]; trend: { change: string; percent: string; positive: boolean } }; +type Cached = { loadedRevision: number; value: T }; +type AccountRow = { account_number: string; label: string; suffix: string; status: string }; +type PortfolioRow = { account_number: string; cash: string | null; buying_power: string | null; day_pnl: string | null; week_pnl: string | null; observed_at: number }; +type PositionRow = { account_number: string; symbol: string; quantity: string | null; average_price: string | null; market_value: string | null }; +type ActivityRow = { account_number: string; activity_id: string; occurred_at: string | null; symbol: string | null; side: string | null; quantity: string | null; price: string | null; amount: string | null; state: string | null; activity_type: string | null }; + +const EMPTY_ACCOUNT: Account = { number: "", label: "ACCOUNT", suffix: "", status: "WAITING FOR ROBINHOOD" }; +const EMPTY_ACTIVITY: Activity = { title: "NO RECENT ACTIVITY", timestamp: "", detail: "", state: "", amount: "", side: "" }; +const UNAVAILABLE_ACTIVITY: Activity = { ...EMPTY_ACTIVITY, title: "ACTIVITY UNAVAILABLE" }; +const BLANK_ACTIVITY: Activity = { ...EMPTY_ACTIVITY, title: "" }; +const EMPTY_POSITION: Position = { symbol: "NO OPEN POSITIONS", quantity: "", averagePrice: "", marketValue: "" }; +const UNAVAILABLE_POSITION: Position = { ...EMPTY_POSITION, symbol: "POSITIONS UNAVAILABLE" }; +const BLANK_POSITION: Position = { ...EMPTY_POSITION, symbol: "" }; +const EMPTY: Dashboard = { + account: EMPTY_ACCOUNT, totalValue: null, cash: null, buyingPower: null, + pnlDay: null, pnlWeek: null, positions: [], activity: [], + positionsAvailable: true, activityAvailable: true, observedAt: null, +}; + +const [screen, setScreen] = createSignal("dashboard"); +const [span, setSpan] = createSignal("day"); +const [accounts, setAccounts] = createSignal([]); +const [selectedAccount, setSelectedAccount] = createSignal(""); +const [dashboard, setDashboard] = createSignal(EMPTY); +const [chartPoints, setChartPoints] = createSignal([]); +const [chartSegments, setChartSegments] = createSignal([]); +const [chartLabels, setChartLabels] = createSignal([]); +const [chartTrend, setChartTrend] = createSignal({ change: "$—", percent: "—", positive: true }); +const [accountScroll, setAccountScroll] = createSignal(0); +const [activityScroll, setActivityScroll] = createSignal(0); +const [positionScroll, setPositionScroll] = createSignal(0); +const [status, setStatus] = createSignal("WAITING FOR ROBINHOOD"); +const [refreshing, setRefreshing] = createSignal(false); +let currentRevision = 0; +let accountsLoadedRevision = -1; +let dashboardsLoadedRevision = -1; +let refreshLoadedRevision = -1; +const dashboardCache = new Map>(); +const chartCache = new Map>(); +function now(): number { return Math.floor(Date.now() / 1000); } +function parse(value: string | null | undefined): any { try { return value ? JSON.parse(value) : null; } catch { return null; } } + +function loadAccounts(): Account[] { + const rows = db.query( + "SELECT account_number,label,suffix,status FROM accounts ORDER BY label,account_number LIMIT 16", + ).all() as unknown as AccountRow[]; + return rows.map((row) => ({ number: row.account_number, label: row.label, suffix: row.suffix, status: row.status })); +} + +function loadDashboardCache(loadedRevision: number, accountRows: Account[]): void { + if (dashboardsLoadedRevision === loadedRevision) return; + const portfolios = db.query( + "SELECT account_number,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current LIMIT 16", + ).all() as unknown as PortfolioRow[]; + const totals = db.query(` + SELECT value.account_number,value.value,value.observed_at + FROM total_value value + JOIN ( + SELECT account_number,MAX(observed_at) AS observed_at + FROM total_value GROUP BY account_number + ) latest ON latest.account_number=value.account_number AND latest.observed_at=value.observed_at + LIMIT 16 + `).all() as unknown as Array<{ account_number: string; value: string; observed_at: number }>; + const positions = db.query( + "SELECT account_number,symbol,quantity,average_price,market_value FROM positions ORDER BY account_number,CAST(market_value AS REAL) DESC,symbol LIMIT 1024", + ).all() as unknown as PositionRow[]; + const activities = db.query( + "SELECT account_number,activity_id,occurred_at,symbol,side,quantity,price,amount,state,activity_type FROM activities ORDER BY account_number,occurred_at DESC,observed_at DESC LIMIT 1024", + ).all() as unknown as ActivityRow[]; + const portfolioByAccount = new Map(portfolios.map((row) => [row.account_number, row])); + const totalByAccount = new Map(totals.map((row) => [row.account_number, row])); + const positionsByAccount = new Map(); + const activitiesByAccount = new Map(); + for (const row of positions) { + const rows = positionsByAccount.get(row.account_number) || []; + if (rows.length < 64) rows.push(row); + positionsByAccount.set(row.account_number, rows); + } + for (const row of activities) { + const rows = activitiesByAccount.get(row.account_number) || []; + if (rows.length < 64) rows.push(row); + activitiesByAccount.set(row.account_number, rows); + } + dashboardCache.clear(); + for (const account of accountRows) { + const portfolio = portfolioByAccount.get(account.number); + const total = totalByAccount.get(account.number); + const accountPositions = positionsByAccount.get(account.number) || []; + const accountActivities = activitiesByAccount.get(account.number) || []; + dashboardCache.set(account.number, { loadedRevision, value: { + account, + totalValue: total?.value ?? null, + cash: portfolio?.cash ?? null, + buyingPower: portfolio?.buying_power ?? null, + pnlDay: portfolio?.day_pnl ?? null, + pnlWeek: portfolio?.week_pnl ?? null, + positions: accountPositions.map((row) => ({ symbol: row.symbol, quantity: row.quantity || "—", averagePrice: row.average_price || "—", marketValue: row.market_value || "" })), + activity: accountActivities.map((row) => ({ + title: (row.side ? row.side + " " : "") + (row.symbol || "ORDER"), + timestamp: formatTime(row.occurred_at), + detail: row.quantity ? row.quantity + " SH · " + (row.activity_type || "ORDER") : row.activity_type || "ORDER", + state: row.state || "RECENT", + amount: row.amount || row.price || row.quantity || "", + side: row.side || "", + })), + positionsAvailable: portfolio !== undefined, + activityAvailable: portfolio !== undefined, + observedAt: Math.max(portfolio?.observed_at ?? 0, total?.observed_at ?? 0) || null, + }}); + } + dashboardsLoadedRevision = loadedRevision; +} + +function number(value: string | null): number | null { + if (value === null) return null; + const parsed = Number(value.replace(/[$,%]/g, "")); + return Number.isFinite(parsed) ? parsed : null; +} + +function formatTime(value: string | null): string { + if (!value) return "RECENT"; + const date = new Date(value); + if (!Number.isFinite(date.getTime())) return value.slice(0, 16).toUpperCase(); + return String(date.getMonth() + 1).padStart(2, "0") + "/" + String(date.getDate()).padStart(2, "0") + " " + String(date.getHours()).padStart(2, "0") + ":" + String(date.getMinutes()).padStart(2, "0"); +} + + +function relativeTime(seconds: number): string { + const age = Math.max(0, now() - seconds); + if (age < 60) return "JUST NOW"; + if (age < 3600) return Math.floor(age / 60) + " MIN AGO"; + if (age < 86400) return Math.floor(age / 3600) + " HR AGO"; + return Math.floor(age / 86400) + " DAY AGO"; +} + +function money(value: string | null | undefined): string { + if (!value) return "$—"; + const parsed = number(value); + if (parsed === null) return value; + const absolute = Math.abs(parsed); + const parts = absolute.toFixed(2).split("."); + const formatted = "$" + parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + "." + parts[1]; + return parsed < 0 ? "-" + formatted : formatted; +} + +function loadChart(accountNumber: string, loadedRevision: number) { + const cacheKey = accountNumber + ":" + span(); + const cached = chartCache.get(cacheKey); + if (cached?.loadedRevision === loadedRevision) { + setChartPoints(cached.value.points); + setChartSegments(cached.value.segments); + setChartLabels(cached.value.labels); + setChartTrend(cached.value.trend); + return; + } + const windowSeconds = span() === "day" ? 86400 : 7 * 86400; + const end = now(); + const cutoff = end - windowSeconds; + const rows = db.query(` + WITH RECURSIVE buckets(bucket_index, bucket_time) AS ( + SELECT 0, ?1 + UNION ALL + SELECT bucket_index + 1, ?1 + CAST((?2 * (bucket_index + 1)) / 19 AS INTEGER) + FROM buckets WHERE bucket_index < 19 + ) + SELECT bucket_index, bucket_time, + (SELECT value FROM total_value + WHERE account_number = ?3 AND observed_at >= ?1 AND observed_at <= bucket_time + ORDER BY observed_at DESC LIMIT 1) AS total_value + FROM buckets ORDER BY bucket_index + `).all(cutoff, windowSeconds, accountNumber) as unknown as Array<{ bucket_index: number; bucket_time: number; total_value: string | null }>; + const buckets = rows.map((row) => ({ time: row.bucket_time, value: number(row.total_value) })); + const bucketTimes = buckets.map((bucket) => bucket.time); + const values = buckets.map((bucket) => bucket.value).filter((value): value is number => value !== null); + const labels = [bucketTimes[0], bucketTimes[9], bucketTimes[19]].map((time) => { + const date = new Date(time * 1000); + return span() === "day" + ? String(date.getHours()).padStart(2, "0") + ":" + String(date.getMinutes()).padStart(2, "0") + : String(date.getMonth() + 1) + "/" + String(date.getDate()); + }); + if (values.length === 0) { + const pnl = span() === "day" ? dashboard().pnlDay : dashboard().pnlWeek; + const value = number(pnl); + const projection = { points: [], segments: [], labels, trend: { change: money(pnl), percent: "—", positive: value === null || value >= 0 } }; + chartCache.set(cacheKey, { loadedRevision, value: projection }); + setChartPoints(projection.points); + setChartSegments(projection.segments); + setChartLabels(projection.labels); + setChartTrend(projection.trend); + return; + } + const low = Math.min(...values); + const high = Math.max(...values); + const range = Math.max(0.01, high - low); + const points = buckets.flatMap((bucket, index) => bucket.value === null ? [] : [{ + x: index * 622 / 19, + y: values.length === 1 ? 80 : 10 + (high - bucket.value) * 140 / range, + }]); + const segments = points.slice(1).map((point, index) => { + const previous = points[index]; + const dx = point.x - previous.x; + const dy = point.y - previous.y; + return { x: previous.x, y: previous.y, width: Math.sqrt(dx * dx + dy * dy), angle: Math.atan2(dy, dx) * 180 / Math.PI }; + }); + const delta = values[values.length - 1] - values[0]; + const trend = { change: money(String(delta)), percent: values[0] === 0 ? "—" : (delta * 100 / values[0]).toFixed(2) + "%", positive: delta >= 0 }; + chartCache.set(cacheKey, { loadedRevision, value: { points, segments, labels, trend } }); + setChartPoints(points); + setChartSegments(segments); + setChartLabels(labels); + setChartTrend(trend); +} + +function loadRefreshProjection(loadedRevision: number): void { + if (refreshLoadedRevision === loadedRevision) return; + const latestRun = db.query("SELECT status,error,completed_at FROM refresh_runs ORDER BY id DESC LIMIT 1").get() as unknown as { status?: string; error?: string | null; completed_at?: number | null } | null; + setRefreshing(false); + if (latestRun?.status === "failed") setStatus("REFRESH FAILED · " + String(latestRun.error || "UNKNOWN ERROR").slice(0, 52)); + else if (latestRun?.status === "partial") setStatus("LIVE WITH PARTIAL DATA"); + else if (dashboard().observedAt) setStatus("LIVE / READ ONLY · " + relativeTime(dashboard().observedAt as number)); + else setStatus("WAITING FOR ROBINHOOD"); + refreshLoadedRevision = loadedRevision; +} + +function loadAccountProjection(accountNumber: string, loadedRevision: number): void { + if (!accountNumber) { + setDashboard(EMPTY); + setChartPoints([]); + setChartSegments([]); + if (!refreshing()) setStatus("WAITING FOR ROBINHOOD"); + return; + } + const cached = dashboardCache.get(accountNumber); + if (cached?.loadedRevision === loadedRevision) { + setDashboard(cached.value); + loadChart(accountNumber, loadedRevision); + if (cached.value.observedAt && !refreshing()) setStatus("LIVE / READ ONLY · " + relativeTime(cached.value.observedAt)); + return; + } + setDashboard(EMPTY); + setChartPoints([]); + setChartSegments([]); +} + +function loadView(loadedRevision = currentRevision) { + // This is the only whole-App projection refresh. The host calls it once on + // initial activation and once for any number of commits coalesced at the + // foreground frame boundary. Normal frames never execute it. + try { + const schema = db.query("PRAGMA user_version").get() as unknown as { user_version?: number } | null; + if (Number(schema?.user_version ?? 0) !== DB_SCHEMA_VERSION) { + setAccounts([]); + setSelectedAccount(""); + setDashboard(EMPTY); + setChartPoints([]); + setChartSegments([]); + setStatus("WAITING FOR ROBINHOOD"); + return; + } + batch(() => { + currentRevision = Math.max(currentRevision, loadedRevision); + let nextAccounts = accounts(); + if (accountsLoadedRevision !== currentRevision) { + nextAccounts = loadAccounts(); + setAccounts(nextAccounts); + accountsLoadedRevision = currentRevision; + } + loadDashboardCache(currentRevision, nextAccounts); + let accountNumber = selectedAccount(); + if (!nextAccounts.some((item) => item.number === accountNumber)) { + accountNumber = nextAccounts[0]?.number || ""; + setSelectedAccount(accountNumber); + } + loadAccountProjection(accountNumber, currentRevision); + loadRefreshProjection(currentRevision); + }); + } catch { + batch(() => { + setAccounts([]); + setSelectedAccount(""); + setDashboard(EMPTY); + setChartPoints([]); + setChartSegments([]); + setStatus("WAITING FOR ROBINHOOD"); + }); + } +} + +function tick(): string { + return ""; +} + +function storageStatus(): any { + const tables = db.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all() as unknown as Array<{ name: string; sql: string }>; + const names = new Set(tables.map((table) => table.name)); + const tableSummary = tables.map((table) => { + const rowCount = (db.query("SELECT COUNT(*) AS count FROM " + table.name).get() as unknown as { count: number }).count; + return { name: table.name, rowCount, schema: table.sql }; + }); + const latestRefreshes = names.has("refresh_runs") + ? db.query("SELECT id,started_at,completed_at,operation_count,success_count,status,error FROM refresh_runs ORDER BY id DESC LIMIT 3").all() : []; + const latestPortfolios = names.has("portfolio_current") + ? db.query("SELECT substr(account_number,-4) AS account_suffix,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current ORDER BY observed_at DESC LIMIT 4").all() : []; + const latestValues = names.has("total_value") + ? db.query("SELECT substr(account_number,-4) AS account_suffix,observed_at,value FROM total_value ORDER BY observed_at DESC LIMIT 8").all() : []; + return { + database: "robinhood.sqlite", + schemaVersion: DB_SCHEMA_VERSION, + tables: tableSummary, + latestRefreshes, + latestPortfolios, + latestValues, + }; +} + +function trend(): { change: string; percent: string; positive: boolean } { + return chartTrend(); +} + +function Header(props: { title: string; metaBottom?: string }) { + return ( + + ); +} + +function Metric(props: { label: string; value: string | null }) { + return ( + + {props.label} + {money(props.value)} + + ); +} + +function SectionTitle(props: { title: string; detail?: string }) { + return ; +} + +function activityPreview(index: number): Activity { + if (index === 0 && !dashboard().activityAvailable) return UNAVAILABLE_ACTIVITY; + return dashboard().activity[index] ?? (index === 0 ? EMPTY_ACTIVITY : BLANK_ACTIVITY); +} + +function CompactActivity(props: { index: number }) { + const item = () => activityPreview(props.index); + return {item().title}{item().timestamp ? item().timestamp + " · " + item().detail : ""}{item().amount ? money(item().amount) : ""}; +} + +function positionPreview(index: number): Position { + if (index === 0 && !dashboard().positionsAvailable) return UNAVAILABLE_POSITION; + return dashboard().positions[index] ?? (index === 0 ? EMPTY_POSITION : BLANK_POSITION); +} + +function CompactPosition(props: { index: number }) { + const item = () => positionPreview(props.index); + return {item().symbol}{item().quantity ? item().quantity + " SH" : ""}{item().averagePrice ? "AVG " + money(item().averagePrice) : ""}; +} + +function Chart() { + return ( + + + + {chartPoints().length < 2 ? "COLLECTING 5M VALUE HISTORY" : ""} + {(item) => } + {(item) => } + + {chartLabels()[0] || ""}{chartLabels()[1] || ""}{chartLabels()[2] || ""} + + ); +} + +function DashboardScreen() { + const currentTrend = () => trend(); + return ( + +
+ + ACCOUNT + {dashboard().account.label + (dashboard().account.suffix ? " ····" + dashboard().account.suffix + " " + (accounts().findIndex((item) => item.number === selectedAccount()) + 1) + "/" + accounts().length : "") + " ›"} + + + + {money(dashboard().totalValue)} + {currentTrend().change + " (" + currentTrend().percent + ")"} + + + + 1D1W{span() === "day" ? "TODAY" : "PAST WEEK"} + + + + {"REALIZED P&L"}{"EQUITIES / " + (span() === "day" ? "TODAY" : "WEEK")}= 0 ? "text-xl text-emerald-600 font-bold" : "text-xl text-red-500 font-bold"}>{money(span() === "day" ? dashboard().pnlDay : dashboard().pnlWeek)} + {status()} + + ); +} + +function SideButtons() { + return <>UPDN; +} + +function AccountsScreen() { + const visible = createMemo(() => accounts().slice(accountScroll(), accountScroll() + 8)); + const selectedAtOpen = selectedAccount(); + return ( + +
+ {(account) => ( + + {account.label}{"····" + account.suffix} + {account.status}SELECTED + + )} + + + ); +} + +function ActivityScreen() { + const visible = createMemo(() => dashboard().activity.slice(activityScroll(), activityScroll() + 8)); + return ( + +
+ 0} fallback={ + {dashboard().activityAvailable ? "NO ACTIVITY YET" : "ACTIVITY UNAVAILABLE"} + }>{(item) => ( + + {item.title}{money(item.amount)} + {item.timestamp + " · " + item.detail} + {item.state} + + )} + + + ); +} + +function PositionsScreen() { + const visible = createMemo(() => dashboard().positions.slice(positionScroll(), positionScroll() + 9)); + return ( + +
+ 0} fallback={ + {dashboard().positionsAvailable ? "NO OPEN POSITIONS" : "POSITIONS UNAVAILABLE"} + }>{(item) => ( + + {item.symbol}{item.quantity + " SH"} + {"AVERAGE COST " + money(item.averagePrice) + (item.marketValue ? " · VALUE " + money(item.marketValue) : "")} + + )} + + + ); +} + +function SubScreen() { + if (screen() === "accounts") return ; + if (screen() === "activity") return ; + return ; +} + +function Robinhood() { + return }>; +} + +loadView(); +mount(() => ); + +(globalThis as any).PocketPiApp = { + tick, + update() { return ""; }, + dataChanged(eventsLine: string) { + const events = parse(eventsLine); + const revision = Array.isArray(events) + ? events.reduce((latest: number, event: any) => Math.max(latest, Number(event?.revision ?? 0)), currentRevision) + : currentRevision; + loadView(revision); + return ""; + }, + invokeTool(name: string) { + try { + const value = name === "robinhood.storage_status" ? storageStatus() + : (() => { throw new Error("Data-writing tools run in the background App Data Action"); })(); + return JSON.stringify({ text: JSON.stringify(value), details: value, isError: false }); + } catch (error) { return JSON.stringify({ text: error instanceof Error ? error.message : String(error), isError: true }); } + }, + invokeTask(name: string) { + return JSON.stringify({ text: "Data Action tasks do not run in the View: " + name, isError: true }); + }, + tap(x: number, y: number) { + if (screen() !== "dashboard") { + if (y < 112 && x < 220) { setScreen("dashboard"); return ""; } + if (x >= 620 && y >= 140 && y < 310) { + if (screen() === "accounts") setAccountScroll((value) => Math.max(0, value - 1)); + if (screen() === "activity") setActivityScroll((value) => Math.max(0, value - 1)); + if (screen() === "positions") setPositionScroll((value) => Math.max(0, value - 1)); + return ""; + } + if (x >= 620 && y >= 940 && y < 1130) { + if (screen() === "accounts") setAccountScroll((value) => Math.min(Math.max(0, accounts().length - 8), value + 1)); + if (screen() === "activity") setActivityScroll((value) => Math.min(Math.max(0, dashboard().activity.length - 8), value + 1)); + if (screen() === "positions") setPositionScroll((value) => Math.min(Math.max(0, dashboard().positions.length - 9), value + 1)); + return ""; + } + if (screen() === "accounts" && x < 610 && y >= 126) { + const index = accountScroll() + Math.floor((y - 126) / 112); + const account = accounts()[index]; + if (account) { + batch(() => { + setSelectedAccount(account.number); + setScreen("dashboard"); + }); + loadAccountProjection(account.number, currentRevision); + } + } + return ""; + } + if (y < 112 && x < 100) return JSON.stringify({ type: "navigate", app: "pi-agent" }); + if (y >= 112 && y < 176) { setScreen("accounts"); return ""; } + if (y >= 480 && y < 540) { batch(() => { setSpan(x < 136 ? "day" : "week"); loadChart(selectedAccount(), currentRevision); }); return ""; } + if (y >= 666 && y < 866) { setScreen("activity"); return ""; } + if (y >= 866 && y < 1050) { setScreen("positions"); return ""; } + if (y >= 1176 && x >= 500) { + if (refreshing()) return ""; + setRefreshing(true); + setStatus("REFRESHING ROBINHOOD…"); + return JSON.stringify({ type: "invokeTask", task: "refreshPortfolio" }); + } + return ""; + }, +}; diff --git a/apps/robinhood/data-action.ts b/apps/robinhood/data-action.ts new file mode 100644 index 0000000..6a5a765 --- /dev/null +++ b/apps/robinhood/data-action.ts @@ -0,0 +1,463 @@ +// Headless Robinhood data plane. Provider bodies are normalized in memory, +// then domain tables are changed in one transaction. The foreground View +// never sees provider payloads and never writes business state. +const nativeDb = (globalThis as any).db; +const handle = nativeDb.open("robinhood"); +if (handle < 0) throw new Error("open robinhood.sqlite"); + +const SCHEMA_VERSION = 4; + +function dbError(): string { return String(nativeDb.lastError(handle) || "SQLite operation failed"); } +function exec(sql: string): void { if (nativeDb.exec(handle, sql) !== 0) throw new Error(dbError()); } +function query(sql: string, args: any[] = []): any { + const result = JSON.parse(nativeDb.query(handle, sql, JSON.stringify(args))); + if (result.error) throw new Error(String(result.error)); + return result; +} +function run(sql: string, args: any[] = []): any { return query(sql, args); } + +const version = query("PRAGMA user_version") as { user_version?: number } | null; +if (Number(version?.user_version ?? 0) !== SCHEMA_VERSION) { + exec(` + CREATE TABLE IF NOT EXISTS accounts ( + account_number TEXT PRIMARY KEY, + label TEXT NOT NULL, + suffix TEXT NOT NULL, + account_type TEXT, + status TEXT NOT NULL, + agentic_allowed INTEGER NOT NULL DEFAULT 0, + updated_at INTEGER NOT NULL + ); + CREATE TABLE IF NOT EXISTS portfolio_current ( + account_number TEXT PRIMARY KEY, + cash TEXT, + buying_power TEXT, + day_pnl TEXT, + week_pnl TEXT, + observed_at INTEGER NOT NULL + ); + CREATE TABLE IF NOT EXISTS total_value ( + account_number TEXT NOT NULL, + observed_at INTEGER NOT NULL, + value TEXT NOT NULL, + PRIMARY KEY(account_number, observed_at) + ); + CREATE TABLE IF NOT EXISTS positions ( + account_number TEXT NOT NULL, + symbol TEXT NOT NULL, + quantity TEXT, + average_price TEXT, + market_value TEXT, + observed_at INTEGER NOT NULL, + PRIMARY KEY(account_number, symbol) + ); + CREATE TABLE IF NOT EXISTS activities ( + account_number TEXT NOT NULL, + activity_id TEXT NOT NULL, + occurred_at TEXT, + observed_at INTEGER NOT NULL, + symbol TEXT, + side TEXT, + quantity TEXT, + price TEXT, + amount TEXT, + state TEXT, + activity_type TEXT, + PRIMARY KEY(account_number, activity_id) + ); + CREATE INDEX IF NOT EXISTS activities_account_recent ON activities(account_number, occurred_at DESC, observed_at DESC); + CREATE TABLE IF NOT EXISTS refresh_runs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + started_at INTEGER NOT NULL, + completed_at INTEGER NOT NULL, + status TEXT NOT NULL, + operation_count INTEGER NOT NULL, + success_count INTEGER NOT NULL, + error TEXT + ); + CREATE INDEX IF NOT EXISTS refresh_runs_recent ON refresh_runs(id DESC); + CREATE TABLE IF NOT EXISTS equity_historicals ( + account_number TEXT NOT NULL, + span TEXT NOT NULL, + point_time TEXT NOT NULL, + price TEXT, + open TEXT, + high TEXT, + low TEXT, + close TEXT, + volume TEXT, + observed_at INTEGER NOT NULL, + PRIMARY KEY(account_number, span, point_time) + ); + CREATE TABLE IF NOT EXISTS pnl_trades ( + account_number TEXT NOT NULL, + trade_id TEXT NOT NULL, + occurred_at TEXT, + symbol TEXT, + side TEXT, + quantity TEXT, + price TEXT, + realized_pnl TEXT, + observed_at INTEGER NOT NULL, + PRIMARY KEY(account_number, trade_id) + ); + CREATE TABLE IF NOT EXISTS order_reviews ( + review_id TEXT PRIMARY KEY, + account_number TEXT, + symbol TEXT, + side TEXT, + quantity TEXT, + limit_price TEXT, + estimated_cost TEXT, + state TEXT, + observed_at INTEGER NOT NULL + ); + PRAGMA user_version=4; + `); +} + +type DomainUpdate = { operation: string; args: any; value: any; observedAt: number }; + +function now(): number { return Math.floor(Date.now() / 1000); } +function text(value: unknown): string | null { + return value === null || value === undefined || typeof value === "object" ? null : String(value); +} +function deep(value: any, names: string[]): string | null { + if (value === null || value === undefined || typeof value !== "object") return null; + for (const name of names) { + const found = text(value[name]); + if (found !== null) return found; + } + for (const child of Object.values(value)) { + const found = deep(child, names); + if (found !== null) return found; + } + return null; +} +function deepArray(value: any, names: string[]): any[] { + if (value === null || value === undefined || typeof value !== "object") return []; + for (const name of names) if (Array.isArray(value[name])) return value[name]; + for (const child of Object.values(value)) { + const found = deepArray(child, names); + if (found.length) return found; + } + return []; +} +function bool(value: any, names: string[]): boolean { + const raw = deep(value, names)?.toLowerCase(); + return raw === "true" || raw === "1" || raw === "yes"; +} +function number(value: string | null): number | null { + if (value === null) return null; + const parsed = Number(value.replace(/[$,%]/g, "")); + return Number.isFinite(parsed) ? parsed : null; +} +function accountNumber(value: any, args: any): string { + return deep(value, ["account_number", "accountNumber", "account"]) + || String(args?.account_number ?? args?.accountNumber ?? ""); +} +function list(value: any, names: string[]): any[] { + const nested = deepArray(value, names); + return nested.length ? nested : Array.isArray(value) ? value : value ? [value] : []; +} + +function callTool(operation: string, args: any): any { + const envelope = JSON.parse((globalThis as any).services.call( + "mcp.client", + "callTool", + JSON.stringify({ connection: "robinhood", name: operation, arguments: args }), + )); + if (!envelope.ok) throw new Error(envelope.error || "Robinhood service failed"); + return envelope.value; +} + +function callTools(calls: Array<{ operation: string; args: any }>): any[] { + const envelope = JSON.parse((globalThis as any).services.call( + "mcp.client", + "callTools", + JSON.stringify({ + connection: "robinhood", + calls: calls.map((call) => ({ name: call.operation, arguments: call.args })), + }), + )); + if (!envelope.ok) throw new Error(envelope.error || "Robinhood batch service failed"); + return Array.isArray(envelope.value?.results) ? envelope.value.results : []; +} + +function transaction(action: () => void): void { + exec("BEGIN IMMEDIATE"); + try { + action(); + exec("COMMIT"); + } catch (error) { + try { exec("ROLLBACK"); } catch {} + throw error; + } + (globalThis as any).app.commit(); +} + +function saveAccounts(value: any, observedAt: number): void { + const rows = list(value, ["accounts"]); + run("DELETE FROM accounts"); + for (const item of rows) { + const account = accountNumber(item, {}); + if (!account) continue; + const accountType = (deep(item, ["nickname", "account_type", "type"]) || "").toUpperCase(); + const agentic = bool(item, ["agentic_allowed", "agenticAllowed"]); + const label = agentic ? "AGENTIC" + : accountType.includes("IRA") || accountType.includes("RETIRE") ? "RETIREMENT" + : accountType.includes("JOINT") ? "JOINT" : "PERSONAL"; + run( + "INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at) VALUES(?,?,?,?,?,?,?)", + [account, label, account.slice(-4), accountType, (deep(item, ["status"]) || "active").toUpperCase(), agentic ? 1 : 0, observedAt], + ); + } +} + +function savePortfolio(value: any, args: any, observedAt: number): void { + const account = accountNumber(value, args); + if (!account) throw new Error("Robinhood portfolio is missing account_number"); + const cash = deep(value, ["cash", "cash_available", "withdrawable_amount"]); + const buyingPower = deep(value, ["buying_power", "buyingPower"]); + const dayPnl = deep(value, ["day_pnl", "dayPnl", "equity_change"]); + const weekPnl = deep(value, ["week_pnl", "weekPnl"]); + run( + `INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) + VALUES(?,?,?,?,?,?) + ON CONFLICT(account_number) DO UPDATE SET + cash=excluded.cash,buying_power=excluded.buying_power, + day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), + week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), + observed_at=excluded.observed_at`, + [account, cash, buyingPower, dayPnl, weekPnl, observedAt], + ); + const total = deep(value, ["total_value", "equity", "total_equity", "portfolio_value", "market_value"]); + if (total !== null) { + run("INSERT OR REPLACE INTO total_value(account_number,observed_at,value) VALUES(?,?,?)", [account, observedAt, total]); + } +} + +function savePositions(value: any, args: any, observedAt: number): void { + const account = accountNumber(value, args); + if (!account) throw new Error("Robinhood positions are missing account_number"); + const rows = list(value, ["positions"]).slice(0, 64); + run("DELETE FROM positions WHERE account_number=?", [account]); + for (const item of rows) { + const symbol = deep(item, ["symbol"]); + if (!symbol) continue; + run( + "INSERT INTO positions(account_number,symbol,quantity,average_price,market_value,observed_at) VALUES(?,?,?,?,?,?)", + [account, symbol, deep(item, ["quantity", "shares"]), deep(item, ["average_price", "averagePrice", "average_buy_price"]), deep(item, ["market_value", "marketValue", "equity"]), observedAt], + ); + } +} + +function saveActivities(value: any, args: any, observedAt: number): void { + const account = accountNumber(value, args); + if (!account) throw new Error("Robinhood activities are missing account_number"); + const rows = list(value, ["orders", "activities", "results"]).slice(0, 64); + run("DELETE FROM activities WHERE account_number=?", [account]); + rows.forEach((item, index) => { + const symbol = deep(item, ["symbol"]); + const side = (deep(item, ["side"]) || "").toUpperCase(); + const quantity = deep(item, ["executed_quantity", "cumulative_quantity", "quantity"]); + const price = deep(item, ["average_price", "averagePrice", "executed_price", "price"]); + const occurredAt = deep(item, ["last_transaction_at", "created_at", "updated_at", "date"]); + const explicitId = deep(item, ["id", "order_id", "orderId", "activity_id"]); + const activityId = explicitId || [occurredAt || observedAt, symbol || "ORDER", side, index].join(":"); + const quantityNumber = number(quantity); + const priceNumber = number(price); + const amount = quantityNumber !== null && priceNumber !== null ? String(quantityNumber * priceNumber) : price || quantity; + run( + `INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) + VALUES(?,?,?,?,?,?,?,?,?,?,?)`, + [account, activityId, occurredAt, observedAt, symbol, side, quantity, price, amount, (deep(item, ["state", "status"]) || "RECENT").toUpperCase(), (deep(item, ["type", "order_type"]) || "ORDER").toUpperCase()], + ); + }); +} + +function saveRealizedPnl(value: any, args: any, observedAt: number): void { + const account = accountNumber(value, args); + if (!account) throw new Error("Robinhood P&L is missing account_number"); + const pnl = deep(value, ["total_returns", "realized_pnl", "total", "amount", "day_pnl", "week_pnl"]); + const span = String(args?.span ?? "day"); + run( + `INSERT INTO portfolio_current(account_number,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?) + ON CONFLICT(account_number) DO UPDATE SET + day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), + week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), + observed_at=MAX(portfolio_current.observed_at,excluded.observed_at)`, + [account, span === "week" ? null : pnl, span === "week" ? pnl : null, observedAt], + ); +} + +function saveHistoricals(value: any, args: any, observedAt: number): void { + const account = accountNumber(value, args); + const span = String(args?.span ?? args?.interval ?? "default"); + const rows = list(value, ["historicals", "results", "data"]); + run("DELETE FROM equity_historicals WHERE account_number=? AND span=?", [account, span]); + rows.forEach((item, index) => { + const pointTime = deep(item, ["begins_at", "timestamp", "time", "date"]) || String(index); + run( + `INSERT INTO equity_historicals(account_number,span,point_time,price,open,high,low,close,volume,observed_at) + VALUES(?,?,?,?,?,?,?,?,?,?)`, + [account, span, pointTime, deep(item, ["price", "adjusted_close", "close_price"]), deep(item, ["open_price", "open"]), deep(item, ["high_price", "high"]), deep(item, ["low_price", "low"]), deep(item, ["close_price", "close"]), deep(item, ["volume"]), observedAt], + ); + }); +} + +function savePnlTrades(value: any, args: any, observedAt: number): void { + const account = accountNumber(value, args); + const rows = list(value, ["trades", "results", "data"]); + run("DELETE FROM pnl_trades WHERE account_number=?", [account]); + rows.forEach((item, index) => { + const occurredAt = deep(item, ["created_at", "updated_at", "date", "timestamp"]); + const tradeId = deep(item, ["id", "trade_id", "tradeId"]) || [occurredAt || observedAt, deep(item, ["symbol"]) || "TRADE", index].join(":"); + run( + `INSERT INTO pnl_trades(account_number,trade_id,occurred_at,symbol,side,quantity,price,realized_pnl,observed_at) + VALUES(?,?,?,?,?,?,?,?,?)`, + [account, tradeId, occurredAt, deep(item, ["symbol"]), (deep(item, ["side"]) || "").toUpperCase(), deep(item, ["quantity", "shares"]), deep(item, ["price", "average_price"]), deep(item, ["realized_pnl", "pnl", "amount"]), observedAt], + ); + }); +} + +function saveOrderReview(value: any, args: any, observedAt: number): void { + const account = accountNumber(value, args); + const symbol = deep(value, ["symbol"]) || text(args?.symbol); + const side = (deep(value, ["side"]) || text(args?.side) || "").toUpperCase(); + const quantity = deep(value, ["quantity", "shares"]) || text(args?.quantity); + const limitPrice = deep(value, ["limit_price", "limitPrice", "price"]) || text(args?.limit_price ?? args?.price); + const reviewId = deep(value, ["id", "review_id", "reviewId"]) || [account, symbol, side, quantity, limitPrice, observedAt].join(":"); + run( + `INSERT OR REPLACE INTO order_reviews(review_id,account_number,symbol,side,quantity,limit_price,estimated_cost,state,observed_at) + VALUES(?,?,?,?,?,?,?,?,?)`, + [reviewId, account, symbol, side, quantity, limitPrice, deep(value, ["estimated_cost", "estimatedCost", "total"]), deep(value, ["state", "status"]), observedAt], + ); +} + +function save(update: DomainUpdate): void { + if (update.operation === "get_accounts") saveAccounts(update.value, update.observedAt); + else if (update.operation === "get_portfolio") savePortfolio(update.value, update.args, update.observedAt); + else if (update.operation === "get_equity_positions") savePositions(update.value, update.args, update.observedAt); + else if (update.operation === "get_equity_orders") saveActivities(update.value, update.args, update.observedAt); + else if (update.operation === "get_realized_pnl") saveRealizedPnl(update.value, update.args, update.observedAt); + else if (update.operation === "get_equity_historicals") saveHistoricals(update.value, update.args, update.observedAt); + else if (update.operation === "get_pnl_trade_history") savePnlTrades(update.value, update.args, update.observedAt); + else if (update.operation === "review_equity_order") saveOrderReview(update.value, update.args, update.observedAt); + else throw new Error("No Robinhood table mapping for " + update.operation); +} + +function isTransportFailure(message: string): boolean { + const value = message.toLowerCase(); + return value.includes("esp_err_http_connect") || value.includes("timeout") + || value.includes("tls") || value.includes("socket") || value.includes("network"); +} + +function refreshPortfolio(): any { + const startedAt = now(); + const updates: DomainUpdate[] = []; + const errors: string[] = []; + let operationCount = 0; + + const request = (operation: string, args: any): any | null => { + operationCount += 1; + try { + const value = callTool(operation, args); + updates.push({ operation, args, value, observedAt: now() }); + return value; + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + errors.push(operation + ": " + message); + if (operation === "get_accounts" || isTransportFailure(message)) throw error; + return null; + } + }; + + let terminalError: string | null = null; + try { + const accountsValue = request("get_accounts", {}); + const accountRows = list(accountsValue, ["accounts"]); + const accountNumbers = accountRows.map((item) => accountNumber(item, {})).filter(Boolean); + if (!accountNumbers.length) throw new Error("Robinhood returned no brokerage accounts"); + const recentOrdersSince = new Date((startedAt - 7 * 24 * 60 * 60) * 1000).toISOString().slice(0, 10); + const calls: Array<{ operation: string; args: any }> = []; + for (const account of accountNumbers) { + const args = { account_number: account }; + calls.push( + { operation: "get_portfolio", args }, + { operation: "get_equity_positions", args }, + { operation: "get_equity_orders", args: { ...args, created_at_gte: recentOrdersSince } }, + { operation: "get_realized_pnl", args: { ...args, span: "day", asset_classes: ["equity"] } }, + { operation: "get_realized_pnl", args: { ...args, span: "week", asset_classes: ["equity"] } }, + ); + } + operationCount += calls.length; + const results = callTools(calls); + if (results.length !== calls.length) throw new Error("Robinhood batch returned an incomplete result set"); + results.forEach((result, index) => { + const call = calls[index]; + if (result?.ok) { + updates.push({ operation: call.operation, args: call.args, value: result.value, observedAt: now() }); + } else { + errors.push(call.operation + ": " + String(result?.error || "unknown provider error")); + } + }); + if (!updates.some((update) => update.operation === "get_portfolio")) { + throw new Error("Robinhood batch returned no portfolio data"); + } + } catch (error) { + terminalError = error instanceof Error ? error.message : String(error); + } + + const status = terminalError ? "failed" : errors.length ? "partial" : "succeeded"; + transaction(() => { + if (!terminalError) for (const update of updates) save(update); + run( + `INSERT INTO refresh_runs(started_at,completed_at,status,operation_count,success_count,error) + VALUES(?,?,?,?,?,?)`, + [startedAt, now(), status, operationCount, terminalError ? 0 : updates.length, terminalError || errors.join(" | ") || null], + ); + }); + if (terminalError) throw new Error(terminalError); + return { status, operationCount, successCount: updates.length }; +} + +const toolOperations: Record = { + "robinhood.get_accounts": "get_accounts", + "robinhood.get_portfolio": "get_portfolio", + "robinhood.get_equity_positions": "get_equity_positions", + "robinhood.get_equity_orders": "get_equity_orders", + "robinhood.get_equity_historicals": "get_equity_historicals", + "robinhood.get_realized_pnl": "get_realized_pnl", + "robinhood.get_pnl_trade_history": "get_pnl_trade_history", + "robinhood.review_equity_order": "review_equity_order", +}; + +function invokeMappedTool(name: string, args: any): any { + const operation = toolOperations[name]; + if (!operation) throw new Error("Unknown Robinhood tool: " + name); + const value = callTool(operation, args); + transaction(() => save({ operation, args, value, observedAt: now() })); + return value; +} + +(globalThis as any).PocketPiData = { + invokeTask(name: string) { + try { + if (name !== "refreshPortfolio") throw new Error("Unknown Robinhood Data Action: " + name); + const value = refreshPortfolio(); + return JSON.stringify({ text: JSON.stringify(value), details: value, isError: false }); + } catch (error) { + return JSON.stringify({ text: error instanceof Error ? error.message : String(error), isError: true }); + } + }, + invokeTool(name: string, argsLine: string) { + try { + const args = JSON.parse(argsLine); + const value = name === "robinhood.refresh_portfolio" ? refreshPortfolio() : invokeMappedTool(name, args); + return JSON.stringify({ text: JSON.stringify(value), details: value, isError: false }); + } catch (error) { + return JSON.stringify({ text: error instanceof Error ? error.message : String(error), isError: true }); + } + }, +}; diff --git a/apps/robinhood/dist/app.js b/apps/robinhood/dist/app.js new file mode 100644 index 0000000..f844129 --- /dev/null +++ b/apps/robinhood/dist/app.js @@ -0,0 +1,22 @@ +(()=>{var _J={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return U1(this.context.count)},getNextContextId(){return U1(this.context.count++)}};function U1(J){let Q=String(J),$=Q.length-1;return _J.context.id+($?String.fromCharCode(96+$):"")+Q}function M1(J){_J.context=J}function G6(){return{..._J.context,id:_J.getNextContextId(),count:0}}var H6=!1,j6=(J,Q)=>J===Q,_0=Symbol("solid-proxy"),F6=typeof Proxy==="function",B6=Symbol("solid-track"),RQ=Symbol("solid-dev-component"),nJ={equals:j6},V1=null,K6=k1,p=1,EJ=2,P1={owned:null,cleanups:null,context:null,owner:null},S=null,B=null,bJ=null,AJ=null,f=null,h=null,N=null,oJ=0;function tJ(J,Q){let $=f,Z=S,X=J.length===0,W=Q===void 0?Z:Q,z=X?P1:{owned:null,cleanups:null,context:W?W.context:null,owner:W},F=X?J:()=>J(()=>WJ(()=>qJ(z)));S=z,f=null;try{return r(F,!0)}finally{f=$,S=Z}}function E(J,Q){Q=Q?Object.assign({},nJ,Q):nJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return O1($,X)};return[R1.bind($),Z]}function XJ(J,Q,$){let Z=I1(J,Q,!1,p);if(bJ&&B&&B.running)h.push(Z);else J0(Z)}function QJ(J,Q,$){$=$?Object.assign({},nJ,$):nJ;let Z=I1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,bJ&&B&&B.running)Z.tState=p,h.push(Z);else J0(Z);return R1.bind(Z)}function eJ(J){return r(J,!1)}function WJ(J){if(!AJ&&f===null)return J();let Q=f;f=null;try{if(AJ)return AJ.untrack(J);return J()}finally{f=Q}}function A0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function U6(J){if(B&&B.running)return J(),B.done;let Q=f,$=S;return Promise.resolve().then(()=>{f=Q,S=$;let Z;if(bJ||M6)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return r(J,!1),f=S=null,Z?Z.done:void 0})}var[OQ,D1]=E(!1),M6;function R1(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===p)J0(this);else{let Q=h;h=null,r(()=>Q0(this),!1),h=Q}if(f){let Q=this.observers;if(!Q||Q[Q.length-1]!==f){let $=Q?Q.length:0;if(!f.sources)f.sources=[this],f.sourceSlots=[$];else f.sources.push(this),f.sourceSlots.push($);if(!Q)this.observers=[f],this.observerSlots=[f.sources.length-1];else Q.push(f),this.observerSlots.push(f.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function O1(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)r(()=>{for(let X=0;X1e6)throw h=[],Error()},!1)}return Q}function J0(J){if(!J.fn)return;qJ(J);let Q=oJ;if(L1(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{r(()=>{B&&(B.running=!0),f=S=J,L1(J,J.tValue,Q),f=S=null},!1)})}function L1(J,Q,$){let Z,X=S,W=f;f=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(B&&B.running)J.tState=p,J.tOwned&&J.tOwned.forEach(qJ),J.tOwned=void 0;else J.state=p,J.owned&&J.owned.forEach(qJ),J.owned=null;return J.updatedAt=$+1,S0(z)}finally{f=W,S=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)O1(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function I1(J,Q,$,Z=p,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(S===null);else if(S!==P1)if(B&&B.running&&S.pure)if(!S.tOwned)S.tOwned=[W];else S.tOwned.push(W);else if(!S.owned)S.owned=[W];else S.owned.push(W);if(AJ&&W.fn){let z=W.fn,[F,P]=E(void 0,{equals:!1}),D=AJ.factory(z,P);A0(()=>D.dispose());let U,H=()=>U6(P).then(()=>{if(U)U.dispose(),U=void 0});W.fn=(w)=>{if(F(),B&&B.running){if(!U)U=AJ.factory(z,H);return U.track(w)}return D.track(w)}}return W}function w0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===EJ)return Q0(J);if(J.suspense&&WJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===p)J0(J);else if((Q?J.tState:J.state)===EJ){let X=h;h=null,r(()=>Q0(J,$[0]),!1),h=X}}}function r(J,Q){if(h)return J();let $=!1;if(!Q)h=[];if(N)$=!0;else N=[];oJ++;try{let Z=J();return V6($),Z}catch(Z){if(!$)N=null;h=null,S0(Z)}}function V6(J){if(h){if(bJ&&B&&B.running)P6(h);else k1(h);h=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;N.push.apply(N,B.effects),Q=B.resolve;for(let W of N)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,r(()=>{for(let W of X)qJ(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let z=0,F=W.owned.length;zK6($),!1);if(Q)Q()}function k1(J){for(let Q=0;Q{Z.delete($),r(()=>{B.running=!0,w0($)},!1),B&&(B.running=!1)})}}function Q0(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)qJ(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)A1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)qJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function A1(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return A0(()=>S1(W)),()=>{let P=J()||[],D=P.length,U,H;return P[B6],WJ(()=>{let C,g,A,s,a,K,j,G,V;if(D===0){if(z!==0)S1(W),W=[],Z=[],X=[],z=0,F&&(F=[]);if($.fallback)Z=[R6],X[0]=tJ((k)=>{return W[0]=k,$.fallback()}),z=1}else if(z===0){X=Array(D);for(H=0;H=K&&G>=K&&Z[j]===P[G];j--,G--)A[G]=X[j],s[G]=W[j],F&&(a[G]=F[j]);C=new Map,g=Array(G+1);for(H=G;H>=K;H--)V=P[H],U=C.get(V),g[H]=U===void 0?-1:U,C.set(V,H);for(U=K;U<=j;U++)if(V=Z[U],H=C.get(V),H!==void 0&&H!==-1)A[H]=X[U],s[H]=W[U],F&&(a[H]=F[U]),H=g[H],C.set(V,H);else W[U]();for(H=K;HJ(Q||{}));return M1($),Z}}return WJ(()=>J(Q||{}))}function $0(){return!0}var k6={get(J,Q,$){if(Q===_0)return $;return J.get(Q)},has(J,Q){if(Q===_0)return!0;return J.has(Q)},set:$0,deleteProperty:$0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:$0,deleteProperty:$0}},ownKeys(J){return J.keys()}};function y0(J){return!(J=typeof J==="function"?J():J)?{}:J}function _6(){for(let J=0,Q=this.length;J=0;F--){let P=y0(J[F])[z];if(P!==void 0)return P}},has(z){for(let F=J.length-1;F>=0;F--)if(z in y0(J[F]))return!0;return!1},keys(){let z=[];for(let F=0;F=0;z--){let F=J[z];if(!F)continue;let P=Object.getOwnPropertyNames(F);for(let D=P.length-1;D>=0;D--){let U=P[D];if(U==="__proto__"||U==="constructor")continue;let H=Object.getOwnPropertyDescriptor(F,U);if(!Z[U])Z[U]=H.get?{enumerable:!0,configurable:!0,get:_6.bind($[U]=[H.get.bind(F)])}:H.value!==void 0?H:void 0;else{let w=$[U];if(w){if(H.get)w.push(H.get.bind(F));else if(H.value!==void 0)w.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let z=W.length-1;z>=0;z--){let F=W[z],P=Z[F];if(P&&P.get)Object.defineProperty(X,F,P);else X[F]=P?P.value:void 0}return X}var A6=(J)=>`Stale read from <${J}>.`;function NJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return QJ(O6(()=>J.each,J.children,Q||void 0))}function Z0(J){let Q=J.keyed,$=QJ(()=>J.when,void 0,void 0),Z=Q?$:QJ($,void 0,{equals:(X,W)=>!X===!W});return QJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?WJ(()=>W(Q?X:()=>{if(!WJ(Z))throw A6("Show");return $()})):W}return J.fallback},void 0,void 0)}var w6=(J)=>QJ(()=>J());function S6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:z,getParentNode:F,getFirstChild:P,getNextSibling:D}){function U(K,j,G,V){if(G!==void 0&&!V)V=[];if(typeof j!=="function")return H(K,j,V,G);XJ((k)=>H(K,j(),k,G),V)}function H(K,j,G,V,k){while(typeof G==="function")G=G();if(j===G)return G;let _=typeof j,I=V!==void 0;if(_==="string"||_==="number"){if(_==="number")j=j.toString();if(I){let O=G[0];if(O&&$(O))Z(O,j);else O=Q(j);G=g(K,G,V,O)}else if(G!==""&&typeof G==="string")Z(P(K),G=j);else g(K,G,V,Q(j)),G=j}else if(j==null||_==="boolean")G=g(K,G,V);else if(_==="function")return XJ(()=>{let O=j();while(typeof O==="function")O=O();G=H(K,O,G,V)}),()=>G;else if(Array.isArray(j)){let O=[];if(w(O,j,k))return XJ(()=>G=H(K,O,G,V,!0)),()=>G;if(O.length===0){let hJ=g(K,G,V);if(I)return G=hJ}else if(Array.isArray(G))if(G.length===0)A(K,O,V);else C(K,G,O);else if(G==null||G==="")A(K,O);else C(K,I&&G||[P(K)],O);G=O}else{if(Array.isArray(G)){if(I)return G=g(K,G,V,j);g(K,G,null,j)}else if(G==null||G===""||!P(K))X(K,j);else s(K,j,P(K));G=j}return G}function w(K,j,G){let V=!1;for(let k=0,_=j.length;k<_;k++){let I=j[k],O;if(I==null||I===!0||I===!1);else if(Array.isArray(I))V=w(K,I)||V;else if((O=typeof I)==="string"||O==="number")K.push(Q(I));else if(O==="function")if(G){while(typeof I==="function")I=I();V=w(K,Array.isArray(I)?I:[I])||V}else K.push(I),V=!0;else K.push(I)}return V}function C(K,j,G){let V=G.length,k=j.length,_=V,I=0,O=0,hJ=D(j[k-1]),IJ=null;while(IJJ-O){let DQ=j[I];while(O=0;I--){let O=j[I];if(k!==O){let hJ=F(O)===K;if(!_&&!I)hJ?s(K,k,O):X(K,k,G);else hJ&&W(K,O)}else _=!0}}else X(K,k,G);return[k]}function A(K,j,G){for(let V=0,k=j.length;VG.children=H(K,j.children,G.children));return XJ(()=>j.ref&&j.ref(K)),XJ(()=>{for(let k in j){if(k==="children"||k==="ref")continue;let _=j[k];if(_===G[k])continue;z(K,k,_,G[k]),G[k]=_}}),G}return{render(K,j){let G;return tJ((V)=>{G=V,U(j,K())}),G},insert:U,spread(K,j,G){if(typeof j==="function")XJ((V)=>a(K,j(),V,G));else a(K,j,void 0,G)},createElement:J,createTextNode:Q,insertNode:X,setProp(K,j,G,V){return z(K,j,G,V),G},mergeProps:y1,effect:XJ,memo:w6,createComponent:I6,use(K,j,G){return WJ(()=>K(j,G))}}}function y6(J){let Q=S6(J);return Q.mergeProps=y1,Q}var f1=480,C1=272,KJ={view:0,text:1,image:2},f6=1,C6=-1,x6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},M={f32:0,color:1,int:2},g6={width:M.f32,height:M.f32,minW:M.f32,minH:M.f32,maxW:M.f32,maxH:M.f32,paddingT:M.f32,paddingR:M.f32,paddingB:M.f32,paddingL:M.f32,marginT:M.f32,marginR:M.f32,marginB:M.f32,marginL:M.f32,gap:M.f32,flexDir:M.int,justify:M.int,align:M.int,grow:M.f32,shrink:M.f32,basis:M.f32,flexWrap:M.int,posType:M.int,insetT:M.f32,insetR:M.f32,insetB:M.f32,insetL:M.f32,display:M.int,overflow:M.int,zIndex:M.int,hitPass:M.int,bgColor:M.color,gradFrom:M.color,gradTo:M.color,gradDir:M.int,radius:M.f32,opacity:M.f32,borderColor:M.color,borderWidth:M.f32,shadow:M.int,bevelOuterLight:M.color,bevelOuterDark:M.color,bevelInnerLight:M.color,bevelInnerDark:M.color,bevelWidth:M.f32,textColor:M.color,fontSlot:M.int,textAlign:M.int,lineHeight:M.f32,tracking:M.f32,translateX:M.f32,translateY:M.f32,scale:M.f32,rotate:M.f32,scaleX:M.f32,scaleY:M.f32,originX:M.f32,originY:M.f32,rotateX:M.f32,rotateY:M.f32,translateZ:M.f32,perspective:M.f32,arcStart:M.f32,arcSweep:M.f32,arcWidth:M.f32},c={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},h6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},E6=1,LQ=2,IQ=1,kQ=2,_Q=131072,AQ=1,wQ=262144,SQ=1,yQ=1,fQ=1,CQ=2,xQ=4,gQ=8,hQ=16,EQ=1,bQ=2;function x1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var NQ=1,b6=1263551300,N6=1,T6=32,v6=24,n={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},UJ=32896,TQ=0.016666666666666666;function g1(J){return J.__viewport??null}var f0=null;function m6(){return null}function h1(J,Q=m6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function l6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return h1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return h1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function u6(J){f0=J}function wJ(){if(!f0)throw Error("PocketJS: host not installed — call render() first");return f0}function b(){return wJ().ops}function p6(J){globalThis.frame=J}function c6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function d6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return x1($>>>16&255,$>>>8&255,$&255,255);return x1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function i6(J,Q){let $=g6[J];if(typeof Q==="string"){if($===M.color)return d6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===M.color||$===M.int)return Q>>>0;return Q}var X0=60,E1=[1,2,3,4,5,6,10,12,15,20,30,60],C0=X0,zJ=-1,s6=0,TJ=[];function a6(J){if(!Number.isFinite(J)||J<=0)return X0;let Q=E1[0];for(let $ of E1)if(Math.abs($-J)Q.at<=zJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;TJ=TJ.filter((Q)=>Q.at>zJ);for(let Q of J)Q.cb()}var x0=0.12,W0=UJ;function t6(J){W0=J===void 0?UJ:J&65535}function e6(){W0=UJ}function T1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function Q8(){return T1(W0&255)}var v1=new Set,$8=0;function Z8(){v1.clear(),$8=0,e6()}function X8(J){for(let Q of[...v1])Q(J)}var MJ=null,m1=null;function W8(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function l1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){g0();let Q=MJ?MJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return m1.slice(Q.off,Q.off+Q.len)}var mJ=null,x=null,VJ=null,q0=0,PJ=[],E0=[],b0=[];function p1(J){if(mJ=J,x=null,VJ=null,q0=0,PJ.length=0,E0.length=0,b0.length=0,d){if(d.pressTarget=null,d.target=null,d.spriteDirty=!0,d.fresh=!0,d.vw=0,d.tex>=0){let Q=b();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(d.tex),d.tex=-1}}}function z8(J,Q){J.onPress=Q??void 0}function Y8(J,Q){if(J.focusable=Q,a1(),!Q&&x===J)v(null)}function v(J){if(VJ&&VJ!==J)DJ(null);x=J,b().setFocus(J?J.id:0)}function DJ(J){if(VJ===J)return;let Q=b();if(VJ)Q.setActive?.(VJ.id,0);if(VJ=J,J)Q.setActive?.(J.id,1)}function N0(){return PJ.length>0?PJ[PJ.length-1]:mJ}function T0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;v($[X])}function j8(){if(!x)return null;let J=N0();if(J&&!o(x,J))return null;for(let Q=E0.length-1;Q>=0;Q--){let $=E0[Q];if(J&&!o($.node,J)&&!o(J,$.node))continue;if(o(x,$.node))return $}return null}function F8(J){let Q=j8();if(!Q)return!1;let $=[];if(T0(Q.node,$),$.length===0){if(x)v(null);return!0}let Z=Q.columns,X=x?$.indexOf(x):-1;if(X<0)return v(c1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)v($[W]);return!0}function B8(){if(!x)return null;let J=N0();if(J&&!o(x,J))return null;for(let Q=b0.length-1;Q>=0;Q--){let $=b0[Q];if(J&&!o($.node,J)&&!o(J,$.node))continue;if(o(x,$.node))return $}return null}function z0(J){let Q=B8();if(Q&&Q.move(J))return;if(F8(J))return;H8(J)}function d1(){i1(x)}function i1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){DJ(J)}function K8(J){v(J),i1(J)}function o(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function v0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=v0(Q.children[X]);if(W){v(W);return}}let Z=Q;while(Z){if(Z.focusable){v(Z);return}Z=Z.parent}}v(null)}var d=null,s1=0;function a1(){s1++}var M8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],V8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function P8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=M8[Q]>>$&1,X=V8[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,z=X?255:0;J[W]=z,J[W+1]=z,J[W+2]=z,J[W+3]=255}return J}function D8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=vJ($.image)}catch(z){if(wJ().strict)throw z;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):R8(Q,W),X<0&&wJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(P8(),16,16,h6.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function R8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&E6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function G0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=G0($[Z],Q);if(X)return X}return null}var H0=null;function r1(J){H0=J}function n1(J){let Q=PJ.length>0?PJ[PJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||o($,Q)))return $;$=$.parent}return null}function o1(J,Q,$){return n1(t1(J,Q,$))}function t1(J,Q,$){if($!==void 0)return $===0?null:G0(H0??mJ,$);let Z=b(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return G0(H0??mJ,X(J,Q))}function O8(J,Q,$){let Z=d,X=b();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=g1(X);if(Z.vw=H?H.w:f1,Z.vh=H?H.h:C1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)D8(Z,X);let W=J8()*Z.speed,z=Q8()*Z.speed;if(Z.dpadSpeed>0&&W===0&&z===0){if(J&n.LEFT)W=-Z.dpadSpeed;if(J&n.RIGHT)W=Z.dpadSpeed;if(J&n.UP)z=-Z.dpadSpeed;if(J&n.DOWN)z=Z.dpadSpeed}let F=Z.fresh;if(W!==0||z!==0){let H=r6()/60,w=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),C=Math.min(Math.max(Z.y+z*H,0),Z.vh-1);if(w!==Z.x||C!==Z.y)Z.x=w,Z.y=C,F=!0}if(F)X.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=s1;if(F||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=n1(G0(H0??mJ,X.hitTest(Z.x,Z.y)));let U=Z.target;if(U!==x)v(U);if(Q&Z.button&&U)Z.pressTarget=U;if(Z.pressTarget){if(DJ(U===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=U===Z.pressTarget;if(Z.pressTarget=null,DJ(null),H)d1()}}else if($&Z.button)DJ(null);return!0}function L8(J){let Q=J&~q0,$=q0&~J;if(q0=J,d&&O8(J,Q,$))return;if($&n.CIRCLE)DJ(null);if(Q===0)return;if(Q&n.DOWN)z0("down");if(Q&n.RIGHT)z0("right");if(Q&n.UP)z0("up");if(Q&n.LEFT)z0("left");if(Q&n.CIRCLE)DJ(x),d1()}var m0=null;function e1(J){m0=J}function SJ(){if(a1(),m0)m0()}function I8(J,Q){J.debugName=Q||void 0,SJ()}var YJ={id:f6,type:KJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},J4=Symbol.for("pocketjs.native-node"),l0=1,lJ=3,$J=8,k8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function j0(J){return J.domAttrs??={}}function Q4(J,Q){let $=J.domNodeType??(uJ(J)?lJ:l0),Z=$===lJ?F0(J.text??""):$===$J?w8(J.domData??""):Y4(J.domTag??K0(J));for(let X of Object.keys(J.domAttrs??{}))u0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)GJ(Z,Q4(X,!0));return Z}function u0(J,Q,$){if(k8.has(Q)){fJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete j0(J)[Q];else j0(J)[Q]=$}function p0(J){if(J[J4]===!0)return J;return Object.defineProperty(J,J4,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?lJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===$J?J.domData??"":J.text??""},set($){if(J.domNodeType===$J)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===$J?J.domData??"":J.text??""},set($){if(J.domNodeType===$J)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===$J)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===$J)J.domData=Z;else if(uJ(J))B0(J,Z);else if(h8(J),Z)GJ(J,F0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return H4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??K0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===lJ)return"#text";if(J.domNodeType===$J)return"#comment";return(J.domTag??K0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){fJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===YJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return GJ(J,$),$},insertBefore($,Z){return GJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return GJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return Q4(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){u0(J,$,Z)},removeAttribute($){u0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}p0(YJ);var c0=null;function _8(J){c0=J}var d0={unknownClass:0,unknownTexture:0},$4=new Map;function Z4(J,Q){$4.set(J,Q)}var X4=new Map;function W4(J,Q){X4.set(J,Q)}var yJ=new Set,A8=new Set;function q4(J){if(!J)return!1;if(A8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return p0({id:b().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function F0(J){let Q=b(),$=Q.createNode(KJ.text);return Q.setText($,J),p0({id:$,type:KJ.text,parent:null,children:[],text:J,domNodeType:lJ,domTag:"#text"})}function w8(J=""){let Q=F0("");return Q.domNodeType=$J,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){b().replaceText(J.id,Q),J.text=Q,SJ()}function uJ(J){return J.type===KJ.text}function G4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function GJ(J,Q,$){let Z=b();if(G4(Q),yJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,SJ()}function pJ(J,Q){if(!Q)return;U8(Q),b().removeChild(J.id,Q.id),G4(Q),yJ.add(Q),SJ()}function S8(J){return J.parent??void 0}function y8(J){return J.children[0]}function H4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function f8(J,Q){let $=b();if(SJ(),Q==null||Q===""){$.setStyle(J.id,C6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=c0?c0(Q):void 0;if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);d0.unknownClass++;return}$.setStyle(J.id,Z)}function C8(J,Q){let $=b();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=$4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);d0.unknownTexture++;return}$.setImage(J.id,Z)}function x8(J,Q){let $=b();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=X4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);d0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function g8(J,Q,$){let Z=b(),X=Q??{},W=$??{},z=!1;for(let F in X){let P=X[F];if(W[F]===P)continue;let D=x6[F];if(D===void 0)throw Error(`PocketJS: unknown style prop '${F}' (see spec PROP)`);Z.setProp(J.id,D,i6(F,P)),z=!0}if(z)SJ()}function fJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete j0(J)[Q];else j0(J)[Q]=$;switch(Q){case"class":return f8(J,$),$;case"onPress":case"on:press":return z8(J,$),$;case"src":return C8(J,$),$;case"sprite":return x8(J,$),$;case"style":return g8(J,$,Z),$;case"focusable":return Y8(J,!!$),$;case"debugName":return I8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${K0(J)}>`)}function h8(J){for(let Q of[...J.children])pJ(J,Q)}function K0(J){for(let Q of Object.keys(KJ))if(KJ[Q]===J.type)return Q;return String(J.type)}function E8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}fJ(J,Q,$,Z)}var b8=y6({createElement:Y4,createTextNode:F0,replaceText:B0,isTextNode:uJ,setProperty:E8,insertNode(J,Q,$){GJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:S8,getFirstChild:y8,getNextSibling:H4}),{render:N8,effect:vQ,memo:HJ,createComponent:q,createElement:j4,insert:mQ,spread:T8,mergeProps:lQ,use:uQ}=b8,pQ={linear:c.Easing.Linear,in:c.Easing.EaseIn,out:c.Easing.EaseOut,"in-out":c.Easing.EaseInOut,"out-back":c.Easing.OutBack,spring:c.Easing.Spring,"spring-bouncy":c.Easing.SpringBouncy},v8=null;function F4(J){v8=J}function m8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function B4(J,Q){let $=j4(J);return T8($,Q,!1),m8(Q.nodeRef,$),$}function R(J){return B4("view",J)}function L(J){return B4("text",J)}var cQ=new WeakMap,dQ=new WeakMap,l8={}!==null?Object.freeze({...{}}):Object.freeze({}),iQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:l8}),sQ=new Map,jJ=36000,i0=30,u8=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(jJ),tapeAnalog:new Uint16Array(jJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-i0,saidHello:!1,hostCalls:0};function p8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-i0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)e1(()=>{Y.treeDirty=!0}),o8();else e1(null);globalThis.__pocketDevtools=e8}function c8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)i8(),r8();let W=Q,z=$===void 0?UJ:$&65535,F=Z,P=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(jJ).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==UJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function M4(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,z]of J)Z.fill(W,X,Math.min(X+z,$)),X+=z;return Z}function V4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return M4(J.masks,0,Q)}function P4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return M4(J.analog??[],UJ,Q)}function D4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,T({t:"hello",app:Y.app,host:t8(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` +`))if(X.trim())s8(X)}}function s8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),s0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),s0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":R4();break;case"eval":{let Z=!0,X;try{X=U0((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}T({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":T({t:"tape",tape:U4()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}T({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=V4(Z),Y.replayAnalog=Z.analog?P4(Z):null,Y.replayTouch=Z.touch?D4(Z):null,Y.replayAt=0;break}default:break}}function a8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=i0)R4();if(Y.frame%u8===0)s0()}function r8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function s0(){T({t:"stats",frame:Y.frame,nodes:I4(YJ),tapeLen:Y.tapeLen,paused:Y.paused})}function R4(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,T({t:"tree",frame:Y.frame,root:L4(YJ)})}function n8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function a0(J,Q){if(Array.isArray(J)){for(let $ of J)a0($,Q);return}if(n8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)a0($,Q)}}function O4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)a0(Z,Q)}function L4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(O4(J,(X)=>{if(X.domNodeType===8)return;Z.push(L4(X))}),Z.length)Q.k=Z;return Q}function I4(J){let Q=1;return O4(J,($)=>{Q+=I4($)}),Q}function o8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{T({t:"log",level:$,args:X.map((W)=>U0(W))}),Z?.apply(Q,X)}}}function U0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?k4(W):JSON.stringify(k4(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((z)=>U0(z,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,z])=>`${W}: ${U0(z,Q+1)}`).join(", ")}}`}function k4(J){return J.length>200?J.slice(0,199)+"…":J}function t8(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var e8={get frame(){return Y.frame},dumpTape:()=>U4(),replay:(J)=>{Y.replayMasks=V4(J),Y.replayAnalog=J.analog?P4(J):null,Y.replayTouch=J.touch?D4(J):null,Y.replayAt=0}},_4=new Map,r0=new Map;function A4(J){return J.trim().replace(/\s+/g," ")}function w4(J){return J.split(" ").sort().join(" ")}var S4=-1;function J2(J){for(let Q of Object.keys(J)){let $=J[Q],Z=A4(Q);_4.set(Z,$);let X=w4(Z),W=r0.get(X);r0.set(X,W!==void 0&&W!==$?S4:$)}}function Q2(J){let Q=A4(J),$=_4.get(Q);if($!==void 0)return $;let Z=r0.get(w4(Q));return Z===S4?void 0:Z}var n0=9,$2=(1<{let X=($&X2)!==0,W=X?o0:n0,z=X?W2:$2;return Object.freeze({id:$>>>(X?q2:Z2)&255,x:$&z,y:$>>>W&z,hit:Q?.[Z]})}))}function Y2(){return M0}function G2(){M0=t0}var y4=8,FJ=8,H2=3,j2=8,F2=6,B2=0.5,t=1,cJ=2,e0=4,RJ=8,CJ=[],f4=0,V0=0,BJ=Array.from({length:y4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(FJ),histY:new Int16Array(FJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function K2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function U2(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=t1(Q,$,Z.fact);let F=Z.hit;if(F)return K2(F,W)}let z=X.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let F=CJ[z];if(F.disposed)continue;if(f4>0&&!F.opts.allowWhenBlocked)continue;if(!U2(F,$,Z,W))continue;F.flags[J.slot]=t,J.owners.push(F)}for(let z of J.owners)z.opts.onDown?.(J)}function P2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%FJ,J.histLenz||Z>z))X.flags[J.slot]|=cJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&t)||W&(cJ|e0))continue;if(!X.opts.onLongPress)continue;let z=Math.max(1,Math.round((X.opts.longPressSeconds??B2)*b1()));if(J.frames=0)CJ.splice($,1)},cancel(){if(!Q.disposed)g4(Q)},get panning(){for(let $ of BJ)if($.used&&Q.flags[$.slot]&RJ)return!0;return!1}}}function I2(J){let Q=L2(J);return A0(()=>Q.dispose()),Q}function h4(){CJ.length=0,f4=0,V0=0;for(let J of BJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function k2(){return I2({onDown:(J)=>{let Q=o1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=o1(J.x,J.y,J.hit);if(Q)K8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var _2=1,J1=new Map,P0=[];function A2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function w2(){_2=1,J1.clear(),P0=[]}function S2(){if(P0.length===0)return;let J=P0;P0=[];for(let{id:Q,result:$}of J){let Z=J1.get(Q);if(!Z)continue;J1.delete(Q),A2()?.({t:"delivery",frame:N1(),id:Q,kind:Z.kind}),Z.onResult($)}}var y2={"w-[210] h-[104] px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":0,"text-sm text-slate-500 font-bold":1,"text-lg text-slate-900 font-bold":2,"h-[72] px-5 flex-row items-center justify-between":3,"w-[450] flex-col gap-2":4,"text-base text-slate-900 font-bold":5,"text-sm text-slate-500":6,"text-sm text-emerald-600 font-bold":7,"text-sm text-slate-900 font-bold":8,"h-[64] px-5 flex-row items-center":9,"w-[240] text-base text-slate-900 font-bold":10,"w-[156] text-sm text-slate-500":11,"relative w-[632] h-[196] flex-col":12,"relative w-[632] h-[160] overflow-hidden":13,"absolute w-[632] h-[2] bg-slate-200":14,"absolute text-sm text-slate-500 font-bold":15,"absolute rounded-lg bg-emerald-500":16,"absolute rounded-lg bg-red-500":17,"absolute w-[9] h-[9] rounded-lg bg-emerald-500":18,"absolute w-[9] h-[9] rounded-lg bg-red-500":19,"h-[36] px-1 flex-row items-center justify-between":20,"flex-col w-full h-full bg-slate-50":21,"h-[64] px-6 pt-2":22,"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":23,"h-[304] px-6 pt-3":24,"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100":25,"h-[64] flex-row items-end justify-between":26,"text-2xl text-slate-950 font-bold":27,"text-base text-emerald-600 font-bold":28,"text-base text-red-500 font-bold":29,"h-[60] px-6 pt-2 flex-row gap-3":30,"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":31,"w-[100] h-[44] items-center justify-center rounded-lg bg-white":32,"text-sm text-white font-bold":33,"pt-3 text-sm text-slate-500":34,"h-[126] px-6 pt-3 flex-row items-start gap-[21]":35,"h-[200] px-6 flex-col":36,"h-[150] flex-col rounded-xl shadow bg-white border-slate-100":37,"h-[184] px-6 flex-col":38,"h-[136] flex-col rounded-xl shadow bg-white border-slate-100":39,"h-[126] px-6 pt-2":40,"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":41,"flex-col gap-3":42,"text-xl text-emerald-600 font-bold":43,"text-xl text-red-500 font-bold":44,"h-[104] px-6 flex-row items-center justify-between":45,"w-[460] text-sm text-red-500":46,"w-[460] text-sm text-slate-500":47,"w-[176] h-[64]":48,"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":49,"text-sm text-orange-600 font-bold":50,"relative flex-col w-full h-full bg-slate-50":51,"px-6 pt-[14] flex-col gap-[12]":52,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":53,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":54,"flex-row items-center justify-between":55,"text-base text-slate-500 font-bold":56,"text-sm text-emerald-600":57,"px-6 pt-[14] flex-col gap-[14]":58,"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100":59,"text-base text-slate-500":60,"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100":61,"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":62,"flex-row items-center":63,"w-[170] text-lg text-slate-900 font-bold":64,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":65,"absolute inset-0 z-50 flex-col items-center justify-center":66,"absolute inset-0 bg-slate-950":67,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":68,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":69,"flex-row flex-wrap":70,grow:71,"text-2xl text-white font-bold":72,"text-sm text-slate-600 font-bold":73,"text-base text-slate-900":74,"px-6":75,"px-6 py-5":76,"gap-4":77,"w-[34] h-[34] rounded-lg bg-amber-400":78,"w-[34] h-[34] rounded-lg bg-red-500":79,"w-[34] h-[34] rounded-lg bg-slate-800":80,"w-[34] h-[34] rounded-lg bg-emerald-500":81,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":82,"flex-row items-center gap-4":83,"w-[34] text-2xl text-white font-bold":84,"w-[332] flex-col items-end gap-2":85,"text-sm text-slate-300 font-bold":86,"text-sm text-slate-400":87,"h-[40] px-1 flex-row items-center justify-between":88,"w-full h-full items-center justify-center rounded-xl bg-slate-200":89,"w-full h-full items-center justify-center rounded-xl bg-orange-600":90,"text-base text-white font-bold":91};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var f2="ui:styles",C2="ui:font.",E4="ui:img.",b4="ui:sprite.";function x2(){return globalThis.ui}function g2(J){if(J.__textures)return;for(let Q of h0(E4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)Z4(Q.slice(E4.length),Z)}}function h2(J){if(J.__sprites)return;for(let Q of h0(b4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),z=$[4],F=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),U=J.uploadTexture($.subarray(16),X,W,z);if(U>=0)W4(Q.slice(b4.length),{handle:U,frames:F,cols:P,step:D})}}function N4(J){let Q=j4("view");return fJ(Q,"style",J,void 0),Q}var D0=null,R0=null;function E2(J,Q){if(!D0||!R0)return;fJ(D0,"style",{width:J,height:Q,overflow:c.Overflow.Hidden},void 0),fJ(R0,"style",{width:J,height:Q,posType:c.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=b();$.__viewport={w:J,h:Q}}function b2(J,Q={}){let $=l6(Q.ops);if(u6($),_8(Q2),Q.styles)J2(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let w in Z)Z4(w,Z[w]);let H=$.ops.__sprites;if(H)for(let w in H)W4(w,H[w])}if($.kind==="injected"||Z===void 0){if(Q.pak)u1(Q.pak);if(q8()){for(let H of h0())if(H===f2)$.ops.loadStyles?.(vJ(H));else if(H.startsWith(C2))$.ops.loadFontAtlas?.(vJ(H))}}let X=g1($.ops),W=X?.w??f1,z=X?.h??C1,F=N4({width:W,height:z,overflow:c.Overflow.Hidden}),P=N4({width:W,height:z,posType:c.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});GJ(YJ,F),GJ(YJ,P),F4(P),D0=F,R0=P,p1(F),r1(YJ),Z8(),h4(),k2(),n6(),w2(),p8($.ops),p6(c8((H,w,C,g)=>{o6(),t6(w),z2(C,g),S2(),O2(),X8(H),L8(H),z4()}));let D=N8(J,F),U=c6(E2);return()=>{U(),G2(),h4(),D(),p1(null),r1(null),F4(null),D0=null,R0=null;for(let H of YJ.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);z4()}}function N2(J,Q={}){let $=Q.ops??x2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)u1(Q.pak);return g2($),h2($),b2(J,{ops:$,styles:Q.styles??y2,pak:Q.pak})}var T4="$b",T2=9007199254740991,v2=":memory:",xJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function m2(J){let Q="";for(let $=0;$>2]+xJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2>16,Z<$.length)$[Z++]=W>>8&255;if(Z<$.length)$[Z++]=W&255}return $}function u2(){let J=globalThis.db;if(!J||typeof J!=="object")return null;return typeof J.open==="function"?J:null}function v4(J){if(J instanceof Uint8Array)return{[T4]:m2(J)};if(typeof J==="number"&&!Number.isFinite(J))throw Error("db: cannot bind a non-finite number");if(typeof J==="number"&&Number.isInteger(J)&&Math.abs(J)>T2)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function p2(J){if(J!==null&&typeof J==="object")return l2(J[T4]);return J}function c2(J){if(Array.isArray(J))return JSON.stringify(J.map(v4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=v4(Z);return JSON.stringify(Q)}class Q1{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,c2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=m4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(p2))}run(...J){let Q=this.execute(m4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function m4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class l4{statements=new Map;txDepth=0;constructor(J=v2){let Q=u2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new Q1(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new Q1(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let z=J(...Q);return this.txDepth--,this.exec(X),z}catch(z){throw this.txDepth--,this.exec(W),z}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var d2={title:"text-2xl text-white font-bold",section:"text-sm text-slate-600 font-bold",body:"text-base text-slate-900",bodyStrong:"text-base text-slate-900 font-bold",caption:"text-sm text-slate-500"};function i2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return q(R,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[q(R,{class:"flex-row items-center gap-4",get children(){return[HJ(()=>HJ(()=>!!J.back)()?q(L,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):q(R,{get["class"](){return Q()}})),q(L,{get["class"](){return d2.title},get children(){return J.title}})]}}),q(R,{class:"w-[332] flex-col items-end gap-2",get children(){return[q(L,{class:"text-sm text-slate-300 font-bold",get children(){return J.metaTop??""}}),q(L,{class:"text-sm text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function s2(J){let Q=()=>J.action?J.detail?J.detail+" · VIEW ALL ›":"VIEW ALL ›":J.detail??"";return q(R,{class:"h-[40] px-1 flex-row items-center justify-between",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",get children(){return J.title}}),q(L,{class:"text-sm text-slate-500 font-bold",get children(){return Q()}})]}})}function a2(J){return q(R,{get["class"](){return J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":"w-full h-full items-center justify-center rounded-xl bg-orange-600"},get children(){return q(L,{get["class"](){return J.disabled?"text-base text-slate-500 font-bold":"text-base text-white font-bold"},get children(){return J.label}})}})}var u4=4,m=new l4("robinhood"),r2={number:"",label:"ACCOUNT",suffix:"",status:"WAITING FOR ROBINHOOD"},$1={title:"NO RECENT ACTIVITY",timestamp:"",detail:"",state:"",amount:"",side:""},n2={...$1,title:"ACTIVITY UNAVAILABLE"},o2={...$1,title:""},Z1={symbol:"NO OPEN POSITIONS",quantity:"",averagePrice:"",marketValue:""},t2={...Z1,symbol:"POSITIONS UNAVAILABLE"},e2={...Z1,symbol:""},iJ={account:r2,totalValue:null,cash:null,buyingPower:null,pnlDay:null,pnlWeek:null,positions:[],activity:[],positionsAvailable:!0,activityAvailable:!0,observedAt:null},[i,sJ]=E("dashboard"),[l,JQ]=E("day"),[gJ,X1]=E([]),[O0,L0]=E(""),[y,aJ]=E(iJ),[p4,OJ]=E([]),[QQ,LJ]=E([]),[W1,q1]=E([]),[$Q,z1]=E({change:"$—",percent:"—",positive:!0}),[Y1,c4]=E(0),[d4,i4]=E(0),[s4,a4]=E(0),[r4,ZJ]=E("WAITING FOR ROBINHOOD"),[rJ,n4]=E(!1),u=0,o4=-1,t4=-1,e4=-1,G1=new Map,H1=new Map;function J6(){return Math.floor(Date.now()/1000)}function ZQ(J){try{return J?JSON.parse(J):null}catch{return null}}function XQ(){return m.query("SELECT account_number,label,suffix,status FROM accounts ORDER BY label,account_number LIMIT 16").all().map((Q)=>({number:Q.account_number,label:Q.label,suffix:Q.suffix,status:Q.status}))}function WQ(J,Q){if(t4===J)return;let $=m.query("SELECT account_number,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current LIMIT 16").all(),Z=m.query(` + SELECT value.account_number,value.value,value.observed_at + FROM total_value value + JOIN ( + SELECT account_number,MAX(observed_at) AS observed_at + FROM total_value GROUP BY account_number + ) latest ON latest.account_number=value.account_number AND latest.observed_at=value.observed_at + LIMIT 16 + `).all(),X=m.query("SELECT account_number,symbol,quantity,average_price,market_value FROM positions ORDER BY account_number,CAST(market_value AS REAL) DESC,symbol LIMIT 1024").all(),W=m.query("SELECT account_number,activity_id,occurred_at,symbol,side,quantity,price,amount,state,activity_type FROM activities ORDER BY account_number,occurred_at DESC,observed_at DESC LIMIT 1024").all(),z=new Map($.map((U)=>[U.account_number,U])),F=new Map(Z.map((U)=>[U.account_number,U])),P=new Map,D=new Map;for(let U of X){let H=P.get(U.account_number)||[];if(H.length<64)H.push(U);P.set(U.account_number,H)}for(let U of W){let H=D.get(U.account_number)||[];if(H.length<64)H.push(U);D.set(U.account_number,H)}G1.clear();for(let U of Q){let H=z.get(U.number),w=F.get(U.number),C=P.get(U.number)||[],g=D.get(U.number)||[];G1.set(U.number,{loadedRevision:J,value:{account:U,totalValue:w?.value??null,cash:H?.cash??null,buyingPower:H?.buying_power??null,pnlDay:H?.day_pnl??null,pnlWeek:H?.week_pnl??null,positions:C.map((A)=>({symbol:A.symbol,quantity:A.quantity||"—",averagePrice:A.average_price||"—",marketValue:A.market_value||""})),activity:g.map((A)=>({title:(A.side?A.side+" ":"")+(A.symbol||"ORDER"),timestamp:qQ(A.occurred_at),detail:A.quantity?A.quantity+" SH · "+(A.activity_type||"ORDER"):A.activity_type||"ORDER",state:A.state||"RECENT",amount:A.amount||A.price||A.quantity||"",side:A.side||""})),positionsAvailable:H!==void 0,activityAvailable:H!==void 0,observedAt:Math.max(H?.observed_at??0,w?.observed_at??0)||null}})}t4=J}function I0(J){if(J===null)return null;let Q=Number(J.replace(/[$,%]/g,""));return Number.isFinite(Q)?Q:null}function qQ(J){if(!J)return"RECENT";let Q=new Date(J);if(!Number.isFinite(Q.getTime()))return J.slice(0,16).toUpperCase();return String(Q.getMonth()+1).padStart(2,"0")+"/"+String(Q.getDate()).padStart(2,"0")+" "+String(Q.getHours()).padStart(2,"0")+":"+String(Q.getMinutes()).padStart(2,"0")}function Q6(J){let Q=Math.max(0,J6()-J);if(Q<60)return"JUST NOW";if(Q<3600)return Math.floor(Q/60)+" MIN AGO";if(Q<86400)return Math.floor(Q/3600)+" HR AGO";return Math.floor(Q/86400)+" DAY AGO"}function e(J){if(!J)return"$—";let Q=I0(J);if(Q===null)return J;let Z=Math.abs(Q).toFixed(2).split("."),X="$"+Z[0].replace(/\B(?=(\d{3})+(?!\d))/g,",")+"."+Z[1];return Q<0?"-"+X:X}function $6(J,Q){let $=J+":"+l(),Z=H1.get($);if(Z?.loadedRevision===Q){OJ(Z.value.points),LJ(Z.value.segments),q1(Z.value.labels),z1(Z.value.trend);return}let X=l()==="day"?86400:604800,z=J6()-X,P=m.query(` + WITH RECURSIVE buckets(bucket_index, bucket_time) AS ( + SELECT 0, ?1 + UNION ALL + SELECT bucket_index + 1, ?1 + CAST((?2 * (bucket_index + 1)) / 19 AS INTEGER) + FROM buckets WHERE bucket_index < 19 + ) + SELECT bucket_index, bucket_time, + (SELECT value FROM total_value + WHERE account_number = ?3 AND observed_at >= ?1 AND observed_at <= bucket_time + ORDER BY observed_at DESC LIMIT 1) AS total_value + FROM buckets ORDER BY bucket_index + `).all(z,X,J).map((j)=>({time:j.bucket_time,value:I0(j.total_value)})),D=P.map((j)=>j.time),U=P.map((j)=>j.value).filter((j)=>j!==null),H=[D[0],D[9],D[19]].map((j)=>{let G=new Date(j*1000);return l()==="day"?String(G.getHours()).padStart(2,"0")+":"+String(G.getMinutes()).padStart(2,"0"):String(G.getMonth()+1)+"/"+String(G.getDate())});if(U.length===0){let j=l()==="day"?y().pnlDay:y().pnlWeek,G=I0(j),V={points:[],segments:[],labels:H,trend:{change:e(j),percent:"—",positive:G===null||G>=0}};H1.set($,{loadedRevision:Q,value:V}),OJ(V.points),LJ(V.segments),q1(V.labels),z1(V.trend);return}let w=Math.min(...U),C=Math.max(...U),g=Math.max(0.01,C-w),A=P.flatMap((j,G)=>j.value===null?[]:[{x:G*622/19,y:U.length===1?80:10+(C-j.value)*140/g}]),s=A.slice(1).map((j,G)=>{let V=A[G],k=j.x-V.x,_=j.y-V.y;return{x:V.x,y:V.y,width:Math.sqrt(k*k+_*_),angle:Math.atan2(_,k)*180/Math.PI}}),a=U[U.length-1]-U[0],K={change:e(String(a)),percent:U[0]===0?"—":(a*100/U[0]).toFixed(2)+"%",positive:a>=0};H1.set($,{loadedRevision:Q,value:{points:A,segments:s,labels:H,trend:K}}),OJ(A),LJ(s),q1(H),z1(K)}function zQ(J){if(e4===J)return;let Q=m.query("SELECT status,error,completed_at FROM refresh_runs ORDER BY id DESC LIMIT 1").get();if(n4(!1),Q?.status==="failed")ZJ("REFRESH FAILED · "+String(Q.error||"UNKNOWN ERROR").slice(0,52));else if(Q?.status==="partial")ZJ("LIVE WITH PARTIAL DATA");else if(y().observedAt)ZJ("LIVE / READ ONLY · "+Q6(y().observedAt));else ZJ("WAITING FOR ROBINHOOD");e4=J}function Z6(J,Q){if(!J){if(aJ(iJ),OJ([]),LJ([]),!rJ())ZJ("WAITING FOR ROBINHOOD");return}let $=G1.get(J);if($?.loadedRevision===Q){if(aJ($.value),$6(J,Q),$.value.observedAt&&!rJ())ZJ("LIVE / READ ONLY · "+Q6($.value.observedAt));return}aJ(iJ),OJ([]),LJ([])}function X6(J=u){try{let Q=m.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==u4){X1([]),L0(""),aJ(iJ),OJ([]),LJ([]),ZJ("WAITING FOR ROBINHOOD");return}eJ(()=>{u=Math.max(u,J);let $=gJ();if(o4!==u)$=XQ(),X1($),o4=u;WQ(u,$);let Z=O0();if(!$.some((X)=>X.number===Z))Z=$[0]?.number||"",L0(Z);Z6(Z,u),zQ(u)})}catch{eJ(()=>{X1([]),L0(""),aJ(iJ),OJ([]),LJ([]),ZJ("WAITING FOR ROBINHOOD")})}}function YQ(){return""}function GQ(){let J=m.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((z)=>z.name)),$=J.map((z)=>{let F=m.query("SELECT COUNT(*) AS count FROM "+z.name).get().count;return{name:z.name,rowCount:F,schema:z.sql}}),Z=Q.has("refresh_runs")?m.query("SELECT id,started_at,completed_at,operation_count,success_count,status,error FROM refresh_runs ORDER BY id DESC LIMIT 3").all():[],X=Q.has("portfolio_current")?m.query("SELECT substr(account_number,-4) AS account_suffix,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current ORDER BY observed_at DESC LIMIT 4").all():[],W=Q.has("total_value")?m.query("SELECT substr(account_number,-4) AS account_suffix,observed_at,value FROM total_value ORDER BY observed_at DESC LIMIT 8").all():[];return{database:"robinhood.sqlite",schemaVersion:u4,tables:$,latestRefreshes:Z,latestPortfolios:X,latestValues:W}}function j1(){return $Q()}function k0(J){return q(i2,{get title(){return J.title},back:!0,metaTop:"READ ONLY",get metaBottom(){return J.metaBottom??"AUTO · 5 MIN"}})}function F1(J){return q(R,{class:"w-[210] h-[104] px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(L,{class:"text-sm text-slate-500 font-bold",get children(){return J.label}}),q(L,{class:"text-lg text-slate-900 font-bold",get children(){return e(J.value)}})]}})}function W6(J){return q(s2,{get title(){return J.title},get detail(){return J.detail},action:!0})}function HQ(J){if(J===0&&!y().activityAvailable)return n2;return y().activity[J]??(J===0?$1:o2)}function q6(J){let Q=()=>HQ(J.index);return q(R,{class:"h-[72] px-5 flex-row items-center justify-between",get children(){return[q(R,{class:"w-[450] flex-col gap-2",get children(){return[q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q().title}}),q(L,{class:"text-sm text-slate-500",get children(){return HJ(()=>!!Q().timestamp)()?Q().timestamp+" · "+Q().detail:""}})]}}),q(L,{get["class"](){return Q().side==="SELL"?"text-sm text-emerald-600 font-bold":"text-sm text-slate-900 font-bold"},get children(){return HJ(()=>!!Q().amount)()?e(Q().amount):""}})]}})}function jQ(J){if(J===0&&!y().positionsAvailable)return t2;return y().positions[J]??(J===0?Z1:e2)}function z6(J){let Q=()=>jQ(J.index);return q(R,{class:"h-[64] px-5 flex-row items-center",get children(){return[q(L,{class:"w-[240] text-base text-slate-900 font-bold",get children(){return Q().symbol}}),q(L,{class:"w-[156] text-sm text-slate-500",get children(){return HJ(()=>!!Q().quantity)()?Q().quantity+" SH":""}}),q(L,{class:"text-sm text-slate-500",get children(){return HJ(()=>!!Q().averagePrice)()?"AVG "+e(Q().averagePrice):""}})]}})}function FQ(){return q(R,{class:"relative w-[632] h-[196] flex-col",get children(){return[q(R,{class:"relative w-[632] h-[160] overflow-hidden",get children(){return[q(R,{class:"absolute w-[632] h-[2] bg-slate-200",style:{posType:1,insetL:0,insetT:158}}),q(L,{class:"absolute text-sm text-slate-500 font-bold",style:{posType:1,insetL:174,insetT:72},get children(){return p4().length<2?"COLLECTING 5M VALUE HISTORY":""}}),q(NJ,{get each(){return QQ()},children:(J)=>q(R,{get["class"](){return j1().positive?"absolute rounded-lg bg-emerald-500":"absolute rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x,insetT:J.y-2,width:J.width,height:4,rotate:J.angle,originX:0,originY:0.5}}})}),q(NJ,{get each(){return p4()},children:(J)=>q(R,{get["class"](){return j1().positive?"absolute w-[9] h-[9] rounded-lg bg-emerald-500":"absolute w-[9] h-[9] rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x-4,insetT:J.y-4}}})})]}}),q(R,{class:"h-[36] px-1 flex-row items-center justify-between",get children(){return[q(L,{class:"text-sm text-slate-500",get children(){return W1()[0]||""}}),q(L,{class:"text-sm text-slate-500",get children(){return W1()[1]||""}}),q(L,{class:"text-sm text-slate-500",get children(){return W1()[2]||""}})]}})]}})}function BQ(){let J=()=>j1();return q(R,{class:"flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ROBINHOOD"}),q(R,{class:"h-[64] px-6 pt-2",get children(){return q(R,{class:"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(L,{class:"text-sm text-slate-500 font-bold",children:"ACCOUNT"}),q(L,{class:"text-sm text-slate-900 font-bold",get children(){return y().account.label+(y().account.suffix?" ····"+y().account.suffix+" "+(gJ().findIndex((Q)=>Q.number===O0())+1)+"/"+gJ().length:"")+" ›"}})]}})}}),q(R,{class:"h-[304] px-6 pt-3",get children(){return q(R,{class:"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"h-[64] flex-row items-end justify-between",get children(){return[q(L,{class:"text-2xl text-slate-950 font-bold",get children(){return e(y().totalValue)}}),q(L,{get["class"](){return J().positive?"text-base text-emerald-600 font-bold":"text-base text-red-500 font-bold"},get children(){return J().change+" ("+J().percent+")"}})]}}),q(FQ,{})]}})}}),q(R,{class:"h-[60] px-6 pt-2 flex-row gap-3",get children(){return[q(R,{get["class"](){return l()==="day"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(L,{get["class"](){return l()==="day"?"text-sm text-white font-bold":"text-sm text-slate-500 font-bold"},children:"1D"})}}),q(R,{get["class"](){return l()==="week"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(L,{get["class"](){return l()==="week"?"text-sm text-white font-bold":"text-sm text-slate-500 font-bold"},children:"1W"})}}),q(L,{class:"pt-3 text-sm text-slate-500",get children(){return l()==="day"?"TODAY":"PAST WEEK"}})]}}),q(R,{class:"h-[126] px-6 pt-3 flex-row items-start gap-[21]",get children(){return[q(F1,{label:"VALUE",get value(){return y().totalValue}}),q(F1,{label:"CASH",get value(){return y().cash}}),q(F1,{label:"BUY POWER",get value(){return y().buyingPower}})]}}),q(R,{class:"h-[200] px-6 flex-col",get children(){return[q(W6,{title:"ACTIVITY",detail:"LAST 7 DAYS"}),q(R,{class:"h-[150] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(q6,{index:0}),q(q6,{index:1})]}})]}}),q(R,{class:"h-[184] px-6 flex-col",get children(){return[q(W6,{title:"POSITIONS"}),q(R,{class:"h-[136] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(z6,{index:0}),q(z6,{index:1})]}})]}}),q(R,{class:"h-[126] px-6 pt-2",get children(){return q(R,{class:"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-col gap-3",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",children:"REALIZED P&L"}),q(L,{class:"text-sm text-slate-500",get children(){return"EQUITIES / "+(l()==="day"?"TODAY":"WEEK")}})]}}),q(L,{get["class"](){return(I0(l()==="day"?y().pnlDay:y().pnlWeek)??0)>=0?"text-xl text-emerald-600 font-bold":"text-xl text-red-500 font-bold"},get children(){return e(l()==="day"?y().pnlDay:y().pnlWeek)}})]}})}}),q(R,{class:"h-[104] px-6 flex-row items-center justify-between",get children(){return[q(L,{get["class"](){return r4().startsWith("REFRESH FAILED")?"w-[460] text-sm text-red-500":"w-[460] text-sm text-slate-500"},get children(){return r4()}}),q(R,{class:"w-[176] h-[64]",get children(){return q(a2,{get label(){return rJ()?"REFRESHING":"REFRESH NOW"},get disabled(){return rJ()}})}})]}})]}})}function B1(){return[q(R,{class:"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",style:{posType:1,insetL:628,insetT:156},get children(){return q(L,{class:"text-sm text-orange-600 font-bold",children:"UP"})}}),q(R,{class:"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",style:{posType:1,insetL:628,insetT:972},get children(){return q(L,{class:"text-sm text-orange-600 font-bold",children:"DN"})}})]}function KQ(){let J=QJ(()=>gJ().slice(Y1(),Y1()+8)),Q=O0();return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ACCOUNTS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(NJ,{get each(){return J()},children:($)=>q(R,{get["class"](){return $.number===Q?"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100"},get children(){return[q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",get children(){return $.label}}),q(L,{class:"text-base text-slate-500 font-bold",get children(){return"····"+$.suffix}})]}}),q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-sm text-emerald-600",get children(){return $.status}}),q(Z0,{get when(){return $.number===Q},get children(){return q(L,{class:"text-sm text-emerald-600 font-bold",children:"SELECTED"})}})]}})]}})})}}),q(B1,{})]}})}function UQ(){let J=QJ(()=>y().activity.slice(d4(),d4()+8));return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ACTIVITY",metaBottom:"LAST 7 DAYS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[14]",get children(){return q(Z0,{get when(){return HJ(()=>!!y().activityAvailable)()&&J().length>0},get fallback(){return q(R,{class:"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100",get children(){return q(L,{class:"text-base text-slate-500",get children(){return y().activityAvailable?"NO ACTIVITY YET":"ACTIVITY UNAVAILABLE"}})}})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(R,{class:"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q.title}}),q(L,{get["class"](){return Q.side==="SELL"?"text-base text-emerald-600 font-bold":"text-base text-slate-900 font-bold"},get children(){return e(Q.amount)}})]}}),q(L,{class:"text-sm text-slate-500",get children(){return Q.timestamp+" · "+Q.detail}}),q(L,{class:"text-sm text-emerald-600 font-bold",get children(){return Q.state}})]}})})}})}}),q(B1,{})]}})}function MQ(){let J=QJ(()=>y().positions.slice(s4(),s4()+9));return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"POSITIONS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(Z0,{get when(){return HJ(()=>!!y().positionsAvailable)()&&J().length>0},get fallback(){return q(R,{class:"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100",get children(){return q(L,{class:"text-base text-slate-500",get children(){return y().positionsAvailable?"NO OPEN POSITIONS":"POSITIONS UNAVAILABLE"}})}})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(R,{class:"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-row items-center",get children(){return[q(L,{class:"w-[170] text-lg text-slate-900 font-bold",get children(){return Q.symbol}}),q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q.quantity+" SH"}})]}}),q(L,{class:"text-sm text-slate-500",get children(){return"AVERAGE COST "+e(Q.averagePrice)+(Q.marketValue?" · VALUE "+e(Q.marketValue):"")}})]}})})}})}}),q(B1,{})]}})}function VQ(){if(i()==="accounts")return q(KQ,{});if(i()==="activity")return q(UQ,{});return q(MQ,{})}function PQ(){return q(Z0,{get when(){return i()==="dashboard"},get fallback(){return q(VQ,{})},get children(){return q(BQ,{})}})}X6(),N2(()=>q(PQ,{})),globalThis.PocketPiApp={tick:YQ,update(){return""},dataChanged(J){let Q=ZQ(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),u):u;return X6($),""},invokeTool(J){try{let Q=J==="robinhood.storage_status"?GQ():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Data Action tasks do not run in the View: "+J,isError:!0})},tap(J,Q){if(i()!=="dashboard"){if(Q<112&&J<220)return sJ("dashboard"),"";if(J>=620&&Q>=140&&Q<310){if(i()==="accounts")c4(($)=>Math.max(0,$-1));if(i()==="activity")i4(($)=>Math.max(0,$-1));if(i()==="positions")a4(($)=>Math.max(0,$-1));return""}if(J>=620&&Q>=940&&Q<1130){if(i()==="accounts")c4(($)=>Math.min(Math.max(0,gJ().length-8),$+1));if(i()==="activity")i4(($)=>Math.min(Math.max(0,y().activity.length-8),$+1));if(i()==="positions")a4(($)=>Math.min(Math.max(0,y().positions.length-9),$+1));return""}if(i()==="accounts"&&J<610&&Q>=126){let $=Y1()+Math.floor((Q-126)/112),Z=gJ()[$];if(Z)eJ(()=>{L0(Z.number),sJ("dashboard")}),Z6(Z.number,u)}return""}if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(Q>=112&&Q<176)return sJ("accounts"),"";if(Q>=480&&Q<540)return eJ(()=>{JQ(J<136?"day":"week"),$6(O0(),u)}),"";if(Q>=666&&Q<866)return sJ("activity"),"";if(Q>=866&&Q<1050)return sJ("positions"),"";if(Q>=1176&&J>=500){if(rJ())return"";return n4(!0),ZJ("REFRESHING ROBINHOOD…"),JSON.stringify({type:"invokeTask",task:"refreshPortfolio"})}return""}}})(); diff --git a/apps/robinhood/dist/app.pak b/apps/robinhood/dist/app.pak new file mode 100644 index 0000000000000000000000000000000000000000..7ed2f2c8332a1d0e76998d6174cd457155e6d34c GIT binary patch literal 294656 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 h=globalThis.db,v=h.open("robinhood");if(v<0)throw Error("open robinhood.sqlite");var C=4;function q(){return String(h.lastError(v)||"SQLite operation failed")}function m(e){if(h.exec(v,e)!==0)throw Error(q())}function O(e,t=[]){let o=JSON.parse(h.query(v,e,JSON.stringify(t)));if(o.error)throw Error(String(o.error));return o}function l(e,t=[]){return O(e,t)}var k=O("PRAGMA user_version");if(Number(k?.user_version??0)!==C)m(` + CREATE TABLE IF NOT EXISTS accounts ( + account_number TEXT PRIMARY KEY, + label TEXT NOT NULL, + suffix TEXT NOT NULL, + account_type TEXT, + status TEXT NOT NULL, + agentic_allowed INTEGER NOT NULL DEFAULT 0, + updated_at INTEGER NOT NULL + ); + CREATE TABLE IF NOT EXISTS portfolio_current ( + account_number TEXT PRIMARY KEY, + cash TEXT, + buying_power TEXT, + day_pnl TEXT, + week_pnl TEXT, + observed_at INTEGER NOT NULL + ); + CREATE TABLE IF NOT EXISTS total_value ( + account_number TEXT NOT NULL, + observed_at INTEGER NOT NULL, + value TEXT NOT NULL, + PRIMARY KEY(account_number, observed_at) + ); + CREATE TABLE IF NOT EXISTS positions ( + account_number TEXT NOT NULL, + symbol TEXT NOT NULL, + quantity TEXT, + average_price TEXT, + market_value TEXT, + observed_at INTEGER NOT NULL, + PRIMARY KEY(account_number, symbol) + ); + CREATE TABLE IF NOT EXISTS activities ( + account_number TEXT NOT NULL, + activity_id TEXT NOT NULL, + occurred_at TEXT, + observed_at INTEGER NOT NULL, + symbol TEXT, + side TEXT, + quantity TEXT, + price TEXT, + amount TEXT, + state TEXT, + activity_type TEXT, + PRIMARY KEY(account_number, activity_id) + ); + CREATE INDEX IF NOT EXISTS activities_account_recent ON activities(account_number, occurred_at DESC, observed_at DESC); + CREATE TABLE IF NOT EXISTS refresh_runs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + started_at INTEGER NOT NULL, + completed_at INTEGER NOT NULL, + status TEXT NOT NULL, + operation_count INTEGER NOT NULL, + success_count INTEGER NOT NULL, + error TEXT + ); + CREATE INDEX IF NOT EXISTS refresh_runs_recent ON refresh_runs(id DESC); + CREATE TABLE IF NOT EXISTS equity_historicals ( + account_number TEXT NOT NULL, + span TEXT NOT NULL, + point_time TEXT NOT NULL, + price TEXT, + open TEXT, + high TEXT, + low TEXT, + close TEXT, + volume TEXT, + observed_at INTEGER NOT NULL, + PRIMARY KEY(account_number, span, point_time) + ); + CREATE TABLE IF NOT EXISTS pnl_trades ( + account_number TEXT NOT NULL, + trade_id TEXT NOT NULL, + occurred_at TEXT, + symbol TEXT, + side TEXT, + quantity TEXT, + price TEXT, + realized_pnl TEXT, + observed_at INTEGER NOT NULL, + PRIMARY KEY(account_number, trade_id) + ); + CREATE TABLE IF NOT EXISTS order_reviews ( + review_id TEXT PRIMARY KEY, + account_number TEXT, + symbol TEXT, + side TEXT, + quantity TEXT, + limit_price TEXT, + estimated_cost TEXT, + state TEXT, + observed_at INTEGER NOT NULL + ); + PRAGMA user_version=4; + `);function N(){return Math.floor(Date.now()/1000)}function g(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function i(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let o of t){let n=g(e[o]);if(n!==null)return n}for(let o of Object.values(e)){let n=i(o,t);if(n!==null)return n}return null}function I(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let o of t)if(Array.isArray(e[o]))return e[o];for(let o of Object.values(e)){let n=I(o,t);if(n.length)return n}return[]}function P(e,t){let o=i(e,t)?.toLowerCase();return o==="true"||o==="1"||o==="yes"}function w(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function d(e,t){return i(e,["account_number","accountNumber","account"])||String(t?.account_number??t?.accountNumber??"")}function f(e,t){let o=I(e,t);return o.length?o:Array.isArray(e)?e:e?[e]:[]}function A(e,t){let o=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t})));if(!o.ok)throw Error(o.error||"Robinhood service failed");return o.value}function D(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((o)=>({name:o.operation,arguments:o.args}))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function S(e){m("BEGIN IMMEDIATE");try{e(),m("COMMIT")}catch(t){try{m("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function M(e,t){let o=f(e,["accounts"]);l("DELETE FROM accounts");for(let n of o){let c=d(n,{});if(!c)continue;let r=(i(n,["nickname","account_type","type"])||"").toUpperCase(),a=P(n,["agentic_allowed","agenticAllowed"]),s=a?"AGENTIC":r.includes("IRA")||r.includes("RETIRE")?"RETIREMENT":r.includes("JOINT")?"JOINT":"PERSONAL";l("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at) VALUES(?,?,?,?,?,?,?)",[c,s,c.slice(-4),r,(i(n,["status"])||"active").toUpperCase(),a?1:0,t])}}function x(e,t,o){let n=d(e,t);if(!n)throw Error("Robinhood portfolio is missing account_number");let c=i(e,["cash","cash_available","withdrawable_amount"]),r=i(e,["buying_power","buyingPower"]),a=i(e,["day_pnl","dayPnl","equity_change"]),s=i(e,["week_pnl","weekPnl"]);l(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) + VALUES(?,?,?,?,?,?) + ON CONFLICT(account_number) DO UPDATE SET + cash=excluded.cash,buying_power=excluded.buying_power, + day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), + week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), + observed_at=excluded.observed_at`,[n,c,r,a,s,o]);let u=i(e,["total_value","equity","total_equity","portfolio_value","market_value"]);if(u!==null)l("INSERT OR REPLACE INTO total_value(account_number,observed_at,value) VALUES(?,?,?)",[n,o,u])}function F(e,t,o){let n=d(e,t);if(!n)throw Error("Robinhood positions are missing account_number");let c=f(e,["positions"]).slice(0,64);l("DELETE FROM positions WHERE account_number=?",[n]);for(let r of c){let a=i(r,["symbol"]);if(!a)continue;l("INSERT INTO positions(account_number,symbol,quantity,average_price,market_value,observed_at) VALUES(?,?,?,?,?,?)",[n,a,i(r,["quantity","shares"]),i(r,["average_price","averagePrice","average_buy_price"]),i(r,["market_value","marketValue","equity"]),o])}}function G(e,t,o){let n=d(e,t);if(!n)throw Error("Robinhood activities are missing account_number");let c=f(e,["orders","activities","results"]).slice(0,64);l("DELETE FROM activities WHERE account_number=?",[n]),c.forEach((r,a)=>{let s=i(r,["symbol"]),u=(i(r,["side"])||"").toUpperCase(),_=i(r,["executed_quantity","cumulative_quantity","quantity"]),p=i(r,["average_price","averagePrice","executed_price","price"]),y=i(r,["last_transaction_at","created_at","updated_at","date"]),T=i(r,["id","order_id","orderId","activity_id"])||[y||o,s||"ORDER",u,a].join(":"),E=w(_),b=w(p),U=E!==null&&b!==null?String(E*b):p||_;l(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) + VALUES(?,?,?,?,?,?,?,?,?,?,?)`,[n,T,y,o,s,u,_,p,U,(i(r,["state","status"])||"RECENT").toUpperCase(),(i(r,["type","order_type"])||"ORDER").toUpperCase()])})}function Y(e,t,o){let n=d(e,t);if(!n)throw Error("Robinhood P&L is missing account_number");let c=i(e,["total_returns","realized_pnl","total","amount","day_pnl","week_pnl"]),r=String(t?.span??"day");l(`INSERT INTO portfolio_current(account_number,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?) + ON CONFLICT(account_number) DO UPDATE SET + day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), + week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), + observed_at=MAX(portfolio_current.observed_at,excluded.observed_at)`,[n,r==="week"?null:c,r==="week"?c:null,o])}function J(e,t,o){let n=d(e,t),c=String(t?.span??t?.interval??"default"),r=f(e,["historicals","results","data"]);l("DELETE FROM equity_historicals WHERE account_number=? AND span=?",[n,c]),r.forEach((a,s)=>{let u=i(a,["begins_at","timestamp","time","date"])||String(s);l(`INSERT INTO equity_historicals(account_number,span,point_time,price,open,high,low,close,volume,observed_at) + VALUES(?,?,?,?,?,?,?,?,?,?)`,[n,c,u,i(a,["price","adjusted_close","close_price"]),i(a,["open_price","open"]),i(a,["high_price","high"]),i(a,["low_price","low"]),i(a,["close_price","close"]),i(a,["volume"]),o])})}function V(e,t,o){let n=d(e,t),c=f(e,["trades","results","data"]);l("DELETE FROM pnl_trades WHERE account_number=?",[n]),c.forEach((r,a)=>{let s=i(r,["created_at","updated_at","date","timestamp"]),u=i(r,["id","trade_id","tradeId"])||[s||o,i(r,["symbol"])||"TRADE",a].join(":");l(`INSERT INTO pnl_trades(account_number,trade_id,occurred_at,symbol,side,quantity,price,realized_pnl,observed_at) + VALUES(?,?,?,?,?,?,?,?,?)`,[n,u,s,i(r,["symbol"]),(i(r,["side"])||"").toUpperCase(),i(r,["quantity","shares"]),i(r,["price","average_price"]),i(r,["realized_pnl","pnl","amount"]),o])})}function B(e,t,o){let n=d(e,t),c=i(e,["symbol"])||g(t?.symbol),r=(i(e,["side"])||g(t?.side)||"").toUpperCase(),a=i(e,["quantity","shares"])||g(t?.quantity),s=i(e,["limit_price","limitPrice","price"])||g(t?.limit_price??t?.price),u=i(e,["id","review_id","reviewId"])||[n,c,r,a,s,o].join(":");l(`INSERT OR REPLACE INTO order_reviews(review_id,account_number,symbol,side,quantity,limit_price,estimated_cost,state,observed_at) + VALUES(?,?,?,?,?,?,?,?,?)`,[u,n,c,r,a,s,i(e,["estimated_cost","estimatedCost","total"]),i(e,["state","status"]),o])}function X(e){if(e.operation==="get_accounts")M(e.value,e.observedAt);else if(e.operation==="get_portfolio")x(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_positions")F(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_orders")G(e.value,e.args,e.observedAt);else if(e.operation==="get_realized_pnl")Y(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_historicals")J(e.value,e.args,e.observedAt);else if(e.operation==="get_pnl_trade_history")V(e.value,e.args,e.observedAt);else if(e.operation==="review_equity_order")B(e.value,e.args,e.observedAt);else throw Error("No Robinhood table mapping for "+e.operation)}function z(e){let t=e.toLowerCase();return t.includes("esp_err_http_connect")||t.includes("timeout")||t.includes("tls")||t.includes("socket")||t.includes("network")}function L(){let e=N(),t=[],o=[],n=0,c=(s,u)=>{n+=1;try{let _=A(s,u);return t.push({operation:s,args:u,value:_,observedAt:N()}),_}catch(_){let p=_ instanceof Error?_.message:String(_);if(o.push(s+": "+p),s==="get_accounts"||z(p))throw _;return null}},r=null;try{let s=c("get_accounts",{}),_=f(s,["accounts"]).map((T)=>d(T,{})).filter(Boolean);if(!_.length)throw Error("Robinhood returned no brokerage accounts");let p=new Date((e-604800)*1000).toISOString().slice(0,10),y=[];for(let T of _){let E={account_number:T};y.push({operation:"get_portfolio",args:E},{operation:"get_equity_positions",args:E},{operation:"get_equity_orders",args:{...E,created_at_gte:p}},{operation:"get_realized_pnl",args:{...E,span:"day",asset_classes:["equity"]}},{operation:"get_realized_pnl",args:{...E,span:"week",asset_classes:["equity"]}})}n+=y.length;let R=D(y);if(R.length!==y.length)throw Error("Robinhood batch returned an incomplete result set");if(R.forEach((T,E)=>{let b=y[E];if(T?.ok)t.push({operation:b.operation,args:b.args,value:T.value,observedAt:N()});else o.push(b.operation+": "+String(T?.error||"unknown provider error"))}),!t.some((T)=>T.operation==="get_portfolio"))throw Error("Robinhood batch returned no portfolio data")}catch(s){r=s instanceof Error?s.message:String(s)}let a=r?"failed":o.length?"partial":"succeeded";if(S(()=>{if(!r)for(let s of t)X(s);l(`INSERT INTO refresh_runs(started_at,completed_at,status,operation_count,success_count,error) + VALUES(?,?,?,?,?,?)`,[e,N(),a,n,r?0:t.length,r||o.join(" | ")||null])}),r)throw Error(r);return{status:a,operationCount:n,successCount:t.length}}var j={"robinhood.get_accounts":"get_accounts","robinhood.get_portfolio":"get_portfolio","robinhood.get_equity_positions":"get_equity_positions","robinhood.get_equity_orders":"get_equity_orders","robinhood.get_equity_historicals":"get_equity_historicals","robinhood.get_realized_pnl":"get_realized_pnl","robinhood.get_pnl_trade_history":"get_pnl_trade_history","robinhood.review_equity_order":"review_equity_order"};function K(e,t){let o=j[e];if(!o)throw Error("Unknown Robinhood tool: "+e);let n=A(o,t);return S(()=>X({operation:o,args:t,value:n,observedAt:N()})),n}globalThis.PocketPiData={invokeTask(e){try{if(e!=="refreshPortfolio")throw Error("Unknown Robinhood Data Action: "+e);let t=L();return JSON.stringify({text:JSON.stringify(t),details:t,isError:!1})}catch(t){return JSON.stringify({text:t instanceof Error?t.message:String(t),isError:!0})}},invokeTool(e,t){try{let o=JSON.parse(t),n=e==="robinhood.refresh_portfolio"?L():K(e,o);return JSON.stringify({text:JSON.stringify(n),details:n,isError:!1})}catch(o){return JSON.stringify({text:o instanceof Error?o.message:String(o),isError:!0})}}};})(); diff --git a/apps/robinhood/pocket.json b/apps/robinhood/pocket.json new file mode 100644 index 0000000..34ab4d3 --- /dev/null +++ b/apps/robinhood/pocket.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://pocketjs.dev/schema/pocket-2.json", + "pocket": 2, + "id": "dev.pocket-stack.robinhood", + "name": "robinhood", + "title": "Robinhood", + "version": "1.0.0", + "engine": {"capabilities":{"requires":["data.fs","data.sqlite"]}}, + "app": {"entry":"app.tsx","output":"app","framework":"solid","viewport":{"logical":[720,1280],"presentation":"fit"}} +} diff --git a/crates/pocket-pi-agentos/Cargo.toml b/crates/pocket-pi-agentos/Cargo.toml new file mode 100644 index 0000000..3fa3980 --- /dev/null +++ b/crates/pocket-pi-agentos/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "pocket-pi-agentos" +version = "0.1.0" +edition.workspace = true +license.workspace = true +repository.workspace = true +description = "Pocket Pi AgentOS app supervisor, bundle runtime and app tool router" +publish = false + +[dependencies] +anyhow.workspace = true +log.workspace = true +pocket-db.workspace = true +pocket-fs.workspace = true +pocket-mod.workspace = true +pocket-ui-surface.workspace = true +pocket-pi-embedded = { path = "../pocket-pi-embedded" } +pocketjs-core.workspace = true +serde.workspace = true +serde_json.workspace = true + +[dev-dependencies] +tempfile = "3" diff --git a/crates/pocket-pi-agentos/src/lib.rs b/crates/pocket-pi-agentos/src/lib.rs new file mode 100644 index 0000000..1fa671b --- /dev/null +++ b/crates/pocket-pi-agentos/src/lib.rs @@ -0,0 +1,1723 @@ +//! Pocket Pi's App runtime: one isolated PocketJS Guest per active App, +//! app-owned FS/SQLite state, namespaced Agent tools and native AppTask wakes. + +use std::cell::{Cell, RefCell}; +use std::collections::BTreeMap; +use std::path::{Path, PathBuf}; +use std::rc::Rc; +use std::sync::atomic::{AtomicBool, AtomicU32, Ordering}; +use std::sync::{mpsc, Arc, Mutex}; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; + +use anyhow::{anyhow, Context as _, Result}; +use pocket_db::{DbModule, Storage as DbStorage}; +use pocket_fs::{FsModule, Storage as FsStorage}; +use pocket_mod::qjs::{CatchResultExt as _, Function, Object}; +use pocket_mod::Guest; +use pocket_pi_embedded::{AgentEvent, GuestAgent, ModelBackend, ToolHost, ToolResult}; +use pocket_ui_surface::UiSurface; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value}; + +pub const ROOT_APP_ID: &str = "pi-agent"; +pub const ROBINHOOD_APP_ID: &str = "robinhood"; +pub const EXA_APP_ID: &str = "exa"; +pub const BUILTIN_RELEASE: &str = "builtin-v1"; +pub const VIEWPORT: (f32, f32) = (720.0, 1280.0); + +// App tools must enqueue remote work quickly. Keep a defensive bound for the +// Tool Router handoff and local read-only diagnostics; remote work itself runs +// in the Data Action runner and never holds the App/UI owner. +const TOOL_TIMEOUT: Duration = Duration::from_secs(45); +const ROOT_JS: &str = include_str!("../../../apps/pi-agent/dist/app.js"); +const ROOT_AGENT_JS: &str = include_str!("../../../apps/pi-agent/dist/agent.js"); +const ROOT_PAK: &[u8] = include_bytes!("../../../apps/pi-agent/dist/app.pak"); +const ROOT_DESCRIPTOR: &str = include_str!("../../../apps/pi-agent/agent-app.json"); +const ROOT_POCKET: &str = include_str!("../../../apps/pi-agent/pocket.json"); +const ROBINHOOD_JS: &str = include_str!("../../../apps/robinhood/dist/app.js"); +const ROBINHOOD_DATA_JS: &str = include_str!("../../../apps/robinhood/dist/data-action.js"); +const ROBINHOOD_PAK: &[u8] = include_bytes!("../../../apps/robinhood/dist/app.pak"); +const ROBINHOOD_DESCRIPTOR: &str = include_str!("../../../apps/robinhood/agent-app.json"); +const ROBINHOOD_POCKET: &str = include_str!("../../../apps/robinhood/pocket.json"); +const EXA_JS: &str = include_str!("../../../apps/exa/dist/app.js"); +const EXA_DATA_JS: &str = include_str!("../../../apps/exa/dist/data-action.js"); +const EXA_PAK: &[u8] = include_bytes!("../../../apps/exa/dist/app.pak"); +const EXA_DESCRIPTOR: &str = include_str!("../../../apps/exa/agent-app.json"); +const EXA_POCKET: &str = include_str!("../../../apps/exa/pocket.json"); + +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct AppDescriptor { + pub id: String, + pub version: String, + #[serde(default)] + pub data_version: u32, + #[serde(default)] + pub tools: Vec, + #[serde(default)] + pub tasks: Vec, + #[serde(default)] + pub schedules: Vec, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct AppSchedule { + pub id: String, + pub every_minutes: u64, + pub task: String, + #[serde(default)] + pub args: Value, +} + +#[derive(Clone)] +struct BuiltinApp { + descriptor: AppDescriptor, + descriptor_json: &'static str, + pocket_json: &'static str, + js: &'static str, + data_js: Option<&'static str>, + pak: &'static [u8], +} + +#[derive(Clone)] +pub struct AppCatalog { + apps: BTreeMap, + tool_owner: BTreeMap, +} + +impl AppCatalog { + pub fn builtin() -> Result { + let mut apps = BTreeMap::new(); + for (descriptor_json, pocket_json, js, data_js, pak) in [ + (ROOT_DESCRIPTOR, ROOT_POCKET, ROOT_JS, None, ROOT_PAK), + ( + ROBINHOOD_DESCRIPTOR, + ROBINHOOD_POCKET, + ROBINHOOD_JS, + Some(ROBINHOOD_DATA_JS), + ROBINHOOD_PAK, + ), + ( + EXA_DESCRIPTOR, + EXA_POCKET, + EXA_JS, + Some(EXA_DATA_JS), + EXA_PAK, + ), + ] { + let descriptor: AppDescriptor = + serde_json::from_str(descriptor_json).context("parse built-in agent-app.json")?; + if apps.contains_key(&descriptor.id) { + anyhow::bail!("duplicate built-in App id: {}", descriptor.id); + } + apps.insert( + descriptor.id.clone(), + BuiltinApp { + descriptor, + descriptor_json, + pocket_json, + js, + data_js, + pak, + }, + ); + } + let mut tool_owner = BTreeMap::new(); + for app in apps.values() { + for tool in &app.descriptor.tools { + let name = tool + .get("name") + .and_then(Value::as_str) + .ok_or_else(|| anyhow!("{} tool is missing name", app.descriptor.id))?; + if !name.starts_with(&format!("{}.", app.descriptor.id)) + && !(app.descriptor.id == EXA_APP_ID && name.starts_with("research.")) + { + anyhow::bail!("App {} owns non-namespaced tool {name}", app.descriptor.id); + } + if tool_owner + .insert(name.to_owned(), app.descriptor.id.clone()) + .is_some() + { + anyhow::bail!("duplicate App tool: {name}"); + } + } + } + Ok(Self { apps, tool_owner }) + } + + pub fn tool_definitions(&self) -> Vec { + self.apps + .values() + .flat_map(|app| app.descriptor.tools.clone()) + .collect() + } + + pub fn app_for_tool(&self, name: &str) -> Option<&str> { + self.tool_owner.get(name).map(String::as_str) + } + + pub fn descriptors(&self) -> impl Iterator { + self.apps.values().map(|app| &app.descriptor) + } + + fn app(&self, id: &str) -> Option<&BuiltinApp> { + self.apps.get(id) + } +} + +/// The native transport/security boundary used by App bundles. Implementations +/// own TLS, credentials and MCP sessions; Apps own operation selection, +/// normalization, SQLite and View behavior. +pub trait AppServiceHost: Send + Sync { + fn call( + &self, + app_id: &str, + service: &str, + operation: &str, + args: &Value, + ) -> Result; + + /// True while a native App worker owns network/TLS activity. + fn busy(&self) -> bool { + false + } +} + +/// One SQLite module instance per App. View and background Data Action guests +/// share this owner, so ESP32's `unix-none` VFS never has two independent +/// connections racing on the same file. Network waits never hold this mutex; +/// only bounded SQLite operations and transactions do. +type SharedDb = Arc>; +type AppRevision = Arc; + +const DATA_ACTION_QUEUE: usize = 8; +pub const DATA_ACTION_STACK_BYTES: usize = 128 * 1024; + +#[derive(Clone, Copy)] +enum DataActionKind { + Task, + Tool, +} + +struct DataActionRequest { + run_id: u64, + app_id: String, + kind: DataActionKind, + name: String, + args: Value, +} + +#[derive(Clone)] +struct DataAppConfig { + app_id: String, + source_path: PathBuf, + database: SharedDb, + revision: AppRevision, +} + +struct DataActionRuntime { + guest: Guest, + _database: SharedDb, + _revision: AppRevision, +} + +impl DataActionRuntime { + fn load(config: &DataAppConfig, services: Arc) -> Result { + let guest = Guest::new()?; + mount_shared_db(&guest, config.database.clone())?; + mount_services(&guest, config.app_id.clone(), services)?; + mount_data_lifecycle(&guest, config.revision.clone())?; + let source = std::fs::read_to_string(&config.source_path) + .with_context(|| format!("read {} Data Action", config.app_id))?; + guest.eval(&format!("{}-data-action", config.app_id), &source)?; + anyhow::ensure!( + guest.with(|ctx| ctx.globals().get::<_, Object>("PocketPiData").is_ok()), + "{} Data Action installed no PocketPiData", + config.app_id + ); + Ok(Self { + guest, + _database: config.database.clone(), + _revision: config.revision.clone(), + }) + } + + fn invoke(&self, request: &DataActionRequest) -> Result { + let method = match request.kind { + DataActionKind::Task => "invokeTask", + DataActionKind::Tool => "invokeTool", + }; + let line: String = self.guest.with(|ctx| { + let data: Object = ctx + .globals() + .get("PocketPiData") + .map_err(|error| anyhow!("PocketPiData missing: {error}"))?; + let function: Function = data + .get(method) + .map_err(|error| anyhow!("PocketPiData.{method} missing: {error}"))?; + function + .call::<_, String>((request.name.clone(), request.args.to_string())) + .catch(&ctx) + .map_err(|error| anyhow!("PocketPiData.{method}: {error}")) + })?; + let value: Value = serde_json::from_str(&line).context("parse Data Action result")?; + Ok(ToolResult { + text: value + .get("text") + .and_then(Value::as_str) + .unwrap_or(&line) + .to_owned(), + details: value.get("details").cloned().unwrap_or(Value::Null), + is_error: value + .get("isError") + .and_then(Value::as_bool) + .unwrap_or(false), + terminate: false, + }) + } +} + +struct AppDataRunner { + tx: mpsc::SyncSender, + next_run_id: AtomicU32, + busy: Arc, +} + +impl AppDataRunner { + fn start(configs: Vec, services: Arc) -> Result { + let (tx, rx) = mpsc::sync_channel::(DATA_ACTION_QUEUE); + let busy = Arc::new(AtomicBool::new(false)); + let worker_busy = busy.clone(); + std::thread::Builder::new() + .name("app-data".to_owned()) + .stack_size(DATA_ACTION_STACK_BYTES) + .spawn(move || { + let configs = configs + .into_iter() + .map(|config| (config.app_id.clone(), config)) + .collect::>(); + let mut runtimes = BTreeMap::::new(); + while let Ok(request) = rx.recv() { + worker_busy.store(true, Ordering::Release); + let result = (|| -> Result { + if !runtimes.contains_key(&request.app_id) { + let config = configs + .get(&request.app_id) + .ok_or_else(|| anyhow!("{} has no Data Action", request.app_id))?; + runtimes.insert( + request.app_id.clone(), + DataActionRuntime::load(config, services.clone())?, + ); + } + runtimes + .get(&request.app_id) + .expect("Data Action runtime inserted") + .invoke(&request) + })(); + match result { + Ok(result) if result.is_error => log::warn!( + "App Data Action run={} {}.{} failed: {}", + request.run_id, + request.app_id, + request.name, + result.text + ), + Ok(result) => log::info!( + "App Data Action run={} {}.{} completed: {}", + request.run_id, + request.app_id, + request.name, + result.text + ), + Err(error) => log::error!( + "App Data Action run={} {}.{} crashed: {error:#}", + request.run_id, + request.app_id, + request.name + ), + } + worker_busy.store(false, Ordering::Release); + } + }) + .context("start App Data Action runner")?; + Ok(Self { + tx, + next_run_id: AtomicU32::new(1), + busy, + }) + } + + fn enqueue(&self, app_id: &str, kind: DataActionKind, name: &str, args: Value) -> Result { + let run_id = u64::from(self.next_run_id.fetch_add(1, Ordering::Relaxed)); + self.tx + .try_send(DataActionRequest { + run_id, + app_id: app_id.to_owned(), + kind, + name: name.to_owned(), + args, + }) + .map_err(|error| anyhow!("queue App Data Action: {error}"))?; + Ok(run_id) + } + + fn busy(&self) -> bool { + self.busy.load(Ordering::Acquire) + } +} + +pub struct AppRuntime { + descriptor: AppDescriptor, + guest: Guest, + surface: UiSurface, + _fs: Rc>, + _db: SharedDb, + revision: AppRevision, + last_seen_revision: Cell, + #[cfg(test)] + projection_refreshes: Cell, +} + +impl AppRuntime { + fn load( + app: &BuiltinApp, + release_dir: &Path, + fs_root: &Path, + tmp_root: &Path, + db: SharedDb, + revision: AppRevision, + services: Arc, + ) -> Result { + let descriptor: AppDescriptor = serde_json::from_slice( + &std::fs::read(release_dir.join("agent-app.json")).context("read agent-app.json")?, + ) + .context("parse installed agent-app.json")?; + anyhow::ensure!( + descriptor.id == app.descriptor.id, + "installed App id mismatch" + ); + let manifest: Value = serde_json::from_slice( + &std::fs::read(release_dir.join("pocket.json")).context("read pocket.json")?, + ) + .context("parse installed pocket.json")?; + anyhow::ensure!( + manifest.get("pocket").and_then(Value::as_u64) == Some(2), + "App requires pocket.json v2" + ); + anyhow::ensure!( + manifest.get("name").and_then(Value::as_str) == Some(app.descriptor.id.as_str()), + "pocket.json name does not match App id" + ); + for capability in manifest + .pointer("/engine/capabilities/requires") + .and_then(Value::as_array) + .into_iter() + .flatten() + .filter_map(Value::as_str) + { + anyhow::ensure!( + matches!(capability, "data.fs" | "data.sqlite"), + "unsupported App capability: {capability}" + ); + } + + std::fs::create_dir_all(fs_root)?; + let guest = Guest::new()?; + let surface = UiSurface::new(VIEWPORT); + let pak = std::fs::read(release_dir.join("app.pak")).context("read App pak")?; + surface.feed_pak(&pak); + surface.mount(&guest)?; + + let fs = Rc::new(RefCell::new(FsModule::with_quota( + FsStorage::Dir { + root: fs_root.to_owned(), + tmp: tmp_root.to_owned(), + }, + 2 * 1024 * 1024, + ))); + pocket_fs::mount(&guest, fs.clone())?; + mount_shared_db(&guest, db.clone())?; + + mount_services(&guest, descriptor.id.clone(), services)?; + let source = + std::fs::read_to_string(release_dir.join("app.js")).context("read App bundle")?; + eval_bundle(&guest, &descriptor.id, &source)?; + anyhow::ensure!( + guest.has_frame(), + "{} bundle installed no frame()", + descriptor.id + ); + + let last_seen_revision = revision.load(Ordering::Acquire); + Ok(Self { + descriptor, + guest, + surface, + _fs: fs, + _db: db, + revision, + last_seen_revision: Cell::new(last_seen_revision), + #[cfg(test)] + projection_refreshes: Cell::new(0), + }) + } + + pub fn id(&self) -> &str { + &self.descriptor.id + } + + pub fn frame(&self) -> Result<()> { + self.advance(true) + } + + fn projection_is_stale(&self) -> bool { + self.revision.load(Ordering::Acquire) != self.last_seen_revision.get() + } + + fn advance(&self, render_surface: bool) -> Result<()> { + // A normal frame never queries SQLite. It only compares one in-memory + // App revision and lets the View refresh a bounded projection when a + // committed Data Action made that revision stale. + self.call_method("tick", ()).map(|_: String| ())?; + if render_surface { + let current_revision = self.revision.load(Ordering::Acquire); + if current_revision != self.last_seen_revision.get() { + // The counter is sampled once at the foreground frame + // boundary. Any number of commits since the previous frame is + // therefore coalesced into one bounded projection refresh. + // A commit racing this query remains visible as a newer + // revision and is picked up on the following frame. + self.call_method::<_, String>( + "dataChanged", + (json!([{"topic":"app","revision":current_revision}]).to_string(),), + )?; + self.last_seen_revision.set(current_revision); + #[cfg(test)] + self.projection_refreshes + .set(self.projection_refreshes.get().saturating_add(1)); + } + } + if render_surface { + self.guest.frame(0)?; + self.surface.tick(); + } + Ok(()) + } + + pub fn update(&self, projection: &Value) -> Result<()> { + self.call_method("update", (projection.to_string(),)) + .map(|_: String| ()) + } + + pub fn tap(&self, x: u16, y: u16) -> Result { + let line: String = self.call_method("tap", (x as i32, y as i32))?; + if line.is_empty() { + return Ok(Value::Null); + } + serde_json::from_str(&line).context("parse App tap action") + } + + pub fn invoke_tool(&self, name: &str, args_json: &str) -> Result { + let line: String = + self.call_method("invokeTool", (name.to_owned(), args_json.to_owned()))?; + self.tool_result(&line) + } + + pub fn invoke_task(&self, name: &str, args: &Value) -> Result { + let line: String = self.call_method("invokeTask", (name.to_owned(), args.to_string()))?; + self.tool_result(&line) + } + + pub fn with_ui(&self, f: impl FnOnce(&mut pocketjs_core::Ui) -> R) -> R { + self.surface.with_ui(f) + } + + fn tool_result(&self, line: &str) -> Result { + let value: Value = serde_json::from_str(line).context("parse App result")?; + Ok(ToolResult { + text: value + .get("text") + .and_then(Value::as_str) + .unwrap_or(line) + .to_owned(), + details: value.get("details").cloned().unwrap_or(Value::Null), + is_error: value + .get("isError") + .and_then(Value::as_bool) + .unwrap_or(false), + terminate: false, + }) + } + + fn call_method(&self, name: &str, args: A) -> Result + where + A: for<'js> pocket_mod::qjs::function::IntoArgs<'js>, + R: for<'js> pocket_mod::qjs::FromJs<'js>, + { + self.guest.with(|ctx| { + let app: Object = ctx + .globals() + .get("PocketPiApp") + .map_err(|error| anyhow!("PocketPiApp missing: {error}"))?; + let function: Function = app + .get(name) + .map_err(|error| anyhow!("PocketPiApp.{name} missing: {error}"))?; + function + .call::<_, R>(args) + .catch(&ctx) + .map_err(|error| anyhow!("PocketPiApp.{name}: {error}")) + }) + } +} + +#[cfg(not(target_os = "espidf"))] +fn eval_bundle(guest: &Guest, label: &str, source: &str) -> Result<()> { + guest.eval(label, source) +} + +#[cfg(target_os = "espidf")] +fn eval_bundle(guest: &Guest, label: &str, source: &str) -> Result<()> { + guest.eval(label, source) +} + +fn mount_shared_db(guest: &Guest, db: SharedDb) -> Result<()> { + guest.mount("db", |ctx, ns| { + let module = db.clone(); + ns.set( + "open", + Function::new(ctx.clone(), move |name: String| -> i32 { + module.lock().map_or(-1, |mut db| db.open(&name)) + })?, + )?; + let module = db.clone(); + ns.set( + "close", + Function::new(ctx.clone(), move |handle: i32| { + if let Ok(mut db) = module.lock() { + db.close(handle); + } + })?, + )?; + let module = db.clone(); + ns.set( + "exec", + Function::new(ctx.clone(), move |handle: i32, sql: String| -> i32 { + module.lock().map_or(1, |mut db| db.exec(handle, &sql)) + })?, + )?; + let module = db.clone(); + ns.set( + "query", + Function::new( + ctx.clone(), + move |handle: i32, sql: String, args: String| -> String { + module.lock().map_or_else( + |_| json!({"error":"App database owner is unavailable"}).to_string(), + |mut db| db.query(handle, &sql, &args), + ) + }, + )?, + )?; + let module = db; + ns.set( + "lastError", + Function::new(ctx.clone(), move |handle: i32| -> String { + module.lock().map_or_else( + |_| "App database owner is unavailable".to_owned(), + |db| db.last_error(handle), + ) + })?, + )?; + Ok(()) + }) +} + +fn mount_services(guest: &Guest, app_id: String, services: Arc) -> Result<()> { + guest.mount("services", |ctx, ns| { + ns.set( + "call", + Function::new( + ctx.clone(), + move |service: String, operation: String, args_json: String| -> String { + let args = serde_json::from_str(&args_json).unwrap_or(Value::Null); + match services.call(&app_id, &service, &operation, &args) { + Ok(value) => json!({"ok":true,"value":value}).to_string(), + Err(error) => json!({"ok":false,"error":error}).to_string(), + } + }, + )?, + )?; + Ok(()) + }) +} + +fn mount_data_lifecycle(guest: &Guest, revision: AppRevision) -> Result<()> { + guest.mount("app", |ctx, ns| { + ns.set( + "commit", + Function::new(ctx.clone(), move || -> f64 { + // Called only after a successful App-owned SQLite COMMIT. + // Release pairs with the foreground View's Acquire load. + revision.fetch_add(1, Ordering::Release).saturating_add(1) as f64 + })?, + )?; + Ok(()) + }) +} + +pub struct AppSupervisor { + workspace: PathBuf, + catalog: AppCatalog, + services: Arc, + data_runner: AppDataRunner, + /// The Pi Agent System App is booted once and remains resident for the + /// entire supervisor lifetime. Foreground navigation never replaces it. + system: AppRuntime, + agent: Option, + /// The small v1 catalog is loaded once at supervisor startup. Background + /// Data Actions do not advance these Views, and navigation only selects + /// an already resident surface. + runtimes: BTreeMap, + active_app: Option, + schedules: AppScheduleStore, +} + +impl AppSupervisor { + pub fn new(workspace: impl Into, services: Arc) -> Result { + let workspace = workspace.into(); + let catalog = AppCatalog::builtin()?; + seed_builtin_releases(&workspace, &catalog)?; + let schedules = AppScheduleStore::load(&workspace, &catalog)?; + let mut databases = BTreeMap::new(); + let mut revisions = BTreeMap::new(); + for descriptor in catalog.descriptors() { + let (_, _, db_root, _) = paths(&workspace, &descriptor.id); + std::fs::create_dir_all(&db_root)?; + reset_development_database(&workspace, descriptor, &db_root)?; + databases.insert( + descriptor.id.clone(), + Arc::new(Mutex::new(DbModule::new(DbStorage::Dir(db_root)))), + ); + revisions.insert(descriptor.id.clone(), Arc::new(AtomicU32::new(0))); + } + let data_configs = catalog + .descriptors() + .filter_map(|descriptor| { + let (release_dir, _, _, _) = paths(&workspace, &descriptor.id); + let source_path = release_dir.join("data-action.js"); + source_path.is_file().then(|| DataAppConfig { + app_id: descriptor.id.clone(), + source_path, + database: databases + .get(&descriptor.id) + .expect("database created for descriptor") + .clone(), + revision: revisions + .get(&descriptor.id) + .expect("revision created for descriptor") + .clone(), + }) + }) + .collect(); + let data_runner = AppDataRunner::start(data_configs, services.clone())?; + log::info!("preloading View Runtime: {ROOT_APP_ID}"); + let system = load_runtime( + &workspace, + &catalog, + &databases, + &revisions, + ROOT_APP_ID, + services.clone(), + )?; + log::info!("preloaded View Runtime: {ROOT_APP_ID}"); + // v1 has a small fixed App catalog. Load every ordinary View once at + // boot so foreground navigation is only a surface switch. Background + // Data Actions remain separate and are still loaded on demand. + let ordinary_app_ids = catalog + .descriptors() + .filter(|descriptor| descriptor.id != ROOT_APP_ID) + .map(|descriptor| descriptor.id.clone()) + .collect::>(); + let mut runtimes = BTreeMap::new(); + for app_id in ordinary_app_ids { + log::info!("preloading View Runtime: {app_id}"); + let runtime = load_runtime( + &workspace, + &catalog, + &databases, + &revisions, + &app_id, + services.clone(), + )?; + log::info!("preloaded View Runtime: {app_id}"); + runtimes.insert(app_id, runtime); + } + Ok(Self { + workspace, + catalog, + services, + data_runner, + system, + agent: None, + runtimes, + active_app: None, + schedules, + }) + } + + pub fn catalog(&self) -> &AppCatalog { + &self.catalog + } + + pub fn services_busy(&self) -> bool { + self.services.busy() || self.data_runner.busy() + } + + pub fn active_id(&self) -> &str { + self.active_app.as_deref().unwrap_or(ROOT_APP_ID) + } + + pub fn open(&mut self, app_id: &str) -> Result<()> { + if self.active_id() == app_id { + return Ok(()); + } + if app_id == ROOT_APP_ID { + self.active_app = None; + return Ok(()); + } + + anyhow::ensure!(self.runtimes.contains_key(app_id), "unknown App: {app_id}"); + self.active_app = Some(app_id.to_owned()); + Ok(()) + } + + pub fn boot_agent( + &mut self, + config_json: &str, + backend: Arc, + tools: Arc, + ) -> Result<()> { + anyhow::ensure!( + self.agent.is_none(), + "Pi Agent System App is already booted" + ); + let release = paths(&self.workspace, ROOT_APP_ID).0; + let agent_source = std::fs::read_to_string(release.join("agent.js")) + .context("read Pi Agent System App loop bundle")?; + self.agent = Some( + GuestAgent::mount_source( + &self.system.guest, + config_json, + backend, + tools, + &agent_source, + Arc::new(|_| {}), + ) + .map_err(|error| anyhow!(error))?, + ); + Ok(()) + } + + pub fn prompt_agent(&self, text: &str) -> Result<()> { + let agent = self + .agent + .as_ref() + .ok_or_else(|| anyhow!("Pi Agent System App is not booted"))?; + agent + .prompt(&self.system.guest, text) + .map_err(|error| anyhow!(error)) + } + + pub fn abort_agent(&self) -> Result<()> { + let agent = self + .agent + .as_ref() + .ok_or_else(|| anyhow!("Pi Agent System App is not booted"))?; + agent + .abort(&self.system.guest) + .map_err(|error| anyhow!(error)) + } + + /// Advance the resident System App and cheap View bookkeeping. Only the + /// selected surface is rendered; Data Actions progress on their own runner. + pub fn frame(&self) -> Result> { + self.frame_render(true) + } + + /// Advance the Agent every host tick, but only ask the selected PocketJS + /// View to produce a new DrawList when the host knows it is dirty. + pub fn frame_render(&self, render_selected: bool) -> Result> { + let events = match &self.agent { + Some(agent) => agent + .tick(&self.system.guest) + .map_err(|error| anyhow!(error))?, + None => Vec::new(), + }; + self.system + .advance(render_selected && self.active_app.is_none())?; + for (app_id, runtime) in &self.runtimes { + runtime + .advance(render_selected && self.active_app.as_deref() == Some(app_id.as_str()))?; + } + Ok(events) + } + + pub fn update_root(&self, projection: &Value) -> Result<()> { + self.system.update(projection) + } + + pub fn tap(&self, x: u16, y: u16) -> Result { + self.active().tap(x, y) + } + + pub fn with_ui(&self, f: impl FnOnce(&mut pocketjs_core::Ui) -> R) -> R { + self.active().with_ui(f) + } + + /// A single atomic comparison lets the host wake the active View after a + /// background commit. It never queries SQLite and closed Apps stay idle. + pub fn active_projection_is_stale(&self) -> bool { + self.active().projection_is_stale() + } + + pub fn invoke_tool(&mut self, name: &str, args_json: &str) -> ToolResult { + let Some(app_id) = self.catalog.app_for_tool(name).map(str::to_owned) else { + return tool_error(format!("unknown App tool: {name}")); + }; + if name.ends_with(".storage_status") { + return self + .with_runtime(&app_id, |runtime| runtime.invoke_tool(name, args_json)) + .unwrap_or_else(|error| tool_error(format!("{name}: {error:#}"))); + } + let args = serde_json::from_str(args_json).unwrap_or(Value::Null); + match self + .data_runner + .enqueue(&app_id, DataActionKind::Tool, name, args) + { + Ok(run_id) => ToolResult { + text: format!("Queued {name} as App Data Action {run_id}"), + details: json!({"status":"queued","runId":run_id,"app":app_id}), + is_error: false, + terminate: false, + }, + Err(error) => tool_error(format!("{name}: {error:#}")), + } + } + + /// Runs a task requested by the currently visible App. The host calls this + /// after presenting the App's immediate pressed/loading state so slow + /// native services never hide touch feedback. + pub fn invoke_active_task(&mut self, name: &str, args: &Value) -> ToolResult { + let app_id = self.active_id().to_owned(); + match self + .data_runner + .enqueue(&app_id, DataActionKind::Task, name, args.clone()) + { + Ok(run_id) => ToolResult { + text: format!("Queued {app_id}.{name} as App Data Action {run_id}"), + details: json!({"status":"queued","runId":run_id,"app":app_id}), + is_error: false, + terminate: false, + }, + Err(error) => tool_error(format!("{app_id}.{name}: {error:#}")), + } + } + + pub fn poll_due_tasks(&mut self) -> Vec<(String, ToolResult)> { + let mut results = Vec::new(); + while let Some(due) = self.schedules.claim_due() { + let label = format!("{}.{}", due.app_id, due.task); + let result = match self.data_runner.enqueue( + &due.app_id, + DataActionKind::Task, + &due.task, + due.args.clone(), + ) { + Ok(run_id) => ToolResult { + text: format!("Queued {label} as App Data Action {run_id}"), + details: json!({"status":"queued","runId":run_id}), + is_error: false, + terminate: false, + }, + Err(error) => tool_error(format!("{label}: {error:#}")), + }; + self.schedules.finish(&due, !result.is_error); + results.push((label, result)); + } + results + } + + fn with_runtime( + &mut self, + app_id: &str, + f: impl FnOnce(&AppRuntime) -> Result, + ) -> Result { + if app_id == ROOT_APP_ID { + let result = f(&self.system)?; + self.system.advance(self.active_app.is_none())?; + return Ok(result); + } + let runtime = self + .runtimes + .get(app_id) + .ok_or_else(|| anyhow!("unknown App: {app_id}"))?; + let result = f(runtime)?; + runtime.advance(self.active_app.as_deref() == Some(app_id))?; + Ok(result) + } + + fn active(&self) -> &AppRuntime { + self.active_app + .as_deref() + .and_then(|app_id| self.runtimes.get(app_id)) + .unwrap_or(&self.system) + } +} + +fn load_runtime( + workspace: &Path, + catalog: &AppCatalog, + databases: &BTreeMap, + revisions: &BTreeMap, + app_id: &str, + services: Arc, +) -> Result { + let app = catalog + .app(app_id) + .ok_or_else(|| anyhow!("unknown App: {app_id}"))?; + let (release_dir, fs_root, db_root, tmp_root) = paths(workspace, app_id); + let db = databases + .get(app_id) + .cloned() + .ok_or_else(|| anyhow!("App {app_id} has no database owner"))?; + let revision = revisions + .get(app_id) + .cloned() + .ok_or_else(|| anyhow!("App {app_id} has no revision owner"))?; + let _ = db_root; + AppRuntime::load( + app, + &release_dir, + &fs_root, + &tmp_root, + db, + revision, + services, + ) + .with_context(|| format!("load App {app_id}")) +} + +fn paths(workspace: &Path, app_id: &str) -> (PathBuf, PathBuf, PathBuf, PathBuf) { + if app_id == ROOT_APP_ID { + ( + workspace.join("data/view/releases").join(BUILTIN_RELEASE), + workspace.to_owned(), + workspace.join("data"), + workspace.join(".system/tmp/pi-agent"), + ) + } else { + let root = workspace.join("apps").join(app_id); + ( + root.join("releases").join(BUILTIN_RELEASE), + root.join("data"), + root.join("data"), + root.join("tmp"), + ) + } +} + +fn reset_development_database( + workspace: &Path, + descriptor: &AppDescriptor, + db_root: &Path, +) -> Result<()> { + if descriptor.data_version == 0 { + return Ok(()); + } + let marker = workspace + .join("apps") + .join(&descriptor.id) + .join(".data-version"); + let expected = descriptor.data_version.to_string(); + if std::fs::read_to_string(&marker).is_ok_and(|value| value == expected) { + return Ok(()); + } + let database = db_root.join(format!("{}.sqlite", descriptor.id)); + for path in [ + database.clone(), + database.with_extension("sqlite-wal"), + database.with_extension("sqlite-shm"), + database.with_extension("sqlite-journal"), + ] { + match std::fs::remove_file(&path) { + Ok(()) => {} + Err(error) if error.kind() == std::io::ErrorKind::NotFound => {} + Err(error) => return Err(error).with_context(|| format!("reset {}", path.display())), + } + } + atomic_write(&marker, expected.as_bytes()) +} + +fn seed_builtin_releases(workspace: &Path, catalog: &AppCatalog) -> Result<()> { + for app in catalog.apps.values() { + let (release_dir, fs_root, db_root, tmp_root) = paths(workspace, &app.descriptor.id); + std::fs::create_dir_all(&release_dir)?; + std::fs::create_dir_all(&fs_root)?; + std::fs::create_dir_all(&db_root)?; + std::fs::create_dir_all(&tmp_root)?; + atomic_write(&release_dir.join("app.js"), app.js.as_bytes())?; + if let Some(data_js) = app.data_js { + atomic_write(&release_dir.join("data-action.js"), data_js.as_bytes())?; + } + if app.descriptor.id == ROOT_APP_ID { + atomic_write(&release_dir.join("agent.js"), ROOT_AGENT_JS.as_bytes())?; + } + atomic_write(&release_dir.join("app.pak"), app.pak)?; + atomic_write( + &release_dir.join("agent-app.json"), + app.descriptor_json.as_bytes(), + )?; + atomic_write(&release_dir.join("pocket.json"), app.pocket_json.as_bytes())?; + atomic_write( + &release_dir.join("plan.json"), + &serde_json::to_vec_pretty(&json!({ + "runtime":"pocket-pi-agentos", + "pocketjsRevision":"afc8d4e8e877dac7f9b0c01b5c0d667642009fc0", + "app":app.descriptor.id, + "modules":["ui","data.fs","data.sqlite"] + }))?, + )?; + let current = if app.descriptor.id == ROOT_APP_ID { + workspace.join("data/view/current") + } else { + workspace + .join("apps") + .join(&app.descriptor.id) + .join("current") + }; + atomic_write(¤t, BUILTIN_RELEASE.as_bytes())?; + } + Ok(()) +} + +fn atomic_write(path: &Path, bytes: &[u8]) -> Result<()> { + if std::fs::read(path).ok().as_deref() == Some(bytes) { + return Ok(()); + } + let parent = path.parent().ok_or_else(|| anyhow!("path has no parent"))?; + std::fs::create_dir_all(parent)?; + let temporary = parent.join(format!( + ".{}.tmp", + path.file_name() + .and_then(|name| name.to_str()) + .unwrap_or("release") + )); + { + use std::io::Write as _; + let mut file = std::fs::File::create(&temporary)?; + file.write_all(bytes)?; + file.sync_all()?; + } + std::fs::rename(&temporary, path)?; + Ok(()) +} + +pub struct AppToolRequest { + pub name: String, + pub args_json: String, + response: mpsc::Sender, +} + +pub struct RoutedToolHost { + native: Arc, + catalog: AppCatalog, + app_tx: mpsc::Sender, +} + +impl RoutedToolHost { + pub fn new( + native: Arc, + catalog: AppCatalog, + ) -> (Self, mpsc::Receiver) { + let (app_tx, app_rx) = mpsc::channel(); + ( + Self { + native, + catalog, + app_tx, + }, + app_rx, + ) + } +} + +impl ToolHost for RoutedToolHost { + fn definitions(&self) -> Vec { + let mut definitions = self.native.definitions(); + definitions.extend(self.catalog.tool_definitions()); + definitions + } + + fn execute(&self, call_id: &str, name: &str, args_json: &str) -> ToolResult { + if self.catalog.app_for_tool(name).is_none() { + return self.native.execute(call_id, name, args_json); + } + let (response, response_rx) = mpsc::channel(); + if self + .app_tx + .send(AppToolRequest { + name: name.to_owned(), + args_json: args_json.to_owned(), + response, + }) + .is_err() + { + return tool_error("App Supervisor is unavailable"); + } + response_rx + .recv_timeout(TOOL_TIMEOUT) + .unwrap_or_else(|_| tool_error(format!("App Tool timed out after {TOOL_TIMEOUT:?}"))) + } +} + +impl AppToolRequest { + pub fn handle(self, supervisor: &mut AppSupervisor) { + let result = supervisor.invoke_tool(&self.name, &self.args_json); + let _ = self.response.send(result); + } +} + +fn tool_error(text: impl Into) -> ToolResult { + ToolResult { + text: text.into(), + details: Value::Null, + is_error: true, + terminate: false, + } +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +struct StoredSchedule { + app_id: String, + schedule_id: String, + task: String, + args: Value, + every_seconds: u64, + next_run_at: u64, + last_ok: Option, +} + +struct DueTask { + app_id: String, + schedule_id: String, + task: String, + args: Value, + scheduled_at: u64, +} + +struct AppScheduleStore { + paths: BTreeMap, + schedules: Vec, +} + +impl AppScheduleStore { + fn load(workspace: &Path, catalog: &AppCatalog) -> Result { + // AppTask declarations travel with the App release, while their + // mutable scheduler cursor belongs to that App's private data root. + // The former central file is read once only to migrate existing + // installs; it is never written again. + let legacy_path = workspace.join(".system/schedules.json"); + let mut legacy: Vec = std::fs::read(&legacy_path) + .ok() + .and_then(|bytes| serde_json::from_slice(&bytes).ok()) + .unwrap_or_default(); + let now = unix_seconds(); + let mut paths = BTreeMap::new(); + let mut schedules = Vec::new(); + for app in catalog.descriptors() { + let path = if app.id == ROOT_APP_ID { + workspace.join("data/.system/schedules.json") + } else { + workspace + .join("apps") + .join(&app.id) + .join("data/.system/schedules.json") + }; + let mut prior: Vec = std::fs::read(&path) + .ok() + .and_then(|bytes| serde_json::from_slice(&bytes).ok()) + .unwrap_or_default(); + paths.insert(app.id.clone(), path); + for declaration in &app.schedules { + anyhow::ensure!( + app.tasks.iter().any(|task| task == &declaration.task), + "{}.{} schedule references missing task {}", + app.id, + declaration.id, + declaration.task + ); + let every_seconds = declaration.every_minutes.saturating_mul(60).max(60); + let existing = prior + .iter_mut() + .chain(legacy.iter_mut()) + .find(|item| item.app_id == app.id && item.schedule_id == declaration.id); + schedules.push(match existing { + Some(item) + if item.task == declaration.task && item.every_seconds == every_seconds => + { + item.clone() + } + _ => StoredSchedule { + app_id: app.id.clone(), + schedule_id: declaration.id.clone(), + task: declaration.task.clone(), + args: declaration.args.clone(), + every_seconds, + next_run_at: now.saturating_add(every_seconds), + last_ok: None, + }, + }); + } + } + let store = Self { paths, schedules }; + store.persist()?; + if legacy_path.exists() { + std::fs::remove_file(&legacy_path) + .with_context(|| format!("remove migrated {}", legacy_path.display()))?; + } + Ok(store) + } + + fn claim_due(&mut self) -> Option { + let now = unix_seconds(); + let item = self + .schedules + .iter_mut() + .filter(|item| item.next_run_at <= now) + .min_by_key(|item| item.next_run_at)?; + let scheduled_at = item.next_run_at; + while item.next_run_at <= now { + item.next_run_at = item.next_run_at.saturating_add(item.every_seconds); + } + let due = DueTask { + app_id: item.app_id.clone(), + schedule_id: item.schedule_id.clone(), + task: item.task.clone(), + args: item.args.clone(), + scheduled_at, + }; + let _ = self.persist(); + Some(due) + } + + fn finish(&mut self, due: &DueTask, ok: bool) { + if let Some(item) = self + .schedules + .iter_mut() + .find(|item| item.app_id == due.app_id && item.schedule_id == due.schedule_id) + { + item.last_ok = Some(ok); + } + log::info!( + "AppTask {}.{} scheduled_at={} ok={ok}", + due.app_id, + due.task, + due.scheduled_at + ); + let _ = self.persist(); + } + + fn persist(&self) -> Result<()> { + for (app_id, path) in &self.paths { + let schedules = self + .schedules + .iter() + .filter(|schedule| &schedule.app_id == app_id) + .collect::>(); + atomic_write(path, &serde_json::to_vec(&schedules)?)?; + } + Ok(()) + } +} + +fn unix_seconds() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .map(|duration| duration.as_secs()) + .unwrap_or(0) +} + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::atomic::{AtomicUsize, Ordering}; + use std::time::Duration; + + struct NoServices; + + impl AppServiceHost for NoServices { + fn call( + &self, + _app_id: &str, + _service: &str, + _operation: &str, + _args: &Value, + ) -> Result { + Err("not used by Pi Agent UI tests".into()) + } + } + + struct BackgroundBackend; + + impl ModelBackend for BackgroundBackend { + fn complete( + &self, + _request_json: &str, + on_delta: &mut dyn FnMut(&str), + ) -> Result { + std::thread::sleep(Duration::from_millis(20)); + on_delta("background-ok"); + Ok(r#"{"text":"background-ok"}"#.to_owned()) + } + } + + struct NoTools; + + impl ToolHost for NoTools { + fn definitions(&self) -> Vec { + Vec::new() + } + + fn execute(&self, _call_id: &str, name: &str, _args_json: &str) -> ToolResult { + tool_error(format!("unexpected tool: {name}")) + } + } + + struct ToolCallingBackend(AtomicUsize); + + impl ModelBackend for ToolCallingBackend { + fn complete( + &self, + _request_json: &str, + on_delta: &mut dyn FnMut(&str), + ) -> Result { + if self.0.fetch_add(1, Ordering::SeqCst) == 0 { + Ok(serde_json::json!({ + "toolCall":{ + "id":"call_portfolio", + "name":"robinhood.get_portfolio", + "arguments":{"account_number":"SIM-001"} + } + }) + .to_string()) + } else { + on_delta("tool-ok"); + Ok(r#"{"text":"tool-ok"}"#.to_owned()) + } + } + } + + struct RobinhoodServices; + + impl AppServiceHost for RobinhoodServices { + fn call( + &self, + app_id: &str, + service: &str, + operation: &str, + _args: &Value, + ) -> Result { + if (app_id, service, operation) == ("robinhood", "mcp.client", "callTool") { + Ok(json!({"equity":"100.00","day_pnl":"1.00","week_pnl":"2.00"})) + } else { + Err("unexpected service call".to_owned()) + } + } + } + + #[test] + fn catalog_exposes_namespaced_app_tools() { + let catalog = AppCatalog::builtin().unwrap(); + let names = catalog + .tool_definitions() + .into_iter() + .filter_map(|tool| tool["name"].as_str().map(str::to_owned)) + .collect::>(); + assert!(names.contains(&"robinhood.get_portfolio".to_owned())); + assert!(names.contains(&"research.search".to_owned())); + } + + #[test] + fn data_version_resets_only_that_app_database_once() { + let temp = tempfile::tempdir().unwrap(); + let db_root = temp.path().join("apps/exa/data"); + std::fs::create_dir_all(&db_root).unwrap(); + let database = db_root.join("exa.sqlite"); + std::fs::write(&database, "old-schema").unwrap(); + let mut descriptor = AppDescriptor { + id: EXA_APP_ID.to_owned(), + version: "1.0.0".to_owned(), + data_version: 3, + tools: Vec::new(), + tasks: Vec::new(), + schedules: Vec::new(), + }; + + reset_development_database(temp.path(), &descriptor, &db_root).unwrap(); + assert!(!database.exists()); + std::fs::write(&database, "current-schema").unwrap(); + reset_development_database(temp.path(), &descriptor, &db_root).unwrap(); + assert_eq!( + std::fs::read_to_string(&database).unwrap(), + "current-schema" + ); + + descriptor.data_version = 4; + reset_development_database(temp.path(), &descriptor, &db_root).unwrap(); + assert!(!database.exists()); + } + + #[test] + fn app_task_schedule_state_is_owned_by_each_app_data_root() { + let temp = tempfile::tempdir().unwrap(); + let legacy = temp.path().join(".system/schedules.json"); + std::fs::create_dir_all(legacy.parent().unwrap()).unwrap(); + std::fs::write( + &legacy, + serde_json::to_vec(&vec![StoredSchedule { + app_id: ROBINHOOD_APP_ID.to_owned(), + schedule_id: "portfolio-refresh".to_owned(), + task: "refreshPortfolio".to_owned(), + args: json!({}), + every_seconds: 300, + next_run_at: unix_seconds().saturating_add(123), + last_ok: Some(true), + }]) + .unwrap(), + ) + .unwrap(); + + let _supervisor = AppSupervisor::new(temp.path(), Arc::new(NoServices)).unwrap(); + let app_state = temp + .path() + .join("apps/robinhood/data/.system/schedules.json"); + let stored: Vec = + serde_json::from_slice(&std::fs::read(app_state).unwrap()).unwrap(); + + assert_eq!(stored.len(), 1); + assert_eq!(stored[0].app_id, ROBINHOOD_APP_ID); + assert_eq!(stored[0].last_ok, Some(true)); + assert!(!legacy.exists()); + } + + #[test] + fn root_view_keeps_legacy_tabs_and_adds_app_navigation() { + let temp = tempfile::tempdir().unwrap(); + std::fs::write(temp.path().join("agent-note.txt"), "top-level workspace").unwrap(); + let supervisor = AppSupervisor::new(temp.path(), Arc::new(NoServices)).unwrap(); + supervisor + .update_root(&json!({ + "agent":"IDLE", + "model":"test", + "messages":[{"role":"assistant","text":"ready"}], + })) + .unwrap(); + + // Files remains a Pi Agent screen and its PocketJS FS is rooted at + // the complete workspace, not only /workspace/data. + assert_eq!(supervisor.tap(270, 1220).unwrap(), Value::Null); + supervisor.frame().unwrap(); + + // Apps is the only new bottom tab; its cards navigate through the + // native App Supervisor instead of embedding another App's View. + assert_eq!(supervisor.tap(450, 1220).unwrap(), Value::Null); + let action = supervisor.tap(300, 220).unwrap(); + assert_eq!(action["type"], "navigate"); + assert_eq!(action["app"], ROBINHOOD_APP_ID); + + // Settings stays in the Root App, while the command is returned to + // the host that owns Wi-Fi credentials and drivers. + assert_eq!(supervisor.tap(630, 1220).unwrap(), Value::Null); + let action = supervisor.tap(560, 170).unwrap(); + assert_eq!(action["type"], "settings"); + assert_eq!(action["command"], "scan"); + } + + #[test] + fn pi_agent_system_app_survives_foreground_app_navigation() { + let temp = tempfile::tempdir().unwrap(); + let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(NoServices)).unwrap(); + assert_eq!(supervisor.runtimes.len(), 2, "all ordinary Views preload"); + let system_guest = &supervisor.system.guest as *const Guest as usize; + let exa_guest = &supervisor + .runtimes + .get(EXA_APP_ID) + .expect("Exa runtime preloaded") + .guest as *const Guest as usize; + supervisor + .boot_agent( + r#"{"model":"offline"}"#, + Arc::new(BackgroundBackend), + Arc::new(NoTools), + ) + .unwrap(); + supervisor.prompt_agent("keep working").unwrap(); + supervisor.open(ROBINHOOD_APP_ID).unwrap(); + + let mut saw_delta = false; + let mut finished = false; + for _ in 0..100 { + for event in supervisor.frame().unwrap() { + saw_delta |= + matches!(event, AgentEvent::ResponseText(ref text) if text == "background-ok"); + finished |= event == AgentEvent::Done; + } + if finished { + break; + } + std::thread::sleep(Duration::from_millis(2)); + } + + assert!(saw_delta && finished); + assert_eq!(supervisor.active_id(), ROBINHOOD_APP_ID); + assert_eq!( + &supervisor.system.guest as *const Guest as usize, + system_guest + ); + let robinhood_guest = &supervisor + .runtimes + .get(ROBINHOOD_APP_ID) + .expect("Robinhood runtime") + .guest as *const Guest as usize; + supervisor.open(ROOT_APP_ID).unwrap(); + assert_eq!(supervisor.active_id(), ROOT_APP_ID); + assert_eq!( + &supervisor.system.guest as *const Guest as usize, + system_guest + ); + supervisor.open(ROBINHOOD_APP_ID).unwrap(); + assert_eq!( + &supervisor + .runtimes + .get(ROBINHOOD_APP_ID) + .expect("cached Robinhood runtime") + .guest as *const Guest as usize, + robinhood_guest + ); + supervisor.open(EXA_APP_ID).unwrap(); + assert_eq!( + &supervisor + .runtimes + .get(EXA_APP_ID) + .expect("resident Exa runtime") + .guest as *const Guest as usize, + exa_guest + ); + } + + #[test] + fn background_agent_routes_headless_app_tool_while_exa_is_foreground() { + let temp = tempfile::tempdir().unwrap(); + let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(RobinhoodServices)).unwrap(); + let (routed, app_rx) = RoutedToolHost::new(Arc::new(NoTools), supervisor.catalog.clone()); + supervisor + .boot_agent( + r#"{"model":"offline"}"#, + Arc::new(ToolCallingBackend(AtomicUsize::new(0))), + Arc::new(routed), + ) + .unwrap(); + supervisor.prompt_agent("check portfolio").unwrap(); + supervisor.open(EXA_APP_ID).unwrap(); + + let mut finished = false; + for _ in 0..200 { + while let Ok(request) = app_rx.try_recv() { + request.handle(&mut supervisor); + } + finished |= supervisor + .frame() + .unwrap() + .into_iter() + .any(|event| event == AgentEvent::Done); + if finished { + break; + } + std::thread::sleep(Duration::from_millis(2)); + } + + assert!(finished); + assert_eq!(supervisor.active_id(), EXA_APP_ID); + assert!(temp + .path() + .join("apps/robinhood/data/robinhood.sqlite") + .exists()); + } + + #[test] + fn app_revisions_coalesce_at_the_foreground_frame_boundary() { + let temp = tempfile::tempdir().unwrap(); + let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(NoServices)).unwrap(); + supervisor.open(EXA_APP_ID).unwrap(); + + let revision = supervisor + .runtimes + .get(EXA_APP_ID) + .unwrap() + .revision + .clone(); + revision.fetch_add(1, Ordering::Release); + revision.fetch_add(1, Ordering::Release); + revision.fetch_add(1, Ordering::Release); + assert!(supervisor.active_projection_is_stale()); + + // A host tick that does not render the selected View never reloads its + // SQLite projection. The next rendered frame observes only the newest + // revision and therefore folds all three commits into one reload. + supervisor.frame_render(false).unwrap(); + let exa = supervisor.runtimes.get(EXA_APP_ID).unwrap(); + assert_eq!(exa.projection_refreshes.get(), 0); + assert_eq!(exa.last_seen_revision.get(), 0); + + supervisor.frame_render(true).unwrap(); + let exa = supervisor.runtimes.get(EXA_APP_ID).unwrap(); + assert_eq!(exa.projection_refreshes.get(), 1); + assert_eq!(exa.last_seen_revision.get(), 3); + assert!(!supervisor.active_projection_is_stale()); + + for _ in 0..5 { + supervisor.frame_render(true).unwrap(); + } + assert_eq!( + supervisor + .runtimes + .get(EXA_APP_ID) + .unwrap() + .projection_refreshes + .get(), + 1 + ); + + // Inactive Apps never query. They catch up exactly once when selected + // again, no matter how many commits happened while they were hidden. + supervisor.open(ROOT_APP_ID).unwrap(); + revision.fetch_add(1, Ordering::Release); + revision.fetch_add(1, Ordering::Release); + supervisor.frame_render(true).unwrap(); + assert_eq!( + supervisor + .runtimes + .get(EXA_APP_ID) + .unwrap() + .projection_refreshes + .get(), + 1 + ); + supervisor.open(EXA_APP_ID).unwrap(); + supervisor.frame_render(true).unwrap(); + let exa = supervisor.runtimes.get(EXA_APP_ID).unwrap(); + assert_eq!(exa.projection_refreshes.get(), 2); + assert_eq!(exa.last_seen_revision.get(), 5); + } +} diff --git a/crates/pocket-pi-device-ui/Cargo.toml b/crates/pocket-pi-device-ui/Cargo.toml deleted file mode 100644 index 8219488..0000000 --- a/crates/pocket-pi-device-ui/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "pocket-pi-device-ui" -version = "0.1.0" -edition.workspace = true -license.workspace = true -repository.workspace = true -publish = false - -[dependencies] -pocket-pi-protocols = { path = "../pocket-pi-protocols" } -pocketjs-core = { git = "https://github.com/pocket-stack/pocketjs.git", rev = "4c5dc9ef1dd26e6f49b036c210931d399f2b52b2" } diff --git a/crates/pocket-pi-device-ui/assets/fonts/INTER-LICENSE.txt b/crates/pocket-pi-device-ui/assets/fonts/INTER-LICENSE.txt deleted file mode 100644 index 9b2ca37..0000000 --- a/crates/pocket-pi-device-ui/assets/fonts/INTER-LICENSE.txt +++ /dev/null @@ -1,92 +0,0 @@ -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/pocket-pi-device-ui/assets/fonts/SOURCE_PROVENANCE.md b/crates/pocket-pi-device-ui/assets/fonts/SOURCE_PROVENANCE.md deleted file mode 100644 index 572a24b..0000000 --- a/crates/pocket-pi-device-ui/assets/fonts/SOURCE_PROVENANCE.md +++ /dev/null @@ -1,17 +0,0 @@ -# PocketJS font atlases - -These `.pfa` files were generated with PocketJS's official -`framework/compiler/bake-font.ts` at the same pinned revision used by the -firmware (`4c5dc9ef1dd26e6f49b036c210931d399f2b52b2`). They contain the ASCII glyph -set plus the common smart punctuation `‘’“”–—…`, baked from PocketJS's bundled -Inter Regular and Inter Bold fonts. Model replies commonly use these -typographic characters even when the prompt contains plain ASCII. - -- slot 3: Inter Regular, 18 px; -- slot 6: Inter Regular, 36 px; -- slot 10: Inter Bold, 18 px; -- slot 12: Inter Bold, 24 px. - -The atlases use PocketJS font-atlas format v3 with one coverage sample per -logical pixel. Inter is distributed under the SIL Open Font License; the full -license is retained as `INTER-LICENSE.txt`. diff --git a/crates/pocket-pi-device-ui/assets/fonts/inter-18-bold.pfa b/crates/pocket-pi-device-ui/assets/fonts/inter-18-bold.pfa deleted file mode 100644 index e9eccfd8fa6c572e8b7ff7369b1b901374e8b724..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43894 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 F{|`PBF)RQ8 diff --git a/crates/pocket-pi-device-ui/assets/fonts/inter-18-regular.pfa b/crates/pocket-pi-device-ui/assets/fonts/inter-18-regular.pfa deleted file mode 100644 index 6966865f227560621d3338cdffe16b846152c696..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41628 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 xS8p8= Self { - Self { - agent: AgentState::Stopped, - } - } -} - -pub use pocket_pi_protocols::model::{ - ModelBackendSettings, ModelSettings, UartProvider, WirelessProvider, -}; - -#[derive(Clone, Debug, Default)] -pub struct ScheduleProjection { - pub name: Option, - pub prompt: String, - pub next_in_seconds: Option, - pub every_minutes: Option, -} - -#[derive(Clone, Debug, Default, Eq, PartialEq)] -pub struct WifiNetworkProjection { - pub ssid: String, - pub rssi_dbm: i16, - pub secured: bool, -} - -#[derive(Clone, Debug, Default, Eq, PartialEq)] -pub struct WifiSettingsProjection { - pub connected_ssid: Option, - pub ip_address: Option, - pub rssi_dbm: Option, - pub scanning: bool, - pub networks: Vec, - pub status: String, -} - -#[derive(Clone, Debug, Default, Eq, PartialEq)] -pub struct SettingsProjection { - pub wifi: WifiSettingsProjection, - pub firmware_version: String, - pub workspace_free_bytes: Option, -} - -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum SettingsCommand { - ScanWifi, - ConnectWifi { ssid: String, password: String }, - ForgetWifi, - Restart, -} diff --git a/crates/pocket-pi-device-ui/src/screen/font.rs b/crates/pocket-pi-device-ui/src/screen/font.rs deleted file mode 100644 index d36d101..0000000 --- a/crates/pocket-pi-device-ui/src/screen/font.rs +++ /dev/null @@ -1,165 +0,0 @@ -use pocketjs_core::{spec, Ui}; - -const BODY_SLOT: u8 = 3; -const BODY_BOLD_SLOT: u8 = 10; -const TITLE_SLOT: u8 = 12; -const COLUMN_WIDTH: usize = 16; - -const BODY_ATLAS: &[u8] = include_bytes!("../../assets/fonts/inter-18-regular.pfa"); -const BODY_BOLD_ATLAS: &[u8] = include_bytes!("../../assets/fonts/inter-18-bold.pfa"); -const TITLE_ATLAS: &[u8] = include_bytes!("../../assets/fonts/inter-24-bold.pfa"); - -#[derive(Clone, Copy)] -pub enum TextStyle { - Body, - Bold, - Title, -} - -impl TextStyle { - const fn slot(self) -> u8 { - match self { - Self::Body => BODY_SLOT, - Self::Bold => BODY_BOLD_SLOT, - Self::Title => TITLE_SLOT, - } - } -} - -pub fn load(ui: &mut Ui) -> bool { - [BODY_ATLAS, BODY_BOLD_ATLAS, TITLE_ATLAS] - .into_iter() - .all(|atlas| ui.load_font_atlas(atlas)) -} - -pub fn text_width(ui: &Ui, text: &str, style: TextStyle) -> i16 { - let Some(atlas) = ui.font_atlas(style.slot()) else { - return 0; - }; - let fallback = atlas.lookup_entry('?' as u32); - text.chars() - .filter_map(|character| atlas.lookup_entry(character as u32).or(fallback)) - .map(|entry| i32::from(entry.advance)) - .sum::() - .min(i32::from(i16::MAX)) as i16 -} - -#[allow(clippy::too_many_arguments)] -pub fn append_text( - ui: &Ui, - words: &mut Vec, - text: &str, - x: i16, - y: i16, - max_columns: usize, - max_rows: usize, - color: u32, - style: TextStyle, -) { - let slot = style.slot(); - let Some(atlas) = ui.font_atlas(slot) else { - return; - }; - let max_width = max_columns.saturating_mul(COLUMN_WIDTH) as i32; - let line_height = atlas.line_height as i32; - let fallback = atlas.lookup_entry('?' as u32); - let mut glyphs = Vec::new(); - let mut pen_x = 0i32; - let mut row = 0usize; - - for character in text.chars() { - if character == '\n' { - row += 1; - pen_x = 0; - if row >= max_rows { - break; - } - continue; - } - - let entry = atlas.lookup_entry(character as u32).or(fallback); - let Some(entry) = entry else { - continue; - }; - let advance = entry.advance as i32; - if pen_x > 0 && pen_x + advance > max_width { - row += 1; - pen_x = 0; - } - if row >= max_rows { - break; - } - - let glyph_x = x as i32 + pen_x - entry.xoff as i32; - let glyph_y = y as i32 + row as i32 * line_height; - glyphs.push(xy(glyph_x as i16, glyph_y as i16)); - glyphs.push(entry.gid as u32); - pen_x += advance; - } - - if glyphs.is_empty() { - return; - } - words.push(spec::draw_op::GLYPH_RUN); - words.push(slot as u32 | ((glyphs.len() as u32 / 2) << 16)); - words.push(color); - words.extend(glyphs); -} - -/// Wrap text with the same glyph advances used by `append_text`, so callers -/// can page through long content without guessing from byte or character count. -pub fn wrap_text(ui: &Ui, text: &str, max_columns: usize, style: TextStyle) -> Vec { - let Some(atlas) = ui.font_atlas(style.slot()) else { - return vec![text.to_owned()]; - }; - let max_width = max_columns.saturating_mul(COLUMN_WIDTH) as i32; - let fallback = atlas.lookup_entry('?' as u32); - let mut lines = Vec::new(); - let mut line = String::new(); - let mut pen_x = 0i32; - - for character in text.chars() { - if character == '\n' { - lines.push(core::mem::take(&mut line)); - pen_x = 0; - continue; - } - let Some(entry) = atlas.lookup_entry(character as u32).or(fallback) else { - continue; - }; - let advance = entry.advance as i32; - if pen_x > 0 && pen_x + advance > max_width { - lines.push(core::mem::take(&mut line)); - pen_x = 0; - } - line.push(character); - pen_x += advance; - } - lines.push(line); - lines -} - -const fn xy(x: i16, y: i16) -> u32 { - x as u16 as u32 | ((y as u16 as u32) << 16) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn atlases_cover_common_model_punctuation() { - let mut ui = Ui::new(); - assert!(load(&mut ui)); - for style in [TextStyle::Body, TextStyle::Bold, TextStyle::Title] { - let atlas = ui.font_atlas(style.slot()).expect("font atlas"); - for character in "‘’“”–—…".chars() { - assert!( - atlas.lookup_entry(character as u32).is_some(), - "missing {character:?} in font slot {}", - style.slot() - ); - } - } - } -} diff --git a/crates/pocket-pi-device-ui/src/screen/mod.rs b/crates/pocket-pi-device-ui/src/screen/mod.rs deleted file mode 100644 index 324915c..0000000 --- a/crates/pocket-pi-device-ui/src/screen/mod.rs +++ /dev/null @@ -1,1649 +0,0 @@ -#![allow( - clippy::if_same_then_else, - clippy::manual_div_ceil, - clippy::too_many_arguments -)] - -mod font; -mod workspace_browser; - -use std::collections::VecDeque; - -use crate::model::{ - AgentState, DeviceState, ModelBackendSettings, ModelSettings, ScheduleProjection, - SettingsCommand, SettingsProjection, UartProvider, WifiNetworkProjection, WirelessProvider, -}; -use pocketjs_core::{spec, Ui}; -use workspace_browser::{format_size, format_timestamp, WorkspaceBrowser}; - -pub fn load_fonts(ui: &mut Ui) -> bool { - font::load(ui) -} - -const PANEL_WIDTH: u16 = 720; -const PANEL_HEIGHT: u16 = 1280; -const HEADER_HEIGHT: i16 = 112; -const BOTTOM_BAR_Y: i16 = 1172; -const FILE_ROW_START_Y: i16 = 190; -const FILE_ROW_HEIGHT: i16 = 108; -const FILE_VISIBLE_ROWS: usize = 8; -const VIEWER_VISIBLE_LINES: usize = 39; -const MESSAGE_VISIBLE_LINES: usize = 39; -const MAX_CHAT_TURNS: usize = 10; -const CHAT_VISIBLE_TURNS: usize = 2; -const WIFI_ROW_START_Y: u16 = 330; -const WIFI_ROW_HEIGHT: u16 = 92; -const WIFI_VISIBLE_ROWS: usize = 5; -const COMPOSE_Y: u16 = 1070; -const MAX_PROMPT_BYTES: usize = 256; -const PENDING_ASSISTANT: &str = "THINKING..."; - -// PocketJS draw-list colors are packed ABGR, not ARGB. -const UI_ACCENT_GREEN: u32 = 0xff3b_d158; // RGB #58D13B -const UI_LOSS_RED: u32 = 0xff44_44ef; // RGB #EF4444 - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum ScreenView { - Chat, - Files, - Settings, - Viewer, - MessageReader, -} - -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ScreenInteraction { - None, - Redraw, - SubmitPrompt(String), - Settings(SettingsCommand), -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -enum KeyboardMode { - Letters, - Numbers, -} - -#[derive(Clone, Debug, Eq, PartialEq)] -enum KeyboardPurpose { - Prompt, - WifiPassword { ssid: String }, -} - -#[derive(Clone, Copy, Debug, Default)] -pub struct SystemTelemetry { - pub psram_used_percent: u8, - pub psram_free_bytes: usize, - pub cpu_percent: Option, - pub ui_fps_tenths: u16, - pub lcd_refresh_hz: u16, -} - -#[derive(Clone, Debug)] -struct BackendProjection { - model: String, - link: String, - auth: String, -} - -impl Default for BackendProjection { - fn default() -> Self { - Self { - model: "CODEX".to_owned(), - link: "UART / MAC".to_owned(), - auth: "CODING PLAN".to_owned(), - } - } -} - -impl BackendProjection { - fn from_settings(settings: &ModelSettings) -> Self { - match &settings.backend { - ModelBackendSettings::Uart { provider } => match provider { - UartProvider::Codex => Self::default(), - UartProvider::ClaudeCode => Self { - model: "CLAUDE CODE".to_owned(), - link: "UART / MAC".to_owned(), - auth: "CLAUDE LOGIN".to_owned(), - }, - }, - ModelBackendSettings::Wireless { provider } => Self { - model: match provider { - WirelessProvider::OpenAi => "OPENAI API", - WirelessProvider::OpenRouter => "OPENROUTER", - WirelessProvider::Anthropic => "ANTHROPIC API", - } - .to_owned(), - link: "WIFI / DIRECT".to_owned(), - auth: "API KEY / RAM".to_owned(), - }, - } - } -} - -#[derive(Clone, Debug)] -pub struct ChatTurn { - pub user: String, - pub assistant: String, - pending: bool, -} - -#[derive(Debug)] -pub struct ChatProjection { - turns: VecDeque, -} - -#[derive(Debug)] -struct MessageReader { - author: &'static str, - lines: Vec, - line_offset: usize, -} - -impl ChatProjection { - pub fn new(user: impl Into, assistant: impl Into) -> Self { - let mut turns = VecDeque::new(); - turns.push_back(ChatTurn { - user: user.into(), - assistant: assistant.into(), - pending: false, - }); - Self { turns } - } - - pub fn push_turn(&mut self, user: impl Into, assistant: impl Into) { - self.turns.push_back(ChatTurn { - user: user.into(), - assistant: assistant.into(), - pending: false, - }); - while self.turns.len() > MAX_CHAT_TURNS { - self.turns.pop_front(); - } - } - - pub fn set_latest_assistant(&mut self, assistant: impl Into) { - if let Some(turn) = self.turns.back_mut() { - turn.assistant = assistant.into(); - turn.pending = false; - } - } - - pub fn push_pending(&mut self, user: impl Into) { - let user = user.into(); - if self - .turns - .back() - .is_some_and(|turn| turn.pending && turn.user == user) - { - return; - } - self.turns.push_back(ChatTurn { - user, - assistant: PENDING_ASSISTANT.to_owned(), - pending: true, - }); - while self.turns.len() > MAX_CHAT_TURNS { - self.turns.pop_front(); - } - } - - pub fn append_model_delta(&mut self, delta: &str) -> bool { - let Some(turn) = self.turns.back_mut().filter(|turn| turn.pending) else { - return false; - }; - if turn.assistant == PENDING_ASSISTANT { - turn.assistant.clear(); - } - turn.assistant.push_str(delta); - true - } - - pub fn finish_pending(&mut self) { - if let Some(turn) = self.turns.back_mut().filter(|turn| turn.pending) { - if turn.assistant.is_empty() || turn.assistant == PENDING_ASSISTANT { - turn.assistant = "TURN COMPLETE".to_owned(); - } - turn.pending = false; - } - } - - pub fn fail_pending(&mut self, error: impl Into) { - let error = error.into(); - if let Some(turn) = self.turns.back_mut() { - if turn.pending { - turn.assistant = error; - turn.pending = false; - return; - } - } - self.push_turn("SYSTEM", error); - } -} - -#[derive(Debug)] -pub struct ScreenState { - pub view: ScreenView, - pub browser: WorkspaceBrowser, - pub telemetry: SystemTelemetry, - schedule: ScheduleProjection, - chat_scroll: usize, - wifi_scroll: usize, - keyboard_open: bool, - keyboard_mode: KeyboardMode, - keyboard_uppercase: bool, - keyboard_purpose: KeyboardPurpose, - keyboard_input: String, - pressed_key: Option, - backend: BackendProjection, - settings: SettingsProjection, - message_reader: Option, -} - -impl ScreenState { - pub fn new(workspace_root: &str) -> Self { - Self { - view: ScreenView::Chat, - browser: WorkspaceBrowser::new(workspace_root), - telemetry: SystemTelemetry::default(), - schedule: ScheduleProjection::default(), - chat_scroll: 0, - wifi_scroll: 0, - keyboard_open: false, - keyboard_mode: KeyboardMode::Letters, - keyboard_uppercase: false, - keyboard_purpose: KeyboardPurpose::Prompt, - keyboard_input: String::new(), - pressed_key: None, - backend: BackendProjection::default(), - settings: SettingsProjection::default(), - message_reader: None, - } - } - - pub fn set_telemetry(&mut self, telemetry: SystemTelemetry) { - self.telemetry = telemetry; - } - - pub fn set_schedule(&mut self, schedule: ScheduleProjection) { - self.schedule = schedule; - } - - pub fn set_model_backend(&mut self, settings: &ModelSettings) { - self.backend = BackendProjection::from_settings(settings); - } - - pub fn set_backend_status(&mut self, model: &str, link: &str, auth: &str) { - self.backend = BackendProjection { - model: model.to_owned(), - link: link.to_owned(), - auth: auth.to_owned(), - }; - } - - pub fn set_settings(&mut self, settings: SettingsProjection) { - self.wifi_scroll = self.wifi_scroll.min( - settings - .wifi - .networks - .len() - .saturating_sub(WIFI_VISIBLE_ROWS), - ); - self.settings = settings; - } - - pub fn handle_touch_release(&mut self) -> bool { - self.pressed_key.take().is_some() && self.keyboard_open - } - - pub fn refresh_workspace(&mut self) { - self.browser.refresh(); - } - - pub fn show_latest_chat(&mut self) { - self.chat_scroll = 0; - } - - pub fn handle_tap( - &mut self, - x: u16, - y: u16, - chat: &ChatProjection, - ui: &Ui, - ) -> ScreenInteraction { - if self.keyboard_open { - return self.handle_keyboard_tap(x, y); - } - if !matches!(self.view, ScreenView::Viewer | ScreenView::MessageReader) - && y as i16 >= BOTTOM_BAR_Y - { - let next = match x { - 0..=239 => ScreenView::Chat, - 240..=479 => { - self.browser.refresh(); - ScreenView::Files - } - _ => ScreenView::Settings, - }; - let changed = self.view != next; - self.view = next; - self.keyboard_open = false; - self.pressed_key = None; - return if changed { - ScreenInteraction::Redraw - } else { - ScreenInteraction::None - }; - } - let changed = match self.view { - ScreenView::Chat => self.handle_chat_tap(x, y, chat, ui), - ScreenView::Files => self.handle_files_tap(x, y), - ScreenView::Settings => return self.handle_settings_tap(x, y), - ScreenView::Viewer => self.handle_viewer_tap(x, y), - ScreenView::MessageReader => self.handle_message_reader_tap(x, y), - }; - if changed { - ScreenInteraction::Redraw - } else { - ScreenInteraction::None - } - } - - fn handle_chat_tap(&mut self, x: u16, y: u16, chat: &ChatProjection, ui: &Ui) -> bool { - if (24..=696).contains(&x) && (COMPOSE_Y..=1150).contains(&y) { - self.keyboard_open = true; - self.keyboard_purpose = KeyboardPurpose::Prompt; - self.keyboard_uppercase = false; - self.keyboard_input.clear(); - self.pressed_key = None; - return true; - } - if x >= 620 && (140..=272).contains(&y) { - self.chat_scroll = self.chat_scroll.saturating_add(CHAT_VISIBLE_TURNS); - return true; - } - if x >= 620 && (610..=790).contains(&y) { - let before = self.chat_scroll; - self.chat_scroll = self.chat_scroll.saturating_sub(CHAT_VISIBLE_TURNS); - return before != self.chat_scroll; - } - if (24..610).contains(&x) { - let len = chat.turns.len(); - let scroll = self.chat_scroll.min(len.saturating_sub(CHAT_VISIBLE_TURNS)); - let end = len.saturating_sub(scroll); - let start = end.saturating_sub(CHAT_VISIBLE_TURNS); - for (row, turn) in chat.turns.iter().skip(start).take(end - start).enumerate() { - let top = 140 + row as u16 * 320; - if (top..top + 150).contains(&y) { - self.open_message(ui, "YOU", &turn.user); - return true; - } - if (top + 150..top + 298).contains(&y) { - self.open_message(ui, "PI", &turn.assistant); - return true; - } - } - } - false - } - - fn open_message(&mut self, ui: &Ui, author: &'static str, text: &str) { - self.message_reader = Some(MessageReader { - author, - lines: font::wrap_text(ui, text, 32, font::TextStyle::Body), - line_offset: 0, - }); - self.view = ScreenView::MessageReader; - } - - fn handle_message_reader_tap(&mut self, x: u16, y: u16) -> bool { - if x < 104 && y < HEADER_HEIGHT as u16 { - self.message_reader = None; - self.view = ScreenView::Chat; - return true; - } - let Some(reader) = self.message_reader.as_mut() else { - self.view = ScreenView::Chat; - return true; - }; - if x >= 620 && (170..=340).contains(&y) { - let before = reader.line_offset; - reader.line_offset = reader.line_offset.saturating_sub(18); - return before != reader.line_offset; - } - if x >= 620 && (920..=1100).contains(&y) { - let max_scroll = reader.lines.len().saturating_sub(MESSAGE_VISIBLE_LINES); - let before = reader.line_offset; - reader.line_offset = (reader.line_offset + 18).min(max_scroll); - return before != reader.line_offset; - } - false - } - - fn handle_keyboard_tap(&mut self, x: u16, y: u16) -> ScreenInteraction { - let max_input_bytes = match &self.keyboard_purpose { - KeyboardPurpose::Prompt => MAX_PROMPT_BYTES, - KeyboardPurpose::WifiPassword { .. } => 63, - }; - if (24..=696).contains(&x) && (1164..=1279).contains(&y) { - self.keyboard_open = false; - self.keyboard_input.clear(); - self.keyboard_uppercase = false; - self.pressed_key = None; - return ScreenInteraction::Redraw; - } - if (548..=680).contains(&x) && (360..=416).contains(&y) { - self.pressed_key = Some("CLEAR".to_owned()); - self.keyboard_input.clear(); - return ScreenInteraction::Redraw; - } - - let rows = match self.keyboard_mode { - KeyboardMode::Letters => ["qwertyuiop", "asdfghjkl", "zxcvbnm"], - KeyboardMode::Numbers => ["1234567890", "-/:;()$&@", ".,?!'\"+"], - }; - let character = if (488..=608).contains(&y) { - row_character(x, 24, 60, 8, rows[0]) - } else if (628..=748).contains(&y) { - row_character(x, 31, 66, 8, rows[1]) - } else if (768..=888).contains(&y) { - row_character(x, 24, 72, 8, rows[2]) - } else { - None - }; - if let Some(character) = character { - self.pressed_key = Some(character.to_ascii_uppercase().to_string()); - if self.keyboard_input.len() < max_input_bytes { - self.keyboard_input.push( - if self.keyboard_mode == KeyboardMode::Letters && self.keyboard_uppercase { - character.to_ascii_uppercase() - } else { - character - }, - ); - } - return ScreenInteraction::Redraw; - } - if (592..=696).contains(&x) && (768..=888).contains(&y) { - self.pressed_key = Some("DEL".to_owned()); - self.keyboard_input.pop(); - return ScreenInteraction::Redraw; - } - if (908..=1064).contains(&y) { - match x { - 24..=116 => { - self.pressed_key = Some( - if self.keyboard_mode == KeyboardMode::Letters { - "123" - } else { - "ABC" - } - .to_owned(), - ); - self.keyboard_mode = match self.keyboard_mode { - KeyboardMode::Letters => KeyboardMode::Numbers, - KeyboardMode::Numbers => KeyboardMode::Letters, - }; - self.keyboard_uppercase = false; - return ScreenInteraction::Redraw; - } - 124..=424 => { - self.pressed_key = Some("SPACE".to_owned()); - if !self.keyboard_input.is_empty() - && self.keyboard_input.len() < max_input_bytes - { - self.keyboard_input.push(' '); - } - return ScreenInteraction::Redraw; - } - 432..=500 => { - if self.keyboard_mode == KeyboardMode::Letters { - self.keyboard_uppercase = !self.keyboard_uppercase; - self.pressed_key = Some("SHIFT".to_owned()); - return ScreenInteraction::Redraw; - } - self.pressed_key = Some(".".to_owned()); - if self.keyboard_input.len() < max_input_bytes { - self.keyboard_input.push('.'); - } - return ScreenInteraction::Redraw; - } - 508..=576 => { - if self.keyboard_mode == KeyboardMode::Letters { - self.keyboard_uppercase = !self.keyboard_uppercase; - self.pressed_key = Some("SHIFT".to_owned()); - return ScreenInteraction::Redraw; - } - self.pressed_key = Some("?".to_owned()); - if self.keyboard_input.len() < max_input_bytes { - self.keyboard_input.push('?'); - } - return ScreenInteraction::Redraw; - } - 584..=696 => { - let value = self.keyboard_input.trim().to_owned(); - if value.is_empty() { - return ScreenInteraction::None; - } - let purpose = self.keyboard_purpose.clone(); - self.keyboard_input.clear(); - self.keyboard_open = false; - self.pressed_key = None; - self.keyboard_mode = KeyboardMode::Letters; - self.keyboard_uppercase = false; - return match purpose { - KeyboardPurpose::Prompt => ScreenInteraction::SubmitPrompt(value), - KeyboardPurpose::WifiPassword { ssid } => { - ScreenInteraction::Settings(SettingsCommand::ConnectWifi { - ssid, - password: value, - }) - } - }; - } - _ => {} - } - } - ScreenInteraction::None - } - - fn handle_settings_tap(&mut self, x: u16, y: u16) -> ScreenInteraction { - if (480..=696).contains(&x) && (142..=218).contains(&y) { - return ScreenInteraction::Settings(SettingsCommand::ScanWifi); - } - if x >= 620 && (330..=462).contains(&y) { - let before = self.wifi_scroll; - self.wifi_scroll = self.wifi_scroll.saturating_sub(WIFI_VISIBLE_ROWS - 1); - return if before == self.wifi_scroll { - ScreenInteraction::None - } else { - ScreenInteraction::Redraw - }; - } - if x >= 620 && (650..=782).contains(&y) { - let max_scroll = self - .settings - .wifi - .networks - .len() - .saturating_sub(WIFI_VISIBLE_ROWS); - let before = self.wifi_scroll; - self.wifi_scroll = (self.wifi_scroll + WIFI_VISIBLE_ROWS - 1).min(max_scroll); - return if before == self.wifi_scroll { - ScreenInteraction::None - } else { - ScreenInteraction::Redraw - }; - } - if x < 610 && (WIFI_ROW_START_Y..790).contains(&y) { - let row = ((y - WIFI_ROW_START_Y) / WIFI_ROW_HEIGHT) as usize; - let row_top = WIFI_ROW_START_Y + row as u16 * WIFI_ROW_HEIGHT; - if y >= row_top + 84 { - return ScreenInteraction::None; - } - if let Some(network) = self.settings.wifi.networks.get(self.wifi_scroll + row) { - if !network.secured { - return ScreenInteraction::Settings(SettingsCommand::ConnectWifi { - ssid: network.ssid.clone(), - password: String::new(), - }); - } - self.keyboard_open = true; - self.keyboard_mode = KeyboardMode::Letters; - self.keyboard_uppercase = false; - self.keyboard_purpose = KeyboardPurpose::WifiPassword { - ssid: network.ssid.clone(), - }; - self.keyboard_input.clear(); - self.pressed_key = None; - return ScreenInteraction::Redraw; - } - } - if (24..=340).contains(&x) && (1010..=1090).contains(&y) { - return ScreenInteraction::Settings(SettingsCommand::ForgetWifi); - } - if (356..=696).contains(&x) && (1010..=1090).contains(&y) { - return ScreenInteraction::Settings(SettingsCommand::Restart); - } - ScreenInteraction::None - } - - fn handle_files_tap(&mut self, x: u16, y: u16) -> bool { - if x < 96 && y < HEADER_HEIGHT as u16 && self.browser.can_go_up() { - self.browser.go_up(); - return true; - } - if x >= 620 && (170..=340).contains(&y) { - self.browser.scroll_list(-4, FILE_VISIBLE_ROWS); - return true; - } - if x >= 620 && (920..=1100).contains(&y) { - self.browser.scroll_list(4, FILE_VISIBLE_ROWS); - return true; - } - if x < 610 && y as i16 >= FILE_ROW_START_Y { - let row = ((y as i16 - FILE_ROW_START_Y) / FILE_ROW_HEIGHT) as usize; - if row < FILE_VISIBLE_ROWS && self.browser.activate_visible_row(row) { - if self.browser.open_file.is_some() { - self.view = ScreenView::Viewer; - } - return true; - } - } - false - } - - fn handle_viewer_tap(&mut self, x: u16, y: u16) -> bool { - if x < 104 && y < HEADER_HEIGHT as u16 { - self.browser.close_file(); - self.view = ScreenView::Files; - return true; - } - if x >= 620 && (170..=340).contains(&y) { - self.browser.scroll_file(-18, VIEWER_VISIBLE_LINES); - return true; - } - if x >= 620 && (920..=1100).contains(&y) { - self.browser.scroll_file(18, VIEWER_VISIBLE_LINES); - return true; - } - false - } - - pub fn draw_list(&self, ui: &Ui, state: &DeviceState, chat: &ChatProjection) -> Vec { - match self.view { - _ if self.keyboard_open => keyboard_draw_list( - ui, - state, - &self.keyboard_input, - self.keyboard_mode, - self.keyboard_uppercase, - self.pressed_key.as_deref(), - &self.keyboard_purpose, - self.telemetry, - ), - ScreenView::Chat => chat_draw_list( - ui, - state, - chat, - self.chat_scroll, - &self.schedule, - self.telemetry, - ), - ScreenView::Files => files_draw_list(ui, state, &self.browser, self.telemetry), - ScreenView::Settings => settings_draw_list( - ui, - state, - &self.settings, - self.wifi_scroll, - &self.backend, - self.telemetry, - ), - ScreenView::Viewer => viewer_draw_list(ui, state, &self.browser, self.telemetry), - ScreenView::MessageReader => { - message_reader_draw_list(ui, state, self.message_reader.as_ref(), self.telemetry) - } - } - } -} - -fn base_words(ui: &Ui, state: &DeviceState, title: &str, telemetry: SystemTelemetry) -> Vec { - let mut words = Vec::new(); - rect(&mut words, 0, 0, PANEL_WIDTH, PANEL_HEIGHT, 0xfff1_f5f9); - rect( - &mut words, - 0, - 0, - PANEL_WIDTH, - HEADER_HEIGHT as u16, - 0xff0f_172a, - ); - status_header( - ui, - &mut words, - state, - title, - telemetry, - 0xffff_ffff, - 0xffcb_d5e1, - 0xff94_a3b8, - ); - words -} - -#[allow(clippy::too_many_arguments)] -fn status_header( - ui: &Ui, - words: &mut Vec, - state: &DeviceState, - title: &str, - telemetry: SystemTelemetry, - title_color: u32, - primary_status_color: u32, - secondary_status_color: u32, -) { - const RIGHT_EDGE: i16 = 696; - rect(words, 24, 38, 36, 36, agent_state_color(state.agent)); - push_title(ui, words, title, 78, 40, 22, title_color); - let cpu = telemetry - .cpu_percent - .map(|value| format!("{value:02}%")) - .unwrap_or_else(|| "--".to_owned()); - let free_megabytes = telemetry.psram_free_bytes as f32 / (1024.0 * 1024.0); - let memory = format!( - "PSRAM {:02}% FREE {free_megabytes:.1}M", - telemetry.psram_used_percent - ); - let runtime = format!( - "CPU {cpu} UI {}.{}FPS LCD {}HZ", - telemetry.ui_fps_tenths / 10, - telemetry.ui_fps_tenths % 10, - telemetry.lcd_refresh_hz, - ); - push_text_right(ui, words, &memory, RIGHT_EDGE, 25, primary_status_color); - push_text_right(ui, words, &runtime, RIGHT_EDGE, 61, secondary_status_color); -} - -fn chat_draw_list( - ui: &Ui, - state: &DeviceState, - chat: &ChatProjection, - scroll: usize, - schedule: &ScheduleProjection, - telemetry: SystemTelemetry, -) -> Vec { - let mut words = base_words(ui, state, "ESP32 PI AGENT", telemetry); - let len = chat.turns.len(); - let max_scroll = len.saturating_sub(CHAT_VISIBLE_TURNS); - let scroll = scroll.min(max_scroll); - let end = len.saturating_sub(scroll); - let start = end.saturating_sub(CHAT_VISIBLE_TURNS); - for (row, turn) in chat.turns.iter().skip(start).take(end - start).enumerate() { - let y = 140 + row as i16 * 320; - rect(&mut words, 24, y, 584, 298, 0xffff_ffff); - rect(&mut words, 40, y + 18, 82, 34, 0xffdb_eafe); - push_text_bold(ui, &mut words, "YOU", 54, y + 27, 8, 0xff1d_4ed8); - push_text_limited(ui, &mut words, &turn.user, 42, y + 70, 34, 4, 0xff0f_172a); - rect(&mut words, 40, y + 160, 62, 34, 0xffdc_fce7); - push_text_bold(ui, &mut words, "PI", 56, y + 169, 8, 0xff04_7a55); - push_text_limited( - ui, - &mut words, - &turn.assistant, - 42, - y + 210, - 34, - 4, - 0xff0f_172a, - ); - } - chat_scroll_buttons(ui, &mut words); - schedule_panel(ui, &mut words, schedule); - compose_button(ui, &mut words); - bottom_bar(ui, &mut words, ScreenView::Chat); - words -} - -fn schedule_panel(ui: &Ui, words: &mut Vec, schedule: &ScheduleProjection) { - rect(words, 24, 798, 672, 252, 0xffe2_e8f0); - push_text_bold(ui, words, "NEXT WAKE", 44, 822, 28, 0xff33_4155); - if let (Some(name), Some(seconds)) = (&schedule.name, schedule.next_in_seconds) { - let remaining = if seconds < 60 { - "IN <1 MIN".to_owned() - } else if seconds < 3600 { - format!("IN {} MIN", (seconds + 59) / 60) - } else { - format!("IN {}H {}M", seconds / 3600, (seconds % 3600) / 60) - }; - let cadence = schedule - .every_minutes - .map(|minutes| format!("EVERY {minutes}M ")) - .unwrap_or_default(); - let time = format!("{name} {cadence}{remaining}"); - push_text_bold(ui, words, &time, 44, 870, 30, 0xff0f_172a); - rect(words, 42, 914, 636, 112, 0xffff_ffff); - push_text_limited(ui, words, &schedule.prompt, 58, 934, 36, 4, 0xff33_4155); - } else { - push_text_bold(ui, words, "NO WAKE SCHEDULED", 44, 884, 34, 0xff64_748b); - push_text_limited( - ui, - words, - "ASK PI TO CREATE ONE WITH SCHEDULE.SET", - 44, - 938, - 38, - 3, - 0xff64_748b, - ); - } -} - -fn compose_button(ui: &Ui, words: &mut Vec) { - rect(words, 24, COMPOSE_Y as i16, 672, 80, 0xff25_63eb); - push_text_bold( - ui, - words, - "TYPE A MESSAGE", - 238, - COMPOSE_Y as i16 + 27, - 18, - 0xffff_ffff, - ); -} - -fn keyboard_draw_list( - ui: &Ui, - state: &DeviceState, - input: &str, - mode: KeyboardMode, - uppercase: bool, - pressed_key: Option<&str>, - purpose: &KeyboardPurpose, - telemetry: SystemTelemetry, -) -> Vec { - let title = match purpose { - KeyboardPurpose::Prompt => "NEW MESSAGE", - KeyboardPurpose::WifiPassword { .. } => "WIFI PASSWORD", - }; - let mut words = base_words(ui, state, title, telemetry); - let display = match purpose { - KeyboardPurpose::Prompt => prompt_tail(input, MAX_PROMPT_BYTES).to_owned(), - KeyboardPurpose::WifiPassword { .. } => "*".repeat(input.len()), - }; - rect(&mut words, 24, 132, 672, 300, 0xffff_ffff); - push_text_limited( - ui, - &mut words, - &display, - 42, - 154, - 29, - 9, - if input.is_empty() { - 0xff94_a3b8 - } else { - 0xff0f_172a - }, - ); - if input.is_empty() { - push_text_limited( - ui, - &mut words, - match purpose { - KeyboardPurpose::Prompt => "TYPE YOUR MESSAGE...", - KeyboardPurpose::WifiPassword { .. } => "ENTER NETWORK PASSWORD...", - }, - 42, - 154, - 29, - 2, - 0xff94_a3b8, - ); - } - draw_key( - ui, - &mut words, - "CLEAR", - 548, - 360, - 132, - 56, - 0xffe2_e8f0, - pressed_key == Some("CLEAR"), - ); - push_text( - ui, - &mut words, - &format!( - "{} / {} ASCII BYTES", - input.len(), - match purpose { - KeyboardPurpose::Prompt => MAX_PROMPT_BYTES, - KeyboardPurpose::WifiPassword { .. } => 63, - } - ), - 30, - 442, - 34, - 0xff64_748b, - ); - - let rows = match mode { - KeyboardMode::Letters => ["qwertyuiop", "asdfghjkl", "zxcvbnm"], - KeyboardMode::Numbers => ["1234567890", "-/:;()$&@", ".,?!'\"+"], - }; - draw_character_row(ui, &mut words, rows[0], 24, 488, 60, 8, pressed_key); - draw_character_row(ui, &mut words, rows[1], 31, 628, 66, 8, pressed_key); - draw_character_row(ui, &mut words, rows[2], 24, 768, 72, 8, pressed_key); - draw_key( - ui, - &mut words, - "DEL", - 592, - 768, - 104, - 120, - 0xffe2_e8f0, - pressed_key == Some("DEL"), - ); - - draw_key( - ui, - &mut words, - if mode == KeyboardMode::Letters { - "123" - } else { - "ABC" - }, - 24, - 908, - 92, - 156, - 0xffe2_e8f0, - pressed_key - == Some(if mode == KeyboardMode::Letters { - "123" - } else { - "ABC" - }), - ); - draw_key( - ui, - &mut words, - "SPACE", - 124, - 908, - 300, - 156, - 0xffe2_e8f0, - pressed_key == Some("SPACE"), - ); - if mode == KeyboardMode::Letters { - draw_key( - ui, - &mut words, - "SHIFT", - 432, - 908, - 144, - 156, - if uppercase { 0xffbf_dbfe } else { 0xffe2_e8f0 }, - pressed_key == Some("SHIFT"), - ); - } else { - draw_key( - ui, - &mut words, - ".", - 432, - 908, - 68, - 156, - 0xffe2_e8f0, - pressed_key == Some("."), - ); - draw_key( - ui, - &mut words, - "?", - 508, - 908, - 68, - 156, - 0xffe2_e8f0, - pressed_key == Some("?"), - ); - } - draw_key( - ui, - &mut words, - match purpose { - KeyboardPurpose::Prompt => "SEND", - KeyboardPurpose::WifiPassword { .. } => "JOIN", - }, - 584, - 908, - 112, - 156, - UI_ACCENT_GREEN, - matches!(pressed_key, Some("SEND" | "JOIN")), - ); - - draw_key( - ui, - &mut words, - "CLOSE KEYBOARD", - 24, - 1172, - 672, - 84, - 0xffe2_e8f0, - false, - ); - words -} - -fn draw_character_row( - ui: &Ui, - words: &mut Vec, - characters: &str, - start_x: i16, - y: i16, - key_width: u16, - gap: i16, - pressed_key: Option<&str>, -) { - for (index, character) in characters.chars().enumerate() { - let x = start_x + index as i16 * (key_width as i16 + gap); - let label = character.to_ascii_uppercase().to_string(); - draw_key( - ui, - words, - &label, - x, - y, - key_width, - 120, - 0xffff_ffff, - pressed_key == Some(label.as_str()), - ); - } -} - -fn draw_key( - ui: &Ui, - words: &mut Vec, - label: &str, - x: i16, - y: i16, - width: u16, - height: u16, - color: u32, - pressed: bool, -) { - let fill = if pressed { 0xff47_3b33 } else { color }; - rect(words, x, y, width, height, fill); - let label_width = label.len() as i16 * 12; - let text_x = x + ((width as i16 - label_width) / 2).max(6); - push_text_bold( - ui, - words, - label, - text_x, - y + (height as i16 / 2) - 10, - label.len() + 1, - if pressed { - 0xffff_ffff - } else if color == UI_ACCENT_GREEN { - 0xff00_0000 - } else { - 0xff0f_172a - }, - ); -} - -fn row_character(x: u16, start_x: u16, key_width: u16, gap: u16, characters: &str) -> Option { - characters - .chars() - .enumerate() - .find_map(|(index, character)| { - let key_x = start_x + index as u16 * (key_width + gap); - (x >= key_x && x < key_x + key_width).then_some(character) - }) -} - -fn prompt_tail(input: &str, max_bytes: usize) -> &str { - if input.len() <= max_bytes { - return input; - } - let mut start = input.len() - max_bytes; - while !input.is_char_boundary(start) { - start += 1; - } - &input[start..] -} - -fn settings_draw_list( - ui: &Ui, - state: &DeviceState, - settings: &SettingsProjection, - wifi_scroll: usize, - backend: &BackendProjection, - telemetry: SystemTelemetry, -) -> Vec { - let mut words = base_words(ui, state, "SETTINGS", telemetry); - rect(&mut words, 24, 132, 672, 154, 0xffff_ffff); - push_text_bold(ui, &mut words, "WI-FI", 44, 154, 12, 0xff0f_172a); - let network = settings - .wifi - .connected_ssid - .as_deref() - .unwrap_or("NOT CONNECTED"); - push_text_bold(ui, &mut words, network, 44, 198, 30, 0xff25_63eb); - let detail = match (&settings.wifi.ip_address, settings.wifi.rssi_dbm) { - (Some(ip), Some(rssi)) => format!("IP {ip} RSSI {rssi} DBM"), - _ if !settings.wifi.status.is_empty() => settings.wifi.status.clone(), - _ => "SCAN AND SELECT A NETWORK".to_owned(), - }; - push_text(ui, &mut words, &detail, 44, 244, 42, 0xff64_748b); - rect(&mut words, 480, 146, 196, 72, 0xff25_63eb); - push_text_bold( - ui, - &mut words, - if settings.wifi.scanning { - "SCANNING" - } else { - "SCAN" - }, - 532, - 172, - 10, - 0xffff_ffff, - ); - - push_text( - ui, - &mut words, - "AVAILABLE NETWORKS", - 28, - 294, - 28, - 0xff64_748b, - ); - if settings.wifi.networks.is_empty() { - rect(&mut words, 24, 330, 672, 112, 0xffe2_e8f0); - push_text_bold( - ui, - &mut words, - "TAP SCAN TO FIND WI-FI", - 52, - 372, - 30, - 0xff64_748b, - ); - } else { - let max_scroll = settings - .wifi - .networks - .len() - .saturating_sub(WIFI_VISIBLE_ROWS); - for (row, network) in settings - .wifi - .networks - .iter() - .skip(wifi_scroll.min(max_scroll)) - .take(WIFI_VISIBLE_ROWS) - .enumerate() - { - wifi_network_row( - ui, - &mut words, - network, - WIFI_ROW_START_Y as i16 + row as i16 * WIFI_ROW_HEIGHT as i16, - ); - } - wifi_scroll_buttons(ui, &mut words, settings.wifi.networks.len()); - } - - rect(&mut words, 24, 806, 672, 176, 0xffff_ffff); - push_text(ui, &mut words, "MODEL BACKEND", 44, 832, 24, 0xff64_748b); - push_text_bold( - ui, - &mut words, - &format!("{} / {}", backend.model, backend.link), - 44, - 874, - 40, - 0xff0f_172a, - ); - push_text(ui, &mut words, &backend.auth, 44, 920, 34, 0xff33_4155); - let storage = settings - .workspace_free_bytes - .map(format_size) - .unwrap_or_else(|| "--".into()); - push_text( - ui, - &mut words, - &format!( - "FIRMWARE {} WORKSPACE FREE {storage}", - settings.firmware_version - ), - 44, - 956, - 44, - 0xff64_748b, - ); - - rect(&mut words, 24, 1010, 316, 80, 0xffe2_e8f0); - push_text_bold(ui, &mut words, "FORGET WI-FI", 94, 1038, 18, 0xff0f_172a); - rect(&mut words, 356, 1010, 340, 80, 0xfffe_e2e2); - push_text_bold(ui, &mut words, "RESTART DEVICE", 424, 1038, 20, UI_LOSS_RED); - bottom_bar(ui, &mut words, ScreenView::Settings); - words -} - -fn wifi_network_row(ui: &Ui, words: &mut Vec, network: &WifiNetworkProjection, y: i16) { - rect(words, 24, y, 584, 84, 0xffff_ffff); - push_text_bold(ui, words, &network.ssid, 44, y + 24, 34, 0xff0f_172a); - push_text( - ui, - words, - &format!( - "{} DBM {}", - network.rssi_dbm, - if network.secured { "LOCK" } else { "OPEN" } - ), - 444, - y + 28, - 18, - 0xff64_748b, - ); -} - -fn wifi_scroll_buttons(ui: &Ui, words: &mut Vec, network_count: usize) { - let color = if network_count > WIFI_VISIBLE_ROWS { - 0xff1d_4ed8 - } else { - 0xff94_a3b8 - }; - rect(words, 628, 330, 68, 132, 0xffdb_eafe); - push_text_bold(ui, words, "UP", 646, 384, 4, color); - rect(words, 628, 650, 68, 132, 0xffdb_eafe); - push_text_bold(ui, words, "DN", 646, 704, 4, color); -} - -fn files_draw_list( - ui: &Ui, - state: &DeviceState, - browser: &WorkspaceBrowser, - telemetry: SystemTelemetry, -) -> Vec { - let title = if browser.can_go_up() { - "< WORKSPACE FILES" - } else { - "WORKSPACE FILES" - }; - let mut words = base_words(ui, state, title, telemetry); - rect(&mut words, 24, 132, 672, 48, 0xffe2_e8f0); - push_text( - ui, - &mut words, - &browser.current_path(), - 40, - 146, - 39, - 0xff33_4155, - ); - for row in 0..FILE_VISIBLE_ROWS { - let index = browser.list_offset + row; - let Some(entry) = browser.entries.get(index) else { - break; - }; - let y = FILE_ROW_START_Y + row as i16 * FILE_ROW_HEIGHT; - rect(&mut words, 24, y, 584, 94, 0xffff_ffff); - rect( - &mut words, - 42, - y + 18, - 48, - 48, - if entry.is_dir { - 0xffbf_dbfe - } else { - 0xffdc_fce7 - }, - ); - push_text( - ui, - &mut words, - if entry.is_dir { "D" } else { "F" }, - 58, - y + 30, - 2, - if entry.is_dir { - 0xff1d_4ed8 - } else { - 0xff04_7a55 - }, - ); - let name = if entry.is_dir { - format!("{}/", entry.name) - } else { - entry.name.clone() - }; - push_text_bold(ui, &mut words, &name, 108, y + 14, 29, 0xff0f_172a); - let detail = if entry.is_dir { - entry - .timestamp - .map(|timestamp| format_timestamp(Some(timestamp))) - .unwrap_or_else(|| "FOLDER".to_owned()) - } else { - format!( - "{} {}", - format_size(entry.size), - format_timestamp(entry.timestamp) - ) - }; - push_text(ui, &mut words, &detail, 108, y + 52, 29, 0xff64_748b); - } - if browser.entries.is_empty() { - push_text( - ui, - &mut words, - "THIS DIRECTORY IS EMPTY", - 64, - 280, - 34, - 0xff64_748b, - ); - } - if let Some(status) = &browser.status { - rect(&mut words, 40, 1038, 560, 72, 0xfffe_e2e2); - push_text(ui, &mut words, status, 56, 1056, 32, 0xffb9_1c1c); - } - scroll_buttons(ui, &mut words); - bottom_bar(ui, &mut words, ScreenView::Files); - words -} - -fn viewer_draw_list( - ui: &Ui, - state: &DeviceState, - browser: &WorkspaceBrowser, - telemetry: SystemTelemetry, -) -> Vec { - let mut words = base_words(ui, state, "< FILE VIEWER", telemetry); - let Some(file) = browser.open_file.as_ref() else { - push_text(ui, &mut words, "NO FILE OPEN", 64, 240, 30, 0xff64_748b); - return words; - }; - rect(&mut words, 24, 132, 584, 82, 0xffff_ffff); - push_text_bold( - ui, - &mut words, - &file.relative_path, - 40, - 146, - 32, - 0xff0f_172a, - ); - push_text( - ui, - &mut words, - &format!( - "{} {}", - format_size(file.size), - format_timestamp(file.timestamp) - ), - 40, - 180, - 32, - 0xff64_748b, - ); - rect(&mut words, 24, 228, 584, 900, 0xff0b_1220); - let visible = file - .lines - .iter() - .skip(file.line_offset) - .take(VIEWER_VISIBLE_LINES) - .cloned() - .collect::>() - .join("\n"); - push_text_limited( - ui, - &mut words, - &visible, - 44, - 248, - 32, - VIEWER_VISIBLE_LINES, - 0xffe2_e8f0, - ); - push_text( - ui, - &mut words, - &format!( - "LINES {}-{} / {}", - file.line_offset + 1, - (file.line_offset + VIEWER_VISIBLE_LINES).min(file.lines.len()), - file.lines.len() - ), - 40, - 1138, - 32, - 0xff64_748b, - ); - scroll_buttons(ui, &mut words); - words -} - -fn message_reader_draw_list( - ui: &Ui, - state: &DeviceState, - reader: Option<&MessageReader>, - telemetry: SystemTelemetry, -) -> Vec { - let mut words = base_words(ui, state, "< MESSAGE READER", telemetry); - let Some(reader) = reader else { - push_text( - ui, - &mut words, - "NO MESSAGE SELECTED", - 64, - 240, - 30, - 0xff64_748b, - ); - return words; - }; - - rect(&mut words, 24, 132, 584, 82, 0xffff_ffff); - rect( - &mut words, - 40, - 154, - if reader.author == "YOU" { 82 } else { 62 }, - 42, - if reader.author == "YOU" { - 0xffdb_eafe - } else { - 0xffdc_fce7 - }, - ); - push_text_bold( - ui, - &mut words, - reader.author, - 54, - 166, - 8, - if reader.author == "YOU" { - 0xff1d_4ed8 - } else { - 0xff04_7a55 - }, - ); - - rect(&mut words, 24, 228, 584, 900, 0xffff_ffff); - let max_scroll = reader.lines.len().saturating_sub(MESSAGE_VISIBLE_LINES); - let offset = reader.line_offset.min(max_scroll); - let visible = reader - .lines - .iter() - .skip(offset) - .take(MESSAGE_VISIBLE_LINES) - .cloned() - .collect::>() - .join("\n"); - push_text_limited( - ui, - &mut words, - &visible, - 44, - 248, - 32, - MESSAGE_VISIBLE_LINES, - 0xff0f_172a, - ); - push_text( - ui, - &mut words, - &format!( - "LINES {}-{} / {}", - offset + 1, - (offset + MESSAGE_VISIBLE_LINES).min(reader.lines.len()), - reader.lines.len() - ), - 40, - 1138, - 32, - 0xff64_748b, - ); - scroll_buttons(ui, &mut words); - words -} - -fn bottom_bar(ui: &Ui, words: &mut Vec, active: ScreenView) { - rect(words, 0, BOTTOM_BAR_Y, PANEL_WIDTH, 108, 0xff0f_172a); - for (x, label, view) in [ - (10, "CHAT", ScreenView::Chat), - (250, "FILES", ScreenView::Files), - (490, "SETTINGS", ScreenView::Settings), - ] { - rect( - words, - x, - BOTTOM_BAR_Y + 16, - 220, - 76, - if active == view { - 0xff25_63eb - } else { - 0xff1e_293b - }, - ); - let label_x = x + (220 - label.len() as i16 * 12) / 2; - push_text_bold(ui, words, label, label_x, BOTTOM_BAR_Y + 44, 8, 0xffff_ffff); - } -} - -fn chat_scroll_buttons(ui: &Ui, words: &mut Vec) { - // Align the top edge with the first chat card at y=140. - rect(words, 628, 140, 68, 132, 0xffdb_eafe); - push_text_bold(ui, words, "UP", 646, 194, 4, 0xff1d_4ed8); - rect(words, 628, 624, 68, 132, 0xffdb_eafe); - push_text_bold(ui, words, "DN", 646, 678, 4, 0xff1d_4ed8); -} - -fn scroll_buttons(ui: &Ui, words: &mut Vec) { - rect(words, 628, 190, 68, 132, 0xffdb_eafe); - push_text_bold(ui, words, "UP", 646, 244, 4, 0xff1d_4ed8); - rect(words, 628, 940, 68, 132, 0xffdb_eafe); - push_text_bold(ui, words, "DN", 646, 994, 4, 0xff1d_4ed8); -} - -fn rect(words: &mut Vec, x: i16, y: i16, width: u16, height: u16, color: u32) { - words.extend_from_slice(&[spec::draw_op::RECT, xy(x, y), wh(width, height), color]); -} - -fn push_text( - ui: &Ui, - words: &mut Vec, - text: &str, - x: i16, - y: i16, - max_columns: usize, - color: u32, -) { - push_text_limited(ui, words, text, x, y, max_columns, 20, color); -} - -fn push_text_right(ui: &Ui, words: &mut Vec, text: &str, right: i16, y: i16, color: u32) { - let width = font::text_width(ui, text, font::TextStyle::Body); - push_text(ui, words, text, right - width, y, text.len(), color); -} - -fn push_text_bold( - ui: &Ui, - words: &mut Vec, - text: &str, - x: i16, - y: i16, - max_columns: usize, - color: u32, -) { - font::append_text( - ui, - words, - text, - x, - y, - max_columns, - 20, - color, - font::TextStyle::Bold, - ); -} - -fn push_title( - ui: &Ui, - words: &mut Vec, - text: &str, - x: i16, - y: i16, - max_columns: usize, - color: u32, -) { - font::append_text( - ui, - words, - text, - x, - y, - max_columns, - 1, - color, - font::TextStyle::Title, - ); -} - -fn push_text_limited( - ui: &Ui, - words: &mut Vec, - text: &str, - x: i16, - y: i16, - max_columns: usize, - max_rows: usize, - color: u32, -) { - font::append_text( - ui, - words, - text, - x, - y, - max_columns, - max_rows, - color, - font::TextStyle::Body, - ); -} - -const fn agent_state_color(state: AgentState) -> u32 { - match state { - AgentState::Stopped => 0xff64_748b, - AgentState::Starting | AgentState::WaitingForAuth => 0xfff5_9e0b, - AgentState::Idle | AgentState::Thinking | AgentState::Acting => 0xff10_b981, - AgentState::NetworkBlocked | AgentState::Faulted => UI_LOSS_RED, - } -} - -const fn xy(x: i16, y: i16) -> u32 { - x as u16 as u32 | ((y as u16 as u32) << 16) -} - -const fn wh(width: u16, height: u16) -> u32 { - width as u32 | ((height as u32) << 16) -} diff --git a/crates/pocket-pi-device-ui/src/screen/workspace_browser.rs b/crates/pocket-pi-device-ui/src/screen/workspace_browser.rs deleted file mode 100644 index ffae28f..0000000 --- a/crates/pocket-pi-device-ui/src/screen/workspace_browser.rs +++ /dev/null @@ -1,325 +0,0 @@ -use std::fs; -use std::path::{Path, PathBuf}; -use std::time::UNIX_EPOCH; - -const MAX_VIEWER_BYTES: u64 = 256 * 1024; -const VIEWER_COLUMNS: usize = 32; - -#[derive(Clone, Debug)] -pub struct FileEntry { - pub name: String, - pub is_dir: bool, - pub size: u64, - pub timestamp: Option, -} - -#[derive(Clone, Copy, Debug)] -pub struct FileTimestamp { - pub unix_seconds: u64, - kind: TimestampKind, -} - -#[derive(Clone, Copy, Debug)] -enum TimestampKind { - Created, - Updated, - Contents, -} - -#[derive(Clone, Debug)] -pub struct OpenFile { - pub relative_path: String, - pub size: u64, - pub timestamp: Option, - pub lines: Vec, - pub line_offset: usize, -} - -#[derive(Debug)] -pub struct WorkspaceBrowser { - root: PathBuf, - current_dir: PathBuf, - pub entries: Vec, - pub list_offset: usize, - pub open_file: Option, - pub status: Option, -} - -impl WorkspaceBrowser { - pub fn new(root: impl Into) -> Self { - Self { - root: root.into(), - current_dir: PathBuf::new(), - entries: Vec::new(), - list_offset: 0, - open_file: None, - status: None, - } - } - - pub fn current_path(&self) -> String { - if self.current_dir.as_os_str().is_empty() { - "/workspace".to_owned() - } else { - format!("/workspace/{}", path_text(&self.current_dir)) - } - } - - pub fn can_go_up(&self) -> bool { - !self.current_dir.as_os_str().is_empty() - } - - pub fn refresh(&mut self) { - self.status = None; - let directory = self.root.join(&self.current_dir); - let read_dir = match fs::read_dir(&directory) { - Ok(entries) => entries, - Err(error) => { - self.status = Some(format!("CANNOT READ DIRECTORY: {error}")); - self.entries.clear(); - return; - } - }; - let mut entries = Vec::new(); - for entry in read_dir.flatten() { - let name = entry.file_name().to_string_lossy().into_owned(); - if hidden_internal_name(&name) { - continue; - } - let Ok(metadata) = entry.metadata() else { - continue; - }; - let path = entry.path(); - entries.push(FileEntry { - name, - is_dir: metadata.is_dir(), - size: if metadata.is_file() { - metadata.len() - } else { - 0 - }, - timestamp: entry_timestamp(&path, &metadata), - }); - } - entries.sort_by(|left, right| { - right - .is_dir - .cmp(&left.is_dir) - .then_with(|| left.name.to_lowercase().cmp(&right.name.to_lowercase())) - }); - self.entries = entries; - self.list_offset = self.list_offset.min(self.entries.len().saturating_sub(1)); - } - - pub fn go_up(&mut self) { - if self.current_dir.pop() { - self.list_offset = 0; - self.refresh(); - } - } - - pub fn activate_visible_row(&mut self, row: usize) -> bool { - let Some(entry) = self.entries.get(self.list_offset + row).cloned() else { - return false; - }; - if entry.is_dir { - self.current_dir.push(&entry.name); - self.list_offset = 0; - self.refresh(); - return true; - } - self.open(&entry); - self.open_file.is_some() - } - - pub fn scroll_list(&mut self, delta: isize, visible_rows: usize) { - let maximum = self.entries.len().saturating_sub(visible_rows); - self.list_offset = self.list_offset.saturating_add_signed(delta).min(maximum); - } - - pub fn scroll_file(&mut self, delta: isize, visible_lines: usize) { - if let Some(file) = self.open_file.as_mut() { - let maximum = file.lines.len().saturating_sub(visible_lines); - file.line_offset = file.line_offset.saturating_add_signed(delta).min(maximum); - } - } - - pub fn close_file(&mut self) { - self.open_file = None; - self.refresh(); - } - - fn open(&mut self, entry: &FileEntry) { - self.status = None; - let relative = self.current_dir.join(&entry.name); - let path = self.root.join(&relative); - if entry.size > MAX_VIEWER_BYTES { - self.status = Some(format!("FILE TOO LARGE: {}", format_size(entry.size))); - return; - } - match fs::read_to_string(&path) { - Ok(content) => { - self.open_file = Some(OpenFile { - relative_path: path_text(&relative), - size: entry.size, - timestamp: entry.timestamp, - lines: wrap_text(&content, VIEWER_COLUMNS), - line_offset: 0, - }); - } - Err(error) => { - self.status = Some(format!("CANNOT OPEN TEXT FILE: {error}")); - } - } - } -} - -fn entry_timestamp(path: &Path, metadata: &fs::Metadata) -> Option { - file_timestamp(metadata).or_else(|| { - metadata.is_dir().then(|| { - let mut remaining = 256; - newest_descendant_timestamp(path, 0, &mut remaining).map(|timestamp| FileTimestamp { - unix_seconds: timestamp.unix_seconds, - kind: TimestampKind::Contents, - }) - })? - }) -} - -fn newest_descendant_timestamp( - directory: &Path, - depth: usize, - remaining: &mut usize, -) -> Option { - if depth >= 8 || *remaining == 0 { - return None; - } - let mut newest = None; - for entry in fs::read_dir(directory).ok()?.flatten() { - if *remaining == 0 { - break; - } - *remaining -= 1; - let name = entry.file_name().to_string_lossy().into_owned(); - if hidden_internal_name(&name) { - continue; - } - let Ok(metadata) = entry.metadata() else { - continue; - }; - let candidate = file_timestamp(&metadata).or_else(|| { - metadata - .is_dir() - .then(|| newest_descendant_timestamp(&entry.path(), depth + 1, remaining))? - }); - if candidate.is_some_and(|candidate| { - newest - .is_none_or(|current: FileTimestamp| candidate.unix_seconds > current.unix_seconds) - }) { - newest = candidate; - } - } - newest -} - -fn hidden_internal_name(name: &str) -> bool { - name == ".pi-agent" || (name.starts_with(".ppi-") && name.ends_with(".tmp")) -} - -fn file_timestamp(metadata: &fs::Metadata) -> Option { - if let Ok(created) = metadata.created() { - if let Ok(duration) = created.duration_since(UNIX_EPOCH) { - let seconds = duration.as_secs(); - if valid_wall_clock(seconds) { - return Some(FileTimestamp { - unix_seconds: seconds, - kind: TimestampKind::Created, - }); - } - } - } - // LittleFS primarily exposes mtime. Some VFS versions return a zero/epoch - // creation time even when the modification time is valid, so creation must - // not prevent this fallback. - let seconds = metadata - .modified() - .ok()? - .duration_since(UNIX_EPOCH) - .ok()? - .as_secs(); - valid_wall_clock(seconds).then_some(FileTimestamp { - unix_seconds: seconds, - kind: TimestampKind::Updated, - }) -} - -fn valid_wall_clock(seconds: u64) -> bool { - // An ESP32 without SNTP commonly starts at the Unix epoch. Do not present - // that as a real file date. - seconds >= 1_577_836_800 -} - -fn wrap_text(content: &str, columns: usize) -> Vec { - let mut output = Vec::new(); - for physical_line in content.replace('\r', "").split('\n') { - let characters = physical_line.chars().collect::>(); - if characters.is_empty() { - output.push(String::new()); - continue; - } - for chunk in characters.chunks(columns) { - output.push(chunk.iter().collect()); - } - } - if output.is_empty() { - output.push(String::new()); - } - output -} - -pub fn format_size(bytes: u64) -> String { - if bytes < 1024 { - format!("{bytes} B") - } else if bytes < 1024 * 1024 { - format!("{} KB", bytes.div_ceil(1024)) - } else { - format!("{} MB", bytes.div_ceil(1024 * 1024)) - } -} - -pub fn format_timestamp(timestamp: Option) -> String { - let Some(timestamp) = timestamp else { - return "TIME UNKNOWN".to_owned(); - }; - let seconds = timestamp.unix_seconds as i64; - let days = seconds.div_euclid(86_400); - let seconds_of_day = seconds.rem_euclid(86_400); - let (year, month, day) = civil_from_days(days); - let hour = seconds_of_day / 3_600; - let minute = (seconds_of_day % 3_600) / 60; - let label = match timestamp.kind { - TimestampKind::Created => "CREATED", - TimestampKind::Updated => "UPDATED", - TimestampKind::Contents => "CONTENTS", - }; - format!("{label} {year:04}-{month:02}-{day:02} {hour:02}:{minute:02}Z") -} - -fn civil_from_days(days_since_epoch: i64) -> (i64, i64, i64) { - let z = days_since_epoch + 719_468; - let era = if z >= 0 { z } else { z - 146_096 } / 146_097; - let day_of_era = z - era * 146_097; - let year_of_era = - (day_of_era - day_of_era / 1_460 + day_of_era / 36_524 - day_of_era / 146_096) / 365; - let mut year = year_of_era + era * 400; - let day_of_year = day_of_era - (365 * year_of_era + year_of_era / 4 - year_of_era / 100); - let month_prime = (5 * day_of_year + 2) / 153; - let day = day_of_year - (153 * month_prime + 2) / 5 + 1; - let month = month_prime + if month_prime < 10 { 3 } else { -9 }; - year += i64::from(month <= 2); - (year, month, day) -} - -fn path_text(path: &Path) -> String { - path.to_string_lossy().replace('\\', "/") -} diff --git a/crates/pocket-pi-embedded/Cargo.toml b/crates/pocket-pi-embedded/Cargo.toml index ee5c22d..2d7c78f 100644 --- a/crates/pocket-pi-embedded/Cargo.toml +++ b/crates/pocket-pi-embedded/Cargo.toml @@ -7,5 +7,6 @@ repository.workspace = true description = "Small pi-agent-core runtime for embedded Pocket Pi hosts" [dependencies] +pocket-mod.workspace = true rquickjs = { version = "=0.12.1", default-features = false, features = ["bindgen", "std"] } serde_json.workspace = true diff --git a/crates/pocket-pi-embedded/js/env.d.ts b/crates/pocket-pi-embedded/js/env.d.ts index e0ee54d..776d4ef 100644 --- a/crates/pocket-pi-embedded/js/env.d.ts +++ b/crates/pocket-pi-embedded/js/env.d.ts @@ -1,8 +1,9 @@ declare global { var host: | { - modelComplete(request: string): string; - tool(callId: string, name: string, args: string): string; + startModel(request: string): number; + startTool(callId: string, name: string, args: string): number; + poll(): string; } | undefined; var PocketPiEmbedded: @@ -10,6 +11,7 @@ declare global { boot(config: string): void; prompt(text: string): void; abort(): void; + tick(): void; drain(): string; } | undefined; diff --git a/crates/pocket-pi-embedded/js/pi-agent.bundle.js b/crates/pocket-pi-embedded/js/pi-agent.bundle.js index d9fb098..ffd4260 100644 --- a/crates/pocket-pi-embedded/js/pi-agent.bundle.js +++ b/crates/pocket-pi-embedded/js/pi-agent.bundle.js @@ -384,11 +384,16 @@ if(this.activeRun){throw new Error("Agent is already processing.")}const abortCo const failureMessage={role:"assistant",content:[{type:"text",text:""}],api:this._state.model.api,provider:this._state.model.provider,model:this._state.model.id,usage:EMPTY_USAGE,stopReason:aborted?"aborted":"error",errorMessage:error instanceof Error?error.message:String(error),timestamp:Date.now()};await this.processEvents({type:"message_start",message:failureMessage});await this.processEvents({type:"message_end",message:failureMessage});await this.processEvents({type:"turn_end",message:failureMessage, toolResults:[]});await this.processEvents({type:"agent_end",messages:[failureMessage]})}finishRun(){this._state.isStreaming=false;this._state.streamingMessage=void 0;this._state.pendingToolCalls=new Set;this.activeRun?.resolve();this.activeRun=void 0}async processEvents(event){switch(event.type){case"message_start":this._state.streamingMessage=event.message;break;case"message_update":this._state.streamingMessage=event.message;break;case"message_end":this._state.streamingMessage=void 0;this._state. messages.push(event.message);break;case"tool_execution_start":{const pendingToolCalls=new Set(this._state.pendingToolCalls);pendingToolCalls.add(event.toolCallId);this._state.pendingToolCalls=pendingToolCalls;break}case"tool_execution_end":{const pendingToolCalls=new Set(this._state.pendingToolCalls);pendingToolCalls.delete(event.toolCallId);this._state.pendingToolCalls=pendingToolCalls;break}case"turn_end":if(event.message.role==="assistant"&&event.message.errorMessage){this._state.errorMessage= -event.message.errorMessage}break;case"agent_end":this._state.streamingMessage=void 0;break}const signal=this.activeRun?.abortController.signal;if(!signal){throw new Error("Agent listener invoked outside active run")}for(const listener of this.listeners){await listener(event,signal)}}};var events=[];var agent=null;var emptyUsage=()=>({input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}});function modelFor(config){const provider=config.provider||"openai";return{id:config.model||"gpt-5-mini",name:config.model||"gpt-5-mini",provider,api:provider==="anthropic"?"anthropic-messages":"openai-responses",baseUrl:provider==="anthropic"?"https://api.anthropic.com":"https://api.openai.com/v1",reasoning:false,input:["text"],cost:{ -input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:128e3,maxTokens:1024}}function hostStream(model,context){const stream=new AssistantMessageEventStream;queueMicrotask(()=>{try{const result=JSON.parse(globalThis.host?.modelComplete(JSON.stringify({model,context}))||"{}");const partial={role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,usage:emptyUsage(),stopReason:result.stopReason||"stop",timestamp:Date.now()};stream.push({type:"start",partial});if(result.toolCall){ -const toolCall={type:"toolCall",id:result.toolCall.id||`tool_${Date.now()}`,name:result.toolCall.name,arguments:result.toolCall.arguments||{}};partial.content=[toolCall];partial.stopReason="toolUse";stream.push({type:"toolcall_start",contentIndex:0,partial:{...partial}});stream.push({type:"toolcall_end",contentIndex:0,toolCall,partial:{...partial}});stream.push({type:"done",reason:"toolUse",message:{...partial}})}else{const text=String(result.text||"");partial.content=[{type:"text",text}];stream. -push({type:"text_start",contentIndex:0,partial:{...partial}});stream.push({type:"text_delta",contentIndex:0,delta:text,partial:{...partial}});stream.push({type:"text_end",contentIndex:0,content:text,partial:{...partial}});stream.push({type:"done",reason:partial.stopReason,message:{...partial}})}}catch(error){stream.push({type:"error",reason:"error",error:{role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,usage:emptyUsage(),stopReason:"error",errorMessage:String(error), -timestamp:Date.now()}})}});return stream}function boot(configJson){const config=JSON.parse(configJson);const model=modelFor(config);const tools=(config.tools||[]).map(tool=>({name:tool.name,label:tool.label||tool.name,description:tool.description||"",parameters:tool.parameters||{type:"object",properties:{}},executionMode:"sequential",execute:async(id,args)=>{const result=JSON.parse(globalThis.host?.tool(id,tool.name,JSON.stringify(args||{}))||JSON.stringify({text:`tool unavailable: ${tool.name}`, -isError:true}));if(result.isError)throw new Error(String(result.text||`tool failed: ${tool.name}`));return{content:[{type:"text",text:String(result.text||"")}],details:result.details,terminate:Boolean(result.terminate)}}}));agent=new Agent({initialState:{systemPrompt:config.systemPrompt||"You are Pocket Pi running on an embedded device.",model,thinkingLevel:"off",tools},streamFn:hostStream,toolExecution:"sequential"});agent.subscribe(event=>{const compact={type:event.type};if(event.type==="messa\ -ge_update"){compact.kind=event.assistantMessageEvent?.type;compact.delta=event.assistantMessageEvent?.delta}else if(event.type==="message_end"){compact.role=event.message?.role;compact.stopReason=event.message?.stopReason}else if(event.type==="tool_execution_start"||event.type==="tool_execution_end"){compact.name=event.toolName;compact.toolCallId=event.toolCallId;compact.isError=Boolean(event.isError)}events.push(compact)});events.push({type:"agent_ready"})}function prompt(text){if(!agent)throw new Error( -"prompt before boot");void agent.prompt(text).catch(error=>events.push({type:"agent_error",message:String(error)}))}function abort(){agent?.abort()}function drain(){return JSON.stringify({phase:agent?.state.isStreaming?"thinking":agent?"ready":"idle",messages:agent?.state.messages.length||0,events:events.splice(0,events.length)})}globalThis.PocketPiEmbedded={boot,prompt,abort,drain};})(); +event.message.errorMessage}break;case"agent_end":this._state.streamingMessage=void 0;break}const signal=this.activeRun?.abortController.signal;if(!signal){throw new Error("Agent listener invoked outside active run")}for(const listener of this.listeners){await listener(event,signal)}}};var events=[];var pendingModels=new Map;var pendingTools=new Map;var agent=null;var emptyUsage=()=>({input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}});function modelFor(config){const provider=config.provider||"openai";return{id:config.model||"gpt-5-mini",name:config.model||"gpt-5-mini",provider,api:provider==="anthropic"?"anthropic-messages":"openai-responses",baseUrl:provider==="anthropic"?"https://api.anthropic.com":"https://api.\ +openai.com/v1",reasoning:false,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:128e3,maxTokens:1024}}function hostStream(model,context){const stream=new AssistantMessageEventStream;const partial={role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,usage:emptyUsage(),stopReason:"stop",timestamp:Date.now()};try{if(!globalThis.host)throw new Error("Pocket Pi Agent host is unavailable");const id=globalThis.host.startModel(JSON.stringify({model, +context}));pendingModels.set(id,{stream,model,partial,started:false,textStarted:false,text:""})}catch(error){pushModelError(stream,model,String(error))}return stream}function ensureModelStarted(pending){if(pending.started)return;pending.started=true;pending.stream.push({type:"start",partial:{...pending.partial}})}function pushModelDelta(pending,delta){ensureModelStarted(pending);if(!pending.textStarted){pending.textStarted=true;pending.stream.push({type:"text_start",contentIndex:0,partial:{...pending. +partial}})}pending.text+=delta;pending.partial.content=[{type:"text",text:pending.text}];pending.stream.push({type:"text_delta",contentIndex:0,delta,partial:{...pending.partial}})}function finishModel(pending,result){ensureModelStarted(pending);pending.partial.stopReason=result.stopReason||"stop";if(result.toolCall){const toolCall={type:"toolCall",id:result.toolCall.id||`tool_${Date.now()}`,name:result.toolCall.name,arguments:result.toolCall.arguments||{}};pending.partial.content=[toolCall];pending. +partial.stopReason="toolUse";pending.stream.push({type:"toolcall_start",contentIndex:0,partial:{...pending.partial}});pending.stream.push({type:"toolcall_end",contentIndex:0,toolCall,partial:{...pending.partial}});pending.stream.push({type:"done",reason:"toolUse",message:{...pending.partial}});return}const finalText=String(result.text||pending.text);if(!pending.textStarted||finalText!==pending.text){const delta=finalText.startsWith(pending.text)?finalText.slice(pending.text.length):finalText;if(delta) +pushModelDelta(pending,delta)}if(!pending.textStarted)pushModelDelta(pending,"");pending.text=finalText;pending.partial.content=[{type:"text",text:finalText}];pending.stream.push({type:"text_end",contentIndex:0,content:finalText,partial:{...pending.partial}});pending.stream.push({type:"done",reason:pending.partial.stopReason,message:{...pending.partial}})}function pushModelError(stream,model,message){stream.push({type:"error",reason:"error",error:{role:"assistant",content:[],api:model.api,provider:model. +provider,model:model.id,usage:emptyUsage(),stopReason:"error",errorMessage:message,timestamp:Date.now()}})}function boot(configJson){const config=JSON.parse(configJson);const model=modelFor(config);const tools=(config.tools||[]).map(tool=>({name:tool.name,label:tool.label||tool.name,description:tool.description||"",parameters:tool.parameters||{type:"object",properties:{}},executionMode:"sequential",execute:(id,args)=>new Promise((resolve,reject)=>{try{if(!globalThis.host)throw new Error("Pocket \ +Pi Agent host is unavailable");const requestId=globalThis.host.startTool(id,tool.name,JSON.stringify(args||{}));pendingTools.set(requestId,{resolve,reject})}catch(error){reject(error instanceof Error?error:new Error(String(error)))}})}));agent=new Agent({initialState:{systemPrompt:config.systemPrompt||"You are Pocket Pi running on an embedded device.",model,thinkingLevel:"off",tools},streamFn:hostStream,toolExecution:"sequential"});agent.subscribe(event=>{const compact={type:event.type};if(event. +type==="message_update"){compact.kind=event.assistantMessageEvent?.type;compact.delta=event.assistantMessageEvent?.delta}else if(event.type==="message_end"){compact.role=event.message?.role;compact.stopReason=event.message?.stopReason}else if(event.type==="tool_execution_start"||event.type==="tool_execution_end"){compact.name=event.toolName;compact.toolCallId=event.toolCallId;compact.isError=Boolean(event.isError)}events.push(compact)});events.push({type:"agent_ready"})}function prompt(text){if(!agent) +throw new Error("prompt before boot");void agent.prompt(text).catch(error=>events.push({type:"agent_error",message:String(error)}))}function abort(){agent?.abort()}function tick(){const batch=JSON.parse(globalThis.host?.poll()||"[]");for(const event of batch){if(event.type==="model_delta"){const pending=pendingModels.get(event.id);if(pending)pushModelDelta(pending,String(event.delta||""))}else if(event.type==="model_done"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels. +delete(event.id);try{finishModel(pending,JSON.parse(event.result||"{}"))}catch(error){pushModelError(pending.stream,pending.model,String(error))}}else if(event.type==="model_error"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);pushModelError(pending.stream,pending.model,event.error)}else if(event.type==="tool_done"){const pending=pendingTools.get(event.id);if(!pending)continue;pendingTools.delete(event.id);try{const result=JSON.parse(event.result|| +"{}");if(result.isError)throw new Error(String(result.text||"App tool failed"));pending.resolve({content:[{type:"text",text:String(result.text||"")}],details:result.details,terminate:Boolean(result.terminate)})}catch(error){pending.reject(error instanceof Error?error:new Error(String(error)))}}}}function drain(){return JSON.stringify({phase:agent?.state.isStreaming?"thinking":agent?"ready":"idle",messages:agent?.state.messages.length||0,events:events.splice(0,events.length)})}globalThis.PocketPiEmbedded= +{boot,prompt,abort,tick,drain};})(); diff --git a/crates/pocket-pi-embedded/js/src/entry.ts b/crates/pocket-pi-embedded/js/src/entry.ts index 22f6966..6cf2d58 100644 --- a/crates/pocket-pi-embedded/js/src/entry.ts +++ b/crates/pocket-pi-embedded/js/src/entry.ts @@ -19,7 +19,27 @@ type ModelResult = { toolCall?: { id?: string; name: string; arguments?: Record }; }; +type HostEvent = + | { type: "model_delta"; id: number; delta: string } + | { type: "model_done"; id: number; result: string } + | { type: "model_error"; id: number; error: string } + | { type: "tool_done"; id: number; result: string }; + +type PendingModel = { + stream: AssistantMessageEventStream; + model: any; + partial: any; + started: boolean; + textStarted: boolean; + text: string; +}; + const events: unknown[] = []; +const pendingModels = new Map(); +const pendingTools = new Map< + number, + { resolve: (value: any) => void; reject: (error: Error) => void } +>(); let agent: Agent | null = null; const emptyUsage = () => ({ @@ -49,61 +69,103 @@ function modelFor(config: Config): any { function hostStream(model: any, context: any): AssistantMessageEventStream { const stream = new AssistantMessageEventStream(); - queueMicrotask(() => { - try { - const result = JSON.parse(globalThis.host?.modelComplete(JSON.stringify({ model, context })) || "{}") as ModelResult; - const partial: any = { - role: "assistant", - content: [], - api: model.api, - provider: model.provider, - model: model.id, - usage: emptyUsage(), - stopReason: result.stopReason || "stop", - timestamp: Date.now(), - }; - stream.push({ type: "start", partial }); - if (result.toolCall) { - const toolCall = { - type: "toolCall" as const, - id: result.toolCall.id || `tool_${Date.now()}`, - name: result.toolCall.name, - arguments: result.toolCall.arguments || {}, - }; - partial.content = [toolCall]; - partial.stopReason = "toolUse"; - stream.push({ type: "toolcall_start", contentIndex: 0, partial: { ...partial } }); - stream.push({ type: "toolcall_end", contentIndex: 0, toolCall, partial: { ...partial } }); - stream.push({ type: "done", reason: "toolUse", message: { ...partial } }); - } else { - const text = String(result.text || ""); - partial.content = [{ type: "text", text }]; - stream.push({ type: "text_start", contentIndex: 0, partial: { ...partial } }); - stream.push({ type: "text_delta", contentIndex: 0, delta: text, partial: { ...partial } }); - stream.push({ type: "text_end", contentIndex: 0, content: text, partial: { ...partial } }); - stream.push({ type: "done", reason: partial.stopReason, message: { ...partial } }); - } - } catch (error) { - stream.push({ - type: "error", - reason: "error", - error: { - role: "assistant", - content: [], - api: model.api, - provider: model.provider, - model: model.id, - usage: emptyUsage(), - stopReason: "error", - errorMessage: String(error), - timestamp: Date.now(), - }, - }); - } - }); + const partial: any = { + role: "assistant", + content: [], + api: model.api, + provider: model.provider, + model: model.id, + usage: emptyUsage(), + stopReason: "stop", + timestamp: Date.now(), + }; + try { + if (!globalThis.host) throw new Error("Pocket Pi Agent host is unavailable"); + const id = globalThis.host.startModel(JSON.stringify({ model, context })); + pendingModels.set(id, { + stream, + model, + partial, + started: false, + textStarted: false, + text: "", + }); + } catch (error) { + pushModelError(stream, model, String(error)); + } return stream; } +function ensureModelStarted(pending: PendingModel): void { + if (pending.started) return; + pending.started = true; + pending.stream.push({ type: "start", partial: { ...pending.partial } }); +} + +function pushModelDelta(pending: PendingModel, delta: string): void { + ensureModelStarted(pending); + if (!pending.textStarted) { + pending.textStarted = true; + pending.stream.push({ type: "text_start", contentIndex: 0, partial: { ...pending.partial } }); + } + pending.text += delta; + pending.partial.content = [{ type: "text", text: pending.text }]; + pending.stream.push({ + type: "text_delta", + contentIndex: 0, + delta, + partial: { ...pending.partial }, + }); +} + +function finishModel(pending: PendingModel, result: ModelResult): void { + ensureModelStarted(pending); + pending.partial.stopReason = result.stopReason || "stop"; + if (result.toolCall) { + const toolCall = { + type: "toolCall" as const, + id: result.toolCall.id || `tool_${Date.now()}`, + name: result.toolCall.name, + arguments: result.toolCall.arguments || {}, + }; + pending.partial.content = [toolCall]; + pending.partial.stopReason = "toolUse"; + pending.stream.push({ type: "toolcall_start", contentIndex: 0, partial: { ...pending.partial } }); + pending.stream.push({ type: "toolcall_end", contentIndex: 0, toolCall, partial: { ...pending.partial } }); + pending.stream.push({ type: "done", reason: "toolUse", message: { ...pending.partial } }); + return; + } + + const finalText = String(result.text || pending.text); + if (!pending.textStarted || finalText !== pending.text) { + const delta = finalText.startsWith(pending.text) ? finalText.slice(pending.text.length) : finalText; + if (delta) pushModelDelta(pending, delta); + } + if (!pending.textStarted) pushModelDelta(pending, ""); + pending.text = finalText; + pending.partial.content = [{ type: "text", text: finalText }]; + pending.stream.push({ type: "text_end", contentIndex: 0, content: finalText, partial: { ...pending.partial } }); + pending.stream.push({ type: "done", reason: pending.partial.stopReason, message: { ...pending.partial } }); +} + +function pushModelError(stream: AssistantMessageEventStream, model: any, message: string): void { + stream.push({ + type: "error", + reason: "error", + error: { + role: "assistant", + content: [], + api: model.api, + provider: model.provider, + model: model.id, + usage: emptyUsage(), + stopReason: "error", + errorMessage: message, + timestamp: Date.now(), + }, + }); +} + function boot(configJson: string): void { const config = JSON.parse(configJson) as Config; const model = modelFor(config); @@ -113,18 +175,16 @@ function boot(configJson: string): void { description: tool.description || "", parameters: tool.parameters || { type: "object", properties: {} }, executionMode: "sequential" as const, - execute: async (id: string, args: unknown) => { - const result = JSON.parse( - globalThis.host?.tool(id, tool.name, JSON.stringify(args || {})) || - JSON.stringify({ text: `tool unavailable: ${tool.name}`, isError: true }), - ); - if (result.isError) throw new Error(String(result.text || `tool failed: ${tool.name}`)); - return { - content: [{ type: "text" as const, text: String(result.text || "") }], - details: result.details, - terminate: Boolean(result.terminate), - }; - }, + execute: (id: string, args: unknown) => + new Promise((resolve, reject) => { + try { + if (!globalThis.host) throw new Error("Pocket Pi Agent host is unavailable"); + const requestId = globalThis.host.startTool(id, tool.name, JSON.stringify(args || {})); + pendingTools.set(requestId, { resolve, reject }); + } catch (error) { + reject(error instanceof Error ? error : new Error(String(error))); + } + }), })); agent = new Agent({ @@ -164,6 +224,45 @@ function abort(): void { agent?.abort(); } +function tick(): void { + const batch = JSON.parse(globalThis.host?.poll() || "[]") as HostEvent[]; + for (const event of batch) { + if (event.type === "model_delta") { + const pending = pendingModels.get(event.id); + if (pending) pushModelDelta(pending, String(event.delta || "")); + } else if (event.type === "model_done") { + const pending = pendingModels.get(event.id); + if (!pending) continue; + pendingModels.delete(event.id); + try { + finishModel(pending, JSON.parse(event.result || "{}") as ModelResult); + } catch (error) { + pushModelError(pending.stream, pending.model, String(error)); + } + } else if (event.type === "model_error") { + const pending = pendingModels.get(event.id); + if (!pending) continue; + pendingModels.delete(event.id); + pushModelError(pending.stream, pending.model, event.error); + } else if (event.type === "tool_done") { + const pending = pendingTools.get(event.id); + if (!pending) continue; + pendingTools.delete(event.id); + try { + const result = JSON.parse(event.result || "{}"); + if (result.isError) throw new Error(String(result.text || "App tool failed")); + pending.resolve({ + content: [{ type: "text" as const, text: String(result.text || "") }], + details: result.details, + terminate: Boolean(result.terminate), + }); + } catch (error) { + pending.reject(error instanceof Error ? error : new Error(String(error))); + } + } + } +} + function drain(): string { return JSON.stringify({ phase: agent?.state.isStreaming ? "thinking" : agent ? "ready" : "idle", @@ -172,4 +271,4 @@ function drain(): string { }); } -globalThis.PocketPiEmbedded = { boot, prompt, abort, drain }; +globalThis.PocketPiEmbedded = { boot, prompt, abort, tick, drain }; diff --git a/crates/pocket-pi-embedded/src/lib.rs b/crates/pocket-pi-embedded/src/lib.rs index 2baa5f8..96047a8 100644 --- a/crates/pocket-pi-embedded/src/lib.rs +++ b/crates/pocket-pi-embedded/src/lib.rs @@ -1,13 +1,12 @@ -use std::sync::{mpsc, Arc}; +use std::sync::atomic::{AtomicI32, Ordering}; +use std::sync::{mpsc, Arc, Mutex}; +use std::time::Duration; -use rquickjs::{CatchResultExt, Context, Function, Object, Runtime}; +use pocket_mod::qjs::{CatchResultExt, Function, Object}; +use pocket_mod::Guest; const AGENT_BUNDLE: &str = include_str!("../js/pi-agent.bundle.js"); const PRELUDE: &str = include_str!("../js/prelude.js"); -#[cfg(target_os = "espidf")] -const QUICKJS_STACK_LIMIT: usize = 96 * 1024; -#[cfg(not(target_os = "espidf"))] -const QUICKJS_STACK_LIMIT: usize = 512 * 1024; pub trait ModelBackend: Send + Sync { fn complete( @@ -33,55 +32,11 @@ pub struct ToolResult { #[derive(Clone, Debug, Eq, PartialEq)] pub enum AgentEvent { Ready, - Delta(String), + ResponseText(String), Done, Failed(String), } -pub fn spawn_agent_worker( - config_json: String, - backend: Arc, - tools: Arc, - stack_size: Option, -) -> Result<(mpsc::Sender, mpsc::Receiver), String> { - let (prompt_tx, prompt_rx) = mpsc::channel::(); - let (event_tx, event_rx) = mpsc::channel::(); - let mut builder = std::thread::Builder::new().name("pi-agent".to_owned()); - if let Some(stack_size) = stack_size { - builder = builder.stack_size(stack_size); - } - builder - .spawn(move || { - let delta_tx = event_tx.clone(); - let runtime = PiEmbedded::new( - &config_json, - backend, - tools, - Arc::new(move |delta| { - delta_tx.send(AgentEvent::Delta(delta)).ok(); - }), - ); - let runtime = match runtime { - Ok(runtime) => runtime, - Err(error) => { - event_tx.send(AgentEvent::Failed(error)).ok(); - return; - } - }; - event_tx.send(AgentEvent::Ready).ok(); - for prompt in prompt_rx { - let result = runtime.prompt(&prompt).and_then(|()| runtime.pump()); - let event = match result { - Ok(_) => AgentEvent::Done, - Err(error) => AgentEvent::Failed(error), - }; - event_tx.send(event).ok(); - } - }) - .map_err(|error| format!("spawn Pi Agent worker: {error}"))?; - Ok((prompt_tx, event_rx)) -} - impl ToolResult { pub fn text(text: impl Into) -> Self { Self { @@ -102,104 +57,295 @@ impl ToolResult { } } -pub struct PiEmbedded { - runtime: Runtime, - context: Context, +/// The Pi Agent half of the Pi Agent System App. +/// +/// This object does not own a QuickJS runtime. It mounts pi-agent-core into +/// the Root App's existing PocketJS Guest, so the Agent Loop, context, tools +/// and Root View have one App lifecycle. Slow model and tool work happens on +/// worker threads; `tick` only delivers completed events into the Guest. +pub struct GuestAgent { + events: mpsc::Receiver, } -impl PiEmbedded { - pub fn new( +impl GuestAgent { + pub fn mount( + guest: &Guest, config_json: &str, backend: Arc, tools: Arc, + ) -> Result { + Self::mount_source( + guest, + config_json, + backend, + tools, + AGENT_BUNDLE, + Arc::new(|_| {}), + ) + } + + pub fn mount_source( + guest: &Guest, + config_json: &str, + backend: Arc, + tools: Arc, + agent_source: &str, on_delta: Arc, ) -> Result { let config_json = config_with_tools(config_json, tools.definitions())?; - let runtime = Runtime::new().map_err(|error| error.to_string())?; - runtime.set_max_stack_size(QUICKJS_STACK_LIMIT); - let context = Context::full(&runtime).map_err(|error| error.to_string())?; - - context.with(|ctx| -> Result<(), String> { - let host = Object::new(ctx.clone()).map_err(|error| error.to_string())?; - host.set( - "modelComplete", - Function::new(ctx.clone(), move |request: String| -> String { - let mut emit = |delta: &str| on_delta(delta.to_owned()); - match backend.complete(&request, &mut emit) { - Ok(response) => response, - Err(error) => { - let text = format!("model backend failed: {error}"); - emit(&text); - serde_json::json!({"text":text}).to_string() - } - } - }) - .map_err(|error| error.to_string())?, - ) + let (host_tx, host_rx) = mpsc::channel::(); + let host_rx = Arc::new(Mutex::new(host_rx)); + let (event_tx, event_rx) = mpsc::channel::(); + let next_request = Arc::new(AtomicI32::new(1)); + + guest + .mount("host", { + let backend = backend.clone(); + let tools = tools.clone(); + move |ctx, host| { + host.set( + "startModel", + Function::new(ctx.clone(), { + let backend = backend.clone(); + let host_tx = host_tx.clone(); + let event_tx = event_tx.clone(); + let next_request = next_request.clone(); + let on_delta = on_delta.clone(); + move |request: String| -> i32 { + let id = next_request.fetch_add(1, Ordering::Relaxed); + let backend = backend.clone(); + let host_tx = host_tx.clone(); + let worker_tx = host_tx.clone(); + let event_tx = event_tx.clone(); + let on_delta = on_delta.clone(); + let spawn = std::thread::Builder::new() + .name(format!("pi-model-{id}")) + .spawn(move || { + // Providers may stream internally, but the embedded UI + // receives one complete text update per model request. + // Fine-grained deltas are prohibitively expensive on the + // ESP32 and add no value to the fixed Chat projection. + let mut buffered = String::new(); + let mut collect = |delta: &str| buffered.push_str(delta); + match backend.complete(&request, &mut collect) { + Ok(result) => { + let final_text = model_result_text(&result) + .or_else(|| (!buffered.is_empty()).then_some(buffered)); + if let Some(text) = final_text { + on_delta(text.clone()); + let _ = event_tx + .send(AgentEvent::ResponseText(text.clone())); + let _ = worker_tx.send(serde_json::json!({ + "type":"model_delta", + "id":id, + "delta":text, + })); + } + let _ = worker_tx.send(serde_json::json!({ + "type":"model_done", + "id":id, + "result":result, + })); + } + Err(error) => { + let _ = worker_tx.send(serde_json::json!({ + "type":"model_error", + "id":id, + "error":format!("model backend failed: {error}"), + })); + } + } + }); + if let Err(error) = spawn { + let _ = host_tx.send(serde_json::json!({ + "type":"model_error", + "id":id, + "error":format!("spawn model worker: {error}"), + })); + } + id + } + })?, + )?; + host.set( + "startTool", + Function::new(ctx.clone(), { + let tools = tools.clone(); + let host_tx = host_tx.clone(); + let next_request = next_request.clone(); + move |call_id: String, name: String, args: String| -> i32 { + let id = next_request.fetch_add(1, Ordering::Relaxed); + let tools = tools.clone(); + let host_tx = host_tx.clone(); + let worker_tx = host_tx.clone(); + let spawn = std::thread::Builder::new() + .name(format!("pi-tool-{id}")) + .spawn(move || { + let result = tools.execute(&call_id, &name, &args); + let _ = worker_tx.send(serde_json::json!({ + "type":"tool_done", + "id":id, + "result":result.to_json(), + })); + }); + if let Err(error) = spawn { + let result = ToolResult { + text: format!("spawn tool worker: {error}"), + is_error: true, + ..ToolResult::default() + }; + let _ = host_tx.send(serde_json::json!({ + "type":"tool_done", + "id":id, + "result":result.to_json(), + })); + } + id + } + })?, + )?; + host.set( + "poll", + Function::new(ctx.clone(), { + let host_rx = host_rx.clone(); + move || -> String { + let batch = host_rx + .lock() + .map(|receiver| receiver.try_iter().collect::>()) + .unwrap_or_default(); + serde_json::to_string(&batch).unwrap_or_else(|_| "[]".to_owned()) + } + })?, + )?; + Ok(()) + } + }) .map_err(|error| error.to_string())?; - host.set( - "tool", - Function::new( - ctx.clone(), - move |call_id: String, name: String, args: String| -> String { - tools.execute(&call_id, &name, &args).to_json() - }, - ) - .map_err(|error| error.to_string())?, - ) + + guest + .eval("pi-agent-prelude", PRELUDE) + .map_err(|error| error.to_string())?; + guest + .eval("pi-agent-core", agent_source) .map_err(|error| error.to_string())?; - ctx.globals() - .set("host", host) - .map_err(|error| error.to_string())?; - - ctx.eval::<(), _>(PRELUDE.as_bytes()) - .catch(&ctx) - .map_err(|error| format!("embedded prelude: {error}"))?; - ctx.eval::<(), _>(AGENT_BUNDLE.as_bytes()) - .catch(&ctx) - .map_err(|error| format!("embedded agent: {error}"))?; - let agent: Object = ctx - .globals() - .get("PocketPiEmbedded") - .map_err(|error| format!("PocketPiEmbedded missing: {error}"))?; - let boot: Function = agent.get("boot").map_err(|error| error.to_string())?; - boot.call::<_, ()>((config_json,)) - .catch(&ctx) - .map_err(|error| format!("embedded boot: {error}")) - })?; - - let runtime = Self { runtime, context }; - runtime.pump()?; - Ok(runtime) + call_agent::<_, ()>(guest, "boot", (config_json,))?; + guest.drain_jobs(); + + Ok(Self { events: event_rx }) + } + + pub fn prompt(&self, guest: &Guest, text: &str) -> Result<(), String> { + call_agent(guest, "prompt", (text.to_owned(),)) + } + + pub fn abort(&self, guest: &Guest) -> Result<(), String> { + call_agent(guest, "abort", ()) + } + + pub fn tick(&self, guest: &Guest) -> Result, String> { + call_agent::<_, ()>(guest, "tick", ())?; + guest.drain_jobs(); + let raw: String = call_agent(guest, "drain", ())?; + let payload: serde_json::Value = serde_json::from_str(&raw) + .map_err(|error| format!("parse Pi Agent events: {error}"))?; + let mut events = self.events.try_iter().collect::>(); + for event in payload["events"].as_array().into_iter().flatten() { + match event["type"].as_str() { + Some("agent_ready") => events.push(AgentEvent::Ready), + Some("agent_end") => events.push(AgentEvent::Done), + Some("agent_error") => events.push(AgentEvent::Failed( + event["message"] + .as_str() + .unwrap_or("Pi Agent failed") + .to_owned(), + )), + _ => {} + } + } + Ok(events) + } +} + +fn model_result_text(result: &str) -> Option { + let result = serde_json::from_str::(result).ok()?; + if result + .get("toolCall") + .is_some_and(serde_json::Value::is_object) + { + return None; + } + result + .get("text")? + .as_str() + .filter(|text| !text.is_empty()) + .map(str::to_owned) +} + +fn call_agent(guest: &Guest, name: &str, args: A) -> Result +where + A: for<'js> pocket_mod::qjs::function::IntoArgs<'js>, + R: for<'js> pocket_mod::qjs::FromJs<'js>, +{ + guest.with(|ctx| { + let agent: Object = ctx + .globals() + .get("PocketPiEmbedded") + .map_err(|error| format!("PocketPiEmbedded missing: {error}"))?; + let function: Function = agent.get(name).map_err(|error| error.to_string())?; + function + .call::<_, R>(args) + .catch(&ctx) + .map_err(|error| format!("PocketPiEmbedded.{name}: {error}")) + }) +} + +/// Standalone compatibility harness. Product hosts should mount `GuestAgent` +/// through `AppSupervisor`, which keeps the System App alive across View +/// navigation. +pub struct PiEmbedded { + guest: Guest, + agent: GuestAgent, +} + +impl PiEmbedded { + pub fn new( + config_json: &str, + backend: Arc, + tools: Arc, + on_delta: Arc, + ) -> Result { + let guest = Guest::new().map_err(|error| error.to_string())?; + let agent = + GuestAgent::mount_source(&guest, config_json, backend, tools, AGENT_BUNDLE, on_delta)?; + Ok(Self { guest, agent }) } pub fn prompt(&self, text: &str) -> Result<(), String> { - self.context.with(|ctx| { - let agent: Object = ctx - .globals() - .get("PocketPiEmbedded") - .map_err(|error| error.to_string())?; - let prompt: Function = agent.get("prompt").map_err(|error| error.to_string())?; - prompt - .call::<_, ()>((text.to_owned(),)) - .catch(&ctx) - .map_err(|error| format!("embedded prompt: {error}")) - }) + self.agent.prompt(&self.guest, text) } pub fn pump(&self) -> Result { - while self.runtime.is_job_pending() { - self.runtime - .execute_pending_job() - .map_err(|error| error.to_string())?; + let mut observed = Vec::new(); + loop { + self.guest.frame(0).map_err(|error| error.to_string())?; + let events = self.agent.tick(&self.guest)?; + let mut finished = false; + for event in events { + match event { + AgentEvent::Ready => observed.push("agent_ready"), + AgentEvent::ResponseText(_) => observed.push("message_update"), + AgentEvent::Done => { + observed.push("agent_end"); + finished = true; + } + AgentEvent::Failed(error) => return Err(error), + } + } + if finished { + return serde_json::to_string(&observed).map_err(|error| error.to_string()); + } + std::thread::sleep(Duration::from_millis(2)); } - self.context - .with(|ctx| { - let agent: Object = ctx.globals().get("PocketPiEmbedded")?; - let drain: Function = agent.get("drain")?; - drain.call::<_, String>(()) - }) - .map_err(|error| error.to_string()) } } @@ -243,6 +389,21 @@ mod tests { } } + struct BurstBackend; + + impl ModelBackend for BurstBackend { + fn complete( + &self, + _request_json: &str, + on_delta: &mut dyn FnMut(&str), + ) -> Result { + for _ in 0..100 { + on_delta("x"); + } + Ok(serde_json::json!({"text":"x".repeat(100)}).to_string()) + } + } + struct Tools; impl ToolHost for Tools { @@ -271,6 +432,16 @@ mod tests { assert_eq!(config["tools"].as_array().unwrap().len(), 1); } + #[test] + fn tool_call_results_do_not_emit_assistant_text() { + let result = serde_json::json!({ + "text":"provider preamble", + "toolCall":{"name":"echo","arguments":{}} + }) + .to_string(); + assert_eq!(model_result_text(&result), None); + } + #[test] fn boots_and_runs_a_real_pi_agent_turn() { let runtime = PiEmbedded::new( @@ -282,6 +453,41 @@ mod tests { .unwrap(); runtime.prompt("hello").unwrap(); let events = runtime.pump().unwrap(); - assert!(events.contains("message_end")); + assert!(events.contains("agent_end")); + } + + #[test] + fn model_deltas_are_coalesced_before_reaching_the_embedded_ui() { + let guest = Guest::new().unwrap(); + let agent = GuestAgent::mount( + &guest, + r#"{"model":"offline"}"#, + Arc::new(BurstBackend), + Arc::new(Tools), + ) + .unwrap(); + agent.prompt(&guest, "burst").unwrap(); + + let mut deltas = Vec::new(); + let mut done = false; + for _ in 0..200 { + let events = agent.tick(&guest).unwrap(); + for event in events { + match event { + AgentEvent::ResponseText(text) => deltas.push(text), + AgentEvent::Done => { + assert_eq!(deltas, ["x".repeat(100)]); + done = true; + } + _ => {} + } + } + if done { + break; + } + std::thread::sleep(Duration::from_millis(2)); + } + assert!(done); + assert_eq!(deltas, ["x".repeat(100)]); } } diff --git a/docs/agentos-architecture.md b/docs/agentos-architecture.md new file mode 100644 index 0000000..cc45aa6 --- /dev/null +++ b/docs/agentos-architecture.md @@ -0,0 +1,1068 @@ +# Pocket Pi AgentOS 架构设计 + +状态:架构基线 + v1 实现记录(以“常驻 Pi Agent System App”为当前实现)。 + +截至 2026-08-08,当前分支已经实现可运行的第一版:Pi Agent Root App、App +Supervisor、App Tool Catalog/Router、`AppTask` Schedule、`data.fs`、 +`data.sqlite`、后台 Data Action、revision-coalesced projection cache,以及 +Robinhood 和 Exa 两个 App。 +Simulator contract tests 已通过;常驻 System App refactor 已在 ESP32-P4 实机 +完成冷启动、LittleFS App 加载、Root View、MIPI-DSI/Touch 初始化、Agent Tool +Registry 启动和一次完整 UART model turn。运行中切换普通 App 的生命周期 contract +已有自动测试;实机触摸切换仍保留为发布前人工体验验收。 + +本文件同时保留最终架构约束。标为“待补齐”的部分不能因为 v1 已经能启动而 +被误认为已经完成。 + +## 1. 一句话结论 + +Pocket Pi 是一套面向 Agent 的本地 App Runtime:Rust 固件提供稳定的硬件和 +能力层;Pi Agent 拥有顶层 `/workspace`;每个 App 是一个预编译 PocketJS +Bundle,里面包含暴露给 Agent 的 Tools、内部 Tasks、Schedules、SQLite +数据和绑定这些数据的固定 View。 + +最短的理解方式是: + +```text +Firmware = 稳定机制 +Pi Agent = /workspace 的 owner + 特殊 System App +App = Public Tools + Data Actions + SQLite State + Cached Fixed View +``` + +这套设计要实现的 core goal 是:**Agent 不是固件外挂的聊天进程,而是 runtime +中拥有长期身份、顶层 workspace 和跨 App 能力的第一等 System App。** 用户切换 +View 或操作其他 App 时,Agent 的 turn、context 和 Tool execution 仍继续;切回 +Pi Agent 时看到的是同一个 session,而不是重新启动的 UI shell。 + +## 2. 设计目标 + +1. 完整保留当前 Pocket Pi 的 Agent、模型、workspace、schedule、设备和 + Settings 能力。 +2. Robinhood、Exa 等产品逻辑和 UI 不再进入通用 Rust 固件。 +3. App 可以给 Pi Agent 暴露 Tools,但不需要暴露内部表结构、凭据、网络协议 + 和 UI 实现。 +4. App 可以在本地按时运行任务,不需要每五分钟都唤醒模型。 +5. SQLite 是 App 数据的唯一持久化真相;成功写入后,正在显示的 View 自动 + 更新,但不能每帧轮询数据库。 +6. 普通 App 彼此隔离;Pi Agent 始终拥有整个 `/workspace`。 +7. 同一套 App 源码和 Module contract 可以在 macOS、模拟器、ESP32-P4 和 + 后续硬件上复用。 +8. Agent 工作与前台 View 导航解耦:模型/Tool 在运行时,触摸、键盘、切换 + Robinhood/Exa 和返回 Agent 都不能中断或重建 Agent。 + +## 3. 第一版明确不做什么 + +- 不做应用市场和远程分发协议。 +- ESP32 不修改 App/Root View 源码,不编译 PocketJS Bundle。 +- 不做 Agent 动态创建 Tools 或 workflow interpreter。 +- Tool 变化后可以 reload Agent session,不要求 live hot-plug。 +- ESP32 不提供通用 POSIX shell、进程、多用户或桌面式多任务。 +- 凭据永远不直接暴露给 App 或模型。 +- 不自动把上游 MCP `tools/list` 的所有 Tool 暴露给模型。 + +合法 Bundle 怎么进入 `/workspace/apps/` 不属于本架构。第一版可以预装,也 +可以通过 Mac 开发/部署路径复制。这里定义“如何加载和运行”,不定义“如何 +分发”。 + +## 4. 核心概念 + +### 4.1 Firmware / Runtime + +受信任的 Rust 代码,负责: + +- 硬件驱动; +- QuickJS 生命周期; +- PocketJS UI core 和渲染; +- SQLite 和文件系统挂载; +- 模型、网络、MCP、凭据; +- Scheduler; +- App 加载、隔离和路由; +- 资源限制与恢复。 + +Firmware 只提供机制,不包含 Robinhood、Exa、Weather 等产品逻辑。 + +### 4.2 Pi Agent Root Runtime + +Pi Agent 不在 `/workspace/apps/` 下。它的 home 和文件权限根就是 +`/workspace`。 + +它同时也是一个特殊 System App:选择它时,板子显示它的 PocketJS Root +View;打开其他 App 后,它可以继续在后台等待模型、Tool 或 Agent Schedule。 + +它不是两个拼接起来的 runtime。`pi-agent-core` Agent Loop、context、Tool +Registry 与 Root View 必须挂载在**同一个 PocketJS Guest**,共同构成一个 +`pi-agent` App instance。App Supervisor 在启动时创建一次这个 instance,并 +保持到系统关机或明确的 System App restart。 + +`foreground App` 只是“当前哪个 View 产生 DrawList、接收触摸”的选择,不是 +Agent 的生命周期开关。打开普通 App 不得 drop、reload 或 reset Pi Agent +Guest,也不得清空 conversation、pending model request 或 pending Tool call。 + +### 4.3 App + +一个 App 是一个独立版本单元: + +```text +Public Tools Agent 能看到的名称、描述和 JSON Schema +Data Actions Tool、Schedule、UI refresh 共用的后台数据入口 +SQLite State App 自己的唯一持久化业务真相 +Fixed View SQLite bounded projection 的内存 cache + PocketJS UI +``` + +“Fixed View”只表示当前 release 内固定,不表示写死在 Rust 固件里。 + +### 4.4 Native Module + +Native Module 用固定 spec 把一个受限 Rust 能力挂载给 QuickJS Guest。 + +PocketJS 已经定义了 `ui`、`data.sqlite`、`data.fs` 的 Module 形状。 +Pocket Pi 再补充 model、net、MCP、schedule、shell、device Settings 和 App +lifecycle。 + +### 4.5 Runtime instance + +Pi Agent System App 的 Agent Loop 和 Root View 共用一个常驻 QuickJS Guest。 +普通 App 则可以有两个互不等待的 execution context:一个 foreground View Guest, +以及一个按需创建的 headless Data Action Guest。schema 变化时,Supervisor 先依据 +App descriptor 的 `dataVersion` 删除该 App 的旧 SQLite file;View 可以立即打开空库, +version guard 不执行任何业务 query。第一次 Tool/Schedule 再在后台初始化新 schema, +不阻塞 UI。二者共享同一个 App-owned +`DbModule` owner、同一个 SQLite 文件和同一个内存 revision counter,但不共享 +网络调用栈或 View reactive state。 + +慢模型、HTTP/MCP 和 Data Action 不在 UI tick 或 touch callback 内执行。Native +只拥有 transport、credential 和 SQLite primitive;App 的 provider mapping、 +完整 response-body 解析和 transaction 仍由 JS/TS Data Action 拥有。View Guest +从不拿网络 response,也不写业务表。 + +## 5. High-level 架构 + +```mermaid +flowchart TB + HW["硬件
Display · Touch · Wi-Fi · Flash · Clock"] + + subgraph FW["Firmware / Pocket AgentOS Runtime"] + DRIVERS["Platform Drivers"] + HOST["App Supervisor
System App lifetime + foreground selection"] + TOOLCAT["Tool Catalog + Router"] + SCHED["Native Scheduler"] + DATA["App Data Action Runner
headless JS/TS"] + REV["Per-App revision
frame-boundary coalescing"] + CONTEXT["Context Assembler"] + QJS["Runtime Manager
多个隔离 Runtime instance"] + RENDER["PocketJS UI Core + Renderer"] + + subgraph MODS["Native Modules"] + UI["ui"] + DB["data.sqlite"] + FS["data.fs"] + NET["net.http"] + MCP["mcp.client"] + MODEL["model.stream"] + SHELL["shell.bounded"] + DEVICE["device.settings"] + end + end + + subgraph ROOT["/workspace — Pi Agent 拥有"] + AGENT["常驻 Pi Agent System App
同一个 Guest: Agent Loop + Root View"] + AGENTDB["data/agent.sqlite"] + ROOTFILES["AGENTS.md · strategy.md · memory/"] + end + + subgraph APPS["/workspace/apps/"] + APP1["Robinhood Bundle
Tools · Data Actions · Schedules · View"] + CACHE1["View projection cache
Solid signals"] + APP1DB["robinhood/data/robinhood.sqlite"] + APP2["Other App Bundle"] + APP2DB["other/data/app.sqlite"] + end + + HW --> DRIVERS + DRIVERS --> HOST + HOST --> QJS + HOST --> RENDER + HOST --> TOOLCAT + HOST --> SCHED + HOST --> DATA + + QJS -->|"一个 QuickJS Guest"| AGENT + QJS -->|"一个 QuickJS Guest"| APP1 + QJS -->|"一个 QuickJS Guest"| APP2 + MODS --> AGENT + MODS --> APP1 + MODS --> APP2 + + ROOTFILES --> CONTEXT + CONTEXT --> AGENT + AGENT --> AGENTDB + APP1 --> APP1DB + DATA --> APP1DB + DATA --> REV + REV -->|"foreground + stale"| CACHE1 + CACHE1 --> APP1 + APP2 --> APP2DB + + AGENT --> TOOLCAT + TOOLCAT --> HOST + SCHED --> HOST + AGENT -->|"Root 被选中时"| RENDER + APP1 -->|"被选中时"| RENDER + RENDER --> HW +``` + +## 6. 必须一直成立的规则 + +1. `/workspace` 的 owner 是 Pi Agent,不是某个普通 App。 +2. 普通 App 只能访问 Host 为它挂载的 data root。 +3. Pi Agent 的 Agent Loop 和 Root View 只有一个常驻 Guest;普通 App 的 View + 与 headless Data Action 可以是两个 Guest,但必须属于同一个 App runtime。 +4. 同一个 App 只有一个 SQLite owner;View 与 Data Action 的 DB ops 经该 owner + 串行化,不能各自创建会竞争同一 LittleFS 文件的 connection。 +5. 只有 `AgentWake` Schedule 才会启动模型;普通 AppTask 不启动模型。 +6. App Tool、App Schedule、UI refresh 可以共用同一个 Data Action。 +7. 每次成功 SQLite transaction 立即递增一次 App revision;revision 通知在前台 + frame boundary 合并,render tick 不轮询 SQLite。 +8. 凭据留在 native 层,不进入 App data、Agent context 或 Tool 参数。 +9. Bundle 只能调用 Host 实际挂载的 capabilities。 +10. 所有硬件差异都留在 Host 和 Native Modules 后面。 +11. Pi Agent System App 在 Supervisor 生命周期内只创建一次;切换普通 App + 只能改变 foreground View,不能替换它。 +12. 一个 host tick、View `tick()` 或 touch callback 不能等待模型、HTTP/MCP + 或 Data Action;View 只操作内存 cache,后台 Data Action 在完整 body 返回后 + 才写 SQLite。 +13. 普通 frame 只能比较内存 revision;revision 未变化、App 在后台或该 + projection cache 已是最新时,SQLite query 数量必须为零。 +14. 产品 UI 不展示 CPU、PSRAM、FPS 或 LCD refresh telemetry;这些指标没有稳定、 + 低开销且可跨硬件复用的语义。底层性能诊断只走 UART/log instrumentation。 + +## 7. Workspace 布局 + +```text +/workspace/ + AGENTS.md + strategy.md + + memory/ + INDEX.md + .md + + .pi-agent/ + schedule.json Pi Agent 自己创建的 AgentWake 状态 + .system/ + app-catalog.json 可选的 App Catalog 缓存 + + data/ + agent.sqlite Pi Agent 数据 + view/ + current 当前 Root View release id + releases/ + / + pocket.json + plan.json + agent-app.json + app.js + agent.js Pi Agent Loop bundle,仅 System App + app.pak + + apps/ + robinhood/ + current + releases/ + / + pocket.json + plan.json + agent-app.json + app.js + data-action.js 可选;headless 数据入口,不挂载 UI + app.pak + migrations.json + data/ + robinhood.sqlite + .system/ + schedules.json Robinhood AppTask 的运行游标和最近结果 + <其他 App 文件> + tmp/ + + / + ... +``` + +Pi Agent 的挂载: + +```text +data.fs root = /workspace +data.sqlite root = /workspace/data +``` + +普通 App 的挂载: + +```text +data.fs root = /workspace/apps//data +data.sqlite root = /workspace/apps//data +``` + +`current` 是保存 active release id 的小文件,不依赖 symlink。它只能在新 +release 完成校验后通过 `data.fs` atomic replace 切换。运行中的 Runtime 绝 +不能 eval 一个只写了一半的 Bundle。 + +## 8. App contract + +概念上,一个 App 可以这样定义: + +```ts +export default defineApp({ + id: "robinhood", + tools: { + get_portfolio: { parameters: accountSchema, action: "getPortfolio" }, + refresh_portfolio: { parameters: {}, action: "refreshPortfolio" }, + }, + actions: { getPortfolio, refreshPortfolio }, + schedules: [{ id: "portfolio-refresh", everyMinutes: 5, + action: "refreshPortfolio", args: {} }], + view: RobinhoodView, +}); +``` + +当前 artifact 对应为: + +```text +agent-app.json Public Tools、Schedules、capability metadata +data-action.js 后台网络、完整 body decode、normalize、SQLite transaction +app.js + app.pak 前台 projection cache 和固定 View +``` + +构建后产生两种不同性质的 metadata: + +1. PocketJS `plan.json`:PocketJS resolver 生成的 target-specific build IR, + 保存 target、HostOps ABI、viewport、resolved capabilities 和 plan hash。 +2. Pocket Pi `agent-app.json`:从 `defineApp()` 静态提取的 runtime descriptor, + 保存 Public Tool schemas、Task/Schedule names、App data schema version 和 + artifact hashes。 + +不能把这两个文件混为一谈。`plan.json` 继续遵守 PocketJS platform contract; +App Supervisor 读取 `agent-app.json` 建立不需要启动 Guest 的 Tool/Schedule +catalog。 + +一个 release 的 metadata 合起来至少包含: + +- App id 和版本; +- Public Tool schemas; +- Schedule declarations; +- capability requirements; +- viewport contract; +- artifact hashes。 + +Supervisor 不需要启动所有 App,就能从 descriptor 建立 Agent Tool Catalog。 + +### App 内部依赖方向 + +```text +Agent Tool ─────┐ +App Schedule ───┼──> Data Action ──> Native transport ──> SQLite transaction +UI refresh ─────┘ │ + ▼ commit + App revision++ + │ + foreground frame coalesces + │ + ▼ + bounded query -> memory cache -> View +``` + +这是一条所有 App 都必须遵守的依赖方向,不是 Robinhood 特例。View 不调用网络、 +不写业务表、也不把 response 直接 render;Data Action 不持有 View state。Agent +不需要知道 App 的 SQLite 表名。 + +## 9. App Supervisor + +App Supervisor 是受信任 Host 代码,负责: + +- 扫描本地 App releases; +- 校验 PocketJS plan、Agent App descriptor、hash、viewport 和 capabilities; +- 选择 active release; +- 创建和销毁 App Runtime; +- 挂载正确的 data root 和 Modules; +- 切换前台 App; +- 路由 App Tool 和 AppTask; +- 保证一个 App 只有一个 execution lease; +- 注册和更新 App Schedules; +- 记录启动、完成、错误和超时; +- Bundle 启动失败时回退到上一个合法 release 或 recovery UI。 + +### 常驻 System App 与前台 View + +Supervisor 持有两种不同的引用: + +```text +system: PiAgentSystemRuntime // 启动一次,始终存在 +runtimes: Map // 固定 catalog 在启动时全部 preload +active_app: Option // None 表示显示 Root View +``` + +每个 host tick 都推进常驻 `system`;普通 App 的 `tick()` 只允许执行常量时间的 +View bookkeeping,不能 poll network、写 SQLite 或重建 projection。只有被选中的 +Runtime 执行 surface render;普通 App 不接管或复制 Agent Loop。由此保证: + +1. Agent turn 跨 App navigation 保持同一 identity/context; +2. 后台 model completion 和 Tool completion 继续进入 System App; +3. Root projection 即使暂时不可见也可更新,返回时直接显示当前状态; +4. foreground App 出错或被卸载不会连带终止 Agent。 + +### 前台与 headless 执行 + +如果 App 正在打开,View Runtime 只处理触摸和缓存 render。Agent Tool、Schedule +或 UI refresh 都进入同一个 bounded Data Action queue;runner 按需加载该 App 的 +`data-action.js`,在独立 headless Guest 中顺序执行。schema DDL 只在 +`PRAGMA user_version` 不匹配时执行;正常启动不重复执行 `CREATE TABLE IF NOT EXISTS`。 + +如果 App 不在前台,已 preload 的 View Guest 不运行 projection reload。Data +Action 仍可更新该 App SQLite 并递增 revision;下次选择这个 View 时,前台 frame +只读取一次当前 bounded projection。preload 解决的是 bundle/QuickJS cold load, +不把后台 App 变成 SQLite polling loop。 + +同一个 App 可以同时有一个 cached View Guest 和一个 headless Data Action Guest, +但只能有一个 Data Action 在执行,且两者共享同一个 SQLite owner。这不是两份 App +实例,而是同一个 App runtime 的 data plane 与 view plane。 + +## 10. Scheduler + +Scheduler 是 Rust 持有的时钟和持久 wake store。它支持两种 target: + +```rust +enum ScheduleTarget { + AgentWake { prompt: String }, + AppTask { + app_id: String, + task: String, + args_json: String, + }, +} +``` + +### 10.1 AgentWake + +启动一个 Agent turn,保留当前 `schedule.set/list/cancel/clear` 和自动唤醒 +能力。只有需要模型判断的任务才用它。 + +### 10.2 AppTask + +直接调用 App 声明的 Task,不调用模型。Robinhood 每五分钟刷新就是 +`AppTask`。 + +### 10.3 生命周期 + +1. Supervisor 校验 Schedule 指向的 Task 确实存在。 +2. 激活 release 时,按 `(app_id, schedule_id)` reconcile Schedule。 +3. Rust Scheduler 把 `next_run_at`、cadence、target、enabled 和 last result + 写入该 App 私有的 `data/.system/schedules.json`。App bundle 中的 + `agent-app.json` 是声明源;运行状态不再集中混放在 workspace 根目录。 +4. 到期后原子 claim wake。 +5. Supervisor 把 AppTask enqueue 到该 App 的 Data Action runner,并立即推进下次 + 时间;不会在 scheduler tick 内等待网络。 +6. Data Action 自己把 running/succeeded/failed 等 domain 结果写入 App SQLite; + Scheduler 的运行游标不复制这份业务状态。 + +ESP32 默认策略: + +- 同一 App 不并发执行; +- 重启后错过多个周期只合并补跑一次; +- idempotency key 为 `::`; +- 执行时间和返回值大小有上限; +- 连续失败不会自动唤醒 Agent; +- App 可以从自己的 SQLite 显示 stale/error 状态。 + +## 11. Tool Catalog 和 Tool Router + +第一版 Pi Agent 看到两类 Tools: + +```text +Native Tools + read · write · edit · find · grep · ls + bash · device.status · time.now + workspace.context + schedule.set · schedule.list · schedule.cancel · schedule.clear + +App Tools + robinhood.get_portfolio + robinhood.refresh_portfolio + research.search +``` + +Workspace 动态自定义 Tools 不属于 v1。 + +### 11.1 注册 + +1. Native modules 提供自己的 Tool definitions。 +2. Supervisor 从 active `agent-app.json` 读取 namespaced App Tool schemas。 +3. Tool Catalog 检查重名和 capability availability。 +4. 合并后的 definitions 注册进 Pi Agent session。 +5. v1 中启用、停用或更改 App Tools 后 reload Agent session;不要求 live + hot-plug。 + +### 11.2 调用 + +```text +Model 产生 Tool call + -> Pi Agent Tool adapter + -> Tool Router + Native name -> CoreToolHost / Native Module + App name -> App Supervisor.enqueue_data_action(app, tool, args) + -> data-action.js -> native transport -> SQLite COMMIT + -> normalized ToolResult + -> Model +``` + +Tool Router 负责 JSON 参数校验和结果大小限制。App Tool 名称必须带 App +namespace,避免冲突。会改变数据或调用 provider 的 App Tool 不在 View Guest +执行;纯只读的诊断 Tool(例如 `storage_status`)可以直接读取 bounded SQLite +projection。 + +## 12. Robinhood MCP 如何接入 + +MCP 是 Robinhood App 使用的上游协议,不是 Pi Agent 看到的 App 边界。 + +### 12.1 Native `mcp.client` + +Firmware 负责: + +- HTTPS/TLS; +- OAuth credential reference; +- MCP initialize 和 session id; +- JSON-RPC/SSE framing; +- retry 和 connection reset; +- response size limit; +- secret isolation。 + +### 12.2 Robinhood Bundle + +App 负责: + +- 选择安全的 upstream operation 子集; +- 定义 Agent-facing Tool 名称和 schema; +- 把本地 Tool/Task 映射到 MCP call; +- normalize provider response; +- 写 Robinhood SQLite; +- 定义 freshness、error 和 history; +- 渲染 View。 + +```ts +function refreshPortfolio(args) { // 只在 headless Data Action Guest + const snapshot = services.call("mcp.client", "callTool", args); + db.exec("BEGIN IMMEDIATE"); + savePortfolio(snapshot); // 完整 body 已返回并 normalize + db.exec("COMMIT"); + app.commit(); // 只 bump revision,不触碰 View +} +``` + +上游 `tools/list` 不会自动变成模型权限。App release 明确选择哪些 Tool 可见。 +认证、session 和不可逆操作留在 native 或单独的批准边界里。 + +### 12.3 Exa 如何接入 + +Exa 使用同一套边界,但走受限的 native `net.http` connection,而不是把 API +key 或任意 URL 交给 Bundle: + +```text +research.search / research.fetch + -> Exa private task + -> net.http(connection="exa", path="/search" | "/contents") + -> normalize response + -> transaction 写 searches / search_results / documents + -> app.commit() 递增 Exa revision + -> 前台下一 rendered frame 最多重查一次搜索历史 projection +``` + +Firmware 注入 credential、绑定 host/path、执行 TLS 和 response limit;Exa +Bundle 拥有请求字段、结果归一化、SQLite schema 和搜索历史 View。这样 Exa +不是 Rust 固件里的特例。 + +Native transport 在进入 ESP HTTP/MCP 之前必须读取一个无锁 connection-ready +状态;未完成 association/DHCP 时立即向 Data Action 返回 error,不能让断网请求 +进入 ESP-Hosted。Data Action 再按本 App 语义写 terminal failure row,View 仍只在 +commit 后重读 SQLite。 + +`connection-ready` 只代表 association + DHCP,不伪装成互联网健康检查。ESP32-P4 +hardware adapter 必须在 link 被动断开/恢复时同步更新这个状态和 Settings projection。 +当前 ESP-Hosted 实机测量表明默认 `WIFI_PS_MIN_MODEM` 会把独立 TLS/HTTP 平均耗时 +放大到约 8 秒;该 adapter 因此在 station start 后使用 `WIFI_PS_NONE`。这是板级 +transport policy,不进入 App Bundle 或 PocketJS portable module contract。TCP/TLS +瞬时失败只重试 transport;只有 provider 明确返回 stale-session 语义时才清空 MCP +session id。 + +## 13. SQLite 和 View 更新 + +SQLite 是持久数据,不是每帧 reactive engine。每个 App v1 只有一个无锁内存 +`revision: AtomicU32`,不是持久表、不是 Boolean,也不是 SQLite watch。 + +```text +Data Action View Runtime +─────────── ──────────── +network / complete body +normalize +BEGIN +write App tables +COMMIT +app.commit(): revision++ ──► foreground frame 读取一次 revision + revision == loadedRevision -> 0 SQLite query + revision != loadedRevision -> bounded query + 更新内存 cache + render cache +``` + +### 13.1 Debounce / coalescing 的准确位置 + +每次成功 transaction 都必须立即 `revision++`,不能 debounce COMMIT,也不能用 +一个容易丢事件的 dirty Boolean。debounce 发生在 **notification delivery / cache +reload**:foreground View 每个 rendered frame 最多采样一次最新 revision;两个 +frame 之间发生 1 次或 20 次 COMMIT,都只执行一次 projection reload,并把 +`loadedRevision` 直接推进到最新值。 + +Data Action 不在网络前写 durable `running` row。UI 发起的 Action 可以用内存状态 +显示正在执行;网络完整返回后,业务表和 terminal run result 在同一 transaction +落库并只递增一次 revision。这样失败或中断不会留下永久 `running` projection。 + +### 13.2 Projection cache + +每个 View projection 在内存中保存: + +```ts +type ProjectionCache = { + key: string; // 例如 account + time span + loadedRevision: number; + value: T; +}; +``` + +第一版 runtime 使用一个 App revision,View 可以有多个 cache,例如 Robinhood +的 accounts、selected portfolio、activity、positions 和 chart。切换已经加载且 +`loadedRevision` 相同的 account/span 只切内存 signal;未加载或 stale 时只查该 +bounded projection,不能重读整个数据库。 + +只有在实测证明单一 revision 导致明显无关 reload 后,才增加 topic/table revision。 +不要一开始为每张表维护 Boolean:它会引入丢更新、跨表 transaction 一致性和大量 +订阅 bookkeeping。App-level monotonic revision 是最小正确 primitive。 + +### 13.3 何时允许读 SQLite + +- View 首次激活; +- foreground View 发现 App revision 变新; +- 用户切换到尚未加载或已经 stale 的 bounded projection。 + +除此之外不读。普通 frame、动画、scroll、已经缓存的 account/span 切换,以及 +后台 App 都是零 SQLite query。View 从不因为打开页面而发起网络请求。 + +### Query 规则 + +- 列表 query 必须有 `LIMIT`、分页或聚合; +- 大型时间序列先聚合成 View 大小的窗口; +- Robinhood 1D/1W chart 固定为 20 个 time buckets;一次 indexed SQLite query + 恰好返回 20 行,View 只绘制这些 bucket 的 point projection; +- migrations 必须创建必要索引; +- provider 的模型 stream 只在 transport/decoder 内部消费;Pi Agent 等完整结果 + 后只向 Root View 发一次文本更新,不能让每个 token 触发 JS event、layout 或 + flash write; +- schema version 和 migrations 由 App 管理。 + +### 13.4 App 数据库保存业务事实,不保存原始 Tool payload + +Tool、Schedule 和 UI refresh 共享 Data Action implementation。每个 provider body +完整返回后,Data Action 在内存中 normalize,再明确更新对应的 domain tables。 +View 不读取原始 provider JSON,也不在前台推断上游字段结构。通用的 append-only +`tool_events`、`results_json` 和 `document_json` 不属于产品 read model。 + +Robinhood v1 schema: + +- `accounts`:账户 identity 和当前状态; +- `portfolio_current`:cash、buying power、day/week P&L 等当前字段,不含 total value; +- `total_value`:按 `account_number + observed_at` 保存折线图所需的 value history; +- `positions`:每个账户的当前持仓 rows; +- `activities`:每个账户最近的 order/activity rows; +- `refresh_runs`:只保存 terminal succeeded/partial/failed result; +- `equity_historicals`、`pnl_trades`、`order_reviews`:分别由对应公开 Tool 更新。 + +Exa v1 schema: + +- `searches`:一次 search 的 query、时间、terminal status 和 result count; +- `search_results`:最多 8 条结构化 result rows; +- `documents`:`research.fetch` 得到的 bounded document text 和 metadata。 + +开发阶段 schema 变化由 App descriptor 的 `dataVersion` 显式触发:Supervisor 在打开 +SQLite 前只删除该 App 的 `.sqlite`,写入 App-local version marker,然后由 +该 App 的 Data Action 创建新 schema;不维护 migration/backward compatibility。 +不得删除其他 App、该 App 的其他 files、顶层 workspace、NVS Wi-Fi 或 credentials。 + +## 14. Pi Agent Root Runtime + +Pi Agent 是拥有更宽 filesystem mount 的特殊 System App,负责: + +- Agent/model loop; +- Chat 和 Tool run 展示; +- `/workspace` coding Tools; +- memory 和 strategy; +- bounded context assembly; +- AgentWake Schedules; +- 发现和调用已安装 App Tools; +- Files、Runs/Schedules、Device Settings View; +- `agent.sqlite` 中的 conversation、message、run、Tool call。 + +Agent Loop 由 System App release 中的 JavaScript `agent.js`(`pi-agent-core`) +提供,并与 `app.js` Root View eval 到同一个 PocketJS Guest。Rust 只提供 +模型 transport、Native/App Tool 路由、调度和生命周期;它不拥有第二套 Agent +state machine。Root View 与 Agent Loop 同属 `pi-agent` release/runtime,这使 +Agent 能在未来通过更新自己的 release 一起演进 context、Tools adapter 和 UI。 + +第一版不要求 Pi Agent 修改 App code、构建 Bundle 或动态增加 Tool definitions。 + +### 14.1 ESP32 支持的自我管理 + +- 读写 Agent workspace files; +- 维护 `AGENTS.md`、strategy、memory; +- 组装 bounded context; +- 创建 AgentWake Schedules; +- 使用 Native Tools 和已安装 App Tools。 + +### 14.2 ESP32 不支持 + +- 作为产品能力编辑 PocketJS 源码; +- 编译 TSX、styles、fonts 或 `.pak`; +- 修改 firmware/Rust modules; +- v1 动态加载 Tool source。 + +### 14.3 macOS 开发能力 + +macOS Host 可以额外提供显式 developer capability,用来编辑源码和构建 +Root/App Bundles。它不属于 ESP32 portable contract。 + +## 15. Context Assembler + +Context Assembler 把选定 workspace files 组装成有严格上限的 Agent context, +不是把整个文件系统全部塞进 prompt。 + +第一版输入: + +```text +固定 system identity +/workspace/AGENTS.md +/workspace/strategy.md +/workspace/memory/INDEX.md +最新或被选中的 memory notes +紧凑的 device state +``` + +规则: + +- 单文件和总 context 都有 byte ceiling; +- 非 UTF-8 和不支持的文件不进入 prompt; +- App 业务表不会自动进入 context; +- App Tool schemas 进入 Tool list,不重复进 system prompt; +- credentials 不进入 context; +- Agent 需要 App 数据时调用 App Tools。 + +## 16. Native Module 归属 + +| Module | Rust/native 负责 | Bundle 负责 | +| --- | --- | --- | +| `ui` | retained tree、layout、text、animation、DrawList | JSX View 和 reactive state | +| `data.sqlite` | SQLite、handles、limits、storage binding | schema、migrations、queries、transactions | +| `data.fs` | confinement、quota、atomic replace | App files 和 config | +| `net.http` | TLS、connection、limits、transport | endpoint 和 domain decoding | +| `mcp.client` | auth、session、framing、limits | safe operation mapping 和 domain semantics | +| `model.stream` | provider transport、内部 stream decode 和完整 result | Agent policy;ESP32 presentation 每次 request 只接收一次完整文本更新 | +| `schedule.wake` | clock、persistence、claiming | AgentWake 或 AppTask declaration | +| `shell.bounded` | allowlisted device/workspace operations | Agent 决定何时调用 | +| `device.settings` | Wi-Fi、NVS、restart | Settings View | +| `app.lifecycle` | catalog、activation、Data Action queue、per-App revision 和 frame-boundary coalescing | descriptor、`app.commit()` 和 projection caches | +| `app.data` | 后台 Guest 生命周期、bounded queue、共享 DB owner | provider mapping、完整 body decode、transaction | + +Native 层拥有稀缺资源、硬件和 secrets;Bundle 拥有产品行为。 + +## 17. 板子上呈现的 UI + +任意时刻只呈现一个 Runtime 的 foreground DrawList。 + +### 17.1 Root/Home + +Pi Agent Root View 提供 Chat、Apps、Files、Runs/Schedules 和 Settings。它会 +替代当前产品 UI 的 Rust `ScreenState`。产品 UI 不保留 legacy Rust 实现或 +双轨 fallback;固件只负责渲染 PocketJS DrawList 和必要的底层硬件错误日志。 + +### 17.2 App foreground + +打开 Robinhood 后,显示 Robinhood View。常驻 Pi Agent System App 继续在原 +Guest 中运行,但 Root View 暂不产生前台 DrawList。用户仍可操作 Robinhood, +再切回时 Agent session 不变。 + +### 17.3 Background update + +- Robinhood 关闭时,五分钟 AppTask 只运行 headless Data Action;完整网络 body + 返回后写 SQLite 并递增 revision,不加载或查询 View; +- Robinhood 打开时,Data Action 与 View 仍分离。成功 COMMIT 后,下一次 + foreground rendered frame 发现 revision 变化,只更新 stale bounded cache。 + +## 18. 当前 Pocket Pi 能力映射 + +最终架构不主动删除任何现有能力;当前 v1 的保留程度见第 22 节。 + +| 当前能力 | 新架构归属 | +| --- | --- | +| model request 和 streaming | `model.stream` + Pi Agent Runtime | +| OpenAI/OpenRouter/Anthropic/UART adapters | Host/provider adapters | +| workspace read/write/edit/find/grep/ls | Root Agent workspace Tools | +| bounded bash | `shell.bounded` | +| `device.status` 和 `time.now` | native device/time Tools | +| `workspace.context` | Context Assembler | +| Agent `schedule.*` 和 autonomous wake | Scheduler `AgentWake` | +| Chat、Files、keyboard、message reader | Root PocketJS View | +| Wi-Fi scan/connect/forget、restart | `device.settings` + Root View | +| simulator/physical contract parity | shared runtime/module contracts | +| macOS full Pi sessions/extensions | macOS Agent profile | + +新增而不是现有的能力包括:App Supervisor、App Catalog、App Tools、AppTask +Schedules、revision-coalesced projection cache 和 Bundle-based Views。 + +## 19. Host profiles 与跨硬件 + +Pocket Pi 继续保留不同 Agent profile: + +| Host | Agent profile | 额外能力 | +| --- | --- | --- | +| macOS | full `pi-coding-agent` | sessions、extensions、可选 Bundle 开发/构建 | +| ESP32 simulator | embedded `pi-agent-core` | 用 macOS adapter 实现相同 embedded contracts | +| ESP32-P4 | embedded `pi-agent-core` | LittleFS、touch/LCD、Wi-Fi/NVS 和嵌入式 limits | + +### 19.1 “一次适配,不同硬件跑”的准确含义 + +它不表示同一个 firmware binary 或同一份 byte-identical App artifact 在所有 +硬件上运行。 + +它表示: + +1. 新硬件只需要实现一次 Host 和它承诺支持的 Native Modules。 +2. Hardware target 发布真实的 capability 和 viewport profile。 +3. 任何 requirements 被满足的 App 都不需要写 App-specific Rust/hardware code。 +4. 同一份 App 源码和业务逻辑根据 ABI、viewport、raster density 和 assets + 生成 target-specific `app.js`/`app.pak`。 + +以 Robinhood 为例,Tool mapping、SQLite schema、refresh Task 和 View source +保持相同;ESP32 与 macOS 只是在同一 specs 后面提供不同 display、filesystem、 +network 和 credential 实现。 + +### 19.2 能做到跨硬件的条件 + +- App 不直接调用 ESP-IDF、wgpu、macOS 或 raw device API; +- capability ids 和 module specs 稳定且 append-only; +- `requires` 是硬条件,可选能力使用 `enhances`; +- UI 声明支持的 viewport policy 或 target variant; +- simulator 验证 contract,physical hardware 做最终验收; +- resource ceiling 是公开 contract,不是隐藏设备事实。 + +一个新 board 完成并通过这些 modules 的 contract tests 后,兼容 App 不需要再 +做 board-specific port。 + +## 20. 这是不是 AgentOS + +从产品和 runtime 的意义上,它符合 AgentOS: + +1. Agent 是系统一级 actor,不是某个 App 里的聊天框。 +2. Agent 拥有持久 workspace 和 context。 +3. App 原生暴露语义化 Tools 给 Agent。 +4. App 同时提供人类可见的 View。 +5. 本地 Schedule 让系统能自主工作,不需要模型参与每个循环。 +6. Host 统一管理 capabilities、credentials、lifecycle 和 hardware。 +7. Tools、Tasks、State 和 View 可以作为 App 单元演进,不改 firmware。 +8. Agent 的执行生命周期独立于当前前台 View,用户和 Agent 可以并行操作同一 + 套 App platform。 + +但它不是传统通用 OS:它不提供任意进程、多用户安全、POSIX 兼容或通用 +desktop。准确说法应当是: + +> Pocket Pi 是一套 embedded AgentOS runtime:Agent 拥有 workspace;本地 +> App 通过 Agent Tools、durable state、autonomous Tasks 和 human View 同时 +> 服务 Agent 与用户。 + +这比“Agent UI”更准确,也比“替代传统操作系统”更克制。 + +## 21. 我对这套架构的理解 + +这套架构最重要的不是“ESP32 能运行 JavaScript”,而是 Agent 和用户用两种 +接口操作同一个本地软件: + +- Pi Agent 通过 App Tools 看见 App; +- 用户通过 App View 看见 App; +- 两条路径最终汇合到同一批 Data Actions 和 SQLite State。 + +Robinhood 是最直观的例子。Rust Schedule 每五分钟触发一次,或者模型调用 +`robinhood.refresh_portfolio`,两者最终都调用同一个 `refreshPortfolio` +Data Action。它使用 native MCP/network transport,等完整 body 返回后向 +Robinhood SQLite commit 一份 snapshot,然后结束。 + +如果 View 正在打开,revision 只使 cache 失效,并在 frame boundary 合并更新; +如果 View 关闭,不发生任何 UI 查询,下次打开直接读取最新 bounded projection。 + +所以 Rust 层应该“小但强”:它拥有 clock、secret、hardware、resource limit、 +isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、业务 +规则、数据库形状和 UI。Pi Agent 拥有 workspace,并决定什么时候使用这些 +能力,但普通 App 的后台任务不需要模型 turn。 + +正是这个分离,让 Pocket Pi 可以从一个 Agent demo 发展成 App platform,也 +可以从一块板扩展到多种硬件,而不需要把每个新产品重新写进 firmware。 + +## 22. 当前实现状态 + +### 22.1 已实现 + +1. PocketJS 固定在 `feat/fs-surface` revision + `afc8d4e8e877dac7f9b0c01b5c0d667642009fc0`;Simulator 和 ESP32-P4 共用 + `pocket-fs`、`pocket-db`、`pocket-mod` 和 `pocket-ui-surface` contracts。 +2. Pi Agent 位于顶层 `/workspace`;Root View release 位于 + `/workspace/data/view`,其中 `app.js` 和 `agent.js` 是同一个 System App + release;普通 App 位于 `/workspace/apps/`。 +3. App Supervisor 会 seed/校验 built-in release,并在启动时创建一次常驻的 + Pi Agent System App;当前固定 catalog 中的普通 App View Runtime 也全部在启动 + 阶段 preload。普通 View Guest 被限制在自己的 `data/` 和 `tmp/`,切换它们不会 + 替换 System App;前台导航只选择已经存在的 surface。这里没有 Marketplace、 + LRU、pinning 或 residency policy。 +4. Tool Catalog/Router 合并 Native Tools 与 namespaced App Tools;Agent Loop + 和 Root View 已挂载在同一个 PocketJS Guest。模型与 Native Tool 的慢 I/O 在 + worker 完成,再以 event batch 回到这个 Guest,因此这些路径不阻塞 UI tick。 +5. AgentWake store 持久化在 `.pi-agent/schedule.json`;Robinhood 的五分钟 + AppTask store 持久化在 `apps/robinhood/data/.system/schedules.json`; + refresh 是 `AppTask`,只 enqueue Data Action,不启动模型。 +6. 每个有后台数据能力的 App release 包含可选 `data-action.js`。一个 bounded + `AppDataRunner` 顺序执行 Tool/Schedule/UI refresh;Robinhood 和 Exa View + bundles 已删除网络调用和业务表写入。 +7. 每个 App 有一个共享 `DbModule` owner。View Guest 与 Data Action Guest 使用 + 同一 connection owner,避免 ESP32 `unix-none` VFS 上两个 connection 竞争同一 + LittleFS 文件;network wait 不持有 DB mutex。 +8. 每次成功 transaction 调用 `app.commit()`,递增该 App 的 `AtomicU32` + revision。只有 foreground rendered frame 会比较 revision;连续多个 commit + 合并成一次 `dataChanged`。普通 frame 与后台 App 不读 SQLite。 +9. Robinhood Data Action 拥有 curated Agent Tools、MCP operation mapping、完整 + response decode 和单次 refresh transaction;每个 operation 更新明确的 domain + table,不保存原始 Tool payload。View 只拥有 accounts/portfolio/positions/ + activity/chart 的 bounded projection 和 cache。chart 的 1D/1W 窗口固定为 20 个 + time buckets,SQLite query 最多返回 20 行,render 不读取 DB。 +10. Exa Data Action 拥有 `research.search`、`research.fetch`、HTTP mapping 与 + SQLite transaction;View 从 `searches + search_results` 只读取最近 8 次搜索。 +11. Root View 已提供 Chat、App 入口、Files、Runs/Schedules、Settings 摘要和 + 屏幕键盘;Agent policy/loop 在 JS,workspace/App Tools 的受限底层实现和 + AgentWake 由 Rust host 提供。Pocket Pi 的小型 shared Design System inventory + 单独记录在 `docs/pocket-pi-design-system.md`;它只包含 PocketJS 上的基础 + typography/tokens/components,不包含 App-specific View 或 native UI logic。 +12. ESP32-P4 使用 4 KiB PSRAM launcher,待 ESP-IDF entry task 退出后创建 64 + KiB internal AgentOS runtime stack;App bundle 构建后会 minify 以降低固件 + footprint,但不会把 minify 当作 stack isolation。 +13. Simulator tests 已证明:Agent turn 进行中打开 Robinhood,仍能收到完整回复 + 和 `agent_end`;前后台切换前后 System App Guest identity 不变;Exa 在前台 + 时 Agent 仍能路由 Robinhood App Tool、写 SQLite 并完成 turn。新增 contract + test 证明 3 次 commit 在下一前台 frame 只 reload 一次,5 个普通 frame 不 + reload,后台 2 次 commit 在重新打开时只 reload 一次。 +14. Simulator Data Action tests 已证明:Exa search 用一次 transaction 写入 + `searches` 和 `search_results`;Robinhood 完整 fixture refresh 用一次 + transaction 写入各业务表与 terminal `refresh_runs`,并成功显示;provider + failure 只写 failed refresh run、保留上一次业务 projection,而且可以再次 + enqueue。 +15. `legacy_main()`、Rust `ScreenState` product UI 和其专属 display path 已删除, + 固件没有保留旧 UI 或死代码。 +16. 删除全部 legacy Rust UI 后的基线固件已刷入 ESP32-P4;实机从 System App + release 的 `agent.js` 在 Root Guest 中启动 Agent,并经 UART Codex backend + 完成 prompt 和 `agent_end`。当前 embedded presentation contract 已进一步改为: + provider 可以在 host/transport 内部 stream,但一次 model request 只给 Root View + 一个完整文本更新。实机长回复测试在 bridge 内部合并 409 个 provider chunks、 + 615 个字符后只发送一个 UART result;完成后继续观察 30 秒没有 task watchdog。 +17. ESP32-P4 的 PocketJS View 已接入真实 PPA backend,矩形填充、A8 字形混合和 + SRM 图像转换不再走全屏 CPU software fallback;每个 triple-buffer framebuffer + 保留独立 incremental render state。实机启动日志已确认 + `RGB565 backend ready: FILL + A8 BLEND + SRM`。 +18. ESP32 UI owner 在运行期不再调用 `heap_caps_get_info`;此前该 API 在 TLS 使用 + 后扫描碎片化 PSRAM 会长期持有全局 heap lock,使 UI 卡住并产生蓝屏式 watchdog + dump。产品 UI 已删除全部 CPU、内存、FPS 和 LCD 状态展示,相关问题只通过 + UART/log diagnostics 观察。 +19. Host 不再无条件以 60Hz 重建所有 PocketJS View。只有当前 foreground View + dirty 时才执行 UI `frame()`、更新 retained DrawList 和提交 panel render。 + ESP32 owner 是原生 FreeRTOS task,主循环必须用 + `vTaskDelay` 明确让出 CPU,不能用 pthread 语义的 `std::thread::sleep` 代替; + 否则即使总 CPU/内存数字不高,CPU0 idle task 仍可能无法喂 watchdog。 +20. 当前代码已通过 `pocket-pi-agentos` 7 个 tests、ESP32-P4 Simulator 5 个 tests, + 通过 ESP32-P4 release cross-build 并刷入实体板。稳态冷启动测得 Root、Exa、 + Robinhood View preload 分别约 2.0、2.8、3.3 秒,约 20.5 秒进入完整 UI;没有 + watchdog 或蓝屏。`dataVersion` reset 只发生一次,正常启动不重复 DDL。 +21. 实机断网 Tool 验证已证明:Agent 调用 `research.search` 后,Data Action 在 + native connection-ready gate 处 fail-fast,写一条 terminal error search,随后 + 删除不安全的 30 秒 ESP-Hosted 自动 reconnect 后,连续观察 120 秒没有 assertion + 或重启;用户仍可从 Settings 明确发起重连。`research.storage_status` 实际返回 + `searches=1`、`search_results=0`、`documents=0`; + `robinhood.storage_status` 返回 9 张新 domain tables,其中 `refresh_runs=1`、 + 其余业务表为 0。旧 `tool_events/search_history/raw JSON` 表均不存在。 + +### 22.2 待补齐,不能视为已实现 + +- Root Files 已有只读文件阅读器;conversation/message/run/tool call 还没有落入 + `data/agent.sqlite`。 +- release 已有 descriptor/`pocket.json` 校验和 atomic `current` 写入,但由 + PocketJS resolver 生成并校验真实 `plan.json`、完整 artifact hash、migration + transaction、上一版本回退和独立 recovery UI 还没有完成。 +- macOS full Agent Host 尚未迁到同一个 App Supervisor;当前跨硬件实证是 + ESP32 simulator + physical ESP32-P4,不代表 macOS parity 已完成。 +- 固定 catalog 的普通 App View 现在全部在 Supervisor 启动时 preload;真实 + ESP32-P4 启动时长已量测,但持续切换仍需人工验收。后续如果 catalog + 扩大,再依据实测在 PocketJS runtime 层设计加载策略,不能先引入 Marketplace、 + LRU/residency policy,也不能把 App UI/数据逻辑写回 Rust。 +- Robinhood OAuth grant 与 Exa key 都由 Mac Keychain 复用,并只在本次 UART + boot config 中以内存态注入;credential 不进入 App DB、workspace 或 View。 + 上一个 schema 的物理板验证曾证明 Exa/Robinhood provider -> SQLite -> View + 链路可达;本节定义的新 normalized schema 已在实体板创建,并验证断网 terminal + rows 与 storage projection,但尚未取得一次新 schema 下的 provider success。 + `agent.robinhood.com` 从当前 AP 建连仍有波动,失败轮次会写 error batch,但不会 + 覆盖最后一次成功的 portfolio projection。 +- 实机已验证后台 Agent turn,但“turn 运行中连续触摸切换 Robinhood/Exa 再返回” + 仍需人工操作验收;自动 lifecycle/tool-routing test 已覆盖同一状态机路径。 +- 通用 Data Action runner 已在当前实机验证 FreeRTOS pthread stack、断网 + failure transaction、SQLite dump 与 network fail-fast;真实 provider success、 + 持续触摸切换和成功/失败交替 retry 仍待验证。 +- 当前修改型 App Tool 返回的是 queued run receipt,Data Action completion 记录在 + App SQLite 和日志。若 Agent 需要同步获得 provider 的最终 ToolResult,应在后续 + 增加一个 bounded completion delivery contract;不能为此把网络调用搬回 View + 或 host tick。 +- v1 是一个 App-level revision。Robinhood 已将 DB read 限制在 initial/ + `dataChanged` 和 account/span 的 bounded cache miss,但所有 projection cache 的 + `loadedRevision` 仍需继续显式化,随后再用板上 query 计数确认交互路径为零重读。 + +明确延后:Marketplace/distribution、ESP32 source editing、Agent-authored Tools、 +通用 live Tool hot-plug,以及不经编译的 declarative View schema。当前固定 catalog +直接 preload 全部普通 App View,不预先实现未来的 residency policy。 + +## 23. 验收标准 + +1. 当前 Agent workspace、model、Settings、Agent Schedule 全部继续工作。 +2. Robinhood Tool definitions 能进入 Pi Agent,但不编译进通用 Pocket Pi core。 +3. Agent Tool 和五分钟 App Schedule 调用同一个 refresh Task。 +4. App Schedule path 不发起模型请求。 +5. 每次成功 transaction 都递增 revision;同一 frame 间隔内的多次递增只让打开 + 的 View reload 一次,revision 不变的普通 frame 是零 SQLite query。 +6. 后台 App 不执行 View query;重新选择时只在 revision stale 时读取一次 bounded + projection,并立即显示当前数据。 +7. 普通 App 无法读取另一个 App 的 data root。 +8. Pi Agent 可以读取和管理顶层 `/workspace`。 +9. 重启后 App 数据保留,错过的 recurring run 按规则合并一次。 +10. Tool schema 非法、capability 缺失、Bundle 损坏、migration 失败时 fail + closed,并进入 recovery 或保留上一个合法 release。 +11. 同一份 Robinhood source 通过 simulator contract tests,并用对应 target + artifacts 在真实 ESP32-P4 上运行。 +12. Agent turn 进行中可以操作键盘、打开 Robinhood/Exa、在 App 内触摸交互并 + 返回 Root;Agent 不重启,pending turn 正常完成,conversation/context 保留。 +13. 切换 foreground 前后 `pi-agent` Guest identity 和 boot count 不变;普通 + App failure 不得终止 System App。 +14. 网络失败、超时或 malformed body 只能更新 App 的失败状态,不能阻塞 View、 + 触发 View 网络重试或让 revision delivery 进入无限 retry loop。 + +## References + +- [PocketJS core concepts](https://pocketjs.dev/docs/concepts/) +- [PocketJS platform contracts](https://pocketjs.dev/docs/platform-contracts/) +- [PocketJS DB module PR #231](https://github.com/pocket-stack/pocketjs/pull/231) +- [PocketJS FS module PR #238](https://github.com/pocket-stack/pocketjs/pull/238) +- [`ARCHITECTURE.md`](../ARCHITECTURE.md):当前已实现的 Pocket Pi profiles 和 + Host ownership diff --git a/docs/esp32-p4-port.md b/docs/esp32-p4-port.md index 2f3527f..5398d96 100644 --- a/docs/esp32-p4-port.md +++ b/docs/esp32-p4-port.md @@ -8,12 +8,11 @@ Pocket Pi has two agent profiles and three hosts: | `esp32-p4` | bounded `pi-agent-core` | ESP32-P4 | | `esp32-p4-sim` | bounded `pi-agent-core` | macOS | -The physical host and simulator use the same -`pocket-pi-device-ui` crate: one 720x1280 draw list, one set of fonts, and one -touch hit map. Simulator mouse clicks are converted to physical panel -coordinates and dispatched through the same `ScreenState::handle_tap` method. -The shared embedded UI displays Chat, Files and Settings. Settings is not part -of the normal macOS host. +The physical host and simulator use the same PocketJS App bundles and +`pocket-pi-agentos` supervisor at a 720x1280 logical viewport. Simulator mouse +clicks and physical touch coordinates are both dispatched to the selected App +View. The Pi Agent Root View displays Chat, Apps, Files and Settings; there is +no parallel Rust product UI. The physical host selects `UartBackend` for a Mac Codex/Claude Code bridge or `WirelessBackend` for direct OpenAI/OpenRouter/Anthropic HTTPS. These remain @@ -92,9 +91,9 @@ UART provisioning also seeds the board clock from the Mac for development. Standalone operation uses ESP-IDF SNTP after Wi-Fi connects. Both feed the same native time and persistent schedule implementation. -## Shared UI boundary +## App UI boundary -`pocket-pi-device-ui` owns rendering, interaction state and the portable -workspace browser. Each host supplies a mounted workspace root and its model -adapter. External applications own their UI adapters, provider clients and -credentials; Pocket Pi core contains no Robinhood or Exa domain code. +`apps/pi-agent`, `apps/robinhood`, and `apps/exa` own their PocketJS Views. +`pocket-pi-agentos` selects the foreground View and keeps the Pi Agent System +App resident. Each host supplies the mounted workspace, capabilities, model +adapter, and renderer; product UI and domain logic do not live in Rust firmware. diff --git a/docs/pocket-pi-design-system.md b/docs/pocket-pi-design-system.md new file mode 100644 index 0000000..c18d5b1 --- /dev/null +++ b/docs/pocket-pi-design-system.md @@ -0,0 +1,54 @@ +# Pocket Pi Design System inventory + +状态:v0.1,刻意保持小型。这里记录哪些 UI 已经成为 Pocket Pi 全局设计语言, +避免在单个 App 中复制后再逐渐漂移。 + +实现位于 `apps/_shared/ui.tsx` 和 `apps/_shared/text.ts`。它只能依赖 PocketJS framework primitives,不能 +调用 ESP-IDF、Pocket Pi Rust 私有接口、网络或 SQLite。App-specific data binding +和交互仍由各 App 自己拥有。 + +## v0.1 tokens + +| Token group | 当前内容 | 使用范围 | +| --- | --- | --- | +| `type` | title、section、body、bodyStrong、caption | Pi Agent、Robinhood | +| `space` | 24px screen gutter、card padding、stack gap | Pi Agent、Robinhood | +| semantic colors | slate shell/surfaces、orange primary、green ready/positive、red error | shared components | +| dynamic prose glyphs | curly quotes、en/em dash、ellipsis、bullet | model/provider text | + +当前统一使用 PocketJS bundle 内的 Inter font atlas;v0.1 只统一字号、字重和行文 +层级,不新增字体或 native font API。`text.ts` 的 glyph seed 只让常见动态英文标点 +进入现有 subset atlas,不引入第二套字体或 runtime font loader。 + +## v0.1 components + +| Component | 责任 | 明确不负责 | +| --- | --- | --- | +| `PocketHeader` | 112px system header、title、back/status affordance、两行 metadata | App data、navigation side effects | +| `SectionHeading` | section title、optional detail/action label | list/query behavior | +| `ActionButton` | primary/disabled visual state、minimum touch surface supplied by caller | 执行动作 | +| `wrapLines` / `wrapPreview` | 用 PocketJS `measureText` 给动态文本插入显式换行,并缓存测量结果 | rich text、Markdown、滚动状态 | + +Card 在 v0.1 只记录为视觉 recipe:`rounded-xl + white + slate border + shadow`。 +当前 PocketJS/Solid Guest 对跨模块传递 arbitrary children 的 generic wrapper 仍会 +产生额外 runtime 风险,因此 App 直接在自己的 `View` literal 上使用这组样式;不 +为“组件化”保留一层不稳定 wrapper。 + +## 仍然属于 App 的组件 + +- Pi Agent conversation turn、Bottom Navigation、keyboard、Files row; +- Robinhood 20-point chart、time-range selector、account selector、portfolio metric、 + activity row、position row; +- Exa search-history projection。 + +只有至少两个 App 需要、语义稳定、并且能完全建立在 PocketJS public UI contract +之上的组件,才进入 Design System。 + +## 演进规则 + +1. 每次抽出或删除 component/token,都更新本 inventory 和 consumer。 +2. v1 仍由 TS/TSX 编译为各 App 的 `app.js`/`app.pak`。 +3. 未来 declarative View schema 只能组合 inventory 中明确注册的稳定组件;在 + schema 和校验边界被单独设计前,不在当前 runtime 中加入 interpreter。 +4. Marketplace 或独立 SDK 真正出现后,再把该目录提取为版本化组件包;当前不 + 预先实现 package registry、compatibility resolver 或 runtime download。 diff --git a/firmware/esp32-p4/.cargo/config.toml b/firmware/esp32-p4/.cargo/config.toml index 659bcb2..d89bb60 100644 --- a/firmware/esp32-p4/.cargo/config.toml +++ b/firmware/esp32-p4/.cargo/config.toml @@ -16,3 +16,4 @@ ESP_IDF_TOOLS_INSTALL_DIR = "workspace" CC_riscv32imafc_esp_espidf = { value = "tools/esp32p4-cc", relative = true } AR_riscv32imafc_esp_espidf = { value = "tools/esp32p4-ar", relative = true } CFLAGS_riscv32imafc_esp_espidf = "-mabi=ilp32f -march=rv32imafc_zicsr_zifencei_xesppie -fno-pic -fno-PIC -Wno-error=incompatible-pointer-types" +LIBSQLITE3_FLAGS = "-DSQLITE_TEMP_STORE=3 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_MAX_MMAP_SIZE=0 -DSQLITE_OMIT_WAL -DSQLITE_OMIT_LOAD_EXTENSION -Dlstat=stat" diff --git a/firmware/esp32-p4/Cargo.lock b/firmware/esp32-p4/Cargo.lock index 211fda6..46fd329 100644 --- a/firmware/esp32-p4/Cargo.lock +++ b/firmware/esp32-p4/Cargo.lock @@ -68,6 +68,12 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "bindgen" version = "0.71.1" @@ -643,6 +649,18 @@ dependencies = [ "which", ] +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fastrand" version = "2.5.0" @@ -768,6 +786,12 @@ dependencies = [ "walkdir", ] +[[package]] +name = "grid" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b40ca9252762c466af32d0b1002e91e4e1bc5398f77455e55474deb466355ff5" + [[package]] name = "hash32" version = "0.3.1" @@ -777,6 +801,15 @@ dependencies = [ "byteorder", ] +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "foldhash", +] + [[package]] name = "hashbrown" version = "0.17.1" @@ -788,6 +821,15 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashlink" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32069d97bb81e38fa67eab65e3393bf804bb85969f2bc06bf13f64aef5aba248" +dependencies = [ + "hashbrown 0.17.1", +] + [[package]] name = "heapless" version = "0.8.0" @@ -883,7 +925,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.17.1", ] [[package]] @@ -943,6 +985,17 @@ dependencies = [ "windows-link", ] +[[package]] +name = "libsqlite3-sys" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6c19a05435c21ac299d71b6a9c13db3e3f47c520517d58990a462a1397a61db" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -1063,17 +1116,68 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] -name = "pocket-pi-device-ui" +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "pocket-db" version = "0.1.0" +source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" dependencies = [ - "pocket-pi-protocols", + "anyhow", + "base64", + "pocket-mod", + "pocketjs-core", + "rusqlite", + "serde_json", +] + +[[package]] +name = "pocket-fs" +version = "0.1.0" +source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +dependencies = [ + "anyhow", + "base64", + "pocket-mod", + "pocketjs-core", + "serde_json", +] + +[[package]] +name = "pocket-mod" +version = "0.1.0" +source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +dependencies = [ + "anyhow", + "log", + "pocketjs-core", + "rquickjs", +] + +[[package]] +name = "pocket-pi-agentos" +version = "0.1.0" +dependencies = [ + "anyhow", + "log", + "pocket-db", + "pocket-fs", + "pocket-mod", + "pocket-pi-embedded", + "pocket-ui-surface", "pocketjs-core", + "serde", + "serde_json", ] [[package]] name = "pocket-pi-embedded" version = "0.1.0" dependencies = [ + "pocket-mod", "rquickjs", "serde_json", ] @@ -1087,12 +1191,13 @@ dependencies = [ "embuild", "esp-idf-svc", "log", - "pocket-pi-device-ui", + "pocket-pi-agentos", "pocket-pi-embedded", "pocket-pi-protocols", "pocket-pi-tools", "pocketjs-core", "pocketjs-esp32p4-ppa", + "rusqlite", "serde_json", ] @@ -1115,10 +1220,21 @@ dependencies = [ "serde_json", ] +[[package]] +name = "pocket-ui-surface" +version = "0.1.0" +source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +dependencies = [ + "anyhow", + "log", + "pocket-mod", + "pocketjs-core", +] + [[package]] name = "pocketjs-core" version = "0.1.0" -source = "git+https://github.com/pocket-stack/pocketjs.git?rev=4c5dc9ef1dd26e6f49b036c210931d399f2b52b2#4c5dc9ef1dd26e6f49b036c210931d399f2b52b2" +source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" dependencies = [ "taffy", ] @@ -1126,7 +1242,7 @@ dependencies = [ [[package]] name = "pocketjs-esp32p4-ppa" version = "0.1.0" -source = "git+https://github.com/pocket-stack/pocketjs.git?rev=4c5dc9ef1dd26e6f49b036c210931d399f2b52b2#4c5dc9ef1dd26e6f49b036c210931d399f2b52b2" +source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" dependencies = [ "pocketjs-core", ] @@ -1242,7 +1358,7 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16e4f499ac5b943d97ee6dbc44f23c2c10426f420f7d2f1793d6318911b6608c" dependencies = [ - "hashbrown", + "hashbrown 0.17.1", "relative-path", "rquickjs-sys", ] @@ -1274,6 +1390,31 @@ dependencies = [ "cc", ] +[[package]] +name = "rsqlite-vfs" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51c9ae4df8a7fba42103df5c621fa3c37eccf3a3c650879e90fc48b11cc192c" +dependencies = [ + "hashbrown 0.16.1", + "thiserror 2.0.19", +] + +[[package]] +name = "rusqlite" +version = "0.40.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11438310b19e3109b6446c33d1ed5e889428cf2e278407bc7896bc4aaea43323" +dependencies = [ + "bitflags 2.13.1", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", + "sqlite-wasm-rs", +] + [[package]] name = "rustc-hash" version = "2.1.3" @@ -1401,6 +1542,24 @@ dependencies = [ "version_check", ] +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "sqlite-wasm-rs" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc3efc0da82635d7e1ced0053bbbfa8c7ab9645d0bf36ceb4f7127bb85315d75" +dependencies = [ + "cc", + "js-sys", + "rsqlite-vfs", + "wasm-bindgen", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -1490,6 +1649,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfde4e2f8595f222ceaae1fb16b4963952e9b33e358869dc4cd6316b0e0790cd" dependencies = [ "arrayvec", + "grid", "serde", "slotmap", ] @@ -1604,6 +1764,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" diff --git a/firmware/esp32-p4/Cargo.toml b/firmware/esp32-p4/Cargo.toml index 73d463c..fe78f4a 100644 --- a/firmware/esp32-p4/Cargo.toml +++ b/firmware/esp32-p4/Cargo.toml @@ -12,6 +12,12 @@ publish = false name = "pocket-pi-p4" harness = false +# Temporary SQLite spike (src/bin/sqlite_probe.rs) — delete with the probe. +[[bin]] +name = "sqlite-probe" +path = "src/bin/sqlite_probe.rs" +harness = false + [profile.release] opt-level = "s" lto = "thin" @@ -25,14 +31,17 @@ opt-level = "z" anyhow = "1" log = "0.4" serde_json = "1" -pocket-pi-device-ui = { path = "../../crates/pocket-pi-device-ui" } +pocket-pi-agentos = { path = "../../crates/pocket-pi-agentos" } pocket-pi-embedded = { path = "../../crates/pocket-pi-embedded" } pocket-pi-protocols = { path = "../../crates/pocket-pi-protocols" } pocket-pi-tools = { path = "../../crates/pocket-pi-tools" } esp-idf-svc = { version = "0.52.1", features = ["critical-section"] } +# Temporary: SQLite spike dependency (src/bin/sqlite_probe.rs). Same version +# as pocketjs pocket-db so the spike proves the exact engine we will reuse. +rusqlite = { version = "0.40", features = ["bundled"] } embedded-svc = "0.29" -pocketjs-core = { git = "https://github.com/pocket-stack/pocketjs.git", rev = "4c5dc9ef1dd26e6f49b036c210931d399f2b52b2" } -pocketjs-esp32p4-ppa = { git = "https://github.com/pocket-stack/pocketjs.git", rev = "4c5dc9ef1dd26e6f49b036c210931d399f2b52b2" } +pocketjs-core = { git = "https://github.com/siwei-yuan/pocketjs.git", rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" } +pocketjs-esp32p4-ppa = { git = "https://github.com/siwei-yuan/pocketjs.git", rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0", features = ["esp-idf"] } [build-dependencies] embuild = "0.33" @@ -41,6 +50,9 @@ embuild = "0.33" component_dirs = ["components/esp32_p4_wifi6_touch_lcd_5"] bindings_header = "src/waveshare_bindings.h" +[[package.metadata.esp-idf-sys.extra_components]] +component_dirs = ["components/pocketjs_ppa"] + [[package.metadata.esp-idf-sys.extra_components]] remote_component = { name = "espressif/esp_wifi_remote", version = "0.14.*" } diff --git a/firmware/esp32-p4/components/esp32_p4_wifi6_touch_lcd_5/pi_p4_touch_bridge.c b/firmware/esp32-p4/components/esp32_p4_wifi6_touch_lcd_5/pi_p4_touch_bridge.c index 9ea508c..2508420 100644 --- a/firmware/esp32-p4/components/esp32_p4_wifi6_touch_lcd_5/pi_p4_touch_bridge.c +++ b/firmware/esp32-p4/components/esp32_p4_wifi6_touch_lcd_5/pi_p4_touch_bridge.c @@ -1,14 +1,11 @@ #include #include -#include #include "bsp/esp32_p4_wifi6_touch_lcd_5.h" #include "bsp/touch.h" #include "driver/i2c_master.h" #include "esp_lcd_panel_io.h" #include "esp_lcd_touch_gt911.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" esp_err_t pi_p4_touch_new(esp_lcd_touch_handle_t *ret_touch) { @@ -71,47 +68,3 @@ bool pi_p4_touch_read(esp_lcd_touch_handle_t touch, uint16_t *x, uint16_t *y) *y = point.y; return true; } - -bool pi_p4_cpu_load_percent(uint8_t *percent) -{ -#if configGENERATE_RUN_TIME_STATS - enum { MAX_TASKS = 64 }; - static TaskStatus_t tasks[MAX_TASKS]; - static configRUN_TIME_COUNTER_TYPE previous_total = 0; - static uint64_t previous_idle = 0; - configRUN_TIME_COUNTER_TYPE total = 0; - uint64_t idle = 0; - - if (percent == NULL) { - return false; - } - UBaseType_t count = uxTaskGetSystemState(tasks, MAX_TASKS, &total); - if (count == 0) { - return false; - } - for (UBaseType_t index = 0; index < count; ++index) { - if (tasks[index].pcTaskName != NULL && strncmp(tasks[index].pcTaskName, "IDLE", 4) == 0) { - idle += tasks[index].ulRunTimeCounter; - } - } - if (previous_total == 0 || total <= previous_total || idle < previous_idle) { - previous_total = total; - previous_idle = idle; - return false; - } - - const uint64_t elapsed = (uint64_t)(total - previous_total) * configNUMBER_OF_CORES; - const uint64_t idle_elapsed = idle - previous_idle; - previous_total = total; - previous_idle = idle; - if (elapsed == 0) { - return false; - } - const uint64_t idle_percent = (idle_elapsed * 100U) / elapsed; - *percent = (uint8_t)(idle_percent >= 100U ? 0U : 100U - idle_percent); - return true; -#else - (void)percent; - return false; -#endif -} diff --git a/firmware/esp32-p4/components/pocketjs_ppa/CMakeLists.txt b/firmware/esp32-p4/components/pocketjs_ppa/CMakeLists.txt new file mode 100644 index 0000000..1e679f6 --- /dev/null +++ b/firmware/esp32-p4/components/pocketjs_ppa/CMakeLists.txt @@ -0,0 +1,17 @@ +idf_component_register( + SRCS "src/pocketjs_ppa.c" + INCLUDE_DIRS "include" + REQUIRES esp_driver_ppa + PRIV_REQUIRES log +) + +# EspIdfPpaOps normally references this C ABI from a Rust static archive. +# Root the symbols so the one-pass linker extracts this component regardless +# of archive ordering. +target_link_options(${COMPONENT_LIB} INTERFACE + "-Wl,--undefined=pocketjs_ppa_create" + "-Wl,--undefined=pocketjs_ppa_destroy" + "-Wl,--undefined=pocketjs_ppa_fill_rgb565" + "-Wl,--undefined=pocketjs_ppa_blend_a8_rgb565" + "-Wl,--undefined=pocketjs_ppa_srm_psm5650_rgb565" +) diff --git a/firmware/esp32-p4/components/pocketjs_ppa/LICENSE b/firmware/esp32-p4/components/pocketjs_ppa/LICENSE new file mode 100644 index 0000000..bac2cb1 --- /dev/null +++ b/firmware/esp32-p4/components/pocketjs_ppa/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Yifeng "Evan" Wang + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/firmware/esp32-p4/components/pocketjs_ppa/README.md b/firmware/esp32-p4/components/pocketjs_ppa/README.md new file mode 100644 index 0000000..eba7b72 --- /dev/null +++ b/firmware/esp32-p4/components/pocketjs_ppa/README.md @@ -0,0 +1,8 @@ +# pocketjs_ppa + +ESP-IDF component implementing blocking RGB565 FILL, A8-over-RGB565 BLEND, and +PSP PSM5650-to-RGB565 SRM operations for PocketJS on ESP32-P4. + +The public C ABI is normally consumed by the `EspIdfPpaOps` Rust type. See the +[ESP32-P4 host documentation](../../README.md) for integration, compatibility, +buffer ownership, and build instructions. diff --git a/firmware/esp32-p4/components/pocketjs_ppa/SOURCE_PROVENANCE.md b/firmware/esp32-p4/components/pocketjs_ppa/SOURCE_PROVENANCE.md new file mode 100644 index 0000000..5ffc65b --- /dev/null +++ b/firmware/esp32-p4/components/pocketjs_ppa/SOURCE_PROVENANCE.md @@ -0,0 +1,8 @@ +# Source provenance + +The C ABI source is copied from `pocket-stack/pocketjs` at commit +`afc8d4e8e877dac7f9b0c01b5c0d667642009fc0`, matching the Rust dependency +pinned in the firmware manifest. The component manifest retains the +ESP-IDF 5.5 compatibility range already proven by `esp32-pi-agent` on this +board. It provides the C ABI used by +`pocketjs_esp32p4_ppa::EspIdfPpaOps` and remains under PocketJS's MIT license. diff --git a/firmware/esp32-p4/components/pocketjs_ppa/idf_component.yml b/firmware/esp32-p4/components/pocketjs_ppa/idf_component.yml new file mode 100644 index 0000000..b2d393b --- /dev/null +++ b/firmware/esp32-p4/components/pocketjs_ppa/idf_component.yml @@ -0,0 +1,11 @@ +version: "0.1.0" +description: ESP-IDF PPA operations for the PocketJS ESP32-P4 RGB565 renderer +license: MIT +repository: https://github.com/pocket-stack/pocketjs +documentation: https://github.com/pocket-stack/pocketjs/tree/main/hosts/esp32p4 +targets: + - esp32p4 +dependencies: + # The PPA API used by this component is available on the board's pinned + # ESP-IDF 5.5 toolchain as well as the PocketJS upstream 6.x toolchain. + idf: ">=5.5,<6.2" diff --git a/firmware/esp32-p4/components/pocketjs_ppa/include/pocketjs_ppa.h b/firmware/esp32-p4/components/pocketjs_ppa/include/pocketjs_ppa.h new file mode 100644 index 0000000..b48fd91 --- /dev/null +++ b/firmware/esp32-p4/components/pocketjs_ppa/include/pocketjs_ppa.h @@ -0,0 +1,89 @@ +#pragma once + +#include +#include + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct pocketjs_ppa_context *pocketjs_ppa_handle_t; + +/** + * Register one blocking FILL, BLEND, and SRM client for a renderer. + * + * ESP-IDF recommends that each task own its clients. The returned handle must + * therefore be used and destroyed by the same rendering task. + */ +esp_err_t pocketjs_ppa_create(pocketjs_ppa_handle_t *out_handle); + +/** + * Unregister all clients and release the handle. A NULL handle is accepted. + */ +void pocketjs_ppa_destroy(pocketjs_ppa_handle_t handle); + +/** + * The following narrow C ABI is consumed by EspIdfPpaOps in the + * pocketjs-esp32p4-ppa crate. Each function returns 1 after a completed + * blocking transaction or 0 when the renderer must use its ordered software + * fallback. + */ +int pocketjs_ppa_fill_rgb565( + pocketjs_ppa_handle_t handle, + uint16_t *destination, + size_t destination_pixels, + uint32_t width, + uint32_t height, + uint32_t x, + uint32_t y, + uint32_t rect_width, + uint32_t rect_height, + uint16_t color +); + +int pocketjs_ppa_blend_a8_rgb565( + pocketjs_ppa_handle_t handle, + uint16_t *destination, + size_t destination_pixels, + uint32_t width, + uint32_t height, + const uint8_t *mask, + size_t mask_len, + uint32_t x, + uint32_t y, + uint32_t rect_width, + uint32_t rect_height, + uint8_t red, + uint8_t green, + uint8_t blue, + uint8_t global_alpha +); + +int pocketjs_ppa_srm_psm5650_rgb565( + pocketjs_ppa_handle_t handle, + uint16_t *destination, + size_t destination_pixels, + uint32_t width, + uint32_t height, + const uint8_t *source, + size_t source_len, + uint32_t source_width, + uint32_t source_height, + uint32_t source_x, + uint32_t source_y, + uint32_t source_rect_width, + uint32_t source_rect_height, + uint32_t destination_x, + uint32_t destination_y, + uint32_t destination_rect_width, + uint32_t destination_rect_height, + uint32_t quarter_turn, + int mirror_x, + int mirror_y +); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/esp32-p4/components/pocketjs_ppa/src/pocketjs_ppa.c b/firmware/esp32-p4/components/pocketjs_ppa/src/pocketjs_ppa.c new file mode 100644 index 0000000..ea91e78 --- /dev/null +++ b/firmware/esp32-p4/components/pocketjs_ppa/src/pocketjs_ppa.c @@ -0,0 +1,468 @@ +#include "pocketjs_ppa.h" + +#include +#include +#include + +#include "driver/ppa.h" +#include "esp_log.h" + +static const char *TAG = "pocketjs_ppa"; + +struct pocketjs_ppa_context { + ppa_client_handle_t fill; + ppa_client_handle_t blend; + ppa_client_handle_t srm; + bool fill_error_logged; + bool blend_error_logged; + bool srm_error_logged; +}; + +static bool surface_is_valid( + const void *buffer, + size_t pixels, + uint32_t width, + uint32_t height, + size_t bytes_per_pixel +) +{ + if (buffer == NULL || width == 0 || height == 0 || bytes_per_pixel == 0) { + return false; + } + return (size_t)width <= SIZE_MAX / (size_t)height && + pixels == (size_t)width * (size_t)height && + pixels <= SIZE_MAX / bytes_per_pixel; +} + +static bool rect_is_valid( + uint32_t surface_width, + uint32_t surface_height, + uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height +) +{ + return width > 0 && + height > 0 && + x <= surface_width && + y <= surface_height && + width <= surface_width - x && + height <= surface_height - y; +} + +static bool byte_ranges_overlap( + const void *first, + size_t first_size, + const void *second, + size_t second_size +) +{ + const uintptr_t first_start = (uintptr_t)first; + const uintptr_t second_start = (uintptr_t)second; + if (first_size > UINTPTR_MAX - first_start || + second_size > UINTPTR_MAX - second_start) { + return true; + } + const uintptr_t first_end = first_start + first_size; + const uintptr_t second_end = second_start + second_size; + return first_start < second_end && second_start < first_end; +} + +static color_pixel_argb8888_data_t rgb565_to_argb8888(uint16_t color) +{ + const uint8_t red5 = (uint8_t)((color >> 11) & 0x1FU); + const uint8_t green6 = (uint8_t)((color >> 5) & 0x3FU); + const uint8_t blue5 = (uint8_t)(color & 0x1FU); + const color_pixel_argb8888_data_t expanded = { + .r = (uint8_t)((red5 << 3) | (red5 >> 2)), + .g = (uint8_t)((green6 << 2) | (green6 >> 4)), + .b = (uint8_t)((blue5 << 3) | (blue5 >> 2)), + .a = UINT8_MAX, + }; + return expanded; +} + +static void log_operation_failure_once( + const char *operation, + esp_err_t error, + bool *already_logged +) +{ + if (!*already_logged) { + ESP_LOGW( + TAG, + "PPA %s failed (%s); using ordered RGB565 software fallback", + operation, + esp_err_to_name(error) + ); + *already_logged = true; + } +} + +static esp_err_t register_client( + ppa_operation_t operation, + ppa_client_handle_t *out_client +) +{ + const ppa_client_config_t config = { + .oper_type = operation, + .max_pending_trans_num = 1, + .data_burst_length = PPA_DATA_BURST_LENGTH_128, + }; + return ppa_register_client(&config, out_client); +} + +esp_err_t pocketjs_ppa_create(pocketjs_ppa_handle_t *out_handle) +{ + if (out_handle == NULL) { + return ESP_ERR_INVALID_ARG; + } + *out_handle = NULL; + + pocketjs_ppa_handle_t handle = calloc(1, sizeof(*handle)); + if (handle == NULL) { + return ESP_ERR_NO_MEM; + } + + esp_err_t result = register_client(PPA_OPERATION_FILL, &handle->fill); + if (result == ESP_OK) { + result = register_client(PPA_OPERATION_BLEND, &handle->blend); + } + if (result == ESP_OK) { + result = register_client(PPA_OPERATION_SRM, &handle->srm); + } + if (result != ESP_OK) { + ESP_LOGE( + TAG, + "failed to register PocketJS PPA clients: %s", + esp_err_to_name(result) + ); + pocketjs_ppa_destroy(handle); + return result; + } + + *out_handle = handle; + ESP_LOGI(TAG, "RGB565 backend ready: FILL + A8 BLEND + SRM"); + return ESP_OK; +} + +void pocketjs_ppa_destroy(pocketjs_ppa_handle_t handle) +{ + if (handle == NULL) { + return; + } + if (handle->srm != NULL) { + (void)ppa_unregister_client(handle->srm); + } + if (handle->blend != NULL) { + (void)ppa_unregister_client(handle->blend); + } + if (handle->fill != NULL) { + (void)ppa_unregister_client(handle->fill); + } + free(handle); +} + +int pocketjs_ppa_fill_rgb565( + pocketjs_ppa_handle_t handle, + uint16_t *destination, + size_t destination_pixels, + uint32_t width, + uint32_t height, + uint32_t x, + uint32_t y, + uint32_t rect_width, + uint32_t rect_height, + uint16_t color +) +{ + if (handle == NULL || + handle->fill == NULL || + !surface_is_valid( + destination, + destination_pixels, + width, + height, + sizeof(*destination) + ) || + !rect_is_valid(width, height, x, y, rect_width, rect_height)) { + return 0; + } + + const ppa_fill_oper_config_t operation = { + .out = { + .buffer = destination, + .buffer_size = destination_pixels * sizeof(*destination), + .pic_w = width, + .pic_h = height, + .block_offset_x = x, + .block_offset_y = y, + .fill_cm = PPA_FILL_COLOR_MODE_RGB565, + }, + .fill_block_w = rect_width, + .fill_block_h = rect_height, + // The fixed fill pixel is supplied as ARGB components even when the + // output mode is RGB565. A packed RGB565 word produces wrong colors. + .fill_argb_color = rgb565_to_argb8888(color), + .mode = PPA_TRANS_MODE_BLOCKING, + }; + const esp_err_t result = ppa_do_fill(handle->fill, &operation); + if (result != ESP_OK) { + log_operation_failure_once( + "fill", + result, + &handle->fill_error_logged + ); + return 0; + } + return 1; +} + +int pocketjs_ppa_blend_a8_rgb565( + pocketjs_ppa_handle_t handle, + uint16_t *destination, + size_t destination_pixels, + uint32_t width, + uint32_t height, + const uint8_t *mask, + size_t mask_len, + uint32_t x, + uint32_t y, + uint32_t rect_width, + uint32_t rect_height, + uint8_t red, + uint8_t green, + uint8_t blue, + uint8_t global_alpha +) +{ + if (global_alpha == 0) { + return 1; + } + if (handle == NULL || + handle->blend == NULL || + !surface_is_valid( + destination, + destination_pixels, + width, + height, + sizeof(*destination) + ) || + !surface_is_valid(mask, mask_len, width, height, sizeof(*mask)) || + !rect_is_valid(width, height, x, y, rect_width, rect_height)) { + return 0; + } + + ppa_blend_oper_config_t operation = { + .in_bg = { + .buffer = destination, + .pic_w = width, + .pic_h = height, + .block_w = rect_width, + .block_h = rect_height, + .block_offset_x = x, + .block_offset_y = y, + .blend_cm = PPA_BLEND_COLOR_MODE_RGB565, + }, + .in_fg = { + .buffer = mask, + .pic_w = width, + .pic_h = height, + .block_w = rect_width, + .block_h = rect_height, + .block_offset_x = x, + .block_offset_y = y, + .blend_cm = PPA_BLEND_COLOR_MODE_A8, + }, + .out = { + .buffer = destination, + .buffer_size = destination_pixels * sizeof(*destination), + .pic_w = width, + .pic_h = height, + .block_offset_x = x, + .block_offset_y = y, + .blend_cm = PPA_BLEND_COLOR_MODE_RGB565, + }, + .bg_alpha_update_mode = PPA_ALPHA_NO_CHANGE, + .fg_alpha_update_mode = PPA_ALPHA_NO_CHANGE, + .fg_fix_rgb_val = { + .r = red, + .g = green, + .b = blue, + }, + .mode = PPA_TRANS_MODE_BLOCKING, + }; + if (global_alpha < UINT8_MAX) { + const uint32_t fixed_alpha = + ((uint32_t)global_alpha * 256U + 127U) / 255U; + operation.fg_alpha_update_mode = PPA_ALPHA_SCALE; + operation.fg_alpha_scale_ratio = (float)fixed_alpha / 256.0f; + } + + const esp_err_t result = ppa_do_blend(handle->blend, &operation); + if (result != ESP_OK) { + log_operation_failure_once( + "blend", + result, + &handle->blend_error_logged + ); + return 0; + } + return 1; +} + +static bool exact_scale( + uint32_t source_extent, + uint32_t destination_extent, + float *out_scale +) +{ + if (source_extent == 0 || destination_extent > UINT32_MAX / 16U) { + return false; + } + const uint32_t sixteenths_numerator = destination_extent * 16U; + if ((sixteenths_numerator % source_extent) != 0) { + return false; + } + const uint32_t sixteenths = sixteenths_numerator / source_extent; + if (sixteenths == 0 || sixteenths >= 256U * 16U) { + return false; + } + *out_scale = (float)sixteenths / 16.0f; + return true; +} + +int pocketjs_ppa_srm_psm5650_rgb565( + pocketjs_ppa_handle_t handle, + uint16_t *destination, + size_t destination_pixels, + uint32_t width, + uint32_t height, + const uint8_t *source, + size_t source_len, + uint32_t source_width, + uint32_t source_height, + uint32_t source_x, + uint32_t source_y, + uint32_t source_rect_width, + uint32_t source_rect_height, + uint32_t destination_x, + uint32_t destination_y, + uint32_t destination_rect_width, + uint32_t destination_rect_height, + uint32_t quarter_turn, + int mirror_x, + int mirror_y +) +{ + if (handle == NULL || + handle->srm == NULL || + !surface_is_valid( + destination, + destination_pixels, + width, + height, + sizeof(*destination) + ) || + source == NULL || + source_width == 0 || + source_height == 0 || + (size_t)source_width > SIZE_MAX / (size_t)source_height || + (size_t)source_width * (size_t)source_height > SIZE_MAX / 2U) { + return 0; + } + + const size_t source_required = + (size_t)source_width * (size_t)source_height * 2U; + const size_t destination_size = + destination_pixels * sizeof(*destination); + if (source_len < source_required || + byte_ranges_overlap( + source, + source_required, + destination, + destination_size + ) || + !rect_is_valid( + source_width, + source_height, + source_x, + source_y, + source_rect_width, + source_rect_height + ) || + !rect_is_valid( + width, + height, + destination_x, + destination_y, + destination_rect_width, + destination_rect_height + ) || + quarter_turn > 3U) { + return 0; + } + + const bool swaps_axes = quarter_turn == 1U || quarter_turn == 3U; + const uint32_t scaled_width = swaps_axes + ? destination_rect_height + : destination_rect_width; + const uint32_t scaled_height = swaps_axes + ? destination_rect_width + : destination_rect_height; + float scale_x = 0.0f; + float scale_y = 0.0f; + if (!exact_scale(source_rect_width, scaled_width, &scale_x) || + !exact_scale(source_rect_height, scaled_height, &scale_y)) { + return 0; + } + + const ppa_srm_rotation_angle_t rotations[] = { + PPA_SRM_ROTATION_ANGLE_0, + PPA_SRM_ROTATION_ANGLE_90, + PPA_SRM_ROTATION_ANGLE_180, + PPA_SRM_ROTATION_ANGLE_270, + }; + const ppa_srm_oper_config_t operation = { + .in = { + .buffer = source, + .pic_w = source_width, + .pic_h = source_height, + .block_w = source_rect_width, + .block_h = source_rect_height, + .block_offset_x = source_x, + .block_offset_y = source_y, + .srm_cm = PPA_SRM_COLOR_MODE_RGB565, + }, + .out = { + .buffer = destination, + .buffer_size = destination_size, + .pic_w = width, + .pic_h = height, + .block_offset_x = destination_x, + .block_offset_y = destination_y, + .srm_cm = PPA_SRM_COLOR_MODE_RGB565, + }, + .rotation_angle = rotations[quarter_turn], + .scale_x = scale_x, + .scale_y = scale_y, + .mirror_x = mirror_x != 0, + .mirror_y = mirror_y != 0, + .rgb_swap = true, + .byte_swap = false, + .alpha_update_mode = PPA_ALPHA_NO_CHANGE, + .mode = PPA_TRANS_MODE_BLOCKING, + }; + const esp_err_t result = + ppa_do_scale_rotate_mirror(handle->srm, &operation); + if (result != ESP_OK) { + log_operation_failure_once( + "SRM", + result, + &handle->srm_error_logged + ); + return 0; + } + return 1; +} diff --git a/firmware/esp32-p4/components_esp32p4.lock b/firmware/esp32-p4/components_esp32p4.lock index d143cff..c852a02 100644 --- a/firmware/esp32-p4/components_esp32p4.lock +++ b/firmware/esp32-p4/components_esp32p4.lock @@ -153,6 +153,6 @@ direct_dependencies: - idf - joltwallet/littlefs - waveshare/esp_lcd_hx8394 -manifest_hash: a4c3032b83ef98ef2fd7e20dcd6f9fe17a1ade1defcb0e8bfa0184245cbf83f1 +manifest_hash: f580ce29f698ad36eb00e6342d57a6c0aa991afcd88977548bbc0fa306c9b088 target: esp32p4 version: 2.0.0 diff --git a/firmware/esp32-p4/sdkconfig.defaults b/firmware/esp32-p4/sdkconfig.defaults index a78cfc5..ab991d9 100644 --- a/firmware/esp32-p4/sdkconfig.defaults +++ b/firmware/esp32-p4/sdkconfig.defaults @@ -27,6 +27,8 @@ CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y CONFIG_BSP_LCD_DPI_BUFFER_NUMS=3 CONFIG_BSP_LCD_COLOR_FORMAT_RGB565=y +# The IDF entry task only queues the small AgentOS launcher. Keeping this small +# releases enough contiguous internal RAM for the full runtime task afterward. CONFIG_ESP_MAIN_TASK_STACK_SIZE=16384 CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096 CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=4096 @@ -34,8 +36,6 @@ CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=4096 # Expose per-task runtime counters so the status bar can report real average # CPU utilization across both ESP32-P4 cores. -CONFIG_FREERTOS_USE_TRACE_FACILITY=y -CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y # HTTPS clients need the ESP-IDF certificate bundle. Model endpoints # still perform normal hostname verification. diff --git a/firmware/esp32-p4/shim/sys/ioctl.h b/firmware/esp32-p4/shim/sys/ioctl.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/firmware/esp32-p4/shim/sys/ioctl.h @@ -0,0 +1 @@ + diff --git a/firmware/esp32-p4/src/agentos_main.rs b/firmware/esp32-p4/src/agentos_main.rs new file mode 100644 index 0000000..08f220f --- /dev/null +++ b/firmware/esp32-p4/src/agentos_main.rs @@ -0,0 +1,731 @@ +use core::time::Duration; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; +use std::time::Instant; + +use pocket_pi_agentos::{ + AppServiceHost, AppSupervisor, RoutedToolHost, DATA_ACTION_STACK_BYTES, +}; +use pocket_pi_embedded::{AgentEvent, ModelBackend, ToolHost}; +use pocket_pi_protocols::model::ModelBackendSettings; +use pocket_pi_tools::CoreToolHost; +use pocketjs_esp32p4_ppa::{EspIdfPpaOps, RenderTargetState, Renderer}; +use serde_json::{json, Value}; + +use super::{ + app_services::EspAppServices, + backend, + device_state::{SettingsProjection, WifiSettingsProjection}, + esp_result, init_wifi, storage, transport, DisplayProbe, EspPlatform, + BOARD_NAME, PANEL_HEIGHT, PANEL_WIDTH, +}; + +#[derive(Clone)] +struct Message { + role: &'static str, + text: String, +} + +pub fn run() -> anyhow::Result<()> { + let _workspace = storage::mount_workspace()?; + + let uart = Arc::new( + transport::UartLineTransport::new() + .map_err(|error| anyhow::anyhow!("initialize UART transport: {error}"))?, + ); + let runtime_config = + match transport::request_runtime_config(uart.as_ref(), Duration::from_secs(5)) { + Ok(config) => config, + Err(error) => { + log::warn!("No UART runtime config received: {error}"); + transport::RuntimeConfig::default() + } + }; + if let Some(seconds) = runtime_config.unix_time_seconds { + let time = esp_idf_svc::sys::timeval { + tv_sec: seconds as i64, + tv_usec: 0, + }; + if unsafe { esp_idf_svc::sys::settimeofday(&time, core::ptr::null()) } == 0 { + log::info!("clock seeded by UART bridge"); + } + } + + let mut wifi = match init_wifi( + runtime_config.wifi_ssid.as_deref(), + runtime_config.wifi_password.as_deref(), + ) { + Ok(wifi) => { + log::info!("C6-SDIO Wi-Fi and lwIP netif active"); + Some(wifi) + } + Err(error) => { + log::error!("C6-SDIO Wi-Fi radio probe failed: {error:#}"); + None + } + }; + let mut settings = wifi + .as_ref() + .map(|wifi| { + wifi.projection(if wifi.is_connecting() { + "CONNECTING..." + } else if wifi.is_connected() { + "CONNECTED" + } else { + "NOT CONNECTED" + }) + }) + .unwrap_or_else(|| SettingsProjection { + firmware_version: env!("CARGO_PKG_VERSION").into(), + workspace_free_bytes: storage::workspace_free_bytes().ok(), + wifi: WifiSettingsProjection { + status: "WI-FI DRIVER UNAVAILABLE".into(), + ..Default::default() + }, + }); + let _sntp = if wifi.is_some() { + esp_idf_svc::sntp::EspSntp::new_default().ok() + } else { + None + }; + + let model_settings = runtime_config.model.clone(); + let provider = match model_settings.backend { + ModelBackendSettings::Uart { .. } => "uart", + ModelBackendSettings::Wireless { provider } => provider.id(), + }; + let resolved_model = model_settings + .resolved_model() + .unwrap_or_else(|_| "unknown".into()); + let uart_poc = matches!(model_settings.backend, ModelBackendSettings::Uart { .. }); + let backend: Arc = match model_settings.backend { + ModelBackendSettings::Uart { .. } => { + let transport: Arc = uart; + Arc::new(backend::UartBackend::new(transport)) + } + ModelBackendSettings::Wireless { provider } => Arc::new( + backend::WirelessBackend::new( + provider, + runtime_config + .model_api_key + .ok_or_else(|| anyhow::anyhow!("wireless backend is missing API key"))?, + ) + .map_err(anyhow::Error::msg)?, + ), + }; + + let network_ready = Arc::new(AtomicBool::new( + wifi.as_ref().is_some_and(|wifi| wifi.is_connected()), + )); + let services: Arc = Arc::new(EspAppServices::new( + network_ready.clone(), + runtime_config.exa_api_key, + runtime_config.robinhood_access_token, + )); + let mut supervisor = with_data_action_pthread_config(|| { + AppSupervisor::new(storage::WORKSPACE_ROOT, services) + })?; + supervisor.frame()?; + + let mut renderer = pocketjs_esp32p4_ppa::Renderer::new(Default::default()) + .ok_or_else(|| anyhow::anyhow!("invalid PocketJS renderer configuration"))?; + let mut ppa = EspIdfPpaOps::new() + .map_err(|error| anyhow::anyhow!("initialize PocketJS PPA: ESP-IDF error 0x{error:x}"))?; + log::info!("Pocket Pi AgentOS hardware boot: {BOARD_NAME}"); + let mut display = match init_display(&mut renderer, &mut ppa, &supervisor) { + Ok(display) => { + log::info!("MIPI-DSI panel active with PocketJS App View"); + Some(display) + } + Err(error) => { + log::error!("MIPI-DSI panel failed: {error:#}"); + None + } + }; + let native_tools = Arc::new(CoreToolHost::new( + storage::WORKSPACE_ROOT, + Arc::new(EspPlatform), + )); + let native: Arc = native_tools.clone(); + let (routed_tools, app_rx) = RoutedToolHost::new(native, supervisor.catalog().clone()); + let config = json!({ + "provider":provider, + "model":resolved_model, + "systemPrompt":"You are Pi Agent, the first-class system App in Pocket Pi AgentOS on an ESP32-P4. You can manage the top-level /workspace and use installed App tools. Be concise. Robinhood data is owned by the Robinhood App; Exa research history is owned by the Exa App." + }); + supervisor.boot_agent(&config.to_string(), backend, Arc::new(routed_tools))?; + + let mut messages = vec![Message { + role: "assistant", + text: "Pocket Pi AgentOS is starting. Robinhood and Exa are installed Apps.".into(), + }]; + let mut agent_status = "STARTING"; + let mut busy = false; + let mut initial_prompt = runtime_config.initial_prompt; + let initial_prompt_not_before = + Instant::now() + Duration::from_secs(runtime_config.initial_prompt_delay_seconds); + let mut touch_was_down = false; + let mut redraw = true; + let mut projection_dirty = true; + let mut pending_ui_task: Option = None; + let mut last_tick = Instant::now(); + let mut last_runtime_pump = Instant::now(); + let mut last_projection_refresh = Instant::now(); + let mut last_heartbeat = Instant::now(); + let mut last_wifi_poll = Instant::now(); + let mut last_wifi_connected = wifi.as_ref().is_some_and(|wifi| wifi.is_connected()); + + loop { + while let Ok(request) = app_rx.try_recv() { + request.handle(&mut supervisor); + redraw = true; + projection_dirty = true; + } + + if let Some(display) = display.as_mut() { + if let Some((x, y)) = display.read_touch() { + if !touch_was_down { + let action = supervisor.tap(x, y)?; + match action.get("type").and_then(Value::as_str) { + Some("navigate") => { + if let Some(app) = action.get("app").and_then(Value::as_str) { + supervisor.open(app)?; + projection_dirty = true; + } + } + Some("submitPrompt") => { + if let Some(prompt) = action.get("prompt").and_then(Value::as_str) { + submit_prompt( + prompt.to_owned(), + &supervisor, + &mut messages, + &mut busy, + &mut agent_status, + ); + projection_dirty = true; + } + } + Some("invokeTask") => { + if let Some(task) = action.get("task").and_then(Value::as_str) { + pending_ui_task = Some(task.to_owned()); + } + } + Some("settings") => { + match action.get("command").and_then(Value::as_str) { + Some("scan") => match wifi.as_mut() { + Some(wifi) => { + settings.wifi.scanning = true; + settings.wifi.status = "SCANNING...".into(); + match wifi.scan() { + Ok(networks) => { + settings = wifi.projection(""); + settings.wifi.networks = networks; + } + Err(error) => { + settings.wifi.status = + format!("SCAN FAILED: {error}"); + } + } + settings.wifi.scanning = false; + } + None => { + settings.wifi.status = "WI-FI DRIVER UNAVAILABLE".into() + } + }, + Some("connect") => { + let ssid = + action.get("ssid").and_then(Value::as_str).unwrap_or(""); + let password = action + .get("password") + .and_then(Value::as_str) + .unwrap_or(""); + match wifi.as_mut() { + Some(wifi) => match wifi.begin_connect(ssid, password, true) { + Ok(()) => { + settings = wifi.projection("CONNECTING..."); + last_wifi_poll = Instant::now(); + } + Err(error) => { + settings.wifi.status = + format!("CONNECT FAILED: {error}") + } + }, + None => { + settings.wifi.status = "WI-FI DRIVER UNAVAILABLE".into() + } + } + } + Some("forget") => match wifi.as_mut() { + Some(wifi) => match wifi.forget() { + Ok(()) => settings = wifi.projection("NETWORK FORGOTTEN"), + Err(error) => { + settings.wifi.status = format!("FORGET FAILED: {error}") + } + }, + None => { + settings.wifi.status = "WI-FI DRIVER UNAVAILABLE".into() + } + }, + Some("restart") => unsafe { + esp_idf_svc::sys::esp_restart(); + }, + _ => {} + } + settings.workspace_free_bytes = storage::workspace_free_bytes().ok(); + projection_dirty = true; + } + _ => {} + } + redraw = true; + } + touch_was_down = true; + } else { + touch_was_down = false; + } + } + + if last_wifi_poll.elapsed() >= Duration::from_millis(500) { + last_wifi_poll = Instant::now(); + if let Some(wifi) = wifi.as_mut() { + match wifi.poll_connect() { + Some(Ok(())) => { + settings = wifi.projection("CONNECTED"); + projection_dirty = true; + redraw = true; + log::info!("Wi-Fi association and DHCP completed"); + } + Some(Err(error)) => { + settings = wifi.projection(format!("CONNECT FAILED: {error}")); + projection_dirty = true; + redraw = true; + log::warn!("Wi-Fi connection attempt failed: {error:#}"); + } + None => {} + } + } + let connected = wifi.as_ref().is_some_and(|wifi| wifi.is_connected()); + network_ready.store(connected, Ordering::Release); + if connected != last_wifi_connected { + last_wifi_connected = connected; + if let Some(wifi) = wifi.as_ref().filter(|wifi| !wifi.is_connecting()) { + let networks = core::mem::take(&mut settings.wifi.networks); + settings = wifi.projection(if connected { + "CONNECTED" + } else { + "NOT CONNECTED" + }); + settings.wifi.networks = networks; + projection_dirty = true; + redraw = true; + } + log::info!( + "Wi-Fi link state changed: {}", + if connected { "connected" } else { "disconnected" } + ); + } + } + + if last_tick.elapsed() >= Duration::from_secs(1) { + if !busy && agent_status == "IDLE" && initial_prompt.is_none() { + if let Some(wake) = native_tools.claim_due() { + submit_prompt( + wake.prompt, + &supervisor, + &mut messages, + &mut busy, + &mut agent_status, + ); + } + // The ESP32 v1 runtime has one App/SQLite execution owner. + // App schedules wait for an active Agent turn to complete so + // they cannot overlap an App Tool or its transaction. + let app_results = if busy { + Vec::new() + } else { + supervisor.poll_due_tasks() + }; + for (task, result) in &app_results { + log::info!("AppTask {task}: {}", result.text); + } + if !app_results.is_empty() { + redraw = true; + } + } + last_tick = Instant::now(); + } + + if last_projection_refresh.elapsed() >= Duration::from_secs(5) { + if supervisor.active_id() == pocket_pi_agentos::ROOT_APP_ID { + projection_dirty = true; + redraw = true; + } + last_projection_refresh = Instant::now(); + } + + if projection_dirty { + let projection = root_projection( + &messages, + agent_status, + provider, + &resolved_model, + &settings, + native_tools.as_ref(), + ); + supervisor.update_root(&projection)?; + projection_dirty = false; + } + if supervisor.active_projection_is_stale() { + // A background App commit is itself a redraw cause. The check is + // one atomic revision comparison; SQLite is read only after the + // active View consumes the invalidation below. + redraw = true; + } + // Touch sampling stays at the display cadence, while entering QuickJS + // is event-driven and capped at 20 Hz. An idle system therefore leaves + // most CPU0 time to FreeRTOS and navigation is not queued behind + // redundant Agent/App tick calls. + if redraw || last_runtime_pump.elapsed() >= Duration::from_millis(50) { + for event in supervisor.frame_render(redraw)? { + match event { + AgentEvent::Ready => { + log::info!("Pi Agent System App ready with App Tool registry"); + if uart_poc { + unsafe { + esp_idf_svc::sys::esp_log_level_set( + c"*".as_ptr(), + esp_idf_svc::sys::esp_log_level_t_ESP_LOG_WARN, + ); + // Keep App transport stage boundaries visible on UART without + // restoring noisy global INFO logging or exposing response data. + esp_idf_svc::sys::esp_log_level_set( + c"pocket_pi_p4::app_services".as_ptr(), + esp_idf_svc::sys::esp_log_level_t_ESP_LOG_INFO, + ); + } + } + agent_status = "IDLE"; + messages[0].text = "ESP32-P4 Pi Agent is ready.".into(); + } + AgentEvent::ResponseText(text) => { + if let Some(message) = messages.last_mut() { + message.text.push_str(&text); + } + } + AgentEvent::Done => { + agent_status = "IDLE"; + busy = false; + } + AgentEvent::Failed(error) => { + log::error!("Pi Agent failed: {error}"); + if let Some(message) = messages.last_mut() { + message.text = format!("Agent failed: {error}"); + } + agent_status = "FAULTED"; + busy = false; + } + } + redraw = true; + projection_dirty = true; + } + last_runtime_pump = Instant::now(); + } + + if agent_status == "IDLE" + && !busy + && initial_prompt.is_some() + && Instant::now() >= initial_prompt_not_before + { + if let Some(prompt) = initial_prompt.take() { + submit_prompt( + prompt, + &supervisor, + &mut messages, + &mut busy, + &mut agent_status, + ); + redraw = true; + projection_dirty = true; + } + } + + if redraw { + if let Some(display) = display.as_mut() { + display.render_agentos(&mut renderer, &mut ppa, &supervisor)?; + } + redraw = false; + } + + // A UI-requested task runs only after its loading state has reached the + // panel. This preserves immediate touch feedback even when HTTPS is slow. + if !busy { + if let Some(task) = pending_ui_task.take() { + let started = Instant::now(); + let result = supervisor.invoke_active_task(&task, &Value::Null); + log::info!( + "UI AppTask {} finished in {}ms: {}", + task, + started.elapsed().as_millis(), + result.text + ); + supervisor.frame()?; + redraw = true; + } + } + + if last_heartbeat.elapsed() >= Duration::from_secs(5) { + log::info!( + "heartbeat app_data_action={} agent={} app={}", + if supervisor.services_busy() { + "running" + } else { + "idle" + }, + agent_status, + supervisor.active_id(), + ); + last_heartbeat = Instant::now(); + } + // AgentOS is a native FreeRTOS task, not a pthread. Use the native + // delay primitive so CPU0's idle task is guaranteed a scheduling + // window and can feed the task watchdog. + unsafe { esp_idf_svc::sys::vTaskDelay(16) }; + } +} + +fn with_data_action_pthread_config( + action: impl FnOnce() -> anyhow::Result, +) -> anyhow::Result { + // std::thread maps to ESP-IDF pthread. Its default stack allocation is + // internal RAM, where a QuickJS Data Action Guest cannot fit. Configure + // only this child creation to use byte-addressable PSRAM, then restore the + // platform default for unrelated threads created later by the System App. + let default = unsafe { esp_idf_svc::sys::esp_pthread_get_default_config() }; + let mut config = default; + config.stack_size = DATA_ACTION_STACK_BYTES; + config.inherit_cfg = false; + config.pin_to_core = 1; + config.stack_alloc_caps = + esp_idf_svc::sys::MALLOC_CAP_SPIRAM | esp_idf_svc::sys::MALLOC_CAP_8BIT; + let configured = unsafe { esp_idf_svc::sys::esp_pthread_set_cfg(&config) }; + if configured != esp_idf_svc::sys::ESP_OK { + anyhow::bail!("configure App Data Action pthread: ESP-IDF error 0x{configured:x}"); + } + let result = action(); + let restored = unsafe { esp_idf_svc::sys::esp_pthread_set_cfg(&default) }; + if restored != esp_idf_svc::sys::ESP_OK { + anyhow::bail!("restore pthread defaults: ESP-IDF error 0x{restored:x}"); + } + result +} + +fn submit_prompt( + prompt: String, + supervisor: &AppSupervisor, + messages: &mut Vec, + busy: &mut bool, + agent_status: &mut &'static str, +) { + if *busy || prompt.trim().is_empty() { + return; + } + messages.push(Message { + role: "user", + text: prompt.clone(), + }); + messages.push(Message { + role: "assistant", + text: String::new(), + }); + *busy = true; + *agent_status = "THINKING"; + if let Err(error) = supervisor.prompt_agent(&prompt) { + messages.last_mut().unwrap().text = format!("Agent is unavailable: {error:#}"); + *busy = false; + *agent_status = "FAULTED"; + } +} + +fn root_projection( + messages: &[Message], + agent_status: &str, + provider: &str, + model: &str, + settings: &SettingsProjection, + tools: &CoreToolHost, +) -> Value { + let schedule = tools.schedule_projection(); + let schedule_text = match schedule.next_in_seconds { + Some(seconds) => schedule.every_minutes.map_or_else( + || format!("in {seconds}s"), + |minutes| format!("in {seconds}s · every {minutes}m"), + ), + None => "not scheduled".to_owned(), + }; + json!({ + "agent":agent_status, + "model":format!("{provider} / {model}"), + "messages":messages.iter().map(|message| json!({"role":message.role,"text":message.text})).collect::>(), + "schedule":{ + "name":schedule.name, + "prompt":schedule.prompt, + "next":schedule_text, + "everyMinutes":schedule.every_minutes, + }, + "settings":{ + "wifi":{ + "connectedSsid":settings.wifi.connected_ssid, + "ipAddress":settings.wifi.ip_address, + "rssiDbm":settings.wifi.rssi_dbm, + "scanning":settings.wifi.scanning, + "networks":settings.wifi.networks.iter().map(|network| json!({ + "ssid":network.ssid, + "rssiDbm":network.rssi_dbm, + "secured":network.secured, + })).collect::>(), + "status":settings.wifi.status, + }, + "firmwareVersion":settings.firmware_version, + "workspaceFree":settings.workspace_free_bytes.map(|bytes| format!("{} KB", bytes / 1024)), + }, + }) +} + +fn init_display( + renderer: &mut Renderer, + ppa: &mut EspIdfPpaOps, + supervisor: &AppSupervisor, +) -> anyhow::Result { + unsafe { + let mut panel = core::ptr::null_mut(); + let mut io = core::ptr::null_mut(); + let mut touch = core::ptr::null_mut(); + let mut framebuffer_0 = core::ptr::null_mut(); + let mut framebuffer_1 = core::ptr::null_mut(); + let mut framebuffer_2 = core::ptr::null_mut(); + + esp_result( + "bsp_display_new", + esp_idf_svc::sys::bsp_display_new(core::ptr::null(), &mut panel, &mut io), + )?; + esp_result( + "esp_lcd_dpi_panel_get_frame_buffer", + esp_idf_svc::sys::esp_lcd_dpi_panel_get_frame_buffer( + panel, + 3, + &mut framebuffer_0, + &mut framebuffer_1, + &mut framebuffer_2, + ), + )?; + let framebuffers = [framebuffer_0, framebuffer_1, framebuffer_2]; + if framebuffers.iter().any(|framebuffer| framebuffer.is_null()) { + anyhow::bail!("esp_lcd_dpi_panel_get_frame_buffer returned a null buffer") + } + + let pixels = core::slice::from_raw_parts_mut( + framebuffers[0].cast::(), + PANEL_WIDTH as usize * PANEL_HEIGHT as usize, + ); + let mut render_states = [ + RenderTargetState::new(), + RenderTargetState::new(), + RenderTargetState::new(), + ]; + supervisor.with_ui(|ui| { + let words = ui.draw().words.clone(); + renderer + .render_incremental( + &mut render_states[0], + ui, + &words, + pixels, + PANEL_WIDTH, + PANEL_HEIGHT, + ppa, + ) + .ok_or_else(|| anyhow::anyhow!("PocketJS rejected the App framebuffer geometry")) + })?; + + esp_result( + "esp_lcd_dpi_panel_set_pattern", + esp_idf_svc::sys::esp_lcd_dpi_panel_set_pattern( + panel, + esp_idf_svc::sys::mipi_dsi_pattern_type_t_MIPI_DSI_PATTERN_NONE, + ), + )?; + esp_result( + "esp_lcd_panel_disp_on_off", + esp_idf_svc::sys::esp_lcd_panel_disp_on_off(panel, true), + )?; + esp_result("esp_lcd_panel_draw_bitmap", { + esp_idf_svc::sys::esp_lcd_panel_draw_bitmap( + panel, + 0, + 0, + PANEL_WIDTH as i32, + PANEL_HEIGHT as i32, + framebuffers[0], + ) + })?; + esp_result( + "bsp_display_backlight_on", + esp_idf_svc::sys::bsp_display_backlight_on(), + )?; + esp_result( + "pi_p4_touch_new", + esp_idf_svc::sys::pi_p4_touch_new(&mut touch), + )?; + + Ok(DisplayProbe { + panel, + _io: io, + touch, + framebuffers: framebuffers.map(|framebuffer| framebuffer.cast()), + render_states, + next_framebuffer: 1, + }) + } +} + +impl DisplayProbe { + fn render_agentos( + &mut self, + renderer: &mut Renderer, + ppa: &mut EspIdfPpaOps, + supervisor: &AppSupervisor, + ) -> anyhow::Result<()> { + let framebuffer = self.framebuffers[self.next_framebuffer]; + let pixels = unsafe { + core::slice::from_raw_parts_mut( + framebuffer, + PANEL_WIDTH as usize * PANEL_HEIGHT as usize, + ) + }; + supervisor.with_ui(|ui| { + let words = ui.draw().words.clone(); + renderer + .render_incremental( + &mut self.render_states[self.next_framebuffer], + ui, + &words, + pixels, + PANEL_WIDTH, + PANEL_HEIGHT, + ppa, + ) + .ok_or_else(|| anyhow::anyhow!("PocketJS rejected the App framebuffer geometry")) + })?; + esp_result("esp_lcd_panel_draw_bitmap", unsafe { + esp_idf_svc::sys::esp_lcd_panel_draw_bitmap( + self.panel, + 0, + 0, + PANEL_WIDTH as i32, + PANEL_HEIGHT as i32, + framebuffer.cast(), + ) + })?; + self.next_framebuffer = (self.next_framebuffer + 1) % self.framebuffers.len(); + Ok(()) + } +} diff --git a/firmware/esp32-p4/src/app_services.rs b/firmware/esp32-p4/src/app_services.rs new file mode 100644 index 0000000..02adee2 --- /dev/null +++ b/firmware/esp32-p4/src/app_services.rs @@ -0,0 +1,708 @@ +use core::time::Duration; +use std::collections::BTreeMap; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{Arc, Mutex}; +use std::time::Instant; + +use embedded_svc::http::{client::Client as HttpClient, Method}; +use embedded_svc::io::Write as _; +use esp_idf_svc::http::client::{Configuration, EspHttpConnection}; +use esp_idf_svc::io::EspIOError; +use pocket_pi_agentos::AppServiceHost; +use serde_json::{json, Value}; + +const EXA_ORIGIN: &str = "https://api.exa.ai"; +const ROBINHOOD_MCP_URL: &str = "https://agent.robinhood.com/mcp/trading"; +const MCP_PROTOCOL_VERSION: &str = "2025-06-18"; +const MAX_EXA_RESPONSE: usize = 96 * 1024; +const MAX_MCP_RESPONSE: usize = 160 * 1024; + +pub struct EspAppServices { + inner: Arc, +} + +struct EspAppServicesInner { + network_ready: Arc, + exa_api_key: Option, + robinhood_access_token: Option, + robinhood: Mutex, +} + +#[derive(Default)] +struct McpState { + session_id: Option, + next_id: u64, +} + +impl EspAppServices { + pub fn new( + network_ready: Arc, + exa_api_key: Option, + robinhood_access_token: Option, + ) -> Self { + let inner = Arc::new(EspAppServicesInner { + network_ready, + exa_api_key, + robinhood_access_token, + robinhood: Mutex::new(McpState { + session_id: None, + next_id: 1, + }), + }); + Self { inner } + } +} + +impl EspAppServicesInner { + fn robinhood_operation_allowed(operation: &str) -> bool { + matches!( + operation, + "get_accounts" + | "get_portfolio" + | "get_equity_positions" + | "get_equity_orders" + | "get_equity_historicals" + | "get_realized_pnl" + | "get_pnl_trade_history" + | "review_equity_order" + ) + } + + + fn exa_post(&self, args: &Value) -> Result { + let api_key = self + .exa_api_key + .as_deref() + .ok_or_else(|| "Exa API key was not provisioned for this boot".to_owned())?; + if args.get("connection").and_then(Value::as_str) != Some("exa") { + return Err("Exa App requested an unknown net connection".to_owned()); + } + let path = args + .get("path") + .and_then(Value::as_str) + .filter(|path| matches!(*path, "/search" | "/contents")) + .ok_or_else(|| "Exa connection only permits /search and /contents".to_owned())?; + let body = args + .get("body") + .filter(|body| body.is_object()) + .ok_or_else(|| "net.http post requires an object body".to_owned())?; + post_json( + &format!("{EXA_ORIGIN}{path}"), + &[("x-api-key", api_key)], + body, + MAX_EXA_RESPONSE, + ) + } + + fn robinhood_call(&self, args: &Value) -> Result { + if args.get("connection").and_then(Value::as_str) != Some("robinhood") { + return Err("Robinhood App requested an unknown MCP connection".to_owned()); + } + let operation = args + .get("name") + .and_then(Value::as_str) + .ok_or_else(|| "mcp.client callTool requires name".to_owned())?; + let arguments = args.get("arguments").unwrap_or(&Value::Null); + if !Self::robinhood_operation_allowed(operation) { + return Err(format!( + "Robinhood operation is not allowlisted: {operation}" + )); + } + let token = self + .robinhood_access_token + .as_deref() + .ok_or_else(|| "Robinhood OAuth token was not provisioned for this boot".to_owned())?; + let mut state = self + .robinhood + .lock() + .map_err(|_| "Robinhood MCP state lock was poisoned".to_owned())?; + for attempt in 0..2 { + let result = self.robinhood_once(token, &mut state, operation, arguments); + match result { + Ok(value) => return Ok(value), + Err(error) if attempt == 0 && stale_mcp_session(&error) => { + log::warn!("Robinhood MCP reconnecting after: {error}"); + state.session_id = None; + std::thread::sleep(Duration::from_millis(250)); + } + Err(error) if attempt == 0 && transient_mcp_connect(&error) => { + log::warn!("Robinhood MCP transport retry after: {error}"); + std::thread::sleep(Duration::from_millis(250)); + } + Err(error) => return Err(error), + } + } + unreachable!() + } + + fn robinhood_calls(&self, args: &Value) -> Result { + if args.get("connection").and_then(Value::as_str) != Some("robinhood") { + return Err("Robinhood App requested an unknown MCP connection".to_owned()); + } + let calls = args + .get("calls") + .and_then(Value::as_array) + .filter(|calls| !calls.is_empty() && calls.len() <= 16) + .ok_or_else(|| "mcp.client callTools requires 1 to 16 calls".to_owned())?; + for call in calls { + let name = call + .get("name") + .and_then(Value::as_str) + .ok_or_else(|| "mcp.client callTools requires a name for every call".to_owned())?; + if !Self::robinhood_operation_allowed(name) { + return Err(format!("Robinhood operation is not allowlisted: {name}")); + } + } + let token = self + .robinhood_access_token + .as_deref() + .ok_or_else(|| "Robinhood OAuth token was not provisioned for this boot".to_owned())?; + let mut state = self + .robinhood + .lock() + .map_err(|_| "Robinhood MCP state lock was poisoned".to_owned())?; + for attempt in 0..2 { + let result = self.robinhood_batch_once(token, &mut state, calls); + match result { + Ok(value) => return Ok(value), + Err(error) if attempt == 0 && stale_mcp_session(&error) => { + log::warn!("Robinhood MCP batch reconnecting after: {error}"); + state.session_id = None; + std::thread::sleep(Duration::from_millis(250)); + } + Err(error) if attempt == 0 && transient_mcp_connect(&error) => { + log::warn!("Robinhood MCP batch transport retry after: {error}"); + std::thread::sleep(Duration::from_millis(250)); + } + Err(error) => return Err(error), + } + } + unreachable!() + } + + fn robinhood_batch_once( + &self, + token: &str, + state: &mut McpState, + calls: &[Value], + ) -> Result { + self.ensure_robinhood_session(token, state)?; + let mut requests = Vec::with_capacity(calls.len()); + let mut request_ids = Vec::with_capacity(calls.len()); + for call in calls { + let id = state.next_id; + state.next_id = state.next_id.saturating_add(1); + request_ids.push(id); + requests.push(json!({ + "jsonrpc":"2.0", + "id":id, + "method":"tools/call", + "params":{ + "name":call.get("name").and_then(Value::as_str).unwrap_or_default(), + "arguments":call.get("arguments").unwrap_or(&Value::Null) + } + })); + } + let started = Instant::now(); + let (responses, returned_session) = post_mcp_batch( + token, + state.session_id.as_deref(), + &requests, + request_ids.len(), + )?; + if returned_session.is_some() { + state.session_id = returned_session; + } + let mut by_id = BTreeMap::new(); + for response in responses { + if let Some(id) = response.get("id").and_then(Value::as_u64) { + by_id.insert(id, response); + } + } + let mut results = Vec::with_capacity(calls.len()); + for (index, call) in calls.iter().enumerate() { + let name = call.get("name").and_then(Value::as_str).unwrap_or_default(); + let response = by_id + .remove(&request_ids[index]) + .ok_or_else(|| format!("Robinhood MCP batch omitted response for {name}"))?; + match normalize_mcp_result(&response) { + Ok(value) => results.push(json!({"name":name,"ok":true,"value":value})), + Err(error) => results.push(json!({"name":name,"ok":false,"error":error})), + } + } + log::info!( + "Robinhood MCP batch calls={} completed in {}ms", + calls.len(), + started.elapsed().as_millis() + ); + Ok(json!({"results":results})) + } + + fn ensure_robinhood_session( + &self, + token: &str, + state: &mut McpState, + ) -> Result<(), String> { + if state.session_id.is_some() { + return Ok(()); + } + let request = json!({ + "jsonrpc":"2.0", + "id":state.next_id, + "method":"initialize", + "params":{"protocolVersion":MCP_PROTOCOL_VERSION,"capabilities":{},"clientInfo":{"name":"pocket-pi-agentos","version":"0.1.0"}} + }); + state.next_id = state.next_id.saturating_add(1); + let (body, session) = post_mcp(token, None, &request)?; + if let Some(error) = body.get("error") { + return Err(format!("Robinhood MCP initialize failed: {error}")); + } + let session = session.ok_or_else(|| "Robinhood MCP omitted session id".to_owned())?; + let notification = json!({"jsonrpc":"2.0","method":"notifications/initialized"}); + let _ = post_mcp(token, Some(&session), ¬ification)?; + state.session_id = Some(session); + log::info!("Robinhood MCP session initialized"); + Ok(()) + } + + fn robinhood_once( + &self, + token: &str, + state: &mut McpState, + operation: &str, + args: &Value, + ) -> Result { + let operation_started = Instant::now(); + log::info!("Robinhood MCP {operation} started"); + self.ensure_robinhood_session(token, state)?; + let request = json!({ + "jsonrpc":"2.0", + "id":state.next_id, + "method":"tools/call", + "params":{"name":operation,"arguments":args} + }); + state.next_id = state.next_id.saturating_add(1); + let (body, returned_session) = post_mcp(token, state.session_id.as_deref(), &request)?; + if returned_session.is_some() { + state.session_id = returned_session; + } + let value = normalize_mcp_result(&body)?; + log::info!( + "Robinhood MCP {operation} completed in {}ms", + operation_started.elapsed().as_millis() + ); + Ok(value) + } +} + +impl AppServiceHost for EspAppServices { + fn call( + &self, + app_id: &str, + service: &str, + operation: &str, + args: &Value, + ) -> Result { + if !self.inner.network_ready.load(Ordering::Acquire) { + return Err("Network is not connected; App data was not changed".to_owned()); + } + match (app_id, service, operation) { + ("exa", "net.http", "post") => self.inner.exa_post(args), + ("robinhood", "mcp.client", "callTool") => self.inner.robinhood_call(args), + ("robinhood", "mcp.client", "callTools") => self.inner.robinhood_calls(args), + _ => Err(format!("App {app_id} cannot access service {service}")), + } + } +} + +fn client() -> Result, String> { + EspHttpConnection::new(&Configuration { + buffer_size: Some(8 * 1024), + buffer_size_tx: Some(4 * 1024), + // A service call is still synchronous in v1, so a dead network must + // fail quickly enough for the App to leave its visible loading state. + timeout: Some(Duration::from_secs(12)), + crt_bundle_attach: Some(esp_idf_svc::sys::esp_crt_bundle_attach), + ..Default::default() + }) + .map(HttpClient::wrap) + .map_err(|error| format!("initialize HTTPS client: {error}")) +} + +fn stale_mcp_session(error: &str) -> bool { + let lower = error.to_ascii_lowercase(); + (lower.contains("mcp http 400") || lower.contains("mcp http 404")) && lower.contains("session") +} + +fn transient_mcp_connect(error: &str) -> bool { + error.contains("ESP_ERR_HTTP_CONNECT") +} + +fn post_json( + url: &str, + extra_headers: &[(&str, &str)], + body: &Value, + limit: usize, +) -> Result { + let payload = body.to_string(); + let length = payload.len().to_string(); + let mut headers = vec![ + ("accept", "application/json"), + ("content-type", "application/json"), + ("content-length", length.as_str()), + ("connection", "close"), + ("user-agent", "pocket-pi-agentos/0.1"), + ]; + headers.extend_from_slice(extra_headers); + let mut client = client()?; + let mut request = client + .request(Method::Post, url, &headers) + .map_err(|error| format!("create HTTPS request: {error}"))?; + request + .write_all(payload.as_bytes()) + .map_err(|error| format!("write HTTPS request: {error}"))?; + request + .flush() + .map_err(|error| format!("flush HTTPS request: {error}"))?; + let mut response = request + .submit() + .map_err(|error| format!("send HTTPS request: {error}"))?; + let status = response.status(); + let expected_length = response + .header("content-length") + .and_then(|value| value.parse::().ok()); + let bytes = read_bounded(&mut response, limit, expected_length)?; + if !(200..300).contains(&status) { + return Err(format!( + "HTTPS {status}: {}", + String::from_utf8_lossy(&bytes) + )); + } + serde_json::from_slice(&bytes).map_err(|error| format!("parse HTTPS JSON: {error}")) +} + +fn post_mcp( + token: &str, + session: Option<&str>, + body: &Value, +) -> Result<(Value, Option), String> { + let request_label = body + .get("params") + .and_then(|params| params.get("name")) + .and_then(Value::as_str) + .or_else(|| body.get("method").and_then(Value::as_str)) + .unwrap_or("unknown"); + let payload = body.to_string(); + let length = payload.len().to_string(); + let authorization = format!("Bearer {token}"); + let mut headers = vec![ + ("accept", "application/json, text/event-stream"), + ("content-type", "application/json"), + ("content-length", length.as_str()), + ("authorization", authorization.as_str()), + ("user-agent", "pocket-pi-agentos/0.1"), + ]; + if let Some(session) = session { + headers.push(("mcp-session-id", session)); + } + let mut client = client()?; + let mut request = client + .request(Method::Post, ROBINHOOD_MCP_URL, &headers) + .map_err(|error| format!("create Robinhood MCP request: {error}"))?; + request + .write_all(payload.as_bytes()) + .map_err(|error| format!("write Robinhood MCP request: {error}"))?; + request + .flush() + .map_err(|error| format!("flush Robinhood MCP request: {error}"))?; + let submit_started = Instant::now(); + let mut response = request + .submit() + .map_err(|error| format!("send Robinhood MCP request: {error}"))?; + let status = response.status(); + log::info!( + "Robinhood MCP HTTP {request_label} headers status={status} in {}ms", + submit_started.elapsed().as_millis() + ); + let returned_session = response.header("Mcp-Session-Id").map(str::to_owned); + let is_event_stream = response + .header("content-type") + .is_some_and(|value| value.to_ascii_lowercase().contains("text/event-stream")); + // JSON-RPC notifications have no response payload. The MCP endpoint keeps + // its HTTP connection alive, so waiting for EOF here would block forever. + if body.get("id").is_none() && (200..300).contains(&status) { + return Ok((Value::Null, returned_session)); + } + let body_started = Instant::now(); + let bytes = if is_event_stream { + read_sse_event(&mut response, MAX_MCP_RESPONSE)? + } else { + let expected_length = response + .header("content-length") + .and_then(|value| value.parse::().ok()); + read_bounded(&mut response, MAX_MCP_RESPONSE, expected_length)? + }; + log::info!( + "Robinhood MCP HTTP {request_label} body bytes={} in {}ms", + bytes.len(), + body_started.elapsed().as_millis() + ); + if !(200..300).contains(&status) { + return Err(format!( + "Robinhood MCP HTTP {status}: {}", + String::from_utf8_lossy(&bytes) + )); + } + let body = parse_json_or_sse(&bytes)?; + Ok((body, returned_session)) +} + +fn post_mcp_batch( + token: &str, + session: Option<&str>, + bodies: &[Value], + expected_responses: usize, +) -> Result<(Vec, Option), String> { + let payload = serde_json::to_string(bodies) + .map_err(|error| format!("encode Robinhood MCP batch: {error}"))?; + let length = payload.len().to_string(); + let authorization = format!("Bearer {token}"); + let mut headers = vec![ + ("accept", "application/json, text/event-stream"), + ("content-type", "application/json"), + ("content-length", length.as_str()), + ("authorization", authorization.as_str()), + ("user-agent", "pocket-pi-agentos/0.1"), + ]; + if let Some(session) = session { + headers.push(("mcp-session-id", session)); + } + let mut client = client()?; + let mut request = client + .request(Method::Post, ROBINHOOD_MCP_URL, &headers) + .map_err(|error| format!("create Robinhood MCP batch request: {error}"))?; + request + .write_all(payload.as_bytes()) + .map_err(|error| format!("write Robinhood MCP batch request: {error}"))?; + request + .flush() + .map_err(|error| format!("flush Robinhood MCP batch request: {error}"))?; + let submit_started = Instant::now(); + let mut response = request + .submit() + .map_err(|error| format!("send Robinhood MCP batch request: {error}"))?; + let status = response.status(); + log::info!( + "Robinhood MCP HTTP batch headers status={status} in {}ms", + submit_started.elapsed().as_millis() + ); + let returned_session = response.header("Mcp-Session-Id").map(str::to_owned); + if !(200..300).contains(&status) { + let bytes = read_bounded(&mut response, MAX_MCP_RESPONSE, None)?; + return Err(format!( + "Robinhood MCP batch HTTP {status}: {}", + String::from_utf8_lossy(&bytes) + )); + } + let body_started = Instant::now(); + let responses = read_sse_values(&mut response, MAX_MCP_RESPONSE, expected_responses)?; + log::info!( + "Robinhood MCP HTTP batch responses={} in {}ms", + responses.len(), + body_started.elapsed().as_millis() + ); + Ok((responses, returned_session)) +} + +fn read_bounded( + reader: &mut impl embedded_svc::io::Read, + limit: usize, + expected_length: Option, +) -> Result, String> { + if expected_length.is_some_and(|length| length > limit) { + return Err(format!("HTTPS response exceeded {limit} bytes")); + } + let mut out = Vec::with_capacity(8 * 1024); + let mut chunk = [0u8; 2048]; + loop { + let count = reader + .read(&mut chunk) + .map_err(|error| format!("read HTTPS response: {error:?}"))?; + if count == 0 { + if let Some(expected) = expected_length { + if out.len() < expected { + return Err(format!( + "HTTPS response ended after {} of {expected} bytes", + out.len() + )); + } + } + break; + } + if out.len().saturating_add(count) > limit { + return Err(format!("HTTPS response exceeded {limit} bytes")); + } + out.extend_from_slice(&chunk[..count]); + if expected_length.is_some_and(|expected| out.len() >= expected) { + break; + } + } + Ok(out) +} + +fn read_sse_event( + reader: &mut impl embedded_svc::io::Read, + limit: usize, +) -> Result, String> { + let mut out = Vec::with_capacity(8 * 1024); + // Stop after the first complete SSE event because the server keeps this + // connection alive. Reading one byte at a time made a normal MCP payload + // expensive enough to trip the ESP32 task watchdog, so consume the bytes + // already available from esp_http_client in bounded chunks instead. + let mut chunk = [0u8; 512]; + loop { + let count = reader + .read(&mut chunk) + .map_err(|error| format!("read MCP SSE response: {error:?}"))?; + if count == 0 { + break; + } + if out.len().saturating_add(count) > limit { + return Err(format!("MCP SSE response exceeded {limit} bytes")); + } + out.extend_from_slice(&chunk[..count]); + if let Some(end) = sse_event_end(&out) { + out.truncate(end); + return Ok(out); + } + } + Ok(out) +} + +fn read_sse_values( + reader: &mut R, + limit: usize, + expected: usize, +) -> Result, String> +where + R: embedded_svc::io::Read, +{ + let mut buffered = Vec::with_capacity(16 * 1024); + let mut consumed = 0; + let mut values = Vec::with_capacity(expected); + let mut chunk = [0u8; 2048]; + let deadline = Instant::now() + Duration::from_secs(120); + while values.len() < expected { + let count = match reader.read(&mut chunk) { + Ok(count) => count, + Err(error) + if error.0.code() == -esp_idf_svc::sys::ESP_ERR_HTTP_EAGAIN + && Instant::now() < deadline => + { + log::info!( + "Robinhood MCP batch waiting for SSE responses ({}/{expected})", + values.len() + ); + continue; + } + Err(error) if error.0.code() == -esp_idf_svc::sys::ESP_ERR_HTTP_EAGAIN => { + return Err(format!( + "Robinhood MCP batch timed out after receiving {} of {expected} responses", + values.len() + )); + } + Err(error) => return Err(format!("read MCP batch SSE response: {error:?}")), + }; + if count == 0 { + break; + } + if buffered.len().saturating_add(count) > limit { + return Err(format!("MCP batch SSE response exceeded {limit} bytes")); + } + buffered.extend_from_slice(&chunk[..count]); + while let Some(relative_end) = buffered[consumed..].iter().position(|byte| *byte == b'\n') { + let end = consumed + relative_end; + let line = &buffered[consumed..end]; + let line = line.strip_suffix(b"\r").unwrap_or(line); + if let Some(data) = line.strip_prefix(b"data:") { + let data = data.strip_prefix(b" ").unwrap_or(data); + values.push( + serde_json::from_slice(data) + .map_err(|error| format!("parse MCP batch SSE JSON: {error}"))?, + ); + } + consumed = end + 1; + } + } + if values.len() != expected { + return Err(format!( + "Robinhood MCP batch returned {} of {expected} responses", + values.len() + )); + } + Ok(values) +} + +fn sse_event_end(bytes: &[u8]) -> Option { + // Robinhood sends one complete JSON value on a `data:` line but may keep + // the chunked stream open without promptly sending the optional blank + // event separator. A terminated data line is already a complete response. + for start in 0..bytes.len() { + if (start == 0 || bytes[start - 1] == b'\n') && bytes[start..].starts_with(b"data:") { + if let Some(relative_end) = bytes[start..].iter().position(|byte| *byte == b'\n') { + return Some(start + relative_end + 1); + } + } + } + bytes + .windows(4) + .position(|window| window == b"\r\n\r\n") + .map(|index| index + 4) + .or_else(|| { + bytes + .windows(2) + .position(|window| window == b"\n\n") + .map(|index| index + 2) + }) +} + +fn parse_json_or_sse(bytes: &[u8]) -> Result { + // JSON-RPC notifications (notably MCP notifications/initialized) have no + // response body on success. Treat that as a valid null result; tools/call + // still goes through normalize_mcp_result and therefore requires result. + if bytes.iter().all(u8::is_ascii_whitespace) { + return Ok(Value::Null); + } + if let Ok(value) = serde_json::from_slice(bytes) { + return Ok(value); + } + for line in String::from_utf8_lossy(bytes).lines().rev() { + if let Some(data) = line.strip_prefix("data: ") { + return serde_json::from_str(data) + .map_err(|error| format!("parse MCP SSE JSON: {error}")); + } + } + Err("MCP response was neither JSON nor SSE".to_owned()) +} + +fn normalize_mcp_result(body: &Value) -> Result { + if let Some(error) = body.get("error") { + return Err(format!("Robinhood MCP error: {error}")); + } + let result = body + .get("result") + .ok_or_else(|| "Robinhood MCP response omitted result".to_owned())?; + let text = result + .get("content") + .and_then(Value::as_array) + .into_iter() + .flatten() + .find(|item| item.get("type").and_then(Value::as_str) == Some("text")) + .and_then(|item| item.get("text")) + .and_then(Value::as_str) + .ok_or_else(|| "Robinhood MCP tool returned no text".to_owned())?; + if result.get("isError").and_then(Value::as_bool) == Some(true) { + return Err(text.to_owned()); + } + Ok(serde_json::from_str(text).unwrap_or_else(|_| Value::String(text.to_owned()))) +} diff --git a/firmware/esp32-p4/src/backend/uart.rs b/firmware/esp32-p4/src/backend/uart.rs index 00ddeac..09a1469 100644 --- a/firmware/esp32-p4/src/backend/uart.rs +++ b/firmware/esp32-p4/src/backend/uart.rs @@ -23,7 +23,7 @@ impl ModelBackend for UartBackend { fn complete( &self, request_json: &str, - on_delta: &mut dyn FnMut(&str), + _on_delta: &mut dyn FnMut(&str), ) -> Result { self.transport.write_line("PPI-RPC-WAITING"); self.transport @@ -42,12 +42,9 @@ impl ModelBackend for UartBackend { ) .map_err(|error| format!("UART stream JSON: {error}"))?; match event.get("type").and_then(serde_json::Value::as_str) { - Some("text_delta") => on_delta( - event - .get("text") - .and_then(serde_json::Value::as_str) - .ok_or_else(|| "UART text delta is missing text".to_owned())?, - ), + // Backward-compatible with an older bridge, but do not forward + // fine-grained text updates into the embedded Agent runtime. + Some("text_delta") => {} Some("done") => { return serde_json::to_string( event diff --git a/firmware/esp32-p4/src/backend/wireless.rs b/firmware/esp32-p4/src/backend/wireless.rs index 2302515..19748ee 100644 --- a/firmware/esp32-p4/src/backend/wireless.rs +++ b/firmware/esp32-p4/src/backend/wireless.rs @@ -46,7 +46,7 @@ impl ModelBackend for WirelessBackend { fn complete( &self, request_json: &str, - on_delta: &mut dyn FnMut(&str), + _on_delta: &mut dyn FnMut(&str), ) -> Result { let (endpoint, body) = self.request(request_json)?; if body.len() > MAX_REQUEST_BYTES { @@ -116,7 +116,7 @@ impl ModelBackend for WirelessBackend { } pending.extend_from_slice(&chunk[..count]); if (200..300).contains(&status) { - drain_sse_lines(&mut pending, &mut decoder, on_delta)?; + drain_sse_lines(&mut pending, &mut decoder)?; } } if !(200..300).contains(&status) { @@ -131,7 +131,7 @@ impl ModelBackend for WirelessBackend { } if !pending.is_empty() { pending.push(b'\n'); - drain_sse_lines(&mut pending, &mut decoder, on_delta)?; + drain_sse_lines(&mut pending, &mut decoder)?; } decoder.finish() } @@ -140,7 +140,6 @@ impl ModelBackend for WirelessBackend { fn drain_sse_lines( pending: &mut Vec, decoder: &mut ProviderStream, - on_delta: &mut dyn FnMut(&str), ) -> Result<(), String> { while let Some(end) = pending.iter().position(|byte| *byte == b'\n') { let mut line = pending.drain(..=end).collect::>(); @@ -154,9 +153,7 @@ fn drain_sse_lines( }; let data = data.trim_start(); if !data.is_empty() && data != "[DONE]" { - if let Some(delta) = decoder.push(data)? { - on_delta(&delta); - } + let _ = decoder.push(data)?; } } Ok(()) diff --git a/firmware/esp32-p4/src/bin/sqlite_probe.rs b/firmware/esp32-p4/src/bin/sqlite_probe.rs new file mode 100644 index 0000000..0559e35 --- /dev/null +++ b/firmware/esp32-p4/src/bin/sqlite_probe.rs @@ -0,0 +1,253 @@ +//! Temporary on-device probe: proves SQLite (rusqlite `bundled`) runs on the +//! ESP32-P4 against the LittleFS `workspace` partition. Flash it, watch UART +//! for `SQLITE-PROBE:` lines, then reflash the real firmware. Not a product +//! binary — delete after the spike. +//! +//! What it exercises, in order: +//! 1. mount /workspace (same LittleFS partition the product uses); +//! 2. open a database with the `unix-none` VFS (no fcntl locking — the one +//! POSIX corner ESP-IDF's newlib does not promise) + device pragmas +//! (journal_mode=TRUNCATE, synchronous=NORMAL); +//! 3. schema DDL, one day of 5-minute samples (288 rows) inside a single +//! transaction — the Robinhood history write shape; +//! 4. aggregate + chart-window reads; +//! 5. close, reopen, recount — persistence across connections; boot counter +//! persists across power cycles. + +use std::time::Instant; + +use esp_idf_svc::fs::littlefs::Littlefs; +use esp_idf_svc::io::vfs::MountedLittlefs; +use rusqlite::{Connection, OpenFlags}; + +const WORKSPACE_ROOT: &str = "/workspace"; +const DB_PATH: &str = "/workspace/sqlite-probe.db"; + +fn main() { + esp_idf_svc::sys::link_patches(); + esp_idf_svc::log::EspLogger::initialize_default(); + if let Err(error) = run() { + log::error!("SQLITE-PROBE: FAIL: {error:#}"); + } + loop { + std::thread::sleep(std::time::Duration::from_secs(10)); + log::info!("SQLITE-PROBE: idle"); + } +} + +fn run() -> anyhow::Result<()> { + log::info!( + "SQLITE-PROBE: boot; sqlite version {}", + rusqlite::version() + ); + let _mount = mount_workspace()?; + let heap_before = unsafe { esp_idf_svc::sys::esp_get_free_heap_size() }; + + let opened_at = Instant::now(); + let conn = Connection::open_with_flags_and_vfs( + DB_PATH, + OpenFlags::SQLITE_OPEN_READ_WRITE + | OpenFlags::SQLITE_OPEN_CREATE + | OpenFlags::SQLITE_OPEN_NO_MUTEX, + "unix-none", + )?; + log::info!("SQLITE-PROBE: open {:?}", opened_at.elapsed()); + + let journal: String = + conn.query_row("PRAGMA journal_mode=TRUNCATE", [], |row| row.get(0))?; + conn.execute_batch("PRAGMA synchronous=NORMAL; PRAGMA cache_size=-32;")?; + log::info!("SQLITE-PROBE: journal_mode={journal}"); + + conn.execute_batch( + "CREATE TABLE IF NOT EXISTS boots ( + boot_index INTEGER PRIMARY KEY, + heap_free INTEGER NOT NULL + ); + CREATE TABLE IF NOT EXISTS samples ( + captured_at INTEGER PRIMARY KEY, + total_cents INTEGER NOT NULL, + day_pnl_cents INTEGER NOT NULL + );", + )?; + + let boot_index: i64 = + conn.query_row("SELECT COUNT(*) FROM boots", [], |row| row.get(0))?; + let prior_rows: i64 = + conn.query_row("SELECT COUNT(*) FROM samples", [], |row| row.get(0))?; + conn.execute( + "INSERT INTO boots (boot_index, heap_free) VALUES (?1, ?2)", + (boot_index, heap_before as i64), + )?; + log::info!("SQLITE-PROBE: boot #{boot_index}, prior samples {prior_rows}"); + + // One day of 5-minute portfolio snapshots, one transaction — the write + // shape the Robinhood history job will produce. + let wrote_at = Instant::now(); + let base = prior_rows * 300; + let tx = conn.unchecked_transaction()?; + { + let mut insert = tx.prepare( + "INSERT INTO samples (captured_at, total_cents, day_pnl_cents) + VALUES (?1, ?2, ?3)", + )?; + for i in 0..288i64 { + let captured_at = base + i * 300; + let total_cents = 1_500_000 + (i % 97) * 137; + let day_pnl_cents = (i % 41) - 20; + insert.execute((captured_at, total_cents, day_pnl_cents))?; + } + } + tx.commit()?; + log::info!("SQLITE-PROBE: insert 288 rows {:?}", wrote_at.elapsed()); + + let read_at = Instant::now(); + let (count, avg_total, max_pnl): (i64, f64, i64) = conn.query_row( + "SELECT COUNT(*), AVG(total_cents), MAX(day_pnl_cents) FROM samples", + [], + |row| Ok((row.get(0)?, row.get(1)?, row.get(2)?)), + )?; + let mut chart = conn.prepare( + "SELECT captured_at, total_cents FROM samples + ORDER BY captured_at DESC LIMIT 24", + )?; + let window: Vec<(i64, i64)> = chart + .query_map([], |row| Ok((row.get(0)?, row.get(1)?)))? + .collect::>()?; + log::info!( + "SQLITE-PROBE: aggregate count={count} avg={avg_total:.1} max_pnl={max_pnl}, \ + chart window {} rows, reads {:?}", + window.len(), + read_at.elapsed() + ); + drop(chart); + + // Close and reopen: the rows must come back from flash, not from cache. + drop(conn); + let reopened_at = Instant::now(); + let conn = Connection::open_with_flags_and_vfs( + DB_PATH, + OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_NO_MUTEX, + "unix-none", + )?; + let recount: i64 = + conn.query_row("SELECT COUNT(*) FROM samples", [], |row| row.get(0))?; + log::info!( + "SQLITE-PROBE: reopen {:?}, recount {recount}", + reopened_at.elapsed() + ); + anyhow::ensure!( + recount == prior_rows + 288, + "expected {} rows after reopen, found {recount}", + prior_rows + 288 + ); + + let file_bytes = std::fs::metadata(DB_PATH)?.len(); + let heap_after = unsafe { esp_idf_svc::sys::esp_get_free_heap_size() }; + log::info!( + "SQLITE-PROBE: db file {file_bytes} bytes, heap {heap_before} -> {heap_after} \ + (delta {})", + heap_before as i64 - heap_after as i64 + ); + log::info!( + "SQLITE-PROBE: PASS (boot #{boot_index}, samples {recount})" + ); + Ok(()) +} + +// -------------------------------------------------------------------------- +// POSIX shims: SQLite's os_unix syscall table takes the ADDRESS of these six +// functions, so the symbols must exist at link time even though our +// configuration (unix-none VFS, lstat=stat, no symlinks, no dotlock files) +// never calls the first five. LittleFS has no users, permissions or +// symlinks, so no-op successes are the honest implementations. nanosleep IS +// called (busy-handler sleeps); route it through ESP-IDF's usleep. +// -------------------------------------------------------------------------- + +#[repr(C)] +struct Timespec { + tv_sec: i64, // espidf_time64: 64-bit time_t + tv_nsec: i32, +} + +unsafe extern "C" { + fn usleep(microseconds: u32) -> i32; +} + +#[unsafe(no_mangle)] +extern "C" fn geteuid() -> u32 { + 0 +} + +#[unsafe(no_mangle)] +extern "C" fn fchmod(_fd: i32, _mode: u32) -> i32 { + 0 +} + +#[unsafe(no_mangle)] +extern "C" fn fchown(_fd: i32, _owner: u32, _group: u32) -> i32 { + 0 +} + +#[unsafe(no_mangle)] +extern "C" fn utimes(_path: *const core::ffi::c_char, _times: *const core::ffi::c_void) -> i32 { + 0 +} + +#[unsafe(no_mangle)] +extern "C" fn readlink( + _path: *const core::ffi::c_char, + _buf: *mut core::ffi::c_char, + _len: usize, +) -> isize { + -1 // never a symlink on LittleFS +} + +#[unsafe(no_mangle)] +extern "C" fn nanosleep(request: *const Timespec, _remain: *mut Timespec) -> i32 { + let request = unsafe { &*request }; + let micros = (request.tv_sec as u64) + .saturating_mul(1_000_000) + .saturating_add((request.tv_nsec as u64) / 1_000); + unsafe { usleep(micros.min(u32::MAX as u64) as u32) } +} + +// Copied from src/storage.rs — the probe is a standalone bin and the package +// has no lib target; keep byte-identical semantics (format only a blank +// partition, never a corrupted one). +type WorkspaceMount = MountedLittlefs>; + +fn mount_workspace() -> anyhow::Result { + let fs = unsafe { Littlefs::<()>::new_partition("workspace")? }; + match MountedLittlefs::mount(fs, WORKSPACE_ROOT) { + Ok(mounted) => Ok(mounted), + Err(_mount_error) if partition_is_blank()? => { + let mut fs = unsafe { Littlefs::<()>::new_partition("workspace")? }; + fs.format()?; + MountedLittlefs::mount(fs, WORKSPACE_ROOT).map_err(Into::into) + } + Err(mount_error) => Err(anyhow::anyhow!( + "LittleFS workspace mount failed; preserving non-blank partition: {mount_error}" + )), + } +} + +fn partition_is_blank() -> anyhow::Result { + let partition = unsafe { + esp_idf_svc::sys::esp_partition_find_first( + esp_idf_svc::sys::esp_partition_type_t_ESP_PARTITION_TYPE_DATA, + esp_idf_svc::sys::esp_partition_subtype_t_ESP_PARTITION_SUBTYPE_DATA_LITTLEFS, + c"workspace".as_ptr(), + ) + }; + if partition.is_null() { + anyhow::bail!("LittleFS workspace partition is missing"); + } + let mut prefix = [0u8; 4096]; + let status = unsafe { + esp_idf_svc::sys::esp_partition_read(partition, 0, prefix.as_mut_ptr().cast(), prefix.len()) + }; + if status != esp_idf_svc::sys::ESP_OK { + anyhow::bail!("read LittleFS workspace partition: ESP error {status}"); + } + Ok(prefix.iter().all(|byte| *byte == 0xff)) +} diff --git a/firmware/esp32-p4/src/device_state.rs b/firmware/esp32-p4/src/device_state.rs new file mode 100644 index 0000000..85aa570 --- /dev/null +++ b/firmware/esp32-p4/src/device_state.rs @@ -0,0 +1,23 @@ +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct WifiNetworkProjection { + pub ssid: String, + pub rssi_dbm: i16, + pub secured: bool, +} + +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct WifiSettingsProjection { + pub connected_ssid: Option, + pub ip_address: Option, + pub rssi_dbm: Option, + pub scanning: bool, + pub networks: Vec, + pub status: String, +} + +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct SettingsProjection { + pub wifi: WifiSettingsProjection, + pub firmware_version: String, + pub workspace_free_bytes: Option, +} diff --git a/firmware/esp32-p4/src/main.rs b/firmware/esp32-p4/src/main.rs index 6018436..64ab1e1 100644 --- a/firmware/esp32-p4/src/main.rs +++ b/firmware/esp32-p4/src/main.rs @@ -1,383 +1,92 @@ use core::time::Duration; -use std::sync::Arc; use std::time::Instant; -use embedded_svc::http::{client::Client as HttpClient, Method}; use esp_idf_svc::eventloop::EspSystemEventLoop; use esp_idf_svc::hal::peripherals::Peripherals; use esp_idf_svc::handle::RawHandle; -use esp_idf_svc::http::client::{Configuration as HttpConfiguration, EspHttpConnection}; use esp_idf_svc::netif::{EspNetif, NetifStack}; use esp_idf_svc::nvs::{EspDefaultNvs, EspDefaultNvsPartition}; use esp_idf_svc::wifi::{AuthMethod, ClientConfiguration, Configuration, WifiDriver}; -use pocket_pi_device_ui::{ - load_fonts, AgentState, ChatProjection, DeviceState, ScreenInteraction, ScreenState, - SettingsCommand, SettingsProjection, SystemTelemetry, -}; -use pocket_pi_embedded::{spawn_agent_worker, AgentEvent, ModelBackend}; -use pocket_pi_protocols::model::ModelBackendSettings; -use pocket_pi_tools::{CoreToolHost, PlatformTools}; -use pocketjs_core::Ui; -use pocketjs_esp32p4_ppa::{PpaOps, Rect, Renderer, RendererConfig, SrmTransform}; +use pocket_pi_tools::PlatformTools; +use pocketjs_esp32p4_ppa::RenderTargetState; +mod agentos_main; +mod app_services; mod backend; +mod device_state; mod storage; mod transport; +use device_state::{SettingsProjection, WifiNetworkProjection}; + const BOARD_NAME: &str = "Waveshare ESP32-P4-WIFI6-Touch-LCD-5"; const PANEL_WIDTH: u32 = 720; const PANEL_HEIGHT: u32 = 1280; -const LCD_REFRESH_HZ: u16 = 32; const WIFI_NVS_NAMESPACE: &str = "pocket_pi"; const WIFI_NVS_SSID_KEY: &str = "wifi_ssid"; const WIFI_NVS_PASSWORD_KEY: &str = "wifi_pass"; +const AGENTOS_LAUNCHER_STACK_BYTES: u32 = 4 * 1024; +const AGENTOS_TASK_STACK_BYTES: u32 = 64 * 1024; fn main() -> anyhow::Result<()> { esp_idf_svc::sys::link_patches(); esp_idf_svc::log::EspLogger::initialize_default(); - let mut ui = Ui::new(); - ui.set_viewport(PANEL_WIDTH as f32, PANEL_HEIGHT as f32); - if !load_fonts(&mut ui) { - anyhow::bail!("PocketJS rejected the shared Inter font atlases") - } - let _workspace = storage::mount_workspace()?; - - let mut device = DeviceState { - agent: AgentState::Starting, - }; - let mut chat = ChatProjection::new("TYPE A MESSAGE", "BOOTING PI AGENT..."); - let mut screen = ScreenState::new(storage::WORKSPACE_ROOT); - screen.refresh_workspace(); - screen.set_telemetry(system_telemetry(0)); - - let mut renderer = Renderer::new(RendererConfig::default()) - .ok_or_else(|| anyhow::anyhow!("invalid PocketJS renderer configuration"))?; - log::info!("Pocket Pi ESP32-P4 hardware probe: {BOARD_NAME}"); - log::info!( - "PocketJS shared device UI ready: viewport={:?} scale={}", - ui.viewport(), - renderer.config().scale, - ); - - let mut display = match init_display_probe(&mut renderer, &ui, &device, &chat, &screen) { - Ok(display) => { - log::info!("MIPI-DSI panel active"); - Some(display) - } - Err(error) => { - log::error!("MIPI-DSI panel failed: {error:#}"); - None - } + let mut task = core::ptr::null_mut(); + let result = unsafe { + esp_idf_svc::sys::xTaskCreatePinnedToCoreWithCaps( + Some(agentos_launcher_task), + c"agentos-launch".as_ptr(), + AGENTOS_LAUNCHER_STACK_BYTES, + core::ptr::null_mut(), + esp_idf_svc::sys::ESP_TASK_MAIN_PRIO, + &mut task, + 0, + esp_idf_svc::sys::MALLOC_CAP_SPIRAM | esp_idf_svc::sys::MALLOC_CAP_8BIT, + ) }; + if result != 1 || task.is_null() { + anyhow::bail!("could not create AgentOS launcher task (result={result})") + } + log::info!("AgentOS runtime launcher queued"); + Ok(()) +} - let uart = Arc::new( - transport::UartLineTransport::new() - .map_err(|error| anyhow::anyhow!("initialize UART transport: {error}"))?, +unsafe extern "C" fn agentos_launcher_task(_argument: *mut core::ffi::c_void) { + // Let ESP-IDF delete its entry task first. That releases enough contiguous + // internal RAM for the large runtime stack required by QuickJS. The tiny + // launcher itself lives in PSRAM and never performs flash I/O. + esp_idf_svc::sys::vTaskDelay(10); + let mut task = core::ptr::null_mut(); + let result = esp_idf_svc::sys::xTaskCreatePinnedToCoreWithCaps( + Some(agentos_task), + c"agentos".as_ptr(), + AGENTOS_TASK_STACK_BYTES, + core::ptr::null_mut(), + esp_idf_svc::sys::ESP_TASK_MAIN_PRIO, + &mut task, + 0, + esp_idf_svc::sys::MALLOC_CAP_INTERNAL | esp_idf_svc::sys::MALLOC_CAP_8BIT, ); - let runtime_config = - match transport::request_runtime_config(uart.as_ref(), Duration::from_secs(5)) { - Ok(config) => config, - Err(error) => { - log::warn!("No UART runtime config received: {error}"); - transport::RuntimeConfig::default() - } - }; - let clock_seeded_by_uart = if let Some(seconds) = runtime_config.unix_time_seconds { - let time = esp_idf_svc::sys::timeval { - tv_sec: seconds as i64, - tv_usec: 0, - }; - if unsafe { esp_idf_svc::sys::settimeofday(&time, core::ptr::null()) } == 0 { - log::info!("clock seeded by UART bridge"); - true - } else { - log::warn!("UART bridge clock seed failed"); - false - } - } else { - false - }; - screen.set_model_backend(&runtime_config.model); - - let mut wifi = match init_wifi( - runtime_config.wifi_ssid.as_deref(), - runtime_config.wifi_password.as_deref(), - ) { - Ok(wifi) => { - log::info!("C6-SDIO Wi-Fi and lwIP netif active"); - Some(wifi) - } - Err(error) => { - log::error!("C6-SDIO Wi-Fi radio probe failed: {error:#}"); - None - } - }; - let mut settings = wifi - .as_ref() - .map(|wifi| wifi.projection("READY")) - .unwrap_or_else(|| SettingsProjection { - firmware_version: env!("CARGO_PKG_VERSION").into(), - workspace_free_bytes: storage::workspace_free_bytes().ok(), - wifi: pocket_pi_device_ui::WifiSettingsProjection { - status: "WI-FI DRIVER UNAVAILABLE".into(), - ..Default::default() - }, - ..Default::default() - }); - screen.set_settings(settings.clone()); - let _sntp = if wifi.is_some() { - match esp_idf_svc::sntp::EspSntp::new_default() { - Ok(sntp) => { - if !clock_seeded_by_uart && wifi.as_ref().is_some_and(WifiConnection::is_connected) - { - let started = Instant::now(); - while started.elapsed() < Duration::from_secs(15) - && sntp.get_sync_status() != esp_idf_svc::sntp::SyncStatus::Completed - { - std::thread::sleep(Duration::from_millis(200)); - } - if sntp.get_sync_status() == esp_idf_svc::sntp::SyncStatus::Completed { - log::info!("SNTP clock synchronized"); - } else { - log::warn!("SNTP synchronization is still pending"); - } - } - Some(sntp) - } - Err(error) => { - log::error!("SNTP initialization failed: {error}"); - None - } - } - } else { - None - }; - let direct_wireless = matches!( - &runtime_config.model.backend, - ModelBackendSettings::Wireless { .. } - ); - if direct_wireless && wifi.as_ref().is_some_and(WifiConnection::is_connected) { + if result == 1 && !task.is_null() { log::info!( - "network targets staged: openai={} codex_plan={}", - pocket_pi_protocols::model::OPENAI_API_BASE_URL, - pocket_pi_protocols::model::CODEX_BACKEND_BASE_URL, + "AgentOS runtime started on a {} KiB internal stack", + AGENTOS_TASK_STACK_BYTES / 1024 ); - match probe_https_origins() { - Ok(reachability) => log::info!("HTTPS connectivity probe completed: {reachability:?}"), - Err(error) => log::error!("HTTPS connectivity probe failed: {error:#}"), - } - } else if !direct_wireless { - log::info!("direct model HTTPS probes skipped for UART backend"); + } else { + log::error!("could not create AgentOS runtime task (result={result})"); } - - let uart_poc = matches!( - runtime_config.model.backend, - ModelBackendSettings::Uart { .. } - ); - let backend: Arc = match runtime_config.model.backend { - ModelBackendSettings::Uart { .. } => { - let transport: Arc = uart; - Arc::new(backend::UartBackend::new(transport)) - } - ModelBackendSettings::Wireless { provider } => Arc::new( - backend::WirelessBackend::new( - provider, - runtime_config - .model_api_key - .ok_or_else(|| anyhow::anyhow!("wireless backend is missing API key"))?, - ) - .map_err(anyhow::Error::msg)?, - ), - }; - let tools = Arc::new(CoreToolHost::new( - storage::WORKSPACE_ROOT, - Arc::new(EspPlatform), - )); - let provider = match runtime_config.model.backend { - ModelBackendSettings::Uart { .. } => "uart", - ModelBackendSettings::Wireless { provider } => provider.id(), - }; - let config = serde_json::json!({ - "provider":provider, - "model":runtime_config.model.resolved_model().unwrap_or_else(|_| "unknown".into()), - "systemPrompt":"You are Pocket Pi on an ESP32-P4. Be concise." - }); - let (prompt_tx, agent_rx) = - spawn_agent_worker(config.to_string(), backend, tools.clone(), Some(64 * 1024)) - .map_err(anyhow::Error::msg)?; - let mut initial_prompt = runtime_config.initial_prompt; - - let mut touch_was_down = false; - let mut redraw = true; - let mut pending_settings = None; - let mut last_telemetry = Instant::now(); - let mut last_heartbeat = Instant::now(); loop { - while let Ok(event) = agent_rx.try_recv() { - match event { - AgentEvent::Ready => { - log::info!("PocketJS Pi Harness ready"); - if uart_poc { - unsafe { - esp_idf_svc::sys::esp_log_level_set( - c"*".as_ptr(), - esp_idf_svc::sys::esp_log_level_t_ESP_LOG_NONE, - ); - } - } - chat.set_latest_assistant("ESP32-P4 PI AGENT READY."); - if let Some(prompt) = initial_prompt.take() { - chat.push_pending(prompt.clone()); - screen.show_latest_chat(); - device.agent = AgentState::Thinking; - if prompt_tx.send(prompt).is_err() { - chat.fail_pending("AGENT WORKER IS NOT AVAILABLE"); - device.agent = AgentState::Faulted; - } - } else { - device.agent = AgentState::Idle; - } - } - AgentEvent::Delta(delta) => { - if chat.append_model_delta(&delta) { - screen.show_latest_chat(); - } - } - AgentEvent::Done => { - chat.finish_pending(); - screen.refresh_workspace(); - device.agent = AgentState::Idle; - } - AgentEvent::Failed(error) => { - log::error!("PocketJS Pi Harness failed: {error}"); - chat.fail_pending(format!("AGENT FAILED: {error}")); - device.agent = AgentState::Faulted; - } - } - redraw = true; - } - - if let Some(display) = display.as_mut() { - if let Some((x, y)) = display.read_touch() { - if !touch_was_down { - match screen.handle_tap(x, y, &chat, &ui) { - ScreenInteraction::None => {} - ScreenInteraction::Redraw => redraw = true, - ScreenInteraction::SubmitPrompt(prompt) => { - chat.push_pending(prompt.clone()); - screen.show_latest_chat(); - device.agent = AgentState::Thinking; - if prompt_tx.send(prompt).is_err() { - chat.fail_pending("AGENT WORKER IS NOT AVAILABLE"); - device.agent = AgentState::Faulted; - } - redraw = true; - } - ScreenInteraction::Settings(command) => { - if command == SettingsCommand::ScanWifi { - settings.wifi.scanning = true; - settings.wifi.status = "SCANNING...".into(); - screen.set_settings(settings.clone()); - } - pending_settings = Some(command); - redraw = true; - } - } - } - touch_was_down = true; - } else { - if touch_was_down && screen.handle_touch_release() { - redraw = true; - } - touch_was_down = false; - } - } + esp_idf_svc::sys::vTaskDelay(1000); + } +} - if last_telemetry.elapsed() >= Duration::from_secs(2) { - let ui_fps_tenths = display - .as_mut() - .map(DisplayProbe::sample_ui_fps_tenths) - .unwrap_or(0); - screen.set_telemetry(system_telemetry(ui_fps_tenths)); - settings.workspace_free_bytes = storage::workspace_free_bytes().ok(); - screen.set_settings(settings.clone()); - let schedule = tools.schedule_projection(); - screen.set_schedule(pocket_pi_device_ui::ScheduleProjection { - name: schedule.name, - prompt: schedule.prompt, - next_in_seconds: schedule.next_in_seconds, - every_minutes: schedule.every_minutes, - }); - if device.agent == AgentState::Idle { - if let Some(wake) = tools.claim_due() { - chat.push_pending(wake.prompt.clone()); - screen.show_latest_chat(); - device.agent = AgentState::Thinking; - if prompt_tx.send(wake.prompt).is_err() { - chat.fail_pending("AGENT WORKER IS NOT AVAILABLE"); - device.agent = AgentState::Faulted; - } - } - } - redraw = true; - last_telemetry = Instant::now(); - } - if redraw { - if let Some(display) = display.as_mut() { - display.render(&mut renderer, &ui, &device, &chat, &screen)?; - } - redraw = false; - } - if let Some(command) = pending_settings.take() { - match command { - SettingsCommand::ScanWifi => match wifi.as_mut() { - Some(wifi) => match wifi.scan() { - Ok(networks) => { - settings = wifi.projection(""); - settings.wifi.networks = networks; - } - Err(error) => { - settings.wifi.scanning = false; - settings.wifi.status = format!("SCAN FAILED: {error}"); - } - }, - None => settings.wifi.status = "WI-FI DRIVER UNAVAILABLE".into(), - }, - SettingsCommand::ConnectWifi { ssid, password } => match wifi.as_mut() { - Some(wifi) => match wifi.connect(&ssid, &password) { - Ok(()) => settings = wifi.projection("CONNECTED"), - Err(error) => settings.wifi.status = format!("CONNECT FAILED: {error}"), - }, - None => settings.wifi.status = "WI-FI DRIVER UNAVAILABLE".into(), - }, - SettingsCommand::ForgetWifi => match wifi.as_mut() { - Some(wifi) => match wifi.forget() { - Ok(()) => settings = wifi.projection("NETWORK FORGOTTEN"), - Err(error) => settings.wifi.status = format!("FORGET FAILED: {error}"), - }, - None => settings.wifi.status = "WI-FI DRIVER UNAVAILABLE".into(), - }, - SettingsCommand::Restart => { - let _ = EspPlatform.reboot(); - settings.wifi.status = "RESTARTING...".into(); - } - } - settings.wifi.scanning = false; - screen.set_settings(settings.clone()); - redraw = true; - } - if last_heartbeat.elapsed() >= Duration::from_secs(5) { - let memory = memory_snapshot(); - log::info!( - "heartbeat heap={} psram_free={} agent={:?}", - memory.free_heap, - memory.psram_free, - device.agent, - ); - last_heartbeat = Instant::now(); - } - std::thread::sleep(Duration::from_millis(16)); +unsafe extern "C" fn agentos_task(_argument: *mut core::ffi::c_void) { + if let Err(error) = agentos_main::run() { + log::error!("AgentOS runtime stopped: {error:#}"); + } + loop { + esp_idf_svc::sys::vTaskDelay(1000); } } @@ -390,12 +99,7 @@ impl PlatformTools for EspPlatform { "board":"esp32-p4", "piHarness":"pi-agent-core", "jsRuntime":"QuickJS via PocketJS host", - "freeHeapBytes":unsafe { esp_idf_svc::sys::esp_get_free_heap_size() }, - "freePsramBytes":unsafe { - esp_idf_svc::sys::heap_caps_get_free_size( - esp_idf_svc::sys::MALLOC_CAP_SPIRAM, - ) - } + "memoryTelemetry":"boot projection only" }) } @@ -432,79 +136,6 @@ impl PlatformTools for EspPlatform { } } -#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] -struct HttpsReachability { - openai_api: bool, - codex_backend: bool, -} - -fn probe_https_origins() -> anyhow::Result { - let probes = [ - ("control", "https://api.github.com/zen", true), - ("openai-api", "https://api.openai.com/v1/models", false), - ( - "codex-backend", - "https://chatgpt.com/backend-api/models", - false, - ), - ]; - - let mut control_ok = false; - let mut target_ok = 0u8; - let mut reachability = HttpsReachability::default(); - for (name, url, control) in probes { - let configuration = HttpConfiguration { - timeout: Some(Duration::from_secs(10)), - crt_bundle_attach: Some(esp_idf_svc::sys::esp_crt_bundle_attach), - ..Default::default() - }; - let mut client = HttpClient::wrap(EspHttpConnection::new(&configuration)?); - let request = match client.request( - Method::Get, - url, - &[ - ("accept", "application/json"), - ("user-agent", "pocket-pi-p4/0.1"), - ], - ) { - Ok(request) => request, - Err(error) => { - log::warn!("HTTPS probe setup failed: origin={name} error={error}"); - continue; - } - }; - match request.submit() { - Ok(response) => { - let status = response.status(); - if !(100..600).contains(&status) { - log::warn!("HTTPS probe invalid status: origin={name} status={status}"); - continue; - } - log::info!("HTTPS probe complete: origin={name} status={status}"); - if control { - control_ok = true; - } else { - target_ok = target_ok.saturating_add(1); - match name { - "openai-api" => reachability.openai_api = true, - "codex-backend" => reachability.codex_backend = true, - _ => {} - } - } - } - Err(error) => { - log::warn!("HTTPS probe unavailable: origin={name} error={error}"); - } - } - } - - if !control_ok { - anyhow::bail!("control HTTPS origin was unreachable") - } - log::info!("target HTTPS reachability: {target_ok}/2"); - Ok(reachability) -} - fn init_wifi( provisioned_ssid: Option<&str>, provisioned_password: Option<&str>, @@ -534,11 +165,12 @@ fn init_wifi( driver, sta_netif, nvs, + pending: None, }; match load_wifi_credentials(wifi.nvs.clone(), provisioned_ssid, provisioned_password) { Ok((ssid, password)) => { - if let Err(error) = wifi.connect(&ssid, &password) { - log::warn!("saved Wi-Fi did not connect: {error:#}"); + if let Err(error) = wifi.begin_connect(&ssid, &password, false) { + log::warn!("saved Wi-Fi connection could not start: {error:#}"); } } Err(error) => log::warn!("Wi-Fi is not configured: {error:#}"), @@ -550,14 +182,18 @@ struct WifiConnection { driver: WifiDriver<'static>, sta_netif: EspNetif, nvs: EspDefaultNvsPartition, + pending: Option, } -impl WifiConnection { - fn is_connected(&self) -> bool { - self.driver.is_connected().unwrap_or(false) && self.sta_netif.is_up().unwrap_or(false) - } +struct PendingWifiConnect { + ssid: String, + password: String, + started_at: Instant, + persist_on_success: bool, +} - fn scan(&mut self) -> anyhow::Result> { +impl WifiConnection { + fn scan(&mut self) -> anyhow::Result> { if !self.driver.is_started()? { self.driver.start()?; } @@ -565,7 +201,7 @@ impl WifiConnection { let mut networks = access_points .into_iter() .filter(|access_point| !access_point.ssid.is_empty()) - .map(|access_point| pocket_pi_device_ui::WifiNetworkProjection { + .map(|access_point| WifiNetworkProjection { ssid: access_point.ssid.as_str().to_owned(), rssi_dbm: access_point.signal_strength as i16, secured: access_point.auth_method != Some(AuthMethod::None), @@ -577,13 +213,22 @@ impl WifiConnection { Ok(networks) } - fn connect(&mut self, ssid: &str, password: &str) -> anyhow::Result<()> { + fn begin_connect( + &mut self, + ssid: &str, + password: &str, + persist_on_success: bool, + ) -> anyhow::Result<()> { validate_wifi_ssid(ssid)?; if !password.is_empty() { validate_wifi_password(password)?; } - if self.driver.is_connected()? { - self.driver.disconnect()?; + if self.driver.is_started()? { + // A timed-out ESP-Hosted association may still be in the remote + // driver's connecting state even though is_connected() is false. + // Clear that state before every explicit attempt or retry. + let _ = self.driver.disconnect(); + std::thread::sleep(Duration::from_millis(50)); } self.driver .set_configuration(&Configuration::Client(ClientConfiguration { @@ -601,21 +246,66 @@ impl WifiConnection { if !self.driver.is_started()? { self.driver.start()?; } + esp_result("disable Wi-Fi modem power save", unsafe { + esp_idf_svc::sys::esp_wifi_set_ps(esp_idf_svc::sys::wifi_ps_type_t_WIFI_PS_NONE) + })?; self.driver.connect()?; - let deadline = Instant::now() + Duration::from_secs(15); - while !self.driver.is_connected()? || !self.sta_netif.is_up()? { - if Instant::now() >= deadline { - anyhow::bail!("Wi-Fi association or DHCP timed out") + self.pending = Some(PendingWifiConnect { + ssid: ssid.to_owned(), + password: password.to_owned(), + started_at: Instant::now(), + persist_on_success, + }); + Ok(()) + } + + fn poll_connect(&mut self) -> Option> { + let pending = self.pending.as_ref()?; + match (self.driver.is_connected(), self.sta_netif.is_up()) { + (Ok(true), Ok(true)) => { + let pending = self.pending.take().expect("pending Wi-Fi connect"); + if pending.persist_on_success { + let result = (|| { + let storage = EspDefaultNvs::new( + self.nvs.clone(), + WIFI_NVS_NAMESPACE, + true, + )?; + storage.set_str(WIFI_NVS_SSID_KEY, &pending.ssid)?; + storage.set_str(WIFI_NVS_PASSWORD_KEY, &pending.password)?; + Ok::<(), anyhow::Error>(()) + })(); + return Some(result); + } + Some(Ok(())) } - std::thread::sleep(Duration::from_millis(50)); + (Err(error), _) => { + self.pending = None; + Some(Err(error.into())) + } + (_, Err(error)) => { + self.pending = None; + Some(Err(error.into())) + } + _ if pending.started_at.elapsed() >= Duration::from_secs(15) => { + let _ = self.driver.disconnect(); + self.pending = None; + Some(Err(anyhow::anyhow!("Wi-Fi association or DHCP timed out"))) + } + _ => None, } - let storage = EspDefaultNvs::new(self.nvs.clone(), WIFI_NVS_NAMESPACE, true)?; - storage.set_str(WIFI_NVS_SSID_KEY, ssid)?; - storage.set_str(WIFI_NVS_PASSWORD_KEY, password)?; - Ok(()) + } + + fn is_connecting(&self) -> bool { + self.pending.is_some() + } + + fn is_connected(&self) -> bool { + self.driver.is_connected().unwrap_or(false) && self.sta_netif.is_up().unwrap_or(false) } fn forget(&mut self) -> anyhow::Result<()> { + self.pending = None; if self.driver.is_connected()? { self.driver.disconnect()?; } @@ -625,8 +315,8 @@ impl WifiConnection { Ok(()) } - fn projection(&self, status: impl Into) -> pocket_pi_device_ui::SettingsProjection { - let mut projection = pocket_pi_device_ui::SettingsProjection { + fn projection(&self, status: impl Into) -> SettingsProjection { + let mut projection = SettingsProjection { firmware_version: env!("CARGO_PKG_VERSION").into(), workspace_free_bytes: storage::workspace_free_bytes().ok(), ..Default::default() @@ -702,200 +392,21 @@ fn validate_wifi_password(password: &str) -> anyhow::Result<()> { Ok(()) } -#[derive(Debug)] struct DisplayProbe { panel: esp_idf_svc::sys::esp_lcd_panel_handle_t, _io: esp_idf_svc::sys::esp_lcd_panel_io_handle_t, touch: esp_idf_svc::sys::esp_lcd_touch_handle_t, framebuffers: [*mut u16; 3], + render_states: [RenderTargetState; 3], next_framebuffer: usize, - presented_frames: u32, - fps_window_started: Instant, -} - -fn init_display_probe( - renderer: &mut Renderer, - ui: &Ui, - device: &DeviceState, - chat: &ChatProjection, - screen: &ScreenState, -) -> anyhow::Result { - unsafe { - let mut panel = core::ptr::null_mut(); - let mut io = core::ptr::null_mut(); - let mut touch = core::ptr::null_mut(); - let mut framebuffer_0 = core::ptr::null_mut(); - let mut framebuffer_1 = core::ptr::null_mut(); - let mut framebuffer_2 = core::ptr::null_mut(); - - esp_result( - "bsp_display_new", - esp_idf_svc::sys::bsp_display_new(core::ptr::null(), &mut panel, &mut io), - )?; - esp_result( - "esp_lcd_dpi_panel_get_frame_buffer", - esp_idf_svc::sys::esp_lcd_dpi_panel_get_frame_buffer( - panel, - 3, - &mut framebuffer_0, - &mut framebuffer_1, - &mut framebuffer_2, - ), - )?; - let framebuffers = [framebuffer_0, framebuffer_1, framebuffer_2]; - if framebuffers.iter().any(|framebuffer| framebuffer.is_null()) { - anyhow::bail!("esp_lcd_dpi_panel_get_frame_buffer returned a null buffer") - } - - let pixels = core::slice::from_raw_parts_mut( - framebuffers[0].cast::(), - PANEL_WIDTH as usize * PANEL_HEIGHT as usize, - ); - let words = screen.draw_list(ui, device, chat); - let mut software = SoftwareOnly; - let stats = renderer - .render(ui, &words, pixels, PANEL_WIDTH, PANEL_HEIGHT, &mut software) - .ok_or_else(|| anyhow::anyhow!("PocketJS rejected the panel framebuffer geometry"))?; - - esp_result( - "esp_lcd_dpi_panel_set_pattern", - esp_idf_svc::sys::esp_lcd_dpi_panel_set_pattern( - panel, - esp_idf_svc::sys::mipi_dsi_pattern_type_t_MIPI_DSI_PATTERN_NONE, - ), - )?; - esp_result( - "esp_lcd_panel_disp_on_off", - esp_idf_svc::sys::esp_lcd_panel_disp_on_off(panel, true), - )?; - esp_result( - "esp_lcd_panel_draw_bitmap", - esp_idf_svc::sys::esp_lcd_panel_draw_bitmap( - panel, - 0, - 0, - PANEL_WIDTH as i32, - PANEL_HEIGHT as i32, - framebuffers[0], - ), - )?; - esp_result( - "bsp_display_backlight_on", - esp_idf_svc::sys::bsp_display_backlight_on(), - )?; - esp_result( - "pi_p4_touch_new", - esp_idf_svc::sys::pi_p4_touch_new(&mut touch), - )?; - - log::info!( - "PocketJS triple-buffer probe: fb0={:p} fb1={:p} fb2={:p} stats={stats:?}", - framebuffers[0], - framebuffers[1], - framebuffers[2] - ); - Ok(DisplayProbe { - panel, - _io: io, - touch, - framebuffers: framebuffers.map(|framebuffer| framebuffer.cast()), - next_framebuffer: 1, - presented_frames: 1, - fps_window_started: Instant::now(), - }) - } } impl DisplayProbe { - fn render( - &mut self, - renderer: &mut Renderer, - ui: &Ui, - device: &DeviceState, - chat: &ChatProjection, - screen: &ScreenState, - ) -> anyhow::Result<()> { - let framebuffer = self.framebuffers[self.next_framebuffer]; - let pixels = unsafe { - core::slice::from_raw_parts_mut( - framebuffer, - PANEL_WIDTH as usize * PANEL_HEIGHT as usize, - ) - }; - let words = screen.draw_list(ui, device, chat); - let mut software = SoftwareOnly; - renderer - .render(ui, &words, pixels, PANEL_WIDTH, PANEL_HEIGHT, &mut software) - .ok_or_else(|| anyhow::anyhow!("PocketJS rejected the status framebuffer geometry"))?; - - esp_result("esp_lcd_panel_draw_bitmap", unsafe { - esp_idf_svc::sys::esp_lcd_panel_draw_bitmap( - self.panel, - 0, - 0, - PANEL_WIDTH as i32, - PANEL_HEIGHT as i32, - framebuffer.cast(), - ) - })?; - self.next_framebuffer = (self.next_framebuffer + 1) % self.framebuffers.len(); - self.presented_frames = self.presented_frames.saturating_add(1); - Ok(()) - } - fn read_touch(&mut self) -> Option<(u16, u16)> { let mut x = 0u16; let mut y = 0u16; unsafe { esp_idf_svc::sys::pi_p4_touch_read(self.touch, &mut x, &mut y).then_some((x, y)) } } - - fn sample_ui_fps_tenths(&mut self) -> u16 { - let elapsed = self.fps_window_started.elapsed().as_secs_f32(); - let fps_tenths = if elapsed > 0.0 { - ((self.presented_frames as f32 / elapsed) * 10.0).round() as u16 - } else { - 0 - }; - self.presented_frames = 0; - self.fps_window_started = Instant::now(); - fps_tenths - } -} - -struct SoftwareOnly; - -impl PpaOps for SoftwareOnly { - fn fill_rgb565(&mut self, _: &mut [u16], _: u32, _: u32, _: Rect, _: u16) -> bool { - false - } - - fn blend_a8_rgb565( - &mut self, - _: &mut [u16], - _: u32, - _: u32, - _: &[u8], - _: Rect, - _: [u8; 3], - _: u8, - ) -> bool { - false - } - - fn srm_psm5650_to_rgb565( - &mut self, - _: &mut [u16], - _: u32, - _: u32, - _: &[u8], - _: u32, - _: u32, - _: Rect, - _: Rect, - _: SrmTransform, - ) -> bool { - false - } } fn esp_result(operation: &str, code: esp_idf_svc::sys::esp_err_t) -> anyhow::Result<()> { @@ -905,44 +416,3 @@ fn esp_result(operation: &str, code: esp_idf_svc::sys::esp_err_t) -> anyhow::Res anyhow::bail!("{operation} returned ESP-IDF error 0x{code:x}") } } - -#[derive(Debug)] -struct MemorySnapshot { - free_heap: u32, - psram_total: usize, - psram_free: usize, -} - -fn memory_snapshot() -> MemorySnapshot { - unsafe { - MemorySnapshot { - free_heap: esp_idf_svc::sys::esp_get_free_heap_size(), - psram_total: esp_idf_svc::sys::heap_caps_get_total_size( - esp_idf_svc::sys::MALLOC_CAP_SPIRAM, - ), - psram_free: esp_idf_svc::sys::heap_caps_get_free_size( - esp_idf_svc::sys::MALLOC_CAP_SPIRAM, - ), - } - } -} - -fn system_telemetry(ui_fps_tenths: u16) -> SystemTelemetry { - let memory = memory_snapshot(); - let used = memory.psram_total.saturating_sub(memory.psram_free); - let used_percent = if memory.psram_total == 0 { - 0 - } else { - ((used.saturating_mul(100)) / memory.psram_total).min(100) as u8 - }; - let mut cpu = 0u8; - let cpu_percent = - unsafe { esp_idf_svc::sys::pi_p4_cpu_load_percent(&mut cpu).then_some(cpu.min(100)) }; - SystemTelemetry { - psram_used_percent: used_percent, - psram_free_bytes: memory.psram_free, - cpu_percent, - ui_fps_tenths, - lcd_refresh_hz: LCD_REFRESH_HZ, - } -} diff --git a/firmware/esp32-p4/src/transport/provisioning.rs b/firmware/esp32-p4/src/transport/provisioning.rs index ff769a2..8823886 100644 --- a/firmware/esp32-p4/src/transport/provisioning.rs +++ b/firmware/esp32-p4/src/transport/provisioning.rs @@ -15,7 +15,10 @@ pub struct RuntimeConfig { pub wifi_password: Option, pub model: ModelSettings, pub model_api_key: Option, + pub exa_api_key: Option, + pub robinhood_access_token: Option, pub initial_prompt: Option, + pub initial_prompt_delay_seconds: u64, pub unix_time_seconds: Option, } @@ -70,7 +73,14 @@ pub fn request_runtime_config( wifi_password: secret(&value, "wifiPassword", 63)?, model, model_api_key, + exa_api_key: secret(&value, "exaApiKey", 512)?, + robinhood_access_token: secret(&value, "robinhoodAccessToken", 4096)?, initial_prompt: text(&value, "initialPrompt", 4_000)?, + initial_prompt_delay_seconds: value + .get("initialPromptDelaySeconds") + .and_then(serde_json::Value::as_u64) + .unwrap_or(0) + .min(120), unix_time_seconds: value .get("unixTimeSeconds") .and_then(serde_json::Value::as_u64), diff --git a/firmware/esp32-p4/src/waveshare_bindings.h b/firmware/esp32-p4/src/waveshare_bindings.h index 7f7f89b..f47fe59 100644 --- a/firmware/esp32-p4/src/waveshare_bindings.h +++ b/firmware/esp32-p4/src/waveshare_bindings.h @@ -11,4 +11,3 @@ esp_err_t pi_p4_touch_new(esp_lcd_touch_handle_t *ret_touch); bool pi_p4_touch_read(esp_lcd_touch_handle_t touch, uint16_t *x, uint16_t *y); -bool pi_p4_cpu_load_percent(uint8_t *percent); diff --git a/firmware/esp32-p4/tools/esp32p4-cc b/firmware/esp32-p4/tools/esp32p4-cc index 53fbf59..23dc1bc 100755 --- a/firmware/esp32-p4/tools/esp32p4-cc +++ b/firmware/esp32-p4/tools/esp32p4-cc @@ -7,7 +7,7 @@ for compiler in \ "$firmware_root"/.embuild/espressif/tools/riscv32-esp-elf/*/riscv32-esp-elf/bin/riscv32-esp-elf-gcc do if [ -x "$compiler" ]; then - exec "$compiler" "$@" + exec "$compiler" -isystem "$firmware_root/shim" "$@" fi done diff --git a/hosts/esp32-p4-sim/Cargo.toml b/hosts/esp32-p4-sim/Cargo.toml index 225e943..1aa9155 100644 --- a/hosts/esp32-p4-sim/Cargo.toml +++ b/hosts/esp32-p4-sim/Cargo.toml @@ -10,13 +10,13 @@ publish = false anyhow.workspace = true env_logger = "0.11" log.workspace = true -pocket-pi-device-ui = { path = "../../crates/pocket-pi-device-ui" } +pocket-pi-agentos = { path = "../../crates/pocket-pi-agentos" } pocket-pi-embedded = { path = "../../crates/pocket-pi-embedded" } pocket-pi-protocols = { path = "../../crates/pocket-pi-protocols" } pocket-pi-tools = { path = "../../crates/pocket-pi-tools" } -pocketjs-core = { git = "https://github.com/pocket-stack/pocketjs.git", rev = "4c5dc9ef1dd26e6f49b036c210931d399f2b52b2" } -pocket-ui-wgpu = { git = "https://github.com/pocket-stack/pocketjs.git", rev = "4c5dc9ef1dd26e6f49b036c210931d399f2b52b2" } -pocket3d = { git = "https://github.com/pocket-stack/pocketjs.git", rev = "4c5dc9ef1dd26e6f49b036c210931d399f2b52b2", default-features = false } +pocketjs-core.workspace = true +pocket-ui-wgpu = { git = "https://github.com/siwei-yuan/pocketjs.git", rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" } +pocket3d = { git = "https://github.com/siwei-yuan/pocketjs.git", rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0", default-features = false } serde_json.workspace = true tempfile = "3" ureq = { version = "2.12", features = ["json"] } diff --git a/hosts/esp32-p4-sim/src/main.rs b/hosts/esp32-p4-sim/src/main.rs index 965e0dc..a614e7d 100644 --- a/hosts/esp32-p4-sim/src/main.rs +++ b/hosts/esp32-p4-sim/src/main.rs @@ -1,19 +1,17 @@ use std::path::{Path, PathBuf}; -use std::sync::mpsc::{Receiver, Sender}; +use std::sync::mpsc::Receiver; use std::sync::Arc; use std::time::{Duration, Instant}; use anyhow::{anyhow, Result}; use pocket3d::gpu::{Gpu, OffscreenTarget}; -use pocket_pi_device_ui::{ - load_fonts, AgentState, ChatProjection, DeviceState, ModelBackendSettings, ModelSettings, - ScreenInteraction, ScreenState, ScreenView, SettingsCommand, SettingsProjection, - SystemTelemetry, UartProvider, WifiNetworkProjection, +use pocket_pi_agentos::{ + AppServiceHost, AppSupervisor, AppToolRequest, RoutedToolHost, EXA_APP_ID, ROOT_APP_ID, }; -use pocket_pi_embedded::{spawn_agent_worker, AgentEvent}; +use pocket_pi_embedded::{AgentEvent, ToolHost}; use pocket_pi_tools::{CoreToolHost, PlatformTools}; use pocket_ui_wgpu::UiRenderer; -use pocketjs_core::Ui; +use serde_json::{json, Value}; use winit::application::ApplicationHandler; use winit::event::{ElementState, MouseButton, WindowEvent}; use winit::event_loop::{ActiveEventLoop, EventLoop}; @@ -33,7 +31,8 @@ struct Args { screenshot: Option, prompt: Option, workspace: PathBuf, - view: ScreenView, + app: String, + root_tap: Option<(u16, u16)>, backend: BackendChoice, } @@ -42,9 +41,22 @@ fn main() -> Result<()> { let args = parse_args()?; prepare_workspace(&args.workspace)?; if let Some(path) = args.screenshot { - headless(path, args.workspace, args.prompt, args.view, args.backend) + headless( + path, + args.workspace, + args.prompt, + args.app, + args.root_tap, + args.backend, + ) } else { - windowed(args.workspace, args.prompt, args.view, args.backend) + windowed( + args.workspace, + args.prompt, + args.app, + args.root_tap, + args.backend, + ) } } @@ -53,7 +65,8 @@ fn parse_args() -> Result { let mut prompt = None; let mut workspace = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../target/esp32-p4-sim/workspace"); - let mut view = ScreenView::Chat; + let mut app = ROOT_APP_ID.to_owned(); + let mut root_tap = None; let mut backend = std::env::var("POCKET_PI_BACKEND").unwrap_or_else(|_| "codex".into()); let mut model = None; let mut args = std::env::args().skip(1); @@ -62,16 +75,39 @@ fn parse_args() -> Result { "--screenshot" => screenshot = Some(PathBuf::from(next(&mut args, "--screenshot")?)), "--prompt" => prompt = Some(next(&mut args, "--prompt")?), "--workspace" => workspace = PathBuf::from(next(&mut args, "--workspace")?), - "--view" => { - view = match next(&mut args, "--view")?.as_str() { - "chat" => ScreenView::Chat, - "workspace" | "files" => ScreenView::Files, - "settings" => ScreenView::Settings, - value => return Err(anyhow!("unknown view: {value}")), + "--app" | "--view" => { + app = match next(&mut args, &argument)?.as_str() { + "chat" | "pi-agent" => ROOT_APP_ID.to_owned(), + "workspace" | "files" => { + root_tap = Some((270, 1220)); + ROOT_APP_ID.to_owned() + } + "apps" | "runs" => { + root_tap = Some((450, 1220)); + ROOT_APP_ID.to_owned() + } + "settings" => { + root_tap = Some((630, 1220)); + ROOT_APP_ID.to_owned() + } + "keyboard" => { + root_tap = Some((350, 1110)); + ROOT_APP_ID.to_owned() + } + "robinhood" => "robinhood".to_owned(), + "exa" => EXA_APP_ID.to_owned(), + value => return Err(anyhow!("unknown App: {value}")), } } "--backend" => backend = next(&mut args, "--backend")?, "--model" => model = Some(next(&mut args, "--model")?), + "--tap" => { + let value = next(&mut args, "--tap")?; + let (x, y) = value + .split_once(',') + .ok_or_else(|| anyhow!("--tap expects x,y"))?; + root_tap = Some((x.parse()?, y.parse()?)); + } other => return Err(anyhow!("unknown argument: {other}")), } } @@ -79,7 +115,8 @@ fn parse_args() -> Result { screenshot, prompt, workspace, - view, + app, + root_tap, backend: BackendChoice::from_name(&backend, model).map_err(anyhow::Error::msg)?, }) } @@ -99,110 +136,218 @@ fn prepare_workspace(root: &Path) -> Result<()> { } let notes = root.join("notes.txt"); if !notes.exists() { - std::fs::write(notes, "Physical ESP32 and simulator share one device UI.\n")?; + std::fs::write(notes, "Pi Agent owns this top-level workspace.\n")?; } Ok(()) } -fn new_ui() -> Result { - let mut ui = Ui::new(); - ui.set_viewport(PANEL_WIDTH as f32, PANEL_HEIGHT as f32); - if !load_fonts(&mut ui) { - return Err(anyhow!("PocketJS rejected the shared Inter font atlases")); - } - Ok(ui) -} - struct SimPlatform; impl PlatformTools for SimPlatform { - fn device_status(&self) -> serde_json::Value { - serde_json::json!({ + fn device_status(&self) -> Value { + json!({ "status":"ok", "board":"esp32-p4-sim", - "piHarness":"pi-agent-core", - "jsRuntime":"QuickJS via PocketJS host", + "agentOs":true, + "jsRuntime":"QuickJS via PocketJS", "simulated":true }) } - fn wifi_status(&self) -> serde_json::Value { - serde_json::json!({ - "status":"connected", - "ssid":"macOS host network", - "simulated":true - }) + fn wifi_status(&self) -> Value { + json!({"status":"connected","ssid":"macOS host network","simulated":true}) } - fn reboot(&self) -> Result { - Ok(serde_json::json!({"status":"scheduled","simulated":true})) + fn reboot(&self) -> Result { + Ok(json!({"status":"scheduled","simulated":true})) + } +} + +/// Deterministic native fixtures keep the simulator useful without credentials. +/// The App code, SQLite writes and View are exactly the same bundles as the board. +#[derive(Default)] +struct SimAppServices; + +impl AppServiceHost for SimAppServices { + fn call( + &self, + app_id: &str, + service: &str, + operation: &str, + args: &Value, + ) -> Result { + let tool_name = args.get("name").and_then(Value::as_str).unwrap_or(""); + let tool_args = args.get("arguments").unwrap_or(&Value::Null); + if app_id == "robinhood" + && std::env::var("POCKET_PI_SIM_ROBINHOOD_FAIL").as_deref() == Ok("1") + { + return Err("simulated Robinhood service outage".into()); + } + if (app_id, service, operation) == ("robinhood", "mcp.client", "callTools") { + let calls = args + .get("calls") + .and_then(Value::as_array) + .ok_or_else(|| "simulated callTools requires calls".to_owned())?; + let results = calls + .iter() + .map(|call| { + let name = call.get("name").and_then(Value::as_str).unwrap_or(""); + let single = json!({ + "name":name, + "arguments":call.get("arguments").unwrap_or(&Value::Null) + }); + match self.call(app_id, service, "callTool", &single) { + Ok(value) => json!({"name":name,"ok":true,"value":value}), + Err(error) => json!({"name":name,"ok":false,"error":error}), + } + }) + .collect::>(); + return Ok(json!({"results":results})); + } + match (app_id, service, operation, tool_name) { + ("robinhood", "mcp.client", "callTool", "get_accounts") => Ok(json!({ + "accounts":[ + {"account_number":"SIM-AGENT-001","status":"active","type":"cash","agentic_allowed":true}, + {"account_number":"SIM-IRA-002","status":"active","type":"traditional_ira"}, + {"account_number":"SIM-JOINT-003","status":"active","type":"joint"} + ] + })), + ("robinhood", "mcp.client", "callTool", "get_portfolio") => { + let account = tool_args + .get("account_number") + .and_then(Value::as_str) + .unwrap_or("SIM-AGENT-001"); + let (equity, cash, buying_power, day_pnl, week_pnl) = match account { + "SIM-IRA-002" => ("84220.18", "4120.40", "4120.40", "-182.14", "1250.42"), + "SIM-JOINT-003" => ("31008.75", "5280.05", "10560.10", "205.80", "935.22"), + _ => ("15320.42", "1280.20", "2560.40", "128.35", "412.80"), + }; + Ok( + json!({"account_number":account,"equity":equity,"cash":cash,"buying_power":buying_power,"day_pnl":day_pnl,"week_pnl":week_pnl}), + ) + } + ("robinhood", "mcp.client", "callTool", "get_equity_positions") => Ok(json!({ + "positions":[ + {"symbol":"NVDA","quantity":"8","average_buy_price":"712.48","market_value":"7344.00"}, + {"symbol":"AAPL","quantity":"12","average_buy_price":"218.32","market_value":"2784.00"}, + {"symbol":"MSFT","quantity":"6","average_buy_price":"405.15","market_value":"2586.00"}, + {"symbol":"META","quantity":"3","average_buy_price":"502.10","market_value":"1581.00"}, + {"symbol":"AMZN","quantity":"5","average_buy_price":"191.25","market_value":"1012.50"}, + {"symbol":"GOOGL","quantity":"4","average_buy_price":"174.82","market_value":"724.00"}, + {"symbol":"TSLA","quantity":"2","average_buy_price":"332.50","market_value":"690.00"}, + {"symbol":"AMD","quantity":"3","average_buy_price":"168.40","market_value":"522.00"}, + {"symbol":"PLTR","quantity":"4","average_buy_price":"112.20","market_value":"468.00"}, + {"symbol":"VTI","quantity":"2","average_buy_price":"289.75","market_value":"602.00"} + ] + })), + ("robinhood", "mcp.client", "callTool", "get_equity_orders") => Ok(json!({"orders":[ + {"symbol":"NVDA","side":"buy","state":"filled","type":"limit","executed_quantity":"2","average_price":"918.00","created_at":"2026-08-08T09:42:00Z"}, + {"symbol":"AAPL","side":"sell","state":"filled","type":"market","executed_quantity":"4","average_price":"232.00","created_at":"2026-08-07T15:14:00Z"}, + {"symbol":"MSFT","side":"buy","state":"filled","type":"market","executed_quantity":"1","average_price":"431.00","created_at":"2026-08-06T18:28:00Z"}, + {"symbol":"META","side":"sell","state":"filled","type":"limit","executed_quantity":"1","average_price":"527.00","created_at":"2026-08-05T11:20:00Z"}, + {"symbol":"AMZN","side":"buy","state":"filled","type":"limit","executed_quantity":"3","average_price":"202.50","created_at":"2026-08-04T10:05:00Z"}, + {"symbol":"GOOGL","side":"buy","state":"cancelled","type":"limit","quantity":"2","price":"179.00","created_at":"2026-08-03T14:01:00Z"}, + {"symbol":"TSLA","side":"sell","state":"filled","type":"market","executed_quantity":"2","average_price":"345.00","created_at":"2026-08-02T16:32:00Z"}, + {"symbol":"AMD","side":"buy","state":"filled","type":"limit","executed_quantity":"3","average_price":"174.00","created_at":"2026-08-01T12:18:00Z"}, + {"symbol":"PLTR","side":"buy","state":"filled","type":"market","executed_quantity":"4","average_price":"117.00","created_at":"2026-07-31T17:11:00Z"} + ]})), + ("robinhood", "mcp.client", "callTool", "get_realized_pnl") => { + Ok(json!({"realized_pnl":"682.15"})) + } + ("robinhood", "mcp.client", "callTool", name) => { + Ok(json!({"operation":name,"simulated":true,"args":tool_args})) + } + ("exa", "net.http", "post", _) + if args.get("path").and_then(Value::as_str) == Some("/search") => + { + let query = args + .get("body") + .unwrap_or(&Value::Null) + .get("query") + .and_then(Value::as_str) + .unwrap_or("Pocket Pi"); + Ok(json!({"results":[ + {"title":format!("Research result for {query}"),"url":"https://example.com/research"}, + {"title":"PocketJS runtime notes","url":"https://pocketjs.dev/docs/concepts/"} + ]})) + } + ("exa", "net.http", "post", _) + if args.get("path").and_then(Value::as_str) == Some("/contents") => + { + Ok(json!({ + "results":[{"title":"Simulated Exa document","url":"https://example.com/research","text":"Local simulator fixture"}] + })) + } + _ => Err(format!( + "unsupported simulated service call: {app_id}/{service}/{operation}" + )), + } } } +#[derive(Clone)] +struct Message { + role: &'static str, + text: String, +} + struct Product { - chat: ChatProjection, - screen: ScreenState, - device: DeviceState, - prompt_tx: Sender, - agent_rx: Receiver, - tools: Arc, - settings: SettingsProjection, + messages: Vec, + agent_status: &'static str, + model_label: String, + native_tools: Arc, + app_rx: Receiver, + supervisor: AppSupervisor, last_schedule_poll: Instant, busy: bool, - dirty: bool, + projection_dirty: bool, + pending_ui_task: Option, + wifi_connected: Option, + wifi_networks: Vec<(&'static str, i32, bool)>, + wifi_status: String, } impl Product { - fn new(workspace: PathBuf, backend: BackendChoice, view: ScreenView) -> Result { - let local_codex = matches!(backend, BackendChoice::Codex { .. }); - let model_settings = settings_for(&backend); - let tools = Arc::new(CoreToolHost::new(workspace.clone(), Arc::new(SimPlatform))); - let config = backend.agent_config(); - let backend = backend.build(); - let (prompt_tx, agent_rx) = - spawn_agent_worker(config, backend, tools.clone(), None).map_err(anyhow::Error::msg)?; - let workspace = workspace - .to_str() - .ok_or_else(|| anyhow!("workspace path is not valid UTF-8"))?; - let mut screen = ScreenState::new(workspace); - let settings = SettingsProjection { - wifi: pocket_pi_device_ui::WifiSettingsProjection { - connected_ssid: Some("macOS host network".into()), - ip_address: Some("192.0.2.2".into()), - rssi_dbm: Some(-42), - status: "SIMULATED ESP32 WI-FI".into(), - ..Default::default() - }, - firmware_version: env!("CARGO_PKG_VERSION").into(), - workspace_free_bytes: None, + fn new(workspace: PathBuf, backend: BackendChoice, app: &str) -> Result { + let model_label = match &backend { + BackendChoice::Wireless { + provider, model, .. + } => { + format!("{} / {model}", provider.id()) + } + BackendChoice::Codex { model } => { + format!("Codex / {}", model.as_deref().unwrap_or("coding-plan")) + } }; - screen.view = view; - screen.set_model_backend(&model_settings); - if local_codex { - screen.set_backend_status("CODEX", "LOCAL / MAC", "CODING PLAN"); - } - screen.set_telemetry(SystemTelemetry { - psram_used_percent: 25, - psram_free_bytes: 24 * 1024 * 1024, - cpu_percent: None, - ui_fps_tenths: 0, - lcd_refresh_hz: 32, - }); - screen.refresh_workspace(); - screen.set_settings(settings.clone()); + let services: Arc = Arc::new(SimAppServices::default()); + let mut supervisor = AppSupervisor::new(workspace.clone(), services)?; + supervisor.open(app)?; + + let native_tools = Arc::new(CoreToolHost::new(workspace.clone(), Arc::new(SimPlatform))); + let catalog = supervisor.catalog().clone(); + let native: Arc = native_tools.clone(); + let (routed, app_rx) = RoutedToolHost::new(native, catalog); + let config = backend.agent_config(); + let model = backend.build(); + supervisor.boot_agent(&config, model, Arc::new(routed))?; + Ok(Self { - chat: ChatProjection::new("TYPE A MESSAGE", "ESP32-P4 PI AGENT SIMULATOR READY."), - screen, - device: DeviceState { - agent: AgentState::Idle, - }, - prompt_tx, - agent_rx, - tools, - settings, + messages: vec![Message { + role: "assistant", + text: "Pocket Pi AgentOS is ready. Robinhood and Exa are installed Apps.".into(), + }], + agent_status: "IDLE", + model_label, + native_tools, + app_rx, + supervisor, last_schedule_poll: Instant::now(), busy: false, - dirty: true, + projection_dirty: true, + pending_ui_task: None, + wifi_connected: Some("macOS host network".into()), + wifi_networks: Vec::new(), + wifi_status: "SIMULATED NETWORK READY".into(), }) } @@ -210,153 +355,174 @@ impl Product { if self.busy || prompt.trim().is_empty() { return; } - self.chat.push_pending(prompt.clone()); - self.screen.show_latest_chat(); - self.device.agent = AgentState::Thinking; + self.messages.push(Message { + role: "user", + text: prompt.clone(), + }); + self.messages.push(Message { + role: "assistant", + text: String::new(), + }); + self.agent_status = "THINKING"; self.busy = true; - if self.prompt_tx.send(prompt).is_err() { - self.chat.fail_pending("AGENT WORKER IS NOT AVAILABLE"); - self.device.agent = AgentState::Faulted; + if let Err(error) = self.supervisor.prompt_agent(&prompt) { + self.messages.last_mut().unwrap().text = format!("Agent is unavailable: {error:#}"); + self.agent_status = "FAULTED"; self.busy = false; } - self.dirty = true; - } - - fn tap(&mut self, x: u16, y: u16, ui: &Ui) { - match self.screen.handle_tap(x, y, &self.chat, ui) { - ScreenInteraction::None => {} - ScreenInteraction::Redraw => self.dirty = true, - ScreenInteraction::SubmitPrompt(prompt) => self.send_prompt(prompt), - ScreenInteraction::Settings(command) => self.handle_settings(command), - } + self.projection_dirty = true; } - fn handle_settings(&mut self, command: SettingsCommand) { - match command { - SettingsCommand::ScanWifi => { - self.settings.wifi.networks = vec![ - WifiNetworkProjection { - ssid: "POCKET-PI-LAB".into(), - rssi_dbm: -38, - secured: true, - }, - WifiNetworkProjection { - ssid: "PHONE-HOTSPOT".into(), - rssi_dbm: -56, - secured: true, - }, - WifiNetworkProjection { - ssid: "GUEST".into(), - rssi_dbm: -71, - secured: false, - }, - WifiNetworkProjection { - ssid: "OFFICE".into(), - rssi_dbm: -74, - secured: true, - }, - WifiNetworkProjection { - ssid: "CAFE".into(), - rssi_dbm: -78, - secured: false, - }, - WifiNetworkProjection { - ssid: "PHONE-2".into(), - rssi_dbm: -82, - secured: true, - }, - ]; - self.settings.wifi.status.clear(); - } - SettingsCommand::ConnectWifi { ssid, password } => { - if !password.is_empty() && !(8..=63).contains(&password.len()) { - self.settings.wifi.status = "PASSWORD MUST BE 8-63 BYTES".into(); - } else { - self.settings.wifi.connected_ssid = Some(ssid); - self.settings.wifi.ip_address = Some("192.0.2.2".into()); - self.settings.wifi.rssi_dbm = Some(-40); - self.settings.wifi.status = "CONNECTED (SIMULATED)".into(); + fn tap(&mut self, x: u16, y: u16) -> Result<()> { + let action = self.supervisor.tap(x, y)?; + match action.get("type").and_then(Value::as_str) { + Some("navigate") => { + if let Some(app) = action.get("app").and_then(Value::as_str) { + self.supervisor.open(app)?; + self.projection_dirty = true; } } - SettingsCommand::ForgetWifi => { - self.settings.wifi.connected_ssid = None; - self.settings.wifi.ip_address = None; - self.settings.wifi.rssi_dbm = None; - self.settings.wifi.status = "NETWORK FORGOTTEN (SIMULATED)".into(); + Some("submitPrompt") => { + if let Some(prompt) = action.get("prompt").and_then(Value::as_str) { + self.send_prompt(prompt.to_owned()); + } } - SettingsCommand::Restart => { - self.settings.wifi.status = "RESTART REQUESTED (SIMULATED)".into(); + Some("invokeTask") => { + if let Some(task) = action.get("task").and_then(Value::as_str) { + self.pending_ui_task = Some(task.to_owned()); + } } + Some("settings") => match action.get("command").and_then(Value::as_str) { + Some("scan") => { + self.wifi_networks = vec![ + ("PocketPi Lab", -42, true), + ("Studio Guest", -61, false), + ("ESP32 Testbench", -73, true), + ]; + self.wifi_status = "3 NETWORKS FOUND".into(); + self.projection_dirty = true; + } + Some("connect") => { + if let Some(ssid) = action.get("ssid").and_then(Value::as_str) { + self.wifi_connected = Some(ssid.to_owned()); + self.wifi_status = format!("CONNECTED TO {ssid}"); + self.projection_dirty = true; + } + } + Some("forget") => { + self.wifi_connected = None; + self.wifi_status = "WI-FI CREDENTIALS FORGOTTEN".into(); + self.projection_dirty = true; + } + Some("restart") => { + self.wifi_status = "SIMULATED RESTART REQUESTED".into(); + self.projection_dirty = true; + } + _ => {} + }, + _ => {} } - self.screen.set_settings(self.settings.clone()); - self.dirty = true; + Ok(()) } - fn release_touch(&mut self) { - self.dirty |= self.screen.handle_touch_release(); + fn run_pending_ui_task(&mut self) { + let Some(task) = self.pending_ui_task.take() else { + return; + }; + let started = Instant::now(); + let result = self.supervisor.invoke_active_task(&task, &Value::Null); + log::info!( + "UI AppTask {} finished in {}ms: {}", + task, + started.elapsed().as_millis(), + result.text + ); + self.projection_dirty = true; } - fn poll_agent(&mut self) { - while let Ok(event) = self.agent_rx.try_recv() { - match event { - AgentEvent::Ready => { - self.device.agent = AgentState::Idle; + fn poll(&mut self) -> Result<()> { + while let Ok(request) = self.app_rx.try_recv() { + request.handle(&mut self.supervisor); + self.projection_dirty = true; + } + if self.last_schedule_poll.elapsed() >= Duration::from_secs(1) { + if !self.busy { + if let Some(wake) = self.native_tools.claim_due() { + self.send_prompt(wake.prompt); } - AgentEvent::Delta(delta) => { - if self.chat.append_model_delta(&delta) { - self.screen.show_latest_chat(); + } + for (task, result) in self.supervisor.poll_due_tasks() { + log::info!("AppTask {task}: {}", result.text); + } + self.last_schedule_poll = Instant::now(); + self.projection_dirty = true; + } + + if self.projection_dirty { + self.supervisor.update_root(&self.root_projection())?; + self.projection_dirty = false; + } + // frame() always advances the Pi Agent System App, even while another + // App owns the visible View. Model/tool work itself remains off-thread. + for event in self.supervisor.frame()? { + match event { + AgentEvent::Ready => self.agent_status = "IDLE", + AgentEvent::ResponseText(text) => { + if let Some(message) = self.messages.last_mut() { + message.text.push_str(&text); } } AgentEvent::Done => { - self.chat.finish_pending(); - self.screen.refresh_workspace(); - self.device.agent = AgentState::Idle; + self.agent_status = "IDLE"; self.busy = false; } AgentEvent::Failed(error) => { - self.chat.fail_pending(format!("AGENT FAILED: {error}")); - self.device.agent = AgentState::Faulted; + if let Some(message) = self.messages.last_mut() { + message.text = format!("Agent failed: {error}"); + } + self.agent_status = "FAULTED"; self.busy = false; } } - self.dirty = true; + self.projection_dirty = true; } - if self.last_schedule_poll.elapsed() >= Duration::from_secs(1) { - let schedule = self.tools.schedule_projection(); - self.screen - .set_schedule(pocket_pi_device_ui::ScheduleProjection { - name: schedule.name, - prompt: schedule.prompt, - next_in_seconds: schedule.next_in_seconds, - every_minutes: schedule.every_minutes, - }); - if !self.busy { - if let Some(wake) = self.tools.claim_due() { - self.send_prompt(wake.prompt); - } - } - self.last_schedule_poll = Instant::now(); - self.dirty = true; - } - } - - fn words(&self, ui: &Ui) -> Vec { - self.screen.draw_list(ui, &self.device, &self.chat) + Ok(()) } -} -fn settings_for(backend: &BackendChoice) -> ModelSettings { - let backend = match backend { - BackendChoice::Wireless { provider, .. } => ModelBackendSettings::Wireless { - provider: *provider, - }, - BackendChoice::Codex { .. } => ModelBackendSettings::Uart { - provider: UartProvider::Codex, - }, - }; - ModelSettings { - backend, - model: None, + fn root_projection(&self) -> Value { + let schedule = self.native_tools.schedule_projection(); + let schedule_next = match schedule.next_in_seconds { + Some(seconds) => schedule.every_minutes.map_or_else( + || format!("in {seconds}s"), + |minutes| format!("in {seconds}s · every {minutes}m"), + ), + None => "not scheduled".to_owned(), + }; + json!({ + "agent":self.agent_status, + "model":self.model_label, + "messages":self.messages.iter().map(|message| json!({"role":message.role,"text":message.text})).collect::>(), + "schedule":{ + "name":schedule.name, + "prompt":schedule.prompt, + "next":schedule_next, + "everyMinutes":schedule.every_minutes, + }, + "settings":{ + "wifi":{ + "connectedSsid":self.wifi_connected, + "ipAddress":if self.wifi_connected.is_some() { Some("192.168.4.20") } else { None }, + "rssiDbm":if self.wifi_connected.is_some() { Some(-42) } else { None }, + "scanning":false, + "networks":self.wifi_networks.iter().map(|(ssid,rssi,secured)| json!({ + "ssid":ssid,"rssiDbm":rssi,"secured":secured + })).collect::>(), + "status":self.wifi_status, + }, + "firmwareVersion":env!("CARGO_PKG_VERSION"), + "workspaceFree":"SIMULATED 24 MB", + } + }) } } @@ -364,18 +530,30 @@ fn headless( output: PathBuf, workspace: PathBuf, prompt: Option, - view: ScreenView, + app: String, + root_tap: Option<(u16, u16)>, backend: BackendChoice, ) -> Result<()> { - let ui = new_ui()?; - let mut product = Product::new(workspace, backend, view)?; + let mut product = Product::new(workspace, backend, &app)?; + if let Some((x, y)) = root_tap { + product.tap(x, y)?; + product.run_pending_ui_task(); + } let wait_for_turn = prompt.is_some(); if let Some(prompt) = prompt { product.send_prompt(prompt); } - for _ in 0..7_500 { - product.poll_agent(); - if !wait_for_turn || !product.busy { + let mut settled_frames = 0; + for frame in 0..7_500 { + product.poll()?; + // Give PocketJS a few ticks to settle reactive insertions and layout + // before taking a deterministic screenshot. + if (!wait_for_turn || !product.busy) && !product.supervisor.services_busy() { + settled_frames += 1; + } else { + settled_frames = 0; + } + if frame >= 2 && settled_frames >= 2 { break; } std::thread::sleep(Duration::from_millis(16)); @@ -385,16 +563,18 @@ fn headless( let target = OffscreenTarget::new(&gpu, PANEL_WIDTH, PANEL_HEIGHT); let mut renderer = UiRenderer::new(&gpu, pocket3d::gpu::OFFSCREEN_FORMAT); let mut encoder = gpu.device.create_command_encoder(&Default::default()); - let words = product.words(&ui); - renderer.render_words( - &gpu, - &ui, - &words, - &mut encoder, - &target.view, - (PANEL_WIDTH, PANEL_HEIGHT), - wgpu::LoadOp::Clear(wgpu::Color::BLACK), - )?; + product.supervisor.with_ui(|ui| { + let words = ui.draw().words.clone(); + renderer.render_words( + &gpu, + ui, + &words, + &mut encoder, + &target.view, + (PANEL_WIDTH, PANEL_HEIGHT), + wgpu::LoadOp::Clear(wgpu::Color::BLACK), + ) + })?; gpu.queue.submit([encoder.finish()]); if let Some(parent) = output.parent() { std::fs::create_dir_all(parent)?; @@ -410,18 +590,16 @@ struct WindowState { surface: wgpu::Surface<'static>, config: wgpu::SurfaceConfiguration, renderer: UiRenderer, - ui: Ui, product: Product, cursor: (u16, u16), touch_down: bool, - frames: u32, - fps_started: Instant, } struct WindowApp { workspace: PathBuf, initial_prompt: Option, - initial_view: ScreenView, + initial_app: String, + initial_root_tap: Option<(u16, u16)>, backend: Option, state: Option, error: Option, @@ -430,14 +608,16 @@ struct WindowApp { fn windowed( workspace: PathBuf, prompt: Option, - view: ScreenView, + app: String, + root_tap: Option<(u16, u16)>, backend: BackendChoice, ) -> Result<()> { let event_loop = EventLoop::new()?; let mut app = WindowApp { workspace, initial_prompt: prompt, - initial_view: view, + initial_app: app, + initial_root_tap: root_tap, backend: Some(backend), state: None, error: None, @@ -448,11 +628,10 @@ fn windowed( impl WindowApp { fn init(&mut self, event_loop: &ActiveEventLoop) -> Result { - let ui = new_ui()?; let window = Arc::new( event_loop.create_window( Window::default_attributes() - .with_title("Pocket Pi — ESP32-P4 Simulator") + .with_title("Pocket Pi AgentOS — ESP32-P4 Simulator") .with_inner_size(winit::dpi::LogicalSize::new(WINDOW_WIDTH, WINDOW_HEIGHT)) .with_resizable(false), )?, @@ -471,7 +650,10 @@ impl WindowApp { .backend .take() .ok_or_else(|| anyhow!("simulator backend was already consumed"))?; - let mut product = Product::new(self.workspace.clone(), backend, self.initial_view)?; + let mut product = Product::new(self.workspace.clone(), backend, &self.initial_app)?; + if let Some((x, y)) = self.initial_root_tap.take() { + product.tap(x, y)?; + } if let Some(prompt) = self.initial_prompt.take() { product.send_prompt(prompt); } @@ -481,27 +663,14 @@ impl WindowApp { surface, config, renderer, - ui, product, cursor: (0, 0), touch_down: false, - frames: 0, - fps_started: Instant::now(), }) } fn redraw(state: &mut WindowState) -> Result<()> { - state.product.poll_agent(); - state.frames += 1; - let elapsed = state.fps_started.elapsed(); - if elapsed >= Duration::from_secs(1) { - state.product.screen.telemetry.ui_fps_tenths = - ((state.frames as f32 / elapsed.as_secs_f32()) * 10.0).round() as u16; - state.frames = 0; - state.fps_started = Instant::now(); - state.product.dirty = true; - } - + state.product.poll()?; let frame = match state.surface.get_current_texture() { Ok(frame) => frame, Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { @@ -513,21 +682,23 @@ impl WindowApp { let view = frame.texture.create_view(&Default::default()); let mut encoder = state.gpu.device.create_command_encoder(&Default::default()); let scale = state.config.width as f32 / PANEL_WIDTH as f32; - let words = state.product.words(&state.ui); - state.renderer.render_words_scaled( - &state.gpu, - &state.ui, - &words, - &mut encoder, - &view, - (state.config.width, state.config.height), - scale, - wgpu::LoadOp::Clear(wgpu::Color::BLACK), - )?; + state.product.supervisor.with_ui(|ui| { + let words = ui.draw().words.clone(); + state.renderer.render_words_scaled( + &state.gpu, + ui, + &words, + &mut encoder, + &view, + (state.config.width, state.config.height), + scale, + wgpu::LoadOp::Clear(wgpu::Color::BLACK), + ) + })?; state.gpu.queue.submit([encoder.finish()]); state.window.pre_present_notify(); frame.present(); - state.product.dirty = false; + state.product.run_pending_ui_task(); state.window.request_redraw(); Ok(()) } @@ -574,22 +745,21 @@ impl ApplicationHandler for WindowApp { .. } if !state.touch_down => { state.touch_down = true; - state.product.tap(state.cursor.0, state.cursor.1, &state.ui); + if let Err(error) = state.product.tap(state.cursor.0, state.cursor.1) { + self.error = Some(error); + event_loop.exit(); + } } WindowEvent::MouseInput { button: MouseButton::Left, state: ElementState::Released, .. - } => { - state.touch_down = false; - state.product.release_touch(); - } - WindowEvent::KeyboardInput { event, .. } => { + } => state.touch_down = false, + WindowEvent::KeyboardInput { event, .. } if event.state == ElementState::Pressed - && matches!(event.physical_key, PhysicalKey::Code(KeyCode::Escape)) - { - event_loop.exit(); - } + && matches!(event.physical_key, PhysicalKey::Code(KeyCode::Escape)) => + { + event_loop.exit(); } WindowEvent::RedrawRequested => { if let Err(error) = Self::redraw(state) { @@ -606,133 +776,208 @@ impl ApplicationHandler for WindowApp { mod tests { use super::*; - #[test] - fn bottom_navigation_uses_the_physical_screen_hit_map() { - let temp = tempfile::tempdir().unwrap(); - let ui = new_ui().unwrap(); - let mut product = Product::new( - temp.path().to_owned(), - BackendChoice::Codex { model: None }, - ScreenView::Chat, - ) - .unwrap(); + fn init_logs() { + let _ = env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")) + .is_test(true) + .try_init(); + } - product.tap(360, 1220, &ui); + struct FailingRobinhood; + + impl AppServiceHost for FailingRobinhood { + fn call( + &self, + _app_id: &str, + service: &str, + operation: &str, + _args: &Value, + ) -> Result { + let _ = (service, operation); + Err("simulated Robinhood outage".into()) + } + } - assert_eq!(product.screen.view, ScreenView::Files); - product.screen.view = ScreenView::Chat; - product.tap(650, 1220, &ui); - assert_eq!(product.screen.view, ScreenView::Settings); + fn wait_for(mut ready: impl FnMut() -> bool) { + for _ in 0..100 { + if ready() { + return; + } + std::thread::sleep(Duration::from_millis(20)); + } + panic!("timed out waiting for background App Data Action"); } #[test] - fn settings_scan_and_wifi_password_use_the_shared_touch_keyboard() { + fn exa_tool_writes_app_owned_sqlite() { + init_logs(); let temp = tempfile::tempdir().unwrap(); - let ui = new_ui().unwrap(); - let mut product = Product::new( - temp.path().to_owned(), - BackendChoice::Codex { model: None }, - ScreenView::Settings, - ) - .unwrap(); - - product.tap(580, 180, &ui); - product.tap(120, 350, &ui); - for _ in 0..8 { - product.tap(54, 548, &ui); - } - product.tap(640, 986, &ui); - - assert_eq!( - product.settings.wifi.connected_ssid.as_deref(), - Some("POCKET-PI-LAB") + let mut supervisor = + AppSupervisor::new(temp.path(), Arc::new(SimAppServices::default())).unwrap(); + let result = supervisor.invoke_tool( + "research.search", + r#"{"query":"NVIDIA FY2026 annual report 10-K revenue data center guidance","numResults":5,"includeDomains":["investor.nvidia.com","sec.gov"]}"#, ); - assert!(!product.screen.handle_touch_release()); + assert!(!result.is_error, "{}", result.text); + assert_eq!(result.details["status"], "queued"); + wait_for(|| { + let storage = supervisor.invoke_tool("research.storage_status", "{}"); + storage.details["latestSearches"] + .as_array() + .is_some_and(|rows| !rows.is_empty()) + }); + assert!(temp.path().join("apps/exa/data/exa.sqlite").exists()); + let storage = supervisor.invoke_tool("research.storage_status", "{}"); + assert!(!storage.is_error, "{}", storage.text); + let searches = storage.details["tables"] + .as_array() + .unwrap() + .iter() + .find(|table| table["name"] == "searches") + .unwrap(); + assert_eq!(searches["rowCount"], 1); + let results = storage.details["tables"] + .as_array() + .unwrap() + .iter() + .find(|table| table["name"] == "search_results") + .unwrap(); + assert_eq!(results["rowCount"], 2); + assert!(storage.details["tables"] + .as_array() + .unwrap() + .iter() + .all(|table| table["name"] != "search_history")); + assert_eq!(storage.details["latestSearches"][0]["status"], "ok"); } #[test] - fn settings_wifi_list_scrolls_to_later_networks() { + fn views_open_empty_databases_without_starting_data_actions() { + init_logs(); let temp = tempfile::tempdir().unwrap(); - let ui = new_ui().unwrap(); - let mut product = Product::new( - temp.path().to_owned(), - BackendChoice::Codex { model: None }, - ScreenView::Settings, - ) - .unwrap(); + let mut supervisor = + AppSupervisor::new(temp.path(), Arc::new(SimAppServices::default())).unwrap(); - product.tap(580, 180, &ui); - assert!(product.settings.wifi.status.is_empty()); - product.tap(660, 710, &ui); - product.tap(120, 626, &ui); + let robinhood = supervisor.invoke_tool("robinhood.storage_status", "{}"); + assert!(!robinhood.is_error, "{}", robinhood.text); + assert!(robinhood.details["tables"].as_array().unwrap().is_empty()); - assert_eq!( - product.settings.wifi.connected_ssid.as_deref(), - Some("CAFE") - ); + let exa = supervisor.invoke_tool("research.storage_status", "{}"); + assert!(!exa.is_error, "{}", exa.text); + assert!(exa.details["tables"].as_array().unwrap().is_empty()); } #[test] - fn mouse_coordinates_drive_the_same_keyboard_as_touch() { + fn app_navigation_keeps_pi_agent_at_workspace_root() { + init_logs(); let temp = tempfile::tempdir().unwrap(); - let ui = new_ui().unwrap(); - let mut screen = ScreenState::new(temp.path().to_str().unwrap()); - let chat = ChatProjection::new("YOU", "PI"); + let mut supervisor = + AppSupervisor::new(temp.path(), Arc::new(SimAppServices::default())).unwrap(); + supervisor.open("robinhood").unwrap(); + assert_eq!(supervisor.active_id(), "robinhood"); + assert!(temp.path().join("data/view/current").exists()); + assert!(temp.path().join("apps/robinhood/current").exists()); + } - assert_eq!( - screen.handle_tap(360, 1100, &chat, &ui), - ScreenInteraction::Redraw - ); - assert_eq!( - screen.handle_tap(54, 548, &chat, &ui), - ScreenInteraction::Redraw - ); - assert_eq!( - screen.handle_tap(640, 986, &chat, &ui), - ScreenInteraction::SubmitPrompt("q".into()) - ); + #[test] + fn robinhood_refresh_recovers_after_service_failure() { + init_logs(); + let temp = tempfile::tempdir().unwrap(); + let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(FailingRobinhood)).unwrap(); + supervisor.open("robinhood").unwrap(); + + let first = supervisor.tap(650, 1220).unwrap(); + assert_eq!(first["type"], "invokeTask"); + let failed = supervisor.invoke_active_task("refreshPortfolio", &Value::Null); + assert!(!failed.is_error); + wait_for(|| { + let storage = supervisor.invoke_tool("robinhood.storage_status", "{}"); + storage.details["latestRefreshes"] + .as_array() + .and_then(|rows| rows.first()) + .is_some_and(|row| row["status"] == "failed") + }); + supervisor.frame().unwrap(); + + let storage = supervisor.invoke_tool("robinhood.storage_status", "{}"); + assert!(!storage.is_error, "{}", storage.text); + assert_eq!(storage.details["latestRefreshes"][0]["status"], "failed"); + let values = storage.details["tables"] + .as_array() + .unwrap() + .iter() + .find(|table| table["name"] == "total_value") + .unwrap(); + assert_eq!(values["rowCount"], 0); + + let retry = supervisor.tap(650, 1220).unwrap(); + assert_eq!(retry["type"], "invokeTask"); } #[test] - fn touch_keyboard_can_type_uppercase_wifi_passwords() { + fn robinhood_full_views_and_account_switch_render() { + init_logs(); let temp = tempfile::tempdir().unwrap(); - let ui = new_ui().unwrap(); - let mut screen = ScreenState::new(temp.path().to_str().unwrap()); - let chat = ChatProjection::new("YOU", "PI"); + let mut supervisor = + AppSupervisor::new(temp.path(), Arc::new(SimAppServices::default())).unwrap(); + supervisor.open("robinhood").unwrap(); + let refreshed = supervisor.invoke_tool("robinhood.refresh_portfolio", "{}"); + assert!(!refreshed.is_error, "{}", refreshed.text); + wait_for(|| { + let storage = supervisor.invoke_tool("robinhood.storage_status", "{}"); + storage.details["latestRefreshes"] + .as_array() + .and_then(|rows| rows.first()) + .is_some_and(|row| row["status"] == "succeeded") + }); + supervisor.frame().unwrap(); + let storage = supervisor.invoke_tool("robinhood.storage_status", "{}"); + assert!(!storage.is_error, "{}", storage.text); assert_eq!( - screen.handle_tap(360, 1100, &chat, &ui), - ScreenInteraction::Redraw + storage.details["latestRefreshes"].as_array().unwrap().len(), + 1 ); + assert_eq!(storage.details["latestRefreshes"][0]["status"], "succeeded"); + assert_eq!(storage.details["latestRefreshes"][0]["operation_count"], 16); + assert_eq!(storage.details["latestRefreshes"][0]["success_count"], 16); + let tables = storage.details["tables"].as_array().unwrap(); + assert!(tables.iter().all(|table| table["name"] != "tool_events")); assert_eq!( - screen.handle_tap(450, 986, &chat, &ui), - ScreenInteraction::Redraw + tables + .iter() + .find(|table| table["name"] == "accounts") + .unwrap()["rowCount"], + 3 ); assert_eq!( - screen.handle_tap(54, 548, &chat, &ui), - ScreenInteraction::Redraw + tables + .iter() + .find(|table| table["name"] == "portfolio_current") + .unwrap()["rowCount"], + 3 ); assert_eq!( - screen.handle_tap(640, 986, &chat, &ui), - ScreenInteraction::SubmitPrompt("Q".into()) + tables + .iter() + .find(|table| table["name"] == "total_value") + .unwrap()["rowCount"], + 3 ); - } - - #[test] - fn workspace_row_opens_the_physical_file_viewer() { - let temp = tempfile::tempdir().unwrap(); - std::fs::write(temp.path().join("memory.md"), "shared-ui").unwrap(); - let ui = new_ui().unwrap(); - let mut product = Product::new( - temp.path().to_owned(), - BackendChoice::Codex { model: None }, - ScreenView::Chat, - ) - .unwrap(); - - product.tap(360, 1220, &ui); - product.tap(120, 220, &ui); - assert_eq!(product.screen.view, ScreenView::Viewer); + supervisor.tap(350, 140).unwrap(); + supervisor.frame().unwrap(); + assert!(supervisor.with_ui(|ui| ui.draw().words.len()) > 100); + + supervisor.tap(350, 250).unwrap(); + supervisor.frame().unwrap(); + supervisor.tap(350, 700).unwrap(); + supervisor.frame().unwrap(); + assert!(supervisor.with_ui(|ui| ui.draw().words.len()) > 100); + + supervisor.tap(80, 60).unwrap(); + supervisor.frame().unwrap(); + supervisor.tap(350, 900).unwrap(); + supervisor.frame().unwrap(); + assert!(supervisor.with_ui(|ui| ui.draw().words.len()) > 100); } } diff --git a/tools/uart-model-bridge.py b/tools/uart-model-bridge.py index 6f2c925..43b25b1 100755 --- a/tools/uart-model-bridge.py +++ b/tools/uart-model-bridge.py @@ -22,6 +22,67 @@ WAITING = "PPI-RPC-WAITING" REQUEST = "PPI-RPC-REQUEST:" STREAM = "PPI-RPC-STREAM:" +ROBINHOOD_KEYCHAIN_SERVICE = "Codex MCP Credentials" +ROBINHOOD_KEYCHAIN_ACCOUNT = "robinhood-trading|5cbe81c78ff5ae58" +EXA_KEYCHAIN_SERVICE = "Pocket Pi Credentials" +EXA_KEYCHAIN_ACCOUNT = "exa-api-key" +WIFI_KEYCHAIN_SERVICE = "Pocket Pi Wi-Fi" +WIFI_KEYCHAIN_ACCOUNT = "TUF WIFI6" + + +def keychain_secret(service: str, account: str) -> str | None: + """Read one generic-password value without ever printing it.""" + try: + result = subprocess.run( + ["security", "find-generic-password", "-s", service, "-a", account, "-w"], + capture_output=True, + text=True, + check=False, + ) + except FileNotFoundError: + return None + value = result.stdout.strip() + return value if result.returncode == 0 and value else None + + +def robinhood_access_token() -> str | None: + """Reuse a completed Codex MCP OAuth grant without exposing it to disk.""" + try: + result = subprocess.run( + [ + "security", + "find-generic-password", + "-s", + ROBINHOOD_KEYCHAIN_SERVICE, + "-a", + ROBINHOOD_KEYCHAIN_ACCOUNT, + "-w", + ], + capture_output=True, + text=True, + check=False, + ) + except FileNotFoundError: + return None + if result.returncode != 0: + return None + try: + credential = json.loads(result.stdout) + token = credential.get("token_response", {}).get("access_token") + return token if isinstance(token, str) and token else None + except (json.JSONDecodeError, AttributeError): + return None + + +def exa_api_key() -> str | None: + """Load the user-provided Exa key from macOS Keychain.""" + return keychain_secret(EXA_KEYCHAIN_SERVICE, EXA_KEYCHAIN_ACCOUNT) + + +def saved_wifi() -> tuple[str, str] | None: + """Load the development board Wi-Fi without exposing it to source or logs.""" + password = keychain_secret(WIFI_KEYCHAIN_SERVICE, WIFI_KEYCHAIN_ACCOUNT) + return (WIFI_KEYCHAIN_ACCOUNT, password) if password else None def write_line(fd: int, line: str) -> None: @@ -35,6 +96,29 @@ def write_line(fd: int, line: str) -> None: payload = payload[count:] +def log_tool_failure(request: dict[str, object]) -> None: + """Print only failed ESP tool text, never successful account payloads.""" + context = request.get("context") + if not isinstance(context, dict): + return + messages = context.get("messages") + if not isinstance(messages, list): + return + for message in reversed(messages): + if not isinstance(message, dict) or message.get("role") != "toolResult": + continue + if message.get("isError") is not True: + return + content = message.get("content") + if not isinstance(content, list): + return + for item in content: + if isinstance(item, dict) and item.get("type") == "text": + failure = str(item.get("text", "App tool failed"))[:400] + print(f"[bridge] ESP tool failure: {failure}", flush=True) + return + + def config(args: argparse.Namespace) -> dict[str, object]: provider = args.provider or ("codex" if args.backend == "uart" else "openai") value: dict[str, object] = { @@ -44,13 +128,40 @@ def config(args: argparse.Namespace) -> dict[str, object]: } if args.model: value["model"] = args.model - if args.provision_wifi: + wifi = saved_wifi() + if wifi: + value["wifiSsid"], value["wifiPassword"] = wifi + print(f"Wi-Fi: provisioning {wifi[0]} from Keychain", flush=True) + elif args.provision_wifi: value["wifiSsid"] = input("Wi-Fi SSID: ").strip() value["wifiPassword"] = getpass.getpass("Wi-Fi password: ") if args.backend == "wireless": value["modelApiKey"] = getpass.getpass(f"{provider} API key: ") + if args.provision_exa: + key = exa_api_key() + if key: + value["exaApiKey"] = key + print("Exa: reusing Keychain API key (RAM only on device)", flush=True) + else: + key = getpass.getpass("Exa API key: ") + if key: + value["exaApiKey"] = key + if args.provision_robinhood: + token = robinhood_access_token() + if token: + value["robinhoodAccessToken"] = token + print( + "Robinhood: reusing existing authorized Codex MCP session (RAM only)", + flush=True, + ) + else: + token = getpass.getpass("Robinhood OAuth access token: ") + if token: + value["robinhoodAccessToken"] = token if args.prompt: value["initialPrompt"] = args.prompt + if args.prompt_delay_seconds: + value["initialPromptDelaySeconds"] = args.prompt_delay_seconds return value @@ -64,7 +175,17 @@ def main() -> int: ) parser.add_argument("--model") parser.add_argument("--prompt", help="submit one prompt after the board agent is ready") + parser.add_argument( + "--prompt-delay-seconds", + type=int, + choices=range(0, 121), + default=0, + metavar="0..120", + help="delay the repeatable boot prompt while device services settle", + ) parser.add_argument("--provision-wifi", action="store_true") + parser.add_argument("--provision-exa", action="store_true") + parser.add_argument("--provision-robinhood", action="store_true") args = parser.parse_args() provider = args.provider or ("codex" if args.backend == "uart" else "openai") if args.backend == "uart" and provider not in ("codex", "claude-code"): @@ -119,21 +240,15 @@ def stop(_signum: int, _frame: object) -> None: if model_backend is None: raise RuntimeError("wireless mode does not provide a UART model backend") stream_stats = [0, 0] + request_payload = json.loads(line[len(REQUEST) :]) + log_tool_failure(request_payload) def emit_delta(delta: str) -> None: stream_stats[0] += 1 stream_stats[1] += len(delta) - write_line( - fd, - STREAM - + json.dumps( - {"type": "text_delta", "text": delta}, - separators=(",", ":"), - ), - ) result = model_backend.complete( - json.loads(line[len(REQUEST) :]), + request_payload, emit_delta, ) call = result.get("toolCall") @@ -146,7 +261,8 @@ def emit_delta(delta: str) -> None: elif isinstance(result.get("text"), str): print(f"[bridge] Pi reply: {result['text']}", flush=True) print( - f"[bridge] streamed {stream_stats[0]} chunks / {stream_stats[1]} chars", + f"[bridge] coalesced {stream_stats[0]} provider chunks / " + f"{stream_stats[1]} chars into one UART result", flush=True, ) write_line( diff --git a/tools/xtask/src/main.rs b/tools/xtask/src/main.rs index 5d59fed..1d7aebb 100644 --- a/tools/xtask/src/main.rs +++ b/tools/xtask/src/main.rs @@ -8,6 +8,7 @@ fn main() -> Result<()> { let mut args = std::env::args().skip(1); match (args.next().as_deref(), args.next().as_deref()) { (Some("build"), Some("macos")) => cargo(&root, ["build", "-p", "pocket-pi-macos"]), + (Some("build"), Some("agentos-apps")) => build_agentos_apps(&root), (Some("build"), Some("esp32-p4")) => { build_embedded_guest(&root)?; command( @@ -48,13 +49,79 @@ fn main() -> Result<()> { } _ => { eprintln!( - "usage:\n cargo xtask build macos|esp32-p4|esp32-p4-sim\n cargo xtask run macos|esp32-p4-sim [args]\n cargo xtask snapshot esp32-p4-sim" + "usage:\n cargo xtask build macos|agentos-apps|esp32-p4|esp32-p4-sim\n cargo xtask run macos|esp32-p4-sim [args]\n cargo xtask snapshot esp32-p4-sim" ); bail!("unknown xtask command") } } } +fn build_agentos_apps(root: &Path) -> Result<()> { + const POCKETJS_REV: &str = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0"; + let pocketjs = std::env::var_os("POCKETJS_ROOT") + .map(PathBuf::from) + .unwrap_or_else(|| root.parent().unwrap_or(root).join("pocketjs")); + let revision = Command::new("git") + .current_dir(&pocketjs) + .args(["rev-parse", "HEAD"]) + .output() + .with_context(|| format!("inspect PocketJS checkout at {}", pocketjs.display()))?; + let actual = String::from_utf8_lossy(&revision.stdout).trim().to_owned(); + if !revision.status.success() || actual != POCKETJS_REV { + bail!( + "POCKETJS_ROOT={} must be checked out at feat/fs-surface revision {POCKETJS_REV}; found {actual}", + pocketjs.display() + ); + } + install_if_missing(&pocketjs)?; + for app in ["pi-agent", "robinhood", "exa"] { + let app_root = root.join("apps").join(app); + command( + Command::new("bun") + .current_dir(&pocketjs) + .arg("tools/build.ts") + .arg(app_root.join("app.tsx")) + .arg(format!("--outdir={}", app_root.join("dist").display())) + .arg("--framework=solid"), + &format!("building AgentOS App {app}"), + )?; + minify_agentos_bundle(&app_root)?; + let data_entry = app_root.join("data-action.ts"); + if data_entry.is_file() { + command( + Command::new("bun") + .arg("build") + .arg(&data_entry) + .arg(format!( + "--outfile={}", + app_root.join("dist/data-action.js").display() + )) + .arg("--target=browser") + .arg("--format=iife") + .arg("--minify"), + &format!("building AgentOS data action {app}"), + )?; + } + } + Ok(()) +} + +fn minify_agentos_bundle(app_root: &Path) -> Result<()> { + let bundle = app_root.join("dist/app.js"); + let minified = app_root.join("dist/app.min.js"); + command( + Command::new("bun") + .arg("build") + .arg(&bundle) + .arg(format!("--outfile={}", minified.display())) + .arg("--minify"), + &format!("minifying {} for the device image", bundle.display()), + )?; + std::fs::rename(&minified, &bundle) + .with_context(|| format!("replace {} with minified bundle", bundle.display()))?; + Ok(()) +} + fn build_embedded_guest(root: &Path) -> Result<()> { let embedded = root.join("crates/pocket-pi-embedded/js"); install_if_missing(&embedded)?; @@ -63,7 +130,18 @@ fn build_embedded_guest(root: &Path) -> Result<()> { .current_dir(&embedded) .args(["run", "build"]), "building embedded Pi guest", - ) + )?; + let source = embedded.join("pi-agent.bundle.js"); + let destination = root.join("apps/pi-agent/dist/agent.js"); + std::fs::create_dir_all(destination.parent().unwrap())?; + std::fs::copy(&source, &destination).with_context(|| { + format!( + "install Pi Agent loop bundle {} -> {}", + source.display(), + destination.display() + ) + })?; + Ok(()) } fn install_if_missing(directory: &Path) -> Result<()> { From 5f863f1ac36276aaf3dc954c66c5923acc2f2f51 Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Mon, 10 Aug 2026 10:31:37 +0800 Subject: [PATCH 02/24] chore(pocketjs): pin AgentOS to upstream main --- Cargo.lock | 16 +- Cargo.toml | 20 +- apps/README.md | 6 +- apps/exa/dist/app.js | 10 +- apps/pi-agent/dist/app.js | 20 +- apps/robinhood/dist/app.js | 8 +- crates/pocket-pi-agentos/src/lib.rs | 2 +- docs/agentos-architecture.md | 9 +- firmware/esp32-p4/Cargo.lock | 13 +- firmware/esp32-p4/Cargo.toml | 13 +- .../pocketjs_ppa/SOURCE_PROVENANCE.md | 2 +- firmware/esp32-p4/src/bin/sqlite_probe.rs | 253 ------------------ hosts/esp32-p4-sim/Cargo.toml | 4 +- tools/xtask/src/main.rs | 4 +- 14 files changed, 60 insertions(+), 320 deletions(-) delete mode 100644 firmware/esp32-p4/src/bin/sqlite_probe.rs diff --git a/Cargo.lock b/Cargo.lock index ebb0c80..2a517a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2531,7 +2531,7 @@ dependencies = [ [[package]] name = "pocket-db" version = "0.1.0" -source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" dependencies = [ "anyhow", "base64 0.23.1", @@ -2544,7 +2544,7 @@ dependencies = [ [[package]] name = "pocket-fs" version = "0.1.0" -source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" dependencies = [ "anyhow", "base64 0.23.1", @@ -2556,7 +2556,7 @@ dependencies = [ [[package]] name = "pocket-mod" version = "0.1.0" -source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" dependencies = [ "anyhow", "log", @@ -2661,7 +2661,7 @@ dependencies = [ [[package]] name = "pocket-ui-surface" version = "0.1.0" -source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" dependencies = [ "anyhow", "log", @@ -2672,7 +2672,7 @@ dependencies = [ [[package]] name = "pocket-ui-wgpu" version = "0.1.0" -source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" dependencies = [ "anyhow", "bytemuck", @@ -2685,7 +2685,7 @@ dependencies = [ [[package]] name = "pocket3d" version = "0.1.0" -source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" dependencies = [ "anyhow", "bytemuck", @@ -2704,7 +2704,7 @@ dependencies = [ [[package]] name = "pocket3d-bsp" version = "0.1.0" -source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" dependencies = [ "anyhow", "glam", @@ -2714,7 +2714,7 @@ dependencies = [ [[package]] name = "pocketjs-core" version = "0.1.0" -source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" dependencies = [ "taffy", ] diff --git a/Cargo.toml b/Cargo.toml index fac91fd..e384541 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,24 +26,24 @@ serde = { version = "1", default-features = false, features = ["derive", "alloc" serde_json = { version = "1", default-features = false, features = ["alloc"] } [workspace.dependencies.pocketjs-core] -git = "https://github.com/siwei-yuan/pocketjs.git" -rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +git = "https://github.com/pocket-stack/pocketjs.git" +rev = "9c809bbd047ddc75c27caa4990951a78d942477a" [workspace.dependencies.pocket-mod] -git = "https://github.com/siwei-yuan/pocketjs.git" -rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +git = "https://github.com/pocket-stack/pocketjs.git" +rev = "9c809bbd047ddc75c27caa4990951a78d942477a" [workspace.dependencies.pocket-ui-surface] -git = "https://github.com/siwei-yuan/pocketjs.git" -rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +git = "https://github.com/pocket-stack/pocketjs.git" +rev = "9c809bbd047ddc75c27caa4990951a78d942477a" [workspace.dependencies.pocket-db] -git = "https://github.com/siwei-yuan/pocketjs.git" -rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +git = "https://github.com/pocket-stack/pocketjs.git" +rev = "9c809bbd047ddc75c27caa4990951a78d942477a" [workspace.dependencies.pocket-fs] -git = "https://github.com/siwei-yuan/pocketjs.git" -rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +git = "https://github.com/pocket-stack/pocketjs.git" +rev = "9c809bbd047ddc75c27caa4990951a78d942477a" [profile.release] opt-level = 2 diff --git a/apps/README.md b/apps/README.md index ba66db0..92b88da 100644 --- a/apps/README.md +++ b/apps/README.md @@ -8,12 +8,12 @@ firmware as the recovery release, then seeded into `/workspace` on boot. - `robinhood`: curated MCP tools, `refreshPortfolio` AppTask, SQLite and View. - `exa`: Exa search/fetch tools, SQLite search history and View. -Build all three from the pinned FS/DB branch checkout: +Build all three from the pinned upstream PocketJS checkout: ```sh -POCKETJS_ROOT=/path/to/pocketjs-feat-fs-surface cargo xtask build agentos-apps +POCKETJS_ROOT=/path/to/pocketjs-main cargo xtask build agentos-apps ``` The task refuses a checkout other than revision -`afc8d4e8e877dac7f9b0c01b5c0d667642009fc0`, so generated recovery bundles +`9c809bbd047ddc75c27caa4990951a78d942477a`, so generated recovery bundles cannot silently drift from the runtime modules linked into the firmware. diff --git a/apps/exa/dist/app.js b/apps/exa/dist/app.js index 99fbb69..82d0f30 100644 --- a/apps/exa/dist/app.js +++ b/apps/exa/dist/app.js @@ -1,15 +1,15 @@ -(()=>{var FJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return m0(this.context.count)},getNextContextId(){return m0(this.context.count++)}};function m0(J){let Q=String(J),$=Q.length-1;return FJ.context.id+($?String.fromCharCode(96+$):"")+Q}function v0(J){FJ.context=J}function U4(){return{...FJ.context,id:FJ.getNextContextId(),count:0}}var V4=!1,P4=(J,Q)=>J===Q,W0=Symbol("solid-proxy"),R4=typeof Proxy==="function",w4=Symbol("solid-track"),q2=Symbol("solid-dev-component"),gJ={equals:P4},u0=null,D4=a0,E=1,LJ=2,l0={owned:null,cleanups:null,context:null,owner:null},L=null,B=null,IJ=null,KJ=null,I=null,S=null,f=null,TJ=0;function EJ(J,Q){let $=I,Z=L,X=J.length===0,W=Q===void 0?Z:Q,q=X?l0:{owned:null,cleanups:null,context:W?W.context:null,owner:W},G=X?J:()=>J(()=>a(()=>r(q)));L=q,I=null;try{return i(G,!0)}finally{I=$,L=Z}}function kJ(J,Q){Q=Q?Object.assign({},gJ,Q):gJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return i0($,X)};return[c0.bind($),Z]}function s(J,Q,$){let Z=s0(J,Q,!1,E);if(IJ&&B&&B.running)S.push(Z);else NJ(Z)}function MJ(J,Q,$){$=$?Object.assign({},gJ,$):gJ;let Z=s0(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,IJ&&B&&B.running)Z.tState=E,S.push(Z);else NJ(Z);return c0.bind(Z)}function a(J){if(!KJ&&I===null)return J();let Q=I;I=null;try{if(KJ)return KJ.untrack(J);return J()}finally{I=Q}}function Y0(J){if(L===null);else if(L.cleanups===null)L.cleanups=[J];else L.cleanups.push(J);return J}function O4(J){if(B&&B.running)return J(),B.done;let Q=I,$=L;return Promise.resolve().then(()=>{I=Q,L=$;let Z;if(IJ||C4)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return i(J,!1),I=L=null,Z?Z.done:void 0})}var[z2,p0]=kJ(!1),C4;function c0(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===E)NJ(this);else{let Q=S;S=null,i(()=>mJ(this),!1),S=Q}if(I){let Q=this.observers;if(!Q||Q[Q.length-1]!==I){let $=Q?Q.length:0;if(!I.sources)I.sources=[this],I.sourceSlots=[$];else I.sources.push(this),I.sourceSlots.push($);if(!Q)this.observers=[I],this.observerSlots=[I.sources.length-1];else Q.push(I),this.observerSlots.push(I.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function i0(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)i(()=>{for(let X=0;X1e6)throw S=[],Error()},!1)}return Q}function NJ(J){if(!J.fn)return;r(J);let Q=TJ;if(d0(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{i(()=>{B&&(B.running=!0),I=L=J,d0(J,J.tValue,Q),I=L=null},!1)})}function d0(J,Q,$){let Z,X=L,W=I;I=L=J;try{Z=J.fn(Q)}catch(q){if(J.pure)if(B&&B.running)J.tState=E,J.tOwned&&J.tOwned.forEach(r),J.tOwned=void 0;else J.state=E,J.owned&&J.owned.forEach(r),J.owned=null;return J.updatedAt=$+1,z0(q)}finally{I=W,L=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)i0(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function s0(J,Q,$,Z=E,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:L,context:L?L.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(L===null);else if(L!==l0)if(B&&B.running&&L.pure)if(!L.tOwned)L.tOwned=[W];else L.tOwned.push(W);else if(!L.owned)L.owned=[W];else L.owned.push(W);if(KJ&&W.fn){let q=W.fn,[G,M]=kJ(void 0,{equals:!1}),V=KJ.factory(q,M);Y0(()=>V.dispose());let R,H=()=>O4(M).then(()=>{if(R)R.dispose(),R=void 0});W.fn=(k)=>{if(G(),B&&B.running){if(!R)R=KJ.factory(q,H);return R.track(k)}return V.track(k)}}return W}function q0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===LJ)return mJ(J);if(J.suspense&&a(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===E)NJ(J);else if((Q?J.tState:J.state)===LJ){let X=S;S=null,i(()=>mJ(J,$[0]),!1),S=X}}}function i(J,Q){if(S)return J();let $=!1;if(!Q)S=[];if(f)$=!0;else f=[];TJ++;try{let Z=J();return L4($),Z}catch(Z){if(!$)f=null;S=null,z0(Z)}}function L4(J){if(S){if(IJ&&B&&B.running)I4(S);else a0(S);S=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;f.push.apply(f,B.effects),Q=B.resolve;for(let W of f)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,i(()=>{for(let W of X)r(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let q=0,G=W.owned.length;qD4($),!1);if(Q)Q()}function a0(J){for(let Q=0;Q{Z.delete($),i(()=>{B.running=!0,q0($)},!1),B&&(B.running=!1)})}}function mJ(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)r(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)o0(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)r(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function o0(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return Y0(()=>t0(W)),()=>{let M=J()||[],V=M.length,R,H;return M[w4],a(()=>{let _,h,p,$J,HJ,F,j,z,U;if(V===0){if(q!==0)t0(W),W=[],Z=[],X=[],q=0,G&&(G=[]);if($.fallback)Z=[A4],X[0]=EJ((D)=>{return W[0]=D,$.fallback()}),q=1}else if(q===0){X=Array(V);for(H=0;H=F&&z>=F&&Z[j]===M[z];j--,z--)p[z]=X[j],$J[z]=W[j],G&&(HJ[z]=G[j]);_=new Map,h=Array(z+1);for(H=z;H>=F;H--)U=M[H],R=_.get(U),h[H]=R===void 0?-1:R,_.set(U,H);for(R=F;R<=j;R++)if(U=Z[R],H=_.get(U),H!==void 0&&H!==-1)p[H]=X[R],$J[H]=W[R],G&&(HJ[H]=G[R]),H=h[H],_.set(U,H);else W[R]();for(H=F;HJ(Q||{}));return v0($),Z}}return a(()=>J(Q||{}))}function vJ(){return!0}var h4={get(J,Q,$){if(Q===W0)return $;return J.get(Q)},has(J,Q){if(Q===W0)return!0;return J.has(Q)},set:vJ,deleteProperty:vJ,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:vJ,deleteProperty:vJ}},ownKeys(J){return J.keys()}};function G0(J){return!(J=typeof J==="function"?J():J)?{}:J}function x4(){for(let J=0,Q=this.length;J=0;G--){let M=G0(J[G])[q];if(M!==void 0)return M}},has(q){for(let G=J.length-1;G>=0;G--)if(q in G0(J[G]))return!0;return!1},keys(){let q=[];for(let G=0;G=0;q--){let G=J[q];if(!G)continue;let M=Object.getOwnPropertyNames(G);for(let V=M.length-1;V>=0;V--){let R=M[V];if(R==="__proto__"||R==="constructor")continue;let H=Object.getOwnPropertyDescriptor(G,R);if(!Z[R])Z[R]=H.get?{enumerable:!0,configurable:!0,get:x4.bind($[R]=[H.get.bind(G)])}:H.value!==void 0?H:void 0;else{let k=$[R];if(k){if(H.get)k.push(H.get.bind(G));else if(H.value!==void 0)k.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let q=W.length-1;q>=0;q--){let G=W[q],M=Z[G];if(M&&M.get)Object.defineProperty(X,G,M);else X[G]=M?M.value:void 0}return X}var f4=(J)=>`Stale read from <${J}>.`;function b4(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return MJ(S4(()=>J.each,J.children,Q||void 0))}function g4(J){let Q=J.keyed,$=MJ(()=>J.when,void 0,void 0),Z=Q?$:MJ($,void 0,{equals:(X,W)=>!X===!W});return MJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?a(()=>W(Q?X:()=>{if(!a(Z))throw f4("Show");return $()})):W}return J.fallback},void 0,void 0)}var T4=(J)=>MJ(()=>J());function E4({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:q,getParentNode:G,getFirstChild:M,getNextSibling:V}){function R(F,j,z,U){if(z!==void 0&&!U)U=[];if(typeof j!=="function")return H(F,j,U,z);s((D)=>H(F,j(),D,z),U)}function H(F,j,z,U,D){while(typeof z==="function")z=z();if(j===z)return z;let C=typeof j,w=U!==void 0;if(C==="string"||C==="number"){if(C==="number")j=j.toString();if(w){let P=z[0];if(P&&$(P))Z(P,j);else P=Q(j);z=h(F,z,U,P)}else if(z!==""&&typeof z==="string")Z(M(F),z=j);else h(F,z,U,Q(j)),z=j}else if(j==null||C==="boolean")z=h(F,z,U);else if(C==="function")return s(()=>{let P=j();while(typeof P==="function")P=P();z=H(F,P,z,U)}),()=>z;else if(Array.isArray(j)){let P=[];if(k(P,j,D))return s(()=>z=H(F,P,z,U,!0)),()=>z;if(P.length===0){let CJ=h(F,z,U);if(w)return z=CJ}else if(Array.isArray(z))if(z.length===0)p(F,P,U);else _(F,z,P);else if(z==null||z==="")p(F,P);else _(F,w&&z||[M(F)],P);z=P}else{if(Array.isArray(z)){if(w)return z=h(F,z,U,j);h(F,z,null,j)}else if(z==null||z===""||!M(F))X(F,j);else $J(F,j,M(F));z=j}return z}function k(F,j,z){let U=!1;for(let D=0,C=j.length;Dc-P){let Y2=j[w];while(P=0;w--){let P=j[w];if(D!==P){let CJ=G(P)===F;if(!C&&!w)CJ?$J(F,D,P):X(F,D,z);else CJ&&W(F,P)}else C=!0}}else X(F,D,z);return[D]}function p(F,j,z){for(let U=0,D=j.length;Uz.children=H(F,j.children,z.children));return s(()=>j.ref&&j.ref(F)),s(()=>{for(let D in j){if(D==="children"||D==="ref")continue;let C=j[D];if(C===z[D])continue;q(F,D,C,z[D]),z[D]=C}}),z}return{render(F,j){let z;return EJ((U)=>{z=U,R(j,F())}),z},insert:R,spread(F,j,z){if(typeof j==="function")s((U)=>HJ(F,j(),U,z));else HJ(F,j,void 0,z)},createElement:J,createTextNode:Q,insertNode:X,setProp(F,j,z,U){return q(F,j,z,U),z},mergeProps:e0,effect:s,memo:T4,createComponent:y4,use(F,j,z){return a(()=>F(j,z))}}}function N4(J){let Q=E4(J);return Q.mergeProps=e0,Q}var J1=480,Q1=272,ZJ={view:0,text:1,image:2},m4=1,v4=-1,u4={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},K={f32:0,color:1,int:2},l4={width:K.f32,height:K.f32,minW:K.f32,minH:K.f32,maxW:K.f32,maxH:K.f32,paddingT:K.f32,paddingR:K.f32,paddingB:K.f32,paddingL:K.f32,marginT:K.f32,marginR:K.f32,marginB:K.f32,marginL:K.f32,gap:K.f32,flexDir:K.int,justify:K.int,align:K.int,grow:K.f32,shrink:K.f32,basis:K.f32,flexWrap:K.int,posType:K.int,insetT:K.f32,insetR:K.f32,insetB:K.f32,insetL:K.f32,display:K.int,overflow:K.int,zIndex:K.int,hitPass:K.int,bgColor:K.color,gradFrom:K.color,gradTo:K.color,gradDir:K.int,radius:K.f32,opacity:K.f32,borderColor:K.color,borderWidth:K.f32,shadow:K.int,bevelOuterLight:K.color,bevelOuterDark:K.color,bevelInnerLight:K.color,bevelInnerDark:K.color,bevelWidth:K.f32,textColor:K.color,fontSlot:K.int,textAlign:K.int,lineHeight:K.f32,tracking:K.f32,translateX:K.f32,translateY:K.f32,scale:K.f32,rotate:K.f32,scaleX:K.f32,scaleY:K.f32,originX:K.f32,originY:K.f32,rotateX:K.f32,rotateY:K.f32,translateZ:K.f32,perspective:K.f32,arcStart:K.f32,arcSweep:K.f32,arcWidth:K.f32},N={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},p4={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},c4=1,G2=2,H2=1,j2=2,B2=131072,F2=1,K2=262144,M2=1,U2=1,V2=1,P2=2,R2=4,w2=8,D2=16,O2=1,C2=2;function $1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var L2=1,i4=1263551300,d4=1,s4=32,a4=24,v={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},XJ=32896,I2=0.016666666666666666;function Z1(J){return J.__viewport??null}var H0=null;function r4(){return null}function X1(J,Q=r4()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function o4(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return X1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return X1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function n4(J){H0=J}function UJ(){if(!H0)throw Error("PocketJS: host not installed — call render() first");return H0}function y(){return UJ().ops}function t4(J){globalThis.frame=J}function e4(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function J6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return $1($>>>16&255,$>>>8&255,$&255,255);return $1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function Q6(J,Q){let $=l4[J];if(typeof Q==="string"){if($===K.color)return J6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===K.color||$===K.int)return Q>>>0;return Q}var uJ=60,W1=[1,2,3,4,5,6,10,12,15,20,30,60],j0=uJ,o=-1,$6=0,AJ=[];function Z6(J){if(!Number.isFinite(J)||J<=0)return uJ;let Q=W1[0];for(let $ of W1)if(Math.abs($-J)Q.at<=o).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;AJ=AJ.filter((Q)=>Q.at>o);for(let Q of J)Q.cb()}var B0=0.12,lJ=XJ;function q6(J){lJ=J===void 0?XJ:J&65535}function z6(){lJ=XJ}function z1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function H6(){return z1(lJ&255)}var G1=new Set,j6=0;function B6(){G1.clear(),j6=0,z6()}function F6(J){for(let Q of[...G1])Q(J)}var WJ=null,H1=null;function K6(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function j1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function SJ(J){F0();let Q=WJ?WJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return H1.slice(Q.off,Q.off+Q.len)}var _J=null,A=null,YJ=null,pJ=0,qJ=[],M0=[],U0=[];function F1(J){if(_J=J,A=null,YJ=null,pJ=0,qJ.length=0,M0.length=0,U0.length=0,m){if(m.pressTarget=null,m.target=null,m.spriteDirty=!0,m.fresh=!0,m.vw=0,m.tex>=0){let Q=y();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(m.tex),m.tex=-1}}}function U6(J,Q){J.onPress=Q??void 0}function V6(J,Q){if(J.focusable=Q,P1(),!Q&&A===J)g(null)}function g(J){if(YJ&&YJ!==J)zJ(null);A=J,y().setFocus(J?J.id:0)}function zJ(J){if(YJ===J)return;let Q=y();if(YJ)Q.setActive?.(YJ.id,0);if(YJ=J,J)Q.setActive?.(J.id,1)}function V0(){return qJ.length>0?qJ[qJ.length-1]:_J}function P0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;g($[X])}function w6(){if(!A)return null;let J=V0();if(J&&!u(A,J))return null;for(let Q=M0.length-1;Q>=0;Q--){let $=M0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function D6(J){let Q=w6();if(!Q)return!1;let $=[];if(P0(Q.node,$),$.length===0){if(A)g(null);return!0}let Z=Q.columns,X=A?$.indexOf(A):-1;if(X<0)return g(K1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)g($[W]);return!0}function O6(){if(!A)return null;let J=V0();if(J&&!u(A,J))return null;for(let Q=U0.length-1;Q>=0;Q--){let $=U0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function cJ(J){let Q=O6();if(Q&&Q.move(J))return;if(D6(J))return;R6(J)}function M1(){U1(A)}function U1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function iJ(J){zJ(J)}function C6(J){g(J),U1(J)}function u(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function R0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=R0(Q.children[X]);if(W){g(W);return}}let Z=Q;while(Z){if(Z.focusable){g(Z);return}Z=Z.parent}}g(null)}var m=null,V1=0;function P1(){V1++}var I6=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],k6=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function A6(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=I6[Q]>>$&1,X=k6[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,q=X?255:0;J[W]=q,J[W+1]=q,J[W+2]=q,J[W+3]=255}return J}function S6(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=SJ($.image)}catch(q){if(UJ().strict)throw q;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):_6(Q,W),X<0&&UJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(A6(),16,16,p4.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function _6(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&c4)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function dJ(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=dJ($[Z],Q);if(X)return X}return null}var sJ=null;function R1(J){sJ=J}function w1(J){let Q=qJ.length>0?qJ[qJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||u($,Q)))return $;$=$.parent}return null}function D1(J,Q,$){return w1(O1(J,Q,$))}function O1(J,Q,$){if($!==void 0)return $===0?null:dJ(sJ??_J,$);let Z=y(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return dJ(sJ??_J,X(J,Q))}function y6(J,Q,$){let Z=m,X=y();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=Z1(X);if(Z.vw=H?H.w:J1,Z.vh=H?H.h:Q1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)S6(Z,X);let W=G6()*Z.speed,q=H6()*Z.speed;if(Z.dpadSpeed>0&&W===0&&q===0){if(J&v.LEFT)W=-Z.dpadSpeed;if(J&v.RIGHT)W=Z.dpadSpeed;if(J&v.UP)q=-Z.dpadSpeed;if(J&v.DOWN)q=Z.dpadSpeed}let G=Z.fresh;if(W!==0||q!==0){let H=X6()/60,k=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),_=Math.min(Math.max(Z.y+q*H,0),Z.vh-1);if(k!==Z.x||_!==Z.y)Z.x=k,Z.y=_,G=!0}if(G)X.setCursorPos(Z.x,Z.y);let M=(Q|$)&Z.button,V=V1;if(G||M!==0||V!==Z.gen)Z.gen=V,Z.fresh=!1,Z.target=w1(dJ(sJ??_J,X.hitTest(Z.x,Z.y)));let R=Z.target;if(R!==A)g(R);if(Q&Z.button&&R)Z.pressTarget=R;if(Z.pressTarget){if(zJ(R===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=R===Z.pressTarget;if(Z.pressTarget=null,zJ(null),H)M1()}}else if($&Z.button)zJ(null);return!0}function h6(J){let Q=J&~pJ,$=pJ&~J;if(pJ=J,m&&y6(J,Q,$))return;if($&v.CIRCLE)zJ(null);if(Q===0)return;if(Q&v.DOWN)cJ("down");if(Q&v.RIGHT)cJ("right");if(Q&v.UP)cJ("up");if(Q&v.LEFT)cJ("left");if(Q&v.CIRCLE)zJ(A),M1()}var w0=null;function C1(J){w0=J}function VJ(){if(P1(),w0)w0()}function x6(J,Q){J.debugName=Q||void 0,VJ()}var n={id:m4,type:ZJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},L1=Symbol.for("pocketjs.native-node"),D0=1,yJ=3,d=8,f6=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function aJ(J){return J.domAttrs??={}}function I1(J,Q){let $=J.domNodeType??(hJ(J)?yJ:D0),Z=$===yJ?rJ(J.text??""):$===d?T6(J.domData??""):x1(J.domTag??nJ(J));for(let X of Object.keys(J.domAttrs??{}))O0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)t(Z,I1(X,!0));return Z}function O0(J,Q,$){if(f6.has(Q)){RJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete aJ(J)[Q];else aJ(J)[Q]=$}function C0(J){if(J[L1]===!0)return J;return Object.defineProperty(J,L1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(hJ(J)?yJ:D0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else oJ(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else oJ(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===d)return J.domData??"";if(hJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===d)J.domData=Z;else if(hJ(J))oJ(J,Z);else if(p6(J),Z)t(J,rJ(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return b1(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??nJ(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===yJ)return"#text";if(J.domNodeType===d)return"#comment";return(J.domTag??nJ(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){RJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===n)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return t(J,$),$},insertBefore($,Z){return t(J,$,Z??null),$},removeChild($){return xJ(J,$),$},replaceChild($,Z){return t(J,$,Z),xJ(J,Z),Z},cloneNode($=!1){return I1(J,!!$)},remove(){if(J.parent)xJ(J.parent,J)},setAttribute($,Z){O0(J,$,Z)},removeAttribute($){O0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}C0(n);var L0=null;function b6(J){L0=J}var I0={unknownClass:0,unknownTexture:0},k1=new Map;function A1(J,Q){k1.set(J,Q)}var S1=new Map;function _1(J,Q){S1.set(J,Q)}var PJ=new Set,g6=new Set;function y1(J){if(!J)return!1;if(g6.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return C0({id:y().createNode(Q),type:Q,parent:null,children:[],domNodeType:D0,domTag:J})}function rJ(J){let Q=y(),$=Q.createNode(ZJ.text);return Q.setText($,J),C0({id:$,type:ZJ.text,parent:null,children:[],text:J,domNodeType:yJ,domTag:"#text"})}function T6(J=""){let Q=rJ("");return Q.domNodeType=d,Q.domTag="#comment",Q.domData=J,Q}function oJ(J,Q){y().replaceText(J.id,Q),J.text=Q,VJ()}function hJ(J){return J.type===ZJ.text}function f1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function t(J,Q,$){let Z=y();if(f1(Q),PJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,VJ()}function xJ(J,Q){if(!Q)return;L6(Q),y().removeChild(J.id,Q.id),f1(Q),PJ.add(Q),VJ()}function E6(J){return J.parent??void 0}function N6(J){return J.children[0]}function b1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function m6(J,Q){let $=y();if(VJ(),Q==null||Q===""){$.setStyle(J.id,v4);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=L0?L0(Q):void 0;if(Z===void 0){if(UJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);I0.unknownClass++;return}$.setStyle(J.id,Z)}function v6(J,Q){let $=y();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=k1.get(Q);if(Z===void 0){if(UJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);I0.unknownTexture++;return}$.setImage(J.id,Z)}function u6(J,Q){let $=y();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=S1.get(Q);if(Z===void 0){if(UJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);I0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function l6(J,Q,$){let Z=y(),X=Q??{},W=$??{},q=!1;for(let G in X){let M=X[G];if(W[G]===M)continue;let V=u4[G];if(V===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,V,Q6(G,M)),q=!0}if(q)VJ()}function RJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete aJ(J)[Q];else aJ(J)[Q]=$;switch(Q){case"class":return m6(J,$),$;case"onPress":case"on:press":return U6(J,$),$;case"src":return v6(J,$),$;case"sprite":return u6(J,$),$;case"style":return l6(J,$,Z),$;case"focusable":return V6(J,!!$),$;case"debugName":return x6(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${nJ(J)}>`)}function p6(J){for(let Q of[...J.children])xJ(J,Q)}function nJ(J){for(let Q of Object.keys(ZJ))if(ZJ[Q]===J.type)return Q;return String(J.type)}function c6(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}RJ(J,Q,$,Z)}var i6=N4({createElement:x1,createTextNode:rJ,replaceText:oJ,isTextNode:hJ,setProperty:c6,insertNode(J,Q,$){t(J,Q,$)},removeNode(J,Q){xJ(J,Q)},getParentNode:E6,getFirstChild:N6,getNextSibling:b1}),{render:d6,effect:k2,memo:s6,createComponent:O,createElement:g1,insert:A2,spread:a6,mergeProps:S2,use:_2}=i6,y2={linear:N.Easing.Linear,in:N.Easing.EaseIn,out:N.Easing.EaseOut,"in-out":N.Easing.EaseInOut,"out-back":N.Easing.OutBack,spring:N.Easing.Spring,"spring-bouncy":N.Easing.SpringBouncy},r6=null;function T1(J){r6=J}function o6(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function E1(J,Q){let $=g1(J);return a6($,Q,!1),o6(Q.nodeRef,$),$}function T(J){return E1("view",J)}function x(J){return E1("text",J)}var h2=new WeakMap,x2=new WeakMap,n6={}!==null?Object.freeze({...{}}):Object.freeze({}),f2=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:n6}),b2=new Map,e=36000,k0=30,t6=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(e),tapeAnalog:new Uint16Array(e),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-k0,saidHello:!1,hostCalls:0};function e6(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-k0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)C1(()=>{Y.treeDirty=!0}),q8();else C1(null);globalThis.__pocketDevtools=G8}function J8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)$8(),W8();let W=Q,q=$===void 0?XJ:$&65535,G=Z,M=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(e).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==XJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function v1(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,q]of J)Z.fill(W,X,Math.min(X+q,$)),X+=q;return Z}function u1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return v1(J.masks,0,Q)}function l1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return v1(J.analog??[],XJ,Q)}function p1(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,b({t:"hello",app:Y.app,host:z8(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` -`))if(X.trim())Z8(X)}}function Z8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)b({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),A0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),A0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":c1();break;case"eval":{let Z=!0,X;try{X=tJ((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}b({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":b({t:"tape",tape:m1()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}b({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())b({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else b({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=u1(Z),Y.replayAnalog=Z.analog?l1(Z):null,Y.replayTouch=Z.touch?p1(Z):null,Y.replayAt=0;break}default:break}}function X8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=k0)c1();if(Y.frame%t6===0)A0()}function W8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,b({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,b({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function A0(){b({t:"stats",frame:Y.frame,nodes:s1(n),tapeLen:Y.tapeLen,paused:Y.paused})}function c1(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,b({t:"tree",frame:Y.frame,root:d1(n)})}function Y8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function S0(J,Q){if(Array.isArray(J)){for(let $ of J)S0($,Q);return}if(Y8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)S0($,Q)}}function i1(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)S0(Z,Q)}function d1(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(i1(J,(X)=>{if(X.domNodeType===8)return;Z.push(d1(X))}),Z.length)Q.k=Z;return Q}function s1(J){let Q=1;return i1(J,($)=>{Q+=s1($)}),Q}function q8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{b({t:"log",level:$,args:X.map((W)=>tJ(W))}),Z?.apply(Q,X)}}}function tJ(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?a1(W):JSON.stringify(a1(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((q)=>tJ(q,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,q])=>`${W}: ${tJ(q,Q+1)}`).join(", ")}}`}function a1(J){return J.length>200?J.slice(0,199)+"…":J}function z8(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var G8={get frame(){return Y.frame},dumpTape:()=>m1(),replay:(J)=>{Y.replayMasks=u1(J),Y.replayAnalog=J.analog?l1(J):null,Y.replayTouch=J.touch?p1(J):null,Y.replayAt=0}},r1=new Map,_0=new Map;function o1(J){return J.trim().replace(/\s+/g," ")}function n1(J){return J.split(" ").sort().join(" ")}var t1=-1;function H8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=o1(Q);r1.set(Z,$);let X=n1(Z),W=_0.get(X);_0.set(X,W!==void 0&&W!==$?t1:$)}}function j8(J){let Q=o1(J),$=r1.get(Q);if($!==void 0)return $;let Z=_0.get(n1(Q));return Z===t1?void 0:Z}var y0=9,B8=(1<{let X=($&K8)!==0,W=X?h0:y0,q=X?M8:B8;return Object.freeze({id:$>>>(X?U8:F8)&255,x:$&q,y:$>>>W&q,hit:Q?.[Z]})}))}function P8(){return eJ}function R8(){eJ=x0}var e1=8,JJ=8,w8=3,D8=8,O8=6,C8=0.5,l=1,fJ=2,f0=4,GJ=8,wJ=[],J4=0,J0=0,QJ=Array.from({length:e1},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(JJ),histY:new Int16Array(JJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function L8(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function I8(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=O1(Q,$,Z.fact);let G=Z.hit;if(G)return L8(G,W)}let q=X.rect?.();if(!q)return!1;return Q>=q.x&&Q=q.y&&$=0;q--){let G=wJ[q];if(G.disposed)continue;if(J4>0&&!G.opts.allowWhenBlocked)continue;if(!I8(G,$,Z,W))continue;G.flags[J.slot]=l,J.owners.push(G)}for(let q of J.owners)q.opts.onDown?.(J)}function S8(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%JJ,J.histLenq||Z>q))X.flags[J.slot]|=fJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&l)||W&(fJ|f0))continue;if(!X.opts.onLongPress)continue;let q=Math.max(1,Math.round((X.opts.longPressSeconds??C8)*Y1()));if(J.frames=0)wJ.splice($,1)},cancel(){if(!Q.disposed)Z4(Q)},get panning(){for(let $ of QJ)if($.used&&Q.flags[$.slot]&GJ)return!0;return!1}}}function f8(J){let Q=x8(J);return Y0(()=>Q.dispose()),Q}function X4(){wJ.length=0,J4=0,J0=0;for(let J of QJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function b8(){return f8({onDown:(J)=>{let Q=D1(J.x,J.y,J.hit);if(Q)iJ(Q)},onTap:(J)=>{iJ(null);let Q=D1(J.x,J.y,J.hit);if(Q)C6(Q)},onUp:()=>iJ(null),onCancel:()=>iJ(null)})}var g8=1,b0=new Map,Q0=[];function T8(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function E8(){g8=1,b0.clear(),Q0=[]}function N8(){if(Q0.length===0)return;let J=Q0;Q0=[];for(let{id:Q,result:$}of J){let Z=b0.get(Q);if(!Z)continue;b0.delete(Q),T8()?.({t:"delivery",frame:q1(),id:Q,kind:Z.kind}),Z.onResult($)}}var m8={"flex-col w-full h-full bg-slate-50":0,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":1,"flex-row items-center gap-4":2,"text-2xl text-white":3,"flex-col":4,"text-sm text-indigo-300 tracking-wide":5,"text-2xl text-white font-bold":6,"px-3 py-2 bg-indigo-900":7,"text-sm text-indigo-200":8,"p-6 flex-col gap-3":9,"text-sm text-indigo-700 font-bold":10,"text-2xl text-slate-950 font-bold":11,"text-base text-slate-600":12,"grow px-6 pt-4 flex-col gap-3":13,"h-[430] px-12 flex-col items-center justify-center bg-white":14,"w-[88] h-[88] items-center justify-center bg-indigo-100":15,"text-2xl text-indigo-700 font-bold":16,"pt-7 text-xl text-slate-900 font-bold":17,"pt-4 text-base text-slate-500":18,"h-[118] px-5 flex-row items-center justify-between bg-white":19,"w-[500] flex-col gap-2":20,"text-base text-slate-900 font-bold":21,"text-sm text-slate-500":22,"text-sm text-indigo-600 font-bold":23,"px-3 py-2 bg-emerald-100":24,"px-3 py-2 bg-red-100":25,"text-sm text-emerald-700":26,"text-sm text-red-500":27,"h-[96] px-6 flex-row items-center bg-slate-950":28,"text-sm text-slate-300":29,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":30,"absolute inset-0 z-50 flex-col items-center justify-center":31,"absolute inset-0 bg-slate-950":32,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":33,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":34,"flex-row flex-wrap":35,grow:36};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var v8="ui:styles",u8="ui:font.",W4="ui:img.",Y4="ui:sprite.";function l8(){return globalThis.ui}function p8(J){if(J.__textures)return;for(let Q of K0(W4)){let $=SJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)A1(Q.slice(W4.length),Z)}}function c8(J){if(J.__sprites)return;for(let Q of K0(Y4)){let $=SJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),q=$[4],G=Z.getUint16(6,!0),M=Z.getUint16(8,!0),V=Z.getUint16(10,!0),R=J.uploadTexture($.subarray(16),X,W,q);if(R>=0)_1(Q.slice(Y4.length),{handle:R,frames:G,cols:M,step:V})}}function q4(J){let Q=g1("view");return RJ(Q,"style",J,void 0),Q}var $0=null,Z0=null;function i8(J,Q){if(!$0||!Z0)return;RJ($0,"style",{width:J,height:Q,overflow:N.Overflow.Hidden},void 0),RJ(Z0,"style",{width:J,height:Q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=y();$.__viewport={w:J,h:Q}}function d8(J,Q={}){let $=o4(Q.ops);if(n4($),b6(j8),Q.styles)H8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let k in Z)A1(k,Z[k]);let H=$.ops.__sprites;if(H)for(let k in H)_1(k,H[k])}if($.kind==="injected"||Z===void 0){if(Q.pak)B1(Q.pak);if(M6()){for(let H of K0())if(H===v8)$.ops.loadStyles?.(SJ(H));else if(H.startsWith(u8))$.ops.loadFontAtlas?.(SJ(H))}}let X=Z1($.ops),W=X?.w??J1,q=X?.h??Q1,G=q4({width:W,height:q,overflow:N.Overflow.Hidden}),M=q4({width:W,height:q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});t(n,G),t(n,M),T1(M),$0=G,Z0=M,F1(G),R1(n),B6(),X4(),b8(),W6(),E8(),e6($.ops),t4(J8((H,k,_,h)=>{Y6(),q6(k),V8(_,h),N8(),h8(),F6(H),h6(H),h1()}));let V=d6(J,G),R=e4(i8);return()=>{R(),R8(),X4(),V(),F1(null),R1(null),T1(null),$0=null,Z0=null;for(let H of n.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);h1()}}function s8(J,Q={}){let $=Q.ops??l8();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)B1(Q.pak);return p8($),c8($),d8(J,{ops:$,styles:Q.styles??m8,pak:Q.pak})}var z4="$b",a8=9007199254740991,r8=":memory:",DJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function o8(J){let Q="";for(let $=0;$>2]+DJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2>16,Z<$.length)$[Z++]=W>>8&255;if(Z<$.length)$[Z++]=W&255}return $}function t8(){let J=globalThis.db;if(!J||typeof J!=="object")return null;return typeof J.open==="function"?J:null}function G4(J){if(J instanceof Uint8Array)return{[z4]:o8(J)};if(typeof J==="number"&&!Number.isFinite(J))throw Error("db: cannot bind a non-finite number");if(typeof J==="number"&&Number.isInteger(J)&&Math.abs(J)>a8)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function e8(J){if(J!==null&&typeof J==="object")return n8(J[z4]);return J}function J2(J){if(Array.isArray(J))return JSON.stringify(J.map(G4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=G4(Z);return JSON.stringify(Q)}class g0{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,J2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=H4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(e8))}run(...J){let Q=this.execute(H4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function H4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class j4{statements=new Map;txDepth=0;constructor(J=r8){let Q=t8();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new g0(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new g0(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let q=J(...Q);return this.txDepth--,this.exec(X),q}catch(q){throw this.txDepth--,this.exec(W),q}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var B4=3,OJ=new j4("exa"),[F4,T0]=kJ([]),[Q2,E0]=kJ("SEARCH HISTORY IS LOCAL"),X0=-1;function $2(J){try{return JSON.parse(J)}catch{return null}}function Z2(J){let Q=new Date(J*1000).toISOString();return Q.slice(0,10)+" · "+Q.slice(11,16)+" UTC"}function K4(J){if(X0===J)return;try{let Q=OJ.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==B4){T0([]),E0("SEARCH HISTORY IS LOCAL");return}let $=OJ.query(` +(()=>{var FJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return m0(this.context.count)},getNextContextId(){return m0(this.context.count++)}};function m0(J){let Q=String(J),$=Q.length-1;return FJ.context.id+($?String.fromCharCode(96+$):"")+Q}function v0(J){FJ.context=J}function V4(){return{...FJ.context,id:FJ.getNextContextId(),count:0}}var P4=!1,R4=(J,Q)=>J===Q,W0=Symbol("solid-proxy"),w4=typeof Proxy==="function",D4=Symbol("solid-track"),G2=Symbol("solid-dev-component"),gJ={equals:R4},u0=null,O4=a0,E=1,LJ=2,l0={owned:null,cleanups:null,context:null,owner:null},L=null,B=null,IJ=null,KJ=null,I=null,S=null,f=null,TJ=0;function EJ(J,Q){let $=I,Z=L,X=J.length===0,W=Q===void 0?Z:Q,q=X?l0:{owned:null,cleanups:null,context:W?W.context:null,owner:W},G=X?J:()=>J(()=>a(()=>r(q)));L=q,I=null;try{return i(G,!0)}finally{I=$,L=Z}}function kJ(J,Q){Q=Q?Object.assign({},gJ,Q):gJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return i0($,X)};return[c0.bind($),Z]}function s(J,Q,$){let Z=s0(J,Q,!1,E);if(IJ&&B&&B.running)S.push(Z);else NJ(Z)}function MJ(J,Q,$){$=$?Object.assign({},gJ,$):gJ;let Z=s0(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,IJ&&B&&B.running)Z.tState=E,S.push(Z);else NJ(Z);return c0.bind(Z)}function a(J){if(!KJ&&I===null)return J();let Q=I;I=null;try{if(KJ)return KJ.untrack(J);return J()}finally{I=Q}}function Y0(J){if(L===null);else if(L.cleanups===null)L.cleanups=[J];else L.cleanups.push(J);return J}function C4(J){if(B&&B.running)return J(),B.done;let Q=I,$=L;return Promise.resolve().then(()=>{I=Q,L=$;let Z;if(IJ||L4)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return i(J,!1),I=L=null,Z?Z.done:void 0})}var[H2,p0]=kJ(!1),L4;function c0(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===E)NJ(this);else{let Q=S;S=null,i(()=>mJ(this),!1),S=Q}if(I){let Q=this.observers;if(!Q||Q[Q.length-1]!==I){let $=Q?Q.length:0;if(!I.sources)I.sources=[this],I.sourceSlots=[$];else I.sources.push(this),I.sourceSlots.push($);if(!Q)this.observers=[I],this.observerSlots=[I.sources.length-1];else Q.push(I),this.observerSlots.push(I.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function i0(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)i(()=>{for(let X=0;X1e6)throw S=[],Error()},!1)}return Q}function NJ(J){if(!J.fn)return;r(J);let Q=TJ;if(d0(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{i(()=>{B&&(B.running=!0),I=L=J,d0(J,J.tValue,Q),I=L=null},!1)})}function d0(J,Q,$){let Z,X=L,W=I;I=L=J;try{Z=J.fn(Q)}catch(q){if(J.pure)if(B&&B.running)J.tState=E,J.tOwned&&J.tOwned.forEach(r),J.tOwned=void 0;else J.state=E,J.owned&&J.owned.forEach(r),J.owned=null;return J.updatedAt=$+1,z0(q)}finally{I=W,L=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)i0(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function s0(J,Q,$,Z=E,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:L,context:L?L.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(L===null);else if(L!==l0)if(B&&B.running&&L.pure)if(!L.tOwned)L.tOwned=[W];else L.tOwned.push(W);else if(!L.owned)L.owned=[W];else L.owned.push(W);if(KJ&&W.fn){let q=W.fn,[G,M]=kJ(void 0,{equals:!1}),V=KJ.factory(q,M);Y0(()=>V.dispose());let R,H=()=>C4(M).then(()=>{if(R)R.dispose(),R=void 0});W.fn=(k)=>{if(G(),B&&B.running){if(!R)R=KJ.factory(q,H);return R.track(k)}return V.track(k)}}return W}function q0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===LJ)return mJ(J);if(J.suspense&&a(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===E)NJ(J);else if((Q?J.tState:J.state)===LJ){let X=S;S=null,i(()=>mJ(J,$[0]),!1),S=X}}}function i(J,Q){if(S)return J();let $=!1;if(!Q)S=[];if(f)$=!0;else f=[];TJ++;try{let Z=J();return I4($),Z}catch(Z){if(!$)f=null;S=null,z0(Z)}}function I4(J){if(S){if(IJ&&B&&B.running)k4(S);else a0(S);S=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;f.push.apply(f,B.effects),Q=B.resolve;for(let W of f)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,i(()=>{for(let W of X)r(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let q=0,G=W.owned.length;qO4($),!1);if(Q)Q()}function a0(J){for(let Q=0;Q{Z.delete($),i(()=>{B.running=!0,q0($)},!1),B&&(B.running=!1)})}}function mJ(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)r(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)o0(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)r(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function o0(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return Y0(()=>t0(W)),()=>{let M=J()||[],V=M.length,R,H;return M[D4],a(()=>{let _,h,p,$J,HJ,F,j,z,U;if(V===0){if(q!==0)t0(W),W=[],Z=[],X=[],q=0,G&&(G=[]);if($.fallback)Z=[S4],X[0]=EJ((D)=>{return W[0]=D,$.fallback()}),q=1}else if(q===0){X=Array(V);for(H=0;H=F&&z>=F&&Z[j]===M[z];j--,z--)p[z]=X[j],$J[z]=W[j],G&&(HJ[z]=G[j]);_=new Map,h=Array(z+1);for(H=z;H>=F;H--)U=M[H],R=_.get(U),h[H]=R===void 0?-1:R,_.set(U,H);for(R=F;R<=j;R++)if(U=Z[R],H=_.get(U),H!==void 0&&H!==-1)p[H]=X[R],$J[H]=W[R],G&&(HJ[H]=G[R]),H=h[H],_.set(U,H);else W[R]();for(H=F;HJ(Q||{}));return v0($),Z}}return a(()=>J(Q||{}))}function vJ(){return!0}var x4={get(J,Q,$){if(Q===W0)return $;return J.get(Q)},has(J,Q){if(Q===W0)return!0;return J.has(Q)},set:vJ,deleteProperty:vJ,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:vJ,deleteProperty:vJ}},ownKeys(J){return J.keys()}};function G0(J){return!(J=typeof J==="function"?J():J)?{}:J}function f4(){for(let J=0,Q=this.length;J=0;G--){let M=G0(J[G])[q];if(M!==void 0)return M}},has(q){for(let G=J.length-1;G>=0;G--)if(q in G0(J[G]))return!0;return!1},keys(){let q=[];for(let G=0;G=0;q--){let G=J[q];if(!G)continue;let M=Object.getOwnPropertyNames(G);for(let V=M.length-1;V>=0;V--){let R=M[V];if(R==="__proto__"||R==="constructor")continue;let H=Object.getOwnPropertyDescriptor(G,R);if(!Z[R])Z[R]=H.get?{enumerable:!0,configurable:!0,get:f4.bind($[R]=[H.get.bind(G)])}:H.value!==void 0?H:void 0;else{let k=$[R];if(k){if(H.get)k.push(H.get.bind(G));else if(H.value!==void 0)k.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let q=W.length-1;q>=0;q--){let G=W[q],M=Z[G];if(M&&M.get)Object.defineProperty(X,G,M);else X[G]=M?M.value:void 0}return X}var b4=(J)=>`Stale read from <${J}>.`;function g4(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return MJ(_4(()=>J.each,J.children,Q||void 0))}function T4(J){let Q=J.keyed,$=MJ(()=>J.when,void 0,void 0),Z=Q?$:MJ($,void 0,{equals:(X,W)=>!X===!W});return MJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?a(()=>W(Q?X:()=>{if(!a(Z))throw b4("Show");return $()})):W}return J.fallback},void 0,void 0)}var E4=(J)=>MJ(()=>J());function N4({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:q,getParentNode:G,getFirstChild:M,getNextSibling:V}){function R(F,j,z,U){if(z!==void 0&&!U)U=[];if(typeof j!=="function")return H(F,j,U,z);s((D)=>H(F,j(),D,z),U)}function H(F,j,z,U,D){while(typeof z==="function")z=z();if(j===z)return z;let C=typeof j,w=U!==void 0;if(C==="string"||C==="number"){if(C==="number")j=j.toString();if(w){let P=z[0];if(P&&$(P))Z(P,j);else P=Q(j);z=h(F,z,U,P)}else if(z!==""&&typeof z==="string")Z(M(F),z=j);else h(F,z,U,Q(j)),z=j}else if(j==null||C==="boolean")z=h(F,z,U);else if(C==="function")return s(()=>{let P=j();while(typeof P==="function")P=P();z=H(F,P,z,U)}),()=>z;else if(Array.isArray(j)){let P=[];if(k(P,j,D))return s(()=>z=H(F,P,z,U,!0)),()=>z;if(P.length===0){let CJ=h(F,z,U);if(w)return z=CJ}else if(Array.isArray(z))if(z.length===0)p(F,P,U);else _(F,z,P);else if(z==null||z==="")p(F,P);else _(F,w&&z||[M(F)],P);z=P}else{if(Array.isArray(z)){if(w)return z=h(F,z,U,j);h(F,z,null,j)}else if(z==null||z===""||!M(F))X(F,j);else $J(F,j,M(F));z=j}return z}function k(F,j,z){let U=!1;for(let D=0,C=j.length;Dc-P){let z2=j[w];while(P=0;w--){let P=j[w];if(D!==P){let CJ=G(P)===F;if(!C&&!w)CJ?$J(F,D,P):X(F,D,z);else CJ&&W(F,P)}else C=!0}}else X(F,D,z);return[D]}function p(F,j,z){for(let U=0,D=j.length;Uz.children=H(F,j.children,z.children));return s(()=>j.ref&&j.ref(F)),s(()=>{for(let D in j){if(D==="children"||D==="ref")continue;let C=j[D];if(C===z[D])continue;q(F,D,C,z[D]),z[D]=C}}),z}return{render(F,j){let z;return EJ((U)=>{z=U,R(j,F())}),z},insert:R,spread(F,j,z){if(typeof j==="function")s((U)=>HJ(F,j(),U,z));else HJ(F,j,void 0,z)},createElement:J,createTextNode:Q,insertNode:X,setProp(F,j,z,U){return q(F,j,z,U),z},mergeProps:e0,effect:s,memo:E4,createComponent:h4,use(F,j,z){return a(()=>F(j,z))}}}function m4(J){let Q=N4(J);return Q.mergeProps=e0,Q}var J1=480,Q1=272,ZJ={view:0,text:1,image:2},v4=1,u4=-1,l4={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},K={f32:0,color:1,int:2},p4={width:K.f32,height:K.f32,minW:K.f32,minH:K.f32,maxW:K.f32,maxH:K.f32,paddingT:K.f32,paddingR:K.f32,paddingB:K.f32,paddingL:K.f32,marginT:K.f32,marginR:K.f32,marginB:K.f32,marginL:K.f32,gap:K.f32,flexDir:K.int,justify:K.int,align:K.int,grow:K.f32,shrink:K.f32,basis:K.f32,flexWrap:K.int,posType:K.int,insetT:K.f32,insetR:K.f32,insetB:K.f32,insetL:K.f32,display:K.int,overflow:K.int,zIndex:K.int,hitPass:K.int,bgColor:K.color,gradFrom:K.color,gradTo:K.color,gradDir:K.int,radius:K.f32,opacity:K.f32,borderColor:K.color,borderWidth:K.f32,shadow:K.int,bevelOuterLight:K.color,bevelOuterDark:K.color,bevelInnerLight:K.color,bevelInnerDark:K.color,bevelWidth:K.f32,textColor:K.color,fontSlot:K.int,textAlign:K.int,lineHeight:K.f32,tracking:K.f32,translateX:K.f32,translateY:K.f32,scale:K.f32,rotate:K.f32,scaleX:K.f32,scaleY:K.f32,originX:K.f32,originY:K.f32,rotateX:K.f32,rotateY:K.f32,translateZ:K.f32,perspective:K.f32,arcStart:K.f32,arcSweep:K.f32,arcWidth:K.f32},N={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},c4={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},i4=1,j2=2,B2=1,F2=2,K2=131072,M2=1,U2=262144,V2=1,P2=1,R2=1,w2=2,D2=4,O2=8,C2=16,L2=1,I2=2;function $1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var k2=1,d4=1263551300,s4=1,a4=32,r4=24,v={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},XJ=32896,A2=0.016666666666666666;function Z1(J){return J.__viewport??null}var H0=null;function o4(){return null}function X1(J,Q=o4()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function n4(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return X1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return X1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function t4(J){H0=J}function UJ(){if(!H0)throw Error("PocketJS: host not installed — call render() first");return H0}function y(){return UJ().ops}function e4(J){globalThis.frame=J}function J6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function Q6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return $1($>>>16&255,$>>>8&255,$&255,255);return $1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function $6(J,Q){let $=p4[J];if(typeof Q==="string"){if($===K.color)return Q6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===K.color||$===K.int)return Q>>>0;return Q}var uJ=60,W1=[1,2,3,4,5,6,10,12,15,20,30,60],j0=uJ,o=-1,Z6=0,AJ=[];function X6(J){if(!Number.isFinite(J)||J<=0)return uJ;let Q=W1[0];for(let $ of W1)if(Math.abs($-J)Q.at<=o).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;AJ=AJ.filter((Q)=>Q.at>o);for(let Q of J)Q.cb()}var B0=0.12,lJ=XJ;function z6(J){lJ=J===void 0?XJ:J&65535}function G6(){lJ=XJ}function z1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function j6(){return z1(lJ&255)}var G1=new Set,B6=0;function F6(){G1.clear(),B6=0,G6()}function K6(J){for(let Q of[...G1])Q(J)}var WJ=null,H1=null;function M6(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function j1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function SJ(J){F0();let Q=WJ?WJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return H1.slice(Q.off,Q.off+Q.len)}var _J=null,A=null,YJ=null,pJ=0,qJ=[],M0=[],U0=[];function F1(J){if(_J=J,A=null,YJ=null,pJ=0,qJ.length=0,M0.length=0,U0.length=0,m){if(m.pressTarget=null,m.target=null,m.spriteDirty=!0,m.fresh=!0,m.vw=0,m.tex>=0){let Q=y();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(m.tex),m.tex=-1}}}function V6(J,Q){J.onPress=Q??void 0}function P6(J,Q){if(J.focusable=Q,P1(),!Q&&A===J)g(null)}function g(J){if(YJ&&YJ!==J)zJ(null);A=J,y().setFocus(J?J.id:0)}function zJ(J){if(YJ===J)return;let Q=y();if(YJ)Q.setActive?.(YJ.id,0);if(YJ=J,J)Q.setActive?.(J.id,1)}function V0(){return qJ.length>0?qJ[qJ.length-1]:_J}function P0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;g($[X])}function D6(){if(!A)return null;let J=V0();if(J&&!u(A,J))return null;for(let Q=M0.length-1;Q>=0;Q--){let $=M0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function O6(J){let Q=D6();if(!Q)return!1;let $=[];if(P0(Q.node,$),$.length===0){if(A)g(null);return!0}let Z=Q.columns,X=A?$.indexOf(A):-1;if(X<0)return g(K1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)g($[W]);return!0}function C6(){if(!A)return null;let J=V0();if(J&&!u(A,J))return null;for(let Q=U0.length-1;Q>=0;Q--){let $=U0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function cJ(J){let Q=C6();if(Q&&Q.move(J))return;if(O6(J))return;w6(J)}function M1(){U1(A)}function U1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function iJ(J){zJ(J)}function L6(J){g(J),U1(J)}function u(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function R0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=R0(Q.children[X]);if(W){g(W);return}}let Z=Q;while(Z){if(Z.focusable){g(Z);return}Z=Z.parent}}g(null)}var m=null,V1=0;function P1(){V1++}var k6=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],A6=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function S6(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=k6[Q]>>$&1,X=A6[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,q=X?255:0;J[W]=q,J[W+1]=q,J[W+2]=q,J[W+3]=255}return J}function _6(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=SJ($.image)}catch(q){if(UJ().strict)throw q;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):y6(Q,W),X<0&&UJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(S6(),16,16,c4.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function y6(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&i4)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function dJ(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=dJ($[Z],Q);if(X)return X}return null}var sJ=null;function R1(J){sJ=J}function w1(J){let Q=qJ.length>0?qJ[qJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||u($,Q)))return $;$=$.parent}return null}function D1(J,Q,$){return w1(O1(J,Q,$))}function O1(J,Q,$){if($!==void 0)return $===0?null:dJ(sJ??_J,$);let Z=y(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return dJ(sJ??_J,X(J,Q))}function h6(J,Q,$){let Z=m,X=y();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=Z1(X);if(Z.vw=H?H.w:J1,Z.vh=H?H.h:Q1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)_6(Z,X);let W=H6()*Z.speed,q=j6()*Z.speed;if(Z.dpadSpeed>0&&W===0&&q===0){if(J&v.LEFT)W=-Z.dpadSpeed;if(J&v.RIGHT)W=Z.dpadSpeed;if(J&v.UP)q=-Z.dpadSpeed;if(J&v.DOWN)q=Z.dpadSpeed}let G=Z.fresh;if(W!==0||q!==0){let H=W6()/60,k=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),_=Math.min(Math.max(Z.y+q*H,0),Z.vh-1);if(k!==Z.x||_!==Z.y)Z.x=k,Z.y=_,G=!0}if(G)X.setCursorPos(Z.x,Z.y);let M=(Q|$)&Z.button,V=V1;if(G||M!==0||V!==Z.gen)Z.gen=V,Z.fresh=!1,Z.target=w1(dJ(sJ??_J,X.hitTest(Z.x,Z.y)));let R=Z.target;if(R!==A)g(R);if(Q&Z.button&&R)Z.pressTarget=R;if(Z.pressTarget){if(zJ(R===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=R===Z.pressTarget;if(Z.pressTarget=null,zJ(null),H)M1()}}else if($&Z.button)zJ(null);return!0}function x6(J){let Q=J&~pJ,$=pJ&~J;if(pJ=J,m&&h6(J,Q,$))return;if($&v.CIRCLE)zJ(null);if(Q===0)return;if(Q&v.DOWN)cJ("down");if(Q&v.RIGHT)cJ("right");if(Q&v.UP)cJ("up");if(Q&v.LEFT)cJ("left");if(Q&v.CIRCLE)zJ(A),M1()}var w0=null;function C1(J){w0=J}function VJ(){if(P1(),w0)w0()}function f6(J,Q){J.debugName=Q||void 0,VJ()}var n={id:v4,type:ZJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},L1=Symbol.for("pocketjs.native-node"),D0=1,yJ=3,d=8,b6=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function aJ(J){return J.domAttrs??={}}function I1(J,Q){let $=J.domNodeType??(hJ(J)?yJ:D0),Z=$===yJ?rJ(J.text??""):$===d?E6(J.domData??""):x1(J.domTag??nJ(J));for(let X of Object.keys(J.domAttrs??{}))O0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)t(Z,I1(X,!0));return Z}function O0(J,Q,$){if(b6.has(Q)){RJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete aJ(J)[Q];else aJ(J)[Q]=$}function C0(J){if(J[L1]===!0)return J;return Object.defineProperty(J,L1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(hJ(J)?yJ:D0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else oJ(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else oJ(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===d)return J.domData??"";if(hJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===d)J.domData=Z;else if(hJ(J))oJ(J,Z);else if(c6(J),Z)t(J,rJ(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return b1(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??nJ(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===yJ)return"#text";if(J.domNodeType===d)return"#comment";return(J.domTag??nJ(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){RJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===n)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return t(J,$),$},insertBefore($,Z){return t(J,$,Z??null),$},removeChild($){return xJ(J,$),$},replaceChild($,Z){return t(J,$,Z),xJ(J,Z),Z},cloneNode($=!1){return I1(J,!!$)},remove(){if(J.parent)xJ(J.parent,J)},setAttribute($,Z){O0(J,$,Z)},removeAttribute($){O0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}C0(n);var L0=null;function g6(J){L0=J}var I0={unknownClass:0,unknownTexture:0},k1=new Map;function A1(J,Q){k1.set(J,Q)}var S1=new Map;function _1(J,Q){S1.set(J,Q)}var PJ=new Set,T6=new Set;function y1(J){if(!J)return!1;if(T6.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return C0({id:y().createNode(Q),type:Q,parent:null,children:[],domNodeType:D0,domTag:J})}function rJ(J){let Q=y(),$=Q.createNode(ZJ.text);return Q.setText($,J),C0({id:$,type:ZJ.text,parent:null,children:[],text:J,domNodeType:yJ,domTag:"#text"})}function E6(J=""){let Q=rJ("");return Q.domNodeType=d,Q.domTag="#comment",Q.domData=J,Q}function oJ(J,Q){y().replaceText(J.id,Q),J.text=Q,VJ()}function hJ(J){return J.type===ZJ.text}function f1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function t(J,Q,$){let Z=y();if(f1(Q),PJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,VJ()}function xJ(J,Q){if(!Q)return;I6(Q),y().removeChild(J.id,Q.id),f1(Q),PJ.add(Q),VJ()}function N6(J){return J.parent??void 0}function m6(J){return J.children[0]}function b1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function v6(J,Q){let $=y();if(VJ(),Q==null||Q===""){$.setStyle(J.id,u4);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=L0?L0(Q):void 0;if(Z===void 0){if(UJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);I0.unknownClass++;return}$.setStyle(J.id,Z)}function u6(J,Q){let $=y();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=k1.get(Q);if(Z===void 0){if(UJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);I0.unknownTexture++;return}$.setImage(J.id,Z)}function l6(J,Q){let $=y();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=S1.get(Q);if(Z===void 0){if(UJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);I0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function p6(J,Q,$){let Z=y(),X=Q??{},W=$??{},q=!1;for(let G in X){let M=X[G];if(W[G]===M)continue;let V=l4[G];if(V===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,V,$6(G,M)),q=!0}if(q)VJ()}function RJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete aJ(J)[Q];else aJ(J)[Q]=$;switch(Q){case"class":return v6(J,$),$;case"onPress":case"on:press":return V6(J,$),$;case"src":return u6(J,$),$;case"sprite":return l6(J,$),$;case"style":return p6(J,$,Z),$;case"focusable":return P6(J,!!$),$;case"debugName":return f6(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${nJ(J)}>`)}function c6(J){for(let Q of[...J.children])xJ(J,Q)}function nJ(J){for(let Q of Object.keys(ZJ))if(ZJ[Q]===J.type)return Q;return String(J.type)}function i6(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}RJ(J,Q,$,Z)}var d6=m4({createElement:x1,createTextNode:rJ,replaceText:oJ,isTextNode:hJ,setProperty:i6,insertNode(J,Q,$){t(J,Q,$)},removeNode(J,Q){xJ(J,Q)},getParentNode:N6,getFirstChild:m6,getNextSibling:b1}),{render:s6,effect:S2,memo:a6,createComponent:O,createElement:g1,insert:_2,spread:r6,mergeProps:y2,use:h2}=d6,x2={linear:N.Easing.Linear,in:N.Easing.EaseIn,out:N.Easing.EaseOut,"in-out":N.Easing.EaseInOut,"out-back":N.Easing.OutBack,spring:N.Easing.Spring,"spring-bouncy":N.Easing.SpringBouncy},o6=null;function T1(J){o6=J}function n6(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function E1(J,Q){let $=g1(J);return r6($,Q,!1),n6(Q.nodeRef,$),$}function T(J){return E1("view",J)}function x(J){return E1("text",J)}var f2=new WeakMap,b2=new WeakMap,t6={}!==null?Object.freeze({...{}}):Object.freeze({}),g2=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:t6}),T2=new Map,e=36000,k0=30,e6=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(e),tapeAnalog:new Uint16Array(e),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-k0,saidHello:!1,hostCalls:0};function J8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-k0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)C1(()=>{Y.treeDirty=!0}),z8();else C1(null);globalThis.__pocketDevtools=H8}function Q8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)Z8(),Y8();let W=Q,q=$===void 0?XJ:$&65535,G=Z,M=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(e).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==XJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function v1(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,q]of J)Z.fill(W,X,Math.min(X+q,$)),X+=q;return Z}function u1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return v1(J.masks,0,Q)}function l1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return v1(J.analog??[],XJ,Q)}function p1(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,b({t:"hello",app:Y.app,host:G8(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` +`))if(X.trim())X8(X)}}function X8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)b({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),A0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),A0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":c1();break;case"eval":{let Z=!0,X;try{X=tJ((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}b({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":b({t:"tape",tape:m1()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}b({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())b({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else b({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=u1(Z),Y.replayAnalog=Z.analog?l1(Z):null,Y.replayTouch=Z.touch?p1(Z):null,Y.replayAt=0;break}default:break}}function W8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=k0)c1();if(Y.frame%e6===0)A0()}function Y8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,b({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,b({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function A0(){b({t:"stats",frame:Y.frame,nodes:s1(n),tapeLen:Y.tapeLen,paused:Y.paused})}function c1(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,b({t:"tree",frame:Y.frame,root:d1(n)})}function q8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function S0(J,Q){if(Array.isArray(J)){for(let $ of J)S0($,Q);return}if(q8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)S0($,Q)}}function i1(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)S0(Z,Q)}function d1(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(i1(J,(X)=>{if(X.domNodeType===8)return;Z.push(d1(X))}),Z.length)Q.k=Z;return Q}function s1(J){let Q=1;return i1(J,($)=>{Q+=s1($)}),Q}function z8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{b({t:"log",level:$,args:X.map((W)=>tJ(W))}),Z?.apply(Q,X)}}}function tJ(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?a1(W):JSON.stringify(a1(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((q)=>tJ(q,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,q])=>`${W}: ${tJ(q,Q+1)}`).join(", ")}}`}function a1(J){return J.length>200?J.slice(0,199)+"…":J}function G8(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var H8={get frame(){return Y.frame},dumpTape:()=>m1(),replay:(J)=>{Y.replayMasks=u1(J),Y.replayAnalog=J.analog?l1(J):null,Y.replayTouch=J.touch?p1(J):null,Y.replayAt=0}},r1=new Map,_0=new Map;function o1(J){return J.trim().replace(/\s+/g," ")}function n1(J){return J.split(" ").sort().join(" ")}var t1=-1;function j8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=o1(Q);r1.set(Z,$);let X=n1(Z),W=_0.get(X);_0.set(X,W!==void 0&&W!==$?t1:$)}}function B8(J){let Q=o1(J),$=r1.get(Q);if($!==void 0)return $;let Z=_0.get(n1(Q));return Z===t1?void 0:Z}var y0=9,F8=(1<{let X=($&M8)!==0,W=X?h0:y0,q=X?U8:F8;return Object.freeze({id:$>>>(X?V8:K8)&255,x:$&q,y:$>>>W&q,hit:Q?.[Z]})}))}function R8(){return eJ}function w8(){eJ=x0}var e1=8,JJ=8,D8=3,O8=8,C8=6,L8=0.5,l=1,fJ=2,f0=4,GJ=8,wJ=[],J4=0,J0=0,QJ=Array.from({length:e1},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(JJ),histY:new Int16Array(JJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function I8(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function k8(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=O1(Q,$,Z.fact);let G=Z.hit;if(G)return I8(G,W)}let q=X.rect?.();if(!q)return!1;return Q>=q.x&&Q=q.y&&$=0;q--){let G=wJ[q];if(G.disposed)continue;if(J4>0&&!G.opts.allowWhenBlocked)continue;if(!k8(G,$,Z,W))continue;G.flags[J.slot]=l,J.owners.push(G)}for(let q of J.owners)q.opts.onDown?.(J)}function _8(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%JJ,J.histLenq||Z>q))X.flags[J.slot]|=fJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&l)||W&(fJ|f0))continue;if(!X.opts.onLongPress)continue;let q=Math.max(1,Math.round((X.opts.longPressSeconds??L8)*Y1()));if(J.frames=0)wJ.splice($,1)},cancel(){if(!Q.disposed)Z4(Q)},get panning(){for(let $ of QJ)if($.used&&Q.flags[$.slot]&GJ)return!0;return!1}}}function b8(J){let Q=f8(J);return Y0(()=>Q.dispose()),Q}function X4(){wJ.length=0,J4=0,J0=0;for(let J of QJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function g8(){return b8({onDown:(J)=>{let Q=D1(J.x,J.y,J.hit);if(Q)iJ(Q)},onTap:(J)=>{iJ(null);let Q=D1(J.x,J.y,J.hit);if(Q)L6(Q)},onUp:()=>iJ(null),onCancel:()=>iJ(null)})}var T8=1,b0=new Map,Q0=[];function E8(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function N8(){T8=1,b0.clear(),Q0=[]}function m8(){if(Q0.length===0)return;let J=Q0;Q0=[];for(let{id:Q,result:$}of J){let Z=b0.get(Q);if(!Z)continue;b0.delete(Q),E8()?.({t:"delivery",frame:q1(),id:Q,kind:Z.kind}),Z.onResult($)}}var W4=new Set;function v8(){if(W4.size===0)return;for(let J of W4)J()}var u8={"flex-col w-full h-full bg-slate-50":0,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":1,"flex-row items-center gap-4":2,"text-2xl text-white":3,"flex-col":4,"text-sm text-indigo-300 tracking-wide":5,"text-2xl text-white font-bold":6,"px-3 py-2 bg-indigo-900":7,"text-sm text-indigo-200":8,"p-6 flex-col gap-3":9,"text-sm text-indigo-700 font-bold":10,"text-2xl text-slate-950 font-bold":11,"text-base text-slate-600":12,"grow px-6 pt-4 flex-col gap-3":13,"h-[430] px-12 flex-col items-center justify-center bg-white":14,"w-[88] h-[88] items-center justify-center bg-indigo-100":15,"text-2xl text-indigo-700 font-bold":16,"pt-7 text-xl text-slate-900 font-bold":17,"pt-4 text-base text-slate-500":18,"h-[118] px-5 flex-row items-center justify-between bg-white":19,"w-[500] flex-col gap-2":20,"text-base text-slate-900 font-bold":21,"text-sm text-slate-500":22,"text-sm text-indigo-600 font-bold":23,"px-3 py-2 bg-emerald-100":24,"px-3 py-2 bg-red-100":25,"text-sm text-emerald-700":26,"text-sm text-red-500":27,"h-[96] px-6 flex-row items-center bg-slate-950":28,"text-sm text-slate-300":29,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":30,"absolute inset-0 z-50 flex-col items-center justify-center":31,"absolute inset-0 bg-slate-950":32,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":33,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":34,"flex-row flex-wrap":35,grow:36};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var l8="ui:styles",p8="ui:font.",Y4="ui:img.",q4="ui:sprite.";function c8(){return globalThis.ui}function i8(J){if(J.__textures)return;for(let Q of K0(Y4)){let $=SJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)A1(Q.slice(Y4.length),Z)}}function d8(J){if(J.__sprites)return;for(let Q of K0(q4)){let $=SJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),q=$[4],G=Z.getUint16(6,!0),M=Z.getUint16(8,!0),V=Z.getUint16(10,!0),R=J.uploadTexture($.subarray(16),X,W,q);if(R>=0)_1(Q.slice(q4.length),{handle:R,frames:G,cols:M,step:V})}}function z4(J){let Q=g1("view");return RJ(Q,"style",J,void 0),Q}var $0=null,Z0=null;function s8(J,Q){if(!$0||!Z0)return;RJ($0,"style",{width:J,height:Q,overflow:N.Overflow.Hidden},void 0),RJ(Z0,"style",{width:J,height:Q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=y();$.__viewport={w:J,h:Q}}function a8(J,Q={}){let $=n4(Q.ops);if(t4($),g6(B8),Q.styles)j8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let k in Z)A1(k,Z[k]);let H=$.ops.__sprites;if(H)for(let k in H)_1(k,H[k])}if($.kind==="injected"||Z===void 0){if(Q.pak)B1(Q.pak);if(U6()){for(let H of K0())if(H===l8)$.ops.loadStyles?.(SJ(H));else if(H.startsWith(p8))$.ops.loadFontAtlas?.(SJ(H))}}let X=Z1($.ops),W=X?.w??J1,q=X?.h??Q1,G=z4({width:W,height:q,overflow:N.Overflow.Hidden}),M=z4({width:W,height:q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});t(n,G),t(n,M),T1(M),$0=G,Z0=M,F1(G),R1(n),F6(),X4(),g8(),Y6(),N8(),J8($.ops),e4(Q8((H,k,_,h)=>{q6(),z6(k),P8(_,h),v8(),m8(),x8(),K6(H),x6(H),h1()}));let V=s6(J,G),R=J6(s8);return()=>{R(),w8(),X4(),V(),F1(null),R1(null),T1(null),$0=null,Z0=null;for(let H of n.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);h1()}}function r8(J,Q={}){let $=Q.ops??c8();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)B1(Q.pak);return i8($),d8($),a8(J,{ops:$,styles:Q.styles??u8,pak:Q.pak})}var G4="$b",o8=9007199254740991,n8=":memory:",DJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function t8(J){let Q="";for(let $=0;$>2]+DJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2o8)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function Q2(J){if(J!==null&&typeof J==="object")return e8(J[G4]);return J}function $2(J){if(Array.isArray(J))return JSON.stringify(J.map(H4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=H4(Z);return JSON.stringify(Q)}class g0{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,$2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=j4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(Q2))}run(...J){let Q=this.execute(j4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function j4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class B4{statements=new Map;txDepth=0;constructor(J=n8){let Q=J2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new g0(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new g0(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let q=J(...Q);return this.txDepth--,this.exec(X),q}catch(q){throw this.txDepth--,this.exec(W),q}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var F4=3,OJ=new B4("exa"),[K4,T0]=kJ([]),[Z2,E0]=kJ("SEARCH HISTORY IS LOCAL"),X0=-1;function X2(J){try{return JSON.parse(J)}catch{return null}}function W2(J){let Q=new Date(J*1000).toISOString();return Q.slice(0,10)+" · "+Q.slice(11,16)+" UTC"}function M4(J){if(X0===J)return;try{let Q=OJ.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==F4){T0([]),E0("SEARCH HISTORY IS LOCAL");return}let $=OJ.query(` SELECT search.id,search.query,search.searched_at,search.status,search.result_count, result.title AS top_title,result.url AS top_url,search.error FROM searches search LEFT JOIN search_results result ON result.search_id=search.id AND result.rank=0 ORDER BY search.id DESC LIMIT 8 - `).all();T0($),E0($[0]?.status==="error"?String($[0].error||"EXA SEARCH FAILED").slice(0,80):$.length?"SEARCH HISTORY UPDATED FROM SQLITE":"SEARCH HISTORY IS LOCAL"),X0=J}catch{T0([]),E0("SEARCH HISTORY IS LOCAL")}}function X2(){let J=OJ.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((W)=>W.name)),$=J.map((W)=>{let q=OJ.query("SELECT COUNT(*) AS count FROM "+W.name).get().count;return{name:W.name,rowCount:q,schema:W.sql}}),Z=Q.has("searches")?OJ.query(` + `).all();T0($),E0($[0]?.status==="error"?String($[0].error||"EXA SEARCH FAILED").slice(0,80):$.length?"SEARCH HISTORY UPDATED FROM SQLITE":"SEARCH HISTORY IS LOCAL"),X0=J}catch{T0([]),E0("SEARCH HISTORY IS LOCAL")}}function Y2(){let J=OJ.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((W)=>W.name)),$=J.map((W)=>{let q=OJ.query("SELECT COUNT(*) AS count FROM "+W.name).get().count;return{name:W.name,rowCount:q,schema:W.sql}}),Z=Q.has("searches")?OJ.query(` SELECT search.id,search.query,search.searched_at,search.status,search.result_count, result.title AS top_title,result.url AS top_url,search.error FROM searches search LEFT JOIN search_results result ON result.search_id=search.id AND result.rank=0 ORDER BY search.id DESC LIMIT 8 - `).all():[],X=Q.has("documents")?OJ.query("SELECT fetched_at,url,title,LENGTH(text) AS text_bytes FROM documents ORDER BY fetched_at DESC LIMIT 5").all():[];return{database:"exa.sqlite",schemaVersion:B4,tables:$,latestSearches:Z,latestDocuments:X}}function W2(){return O(T,{class:"flex-col w-full h-full bg-slate-50",get children(){return[O(T,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[O(T,{class:"flex-row items-center gap-4",get children(){return[O(x,{class:"text-2xl text-white",children:"‹"}),O(T,{class:"flex-col",get children(){return[O(x,{class:"text-sm text-indigo-300 tracking-wide",children:"POCKET APP"}),O(x,{class:"text-2xl text-white font-bold",children:"Exa Research"})]}})]}}),O(T,{class:"px-3 py-2 bg-indigo-900",get children(){return O(x,{class:"text-sm text-indigo-200",children:"SQLITE HISTORY"})}})]}}),O(T,{class:"p-6 flex-col gap-3",get children(){return[O(x,{class:"text-sm text-indigo-700 font-bold",children:"AGENT RESEARCH MEMORY"}),O(x,{class:"text-2xl text-slate-950 font-bold",children:"Search history"}),O(x,{class:"text-base text-slate-600",children:"Every research.search call is saved here automatically."})]}}),O(T,{class:"grow px-6 pt-4 flex-col gap-3",get children(){return[O(g4,{get when(){return F4().length===0},get children(){return O(T,{class:"h-[430] px-12 flex-col items-center justify-center bg-white",get children(){return[O(T,{class:"w-[88] h-[88] items-center justify-center bg-indigo-100",get children(){return O(x,{class:"text-2xl text-indigo-700 font-bold",children:"E"})}}),O(x,{class:"pt-7 text-xl text-slate-900 font-bold",children:"No searches yet"}),O(x,{class:"pt-4 text-base text-slate-500",children:`Ask Pi Agent to research a topic. -The search and its results will appear here.`})]}})}}),O(b4,{get each(){return F4()},children:(J)=>O(T,{class:"h-[118] px-5 flex-row items-center justify-between bg-white",get children(){return[O(T,{class:"w-[500] flex-col gap-2",get children(){return[O(x,{class:"text-base text-slate-900 font-bold",get children(){return J.query.slice(0,72)}}),O(x,{class:"text-sm text-slate-500",get children(){return(J.top_title||J.error||"No result title").slice(0,92)}}),O(x,{class:"text-sm text-indigo-600 font-bold",get children(){return Z2(J.searched_at)}})]}}),O(T,{get["class"](){return J.status==="ok"?"px-3 py-2 bg-emerald-100":"px-3 py-2 bg-red-100"},get children(){return O(x,{get["class"](){return J.status==="ok"?"text-sm text-emerald-700":"text-sm text-red-500"},get children(){return s6(()=>J.status==="ok")()?J.result_count+" RESULTS":"FAILED"}})}})]}})})]}}),O(T,{class:"h-[96] px-6 flex-row items-center bg-slate-950",get children(){return O(x,{class:"text-sm text-slate-300",get children(){return Q2()}})}})]}})}K4(0),s8(()=>O(W2,{})),globalThis.PocketPiApp={tick(){return""},update(){return""},dataChanged(J){let Q=$2(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),X0):X0;return K4($),""},invokeTool(J){try{let Q=J==="research.storage_status"?X2():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Unknown Exa task: "+J,isError:!0})},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});return""}}})(); + `).all():[],X=Q.has("documents")?OJ.query("SELECT fetched_at,url,title,LENGTH(text) AS text_bytes FROM documents ORDER BY fetched_at DESC LIMIT 5").all():[];return{database:"exa.sqlite",schemaVersion:F4,tables:$,latestSearches:Z,latestDocuments:X}}function q2(){return O(T,{class:"flex-col w-full h-full bg-slate-50",get children(){return[O(T,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[O(T,{class:"flex-row items-center gap-4",get children(){return[O(x,{class:"text-2xl text-white",children:"‹"}),O(T,{class:"flex-col",get children(){return[O(x,{class:"text-sm text-indigo-300 tracking-wide",children:"POCKET APP"}),O(x,{class:"text-2xl text-white font-bold",children:"Exa Research"})]}})]}}),O(T,{class:"px-3 py-2 bg-indigo-900",get children(){return O(x,{class:"text-sm text-indigo-200",children:"SQLITE HISTORY"})}})]}}),O(T,{class:"p-6 flex-col gap-3",get children(){return[O(x,{class:"text-sm text-indigo-700 font-bold",children:"AGENT RESEARCH MEMORY"}),O(x,{class:"text-2xl text-slate-950 font-bold",children:"Search history"}),O(x,{class:"text-base text-slate-600",children:"Every research.search call is saved here automatically."})]}}),O(T,{class:"grow px-6 pt-4 flex-col gap-3",get children(){return[O(T4,{get when(){return K4().length===0},get children(){return O(T,{class:"h-[430] px-12 flex-col items-center justify-center bg-white",get children(){return[O(T,{class:"w-[88] h-[88] items-center justify-center bg-indigo-100",get children(){return O(x,{class:"text-2xl text-indigo-700 font-bold",children:"E"})}}),O(x,{class:"pt-7 text-xl text-slate-900 font-bold",children:"No searches yet"}),O(x,{class:"pt-4 text-base text-slate-500",children:`Ask Pi Agent to research a topic. +The search and its results will appear here.`})]}})}}),O(g4,{get each(){return K4()},children:(J)=>O(T,{class:"h-[118] px-5 flex-row items-center justify-between bg-white",get children(){return[O(T,{class:"w-[500] flex-col gap-2",get children(){return[O(x,{class:"text-base text-slate-900 font-bold",get children(){return J.query.slice(0,72)}}),O(x,{class:"text-sm text-slate-500",get children(){return(J.top_title||J.error||"No result title").slice(0,92)}}),O(x,{class:"text-sm text-indigo-600 font-bold",get children(){return W2(J.searched_at)}})]}}),O(T,{get["class"](){return J.status==="ok"?"px-3 py-2 bg-emerald-100":"px-3 py-2 bg-red-100"},get children(){return O(x,{get["class"](){return J.status==="ok"?"text-sm text-emerald-700":"text-sm text-red-500"},get children(){return a6(()=>J.status==="ok")()?J.result_count+" RESULTS":"FAILED"}})}})]}})})]}}),O(T,{class:"h-[96] px-6 flex-row items-center bg-slate-950",get children(){return O(x,{class:"text-sm text-slate-300",get children(){return Z2()}})}})]}})}M4(0),r8(()=>O(q2,{})),globalThis.PocketPiApp={tick(){return""},update(){return""},dataChanged(J){let Q=X2(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),X0):X0;return M4($),""},invokeTool(J){try{let Q=J==="research.storage_status"?Y2():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Unknown Exa task: "+J,isError:!0})},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});return""}}})(); diff --git a/apps/pi-agent/dist/app.js b/apps/pi-agent/dist/app.js index adc6f0c..607b582 100644 --- a/apps/pi-agent/dist/app.js +++ b/apps/pi-agent/dist/app.js @@ -1,16 +1,16 @@ -(()=>{var IJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return H1(this.context.count)},getNextContextId(){return H1(this.context.count++)}};function H1(J){let Q=String(J),$=Q.length-1;return IJ.context.id+($?String.fromCharCode(96+$):"")+Q}function B1(J){IJ.context=J}function $6(){return{...IJ.context,id:IJ.getNextContextId(),count:0}}var Z6=!1,q6=(J,Q)=>J===Q,k0=Symbol("solid-proxy"),X6=typeof Proxy==="function",Y6=Symbol("solid-track"),WQ=Symbol("solid-dev-component"),oJ={equals:q6},j1=null,z6=D1,m=1,yJ=2,K1={owned:null,cleanups:null,context:null,owner:null},S=null,K=null,TJ=null,AJ=null,b=null,w=null,y=null,nJ=0;function tJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?K1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>QJ(()=>$J(z)));S=z,b=null;try{return c(G,!0)}finally{b=$,S=Z}}function C(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return U1($,q)};return[M1.bind($),Z]}function JJ(J,Q,$){let Z=P1(J,Q,!1,m);if(TJ&&K&&K.running)w.push(Z);else eJ(Z)}function _J(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=P1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,TJ&&K&&K.running)Z.tState=m,w.push(Z);else eJ(Z);return M1.bind(Z)}function W6(J){return c(J,!1)}function QJ(J){if(!AJ&&b===null)return J();let Q=b;b=null;try{if(AJ)return AJ.untrack(J);return J()}finally{b=Q}}function S0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function G6(J){if(K&&K.running)return J(),K.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(TJ||H6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[GQ,F1]=C(!1),H6;function M1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)eJ(this);else{let Q=w;w=null,c(()=>J0(this),!1),w=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function U1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw w=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;$J(J);let Q=nJ;if(R1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{c(()=>{K&&(K.running=!0),b=S=J,R1(J,J.tValue,Q),b=S=null},!1)})}function R1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=m,J.tOwned&&J.tOwned.forEach($J),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach($J),J.owned=null;return J.updatedAt=$+1,g0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)U1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function P1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(S===null);else if(S!==K1)if(K&&K.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(AJ&&X.fn){let z=X.fn,[G,P]=C(void 0,{equals:!1}),D=AJ.factory(z,P);S0(()=>D.dispose());let V,B=()=>G6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),K&&K.running){if(!V)V=AJ.factory(z,B);return V.track(_)}return D.track(_)}}return X}function b0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===yJ)return J0(J);if(J.suspense&&QJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===m)eJ(J);else if((Q?J.tState:J.state)===yJ){let q=w;w=null,c(()=>J0(J,$[0]),!1),w=q}}}function c(J,Q){if(w)return J();let $=!1;if(!Q)w=[];if(y)$=!0;else y=[];nJ++;try{let Z=J();return B6($),Z}catch(Z){if(!$)y=null;w=null,g0(Z)}}function B6(J){if(w){if(TJ&&K&&K.running)j6(w);else D1(w);w=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;y.push.apply(y,K.effects),Q=K.resolve;for(let X of y)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,c(()=>{for(let X of q)$J(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zz6($),!1);if(Q)Q()}function D1(J){for(let Q=0;Q{Z.delete($),c(()=>{K.running=!0,b0($)},!1),K&&(K.running=!1)})}}function J0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)$J(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)L1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)$J(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function L1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return S0(()=>I1(X)),()=>{let P=J()||[],D=P.length,V,B;return P[Y6],QJ(()=>{let N,h,a,GJ,VJ,M,j,H,L;if(D===0){if(z!==0)I1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[F6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=M&&H>=M&&Z[j]===P[H];j--,H--)a[H]=q[j],GJ[H]=X[j],G&&(VJ[H]=G[j]);N=new Map,h=Array(H+1);for(B=H;B>=M;B--)L=P[B],V=N.get(L),h[B]=V===void 0?-1:V,N.set(L,B);for(V=M;V<=j;V++)if(L=Z[V],B=N.get(L),B!==void 0&&B!==-1)a[B]=q[V],GJ[B]=X[V],G&&(VJ[B]=G[V]),B=h[B],N.set(L,B);else X[V]();for(B=M;BJ(Q||{}));return B1($),Z}}return QJ(()=>J(Q||{}))}function Q0(){return!0}var P6={get(J,Q,$){if(Q===k0)return $;return J.get(Q)},has(J,Q){if(Q===k0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function w0(J){return!(J=typeof J==="function"?J():J)?{}:J}function D6(){for(let J=0,Q=this.length;J=0;G--){let P=w0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in w0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:D6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var V6=(J)=>`Stale read from <${J}>.`;function kJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return _J(M6(()=>J.each,J.children,Q||void 0))}function SJ(J){let Q=J.keyed,$=_J(()=>J.when,void 0,void 0),Z=Q?$:_J($,void 0,{equals:(q,X)=>!q===!X});return _J(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?QJ(()=>X(Q?q:()=>{if(!QJ(Z))throw V6("Show");return $()})):X}return J.fallback},void 0,void 0)}var L6=(J)=>_J(()=>J());function O6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(M,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(M,j,L,H);JJ((A)=>B(M,j(),A,H),L)}function B(M,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=h(M,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(M),H=j);else h(M,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=h(M,H,L);else if(k==="function")return JJ(()=>{let O=j();while(typeof O==="function")O=O();H=B(M,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return JJ(()=>H=B(M,O,H,L,!0)),()=>H;if(O.length===0){let hJ=h(M,H,L);if(I)return H=hJ}else if(Array.isArray(H))if(H.length===0)a(M,O,L);else N(M,H,O);else if(H==null||H==="")a(M,O);else N(M,I&&H||[P(M)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(M,H,L,j);h(M,H,null,j)}else if(H==null||H===""||!P(M))q(M,j);else GJ(M,j,P(M));H=j}return H}function _(M,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let zQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let hJ=G(O)===M;if(!k&&!I)hJ?GJ(M,A,O):q(M,A,H);else hJ&&X(M,O)}else k=!0}}else q(M,A,H);return[A]}function a(M,j,H){for(let L=0,A=j.length;LH.children=B(M,j.children,H.children));return JJ(()=>j.ref&&j.ref(M)),JJ(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(M,A,k,H[A]),H[A]=k}}),H}return{render(M,j){let H;return tJ((L)=>{H=L,V(j,M())}),H},insert:V,spread(M,j,H){if(typeof j==="function")JJ((L)=>VJ(M,j(),L,H));else VJ(M,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(M,j,H,L){return z(M,j,H,L),H},mergeProps:A1,effect:JJ,memo:L6,createComponent:R6,use(M,j,H){return QJ(()=>M(j,H))}}}function I6(J){let Q=O6(J);return Q.mergeProps=A1,Q}var _1=480,k1=272,HJ={view:0,text:1,image:2},A6=1,_6=-1,k6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},S6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},b6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},g6=1,HQ=2,BQ=1,jQ=2,KQ=131072,FQ=1,MQ=262144,UQ=1,RQ=1,PQ=1,DQ=2,VQ=4,LQ=8,OQ=16,IQ=1,AQ=2;function S1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var _Q=1,w6=1263551300,C6=1,E6=32,N6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},BJ=32896,kQ=0.016666666666666666;function b1(J){return J.__viewport??null}var C0=null;function h6(){return null}function g1(J,Q=h6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function y6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return g1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return g1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function T6(J){C0=J}function bJ(){if(!C0)throw Error("PocketJS: host not installed — call render() first");return C0}function E(){return bJ().ops}function x6(J){globalThis.frame=J}function f6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function v6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return S1($>>>16&255,$>>>8&255,$&255,255);return S1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function m6(J,Q){let $=S6[J];if(typeof Q==="string"){if($===U.color)return v6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var $0=60,w1=[1,2,3,4,5,6,10,12,15,20,30,60],E0=$0,ZJ=-1,u6=0,xJ=[];function l6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=w1[0];for(let $ of w1)if(Math.abs($-J)Q.at<=ZJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>ZJ);for(let Q of J)Q.cb()}var N0=0.12,Z0=BJ;function i6(J){Z0=J===void 0?BJ:J&65535}function s6(){Z0=BJ}function N1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function r6(){return N1(Z0&255)}var h1=new Set,o6=0;function n6(){h1.clear(),o6=0,s6()}function t6(J){for(let Q of[...h1])Q(J)}var jJ=null,y1=null;function e6(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function T1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function fJ(J){h0();let Q=jJ?jJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return y1.slice(Q.off,Q.off+Q.len)}var vJ=null,g=null,KJ=null,q0=0,FJ=[],T0=[],x0=[];function f1(J){if(vJ=J,g=null,KJ=null,q0=0,FJ.length=0,T0.length=0,x0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function Q8(J,Q){J.onPress=Q??void 0}function $8(J,Q){if(J.focusable=Q,p1(),!Q&&g===J)x(null)}function x(J){if(KJ&&KJ!==J)MJ(null);g=J,E().setFocus(J?J.id:0)}function MJ(J){if(KJ===J)return;let Q=E();if(KJ)Q.setActive?.(KJ.id,0);if(KJ=J,J)Q.setActive?.(J.id,1)}function f0(){return FJ.length>0?FJ[FJ.length-1]:vJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function X8(){if(!g)return null;let J=f0();if(J&&!i(g,J))return null;for(let Q=T0.length-1;Q>=0;Q--){let $=T0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(g,$.node))return $}return null}function Y8(J){let Q=X8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(g)x(null);return!0}let Z=Q.columns,q=g?$.indexOf(g):-1;if(q<0)return x(v1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function z8(){if(!g)return null;let J=f0();if(J&&!i(g,J))return null;for(let Q=x0.length-1;Q>=0;Q--){let $=x0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(g,$.node))return $}return null}function X0(J){let Q=z8();if(Q&&Q.move(J))return;if(Y8(J))return;q8(J)}function m1(){u1(g)}function u1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){MJ(J)}function W8(J){x(J),u1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=m0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,l1=0;function p1(){l1++}var H8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],B8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function j8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=H8[Q]>>$&1,q=B8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function K8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=fJ($.image)}catch(z){if(bJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):F8(Q,X),q<0&&bJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(j8(),16,16,b6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function F8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&g6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var W0=null;function c1(J){W0=J}function d1(J){let Q=FJ.length>0?FJ[FJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function i1(J,Q,$){return d1(s1(J,Q,$))}function s1(J,Q,$){if($!==void 0)return $===0?null:z0(W0??vJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(W0??vJ,q(J,Q))}function M8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=b1(q);if(Z.vw=B?B.w:_1,Z.vh=B?B.h:k1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)K8(Z,q);let X=a6()*Z.speed,z=r6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=p6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=l1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=d1(z0(W0??vJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==g)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(MJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,MJ(null),B)m1()}}else if($&Z.button)MJ(null);return!0}function U8(J){let Q=J&~q0,$=q0&~J;if(q0=J,l&&M8(J,Q,$))return;if($&d.CIRCLE)MJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)MJ(g),m1()}var u0=null;function a1(J){u0=J}function gJ(){if(p1(),u0)u0()}function R8(J,Q){J.debugName=Q||void 0,gJ()}var qJ={id:A6,type:HJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},r1=Symbol.for("pocketjs.native-node"),l0=1,mJ=3,o=8,P8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function G0(J){return J.domAttrs??={}}function o1(J,Q){let $=J.domNodeType??(uJ(J)?mJ:l0),Z=$===mJ?H0(J.text??""):$===o?L8(J.domData??""):Z4(J.domTag??j0(J));for(let q of Object.keys(J.domAttrs??{}))p0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)XJ(Z,o1(q,!0));return Z}function p0(J,Q,$){if(P8.has(Q)){CJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete G0(J)[Q];else G0(J)[Q]=$}function c0(J){if(J[r1]===!0)return J;return Object.defineProperty(J,r1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?mJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(uJ(J))B0(J,Z);else if(b8(J),Z)XJ(J,H0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return X4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??j0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===mJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??j0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){CJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===qJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return XJ(J,$),$},insertBefore($,Z){return XJ(J,$,Z??null),$},removeChild($){return lJ(J,$),$},replaceChild($,Z){return XJ(J,$,Z),lJ(J,Z),Z},cloneNode($=!1){return o1(J,!!$)},remove(){if(J.parent)lJ(J.parent,J)},setAttribute($,Z){p0(J,$,Z)},removeAttribute($){p0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(qJ);var d0=null;function D8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},n1=new Map;function t1(J,Q){n1.set(J,Q)}var e1=new Map;function J4(J,Q){e1.set(J,Q)}var wJ=new Set,V8=new Set;function Q4(J){if(!J)return!1;if(V8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function H0(J){let Q=E(),$=Q.createNode(HJ.text);return Q.setText($,J),c0({id:$,type:HJ.text,parent:null,children:[],text:J,domNodeType:mJ,domTag:"#text"})}function L8(J=""){let Q=H0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){E().replaceText(J.id,Q),J.text=Q,gJ()}function uJ(J){return J.type===HJ.text}function q4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function XJ(J,Q,$){let Z=E();if(q4(Q),wJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,gJ()}function lJ(J,Q){if(!Q)return;G8(Q),E().removeChild(J.id,Q.id),q4(Q),wJ.add(Q),gJ()}function O8(J){return J.parent??void 0}function I8(J){return J.children[0]}function X4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function A8(J,Q){let $=E();if(gJ(),Q==null||Q===""){$.setStyle(J.id,_6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(bJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function _8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=n1.get(Q);if(Z===void 0){if(bJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function k8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=e1.get(Q);if(Z===void 0){if(bJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function S8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=k6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,m6(G,P)),z=!0}if(z)gJ()}function CJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete G0(J)[Q];else G0(J)[Q]=$;switch(Q){case"class":return A8(J,$),$;case"onPress":case"on:press":return Q8(J,$),$;case"src":return _8(J,$),$;case"sprite":return k8(J,$),$;case"style":return S8(J,$,Z),$;case"focusable":return $8(J,!!$),$;case"debugName":return R8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${j0(J)}>`)}function b8(J){for(let Q of[...J.children])lJ(J,Q)}function j0(J){for(let Q of Object.keys(HJ))if(HJ[Q]===J.type)return Q;return String(J.type)}function g8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}CJ(J,Q,$,Z)}var w8=I6({createElement:Z4,createTextNode:H0,replaceText:B0,isTextNode:uJ,setProperty:g8,insertNode(J,Q,$){XJ(J,Q,$)},removeNode(J,Q){lJ(J,Q)},getParentNode:O8,getFirstChild:I8,getNextSibling:X4}),{render:C8,effect:SQ,memo:p,createComponent:Y,createElement:Y4,insert:bQ,spread:E8,mergeProps:gQ,use:wQ}=w8,CQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},N8=null;function z4(J){N8=J}function h8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function W4(J,Q){let $=Y4(J);return E8($,Q,!1),h8(Q.nodeRef,$),$}function F(J){return W4("view",J)}function R(J){return W4("text",J)}var EQ=new WeakMap,NQ=new WeakMap,y8={}!==null?Object.freeze({...{}}):Object.freeze({}),hQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:y8}),yQ=new Map,YJ=36000,s0=30,T8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(YJ),tapeAnalog:new Uint16Array(YJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function x8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-s0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)a1(()=>{W.treeDirty=!0}),d8();else a1(null);globalThis.__pocketDevtools=s8}function f8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)m8(),p8();let X=Q,z=$===void 0?BJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(YJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==BJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function B4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function j4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.masks,0,Q)}function K4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.analog??[],BJ,Q)}function F4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,T({t:"hello",app:W.app,host:i8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` -`))if(q.trim())u8(q)}}function u8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),a0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":M4();break;case"eval":{let Z=!0,q;try{q=K0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}T({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":T({t:"tape",tape:H4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}T({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=j4(Z),W.replayAnalog=Z.analog?K4(Z):null,W.replayTouch=Z.touch?F4(Z):null,W.replayAt=0;break}default:break}}function l8(){if(W.treeDirty&&W.frame-W.treeSentAt>=s0)M4();if(W.frame%T8===0)a0()}function p8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){T({t:"stats",frame:W.frame,nodes:P4(qJ),tapeLen:W.tapeLen,paused:W.paused})}function M4(){W.treeDirty=!1,W.treeSentAt=W.frame,T({t:"tree",frame:W.frame,root:R4(qJ)})}function c8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(c8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function U4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function R4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(U4(J,(q)=>{if(q.domNodeType===8)return;Z.push(R4(q))}),Z.length)Q.k=Z;return Q}function P4(J){let Q=1;return U4(J,($)=>{Q+=P4($)}),Q}function d8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{T({t:"log",level:$,args:q.map((X)=>K0(X))}),Z?.apply(Q,q)}}}function K0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?D4(X):JSON.stringify(D4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>K0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${K0(z,Q+1)}`).join(", ")}}`}function D4(J){return J.length>200?J.slice(0,199)+"…":J}function i8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var s8={get frame(){return W.frame},dumpTape:()=>H4(),replay:(J)=>{W.replayMasks=j4(J),W.replayAnalog=J.analog?K4(J):null,W.replayTouch=J.touch?F4(J):null,W.replayAt=0}},V4=new Map,o0=new Map;function L4(J){return J.trim().replace(/\s+/g," ")}function O4(J){return J.split(" ").sort().join(" ")}var I4=-1;function a8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=L4(Q);V4.set(Z,$);let q=O4(Z),X=o0.get(q);o0.set(q,X!==void 0&&X!==$?I4:$)}}function r8(J){let Q=L4(J),$=V4.get(Q);if($!==void 0)return $;let Z=o0.get(O4(Q));return Z===I4?void 0:Z}var n0=9,o8=(1<{let q=($&t8)!==0,X=q?t0:n0,z=q?e8:o8;return Object.freeze({id:$>>>(q?J2:n8)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function $2(){return F0}function Z2(){F0=e0}var A4=8,zJ=8,q2=3,X2=8,Y2=6,z2=0.5,s=1,pJ=2,J1=4,UJ=8,EJ=[],_4=0,M0=0,WJ=Array.from({length:A4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(zJ),histY:new Int16Array(zJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function W2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function G2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=s1(Q,$,Z.fact);let G=Z.hit;if(G)return W2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=EJ[z];if(G.disposed)continue;if(_4>0&&!G.opts.allowWhenBlocked)continue;if(!G2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function j2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%zJ,J.histLenz||Z>z))q.flags[J.slot]|=pJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(pJ|J1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??z2)*C1()));if(J.frames=0)EJ.splice($,1)},cancel(){if(!Q.disposed)b4(Q)},get panning(){for(let $ of WJ)if($.used&&Q.flags[$.slot]&UJ)return!0;return!1}}}function R2(J){let Q=U2(J);return S0(()=>Q.dispose()),Q}function g4(){EJ.length=0,_4=0,M0=0;for(let J of WJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function P2(){return R2({onDown:(J)=>{let Q=i1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=i1(J.x,J.y,J.hit);if(Q)W8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var D2=1,Q1=new Map,U0=[];function V2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function L2(){D2=1,Q1.clear(),U0=[]}function O2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),V2()?.({t:"delivery",frame:E1(),id:Q,kind:Z.kind}),Z.onResult($)}}var I2={"text-lg text-orange-600 font-bold":0,"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":1,"w-[165] h-[76] items-center justify-center bg-orange-600":2,"w-[165] h-[76] items-center justify-center bg-slate-900":3,"text-sm text-white font-bold":4,"flex-col w-full h-full bg-slate-50":5,"h-[686] px-6 pt-7 flex-col gap-[22]":6,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":7,"h-[28] flex-row items-center gap-3":8,"w-[10] h-[10] rounded bg-orange-500":9,"text-sm text-orange-600 font-bold":10,"h-[76] pt-3 text-base text-slate-900":11,"h-[2] mx-1 my-4 bg-slate-100":12,"w-[10] h-[10] rounded bg-emerald-500":13,"text-sm text-emerald-700 font-bold":14,"h-[84] pt-3 text-base text-slate-900":15,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":16,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":17,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":18,"text-sm text-slate-600 font-bold":19,"pt-6 text-base text-slate-500":20,"pt-6 text-base text-slate-900 font-bold":21,"h-[146] px-6 pt-7 flex-col bg-slate-50":22,"h-[80]":23,"h-[1060] px-6 pt-5 flex-col":24,"h-[48] px-4 justify-center bg-slate-100":25,"text-sm text-slate-600":26,"pt-[10] flex-col gap-[12]":27,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":28,"w-[48] h-[48] items-center justify-center bg-blue-100":29,"w-[48] h-[48] items-center justify-center bg-emerald-100":30,"text-base text-blue-700 font-bold":31,"text-base text-emerald-700 font-bold":32,"w-[474] flex-col gap-2":33,"text-base text-slate-900 font-bold":34,"text-sm text-slate-500":35,"pt-20 pl-10 text-base text-slate-500":36,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":37,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":38,"h-[1060] px-6 pt-7 flex-col gap-4":39,"text-sm text-slate-500 font-bold":40,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":41,"flex-row items-center gap-5":42,"w-[68] h-[68] items-center justify-center bg-emerald-100":43,"text-xl text-emerald-700 font-bold":44,"flex-col gap-2":45,"text-lg text-slate-900 font-bold":46,"text-base text-slate-600":47,"text-2xl text-orange-600":48,"w-[68] h-[68] items-center justify-center bg-indigo-100":49,"text-xl text-indigo-700 font-bold":50,"mt-4 h-[112] px-6 justify-center bg-slate-100":51,"relative h-[154] px-5 pt-5 flex-col bg-white":52,"pt-3 text-base text-orange-600 font-bold":53,"pt-3 text-sm text-slate-500":54,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":55,"text-base text-white font-bold":56,"h-[40] pt-3 text-sm text-slate-500":57,"h-[470] flex-col gap-2":58,"h-[214] px-7 items-center justify-center bg-slate-100":59,"text-base text-slate-500 font-bold":60,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":61,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":62,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":63,"h-[160] px-5 pt-5 flex-col bg-white":64,"pt-3 text-base text-slate-900 font-bold":65,"pt-3 text-sm text-slate-600":66,"h-[108] pt-7 flex-row gap-4":67,"w-[316] h-[80] items-center justify-center bg-slate-100":68,"w-[340] h-[80] items-center justify-center bg-red-100":69,"text-base text-red-500 font-bold":70,"h-[1052] px-6 pt-5 flex-col":71,"h-[270] px-[22] pt-6 bg-white":72,"text-lg text-slate-900":73,"text-lg text-slate-400":74,"h-[86] px-1 flex-row items-center justify-between":75,"w-[132] h-[58] items-center justify-center bg-slate-100":76,"text-sm text-slate-900 font-bold":77,"h-[140] flex-row gap-2":78,"grow h-[120] items-center justify-center bg-white":79,"text-xl text-slate-900 font-bold":80,"w-[104] h-[120] items-center justify-center bg-slate-100":81,"h-[176] flex-row gap-2":82,"w-[92] h-[156] items-center justify-center bg-slate-100":83,"w-[300] h-[156] items-center justify-center bg-slate-100":84,"w-[144] h-[156] items-center justify-center bg-slate-100":85,"w-[112] h-[156] items-center justify-center bg-emerald-500":86,"text-sm text-slate-950 font-bold":87,"h-[108] px-6 py-3 flex-col bg-slate-50":88,"h-[84] items-center justify-center bg-slate-100":89,"h-[1168] px-6 pt-5 flex-col":90,"h-[82] px-4 justify-center bg-white":91,"w-[584] h-[900] px-5 pt-5 bg-slate-950":92,"text-sm text-slate-200":93,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":94,"text-base text-orange-600 font-bold":95,"w-[584] h-[900] px-5 pt-5 bg-white":96,"text-sm text-slate-900":97,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":98,"absolute inset-0 z-50 flex-col items-center justify-center":99,"absolute inset-0 bg-slate-950":100,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":101,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":102,"flex-row flex-wrap":103,grow:104,"text-2xl text-white font-bold":105,"text-base text-slate-900":106,"px-6":107,"px-6 py-5":108,"gap-4":109,"w-[34] h-[34] rounded-lg bg-amber-400":110,"w-[34] h-[34] rounded-lg bg-red-500":111,"w-[34] h-[34] rounded-lg bg-slate-800":112,"w-[34] h-[34] rounded-lg bg-emerald-500":113,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":114,"flex-row items-center gap-4":115,"w-[34] text-2xl text-white font-bold":116,"w-[332] flex-col items-end gap-2":117,"text-sm text-slate-300 font-bold":118,"text-sm text-slate-400":119,"h-[40] px-1 flex-row items-center justify-between":120,"w-full h-full items-center justify-center rounded-xl bg-slate-200":121,"w-full h-full items-center justify-center rounded-xl bg-orange-600":122};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var A2="ui:styles",_2="ui:font.",w4="ui:img.",C4="ui:sprite.";function k2(){return globalThis.ui}function S2(J){if(J.__textures)return;for(let Q of y0(w4)){let $=fJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)t1(Q.slice(w4.length),Z)}}function b2(J){if(J.__sprites)return;for(let Q of y0(C4)){let $=fJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)J4(Q.slice(C4.length),{handle:V,frames:G,cols:P,step:D})}}function E4(J){let Q=Y4("view");return CJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function g2(J,Q){if(!R0||!P0)return;CJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),CJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function w2(J,Q={}){let $=y6(Q.ops);if(T6($),D8(r8),Q.styles)a8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)t1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)J4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)x1(Q.pak);if(J8()){for(let B of y0())if(B===A2)$.ops.loadStyles?.(fJ(B));else if(B.startsWith(_2))$.ops.loadFontAtlas?.(fJ(B))}}let q=b1($.ops),X=q?.w??_1,z=q?.h??k1,G=E4({width:X,height:z,overflow:u.Overflow.Hidden}),P=E4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});XJ(qJ,G),XJ(qJ,P),z4(P),R0=G,P0=P,f1(G),c1(qJ),n6(),g4(),P2(),c6(),L2(),x8($.ops),x6(f8((B,_,N,h)=>{d6(),i6(_),Q2(N,h),O2(),M2(),t6(B),U8(B),$4()}));let D=C8(J,G),V=f6(g2);return()=>{V(),Z2(),g4(),D(),f1(null),c1(null),z4(null),R0=null,P0=null;for(let B of qJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);$4()}}function C2(J,Q={}){let $=Q.ops??k2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)x1(Q.pak);return S2($),b2($),w2(J,{ops:$,styles:Q.styles??I2,pak:Q.pak})}var E2="$b",N2=65536,N4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",cJ={};for(let J=0;J>16,Z<$.length)$[Z++]=X>>8&255;if(Z<$.length)$[Z++]=X&255}return $}function y2(J){let Q="",$=0;while($J.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function T2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function h4(){let J=T2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function x2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,N2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=h2(z.data[E2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function f2(J,Q){let $=x2(h4(),J);return Q==="utf8"||Q==="utf-8"?y2($):$}function v2(J,Q){let $=h4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var m2={title:"text-2xl text-white font-bold",section:"text-sm text-slate-600 font-bold",body:"text-base text-slate-900",bodyStrong:"text-base text-slate-900 font-bold",caption:"text-sm text-slate-500"};function u2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(F,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(F,{class:"flex-row items-center gap-4",get children(){return[p(()=>p(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(F,{get["class"](){return Q()}})),Y(R,{get["class"](){return m2.title},get children(){return J.title}})]}}),Y(F,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-sm text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-sm text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function l2(J){return Y(F,{get["class"](){return J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":"w-full h-full items-center justify-center rounded-xl bg-orange-600"},get children(){return Y(R,{get["class"](){return J.disabled?"text-base text-slate-500 font-bold":"text-base text-white font-bold"},get children(){return J.label}})}})}var TQ="‘’“”–—…•",y4=new Map,T4=new Map;function D0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=y4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return y4.set($,q),q}function p2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=D0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function $1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=T4.get(Z);if(q)return q;let X=[],z=D0(" ",Q);for(let G of J.split(` -`)){let P=G.split(" ").flatMap((B)=>B&&D0(B,Q)>$?p2(B,Q,$):[B]),D="",V=0;for(let B of P){let _=D0(B,Q);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return T4.set(Z,X),X}function x4(J,Q,$,Z){let q=$1(J,Q,$);if(q.length<=Z)return q.join(` +(()=>{var IJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return H1(this.context.count)},getNextContextId(){return H1(this.context.count++)}};function H1(J){let Q=String(J),$=Q.length-1;return IJ.context.id+($?String.fromCharCode(96+$):"")+Q}function B1(J){IJ.context=J}function Z6(){return{...IJ.context,id:IJ.getNextContextId(),count:0}}var q6=!1,X6=(J,Q)=>J===Q,k0=Symbol("solid-proxy"),Y6=typeof Proxy==="function",z6=Symbol("solid-track"),HQ=Symbol("solid-dev-component"),oJ={equals:X6},j1=null,W6=D1,m=1,yJ=2,K1={owned:null,cleanups:null,context:null,owner:null},S=null,K=null,TJ=null,AJ=null,b=null,w=null,y=null,nJ=0;function tJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?K1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>QJ(()=>$J(z)));S=z,b=null;try{return c(G,!0)}finally{b=$,S=Z}}function C(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return U1($,q)};return[M1.bind($),Z]}function JJ(J,Q,$){let Z=P1(J,Q,!1,m);if(TJ&&K&&K.running)w.push(Z);else eJ(Z)}function _J(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=P1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,TJ&&K&&K.running)Z.tState=m,w.push(Z);else eJ(Z);return M1.bind(Z)}function G6(J){return c(J,!1)}function QJ(J){if(!AJ&&b===null)return J();let Q=b;b=null;try{if(AJ)return AJ.untrack(J);return J()}finally{b=Q}}function S0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function H6(J){if(K&&K.running)return J(),K.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(TJ||B6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[BQ,F1]=C(!1),B6;function M1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)eJ(this);else{let Q=w;w=null,c(()=>J0(this),!1),w=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function U1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw w=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;$J(J);let Q=nJ;if(R1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{c(()=>{K&&(K.running=!0),b=S=J,R1(J,J.tValue,Q),b=S=null},!1)})}function R1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=m,J.tOwned&&J.tOwned.forEach($J),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach($J),J.owned=null;return J.updatedAt=$+1,g0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)U1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function P1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(S===null);else if(S!==K1)if(K&&K.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(AJ&&X.fn){let z=X.fn,[G,P]=C(void 0,{equals:!1}),D=AJ.factory(z,P);S0(()=>D.dispose());let V,B=()=>H6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),K&&K.running){if(!V)V=AJ.factory(z,B);return V.track(_)}return D.track(_)}}return X}function b0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===yJ)return J0(J);if(J.suspense&&QJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===m)eJ(J);else if((Q?J.tState:J.state)===yJ){let q=w;w=null,c(()=>J0(J,$[0]),!1),w=q}}}function c(J,Q){if(w)return J();let $=!1;if(!Q)w=[];if(y)$=!0;else y=[];nJ++;try{let Z=J();return j6($),Z}catch(Z){if(!$)y=null;w=null,g0(Z)}}function j6(J){if(w){if(TJ&&K&&K.running)K6(w);else D1(w);w=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;y.push.apply(y,K.effects),Q=K.resolve;for(let X of y)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,c(()=>{for(let X of q)$J(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zW6($),!1);if(Q)Q()}function D1(J){for(let Q=0;Q{Z.delete($),c(()=>{K.running=!0,b0($)},!1),K&&(K.running=!1)})}}function J0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)$J(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)L1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)$J(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function L1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return S0(()=>I1(X)),()=>{let P=J()||[],D=P.length,V,B;return P[z6],QJ(()=>{let N,h,a,GJ,VJ,M,j,H,L;if(D===0){if(z!==0)I1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[M6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=M&&H>=M&&Z[j]===P[H];j--,H--)a[H]=q[j],GJ[H]=X[j],G&&(VJ[H]=G[j]);N=new Map,h=Array(H+1);for(B=H;B>=M;B--)L=P[B],V=N.get(L),h[B]=V===void 0?-1:V,N.set(L,B);for(V=M;V<=j;V++)if(L=Z[V],B=N.get(L),B!==void 0&&B!==-1)a[B]=q[V],GJ[B]=X[V],G&&(VJ[B]=G[V]),B=h[B],N.set(L,B);else X[V]();for(B=M;BJ(Q||{}));return B1($),Z}}return QJ(()=>J(Q||{}))}function Q0(){return!0}var D6={get(J,Q,$){if(Q===k0)return $;return J.get(Q)},has(J,Q){if(Q===k0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function w0(J){return!(J=typeof J==="function"?J():J)?{}:J}function V6(){for(let J=0,Q=this.length;J=0;G--){let P=w0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in w0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:V6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var L6=(J)=>`Stale read from <${J}>.`;function kJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return _J(U6(()=>J.each,J.children,Q||void 0))}function SJ(J){let Q=J.keyed,$=_J(()=>J.when,void 0,void 0),Z=Q?$:_J($,void 0,{equals:(q,X)=>!q===!X});return _J(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?QJ(()=>X(Q?q:()=>{if(!QJ(Z))throw L6("Show");return $()})):X}return J.fallback},void 0,void 0)}var O6=(J)=>_J(()=>J());function I6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(M,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(M,j,L,H);JJ((A)=>B(M,j(),A,H),L)}function B(M,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=h(M,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(M),H=j);else h(M,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=h(M,H,L);else if(k==="function")return JJ(()=>{let O=j();while(typeof O==="function")O=O();H=B(M,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return JJ(()=>H=B(M,O,H,L,!0)),()=>H;if(O.length===0){let hJ=h(M,H,L);if(I)return H=hJ}else if(Array.isArray(H))if(H.length===0)a(M,O,L);else N(M,H,O);else if(H==null||H==="")a(M,O);else N(M,I&&H||[P(M)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(M,H,L,j);h(M,H,null,j)}else if(H==null||H===""||!P(M))q(M,j);else GJ(M,j,P(M));H=j}return H}function _(M,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let GQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let hJ=G(O)===M;if(!k&&!I)hJ?GJ(M,A,O):q(M,A,H);else hJ&&X(M,O)}else k=!0}}else q(M,A,H);return[A]}function a(M,j,H){for(let L=0,A=j.length;LH.children=B(M,j.children,H.children));return JJ(()=>j.ref&&j.ref(M)),JJ(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(M,A,k,H[A]),H[A]=k}}),H}return{render(M,j){let H;return tJ((L)=>{H=L,V(j,M())}),H},insert:V,spread(M,j,H){if(typeof j==="function")JJ((L)=>VJ(M,j(),L,H));else VJ(M,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(M,j,H,L){return z(M,j,H,L),H},mergeProps:A1,effect:JJ,memo:O6,createComponent:P6,use(M,j,H){return QJ(()=>M(j,H))}}}function A6(J){let Q=I6(J);return Q.mergeProps=A1,Q}var _1=480,k1=272,HJ={view:0,text:1,image:2},_6=1,k6=-1,S6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},b6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},g6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},w6=1,jQ=2,KQ=1,FQ=2,MQ=131072,UQ=1,RQ=262144,PQ=1,DQ=1,VQ=1,LQ=2,OQ=4,IQ=8,AQ=16,_Q=1,kQ=2;function S1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var SQ=1,C6=1263551300,E6=1,N6=32,h6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},BJ=32896,bQ=0.016666666666666666;function b1(J){return J.__viewport??null}var C0=null;function y6(){return null}function g1(J,Q=y6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function T6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return g1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return g1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function x6(J){C0=J}function bJ(){if(!C0)throw Error("PocketJS: host not installed — call render() first");return C0}function E(){return bJ().ops}function f6(J){globalThis.frame=J}function v6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function m6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return S1($>>>16&255,$>>>8&255,$&255,255);return S1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function u6(J,Q){let $=b6[J];if(typeof Q==="string"){if($===U.color)return m6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var $0=60,w1=[1,2,3,4,5,6,10,12,15,20,30,60],E0=$0,ZJ=-1,l6=0,xJ=[];function p6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=w1[0];for(let $ of w1)if(Math.abs($-J)Q.at<=ZJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>ZJ);for(let Q of J)Q.cb()}var N0=0.12,Z0=BJ;function s6(J){Z0=J===void 0?BJ:J&65535}function a6(){Z0=BJ}function N1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function o6(){return N1(Z0&255)}var h1=new Set,n6=0;function t6(){h1.clear(),n6=0,a6()}function e6(J){for(let Q of[...h1])Q(J)}var jJ=null,y1=null;function J8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function T1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function fJ(J){h0();let Q=jJ?jJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return y1.slice(Q.off,Q.off+Q.len)}var vJ=null,g=null,KJ=null,q0=0,FJ=[],T0=[],x0=[];function f1(J){if(vJ=J,g=null,KJ=null,q0=0,FJ.length=0,T0.length=0,x0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function $8(J,Q){J.onPress=Q??void 0}function Z8(J,Q){if(J.focusable=Q,p1(),!Q&&g===J)x(null)}function x(J){if(KJ&&KJ!==J)MJ(null);g=J,E().setFocus(J?J.id:0)}function MJ(J){if(KJ===J)return;let Q=E();if(KJ)Q.setActive?.(KJ.id,0);if(KJ=J,J)Q.setActive?.(J.id,1)}function f0(){return FJ.length>0?FJ[FJ.length-1]:vJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function Y8(){if(!g)return null;let J=f0();if(J&&!i(g,J))return null;for(let Q=T0.length-1;Q>=0;Q--){let $=T0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(g,$.node))return $}return null}function z8(J){let Q=Y8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(g)x(null);return!0}let Z=Q.columns,q=g?$.indexOf(g):-1;if(q<0)return x(v1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function W8(){if(!g)return null;let J=f0();if(J&&!i(g,J))return null;for(let Q=x0.length-1;Q>=0;Q--){let $=x0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(g,$.node))return $}return null}function X0(J){let Q=W8();if(Q&&Q.move(J))return;if(z8(J))return;X8(J)}function m1(){u1(g)}function u1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){MJ(J)}function G8(J){x(J),u1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=m0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,l1=0;function p1(){l1++}var B8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],j8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function K8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=B8[Q]>>$&1,q=j8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function F8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=fJ($.image)}catch(z){if(bJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):M8(Q,X),q<0&&bJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(K8(),16,16,g6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function M8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&w6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var W0=null;function c1(J){W0=J}function d1(J){let Q=FJ.length>0?FJ[FJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function i1(J,Q,$){return d1(s1(J,Q,$))}function s1(J,Q,$){if($!==void 0)return $===0?null:z0(W0??vJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(W0??vJ,q(J,Q))}function U8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=b1(q);if(Z.vw=B?B.w:_1,Z.vh=B?B.h:k1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)F8(Z,q);let X=r6()*Z.speed,z=o6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=c6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=l1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=d1(z0(W0??vJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==g)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(MJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,MJ(null),B)m1()}}else if($&Z.button)MJ(null);return!0}function R8(J){let Q=J&~q0,$=q0&~J;if(q0=J,l&&U8(J,Q,$))return;if($&d.CIRCLE)MJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)MJ(g),m1()}var u0=null;function a1(J){u0=J}function gJ(){if(p1(),u0)u0()}function P8(J,Q){J.debugName=Q||void 0,gJ()}var qJ={id:_6,type:HJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},r1=Symbol.for("pocketjs.native-node"),l0=1,mJ=3,o=8,D8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function G0(J){return J.domAttrs??={}}function o1(J,Q){let $=J.domNodeType??(uJ(J)?mJ:l0),Z=$===mJ?H0(J.text??""):$===o?O8(J.domData??""):Z4(J.domTag??j0(J));for(let q of Object.keys(J.domAttrs??{}))p0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)XJ(Z,o1(q,!0));return Z}function p0(J,Q,$){if(D8.has(Q)){CJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete G0(J)[Q];else G0(J)[Q]=$}function c0(J){if(J[r1]===!0)return J;return Object.defineProperty(J,r1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?mJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(uJ(J))B0(J,Z);else if(g8(J),Z)XJ(J,H0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return X4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??j0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===mJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??j0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){CJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===qJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return XJ(J,$),$},insertBefore($,Z){return XJ(J,$,Z??null),$},removeChild($){return lJ(J,$),$},replaceChild($,Z){return XJ(J,$,Z),lJ(J,Z),Z},cloneNode($=!1){return o1(J,!!$)},remove(){if(J.parent)lJ(J.parent,J)},setAttribute($,Z){p0(J,$,Z)},removeAttribute($){p0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(qJ);var d0=null;function V8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},n1=new Map;function t1(J,Q){n1.set(J,Q)}var e1=new Map;function J4(J,Q){e1.set(J,Q)}var wJ=new Set,L8=new Set;function Q4(J){if(!J)return!1;if(L8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function H0(J){let Q=E(),$=Q.createNode(HJ.text);return Q.setText($,J),c0({id:$,type:HJ.text,parent:null,children:[],text:J,domNodeType:mJ,domTag:"#text"})}function O8(J=""){let Q=H0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){E().replaceText(J.id,Q),J.text=Q,gJ()}function uJ(J){return J.type===HJ.text}function q4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function XJ(J,Q,$){let Z=E();if(q4(Q),wJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,gJ()}function lJ(J,Q){if(!Q)return;H8(Q),E().removeChild(J.id,Q.id),q4(Q),wJ.add(Q),gJ()}function I8(J){return J.parent??void 0}function A8(J){return J.children[0]}function X4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function _8(J,Q){let $=E();if(gJ(),Q==null||Q===""){$.setStyle(J.id,k6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(bJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function k8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=n1.get(Q);if(Z===void 0){if(bJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function S8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=e1.get(Q);if(Z===void 0){if(bJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function b8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=S6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,u6(G,P)),z=!0}if(z)gJ()}function CJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete G0(J)[Q];else G0(J)[Q]=$;switch(Q){case"class":return _8(J,$),$;case"onPress":case"on:press":return $8(J,$),$;case"src":return k8(J,$),$;case"sprite":return S8(J,$),$;case"style":return b8(J,$,Z),$;case"focusable":return Z8(J,!!$),$;case"debugName":return P8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${j0(J)}>`)}function g8(J){for(let Q of[...J.children])lJ(J,Q)}function j0(J){for(let Q of Object.keys(HJ))if(HJ[Q]===J.type)return Q;return String(J.type)}function w8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}CJ(J,Q,$,Z)}var C8=A6({createElement:Z4,createTextNode:H0,replaceText:B0,isTextNode:uJ,setProperty:w8,insertNode(J,Q,$){XJ(J,Q,$)},removeNode(J,Q){lJ(J,Q)},getParentNode:I8,getFirstChild:A8,getNextSibling:X4}),{render:E8,effect:gQ,memo:p,createComponent:Y,createElement:Y4,insert:wQ,spread:N8,mergeProps:CQ,use:EQ}=C8,NQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},h8=null;function z4(J){h8=J}function y8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function W4(J,Q){let $=Y4(J);return N8($,Q,!1),y8(Q.nodeRef,$),$}function F(J){return W4("view",J)}function R(J){return W4("text",J)}var hQ=new WeakMap,yQ=new WeakMap,T8={}!==null?Object.freeze({...{}}):Object.freeze({}),TQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:T8}),xQ=new Map,YJ=36000,s0=30,x8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(YJ),tapeAnalog:new Uint16Array(YJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function f8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-s0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)a1(()=>{W.treeDirty=!0}),i8();else a1(null);globalThis.__pocketDevtools=a8}function v8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)u8(),c8();let X=Q,z=$===void 0?BJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(YJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==BJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function B4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function j4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.masks,0,Q)}function K4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.analog??[],BJ,Q)}function F4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,T({t:"hello",app:W.app,host:s8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` +`))if(q.trim())l8(q)}}function l8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),a0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":M4();break;case"eval":{let Z=!0,q;try{q=K0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}T({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":T({t:"tape",tape:H4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}T({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=j4(Z),W.replayAnalog=Z.analog?K4(Z):null,W.replayTouch=Z.touch?F4(Z):null,W.replayAt=0;break}default:break}}function p8(){if(W.treeDirty&&W.frame-W.treeSentAt>=s0)M4();if(W.frame%x8===0)a0()}function c8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){T({t:"stats",frame:W.frame,nodes:P4(qJ),tapeLen:W.tapeLen,paused:W.paused})}function M4(){W.treeDirty=!1,W.treeSentAt=W.frame,T({t:"tree",frame:W.frame,root:R4(qJ)})}function d8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(d8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function U4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function R4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(U4(J,(q)=>{if(q.domNodeType===8)return;Z.push(R4(q))}),Z.length)Q.k=Z;return Q}function P4(J){let Q=1;return U4(J,($)=>{Q+=P4($)}),Q}function i8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{T({t:"log",level:$,args:q.map((X)=>K0(X))}),Z?.apply(Q,q)}}}function K0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?D4(X):JSON.stringify(D4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>K0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${K0(z,Q+1)}`).join(", ")}}`}function D4(J){return J.length>200?J.slice(0,199)+"…":J}function s8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var a8={get frame(){return W.frame},dumpTape:()=>H4(),replay:(J)=>{W.replayMasks=j4(J),W.replayAnalog=J.analog?K4(J):null,W.replayTouch=J.touch?F4(J):null,W.replayAt=0}},V4=new Map,o0=new Map;function L4(J){return J.trim().replace(/\s+/g," ")}function O4(J){return J.split(" ").sort().join(" ")}var I4=-1;function r8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=L4(Q);V4.set(Z,$);let q=O4(Z),X=o0.get(q);o0.set(q,X!==void 0&&X!==$?I4:$)}}function o8(J){let Q=L4(J),$=V4.get(Q);if($!==void 0)return $;let Z=o0.get(O4(Q));return Z===I4?void 0:Z}var n0=9,n8=(1<{let q=($&e8)!==0,X=q?t0:n0,z=q?J2:n8;return Object.freeze({id:$>>>(q?Q2:t8)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Z2(){return F0}function q2(){F0=e0}var A4=8,zJ=8,X2=3,Y2=8,z2=6,W2=0.5,s=1,pJ=2,J1=4,UJ=8,EJ=[],_4=0,M0=0,WJ=Array.from({length:A4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(zJ),histY:new Int16Array(zJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function G2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function H2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=s1(Q,$,Z.fact);let G=Z.hit;if(G)return G2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=EJ[z];if(G.disposed)continue;if(_4>0&&!G.opts.allowWhenBlocked)continue;if(!H2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function K2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%zJ,J.histLenz||Z>z))q.flags[J.slot]|=pJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(pJ|J1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??W2)*C1()));if(J.frames=0)EJ.splice($,1)},cancel(){if(!Q.disposed)b4(Q)},get panning(){for(let $ of WJ)if($.used&&Q.flags[$.slot]&UJ)return!0;return!1}}}function P2(J){let Q=R2(J);return S0(()=>Q.dispose()),Q}function g4(){EJ.length=0,_4=0,M0=0;for(let J of WJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function D2(){return P2({onDown:(J)=>{let Q=i1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=i1(J.x,J.y,J.hit);if(Q)G8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var V2=1,Q1=new Map,U0=[];function L2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function O2(){V2=1,Q1.clear(),U0=[]}function I2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),L2()?.({t:"delivery",frame:E1(),id:Q,kind:Z.kind}),Z.onResult($)}}var w4=new Set;function A2(){if(w4.size===0)return;for(let J of w4)J()}var _2={"text-lg text-orange-600 font-bold":0,"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":1,"w-[165] h-[76] items-center justify-center bg-orange-600":2,"w-[165] h-[76] items-center justify-center bg-slate-900":3,"text-sm text-white font-bold":4,"flex-col w-full h-full bg-slate-50":5,"h-[686] px-6 pt-7 flex-col gap-[22]":6,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":7,"h-[28] flex-row items-center gap-3":8,"w-[10] h-[10] rounded bg-orange-500":9,"text-sm text-orange-600 font-bold":10,"h-[76] pt-3 text-base text-slate-900":11,"h-[2] mx-1 my-4 bg-slate-100":12,"w-[10] h-[10] rounded bg-emerald-500":13,"text-sm text-emerald-700 font-bold":14,"h-[84] pt-3 text-base text-slate-900":15,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":16,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":17,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":18,"text-sm text-slate-600 font-bold":19,"pt-6 text-base text-slate-500":20,"pt-6 text-base text-slate-900 font-bold":21,"h-[146] px-6 pt-7 flex-col bg-slate-50":22,"h-[80]":23,"h-[1060] px-6 pt-5 flex-col":24,"h-[48] px-4 justify-center bg-slate-100":25,"text-sm text-slate-600":26,"pt-[10] flex-col gap-[12]":27,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":28,"w-[48] h-[48] items-center justify-center bg-blue-100":29,"w-[48] h-[48] items-center justify-center bg-emerald-100":30,"text-base text-blue-700 font-bold":31,"text-base text-emerald-700 font-bold":32,"w-[474] flex-col gap-2":33,"text-base text-slate-900 font-bold":34,"text-sm text-slate-500":35,"pt-20 pl-10 text-base text-slate-500":36,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":37,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":38,"h-[1060] px-6 pt-7 flex-col gap-4":39,"text-sm text-slate-500 font-bold":40,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":41,"flex-row items-center gap-5":42,"w-[68] h-[68] items-center justify-center bg-emerald-100":43,"text-xl text-emerald-700 font-bold":44,"flex-col gap-2":45,"text-lg text-slate-900 font-bold":46,"text-base text-slate-600":47,"text-2xl text-orange-600":48,"w-[68] h-[68] items-center justify-center bg-indigo-100":49,"text-xl text-indigo-700 font-bold":50,"mt-4 h-[112] px-6 justify-center bg-slate-100":51,"relative h-[154] px-5 pt-5 flex-col bg-white":52,"pt-3 text-base text-orange-600 font-bold":53,"pt-3 text-sm text-slate-500":54,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":55,"text-base text-white font-bold":56,"h-[40] pt-3 text-sm text-slate-500":57,"h-[470] flex-col gap-2":58,"h-[214] px-7 items-center justify-center bg-slate-100":59,"text-base text-slate-500 font-bold":60,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":61,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":62,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":63,"h-[160] px-5 pt-5 flex-col bg-white":64,"pt-3 text-base text-slate-900 font-bold":65,"pt-3 text-sm text-slate-600":66,"h-[108] pt-7 flex-row gap-4":67,"w-[316] h-[80] items-center justify-center bg-slate-100":68,"w-[340] h-[80] items-center justify-center bg-red-100":69,"text-base text-red-500 font-bold":70,"h-[1052] px-6 pt-5 flex-col":71,"h-[270] px-[22] pt-6 bg-white":72,"text-lg text-slate-900":73,"text-lg text-slate-400":74,"h-[86] px-1 flex-row items-center justify-between":75,"w-[132] h-[58] items-center justify-center bg-slate-100":76,"text-sm text-slate-900 font-bold":77,"h-[140] flex-row gap-2":78,"grow h-[120] items-center justify-center bg-white":79,"text-xl text-slate-900 font-bold":80,"w-[104] h-[120] items-center justify-center bg-slate-100":81,"h-[176] flex-row gap-2":82,"w-[92] h-[156] items-center justify-center bg-slate-100":83,"w-[300] h-[156] items-center justify-center bg-slate-100":84,"w-[144] h-[156] items-center justify-center bg-slate-100":85,"w-[112] h-[156] items-center justify-center bg-emerald-500":86,"text-sm text-slate-950 font-bold":87,"h-[108] px-6 py-3 flex-col bg-slate-50":88,"h-[84] items-center justify-center bg-slate-100":89,"h-[1168] px-6 pt-5 flex-col":90,"h-[82] px-4 justify-center bg-white":91,"w-[584] h-[900] px-5 pt-5 bg-slate-950":92,"text-sm text-slate-200":93,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":94,"text-base text-orange-600 font-bold":95,"w-[584] h-[900] px-5 pt-5 bg-white":96,"text-sm text-slate-900":97,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":98,"absolute inset-0 z-50 flex-col items-center justify-center":99,"absolute inset-0 bg-slate-950":100,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":101,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":102,"flex-row flex-wrap":103,grow:104,"text-2xl text-white font-bold":105,"text-base text-slate-900":106,"px-6":107,"px-6 py-5":108,"gap-4":109,"w-[34] h-[34] rounded-lg bg-amber-400":110,"w-[34] h-[34] rounded-lg bg-red-500":111,"w-[34] h-[34] rounded-lg bg-slate-800":112,"w-[34] h-[34] rounded-lg bg-emerald-500":113,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":114,"flex-row items-center gap-4":115,"w-[34] text-2xl text-white font-bold":116,"w-[332] flex-col items-end gap-2":117,"text-sm text-slate-300 font-bold":118,"text-sm text-slate-400":119,"h-[40] px-1 flex-row items-center justify-between":120,"w-full h-full items-center justify-center rounded-xl bg-slate-200":121,"w-full h-full items-center justify-center rounded-xl bg-orange-600":122};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var k2="ui:styles",S2="ui:font.",C4="ui:img.",E4="ui:sprite.";function b2(){return globalThis.ui}function g2(J){if(J.__textures)return;for(let Q of y0(C4)){let $=fJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)t1(Q.slice(C4.length),Z)}}function w2(J){if(J.__sprites)return;for(let Q of y0(E4)){let $=fJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)J4(Q.slice(E4.length),{handle:V,frames:G,cols:P,step:D})}}function N4(J){let Q=Y4("view");return CJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function C2(J,Q){if(!R0||!P0)return;CJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),CJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function E2(J,Q={}){let $=T6(Q.ops);if(x6($),V8(o8),Q.styles)r8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)t1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)J4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)x1(Q.pak);if(Q8()){for(let B of y0())if(B===k2)$.ops.loadStyles?.(fJ(B));else if(B.startsWith(S2))$.ops.loadFontAtlas?.(fJ(B))}}let q=b1($.ops),X=q?.w??_1,z=q?.h??k1,G=N4({width:X,height:z,overflow:u.Overflow.Hidden}),P=N4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});XJ(qJ,G),XJ(qJ,P),z4(P),R0=G,P0=P,f1(G),c1(qJ),t6(),g4(),D2(),d6(),O2(),f8($.ops),f6(v8((B,_,N,h)=>{i6(),s6(_),$2(N,h),A2(),I2(),U2(),e6(B),R8(B),$4()}));let D=E8(J,G),V=v6(C2);return()=>{V(),q2(),g4(),D(),f1(null),c1(null),z4(null),R0=null,P0=null;for(let B of qJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);$4()}}function N2(J,Q={}){let $=Q.ops??b2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)x1(Q.pak);return g2($),w2($),E2(J,{ops:$,styles:Q.styles??_2,pak:Q.pak})}var h2="$b",y2=65536,h4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",cJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function f2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function y4(){let J=f2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function v2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,y2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=T2(z.data[h2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function m2(J,Q){let $=v2(y4(),J);return Q==="utf8"||Q==="utf-8"?x2($):$}function u2(J,Q){let $=y4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var l2={title:"text-2xl text-white font-bold",section:"text-sm text-slate-600 font-bold",body:"text-base text-slate-900",bodyStrong:"text-base text-slate-900 font-bold",caption:"text-sm text-slate-500"};function p2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(F,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(F,{class:"flex-row items-center gap-4",get children(){return[p(()=>p(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(F,{get["class"](){return Q()}})),Y(R,{get["class"](){return l2.title},get children(){return J.title}})]}}),Y(F,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-sm text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-sm text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function c2(J){return Y(F,{get["class"](){return J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":"w-full h-full items-center justify-center rounded-xl bg-orange-600"},get children(){return Y(R,{get["class"](){return J.disabled?"text-base text-slate-500 font-bold":"text-base text-white font-bold"},get children(){return J.label}})}})}var fQ="‘’“”–—…•",T4=new Map,x4=new Map;function D0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=T4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return T4.set($,q),q}function d2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=D0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function $1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=x4.get(Z);if(q)return q;let X=[],z=D0(" ",Q);for(let G of J.split(` +`)){let P=G.split(" ").flatMap((B)=>B&&D0(B,Q)>$?d2(B,Q,$):[B]),D="",V=0;for(let B of P){let _=D0(B,Q);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return x4.set(Z,X),X}function f4(J,Q,$,Z){let q=$1(J,Q,$);if(q.length<=Z)return q.join(` `);let X=q.slice(0,Z);return X[Z-1]=X[Z-1].replace(/[\s.]+$/,"")+"…",X.join(` -`)}var f4=2,v4=1,m4=536,u4=544,l4=46,[RJ,c2]=C({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[f,n]=C("chat"),[V0,d2]=C("chat"),[Z1,p4]=C(0),[t,c4]=C(""),[dJ,NJ]=C(0),[iJ,q1]=C([]),[i2,L0]=C(""),[d4,O0]=C(null),[i4,s4]=C(null),[I0,A0]=C(0),[v,e]=C(""),[PJ,a4]=C("letters"),[X1,Y1]=C(!1),[z1,r4]=C({type:"prompt"}),[sJ,o4]=C(0),W1=new Map,n4=["qwertyuiop","asdfghjkl","zxcvbnm"],t4=["1234567890","-/:;()$&@",`.,?!'"+`],e4=["chat","files","apps","settings"];function s2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function a2(J,Q){return J?J+"/"+Q:Q}function aJ(J=t(),Q=!1){let $=W1.get(J);if(!Q&&$){q1($),L0(""),NJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=v2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));W1.set(J,Z),q1(Z),L0(""),NJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){q1([]),L0(Z instanceof Error?Z.message:String(Z))}}function r2(){let J=[];for(let Q of RJ().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function J6(){let J=r2(),Q=Math.max(0,J.length-2),$=Math.min(Z1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function DJ(J){return Y(u2,{get title(){return J.title},get accent(){return p(()=>RJ().agent==="FAULTED")()?"danger":RJ().agent==="THINKING"?"busy":"ready"}})}function rJ(J){return[Y(F,{get["class"](){return J.top},get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",children:"UP"})}}),Y(F,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",children:"DN"})}})]}function _0(){return Y(F,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(kJ,{each:e4,children:(J)=>Y(F,{get["class"](){return V0()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-sm text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function o2(){let J=()=>RJ().schedule;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"ESP32 PI AGENT"}),Y(F,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(kJ,{get each(){return J6()},children:(Q)=>Y(F,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-sm text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-base text-slate-900",get children(){return x4(Q.user,f4,m4,3)}}),Y(F,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-sm text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-base text-slate-900",get children(){return x4(Q.assistant,f4,m4,3)}})]}})}),Y(rJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(F,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-sm text-slate-600 font-bold",children:"NEXT WAKE"}),Y(SJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-base text-slate-500",children:`NO WAKE SCHEDULED +`)}var v4=2,m4=1,u4=536,l4=544,p4=46,[RJ,i2]=C({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[f,n]=C("chat"),[V0,s2]=C("chat"),[Z1,c4]=C(0),[t,d4]=C(""),[dJ,NJ]=C(0),[iJ,q1]=C([]),[a2,L0]=C(""),[i4,O0]=C(null),[s4,a4]=C(null),[I0,A0]=C(0),[v,e]=C(""),[PJ,r4]=C("letters"),[X1,Y1]=C(!1),[z1,o4]=C({type:"prompt"}),[sJ,n4]=C(0),W1=new Map,t4=["qwertyuiop","asdfghjkl","zxcvbnm"],e4=["1234567890","-/:;()$&@",`.,?!'"+`],J6=["chat","files","apps","settings"];function r2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function o2(J,Q){return J?J+"/"+Q:Q}function aJ(J=t(),Q=!1){let $=W1.get(J);if(!Q&&$){q1($),L0(""),NJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=u2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));W1.set(J,Z),q1(Z),L0(""),NJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){q1([]),L0(Z instanceof Error?Z.message:String(Z))}}function n2(){let J=[];for(let Q of RJ().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Q6(){let J=n2(),Q=Math.max(0,J.length-2),$=Math.min(Z1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function DJ(J){return Y(p2,{get title(){return J.title},get accent(){return p(()=>RJ().agent==="FAULTED")()?"danger":RJ().agent==="THINKING"?"busy":"ready"}})}function rJ(J){return[Y(F,{get["class"](){return J.top},get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",children:"UP"})}}),Y(F,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",children:"DN"})}})]}function _0(){return Y(F,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(kJ,{each:J6,children:(J)=>Y(F,{get["class"](){return V0()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-sm text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function t2(){let J=()=>RJ().schedule;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"ESP32 PI AGENT"}),Y(F,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(kJ,{get each(){return Q6()},children:(Q)=>Y(F,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-sm text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-base text-slate-900",get children(){return f4(Q.user,v4,u4,3)}}),Y(F,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-sm text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-base text-slate-900",get children(){return f4(Q.assistant,v4,u4,3)}})]}})}),Y(rJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(F,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-sm text-slate-600 font-bold",children:"NEXT WAKE"}),Y(SJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-base text-slate-500",children:`NO WAKE SCHEDULED ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(R,{class:"pt-6 text-base text-slate-900 font-bold",get children(){return String(J()?.name)+" "+String(J()?.next??"")+` -`+String(J()?.prompt??"")}})}})]}}),Y(F,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(F,{class:"h-[80]",get children(){return Y(l2,{label:"TYPE A MESSAGE"})}})}}),Y(_0,{})]}})}function n2(){let J=()=>iJ().slice(dJ(),dJ()+8);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{get title(){return t()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-600",get children(){return"/workspace"+(t()?"/"+t():"")}})}}),Y(F,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(kJ,{get each(){return J()},children:(Q)=>Y(F,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(F,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-base text-blue-700 font-bold":"text-base text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(F,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,60)}}),Y(R,{class:"text-sm text-slate-500",get children(){return p(()=>Q.kind==="dir")()?"FOLDER":s2(Q.size)}})]}})]}})})}}),Y(SJ,{get when(){return iJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-base text-slate-500",get children(){return i2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(SJ,{get when(){return iJ().length>8},get children(){return Y(rJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(_0,{})]}})}function t2(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"APPS"}),Y(F,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-sm text-slate-500 font-bold",children:"2 INSTALLED APPS"}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-emerald-100",get children(){return Y(R,{class:"text-xl text-emerald-700 font-bold",children:"R"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"Robinhood"}),Y(R,{class:"text-base text-slate-600",children:"Portfolio and positions"}),Y(R,{class:"text-sm text-slate-500",children:"UPDATES EVERY 5 MINUTES"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-indigo-100",get children(){return Y(R,{class:"text-xl text-indigo-700 font-bold",children:"E"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"Exa Research"}),Y(R,{class:"text-base text-slate-600",children:"Agent search history"}),Y(R,{class:"text-sm text-slate-500",children:"STORED LOCALLY IN SQLITE"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-600",children:`APP DATA STAYS ISOLATED. -PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(_0,{})]}})}function e2(){let J=()=>RJ().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(sJ(),sJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"SETTINGS"}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-base text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-sm text-slate-500",get children(){return Z()}}),Y(F,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-sm text-slate-500",children:"AVAILABLE NETWORKS"}),Y(F,{class:"h-[470] flex-col gap-2",get children(){return[Y(SJ,{get when(){return $().length>0},get fallback(){return Y(F,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-500 font-bold",children:`NO NETWORK LIST YET +`+String(J()?.prompt??"")}})}})]}}),Y(F,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(F,{class:"h-[80]",get children(){return Y(c2,{label:"TYPE A MESSAGE"})}})}}),Y(_0,{})]}})}function e2(){let J=()=>iJ().slice(dJ(),dJ()+8);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{get title(){return t()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-600",get children(){return"/workspace"+(t()?"/"+t():"")}})}}),Y(F,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(kJ,{get each(){return J()},children:(Q)=>Y(F,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(F,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-base text-blue-700 font-bold":"text-base text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(F,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,60)}}),Y(R,{class:"text-sm text-slate-500",get children(){return p(()=>Q.kind==="dir")()?"FOLDER":r2(Q.size)}})]}})]}})})}}),Y(SJ,{get when(){return iJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-base text-slate-500",get children(){return a2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(SJ,{get when(){return iJ().length>8},get children(){return Y(rJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(_0,{})]}})}function JQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"APPS"}),Y(F,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-sm text-slate-500 font-bold",children:"2 INSTALLED APPS"}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-emerald-100",get children(){return Y(R,{class:"text-xl text-emerald-700 font-bold",children:"R"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"Robinhood"}),Y(R,{class:"text-base text-slate-600",children:"Portfolio and positions"}),Y(R,{class:"text-sm text-slate-500",children:"UPDATES EVERY 5 MINUTES"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-indigo-100",get children(){return Y(R,{class:"text-xl text-indigo-700 font-bold",children:"E"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"Exa Research"}),Y(R,{class:"text-base text-slate-600",children:"Agent search history"}),Y(R,{class:"text-sm text-slate-500",children:"STORED LOCALLY IN SQLITE"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-600",children:`APP DATA STAYS ISOLATED. +PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(_0,{})]}})}function QQ(){let J=()=>RJ().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(sJ(),sJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"SETTINGS"}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-base text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-sm text-slate-500",get children(){return Z()}}),Y(F,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-sm text-slate-500",children:"AVAILABLE NETWORKS"}),Y(F,{class:"h-[470] flex-col gap-2",get children(){return[Y(SJ,{get when(){return $().length>0},get fallback(){return Y(F,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-500 font-bold",children:`NO NETWORK LIST YET -TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(kJ,{get each(){return $()},children:(q)=>Y(F,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-sm text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(SJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(rJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(F,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-sm text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-base text-slate-900 font-bold",get children(){return RJ().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-sm text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(F,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(F,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(F,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-base text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(_0,{})]}})}function JQ(){let J=()=>z1(),Q=()=>PJ()==="letters"?n4:t4,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(F,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(F,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-sm text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(F,{class:"w-[132] h-[58] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(kJ,{get each(){return Q()},children:(Z,q)=>Y(F,{class:"h-[140] flex-row gap-2",get children(){return[Y(kJ,{get each(){return Z.split("")},children:(X)=>Y(F,{class:"grow h-[120] items-center justify-center bg-white",get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return p(()=>!!X1())()?X.toUpperCase():X}})}})}),Y(SJ,{get when(){return q()===2},get children(){return Y(F,{class:"w-[104] h-[120] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(F,{class:"h-[176] flex-row gap-2",get children(){return[Y(F,{class:"w-[92] h-[156] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",get children(){return PJ()==="letters"?"123":"ABC"}})}}),Y(F,{class:"w-[300] h-[156] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"SPACE"})}}),Y(F,{class:"w-[144] h-[156] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",get children(){return PJ()==="letters"?"SHIFT":". ?"}})}}),Y(F,{class:"w-[112] h-[156] items-center justify-center bg-emerald-500",get children(){return Y(R,{class:"text-sm text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(F,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(F,{class:"h-[84] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function QQ(){let J=()=>d4(),Q=()=>(J()?.text??"").split(` +TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(kJ,{get each(){return $()},children:(q)=>Y(F,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-sm text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(SJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(rJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(F,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-sm text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-base text-slate-900 font-bold",get children(){return RJ().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-sm text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(F,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(F,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(F,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-base text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(_0,{})]}})}function $Q(){let J=()=>z1(),Q=()=>PJ()==="letters"?t4:e4,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(F,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(F,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-sm text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(F,{class:"w-[132] h-[58] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(kJ,{get each(){return Q()},children:(Z,q)=>Y(F,{class:"h-[140] flex-row gap-2",get children(){return[Y(kJ,{get each(){return Z.split("")},children:(X)=>Y(F,{class:"grow h-[120] items-center justify-center bg-white",get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return p(()=>!!X1())()?X.toUpperCase():X}})}})}),Y(SJ,{get when(){return q()===2},get children(){return Y(F,{class:"w-[104] h-[120] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(F,{class:"h-[176] flex-row gap-2",get children(){return[Y(F,{class:"w-[92] h-[156] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",get children(){return PJ()==="letters"?"123":"ABC"}})}}),Y(F,{class:"w-[300] h-[156] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"SPACE"})}}),Y(F,{class:"w-[144] h-[156] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",get children(){return PJ()==="letters"?"SHIFT":". ?"}})}}),Y(F,{class:"w-[112] h-[156] items-center justify-center bg-emerald-500",get children(){return Y(R,{class:"text-sm text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(F,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(F,{class:"h-[84] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function ZQ(){let J=()=>i4(),Q=()=>(J()?.text??"").split(` `),$=()=>J()?.lineOffset??0;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"< FILE VIEWER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(R,{class:"text-sm text-slate-200",get children(){return Q().slice($(),$()+39).join(` -`)}})}}),Y(R,{class:"pt-3 text-sm text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(rJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function $Q(){let J=()=>i4(),Q=()=>$1(J()?.text??"",v4,u4);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"< MESSAGE READER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-base text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-sm text-slate-900",get children(){return Q().slice(I0(),I0()+l4).join(` -`)}})}}),Y(rJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function ZQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return p(()=>f()==="chat")()?Y(o2,{}):p(()=>f()==="files")()?Y(n2,{}):p(()=>f()==="apps")()?Y(t2,{}):p(()=>f()==="settings")()?Y(e2,{}):p(()=>f()==="keyboard")()?Y(JQ,{}):p(()=>f()==="viewer")()?Y(QQ,{}):Y($Q,{})}})}function qQ(J){W6(()=>{if(d2(J),n(J),J==="files")aJ()})}function XQ(J,Q){let $=PJ()==="letters"?n4:t4,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return e(""),n(V0()),"";if(J>=548&&Q>=402&&Q<=482)return e(""),"";let $=XQ(J,Q);if($){let Z=PJ()==="letters"&&X1()?$.toUpperCase():$,q=z1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return e(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)a4(PJ()==="letters"?"numbers":"letters"),Y1(!1);else if(J<=424){if(v())e(v()+" ")}else if(J<=576)if(PJ()==="letters")Y1(!X1());else e(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=z1();if(e(""),a4("letters"),Y1(!1),n(V0()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}C2(()=>Y(ZQ,{})),queueMicrotask(()=>aJ("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return c2(JSON.parse(J)),""},dataChanged(){if(W1.delete(t()),V0()==="files")aJ(t(),!0);return""},invokeTool(){return JSON.stringify({text:"Pi Agent has no App tools",isError:!0})},invokeTask(){return JSON.stringify({text:"Pi Agent has no App tasks",isError:!0})},tap(J,Q){if(f()==="keyboard")return YQ(J,Q);if(f()==="viewer"){let $=d4();if(J<104&&Q<112)O0(null),n("files");else if($&&J>=620&&Q>=170&&Q<=340)O0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)O0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` -`).length-39),$.lineOffset+18)});return""}if(f()==="reader"){if(J<104&&Q<112)s4(null),A0(0),n("chat");else if(J>=620&&Q>=170&&Q<=340)A0(Math.max(0,I0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=$1(i4()?.text??"",v4,u4).length;A0(Math.min(Math.max(0,$-l4),I0()+18))}return""}if(Q>=1172)return qQ(e4[Math.min(3,Math.floor(J/180))]),"";if(f()==="chat"){if(J>=620&&Q>=140&&Q<=272)p4(Z1()+2);else if(J>=620&&Q>=624&&Q<=756)p4(Math.max(0,Z1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=J6()[$];if(Z){let q=Q>=140+$*320+150;s4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),A0(0),n("reader")}}else if(Q>=1070&&Q<=1150)r4({type:"prompt"}),e(""),n("keyboard");return""}if(f()==="files"){if(J<104&&Q<112&&t()){let $=t().split("/");$.pop();let Z=$.join("/");c4(Z),NJ(0),aJ(Z)}else if(J>=620&&Q>=170&&Q<=340)NJ(Math.max(0,dJ()-4));else if(J>=620&&Q>=920&&Q<=1100)NJ(Math.min(Math.max(0,iJ().length-8),dJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=iJ()[dJ()+$];if(Z){let q=a2(t(),Z.name);if(Z.kind==="dir")c4(q),NJ(0),aJ(q);else try{O0({path:"/workspace/"+q,text:f2(q,"utf8"),lineOffset:0}),n("viewer")}catch(X){L0(X instanceof Error?X.message:String(X))}}}return""}if(f()==="apps"){if(Q>=162&&Q<324)return JSON.stringify({type:"navigate",app:"robinhood"});if(Q>=324&&Q<490)return JSON.stringify({type:"navigate",app:"exa"});return""}if(f()==="settings"){let $=RJ().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)o4(Math.max(0,sJ()-4));else if(J>=620&&Q>=650&&Q<=782)o4(Math.min(Math.max(0,$.length-5),sJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[sJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});r4({type:"wifi",ssid:q.ssid}),e(""),n("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); +`)}})}}),Y(R,{class:"pt-3 text-sm text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(rJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function qQ(){let J=()=>s4(),Q=()=>$1(J()?.text??"",m4,l4);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"< MESSAGE READER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-base text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-sm text-slate-900",get children(){return Q().slice(I0(),I0()+p4).join(` +`)}})}}),Y(rJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function XQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return p(()=>f()==="chat")()?Y(t2,{}):p(()=>f()==="files")()?Y(e2,{}):p(()=>f()==="apps")()?Y(JQ,{}):p(()=>f()==="settings")()?Y(QQ,{}):p(()=>f()==="keyboard")()?Y($Q,{}):p(()=>f()==="viewer")()?Y(ZQ,{}):Y(qQ,{})}})}function YQ(J){G6(()=>{if(s2(J),n(J),J==="files")aJ()})}function zQ(J,Q){let $=PJ()==="letters"?t4:e4,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return e(""),n(V0()),"";if(J>=548&&Q>=402&&Q<=482)return e(""),"";let $=zQ(J,Q);if($){let Z=PJ()==="letters"&&X1()?$.toUpperCase():$,q=z1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return e(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)r4(PJ()==="letters"?"numbers":"letters"),Y1(!1);else if(J<=424){if(v())e(v()+" ")}else if(J<=576)if(PJ()==="letters")Y1(!X1());else e(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=z1();if(e(""),r4("letters"),Y1(!1),n(V0()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}N2(()=>Y(XQ,{})),queueMicrotask(()=>aJ("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return i2(JSON.parse(J)),""},dataChanged(){if(W1.delete(t()),V0()==="files")aJ(t(),!0);return""},invokeTool(){return JSON.stringify({text:"Pi Agent has no App tools",isError:!0})},invokeTask(){return JSON.stringify({text:"Pi Agent has no App tasks",isError:!0})},tap(J,Q){if(f()==="keyboard")return WQ(J,Q);if(f()==="viewer"){let $=i4();if(J<104&&Q<112)O0(null),n("files");else if($&&J>=620&&Q>=170&&Q<=340)O0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)O0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` +`).length-39),$.lineOffset+18)});return""}if(f()==="reader"){if(J<104&&Q<112)a4(null),A0(0),n("chat");else if(J>=620&&Q>=170&&Q<=340)A0(Math.max(0,I0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=$1(s4()?.text??"",m4,l4).length;A0(Math.min(Math.max(0,$-p4),I0()+18))}return""}if(Q>=1172)return YQ(J6[Math.min(3,Math.floor(J/180))]),"";if(f()==="chat"){if(J>=620&&Q>=140&&Q<=272)c4(Z1()+2);else if(J>=620&&Q>=624&&Q<=756)c4(Math.max(0,Z1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=Q6()[$];if(Z){let q=Q>=140+$*320+150;a4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),A0(0),n("reader")}}else if(Q>=1070&&Q<=1150)o4({type:"prompt"}),e(""),n("keyboard");return""}if(f()==="files"){if(J<104&&Q<112&&t()){let $=t().split("/");$.pop();let Z=$.join("/");d4(Z),NJ(0),aJ(Z)}else if(J>=620&&Q>=170&&Q<=340)NJ(Math.max(0,dJ()-4));else if(J>=620&&Q>=920&&Q<=1100)NJ(Math.min(Math.max(0,iJ().length-8),dJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=iJ()[dJ()+$];if(Z){let q=o2(t(),Z.name);if(Z.kind==="dir")d4(q),NJ(0),aJ(q);else try{O0({path:"/workspace/"+q,text:m2(q,"utf8"),lineOffset:0}),n("viewer")}catch(X){L0(X instanceof Error?X.message:String(X))}}}return""}if(f()==="apps"){if(Q>=162&&Q<324)return JSON.stringify({type:"navigate",app:"robinhood"});if(Q>=324&&Q<490)return JSON.stringify({type:"navigate",app:"exa"});return""}if(f()==="settings"){let $=RJ().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)n4(Math.max(0,sJ()-4));else if(J>=620&&Q>=650&&Q<=782)n4(Math.min(Math.max(0,$.length-5),sJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[sJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});o4({type:"wifi",ssid:q.ssid}),e(""),n("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); diff --git a/apps/robinhood/dist/app.js b/apps/robinhood/dist/app.js index f844129..b959b48 100644 --- a/apps/robinhood/dist/app.js +++ b/apps/robinhood/dist/app.js @@ -1,5 +1,5 @@ -(()=>{var _J={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return U1(this.context.count)},getNextContextId(){return U1(this.context.count++)}};function U1(J){let Q=String(J),$=Q.length-1;return _J.context.id+($?String.fromCharCode(96+$):"")+Q}function M1(J){_J.context=J}function G6(){return{..._J.context,id:_J.getNextContextId(),count:0}}var H6=!1,j6=(J,Q)=>J===Q,_0=Symbol("solid-proxy"),F6=typeof Proxy==="function",B6=Symbol("solid-track"),RQ=Symbol("solid-dev-component"),nJ={equals:j6},V1=null,K6=k1,p=1,EJ=2,P1={owned:null,cleanups:null,context:null,owner:null},S=null,B=null,bJ=null,AJ=null,f=null,h=null,N=null,oJ=0;function tJ(J,Q){let $=f,Z=S,X=J.length===0,W=Q===void 0?Z:Q,z=X?P1:{owned:null,cleanups:null,context:W?W.context:null,owner:W},F=X?J:()=>J(()=>WJ(()=>qJ(z)));S=z,f=null;try{return r(F,!0)}finally{f=$,S=Z}}function E(J,Q){Q=Q?Object.assign({},nJ,Q):nJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return O1($,X)};return[R1.bind($),Z]}function XJ(J,Q,$){let Z=I1(J,Q,!1,p);if(bJ&&B&&B.running)h.push(Z);else J0(Z)}function QJ(J,Q,$){$=$?Object.assign({},nJ,$):nJ;let Z=I1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,bJ&&B&&B.running)Z.tState=p,h.push(Z);else J0(Z);return R1.bind(Z)}function eJ(J){return r(J,!1)}function WJ(J){if(!AJ&&f===null)return J();let Q=f;f=null;try{if(AJ)return AJ.untrack(J);return J()}finally{f=Q}}function A0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function U6(J){if(B&&B.running)return J(),B.done;let Q=f,$=S;return Promise.resolve().then(()=>{f=Q,S=$;let Z;if(bJ||M6)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return r(J,!1),f=S=null,Z?Z.done:void 0})}var[OQ,D1]=E(!1),M6;function R1(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===p)J0(this);else{let Q=h;h=null,r(()=>Q0(this),!1),h=Q}if(f){let Q=this.observers;if(!Q||Q[Q.length-1]!==f){let $=Q?Q.length:0;if(!f.sources)f.sources=[this],f.sourceSlots=[$];else f.sources.push(this),f.sourceSlots.push($);if(!Q)this.observers=[f],this.observerSlots=[f.sources.length-1];else Q.push(f),this.observerSlots.push(f.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function O1(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)r(()=>{for(let X=0;X1e6)throw h=[],Error()},!1)}return Q}function J0(J){if(!J.fn)return;qJ(J);let Q=oJ;if(L1(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{r(()=>{B&&(B.running=!0),f=S=J,L1(J,J.tValue,Q),f=S=null},!1)})}function L1(J,Q,$){let Z,X=S,W=f;f=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(B&&B.running)J.tState=p,J.tOwned&&J.tOwned.forEach(qJ),J.tOwned=void 0;else J.state=p,J.owned&&J.owned.forEach(qJ),J.owned=null;return J.updatedAt=$+1,S0(z)}finally{f=W,S=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)O1(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function I1(J,Q,$,Z=p,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(S===null);else if(S!==P1)if(B&&B.running&&S.pure)if(!S.tOwned)S.tOwned=[W];else S.tOwned.push(W);else if(!S.owned)S.owned=[W];else S.owned.push(W);if(AJ&&W.fn){let z=W.fn,[F,P]=E(void 0,{equals:!1}),D=AJ.factory(z,P);A0(()=>D.dispose());let U,H=()=>U6(P).then(()=>{if(U)U.dispose(),U=void 0});W.fn=(w)=>{if(F(),B&&B.running){if(!U)U=AJ.factory(z,H);return U.track(w)}return D.track(w)}}return W}function w0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===EJ)return Q0(J);if(J.suspense&&WJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===p)J0(J);else if((Q?J.tState:J.state)===EJ){let X=h;h=null,r(()=>Q0(J,$[0]),!1),h=X}}}function r(J,Q){if(h)return J();let $=!1;if(!Q)h=[];if(N)$=!0;else N=[];oJ++;try{let Z=J();return V6($),Z}catch(Z){if(!$)N=null;h=null,S0(Z)}}function V6(J){if(h){if(bJ&&B&&B.running)P6(h);else k1(h);h=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;N.push.apply(N,B.effects),Q=B.resolve;for(let W of N)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,r(()=>{for(let W of X)qJ(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let z=0,F=W.owned.length;zK6($),!1);if(Q)Q()}function k1(J){for(let Q=0;Q{Z.delete($),r(()=>{B.running=!0,w0($)},!1),B&&(B.running=!1)})}}function Q0(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)qJ(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)A1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)qJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function A1(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return A0(()=>S1(W)),()=>{let P=J()||[],D=P.length,U,H;return P[B6],WJ(()=>{let C,g,A,s,a,K,j,G,V;if(D===0){if(z!==0)S1(W),W=[],Z=[],X=[],z=0,F&&(F=[]);if($.fallback)Z=[R6],X[0]=tJ((k)=>{return W[0]=k,$.fallback()}),z=1}else if(z===0){X=Array(D);for(H=0;H=K&&G>=K&&Z[j]===P[G];j--,G--)A[G]=X[j],s[G]=W[j],F&&(a[G]=F[j]);C=new Map,g=Array(G+1);for(H=G;H>=K;H--)V=P[H],U=C.get(V),g[H]=U===void 0?-1:U,C.set(V,H);for(U=K;U<=j;U++)if(V=Z[U],H=C.get(V),H!==void 0&&H!==-1)A[H]=X[U],s[H]=W[U],F&&(a[H]=F[U]),H=g[H],C.set(V,H);else W[U]();for(H=K;HJ(Q||{}));return M1($),Z}}return WJ(()=>J(Q||{}))}function $0(){return!0}var k6={get(J,Q,$){if(Q===_0)return $;return J.get(Q)},has(J,Q){if(Q===_0)return!0;return J.has(Q)},set:$0,deleteProperty:$0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:$0,deleteProperty:$0}},ownKeys(J){return J.keys()}};function y0(J){return!(J=typeof J==="function"?J():J)?{}:J}function _6(){for(let J=0,Q=this.length;J=0;F--){let P=y0(J[F])[z];if(P!==void 0)return P}},has(z){for(let F=J.length-1;F>=0;F--)if(z in y0(J[F]))return!0;return!1},keys(){let z=[];for(let F=0;F=0;z--){let F=J[z];if(!F)continue;let P=Object.getOwnPropertyNames(F);for(let D=P.length-1;D>=0;D--){let U=P[D];if(U==="__proto__"||U==="constructor")continue;let H=Object.getOwnPropertyDescriptor(F,U);if(!Z[U])Z[U]=H.get?{enumerable:!0,configurable:!0,get:_6.bind($[U]=[H.get.bind(F)])}:H.value!==void 0?H:void 0;else{let w=$[U];if(w){if(H.get)w.push(H.get.bind(F));else if(H.value!==void 0)w.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let z=W.length-1;z>=0;z--){let F=W[z],P=Z[F];if(P&&P.get)Object.defineProperty(X,F,P);else X[F]=P?P.value:void 0}return X}var A6=(J)=>`Stale read from <${J}>.`;function NJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return QJ(O6(()=>J.each,J.children,Q||void 0))}function Z0(J){let Q=J.keyed,$=QJ(()=>J.when,void 0,void 0),Z=Q?$:QJ($,void 0,{equals:(X,W)=>!X===!W});return QJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?WJ(()=>W(Q?X:()=>{if(!WJ(Z))throw A6("Show");return $()})):W}return J.fallback},void 0,void 0)}var w6=(J)=>QJ(()=>J());function S6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:z,getParentNode:F,getFirstChild:P,getNextSibling:D}){function U(K,j,G,V){if(G!==void 0&&!V)V=[];if(typeof j!=="function")return H(K,j,V,G);XJ((k)=>H(K,j(),k,G),V)}function H(K,j,G,V,k){while(typeof G==="function")G=G();if(j===G)return G;let _=typeof j,I=V!==void 0;if(_==="string"||_==="number"){if(_==="number")j=j.toString();if(I){let O=G[0];if(O&&$(O))Z(O,j);else O=Q(j);G=g(K,G,V,O)}else if(G!==""&&typeof G==="string")Z(P(K),G=j);else g(K,G,V,Q(j)),G=j}else if(j==null||_==="boolean")G=g(K,G,V);else if(_==="function")return XJ(()=>{let O=j();while(typeof O==="function")O=O();G=H(K,O,G,V)}),()=>G;else if(Array.isArray(j)){let O=[];if(w(O,j,k))return XJ(()=>G=H(K,O,G,V,!0)),()=>G;if(O.length===0){let hJ=g(K,G,V);if(I)return G=hJ}else if(Array.isArray(G))if(G.length===0)A(K,O,V);else C(K,G,O);else if(G==null||G==="")A(K,O);else C(K,I&&G||[P(K)],O);G=O}else{if(Array.isArray(G)){if(I)return G=g(K,G,V,j);g(K,G,null,j)}else if(G==null||G===""||!P(K))X(K,j);else s(K,j,P(K));G=j}return G}function w(K,j,G){let V=!1;for(let k=0,_=j.length;k<_;k++){let I=j[k],O;if(I==null||I===!0||I===!1);else if(Array.isArray(I))V=w(K,I)||V;else if((O=typeof I)==="string"||O==="number")K.push(Q(I));else if(O==="function")if(G){while(typeof I==="function")I=I();V=w(K,Array.isArray(I)?I:[I])||V}else K.push(I),V=!0;else K.push(I)}return V}function C(K,j,G){let V=G.length,k=j.length,_=V,I=0,O=0,hJ=D(j[k-1]),IJ=null;while(IJJ-O){let DQ=j[I];while(O=0;I--){let O=j[I];if(k!==O){let hJ=F(O)===K;if(!_&&!I)hJ?s(K,k,O):X(K,k,G);else hJ&&W(K,O)}else _=!0}}else X(K,k,G);return[k]}function A(K,j,G){for(let V=0,k=j.length;VG.children=H(K,j.children,G.children));return XJ(()=>j.ref&&j.ref(K)),XJ(()=>{for(let k in j){if(k==="children"||k==="ref")continue;let _=j[k];if(_===G[k])continue;z(K,k,_,G[k]),G[k]=_}}),G}return{render(K,j){let G;return tJ((V)=>{G=V,U(j,K())}),G},insert:U,spread(K,j,G){if(typeof j==="function")XJ((V)=>a(K,j(),V,G));else a(K,j,void 0,G)},createElement:J,createTextNode:Q,insertNode:X,setProp(K,j,G,V){return z(K,j,G,V),G},mergeProps:y1,effect:XJ,memo:w6,createComponent:I6,use(K,j,G){return WJ(()=>K(j,G))}}}function y6(J){let Q=S6(J);return Q.mergeProps=y1,Q}var f1=480,C1=272,KJ={view:0,text:1,image:2},f6=1,C6=-1,x6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},M={f32:0,color:1,int:2},g6={width:M.f32,height:M.f32,minW:M.f32,minH:M.f32,maxW:M.f32,maxH:M.f32,paddingT:M.f32,paddingR:M.f32,paddingB:M.f32,paddingL:M.f32,marginT:M.f32,marginR:M.f32,marginB:M.f32,marginL:M.f32,gap:M.f32,flexDir:M.int,justify:M.int,align:M.int,grow:M.f32,shrink:M.f32,basis:M.f32,flexWrap:M.int,posType:M.int,insetT:M.f32,insetR:M.f32,insetB:M.f32,insetL:M.f32,display:M.int,overflow:M.int,zIndex:M.int,hitPass:M.int,bgColor:M.color,gradFrom:M.color,gradTo:M.color,gradDir:M.int,radius:M.f32,opacity:M.f32,borderColor:M.color,borderWidth:M.f32,shadow:M.int,bevelOuterLight:M.color,bevelOuterDark:M.color,bevelInnerLight:M.color,bevelInnerDark:M.color,bevelWidth:M.f32,textColor:M.color,fontSlot:M.int,textAlign:M.int,lineHeight:M.f32,tracking:M.f32,translateX:M.f32,translateY:M.f32,scale:M.f32,rotate:M.f32,scaleX:M.f32,scaleY:M.f32,originX:M.f32,originY:M.f32,rotateX:M.f32,rotateY:M.f32,translateZ:M.f32,perspective:M.f32,arcStart:M.f32,arcSweep:M.f32,arcWidth:M.f32},c={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},h6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},E6=1,LQ=2,IQ=1,kQ=2,_Q=131072,AQ=1,wQ=262144,SQ=1,yQ=1,fQ=1,CQ=2,xQ=4,gQ=8,hQ=16,EQ=1,bQ=2;function x1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var NQ=1,b6=1263551300,N6=1,T6=32,v6=24,n={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},UJ=32896,TQ=0.016666666666666666;function g1(J){return J.__viewport??null}var f0=null;function m6(){return null}function h1(J,Q=m6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function l6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return h1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return h1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function u6(J){f0=J}function wJ(){if(!f0)throw Error("PocketJS: host not installed — call render() first");return f0}function b(){return wJ().ops}function p6(J){globalThis.frame=J}function c6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function d6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return x1($>>>16&255,$>>>8&255,$&255,255);return x1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function i6(J,Q){let $=g6[J];if(typeof Q==="string"){if($===M.color)return d6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===M.color||$===M.int)return Q>>>0;return Q}var X0=60,E1=[1,2,3,4,5,6,10,12,15,20,30,60],C0=X0,zJ=-1,s6=0,TJ=[];function a6(J){if(!Number.isFinite(J)||J<=0)return X0;let Q=E1[0];for(let $ of E1)if(Math.abs($-J)Q.at<=zJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;TJ=TJ.filter((Q)=>Q.at>zJ);for(let Q of J)Q.cb()}var x0=0.12,W0=UJ;function t6(J){W0=J===void 0?UJ:J&65535}function e6(){W0=UJ}function T1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function Q8(){return T1(W0&255)}var v1=new Set,$8=0;function Z8(){v1.clear(),$8=0,e6()}function X8(J){for(let Q of[...v1])Q(J)}var MJ=null,m1=null;function W8(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function l1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){g0();let Q=MJ?MJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return m1.slice(Q.off,Q.off+Q.len)}var mJ=null,x=null,VJ=null,q0=0,PJ=[],E0=[],b0=[];function p1(J){if(mJ=J,x=null,VJ=null,q0=0,PJ.length=0,E0.length=0,b0.length=0,d){if(d.pressTarget=null,d.target=null,d.spriteDirty=!0,d.fresh=!0,d.vw=0,d.tex>=0){let Q=b();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(d.tex),d.tex=-1}}}function z8(J,Q){J.onPress=Q??void 0}function Y8(J,Q){if(J.focusable=Q,a1(),!Q&&x===J)v(null)}function v(J){if(VJ&&VJ!==J)DJ(null);x=J,b().setFocus(J?J.id:0)}function DJ(J){if(VJ===J)return;let Q=b();if(VJ)Q.setActive?.(VJ.id,0);if(VJ=J,J)Q.setActive?.(J.id,1)}function N0(){return PJ.length>0?PJ[PJ.length-1]:mJ}function T0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;v($[X])}function j8(){if(!x)return null;let J=N0();if(J&&!o(x,J))return null;for(let Q=E0.length-1;Q>=0;Q--){let $=E0[Q];if(J&&!o($.node,J)&&!o(J,$.node))continue;if(o(x,$.node))return $}return null}function F8(J){let Q=j8();if(!Q)return!1;let $=[];if(T0(Q.node,$),$.length===0){if(x)v(null);return!0}let Z=Q.columns,X=x?$.indexOf(x):-1;if(X<0)return v(c1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)v($[W]);return!0}function B8(){if(!x)return null;let J=N0();if(J&&!o(x,J))return null;for(let Q=b0.length-1;Q>=0;Q--){let $=b0[Q];if(J&&!o($.node,J)&&!o(J,$.node))continue;if(o(x,$.node))return $}return null}function z0(J){let Q=B8();if(Q&&Q.move(J))return;if(F8(J))return;H8(J)}function d1(){i1(x)}function i1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){DJ(J)}function K8(J){v(J),i1(J)}function o(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function v0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=v0(Q.children[X]);if(W){v(W);return}}let Z=Q;while(Z){if(Z.focusable){v(Z);return}Z=Z.parent}}v(null)}var d=null,s1=0;function a1(){s1++}var M8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],V8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function P8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=M8[Q]>>$&1,X=V8[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,z=X?255:0;J[W]=z,J[W+1]=z,J[W+2]=z,J[W+3]=255}return J}function D8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=vJ($.image)}catch(z){if(wJ().strict)throw z;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):R8(Q,W),X<0&&wJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(P8(),16,16,h6.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function R8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&E6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function G0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=G0($[Z],Q);if(X)return X}return null}var H0=null;function r1(J){H0=J}function n1(J){let Q=PJ.length>0?PJ[PJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||o($,Q)))return $;$=$.parent}return null}function o1(J,Q,$){return n1(t1(J,Q,$))}function t1(J,Q,$){if($!==void 0)return $===0?null:G0(H0??mJ,$);let Z=b(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return G0(H0??mJ,X(J,Q))}function O8(J,Q,$){let Z=d,X=b();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=g1(X);if(Z.vw=H?H.w:f1,Z.vh=H?H.h:C1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)D8(Z,X);let W=J8()*Z.speed,z=Q8()*Z.speed;if(Z.dpadSpeed>0&&W===0&&z===0){if(J&n.LEFT)W=-Z.dpadSpeed;if(J&n.RIGHT)W=Z.dpadSpeed;if(J&n.UP)z=-Z.dpadSpeed;if(J&n.DOWN)z=Z.dpadSpeed}let F=Z.fresh;if(W!==0||z!==0){let H=r6()/60,w=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),C=Math.min(Math.max(Z.y+z*H,0),Z.vh-1);if(w!==Z.x||C!==Z.y)Z.x=w,Z.y=C,F=!0}if(F)X.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=s1;if(F||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=n1(G0(H0??mJ,X.hitTest(Z.x,Z.y)));let U=Z.target;if(U!==x)v(U);if(Q&Z.button&&U)Z.pressTarget=U;if(Z.pressTarget){if(DJ(U===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=U===Z.pressTarget;if(Z.pressTarget=null,DJ(null),H)d1()}}else if($&Z.button)DJ(null);return!0}function L8(J){let Q=J&~q0,$=q0&~J;if(q0=J,d&&O8(J,Q,$))return;if($&n.CIRCLE)DJ(null);if(Q===0)return;if(Q&n.DOWN)z0("down");if(Q&n.RIGHT)z0("right");if(Q&n.UP)z0("up");if(Q&n.LEFT)z0("left");if(Q&n.CIRCLE)DJ(x),d1()}var m0=null;function e1(J){m0=J}function SJ(){if(a1(),m0)m0()}function I8(J,Q){J.debugName=Q||void 0,SJ()}var YJ={id:f6,type:KJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},J4=Symbol.for("pocketjs.native-node"),l0=1,lJ=3,$J=8,k8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function j0(J){return J.domAttrs??={}}function Q4(J,Q){let $=J.domNodeType??(uJ(J)?lJ:l0),Z=$===lJ?F0(J.text??""):$===$J?w8(J.domData??""):Y4(J.domTag??K0(J));for(let X of Object.keys(J.domAttrs??{}))u0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)GJ(Z,Q4(X,!0));return Z}function u0(J,Q,$){if(k8.has(Q)){fJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete j0(J)[Q];else j0(J)[Q]=$}function p0(J){if(J[J4]===!0)return J;return Object.defineProperty(J,J4,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?lJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===$J?J.domData??"":J.text??""},set($){if(J.domNodeType===$J)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===$J?J.domData??"":J.text??""},set($){if(J.domNodeType===$J)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===$J)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===$J)J.domData=Z;else if(uJ(J))B0(J,Z);else if(h8(J),Z)GJ(J,F0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return H4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??K0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===lJ)return"#text";if(J.domNodeType===$J)return"#comment";return(J.domTag??K0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){fJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===YJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return GJ(J,$),$},insertBefore($,Z){return GJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return GJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return Q4(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){u0(J,$,Z)},removeAttribute($){u0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}p0(YJ);var c0=null;function _8(J){c0=J}var d0={unknownClass:0,unknownTexture:0},$4=new Map;function Z4(J,Q){$4.set(J,Q)}var X4=new Map;function W4(J,Q){X4.set(J,Q)}var yJ=new Set,A8=new Set;function q4(J){if(!J)return!1;if(A8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return p0({id:b().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function F0(J){let Q=b(),$=Q.createNode(KJ.text);return Q.setText($,J),p0({id:$,type:KJ.text,parent:null,children:[],text:J,domNodeType:lJ,domTag:"#text"})}function w8(J=""){let Q=F0("");return Q.domNodeType=$J,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){b().replaceText(J.id,Q),J.text=Q,SJ()}function uJ(J){return J.type===KJ.text}function G4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function GJ(J,Q,$){let Z=b();if(G4(Q),yJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,SJ()}function pJ(J,Q){if(!Q)return;U8(Q),b().removeChild(J.id,Q.id),G4(Q),yJ.add(Q),SJ()}function S8(J){return J.parent??void 0}function y8(J){return J.children[0]}function H4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function f8(J,Q){let $=b();if(SJ(),Q==null||Q===""){$.setStyle(J.id,C6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=c0?c0(Q):void 0;if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);d0.unknownClass++;return}$.setStyle(J.id,Z)}function C8(J,Q){let $=b();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=$4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);d0.unknownTexture++;return}$.setImage(J.id,Z)}function x8(J,Q){let $=b();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=X4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);d0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function g8(J,Q,$){let Z=b(),X=Q??{},W=$??{},z=!1;for(let F in X){let P=X[F];if(W[F]===P)continue;let D=x6[F];if(D===void 0)throw Error(`PocketJS: unknown style prop '${F}' (see spec PROP)`);Z.setProp(J.id,D,i6(F,P)),z=!0}if(z)SJ()}function fJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete j0(J)[Q];else j0(J)[Q]=$;switch(Q){case"class":return f8(J,$),$;case"onPress":case"on:press":return z8(J,$),$;case"src":return C8(J,$),$;case"sprite":return x8(J,$),$;case"style":return g8(J,$,Z),$;case"focusable":return Y8(J,!!$),$;case"debugName":return I8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${K0(J)}>`)}function h8(J){for(let Q of[...J.children])pJ(J,Q)}function K0(J){for(let Q of Object.keys(KJ))if(KJ[Q]===J.type)return Q;return String(J.type)}function E8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}fJ(J,Q,$,Z)}var b8=y6({createElement:Y4,createTextNode:F0,replaceText:B0,isTextNode:uJ,setProperty:E8,insertNode(J,Q,$){GJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:S8,getFirstChild:y8,getNextSibling:H4}),{render:N8,effect:vQ,memo:HJ,createComponent:q,createElement:j4,insert:mQ,spread:T8,mergeProps:lQ,use:uQ}=b8,pQ={linear:c.Easing.Linear,in:c.Easing.EaseIn,out:c.Easing.EaseOut,"in-out":c.Easing.EaseInOut,"out-back":c.Easing.OutBack,spring:c.Easing.Spring,"spring-bouncy":c.Easing.SpringBouncy},v8=null;function F4(J){v8=J}function m8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function B4(J,Q){let $=j4(J);return T8($,Q,!1),m8(Q.nodeRef,$),$}function R(J){return B4("view",J)}function L(J){return B4("text",J)}var cQ=new WeakMap,dQ=new WeakMap,l8={}!==null?Object.freeze({...{}}):Object.freeze({}),iQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:l8}),sQ=new Map,jJ=36000,i0=30,u8=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(jJ),tapeAnalog:new Uint16Array(jJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-i0,saidHello:!1,hostCalls:0};function p8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-i0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)e1(()=>{Y.treeDirty=!0}),o8();else e1(null);globalThis.__pocketDevtools=e8}function c8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)i8(),r8();let W=Q,z=$===void 0?UJ:$&65535,F=Z,P=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(jJ).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==UJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function M4(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,z]of J)Z.fill(W,X,Math.min(X+z,$)),X+=z;return Z}function V4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return M4(J.masks,0,Q)}function P4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return M4(J.analog??[],UJ,Q)}function D4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,T({t:"hello",app:Y.app,host:t8(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` -`))if(X.trim())s8(X)}}function s8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),s0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),s0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":R4();break;case"eval":{let Z=!0,X;try{X=U0((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}T({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":T({t:"tape",tape:U4()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}T({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=V4(Z),Y.replayAnalog=Z.analog?P4(Z):null,Y.replayTouch=Z.touch?D4(Z):null,Y.replayAt=0;break}default:break}}function a8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=i0)R4();if(Y.frame%u8===0)s0()}function r8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function s0(){T({t:"stats",frame:Y.frame,nodes:I4(YJ),tapeLen:Y.tapeLen,paused:Y.paused})}function R4(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,T({t:"tree",frame:Y.frame,root:L4(YJ)})}function n8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function a0(J,Q){if(Array.isArray(J)){for(let $ of J)a0($,Q);return}if(n8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)a0($,Q)}}function O4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)a0(Z,Q)}function L4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(O4(J,(X)=>{if(X.domNodeType===8)return;Z.push(L4(X))}),Z.length)Q.k=Z;return Q}function I4(J){let Q=1;return O4(J,($)=>{Q+=I4($)}),Q}function o8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{T({t:"log",level:$,args:X.map((W)=>U0(W))}),Z?.apply(Q,X)}}}function U0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?k4(W):JSON.stringify(k4(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((z)=>U0(z,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,z])=>`${W}: ${U0(z,Q+1)}`).join(", ")}}`}function k4(J){return J.length>200?J.slice(0,199)+"…":J}function t8(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var e8={get frame(){return Y.frame},dumpTape:()=>U4(),replay:(J)=>{Y.replayMasks=V4(J),Y.replayAnalog=J.analog?P4(J):null,Y.replayTouch=J.touch?D4(J):null,Y.replayAt=0}},_4=new Map,r0=new Map;function A4(J){return J.trim().replace(/\s+/g," ")}function w4(J){return J.split(" ").sort().join(" ")}var S4=-1;function J2(J){for(let Q of Object.keys(J)){let $=J[Q],Z=A4(Q);_4.set(Z,$);let X=w4(Z),W=r0.get(X);r0.set(X,W!==void 0&&W!==$?S4:$)}}function Q2(J){let Q=A4(J),$=_4.get(Q);if($!==void 0)return $;let Z=r0.get(w4(Q));return Z===S4?void 0:Z}var n0=9,$2=(1<{let X=($&X2)!==0,W=X?o0:n0,z=X?W2:$2;return Object.freeze({id:$>>>(X?q2:Z2)&255,x:$&z,y:$>>>W&z,hit:Q?.[Z]})}))}function Y2(){return M0}function G2(){M0=t0}var y4=8,FJ=8,H2=3,j2=8,F2=6,B2=0.5,t=1,cJ=2,e0=4,RJ=8,CJ=[],f4=0,V0=0,BJ=Array.from({length:y4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(FJ),histY:new Int16Array(FJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function K2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function U2(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=t1(Q,$,Z.fact);let F=Z.hit;if(F)return K2(F,W)}let z=X.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let F=CJ[z];if(F.disposed)continue;if(f4>0&&!F.opts.allowWhenBlocked)continue;if(!U2(F,$,Z,W))continue;F.flags[J.slot]=t,J.owners.push(F)}for(let z of J.owners)z.opts.onDown?.(J)}function P2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%FJ,J.histLenz||Z>z))X.flags[J.slot]|=cJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&t)||W&(cJ|e0))continue;if(!X.opts.onLongPress)continue;let z=Math.max(1,Math.round((X.opts.longPressSeconds??B2)*b1()));if(J.frames=0)CJ.splice($,1)},cancel(){if(!Q.disposed)g4(Q)},get panning(){for(let $ of BJ)if($.used&&Q.flags[$.slot]&RJ)return!0;return!1}}}function I2(J){let Q=L2(J);return A0(()=>Q.dispose()),Q}function h4(){CJ.length=0,f4=0,V0=0;for(let J of BJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function k2(){return I2({onDown:(J)=>{let Q=o1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=o1(J.x,J.y,J.hit);if(Q)K8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var _2=1,J1=new Map,P0=[];function A2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function w2(){_2=1,J1.clear(),P0=[]}function S2(){if(P0.length===0)return;let J=P0;P0=[];for(let{id:Q,result:$}of J){let Z=J1.get(Q);if(!Z)continue;J1.delete(Q),A2()?.({t:"delivery",frame:N1(),id:Q,kind:Z.kind}),Z.onResult($)}}var y2={"w-[210] h-[104] px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":0,"text-sm text-slate-500 font-bold":1,"text-lg text-slate-900 font-bold":2,"h-[72] px-5 flex-row items-center justify-between":3,"w-[450] flex-col gap-2":4,"text-base text-slate-900 font-bold":5,"text-sm text-slate-500":6,"text-sm text-emerald-600 font-bold":7,"text-sm text-slate-900 font-bold":8,"h-[64] px-5 flex-row items-center":9,"w-[240] text-base text-slate-900 font-bold":10,"w-[156] text-sm text-slate-500":11,"relative w-[632] h-[196] flex-col":12,"relative w-[632] h-[160] overflow-hidden":13,"absolute w-[632] h-[2] bg-slate-200":14,"absolute text-sm text-slate-500 font-bold":15,"absolute rounded-lg bg-emerald-500":16,"absolute rounded-lg bg-red-500":17,"absolute w-[9] h-[9] rounded-lg bg-emerald-500":18,"absolute w-[9] h-[9] rounded-lg bg-red-500":19,"h-[36] px-1 flex-row items-center justify-between":20,"flex-col w-full h-full bg-slate-50":21,"h-[64] px-6 pt-2":22,"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":23,"h-[304] px-6 pt-3":24,"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100":25,"h-[64] flex-row items-end justify-between":26,"text-2xl text-slate-950 font-bold":27,"text-base text-emerald-600 font-bold":28,"text-base text-red-500 font-bold":29,"h-[60] px-6 pt-2 flex-row gap-3":30,"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":31,"w-[100] h-[44] items-center justify-center rounded-lg bg-white":32,"text-sm text-white font-bold":33,"pt-3 text-sm text-slate-500":34,"h-[126] px-6 pt-3 flex-row items-start gap-[21]":35,"h-[200] px-6 flex-col":36,"h-[150] flex-col rounded-xl shadow bg-white border-slate-100":37,"h-[184] px-6 flex-col":38,"h-[136] flex-col rounded-xl shadow bg-white border-slate-100":39,"h-[126] px-6 pt-2":40,"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":41,"flex-col gap-3":42,"text-xl text-emerald-600 font-bold":43,"text-xl text-red-500 font-bold":44,"h-[104] px-6 flex-row items-center justify-between":45,"w-[460] text-sm text-red-500":46,"w-[460] text-sm text-slate-500":47,"w-[176] h-[64]":48,"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":49,"text-sm text-orange-600 font-bold":50,"relative flex-col w-full h-full bg-slate-50":51,"px-6 pt-[14] flex-col gap-[12]":52,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":53,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":54,"flex-row items-center justify-between":55,"text-base text-slate-500 font-bold":56,"text-sm text-emerald-600":57,"px-6 pt-[14] flex-col gap-[14]":58,"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100":59,"text-base text-slate-500":60,"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100":61,"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":62,"flex-row items-center":63,"w-[170] text-lg text-slate-900 font-bold":64,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":65,"absolute inset-0 z-50 flex-col items-center justify-center":66,"absolute inset-0 bg-slate-950":67,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":68,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":69,"flex-row flex-wrap":70,grow:71,"text-2xl text-white font-bold":72,"text-sm text-slate-600 font-bold":73,"text-base text-slate-900":74,"px-6":75,"px-6 py-5":76,"gap-4":77,"w-[34] h-[34] rounded-lg bg-amber-400":78,"w-[34] h-[34] rounded-lg bg-red-500":79,"w-[34] h-[34] rounded-lg bg-slate-800":80,"w-[34] h-[34] rounded-lg bg-emerald-500":81,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":82,"flex-row items-center gap-4":83,"w-[34] text-2xl text-white font-bold":84,"w-[332] flex-col items-end gap-2":85,"text-sm text-slate-300 font-bold":86,"text-sm text-slate-400":87,"h-[40] px-1 flex-row items-center justify-between":88,"w-full h-full items-center justify-center rounded-xl bg-slate-200":89,"w-full h-full items-center justify-center rounded-xl bg-orange-600":90,"text-base text-white font-bold":91};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var f2="ui:styles",C2="ui:font.",E4="ui:img.",b4="ui:sprite.";function x2(){return globalThis.ui}function g2(J){if(J.__textures)return;for(let Q of h0(E4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)Z4(Q.slice(E4.length),Z)}}function h2(J){if(J.__sprites)return;for(let Q of h0(b4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),z=$[4],F=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),U=J.uploadTexture($.subarray(16),X,W,z);if(U>=0)W4(Q.slice(b4.length),{handle:U,frames:F,cols:P,step:D})}}function N4(J){let Q=j4("view");return fJ(Q,"style",J,void 0),Q}var D0=null,R0=null;function E2(J,Q){if(!D0||!R0)return;fJ(D0,"style",{width:J,height:Q,overflow:c.Overflow.Hidden},void 0),fJ(R0,"style",{width:J,height:Q,posType:c.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=b();$.__viewport={w:J,h:Q}}function b2(J,Q={}){let $=l6(Q.ops);if(u6($),_8(Q2),Q.styles)J2(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let w in Z)Z4(w,Z[w]);let H=$.ops.__sprites;if(H)for(let w in H)W4(w,H[w])}if($.kind==="injected"||Z===void 0){if(Q.pak)u1(Q.pak);if(q8()){for(let H of h0())if(H===f2)$.ops.loadStyles?.(vJ(H));else if(H.startsWith(C2))$.ops.loadFontAtlas?.(vJ(H))}}let X=g1($.ops),W=X?.w??f1,z=X?.h??C1,F=N4({width:W,height:z,overflow:c.Overflow.Hidden}),P=N4({width:W,height:z,posType:c.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});GJ(YJ,F),GJ(YJ,P),F4(P),D0=F,R0=P,p1(F),r1(YJ),Z8(),h4(),k2(),n6(),w2(),p8($.ops),p6(c8((H,w,C,g)=>{o6(),t6(w),z2(C,g),S2(),O2(),X8(H),L8(H),z4()}));let D=N8(J,F),U=c6(E2);return()=>{U(),G2(),h4(),D(),p1(null),r1(null),F4(null),D0=null,R0=null;for(let H of YJ.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);z4()}}function N2(J,Q={}){let $=Q.ops??x2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)u1(Q.pak);return g2($),h2($),b2(J,{ops:$,styles:Q.styles??y2,pak:Q.pak})}var T4="$b",T2=9007199254740991,v2=":memory:",xJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function m2(J){let Q="";for(let $=0;$>2]+xJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2>16,Z<$.length)$[Z++]=W>>8&255;if(Z<$.length)$[Z++]=W&255}return $}function u2(){let J=globalThis.db;if(!J||typeof J!=="object")return null;return typeof J.open==="function"?J:null}function v4(J){if(J instanceof Uint8Array)return{[T4]:m2(J)};if(typeof J==="number"&&!Number.isFinite(J))throw Error("db: cannot bind a non-finite number");if(typeof J==="number"&&Number.isInteger(J)&&Math.abs(J)>T2)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function p2(J){if(J!==null&&typeof J==="object")return l2(J[T4]);return J}function c2(J){if(Array.isArray(J))return JSON.stringify(J.map(v4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=v4(Z);return JSON.stringify(Q)}class Q1{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,c2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=m4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(p2))}run(...J){let Q=this.execute(m4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function m4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class l4{statements=new Map;txDepth=0;constructor(J=v2){let Q=u2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new Q1(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new Q1(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let z=J(...Q);return this.txDepth--,this.exec(X),z}catch(z){throw this.txDepth--,this.exec(W),z}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var d2={title:"text-2xl text-white font-bold",section:"text-sm text-slate-600 font-bold",body:"text-base text-slate-900",bodyStrong:"text-base text-slate-900 font-bold",caption:"text-sm text-slate-500"};function i2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return q(R,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[q(R,{class:"flex-row items-center gap-4",get children(){return[HJ(()=>HJ(()=>!!J.back)()?q(L,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):q(R,{get["class"](){return Q()}})),q(L,{get["class"](){return d2.title},get children(){return J.title}})]}}),q(R,{class:"w-[332] flex-col items-end gap-2",get children(){return[q(L,{class:"text-sm text-slate-300 font-bold",get children(){return J.metaTop??""}}),q(L,{class:"text-sm text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function s2(J){let Q=()=>J.action?J.detail?J.detail+" · VIEW ALL ›":"VIEW ALL ›":J.detail??"";return q(R,{class:"h-[40] px-1 flex-row items-center justify-between",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",get children(){return J.title}}),q(L,{class:"text-sm text-slate-500 font-bold",get children(){return Q()}})]}})}function a2(J){return q(R,{get["class"](){return J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":"w-full h-full items-center justify-center rounded-xl bg-orange-600"},get children(){return q(L,{get["class"](){return J.disabled?"text-base text-slate-500 font-bold":"text-base text-white font-bold"},get children(){return J.label}})}})}var u4=4,m=new l4("robinhood"),r2={number:"",label:"ACCOUNT",suffix:"",status:"WAITING FOR ROBINHOOD"},$1={title:"NO RECENT ACTIVITY",timestamp:"",detail:"",state:"",amount:"",side:""},n2={...$1,title:"ACTIVITY UNAVAILABLE"},o2={...$1,title:""},Z1={symbol:"NO OPEN POSITIONS",quantity:"",averagePrice:"",marketValue:""},t2={...Z1,symbol:"POSITIONS UNAVAILABLE"},e2={...Z1,symbol:""},iJ={account:r2,totalValue:null,cash:null,buyingPower:null,pnlDay:null,pnlWeek:null,positions:[],activity:[],positionsAvailable:!0,activityAvailable:!0,observedAt:null},[i,sJ]=E("dashboard"),[l,JQ]=E("day"),[gJ,X1]=E([]),[O0,L0]=E(""),[y,aJ]=E(iJ),[p4,OJ]=E([]),[QQ,LJ]=E([]),[W1,q1]=E([]),[$Q,z1]=E({change:"$—",percent:"—",positive:!0}),[Y1,c4]=E(0),[d4,i4]=E(0),[s4,a4]=E(0),[r4,ZJ]=E("WAITING FOR ROBINHOOD"),[rJ,n4]=E(!1),u=0,o4=-1,t4=-1,e4=-1,G1=new Map,H1=new Map;function J6(){return Math.floor(Date.now()/1000)}function ZQ(J){try{return J?JSON.parse(J):null}catch{return null}}function XQ(){return m.query("SELECT account_number,label,suffix,status FROM accounts ORDER BY label,account_number LIMIT 16").all().map((Q)=>({number:Q.account_number,label:Q.label,suffix:Q.suffix,status:Q.status}))}function WQ(J,Q){if(t4===J)return;let $=m.query("SELECT account_number,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current LIMIT 16").all(),Z=m.query(` +(()=>{var _J={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return U1(this.context.count)},getNextContextId(){return U1(this.context.count++)}};function U1(J){let Q=String(J),$=Q.length-1;return _J.context.id+($?String.fromCharCode(96+$):"")+Q}function M1(J){_J.context=J}function H6(){return{..._J.context,id:_J.getNextContextId(),count:0}}var j6=!1,F6=(J,Q)=>J===Q,_0=Symbol("solid-proxy"),B6=typeof Proxy==="function",K6=Symbol("solid-track"),LQ=Symbol("solid-dev-component"),nJ={equals:F6},V1=null,U6=k1,p=1,EJ=2,P1={owned:null,cleanups:null,context:null,owner:null},S=null,B=null,bJ=null,AJ=null,f=null,h=null,N=null,oJ=0;function tJ(J,Q){let $=f,Z=S,X=J.length===0,W=Q===void 0?Z:Q,z=X?P1:{owned:null,cleanups:null,context:W?W.context:null,owner:W},F=X?J:()=>J(()=>WJ(()=>qJ(z)));S=z,f=null;try{return r(F,!0)}finally{f=$,S=Z}}function E(J,Q){Q=Q?Object.assign({},nJ,Q):nJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return O1($,X)};return[R1.bind($),Z]}function XJ(J,Q,$){let Z=I1(J,Q,!1,p);if(bJ&&B&&B.running)h.push(Z);else J0(Z)}function QJ(J,Q,$){$=$?Object.assign({},nJ,$):nJ;let Z=I1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,bJ&&B&&B.running)Z.tState=p,h.push(Z);else J0(Z);return R1.bind(Z)}function eJ(J){return r(J,!1)}function WJ(J){if(!AJ&&f===null)return J();let Q=f;f=null;try{if(AJ)return AJ.untrack(J);return J()}finally{f=Q}}function A0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function M6(J){if(B&&B.running)return J(),B.done;let Q=f,$=S;return Promise.resolve().then(()=>{f=Q,S=$;let Z;if(bJ||V6)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return r(J,!1),f=S=null,Z?Z.done:void 0})}var[IQ,D1]=E(!1),V6;function R1(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===p)J0(this);else{let Q=h;h=null,r(()=>Q0(this),!1),h=Q}if(f){let Q=this.observers;if(!Q||Q[Q.length-1]!==f){let $=Q?Q.length:0;if(!f.sources)f.sources=[this],f.sourceSlots=[$];else f.sources.push(this),f.sourceSlots.push($);if(!Q)this.observers=[f],this.observerSlots=[f.sources.length-1];else Q.push(f),this.observerSlots.push(f.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function O1(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)r(()=>{for(let X=0;X1e6)throw h=[],Error()},!1)}return Q}function J0(J){if(!J.fn)return;qJ(J);let Q=oJ;if(L1(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{r(()=>{B&&(B.running=!0),f=S=J,L1(J,J.tValue,Q),f=S=null},!1)})}function L1(J,Q,$){let Z,X=S,W=f;f=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(B&&B.running)J.tState=p,J.tOwned&&J.tOwned.forEach(qJ),J.tOwned=void 0;else J.state=p,J.owned&&J.owned.forEach(qJ),J.owned=null;return J.updatedAt=$+1,S0(z)}finally{f=W,S=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)O1(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function I1(J,Q,$,Z=p,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(S===null);else if(S!==P1)if(B&&B.running&&S.pure)if(!S.tOwned)S.tOwned=[W];else S.tOwned.push(W);else if(!S.owned)S.owned=[W];else S.owned.push(W);if(AJ&&W.fn){let z=W.fn,[F,P]=E(void 0,{equals:!1}),D=AJ.factory(z,P);A0(()=>D.dispose());let U,H=()=>M6(P).then(()=>{if(U)U.dispose(),U=void 0});W.fn=(w)=>{if(F(),B&&B.running){if(!U)U=AJ.factory(z,H);return U.track(w)}return D.track(w)}}return W}function w0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===EJ)return Q0(J);if(J.suspense&&WJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===p)J0(J);else if((Q?J.tState:J.state)===EJ){let X=h;h=null,r(()=>Q0(J,$[0]),!1),h=X}}}function r(J,Q){if(h)return J();let $=!1;if(!Q)h=[];if(N)$=!0;else N=[];oJ++;try{let Z=J();return P6($),Z}catch(Z){if(!$)N=null;h=null,S0(Z)}}function P6(J){if(h){if(bJ&&B&&B.running)D6(h);else k1(h);h=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;N.push.apply(N,B.effects),Q=B.resolve;for(let W of N)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,r(()=>{for(let W of X)qJ(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let z=0,F=W.owned.length;zU6($),!1);if(Q)Q()}function k1(J){for(let Q=0;Q{Z.delete($),r(()=>{B.running=!0,w0($)},!1),B&&(B.running=!1)})}}function Q0(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)qJ(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)A1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)qJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function A1(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return A0(()=>S1(W)),()=>{let P=J()||[],D=P.length,U,H;return P[K6],WJ(()=>{let C,g,A,s,a,K,j,G,V;if(D===0){if(z!==0)S1(W),W=[],Z=[],X=[],z=0,F&&(F=[]);if($.fallback)Z=[O6],X[0]=tJ((k)=>{return W[0]=k,$.fallback()}),z=1}else if(z===0){X=Array(D);for(H=0;H=K&&G>=K&&Z[j]===P[G];j--,G--)A[G]=X[j],s[G]=W[j],F&&(a[G]=F[j]);C=new Map,g=Array(G+1);for(H=G;H>=K;H--)V=P[H],U=C.get(V),g[H]=U===void 0?-1:U,C.set(V,H);for(U=K;U<=j;U++)if(V=Z[U],H=C.get(V),H!==void 0&&H!==-1)A[H]=X[U],s[H]=W[U],F&&(a[H]=F[U]),H=g[H],C.set(V,H);else W[U]();for(H=K;HJ(Q||{}));return M1($),Z}}return WJ(()=>J(Q||{}))}function $0(){return!0}var _6={get(J,Q,$){if(Q===_0)return $;return J.get(Q)},has(J,Q){if(Q===_0)return!0;return J.has(Q)},set:$0,deleteProperty:$0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:$0,deleteProperty:$0}},ownKeys(J){return J.keys()}};function y0(J){return!(J=typeof J==="function"?J():J)?{}:J}function A6(){for(let J=0,Q=this.length;J=0;F--){let P=y0(J[F])[z];if(P!==void 0)return P}},has(z){for(let F=J.length-1;F>=0;F--)if(z in y0(J[F]))return!0;return!1},keys(){let z=[];for(let F=0;F=0;z--){let F=J[z];if(!F)continue;let P=Object.getOwnPropertyNames(F);for(let D=P.length-1;D>=0;D--){let U=P[D];if(U==="__proto__"||U==="constructor")continue;let H=Object.getOwnPropertyDescriptor(F,U);if(!Z[U])Z[U]=H.get?{enumerable:!0,configurable:!0,get:A6.bind($[U]=[H.get.bind(F)])}:H.value!==void 0?H:void 0;else{let w=$[U];if(w){if(H.get)w.push(H.get.bind(F));else if(H.value!==void 0)w.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let z=W.length-1;z>=0;z--){let F=W[z],P=Z[F];if(P&&P.get)Object.defineProperty(X,F,P);else X[F]=P?P.value:void 0}return X}var w6=(J)=>`Stale read from <${J}>.`;function NJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return QJ(L6(()=>J.each,J.children,Q||void 0))}function Z0(J){let Q=J.keyed,$=QJ(()=>J.when,void 0,void 0),Z=Q?$:QJ($,void 0,{equals:(X,W)=>!X===!W});return QJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?WJ(()=>W(Q?X:()=>{if(!WJ(Z))throw w6("Show");return $()})):W}return J.fallback},void 0,void 0)}var S6=(J)=>QJ(()=>J());function y6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:z,getParentNode:F,getFirstChild:P,getNextSibling:D}){function U(K,j,G,V){if(G!==void 0&&!V)V=[];if(typeof j!=="function")return H(K,j,V,G);XJ((k)=>H(K,j(),k,G),V)}function H(K,j,G,V,k){while(typeof G==="function")G=G();if(j===G)return G;let _=typeof j,I=V!==void 0;if(_==="string"||_==="number"){if(_==="number")j=j.toString();if(I){let O=G[0];if(O&&$(O))Z(O,j);else O=Q(j);G=g(K,G,V,O)}else if(G!==""&&typeof G==="string")Z(P(K),G=j);else g(K,G,V,Q(j)),G=j}else if(j==null||_==="boolean")G=g(K,G,V);else if(_==="function")return XJ(()=>{let O=j();while(typeof O==="function")O=O();G=H(K,O,G,V)}),()=>G;else if(Array.isArray(j)){let O=[];if(w(O,j,k))return XJ(()=>G=H(K,O,G,V,!0)),()=>G;if(O.length===0){let hJ=g(K,G,V);if(I)return G=hJ}else if(Array.isArray(G))if(G.length===0)A(K,O,V);else C(K,G,O);else if(G==null||G==="")A(K,O);else C(K,I&&G||[P(K)],O);G=O}else{if(Array.isArray(G)){if(I)return G=g(K,G,V,j);g(K,G,null,j)}else if(G==null||G===""||!P(K))X(K,j);else s(K,j,P(K));G=j}return G}function w(K,j,G){let V=!1;for(let k=0,_=j.length;k<_;k++){let I=j[k],O;if(I==null||I===!0||I===!1);else if(Array.isArray(I))V=w(K,I)||V;else if((O=typeof I)==="string"||O==="number")K.push(Q(I));else if(O==="function")if(G){while(typeof I==="function")I=I();V=w(K,Array.isArray(I)?I:[I])||V}else K.push(I),V=!0;else K.push(I)}return V}function C(K,j,G){let V=G.length,k=j.length,_=V,I=0,O=0,hJ=D(j[k-1]),IJ=null;while(IJJ-O){let OQ=j[I];while(O=0;I--){let O=j[I];if(k!==O){let hJ=F(O)===K;if(!_&&!I)hJ?s(K,k,O):X(K,k,G);else hJ&&W(K,O)}else _=!0}}else X(K,k,G);return[k]}function A(K,j,G){for(let V=0,k=j.length;VG.children=H(K,j.children,G.children));return XJ(()=>j.ref&&j.ref(K)),XJ(()=>{for(let k in j){if(k==="children"||k==="ref")continue;let _=j[k];if(_===G[k])continue;z(K,k,_,G[k]),G[k]=_}}),G}return{render(K,j){let G;return tJ((V)=>{G=V,U(j,K())}),G},insert:U,spread(K,j,G){if(typeof j==="function")XJ((V)=>a(K,j(),V,G));else a(K,j,void 0,G)},createElement:J,createTextNode:Q,insertNode:X,setProp(K,j,G,V){return z(K,j,G,V),G},mergeProps:y1,effect:XJ,memo:S6,createComponent:k6,use(K,j,G){return WJ(()=>K(j,G))}}}function f6(J){let Q=y6(J);return Q.mergeProps=y1,Q}var f1=480,C1=272,KJ={view:0,text:1,image:2},C6=1,x6=-1,g6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},M={f32:0,color:1,int:2},h6={width:M.f32,height:M.f32,minW:M.f32,minH:M.f32,maxW:M.f32,maxH:M.f32,paddingT:M.f32,paddingR:M.f32,paddingB:M.f32,paddingL:M.f32,marginT:M.f32,marginR:M.f32,marginB:M.f32,marginL:M.f32,gap:M.f32,flexDir:M.int,justify:M.int,align:M.int,grow:M.f32,shrink:M.f32,basis:M.f32,flexWrap:M.int,posType:M.int,insetT:M.f32,insetR:M.f32,insetB:M.f32,insetL:M.f32,display:M.int,overflow:M.int,zIndex:M.int,hitPass:M.int,bgColor:M.color,gradFrom:M.color,gradTo:M.color,gradDir:M.int,radius:M.f32,opacity:M.f32,borderColor:M.color,borderWidth:M.f32,shadow:M.int,bevelOuterLight:M.color,bevelOuterDark:M.color,bevelInnerLight:M.color,bevelInnerDark:M.color,bevelWidth:M.f32,textColor:M.color,fontSlot:M.int,textAlign:M.int,lineHeight:M.f32,tracking:M.f32,translateX:M.f32,translateY:M.f32,scale:M.f32,rotate:M.f32,scaleX:M.f32,scaleY:M.f32,originX:M.f32,originY:M.f32,rotateX:M.f32,rotateY:M.f32,translateZ:M.f32,perspective:M.f32,arcStart:M.f32,arcSweep:M.f32,arcWidth:M.f32},c={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},E6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},b6=1,kQ=2,_Q=1,AQ=2,wQ=131072,SQ=1,yQ=262144,fQ=1,CQ=1,xQ=1,gQ=2,hQ=4,EQ=8,bQ=16,NQ=1,TQ=2;function x1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var vQ=1,N6=1263551300,T6=1,v6=32,m6=24,n={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},UJ=32896,mQ=0.016666666666666666;function g1(J){return J.__viewport??null}var f0=null;function l6(){return null}function h1(J,Q=l6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function u6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return h1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return h1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function p6(J){f0=J}function wJ(){if(!f0)throw Error("PocketJS: host not installed — call render() first");return f0}function b(){return wJ().ops}function c6(J){globalThis.frame=J}function d6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function i6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return x1($>>>16&255,$>>>8&255,$&255,255);return x1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function s6(J,Q){let $=h6[J];if(typeof Q==="string"){if($===M.color)return i6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===M.color||$===M.int)return Q>>>0;return Q}var X0=60,E1=[1,2,3,4,5,6,10,12,15,20,30,60],C0=X0,zJ=-1,a6=0,TJ=[];function r6(J){if(!Number.isFinite(J)||J<=0)return X0;let Q=E1[0];for(let $ of E1)if(Math.abs($-J)Q.at<=zJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;TJ=TJ.filter((Q)=>Q.at>zJ);for(let Q of J)Q.cb()}var x0=0.12,W0=UJ;function e6(J){W0=J===void 0?UJ:J&65535}function J8(){W0=UJ}function T1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function $8(){return T1(W0&255)}var v1=new Set,Z8=0;function X8(){v1.clear(),Z8=0,J8()}function W8(J){for(let Q of[...v1])Q(J)}var MJ=null,m1=null;function q8(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function l1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){g0();let Q=MJ?MJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return m1.slice(Q.off,Q.off+Q.len)}var mJ=null,x=null,VJ=null,q0=0,PJ=[],E0=[],b0=[];function p1(J){if(mJ=J,x=null,VJ=null,q0=0,PJ.length=0,E0.length=0,b0.length=0,d){if(d.pressTarget=null,d.target=null,d.spriteDirty=!0,d.fresh=!0,d.vw=0,d.tex>=0){let Q=b();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(d.tex),d.tex=-1}}}function Y8(J,Q){J.onPress=Q??void 0}function G8(J,Q){if(J.focusable=Q,a1(),!Q&&x===J)v(null)}function v(J){if(VJ&&VJ!==J)DJ(null);x=J,b().setFocus(J?J.id:0)}function DJ(J){if(VJ===J)return;let Q=b();if(VJ)Q.setActive?.(VJ.id,0);if(VJ=J,J)Q.setActive?.(J.id,1)}function N0(){return PJ.length>0?PJ[PJ.length-1]:mJ}function T0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;v($[X])}function F8(){if(!x)return null;let J=N0();if(J&&!o(x,J))return null;for(let Q=E0.length-1;Q>=0;Q--){let $=E0[Q];if(J&&!o($.node,J)&&!o(J,$.node))continue;if(o(x,$.node))return $}return null}function B8(J){let Q=F8();if(!Q)return!1;let $=[];if(T0(Q.node,$),$.length===0){if(x)v(null);return!0}let Z=Q.columns,X=x?$.indexOf(x):-1;if(X<0)return v(c1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)v($[W]);return!0}function K8(){if(!x)return null;let J=N0();if(J&&!o(x,J))return null;for(let Q=b0.length-1;Q>=0;Q--){let $=b0[Q];if(J&&!o($.node,J)&&!o(J,$.node))continue;if(o(x,$.node))return $}return null}function z0(J){let Q=K8();if(Q&&Q.move(J))return;if(B8(J))return;j8(J)}function d1(){i1(x)}function i1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){DJ(J)}function U8(J){v(J),i1(J)}function o(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function v0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=v0(Q.children[X]);if(W){v(W);return}}let Z=Q;while(Z){if(Z.focusable){v(Z);return}Z=Z.parent}}v(null)}var d=null,s1=0;function a1(){s1++}var V8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],P8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function D8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=V8[Q]>>$&1,X=P8[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,z=X?255:0;J[W]=z,J[W+1]=z,J[W+2]=z,J[W+3]=255}return J}function R8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=vJ($.image)}catch(z){if(wJ().strict)throw z;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):O8(Q,W),X<0&&wJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(D8(),16,16,E6.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function O8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&b6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function G0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=G0($[Z],Q);if(X)return X}return null}var H0=null;function r1(J){H0=J}function n1(J){let Q=PJ.length>0?PJ[PJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||o($,Q)))return $;$=$.parent}return null}function o1(J,Q,$){return n1(t1(J,Q,$))}function t1(J,Q,$){if($!==void 0)return $===0?null:G0(H0??mJ,$);let Z=b(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return G0(H0??mJ,X(J,Q))}function L8(J,Q,$){let Z=d,X=b();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=g1(X);if(Z.vw=H?H.w:f1,Z.vh=H?H.h:C1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)R8(Z,X);let W=Q8()*Z.speed,z=$8()*Z.speed;if(Z.dpadSpeed>0&&W===0&&z===0){if(J&n.LEFT)W=-Z.dpadSpeed;if(J&n.RIGHT)W=Z.dpadSpeed;if(J&n.UP)z=-Z.dpadSpeed;if(J&n.DOWN)z=Z.dpadSpeed}let F=Z.fresh;if(W!==0||z!==0){let H=n6()/60,w=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),C=Math.min(Math.max(Z.y+z*H,0),Z.vh-1);if(w!==Z.x||C!==Z.y)Z.x=w,Z.y=C,F=!0}if(F)X.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=s1;if(F||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=n1(G0(H0??mJ,X.hitTest(Z.x,Z.y)));let U=Z.target;if(U!==x)v(U);if(Q&Z.button&&U)Z.pressTarget=U;if(Z.pressTarget){if(DJ(U===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=U===Z.pressTarget;if(Z.pressTarget=null,DJ(null),H)d1()}}else if($&Z.button)DJ(null);return!0}function I8(J){let Q=J&~q0,$=q0&~J;if(q0=J,d&&L8(J,Q,$))return;if($&n.CIRCLE)DJ(null);if(Q===0)return;if(Q&n.DOWN)z0("down");if(Q&n.RIGHT)z0("right");if(Q&n.UP)z0("up");if(Q&n.LEFT)z0("left");if(Q&n.CIRCLE)DJ(x),d1()}var m0=null;function e1(J){m0=J}function SJ(){if(a1(),m0)m0()}function k8(J,Q){J.debugName=Q||void 0,SJ()}var YJ={id:C6,type:KJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},J4=Symbol.for("pocketjs.native-node"),l0=1,lJ=3,$J=8,_8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function j0(J){return J.domAttrs??={}}function Q4(J,Q){let $=J.domNodeType??(uJ(J)?lJ:l0),Z=$===lJ?F0(J.text??""):$===$J?S8(J.domData??""):Y4(J.domTag??K0(J));for(let X of Object.keys(J.domAttrs??{}))u0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)GJ(Z,Q4(X,!0));return Z}function u0(J,Q,$){if(_8.has(Q)){fJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete j0(J)[Q];else j0(J)[Q]=$}function p0(J){if(J[J4]===!0)return J;return Object.defineProperty(J,J4,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?lJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===$J?J.domData??"":J.text??""},set($){if(J.domNodeType===$J)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===$J?J.domData??"":J.text??""},set($){if(J.domNodeType===$J)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===$J)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===$J)J.domData=Z;else if(uJ(J))B0(J,Z);else if(E8(J),Z)GJ(J,F0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return H4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??K0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===lJ)return"#text";if(J.domNodeType===$J)return"#comment";return(J.domTag??K0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){fJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===YJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return GJ(J,$),$},insertBefore($,Z){return GJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return GJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return Q4(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){u0(J,$,Z)},removeAttribute($){u0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}p0(YJ);var c0=null;function A8(J){c0=J}var d0={unknownClass:0,unknownTexture:0},$4=new Map;function Z4(J,Q){$4.set(J,Q)}var X4=new Map;function W4(J,Q){X4.set(J,Q)}var yJ=new Set,w8=new Set;function q4(J){if(!J)return!1;if(w8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return p0({id:b().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function F0(J){let Q=b(),$=Q.createNode(KJ.text);return Q.setText($,J),p0({id:$,type:KJ.text,parent:null,children:[],text:J,domNodeType:lJ,domTag:"#text"})}function S8(J=""){let Q=F0("");return Q.domNodeType=$J,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){b().replaceText(J.id,Q),J.text=Q,SJ()}function uJ(J){return J.type===KJ.text}function G4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function GJ(J,Q,$){let Z=b();if(G4(Q),yJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,SJ()}function pJ(J,Q){if(!Q)return;M8(Q),b().removeChild(J.id,Q.id),G4(Q),yJ.add(Q),SJ()}function y8(J){return J.parent??void 0}function f8(J){return J.children[0]}function H4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function C8(J,Q){let $=b();if(SJ(),Q==null||Q===""){$.setStyle(J.id,x6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=c0?c0(Q):void 0;if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);d0.unknownClass++;return}$.setStyle(J.id,Z)}function x8(J,Q){let $=b();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=$4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);d0.unknownTexture++;return}$.setImage(J.id,Z)}function g8(J,Q){let $=b();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=X4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);d0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function h8(J,Q,$){let Z=b(),X=Q??{},W=$??{},z=!1;for(let F in X){let P=X[F];if(W[F]===P)continue;let D=g6[F];if(D===void 0)throw Error(`PocketJS: unknown style prop '${F}' (see spec PROP)`);Z.setProp(J.id,D,s6(F,P)),z=!0}if(z)SJ()}function fJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete j0(J)[Q];else j0(J)[Q]=$;switch(Q){case"class":return C8(J,$),$;case"onPress":case"on:press":return Y8(J,$),$;case"src":return x8(J,$),$;case"sprite":return g8(J,$),$;case"style":return h8(J,$,Z),$;case"focusable":return G8(J,!!$),$;case"debugName":return k8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${K0(J)}>`)}function E8(J){for(let Q of[...J.children])pJ(J,Q)}function K0(J){for(let Q of Object.keys(KJ))if(KJ[Q]===J.type)return Q;return String(J.type)}function b8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}fJ(J,Q,$,Z)}var N8=f6({createElement:Y4,createTextNode:F0,replaceText:B0,isTextNode:uJ,setProperty:b8,insertNode(J,Q,$){GJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:y8,getFirstChild:f8,getNextSibling:H4}),{render:T8,effect:lQ,memo:HJ,createComponent:q,createElement:j4,insert:uQ,spread:v8,mergeProps:pQ,use:cQ}=N8,dQ={linear:c.Easing.Linear,in:c.Easing.EaseIn,out:c.Easing.EaseOut,"in-out":c.Easing.EaseInOut,"out-back":c.Easing.OutBack,spring:c.Easing.Spring,"spring-bouncy":c.Easing.SpringBouncy},m8=null;function F4(J){m8=J}function l8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function B4(J,Q){let $=j4(J);return v8($,Q,!1),l8(Q.nodeRef,$),$}function R(J){return B4("view",J)}function L(J){return B4("text",J)}var iQ=new WeakMap,sQ=new WeakMap,u8={}!==null?Object.freeze({...{}}):Object.freeze({}),aQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:u8}),rQ=new Map,jJ=36000,i0=30,p8=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(jJ),tapeAnalog:new Uint16Array(jJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-i0,saidHello:!1,hostCalls:0};function c8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-i0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)e1(()=>{Y.treeDirty=!0}),t8();else e1(null);globalThis.__pocketDevtools=J2}function d8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)s8(),n8();let W=Q,z=$===void 0?UJ:$&65535,F=Z,P=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(jJ).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==UJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function M4(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,z]of J)Z.fill(W,X,Math.min(X+z,$)),X+=z;return Z}function V4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return M4(J.masks,0,Q)}function P4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return M4(J.analog??[],UJ,Q)}function D4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,T({t:"hello",app:Y.app,host:e8(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` +`))if(X.trim())a8(X)}}function a8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),s0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),s0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":R4();break;case"eval":{let Z=!0,X;try{X=U0((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}T({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":T({t:"tape",tape:U4()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}T({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=V4(Z),Y.replayAnalog=Z.analog?P4(Z):null,Y.replayTouch=Z.touch?D4(Z):null,Y.replayAt=0;break}default:break}}function r8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=i0)R4();if(Y.frame%p8===0)s0()}function n8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function s0(){T({t:"stats",frame:Y.frame,nodes:I4(YJ),tapeLen:Y.tapeLen,paused:Y.paused})}function R4(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,T({t:"tree",frame:Y.frame,root:L4(YJ)})}function o8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function a0(J,Q){if(Array.isArray(J)){for(let $ of J)a0($,Q);return}if(o8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)a0($,Q)}}function O4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)a0(Z,Q)}function L4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(O4(J,(X)=>{if(X.domNodeType===8)return;Z.push(L4(X))}),Z.length)Q.k=Z;return Q}function I4(J){let Q=1;return O4(J,($)=>{Q+=I4($)}),Q}function t8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{T({t:"log",level:$,args:X.map((W)=>U0(W))}),Z?.apply(Q,X)}}}function U0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?k4(W):JSON.stringify(k4(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((z)=>U0(z,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,z])=>`${W}: ${U0(z,Q+1)}`).join(", ")}}`}function k4(J){return J.length>200?J.slice(0,199)+"…":J}function e8(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var J2={get frame(){return Y.frame},dumpTape:()=>U4(),replay:(J)=>{Y.replayMasks=V4(J),Y.replayAnalog=J.analog?P4(J):null,Y.replayTouch=J.touch?D4(J):null,Y.replayAt=0}},_4=new Map,r0=new Map;function A4(J){return J.trim().replace(/\s+/g," ")}function w4(J){return J.split(" ").sort().join(" ")}var S4=-1;function Q2(J){for(let Q of Object.keys(J)){let $=J[Q],Z=A4(Q);_4.set(Z,$);let X=w4(Z),W=r0.get(X);r0.set(X,W!==void 0&&W!==$?S4:$)}}function $2(J){let Q=A4(J),$=_4.get(Q);if($!==void 0)return $;let Z=r0.get(w4(Q));return Z===S4?void 0:Z}var n0=9,Z2=(1<{let X=($&W2)!==0,W=X?o0:n0,z=X?q2:Z2;return Object.freeze({id:$>>>(X?z2:X2)&255,x:$&z,y:$>>>W&z,hit:Q?.[Z]})}))}function G2(){return M0}function H2(){M0=t0}var y4=8,FJ=8,j2=3,F2=8,B2=6,K2=0.5,t=1,cJ=2,e0=4,RJ=8,CJ=[],f4=0,V0=0,BJ=Array.from({length:y4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(FJ),histY:new Int16Array(FJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function U2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function M2(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=t1(Q,$,Z.fact);let F=Z.hit;if(F)return U2(F,W)}let z=X.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let F=CJ[z];if(F.disposed)continue;if(f4>0&&!F.opts.allowWhenBlocked)continue;if(!M2(F,$,Z,W))continue;F.flags[J.slot]=t,J.owners.push(F)}for(let z of J.owners)z.opts.onDown?.(J)}function D2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%FJ,J.histLenz||Z>z))X.flags[J.slot]|=cJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&t)||W&(cJ|e0))continue;if(!X.opts.onLongPress)continue;let z=Math.max(1,Math.round((X.opts.longPressSeconds??K2)*b1()));if(J.frames=0)CJ.splice($,1)},cancel(){if(!Q.disposed)g4(Q)},get panning(){for(let $ of BJ)if($.used&&Q.flags[$.slot]&RJ)return!0;return!1}}}function k2(J){let Q=I2(J);return A0(()=>Q.dispose()),Q}function h4(){CJ.length=0,f4=0,V0=0;for(let J of BJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function _2(){return k2({onDown:(J)=>{let Q=o1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=o1(J.x,J.y,J.hit);if(Q)U8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var A2=1,J1=new Map,P0=[];function w2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function S2(){A2=1,J1.clear(),P0=[]}function y2(){if(P0.length===0)return;let J=P0;P0=[];for(let{id:Q,result:$}of J){let Z=J1.get(Q);if(!Z)continue;J1.delete(Q),w2()?.({t:"delivery",frame:N1(),id:Q,kind:Z.kind}),Z.onResult($)}}var E4=new Set;function f2(){if(E4.size===0)return;for(let J of E4)J()}var C2={"w-[210] h-[104] px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":0,"text-sm text-slate-500 font-bold":1,"text-lg text-slate-900 font-bold":2,"h-[72] px-5 flex-row items-center justify-between":3,"w-[450] flex-col gap-2":4,"text-base text-slate-900 font-bold":5,"text-sm text-slate-500":6,"text-sm text-emerald-600 font-bold":7,"text-sm text-slate-900 font-bold":8,"h-[64] px-5 flex-row items-center":9,"w-[240] text-base text-slate-900 font-bold":10,"w-[156] text-sm text-slate-500":11,"relative w-[632] h-[196] flex-col":12,"relative w-[632] h-[160] overflow-hidden":13,"absolute w-[632] h-[2] bg-slate-200":14,"absolute text-sm text-slate-500 font-bold":15,"absolute rounded-lg bg-emerald-500":16,"absolute rounded-lg bg-red-500":17,"absolute w-[9] h-[9] rounded-lg bg-emerald-500":18,"absolute w-[9] h-[9] rounded-lg bg-red-500":19,"h-[36] px-1 flex-row items-center justify-between":20,"flex-col w-full h-full bg-slate-50":21,"h-[64] px-6 pt-2":22,"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":23,"h-[304] px-6 pt-3":24,"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100":25,"h-[64] flex-row items-end justify-between":26,"text-2xl text-slate-950 font-bold":27,"text-base text-emerald-600 font-bold":28,"text-base text-red-500 font-bold":29,"h-[60] px-6 pt-2 flex-row gap-3":30,"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":31,"w-[100] h-[44] items-center justify-center rounded-lg bg-white":32,"text-sm text-white font-bold":33,"pt-3 text-sm text-slate-500":34,"h-[126] px-6 pt-3 flex-row items-start gap-[21]":35,"h-[200] px-6 flex-col":36,"h-[150] flex-col rounded-xl shadow bg-white border-slate-100":37,"h-[184] px-6 flex-col":38,"h-[136] flex-col rounded-xl shadow bg-white border-slate-100":39,"h-[126] px-6 pt-2":40,"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":41,"flex-col gap-3":42,"text-xl text-emerald-600 font-bold":43,"text-xl text-red-500 font-bold":44,"h-[104] px-6 flex-row items-center justify-between":45,"w-[460] text-sm text-red-500":46,"w-[460] text-sm text-slate-500":47,"w-[176] h-[64]":48,"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":49,"text-sm text-orange-600 font-bold":50,"relative flex-col w-full h-full bg-slate-50":51,"px-6 pt-[14] flex-col gap-[12]":52,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":53,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":54,"flex-row items-center justify-between":55,"text-base text-slate-500 font-bold":56,"text-sm text-emerald-600":57,"px-6 pt-[14] flex-col gap-[14]":58,"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100":59,"text-base text-slate-500":60,"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100":61,"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":62,"flex-row items-center":63,"w-[170] text-lg text-slate-900 font-bold":64,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":65,"absolute inset-0 z-50 flex-col items-center justify-center":66,"absolute inset-0 bg-slate-950":67,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":68,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":69,"flex-row flex-wrap":70,grow:71,"text-2xl text-white font-bold":72,"text-sm text-slate-600 font-bold":73,"text-base text-slate-900":74,"px-6":75,"px-6 py-5":76,"gap-4":77,"w-[34] h-[34] rounded-lg bg-amber-400":78,"w-[34] h-[34] rounded-lg bg-red-500":79,"w-[34] h-[34] rounded-lg bg-slate-800":80,"w-[34] h-[34] rounded-lg bg-emerald-500":81,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":82,"flex-row items-center gap-4":83,"w-[34] text-2xl text-white font-bold":84,"w-[332] flex-col items-end gap-2":85,"text-sm text-slate-300 font-bold":86,"text-sm text-slate-400":87,"h-[40] px-1 flex-row items-center justify-between":88,"w-full h-full items-center justify-center rounded-xl bg-slate-200":89,"w-full h-full items-center justify-center rounded-xl bg-orange-600":90,"text-base text-white font-bold":91};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var x2="ui:styles",g2="ui:font.",b4="ui:img.",N4="ui:sprite.";function h2(){return globalThis.ui}function E2(J){if(J.__textures)return;for(let Q of h0(b4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)Z4(Q.slice(b4.length),Z)}}function b2(J){if(J.__sprites)return;for(let Q of h0(N4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),z=$[4],F=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),U=J.uploadTexture($.subarray(16),X,W,z);if(U>=0)W4(Q.slice(N4.length),{handle:U,frames:F,cols:P,step:D})}}function T4(J){let Q=j4("view");return fJ(Q,"style",J,void 0),Q}var D0=null,R0=null;function N2(J,Q){if(!D0||!R0)return;fJ(D0,"style",{width:J,height:Q,overflow:c.Overflow.Hidden},void 0),fJ(R0,"style",{width:J,height:Q,posType:c.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=b();$.__viewport={w:J,h:Q}}function T2(J,Q={}){let $=u6(Q.ops);if(p6($),A8($2),Q.styles)Q2(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let w in Z)Z4(w,Z[w]);let H=$.ops.__sprites;if(H)for(let w in H)W4(w,H[w])}if($.kind==="injected"||Z===void 0){if(Q.pak)u1(Q.pak);if(z8()){for(let H of h0())if(H===x2)$.ops.loadStyles?.(vJ(H));else if(H.startsWith(g2))$.ops.loadFontAtlas?.(vJ(H))}}let X=g1($.ops),W=X?.w??f1,z=X?.h??C1,F=T4({width:W,height:z,overflow:c.Overflow.Hidden}),P=T4({width:W,height:z,posType:c.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});GJ(YJ,F),GJ(YJ,P),F4(P),D0=F,R0=P,p1(F),r1(YJ),X8(),h4(),_2(),o6(),S2(),c8($.ops),c6(d8((H,w,C,g)=>{t6(),e6(w),Y2(C,g),f2(),y2(),L2(),W8(H),I8(H),z4()}));let D=T8(J,F),U=d6(N2);return()=>{U(),H2(),h4(),D(),p1(null),r1(null),F4(null),D0=null,R0=null;for(let H of YJ.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);z4()}}function v2(J,Q={}){let $=Q.ops??h2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)u1(Q.pak);return E2($),b2($),T2(J,{ops:$,styles:Q.styles??C2,pak:Q.pak})}var v4="$b",m2=9007199254740991,l2=":memory:",xJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function u2(J){let Q="";for(let $=0;$>2]+xJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2m2)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function d2(J){if(J!==null&&typeof J==="object")return p2(J[v4]);return J}function i2(J){if(Array.isArray(J))return JSON.stringify(J.map(m4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=m4(Z);return JSON.stringify(Q)}class Q1{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,i2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=l4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(d2))}run(...J){let Q=this.execute(l4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function l4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class u4{statements=new Map;txDepth=0;constructor(J=l2){let Q=c2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new Q1(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new Q1(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let z=J(...Q);return this.txDepth--,this.exec(X),z}catch(z){throw this.txDepth--,this.exec(W),z}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var s2={title:"text-2xl text-white font-bold",section:"text-sm text-slate-600 font-bold",body:"text-base text-slate-900",bodyStrong:"text-base text-slate-900 font-bold",caption:"text-sm text-slate-500"};function a2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return q(R,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[q(R,{class:"flex-row items-center gap-4",get children(){return[HJ(()=>HJ(()=>!!J.back)()?q(L,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):q(R,{get["class"](){return Q()}})),q(L,{get["class"](){return s2.title},get children(){return J.title}})]}}),q(R,{class:"w-[332] flex-col items-end gap-2",get children(){return[q(L,{class:"text-sm text-slate-300 font-bold",get children(){return J.metaTop??""}}),q(L,{class:"text-sm text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function r2(J){let Q=()=>J.action?J.detail?J.detail+" · VIEW ALL ›":"VIEW ALL ›":J.detail??"";return q(R,{class:"h-[40] px-1 flex-row items-center justify-between",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",get children(){return J.title}}),q(L,{class:"text-sm text-slate-500 font-bold",get children(){return Q()}})]}})}function n2(J){return q(R,{get["class"](){return J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":"w-full h-full items-center justify-center rounded-xl bg-orange-600"},get children(){return q(L,{get["class"](){return J.disabled?"text-base text-slate-500 font-bold":"text-base text-white font-bold"},get children(){return J.label}})}})}var p4=4,m=new u4("robinhood"),o2={number:"",label:"ACCOUNT",suffix:"",status:"WAITING FOR ROBINHOOD"},$1={title:"NO RECENT ACTIVITY",timestamp:"",detail:"",state:"",amount:"",side:""},t2={...$1,title:"ACTIVITY UNAVAILABLE"},e2={...$1,title:""},Z1={symbol:"NO OPEN POSITIONS",quantity:"",averagePrice:"",marketValue:""},JQ={...Z1,symbol:"POSITIONS UNAVAILABLE"},QQ={...Z1,symbol:""},iJ={account:o2,totalValue:null,cash:null,buyingPower:null,pnlDay:null,pnlWeek:null,positions:[],activity:[],positionsAvailable:!0,activityAvailable:!0,observedAt:null},[i,sJ]=E("dashboard"),[l,$Q]=E("day"),[gJ,X1]=E([]),[O0,L0]=E(""),[y,aJ]=E(iJ),[c4,OJ]=E([]),[ZQ,LJ]=E([]),[W1,q1]=E([]),[XQ,z1]=E({change:"$—",percent:"—",positive:!0}),[Y1,d4]=E(0),[i4,s4]=E(0),[a4,r4]=E(0),[n4,ZJ]=E("WAITING FOR ROBINHOOD"),[rJ,o4]=E(!1),u=0,t4=-1,e4=-1,J6=-1,G1=new Map,H1=new Map;function Q6(){return Math.floor(Date.now()/1000)}function WQ(J){try{return J?JSON.parse(J):null}catch{return null}}function qQ(){return m.query("SELECT account_number,label,suffix,status FROM accounts ORDER BY label,account_number LIMIT 16").all().map((Q)=>({number:Q.account_number,label:Q.label,suffix:Q.suffix,status:Q.status}))}function zQ(J,Q){if(e4===J)return;let $=m.query("SELECT account_number,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current LIMIT 16").all(),Z=m.query(` SELECT value.account_number,value.value,value.observed_at FROM total_value value JOIN ( @@ -7,7 +7,7 @@ FROM total_value GROUP BY account_number ) latest ON latest.account_number=value.account_number AND latest.observed_at=value.observed_at LIMIT 16 - `).all(),X=m.query("SELECT account_number,symbol,quantity,average_price,market_value FROM positions ORDER BY account_number,CAST(market_value AS REAL) DESC,symbol LIMIT 1024").all(),W=m.query("SELECT account_number,activity_id,occurred_at,symbol,side,quantity,price,amount,state,activity_type FROM activities ORDER BY account_number,occurred_at DESC,observed_at DESC LIMIT 1024").all(),z=new Map($.map((U)=>[U.account_number,U])),F=new Map(Z.map((U)=>[U.account_number,U])),P=new Map,D=new Map;for(let U of X){let H=P.get(U.account_number)||[];if(H.length<64)H.push(U);P.set(U.account_number,H)}for(let U of W){let H=D.get(U.account_number)||[];if(H.length<64)H.push(U);D.set(U.account_number,H)}G1.clear();for(let U of Q){let H=z.get(U.number),w=F.get(U.number),C=P.get(U.number)||[],g=D.get(U.number)||[];G1.set(U.number,{loadedRevision:J,value:{account:U,totalValue:w?.value??null,cash:H?.cash??null,buyingPower:H?.buying_power??null,pnlDay:H?.day_pnl??null,pnlWeek:H?.week_pnl??null,positions:C.map((A)=>({symbol:A.symbol,quantity:A.quantity||"—",averagePrice:A.average_price||"—",marketValue:A.market_value||""})),activity:g.map((A)=>({title:(A.side?A.side+" ":"")+(A.symbol||"ORDER"),timestamp:qQ(A.occurred_at),detail:A.quantity?A.quantity+" SH · "+(A.activity_type||"ORDER"):A.activity_type||"ORDER",state:A.state||"RECENT",amount:A.amount||A.price||A.quantity||"",side:A.side||""})),positionsAvailable:H!==void 0,activityAvailable:H!==void 0,observedAt:Math.max(H?.observed_at??0,w?.observed_at??0)||null}})}t4=J}function I0(J){if(J===null)return null;let Q=Number(J.replace(/[$,%]/g,""));return Number.isFinite(Q)?Q:null}function qQ(J){if(!J)return"RECENT";let Q=new Date(J);if(!Number.isFinite(Q.getTime()))return J.slice(0,16).toUpperCase();return String(Q.getMonth()+1).padStart(2,"0")+"/"+String(Q.getDate()).padStart(2,"0")+" "+String(Q.getHours()).padStart(2,"0")+":"+String(Q.getMinutes()).padStart(2,"0")}function Q6(J){let Q=Math.max(0,J6()-J);if(Q<60)return"JUST NOW";if(Q<3600)return Math.floor(Q/60)+" MIN AGO";if(Q<86400)return Math.floor(Q/3600)+" HR AGO";return Math.floor(Q/86400)+" DAY AGO"}function e(J){if(!J)return"$—";let Q=I0(J);if(Q===null)return J;let Z=Math.abs(Q).toFixed(2).split("."),X="$"+Z[0].replace(/\B(?=(\d{3})+(?!\d))/g,",")+"."+Z[1];return Q<0?"-"+X:X}function $6(J,Q){let $=J+":"+l(),Z=H1.get($);if(Z?.loadedRevision===Q){OJ(Z.value.points),LJ(Z.value.segments),q1(Z.value.labels),z1(Z.value.trend);return}let X=l()==="day"?86400:604800,z=J6()-X,P=m.query(` + `).all(),X=m.query("SELECT account_number,symbol,quantity,average_price,market_value FROM positions ORDER BY account_number,CAST(market_value AS REAL) DESC,symbol LIMIT 1024").all(),W=m.query("SELECT account_number,activity_id,occurred_at,symbol,side,quantity,price,amount,state,activity_type FROM activities ORDER BY account_number,occurred_at DESC,observed_at DESC LIMIT 1024").all(),z=new Map($.map((U)=>[U.account_number,U])),F=new Map(Z.map((U)=>[U.account_number,U])),P=new Map,D=new Map;for(let U of X){let H=P.get(U.account_number)||[];if(H.length<64)H.push(U);P.set(U.account_number,H)}for(let U of W){let H=D.get(U.account_number)||[];if(H.length<64)H.push(U);D.set(U.account_number,H)}G1.clear();for(let U of Q){let H=z.get(U.number),w=F.get(U.number),C=P.get(U.number)||[],g=D.get(U.number)||[];G1.set(U.number,{loadedRevision:J,value:{account:U,totalValue:w?.value??null,cash:H?.cash??null,buyingPower:H?.buying_power??null,pnlDay:H?.day_pnl??null,pnlWeek:H?.week_pnl??null,positions:C.map((A)=>({symbol:A.symbol,quantity:A.quantity||"—",averagePrice:A.average_price||"—",marketValue:A.market_value||""})),activity:g.map((A)=>({title:(A.side?A.side+" ":"")+(A.symbol||"ORDER"),timestamp:YQ(A.occurred_at),detail:A.quantity?A.quantity+" SH · "+(A.activity_type||"ORDER"):A.activity_type||"ORDER",state:A.state||"RECENT",amount:A.amount||A.price||A.quantity||"",side:A.side||""})),positionsAvailable:H!==void 0,activityAvailable:H!==void 0,observedAt:Math.max(H?.observed_at??0,w?.observed_at??0)||null}})}e4=J}function I0(J){if(J===null)return null;let Q=Number(J.replace(/[$,%]/g,""));return Number.isFinite(Q)?Q:null}function YQ(J){if(!J)return"RECENT";let Q=new Date(J);if(!Number.isFinite(Q.getTime()))return J.slice(0,16).toUpperCase();return String(Q.getMonth()+1).padStart(2,"0")+"/"+String(Q.getDate()).padStart(2,"0")+" "+String(Q.getHours()).padStart(2,"0")+":"+String(Q.getMinutes()).padStart(2,"0")}function $6(J){let Q=Math.max(0,Q6()-J);if(Q<60)return"JUST NOW";if(Q<3600)return Math.floor(Q/60)+" MIN AGO";if(Q<86400)return Math.floor(Q/3600)+" HR AGO";return Math.floor(Q/86400)+" DAY AGO"}function e(J){if(!J)return"$—";let Q=I0(J);if(Q===null)return J;let Z=Math.abs(Q).toFixed(2).split("."),X="$"+Z[0].replace(/\B(?=(\d{3})+(?!\d))/g,",")+"."+Z[1];return Q<0?"-"+X:X}function Z6(J,Q){let $=J+":"+l(),Z=H1.get($);if(Z?.loadedRevision===Q){OJ(Z.value.points),LJ(Z.value.segments),q1(Z.value.labels),z1(Z.value.trend);return}let X=l()==="day"?86400:604800,z=Q6()-X,P=m.query(` WITH RECURSIVE buckets(bucket_index, bucket_time) AS ( SELECT 0, ?1 UNION ALL @@ -19,4 +19,4 @@ WHERE account_number = ?3 AND observed_at >= ?1 AND observed_at <= bucket_time ORDER BY observed_at DESC LIMIT 1) AS total_value FROM buckets ORDER BY bucket_index - `).all(z,X,J).map((j)=>({time:j.bucket_time,value:I0(j.total_value)})),D=P.map((j)=>j.time),U=P.map((j)=>j.value).filter((j)=>j!==null),H=[D[0],D[9],D[19]].map((j)=>{let G=new Date(j*1000);return l()==="day"?String(G.getHours()).padStart(2,"0")+":"+String(G.getMinutes()).padStart(2,"0"):String(G.getMonth()+1)+"/"+String(G.getDate())});if(U.length===0){let j=l()==="day"?y().pnlDay:y().pnlWeek,G=I0(j),V={points:[],segments:[],labels:H,trend:{change:e(j),percent:"—",positive:G===null||G>=0}};H1.set($,{loadedRevision:Q,value:V}),OJ(V.points),LJ(V.segments),q1(V.labels),z1(V.trend);return}let w=Math.min(...U),C=Math.max(...U),g=Math.max(0.01,C-w),A=P.flatMap((j,G)=>j.value===null?[]:[{x:G*622/19,y:U.length===1?80:10+(C-j.value)*140/g}]),s=A.slice(1).map((j,G)=>{let V=A[G],k=j.x-V.x,_=j.y-V.y;return{x:V.x,y:V.y,width:Math.sqrt(k*k+_*_),angle:Math.atan2(_,k)*180/Math.PI}}),a=U[U.length-1]-U[0],K={change:e(String(a)),percent:U[0]===0?"—":(a*100/U[0]).toFixed(2)+"%",positive:a>=0};H1.set($,{loadedRevision:Q,value:{points:A,segments:s,labels:H,trend:K}}),OJ(A),LJ(s),q1(H),z1(K)}function zQ(J){if(e4===J)return;let Q=m.query("SELECT status,error,completed_at FROM refresh_runs ORDER BY id DESC LIMIT 1").get();if(n4(!1),Q?.status==="failed")ZJ("REFRESH FAILED · "+String(Q.error||"UNKNOWN ERROR").slice(0,52));else if(Q?.status==="partial")ZJ("LIVE WITH PARTIAL DATA");else if(y().observedAt)ZJ("LIVE / READ ONLY · "+Q6(y().observedAt));else ZJ("WAITING FOR ROBINHOOD");e4=J}function Z6(J,Q){if(!J){if(aJ(iJ),OJ([]),LJ([]),!rJ())ZJ("WAITING FOR ROBINHOOD");return}let $=G1.get(J);if($?.loadedRevision===Q){if(aJ($.value),$6(J,Q),$.value.observedAt&&!rJ())ZJ("LIVE / READ ONLY · "+Q6($.value.observedAt));return}aJ(iJ),OJ([]),LJ([])}function X6(J=u){try{let Q=m.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==u4){X1([]),L0(""),aJ(iJ),OJ([]),LJ([]),ZJ("WAITING FOR ROBINHOOD");return}eJ(()=>{u=Math.max(u,J);let $=gJ();if(o4!==u)$=XQ(),X1($),o4=u;WQ(u,$);let Z=O0();if(!$.some((X)=>X.number===Z))Z=$[0]?.number||"",L0(Z);Z6(Z,u),zQ(u)})}catch{eJ(()=>{X1([]),L0(""),aJ(iJ),OJ([]),LJ([]),ZJ("WAITING FOR ROBINHOOD")})}}function YQ(){return""}function GQ(){let J=m.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((z)=>z.name)),$=J.map((z)=>{let F=m.query("SELECT COUNT(*) AS count FROM "+z.name).get().count;return{name:z.name,rowCount:F,schema:z.sql}}),Z=Q.has("refresh_runs")?m.query("SELECT id,started_at,completed_at,operation_count,success_count,status,error FROM refresh_runs ORDER BY id DESC LIMIT 3").all():[],X=Q.has("portfolio_current")?m.query("SELECT substr(account_number,-4) AS account_suffix,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current ORDER BY observed_at DESC LIMIT 4").all():[],W=Q.has("total_value")?m.query("SELECT substr(account_number,-4) AS account_suffix,observed_at,value FROM total_value ORDER BY observed_at DESC LIMIT 8").all():[];return{database:"robinhood.sqlite",schemaVersion:u4,tables:$,latestRefreshes:Z,latestPortfolios:X,latestValues:W}}function j1(){return $Q()}function k0(J){return q(i2,{get title(){return J.title},back:!0,metaTop:"READ ONLY",get metaBottom(){return J.metaBottom??"AUTO · 5 MIN"}})}function F1(J){return q(R,{class:"w-[210] h-[104] px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(L,{class:"text-sm text-slate-500 font-bold",get children(){return J.label}}),q(L,{class:"text-lg text-slate-900 font-bold",get children(){return e(J.value)}})]}})}function W6(J){return q(s2,{get title(){return J.title},get detail(){return J.detail},action:!0})}function HQ(J){if(J===0&&!y().activityAvailable)return n2;return y().activity[J]??(J===0?$1:o2)}function q6(J){let Q=()=>HQ(J.index);return q(R,{class:"h-[72] px-5 flex-row items-center justify-between",get children(){return[q(R,{class:"w-[450] flex-col gap-2",get children(){return[q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q().title}}),q(L,{class:"text-sm text-slate-500",get children(){return HJ(()=>!!Q().timestamp)()?Q().timestamp+" · "+Q().detail:""}})]}}),q(L,{get["class"](){return Q().side==="SELL"?"text-sm text-emerald-600 font-bold":"text-sm text-slate-900 font-bold"},get children(){return HJ(()=>!!Q().amount)()?e(Q().amount):""}})]}})}function jQ(J){if(J===0&&!y().positionsAvailable)return t2;return y().positions[J]??(J===0?Z1:e2)}function z6(J){let Q=()=>jQ(J.index);return q(R,{class:"h-[64] px-5 flex-row items-center",get children(){return[q(L,{class:"w-[240] text-base text-slate-900 font-bold",get children(){return Q().symbol}}),q(L,{class:"w-[156] text-sm text-slate-500",get children(){return HJ(()=>!!Q().quantity)()?Q().quantity+" SH":""}}),q(L,{class:"text-sm text-slate-500",get children(){return HJ(()=>!!Q().averagePrice)()?"AVG "+e(Q().averagePrice):""}})]}})}function FQ(){return q(R,{class:"relative w-[632] h-[196] flex-col",get children(){return[q(R,{class:"relative w-[632] h-[160] overflow-hidden",get children(){return[q(R,{class:"absolute w-[632] h-[2] bg-slate-200",style:{posType:1,insetL:0,insetT:158}}),q(L,{class:"absolute text-sm text-slate-500 font-bold",style:{posType:1,insetL:174,insetT:72},get children(){return p4().length<2?"COLLECTING 5M VALUE HISTORY":""}}),q(NJ,{get each(){return QQ()},children:(J)=>q(R,{get["class"](){return j1().positive?"absolute rounded-lg bg-emerald-500":"absolute rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x,insetT:J.y-2,width:J.width,height:4,rotate:J.angle,originX:0,originY:0.5}}})}),q(NJ,{get each(){return p4()},children:(J)=>q(R,{get["class"](){return j1().positive?"absolute w-[9] h-[9] rounded-lg bg-emerald-500":"absolute w-[9] h-[9] rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x-4,insetT:J.y-4}}})})]}}),q(R,{class:"h-[36] px-1 flex-row items-center justify-between",get children(){return[q(L,{class:"text-sm text-slate-500",get children(){return W1()[0]||""}}),q(L,{class:"text-sm text-slate-500",get children(){return W1()[1]||""}}),q(L,{class:"text-sm text-slate-500",get children(){return W1()[2]||""}})]}})]}})}function BQ(){let J=()=>j1();return q(R,{class:"flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ROBINHOOD"}),q(R,{class:"h-[64] px-6 pt-2",get children(){return q(R,{class:"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(L,{class:"text-sm text-slate-500 font-bold",children:"ACCOUNT"}),q(L,{class:"text-sm text-slate-900 font-bold",get children(){return y().account.label+(y().account.suffix?" ····"+y().account.suffix+" "+(gJ().findIndex((Q)=>Q.number===O0())+1)+"/"+gJ().length:"")+" ›"}})]}})}}),q(R,{class:"h-[304] px-6 pt-3",get children(){return q(R,{class:"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"h-[64] flex-row items-end justify-between",get children(){return[q(L,{class:"text-2xl text-slate-950 font-bold",get children(){return e(y().totalValue)}}),q(L,{get["class"](){return J().positive?"text-base text-emerald-600 font-bold":"text-base text-red-500 font-bold"},get children(){return J().change+" ("+J().percent+")"}})]}}),q(FQ,{})]}})}}),q(R,{class:"h-[60] px-6 pt-2 flex-row gap-3",get children(){return[q(R,{get["class"](){return l()==="day"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(L,{get["class"](){return l()==="day"?"text-sm text-white font-bold":"text-sm text-slate-500 font-bold"},children:"1D"})}}),q(R,{get["class"](){return l()==="week"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(L,{get["class"](){return l()==="week"?"text-sm text-white font-bold":"text-sm text-slate-500 font-bold"},children:"1W"})}}),q(L,{class:"pt-3 text-sm text-slate-500",get children(){return l()==="day"?"TODAY":"PAST WEEK"}})]}}),q(R,{class:"h-[126] px-6 pt-3 flex-row items-start gap-[21]",get children(){return[q(F1,{label:"VALUE",get value(){return y().totalValue}}),q(F1,{label:"CASH",get value(){return y().cash}}),q(F1,{label:"BUY POWER",get value(){return y().buyingPower}})]}}),q(R,{class:"h-[200] px-6 flex-col",get children(){return[q(W6,{title:"ACTIVITY",detail:"LAST 7 DAYS"}),q(R,{class:"h-[150] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(q6,{index:0}),q(q6,{index:1})]}})]}}),q(R,{class:"h-[184] px-6 flex-col",get children(){return[q(W6,{title:"POSITIONS"}),q(R,{class:"h-[136] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(z6,{index:0}),q(z6,{index:1})]}})]}}),q(R,{class:"h-[126] px-6 pt-2",get children(){return q(R,{class:"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-col gap-3",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",children:"REALIZED P&L"}),q(L,{class:"text-sm text-slate-500",get children(){return"EQUITIES / "+(l()==="day"?"TODAY":"WEEK")}})]}}),q(L,{get["class"](){return(I0(l()==="day"?y().pnlDay:y().pnlWeek)??0)>=0?"text-xl text-emerald-600 font-bold":"text-xl text-red-500 font-bold"},get children(){return e(l()==="day"?y().pnlDay:y().pnlWeek)}})]}})}}),q(R,{class:"h-[104] px-6 flex-row items-center justify-between",get children(){return[q(L,{get["class"](){return r4().startsWith("REFRESH FAILED")?"w-[460] text-sm text-red-500":"w-[460] text-sm text-slate-500"},get children(){return r4()}}),q(R,{class:"w-[176] h-[64]",get children(){return q(a2,{get label(){return rJ()?"REFRESHING":"REFRESH NOW"},get disabled(){return rJ()}})}})]}})]}})}function B1(){return[q(R,{class:"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",style:{posType:1,insetL:628,insetT:156},get children(){return q(L,{class:"text-sm text-orange-600 font-bold",children:"UP"})}}),q(R,{class:"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",style:{posType:1,insetL:628,insetT:972},get children(){return q(L,{class:"text-sm text-orange-600 font-bold",children:"DN"})}})]}function KQ(){let J=QJ(()=>gJ().slice(Y1(),Y1()+8)),Q=O0();return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ACCOUNTS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(NJ,{get each(){return J()},children:($)=>q(R,{get["class"](){return $.number===Q?"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100"},get children(){return[q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",get children(){return $.label}}),q(L,{class:"text-base text-slate-500 font-bold",get children(){return"····"+$.suffix}})]}}),q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-sm text-emerald-600",get children(){return $.status}}),q(Z0,{get when(){return $.number===Q},get children(){return q(L,{class:"text-sm text-emerald-600 font-bold",children:"SELECTED"})}})]}})]}})})}}),q(B1,{})]}})}function UQ(){let J=QJ(()=>y().activity.slice(d4(),d4()+8));return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ACTIVITY",metaBottom:"LAST 7 DAYS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[14]",get children(){return q(Z0,{get when(){return HJ(()=>!!y().activityAvailable)()&&J().length>0},get fallback(){return q(R,{class:"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100",get children(){return q(L,{class:"text-base text-slate-500",get children(){return y().activityAvailable?"NO ACTIVITY YET":"ACTIVITY UNAVAILABLE"}})}})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(R,{class:"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q.title}}),q(L,{get["class"](){return Q.side==="SELL"?"text-base text-emerald-600 font-bold":"text-base text-slate-900 font-bold"},get children(){return e(Q.amount)}})]}}),q(L,{class:"text-sm text-slate-500",get children(){return Q.timestamp+" · "+Q.detail}}),q(L,{class:"text-sm text-emerald-600 font-bold",get children(){return Q.state}})]}})})}})}}),q(B1,{})]}})}function MQ(){let J=QJ(()=>y().positions.slice(s4(),s4()+9));return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"POSITIONS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(Z0,{get when(){return HJ(()=>!!y().positionsAvailable)()&&J().length>0},get fallback(){return q(R,{class:"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100",get children(){return q(L,{class:"text-base text-slate-500",get children(){return y().positionsAvailable?"NO OPEN POSITIONS":"POSITIONS UNAVAILABLE"}})}})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(R,{class:"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-row items-center",get children(){return[q(L,{class:"w-[170] text-lg text-slate-900 font-bold",get children(){return Q.symbol}}),q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q.quantity+" SH"}})]}}),q(L,{class:"text-sm text-slate-500",get children(){return"AVERAGE COST "+e(Q.averagePrice)+(Q.marketValue?" · VALUE "+e(Q.marketValue):"")}})]}})})}})}}),q(B1,{})]}})}function VQ(){if(i()==="accounts")return q(KQ,{});if(i()==="activity")return q(UQ,{});return q(MQ,{})}function PQ(){return q(Z0,{get when(){return i()==="dashboard"},get fallback(){return q(VQ,{})},get children(){return q(BQ,{})}})}X6(),N2(()=>q(PQ,{})),globalThis.PocketPiApp={tick:YQ,update(){return""},dataChanged(J){let Q=ZQ(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),u):u;return X6($),""},invokeTool(J){try{let Q=J==="robinhood.storage_status"?GQ():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Data Action tasks do not run in the View: "+J,isError:!0})},tap(J,Q){if(i()!=="dashboard"){if(Q<112&&J<220)return sJ("dashboard"),"";if(J>=620&&Q>=140&&Q<310){if(i()==="accounts")c4(($)=>Math.max(0,$-1));if(i()==="activity")i4(($)=>Math.max(0,$-1));if(i()==="positions")a4(($)=>Math.max(0,$-1));return""}if(J>=620&&Q>=940&&Q<1130){if(i()==="accounts")c4(($)=>Math.min(Math.max(0,gJ().length-8),$+1));if(i()==="activity")i4(($)=>Math.min(Math.max(0,y().activity.length-8),$+1));if(i()==="positions")a4(($)=>Math.min(Math.max(0,y().positions.length-9),$+1));return""}if(i()==="accounts"&&J<610&&Q>=126){let $=Y1()+Math.floor((Q-126)/112),Z=gJ()[$];if(Z)eJ(()=>{L0(Z.number),sJ("dashboard")}),Z6(Z.number,u)}return""}if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(Q>=112&&Q<176)return sJ("accounts"),"";if(Q>=480&&Q<540)return eJ(()=>{JQ(J<136?"day":"week"),$6(O0(),u)}),"";if(Q>=666&&Q<866)return sJ("activity"),"";if(Q>=866&&Q<1050)return sJ("positions"),"";if(Q>=1176&&J>=500){if(rJ())return"";return n4(!0),ZJ("REFRESHING ROBINHOOD…"),JSON.stringify({type:"invokeTask",task:"refreshPortfolio"})}return""}}})(); + `).all(z,X,J).map((j)=>({time:j.bucket_time,value:I0(j.total_value)})),D=P.map((j)=>j.time),U=P.map((j)=>j.value).filter((j)=>j!==null),H=[D[0],D[9],D[19]].map((j)=>{let G=new Date(j*1000);return l()==="day"?String(G.getHours()).padStart(2,"0")+":"+String(G.getMinutes()).padStart(2,"0"):String(G.getMonth()+1)+"/"+String(G.getDate())});if(U.length===0){let j=l()==="day"?y().pnlDay:y().pnlWeek,G=I0(j),V={points:[],segments:[],labels:H,trend:{change:e(j),percent:"—",positive:G===null||G>=0}};H1.set($,{loadedRevision:Q,value:V}),OJ(V.points),LJ(V.segments),q1(V.labels),z1(V.trend);return}let w=Math.min(...U),C=Math.max(...U),g=Math.max(0.01,C-w),A=P.flatMap((j,G)=>j.value===null?[]:[{x:G*622/19,y:U.length===1?80:10+(C-j.value)*140/g}]),s=A.slice(1).map((j,G)=>{let V=A[G],k=j.x-V.x,_=j.y-V.y;return{x:V.x,y:V.y,width:Math.sqrt(k*k+_*_),angle:Math.atan2(_,k)*180/Math.PI}}),a=U[U.length-1]-U[0],K={change:e(String(a)),percent:U[0]===0?"—":(a*100/U[0]).toFixed(2)+"%",positive:a>=0};H1.set($,{loadedRevision:Q,value:{points:A,segments:s,labels:H,trend:K}}),OJ(A),LJ(s),q1(H),z1(K)}function GQ(J){if(J6===J)return;let Q=m.query("SELECT status,error,completed_at FROM refresh_runs ORDER BY id DESC LIMIT 1").get();if(o4(!1),Q?.status==="failed")ZJ("REFRESH FAILED · "+String(Q.error||"UNKNOWN ERROR").slice(0,52));else if(Q?.status==="partial")ZJ("LIVE WITH PARTIAL DATA");else if(y().observedAt)ZJ("LIVE / READ ONLY · "+$6(y().observedAt));else ZJ("WAITING FOR ROBINHOOD");J6=J}function X6(J,Q){if(!J){if(aJ(iJ),OJ([]),LJ([]),!rJ())ZJ("WAITING FOR ROBINHOOD");return}let $=G1.get(J);if($?.loadedRevision===Q){if(aJ($.value),Z6(J,Q),$.value.observedAt&&!rJ())ZJ("LIVE / READ ONLY · "+$6($.value.observedAt));return}aJ(iJ),OJ([]),LJ([])}function W6(J=u){try{let Q=m.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==p4){X1([]),L0(""),aJ(iJ),OJ([]),LJ([]),ZJ("WAITING FOR ROBINHOOD");return}eJ(()=>{u=Math.max(u,J);let $=gJ();if(t4!==u)$=qQ(),X1($),t4=u;zQ(u,$);let Z=O0();if(!$.some((X)=>X.number===Z))Z=$[0]?.number||"",L0(Z);X6(Z,u),GQ(u)})}catch{eJ(()=>{X1([]),L0(""),aJ(iJ),OJ([]),LJ([]),ZJ("WAITING FOR ROBINHOOD")})}}function HQ(){return""}function jQ(){let J=m.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((z)=>z.name)),$=J.map((z)=>{let F=m.query("SELECT COUNT(*) AS count FROM "+z.name).get().count;return{name:z.name,rowCount:F,schema:z.sql}}),Z=Q.has("refresh_runs")?m.query("SELECT id,started_at,completed_at,operation_count,success_count,status,error FROM refresh_runs ORDER BY id DESC LIMIT 3").all():[],X=Q.has("portfolio_current")?m.query("SELECT substr(account_number,-4) AS account_suffix,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current ORDER BY observed_at DESC LIMIT 4").all():[],W=Q.has("total_value")?m.query("SELECT substr(account_number,-4) AS account_suffix,observed_at,value FROM total_value ORDER BY observed_at DESC LIMIT 8").all():[];return{database:"robinhood.sqlite",schemaVersion:p4,tables:$,latestRefreshes:Z,latestPortfolios:X,latestValues:W}}function j1(){return XQ()}function k0(J){return q(a2,{get title(){return J.title},back:!0,metaTop:"READ ONLY",get metaBottom(){return J.metaBottom??"AUTO · 5 MIN"}})}function F1(J){return q(R,{class:"w-[210] h-[104] px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(L,{class:"text-sm text-slate-500 font-bold",get children(){return J.label}}),q(L,{class:"text-lg text-slate-900 font-bold",get children(){return e(J.value)}})]}})}function q6(J){return q(r2,{get title(){return J.title},get detail(){return J.detail},action:!0})}function FQ(J){if(J===0&&!y().activityAvailable)return t2;return y().activity[J]??(J===0?$1:e2)}function z6(J){let Q=()=>FQ(J.index);return q(R,{class:"h-[72] px-5 flex-row items-center justify-between",get children(){return[q(R,{class:"w-[450] flex-col gap-2",get children(){return[q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q().title}}),q(L,{class:"text-sm text-slate-500",get children(){return HJ(()=>!!Q().timestamp)()?Q().timestamp+" · "+Q().detail:""}})]}}),q(L,{get["class"](){return Q().side==="SELL"?"text-sm text-emerald-600 font-bold":"text-sm text-slate-900 font-bold"},get children(){return HJ(()=>!!Q().amount)()?e(Q().amount):""}})]}})}function BQ(J){if(J===0&&!y().positionsAvailable)return JQ;return y().positions[J]??(J===0?Z1:QQ)}function Y6(J){let Q=()=>BQ(J.index);return q(R,{class:"h-[64] px-5 flex-row items-center",get children(){return[q(L,{class:"w-[240] text-base text-slate-900 font-bold",get children(){return Q().symbol}}),q(L,{class:"w-[156] text-sm text-slate-500",get children(){return HJ(()=>!!Q().quantity)()?Q().quantity+" SH":""}}),q(L,{class:"text-sm text-slate-500",get children(){return HJ(()=>!!Q().averagePrice)()?"AVG "+e(Q().averagePrice):""}})]}})}function KQ(){return q(R,{class:"relative w-[632] h-[196] flex-col",get children(){return[q(R,{class:"relative w-[632] h-[160] overflow-hidden",get children(){return[q(R,{class:"absolute w-[632] h-[2] bg-slate-200",style:{posType:1,insetL:0,insetT:158}}),q(L,{class:"absolute text-sm text-slate-500 font-bold",style:{posType:1,insetL:174,insetT:72},get children(){return c4().length<2?"COLLECTING 5M VALUE HISTORY":""}}),q(NJ,{get each(){return ZQ()},children:(J)=>q(R,{get["class"](){return j1().positive?"absolute rounded-lg bg-emerald-500":"absolute rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x,insetT:J.y-2,width:J.width,height:4,rotate:J.angle,originX:0,originY:0.5}}})}),q(NJ,{get each(){return c4()},children:(J)=>q(R,{get["class"](){return j1().positive?"absolute w-[9] h-[9] rounded-lg bg-emerald-500":"absolute w-[9] h-[9] rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x-4,insetT:J.y-4}}})})]}}),q(R,{class:"h-[36] px-1 flex-row items-center justify-between",get children(){return[q(L,{class:"text-sm text-slate-500",get children(){return W1()[0]||""}}),q(L,{class:"text-sm text-slate-500",get children(){return W1()[1]||""}}),q(L,{class:"text-sm text-slate-500",get children(){return W1()[2]||""}})]}})]}})}function UQ(){let J=()=>j1();return q(R,{class:"flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ROBINHOOD"}),q(R,{class:"h-[64] px-6 pt-2",get children(){return q(R,{class:"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(L,{class:"text-sm text-slate-500 font-bold",children:"ACCOUNT"}),q(L,{class:"text-sm text-slate-900 font-bold",get children(){return y().account.label+(y().account.suffix?" ····"+y().account.suffix+" "+(gJ().findIndex((Q)=>Q.number===O0())+1)+"/"+gJ().length:"")+" ›"}})]}})}}),q(R,{class:"h-[304] px-6 pt-3",get children(){return q(R,{class:"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"h-[64] flex-row items-end justify-between",get children(){return[q(L,{class:"text-2xl text-slate-950 font-bold",get children(){return e(y().totalValue)}}),q(L,{get["class"](){return J().positive?"text-base text-emerald-600 font-bold":"text-base text-red-500 font-bold"},get children(){return J().change+" ("+J().percent+")"}})]}}),q(KQ,{})]}})}}),q(R,{class:"h-[60] px-6 pt-2 flex-row gap-3",get children(){return[q(R,{get["class"](){return l()==="day"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(L,{get["class"](){return l()==="day"?"text-sm text-white font-bold":"text-sm text-slate-500 font-bold"},children:"1D"})}}),q(R,{get["class"](){return l()==="week"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(L,{get["class"](){return l()==="week"?"text-sm text-white font-bold":"text-sm text-slate-500 font-bold"},children:"1W"})}}),q(L,{class:"pt-3 text-sm text-slate-500",get children(){return l()==="day"?"TODAY":"PAST WEEK"}})]}}),q(R,{class:"h-[126] px-6 pt-3 flex-row items-start gap-[21]",get children(){return[q(F1,{label:"VALUE",get value(){return y().totalValue}}),q(F1,{label:"CASH",get value(){return y().cash}}),q(F1,{label:"BUY POWER",get value(){return y().buyingPower}})]}}),q(R,{class:"h-[200] px-6 flex-col",get children(){return[q(q6,{title:"ACTIVITY",detail:"LAST 7 DAYS"}),q(R,{class:"h-[150] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(z6,{index:0}),q(z6,{index:1})]}})]}}),q(R,{class:"h-[184] px-6 flex-col",get children(){return[q(q6,{title:"POSITIONS"}),q(R,{class:"h-[136] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(Y6,{index:0}),q(Y6,{index:1})]}})]}}),q(R,{class:"h-[126] px-6 pt-2",get children(){return q(R,{class:"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-col gap-3",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",children:"REALIZED P&L"}),q(L,{class:"text-sm text-slate-500",get children(){return"EQUITIES / "+(l()==="day"?"TODAY":"WEEK")}})]}}),q(L,{get["class"](){return(I0(l()==="day"?y().pnlDay:y().pnlWeek)??0)>=0?"text-xl text-emerald-600 font-bold":"text-xl text-red-500 font-bold"},get children(){return e(l()==="day"?y().pnlDay:y().pnlWeek)}})]}})}}),q(R,{class:"h-[104] px-6 flex-row items-center justify-between",get children(){return[q(L,{get["class"](){return n4().startsWith("REFRESH FAILED")?"w-[460] text-sm text-red-500":"w-[460] text-sm text-slate-500"},get children(){return n4()}}),q(R,{class:"w-[176] h-[64]",get children(){return q(n2,{get label(){return rJ()?"REFRESHING":"REFRESH NOW"},get disabled(){return rJ()}})}})]}})]}})}function B1(){return[q(R,{class:"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",style:{posType:1,insetL:628,insetT:156},get children(){return q(L,{class:"text-sm text-orange-600 font-bold",children:"UP"})}}),q(R,{class:"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",style:{posType:1,insetL:628,insetT:972},get children(){return q(L,{class:"text-sm text-orange-600 font-bold",children:"DN"})}})]}function MQ(){let J=QJ(()=>gJ().slice(Y1(),Y1()+8)),Q=O0();return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ACCOUNTS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(NJ,{get each(){return J()},children:($)=>q(R,{get["class"](){return $.number===Q?"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100"},get children(){return[q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",get children(){return $.label}}),q(L,{class:"text-base text-slate-500 font-bold",get children(){return"····"+$.suffix}})]}}),q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-sm text-emerald-600",get children(){return $.status}}),q(Z0,{get when(){return $.number===Q},get children(){return q(L,{class:"text-sm text-emerald-600 font-bold",children:"SELECTED"})}})]}})]}})})}}),q(B1,{})]}})}function VQ(){let J=QJ(()=>y().activity.slice(i4(),i4()+8));return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ACTIVITY",metaBottom:"LAST 7 DAYS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[14]",get children(){return q(Z0,{get when(){return HJ(()=>!!y().activityAvailable)()&&J().length>0},get fallback(){return q(R,{class:"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100",get children(){return q(L,{class:"text-base text-slate-500",get children(){return y().activityAvailable?"NO ACTIVITY YET":"ACTIVITY UNAVAILABLE"}})}})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(R,{class:"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q.title}}),q(L,{get["class"](){return Q.side==="SELL"?"text-base text-emerald-600 font-bold":"text-base text-slate-900 font-bold"},get children(){return e(Q.amount)}})]}}),q(L,{class:"text-sm text-slate-500",get children(){return Q.timestamp+" · "+Q.detail}}),q(L,{class:"text-sm text-emerald-600 font-bold",get children(){return Q.state}})]}})})}})}}),q(B1,{})]}})}function PQ(){let J=QJ(()=>y().positions.slice(a4(),a4()+9));return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"POSITIONS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(Z0,{get when(){return HJ(()=>!!y().positionsAvailable)()&&J().length>0},get fallback(){return q(R,{class:"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100",get children(){return q(L,{class:"text-base text-slate-500",get children(){return y().positionsAvailable?"NO OPEN POSITIONS":"POSITIONS UNAVAILABLE"}})}})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(R,{class:"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-row items-center",get children(){return[q(L,{class:"w-[170] text-lg text-slate-900 font-bold",get children(){return Q.symbol}}),q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q.quantity+" SH"}})]}}),q(L,{class:"text-sm text-slate-500",get children(){return"AVERAGE COST "+e(Q.averagePrice)+(Q.marketValue?" · VALUE "+e(Q.marketValue):"")}})]}})})}})}}),q(B1,{})]}})}function DQ(){if(i()==="accounts")return q(MQ,{});if(i()==="activity")return q(VQ,{});return q(PQ,{})}function RQ(){return q(Z0,{get when(){return i()==="dashboard"},get fallback(){return q(DQ,{})},get children(){return q(UQ,{})}})}W6(),v2(()=>q(RQ,{})),globalThis.PocketPiApp={tick:HQ,update(){return""},dataChanged(J){let Q=WQ(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),u):u;return W6($),""},invokeTool(J){try{let Q=J==="robinhood.storage_status"?jQ():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Data Action tasks do not run in the View: "+J,isError:!0})},tap(J,Q){if(i()!=="dashboard"){if(Q<112&&J<220)return sJ("dashboard"),"";if(J>=620&&Q>=140&&Q<310){if(i()==="accounts")d4(($)=>Math.max(0,$-1));if(i()==="activity")s4(($)=>Math.max(0,$-1));if(i()==="positions")r4(($)=>Math.max(0,$-1));return""}if(J>=620&&Q>=940&&Q<1130){if(i()==="accounts")d4(($)=>Math.min(Math.max(0,gJ().length-8),$+1));if(i()==="activity")s4(($)=>Math.min(Math.max(0,y().activity.length-8),$+1));if(i()==="positions")r4(($)=>Math.min(Math.max(0,y().positions.length-9),$+1));return""}if(i()==="accounts"&&J<610&&Q>=126){let $=Y1()+Math.floor((Q-126)/112),Z=gJ()[$];if(Z)eJ(()=>{L0(Z.number),sJ("dashboard")}),X6(Z.number,u)}return""}if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(Q>=112&&Q<176)return sJ("accounts"),"";if(Q>=480&&Q<540)return eJ(()=>{$Q(J<136?"day":"week"),Z6(O0(),u)}),"";if(Q>=666&&Q<866)return sJ("activity"),"";if(Q>=866&&Q<1050)return sJ("positions"),"";if(Q>=1176&&J>=500){if(rJ())return"";return o4(!0),ZJ("REFRESHING ROBINHOOD…"),JSON.stringify({type:"invokeTask",task:"refreshPortfolio"})}return""}}})(); diff --git a/crates/pocket-pi-agentos/src/lib.rs b/crates/pocket-pi-agentos/src/lib.rs index 1fa671b..7e74c04 100644 --- a/crates/pocket-pi-agentos/src/lib.rs +++ b/crates/pocket-pi-agentos/src/lib.rs @@ -1083,7 +1083,7 @@ fn seed_builtin_releases(workspace: &Path, catalog: &AppCatalog) -> Result<()> { &release_dir.join("plan.json"), &serde_json::to_vec_pretty(&json!({ "runtime":"pocket-pi-agentos", - "pocketjsRevision":"afc8d4e8e877dac7f9b0c01b5c0d667642009fc0", + "pocketjsRevision":"9c809bbd047ddc75c27caa4990951a78d942477a", "app":app.descriptor.id, "modules":["ui","data.fs","data.sqlite"] }))?, diff --git a/docs/agentos-architecture.md b/docs/agentos-architecture.md index cc45aa6..e2709cb 100644 --- a/docs/agentos-architecture.md +++ b/docs/agentos-architecture.md @@ -913,9 +913,12 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 ### 22.1 已实现 -1. PocketJS 固定在 `feat/fs-surface` revision - `afc8d4e8e877dac7f9b0c01b5c0d667642009fc0`;Simulator 和 ESP32-P4 共用 - `pocket-fs`、`pocket-db`、`pocket-mod` 和 `pocket-ui-surface` contracts。 +1. PocketJS 固定在 upstream `origin/main` revision + `9c809bbd047ddc75c27caa4990951a78d942477a`;Simulator 和 ESP32-P4 共用 + 正式合并的 `pocket-fs`、`pocket-db`、`pocket-mod` 和 + `pocket-ui-surface` contracts。该 revision 同时包含正式 `pocket-net` + contract;Pocket Pi 对它的 Host adapter/mount 属于下一阶段,不在依赖迁移中 + 伪装成已经接入。 2. Pi Agent 位于顶层 `/workspace`;Root View release 位于 `/workspace/data/view`,其中 `app.js` 和 `agent.js` 是同一个 System App release;普通 App 位于 `/workspace/apps/`。 diff --git a/firmware/esp32-p4/Cargo.lock b/firmware/esp32-p4/Cargo.lock index 46fd329..78b38ea 100644 --- a/firmware/esp32-p4/Cargo.lock +++ b/firmware/esp32-p4/Cargo.lock @@ -1124,7 +1124,7 @@ checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" [[package]] name = "pocket-db" version = "0.1.0" -source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" dependencies = [ "anyhow", "base64", @@ -1137,7 +1137,7 @@ dependencies = [ [[package]] name = "pocket-fs" version = "0.1.0" -source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" dependencies = [ "anyhow", "base64", @@ -1149,7 +1149,7 @@ dependencies = [ [[package]] name = "pocket-mod" version = "0.1.0" -source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" dependencies = [ "anyhow", "log", @@ -1197,7 +1197,6 @@ dependencies = [ "pocket-pi-tools", "pocketjs-core", "pocketjs-esp32p4-ppa", - "rusqlite", "serde_json", ] @@ -1223,7 +1222,7 @@ dependencies = [ [[package]] name = "pocket-ui-surface" version = "0.1.0" -source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" dependencies = [ "anyhow", "log", @@ -1234,7 +1233,7 @@ dependencies = [ [[package]] name = "pocketjs-core" version = "0.1.0" -source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" dependencies = [ "taffy", ] @@ -1242,7 +1241,7 @@ dependencies = [ [[package]] name = "pocketjs-esp32p4-ppa" version = "0.1.0" -source = "git+https://github.com/siwei-yuan/pocketjs.git?rev=afc8d4e8e877dac7f9b0c01b5c0d667642009fc0#afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" dependencies = [ "pocketjs-core", ] diff --git a/firmware/esp32-p4/Cargo.toml b/firmware/esp32-p4/Cargo.toml index fe78f4a..a1ade00 100644 --- a/firmware/esp32-p4/Cargo.toml +++ b/firmware/esp32-p4/Cargo.toml @@ -12,12 +12,6 @@ publish = false name = "pocket-pi-p4" harness = false -# Temporary SQLite spike (src/bin/sqlite_probe.rs) — delete with the probe. -[[bin]] -name = "sqlite-probe" -path = "src/bin/sqlite_probe.rs" -harness = false - [profile.release] opt-level = "s" lto = "thin" @@ -36,12 +30,9 @@ pocket-pi-embedded = { path = "../../crates/pocket-pi-embedded" } pocket-pi-protocols = { path = "../../crates/pocket-pi-protocols" } pocket-pi-tools = { path = "../../crates/pocket-pi-tools" } esp-idf-svc = { version = "0.52.1", features = ["critical-section"] } -# Temporary: SQLite spike dependency (src/bin/sqlite_probe.rs). Same version -# as pocketjs pocket-db so the spike proves the exact engine we will reuse. -rusqlite = { version = "0.40", features = ["bundled"] } embedded-svc = "0.29" -pocketjs-core = { git = "https://github.com/siwei-yuan/pocketjs.git", rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" } -pocketjs-esp32p4-ppa = { git = "https://github.com/siwei-yuan/pocketjs.git", rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0", features = ["esp-idf"] } +pocketjs-core = { git = "https://github.com/pocket-stack/pocketjs.git", rev = "9c809bbd047ddc75c27caa4990951a78d942477a" } +pocketjs-esp32p4-ppa = { git = "https://github.com/pocket-stack/pocketjs.git", rev = "9c809bbd047ddc75c27caa4990951a78d942477a", features = ["esp-idf"] } [build-dependencies] embuild = "0.33" diff --git a/firmware/esp32-p4/components/pocketjs_ppa/SOURCE_PROVENANCE.md b/firmware/esp32-p4/components/pocketjs_ppa/SOURCE_PROVENANCE.md index 5ffc65b..afb3cfe 100644 --- a/firmware/esp32-p4/components/pocketjs_ppa/SOURCE_PROVENANCE.md +++ b/firmware/esp32-p4/components/pocketjs_ppa/SOURCE_PROVENANCE.md @@ -1,7 +1,7 @@ # Source provenance The C ABI source is copied from `pocket-stack/pocketjs` at commit -`afc8d4e8e877dac7f9b0c01b5c0d667642009fc0`, matching the Rust dependency +`9c809bbd047ddc75c27caa4990951a78d942477a`, matching the Rust dependency pinned in the firmware manifest. The component manifest retains the ESP-IDF 5.5 compatibility range already proven by `esp32-pi-agent` on this board. It provides the C ABI used by diff --git a/firmware/esp32-p4/src/bin/sqlite_probe.rs b/firmware/esp32-p4/src/bin/sqlite_probe.rs deleted file mode 100644 index 0559e35..0000000 --- a/firmware/esp32-p4/src/bin/sqlite_probe.rs +++ /dev/null @@ -1,253 +0,0 @@ -//! Temporary on-device probe: proves SQLite (rusqlite `bundled`) runs on the -//! ESP32-P4 against the LittleFS `workspace` partition. Flash it, watch UART -//! for `SQLITE-PROBE:` lines, then reflash the real firmware. Not a product -//! binary — delete after the spike. -//! -//! What it exercises, in order: -//! 1. mount /workspace (same LittleFS partition the product uses); -//! 2. open a database with the `unix-none` VFS (no fcntl locking — the one -//! POSIX corner ESP-IDF's newlib does not promise) + device pragmas -//! (journal_mode=TRUNCATE, synchronous=NORMAL); -//! 3. schema DDL, one day of 5-minute samples (288 rows) inside a single -//! transaction — the Robinhood history write shape; -//! 4. aggregate + chart-window reads; -//! 5. close, reopen, recount — persistence across connections; boot counter -//! persists across power cycles. - -use std::time::Instant; - -use esp_idf_svc::fs::littlefs::Littlefs; -use esp_idf_svc::io::vfs::MountedLittlefs; -use rusqlite::{Connection, OpenFlags}; - -const WORKSPACE_ROOT: &str = "/workspace"; -const DB_PATH: &str = "/workspace/sqlite-probe.db"; - -fn main() { - esp_idf_svc::sys::link_patches(); - esp_idf_svc::log::EspLogger::initialize_default(); - if let Err(error) = run() { - log::error!("SQLITE-PROBE: FAIL: {error:#}"); - } - loop { - std::thread::sleep(std::time::Duration::from_secs(10)); - log::info!("SQLITE-PROBE: idle"); - } -} - -fn run() -> anyhow::Result<()> { - log::info!( - "SQLITE-PROBE: boot; sqlite version {}", - rusqlite::version() - ); - let _mount = mount_workspace()?; - let heap_before = unsafe { esp_idf_svc::sys::esp_get_free_heap_size() }; - - let opened_at = Instant::now(); - let conn = Connection::open_with_flags_and_vfs( - DB_PATH, - OpenFlags::SQLITE_OPEN_READ_WRITE - | OpenFlags::SQLITE_OPEN_CREATE - | OpenFlags::SQLITE_OPEN_NO_MUTEX, - "unix-none", - )?; - log::info!("SQLITE-PROBE: open {:?}", opened_at.elapsed()); - - let journal: String = - conn.query_row("PRAGMA journal_mode=TRUNCATE", [], |row| row.get(0))?; - conn.execute_batch("PRAGMA synchronous=NORMAL; PRAGMA cache_size=-32;")?; - log::info!("SQLITE-PROBE: journal_mode={journal}"); - - conn.execute_batch( - "CREATE TABLE IF NOT EXISTS boots ( - boot_index INTEGER PRIMARY KEY, - heap_free INTEGER NOT NULL - ); - CREATE TABLE IF NOT EXISTS samples ( - captured_at INTEGER PRIMARY KEY, - total_cents INTEGER NOT NULL, - day_pnl_cents INTEGER NOT NULL - );", - )?; - - let boot_index: i64 = - conn.query_row("SELECT COUNT(*) FROM boots", [], |row| row.get(0))?; - let prior_rows: i64 = - conn.query_row("SELECT COUNT(*) FROM samples", [], |row| row.get(0))?; - conn.execute( - "INSERT INTO boots (boot_index, heap_free) VALUES (?1, ?2)", - (boot_index, heap_before as i64), - )?; - log::info!("SQLITE-PROBE: boot #{boot_index}, prior samples {prior_rows}"); - - // One day of 5-minute portfolio snapshots, one transaction — the write - // shape the Robinhood history job will produce. - let wrote_at = Instant::now(); - let base = prior_rows * 300; - let tx = conn.unchecked_transaction()?; - { - let mut insert = tx.prepare( - "INSERT INTO samples (captured_at, total_cents, day_pnl_cents) - VALUES (?1, ?2, ?3)", - )?; - for i in 0..288i64 { - let captured_at = base + i * 300; - let total_cents = 1_500_000 + (i % 97) * 137; - let day_pnl_cents = (i % 41) - 20; - insert.execute((captured_at, total_cents, day_pnl_cents))?; - } - } - tx.commit()?; - log::info!("SQLITE-PROBE: insert 288 rows {:?}", wrote_at.elapsed()); - - let read_at = Instant::now(); - let (count, avg_total, max_pnl): (i64, f64, i64) = conn.query_row( - "SELECT COUNT(*), AVG(total_cents), MAX(day_pnl_cents) FROM samples", - [], - |row| Ok((row.get(0)?, row.get(1)?, row.get(2)?)), - )?; - let mut chart = conn.prepare( - "SELECT captured_at, total_cents FROM samples - ORDER BY captured_at DESC LIMIT 24", - )?; - let window: Vec<(i64, i64)> = chart - .query_map([], |row| Ok((row.get(0)?, row.get(1)?)))? - .collect::>()?; - log::info!( - "SQLITE-PROBE: aggregate count={count} avg={avg_total:.1} max_pnl={max_pnl}, \ - chart window {} rows, reads {:?}", - window.len(), - read_at.elapsed() - ); - drop(chart); - - // Close and reopen: the rows must come back from flash, not from cache. - drop(conn); - let reopened_at = Instant::now(); - let conn = Connection::open_with_flags_and_vfs( - DB_PATH, - OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_NO_MUTEX, - "unix-none", - )?; - let recount: i64 = - conn.query_row("SELECT COUNT(*) FROM samples", [], |row| row.get(0))?; - log::info!( - "SQLITE-PROBE: reopen {:?}, recount {recount}", - reopened_at.elapsed() - ); - anyhow::ensure!( - recount == prior_rows + 288, - "expected {} rows after reopen, found {recount}", - prior_rows + 288 - ); - - let file_bytes = std::fs::metadata(DB_PATH)?.len(); - let heap_after = unsafe { esp_idf_svc::sys::esp_get_free_heap_size() }; - log::info!( - "SQLITE-PROBE: db file {file_bytes} bytes, heap {heap_before} -> {heap_after} \ - (delta {})", - heap_before as i64 - heap_after as i64 - ); - log::info!( - "SQLITE-PROBE: PASS (boot #{boot_index}, samples {recount})" - ); - Ok(()) -} - -// -------------------------------------------------------------------------- -// POSIX shims: SQLite's os_unix syscall table takes the ADDRESS of these six -// functions, so the symbols must exist at link time even though our -// configuration (unix-none VFS, lstat=stat, no symlinks, no dotlock files) -// never calls the first five. LittleFS has no users, permissions or -// symlinks, so no-op successes are the honest implementations. nanosleep IS -// called (busy-handler sleeps); route it through ESP-IDF's usleep. -// -------------------------------------------------------------------------- - -#[repr(C)] -struct Timespec { - tv_sec: i64, // espidf_time64: 64-bit time_t - tv_nsec: i32, -} - -unsafe extern "C" { - fn usleep(microseconds: u32) -> i32; -} - -#[unsafe(no_mangle)] -extern "C" fn geteuid() -> u32 { - 0 -} - -#[unsafe(no_mangle)] -extern "C" fn fchmod(_fd: i32, _mode: u32) -> i32 { - 0 -} - -#[unsafe(no_mangle)] -extern "C" fn fchown(_fd: i32, _owner: u32, _group: u32) -> i32 { - 0 -} - -#[unsafe(no_mangle)] -extern "C" fn utimes(_path: *const core::ffi::c_char, _times: *const core::ffi::c_void) -> i32 { - 0 -} - -#[unsafe(no_mangle)] -extern "C" fn readlink( - _path: *const core::ffi::c_char, - _buf: *mut core::ffi::c_char, - _len: usize, -) -> isize { - -1 // never a symlink on LittleFS -} - -#[unsafe(no_mangle)] -extern "C" fn nanosleep(request: *const Timespec, _remain: *mut Timespec) -> i32 { - let request = unsafe { &*request }; - let micros = (request.tv_sec as u64) - .saturating_mul(1_000_000) - .saturating_add((request.tv_nsec as u64) / 1_000); - unsafe { usleep(micros.min(u32::MAX as u64) as u32) } -} - -// Copied from src/storage.rs — the probe is a standalone bin and the package -// has no lib target; keep byte-identical semantics (format only a blank -// partition, never a corrupted one). -type WorkspaceMount = MountedLittlefs>; - -fn mount_workspace() -> anyhow::Result { - let fs = unsafe { Littlefs::<()>::new_partition("workspace")? }; - match MountedLittlefs::mount(fs, WORKSPACE_ROOT) { - Ok(mounted) => Ok(mounted), - Err(_mount_error) if partition_is_blank()? => { - let mut fs = unsafe { Littlefs::<()>::new_partition("workspace")? }; - fs.format()?; - MountedLittlefs::mount(fs, WORKSPACE_ROOT).map_err(Into::into) - } - Err(mount_error) => Err(anyhow::anyhow!( - "LittleFS workspace mount failed; preserving non-blank partition: {mount_error}" - )), - } -} - -fn partition_is_blank() -> anyhow::Result { - let partition = unsafe { - esp_idf_svc::sys::esp_partition_find_first( - esp_idf_svc::sys::esp_partition_type_t_ESP_PARTITION_TYPE_DATA, - esp_idf_svc::sys::esp_partition_subtype_t_ESP_PARTITION_SUBTYPE_DATA_LITTLEFS, - c"workspace".as_ptr(), - ) - }; - if partition.is_null() { - anyhow::bail!("LittleFS workspace partition is missing"); - } - let mut prefix = [0u8; 4096]; - let status = unsafe { - esp_idf_svc::sys::esp_partition_read(partition, 0, prefix.as_mut_ptr().cast(), prefix.len()) - }; - if status != esp_idf_svc::sys::ESP_OK { - anyhow::bail!("read LittleFS workspace partition: ESP error {status}"); - } - Ok(prefix.iter().all(|byte| *byte == 0xff)) -} diff --git a/hosts/esp32-p4-sim/Cargo.toml b/hosts/esp32-p4-sim/Cargo.toml index 1aa9155..e82470e 100644 --- a/hosts/esp32-p4-sim/Cargo.toml +++ b/hosts/esp32-p4-sim/Cargo.toml @@ -15,8 +15,8 @@ pocket-pi-embedded = { path = "../../crates/pocket-pi-embedded" } pocket-pi-protocols = { path = "../../crates/pocket-pi-protocols" } pocket-pi-tools = { path = "../../crates/pocket-pi-tools" } pocketjs-core.workspace = true -pocket-ui-wgpu = { git = "https://github.com/siwei-yuan/pocketjs.git", rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0" } -pocket3d = { git = "https://github.com/siwei-yuan/pocketjs.git", rev = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0", default-features = false } +pocket-ui-wgpu = { git = "https://github.com/pocket-stack/pocketjs.git", rev = "9c809bbd047ddc75c27caa4990951a78d942477a" } +pocket3d = { git = "https://github.com/pocket-stack/pocketjs.git", rev = "9c809bbd047ddc75c27caa4990951a78d942477a", default-features = false } serde_json.workspace = true tempfile = "3" ureq = { version = "2.12", features = ["json"] } diff --git a/tools/xtask/src/main.rs b/tools/xtask/src/main.rs index 1d7aebb..8ad4a79 100644 --- a/tools/xtask/src/main.rs +++ b/tools/xtask/src/main.rs @@ -57,7 +57,7 @@ fn main() -> Result<()> { } fn build_agentos_apps(root: &Path) -> Result<()> { - const POCKETJS_REV: &str = "afc8d4e8e877dac7f9b0c01b5c0d667642009fc0"; + const POCKETJS_REV: &str = "9c809bbd047ddc75c27caa4990951a78d942477a"; let pocketjs = std::env::var_os("POCKETJS_ROOT") .map(PathBuf::from) .unwrap_or_else(|| root.parent().unwrap_or(root).join("pocketjs")); @@ -69,7 +69,7 @@ fn build_agentos_apps(root: &Path) -> Result<()> { let actual = String::from_utf8_lossy(&revision.stdout).trim().to_owned(); if !revision.status.success() || actual != POCKETJS_REV { bail!( - "POCKETJS_ROOT={} must be checked out at feat/fs-surface revision {POCKETJS_REV}; found {actual}", + "POCKETJS_ROOT={} must be checked out at the pinned upstream PocketJS revision {POCKETJS_REV}; found {actual}", pocketjs.display() ); } From 8f294dac92d4affeb114a3ce65facb4df7b630d5 Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Mon, 10 Aug 2026 10:43:14 +0800 Subject: [PATCH 03/24] feat(agentos): adopt PocketJS net for Exa --- Cargo.lock | 13 ++ Cargo.toml | 4 + apps/exa/data-action.ts | 78 ++++++--- apps/exa/dist/data-action.js | 10 +- apps/exa/pocket.json | 2 +- apps/robinhood/dist/data-action.js | 18 +-- crates/pocket-pi-agentos/Cargo.toml | 1 + crates/pocket-pi-agentos/src/lib.rs | 220 ++++++++++++++++++++------ docs/agentos-architecture.md | 39 +++-- firmware/esp32-p4/Cargo.lock | 13 ++ firmware/esp32-p4/src/agentos_main.rs | 7 +- firmware/esp32-p4/src/app_services.rs | 155 +++++++++++------- hosts/esp32-p4-sim/src/main.rs | 63 +++++--- tools/build-agentos-data.ts | 23 +++ tools/xtask/src/main.rs | 11 +- 15 files changed, 472 insertions(+), 185 deletions(-) create mode 100644 tools/build-agentos-data.ts diff --git a/Cargo.lock b/Cargo.lock index 2a517a5..72e99b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2564,6 +2564,18 @@ dependencies = [ "rquickjs", ] +[[package]] +name = "pocket-net" +version = "0.1.0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" +dependencies = [ + "anyhow", + "pocket-mod", + "pocketjs-core", + "serde", + "serde_json", +] + [[package]] name = "pocket-pi" version = "0.1.0" @@ -2592,6 +2604,7 @@ dependencies = [ "pocket-db", "pocket-fs", "pocket-mod", + "pocket-net", "pocket-pi-embedded", "pocket-ui-surface", "pocketjs-core", diff --git a/Cargo.toml b/Cargo.toml index e384541..46d91fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,5 +45,9 @@ rev = "9c809bbd047ddc75c27caa4990951a78d942477a" git = "https://github.com/pocket-stack/pocketjs.git" rev = "9c809bbd047ddc75c27caa4990951a78d942477a" +[workspace.dependencies.pocket-net] +git = "https://github.com/pocket-stack/pocketjs.git" +rev = "9c809bbd047ddc75c27caa4990951a78d942477a" + [profile.release] opt-level = 2 diff --git a/apps/exa/data-action.ts b/apps/exa/data-action.ts index 042cdd0..d6eccd3 100644 --- a/apps/exa/data-action.ts +++ b/apps/exa/data-action.ts @@ -1,5 +1,7 @@ // Headless Exa data plane. Search and document responses are normalized into // App-owned domain rows before one transaction invalidates the View cache. +import { __pumpNet, fetch } from "@pocketjs/framework/net"; + const nativeDb = (globalThis as any).db; const handle = nativeDb.open("exa"); if (handle < 0) throw new Error("open exa.sqlite"); @@ -69,14 +71,17 @@ function highlight(value: any): string | null { return firstText(value, ["highlight", "summary", "text"])?.slice(0, 1200) ?? null; } -function post(path: string, body: any): any { - const envelope = JSON.parse((globalThis as any).services.call( - "net.http", - "post", - JSON.stringify({ connection: "exa", path, body }), - )); - if (!envelope.ok) throw new Error(envelope.error || "Exa service failed"); - return envelope.value; +async function post(path: "/search" | "/contents", body: any): Promise { + const response = await fetch(`https://api.exa.ai${path}`, { + method: "POST", + headers: { accept: "application/json", "content-type": "application/json" }, + body: JSON.stringify(body), + timeoutMs: 12_000, + maxBytes: 96 * 1024, + }); + const value = await response.json(); + if (!response.ok) throw new Error(`Exa HTTP ${response.status}: ${JSON.stringify(value)}`); + return value; } function transaction(action: () => void): void { @@ -91,7 +96,7 @@ function transaction(action: () => void): void { (globalThis as any).app.commit(); } -function search(args: any): any { +async function search(args: any): Promise { const searchQuery = String(args.query ?? "").trim(); if (!searchQuery) throw new Error("query is required"); const searchedAt = now(); @@ -105,7 +110,7 @@ function search(args: any): any { for (const key of ["includeDomains", "excludeDomains", "startPublishedDate", "endPublishedDate"]) { if (args[key] !== undefined) body[key] = args[key]; } - const value = post("/search", body); + const value = await post("/search", body); const results = Array.isArray(value?.results) ? value.results.slice(0, 8) : []; transaction(() => { const inserted = run( @@ -134,10 +139,10 @@ function search(args: any): any { } } -function fetchDocument(args: any): any { +async function fetchDocument(args: any): Promise { const requestedUrl = String(args.url ?? "").trim(); if (!requestedUrl) throw new Error("url is required"); - const response = post("/contents", { + const response = await post("/contents", { urls: [requestedUrl], text: { maxCharacters: Math.max(200, Math.min(12000, Number(args.maxCharacters ?? 6000))), @@ -163,22 +168,51 @@ function fetchDocument(args: any): any { }; } +let pendingResult: string | undefined; +let active = false; + +function failure(error: unknown): string { + return JSON.stringify({ + text: error instanceof Error ? error.message : String(error), + isError: true, + }); +} + +function begin(action: () => Promise): void { + if (active) throw new Error("Exa Data Action is already running"); + active = true; + pendingResult = undefined; + action().then( + (value) => { + pendingResult = JSON.stringify({ text: JSON.stringify(value), details: value, isError: false }); + active = false; + }, + (error) => { + pendingResult = failure(error); + active = false; + }, + ); +} + (globalThis as any).PocketPiData = { - invokeTask(name: string) { - return JSON.stringify({ text: "Unknown Exa Data Action: " + name, isError: true }); + beginInvokeTask(name: string) { + begin(async () => { throw new Error("Unknown Exa Data Action: " + name); }); }, - invokeTool(name: string, argsLine: string) { + beginInvokeTool(name: string, argsLine: string) { try { const args = JSON.parse(argsLine); - const value = name === "research.search" ? search(args) + begin(() => name === "research.search" ? search(args) : name === "research.fetch" ? fetchDocument(args) - : (() => { throw new Error("Unknown Exa tool: " + name); })(); - return JSON.stringify({ text: JSON.stringify(value), details: value, isError: false }); + : Promise.reject(new Error("Unknown Exa tool: " + name))); } catch (error) { - return JSON.stringify({ - text: error instanceof Error ? error.message : String(error), - isError: true, - }); + pendingResult = failure(error); + active = false; } }, + tick() { __pumpNet(); }, + pollResult() { + const result = pendingResult; + pendingResult = undefined; + return result; + }, }; diff --git a/apps/exa/dist/data-action.js b/apps/exa/dist/data-action.js index 705e838..2b015d5 100644 --- a/apps/exa/dist/data-action.js +++ b/apps/exa/dist/data-action.js @@ -1,4 +1,4 @@ -(()=>{var h=globalThis.db,E=h.open("exa");if(E<0)throw Error("open exa.sqlite");var I=3;function O(){return String(h.lastError(E)||"SQLite operation failed")}function c(r){if(h.exec(E,r)!==0)throw Error(O())}function N(r,n=[]){let e=JSON.parse(h.query(E,r,JSON.stringify(n)));if(e.error)throw Error(String(e.error));return e}function l(r,n=[]){return N(r,n)}var m=N("PRAGMA user_version");if(Number(m?.user_version??0)!==I)c(` +(()=>{var O=["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"];var d=65536,F=131072,J=262144,$=32,j=8192,V=30000,z=120000;var l={unavailable:"unavailable",invalidRequest:"invalid_request",busy:"busy",dns:"dns",connect:"connect",tls:"tls",timeout:"timeout",redirect:"redirect",responseTooLarge:"response_too_large",protocol:"protocol",cancelled:"cancelled",other:"other"};var b={};for(let r=0;r<64;r++)b["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[r]]=r;function X(r){let n=0;for(let t=0;t65535)t++;n+=a<128?1:a<2048?2:a<65536?3:4}let c=new Uint8Array(n),h=0;for(let t=0;t65535)t++;else if(a>=55296&&a<=57343)a=65533;if(a<128)c[h++]=a;else if(a<2048)c[h++]=192|a>>6,c[h++]=128|a&63;else if(a<65536)c[h++]=224|a>>12,c[h++]=128|a>>6&63,c[h++]=128|a&63;else c[h++]=240|a>>18,c[h++]=128|a>>12&63,c[h++]=128|a>>6&63,c[h++]=128|a&63}return c}function Q(r){let n="",c=0;while(cr.length)throw Error("invalid UTF-8");for(let i=0;i1114111||t>=55296&&t<=57343||a===1&&t<128||a===2&&t<2048||a===3&&t<65536)throw Error("invalid UTF-8");if(t<65536)n+=String.fromCharCode(t);else t-=65536,n+=String.fromCharCode(55296+(t>>10),56320+(t&1023))}return n}var W=new Set;function Z(r){return W.add(r),()=>W.delete(r)}class f extends Error{constructor(r,n){super(n);this.name="NetError",this.code=r}}class H{constructor(r,n,c,h){this.status=r,this.url=n,this.headers=Object.freeze({...c}),this.ok=r>=200&&r<300,this.data=new Uint8Array(h)}get byteLength(){return this.data.byteLength}async bytes(){return this.data.slice()}async arrayBuffer(){return this.data.slice().buffer}async text(){try{return Q(this.data)}catch{throw Error("net: response is not valid UTF-8")}}async json(){return JSON.parse(await this.text())}}var T=new Map,w=null,A=null;function R(){let r=globalThis.net;if(!r||typeof r!=="object")return null;let n=r;return typeof n.start==="function"&&typeof n.take==="function"&&typeof n.cancel==="function"&&typeof n.poll==="function"&&typeof n.lastError==="function"?n:null}function M(r){let n=String(r);for(let c of Object.values(l))if(c===n)return c;return l.other}function o(r){let n=T.get(r.h);if(!n)return;if(T.delete(r.h),r.t==="error")n.reject(new f(M(r.code),String(r.message||r.code)));else if(!Number.isInteger(r.status)||r.status<100||r.status>599||typeof r.url!=="string"||typeof r.headers!=="object"||r.headers===null||!Number.isInteger(r.bytes)||r.bytes<0||r.bytes>J)n.ops.cancel(r.h),n.reject(new f(l.protocol,"net: malformed done event"));else{let c=new ArrayBuffer(r.bytes);if(n.ops.take(r.h,c)!==r.bytes)n.ops.cancel(r.h),n.reject(new f(l.protocol,"net: response body transfer failed"));else n.resolve(new H(r.status,r.url,r.headers,c))}if(T.size===0&&w)w(),w=null,A=null}function k(){if(T.size===0)return;let r=A;if(!r)return;let n=r.poll();if(n!==void 0){let c=null;try{c=JSON.parse(n)}catch{}if(!Array.isArray(c))for(let[h,t]of T)r.cancel(h),T.delete(h),t.reject(new f(l.protocol,"net: malformed event batch"));else for(let h of c){if(!h||typeof h!=="object")continue;let t=h;if(!Number.isInteger(t.h)||t.t!=="done"&&t.t!=="error")continue;o(t)}}if(T.size===0&&w)w(),w=null,A=null}function U(r,n){return Promise.reject(new f(r,n))}function Y(r,n,c,h){if(!Number.isInteger(r)||rc)throw new f(l.invalidRequest,`net: ${h} must be ${n}..${c}`);return r}function p(r){let n=Object.create(null),c=0,h=0;for(let t of Object.keys(r??{})){let a=t.toLowerCase(),i=String(r[t]);if(!/^[!#$%&'*+.^_`|~0-9a-z-]+$/.test(a)||/[\r\n]/.test(i))throw new f(l.invalidRequest,`net: invalid header ${t}`);if(c++,h+=X(a).byteLength+X(i).byteLength+4,c>$||h>j)throw new f(l.invalidRequest,"net: request headers exceed limits");n[a]=i}return n}function v(r){if(r===void 0)return new Uint8Array(0);if(typeof r==="string")return X(r);if(r instanceof Uint8Array)return r.slice();if(r instanceof ArrayBuffer)return new Uint8Array(r.slice(0));throw new f(l.invalidRequest,"net: body must be string or bytes")}function B(r,n={}){let c=R();if(!c)return U(l.unavailable,"net: host did not mount the net module");try{if(typeof r!=="string"||!/^https?:\/\/[^\s/]+(?:\/|$)/.test(r))throw new f(l.invalidRequest,"net: url must be absolute http:// or https://");let h=n.method??"GET";if(!O.includes(h))throw new f(l.invalidRequest,`net: unsupported method ${String(h)}`);let t=v(n.body);if((h==="GET"||h==="HEAD")&&t.byteLength>0)throw new f(l.invalidRequest,`net: ${h} cannot have a body`);if(t.byteLength>d)throw new f(l.invalidRequest,"net: request body exceeds 64 KiB");let a=Y(n.timeoutMs??V,1,z,"timeoutMs"),i=Y(n.maxBytes??F,1,J,"maxBytes"),x=JSON.stringify({url:r,method:h,headers:p(n.headers),timeoutMs:a,maxBytes:i});if(A&&A!==c)throw new f(l.unavailable,"net: mounted host changed while requests are pending");let s=c.start(x,t.buffer);if(!Number.isInteger(s)||s<0){let L=c.lastError()||"unavailable: request refused",I=L.indexOf(":"),E=M(I<0?l.other:L.slice(0,I)),_=I<0?L:L.slice(I+1).trim();return U(E,_)}return new Promise((L,I)=>{if(T.set(s,{ops:c,resolve:L,reject:I}),A=c,!w)w=Z(k)})}catch(h){return h instanceof f?Promise.reject(h):U(l.invalidRequest,String(h))}}var G=globalThis.db,g=G.open("exa");if(g<0)throw Error("open exa.sqlite");var rr=3;function nr(){return String(G.lastError(g)||"SQLite operation failed")}function S(r){if(G.exec(g,r)!==0)throw Error(nr())}function N(r,n=[]){let c=JSON.parse(G.query(g,r,JSON.stringify(n)));if(c.error)throw Error(String(c.error));return c}function q(r,n=[]){return N(r,n)}var hr=N("PRAGMA user_version");if(Number(hr?.user_version??0)!==rr)S(` CREATE TABLE IF NOT EXISTS searches ( id INTEGER PRIMARY KEY AUTOINCREMENT, query TEXT NOT NULL, @@ -30,8 +30,8 @@ ); CREATE INDEX IF NOT EXISTS documents_recent ON documents(fetched_at DESC); PRAGMA user_version=3; - `);function f(){return Math.floor(Date.now()/1000)}function A(r){return r===null||r===void 0||typeof r==="object"?null:String(r)}function s(r,n){if(!r||typeof r!=="object")return null;for(let e of n){let t=A(r[e]);if(t!==null)return t}return null}function x(r){if(Array.isArray(r?.highlights))return r.highlights.map(String).join(` -`).slice(0,1200);return s(r,["highlight","summary","text"])?.slice(0,1200)??null}function y(r,n){let e=JSON.parse(globalThis.services.call("net.http","post",JSON.stringify({connection:"exa",path:r,body:n})));if(!e.ok)throw Error(e.error||"Exa service failed");return e.value}function T(r){c("BEGIN IMMEDIATE");try{r(),c("COMMIT")}catch(n){try{c("ROLLBACK")}catch{}throw n}globalThis.app.commit()}function _(r){let n=String(r.query??"").trim();if(!n)throw Error("query is required");let e=f();try{let t={query:n,type:r.searchType??"auto",numResults:Math.max(1,Math.min(8,Number(r.numResults??5))),contents:{highlights:{maxCharacters:800}}};for(let i of["includeDomains","excludeDomains","startPublishedDate","endPublishedDate"])if(r[i]!==void 0)t[i]=r[i];let o=y("/search",t),u=Array.isArray(o?.results)?o.results.slice(0,8):[];return T(()=>{let i=l("INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,?,NULL)",[n,e,"ok",u.length]),g=Number(i.lastInsertRowid||0);u.forEach((a,S)=>{let d=s(a,["url","id"]);if(!d)return;l(`INSERT INTO search_results(search_id,rank,title,url,published_at,author,score,highlight) - VALUES(?,?,?,?,?,?,?,?)`,[g,S,s(a,["title"]),d,s(a,["publishedDate","published_at","date"]),s(a,["author"]),s(a,["score"]),x(a)])})}),o}catch(t){let o=t instanceof Error?t.message:String(t);throw T(()=>l("INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,0,?)",[n,e,"error",o])),t}}function p(r){let n=String(r.url??"").trim();if(!n)throw Error("url is required");let e=y("/contents",{urls:[n],text:{maxCharacters:Math.max(200,Math.min(12000,Number(r.maxCharacters??6000))),includeHtmlTags:!1}}),t=Array.isArray(e?.results)?e.results[0]:e;if(!t)throw Error("Exa returned no document");let o=s(t,["url","id"])||n,u=s(t,["text","content","summary"])||"";return T(()=>l(`INSERT INTO documents(url,fetched_at,title,published_at,author,text) VALUES(?,?,?,?,?,?) + `);function y(){return Math.floor(Date.now()/1000)}function cr(r){return r===null||r===void 0||typeof r==="object"?null:String(r)}function u(r,n){if(!r||typeof r!=="object")return null;for(let c of n){let h=cr(r[c]);if(h!==null)return h}return null}function tr(r){if(Array.isArray(r?.highlights))return r.highlights.map(String).join(` +`).slice(0,1200);return u(r,["highlight","summary","text"])?.slice(0,1200)??null}async function e(r,n){let c=await B(`https://api.exa.ai${r}`,{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify(n),timeoutMs:12000,maxBytes:98304}),h=await c.json();if(!c.ok)throw Error(`Exa HTTP ${c.status}: ${JSON.stringify(h)}`);return h}function K(r){S("BEGIN IMMEDIATE");try{r(),S("COMMIT")}catch(n){try{S("ROLLBACK")}catch{}throw n}globalThis.app.commit()}async function ar(r){let n=String(r.query??"").trim();if(!n)throw Error("query is required");let c=y();try{let h={query:n,type:r.searchType??"auto",numResults:Math.max(1,Math.min(8,Number(r.numResults??5))),contents:{highlights:{maxCharacters:800}}};for(let i of["includeDomains","excludeDomains","startPublishedDate","endPublishedDate"])if(r[i]!==void 0)h[i]=r[i];let t=await e("/search",h),a=Array.isArray(t?.results)?t.results.slice(0,8):[];return K(()=>{let i=q("INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,?,NULL)",[n,c,"ok",a.length]),x=Number(i.lastInsertRowid||0);a.forEach((s,L)=>{let I=u(s,["url","id"]);if(!I)return;q(`INSERT INTO search_results(search_id,rank,title,url,published_at,author,score,highlight) + VALUES(?,?,?,?,?,?,?,?)`,[x,L,u(s,["title"]),I,u(s,["publishedDate","published_at","date"]),u(s,["author"]),u(s,["score"]),tr(s)])})}),t}catch(h){let t=h instanceof Error?h.message:String(h);throw K(()=>q("INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,0,?)",[n,c,"error",t])),h}}async function lr(r){let n=String(r.url??"").trim();if(!n)throw Error("url is required");let c=await e("/contents",{urls:[n],text:{maxCharacters:Math.max(200,Math.min(12000,Number(r.maxCharacters??6000))),includeHtmlTags:!1}}),h=Array.isArray(c?.results)?c.results[0]:c;if(!h)throw Error("Exa returned no document");let t=u(h,["url","id"])||n,a=u(h,["text","content","summary"])||"";return K(()=>q(`INSERT INTO documents(url,fetched_at,title,published_at,author,text) VALUES(?,?,?,?,?,?) ON CONFLICT(url) DO UPDATE SET fetched_at=excluded.fetched_at,title=excluded.title, - published_at=excluded.published_at,author=excluded.author,text=excluded.text`,[o,f(),s(t,["title"]),s(t,["publishedDate","published_at","date"]),s(t,["author"]),u])),{status:"ok",provider:"exa",requestId:e?.requestId,document:t,costDollars:e?.costDollars}}globalThis.PocketPiData={invokeTask(r){return JSON.stringify({text:"Unknown Exa Data Action: "+r,isError:!0})},invokeTool(r,n){try{let e=JSON.parse(n),t=r==="research.search"?_(e):r==="research.fetch"?p(e):(()=>{throw Error("Unknown Exa tool: "+r)})();return JSON.stringify({text:JSON.stringify(t),details:t,isError:!1})}catch(e){return JSON.stringify({text:e instanceof Error?e.message:String(e),isError:!0})}}};})(); + published_at=excluded.published_at,author=excluded.author,text=excluded.text`,[t,y(),u(h,["title"]),u(h,["publishedDate","published_at","date"]),u(h,["author"]),a])),{status:"ok",provider:"exa",requestId:c?.requestId,document:h,costDollars:c?.costDollars}}var C,D=!1;function m(r){return JSON.stringify({text:r instanceof Error?r.message:String(r),isError:!0})}function P(r){if(D)throw Error("Exa Data Action is already running");D=!0,C=void 0,r().then((n)=>{C=JSON.stringify({text:JSON.stringify(n),details:n,isError:!1}),D=!1},(n)=>{C=m(n),D=!1})}globalThis.PocketPiData={beginInvokeTask(r){P(async()=>{throw Error("Unknown Exa Data Action: "+r)})},beginInvokeTool(r,n){try{let c=JSON.parse(n);P(()=>r==="research.search"?ar(c):r==="research.fetch"?lr(c):Promise.reject(Error("Unknown Exa tool: "+r)))}catch(c){C=m(c),D=!1}},tick(){k()},pollResult(){let r=C;return C=void 0,r}};})(); diff --git a/apps/exa/pocket.json b/apps/exa/pocket.json index dd51fa8..5064dba 100644 --- a/apps/exa/pocket.json +++ b/apps/exa/pocket.json @@ -5,6 +5,6 @@ "name": "exa", "title": "Exa Research", "version": "1.0.0", - "engine": {"capabilities":{"requires":["data.fs","data.sqlite"]}}, + "engine": {"capabilities":{"requires":["data.fs","data.sqlite","net.http"]}}, "app": {"entry":"app.tsx","output":"app","framework":"solid","viewport":{"logical":[720,1280],"presentation":"fit"}} } diff --git a/apps/robinhood/dist/data-action.js b/apps/robinhood/dist/data-action.js index 4698a20..dfe2ebd 100644 --- a/apps/robinhood/dist/data-action.js +++ b/apps/robinhood/dist/data-action.js @@ -1,4 +1,4 @@ -(()=>{var h=globalThis.db,v=h.open("robinhood");if(v<0)throw Error("open robinhood.sqlite");var C=4;function q(){return String(h.lastError(v)||"SQLite operation failed")}function m(e){if(h.exec(v,e)!==0)throw Error(q())}function O(e,t=[]){let o=JSON.parse(h.query(v,e,JSON.stringify(t)));if(o.error)throw Error(String(o.error));return o}function l(e,t=[]){return O(e,t)}var k=O("PRAGMA user_version");if(Number(k?.user_version??0)!==C)m(` +(()=>{var m=globalThis.db,R=m.open("robinhood");if(R<0)throw Error("open robinhood.sqlite");var C=4;function q(){return String(m.lastError(R)||"SQLite operation failed")}function g(e){if(m.exec(R,e)!==0)throw Error(q())}function v(e,t=[]){let o=JSON.parse(m.query(R,e,JSON.stringify(t)));if(o.error)throw Error(String(o.error));return o}function l(e,t=[]){return v(e,t)}var k=v("PRAGMA user_version");if(Number(k?.user_version??0)!==C)g(` CREATE TABLE IF NOT EXISTS accounts ( account_number TEXT PRIMARY KEY, label TEXT NOT NULL, @@ -93,19 +93,19 @@ observed_at INTEGER NOT NULL ); PRAGMA user_version=4; - `);function N(){return Math.floor(Date.now()/1000)}function g(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function i(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let o of t){let n=g(e[o]);if(n!==null)return n}for(let o of Object.values(e)){let n=i(o,t);if(n!==null)return n}return null}function I(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let o of t)if(Array.isArray(e[o]))return e[o];for(let o of Object.values(e)){let n=I(o,t);if(n.length)return n}return[]}function P(e,t){let o=i(e,t)?.toLowerCase();return o==="true"||o==="1"||o==="yes"}function w(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function d(e,t){return i(e,["account_number","accountNumber","account"])||String(t?.account_number??t?.accountNumber??"")}function f(e,t){let o=I(e,t);return o.length?o:Array.isArray(e)?e:e?[e]:[]}function A(e,t){let o=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t})));if(!o.ok)throw Error(o.error||"Robinhood service failed");return o.value}function D(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((o)=>({name:o.operation,arguments:o.args}))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function S(e){m("BEGIN IMMEDIATE");try{e(),m("COMMIT")}catch(t){try{m("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function M(e,t){let o=f(e,["accounts"]);l("DELETE FROM accounts");for(let n of o){let c=d(n,{});if(!c)continue;let r=(i(n,["nickname","account_type","type"])||"").toUpperCase(),a=P(n,["agentic_allowed","agenticAllowed"]),s=a?"AGENTIC":r.includes("IRA")||r.includes("RETIRE")?"RETIREMENT":r.includes("JOINT")?"JOINT":"PERSONAL";l("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at) VALUES(?,?,?,?,?,?,?)",[c,s,c.slice(-4),r,(i(n,["status"])||"active").toUpperCase(),a?1:0,t])}}function x(e,t,o){let n=d(e,t);if(!n)throw Error("Robinhood portfolio is missing account_number");let c=i(e,["cash","cash_available","withdrawable_amount"]),r=i(e,["buying_power","buyingPower"]),a=i(e,["day_pnl","dayPnl","equity_change"]),s=i(e,["week_pnl","weekPnl"]);l(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) + `);function y(){return Math.floor(Date.now()/1000)}function h(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function i(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let o of t){let r=h(e[o]);if(r!==null)return r}for(let o of Object.values(e)){let r=i(o,t);if(r!==null)return r}return null}function I(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let o of t)if(Array.isArray(e[o]))return e[o];for(let o of Object.values(e)){let r=I(o,t);if(r.length)return r}return[]}function P(e,t){let o=i(e,t)?.toLowerCase();return o==="true"||o==="1"||o==="yes"}function L(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function d(e,t){return i(e,["account_number","accountNumber","account"])||String(t?.account_number??t?.accountNumber??"")}function N(e,t){let o=I(e,t);return o.length?o:Array.isArray(e)?e:e?[e]:[]}function S(e,t){let o=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t})));if(!o.ok)throw Error(o.error||"Robinhood service failed");return o.value}function M(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((o)=>({name:o.operation,arguments:o.args}))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function A(e){g("BEGIN IMMEDIATE");try{e(),g("COMMIT")}catch(t){try{g("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function D(e,t){let o=N(e,["accounts"]);l("DELETE FROM accounts");for(let r of o){let a=d(r,{});if(!a)continue;let n=(i(r,["nickname","account_type","type"])||"").toUpperCase(),c=P(r,["agentic_allowed","agenticAllowed"]),s=c?"AGENTIC":n.includes("IRA")||n.includes("RETIRE")?"RETIREMENT":n.includes("JOINT")?"JOINT":"PERSONAL";l("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at) VALUES(?,?,?,?,?,?,?)",[a,s,a.slice(-4),n,(i(r,["status"])||"active").toUpperCase(),c?1:0,t])}}function x(e,t,o){let r=d(e,t);if(!r)throw Error("Robinhood portfolio is missing account_number");let a=i(e,["cash","cash_available","withdrawable_amount"]),n=i(e,["buying_power","buyingPower"]),c=i(e,["day_pnl","dayPnl","equity_change"]),s=i(e,["week_pnl","weekPnl"]);l(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?,?,?) ON CONFLICT(account_number) DO UPDATE SET cash=excluded.cash,buying_power=excluded.buying_power, day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), - observed_at=excluded.observed_at`,[n,c,r,a,s,o]);let u=i(e,["total_value","equity","total_equity","portfolio_value","market_value"]);if(u!==null)l("INSERT OR REPLACE INTO total_value(account_number,observed_at,value) VALUES(?,?,?)",[n,o,u])}function F(e,t,o){let n=d(e,t);if(!n)throw Error("Robinhood positions are missing account_number");let c=f(e,["positions"]).slice(0,64);l("DELETE FROM positions WHERE account_number=?",[n]);for(let r of c){let a=i(r,["symbol"]);if(!a)continue;l("INSERT INTO positions(account_number,symbol,quantity,average_price,market_value,observed_at) VALUES(?,?,?,?,?,?)",[n,a,i(r,["quantity","shares"]),i(r,["average_price","averagePrice","average_buy_price"]),i(r,["market_value","marketValue","equity"]),o])}}function G(e,t,o){let n=d(e,t);if(!n)throw Error("Robinhood activities are missing account_number");let c=f(e,["orders","activities","results"]).slice(0,64);l("DELETE FROM activities WHERE account_number=?",[n]),c.forEach((r,a)=>{let s=i(r,["symbol"]),u=(i(r,["side"])||"").toUpperCase(),_=i(r,["executed_quantity","cumulative_quantity","quantity"]),p=i(r,["average_price","averagePrice","executed_price","price"]),y=i(r,["last_transaction_at","created_at","updated_at","date"]),T=i(r,["id","order_id","orderId","activity_id"])||[y||o,s||"ORDER",u,a].join(":"),E=w(_),b=w(p),U=E!==null&&b!==null?String(E*b):p||_;l(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) - VALUES(?,?,?,?,?,?,?,?,?,?,?)`,[n,T,y,o,s,u,_,p,U,(i(r,["state","status"])||"RECENT").toUpperCase(),(i(r,["type","order_type"])||"ORDER").toUpperCase()])})}function Y(e,t,o){let n=d(e,t);if(!n)throw Error("Robinhood P&L is missing account_number");let c=i(e,["total_returns","realized_pnl","total","amount","day_pnl","week_pnl"]),r=String(t?.span??"day");l(`INSERT INTO portfolio_current(account_number,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?) + observed_at=excluded.observed_at`,[r,a,n,c,s,o]);let u=i(e,["total_value","equity","total_equity","portfolio_value","market_value"]);if(u!==null)l("INSERT OR REPLACE INTO total_value(account_number,observed_at,value) VALUES(?,?,?)",[r,o,u])}function F(e,t,o){let r=d(e,t);if(!r)throw Error("Robinhood positions are missing account_number");let a=N(e,["positions"]).slice(0,64);l("DELETE FROM positions WHERE account_number=?",[r]);for(let n of a){let c=i(n,["symbol"]);if(!c)continue;l("INSERT INTO positions(account_number,symbol,quantity,average_price,market_value,observed_at) VALUES(?,?,?,?,?,?)",[r,c,i(n,["quantity","shares"]),i(n,["average_price","averagePrice","average_buy_price"]),i(n,["market_value","marketValue","equity"]),o])}}function G(e,t,o){let r=d(e,t);if(!r)throw Error("Robinhood activities are missing account_number");let a=N(e,["orders","activities","results"]).slice(0,64);l("DELETE FROM activities WHERE account_number=?",[r]),a.forEach((n,c)=>{let s=i(n,["symbol"]),u=(i(n,["side"])||"").toUpperCase(),_=i(n,["executed_quantity","cumulative_quantity","quantity"]),p=i(n,["average_price","averagePrice","executed_price","price"]),b=i(n,["last_transaction_at","created_at","updated_at","date"]),T=i(n,["id","order_id","orderId","activity_id"])||[b||o,s||"ORDER",u,c].join(":"),E=L(_),f=L(p),U=E!==null&&f!==null?String(E*f):p||_;l(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) + VALUES(?,?,?,?,?,?,?,?,?,?,?)`,[r,T,b,o,s,u,_,p,U,(i(n,["state","status"])||"RECENT").toUpperCase(),(i(n,["type","order_type"])||"ORDER").toUpperCase()])})}function Y(e,t,o){let r=d(e,t);if(!r)throw Error("Robinhood P&L is missing account_number");let a=i(e,["total_returns","realized_pnl","total","amount","day_pnl","week_pnl"]),n=String(t?.span??"day");l(`INSERT INTO portfolio_current(account_number,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?) ON CONFLICT(account_number) DO UPDATE SET day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), - observed_at=MAX(portfolio_current.observed_at,excluded.observed_at)`,[n,r==="week"?null:c,r==="week"?c:null,o])}function J(e,t,o){let n=d(e,t),c=String(t?.span??t?.interval??"default"),r=f(e,["historicals","results","data"]);l("DELETE FROM equity_historicals WHERE account_number=? AND span=?",[n,c]),r.forEach((a,s)=>{let u=i(a,["begins_at","timestamp","time","date"])||String(s);l(`INSERT INTO equity_historicals(account_number,span,point_time,price,open,high,low,close,volume,observed_at) - VALUES(?,?,?,?,?,?,?,?,?,?)`,[n,c,u,i(a,["price","adjusted_close","close_price"]),i(a,["open_price","open"]),i(a,["high_price","high"]),i(a,["low_price","low"]),i(a,["close_price","close"]),i(a,["volume"]),o])})}function V(e,t,o){let n=d(e,t),c=f(e,["trades","results","data"]);l("DELETE FROM pnl_trades WHERE account_number=?",[n]),c.forEach((r,a)=>{let s=i(r,["created_at","updated_at","date","timestamp"]),u=i(r,["id","trade_id","tradeId"])||[s||o,i(r,["symbol"])||"TRADE",a].join(":");l(`INSERT INTO pnl_trades(account_number,trade_id,occurred_at,symbol,side,quantity,price,realized_pnl,observed_at) - VALUES(?,?,?,?,?,?,?,?,?)`,[n,u,s,i(r,["symbol"]),(i(r,["side"])||"").toUpperCase(),i(r,["quantity","shares"]),i(r,["price","average_price"]),i(r,["realized_pnl","pnl","amount"]),o])})}function B(e,t,o){let n=d(e,t),c=i(e,["symbol"])||g(t?.symbol),r=(i(e,["side"])||g(t?.side)||"").toUpperCase(),a=i(e,["quantity","shares"])||g(t?.quantity),s=i(e,["limit_price","limitPrice","price"])||g(t?.limit_price??t?.price),u=i(e,["id","review_id","reviewId"])||[n,c,r,a,s,o].join(":");l(`INSERT OR REPLACE INTO order_reviews(review_id,account_number,symbol,side,quantity,limit_price,estimated_cost,state,observed_at) - VALUES(?,?,?,?,?,?,?,?,?)`,[u,n,c,r,a,s,i(e,["estimated_cost","estimatedCost","total"]),i(e,["state","status"]),o])}function X(e){if(e.operation==="get_accounts")M(e.value,e.observedAt);else if(e.operation==="get_portfolio")x(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_positions")F(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_orders")G(e.value,e.args,e.observedAt);else if(e.operation==="get_realized_pnl")Y(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_historicals")J(e.value,e.args,e.observedAt);else if(e.operation==="get_pnl_trade_history")V(e.value,e.args,e.observedAt);else if(e.operation==="review_equity_order")B(e.value,e.args,e.observedAt);else throw Error("No Robinhood table mapping for "+e.operation)}function z(e){let t=e.toLowerCase();return t.includes("esp_err_http_connect")||t.includes("timeout")||t.includes("tls")||t.includes("socket")||t.includes("network")}function L(){let e=N(),t=[],o=[],n=0,c=(s,u)=>{n+=1;try{let _=A(s,u);return t.push({operation:s,args:u,value:_,observedAt:N()}),_}catch(_){let p=_ instanceof Error?_.message:String(_);if(o.push(s+": "+p),s==="get_accounts"||z(p))throw _;return null}},r=null;try{let s=c("get_accounts",{}),_=f(s,["accounts"]).map((T)=>d(T,{})).filter(Boolean);if(!_.length)throw Error("Robinhood returned no brokerage accounts");let p=new Date((e-604800)*1000).toISOString().slice(0,10),y=[];for(let T of _){let E={account_number:T};y.push({operation:"get_portfolio",args:E},{operation:"get_equity_positions",args:E},{operation:"get_equity_orders",args:{...E,created_at_gte:p}},{operation:"get_realized_pnl",args:{...E,span:"day",asset_classes:["equity"]}},{operation:"get_realized_pnl",args:{...E,span:"week",asset_classes:["equity"]}})}n+=y.length;let R=D(y);if(R.length!==y.length)throw Error("Robinhood batch returned an incomplete result set");if(R.forEach((T,E)=>{let b=y[E];if(T?.ok)t.push({operation:b.operation,args:b.args,value:T.value,observedAt:N()});else o.push(b.operation+": "+String(T?.error||"unknown provider error"))}),!t.some((T)=>T.operation==="get_portfolio"))throw Error("Robinhood batch returned no portfolio data")}catch(s){r=s instanceof Error?s.message:String(s)}let a=r?"failed":o.length?"partial":"succeeded";if(S(()=>{if(!r)for(let s of t)X(s);l(`INSERT INTO refresh_runs(started_at,completed_at,status,operation_count,success_count,error) - VALUES(?,?,?,?,?,?)`,[e,N(),a,n,r?0:t.length,r||o.join(" | ")||null])}),r)throw Error(r);return{status:a,operationCount:n,successCount:t.length}}var j={"robinhood.get_accounts":"get_accounts","robinhood.get_portfolio":"get_portfolio","robinhood.get_equity_positions":"get_equity_positions","robinhood.get_equity_orders":"get_equity_orders","robinhood.get_equity_historicals":"get_equity_historicals","robinhood.get_realized_pnl":"get_realized_pnl","robinhood.get_pnl_trade_history":"get_pnl_trade_history","robinhood.review_equity_order":"review_equity_order"};function K(e,t){let o=j[e];if(!o)throw Error("Unknown Robinhood tool: "+e);let n=A(o,t);return S(()=>X({operation:o,args:t,value:n,observedAt:N()})),n}globalThis.PocketPiData={invokeTask(e){try{if(e!=="refreshPortfolio")throw Error("Unknown Robinhood Data Action: "+e);let t=L();return JSON.stringify({text:JSON.stringify(t),details:t,isError:!1})}catch(t){return JSON.stringify({text:t instanceof Error?t.message:String(t),isError:!0})}},invokeTool(e,t){try{let o=JSON.parse(t),n=e==="robinhood.refresh_portfolio"?L():K(e,o);return JSON.stringify({text:JSON.stringify(n),details:n,isError:!1})}catch(o){return JSON.stringify({text:o instanceof Error?o.message:String(o),isError:!0})}}};})(); + observed_at=MAX(portfolio_current.observed_at,excluded.observed_at)`,[r,n==="week"?null:a,n==="week"?a:null,o])}function J(e,t,o){let r=d(e,t),a=String(t?.span??t?.interval??"default"),n=N(e,["historicals","results","data"]);l("DELETE FROM equity_historicals WHERE account_number=? AND span=?",[r,a]),n.forEach((c,s)=>{let u=i(c,["begins_at","timestamp","time","date"])||String(s);l(`INSERT INTO equity_historicals(account_number,span,point_time,price,open,high,low,close,volume,observed_at) + VALUES(?,?,?,?,?,?,?,?,?,?)`,[r,a,u,i(c,["price","adjusted_close","close_price"]),i(c,["open_price","open"]),i(c,["high_price","high"]),i(c,["low_price","low"]),i(c,["close_price","close"]),i(c,["volume"]),o])})}function V(e,t,o){let r=d(e,t),a=N(e,["trades","results","data"]);l("DELETE FROM pnl_trades WHERE account_number=?",[r]),a.forEach((n,c)=>{let s=i(n,["created_at","updated_at","date","timestamp"]),u=i(n,["id","trade_id","tradeId"])||[s||o,i(n,["symbol"])||"TRADE",c].join(":");l(`INSERT INTO pnl_trades(account_number,trade_id,occurred_at,symbol,side,quantity,price,realized_pnl,observed_at) + VALUES(?,?,?,?,?,?,?,?,?)`,[r,u,s,i(n,["symbol"]),(i(n,["side"])||"").toUpperCase(),i(n,["quantity","shares"]),i(n,["price","average_price"]),i(n,["realized_pnl","pnl","amount"]),o])})}function B(e,t,o){let r=d(e,t),a=i(e,["symbol"])||h(t?.symbol),n=(i(e,["side"])||h(t?.side)||"").toUpperCase(),c=i(e,["quantity","shares"])||h(t?.quantity),s=i(e,["limit_price","limitPrice","price"])||h(t?.limit_price??t?.price),u=i(e,["id","review_id","reviewId"])||[r,a,n,c,s,o].join(":");l(`INSERT OR REPLACE INTO order_reviews(review_id,account_number,symbol,side,quantity,limit_price,estimated_cost,state,observed_at) + VALUES(?,?,?,?,?,?,?,?,?)`,[u,r,a,n,c,s,i(e,["estimated_cost","estimatedCost","total"]),i(e,["state","status"]),o])}function X(e){if(e.operation==="get_accounts")D(e.value,e.observedAt);else if(e.operation==="get_portfolio")x(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_positions")F(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_orders")G(e.value,e.args,e.observedAt);else if(e.operation==="get_realized_pnl")Y(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_historicals")J(e.value,e.args,e.observedAt);else if(e.operation==="get_pnl_trade_history")V(e.value,e.args,e.observedAt);else if(e.operation==="review_equity_order")B(e.value,e.args,e.observedAt);else throw Error("No Robinhood table mapping for "+e.operation)}function z(e){let t=e.toLowerCase();return t.includes("esp_err_http_connect")||t.includes("timeout")||t.includes("tls")||t.includes("socket")||t.includes("network")}function O(){let e=y(),t=[],o=[],r=0,a=(s,u)=>{r+=1;try{let _=S(s,u);return t.push({operation:s,args:u,value:_,observedAt:y()}),_}catch(_){let p=_ instanceof Error?_.message:String(_);if(o.push(s+": "+p),s==="get_accounts"||z(p))throw _;return null}},n=null;try{let s=a("get_accounts",{}),_=N(s,["accounts"]).map((T)=>d(T,{})).filter(Boolean);if(!_.length)throw Error("Robinhood returned no brokerage accounts");let p=new Date((e-604800)*1000).toISOString().slice(0,10),b=[];for(let T of _){let E={account_number:T};b.push({operation:"get_portfolio",args:E},{operation:"get_equity_positions",args:E},{operation:"get_equity_orders",args:{...E,created_at_gte:p}},{operation:"get_realized_pnl",args:{...E,span:"day",asset_classes:["equity"]}},{operation:"get_realized_pnl",args:{...E,span:"week",asset_classes:["equity"]}})}r+=b.length;let w=M(b);if(w.length!==b.length)throw Error("Robinhood batch returned an incomplete result set");if(w.forEach((T,E)=>{let f=b[E];if(T?.ok)t.push({operation:f.operation,args:f.args,value:T.value,observedAt:y()});else o.push(f.operation+": "+String(T?.error||"unknown provider error"))}),!t.some((T)=>T.operation==="get_portfolio"))throw Error("Robinhood batch returned no portfolio data")}catch(s){n=s instanceof Error?s.message:String(s)}let c=n?"failed":o.length?"partial":"succeeded";if(A(()=>{if(!n)for(let s of t)X(s);l(`INSERT INTO refresh_runs(started_at,completed_at,status,operation_count,success_count,error) + VALUES(?,?,?,?,?,?)`,[e,y(),c,r,n?0:t.length,n||o.join(" | ")||null])}),n)throw Error(n);return{status:c,operationCount:r,successCount:t.length}}var j={"robinhood.get_accounts":"get_accounts","robinhood.get_portfolio":"get_portfolio","robinhood.get_equity_positions":"get_equity_positions","robinhood.get_equity_orders":"get_equity_orders","robinhood.get_equity_historicals":"get_equity_historicals","robinhood.get_realized_pnl":"get_realized_pnl","robinhood.get_pnl_trade_history":"get_pnl_trade_history","robinhood.review_equity_order":"review_equity_order"};function K(e,t){let o=j[e];if(!o)throw Error("Unknown Robinhood tool: "+e);let r=S(o,t);return A(()=>X({operation:o,args:t,value:r,observedAt:y()})),r}globalThis.PocketPiData={invokeTask(e){try{if(e!=="refreshPortfolio")throw Error("Unknown Robinhood Data Action: "+e);let t=O();return JSON.stringify({text:JSON.stringify(t),details:t,isError:!1})}catch(t){return JSON.stringify({text:t instanceof Error?t.message:String(t),isError:!0})}},invokeTool(e,t){try{let o=JSON.parse(t),r=e==="robinhood.refresh_portfolio"?O():K(e,o);return JSON.stringify({text:JSON.stringify(r),details:r,isError:!1})}catch(o){return JSON.stringify({text:o instanceof Error?o.message:String(o),isError:!0})}}};})(); diff --git a/crates/pocket-pi-agentos/Cargo.toml b/crates/pocket-pi-agentos/Cargo.toml index 3fa3980..668327d 100644 --- a/crates/pocket-pi-agentos/Cargo.toml +++ b/crates/pocket-pi-agentos/Cargo.toml @@ -13,6 +13,7 @@ log.workspace = true pocket-db.workspace = true pocket-fs.workspace = true pocket-mod.workspace = true +pocket-net.workspace = true pocket-ui-surface.workspace = true pocket-pi-embedded = { path = "../pocket-pi-embedded" } pocketjs-core.workspace = true diff --git a/crates/pocket-pi-agentos/src/lib.rs b/crates/pocket-pi-agentos/src/lib.rs index 7e74c04..0956165 100644 --- a/crates/pocket-pi-agentos/src/lib.rs +++ b/crates/pocket-pi-agentos/src/lib.rs @@ -2,7 +2,7 @@ //! app-owned FS/SQLite state, namespaced Agent tools and native AppTask wakes. use std::cell::{Cell, RefCell}; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use std::path::{Path, PathBuf}; use std::rc::Rc; use std::sync::atomic::{AtomicBool, AtomicU32, Ordering}; @@ -14,6 +14,8 @@ use pocket_db::{DbModule, Storage as DbStorage}; use pocket_fs::{FsModule, Storage as FsStorage}; use pocket_mod::qjs::{CatchResultExt as _, Function, Object}; use pocket_mod::Guest; +pub use pocket_net::{HttpRequest, NetFailure, TransportCompletion}; +use pocket_net::{HttpTransport, NetSurface}; use pocket_pi_embedded::{AgentEvent, GuestAgent, ModelBackend, ToolHost, ToolResult}; use pocket_ui_surface::UiSurface; use serde::{Deserialize, Serialize}; @@ -178,6 +180,19 @@ pub trait AppServiceHost: Send + Sync { args: &Value, ) -> Result; + /// Execute one policy-checked PocketJS HTTP request. This is called only + /// from the native NET worker, never from the QuickJS/App Data thread. + fn http( + &self, + _app_id: &str, + request: HttpRequest, + ) -> std::result::Result { + Err(NetFailure::new( + "unavailable", + format!("HTTP is unavailable for handle {}", request.handle), + )) + } + /// True while a native App worker owns network/TLS activity. fn busy(&self) -> bool { false @@ -192,6 +207,8 @@ type SharedDb = Arc>; type AppRevision = Arc; const DATA_ACTION_QUEUE: usize = 8; +const NET_COMPLETION_QUEUE: usize = 2; +const NET_WORKER_STACK_BYTES: usize = 96 * 1024; pub const DATA_ACTION_STACK_BYTES: usize = 128 * 1024; #[derive(Clone, Copy)] @@ -214,10 +231,71 @@ struct DataAppConfig { source_path: PathBuf, database: SharedDb, revision: AppRevision, + net: bool, +} + +struct AppNetTransport { + requests: mpsc::SyncSender, + completions: mpsc::Receiver, + cancelled: BTreeSet, +} + +impl AppNetTransport { + fn start(app_id: String, services: Arc) -> Result { + let (request_tx, request_rx) = mpsc::sync_channel::(NET_COMPLETION_QUEUE); + let (completion_tx, completion_rx) = + mpsc::sync_channel::(NET_COMPLETION_QUEUE); + let worker_name = format!("net-{app_id}"); + std::thread::Builder::new() + .name(worker_name) + .stack_size(NET_WORKER_STACK_BYTES) + .spawn(move || { + while let Ok(request) = request_rx.recv() { + let handle = request.handle; + let completion = services + .http(&app_id, request) + .unwrap_or_else(|failure| TransportCompletion::Error { handle, failure }); + if completion_tx.send(completion).is_err() { + break; + } + } + }) + .context("start App NET worker")?; + Ok(Self { + requests: request_tx, + completions: completion_rx, + cancelled: BTreeSet::new(), + }) + } +} + +impl HttpTransport for AppNetTransport { + fn start(&mut self, request: HttpRequest) -> std::result::Result<(), NetFailure> { + self.requests + .try_send(request) + .map_err(|_| NetFailure::new("busy", "native HTTP worker queue is full")) + } + + fn cancel(&mut self, handle: i32) { + self.cancelled.insert(handle); + } + + fn drain(&mut self, completions: &mut Vec) { + while let Ok(completion) = self.completions.try_recv() { + let handle = match &completion { + TransportCompletion::Done { handle, .. } + | TransportCompletion::Error { handle, .. } => *handle, + }; + if !self.cancelled.remove(&handle) { + completions.push(completion); + } + } + } } struct DataActionRuntime { guest: Guest, + net: Option>, _database: SharedDb, _revision: AppRevision, } @@ -226,8 +304,15 @@ impl DataActionRuntime { fn load(config: &DataAppConfig, services: Arc) -> Result { let guest = Guest::new()?; mount_shared_db(&guest, config.database.clone())?; - mount_services(&guest, config.app_id.clone(), services)?; mount_data_lifecycle(&guest, config.revision.clone())?; + let net = if config.net { + let surface = NetSurface::new(AppNetTransport::start(config.app_id.clone(), services)?); + surface.mount(&guest)?; + Some(surface) + } else { + mount_services(&guest, config.app_id.clone(), services)?; + None + }; let source = std::fs::read_to_string(&config.source_path) .with_context(|| format!("read {} Data Action", config.app_id))?; guest.eval(&format!("{}-data-action", config.app_id), &source)?; @@ -238,12 +323,16 @@ impl DataActionRuntime { ); Ok(Self { guest, + net, _database: config.database.clone(), _revision: config.revision.clone(), }) } fn invoke(&self, request: &DataActionRequest) -> Result { + if let Some(net) = &self.net { + return self.invoke_net(request, net); + } let method = match request.kind { DataActionKind::Task => "invokeTask", DataActionKind::Tool => "invokeTool", @@ -261,21 +350,62 @@ impl DataActionRuntime { .catch(&ctx) .map_err(|error| anyhow!("PocketPiData.{method}: {error}")) })?; - let value: Value = serde_json::from_str(&line).context("parse Data Action result")?; - Ok(ToolResult { - text: value - .get("text") - .and_then(Value::as_str) - .unwrap_or(&line) - .to_owned(), - details: value.get("details").cloned().unwrap_or(Value::Null), - is_error: value - .get("isError") - .and_then(Value::as_bool) - .unwrap_or(false), - terminate: false, - }) + parse_data_result(&line) } + + fn invoke_net( + &self, + request: &DataActionRequest, + net: &NetSurface, + ) -> Result { + let method = match request.kind { + DataActionKind::Task => "beginInvokeTask", + DataActionKind::Tool => "beginInvokeTool", + }; + self.guest.with(|ctx| -> Result<()> { + let data: Object = ctx.globals().get("PocketPiData")?; + let function: Function = data.get(method)?; + function.call::<_, ()>((request.name.clone(), request.args.to_string()))?; + Ok(()) + })?; + let deadline = std::time::Instant::now() + TOOL_TIMEOUT; + loop { + net.begin_tick(); + let line = self.guest.with(|ctx| -> Result> { + let data: Object = ctx.globals().get("PocketPiData")?; + let tick: Function = data.get("tick")?; + tick.call::<_, ()>(())?; + let poll: Function = data.get("pollResult")?; + Ok(poll.call::<_, Option>(())?) + })?; + self.guest.drain_jobs(); + if let Some(line) = line { + return parse_data_result(&line); + } + anyhow::ensure!( + std::time::Instant::now() < deadline, + "PocketPiData.{method} timed out" + ); + std::thread::sleep(Duration::from_millis(5)); + } + } +} + +fn parse_data_result(line: &str) -> Result { + let value: Value = serde_json::from_str(line).context("parse Data Action result")?; + Ok(ToolResult { + text: value + .get("text") + .and_then(Value::as_str) + .unwrap_or(line) + .to_owned(), + details: value.get("details").cloned().unwrap_or(Value::Null), + is_error: value + .get("isError") + .and_then(Value::as_bool) + .unwrap_or(false), + terminate: false, + }) } struct AppDataRunner { @@ -387,7 +517,6 @@ impl AppRuntime { tmp_root: &Path, db: SharedDb, revision: AppRevision, - services: Arc, ) -> Result { let descriptor: AppDescriptor = serde_json::from_slice( &std::fs::read(release_dir.join("agent-app.json")).context("read agent-app.json")?, @@ -417,7 +546,7 @@ impl AppRuntime { .filter_map(Value::as_str) { anyhow::ensure!( - matches!(capability, "data.fs" | "data.sqlite"), + matches!(capability, "data.fs" | "data.sqlite" | "net.http"), "unsupported App capability: {capability}" ); } @@ -439,7 +568,6 @@ impl AppRuntime { pocket_fs::mount(&guest, fs.clone())?; mount_shared_db(&guest, db.clone())?; - mount_services(&guest, descriptor.id.clone(), services)?; let source = std::fs::read_to_string(release_dir.join("app.js")).context("read App bundle")?; eval_bundle(&guest, &descriptor.id, &source)?; @@ -702,8 +830,10 @@ impl AppSupervisor { revisions.insert(descriptor.id.clone(), Arc::new(AtomicU32::new(0))); } let data_configs = catalog - .descriptors() - .filter_map(|descriptor| { + .apps + .values() + .filter_map(|app| { + let descriptor = &app.descriptor; let (release_dir, _, _, _) = paths(&workspace, &descriptor.id); let source_path = release_dir.join("data-action.js"); source_path.is_file().then(|| DataAppConfig { @@ -717,19 +847,23 @@ impl AppSupervisor { .get(&descriptor.id) .expect("revision created for descriptor") .clone(), + net: serde_json::from_str::(app.pocket_json) + .ok() + .and_then(|manifest| { + manifest + .pointer("/engine/capabilities/requires") + .and_then(Value::as_array) + .cloned() + }) + .is_some_and(|capabilities| { + capabilities.iter().any(|value| value == "net.http") + }), }) }) .collect(); let data_runner = AppDataRunner::start(data_configs, services.clone())?; log::info!("preloading View Runtime: {ROOT_APP_ID}"); - let system = load_runtime( - &workspace, - &catalog, - &databases, - &revisions, - ROOT_APP_ID, - services.clone(), - )?; + let system = load_runtime(&workspace, &catalog, &databases, &revisions, ROOT_APP_ID)?; log::info!("preloaded View Runtime: {ROOT_APP_ID}"); // v1 has a small fixed App catalog. Load every ordinary View once at // boot so foreground navigation is only a surface switch. Background @@ -742,14 +876,7 @@ impl AppSupervisor { let mut runtimes = BTreeMap::new(); for app_id in ordinary_app_ids { log::info!("preloading View Runtime: {app_id}"); - let runtime = load_runtime( - &workspace, - &catalog, - &databases, - &revisions, - &app_id, - services.clone(), - )?; + let runtime = load_runtime(&workspace, &catalog, &databases, &revisions, &app_id)?; log::info!("preloaded View Runtime: {app_id}"); runtimes.insert(app_id, runtime); } @@ -981,7 +1108,6 @@ fn load_runtime( databases: &BTreeMap, revisions: &BTreeMap, app_id: &str, - services: Arc, ) -> Result { let app = catalog .app(app_id) @@ -996,16 +1122,8 @@ fn load_runtime( .cloned() .ok_or_else(|| anyhow!("App {app_id} has no revision owner"))?; let _ = db_root; - AppRuntime::load( - app, - &release_dir, - &fs_root, - &tmp_root, - db, - revision, - services, - ) - .with_context(|| format!("load App {app_id}")) + AppRuntime::load(app, &release_dir, &fs_root, &tmp_root, db, revision) + .with_context(|| format!("load App {app_id}")) } fn paths(workspace: &Path, app_id: &str) -> (PathBuf, PathBuf, PathBuf, PathBuf) { @@ -1079,13 +1197,17 @@ fn seed_builtin_releases(workspace: &Path, catalog: &AppCatalog) -> Result<()> { app.descriptor_json.as_bytes(), )?; atomic_write(&release_dir.join("pocket.json"), app.pocket_json.as_bytes())?; + let mut modules = vec!["ui", "data.fs", "data.sqlite"]; + if app.descriptor.id == EXA_APP_ID { + modules.push("net.http"); + } atomic_write( &release_dir.join("plan.json"), &serde_json::to_vec_pretty(&json!({ "runtime":"pocket-pi-agentos", "pocketjsRevision":"9c809bbd047ddc75c27caa4990951a78d942477a", "app":app.descriptor.id, - "modules":["ui","data.fs","data.sqlite"] + "modules":modules }))?, )?; let current = if app.descriptor.id == ROOT_APP_ID { diff --git a/docs/agentos-architecture.md b/docs/agentos-architecture.md index e2709cb..7ac0511 100644 --- a/docs/agentos-architecture.md +++ b/docs/agentos-architecture.md @@ -561,22 +561,27 @@ function refreshPortfolio(args) { // 只在 headless Data Action Guest ### 12.3 Exa 如何接入 -Exa 使用同一套边界,但走受限的 native `net.http` connection,而不是把 API -key 或任意 URL 交给 Bundle: +Exa 使用正式 PocketJS `fetch()` / `pocket-net` contract,而不是私有同步 +`services.call("net.http")`。Bundle 选择 Exa endpoint,native policy 再把它限制为 +两个固定 URL;API key 不进入 Bundle: ```text research.search / research.fetch -> Exa private task - -> net.http(connection="exa", path="/search" | "/contents") + -> fetch("https://api.exa.ai/search" | "/contents") + -> pocket-net start(立即返回 handle) + -> native HTTPS worker(注入 x-api-key) + -> tick boundary drain / fetch Promise resolve -> normalize response -> transaction 写 searches / search_results / documents -> app.commit() 递增 Exa revision -> 前台下一 rendered frame 最多重查一次搜索历史 projection ``` -Firmware 注入 credential、绑定 host/path、执行 TLS 和 response limit;Exa -Bundle 拥有请求字段、结果归一化、SQLite schema 和搜索历史 View。这样 Exa -不是 Rust 固件里的特例。 +Firmware 注入 credential、执行 host/path allowlist、TLS、timeout 和 response +limit;Exa Bundle 拥有 endpoint 选择、请求字段、结果归一化、SQLite schema 和 +搜索历史 View。native transport 不调用 QuickJS;只有 Data Action runner 的 tick +把完成事件带回 Guest。 Native transport 在进入 ESP HTTP/MCP 之前必须读取一个无锁 connection-ready 状态;未完成 association/DHCP 时立即向 Data Action 返回 error,不能让断网请求 @@ -767,7 +772,7 @@ Context Assembler 把选定 workspace files 组装成有严格上限的 Agent co | `ui` | retained tree、layout、text、animation、DrawList | JSX View 和 reactive state | | `data.sqlite` | SQLite、handles、limits、storage binding | schema、migrations、queries、transactions | | `data.fs` | confinement、quota、atomic replace | App files 和 config | -| `net.http` | TLS、connection、limits、transport | endpoint 和 domain decoding | +| `net.http` | TLS、credential、policy allowlist、limits、non-blocking transport | `fetch()`、endpoint 选择和 domain decoding | | `mcp.client` | auth、session、framing、limits | safe operation mapping 和 domain semantics | | `model.stream` | provider transport、内部 stream decode 和完整 result | Agent policy;ESP32 presentation 每次 request 只接收一次完整文本更新 | | `schedule.wake` | clock、persistence、claiming | AgentWake 或 AppTask declaration | @@ -915,10 +920,10 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 1. PocketJS 固定在 upstream `origin/main` revision `9c809bbd047ddc75c27caa4990951a78d942477a`;Simulator 和 ESP32-P4 共用 - 正式合并的 `pocket-fs`、`pocket-db`、`pocket-mod` 和 - `pocket-ui-surface` contracts。该 revision 同时包含正式 `pocket-net` - contract;Pocket Pi 对它的 Host adapter/mount 属于下一阶段,不在依赖迁移中 - 伪装成已经接入。 + 正式合并的 `pocket-fs`、`pocket-db`、`pocket-mod`、`pocket-net` 和 + `pocket-ui-surface` contracts。Exa Data Action 已使用正式 `fetch()` API; + `pocket-net` 的 `start/cancel/drain` 由独立 native worker 实现,completion 只在 + Data Action tick boundary 进入 Guest。 2. Pi Agent 位于顶层 `/workspace`;Root View release 位于 `/workspace/data/view`,其中 `app.js` 和 `agent.js` 是同一个 System App release;普通 App 位于 `/workspace/apps/`。 @@ -947,8 +952,9 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 table,不保存原始 Tool payload。View 只拥有 accounts/portfolio/positions/ activity/chart 的 bounded projection 和 cache。chart 的 1D/1W 窗口固定为 20 个 time buckets,SQLite query 最多返回 20 行,render 不读取 DB。 -10. Exa Data Action 拥有 `research.search`、`research.fetch`、HTTP mapping 与 - SQLite transaction;View 从 `searches + search_results` 只读取最近 8 次搜索。 +10. Exa Data Action 拥有 `research.search`、`research.fetch`、PocketJS `fetch()` + mapping 与 SQLite transaction;native 只允许 Exa 的 `/search`、`/contents` + 并注入 API key。View 从 `searches + search_results` 只读取最近 8 次搜索。 11. Root View 已提供 Chat、App 入口、Files、Runs/Schedules、Settings 摘要和 屏幕键盘;Agent policy/loop 在 JS,workspace/App Tools 的受限底层实现和 AgentWake 由 Rust host 提供。Pocket Pi 的小型 shared Design System inventory @@ -956,7 +962,9 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 typography/tokens/components,不包含 App-specific View 或 native UI logic。 12. ESP32-P4 使用 4 KiB PSRAM launcher,待 ESP-IDF entry task 退出后创建 64 KiB internal AgentOS runtime stack;App bundle 构建后会 minify 以降低固件 - footprint,但不会把 minify 当作 stack isolation。 + footprint,但不会把 minify 当作 stack isolation。App Data pthread 使用 128 + KiB PSRAM stack,并把 PSRAM allocation caps 只继承给按需创建的 96 KiB NET + worker;System App 的其他线程仍使用恢复后的 platform default。 13. Simulator tests 已证明:Agent turn 进行中打开 Robinhood,仍能收到完整回复 和 `agent_end`;前后台切换前后 System App Guest identity 不变;Exa 在前台 时 Agent 仍能路由 Robinhood App Tool、写 SQLite 并完成 turn。新增 contract @@ -1002,6 +1010,9 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 ### 22.2 待补齐,不能视为已实现 +- 正式 `pocket-net` 路径已通过 Simulator E2E 与 ESP32-P4 release cross-build; + 尚未刷板验证一次新的 Exa provider success,因此不能把旧同步 service 路径的 + 实机证据沿用为新 NET adapter 的实体板证据。 - Root Files 已有只读文件阅读器;conversation/message/run/tool call 还没有落入 `data/agent.sqlite`。 - release 已有 descriptor/`pocket.json` 校验和 atomic `current` 写入,但由 diff --git a/firmware/esp32-p4/Cargo.lock b/firmware/esp32-p4/Cargo.lock index 78b38ea..f8660a7 100644 --- a/firmware/esp32-p4/Cargo.lock +++ b/firmware/esp32-p4/Cargo.lock @@ -1157,6 +1157,18 @@ dependencies = [ "rquickjs", ] +[[package]] +name = "pocket-net" +version = "0.1.0" +source = "git+https://github.com/pocket-stack/pocketjs.git?rev=9c809bbd047ddc75c27caa4990951a78d942477a#9c809bbd047ddc75c27caa4990951a78d942477a" +dependencies = [ + "anyhow", + "pocket-mod", + "pocketjs-core", + "serde", + "serde_json", +] + [[package]] name = "pocket-pi-agentos" version = "0.1.0" @@ -1166,6 +1178,7 @@ dependencies = [ "pocket-db", "pocket-fs", "pocket-mod", + "pocket-net", "pocket-pi-embedded", "pocket-ui-surface", "pocketjs-core", diff --git a/firmware/esp32-p4/src/agentos_main.rs b/firmware/esp32-p4/src/agentos_main.rs index 08f220f..66f922f 100644 --- a/firmware/esp32-p4/src/agentos_main.rs +++ b/firmware/esp32-p4/src/agentos_main.rs @@ -497,12 +497,13 @@ fn with_data_action_pthread_config( ) -> anyhow::Result { // std::thread maps to ESP-IDF pthread. Its default stack allocation is // internal RAM, where a QuickJS Data Action Guest cannot fit. Configure - // only this child creation to use byte-addressable PSRAM, then restore the - // platform default for unrelated threads created later by the System App. + // this worker family to use byte-addressable PSRAM. The Data Action thread + // must pass the allocation caps to its on-demand NET child; the platform + // default is restored before unrelated System App threads are created. let default = unsafe { esp_idf_svc::sys::esp_pthread_get_default_config() }; let mut config = default; config.stack_size = DATA_ACTION_STACK_BYTES; - config.inherit_cfg = false; + config.inherit_cfg = true; config.pin_to_core = 1; config.stack_alloc_caps = esp_idf_svc::sys::MALLOC_CAP_SPIRAM | esp_idf_svc::sys::MALLOC_CAP_8BIT; diff --git a/firmware/esp32-p4/src/app_services.rs b/firmware/esp32-p4/src/app_services.rs index 02adee2..18a83dc 100644 --- a/firmware/esp32-p4/src/app_services.rs +++ b/firmware/esp32-p4/src/app_services.rs @@ -8,13 +8,11 @@ use embedded_svc::http::{client::Client as HttpClient, Method}; use embedded_svc::io::Write as _; use esp_idf_svc::http::client::{Configuration, EspHttpConnection}; use esp_idf_svc::io::EspIOError; -use pocket_pi_agentos::AppServiceHost; +use pocket_pi_agentos::{AppServiceHost, HttpRequest, NetFailure, TransportCompletion}; use serde_json::{json, Value}; -const EXA_ORIGIN: &str = "https://api.exa.ai"; const ROBINHOOD_MCP_URL: &str = "https://agent.robinhood.com/mcp/trading"; const MCP_PROTOCOL_VERSION: &str = "2025-06-18"; -const MAX_EXA_RESPONSE: usize = 96 * 1024; const MAX_MCP_RESPONSE: usize = 160 * 1024; pub struct EspAppServices { @@ -68,30 +66,44 @@ impl EspAppServicesInner { ) } - - fn exa_post(&self, args: &Value) -> Result { + fn exa_http( + &self, + request: HttpRequest, + ) -> std::result::Result { + if request.method != "POST" + || !matches!( + request.url.as_str(), + "https://api.exa.ai/search" | "https://api.exa.ai/contents" + ) + { + return Err(NetFailure::new( + "invalid_request", + "Exa NET capability permits only POST /search and /contents", + )); + } + if request + .headers + .keys() + .any(|name| !matches!(name.as_str(), "accept" | "content-type")) + { + return Err(NetFailure::new( + "invalid_request", + "Exa App supplied a forbidden HTTP header", + )); + } + let body: Value = serde_json::from_slice(&request.body) + .map_err(|error| NetFailure::new("invalid_request", error.to_string()))?; + if !body.is_object() { + return Err(NetFailure::new( + "invalid_request", + "Exa request body must be a JSON object", + )); + } let api_key = self .exa_api_key .as_deref() - .ok_or_else(|| "Exa API key was not provisioned for this boot".to_owned())?; - if args.get("connection").and_then(Value::as_str) != Some("exa") { - return Err("Exa App requested an unknown net connection".to_owned()); - } - let path = args - .get("path") - .and_then(Value::as_str) - .filter(|path| matches!(*path, "/search" | "/contents")) - .ok_or_else(|| "Exa connection only permits /search and /contents".to_owned())?; - let body = args - .get("body") - .filter(|body| body.is_object()) - .ok_or_else(|| "net.http post requires an object body".to_owned())?; - post_json( - &format!("{EXA_ORIGIN}{path}"), - &[("x-api-key", api_key)], - body, - MAX_EXA_RESPONSE, - ) + .ok_or_else(|| NetFailure::new("unavailable", "Exa API key was not provisioned"))?; + execute_exa_http(request, api_key) } fn robinhood_call(&self, args: &Value) -> Result { @@ -307,21 +319,35 @@ impl AppServiceHost for EspAppServices { return Err("Network is not connected; App data was not changed".to_owned()); } match (app_id, service, operation) { - ("exa", "net.http", "post") => self.inner.exa_post(args), ("robinhood", "mcp.client", "callTool") => self.inner.robinhood_call(args), ("robinhood", "mcp.client", "callTools") => self.inner.robinhood_calls(args), _ => Err(format!("App {app_id} cannot access service {service}")), } } + + fn http( + &self, + app_id: &str, + request: HttpRequest, + ) -> std::result::Result { + if !self.inner.network_ready.load(Ordering::Acquire) { + return Err(NetFailure::new("unavailable", "network is not connected")); + } + if app_id != "exa" { + return Err(NetFailure::new( + "invalid_request", + format!("App {app_id} has no NET capability"), + )); + } + self.inner.exa_http(request) + } } -fn client() -> Result, String> { +fn client(timeout: Duration) -> Result, String> { EspHttpConnection::new(&Configuration { buffer_size: Some(8 * 1024), buffer_size_tx: Some(4 * 1024), - // A service call is still synchronous in v1, so a dead network must - // fail quickly enough for the App to leave its visible loading state. - timeout: Some(Duration::from_secs(12)), + timeout: Some(timeout), crt_bundle_attach: Some(esp_idf_svc::sys::esp_crt_bundle_attach), ..Default::default() }) @@ -338,47 +364,66 @@ fn transient_mcp_connect(error: &str) -> bool { error.contains("ESP_ERR_HTTP_CONNECT") } -fn post_json( - url: &str, - extra_headers: &[(&str, &str)], - body: &Value, - limit: usize, -) -> Result { - let payload = body.to_string(); - let length = payload.len().to_string(); - let mut headers = vec![ +fn execute_exa_http( + meta: HttpRequest, + api_key: &str, +) -> std::result::Result { + let length = meta.body.len().to_string(); + let headers = [ ("accept", "application/json"), ("content-type", "application/json"), ("content-length", length.as_str()), ("connection", "close"), ("user-agent", "pocket-pi-agentos/0.1"), + ("x-api-key", api_key), ]; - headers.extend_from_slice(extra_headers); - let mut client = client()?; + let mut client = + client(Duration::from_millis(u64::from(meta.timeout_ms))).map_err(net_failure)?; let mut request = client - .request(Method::Post, url, &headers) - .map_err(|error| format!("create HTTPS request: {error}"))?; + .request(Method::Post, &meta.url, &headers) + .map_err(|error| net_failure(format!("create HTTPS request: {error}")))?; request - .write_all(payload.as_bytes()) - .map_err(|error| format!("write HTTPS request: {error}"))?; + .write_all(&meta.body) + .map_err(|error| net_failure(format!("write HTTPS request: {error}")))?; request .flush() - .map_err(|error| format!("flush HTTPS request: {error}"))?; + .map_err(|error| net_failure(format!("flush HTTPS request: {error}")))?; let mut response = request .submit() - .map_err(|error| format!("send HTTPS request: {error}"))?; + .map_err(|error| net_failure(format!("send HTTPS request: {error}")))?; let status = response.status(); + let content_type = response.header("content-type").map(str::to_owned); let expected_length = response .header("content-length") .and_then(|value| value.parse::().ok()); - let bytes = read_bounded(&mut response, limit, expected_length)?; - if !(200..300).contains(&status) { - return Err(format!( - "HTTPS {status}: {}", - String::from_utf8_lossy(&bytes) - )); + let body = read_bounded(&mut response, meta.max_bytes, expected_length).map_err(net_failure)?; + let mut response_headers = BTreeMap::new(); + if let Some(content_type) = content_type { + response_headers.insert("content-type".to_owned(), content_type); } - serde_json::from_slice(&bytes).map_err(|error| format!("parse HTTPS JSON: {error}")) + Ok(TransportCompletion::Done { + handle: meta.handle, + status, + url: meta.url, + headers: response_headers, + body, + }) +} + +fn net_failure(message: String) -> NetFailure { + let lower = message.to_ascii_lowercase(); + let code = if lower.contains("exceeded") { + "response_too_large" + } else if lower.contains("timeout") { + "timeout" + } else if lower.contains("tls") || lower.contains("certificate") { + "tls" + } else if lower.contains("connect") { + "connect" + } else { + "other" + }; + NetFailure::new(code, message) } fn post_mcp( @@ -405,7 +450,7 @@ fn post_mcp( if let Some(session) = session { headers.push(("mcp-session-id", session)); } - let mut client = client()?; + let mut client = client(Duration::from_secs(12))?; let mut request = client .request(Method::Post, ROBINHOOD_MCP_URL, &headers) .map_err(|error| format!("create Robinhood MCP request: {error}"))?; @@ -477,7 +522,7 @@ fn post_mcp_batch( if let Some(session) = session { headers.push(("mcp-session-id", session)); } - let mut client = client()?; + let mut client = client(Duration::from_secs(12))?; let mut request = client .request(Method::Post, ROBINHOOD_MCP_URL, &headers) .map_err(|error| format!("create Robinhood MCP batch request: {error}"))?; diff --git a/hosts/esp32-p4-sim/src/main.rs b/hosts/esp32-p4-sim/src/main.rs index a614e7d..bdb0ed4 100644 --- a/hosts/esp32-p4-sim/src/main.rs +++ b/hosts/esp32-p4-sim/src/main.rs @@ -1,3 +1,4 @@ +use std::collections::BTreeMap; use std::path::{Path, PathBuf}; use std::sync::mpsc::Receiver; use std::sync::Arc; @@ -6,7 +7,8 @@ use std::time::{Duration, Instant}; use anyhow::{anyhow, Result}; use pocket3d::gpu::{Gpu, OffscreenTarget}; use pocket_pi_agentos::{ - AppServiceHost, AppSupervisor, AppToolRequest, RoutedToolHost, EXA_APP_ID, ROOT_APP_ID, + AppServiceHost, AppSupervisor, AppToolRequest, HttpRequest, NetFailure, RoutedToolHost, + TransportCompletion, EXA_APP_ID, ROOT_APP_ID, }; use pocket_pi_embedded::{AgentEvent, ToolHost}; use pocket_pi_tools::{CoreToolHost, PlatformTools}; @@ -257,31 +259,54 @@ impl AppServiceHost for SimAppServices { ("robinhood", "mcp.client", "callTool", name) => { Ok(json!({"operation":name,"simulated":true,"args":tool_args})) } - ("exa", "net.http", "post", _) - if args.get("path").and_then(Value::as_str) == Some("/search") => - { - let query = args - .get("body") - .unwrap_or(&Value::Null) + _ => Err(format!( + "unsupported simulated service call: {app_id}/{service}/{operation}" + )), + } + } + + fn http( + &self, + app_id: &str, + request: HttpRequest, + ) -> std::result::Result { + if app_id != EXA_APP_ID || request.method != "POST" { + return Err(NetFailure::new( + "invalid_request", + "simulator denied HTTP request", + )); + } + let body: Value = serde_json::from_slice(&request.body) + .map_err(|error| NetFailure::new("invalid_request", error.to_string()))?; + let value = match request.url.as_str() { + "https://api.exa.ai/search" => { + let query = body .get("query") .and_then(Value::as_str) .unwrap_or("Pocket Pi"); - Ok(json!({"results":[ + json!({"results":[ {"title":format!("Research result for {query}"),"url":"https://example.com/research"}, {"title":"PocketJS runtime notes","url":"https://pocketjs.dev/docs/concepts/"} - ]})) + ]}) } - ("exa", "net.http", "post", _) - if args.get("path").and_then(Value::as_str) == Some("/contents") => - { - Ok(json!({ - "results":[{"title":"Simulated Exa document","url":"https://example.com/research","text":"Local simulator fixture"}] - })) + "https://api.exa.ai/contents" => json!({ + "results":[{"title":"Simulated Exa document","url":"https://example.com/research","text":"Local simulator fixture"}] + }), + _ => { + return Err(NetFailure::new( + "invalid_request", + "simulator denied HTTP URL", + )) } - _ => Err(format!( - "unsupported simulated service call: {app_id}/{service}/{operation}" - )), - } + }; + Ok(TransportCompletion::Done { + handle: request.handle, + status: 200, + url: request.url, + headers: BTreeMap::from([("content-type".into(), "application/json".into())]), + body: serde_json::to_vec(&value) + .map_err(|error| NetFailure::new("other", error.to_string()))?, + }) } } diff --git a/tools/build-agentos-data.ts b/tools/build-agentos-data.ts new file mode 100644 index 0000000..d23e62f --- /dev/null +++ b/tools/build-agentos-data.ts @@ -0,0 +1,23 @@ +import { basename, dirname } from "node:path"; + +const [entry, output, pocketjsRoot] = Bun.argv.slice(2); +if (!entry || !output || !pocketjsRoot) { + throw new Error("usage: build-agentos-data.ts "); +} + +const compiler = await import(`${pocketjsRoot}/framework/compiler/jsx-plugin.ts`); +const result = await Bun.build({ + entrypoints: [entry], + outdir: dirname(output), + naming: basename(output), + target: "browser", + format: "iife", + minify: true, + conditions: ["browser"], + define: { "process.env.NODE_ENV": '"production"' }, + plugins: [compiler.jsxPlugin("solid", { entry })], +}); +if (!result.success) { + for (const log of result.logs) console.error(log); + process.exit(1); +} diff --git a/tools/xtask/src/main.rs b/tools/xtask/src/main.rs index 8ad4a79..b928e53 100644 --- a/tools/xtask/src/main.rs +++ b/tools/xtask/src/main.rs @@ -90,15 +90,10 @@ fn build_agentos_apps(root: &Path) -> Result<()> { if data_entry.is_file() { command( Command::new("bun") - .arg("build") + .arg(root.join("tools/build-agentos-data.ts")) .arg(&data_entry) - .arg(format!( - "--outfile={}", - app_root.join("dist/data-action.js").display() - )) - .arg("--target=browser") - .arg("--format=iife") - .arg("--minify"), + .arg(app_root.join("dist/data-action.js")) + .arg(&pocketjs), &format!("building AgentOS data action {app}"), )?; } From bbd1d64ced047f9076526e8c64ecdbee2a02af4e Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Mon, 10 Aug 2026 11:50:46 +0800 Subject: [PATCH 04/24] fix(agentos): provision Robinhood and bound Exa storage --- Cargo.lock | 1 + README.md | 5 ++ apps/exa/agent-app.json | 4 +- apps/exa/app.tsx | 61 ++++++++++++++--------- apps/exa/data-action.ts | 54 ++++++++++++++------- apps/exa/dist/app.js | 17 +++---- apps/exa/dist/data-action.js | 28 ++++++----- docs/agentos-architecture.md | 34 +++++++++---- hosts/esp32-p4-sim/Cargo.toml | 3 ++ hosts/esp32-p4-sim/src/main.rs | 88 ++++++++++++++++++++++++---------- tools/uart-model-bridge.py | 23 +++++---- 11 files changed, 208 insertions(+), 110 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 72e99b8..d7555eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2629,6 +2629,7 @@ dependencies = [ "anyhow", "env_logger", "log", + "pocket-db", "pocket-pi-agentos", "pocket-pi-embedded", "pocket-pi-protocols", diff --git a/README.md b/README.md index e6bb200..2a601ac 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,11 @@ interactively. Wi-Fi can subsequently be changed from the device Settings UI without reflashing. Credentials are kept out of Agent workspace files and PocketJS UI state. +The UART bridge automatically reuses an existing authorized Robinhood session +from Keychain and injects its access token into the board's RAM-only boot +configuration. `--provision-robinhood` is only the interactive fallback when no +saved authorization exists. + ## Model backends Backends belong to their host composition, not to the Agent core: diff --git a/apps/exa/agent-app.json b/apps/exa/agent-app.json index 2b35709..864800b 100644 --- a/apps/exa/agent-app.json +++ b/apps/exa/agent-app.json @@ -1,11 +1,11 @@ { "id": "exa", "version": "1.0.0", - "dataVersion": 3, + "dataVersion": 4, "tools": [ {"name":"research.search","description":"Search the web through Exa, return bounded source-linked highlights, and save the search to local history.","parameters":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":2000},"numResults":{"type":"integer","minimum":1,"maximum":8},"searchType":{"type":"string","enum":["auto","fast","instant"]},"includeDomains":{"type":"array","items":{"type":"string"},"maxItems":8},"excludeDomains":{"type":"array","items":{"type":"string"},"maxItems":8}},"required":["query"],"additionalProperties":false}}, {"name":"research.fetch","description":"Fetch a bounded research document through Exa and save it as the latest opened document.","parameters":{"type":"object","properties":{"url":{"type":"string","maxLength":2048},"maxCharacters":{"type":"integer","minimum":200,"maximum":12000}},"required":["url"],"additionalProperties":false}}, - {"name":"research.storage_status","description":"Inspect this App's local SQLite schema, row counts, and bounded recent row summaries without contacting Exa.","parameters":{"type":"object","properties":{},"additionalProperties":false}} + {"name":"research.storage_status","description":"Return compact local SQLite counts, space usage, 7-day retention policy, and latest run status without contacting Exa.","parameters":{"type":"object","properties":{},"additionalProperties":false}} ], "tasks": [], "schedules": [] diff --git a/apps/exa/app.tsx b/apps/exa/app.tsx index 01133b4..a6cb475 100644 --- a/apps/exa/app.tsx +++ b/apps/exa/app.tsx @@ -3,7 +3,8 @@ import { Text, View } from "@pocketjs/framework/components"; import { mount } from "@pocketjs/framework"; import { Database } from "@pocketjs/framework/db"; -const DB_SCHEMA_VERSION = 3; +const DB_SCHEMA_VERSION = 4; +const RETENTION_DAYS = 7; const db = new Database("exa"); type SearchRow = { id: number; query: string; searched_at: number; status: string; result_count: number; top_title: string | null; top_url: string | null; error: string | null }; @@ -44,28 +45,42 @@ function loadView(revision: number) { } } -function storageStatus(): any { - const tables = db.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all() as unknown as Array<{ name: string; sql: string }>; - const names = new Set(tables.map((table) => table.name)); - const tableSummary = tables.map((table) => { - const rowCount = (db.query("SELECT COUNT(*) AS count FROM " + table.name).get() as unknown as { count: number }).count; - return { name: table.name, rowCount, schema: table.sql }; - }); - const latestSearches = names.has("searches") ? db.query(` - SELECT search.id,search.query,search.searched_at,search.status,search.result_count, - result.title AS top_title,result.url AS top_url,search.error - FROM searches search - LEFT JOIN search_results result ON result.search_id=search.id AND result.rank=0 - ORDER BY search.id DESC LIMIT 8 - `).all() : []; - const latestDocuments = names.has("documents") - ? db.query("SELECT fetched_at,url,title,LENGTH(text) AS text_bytes FROM documents ORDER BY fetched_at DESC LIMIT 5").all() : []; - return { +function storageStatus(): { text: string; details: any } { + const tableRows = db.query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").all() as unknown as Array<{ name: string }>; + const names = new Set(tableRows.map((table) => table.name)); + const count = (table: string): number => names.has(table) + ? Number((db.query(`SELECT COUNT(*) AS count FROM ${table}`).get() as unknown as { count?: number } | null)?.count ?? 0) + : 0; + const pageSize = Number((db.query("PRAGMA page_size").get() as unknown as { page_size?: number } | null)?.page_size ?? 0); + const pageCount = Number((db.query("PRAGMA page_count").get() as unknown as { page_count?: number } | null)?.page_count ?? 0); + const freelistCount = Number((db.query("PRAGMA freelist_count").get() as unknown as { freelist_count?: number } | null)?.freelist_count ?? 0); + const schemaVersion = Number((db.query("PRAGMA user_version").get() as unknown as { user_version?: number } | null)?.user_version ?? 0); + const latestSearch = names.has("searches") ? db.query(` + SELECT id,searched_at,status,result_count,error + FROM searches ORDER BY id DESC LIMIT 1 + `).get() : null; + const tableCounts = { + searches: count("searches"), + searchResults: count("search_results"), + documents: count("documents"), + }; + const details = { database: "exa.sqlite", - schemaVersion: DB_SCHEMA_VERSION, - tables: tableSummary, - latestSearches, - latestDocuments, + schemaVersion, + expectedSchemaVersion: DB_SCHEMA_VERSION, + retentionDays: RETENTION_DAYS, + tableCounts, + allocatedBytes: pageSize * pageCount, + reusableBytes: pageSize * freelistCount, + latestSearch, + }; + const latest = latestSearch as null | { id?: number; status?: string; result_count?: number }; + const latestText = latest + ? ` Latest #${latest.id ?? "?"}: ${latest.status ?? "unknown"}, ${latest.result_count ?? 0} results.` + : " No searches yet."; + return { + text: `Exa storage (schema ${schemaVersion}/${DB_SCHEMA_VERSION}): ${tableCounts.searches} searches, ${tableCounts.searchResults} results, ${tableCounts.documents} documents; ${RETENTION_DAYS}-day retention; ${details.allocatedBytes} bytes allocated (${details.reusableBytes} reusable).${latestText}`, + details, }; } @@ -128,7 +143,7 @@ mount(() => ); try { const value = name === "research.storage_status" ? storageStatus() : (() => { throw new Error("Data-writing tools run in the background App Data Action"); })(); - return JSON.stringify({ text: JSON.stringify(value), details: value, isError: false }); + return JSON.stringify({ text: value.text, details: value.details, isError: false }); } catch (error) { return JSON.stringify({ text: error instanceof Error ? error.message : String(error), isError: true }); } diff --git a/apps/exa/data-action.ts b/apps/exa/data-action.ts index d6eccd3..cfa7856 100644 --- a/apps/exa/data-action.ts +++ b/apps/exa/data-action.ts @@ -6,7 +6,9 @@ const nativeDb = (globalThis as any).db; const handle = nativeDb.open("exa"); if (handle < 0) throw new Error("open exa.sqlite"); -const SCHEMA_VERSION = 3; +const SCHEMA_VERSION = 4; +const RETENTION_DAYS = 7; +const RETENTION_SECONDS = RETENTION_DAYS * 24 * 60 * 60; function dbError(): string { return String(nativeDb.lastError(handle) || "SQLite operation failed"); } function exec(sql: string): void { if (nativeDb.exec(handle, sql) !== 0) throw new Error(dbError()); } @@ -20,7 +22,10 @@ function run(sql: string, args: any[] = []): any { return query(sql, args); } const version = query("PRAGMA user_version") as { user_version?: number } | null; if (Number(version?.user_version ?? 0) !== SCHEMA_VERSION) { exec(` - CREATE TABLE IF NOT EXISTS searches ( + DROP TABLE IF EXISTS search_results; + DROP TABLE IF EXISTS searches; + DROP TABLE IF EXISTS documents; + CREATE TABLE searches ( id INTEGER PRIMARY KEY AUTOINCREMENT, query TEXT NOT NULL, searched_at INTEGER NOT NULL, @@ -28,8 +33,8 @@ if (Number(version?.user_version ?? 0) !== SCHEMA_VERSION) { result_count INTEGER NOT NULL DEFAULT 0, error TEXT ); - CREATE INDEX IF NOT EXISTS searches_recent ON searches(id DESC); - CREATE TABLE IF NOT EXISTS search_results ( + CREATE INDEX searches_retention ON searches(searched_at); + CREATE TABLE search_results ( search_id INTEGER NOT NULL, rank INTEGER NOT NULL, title TEXT, @@ -40,8 +45,7 @@ if (Number(version?.user_version ?? 0) !== SCHEMA_VERSION) { highlight TEXT, PRIMARY KEY(search_id, rank) ); - CREATE INDEX IF NOT EXISTS search_results_url ON search_results(url); - CREATE TABLE IF NOT EXISTS documents ( + CREATE TABLE documents ( url TEXT PRIMARY KEY, fetched_at INTEGER NOT NULL, title TEXT, @@ -49,12 +53,18 @@ if (Number(version?.user_version ?? 0) !== SCHEMA_VERSION) { author TEXT, text TEXT NOT NULL ); - CREATE INDEX IF NOT EXISTS documents_recent ON documents(fetched_at DESC); - PRAGMA user_version=3; + CREATE INDEX documents_recent ON documents(fetched_at DESC); + PRAGMA user_version=4; `); } function now(): number { return Math.floor(Date.now() / 1000); } +function cleanupExpired(referenceTime: number): void { + const cutoff = referenceTime - RETENTION_SECONDS; + run("DELETE FROM search_results WHERE search_id IN (SELECT id FROM searches WHERE searched_at < ?)", [cutoff]); + run("DELETE FROM searches WHERE searched_at < ?", [cutoff]); + run("DELETE FROM documents WHERE fetched_at < ?", [cutoff]); +} function text(value: unknown): string | null { return value === null || value === undefined || typeof value === "object" ? null : String(value); } @@ -127,14 +137,18 @@ async function search(args: any): Promise { [searchId, rank, firstText(item, ["title"]), url, firstText(item, ["publishedDate", "published_at", "date"]), firstText(item, ["author"]), firstText(item, ["score"]), highlight(item)], ); }); + cleanupExpired(searchedAt); }); return value; } catch (error) { const message = error instanceof Error ? error.message : String(error); - transaction(() => run( - "INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,0,?)", - [searchQuery, searchedAt, "error", message], - )); + transaction(() => { + run( + "INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,0,?)", + [searchQuery, searchedAt, "error", message], + ); + cleanupExpired(searchedAt); + }); throw error; } } @@ -153,12 +167,16 @@ async function fetchDocument(args: any): Promise { if (!document) throw new Error("Exa returned no document"); const url = firstText(document, ["url", "id"]) || requestedUrl; const body = firstText(document, ["text", "content", "summary"]) || ""; - transaction(() => run( - `INSERT INTO documents(url,fetched_at,title,published_at,author,text) VALUES(?,?,?,?,?,?) - ON CONFLICT(url) DO UPDATE SET fetched_at=excluded.fetched_at,title=excluded.title, - published_at=excluded.published_at,author=excluded.author,text=excluded.text`, - [url, now(), firstText(document, ["title"]), firstText(document, ["publishedDate", "published_at", "date"]), firstText(document, ["author"]), body], - )); + const fetchedAt = now(); + transaction(() => { + run( + `INSERT INTO documents(url,fetched_at,title,published_at,author,text) VALUES(?,?,?,?,?,?) + ON CONFLICT(url) DO UPDATE SET fetched_at=excluded.fetched_at,title=excluded.title, + published_at=excluded.published_at,author=excluded.author,text=excluded.text`, + [url, fetchedAt, firstText(document, ["title"]), firstText(document, ["publishedDate", "published_at", "date"]), firstText(document, ["author"]), body], + ); + cleanupExpired(fetchedAt); + }); return { status: "ok", provider: "exa", diff --git a/apps/exa/dist/app.js b/apps/exa/dist/app.js index 82d0f30..170c1d0 100644 --- a/apps/exa/dist/app.js +++ b/apps/exa/dist/app.js @@ -1,15 +1,12 @@ -(()=>{var FJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return m0(this.context.count)},getNextContextId(){return m0(this.context.count++)}};function m0(J){let Q=String(J),$=Q.length-1;return FJ.context.id+($?String.fromCharCode(96+$):"")+Q}function v0(J){FJ.context=J}function V4(){return{...FJ.context,id:FJ.getNextContextId(),count:0}}var P4=!1,R4=(J,Q)=>J===Q,W0=Symbol("solid-proxy"),w4=typeof Proxy==="function",D4=Symbol("solid-track"),G2=Symbol("solid-dev-component"),gJ={equals:R4},u0=null,O4=a0,E=1,LJ=2,l0={owned:null,cleanups:null,context:null,owner:null},L=null,B=null,IJ=null,KJ=null,I=null,S=null,f=null,TJ=0;function EJ(J,Q){let $=I,Z=L,X=J.length===0,W=Q===void 0?Z:Q,q=X?l0:{owned:null,cleanups:null,context:W?W.context:null,owner:W},G=X?J:()=>J(()=>a(()=>r(q)));L=q,I=null;try{return i(G,!0)}finally{I=$,L=Z}}function kJ(J,Q){Q=Q?Object.assign({},gJ,Q):gJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return i0($,X)};return[c0.bind($),Z]}function s(J,Q,$){let Z=s0(J,Q,!1,E);if(IJ&&B&&B.running)S.push(Z);else NJ(Z)}function MJ(J,Q,$){$=$?Object.assign({},gJ,$):gJ;let Z=s0(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,IJ&&B&&B.running)Z.tState=E,S.push(Z);else NJ(Z);return c0.bind(Z)}function a(J){if(!KJ&&I===null)return J();let Q=I;I=null;try{if(KJ)return KJ.untrack(J);return J()}finally{I=Q}}function Y0(J){if(L===null);else if(L.cleanups===null)L.cleanups=[J];else L.cleanups.push(J);return J}function C4(J){if(B&&B.running)return J(),B.done;let Q=I,$=L;return Promise.resolve().then(()=>{I=Q,L=$;let Z;if(IJ||L4)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return i(J,!1),I=L=null,Z?Z.done:void 0})}var[H2,p0]=kJ(!1),L4;function c0(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===E)NJ(this);else{let Q=S;S=null,i(()=>mJ(this),!1),S=Q}if(I){let Q=this.observers;if(!Q||Q[Q.length-1]!==I){let $=Q?Q.length:0;if(!I.sources)I.sources=[this],I.sourceSlots=[$];else I.sources.push(this),I.sourceSlots.push($);if(!Q)this.observers=[I],this.observerSlots=[I.sources.length-1];else Q.push(I),this.observerSlots.push(I.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function i0(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)i(()=>{for(let X=0;X1e6)throw S=[],Error()},!1)}return Q}function NJ(J){if(!J.fn)return;r(J);let Q=TJ;if(d0(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{i(()=>{B&&(B.running=!0),I=L=J,d0(J,J.tValue,Q),I=L=null},!1)})}function d0(J,Q,$){let Z,X=L,W=I;I=L=J;try{Z=J.fn(Q)}catch(q){if(J.pure)if(B&&B.running)J.tState=E,J.tOwned&&J.tOwned.forEach(r),J.tOwned=void 0;else J.state=E,J.owned&&J.owned.forEach(r),J.owned=null;return J.updatedAt=$+1,z0(q)}finally{I=W,L=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)i0(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function s0(J,Q,$,Z=E,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:L,context:L?L.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(L===null);else if(L!==l0)if(B&&B.running&&L.pure)if(!L.tOwned)L.tOwned=[W];else L.tOwned.push(W);else if(!L.owned)L.owned=[W];else L.owned.push(W);if(KJ&&W.fn){let q=W.fn,[G,M]=kJ(void 0,{equals:!1}),V=KJ.factory(q,M);Y0(()=>V.dispose());let R,H=()=>C4(M).then(()=>{if(R)R.dispose(),R=void 0});W.fn=(k)=>{if(G(),B&&B.running){if(!R)R=KJ.factory(q,H);return R.track(k)}return V.track(k)}}return W}function q0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===LJ)return mJ(J);if(J.suspense&&a(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===E)NJ(J);else if((Q?J.tState:J.state)===LJ){let X=S;S=null,i(()=>mJ(J,$[0]),!1),S=X}}}function i(J,Q){if(S)return J();let $=!1;if(!Q)S=[];if(f)$=!0;else f=[];TJ++;try{let Z=J();return I4($),Z}catch(Z){if(!$)f=null;S=null,z0(Z)}}function I4(J){if(S){if(IJ&&B&&B.running)k4(S);else a0(S);S=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;f.push.apply(f,B.effects),Q=B.resolve;for(let W of f)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,i(()=>{for(let W of X)r(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let q=0,G=W.owned.length;qO4($),!1);if(Q)Q()}function a0(J){for(let Q=0;Q{Z.delete($),i(()=>{B.running=!0,q0($)},!1),B&&(B.running=!1)})}}function mJ(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)r(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)o0(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)r(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function o0(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return Y0(()=>t0(W)),()=>{let M=J()||[],V=M.length,R,H;return M[D4],a(()=>{let _,h,p,$J,HJ,F,j,z,U;if(V===0){if(q!==0)t0(W),W=[],Z=[],X=[],q=0,G&&(G=[]);if($.fallback)Z=[S4],X[0]=EJ((D)=>{return W[0]=D,$.fallback()}),q=1}else if(q===0){X=Array(V);for(H=0;H=F&&z>=F&&Z[j]===M[z];j--,z--)p[z]=X[j],$J[z]=W[j],G&&(HJ[z]=G[j]);_=new Map,h=Array(z+1);for(H=z;H>=F;H--)U=M[H],R=_.get(U),h[H]=R===void 0?-1:R,_.set(U,H);for(R=F;R<=j;R++)if(U=Z[R],H=_.get(U),H!==void 0&&H!==-1)p[H]=X[R],$J[H]=W[R],G&&(HJ[H]=G[R]),H=h[H],_.set(U,H);else W[R]();for(H=F;HJ(Q||{}));return v0($),Z}}return a(()=>J(Q||{}))}function vJ(){return!0}var x4={get(J,Q,$){if(Q===W0)return $;return J.get(Q)},has(J,Q){if(Q===W0)return!0;return J.has(Q)},set:vJ,deleteProperty:vJ,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:vJ,deleteProperty:vJ}},ownKeys(J){return J.keys()}};function G0(J){return!(J=typeof J==="function"?J():J)?{}:J}function f4(){for(let J=0,Q=this.length;J=0;G--){let M=G0(J[G])[q];if(M!==void 0)return M}},has(q){for(let G=J.length-1;G>=0;G--)if(q in G0(J[G]))return!0;return!1},keys(){let q=[];for(let G=0;G=0;q--){let G=J[q];if(!G)continue;let M=Object.getOwnPropertyNames(G);for(let V=M.length-1;V>=0;V--){let R=M[V];if(R==="__proto__"||R==="constructor")continue;let H=Object.getOwnPropertyDescriptor(G,R);if(!Z[R])Z[R]=H.get?{enumerable:!0,configurable:!0,get:f4.bind($[R]=[H.get.bind(G)])}:H.value!==void 0?H:void 0;else{let k=$[R];if(k){if(H.get)k.push(H.get.bind(G));else if(H.value!==void 0)k.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let q=W.length-1;q>=0;q--){let G=W[q],M=Z[G];if(M&&M.get)Object.defineProperty(X,G,M);else X[G]=M?M.value:void 0}return X}var b4=(J)=>`Stale read from <${J}>.`;function g4(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return MJ(_4(()=>J.each,J.children,Q||void 0))}function T4(J){let Q=J.keyed,$=MJ(()=>J.when,void 0,void 0),Z=Q?$:MJ($,void 0,{equals:(X,W)=>!X===!W});return MJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?a(()=>W(Q?X:()=>{if(!a(Z))throw b4("Show");return $()})):W}return J.fallback},void 0,void 0)}var E4=(J)=>MJ(()=>J());function N4({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:q,getParentNode:G,getFirstChild:M,getNextSibling:V}){function R(F,j,z,U){if(z!==void 0&&!U)U=[];if(typeof j!=="function")return H(F,j,U,z);s((D)=>H(F,j(),D,z),U)}function H(F,j,z,U,D){while(typeof z==="function")z=z();if(j===z)return z;let C=typeof j,w=U!==void 0;if(C==="string"||C==="number"){if(C==="number")j=j.toString();if(w){let P=z[0];if(P&&$(P))Z(P,j);else P=Q(j);z=h(F,z,U,P)}else if(z!==""&&typeof z==="string")Z(M(F),z=j);else h(F,z,U,Q(j)),z=j}else if(j==null||C==="boolean")z=h(F,z,U);else if(C==="function")return s(()=>{let P=j();while(typeof P==="function")P=P();z=H(F,P,z,U)}),()=>z;else if(Array.isArray(j)){let P=[];if(k(P,j,D))return s(()=>z=H(F,P,z,U,!0)),()=>z;if(P.length===0){let CJ=h(F,z,U);if(w)return z=CJ}else if(Array.isArray(z))if(z.length===0)p(F,P,U);else _(F,z,P);else if(z==null||z==="")p(F,P);else _(F,w&&z||[M(F)],P);z=P}else{if(Array.isArray(z)){if(w)return z=h(F,z,U,j);h(F,z,null,j)}else if(z==null||z===""||!M(F))X(F,j);else $J(F,j,M(F));z=j}return z}function k(F,j,z){let U=!1;for(let D=0,C=j.length;Dc-P){let z2=j[w];while(P=0;w--){let P=j[w];if(D!==P){let CJ=G(P)===F;if(!C&&!w)CJ?$J(F,D,P):X(F,D,z);else CJ&&W(F,P)}else C=!0}}else X(F,D,z);return[D]}function p(F,j,z){for(let U=0,D=j.length;Uz.children=H(F,j.children,z.children));return s(()=>j.ref&&j.ref(F)),s(()=>{for(let D in j){if(D==="children"||D==="ref")continue;let C=j[D];if(C===z[D])continue;q(F,D,C,z[D]),z[D]=C}}),z}return{render(F,j){let z;return EJ((U)=>{z=U,R(j,F())}),z},insert:R,spread(F,j,z){if(typeof j==="function")s((U)=>HJ(F,j(),U,z));else HJ(F,j,void 0,z)},createElement:J,createTextNode:Q,insertNode:X,setProp(F,j,z,U){return q(F,j,z,U),z},mergeProps:e0,effect:s,memo:E4,createComponent:h4,use(F,j,z){return a(()=>F(j,z))}}}function m4(J){let Q=N4(J);return Q.mergeProps=e0,Q}var J1=480,Q1=272,ZJ={view:0,text:1,image:2},v4=1,u4=-1,l4={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},K={f32:0,color:1,int:2},p4={width:K.f32,height:K.f32,minW:K.f32,minH:K.f32,maxW:K.f32,maxH:K.f32,paddingT:K.f32,paddingR:K.f32,paddingB:K.f32,paddingL:K.f32,marginT:K.f32,marginR:K.f32,marginB:K.f32,marginL:K.f32,gap:K.f32,flexDir:K.int,justify:K.int,align:K.int,grow:K.f32,shrink:K.f32,basis:K.f32,flexWrap:K.int,posType:K.int,insetT:K.f32,insetR:K.f32,insetB:K.f32,insetL:K.f32,display:K.int,overflow:K.int,zIndex:K.int,hitPass:K.int,bgColor:K.color,gradFrom:K.color,gradTo:K.color,gradDir:K.int,radius:K.f32,opacity:K.f32,borderColor:K.color,borderWidth:K.f32,shadow:K.int,bevelOuterLight:K.color,bevelOuterDark:K.color,bevelInnerLight:K.color,bevelInnerDark:K.color,bevelWidth:K.f32,textColor:K.color,fontSlot:K.int,textAlign:K.int,lineHeight:K.f32,tracking:K.f32,translateX:K.f32,translateY:K.f32,scale:K.f32,rotate:K.f32,scaleX:K.f32,scaleY:K.f32,originX:K.f32,originY:K.f32,rotateX:K.f32,rotateY:K.f32,translateZ:K.f32,perspective:K.f32,arcStart:K.f32,arcSweep:K.f32,arcWidth:K.f32},N={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},c4={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},i4=1,j2=2,B2=1,F2=2,K2=131072,M2=1,U2=262144,V2=1,P2=1,R2=1,w2=2,D2=4,O2=8,C2=16,L2=1,I2=2;function $1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var k2=1,d4=1263551300,s4=1,a4=32,r4=24,v={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},XJ=32896,A2=0.016666666666666666;function Z1(J){return J.__viewport??null}var H0=null;function o4(){return null}function X1(J,Q=o4()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function n4(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return X1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return X1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function t4(J){H0=J}function UJ(){if(!H0)throw Error("PocketJS: host not installed — call render() first");return H0}function y(){return UJ().ops}function e4(J){globalThis.frame=J}function J6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function Q6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return $1($>>>16&255,$>>>8&255,$&255,255);return $1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function $6(J,Q){let $=p4[J];if(typeof Q==="string"){if($===K.color)return Q6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===K.color||$===K.int)return Q>>>0;return Q}var uJ=60,W1=[1,2,3,4,5,6,10,12,15,20,30,60],j0=uJ,o=-1,Z6=0,AJ=[];function X6(J){if(!Number.isFinite(J)||J<=0)return uJ;let Q=W1[0];for(let $ of W1)if(Math.abs($-J)Q.at<=o).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;AJ=AJ.filter((Q)=>Q.at>o);for(let Q of J)Q.cb()}var B0=0.12,lJ=XJ;function z6(J){lJ=J===void 0?XJ:J&65535}function G6(){lJ=XJ}function z1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function j6(){return z1(lJ&255)}var G1=new Set,B6=0;function F6(){G1.clear(),B6=0,G6()}function K6(J){for(let Q of[...G1])Q(J)}var WJ=null,H1=null;function M6(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function j1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function SJ(J){F0();let Q=WJ?WJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return H1.slice(Q.off,Q.off+Q.len)}var _J=null,A=null,YJ=null,pJ=0,qJ=[],M0=[],U0=[];function F1(J){if(_J=J,A=null,YJ=null,pJ=0,qJ.length=0,M0.length=0,U0.length=0,m){if(m.pressTarget=null,m.target=null,m.spriteDirty=!0,m.fresh=!0,m.vw=0,m.tex>=0){let Q=y();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(m.tex),m.tex=-1}}}function V6(J,Q){J.onPress=Q??void 0}function P6(J,Q){if(J.focusable=Q,P1(),!Q&&A===J)g(null)}function g(J){if(YJ&&YJ!==J)zJ(null);A=J,y().setFocus(J?J.id:0)}function zJ(J){if(YJ===J)return;let Q=y();if(YJ)Q.setActive?.(YJ.id,0);if(YJ=J,J)Q.setActive?.(J.id,1)}function V0(){return qJ.length>0?qJ[qJ.length-1]:_J}function P0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;g($[X])}function D6(){if(!A)return null;let J=V0();if(J&&!u(A,J))return null;for(let Q=M0.length-1;Q>=0;Q--){let $=M0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function O6(J){let Q=D6();if(!Q)return!1;let $=[];if(P0(Q.node,$),$.length===0){if(A)g(null);return!0}let Z=Q.columns,X=A?$.indexOf(A):-1;if(X<0)return g(K1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)g($[W]);return!0}function C6(){if(!A)return null;let J=V0();if(J&&!u(A,J))return null;for(let Q=U0.length-1;Q>=0;Q--){let $=U0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function cJ(J){let Q=C6();if(Q&&Q.move(J))return;if(O6(J))return;w6(J)}function M1(){U1(A)}function U1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function iJ(J){zJ(J)}function L6(J){g(J),U1(J)}function u(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function R0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=R0(Q.children[X]);if(W){g(W);return}}let Z=Q;while(Z){if(Z.focusable){g(Z);return}Z=Z.parent}}g(null)}var m=null,V1=0;function P1(){V1++}var k6=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],A6=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function S6(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=k6[Q]>>$&1,X=A6[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,q=X?255:0;J[W]=q,J[W+1]=q,J[W+2]=q,J[W+3]=255}return J}function _6(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=SJ($.image)}catch(q){if(UJ().strict)throw q;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):y6(Q,W),X<0&&UJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(S6(),16,16,c4.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function y6(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&i4)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function dJ(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=dJ($[Z],Q);if(X)return X}return null}var sJ=null;function R1(J){sJ=J}function w1(J){let Q=qJ.length>0?qJ[qJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||u($,Q)))return $;$=$.parent}return null}function D1(J,Q,$){return w1(O1(J,Q,$))}function O1(J,Q,$){if($!==void 0)return $===0?null:dJ(sJ??_J,$);let Z=y(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return dJ(sJ??_J,X(J,Q))}function h6(J,Q,$){let Z=m,X=y();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=Z1(X);if(Z.vw=H?H.w:J1,Z.vh=H?H.h:Q1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)_6(Z,X);let W=H6()*Z.speed,q=j6()*Z.speed;if(Z.dpadSpeed>0&&W===0&&q===0){if(J&v.LEFT)W=-Z.dpadSpeed;if(J&v.RIGHT)W=Z.dpadSpeed;if(J&v.UP)q=-Z.dpadSpeed;if(J&v.DOWN)q=Z.dpadSpeed}let G=Z.fresh;if(W!==0||q!==0){let H=W6()/60,k=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),_=Math.min(Math.max(Z.y+q*H,0),Z.vh-1);if(k!==Z.x||_!==Z.y)Z.x=k,Z.y=_,G=!0}if(G)X.setCursorPos(Z.x,Z.y);let M=(Q|$)&Z.button,V=V1;if(G||M!==0||V!==Z.gen)Z.gen=V,Z.fresh=!1,Z.target=w1(dJ(sJ??_J,X.hitTest(Z.x,Z.y)));let R=Z.target;if(R!==A)g(R);if(Q&Z.button&&R)Z.pressTarget=R;if(Z.pressTarget){if(zJ(R===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=R===Z.pressTarget;if(Z.pressTarget=null,zJ(null),H)M1()}}else if($&Z.button)zJ(null);return!0}function x6(J){let Q=J&~pJ,$=pJ&~J;if(pJ=J,m&&h6(J,Q,$))return;if($&v.CIRCLE)zJ(null);if(Q===0)return;if(Q&v.DOWN)cJ("down");if(Q&v.RIGHT)cJ("right");if(Q&v.UP)cJ("up");if(Q&v.LEFT)cJ("left");if(Q&v.CIRCLE)zJ(A),M1()}var w0=null;function C1(J){w0=J}function VJ(){if(P1(),w0)w0()}function f6(J,Q){J.debugName=Q||void 0,VJ()}var n={id:v4,type:ZJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},L1=Symbol.for("pocketjs.native-node"),D0=1,yJ=3,d=8,b6=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function aJ(J){return J.domAttrs??={}}function I1(J,Q){let $=J.domNodeType??(hJ(J)?yJ:D0),Z=$===yJ?rJ(J.text??""):$===d?E6(J.domData??""):x1(J.domTag??nJ(J));for(let X of Object.keys(J.domAttrs??{}))O0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)t(Z,I1(X,!0));return Z}function O0(J,Q,$){if(b6.has(Q)){RJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete aJ(J)[Q];else aJ(J)[Q]=$}function C0(J){if(J[L1]===!0)return J;return Object.defineProperty(J,L1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(hJ(J)?yJ:D0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else oJ(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else oJ(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===d)return J.domData??"";if(hJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===d)J.domData=Z;else if(hJ(J))oJ(J,Z);else if(c6(J),Z)t(J,rJ(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return b1(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??nJ(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===yJ)return"#text";if(J.domNodeType===d)return"#comment";return(J.domTag??nJ(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){RJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===n)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return t(J,$),$},insertBefore($,Z){return t(J,$,Z??null),$},removeChild($){return xJ(J,$),$},replaceChild($,Z){return t(J,$,Z),xJ(J,Z),Z},cloneNode($=!1){return I1(J,!!$)},remove(){if(J.parent)xJ(J.parent,J)},setAttribute($,Z){O0(J,$,Z)},removeAttribute($){O0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}C0(n);var L0=null;function g6(J){L0=J}var I0={unknownClass:0,unknownTexture:0},k1=new Map;function A1(J,Q){k1.set(J,Q)}var S1=new Map;function _1(J,Q){S1.set(J,Q)}var PJ=new Set,T6=new Set;function y1(J){if(!J)return!1;if(T6.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return C0({id:y().createNode(Q),type:Q,parent:null,children:[],domNodeType:D0,domTag:J})}function rJ(J){let Q=y(),$=Q.createNode(ZJ.text);return Q.setText($,J),C0({id:$,type:ZJ.text,parent:null,children:[],text:J,domNodeType:yJ,domTag:"#text"})}function E6(J=""){let Q=rJ("");return Q.domNodeType=d,Q.domTag="#comment",Q.domData=J,Q}function oJ(J,Q){y().replaceText(J.id,Q),J.text=Q,VJ()}function hJ(J){return J.type===ZJ.text}function f1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function t(J,Q,$){let Z=y();if(f1(Q),PJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,VJ()}function xJ(J,Q){if(!Q)return;I6(Q),y().removeChild(J.id,Q.id),f1(Q),PJ.add(Q),VJ()}function N6(J){return J.parent??void 0}function m6(J){return J.children[0]}function b1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function v6(J,Q){let $=y();if(VJ(),Q==null||Q===""){$.setStyle(J.id,u4);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=L0?L0(Q):void 0;if(Z===void 0){if(UJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);I0.unknownClass++;return}$.setStyle(J.id,Z)}function u6(J,Q){let $=y();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=k1.get(Q);if(Z===void 0){if(UJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);I0.unknownTexture++;return}$.setImage(J.id,Z)}function l6(J,Q){let $=y();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=S1.get(Q);if(Z===void 0){if(UJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);I0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function p6(J,Q,$){let Z=y(),X=Q??{},W=$??{},q=!1;for(let G in X){let M=X[G];if(W[G]===M)continue;let V=l4[G];if(V===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,V,$6(G,M)),q=!0}if(q)VJ()}function RJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete aJ(J)[Q];else aJ(J)[Q]=$;switch(Q){case"class":return v6(J,$),$;case"onPress":case"on:press":return V6(J,$),$;case"src":return u6(J,$),$;case"sprite":return l6(J,$),$;case"style":return p6(J,$,Z),$;case"focusable":return P6(J,!!$),$;case"debugName":return f6(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${nJ(J)}>`)}function c6(J){for(let Q of[...J.children])xJ(J,Q)}function nJ(J){for(let Q of Object.keys(ZJ))if(ZJ[Q]===J.type)return Q;return String(J.type)}function i6(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}RJ(J,Q,$,Z)}var d6=m4({createElement:x1,createTextNode:rJ,replaceText:oJ,isTextNode:hJ,setProperty:i6,insertNode(J,Q,$){t(J,Q,$)},removeNode(J,Q){xJ(J,Q)},getParentNode:N6,getFirstChild:m6,getNextSibling:b1}),{render:s6,effect:S2,memo:a6,createComponent:O,createElement:g1,insert:_2,spread:r6,mergeProps:y2,use:h2}=d6,x2={linear:N.Easing.Linear,in:N.Easing.EaseIn,out:N.Easing.EaseOut,"in-out":N.Easing.EaseInOut,"out-back":N.Easing.OutBack,spring:N.Easing.Spring,"spring-bouncy":N.Easing.SpringBouncy},o6=null;function T1(J){o6=J}function n6(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function E1(J,Q){let $=g1(J);return r6($,Q,!1),n6(Q.nodeRef,$),$}function T(J){return E1("view",J)}function x(J){return E1("text",J)}var f2=new WeakMap,b2=new WeakMap,t6={}!==null?Object.freeze({...{}}):Object.freeze({}),g2=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:t6}),T2=new Map,e=36000,k0=30,e6=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(e),tapeAnalog:new Uint16Array(e),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-k0,saidHello:!1,hostCalls:0};function J8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-k0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)C1(()=>{Y.treeDirty=!0}),z8();else C1(null);globalThis.__pocketDevtools=H8}function Q8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)Z8(),Y8();let W=Q,q=$===void 0?XJ:$&65535,G=Z,M=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(e).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==XJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function v1(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,q]of J)Z.fill(W,X,Math.min(X+q,$)),X+=q;return Z}function u1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return v1(J.masks,0,Q)}function l1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return v1(J.analog??[],XJ,Q)}function p1(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,b({t:"hello",app:Y.app,host:G8(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` -`))if(X.trim())X8(X)}}function X8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)b({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),A0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),A0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":c1();break;case"eval":{let Z=!0,X;try{X=tJ((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}b({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":b({t:"tape",tape:m1()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}b({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())b({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else b({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=u1(Z),Y.replayAnalog=Z.analog?l1(Z):null,Y.replayTouch=Z.touch?p1(Z):null,Y.replayAt=0;break}default:break}}function W8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=k0)c1();if(Y.frame%e6===0)A0()}function Y8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,b({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,b({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function A0(){b({t:"stats",frame:Y.frame,nodes:s1(n),tapeLen:Y.tapeLen,paused:Y.paused})}function c1(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,b({t:"tree",frame:Y.frame,root:d1(n)})}function q8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function S0(J,Q){if(Array.isArray(J)){for(let $ of J)S0($,Q);return}if(q8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)S0($,Q)}}function i1(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)S0(Z,Q)}function d1(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(i1(J,(X)=>{if(X.domNodeType===8)return;Z.push(d1(X))}),Z.length)Q.k=Z;return Q}function s1(J){let Q=1;return i1(J,($)=>{Q+=s1($)}),Q}function z8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{b({t:"log",level:$,args:X.map((W)=>tJ(W))}),Z?.apply(Q,X)}}}function tJ(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?a1(W):JSON.stringify(a1(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((q)=>tJ(q,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,q])=>`${W}: ${tJ(q,Q+1)}`).join(", ")}}`}function a1(J){return J.length>200?J.slice(0,199)+"…":J}function G8(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var H8={get frame(){return Y.frame},dumpTape:()=>m1(),replay:(J)=>{Y.replayMasks=u1(J),Y.replayAnalog=J.analog?l1(J):null,Y.replayTouch=J.touch?p1(J):null,Y.replayAt=0}},r1=new Map,_0=new Map;function o1(J){return J.trim().replace(/\s+/g," ")}function n1(J){return J.split(" ").sort().join(" ")}var t1=-1;function j8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=o1(Q);r1.set(Z,$);let X=n1(Z),W=_0.get(X);_0.set(X,W!==void 0&&W!==$?t1:$)}}function B8(J){let Q=o1(J),$=r1.get(Q);if($!==void 0)return $;let Z=_0.get(n1(Q));return Z===t1?void 0:Z}var y0=9,F8=(1<{let X=($&M8)!==0,W=X?h0:y0,q=X?U8:F8;return Object.freeze({id:$>>>(X?V8:K8)&255,x:$&q,y:$>>>W&q,hit:Q?.[Z]})}))}function R8(){return eJ}function w8(){eJ=x0}var e1=8,JJ=8,D8=3,O8=8,C8=6,L8=0.5,l=1,fJ=2,f0=4,GJ=8,wJ=[],J4=0,J0=0,QJ=Array.from({length:e1},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(JJ),histY:new Int16Array(JJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function I8(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function k8(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=O1(Q,$,Z.fact);let G=Z.hit;if(G)return I8(G,W)}let q=X.rect?.();if(!q)return!1;return Q>=q.x&&Q=q.y&&$=0;q--){let G=wJ[q];if(G.disposed)continue;if(J4>0&&!G.opts.allowWhenBlocked)continue;if(!k8(G,$,Z,W))continue;G.flags[J.slot]=l,J.owners.push(G)}for(let q of J.owners)q.opts.onDown?.(J)}function _8(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%JJ,J.histLenq||Z>q))X.flags[J.slot]|=fJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&l)||W&(fJ|f0))continue;if(!X.opts.onLongPress)continue;let q=Math.max(1,Math.round((X.opts.longPressSeconds??L8)*Y1()));if(J.frames=0)wJ.splice($,1)},cancel(){if(!Q.disposed)Z4(Q)},get panning(){for(let $ of QJ)if($.used&&Q.flags[$.slot]&GJ)return!0;return!1}}}function b8(J){let Q=f8(J);return Y0(()=>Q.dispose()),Q}function X4(){wJ.length=0,J4=0,J0=0;for(let J of QJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function g8(){return b8({onDown:(J)=>{let Q=D1(J.x,J.y,J.hit);if(Q)iJ(Q)},onTap:(J)=>{iJ(null);let Q=D1(J.x,J.y,J.hit);if(Q)L6(Q)},onUp:()=>iJ(null),onCancel:()=>iJ(null)})}var T8=1,b0=new Map,Q0=[];function E8(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function N8(){T8=1,b0.clear(),Q0=[]}function m8(){if(Q0.length===0)return;let J=Q0;Q0=[];for(let{id:Q,result:$}of J){let Z=b0.get(Q);if(!Z)continue;b0.delete(Q),E8()?.({t:"delivery",frame:q1(),id:Q,kind:Z.kind}),Z.onResult($)}}var W4=new Set;function v8(){if(W4.size===0)return;for(let J of W4)J()}var u8={"flex-col w-full h-full bg-slate-50":0,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":1,"flex-row items-center gap-4":2,"text-2xl text-white":3,"flex-col":4,"text-sm text-indigo-300 tracking-wide":5,"text-2xl text-white font-bold":6,"px-3 py-2 bg-indigo-900":7,"text-sm text-indigo-200":8,"p-6 flex-col gap-3":9,"text-sm text-indigo-700 font-bold":10,"text-2xl text-slate-950 font-bold":11,"text-base text-slate-600":12,"grow px-6 pt-4 flex-col gap-3":13,"h-[430] px-12 flex-col items-center justify-center bg-white":14,"w-[88] h-[88] items-center justify-center bg-indigo-100":15,"text-2xl text-indigo-700 font-bold":16,"pt-7 text-xl text-slate-900 font-bold":17,"pt-4 text-base text-slate-500":18,"h-[118] px-5 flex-row items-center justify-between bg-white":19,"w-[500] flex-col gap-2":20,"text-base text-slate-900 font-bold":21,"text-sm text-slate-500":22,"text-sm text-indigo-600 font-bold":23,"px-3 py-2 bg-emerald-100":24,"px-3 py-2 bg-red-100":25,"text-sm text-emerald-700":26,"text-sm text-red-500":27,"h-[96] px-6 flex-row items-center bg-slate-950":28,"text-sm text-slate-300":29,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":30,"absolute inset-0 z-50 flex-col items-center justify-center":31,"absolute inset-0 bg-slate-950":32,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":33,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":34,"flex-row flex-wrap":35,grow:36};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var l8="ui:styles",p8="ui:font.",Y4="ui:img.",q4="ui:sprite.";function c8(){return globalThis.ui}function i8(J){if(J.__textures)return;for(let Q of K0(Y4)){let $=SJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)A1(Q.slice(Y4.length),Z)}}function d8(J){if(J.__sprites)return;for(let Q of K0(q4)){let $=SJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),q=$[4],G=Z.getUint16(6,!0),M=Z.getUint16(8,!0),V=Z.getUint16(10,!0),R=J.uploadTexture($.subarray(16),X,W,q);if(R>=0)_1(Q.slice(q4.length),{handle:R,frames:G,cols:M,step:V})}}function z4(J){let Q=g1("view");return RJ(Q,"style",J,void 0),Q}var $0=null,Z0=null;function s8(J,Q){if(!$0||!Z0)return;RJ($0,"style",{width:J,height:Q,overflow:N.Overflow.Hidden},void 0),RJ(Z0,"style",{width:J,height:Q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=y();$.__viewport={w:J,h:Q}}function a8(J,Q={}){let $=n4(Q.ops);if(t4($),g6(B8),Q.styles)j8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let k in Z)A1(k,Z[k]);let H=$.ops.__sprites;if(H)for(let k in H)_1(k,H[k])}if($.kind==="injected"||Z===void 0){if(Q.pak)B1(Q.pak);if(U6()){for(let H of K0())if(H===l8)$.ops.loadStyles?.(SJ(H));else if(H.startsWith(p8))$.ops.loadFontAtlas?.(SJ(H))}}let X=Z1($.ops),W=X?.w??J1,q=X?.h??Q1,G=z4({width:W,height:q,overflow:N.Overflow.Hidden}),M=z4({width:W,height:q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});t(n,G),t(n,M),T1(M),$0=G,Z0=M,F1(G),R1(n),F6(),X4(),g8(),Y6(),N8(),J8($.ops),e4(Q8((H,k,_,h)=>{q6(),z6(k),P8(_,h),v8(),m8(),x8(),K6(H),x6(H),h1()}));let V=s6(J,G),R=J6(s8);return()=>{R(),w8(),X4(),V(),F1(null),R1(null),T1(null),$0=null,Z0=null;for(let H of n.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);h1()}}function r8(J,Q={}){let $=Q.ops??c8();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)B1(Q.pak);return i8($),d8($),a8(J,{ops:$,styles:Q.styles??u8,pak:Q.pak})}var G4="$b",o8=9007199254740991,n8=":memory:",DJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function t8(J){let Q="";for(let $=0;$>2]+DJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2o8)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function Q2(J){if(J!==null&&typeof J==="object")return e8(J[G4]);return J}function $2(J){if(Array.isArray(J))return JSON.stringify(J.map(H4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=H4(Z);return JSON.stringify(Q)}class g0{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,$2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=j4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(Q2))}run(...J){let Q=this.execute(j4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function j4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class B4{statements=new Map;txDepth=0;constructor(J=n8){let Q=J2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new g0(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new g0(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let q=J(...Q);return this.txDepth--,this.exec(X),q}catch(q){throw this.txDepth--,this.exec(W),q}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var F4=3,OJ=new B4("exa"),[K4,T0]=kJ([]),[Z2,E0]=kJ("SEARCH HISTORY IS LOCAL"),X0=-1;function X2(J){try{return JSON.parse(J)}catch{return null}}function W2(J){let Q=new Date(J*1000).toISOString();return Q.slice(0,10)+" · "+Q.slice(11,16)+" UTC"}function M4(J){if(X0===J)return;try{let Q=OJ.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==F4){T0([]),E0("SEARCH HISTORY IS LOCAL");return}let $=OJ.query(` +(()=>{var KJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return v0(this.context.count)},getNextContextId(){return v0(this.context.count++)}};function v0(J){let Q=String(J),$=Q.length-1;return KJ.context.id+($?String.fromCharCode(96+$):"")+Q}function u0(J){KJ.context=J}function P4(){return{...KJ.context,id:KJ.getNextContextId(),count:0}}var R4=!1,w4=(J,Q)=>J===Q,W0=Symbol("solid-proxy"),D4=typeof Proxy==="function",O4=Symbol("solid-track"),H2=Symbol("solid-dev-component"),gJ={equals:w4},l0=null,L4=r0,E=1,CJ=2,p0={owned:null,cleanups:null,context:null,owner:null},I=null,B=null,IJ=null,MJ=null,k=null,S=null,f=null,TJ=0;function EJ(J,Q){let $=k,Z=I,X=J.length===0,W=Q===void 0?Z:Q,q=X?p0:{owned:null,cleanups:null,context:W?W.context:null,owner:W},G=X?J:()=>J(()=>r(()=>o(q)));I=q,k=null;try{return i(G,!0)}finally{k=$,I=Z}}function kJ(J,Q){Q=Q?Object.assign({},gJ,Q):gJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return d0($,X)};return[i0.bind($),Z]}function a(J,Q,$){let Z=a0(J,Q,!1,E);if(IJ&&B&&B.running)S.push(Z);else NJ(Z)}function UJ(J,Q,$){$=$?Object.assign({},gJ,$):gJ;let Z=a0(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,IJ&&B&&B.running)Z.tState=E,S.push(Z);else NJ(Z);return i0.bind(Z)}function r(J){if(!MJ&&k===null)return J();let Q=k;k=null;try{if(MJ)return MJ.untrack(J);return J()}finally{k=Q}}function Y0(J){if(I===null);else if(I.cleanups===null)I.cleanups=[J];else I.cleanups.push(J);return J}function C4(J){if(B&&B.running)return J(),B.done;let Q=k,$=I;return Promise.resolve().then(()=>{k=Q,I=$;let Z;if(IJ||I4)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return i(J,!1),k=I=null,Z?Z.done:void 0})}var[j2,c0]=kJ(!1),I4;function i0(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===E)NJ(this);else{let Q=S;S=null,i(()=>mJ(this),!1),S=Q}if(k){let Q=this.observers;if(!Q||Q[Q.length-1]!==k){let $=Q?Q.length:0;if(!k.sources)k.sources=[this],k.sourceSlots=[$];else k.sources.push(this),k.sourceSlots.push($);if(!Q)this.observers=[k],this.observerSlots=[k.sources.length-1];else Q.push(k),this.observerSlots.push(k.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function d0(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)i(()=>{for(let X=0;X1e6)throw S=[],Error()},!1)}return Q}function NJ(J){if(!J.fn)return;o(J);let Q=TJ;if(s0(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{i(()=>{B&&(B.running=!0),k=I=J,s0(J,J.tValue,Q),k=I=null},!1)})}function s0(J,Q,$){let Z,X=I,W=k;k=I=J;try{Z=J.fn(Q)}catch(q){if(J.pure)if(B&&B.running)J.tState=E,J.tOwned&&J.tOwned.forEach(o),J.tOwned=void 0;else J.state=E,J.owned&&J.owned.forEach(o),J.owned=null;return J.updatedAt=$+1,z0(q)}finally{k=W,I=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)d0(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function a0(J,Q,$,Z=E,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:I,context:I?I.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(I===null);else if(I!==p0)if(B&&B.running&&I.pure)if(!I.tOwned)I.tOwned=[W];else I.tOwned.push(W);else if(!I.owned)I.owned=[W];else I.owned.push(W);if(MJ&&W.fn){let q=W.fn,[G,M]=kJ(void 0,{equals:!1}),U=MJ.factory(q,M);Y0(()=>U.dispose());let V,H=()=>C4(M).then(()=>{if(V)V.dispose(),V=void 0});W.fn=(L)=>{if(G(),B&&B.running){if(!V)V=MJ.factory(q,H);return V.track(L)}return U.track(L)}}return W}function q0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===CJ)return mJ(J);if(J.suspense&&r(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===E)NJ(J);else if((Q?J.tState:J.state)===CJ){let X=S;S=null,i(()=>mJ(J,$[0]),!1),S=X}}}function i(J,Q){if(S)return J();let $=!1;if(!Q)S=[];if(f)$=!0;else f=[];TJ++;try{let Z=J();return k4($),Z}catch(Z){if(!$)f=null;S=null,z0(Z)}}function k4(J){if(S){if(IJ&&B&&B.running)A4(S);else r0(S);S=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;f.push.apply(f,B.effects),Q=B.resolve;for(let W of f)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,i(()=>{for(let W of X)o(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let q=0,G=W.owned.length;qL4($),!1);if(Q)Q()}function r0(J){for(let Q=0;Q{Z.delete($),i(()=>{B.running=!0,q0($)},!1),B&&(B.running=!1)})}}function mJ(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)o(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)n0(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)o(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function n0(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return Y0(()=>e0(W)),()=>{let M=J()||[],U=M.length,V,H;return M[O4],r(()=>{let y,h,p,ZJ,jJ,F,j,z,P;if(U===0){if(q!==0)e0(W),W=[],Z=[],X=[],q=0,G&&(G=[]);if($.fallback)Z=[y4],X[0]=EJ((D)=>{return W[0]=D,$.fallback()}),q=1}else if(q===0){X=Array(U);for(H=0;H=F&&z>=F&&Z[j]===M[z];j--,z--)p[z]=X[j],ZJ[z]=W[j],G&&(jJ[z]=G[j]);y=new Map,h=Array(z+1);for(H=z;H>=F;H--)P=M[H],V=y.get(P),h[H]=V===void 0?-1:V,y.set(P,H);for(V=F;V<=j;V++)if(P=Z[V],H=y.get(P),H!==void 0&&H!==-1)p[H]=X[V],ZJ[H]=W[V],G&&(jJ[H]=G[V]),H=h[H],y.set(P,H);else W[V]();for(H=F;HJ(Q||{}));return u0($),Z}}return r(()=>J(Q||{}))}function vJ(){return!0}var f4={get(J,Q,$){if(Q===W0)return $;return J.get(Q)},has(J,Q){if(Q===W0)return!0;return J.has(Q)},set:vJ,deleteProperty:vJ,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:vJ,deleteProperty:vJ}},ownKeys(J){return J.keys()}};function G0(J){return!(J=typeof J==="function"?J():J)?{}:J}function b4(){for(let J=0,Q=this.length;J=0;G--){let M=G0(J[G])[q];if(M!==void 0)return M}},has(q){for(let G=J.length-1;G>=0;G--)if(q in G0(J[G]))return!0;return!1},keys(){let q=[];for(let G=0;G=0;q--){let G=J[q];if(!G)continue;let M=Object.getOwnPropertyNames(G);for(let U=M.length-1;U>=0;U--){let V=M[U];if(V==="__proto__"||V==="constructor")continue;let H=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=H.get?{enumerable:!0,configurable:!0,get:b4.bind($[V]=[H.get.bind(G)])}:H.value!==void 0?H:void 0;else{let L=$[V];if(L){if(H.get)L.push(H.get.bind(G));else if(H.value!==void 0)L.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let q=W.length-1;q>=0;q--){let G=W[q],M=Z[G];if(M&&M.get)Object.defineProperty(X,G,M);else X[G]=M?M.value:void 0}return X}var g4=(J)=>`Stale read from <${J}>.`;function T4(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return UJ(_4(()=>J.each,J.children,Q||void 0))}function E4(J){let Q=J.keyed,$=UJ(()=>J.when,void 0,void 0),Z=Q?$:UJ($,void 0,{equals:(X,W)=>!X===!W});return UJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?r(()=>W(Q?X:()=>{if(!r(Z))throw g4("Show");return $()})):W}return J.fallback},void 0,void 0)}var N4=(J)=>UJ(()=>J());function m4({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:q,getParentNode:G,getFirstChild:M,getNextSibling:U}){function V(F,j,z,P){if(z!==void 0&&!P)P=[];if(typeof j!=="function")return H(F,j,P,z);a((D)=>H(F,j(),D,z),P)}function H(F,j,z,P,D){while(typeof z==="function")z=z();if(j===z)return z;let C=typeof j,w=P!==void 0;if(C==="string"||C==="number"){if(C==="number")j=j.toString();if(w){let R=z[0];if(R&&$(R))Z(R,j);else R=Q(j);z=h(F,z,P,R)}else if(z!==""&&typeof z==="string")Z(M(F),z=j);else h(F,z,P,Q(j)),z=j}else if(j==null||C==="boolean")z=h(F,z,P);else if(C==="function")return a(()=>{let R=j();while(typeof R==="function")R=R();z=H(F,R,z,P)}),()=>z;else if(Array.isArray(j)){let R=[];if(L(R,j,D))return a(()=>z=H(F,R,z,P,!0)),()=>z;if(R.length===0){let LJ=h(F,z,P);if(w)return z=LJ}else if(Array.isArray(z))if(z.length===0)p(F,R,P);else y(F,z,R);else if(z==null||z==="")p(F,R);else y(F,w&&z||[M(F)],R);z=R}else{if(Array.isArray(z)){if(w)return z=h(F,z,P,j);h(F,z,null,j)}else if(z==null||z===""||!M(F))X(F,j);else ZJ(F,j,M(F));z=j}return z}function L(F,j,z){let P=!1;for(let D=0,C=j.length;Dc-R){let G2=j[w];while(R=0;w--){let R=j[w];if(D!==R){let LJ=G(R)===F;if(!C&&!w)LJ?ZJ(F,D,R):X(F,D,z);else LJ&&W(F,R)}else C=!0}}else X(F,D,z);return[D]}function p(F,j,z){for(let P=0,D=j.length;Pz.children=H(F,j.children,z.children));return a(()=>j.ref&&j.ref(F)),a(()=>{for(let D in j){if(D==="children"||D==="ref")continue;let C=j[D];if(C===z[D])continue;q(F,D,C,z[D]),z[D]=C}}),z}return{render(F,j){let z;return EJ((P)=>{z=P,V(j,F())}),z},insert:V,spread(F,j,z){if(typeof j==="function")a((P)=>jJ(F,j(),P,z));else jJ(F,j,void 0,z)},createElement:J,createTextNode:Q,insertNode:X,setProp(F,j,z,P){return q(F,j,z,P),z},mergeProps:J1,effect:a,memo:N4,createComponent:x4,use(F,j,z){return r(()=>F(j,z))}}}function v4(J){let Q=m4(J);return Q.mergeProps=J1,Q}var Q1=480,$1=272,XJ={view:0,text:1,image:2},u4=1,l4=-1,p4={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},K={f32:0,color:1,int:2},c4={width:K.f32,height:K.f32,minW:K.f32,minH:K.f32,maxW:K.f32,maxH:K.f32,paddingT:K.f32,paddingR:K.f32,paddingB:K.f32,paddingL:K.f32,marginT:K.f32,marginR:K.f32,marginB:K.f32,marginL:K.f32,gap:K.f32,flexDir:K.int,justify:K.int,align:K.int,grow:K.f32,shrink:K.f32,basis:K.f32,flexWrap:K.int,posType:K.int,insetT:K.f32,insetR:K.f32,insetB:K.f32,insetL:K.f32,display:K.int,overflow:K.int,zIndex:K.int,hitPass:K.int,bgColor:K.color,gradFrom:K.color,gradTo:K.color,gradDir:K.int,radius:K.f32,opacity:K.f32,borderColor:K.color,borderWidth:K.f32,shadow:K.int,bevelOuterLight:K.color,bevelOuterDark:K.color,bevelInnerLight:K.color,bevelInnerDark:K.color,bevelWidth:K.f32,textColor:K.color,fontSlot:K.int,textAlign:K.int,lineHeight:K.f32,tracking:K.f32,translateX:K.f32,translateY:K.f32,scale:K.f32,rotate:K.f32,scaleX:K.f32,scaleY:K.f32,originX:K.f32,originY:K.f32,rotateX:K.f32,rotateY:K.f32,translateZ:K.f32,perspective:K.f32,arcStart:K.f32,arcSweep:K.f32,arcWidth:K.f32},N={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},i4={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},d4=1,B2=2,F2=1,K2=2,M2=131072,U2=1,V2=262144,P2=1,R2=1,w2=1,D2=2,O2=4,L2=8,C2=16,I2=1,k2=2;function Z1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var A2=1,s4=1263551300,a4=1,r4=32,o4=24,v={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},WJ=32896,S2=0.016666666666666666;function X1(J){return J.__viewport??null}var H0=null;function n4(){return null}function W1(J,Q=n4()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function t4(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return W1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return W1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function e4(J){H0=J}function VJ(){if(!H0)throw Error("PocketJS: host not installed — call render() first");return H0}function _(){return VJ().ops}function J6(J){globalThis.frame=J}function Q6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function $6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return Z1($>>>16&255,$>>>8&255,$&255,255);return Z1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function Z6(J,Q){let $=c4[J];if(typeof Q==="string"){if($===K.color)return $6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===K.color||$===K.int)return Q>>>0;return Q}var uJ=60,Y1=[1,2,3,4,5,6,10,12,15,20,30,60],j0=uJ,n=-1,X6=0,AJ=[];function W6(J){if(!Number.isFinite(J)||J<=0)return uJ;let Q=Y1[0];for(let $ of Y1)if(Math.abs($-J)Q.at<=n).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;AJ=AJ.filter((Q)=>Q.at>n);for(let Q of J)Q.cb()}var B0=0.12,lJ=WJ;function G6(J){lJ=J===void 0?WJ:J&65535}function H6(){lJ=WJ}function G1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function B6(){return G1(lJ&255)}var H1=new Set,F6=0;function K6(){H1.clear(),F6=0,H6()}function M6(J){for(let Q of[...H1])Q(J)}var YJ=null,j1=null;function U6(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function B1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function SJ(J){F0();let Q=YJ?YJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return j1.slice(Q.off,Q.off+Q.len)}var yJ=null,A=null,qJ=null,pJ=0,zJ=[],M0=[],U0=[];function K1(J){if(yJ=J,A=null,qJ=null,pJ=0,zJ.length=0,M0.length=0,U0.length=0,m){if(m.pressTarget=null,m.target=null,m.spriteDirty=!0,m.fresh=!0,m.vw=0,m.tex>=0){let Q=_();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(m.tex),m.tex=-1}}}function P6(J,Q){J.onPress=Q??void 0}function R6(J,Q){if(J.focusable=Q,R1(),!Q&&A===J)g(null)}function g(J){if(qJ&&qJ!==J)GJ(null);A=J,_().setFocus(J?J.id:0)}function GJ(J){if(qJ===J)return;let Q=_();if(qJ)Q.setActive?.(qJ.id,0);if(qJ=J,J)Q.setActive?.(J.id,1)}function V0(){return zJ.length>0?zJ[zJ.length-1]:yJ}function P0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;g($[X])}function O6(){if(!A)return null;let J=V0();if(J&&!u(A,J))return null;for(let Q=M0.length-1;Q>=0;Q--){let $=M0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function L6(J){let Q=O6();if(!Q)return!1;let $=[];if(P0(Q.node,$),$.length===0){if(A)g(null);return!0}let Z=Q.columns,X=A?$.indexOf(A):-1;if(X<0)return g(M1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)g($[W]);return!0}function C6(){if(!A)return null;let J=V0();if(J&&!u(A,J))return null;for(let Q=U0.length-1;Q>=0;Q--){let $=U0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function cJ(J){let Q=C6();if(Q&&Q.move(J))return;if(L6(J))return;D6(J)}function U1(){V1(A)}function V1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function iJ(J){GJ(J)}function I6(J){g(J),V1(J)}function u(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function R0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=R0(Q.children[X]);if(W){g(W);return}}let Z=Q;while(Z){if(Z.focusable){g(Z);return}Z=Z.parent}}g(null)}var m=null,P1=0;function R1(){P1++}var A6=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],S6=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function y6(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=A6[Q]>>$&1,X=S6[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,q=X?255:0;J[W]=q,J[W+1]=q,J[W+2]=q,J[W+3]=255}return J}function _6(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=SJ($.image)}catch(q){if(VJ().strict)throw q;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):h6(Q,W),X<0&&VJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(y6(),16,16,i4.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function h6(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&d4)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function dJ(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=dJ($[Z],Q);if(X)return X}return null}var sJ=null;function w1(J){sJ=J}function D1(J){let Q=zJ.length>0?zJ[zJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||u($,Q)))return $;$=$.parent}return null}function O1(J,Q,$){return D1(L1(J,Q,$))}function L1(J,Q,$){if($!==void 0)return $===0?null:dJ(sJ??yJ,$);let Z=_(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return dJ(sJ??yJ,X(J,Q))}function x6(J,Q,$){let Z=m,X=_();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=X1(X);if(Z.vw=H?H.w:Q1,Z.vh=H?H.h:$1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)_6(Z,X);let W=j6()*Z.speed,q=B6()*Z.speed;if(Z.dpadSpeed>0&&W===0&&q===0){if(J&v.LEFT)W=-Z.dpadSpeed;if(J&v.RIGHT)W=Z.dpadSpeed;if(J&v.UP)q=-Z.dpadSpeed;if(J&v.DOWN)q=Z.dpadSpeed}let G=Z.fresh;if(W!==0||q!==0){let H=Y6()/60,L=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),y=Math.min(Math.max(Z.y+q*H,0),Z.vh-1);if(L!==Z.x||y!==Z.y)Z.x=L,Z.y=y,G=!0}if(G)X.setCursorPos(Z.x,Z.y);let M=(Q|$)&Z.button,U=P1;if(G||M!==0||U!==Z.gen)Z.gen=U,Z.fresh=!1,Z.target=D1(dJ(sJ??yJ,X.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==A)g(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(GJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=V===Z.pressTarget;if(Z.pressTarget=null,GJ(null),H)U1()}}else if($&Z.button)GJ(null);return!0}function f6(J){let Q=J&~pJ,$=pJ&~J;if(pJ=J,m&&x6(J,Q,$))return;if($&v.CIRCLE)GJ(null);if(Q===0)return;if(Q&v.DOWN)cJ("down");if(Q&v.RIGHT)cJ("right");if(Q&v.UP)cJ("up");if(Q&v.LEFT)cJ("left");if(Q&v.CIRCLE)GJ(A),U1()}var w0=null;function C1(J){w0=J}function PJ(){if(R1(),w0)w0()}function b6(J,Q){J.debugName=Q||void 0,PJ()}var t={id:u4,type:XJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},I1=Symbol.for("pocketjs.native-node"),D0=1,_J=3,d=8,g6=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function aJ(J){return J.domAttrs??={}}function k1(J,Q){let $=J.domNodeType??(hJ(J)?_J:D0),Z=$===_J?rJ(J.text??""):$===d?N6(J.domData??""):f1(J.domTag??nJ(J));for(let X of Object.keys(J.domAttrs??{}))O0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)e(Z,k1(X,!0));return Z}function O0(J,Q,$){if(g6.has(Q)){wJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete aJ(J)[Q];else aJ(J)[Q]=$}function L0(J){if(J[I1]===!0)return J;return Object.defineProperty(J,I1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(hJ(J)?_J:D0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else oJ(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else oJ(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===d)return J.domData??"";if(hJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===d)J.domData=Z;else if(hJ(J))oJ(J,Z);else if(i6(J),Z)e(J,rJ(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return g1(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??nJ(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===_J)return"#text";if(J.domNodeType===d)return"#comment";return(J.domTag??nJ(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){wJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===t)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return e(J,$),$},insertBefore($,Z){return e(J,$,Z??null),$},removeChild($){return xJ(J,$),$},replaceChild($,Z){return e(J,$,Z),xJ(J,Z),Z},cloneNode($=!1){return k1(J,!!$)},remove(){if(J.parent)xJ(J.parent,J)},setAttribute($,Z){O0(J,$,Z)},removeAttribute($){O0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}L0(t);var C0=null;function T6(J){C0=J}var I0={unknownClass:0,unknownTexture:0},A1=new Map;function S1(J,Q){A1.set(J,Q)}var y1=new Map;function _1(J,Q){y1.set(J,Q)}var RJ=new Set,E6=new Set;function h1(J){if(!J)return!1;if(E6.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return L0({id:_().createNode(Q),type:Q,parent:null,children:[],domNodeType:D0,domTag:J})}function rJ(J){let Q=_(),$=Q.createNode(XJ.text);return Q.setText($,J),L0({id:$,type:XJ.text,parent:null,children:[],text:J,domNodeType:_J,domTag:"#text"})}function N6(J=""){let Q=rJ("");return Q.domNodeType=d,Q.domTag="#comment",Q.domData=J,Q}function oJ(J,Q){_().replaceText(J.id,Q),J.text=Q,PJ()}function hJ(J){return J.type===XJ.text}function b1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function e(J,Q,$){let Z=_();if(b1(Q),RJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,PJ()}function xJ(J,Q){if(!Q)return;k6(Q),_().removeChild(J.id,Q.id),b1(Q),RJ.add(Q),PJ()}function m6(J){return J.parent??void 0}function v6(J){return J.children[0]}function g1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function u6(J,Q){let $=_();if(PJ(),Q==null||Q===""){$.setStyle(J.id,l4);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=C0?C0(Q):void 0;if(Z===void 0){if(VJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);I0.unknownClass++;return}$.setStyle(J.id,Z)}function l6(J,Q){let $=_();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=A1.get(Q);if(Z===void 0){if(VJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);I0.unknownTexture++;return}$.setImage(J.id,Z)}function p6(J,Q){let $=_();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=y1.get(Q);if(Z===void 0){if(VJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);I0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function c6(J,Q,$){let Z=_(),X=Q??{},W=$??{},q=!1;for(let G in X){let M=X[G];if(W[G]===M)continue;let U=p4[G];if(U===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,U,Z6(G,M)),q=!0}if(q)PJ()}function wJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete aJ(J)[Q];else aJ(J)[Q]=$;switch(Q){case"class":return u6(J,$),$;case"onPress":case"on:press":return P6(J,$),$;case"src":return l6(J,$),$;case"sprite":return p6(J,$),$;case"style":return c6(J,$,Z),$;case"focusable":return R6(J,!!$),$;case"debugName":return b6(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${nJ(J)}>`)}function i6(J){for(let Q of[...J.children])xJ(J,Q)}function nJ(J){for(let Q of Object.keys(XJ))if(XJ[Q]===J.type)return Q;return String(J.type)}function d6(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}wJ(J,Q,$,Z)}var s6=v4({createElement:f1,createTextNode:rJ,replaceText:oJ,isTextNode:hJ,setProperty:d6,insertNode(J,Q,$){e(J,Q,$)},removeNode(J,Q){xJ(J,Q)},getParentNode:m6,getFirstChild:v6,getNextSibling:g1}),{render:a6,effect:y2,memo:r6,createComponent:O,createElement:T1,insert:_2,spread:o6,mergeProps:h2,use:x2}=s6,f2={linear:N.Easing.Linear,in:N.Easing.EaseIn,out:N.Easing.EaseOut,"in-out":N.Easing.EaseInOut,"out-back":N.Easing.OutBack,spring:N.Easing.Spring,"spring-bouncy":N.Easing.SpringBouncy},n6=null;function E1(J){n6=J}function t6(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function N1(J,Q){let $=T1(J);return o6($,Q,!1),t6(Q.nodeRef,$),$}function T(J){return N1("view",J)}function x(J){return N1("text",J)}var b2=new WeakMap,g2=new WeakMap,e6={}!==null?Object.freeze({...{}}):Object.freeze({}),T2=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:e6}),E2=new Map,JJ=36000,k0=30,J8=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(JJ),tapeAnalog:new Uint16Array(JJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-k0,saidHello:!1,hostCalls:0};function Q8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-k0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)C1(()=>{Y.treeDirty=!0}),G8();else C1(null);globalThis.__pocketDevtools=j8}function $8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)X8(),q8();let W=Q,q=$===void 0?WJ:$&65535,G=Z,M=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(JJ).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==WJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function u1(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,q]of J)Z.fill(W,X,Math.min(X+q,$)),X+=q;return Z}function l1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return u1(J.masks,0,Q)}function p1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return u1(J.analog??[],WJ,Q)}function c1(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,b({t:"hello",app:Y.app,host:H8(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` +`))if(X.trim())W8(X)}}function W8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)b({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),A0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),A0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":i1();break;case"eval":{let Z=!0,X;try{X=tJ((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}b({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":b({t:"tape",tape:v1()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}b({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())b({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else b({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=l1(Z),Y.replayAnalog=Z.analog?p1(Z):null,Y.replayTouch=Z.touch?c1(Z):null,Y.replayAt=0;break}default:break}}function Y8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=k0)i1();if(Y.frame%J8===0)A0()}function q8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,b({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,b({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function A0(){b({t:"stats",frame:Y.frame,nodes:a1(t),tapeLen:Y.tapeLen,paused:Y.paused})}function i1(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,b({t:"tree",frame:Y.frame,root:s1(t)})}function z8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function S0(J,Q){if(Array.isArray(J)){for(let $ of J)S0($,Q);return}if(z8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)S0($,Q)}}function d1(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)S0(Z,Q)}function s1(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(d1(J,(X)=>{if(X.domNodeType===8)return;Z.push(s1(X))}),Z.length)Q.k=Z;return Q}function a1(J){let Q=1;return d1(J,($)=>{Q+=a1($)}),Q}function G8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{b({t:"log",level:$,args:X.map((W)=>tJ(W))}),Z?.apply(Q,X)}}}function tJ(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?r1(W):JSON.stringify(r1(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((q)=>tJ(q,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,q])=>`${W}: ${tJ(q,Q+1)}`).join(", ")}}`}function r1(J){return J.length>200?J.slice(0,199)+"…":J}function H8(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var j8={get frame(){return Y.frame},dumpTape:()=>v1(),replay:(J)=>{Y.replayMasks=l1(J),Y.replayAnalog=J.analog?p1(J):null,Y.replayTouch=J.touch?c1(J):null,Y.replayAt=0}},o1=new Map,y0=new Map;function n1(J){return J.trim().replace(/\s+/g," ")}function t1(J){return J.split(" ").sort().join(" ")}var e1=-1;function B8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=n1(Q);o1.set(Z,$);let X=t1(Z),W=y0.get(X);y0.set(X,W!==void 0&&W!==$?e1:$)}}function F8(J){let Q=n1(J),$=o1.get(Q);if($!==void 0)return $;let Z=y0.get(t1(Q));return Z===e1?void 0:Z}var _0=9,K8=(1<<_0)-1,M8=_0*2,U8=2147483648,h0=10,V8=(1<{let X=($&U8)!==0,W=X?h0:_0,q=X?V8:K8;return Object.freeze({id:$>>>(X?P8:M8)&255,x:$&q,y:$>>>W&q,hit:Q?.[Z]})}))}function w8(){return eJ}function D8(){eJ=x0}var J4=8,QJ=8,O8=3,L8=8,C8=6,I8=0.5,l=1,fJ=2,f0=4,HJ=8,DJ=[],Q4=0,J0=0,$J=Array.from({length:J4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(QJ),histY:new Int16Array(QJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function k8(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function A8(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=L1(Q,$,Z.fact);let G=Z.hit;if(G)return k8(G,W)}let q=X.rect?.();if(!q)return!1;return Q>=q.x&&Q=q.y&&$=0;q--){let G=DJ[q];if(G.disposed)continue;if(Q4>0&&!G.opts.allowWhenBlocked)continue;if(!A8(G,$,Z,W))continue;G.flags[J.slot]=l,J.owners.push(G)}for(let q of J.owners)q.opts.onDown?.(J)}function _8(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%QJ,J.histLenq||Z>q))X.flags[J.slot]|=fJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&l)||W&(fJ|f0))continue;if(!X.opts.onLongPress)continue;let q=Math.max(1,Math.round((X.opts.longPressSeconds??I8)*q1()));if(J.frames=0)DJ.splice($,1)},cancel(){if(!Q.disposed)X4(Q)},get panning(){for(let $ of $J)if($.used&&Q.flags[$.slot]&HJ)return!0;return!1}}}function g8(J){let Q=b8(J);return Y0(()=>Q.dispose()),Q}function W4(){DJ.length=0,Q4=0,J0=0;for(let J of $J)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function T8(){return g8({onDown:(J)=>{let Q=O1(J.x,J.y,J.hit);if(Q)iJ(Q)},onTap:(J)=>{iJ(null);let Q=O1(J.x,J.y,J.hit);if(Q)I6(Q)},onUp:()=>iJ(null),onCancel:()=>iJ(null)})}var E8=1,b0=new Map,Q0=[];function N8(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function m8(){E8=1,b0.clear(),Q0=[]}function v8(){if(Q0.length===0)return;let J=Q0;Q0=[];for(let{id:Q,result:$}of J){let Z=b0.get(Q);if(!Z)continue;b0.delete(Q),N8()?.({t:"delivery",frame:z1(),id:Q,kind:Z.kind}),Z.onResult($)}}var Y4=new Set;function u8(){if(Y4.size===0)return;for(let J of Y4)J()}var l8={"flex-col w-full h-full bg-slate-50":0,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":1,"flex-row items-center gap-4":2,"text-2xl text-white":3,"flex-col":4,"text-sm text-indigo-300 tracking-wide":5,"text-2xl text-white font-bold":6,"px-3 py-2 bg-indigo-900":7,"text-sm text-indigo-200":8,"p-6 flex-col gap-3":9,"text-sm text-indigo-700 font-bold":10,"text-2xl text-slate-950 font-bold":11,"text-base text-slate-600":12,"grow px-6 pt-4 flex-col gap-3":13,"h-[430] px-12 flex-col items-center justify-center bg-white":14,"w-[88] h-[88] items-center justify-center bg-indigo-100":15,"text-2xl text-indigo-700 font-bold":16,"pt-7 text-xl text-slate-900 font-bold":17,"pt-4 text-base text-slate-500":18,"h-[118] px-5 flex-row items-center justify-between bg-white":19,"w-[500] flex-col gap-2":20,"text-base text-slate-900 font-bold":21,"text-sm text-slate-500":22,"text-sm text-indigo-600 font-bold":23,"px-3 py-2 bg-emerald-100":24,"px-3 py-2 bg-red-100":25,"text-sm text-emerald-700":26,"text-sm text-red-500":27,"h-[96] px-6 flex-row items-center bg-slate-950":28,"text-sm text-slate-300":29,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":30,"absolute inset-0 z-50 flex-col items-center justify-center":31,"absolute inset-0 bg-slate-950":32,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":33,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":34,"flex-row flex-wrap":35,grow:36};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var p8="ui:styles",c8="ui:font.",q4="ui:img.",z4="ui:sprite.";function i8(){return globalThis.ui}function d8(J){if(J.__textures)return;for(let Q of K0(q4)){let $=SJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)S1(Q.slice(q4.length),Z)}}function s8(J){if(J.__sprites)return;for(let Q of K0(z4)){let $=SJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),q=$[4],G=Z.getUint16(6,!0),M=Z.getUint16(8,!0),U=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),X,W,q);if(V>=0)_1(Q.slice(z4.length),{handle:V,frames:G,cols:M,step:U})}}function G4(J){let Q=T1("view");return wJ(Q,"style",J,void 0),Q}var $0=null,Z0=null;function a8(J,Q){if(!$0||!Z0)return;wJ($0,"style",{width:J,height:Q,overflow:N.Overflow.Hidden},void 0),wJ(Z0,"style",{width:J,height:Q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=_();$.__viewport={w:J,h:Q}}function r8(J,Q={}){let $=t4(Q.ops);if(e4($),T6(F8),Q.styles)B8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let L in Z)S1(L,Z[L]);let H=$.ops.__sprites;if(H)for(let L in H)_1(L,H[L])}if($.kind==="injected"||Z===void 0){if(Q.pak)F1(Q.pak);if(V6()){for(let H of K0())if(H===p8)$.ops.loadStyles?.(SJ(H));else if(H.startsWith(c8))$.ops.loadFontAtlas?.(SJ(H))}}let X=X1($.ops),W=X?.w??Q1,q=X?.h??$1,G=G4({width:W,height:q,overflow:N.Overflow.Hidden}),M=G4({width:W,height:q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});e(t,G),e(t,M),E1(M),$0=G,Z0=M,K1(G),w1(t),K6(),W4(),T8(),q6(),m8(),Q8($.ops),J6($8((H,L,y,h)=>{z6(),G6(L),R8(y,h),u8(),v8(),f8(),M6(H),f6(H),x1()}));let U=a6(J,G),V=Q6(a8);return()=>{V(),D8(),W4(),U(),K1(null),w1(null),E1(null),$0=null,Z0=null;for(let H of t.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);x1()}}function o8(J,Q={}){let $=Q.ops??i8();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)F1(Q.pak);return d8($),s8($),r8(J,{ops:$,styles:Q.styles??l8,pak:Q.pak})}var H4="$b",n8=9007199254740991,t8=":memory:",OJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function e8(J){let Q="";for(let $=0;$>2]+OJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2n8)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function $2(J){if(J!==null&&typeof J==="object")return J2(J[H4]);return J}function Z2(J){if(Array.isArray(J))return JSON.stringify(J.map(j4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=j4(Z);return JSON.stringify(Q)}class g0{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,Z2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=B4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map($2))}run(...J){let Q=this.execute(B4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function B4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class F4{statements=new Map;txDepth=0;constructor(J=t8){let Q=Q2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new g0(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new g0(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let q=J(...Q);return this.txDepth--,this.exec(X),q}catch(q){throw this.txDepth--,this.exec(W),q}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var T0=4,K4=7,s=new F4("exa"),[M4,E0]=kJ([]),[X2,N0]=kJ("SEARCH HISTORY IS LOCAL"),X0=-1;function W2(J){try{return JSON.parse(J)}catch{return null}}function Y2(J){let Q=new Date(J*1000).toISOString();return Q.slice(0,10)+" · "+Q.slice(11,16)+" UTC"}function U4(J){if(X0===J)return;try{let Q=s.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==T0){E0([]),N0("SEARCH HISTORY IS LOCAL");return}let $=s.query(` SELECT search.id,search.query,search.searched_at,search.status,search.result_count, result.title AS top_title,result.url AS top_url,search.error FROM searches search LEFT JOIN search_results result ON result.search_id=search.id AND result.rank=0 ORDER BY search.id DESC LIMIT 8 - `).all();T0($),E0($[0]?.status==="error"?String($[0].error||"EXA SEARCH FAILED").slice(0,80):$.length?"SEARCH HISTORY UPDATED FROM SQLITE":"SEARCH HISTORY IS LOCAL"),X0=J}catch{T0([]),E0("SEARCH HISTORY IS LOCAL")}}function Y2(){let J=OJ.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((W)=>W.name)),$=J.map((W)=>{let q=OJ.query("SELECT COUNT(*) AS count FROM "+W.name).get().count;return{name:W.name,rowCount:q,schema:W.sql}}),Z=Q.has("searches")?OJ.query(` - SELECT search.id,search.query,search.searched_at,search.status,search.result_count, - result.title AS top_title,result.url AS top_url,search.error - FROM searches search - LEFT JOIN search_results result ON result.search_id=search.id AND result.rank=0 - ORDER BY search.id DESC LIMIT 8 - `).all():[],X=Q.has("documents")?OJ.query("SELECT fetched_at,url,title,LENGTH(text) AS text_bytes FROM documents ORDER BY fetched_at DESC LIMIT 5").all():[];return{database:"exa.sqlite",schemaVersion:F4,tables:$,latestSearches:Z,latestDocuments:X}}function q2(){return O(T,{class:"flex-col w-full h-full bg-slate-50",get children(){return[O(T,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[O(T,{class:"flex-row items-center gap-4",get children(){return[O(x,{class:"text-2xl text-white",children:"‹"}),O(T,{class:"flex-col",get children(){return[O(x,{class:"text-sm text-indigo-300 tracking-wide",children:"POCKET APP"}),O(x,{class:"text-2xl text-white font-bold",children:"Exa Research"})]}})]}}),O(T,{class:"px-3 py-2 bg-indigo-900",get children(){return O(x,{class:"text-sm text-indigo-200",children:"SQLITE HISTORY"})}})]}}),O(T,{class:"p-6 flex-col gap-3",get children(){return[O(x,{class:"text-sm text-indigo-700 font-bold",children:"AGENT RESEARCH MEMORY"}),O(x,{class:"text-2xl text-slate-950 font-bold",children:"Search history"}),O(x,{class:"text-base text-slate-600",children:"Every research.search call is saved here automatically."})]}}),O(T,{class:"grow px-6 pt-4 flex-col gap-3",get children(){return[O(T4,{get when(){return K4().length===0},get children(){return O(T,{class:"h-[430] px-12 flex-col items-center justify-center bg-white",get children(){return[O(T,{class:"w-[88] h-[88] items-center justify-center bg-indigo-100",get children(){return O(x,{class:"text-2xl text-indigo-700 font-bold",children:"E"})}}),O(x,{class:"pt-7 text-xl text-slate-900 font-bold",children:"No searches yet"}),O(x,{class:"pt-4 text-base text-slate-500",children:`Ask Pi Agent to research a topic. -The search and its results will appear here.`})]}})}}),O(g4,{get each(){return K4()},children:(J)=>O(T,{class:"h-[118] px-5 flex-row items-center justify-between bg-white",get children(){return[O(T,{class:"w-[500] flex-col gap-2",get children(){return[O(x,{class:"text-base text-slate-900 font-bold",get children(){return J.query.slice(0,72)}}),O(x,{class:"text-sm text-slate-500",get children(){return(J.top_title||J.error||"No result title").slice(0,92)}}),O(x,{class:"text-sm text-indigo-600 font-bold",get children(){return W2(J.searched_at)}})]}}),O(T,{get["class"](){return J.status==="ok"?"px-3 py-2 bg-emerald-100":"px-3 py-2 bg-red-100"},get children(){return O(x,{get["class"](){return J.status==="ok"?"text-sm text-emerald-700":"text-sm text-red-500"},get children(){return a6(()=>J.status==="ok")()?J.result_count+" RESULTS":"FAILED"}})}})]}})})]}}),O(T,{class:"h-[96] px-6 flex-row items-center bg-slate-950",get children(){return O(x,{class:"text-sm text-slate-300",get children(){return Z2()}})}})]}})}M4(0),r8(()=>O(q2,{})),globalThis.PocketPiApp={tick(){return""},update(){return""},dataChanged(J){let Q=X2(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),X0):X0;return M4($),""},invokeTool(J){try{let Q=J==="research.storage_status"?Y2():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Unknown Exa task: "+J,isError:!0})},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});return""}}})(); + `).all();E0($),N0($[0]?.status==="error"?String($[0].error||"EXA SEARCH FAILED").slice(0,80):$.length?"SEARCH HISTORY UPDATED FROM SQLITE":"SEARCH HISTORY IS LOCAL"),X0=J}catch{E0([]),N0("SEARCH HISTORY IS LOCAL")}}function q2(){let J=s.query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").all(),Q=new Set(J.map((L)=>L.name)),$=(L)=>Q.has(L)?Number(s.query(`SELECT COUNT(*) AS count FROM ${L}`).get()?.count??0):0,Z=Number(s.query("PRAGMA page_size").get()?.page_size??0),X=Number(s.query("PRAGMA page_count").get()?.page_count??0),W=Number(s.query("PRAGMA freelist_count").get()?.freelist_count??0),q=Number(s.query("PRAGMA user_version").get()?.user_version??0),G=Q.has("searches")?s.query(` + SELECT id,searched_at,status,result_count,error + FROM searches ORDER BY id DESC LIMIT 1 + `).get():null,M={searches:$("searches"),searchResults:$("search_results"),documents:$("documents")},U={database:"exa.sqlite",schemaVersion:q,expectedSchemaVersion:T0,retentionDays:K4,tableCounts:M,allocatedBytes:Z*X,reusableBytes:Z*W,latestSearch:G},V=G,H=V?` Latest #${V.id??"?"}: ${V.status??"unknown"}, ${V.result_count??0} results.`:" No searches yet.";return{text:`Exa storage (schema ${q}/${T0}): ${M.searches} searches, ${M.searchResults} results, ${M.documents} documents; ${K4}-day retention; ${U.allocatedBytes} bytes allocated (${U.reusableBytes} reusable).${H}`,details:U}}function z2(){return O(T,{class:"flex-col w-full h-full bg-slate-50",get children(){return[O(T,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[O(T,{class:"flex-row items-center gap-4",get children(){return[O(x,{class:"text-2xl text-white",children:"‹"}),O(T,{class:"flex-col",get children(){return[O(x,{class:"text-sm text-indigo-300 tracking-wide",children:"POCKET APP"}),O(x,{class:"text-2xl text-white font-bold",children:"Exa Research"})]}})]}}),O(T,{class:"px-3 py-2 bg-indigo-900",get children(){return O(x,{class:"text-sm text-indigo-200",children:"SQLITE HISTORY"})}})]}}),O(T,{class:"p-6 flex-col gap-3",get children(){return[O(x,{class:"text-sm text-indigo-700 font-bold",children:"AGENT RESEARCH MEMORY"}),O(x,{class:"text-2xl text-slate-950 font-bold",children:"Search history"}),O(x,{class:"text-base text-slate-600",children:"Every research.search call is saved here automatically."})]}}),O(T,{class:"grow px-6 pt-4 flex-col gap-3",get children(){return[O(E4,{get when(){return M4().length===0},get children(){return O(T,{class:"h-[430] px-12 flex-col items-center justify-center bg-white",get children(){return[O(T,{class:"w-[88] h-[88] items-center justify-center bg-indigo-100",get children(){return O(x,{class:"text-2xl text-indigo-700 font-bold",children:"E"})}}),O(x,{class:"pt-7 text-xl text-slate-900 font-bold",children:"No searches yet"}),O(x,{class:"pt-4 text-base text-slate-500",children:`Ask Pi Agent to research a topic. +The search and its results will appear here.`})]}})}}),O(T4,{get each(){return M4()},children:(J)=>O(T,{class:"h-[118] px-5 flex-row items-center justify-between bg-white",get children(){return[O(T,{class:"w-[500] flex-col gap-2",get children(){return[O(x,{class:"text-base text-slate-900 font-bold",get children(){return J.query.slice(0,72)}}),O(x,{class:"text-sm text-slate-500",get children(){return(J.top_title||J.error||"No result title").slice(0,92)}}),O(x,{class:"text-sm text-indigo-600 font-bold",get children(){return Y2(J.searched_at)}})]}}),O(T,{get["class"](){return J.status==="ok"?"px-3 py-2 bg-emerald-100":"px-3 py-2 bg-red-100"},get children(){return O(x,{get["class"](){return J.status==="ok"?"text-sm text-emerald-700":"text-sm text-red-500"},get children(){return r6(()=>J.status==="ok")()?J.result_count+" RESULTS":"FAILED"}})}})]}})})]}}),O(T,{class:"h-[96] px-6 flex-row items-center bg-slate-950",get children(){return O(x,{class:"text-sm text-slate-300",get children(){return X2()}})}})]}})}U4(0),o8(()=>O(z2,{})),globalThis.PocketPiApp={tick(){return""},update(){return""},dataChanged(J){let Q=W2(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),X0):X0;return U4($),""},invokeTool(J){try{let Q=J==="research.storage_status"?q2():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:Q.text,details:Q.details,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Unknown Exa task: "+J,isError:!0})},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});return""}}})(); diff --git a/apps/exa/dist/data-action.js b/apps/exa/dist/data-action.js index 2b015d5..75487cf 100644 --- a/apps/exa/dist/data-action.js +++ b/apps/exa/dist/data-action.js @@ -1,5 +1,8 @@ -(()=>{var O=["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"];var d=65536,F=131072,J=262144,$=32,j=8192,V=30000,z=120000;var l={unavailable:"unavailable",invalidRequest:"invalid_request",busy:"busy",dns:"dns",connect:"connect",tls:"tls",timeout:"timeout",redirect:"redirect",responseTooLarge:"response_too_large",protocol:"protocol",cancelled:"cancelled",other:"other"};var b={};for(let r=0;r<64;r++)b["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[r]]=r;function X(r){let n=0;for(let t=0;t65535)t++;n+=a<128?1:a<2048?2:a<65536?3:4}let c=new Uint8Array(n),h=0;for(let t=0;t65535)t++;else if(a>=55296&&a<=57343)a=65533;if(a<128)c[h++]=a;else if(a<2048)c[h++]=192|a>>6,c[h++]=128|a&63;else if(a<65536)c[h++]=224|a>>12,c[h++]=128|a>>6&63,c[h++]=128|a&63;else c[h++]=240|a>>18,c[h++]=128|a>>12&63,c[h++]=128|a>>6&63,c[h++]=128|a&63}return c}function Q(r){let n="",c=0;while(cr.length)throw Error("invalid UTF-8");for(let i=0;i1114111||t>=55296&&t<=57343||a===1&&t<128||a===2&&t<2048||a===3&&t<65536)throw Error("invalid UTF-8");if(t<65536)n+=String.fromCharCode(t);else t-=65536,n+=String.fromCharCode(55296+(t>>10),56320+(t&1023))}return n}var W=new Set;function Z(r){return W.add(r),()=>W.delete(r)}class f extends Error{constructor(r,n){super(n);this.name="NetError",this.code=r}}class H{constructor(r,n,c,h){this.status=r,this.url=n,this.headers=Object.freeze({...c}),this.ok=r>=200&&r<300,this.data=new Uint8Array(h)}get byteLength(){return this.data.byteLength}async bytes(){return this.data.slice()}async arrayBuffer(){return this.data.slice().buffer}async text(){try{return Q(this.data)}catch{throw Error("net: response is not valid UTF-8")}}async json(){return JSON.parse(await this.text())}}var T=new Map,w=null,A=null;function R(){let r=globalThis.net;if(!r||typeof r!=="object")return null;let n=r;return typeof n.start==="function"&&typeof n.take==="function"&&typeof n.cancel==="function"&&typeof n.poll==="function"&&typeof n.lastError==="function"?n:null}function M(r){let n=String(r);for(let c of Object.values(l))if(c===n)return c;return l.other}function o(r){let n=T.get(r.h);if(!n)return;if(T.delete(r.h),r.t==="error")n.reject(new f(M(r.code),String(r.message||r.code)));else if(!Number.isInteger(r.status)||r.status<100||r.status>599||typeof r.url!=="string"||typeof r.headers!=="object"||r.headers===null||!Number.isInteger(r.bytes)||r.bytes<0||r.bytes>J)n.ops.cancel(r.h),n.reject(new f(l.protocol,"net: malformed done event"));else{let c=new ArrayBuffer(r.bytes);if(n.ops.take(r.h,c)!==r.bytes)n.ops.cancel(r.h),n.reject(new f(l.protocol,"net: response body transfer failed"));else n.resolve(new H(r.status,r.url,r.headers,c))}if(T.size===0&&w)w(),w=null,A=null}function k(){if(T.size===0)return;let r=A;if(!r)return;let n=r.poll();if(n!==void 0){let c=null;try{c=JSON.parse(n)}catch{}if(!Array.isArray(c))for(let[h,t]of T)r.cancel(h),T.delete(h),t.reject(new f(l.protocol,"net: malformed event batch"));else for(let h of c){if(!h||typeof h!=="object")continue;let t=h;if(!Number.isInteger(t.h)||t.t!=="done"&&t.t!=="error")continue;o(t)}}if(T.size===0&&w)w(),w=null,A=null}function U(r,n){return Promise.reject(new f(r,n))}function Y(r,n,c,h){if(!Number.isInteger(r)||rc)throw new f(l.invalidRequest,`net: ${h} must be ${n}..${c}`);return r}function p(r){let n=Object.create(null),c=0,h=0;for(let t of Object.keys(r??{})){let a=t.toLowerCase(),i=String(r[t]);if(!/^[!#$%&'*+.^_`|~0-9a-z-]+$/.test(a)||/[\r\n]/.test(i))throw new f(l.invalidRequest,`net: invalid header ${t}`);if(c++,h+=X(a).byteLength+X(i).byteLength+4,c>$||h>j)throw new f(l.invalidRequest,"net: request headers exceed limits");n[a]=i}return n}function v(r){if(r===void 0)return new Uint8Array(0);if(typeof r==="string")return X(r);if(r instanceof Uint8Array)return r.slice();if(r instanceof ArrayBuffer)return new Uint8Array(r.slice(0));throw new f(l.invalidRequest,"net: body must be string or bytes")}function B(r,n={}){let c=R();if(!c)return U(l.unavailable,"net: host did not mount the net module");try{if(typeof r!=="string"||!/^https?:\/\/[^\s/]+(?:\/|$)/.test(r))throw new f(l.invalidRequest,"net: url must be absolute http:// or https://");let h=n.method??"GET";if(!O.includes(h))throw new f(l.invalidRequest,`net: unsupported method ${String(h)}`);let t=v(n.body);if((h==="GET"||h==="HEAD")&&t.byteLength>0)throw new f(l.invalidRequest,`net: ${h} cannot have a body`);if(t.byteLength>d)throw new f(l.invalidRequest,"net: request body exceeds 64 KiB");let a=Y(n.timeoutMs??V,1,z,"timeoutMs"),i=Y(n.maxBytes??F,1,J,"maxBytes"),x=JSON.stringify({url:r,method:h,headers:p(n.headers),timeoutMs:a,maxBytes:i});if(A&&A!==c)throw new f(l.unavailable,"net: mounted host changed while requests are pending");let s=c.start(x,t.buffer);if(!Number.isInteger(s)||s<0){let L=c.lastError()||"unavailable: request refused",I=L.indexOf(":"),E=M(I<0?l.other:L.slice(0,I)),_=I<0?L:L.slice(I+1).trim();return U(E,_)}return new Promise((L,I)=>{if(T.set(s,{ops:c,resolve:L,reject:I}),A=c,!w)w=Z(k)})}catch(h){return h instanceof f?Promise.reject(h):U(l.invalidRequest,String(h))}}var G=globalThis.db,g=G.open("exa");if(g<0)throw Error("open exa.sqlite");var rr=3;function nr(){return String(G.lastError(g)||"SQLite operation failed")}function S(r){if(G.exec(g,r)!==0)throw Error(nr())}function N(r,n=[]){let c=JSON.parse(G.query(g,r,JSON.stringify(n)));if(c.error)throw Error(String(c.error));return c}function q(r,n=[]){return N(r,n)}var hr=N("PRAGMA user_version");if(Number(hr?.user_version??0)!==rr)S(` - CREATE TABLE IF NOT EXISTS searches ( +(()=>{var k=["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"];var F=65536,K=131072,g=262144,W=32,$=8192,E=30000,j=120000;var f={unavailable:"unavailable",invalidRequest:"invalid_request",busy:"busy",dns:"dns",connect:"connect",tls:"tls",timeout:"timeout",redirect:"redirect",responseTooLarge:"response_too_large",protocol:"protocol",cancelled:"cancelled",other:"other"};var b={};for(let r=0;r<64;r++)b["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[r]]=r;function q(r){let n=0;for(let t=0;t65535)t++;n+=a<128?1:a<2048?2:a<65536?3:4}let c=new Uint8Array(n),h=0;for(let t=0;t65535)t++;else if(a>=55296&&a<=57343)a=65533;if(a<128)c[h++]=a;else if(a<2048)c[h++]=192|a>>6,c[h++]=128|a&63;else if(a<65536)c[h++]=224|a>>12,c[h++]=128|a>>6&63,c[h++]=128|a&63;else c[h++]=240|a>>18,c[h++]=128|a>>12&63,c[h++]=128|a>>6&63,c[h++]=128|a&63}return c}function H(r){let n="",c=0;while(cr.length)throw Error("invalid UTF-8");for(let i=0;i1114111||t>=55296&&t<=57343||a===1&&t<128||a===2&&t<2048||a===3&&t<65536)throw Error("invalid UTF-8");if(t<65536)n+=String.fromCharCode(t);else t-=65536,n+=String.fromCharCode(55296+(t>>10),56320+(t&1023))}return n}var M=new Set;function V(r){return M.add(r),()=>M.delete(r)}class l extends Error{constructor(r,n){super(n);this.name="NetError",this.code=r}}class Q{constructor(r,n,c,h){this.status=r,this.url=n,this.headers=Object.freeze({...c}),this.ok=r>=200&&r<300,this.data=new Uint8Array(h)}get byteLength(){return this.data.byteLength}async bytes(){return this.data.slice()}async arrayBuffer(){return this.data.slice().buffer}async text(){try{return H(this.data)}catch{throw Error("net: response is not valid UTF-8")}}async json(){return JSON.parse(await this.text())}}var I=new Map,w=null,D=null;function o(){let r=globalThis.net;if(!r||typeof r!=="object")return null;let n=r;return typeof n.start==="function"&&typeof n.take==="function"&&typeof n.cancel==="function"&&typeof n.poll==="function"&&typeof n.lastError==="function"?n:null}function Z(r){let n=String(r);for(let c of Object.values(f))if(c===n)return c;return f.other}function p(r){let n=I.get(r.h);if(!n)return;if(I.delete(r.h),r.t==="error")n.reject(new l(Z(r.code),String(r.message||r.code)));else if(!Number.isInteger(r.status)||r.status<100||r.status>599||typeof r.url!=="string"||typeof r.headers!=="object"||r.headers===null||!Number.isInteger(r.bytes)||r.bytes<0||r.bytes>g)n.ops.cancel(r.h),n.reject(new l(f.protocol,"net: malformed done event"));else{let c=new ArrayBuffer(r.bytes);if(n.ops.take(r.h,c)!==r.bytes)n.ops.cancel(r.h),n.reject(new l(f.protocol,"net: response body transfer failed"));else n.resolve(new Q(r.status,r.url,r.headers,c))}if(I.size===0&&w)w(),w=null,D=null}function O(){if(I.size===0)return;let r=D;if(!r)return;let n=r.poll();if(n!==void 0){let c=null;try{c=JSON.parse(n)}catch{}if(!Array.isArray(c))for(let[h,t]of I)r.cancel(h),I.delete(h),t.reject(new l(f.protocol,"net: malformed event batch"));else for(let h of c){if(!h||typeof h!=="object")continue;let t=h;if(!Number.isInteger(t.h)||t.t!=="done"&&t.t!=="error")continue;p(t)}}if(I.size===0&&w)w(),w=null,D=null}function J(r,n){return Promise.reject(new l(r,n))}function z(r,n,c,h){if(!Number.isInteger(r)||rc)throw new l(f.invalidRequest,`net: ${h} must be ${n}..${c}`);return r}function v(r){let n=Object.create(null),c=0,h=0;for(let t of Object.keys(r??{})){let a=t.toLowerCase(),i=String(r[t]);if(!/^[!#$%&'*+.^_`|~0-9a-z-]+$/.test(a)||/[\r\n]/.test(i))throw new l(f.invalidRequest,`net: invalid header ${t}`);if(c++,h+=q(a).byteLength+q(i).byteLength+4,c>W||h>$)throw new l(f.invalidRequest,"net: request headers exceed limits");n[a]=i}return n}function rr(r){if(r===void 0)return new Uint8Array(0);if(typeof r==="string")return q(r);if(r instanceof Uint8Array)return r.slice();if(r instanceof ArrayBuffer)return new Uint8Array(r.slice(0));throw new l(f.invalidRequest,"net: body must be string or bytes")}function Y(r,n={}){let c=o();if(!c)return J(f.unavailable,"net: host did not mount the net module");try{if(typeof r!=="string"||!/^https?:\/\/[^\s/]+(?:\/|$)/.test(r))throw new l(f.invalidRequest,"net: url must be absolute http:// or https://");let h=n.method??"GET";if(!k.includes(h))throw new l(f.invalidRequest,`net: unsupported method ${String(h)}`);let t=rr(n.body);if((h==="GET"||h==="HEAD")&&t.byteLength>0)throw new l(f.invalidRequest,`net: ${h} cannot have a body`);if(t.byteLength>F)throw new l(f.invalidRequest,"net: request body exceeds 64 KiB");let a=z(n.timeoutMs??E,1,j,"timeoutMs"),i=z(n.maxBytes??K,1,g,"maxBytes"),x=JSON.stringify({url:r,method:h,headers:v(n.headers),timeoutMs:a,maxBytes:i});if(D&&D!==c)throw new l(f.unavailable,"net: mounted host changed while requests are pending");let s=c.start(x,t.buffer);if(!Number.isInteger(s)||s<0){let T=c.lastError()||"unavailable: request refused",L=T.indexOf(":"),R=Z(L<0?f.other:T.slice(0,L)),_=L<0?T:T.slice(L+1).trim();return J(R,_)}return new Promise((T,L)=>{if(I.set(s,{ops:c,resolve:T,reject:L}),D=c,!w)w=V(O)})}catch(h){return h instanceof l?Promise.reject(h):J(f.invalidRequest,String(h))}}var X=globalThis.db,G=X.open("exa");if(G<0)throw Error("open exa.sqlite");var nr=4,cr=7,hr=cr*24*60*60;function tr(){return String(X.lastError(G)||"SQLite operation failed")}function S(r){if(X.exec(G,r)!==0)throw Error(tr())}function P(r,n=[]){let c=JSON.parse(X.query(G,r,JSON.stringify(n)));if(c.error)throw Error(String(c.error));return c}function A(r,n=[]){return P(r,n)}var ar=P("PRAGMA user_version");if(Number(ar?.user_version??0)!==nr)S(` + DROP TABLE IF EXISTS search_results; + DROP TABLE IF EXISTS searches; + DROP TABLE IF EXISTS documents; + CREATE TABLE searches ( id INTEGER PRIMARY KEY AUTOINCREMENT, query TEXT NOT NULL, searched_at INTEGER NOT NULL, @@ -7,8 +10,8 @@ result_count INTEGER NOT NULL DEFAULT 0, error TEXT ); - CREATE INDEX IF NOT EXISTS searches_recent ON searches(id DESC); - CREATE TABLE IF NOT EXISTS search_results ( + CREATE INDEX searches_retention ON searches(searched_at); + CREATE TABLE search_results ( search_id INTEGER NOT NULL, rank INTEGER NOT NULL, title TEXT, @@ -19,8 +22,7 @@ highlight TEXT, PRIMARY KEY(search_id, rank) ); - CREATE INDEX IF NOT EXISTS search_results_url ON search_results(url); - CREATE TABLE IF NOT EXISTS documents ( + CREATE TABLE documents ( url TEXT PRIMARY KEY, fetched_at INTEGER NOT NULL, title TEXT, @@ -28,10 +30,10 @@ author TEXT, text TEXT NOT NULL ); - CREATE INDEX IF NOT EXISTS documents_recent ON documents(fetched_at DESC); - PRAGMA user_version=3; - `);function y(){return Math.floor(Date.now()/1000)}function cr(r){return r===null||r===void 0||typeof r==="object"?null:String(r)}function u(r,n){if(!r||typeof r!=="object")return null;for(let c of n){let h=cr(r[c]);if(h!==null)return h}return null}function tr(r){if(Array.isArray(r?.highlights))return r.highlights.map(String).join(` -`).slice(0,1200);return u(r,["highlight","summary","text"])?.slice(0,1200)??null}async function e(r,n){let c=await B(`https://api.exa.ai${r}`,{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify(n),timeoutMs:12000,maxBytes:98304}),h=await c.json();if(!c.ok)throw Error(`Exa HTTP ${c.status}: ${JSON.stringify(h)}`);return h}function K(r){S("BEGIN IMMEDIATE");try{r(),S("COMMIT")}catch(n){try{S("ROLLBACK")}catch{}throw n}globalThis.app.commit()}async function ar(r){let n=String(r.query??"").trim();if(!n)throw Error("query is required");let c=y();try{let h={query:n,type:r.searchType??"auto",numResults:Math.max(1,Math.min(8,Number(r.numResults??5))),contents:{highlights:{maxCharacters:800}}};for(let i of["includeDomains","excludeDomains","startPublishedDate","endPublishedDate"])if(r[i]!==void 0)h[i]=r[i];let t=await e("/search",h),a=Array.isArray(t?.results)?t.results.slice(0,8):[];return K(()=>{let i=q("INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,?,NULL)",[n,c,"ok",a.length]),x=Number(i.lastInsertRowid||0);a.forEach((s,L)=>{let I=u(s,["url","id"]);if(!I)return;q(`INSERT INTO search_results(search_id,rank,title,url,published_at,author,score,highlight) - VALUES(?,?,?,?,?,?,?,?)`,[x,L,u(s,["title"]),I,u(s,["publishedDate","published_at","date"]),u(s,["author"]),u(s,["score"]),tr(s)])})}),t}catch(h){let t=h instanceof Error?h.message:String(h);throw K(()=>q("INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,0,?)",[n,c,"error",t])),h}}async function lr(r){let n=String(r.url??"").trim();if(!n)throw Error("url is required");let c=await e("/contents",{urls:[n],text:{maxCharacters:Math.max(200,Math.min(12000,Number(r.maxCharacters??6000))),includeHtmlTags:!1}}),h=Array.isArray(c?.results)?c.results[0]:c;if(!h)throw Error("Exa returned no document");let t=u(h,["url","id"])||n,a=u(h,["text","content","summary"])||"";return K(()=>q(`INSERT INTO documents(url,fetched_at,title,published_at,author,text) VALUES(?,?,?,?,?,?) - ON CONFLICT(url) DO UPDATE SET fetched_at=excluded.fetched_at,title=excluded.title, - published_at=excluded.published_at,author=excluded.author,text=excluded.text`,[t,y(),u(h,["title"]),u(h,["publishedDate","published_at","date"]),u(h,["author"]),a])),{status:"ok",provider:"exa",requestId:c?.requestId,document:h,costDollars:c?.costDollars}}var C,D=!1;function m(r){return JSON.stringify({text:r instanceof Error?r.message:String(r),isError:!0})}function P(r){if(D)throw Error("Exa Data Action is already running");D=!0,C=void 0,r().then((n)=>{C=JSON.stringify({text:JSON.stringify(n),details:n,isError:!1}),D=!1},(n)=>{C=m(n),D=!1})}globalThis.PocketPiData={beginInvokeTask(r){P(async()=>{throw Error("Unknown Exa Data Action: "+r)})},beginInvokeTool(r,n){try{let c=JSON.parse(n);P(()=>r==="research.search"?ar(c):r==="research.fetch"?lr(c):Promise.reject(Error("Unknown Exa tool: "+r)))}catch(c){C=m(c),D=!1}},tick(){k()},pollResult(){let r=C;return C=void 0,r}};})(); + CREATE INDEX documents_recent ON documents(fetched_at DESC); + PRAGMA user_version=4; + `);function y(){return Math.floor(Date.now()/1000)}function U(r){let n=r-hr;A("DELETE FROM search_results WHERE search_id IN (SELECT id FROM searches WHERE searched_at < ?)",[n]),A("DELETE FROM searches WHERE searched_at < ?",[n]),A("DELETE FROM documents WHERE fetched_at < ?",[n])}function fr(r){return r===null||r===void 0||typeof r==="object"?null:String(r)}function u(r,n){if(!r||typeof r!=="object")return null;for(let c of n){let h=fr(r[c]);if(h!==null)return h}return null}function ir(r){if(Array.isArray(r?.highlights))return r.highlights.map(String).join(` +`).slice(0,1200);return u(r,["highlight","summary","text"])?.slice(0,1200)??null}async function N(r,n){let c=await Y(`https://api.exa.ai${r}`,{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify(n),timeoutMs:12000,maxBytes:98304}),h=await c.json();if(!c.ok)throw Error(`Exa HTTP ${c.status}: ${JSON.stringify(h)}`);return h}function e(r){S("BEGIN IMMEDIATE");try{r(),S("COMMIT")}catch(n){try{S("ROLLBACK")}catch{}throw n}globalThis.app.commit()}async function lr(r){let n=String(r.query??"").trim();if(!n)throw Error("query is required");let c=y();try{let h={query:n,type:r.searchType??"auto",numResults:Math.max(1,Math.min(8,Number(r.numResults??5))),contents:{highlights:{maxCharacters:800}}};for(let i of["includeDomains","excludeDomains","startPublishedDate","endPublishedDate"])if(r[i]!==void 0)h[i]=r[i];let t=await N("/search",h),a=Array.isArray(t?.results)?t.results.slice(0,8):[];return e(()=>{let i=A("INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,?,NULL)",[n,c,"ok",a.length]),x=Number(i.lastInsertRowid||0);a.forEach((s,T)=>{let L=u(s,["url","id"]);if(!L)return;A(`INSERT INTO search_results(search_id,rank,title,url,published_at,author,score,highlight) + VALUES(?,?,?,?,?,?,?,?)`,[x,T,u(s,["title"]),L,u(s,["publishedDate","published_at","date"]),u(s,["author"]),u(s,["score"]),ir(s)])}),U(c)}),t}catch(h){let t=h instanceof Error?h.message:String(h);throw e(()=>{A("INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,0,?)",[n,c,"error",t]),U(c)}),h}}async function ur(r){let n=String(r.url??"").trim();if(!n)throw Error("url is required");let c=await N("/contents",{urls:[n],text:{maxCharacters:Math.max(200,Math.min(12000,Number(r.maxCharacters??6000))),includeHtmlTags:!1}}),h=Array.isArray(c?.results)?c.results[0]:c;if(!h)throw Error("Exa returned no document");let t=u(h,["url","id"])||n,a=u(h,["text","content","summary"])||"",i=y();return e(()=>{A(`INSERT INTO documents(url,fetched_at,title,published_at,author,text) VALUES(?,?,?,?,?,?) + ON CONFLICT(url) DO UPDATE SET fetched_at=excluded.fetched_at,title=excluded.title, + published_at=excluded.published_at,author=excluded.author,text=excluded.text`,[t,i,u(h,["title"]),u(h,["publishedDate","published_at","date"]),u(h,["author"]),a]),U(i)}),{status:"ok",provider:"exa",requestId:c?.requestId,document:h,costDollars:c?.costDollars}}var C,d=!1;function m(r){return JSON.stringify({text:r instanceof Error?r.message:String(r),isError:!0})}function B(r){if(d)throw Error("Exa Data Action is already running");d=!0,C=void 0,r().then((n)=>{C=JSON.stringify({text:JSON.stringify(n),details:n,isError:!1}),d=!1},(n)=>{C=m(n),d=!1})}globalThis.PocketPiData={beginInvokeTask(r){B(async()=>{throw Error("Unknown Exa Data Action: "+r)})},beginInvokeTool(r,n){try{let c=JSON.parse(n);B(()=>r==="research.search"?lr(c):r==="research.fetch"?ur(c):Promise.reject(Error("Unknown Exa tool: "+r)))}catch(c){C=m(c),d=!1}},tick(){O()},pollResult(){let r=C;return C=void 0,r}};})(); diff --git a/docs/agentos-architecture.md b/docs/agentos-architecture.md index 7ac0511..6fce286 100644 --- a/docs/agentos-architecture.md +++ b/docs/agentos-architecture.md @@ -1007,12 +1007,31 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 `searches=1`、`search_results=0`、`documents=0`; `robinhood.storage_status` 返回 9 张新 domain tables,其中 `refresh_runs=1`、 其余业务表为 0。旧 `tool_events/search_history/raw JSON` 表均不存在。 +22. Exa 只保存有上限的规范化字段,不保存 provider 原始 JSON:每次 search 最多 + 8 条结果、highlight 最多 1200 字符,document text 最多 12000 字符。每个 + search/fetch 写事务同时删除 7 天前的 searches、对应 search_results 和 + documents;SQLite freelist 页面留作后续写入复用,不在闪存上自动执行 + `VACUUM`。`research.storage_status` 只返回行数、allocated/reusable bytes、 + retention policy 和最近一次运行状态,不再把完整 schema 或多行内容送入模型。 + 该策略直接 bump `dataVersion`/schema v4 并一次性重建 Exa cache,不保留旧索引 + 或兼容迁移分支。 +23. 正式 `pocket-net` 路径已在实体 ESP32-P4 上完成 Exa provider success:一次 + `research.search` 完成后 storage counts 为 `searches=4`、`search_results=13`、 + `documents=2`,其中新增 search 为 `ok` 且有 3 条结果。紧凑版 + `research.storage_status` 的实机 + Agent 回复为 114 字符,报告 4/13/2、7-day retention 和 57344/0 bytes;继续 + 观察 30 秒没有 watchdog。最终 schema v4 镜像又确认旧 cache 被一次性 reset, + compact status 先为 0/0/0;随后同一镜像的 provider search 持久化成功,重启后 + status 为 schema 4/4、1 search、3 results、0 documents、latest `ok`/3,继续 + 观察 30 秒仍无 watchdog。 +24. UART bridge 现在默认复用 Keychain 中已有的 Robinhood OAuth session,并只把 + access token 注入板子的 RAM-only boot config;`--provision-robinhood` 只在没有 + saved authorization 时交互补录。未传该 flag 的实机 `get_accounts` 已完成 MCP + initialize 与 provider HTTP 200,收到 7222-byte body,不再出现 + `OAuth token not provided`。 ### 22.2 待补齐,不能视为已实现 -- 正式 `pocket-net` 路径已通过 Simulator E2E 与 ESP32-P4 release cross-build; - 尚未刷板验证一次新的 Exa provider success,因此不能把旧同步 service 路径的 - 实机证据沿用为新 NET adapter 的实体板证据。 - Root Files 已有只读文件阅读器;conversation/message/run/tool call 还没有落入 `data/agent.sqlite`。 - release 已有 descriptor/`pocket.json` 校验和 atomic `current` 写入,但由 @@ -1026,16 +1045,15 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 LRU/residency policy,也不能把 App UI/数据逻辑写回 Rust。 - Robinhood OAuth grant 与 Exa key 都由 Mac Keychain 复用,并只在本次 UART boot config 中以内存态注入;credential 不进入 App DB、workspace 或 View。 - 上一个 schema 的物理板验证曾证明 Exa/Robinhood provider -> SQLite -> View - 链路可达;本节定义的新 normalized schema 已在实体板创建,并验证断网 terminal - rows 与 storage projection,但尚未取得一次新 schema 下的 provider success。 + 当前 normalized schema 已分别取得 Exa search 和 Robinhood get_accounts 的实机 + provider success。 `agent.robinhood.com` 从当前 AP 建连仍有波动,失败轮次会写 error batch,但不会 覆盖最后一次成功的 portfolio projection。 - 实机已验证后台 Agent turn,但“turn 运行中连续触摸切换 Robinhood/Exa 再返回” 仍需人工操作验收;自动 lifecycle/tool-routing test 已覆盖同一状态机路径。 - 通用 Data Action runner 已在当前实机验证 FreeRTOS pthread stack、断网 - failure transaction、SQLite dump 与 network fail-fast;真实 provider success、 - 持续触摸切换和成功/失败交替 retry 仍待验证。 + failure transaction、SQLite dump、network fail-fast 与 provider success;持续 + 触摸切换和成功/失败交替 retry 仍待验证。 - 当前修改型 App Tool 返回的是 queued run receipt,Data Action completion 记录在 App SQLite 和日志。若 Agent 需要同步获得 provider 的最终 ToolResult,应在后续 增加一个 bounded completion delivery contract;不能为此把网络调用搬回 View diff --git a/hosts/esp32-p4-sim/Cargo.toml b/hosts/esp32-p4-sim/Cargo.toml index e82470e..0c4f691 100644 --- a/hosts/esp32-p4-sim/Cargo.toml +++ b/hosts/esp32-p4-sim/Cargo.toml @@ -22,3 +22,6 @@ tempfile = "3" ureq = { version = "2.12", features = ["json"] } wgpu = "25" winit = "0.30" + +[dev-dependencies] +pocket-db.workspace = true diff --git a/hosts/esp32-p4-sim/src/main.rs b/hosts/esp32-p4-sim/src/main.rs index bdb0ed4..e2d43a6 100644 --- a/hosts/esp32-p4-sim/src/main.rs +++ b/hosts/esp32-p4-sim/src/main.rs @@ -846,33 +846,67 @@ mod tests { assert_eq!(result.details["status"], "queued"); wait_for(|| { let storage = supervisor.invoke_tool("research.storage_status", "{}"); - storage.details["latestSearches"] - .as_array() - .is_some_and(|rows| !rows.is_empty()) + storage.details["tableCounts"]["searches"] == 1 }); assert!(temp.path().join("apps/exa/data/exa.sqlite").exists()); let storage = supervisor.invoke_tool("research.storage_status", "{}"); assert!(!storage.is_error, "{}", storage.text); - let searches = storage.details["tables"] - .as_array() - .unwrap() - .iter() - .find(|table| table["name"] == "searches") - .unwrap(); - assert_eq!(searches["rowCount"], 1); - let results = storage.details["tables"] - .as_array() - .unwrap() - .iter() - .find(|table| table["name"] == "search_results") - .unwrap(); - assert_eq!(results["rowCount"], 2); - assert!(storage.details["tables"] - .as_array() - .unwrap() - .iter() - .all(|table| table["name"] != "search_history")); - assert_eq!(storage.details["latestSearches"][0]["status"], "ok"); + assert_eq!(storage.details["tableCounts"]["searches"], 1); + assert_eq!(storage.details["tableCounts"]["searchResults"], 2); + assert_eq!(storage.details["tableCounts"]["documents"], 0); + assert_eq!(storage.details["retentionDays"], 7); + assert_eq!(storage.details["schemaVersion"], 4); + assert_eq!(storage.details["expectedSchemaVersion"], 4); + assert_eq!(storage.details["latestSearch"]["status"], "ok"); + assert!(storage.text.len() < 240, "{}", storage.text); + assert!(storage.details.get("tables").is_none()); + assert!(storage.details.get("latestSearches").is_none()); + } + + #[test] + fn exa_write_removes_rows_older_than_seven_days() { + init_logs(); + let temp = tempfile::tempdir().unwrap(); + let mut supervisor = + AppSupervisor::new(temp.path(), Arc::new(SimAppServices::default())).unwrap(); + let first = supervisor.invoke_tool("research.search", r#"{"query":"old search"}"#); + assert!(!first.is_error, "{}", first.text); + wait_for(|| { + supervisor + .invoke_tool("research.storage_status", "{}") + .details["tableCounts"]["searches"] + == 1 + }); + + let mut database = + pocket_db::DbModule::new(pocket_db::Storage::Dir(temp.path().join("apps/exa/data"))); + let handle = database.open("exa"); + assert!(handle >= 0); + assert_eq!( + database.exec( + handle, + "UPDATE searches SET searched_at=0;\ + INSERT INTO documents(url,fetched_at,title,published_at,author,text)\ + VALUES('https://expired.example',0,NULL,NULL,NULL,'expired');", + ), + 0, + "{}", + database.last_error(handle) + ); + database.close(handle); + + let second = supervisor.invoke_tool("research.search", r#"{"query":"new search"}"#); + assert!(!second.is_error, "{}", second.text); + wait_for(|| { + supervisor + .invoke_tool("research.storage_status", "{}") + .details["latestSearch"]["id"] + == 2 + }); + let storage = supervisor.invoke_tool("research.storage_status", "{}"); + assert_eq!(storage.details["tableCounts"]["searches"], 1); + assert_eq!(storage.details["tableCounts"]["searchResults"], 2); + assert_eq!(storage.details["tableCounts"]["documents"], 0); } #[test] @@ -888,7 +922,13 @@ mod tests { let exa = supervisor.invoke_tool("research.storage_status", "{}"); assert!(!exa.is_error, "{}", exa.text); - assert!(exa.details["tables"].as_array().unwrap().is_empty()); + assert_eq!(exa.details["tableCounts"]["searches"], 0); + assert_eq!(exa.details["tableCounts"]["searchResults"], 0); + assert_eq!(exa.details["tableCounts"]["documents"], 0); + assert_eq!(exa.details["retentionDays"], 7); + assert_eq!(exa.details["schemaVersion"], 0); + assert_eq!(exa.details["expectedSchemaVersion"], 4); + assert!(exa.details["latestSearch"].is_null()); } #[test] diff --git a/tools/uart-model-bridge.py b/tools/uart-model-bridge.py index 43b25b1..dcd51a4 100755 --- a/tools/uart-model-bridge.py +++ b/tools/uart-model-bridge.py @@ -128,11 +128,11 @@ def config(args: argparse.Namespace) -> dict[str, object]: } if args.model: value["model"] = args.model - wifi = saved_wifi() + wifi = None if args.provision_wifi else saved_wifi() if wifi: value["wifiSsid"], value["wifiPassword"] = wifi print(f"Wi-Fi: provisioning {wifi[0]} from Keychain", flush=True) - elif args.provision_wifi: + if args.provision_wifi: value["wifiSsid"] = input("Wi-Fi SSID: ").strip() value["wifiPassword"] = getpass.getpass("Wi-Fi password: ") if args.backend == "wireless": @@ -146,18 +146,17 @@ def config(args: argparse.Namespace) -> dict[str, object]: key = getpass.getpass("Exa API key: ") if key: value["exaApiKey"] = key - if args.provision_robinhood: - token = robinhood_access_token() + token = robinhood_access_token() + if token: + value["robinhoodAccessToken"] = token + print( + "Robinhood: reusing existing authorized Codex MCP session (RAM only)", + flush=True, + ) + elif args.provision_robinhood: + token = getpass.getpass("Robinhood OAuth access token: ") if token: value["robinhoodAccessToken"] = token - print( - "Robinhood: reusing existing authorized Codex MCP session (RAM only)", - flush=True, - ) - else: - token = getpass.getpass("Robinhood OAuth access token: ") - if token: - value["robinhoodAccessToken"] = token if args.prompt: value["initialPrompt"] = args.prompt if args.prompt_delay_seconds: From ca3335c7b64da34dfced2f56ed4c8978a9e2f5e1 Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Mon, 10 Aug 2026 12:15:55 +0800 Subject: [PATCH 05/24] feat(ui): add keyboard press feedback --- apps/pi-agent/app.tsx | 38 +++++++++++++---- apps/pi-agent/dist/app.js | 22 +++++----- apps/pi-agent/dist/app.pak | Bin 431376 -> 431632 bytes crates/pocket-pi-agentos/src/lib.rs | 58 ++++++++++++++++++++++++++ firmware/esp32-p4/src/agentos_main.rs | 5 +++ hosts/esp32-p4-sim/src/main.rs | 19 ++++++++- 6 files changed, 121 insertions(+), 21 deletions(-) diff --git a/apps/pi-agent/app.tsx b/apps/pi-agent/app.tsx index 4504605..262cd47 100644 --- a/apps/pi-agent/app.tsx +++ b/apps/pi-agent/app.tsx @@ -57,6 +57,7 @@ const [input, setInput] = createSignal(""); const [keyboardMode, setKeyboardMode] = createSignal<"letters" | "numbers">("letters"); const [uppercase, setUppercase] = createSignal(false); const [keyboardPurpose, setKeyboardPurpose] = createSignal({ type: "prompt" }); +const [pressedKey, setPressedKey] = createSignal(null); const [wifiOffset, setWifiOffset] = createSignal(0); const fileCache = new Map(); @@ -322,23 +323,23 @@ function KeyboardScreen() { {display() || (purpose().type === "wifi" ? "ENTER NETWORK PASSWORD..." : "TYPE YOUR MESSAGE...")} - {String(input().length) + " / " + (purpose().type === "wifi" ? "63" : "256") + " CHARACTERS"}CLEAR + {String(input().length) + " / " + (purpose().type === "wifi" ? "63" : "256") + " CHARACTERS"}CLEAR {(row, rowIndex) => ( {(key) => ( - {uppercase() ? key.toUpperCase() : key} + {uppercase() ? key.toUpperCase() : key} )} - DEL + DEL )} - {keyboardMode() === "letters" ? "123" : "ABC"} - SPACE - {keyboardMode() === "letters" ? "SHIFT" : ". ?"} - {purpose().type === "wifi" ? "JOIN" : "SEND"} + {keyboardMode() === "letters" ? "123" : "ABC"} + SPACE + {keyboardMode() === "letters" ? "SHIFT" : ". ?"} + {purpose().type === "wifi" ? "JOIN" : "SEND"} - CLOSE KEYBOARD + CLOSE KEYBOARD ); } @@ -419,6 +420,19 @@ function keyboardCharacterAt(x: number, y: number): string | null { return null; } +function keyboardButtonAt(x: number, y: number): string | null { + if (y >= 1164) return "close"; + if (x >= 548 && y >= 402 && y <= 482) return "clear"; + const character = keyboardCharacterAt(x, y); + if (character) return "char:" + character; + if (x >= 592 && y >= 768 && y <= 888) return "delete"; + if (y < 908 || y > 1064) return null; + if (x <= 116) return "mode"; + if (x <= 424) return "space"; + if (x <= 576) return "shift"; + return "submit"; +} + function handleKeyboardTap(x: number, y: number): string { if (y >= 1164) { setInput(""); @@ -485,6 +499,14 @@ queueMicrotask(() => refreshFiles("", true)); invokeTask() { return JSON.stringify({ text: "Pi Agent has no App tasks", isError: true }); }, + pointerDown(x: number, y: number) { + setPressedKey(screen() === "keyboard" ? keyboardButtonAt(x, y) : null); + return ""; + }, + pointerUp() { + setPressedKey(null); + return ""; + }, tap(x: number, y: number) { if (screen() === "keyboard") return handleKeyboardTap(x, y); if (screen() === "viewer") { diff --git a/apps/pi-agent/dist/app.js b/apps/pi-agent/dist/app.js index 607b582..1855bf2 100644 --- a/apps/pi-agent/dist/app.js +++ b/apps/pi-agent/dist/app.js @@ -1,16 +1,16 @@ -(()=>{var IJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return H1(this.context.count)},getNextContextId(){return H1(this.context.count++)}};function H1(J){let Q=String(J),$=Q.length-1;return IJ.context.id+($?String.fromCharCode(96+$):"")+Q}function B1(J){IJ.context=J}function Z6(){return{...IJ.context,id:IJ.getNextContextId(),count:0}}var q6=!1,X6=(J,Q)=>J===Q,k0=Symbol("solid-proxy"),Y6=typeof Proxy==="function",z6=Symbol("solid-track"),HQ=Symbol("solid-dev-component"),oJ={equals:X6},j1=null,W6=D1,m=1,yJ=2,K1={owned:null,cleanups:null,context:null,owner:null},S=null,K=null,TJ=null,AJ=null,b=null,w=null,y=null,nJ=0;function tJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?K1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>QJ(()=>$J(z)));S=z,b=null;try{return c(G,!0)}finally{b=$,S=Z}}function C(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return U1($,q)};return[M1.bind($),Z]}function JJ(J,Q,$){let Z=P1(J,Q,!1,m);if(TJ&&K&&K.running)w.push(Z);else eJ(Z)}function _J(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=P1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,TJ&&K&&K.running)Z.tState=m,w.push(Z);else eJ(Z);return M1.bind(Z)}function G6(J){return c(J,!1)}function QJ(J){if(!AJ&&b===null)return J();let Q=b;b=null;try{if(AJ)return AJ.untrack(J);return J()}finally{b=Q}}function S0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function H6(J){if(K&&K.running)return J(),K.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(TJ||B6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[BQ,F1]=C(!1),B6;function M1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)eJ(this);else{let Q=w;w=null,c(()=>J0(this),!1),w=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function U1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw w=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;$J(J);let Q=nJ;if(R1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{c(()=>{K&&(K.running=!0),b=S=J,R1(J,J.tValue,Q),b=S=null},!1)})}function R1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=m,J.tOwned&&J.tOwned.forEach($J),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach($J),J.owned=null;return J.updatedAt=$+1,g0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)U1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function P1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(S===null);else if(S!==K1)if(K&&K.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(AJ&&X.fn){let z=X.fn,[G,P]=C(void 0,{equals:!1}),D=AJ.factory(z,P);S0(()=>D.dispose());let V,B=()=>H6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),K&&K.running){if(!V)V=AJ.factory(z,B);return V.track(_)}return D.track(_)}}return X}function b0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===yJ)return J0(J);if(J.suspense&&QJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===m)eJ(J);else if((Q?J.tState:J.state)===yJ){let q=w;w=null,c(()=>J0(J,$[0]),!1),w=q}}}function c(J,Q){if(w)return J();let $=!1;if(!Q)w=[];if(y)$=!0;else y=[];nJ++;try{let Z=J();return j6($),Z}catch(Z){if(!$)y=null;w=null,g0(Z)}}function j6(J){if(w){if(TJ&&K&&K.running)K6(w);else D1(w);w=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;y.push.apply(y,K.effects),Q=K.resolve;for(let X of y)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,c(()=>{for(let X of q)$J(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zW6($),!1);if(Q)Q()}function D1(J){for(let Q=0;Q{Z.delete($),c(()=>{K.running=!0,b0($)},!1),K&&(K.running=!1)})}}function J0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)$J(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)L1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)$J(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function L1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return S0(()=>I1(X)),()=>{let P=J()||[],D=P.length,V,B;return P[z6],QJ(()=>{let N,h,a,GJ,VJ,M,j,H,L;if(D===0){if(z!==0)I1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[M6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=M&&H>=M&&Z[j]===P[H];j--,H--)a[H]=q[j],GJ[H]=X[j],G&&(VJ[H]=G[j]);N=new Map,h=Array(H+1);for(B=H;B>=M;B--)L=P[B],V=N.get(L),h[B]=V===void 0?-1:V,N.set(L,B);for(V=M;V<=j;V++)if(L=Z[V],B=N.get(L),B!==void 0&&B!==-1)a[B]=q[V],GJ[B]=X[V],G&&(VJ[B]=G[V]),B=h[B],N.set(L,B);else X[V]();for(B=M;BJ(Q||{}));return B1($),Z}}return QJ(()=>J(Q||{}))}function Q0(){return!0}var D6={get(J,Q,$){if(Q===k0)return $;return J.get(Q)},has(J,Q){if(Q===k0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function w0(J){return!(J=typeof J==="function"?J():J)?{}:J}function V6(){for(let J=0,Q=this.length;J=0;G--){let P=w0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in w0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:V6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var L6=(J)=>`Stale read from <${J}>.`;function kJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return _J(U6(()=>J.each,J.children,Q||void 0))}function SJ(J){let Q=J.keyed,$=_J(()=>J.when,void 0,void 0),Z=Q?$:_J($,void 0,{equals:(q,X)=>!q===!X});return _J(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?QJ(()=>X(Q?q:()=>{if(!QJ(Z))throw L6("Show");return $()})):X}return J.fallback},void 0,void 0)}var O6=(J)=>_J(()=>J());function I6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(M,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(M,j,L,H);JJ((A)=>B(M,j(),A,H),L)}function B(M,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=h(M,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(M),H=j);else h(M,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=h(M,H,L);else if(k==="function")return JJ(()=>{let O=j();while(typeof O==="function")O=O();H=B(M,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return JJ(()=>H=B(M,O,H,L,!0)),()=>H;if(O.length===0){let hJ=h(M,H,L);if(I)return H=hJ}else if(Array.isArray(H))if(H.length===0)a(M,O,L);else N(M,H,O);else if(H==null||H==="")a(M,O);else N(M,I&&H||[P(M)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(M,H,L,j);h(M,H,null,j)}else if(H==null||H===""||!P(M))q(M,j);else GJ(M,j,P(M));H=j}return H}function _(M,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let GQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let hJ=G(O)===M;if(!k&&!I)hJ?GJ(M,A,O):q(M,A,H);else hJ&&X(M,O)}else k=!0}}else q(M,A,H);return[A]}function a(M,j,H){for(let L=0,A=j.length;LH.children=B(M,j.children,H.children));return JJ(()=>j.ref&&j.ref(M)),JJ(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(M,A,k,H[A]),H[A]=k}}),H}return{render(M,j){let H;return tJ((L)=>{H=L,V(j,M())}),H},insert:V,spread(M,j,H){if(typeof j==="function")JJ((L)=>VJ(M,j(),L,H));else VJ(M,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(M,j,H,L){return z(M,j,H,L),H},mergeProps:A1,effect:JJ,memo:O6,createComponent:P6,use(M,j,H){return QJ(()=>M(j,H))}}}function A6(J){let Q=I6(J);return Q.mergeProps=A1,Q}var _1=480,k1=272,HJ={view:0,text:1,image:2},_6=1,k6=-1,S6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},b6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},g6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},w6=1,jQ=2,KQ=1,FQ=2,MQ=131072,UQ=1,RQ=262144,PQ=1,DQ=1,VQ=1,LQ=2,OQ=4,IQ=8,AQ=16,_Q=1,kQ=2;function S1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var SQ=1,C6=1263551300,E6=1,N6=32,h6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},BJ=32896,bQ=0.016666666666666666;function b1(J){return J.__viewport??null}var C0=null;function y6(){return null}function g1(J,Q=y6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function T6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return g1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return g1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function x6(J){C0=J}function bJ(){if(!C0)throw Error("PocketJS: host not installed — call render() first");return C0}function E(){return bJ().ops}function f6(J){globalThis.frame=J}function v6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function m6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return S1($>>>16&255,$>>>8&255,$&255,255);return S1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function u6(J,Q){let $=b6[J];if(typeof Q==="string"){if($===U.color)return m6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var $0=60,w1=[1,2,3,4,5,6,10,12,15,20,30,60],E0=$0,ZJ=-1,l6=0,xJ=[];function p6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=w1[0];for(let $ of w1)if(Math.abs($-J)Q.at<=ZJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>ZJ);for(let Q of J)Q.cb()}var N0=0.12,Z0=BJ;function s6(J){Z0=J===void 0?BJ:J&65535}function a6(){Z0=BJ}function N1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function o6(){return N1(Z0&255)}var h1=new Set,n6=0;function t6(){h1.clear(),n6=0,a6()}function e6(J){for(let Q of[...h1])Q(J)}var jJ=null,y1=null;function J8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function T1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function fJ(J){h0();let Q=jJ?jJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return y1.slice(Q.off,Q.off+Q.len)}var vJ=null,g=null,KJ=null,q0=0,FJ=[],T0=[],x0=[];function f1(J){if(vJ=J,g=null,KJ=null,q0=0,FJ.length=0,T0.length=0,x0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function $8(J,Q){J.onPress=Q??void 0}function Z8(J,Q){if(J.focusable=Q,p1(),!Q&&g===J)x(null)}function x(J){if(KJ&&KJ!==J)MJ(null);g=J,E().setFocus(J?J.id:0)}function MJ(J){if(KJ===J)return;let Q=E();if(KJ)Q.setActive?.(KJ.id,0);if(KJ=J,J)Q.setActive?.(J.id,1)}function f0(){return FJ.length>0?FJ[FJ.length-1]:vJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function Y8(){if(!g)return null;let J=f0();if(J&&!i(g,J))return null;for(let Q=T0.length-1;Q>=0;Q--){let $=T0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(g,$.node))return $}return null}function z8(J){let Q=Y8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(g)x(null);return!0}let Z=Q.columns,q=g?$.indexOf(g):-1;if(q<0)return x(v1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function W8(){if(!g)return null;let J=f0();if(J&&!i(g,J))return null;for(let Q=x0.length-1;Q>=0;Q--){let $=x0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(g,$.node))return $}return null}function X0(J){let Q=W8();if(Q&&Q.move(J))return;if(z8(J))return;X8(J)}function m1(){u1(g)}function u1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){MJ(J)}function G8(J){x(J),u1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=m0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,l1=0;function p1(){l1++}var B8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],j8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function K8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=B8[Q]>>$&1,q=j8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function F8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=fJ($.image)}catch(z){if(bJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):M8(Q,X),q<0&&bJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(K8(),16,16,g6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function M8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&w6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var W0=null;function c1(J){W0=J}function d1(J){let Q=FJ.length>0?FJ[FJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function i1(J,Q,$){return d1(s1(J,Q,$))}function s1(J,Q,$){if($!==void 0)return $===0?null:z0(W0??vJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(W0??vJ,q(J,Q))}function U8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=b1(q);if(Z.vw=B?B.w:_1,Z.vh=B?B.h:k1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)F8(Z,q);let X=r6()*Z.speed,z=o6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=c6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=l1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=d1(z0(W0??vJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==g)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(MJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,MJ(null),B)m1()}}else if($&Z.button)MJ(null);return!0}function R8(J){let Q=J&~q0,$=q0&~J;if(q0=J,l&&U8(J,Q,$))return;if($&d.CIRCLE)MJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)MJ(g),m1()}var u0=null;function a1(J){u0=J}function gJ(){if(p1(),u0)u0()}function P8(J,Q){J.debugName=Q||void 0,gJ()}var qJ={id:_6,type:HJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},r1=Symbol.for("pocketjs.native-node"),l0=1,mJ=3,o=8,D8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function G0(J){return J.domAttrs??={}}function o1(J,Q){let $=J.domNodeType??(uJ(J)?mJ:l0),Z=$===mJ?H0(J.text??""):$===o?O8(J.domData??""):Z4(J.domTag??j0(J));for(let q of Object.keys(J.domAttrs??{}))p0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)XJ(Z,o1(q,!0));return Z}function p0(J,Q,$){if(D8.has(Q)){CJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete G0(J)[Q];else G0(J)[Q]=$}function c0(J){if(J[r1]===!0)return J;return Object.defineProperty(J,r1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?mJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(uJ(J))B0(J,Z);else if(g8(J),Z)XJ(J,H0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return X4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??j0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===mJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??j0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){CJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===qJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return XJ(J,$),$},insertBefore($,Z){return XJ(J,$,Z??null),$},removeChild($){return lJ(J,$),$},replaceChild($,Z){return XJ(J,$,Z),lJ(J,Z),Z},cloneNode($=!1){return o1(J,!!$)},remove(){if(J.parent)lJ(J.parent,J)},setAttribute($,Z){p0(J,$,Z)},removeAttribute($){p0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(qJ);var d0=null;function V8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},n1=new Map;function t1(J,Q){n1.set(J,Q)}var e1=new Map;function J4(J,Q){e1.set(J,Q)}var wJ=new Set,L8=new Set;function Q4(J){if(!J)return!1;if(L8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function H0(J){let Q=E(),$=Q.createNode(HJ.text);return Q.setText($,J),c0({id:$,type:HJ.text,parent:null,children:[],text:J,domNodeType:mJ,domTag:"#text"})}function O8(J=""){let Q=H0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){E().replaceText(J.id,Q),J.text=Q,gJ()}function uJ(J){return J.type===HJ.text}function q4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function XJ(J,Q,$){let Z=E();if(q4(Q),wJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,gJ()}function lJ(J,Q){if(!Q)return;H8(Q),E().removeChild(J.id,Q.id),q4(Q),wJ.add(Q),gJ()}function I8(J){return J.parent??void 0}function A8(J){return J.children[0]}function X4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function _8(J,Q){let $=E();if(gJ(),Q==null||Q===""){$.setStyle(J.id,k6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(bJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function k8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=n1.get(Q);if(Z===void 0){if(bJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function S8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=e1.get(Q);if(Z===void 0){if(bJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function b8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=S6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,u6(G,P)),z=!0}if(z)gJ()}function CJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete G0(J)[Q];else G0(J)[Q]=$;switch(Q){case"class":return _8(J,$),$;case"onPress":case"on:press":return $8(J,$),$;case"src":return k8(J,$),$;case"sprite":return S8(J,$),$;case"style":return b8(J,$,Z),$;case"focusable":return Z8(J,!!$),$;case"debugName":return P8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${j0(J)}>`)}function g8(J){for(let Q of[...J.children])lJ(J,Q)}function j0(J){for(let Q of Object.keys(HJ))if(HJ[Q]===J.type)return Q;return String(J.type)}function w8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}CJ(J,Q,$,Z)}var C8=A6({createElement:Z4,createTextNode:H0,replaceText:B0,isTextNode:uJ,setProperty:w8,insertNode(J,Q,$){XJ(J,Q,$)},removeNode(J,Q){lJ(J,Q)},getParentNode:I8,getFirstChild:A8,getNextSibling:X4}),{render:E8,effect:gQ,memo:p,createComponent:Y,createElement:Y4,insert:wQ,spread:N8,mergeProps:CQ,use:EQ}=C8,NQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},h8=null;function z4(J){h8=J}function y8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function W4(J,Q){let $=Y4(J);return N8($,Q,!1),y8(Q.nodeRef,$),$}function F(J){return W4("view",J)}function R(J){return W4("text",J)}var hQ=new WeakMap,yQ=new WeakMap,T8={}!==null?Object.freeze({...{}}):Object.freeze({}),TQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:T8}),xQ=new Map,YJ=36000,s0=30,x8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(YJ),tapeAnalog:new Uint16Array(YJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function f8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-s0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)a1(()=>{W.treeDirty=!0}),i8();else a1(null);globalThis.__pocketDevtools=a8}function v8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)u8(),c8();let X=Q,z=$===void 0?BJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(YJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==BJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function B4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function j4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.masks,0,Q)}function K4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.analog??[],BJ,Q)}function F4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,T({t:"hello",app:W.app,host:s8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` -`))if(q.trim())l8(q)}}function l8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),a0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":M4();break;case"eval":{let Z=!0,q;try{q=K0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}T({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":T({t:"tape",tape:H4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}T({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=j4(Z),W.replayAnalog=Z.analog?K4(Z):null,W.replayTouch=Z.touch?F4(Z):null,W.replayAt=0;break}default:break}}function p8(){if(W.treeDirty&&W.frame-W.treeSentAt>=s0)M4();if(W.frame%x8===0)a0()}function c8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){T({t:"stats",frame:W.frame,nodes:P4(qJ),tapeLen:W.tapeLen,paused:W.paused})}function M4(){W.treeDirty=!1,W.treeSentAt=W.frame,T({t:"tree",frame:W.frame,root:R4(qJ)})}function d8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(d8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function U4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function R4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(U4(J,(q)=>{if(q.domNodeType===8)return;Z.push(R4(q))}),Z.length)Q.k=Z;return Q}function P4(J){let Q=1;return U4(J,($)=>{Q+=P4($)}),Q}function i8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{T({t:"log",level:$,args:q.map((X)=>K0(X))}),Z?.apply(Q,q)}}}function K0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?D4(X):JSON.stringify(D4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>K0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${K0(z,Q+1)}`).join(", ")}}`}function D4(J){return J.length>200?J.slice(0,199)+"…":J}function s8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var a8={get frame(){return W.frame},dumpTape:()=>H4(),replay:(J)=>{W.replayMasks=j4(J),W.replayAnalog=J.analog?K4(J):null,W.replayTouch=J.touch?F4(J):null,W.replayAt=0}},V4=new Map,o0=new Map;function L4(J){return J.trim().replace(/\s+/g," ")}function O4(J){return J.split(" ").sort().join(" ")}var I4=-1;function r8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=L4(Q);V4.set(Z,$);let q=O4(Z),X=o0.get(q);o0.set(q,X!==void 0&&X!==$?I4:$)}}function o8(J){let Q=L4(J),$=V4.get(Q);if($!==void 0)return $;let Z=o0.get(O4(Q));return Z===I4?void 0:Z}var n0=9,n8=(1<{let q=($&e8)!==0,X=q?t0:n0,z=q?J2:n8;return Object.freeze({id:$>>>(q?Q2:t8)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Z2(){return F0}function q2(){F0=e0}var A4=8,zJ=8,X2=3,Y2=8,z2=6,W2=0.5,s=1,pJ=2,J1=4,UJ=8,EJ=[],_4=0,M0=0,WJ=Array.from({length:A4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(zJ),histY:new Int16Array(zJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function G2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function H2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=s1(Q,$,Z.fact);let G=Z.hit;if(G)return G2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=EJ[z];if(G.disposed)continue;if(_4>0&&!G.opts.allowWhenBlocked)continue;if(!H2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function K2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%zJ,J.histLenz||Z>z))q.flags[J.slot]|=pJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(pJ|J1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??W2)*C1()));if(J.frames=0)EJ.splice($,1)},cancel(){if(!Q.disposed)b4(Q)},get panning(){for(let $ of WJ)if($.used&&Q.flags[$.slot]&UJ)return!0;return!1}}}function P2(J){let Q=R2(J);return S0(()=>Q.dispose()),Q}function g4(){EJ.length=0,_4=0,M0=0;for(let J of WJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function D2(){return P2({onDown:(J)=>{let Q=i1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=i1(J.x,J.y,J.hit);if(Q)G8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var V2=1,Q1=new Map,U0=[];function L2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function O2(){V2=1,Q1.clear(),U0=[]}function I2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),L2()?.({t:"delivery",frame:E1(),id:Q,kind:Z.kind}),Z.onResult($)}}var w4=new Set;function A2(){if(w4.size===0)return;for(let J of w4)J()}var _2={"text-lg text-orange-600 font-bold":0,"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":1,"w-[165] h-[76] items-center justify-center bg-orange-600":2,"w-[165] h-[76] items-center justify-center bg-slate-900":3,"text-sm text-white font-bold":4,"flex-col w-full h-full bg-slate-50":5,"h-[686] px-6 pt-7 flex-col gap-[22]":6,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":7,"h-[28] flex-row items-center gap-3":8,"w-[10] h-[10] rounded bg-orange-500":9,"text-sm text-orange-600 font-bold":10,"h-[76] pt-3 text-base text-slate-900":11,"h-[2] mx-1 my-4 bg-slate-100":12,"w-[10] h-[10] rounded bg-emerald-500":13,"text-sm text-emerald-700 font-bold":14,"h-[84] pt-3 text-base text-slate-900":15,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":16,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":17,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":18,"text-sm text-slate-600 font-bold":19,"pt-6 text-base text-slate-500":20,"pt-6 text-base text-slate-900 font-bold":21,"h-[146] px-6 pt-7 flex-col bg-slate-50":22,"h-[80]":23,"h-[1060] px-6 pt-5 flex-col":24,"h-[48] px-4 justify-center bg-slate-100":25,"text-sm text-slate-600":26,"pt-[10] flex-col gap-[12]":27,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":28,"w-[48] h-[48] items-center justify-center bg-blue-100":29,"w-[48] h-[48] items-center justify-center bg-emerald-100":30,"text-base text-blue-700 font-bold":31,"text-base text-emerald-700 font-bold":32,"w-[474] flex-col gap-2":33,"text-base text-slate-900 font-bold":34,"text-sm text-slate-500":35,"pt-20 pl-10 text-base text-slate-500":36,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":37,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":38,"h-[1060] px-6 pt-7 flex-col gap-4":39,"text-sm text-slate-500 font-bold":40,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":41,"flex-row items-center gap-5":42,"w-[68] h-[68] items-center justify-center bg-emerald-100":43,"text-xl text-emerald-700 font-bold":44,"flex-col gap-2":45,"text-lg text-slate-900 font-bold":46,"text-base text-slate-600":47,"text-2xl text-orange-600":48,"w-[68] h-[68] items-center justify-center bg-indigo-100":49,"text-xl text-indigo-700 font-bold":50,"mt-4 h-[112] px-6 justify-center bg-slate-100":51,"relative h-[154] px-5 pt-5 flex-col bg-white":52,"pt-3 text-base text-orange-600 font-bold":53,"pt-3 text-sm text-slate-500":54,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":55,"text-base text-white font-bold":56,"h-[40] pt-3 text-sm text-slate-500":57,"h-[470] flex-col gap-2":58,"h-[214] px-7 items-center justify-center bg-slate-100":59,"text-base text-slate-500 font-bold":60,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":61,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":62,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":63,"h-[160] px-5 pt-5 flex-col bg-white":64,"pt-3 text-base text-slate-900 font-bold":65,"pt-3 text-sm text-slate-600":66,"h-[108] pt-7 flex-row gap-4":67,"w-[316] h-[80] items-center justify-center bg-slate-100":68,"w-[340] h-[80] items-center justify-center bg-red-100":69,"text-base text-red-500 font-bold":70,"h-[1052] px-6 pt-5 flex-col":71,"h-[270] px-[22] pt-6 bg-white":72,"text-lg text-slate-900":73,"text-lg text-slate-400":74,"h-[86] px-1 flex-row items-center justify-between":75,"w-[132] h-[58] items-center justify-center bg-slate-100":76,"text-sm text-slate-900 font-bold":77,"h-[140] flex-row gap-2":78,"grow h-[120] items-center justify-center bg-white":79,"text-xl text-slate-900 font-bold":80,"w-[104] h-[120] items-center justify-center bg-slate-100":81,"h-[176] flex-row gap-2":82,"w-[92] h-[156] items-center justify-center bg-slate-100":83,"w-[300] h-[156] items-center justify-center bg-slate-100":84,"w-[144] h-[156] items-center justify-center bg-slate-100":85,"w-[112] h-[156] items-center justify-center bg-emerald-500":86,"text-sm text-slate-950 font-bold":87,"h-[108] px-6 py-3 flex-col bg-slate-50":88,"h-[84] items-center justify-center bg-slate-100":89,"h-[1168] px-6 pt-5 flex-col":90,"h-[82] px-4 justify-center bg-white":91,"w-[584] h-[900] px-5 pt-5 bg-slate-950":92,"text-sm text-slate-200":93,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":94,"text-base text-orange-600 font-bold":95,"w-[584] h-[900] px-5 pt-5 bg-white":96,"text-sm text-slate-900":97,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":98,"absolute inset-0 z-50 flex-col items-center justify-center":99,"absolute inset-0 bg-slate-950":100,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":101,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":102,"flex-row flex-wrap":103,grow:104,"text-2xl text-white font-bold":105,"text-base text-slate-900":106,"px-6":107,"px-6 py-5":108,"gap-4":109,"w-[34] h-[34] rounded-lg bg-amber-400":110,"w-[34] h-[34] rounded-lg bg-red-500":111,"w-[34] h-[34] rounded-lg bg-slate-800":112,"w-[34] h-[34] rounded-lg bg-emerald-500":113,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":114,"flex-row items-center gap-4":115,"w-[34] text-2xl text-white font-bold":116,"w-[332] flex-col items-end gap-2":117,"text-sm text-slate-300 font-bold":118,"text-sm text-slate-400":119,"h-[40] px-1 flex-row items-center justify-between":120,"w-full h-full items-center justify-center rounded-xl bg-slate-200":121,"w-full h-full items-center justify-center rounded-xl bg-orange-600":122};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var k2="ui:styles",S2="ui:font.",C4="ui:img.",E4="ui:sprite.";function b2(){return globalThis.ui}function g2(J){if(J.__textures)return;for(let Q of y0(C4)){let $=fJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)t1(Q.slice(C4.length),Z)}}function w2(J){if(J.__sprites)return;for(let Q of y0(E4)){let $=fJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)J4(Q.slice(E4.length),{handle:V,frames:G,cols:P,step:D})}}function N4(J){let Q=Y4("view");return CJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function C2(J,Q){if(!R0||!P0)return;CJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),CJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function E2(J,Q={}){let $=T6(Q.ops);if(x6($),V8(o8),Q.styles)r8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)t1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)J4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)x1(Q.pak);if(Q8()){for(let B of y0())if(B===k2)$.ops.loadStyles?.(fJ(B));else if(B.startsWith(S2))$.ops.loadFontAtlas?.(fJ(B))}}let q=b1($.ops),X=q?.w??_1,z=q?.h??k1,G=N4({width:X,height:z,overflow:u.Overflow.Hidden}),P=N4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});XJ(qJ,G),XJ(qJ,P),z4(P),R0=G,P0=P,f1(G),c1(qJ),t6(),g4(),D2(),d6(),O2(),f8($.ops),f6(v8((B,_,N,h)=>{i6(),s6(_),$2(N,h),A2(),I2(),U2(),e6(B),R8(B),$4()}));let D=E8(J,G),V=v6(C2);return()=>{V(),q2(),g4(),D(),f1(null),c1(null),z4(null),R0=null,P0=null;for(let B of qJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);$4()}}function N2(J,Q={}){let $=Q.ops??b2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)x1(Q.pak);return g2($),w2($),E2(J,{ops:$,styles:Q.styles??_2,pak:Q.pak})}var h2="$b",y2=65536,h4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",cJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function f2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function y4(){let J=f2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function v2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,y2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=T2(z.data[h2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function m2(J,Q){let $=v2(y4(),J);return Q==="utf8"||Q==="utf-8"?x2($):$}function u2(J,Q){let $=y4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var l2={title:"text-2xl text-white font-bold",section:"text-sm text-slate-600 font-bold",body:"text-base text-slate-900",bodyStrong:"text-base text-slate-900 font-bold",caption:"text-sm text-slate-500"};function p2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(F,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(F,{class:"flex-row items-center gap-4",get children(){return[p(()=>p(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(F,{get["class"](){return Q()}})),Y(R,{get["class"](){return l2.title},get children(){return J.title}})]}}),Y(F,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-sm text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-sm text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function c2(J){return Y(F,{get["class"](){return J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":"w-full h-full items-center justify-center rounded-xl bg-orange-600"},get children(){return Y(R,{get["class"](){return J.disabled?"text-base text-slate-500 font-bold":"text-base text-white font-bold"},get children(){return J.label}})}})}var fQ="‘’“”–—…•",T4=new Map,x4=new Map;function D0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=T4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return T4.set($,q),q}function d2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=D0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function $1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=x4.get(Z);if(q)return q;let X=[],z=D0(" ",Q);for(let G of J.split(` -`)){let P=G.split(" ").flatMap((B)=>B&&D0(B,Q)>$?d2(B,Q,$):[B]),D="",V=0;for(let B of P){let _=D0(B,Q);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return x4.set(Z,X),X}function f4(J,Q,$,Z){let q=$1(J,Q,$);if(q.length<=Z)return q.join(` +(()=>{var AJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return B1(this.context.count)},getNextContextId(){return B1(this.context.count++)}};function B1(J){let Q=String(J),$=Q.length-1;return AJ.context.id+($?String.fromCharCode(96+$):"")+Q}function j1(J){AJ.context=J}function Y6(){return{...AJ.context,id:AJ.getNextContextId(),count:0}}var z6=!1,W6=(J,Q)=>J===Q,S0=Symbol("solid-proxy"),G6=typeof Proxy==="function",H6=Symbol("solid-track"),KQ=Symbol("solid-dev-component"),nJ={equals:W6},K1=null,B6=V1,m=1,fJ=2,F1={owned:null,cleanups:null,context:null,owner:null},S=null,K=null,yJ=null,_J=null,b=null,C=null,T=null,tJ=0;function eJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?F1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>QJ(()=>$J(z)));S=z,b=null;try{return c(G,!0)}finally{b=$,S=Z}}function g(J,Q){Q=Q?Object.assign({},nJ,Q):nJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return R1($,q)};return[U1.bind($),Z]}function JJ(J,Q,$){let Z=D1(J,Q,!1,m);if(yJ&&K&&K.running)C.push(Z);else J0(Z)}function kJ(J,Q,$){$=$?Object.assign({},nJ,$):nJ;let Z=D1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,yJ&&K&&K.running)Z.tState=m,C.push(Z);else J0(Z);return U1.bind(Z)}function j6(J){return c(J,!1)}function QJ(J){if(!_J&&b===null)return J();let Q=b;b=null;try{if(_J)return _J.untrack(J);return J()}finally{b=Q}}function b0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function K6(J){if(K&&K.running)return J(),K.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(yJ||F6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[FQ,M1]=g(!1),F6;function U1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)J0(this);else{let Q=C;C=null,c(()=>Q0(this),!1),C=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function R1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw C=[],Error()},!1)}return Q}function J0(J){if(!J.fn)return;$J(J);let Q=tJ;if(P1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{c(()=>{K&&(K.running=!0),b=S=J,P1(J,J.tValue,Q),b=S=null},!1)})}function P1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=m,J.tOwned&&J.tOwned.forEach($J),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach($J),J.owned=null;return J.updatedAt=$+1,w0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)R1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function D1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(S===null);else if(S!==F1)if(K&&K.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(_J&&X.fn){let z=X.fn,[G,P]=g(void 0,{equals:!1}),D=_J.factory(z,P);b0(()=>D.dispose());let V,B=()=>K6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),K&&K.running){if(!V)V=_J.factory(z,B);return V.track(_)}return D.track(_)}}return X}function g0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===fJ)return Q0(J);if(J.suspense&&QJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===m)J0(J);else if((Q?J.tState:J.state)===fJ){let q=C;C=null,c(()=>Q0(J,$[0]),!1),C=q}}}function c(J,Q){if(C)return J();let $=!1;if(!Q)C=[];if(T)$=!0;else T=[];tJ++;try{let Z=J();return M6($),Z}catch(Z){if(!$)T=null;C=null,w0(Z)}}function M6(J){if(C){if(yJ&&K&&K.running)U6(C);else V1(C);C=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;T.push.apply(T,K.effects),Q=K.resolve;for(let X of T)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,c(()=>{for(let X of q)$J(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zB6($),!1);if(Q)Q()}function V1(J){for(let Q=0;Q{Z.delete($),c(()=>{K.running=!0,g0($)},!1),K&&(K.running=!1)})}}function Q0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)$J(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)O1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)$J(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function O1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return b0(()=>A1(X)),()=>{let P=J()||[],D=P.length,V,B;return P[H6],QJ(()=>{let N,h,a,HJ,LJ,M,j,H,L;if(D===0){if(z!==0)A1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[P6],q[0]=eJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=M&&H>=M&&Z[j]===P[H];j--,H--)a[H]=q[j],HJ[H]=X[j],G&&(LJ[H]=G[j]);N=new Map,h=Array(H+1);for(B=H;B>=M;B--)L=P[B],V=N.get(L),h[B]=V===void 0?-1:V,N.set(L,B);for(V=M;V<=j;V++)if(L=Z[V],B=N.get(L),B!==void 0&&B!==-1)a[B]=q[V],HJ[B]=X[V],G&&(LJ[B]=G[V]),B=h[B],N.set(L,B);else X[V]();for(B=M;BJ(Q||{}));return j1($),Z}}return QJ(()=>J(Q||{}))}function $0(){return!0}var O6={get(J,Q,$){if(Q===S0)return $;return J.get(Q)},has(J,Q){if(Q===S0)return!0;return J.has(Q)},set:$0,deleteProperty:$0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:$0,deleteProperty:$0}},ownKeys(J){return J.keys()}};function C0(J){return!(J=typeof J==="function"?J():J)?{}:J}function I6(){for(let J=0,Q=this.length;J=0;G--){let P=C0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in C0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:I6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var A6=(J)=>`Stale read from <${J}>.`;function SJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return kJ(D6(()=>J.each,J.children,Q||void 0))}function bJ(J){let Q=J.keyed,$=kJ(()=>J.when,void 0,void 0),Z=Q?$:kJ($,void 0,{equals:(q,X)=>!q===!X});return kJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?QJ(()=>X(Q?q:()=>{if(!QJ(Z))throw A6("Show");return $()})):X}return J.fallback},void 0,void 0)}var _6=(J)=>kJ(()=>J());function k6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(M,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(M,j,L,H);JJ((A)=>B(M,j(),A,H),L)}function B(M,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=h(M,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(M),H=j);else h(M,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=h(M,H,L);else if(k==="function")return JJ(()=>{let O=j();while(typeof O==="function")O=O();H=B(M,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return JJ(()=>H=B(M,O,H,L,!0)),()=>H;if(O.length===0){let TJ=h(M,H,L);if(I)return H=TJ}else if(Array.isArray(H))if(H.length===0)a(M,O,L);else N(M,H,O);else if(H==null||H==="")a(M,O);else N(M,I&&H||[P(M)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(M,H,L,j);h(M,H,null,j)}else if(H==null||H===""||!P(M))q(M,j);else HJ(M,j,P(M));H=j}return H}function _(M,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let jQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let TJ=G(O)===M;if(!k&&!I)TJ?HJ(M,A,O):q(M,A,H);else TJ&&X(M,O)}else k=!0}}else q(M,A,H);return[A]}function a(M,j,H){for(let L=0,A=j.length;LH.children=B(M,j.children,H.children));return JJ(()=>j.ref&&j.ref(M)),JJ(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(M,A,k,H[A]),H[A]=k}}),H}return{render(M,j){let H;return eJ((L)=>{H=L,V(j,M())}),H},insert:V,spread(M,j,H){if(typeof j==="function")JJ((L)=>LJ(M,j(),L,H));else LJ(M,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(M,j,H,L){return z(M,j,H,L),H},mergeProps:_1,effect:JJ,memo:_6,createComponent:L6,use(M,j,H){return QJ(()=>M(j,H))}}}function S6(J){let Q=k6(J);return Q.mergeProps=_1,Q}var k1=480,S1=272,BJ={view:0,text:1,image:2},b6=1,g6=-1,w6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},C6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},E6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},N6=1,MQ=2,UQ=1,RQ=2,PQ=131072,DQ=1,VQ=262144,LQ=1,OQ=1,IQ=1,AQ=2,_Q=4,kQ=8,SQ=16,bQ=1,gQ=2;function b1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var wQ=1,h6=1263551300,T6=1,f6=32,y6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},jJ=32896,CQ=0.016666666666666666;function g1(J){return J.__viewport??null}var E0=null;function x6(){return null}function w1(J,Q=x6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function v6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return w1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return w1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function m6(J){E0=J}function gJ(){if(!E0)throw Error("PocketJS: host not installed — call render() first");return E0}function E(){return gJ().ops}function u6(J){globalThis.frame=J}function l6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function p6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return b1($>>>16&255,$>>>8&255,$&255,255);return b1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function c6(J,Q){let $=C6[J];if(typeof Q==="string"){if($===U.color)return p6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var Z0=60,C1=[1,2,3,4,5,6,10,12,15,20,30,60],N0=Z0,ZJ=-1,d6=0,xJ=[];function i6(J){if(!Number.isFinite(J)||J<=0)return Z0;let Q=C1[0];for(let $ of C1)if(Math.abs($-J)Q.at<=ZJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>ZJ);for(let Q of J)Q.cb()}var h0=0.12,q0=jJ;function o6(J){q0=J===void 0?jJ:J&65535}function n6(){q0=jJ}function h1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function e6(){return h1(q0&255)}var T1=new Set,J8=0;function Q8(){T1.clear(),J8=0,n6()}function $8(J){for(let Q of[...T1])Q(J)}var KJ=null,f1=null;function Z8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function y1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){T0();let Q=KJ?KJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return f1.slice(Q.off,Q.off+Q.len)}var mJ=null,w=null,FJ=null,X0=0,MJ=[],y0=[],x0=[];function v1(J){if(mJ=J,w=null,FJ=null,X0=0,MJ.length=0,y0.length=0,x0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function X8(J,Q){J.onPress=Q??void 0}function Y8(J,Q){if(J.focusable=Q,c1(),!Q&&w===J)x(null)}function x(J){if(FJ&&FJ!==J)UJ(null);w=J,E().setFocus(J?J.id:0)}function UJ(J){if(FJ===J)return;let Q=E();if(FJ)Q.setActive?.(FJ.id,0);if(FJ=J,J)Q.setActive?.(J.id,1)}function v0(){return MJ.length>0?MJ[MJ.length-1]:mJ}function m0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function G8(){if(!w)return null;let J=v0();if(J&&!i(w,J))return null;for(let Q=y0.length-1;Q>=0;Q--){let $=y0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function H8(J){let Q=G8();if(!Q)return!1;let $=[];if(m0(Q.node,$),$.length===0){if(w)x(null);return!0}let Z=Q.columns,q=w?$.indexOf(w):-1;if(q<0)return x(m1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function B8(){if(!w)return null;let J=v0();if(J&&!i(w,J))return null;for(let Q=x0.length-1;Q>=0;Q--){let $=x0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function Y0(J){let Q=B8();if(Q&&Q.move(J))return;if(H8(J))return;W8(J)}function u1(){l1(w)}function l1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function z0(J){UJ(J)}function j8(J){x(J),l1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function u0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=u0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,p1=0;function c1(){p1++}var F8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],M8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function U8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=F8[Q]>>$&1,q=M8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function R8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):P8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(U8(),16,16,E6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function P8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&N6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function W0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=W0($[Z],Q);if(q)return q}return null}var G0=null;function d1(J){G0=J}function i1(J){let Q=MJ.length>0?MJ[MJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function s1(J,Q,$){return i1(a1(J,Q,$))}function a1(J,Q,$){if($!==void 0)return $===0?null:W0(G0??mJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return W0(G0??mJ,q(J,Q))}function D8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=g1(q);if(Z.vw=B?B.w:k1,Z.vh=B?B.h:S1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)R8(Z,q);let X=t6()*Z.speed,z=e6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=s6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=p1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=i1(W0(G0??mJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==w)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(UJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,UJ(null),B)u1()}}else if($&Z.button)UJ(null);return!0}function V8(J){let Q=J&~X0,$=X0&~J;if(X0=J,l&&D8(J,Q,$))return;if($&d.CIRCLE)UJ(null);if(Q===0)return;if(Q&d.DOWN)Y0("down");if(Q&d.RIGHT)Y0("right");if(Q&d.UP)Y0("up");if(Q&d.LEFT)Y0("left");if(Q&d.CIRCLE)UJ(w),u1()}var l0=null;function r1(J){l0=J}function wJ(){if(c1(),l0)l0()}function L8(J,Q){J.debugName=Q||void 0,wJ()}var qJ={id:b6,type:BJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},o1=Symbol.for("pocketjs.native-node"),p0=1,uJ=3,o=8,O8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function H0(J){return J.domAttrs??={}}function n1(J,Q){let $=J.domNodeType??(lJ(J)?uJ:p0),Z=$===uJ?B0(J.text??""):$===o?_8(J.domData??""):q4(J.domTag??K0(J));for(let q of Object.keys(J.domAttrs??{}))c0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)XJ(Z,n1(q,!0));return Z}function c0(J,Q,$){if(O8.has(Q)){EJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete H0(J)[Q];else H0(J)[Q]=$}function d0(J){if(J[o1]===!0)return J;return Object.defineProperty(J,o1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(lJ(J)?uJ:p0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else j0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else j0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(lJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(lJ(J))j0(J,Z);else if(E8(J),Z)XJ(J,B0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return Y4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??K0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===uJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??K0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){EJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===qJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return XJ(J,$),$},insertBefore($,Z){return XJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return XJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return n1(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){c0(J,$,Z)},removeAttribute($){c0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}d0(qJ);var i0=null;function I8(J){i0=J}var s0={unknownClass:0,unknownTexture:0},t1=new Map;function e1(J,Q){t1.set(J,Q)}var J4=new Map;function Q4(J,Q){J4.set(J,Q)}var CJ=new Set,A8=new Set;function $4(J){if(!J)return!1;if(A8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return d0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:p0,domTag:J})}function B0(J){let Q=E(),$=Q.createNode(BJ.text);return Q.setText($,J),d0({id:$,type:BJ.text,parent:null,children:[],text:J,domNodeType:uJ,domTag:"#text"})}function _8(J=""){let Q=B0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function j0(J,Q){E().replaceText(J.id,Q),J.text=Q,wJ()}function lJ(J){return J.type===BJ.text}function X4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function XJ(J,Q,$){let Z=E();if(X4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function pJ(J,Q){if(!Q)return;K8(Q),E().removeChild(J.id,Q.id),X4(Q),CJ.add(Q),wJ()}function k8(J){return J.parent??void 0}function S8(J){return J.children[0]}function Y4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function b8(J,Q){let $=E();if(wJ(),Q==null||Q===""){$.setStyle(J.id,g6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=i0?i0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);s0.unknownClass++;return}$.setStyle(J.id,Z)}function g8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=t1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);s0.unknownTexture++;return}$.setImage(J.id,Z)}function w8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=J4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);s0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function C8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=w6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,c6(G,P)),z=!0}if(z)wJ()}function EJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete H0(J)[Q];else H0(J)[Q]=$;switch(Q){case"class":return b8(J,$),$;case"onPress":case"on:press":return X8(J,$),$;case"src":return g8(J,$),$;case"sprite":return w8(J,$),$;case"style":return C8(J,$,Z),$;case"focusable":return Y8(J,!!$),$;case"debugName":return L8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${K0(J)}>`)}function E8(J){for(let Q of[...J.children])pJ(J,Q)}function K0(J){for(let Q of Object.keys(BJ))if(BJ[Q]===J.type)return Q;return String(J.type)}function N8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}EJ(J,Q,$,Z)}var h8=S6({createElement:q4,createTextNode:B0,replaceText:j0,isTextNode:lJ,setProperty:N8,insertNode(J,Q,$){XJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:k8,getFirstChild:S8,getNextSibling:Y4}),{render:T8,effect:EQ,memo:p,createComponent:Y,createElement:z4,insert:NQ,spread:f8,mergeProps:hQ,use:TQ}=h8,fQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},y8=null;function W4(J){y8=J}function x8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function G4(J,Q){let $=z4(J);return f8($,Q,!1),x8(Q.nodeRef,$),$}function F(J){return G4("view",J)}function R(J){return G4("text",J)}var yQ=new WeakMap,xQ=new WeakMap,v8={}!==null?Object.freeze({...{}}):Object.freeze({}),vQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:v8}),mQ=new Map,YJ=36000,a0=30,m8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(YJ),tapeAnalog:new Uint16Array(YJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-a0,saidHello:!1,hostCalls:0};function u8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-a0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)r1(()=>{W.treeDirty=!0}),r8();else r1(null);globalThis.__pocketDevtools=n8}function l8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)c8(),s8();let X=Q,z=$===void 0?jJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(YJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==jJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function j4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function K4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return j4(J.masks,0,Q)}function F4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return j4(J.analog??[],jJ,Q)}function M4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,f({t:"hello",app:W.app,host:o8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` +`))if(q.trim())d8(q)}}function d8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)f({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),r0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),r0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":U4();break;case"eval":{let Z=!0,q;try{q=F0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}f({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":f({t:"tape",tape:B4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}f({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())f({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else f({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=K4(Z),W.replayAnalog=Z.analog?F4(Z):null,W.replayTouch=Z.touch?M4(Z):null,W.replayAt=0;break}default:break}}function i8(){if(W.treeDirty&&W.frame-W.treeSentAt>=a0)U4();if(W.frame%m8===0)r0()}function s8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,f({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,f({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function r0(){f({t:"stats",frame:W.frame,nodes:D4(qJ),tapeLen:W.tapeLen,paused:W.paused})}function U4(){W.treeDirty=!1,W.treeSentAt=W.frame,f({t:"tree",frame:W.frame,root:P4(qJ)})}function a8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function o0(J,Q){if(Array.isArray(J)){for(let $ of J)o0($,Q);return}if(a8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)o0($,Q)}}function R4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)o0(Z,Q)}function P4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(R4(J,(q)=>{if(q.domNodeType===8)return;Z.push(P4(q))}),Z.length)Q.k=Z;return Q}function D4(J){let Q=1;return R4(J,($)=>{Q+=D4($)}),Q}function r8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{f({t:"log",level:$,args:q.map((X)=>F0(X))}),Z?.apply(Q,q)}}}function F0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?V4(X):JSON.stringify(V4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>F0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${F0(z,Q+1)}`).join(", ")}}`}function V4(J){return J.length>200?J.slice(0,199)+"…":J}function o8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var n8={get frame(){return W.frame},dumpTape:()=>B4(),replay:(J)=>{W.replayMasks=K4(J),W.replayAnalog=J.analog?F4(J):null,W.replayTouch=J.touch?M4(J):null,W.replayAt=0}},L4=new Map,n0=new Map;function O4(J){return J.trim().replace(/\s+/g," ")}function I4(J){return J.split(" ").sort().join(" ")}var A4=-1;function t8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=O4(Q);L4.set(Z,$);let q=I4(Z),X=n0.get(q);n0.set(q,X!==void 0&&X!==$?A4:$)}}function e8(J){let Q=O4(J),$=L4.get(Q);if($!==void 0)return $;let Z=n0.get(I4(Q));return Z===A4?void 0:Z}var t0=9,J2=(1<{let q=($&$2)!==0,X=q?e0:t0,z=q?Z2:J2;return Object.freeze({id:$>>>(q?q2:Q2)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Y2(){return M0}function z2(){M0=J1}var _4=8,zJ=8,W2=3,G2=8,H2=6,B2=0.5,s=1,cJ=2,Q1=4,RJ=8,NJ=[],k4=0,U0=0,WJ=Array.from({length:_4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(zJ),histY:new Int16Array(zJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function j2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function K2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=a1(Q,$,Z.fact);let G=Z.hit;if(G)return j2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=NJ[z];if(G.disposed)continue;if(k4>0&&!G.opts.allowWhenBlocked)continue;if(!K2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function U2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%zJ,J.histLenz||Z>z))q.flags[J.slot]|=cJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(cJ|Q1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??B2)*E1()));if(J.frames=0)NJ.splice($,1)},cancel(){if(!Q.disposed)g4(Q)},get panning(){for(let $ of WJ)if($.used&&Q.flags[$.slot]&RJ)return!0;return!1}}}function L2(J){let Q=V2(J);return b0(()=>Q.dispose()),Q}function w4(){NJ.length=0,k4=0,U0=0;for(let J of WJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function O2(){return L2({onDown:(J)=>{let Q=s1(J.x,J.y,J.hit);if(Q)z0(Q)},onTap:(J)=>{z0(null);let Q=s1(J.x,J.y,J.hit);if(Q)j8(Q)},onUp:()=>z0(null),onCancel:()=>z0(null)})}var I2=1,$1=new Map,R0=[];function A2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function _2(){I2=1,$1.clear(),R0=[]}function k2(){if(R0.length===0)return;let J=R0;R0=[];for(let{id:Q,result:$}of J){let Z=$1.get(Q);if(!Z)continue;$1.delete(Q),A2()?.({t:"delivery",frame:N1(),id:Q,kind:Z.kind}),Z.onResult($)}}var C4=new Set;function S2(){if(C4.size===0)return;for(let J of C4)J()}var b2={"text-lg text-orange-600 font-bold":0,"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":1,"w-[165] h-[76] items-center justify-center bg-orange-600":2,"w-[165] h-[76] items-center justify-center bg-slate-900":3,"text-sm text-white font-bold":4,"flex-col w-full h-full bg-slate-50":5,"h-[686] px-6 pt-7 flex-col gap-[22]":6,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":7,"h-[28] flex-row items-center gap-3":8,"w-[10] h-[10] rounded bg-orange-500":9,"text-sm text-orange-600 font-bold":10,"h-[76] pt-3 text-base text-slate-900":11,"h-[2] mx-1 my-4 bg-slate-100":12,"w-[10] h-[10] rounded bg-emerald-500":13,"text-sm text-emerald-700 font-bold":14,"h-[84] pt-3 text-base text-slate-900":15,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":16,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":17,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":18,"text-sm text-slate-600 font-bold":19,"pt-6 text-base text-slate-500":20,"pt-6 text-base text-slate-900 font-bold":21,"h-[146] px-6 pt-7 flex-col bg-slate-50":22,"h-[80]":23,"h-[1060] px-6 pt-5 flex-col":24,"h-[48] px-4 justify-center bg-slate-100":25,"text-sm text-slate-600":26,"pt-[10] flex-col gap-[12]":27,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":28,"w-[48] h-[48] items-center justify-center bg-blue-100":29,"w-[48] h-[48] items-center justify-center bg-emerald-100":30,"text-base text-blue-700 font-bold":31,"text-base text-emerald-700 font-bold":32,"w-[474] flex-col gap-2":33,"text-base text-slate-900 font-bold":34,"text-sm text-slate-500":35,"pt-20 pl-10 text-base text-slate-500":36,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":37,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":38,"h-[1060] px-6 pt-7 flex-col gap-4":39,"text-sm text-slate-500 font-bold":40,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":41,"flex-row items-center gap-5":42,"w-[68] h-[68] items-center justify-center bg-emerald-100":43,"text-xl text-emerald-700 font-bold":44,"flex-col gap-2":45,"text-lg text-slate-900 font-bold":46,"text-base text-slate-600":47,"text-2xl text-orange-600":48,"w-[68] h-[68] items-center justify-center bg-indigo-100":49,"text-xl text-indigo-700 font-bold":50,"mt-4 h-[112] px-6 justify-center bg-slate-100":51,"relative h-[154] px-5 pt-5 flex-col bg-white":52,"pt-3 text-base text-orange-600 font-bold":53,"pt-3 text-sm text-slate-500":54,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":55,"text-base text-white font-bold":56,"h-[40] pt-3 text-sm text-slate-500":57,"h-[470] flex-col gap-2":58,"h-[214] px-7 items-center justify-center bg-slate-100":59,"text-base text-slate-500 font-bold":60,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":61,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":62,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":63,"h-[160] px-5 pt-5 flex-col bg-white":64,"pt-3 text-base text-slate-900 font-bold":65,"pt-3 text-sm text-slate-600":66,"h-[108] pt-7 flex-row gap-4":67,"w-[316] h-[80] items-center justify-center bg-slate-100":68,"w-[340] h-[80] items-center justify-center bg-red-100":69,"text-base text-red-500 font-bold":70,"h-[1052] px-6 pt-5 flex-col":71,"h-[270] px-[22] pt-6 bg-white":72,"text-lg text-slate-900":73,"text-lg text-slate-400":74,"h-[86] px-1 flex-row items-center justify-between":75,"w-[132] h-[58] items-center justify-center bg-slate-300":76,"w-[132] h-[58] items-center justify-center bg-slate-100":77,"text-sm text-slate-900 font-bold":78,"h-[140] flex-row gap-2":79,"grow h-[120] items-center justify-center bg-slate-300":80,"grow h-[120] items-center justify-center bg-white":81,"text-xl text-slate-900 font-bold":82,"w-[104] h-[120] items-center justify-center bg-slate-300":83,"w-[104] h-[120] items-center justify-center bg-slate-100":84,"h-[176] flex-row gap-2":85,"w-[92] h-[156] items-center justify-center bg-slate-300":86,"w-[92] h-[156] items-center justify-center bg-slate-100":87,"w-[300] h-[156] items-center justify-center bg-slate-300":88,"w-[300] h-[156] items-center justify-center bg-slate-100":89,"w-[144] h-[156] items-center justify-center bg-slate-300":90,"w-[144] h-[156] items-center justify-center bg-slate-100":91,"w-[112] h-[156] items-center justify-center bg-emerald-700":92,"w-[112] h-[156] items-center justify-center bg-emerald-500":93,"text-sm text-slate-950 font-bold":94,"h-[108] px-6 py-3 flex-col bg-slate-50":95,"h-[84] items-center justify-center bg-slate-300":96,"h-[84] items-center justify-center bg-slate-100":97,"h-[1168] px-6 pt-5 flex-col":98,"h-[82] px-4 justify-center bg-white":99,"w-[584] h-[900] px-5 pt-5 bg-slate-950":100,"text-sm text-slate-200":101,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":102,"text-base text-orange-600 font-bold":103,"w-[584] h-[900] px-5 pt-5 bg-white":104,"text-sm text-slate-900":105,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":106,"absolute inset-0 z-50 flex-col items-center justify-center":107,"absolute inset-0 bg-slate-950":108,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":109,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":110,"flex-row flex-wrap":111,grow:112,"text-2xl text-white font-bold":113,"text-base text-slate-900":114,"px-6":115,"px-6 py-5":116,"gap-4":117,"w-[34] h-[34] rounded-lg bg-amber-400":118,"w-[34] h-[34] rounded-lg bg-red-500":119,"w-[34] h-[34] rounded-lg bg-slate-800":120,"w-[34] h-[34] rounded-lg bg-emerald-500":121,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":122,"flex-row items-center gap-4":123,"w-[34] text-2xl text-white font-bold":124,"w-[332] flex-col items-end gap-2":125,"text-sm text-slate-300 font-bold":126,"text-sm text-slate-400":127,"h-[40] px-1 flex-row items-center justify-between":128,"w-full h-full items-center justify-center rounded-xl bg-slate-200":129,"w-full h-full items-center justify-center rounded-xl bg-orange-600":130};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var g2="ui:styles",w2="ui:font.",E4="ui:img.",N4="ui:sprite.";function C2(){return globalThis.ui}function E2(J){if(J.__textures)return;for(let Q of f0(E4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)e1(Q.slice(E4.length),Z)}}function N2(J){if(J.__sprites)return;for(let Q of f0(N4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)Q4(Q.slice(N4.length),{handle:V,frames:G,cols:P,step:D})}}function h4(J){let Q=z4("view");return EJ(Q,"style",J,void 0),Q}var P0=null,D0=null;function h2(J,Q){if(!P0||!D0)return;EJ(P0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),EJ(D0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function T2(J,Q={}){let $=v6(Q.ops);if(m6($),I8(e8),Q.styles)t8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)e1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)Q4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)x1(Q.pak);if(q8()){for(let B of f0())if(B===g2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(w2))$.ops.loadFontAtlas?.(vJ(B))}}let q=g1($.ops),X=q?.w??k1,z=q?.h??S1,G=h4({width:X,height:z,overflow:u.Overflow.Hidden}),P=h4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});XJ(qJ,G),XJ(qJ,P),W4(P),P0=G,D0=P,v1(G),d1(qJ),Q8(),w4(),O2(),a6(),_2(),u8($.ops),u6(l8((B,_,N,h)=>{r6(),o6(_),X2(N,h),S2(),k2(),D2(),$8(B),V8(B),Z4()}));let D=T8(J,G),V=l6(h2);return()=>{V(),z2(),w4(),D(),v1(null),d1(null),W4(null),P0=null,D0=null;for(let B of qJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);Z4()}}function f2(J,Q={}){let $=Q.ops??C2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)x1(Q.pak);return E2($),N2($),T2(J,{ops:$,styles:Q.styles??b2,pak:Q.pak})}var y2="$b",x2=65536,T4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function u2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function f4(){let J=u2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function l2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,x2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=v2(z.data[y2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function p2(J,Q){let $=l2(f4(),J);return Q==="utf8"||Q==="utf-8"?m2($):$}function c2(J,Q){let $=f4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var d2={title:"text-2xl text-white font-bold",section:"text-sm text-slate-600 font-bold",body:"text-base text-slate-900",bodyStrong:"text-base text-slate-900 font-bold",caption:"text-sm text-slate-500"};function i2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(F,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(F,{class:"flex-row items-center gap-4",get children(){return[p(()=>p(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(F,{get["class"](){return Q()}})),Y(R,{get["class"](){return d2.title},get children(){return J.title}})]}}),Y(F,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-sm text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-sm text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function s2(J){return Y(F,{get["class"](){return J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":"w-full h-full items-center justify-center rounded-xl bg-orange-600"},get children(){return Y(R,{get["class"](){return J.disabled?"text-base text-slate-500 font-bold":"text-base text-white font-bold"},get children(){return J.label}})}})}var uQ="‘’“”–—…•",y4=new Map,x4=new Map;function V0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=y4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return y4.set($,q),q}function a2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=V0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function Z1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=x4.get(Z);if(q)return q;let X=[],z=V0(" ",Q);for(let G of J.split(` +`)){let P=G.split(" ").flatMap((B)=>B&&V0(B,Q)>$?a2(B,Q,$):[B]),D="",V=0;for(let B of P){let _=V0(B,Q);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return x4.set(Z,X),X}function v4(J,Q,$,Z){let q=Z1(J,Q,$);if(q.length<=Z)return q.join(` `);let X=q.slice(0,Z);return X[Z-1]=X[Z-1].replace(/[\s.]+$/,"")+"…",X.join(` -`)}var v4=2,m4=1,u4=536,l4=544,p4=46,[RJ,i2]=C({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[f,n]=C("chat"),[V0,s2]=C("chat"),[Z1,c4]=C(0),[t,d4]=C(""),[dJ,NJ]=C(0),[iJ,q1]=C([]),[a2,L0]=C(""),[i4,O0]=C(null),[s4,a4]=C(null),[I0,A0]=C(0),[v,e]=C(""),[PJ,r4]=C("letters"),[X1,Y1]=C(!1),[z1,o4]=C({type:"prompt"}),[sJ,n4]=C(0),W1=new Map,t4=["qwertyuiop","asdfghjkl","zxcvbnm"],e4=["1234567890","-/:;()$&@",`.,?!'"+`],J6=["chat","files","apps","settings"];function r2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function o2(J,Q){return J?J+"/"+Q:Q}function aJ(J=t(),Q=!1){let $=W1.get(J);if(!Q&&$){q1($),L0(""),NJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=u2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));W1.set(J,Z),q1(Z),L0(""),NJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){q1([]),L0(Z instanceof Error?Z.message:String(Z))}}function n2(){let J=[];for(let Q of RJ().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Q6(){let J=n2(),Q=Math.max(0,J.length-2),$=Math.min(Z1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function DJ(J){return Y(p2,{get title(){return J.title},get accent(){return p(()=>RJ().agent==="FAULTED")()?"danger":RJ().agent==="THINKING"?"busy":"ready"}})}function rJ(J){return[Y(F,{get["class"](){return J.top},get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",children:"UP"})}}),Y(F,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",children:"DN"})}})]}function _0(){return Y(F,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(kJ,{each:J6,children:(J)=>Y(F,{get["class"](){return V0()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-sm text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function t2(){let J=()=>RJ().schedule;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"ESP32 PI AGENT"}),Y(F,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(kJ,{get each(){return Q6()},children:(Q)=>Y(F,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-sm text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-base text-slate-900",get children(){return f4(Q.user,v4,u4,3)}}),Y(F,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-sm text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-base text-slate-900",get children(){return f4(Q.assistant,v4,u4,3)}})]}})}),Y(rJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(F,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-sm text-slate-600 font-bold",children:"NEXT WAKE"}),Y(SJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-base text-slate-500",children:`NO WAKE SCHEDULED +`)}var m4=2,u4=1,l4=536,p4=544,c4=46,[PJ,r2]=g({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[y,n]=g("chat"),[L0,o2]=g("chat"),[q1,d4]=g(0),[t,i4]=g(""),[iJ,hJ]=g(0),[sJ,X1]=g([]),[n2,O0]=g(""),[s4,I0]=g(null),[a4,r4]=g(null),[A0,_0]=g(0),[v,e]=g(""),[DJ,o4]=g("letters"),[Y1,z1]=g(!1),[W1,n4]=g({type:"prompt"}),[GJ,t4]=g(null),[aJ,e4]=g(0),G1=new Map,J6=["qwertyuiop","asdfghjkl","zxcvbnm"],Q6=["1234567890","-/:;()$&@",`.,?!'"+`],$6=["chat","files","apps","settings"];function t2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function e2(J,Q){return J?J+"/"+Q:Q}function rJ(J=t(),Q=!1){let $=G1.get(J);if(!Q&&$){X1($),O0(""),hJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=c2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));G1.set(J,Z),X1(Z),O0(""),hJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){X1([]),O0(Z instanceof Error?Z.message:String(Z))}}function JQ(){let J=[];for(let Q of PJ().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Z6(){let J=JQ(),Q=Math.max(0,J.length-2),$=Math.min(q1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function VJ(J){return Y(i2,{get title(){return J.title},get accent(){return p(()=>PJ().agent==="FAULTED")()?"danger":PJ().agent==="THINKING"?"busy":"ready"}})}function oJ(J){return[Y(F,{get["class"](){return J.top},get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",children:"UP"})}}),Y(F,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",children:"DN"})}})]}function k0(){return Y(F,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(SJ,{each:$6,children:(J)=>Y(F,{get["class"](){return L0()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-sm text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function QQ(){let J=()=>PJ().schedule;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"ESP32 PI AGENT"}),Y(F,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(SJ,{get each(){return Z6()},children:(Q)=>Y(F,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-sm text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-base text-slate-900",get children(){return v4(Q.user,m4,l4,3)}}),Y(F,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-sm text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-base text-slate-900",get children(){return v4(Q.assistant,m4,l4,3)}})]}})}),Y(oJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(F,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-sm text-slate-600 font-bold",children:"NEXT WAKE"}),Y(bJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-base text-slate-500",children:`NO WAKE SCHEDULED ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(R,{class:"pt-6 text-base text-slate-900 font-bold",get children(){return String(J()?.name)+" "+String(J()?.next??"")+` -`+String(J()?.prompt??"")}})}})]}}),Y(F,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(F,{class:"h-[80]",get children(){return Y(c2,{label:"TYPE A MESSAGE"})}})}}),Y(_0,{})]}})}function e2(){let J=()=>iJ().slice(dJ(),dJ()+8);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{get title(){return t()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-600",get children(){return"/workspace"+(t()?"/"+t():"")}})}}),Y(F,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(kJ,{get each(){return J()},children:(Q)=>Y(F,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(F,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-base text-blue-700 font-bold":"text-base text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(F,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,60)}}),Y(R,{class:"text-sm text-slate-500",get children(){return p(()=>Q.kind==="dir")()?"FOLDER":r2(Q.size)}})]}})]}})})}}),Y(SJ,{get when(){return iJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-base text-slate-500",get children(){return a2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(SJ,{get when(){return iJ().length>8},get children(){return Y(rJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(_0,{})]}})}function JQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"APPS"}),Y(F,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-sm text-slate-500 font-bold",children:"2 INSTALLED APPS"}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-emerald-100",get children(){return Y(R,{class:"text-xl text-emerald-700 font-bold",children:"R"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"Robinhood"}),Y(R,{class:"text-base text-slate-600",children:"Portfolio and positions"}),Y(R,{class:"text-sm text-slate-500",children:"UPDATES EVERY 5 MINUTES"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-indigo-100",get children(){return Y(R,{class:"text-xl text-indigo-700 font-bold",children:"E"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"Exa Research"}),Y(R,{class:"text-base text-slate-600",children:"Agent search history"}),Y(R,{class:"text-sm text-slate-500",children:"STORED LOCALLY IN SQLITE"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-600",children:`APP DATA STAYS ISOLATED. -PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(_0,{})]}})}function QQ(){let J=()=>RJ().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(sJ(),sJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"SETTINGS"}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-base text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-sm text-slate-500",get children(){return Z()}}),Y(F,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-sm text-slate-500",children:"AVAILABLE NETWORKS"}),Y(F,{class:"h-[470] flex-col gap-2",get children(){return[Y(SJ,{get when(){return $().length>0},get fallback(){return Y(F,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-500 font-bold",children:`NO NETWORK LIST YET +`+String(J()?.prompt??"")}})}})]}}),Y(F,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(F,{class:"h-[80]",get children(){return Y(s2,{label:"TYPE A MESSAGE"})}})}}),Y(k0,{})]}})}function $Q(){let J=()=>sJ().slice(iJ(),iJ()+8);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return t()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-600",get children(){return"/workspace"+(t()?"/"+t():"")}})}}),Y(F,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(SJ,{get each(){return J()},children:(Q)=>Y(F,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(F,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-base text-blue-700 font-bold":"text-base text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(F,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,60)}}),Y(R,{class:"text-sm text-slate-500",get children(){return p(()=>Q.kind==="dir")()?"FOLDER":t2(Q.size)}})]}})]}})})}}),Y(bJ,{get when(){return sJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-base text-slate-500",get children(){return n2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(bJ,{get when(){return sJ().length>8},get children(){return Y(oJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(k0,{})]}})}function ZQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"APPS"}),Y(F,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-sm text-slate-500 font-bold",children:"2 INSTALLED APPS"}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-emerald-100",get children(){return Y(R,{class:"text-xl text-emerald-700 font-bold",children:"R"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"Robinhood"}),Y(R,{class:"text-base text-slate-600",children:"Portfolio and positions"}),Y(R,{class:"text-sm text-slate-500",children:"UPDATES EVERY 5 MINUTES"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-indigo-100",get children(){return Y(R,{class:"text-xl text-indigo-700 font-bold",children:"E"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"Exa Research"}),Y(R,{class:"text-base text-slate-600",children:"Agent search history"}),Y(R,{class:"text-sm text-slate-500",children:"STORED LOCALLY IN SQLITE"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-600",children:`APP DATA STAYS ISOLATED. +PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(k0,{})]}})}function qQ(){let J=()=>PJ().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(aJ(),aJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"SETTINGS"}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-base text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-sm text-slate-500",get children(){return Z()}}),Y(F,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-sm text-slate-500",children:"AVAILABLE NETWORKS"}),Y(F,{class:"h-[470] flex-col gap-2",get children(){return[Y(bJ,{get when(){return $().length>0},get fallback(){return Y(F,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-500 font-bold",children:`NO NETWORK LIST YET -TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(kJ,{get each(){return $()},children:(q)=>Y(F,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-sm text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(SJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(rJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(F,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-sm text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-base text-slate-900 font-bold",get children(){return RJ().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-sm text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(F,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(F,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(F,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-base text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(_0,{})]}})}function $Q(){let J=()=>z1(),Q=()=>PJ()==="letters"?t4:e4,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(F,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(F,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-sm text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(F,{class:"w-[132] h-[58] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(kJ,{get each(){return Q()},children:(Z,q)=>Y(F,{class:"h-[140] flex-row gap-2",get children(){return[Y(kJ,{get each(){return Z.split("")},children:(X)=>Y(F,{class:"grow h-[120] items-center justify-center bg-white",get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return p(()=>!!X1())()?X.toUpperCase():X}})}})}),Y(SJ,{get when(){return q()===2},get children(){return Y(F,{class:"w-[104] h-[120] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(F,{class:"h-[176] flex-row gap-2",get children(){return[Y(F,{class:"w-[92] h-[156] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",get children(){return PJ()==="letters"?"123":"ABC"}})}}),Y(F,{class:"w-[300] h-[156] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"SPACE"})}}),Y(F,{class:"w-[144] h-[156] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",get children(){return PJ()==="letters"?"SHIFT":". ?"}})}}),Y(F,{class:"w-[112] h-[156] items-center justify-center bg-emerald-500",get children(){return Y(R,{class:"text-sm text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(F,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(F,{class:"h-[84] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function ZQ(){let J=()=>i4(),Q=()=>(J()?.text??"").split(` -`),$=()=>J()?.lineOffset??0;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"< FILE VIEWER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(R,{class:"text-sm text-slate-200",get children(){return Q().slice($(),$()+39).join(` -`)}})}}),Y(R,{class:"pt-3 text-sm text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(rJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function qQ(){let J=()=>s4(),Q=()=>$1(J()?.text??"",m4,l4);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(DJ,{title:"< MESSAGE READER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-base text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-sm text-slate-900",get children(){return Q().slice(I0(),I0()+p4).join(` -`)}})}}),Y(rJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function XQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return p(()=>f()==="chat")()?Y(t2,{}):p(()=>f()==="files")()?Y(e2,{}):p(()=>f()==="apps")()?Y(JQ,{}):p(()=>f()==="settings")()?Y(QQ,{}):p(()=>f()==="keyboard")()?Y($Q,{}):p(()=>f()==="viewer")()?Y(ZQ,{}):Y(qQ,{})}})}function YQ(J){G6(()=>{if(s2(J),n(J),J==="files")aJ()})}function zQ(J,Q){let $=PJ()==="letters"?t4:e4,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return e(""),n(V0()),"";if(J>=548&&Q>=402&&Q<=482)return e(""),"";let $=zQ(J,Q);if($){let Z=PJ()==="letters"&&X1()?$.toUpperCase():$,q=z1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return e(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)r4(PJ()==="letters"?"numbers":"letters"),Y1(!1);else if(J<=424){if(v())e(v()+" ")}else if(J<=576)if(PJ()==="letters")Y1(!X1());else e(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=z1();if(e(""),r4("letters"),Y1(!1),n(V0()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}N2(()=>Y(XQ,{})),queueMicrotask(()=>aJ("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return i2(JSON.parse(J)),""},dataChanged(){if(W1.delete(t()),V0()==="files")aJ(t(),!0);return""},invokeTool(){return JSON.stringify({text:"Pi Agent has no App tools",isError:!0})},invokeTask(){return JSON.stringify({text:"Pi Agent has no App tasks",isError:!0})},tap(J,Q){if(f()==="keyboard")return WQ(J,Q);if(f()==="viewer"){let $=i4();if(J<104&&Q<112)O0(null),n("files");else if($&&J>=620&&Q>=170&&Q<=340)O0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)O0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` -`).length-39),$.lineOffset+18)});return""}if(f()==="reader"){if(J<104&&Q<112)a4(null),A0(0),n("chat");else if(J>=620&&Q>=170&&Q<=340)A0(Math.max(0,I0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=$1(s4()?.text??"",m4,l4).length;A0(Math.min(Math.max(0,$-p4),I0()+18))}return""}if(Q>=1172)return YQ(J6[Math.min(3,Math.floor(J/180))]),"";if(f()==="chat"){if(J>=620&&Q>=140&&Q<=272)c4(Z1()+2);else if(J>=620&&Q>=624&&Q<=756)c4(Math.max(0,Z1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=Q6()[$];if(Z){let q=Q>=140+$*320+150;a4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),A0(0),n("reader")}}else if(Q>=1070&&Q<=1150)o4({type:"prompt"}),e(""),n("keyboard");return""}if(f()==="files"){if(J<104&&Q<112&&t()){let $=t().split("/");$.pop();let Z=$.join("/");d4(Z),NJ(0),aJ(Z)}else if(J>=620&&Q>=170&&Q<=340)NJ(Math.max(0,dJ()-4));else if(J>=620&&Q>=920&&Q<=1100)NJ(Math.min(Math.max(0,iJ().length-8),dJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=iJ()[dJ()+$];if(Z){let q=o2(t(),Z.name);if(Z.kind==="dir")d4(q),NJ(0),aJ(q);else try{O0({path:"/workspace/"+q,text:m2(q,"utf8"),lineOffset:0}),n("viewer")}catch(X){L0(X instanceof Error?X.message:String(X))}}}return""}if(f()==="apps"){if(Q>=162&&Q<324)return JSON.stringify({type:"navigate",app:"robinhood"});if(Q>=324&&Q<490)return JSON.stringify({type:"navigate",app:"exa"});return""}if(f()==="settings"){let $=RJ().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)n4(Math.max(0,sJ()-4));else if(J>=620&&Q>=650&&Q<=782)n4(Math.min(Math.max(0,$.length-5),sJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[sJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});o4({type:"wifi",ssid:q.ssid}),e(""),n("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); +TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(SJ,{get each(){return $()},children:(q)=>Y(F,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-sm text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(bJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(oJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(F,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-sm text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-base text-slate-900 font-bold",get children(){return PJ().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-sm text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(F,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(F,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(F,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-base text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(k0,{})]}})}function XQ(){let J=()=>W1(),Q=()=>DJ()==="letters"?J6:Q6,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(F,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(F,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-sm text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(F,{get["class"](){return GJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(SJ,{get each(){return Q()},children:(Z,q)=>Y(F,{class:"h-[140] flex-row gap-2",get children(){return[Y(SJ,{get each(){return Z.split("")},children:(X)=>Y(F,{get["class"](){return GJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return p(()=>!!Y1())()?X.toUpperCase():X}})}})}),Y(bJ,{get when(){return q()===2},get children(){return Y(F,{get["class"](){return GJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(F,{class:"h-[176] flex-row gap-2",get children(){return[Y(F,{get["class"](){return GJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",get children(){return DJ()==="letters"?"123":"ABC"}})}}),Y(F,{get["class"](){return GJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"SPACE"})}}),Y(F,{get["class"](){return GJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",get children(){return DJ()==="letters"?"SHIFT":". ?"}})}}),Y(F,{get["class"](){return GJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(R,{class:"text-sm text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(F,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(F,{get["class"](){return GJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function YQ(){let J=()=>s4(),Q=()=>(J()?.text??"").split(` +`),$=()=>J()?.lineOffset??0;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< FILE VIEWER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(R,{class:"text-sm text-slate-200",get children(){return Q().slice($(),$()+39).join(` +`)}})}}),Y(R,{class:"pt-3 text-sm text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(oJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function zQ(){let J=()=>a4(),Q=()=>Z1(J()?.text??"",u4,p4);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< MESSAGE READER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-base text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-sm text-slate-900",get children(){return Q().slice(A0(),A0()+c4).join(` +`)}})}}),Y(oJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function WQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return p(()=>y()==="chat")()?Y(QQ,{}):p(()=>y()==="files")()?Y($Q,{}):p(()=>y()==="apps")()?Y(ZQ,{}):p(()=>y()==="settings")()?Y(qQ,{}):p(()=>y()==="keyboard")()?Y(XQ,{}):p(()=>y()==="viewer")()?Y(YQ,{}):Y(zQ,{})}})}function GQ(J){j6(()=>{if(o2(J),n(J),J==="files")rJ()})}function q6(J,Q){let $=DJ()==="letters"?J6:Q6,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=q6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function BQ(J,Q){if(Q>=1164)return e(""),n(L0()),"";if(J>=548&&Q>=402&&Q<=482)return e(""),"";let $=q6(J,Q);if($){let Z=DJ()==="letters"&&Y1()?$.toUpperCase():$,q=W1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return e(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)o4(DJ()==="letters"?"numbers":"letters"),z1(!1);else if(J<=424){if(v())e(v()+" ")}else if(J<=576)if(DJ()==="letters")z1(!Y1());else e(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=W1();if(e(""),o4("letters"),z1(!1),n(L0()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}f2(()=>Y(WQ,{})),queueMicrotask(()=>rJ("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return r2(JSON.parse(J)),""},dataChanged(){if(G1.delete(t()),L0()==="files")rJ(t(),!0);return""},invokeTool(){return JSON.stringify({text:"Pi Agent has no App tools",isError:!0})},invokeTask(){return JSON.stringify({text:"Pi Agent has no App tasks",isError:!0})},pointerDown(J,Q){return t4(y()==="keyboard"?HQ(J,Q):null),""},pointerUp(){return t4(null),""},tap(J,Q){if(y()==="keyboard")return BQ(J,Q);if(y()==="viewer"){let $=s4();if(J<104&&Q<112)I0(null),n("files");else if($&&J>=620&&Q>=170&&Q<=340)I0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)I0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` +`).length-39),$.lineOffset+18)});return""}if(y()==="reader"){if(J<104&&Q<112)r4(null),_0(0),n("chat");else if(J>=620&&Q>=170&&Q<=340)_0(Math.max(0,A0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=Z1(a4()?.text??"",u4,p4).length;_0(Math.min(Math.max(0,$-c4),A0()+18))}return""}if(Q>=1172)return GQ($6[Math.min(3,Math.floor(J/180))]),"";if(y()==="chat"){if(J>=620&&Q>=140&&Q<=272)d4(q1()+2);else if(J>=620&&Q>=624&&Q<=756)d4(Math.max(0,q1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=Z6()[$];if(Z){let q=Q>=140+$*320+150;r4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),_0(0),n("reader")}}else if(Q>=1070&&Q<=1150)n4({type:"prompt"}),e(""),n("keyboard");return""}if(y()==="files"){if(J<104&&Q<112&&t()){let $=t().split("/");$.pop();let Z=$.join("/");i4(Z),hJ(0),rJ(Z)}else if(J>=620&&Q>=170&&Q<=340)hJ(Math.max(0,iJ()-4));else if(J>=620&&Q>=920&&Q<=1100)hJ(Math.min(Math.max(0,sJ().length-8),iJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=sJ()[iJ()+$];if(Z){let q=e2(t(),Z.name);if(Z.kind==="dir")i4(q),hJ(0),rJ(q);else try{I0({path:"/workspace/"+q,text:p2(q,"utf8"),lineOffset:0}),n("viewer")}catch(X){O0(X instanceof Error?X.message:String(X))}}}return""}if(y()==="apps"){if(Q>=162&&Q<324)return JSON.stringify({type:"navigate",app:"robinhood"});if(Q>=324&&Q<490)return JSON.stringify({type:"navigate",app:"exa"});return""}if(y()==="settings"){let $=PJ().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)e4(Math.max(0,aJ()-4));else if(J>=620&&Q>=650&&Q<=782)e4(Math.min(Math.max(0,$.length-5),aJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[aJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});n4({type:"wifi",ssid:q.ssid}),e(""),n("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); diff --git a/apps/pi-agent/dist/app.pak b/apps/pi-agent/dist/app.pak index 59847a83fdcd8c1ae6e25dad35cbda2ecbf22d95..1037dbbb1e3d3a3d1febb0a503f3feab87c52b6f 100644 GIT binary patch delta 137 zcmbQRN@~IysR@#d( Result<()> { + self.call_optional_method("pointerDown", (x as i32, y as i32)) + } + + pub fn pointer_up(&self) -> Result<()> { + self.call_optional_method("pointerUp", ()) + } + pub fn invoke_tool(&self, name: &str, args_json: &str) -> Result { let line: String = self.call_method("invokeTool", (name.to_owned(), args_json.to_owned()))?; @@ -697,6 +705,26 @@ impl AppRuntime { .map_err(|error| anyhow!("PocketPiApp.{name}: {error}")) }) } + + fn call_optional_method
(&self, name: &str, args: A) -> Result<()> + where + A: for<'js> pocket_mod::qjs::function::IntoArgs<'js>, + { + self.guest.with(|ctx| { + let app: Object = ctx + .globals() + .get("PocketPiApp") + .map_err(|error| anyhow!("PocketPiApp missing: {error}"))?; + let Some(function) = app.get::<_, Function>(name).ok() else { + return Ok(()); + }; + function + .call::<_, String>(args) + .catch(&ctx) + .map_err(|error| anyhow!("PocketPiApp.{name}: {error}"))?; + Ok(()) + }) + } } #[cfg(not(target_os = "espidf"))] @@ -998,6 +1026,14 @@ impl AppSupervisor { self.active().tap(x, y) } + pub fn pointer_down(&self, x: u16, y: u16) -> Result<()> { + self.active().pointer_down(x, y) + } + + pub fn pointer_up(&self) -> Result<()> { + self.active().pointer_up() + } + pub fn with_ui(&self, f: impl FnOnce(&mut pocketjs_core::Ui) -> R) -> R { self.active().with_ui(f) } @@ -1666,6 +1702,28 @@ mod tests { assert_eq!(action["command"], "scan"); } + #[test] + fn keyboard_key_has_a_bounded_pointer_down_visual_state() { + let temp = tempfile::tempdir().unwrap(); + let supervisor = AppSupervisor::new(temp.path(), Arc::new(NoServices)).unwrap(); + + // Open the prompt keyboard, then press Q without invoking the key. The + // DrawList must change only while the pointer is held down. + supervisor.tap(300, 1110).unwrap(); + supervisor.frame().unwrap(); + let idle = supervisor.with_ui(|ui| ui.draw().words.clone()); + + supervisor.pointer_down(50, 520).unwrap(); + supervisor.frame().unwrap(); + let pressed = supervisor.with_ui(|ui| ui.draw().words.clone()); + assert_ne!(pressed, idle); + + supervisor.pointer_up().unwrap(); + supervisor.frame().unwrap(); + let released = supervisor.with_ui(|ui| ui.draw().words.clone()); + assert_eq!(released, idle); + } + #[test] fn pi_agent_system_app_survives_foreground_app_navigation() { let temp = tempfile::tempdir().unwrap(); diff --git a/firmware/esp32-p4/src/agentos_main.rs b/firmware/esp32-p4/src/agentos_main.rs index 66f922f..33389dd 100644 --- a/firmware/esp32-p4/src/agentos_main.rs +++ b/firmware/esp32-p4/src/agentos_main.rs @@ -185,6 +185,7 @@ pub fn run() -> anyhow::Result<()> { if let Some(display) = display.as_mut() { if let Some((x, y)) = display.read_touch() { if !touch_was_down { + supervisor.pointer_down(x, y)?; let action = supervisor.tap(x, y)?; match action.get("type").and_then(Value::as_str) { Some("navigate") => { @@ -280,6 +281,10 @@ pub fn run() -> anyhow::Result<()> { } touch_was_down = true; } else { + if touch_was_down { + supervisor.pointer_up()?; + redraw = true; + } touch_was_down = false; } } diff --git a/hosts/esp32-p4-sim/src/main.rs b/hosts/esp32-p4-sim/src/main.rs index e2d43a6..a3cfbe6 100644 --- a/hosts/esp32-p4-sim/src/main.rs +++ b/hosts/esp32-p4-sim/src/main.rs @@ -450,6 +450,15 @@ impl Product { Ok(()) } + fn pointer_down(&mut self, x: u16, y: u16) -> Result<()> { + self.supervisor.pointer_down(x, y)?; + self.tap(x, y) + } + + fn pointer_up(&mut self) -> Result<()> { + self.supervisor.pointer_up() + } + fn run_pending_ui_task(&mut self) { let Some(task) = self.pending_ui_task.take() else { return; @@ -770,7 +779,7 @@ impl ApplicationHandler for WindowApp { .. } if !state.touch_down => { state.touch_down = true; - if let Err(error) = state.product.tap(state.cursor.0, state.cursor.1) { + if let Err(error) = state.product.pointer_down(state.cursor.0, state.cursor.1) { self.error = Some(error); event_loop.exit(); } @@ -779,7 +788,13 @@ impl ApplicationHandler for WindowApp { button: MouseButton::Left, state: ElementState::Released, .. - } => state.touch_down = false, + } => { + state.touch_down = false; + if let Err(error) = state.product.pointer_up() { + self.error = Some(error); + event_loop.exit(); + } + } WindowEvent::KeyboardInput { event, .. } if event.state == ElementState::Pressed && matches!(event.physical_key, PhysicalKey::Code(KeyCode::Escape)) => From 2fd0182ff7404b0e77260a345a21fdda45ae1d10 Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Mon, 10 Aug 2026 13:46:43 +0800 Subject: [PATCH 06/24] fix(esp32): reduce touch polling latency --- firmware/esp32-p4/src/agentos_main.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/esp32-p4/src/agentos_main.rs b/firmware/esp32-p4/src/agentos_main.rs index 33389dd..3f75f9f 100644 --- a/firmware/esp32-p4/src/agentos_main.rs +++ b/firmware/esp32-p4/src/agentos_main.rs @@ -490,10 +490,10 @@ pub fn run() -> anyhow::Result<()> { ); last_heartbeat = Instant::now(); } - // AgentOS is a native FreeRTOS task, not a pthread. Use the native - // delay primitive so CPU0's idle task is guaranteed a scheduling - // window and can feed the task watchdog. - unsafe { esp_idf_svc::sys::vTaskDelay(16) }; + // AgentOS is a native FreeRTOS task, not a pthread. The firmware uses + // a 100 Hz tick, so one tick polls touch every 10 ms while still + // giving CPU0's idle task a watchdog-feeding scheduling window. + unsafe { esp_idf_svc::sys::vTaskDelay(1) }; } } From c5861b920749865a2e11e564edef84a00ba104d0 Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Mon, 10 Aug 2026 15:48:07 +0800 Subject: [PATCH 07/24] feat(agent): add DeepSeek V4 backend and fix chart rendering --- Cargo.lock | 1 + Cargo.toml | 1 + README.md | 12 +- apps/pi-agent/dist/agent.js | 31 +- apps/robinhood/app.tsx | 2 +- apps/robinhood/dist/app.js | 2 +- crates/pocket-pi-agentos/src/lib.rs | 37 +- crates/pocket-pi-embedded/Cargo.toml | 1 + .../pocket-pi-embedded/js/pi-agent.bundle.js | 31 +- crates/pocket-pi-embedded/js/src/entry.ts | 222 +++++++-- crates/pocket-pi-embedded/src/lib.rs | 281 +++++++++--- .../src/anthropic_messages.rs | 112 +++-- .../pocket-pi-protocols/src/codex_decision.rs | 74 ++- crates/pocket-pi-protocols/src/model.rs | 37 +- crates/pocket-pi-protocols/src/openai_chat.rs | 428 +++++++++++++----- crates/pocket-pi-tools/src/lib.rs | 44 +- docs/agentos-architecture.md | 4 +- docs/esp32-p4-port.md | 4 +- firmware/esp32-p4/Cargo.lock | 1 + firmware/esp32-p4/src/agentos_main.rs | 9 +- firmware/esp32-p4/src/backend/uart.rs | 6 +- firmware/esp32-p4/src/backend/wireless.rs | 37 +- .../esp32-p4/src/transport/provisioning.rs | 12 +- hosts/esp32-p4-sim/src/backend.rs | 49 +- tools/uart-model-bridge.py | 58 +-- tools/uart_bridge/backends.py | 46 +- 26 files changed, 1145 insertions(+), 397 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7555eb..9661827 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2618,6 +2618,7 @@ name = "pocket-pi-embedded" version = "0.1.0" dependencies = [ "pocket-mod", + "pocket-pi-protocols", "rquickjs", "serde_json", ] diff --git a/Cargo.toml b/Cargo.toml index 46d91fc..7a0f7d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ repository = "https://github.com/pocket-stack/pocket-pi" [workspace.dependencies] anyhow = "1" log = "0.4" +pocket-pi-protocols = { path = "crates/pocket-pi-protocols" } serde = { version = "1", default-features = false, features = ["derive", "alloc"] } serde_json = { version = "1", default-features = false, features = ["alloc"] } diff --git a/README.md b/README.md index 2a601ac..56d1791 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,9 @@ OPENROUTER_API_KEY=... \ ANTHROPIC_API_KEY=... \ cargo xtask run esp32-p4-sim \ --backend anthropic --model claude-sonnet-4-6 + +DEEPSEEK_API_KEY=... DEEPSEEK_THINKING_LEVEL=xhigh \ + cargo xtask run esp32-p4-sim --backend deepseek ``` The window uses the ESP32's 720x1280 coordinate system. Mouse input is mapped @@ -170,14 +173,19 @@ Backends belong to their host composition, not to the Agent core: | Host | Supported backends | |---|---| | Native macOS | OpenAI, Anthropic, offline Faux Provider | -| ESP32 simulator | local Codex, OpenAI, OpenRouter, Anthropic | -| Physical ESP32-P4 | UART to Mac Codex or Claude Code; wireless OpenAI, OpenRouter or Anthropic | +| ESP32 simulator | local Codex, OpenAI, OpenRouter, Anthropic, DeepSeek V4 | +| Physical ESP32-P4 | UART to Mac Codex or Claude Code; wireless OpenAI, OpenRouter, Anthropic or DeepSeek V4 | `UartBackend` and `WirelessBackend` expose the same streaming model boundary to the embedded Agent. Provider request/streaming codecs live in `pocket-pi-protocols`; serial framing, desktop CLIs and ESP-IDF HTTPS stay in their platform layers. +DeepSeek defaults to `deepseek-v4-pro` with thinking level `high`. Set +`DEEPSEEK_THINKING_LEVEL=xhigh` in the simulator, or pass +`--thinking-level xhigh` while provisioning the physical board, to request the +provider's `max` reasoning effort. + ## Embedded Agent capabilities The simulator and physical firmware register the same portable core tools: diff --git a/apps/pi-agent/dist/agent.js b/apps/pi-agent/dist/agent.js index ffd4260..806a0e8 100644 --- a/apps/pi-agent/dist/agent.js +++ b/apps/pi-agent/dist/agent.js @@ -384,16 +384,21 @@ if(this.activeRun){throw new Error("Agent is already processing.")}const abortCo const failureMessage={role:"assistant",content:[{type:"text",text:""}],api:this._state.model.api,provider:this._state.model.provider,model:this._state.model.id,usage:EMPTY_USAGE,stopReason:aborted?"aborted":"error",errorMessage:error instanceof Error?error.message:String(error),timestamp:Date.now()};await this.processEvents({type:"message_start",message:failureMessage});await this.processEvents({type:"message_end",message:failureMessage});await this.processEvents({type:"turn_end",message:failureMessage, toolResults:[]});await this.processEvents({type:"agent_end",messages:[failureMessage]})}finishRun(){this._state.isStreaming=false;this._state.streamingMessage=void 0;this._state.pendingToolCalls=new Set;this.activeRun?.resolve();this.activeRun=void 0}async processEvents(event){switch(event.type){case"message_start":this._state.streamingMessage=event.message;break;case"message_update":this._state.streamingMessage=event.message;break;case"message_end":this._state.streamingMessage=void 0;this._state. messages.push(event.message);break;case"tool_execution_start":{const pendingToolCalls=new Set(this._state.pendingToolCalls);pendingToolCalls.add(event.toolCallId);this._state.pendingToolCalls=pendingToolCalls;break}case"tool_execution_end":{const pendingToolCalls=new Set(this._state.pendingToolCalls);pendingToolCalls.delete(event.toolCallId);this._state.pendingToolCalls=pendingToolCalls;break}case"turn_end":if(event.message.role==="assistant"&&event.message.errorMessage){this._state.errorMessage= -event.message.errorMessage}break;case"agent_end":this._state.streamingMessage=void 0;break}const signal=this.activeRun?.abortController.signal;if(!signal){throw new Error("Agent listener invoked outside active run")}for(const listener of this.listeners){await listener(event,signal)}}};var events=[];var pendingModels=new Map;var pendingTools=new Map;var agent=null;var emptyUsage=()=>({input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}});function modelFor(config){const provider=config.provider||"openai";return{id:config.model||"gpt-5-mini",name:config.model||"gpt-5-mini",provider,api:provider==="anthropic"?"anthropic-messages":"openai-responses",baseUrl:provider==="anthropic"?"https://api.anthropic.com":"https://api.\ -openai.com/v1",reasoning:false,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:128e3,maxTokens:1024}}function hostStream(model,context){const stream=new AssistantMessageEventStream;const partial={role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,usage:emptyUsage(),stopReason:"stop",timestamp:Date.now()};try{if(!globalThis.host)throw new Error("Pocket Pi Agent host is unavailable");const id=globalThis.host.startModel(JSON.stringify({model, -context}));pendingModels.set(id,{stream,model,partial,started:false,textStarted:false,text:""})}catch(error){pushModelError(stream,model,String(error))}return stream}function ensureModelStarted(pending){if(pending.started)return;pending.started=true;pending.stream.push({type:"start",partial:{...pending.partial}})}function pushModelDelta(pending,delta){ensureModelStarted(pending);if(!pending.textStarted){pending.textStarted=true;pending.stream.push({type:"text_start",contentIndex:0,partial:{...pending. -partial}})}pending.text+=delta;pending.partial.content=[{type:"text",text:pending.text}];pending.stream.push({type:"text_delta",contentIndex:0,delta,partial:{...pending.partial}})}function finishModel(pending,result){ensureModelStarted(pending);pending.partial.stopReason=result.stopReason||"stop";if(result.toolCall){const toolCall={type:"toolCall",id:result.toolCall.id||`tool_${Date.now()}`,name:result.toolCall.name,arguments:result.toolCall.arguments||{}};pending.partial.content=[toolCall];pending. -partial.stopReason="toolUse";pending.stream.push({type:"toolcall_start",contentIndex:0,partial:{...pending.partial}});pending.stream.push({type:"toolcall_end",contentIndex:0,toolCall,partial:{...pending.partial}});pending.stream.push({type:"done",reason:"toolUse",message:{...pending.partial}});return}const finalText=String(result.text||pending.text);if(!pending.textStarted||finalText!==pending.text){const delta=finalText.startsWith(pending.text)?finalText.slice(pending.text.length):finalText;if(delta) -pushModelDelta(pending,delta)}if(!pending.textStarted)pushModelDelta(pending,"");pending.text=finalText;pending.partial.content=[{type:"text",text:finalText}];pending.stream.push({type:"text_end",contentIndex:0,content:finalText,partial:{...pending.partial}});pending.stream.push({type:"done",reason:pending.partial.stopReason,message:{...pending.partial}})}function pushModelError(stream,model,message){stream.push({type:"error",reason:"error",error:{role:"assistant",content:[],api:model.api,provider:model. -provider,model:model.id,usage:emptyUsage(),stopReason:"error",errorMessage:message,timestamp:Date.now()}})}function boot(configJson){const config=JSON.parse(configJson);const model=modelFor(config);const tools=(config.tools||[]).map(tool=>({name:tool.name,label:tool.label||tool.name,description:tool.description||"",parameters:tool.parameters||{type:"object",properties:{}},executionMode:"sequential",execute:(id,args)=>new Promise((resolve,reject)=>{try{if(!globalThis.host)throw new Error("Pocket \ -Pi Agent host is unavailable");const requestId=globalThis.host.startTool(id,tool.name,JSON.stringify(args||{}));pendingTools.set(requestId,{resolve,reject})}catch(error){reject(error instanceof Error?error:new Error(String(error)))}})}));agent=new Agent({initialState:{systemPrompt:config.systemPrompt||"You are Pocket Pi running on an embedded device.",model,thinkingLevel:"off",tools},streamFn:hostStream,toolExecution:"sequential"});agent.subscribe(event=>{const compact={type:event.type};if(event. -type==="message_update"){compact.kind=event.assistantMessageEvent?.type;compact.delta=event.assistantMessageEvent?.delta}else if(event.type==="message_end"){compact.role=event.message?.role;compact.stopReason=event.message?.stopReason}else if(event.type==="tool_execution_start"||event.type==="tool_execution_end"){compact.name=event.toolName;compact.toolCallId=event.toolCallId;compact.isError=Boolean(event.isError)}events.push(compact)});events.push({type:"agent_ready"})}function prompt(text){if(!agent) -throw new Error("prompt before boot");void agent.prompt(text).catch(error=>events.push({type:"agent_error",message:String(error)}))}function abort(){agent?.abort()}function tick(){const batch=JSON.parse(globalThis.host?.poll()||"[]");for(const event of batch){if(event.type==="model_delta"){const pending=pendingModels.get(event.id);if(pending)pushModelDelta(pending,String(event.delta||""))}else if(event.type==="model_done"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels. -delete(event.id);try{finishModel(pending,JSON.parse(event.result||"{}"))}catch(error){pushModelError(pending.stream,pending.model,String(error))}}else if(event.type==="model_error"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);pushModelError(pending.stream,pending.model,event.error)}else if(event.type==="tool_done"){const pending=pendingTools.get(event.id);if(!pending)continue;pendingTools.delete(event.id);try{const result=JSON.parse(event.result|| -"{}");if(result.isError)throw new Error(String(result.text||"App tool failed"));pending.resolve({content:[{type:"text",text:String(result.text||"")}],details:result.details,terminate:Boolean(result.terminate)})}catch(error){pending.reject(error instanceof Error?error:new Error(String(error)))}}}}function drain(){return JSON.stringify({phase:agent?.state.isStreaming?"thinking":agent?"ready":"idle",messages:agent?.state.messages.length||0,events:events.splice(0,events.length)})}globalThis.PocketPiEmbedded= -{boot,prompt,abort,tick,drain};})(); +event.message.errorMessage}break;case"agent_end":this._state.streamingMessage=void 0;break}const signal=this.activeRun?.abortController.signal;if(!signal){throw new Error("Agent listener invoked outside active run")}for(const listener of this.listeners){await listener(event,signal)}}};var events=[];var pendingModels=new Map;var pendingTools=new Map;var agent=null;var emptyUsage=()=>({input:0,output:0,cacheRead:0,cacheWrite:0,reasoning:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}});function modelFor(config){const provider=config.provider||"openai";const deepseek=provider==="deepseek";const anthropic=provider==="anthropic";const defaultModel=deepseek?"deepseek-v4-pro":"gpt-5-mini";return{id:config.model||defaultModel,name:config.model||defaultModel,provider, +api:anthropic?"anthropic-messages":"openai-completions",baseUrl:deepseek?"https://api.deepseek.com":anthropic?"https://api.anthropic.com":"https://api.openai.com/v1",reasoning:deepseek,thinkingLevelMap:deepseek?{off:null,minimal:null,low:null,medium:null,high:"high",xhigh:"max",max:"max"}:void 0,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:deepseek?1e6:128e3,maxTokens:deepseek?384e3:16384}}function hostStream(model,context,options={}){const stream=new AssistantMessageEventStream; +const partial={role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,usage:emptyUsage(),stopReason:"stop",timestamp:Date.now()};try{if(!globalThis.host)throw new Error("Pocket Pi Agent host is unavailable");const id=globalThis.host.startModel(JSON.stringify({model,context,options}));pendingModels.set(id,{stream,model,partial,started:false,thinkingStarted:false,textStarted:false,thinking:"",text:""})}catch(error){pushModelError(stream,model,String(error))}return stream} +function ensureModelStarted(pending){if(pending.started)return;pending.started=true;pending.stream.push({type:"start",partial:{...pending.partial}})}function syncContent(pending){const content=[];if(pending.thinkingStarted){content.push({type:"thinking",thinking:pending.thinking,thinkingSignature:"reasoning_content"})}if(pending.textStarted)content.push({type:"text",text:pending.text});pending.partial.content=content}function pushThinkingDelta(pending,delta){if(!delta)return;if(pending.textStarted) +throw new Error("thinking delta arrived after text output started");ensureModelStarted(pending);if(!pending.thinkingStarted){pending.thinkingStarted=true;syncContent(pending);pending.stream.push({type:"thinking_start",contentIndex:0,partial:{...pending.partial}})}pending.thinking+=delta;syncContent(pending);pending.stream.push({type:"thinking_delta",contentIndex:0,delta,partial:{...pending.partial}})}function textIndex(pending){return pending.thinkingStarted?1:0}function pushTextDelta(pending,delta){ +if(!delta)return;ensureModelStarted(pending);if(!pending.textStarted){pending.textStarted=true;syncContent(pending);pending.stream.push({type:"text_start",contentIndex:textIndex(pending),partial:{...pending.partial}})}pending.text+=delta;syncContent(pending);pending.stream.push({type:"text_delta",contentIndex:textIndex(pending),delta,partial:{...pending.partial}})}function appendFinalDelta(current,complete,append,label){if(current===complete)return;if(!complete.startsWith(current))throw new Error( +`${label} stream does not match final result`);append(complete.slice(current.length))}function finishModel(pending,result){ensureModelStarted(pending);if(typeof result.thinking!=="string"||typeof result.text!=="string"){throw new Error("model result is missing thinking or text")}if(!Array.isArray(result.toolCalls))throw new Error("model result is missing toolCalls");if(!result.usage||typeof result.usage!=="object"){throw new Error("model result is missing usage")}if(result.thinking&&typeof result. +thinkingSignature!=="string"){throw new Error("thinking result is missing thinkingSignature")}if(!["stop","length","toolUse"].includes(result.stopReason)){throw new Error("model result has an invalid stopReason")}appendFinalDelta(pending.thinking,result.thinking,delta=>pushThinkingDelta(pending,delta),"thinking");appendFinalDelta(pending.text,result.text,delta=>pushTextDelta(pending,delta),"text");pending.partial.usage={...emptyUsage(),...result.usage};if(pending.thinkingStarted){const thinking=pending. +partial.content[0];thinking.thinkingSignature=result.thinkingSignature;pending.stream.push({type:"thinking_end",contentIndex:0,content:pending.thinking,partial:{...pending.partial}})}if(pending.textStarted){pending.stream.push({type:"text_end",contentIndex:textIndex(pending),content:pending.text,partial:{...pending.partial}})}if(result.toolCalls.length>0&&result.stopReason!=="toolUse"){throw new Error("tool calls require toolUse stopReason")}if(result.toolCalls.length===0&&result.stopReason==="t\ +oolUse"){throw new Error("toolUse stopReason requires tool calls")}for(const call of result.toolCalls){if(!call.id||!call.name||!call.arguments||typeof call.arguments!=="object"||Array.isArray(call.arguments)){throw new Error("model result contains an invalid tool call")}const toolCall={type:"toolCall",id:call.id,name:call.name,arguments:call.arguments};const contentIndex=pending.partial.content.length;pending.partial.content=[...pending.partial.content,toolCall];pending.stream.push({type:"toolc\ +all_start",contentIndex,partial:{...pending.partial}});pending.stream.push({type:"toolcall_end",contentIndex,toolCall,partial:{...pending.partial}})}if(pending.partial.content.length===0)throw new Error("model result contains no decision");pending.partial.stopReason=result.stopReason;pending.stream.push({type:"done",reason:result.stopReason,message:{...pending.partial}})}function pushModelError(stream,model,message){stream.push({type:"error",reason:"error",error:{role:"assistant",content:[],api:model. +api,provider:model.provider,model:model.id,usage:emptyUsage(),stopReason:"error",errorMessage:message,timestamp:Date.now()}})}function boot(configJson){const config=JSON.parse(configJson);const model=modelFor(config);const tools=(config.tools||[]).map(tool=>({name:tool.name,label:tool.label||tool.name,description:tool.description||"",parameters:tool.parameters||{type:"object",properties:{}},executionMode:"sequential",execute:(id,args)=>new Promise((resolve,reject)=>{try{if(!globalThis.host)throw new Error( +"Pocket Pi Agent host is unavailable");const requestId=globalThis.host.startTool(id,tool.name,JSON.stringify(args||{}));pendingTools.set(requestId,{resolve,reject})}catch(error){reject(error instanceof Error?error:new Error(String(error)))}})}));agent=new Agent({initialState:{systemPrompt:config.systemPrompt||"You are Pocket Pi running on an embedded device.",model,thinkingLevel:model.reasoning?config.thinkingLevel||"high":"off",tools},streamFn:hostStream,toolExecution:"sequential"});agent.subscribe( +event=>{const compact={type:event.type};if(event.type==="message_update"){compact.kind=event.assistantMessageEvent?.type;compact.delta=event.assistantMessageEvent?.delta}else if(event.type==="message_end"){compact.role=event.message?.role;compact.stopReason=event.message?.stopReason}else if(event.type==="tool_execution_start"||event.type==="tool_execution_end"){compact.name=event.toolName;compact.toolCallId=event.toolCallId;compact.isError=Boolean(event.isError)}events.push(compact)});events.push( +{type:"agent_ready"})}function prompt(text){if(!agent)throw new Error("prompt before boot");void agent.prompt(text).catch(error=>events.push({type:"agent_error",message:String(error)}))}function abort(){agent?.abort()}function tick(){const batch=JSON.parse(globalThis.host?.poll()||"[]");for(const event of batch){if(event.type==="model_progress"){const pending=pendingModels.get(event.id);if(!pending)continue;pushThinkingDelta(pending,event.thinkingDelta);pushTextDelta(pending,event.textDelta)}else if(event. +type==="model_done"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);try{finishModel(pending,JSON.parse(event.result))}catch(error){pushModelError(pending.stream,pending.model,String(error))}}else if(event.type==="model_error"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);pushModelError(pending.stream,pending.model,event.error)}else if(event.type==="tool_done"){const pending=pendingTools.get(event.id); +if(!pending)continue;pendingTools.delete(event.id);try{const result=JSON.parse(event.result);if(result.isError)throw new Error(String(result.text||"App tool failed"));pending.resolve({content:[{type:"text",text:String(result.text||"")}],details:result.details,terminate:Boolean(result.terminate)})}catch(error){pending.reject(error instanceof Error?error:new Error(String(error)))}}}}function drain(){return JSON.stringify({phase:agent?.state.isStreaming?"thinking":agent?"ready":"idle",messages:agent?. +state.messages.length||0,events:events.splice(0,events.length)})}globalThis.PocketPiEmbedded={boot,prompt,abort,tick,drain};})(); diff --git a/apps/robinhood/app.tsx b/apps/robinhood/app.tsx index e376db7..019b31c 100644 --- a/apps/robinhood/app.tsx +++ b/apps/robinhood/app.tsx @@ -392,7 +392,7 @@ function Chart() { {chartPoints().length < 2 ? "COLLECTING 5M VALUE HISTORY" : ""} - {(item) => } + {(item) => } {(item) => } {chartLabels()[0] || ""}{chartLabels()[1] || ""}{chartLabels()[2] || ""} diff --git a/apps/robinhood/dist/app.js b/apps/robinhood/dist/app.js index b959b48..9a7c260 100644 --- a/apps/robinhood/dist/app.js +++ b/apps/robinhood/dist/app.js @@ -19,4 +19,4 @@ WHERE account_number = ?3 AND observed_at >= ?1 AND observed_at <= bucket_time ORDER BY observed_at DESC LIMIT 1) AS total_value FROM buckets ORDER BY bucket_index - `).all(z,X,J).map((j)=>({time:j.bucket_time,value:I0(j.total_value)})),D=P.map((j)=>j.time),U=P.map((j)=>j.value).filter((j)=>j!==null),H=[D[0],D[9],D[19]].map((j)=>{let G=new Date(j*1000);return l()==="day"?String(G.getHours()).padStart(2,"0")+":"+String(G.getMinutes()).padStart(2,"0"):String(G.getMonth()+1)+"/"+String(G.getDate())});if(U.length===0){let j=l()==="day"?y().pnlDay:y().pnlWeek,G=I0(j),V={points:[],segments:[],labels:H,trend:{change:e(j),percent:"—",positive:G===null||G>=0}};H1.set($,{loadedRevision:Q,value:V}),OJ(V.points),LJ(V.segments),q1(V.labels),z1(V.trend);return}let w=Math.min(...U),C=Math.max(...U),g=Math.max(0.01,C-w),A=P.flatMap((j,G)=>j.value===null?[]:[{x:G*622/19,y:U.length===1?80:10+(C-j.value)*140/g}]),s=A.slice(1).map((j,G)=>{let V=A[G],k=j.x-V.x,_=j.y-V.y;return{x:V.x,y:V.y,width:Math.sqrt(k*k+_*_),angle:Math.atan2(_,k)*180/Math.PI}}),a=U[U.length-1]-U[0],K={change:e(String(a)),percent:U[0]===0?"—":(a*100/U[0]).toFixed(2)+"%",positive:a>=0};H1.set($,{loadedRevision:Q,value:{points:A,segments:s,labels:H,trend:K}}),OJ(A),LJ(s),q1(H),z1(K)}function GQ(J){if(J6===J)return;let Q=m.query("SELECT status,error,completed_at FROM refresh_runs ORDER BY id DESC LIMIT 1").get();if(o4(!1),Q?.status==="failed")ZJ("REFRESH FAILED · "+String(Q.error||"UNKNOWN ERROR").slice(0,52));else if(Q?.status==="partial")ZJ("LIVE WITH PARTIAL DATA");else if(y().observedAt)ZJ("LIVE / READ ONLY · "+$6(y().observedAt));else ZJ("WAITING FOR ROBINHOOD");J6=J}function X6(J,Q){if(!J){if(aJ(iJ),OJ([]),LJ([]),!rJ())ZJ("WAITING FOR ROBINHOOD");return}let $=G1.get(J);if($?.loadedRevision===Q){if(aJ($.value),Z6(J,Q),$.value.observedAt&&!rJ())ZJ("LIVE / READ ONLY · "+$6($.value.observedAt));return}aJ(iJ),OJ([]),LJ([])}function W6(J=u){try{let Q=m.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==p4){X1([]),L0(""),aJ(iJ),OJ([]),LJ([]),ZJ("WAITING FOR ROBINHOOD");return}eJ(()=>{u=Math.max(u,J);let $=gJ();if(t4!==u)$=qQ(),X1($),t4=u;zQ(u,$);let Z=O0();if(!$.some((X)=>X.number===Z))Z=$[0]?.number||"",L0(Z);X6(Z,u),GQ(u)})}catch{eJ(()=>{X1([]),L0(""),aJ(iJ),OJ([]),LJ([]),ZJ("WAITING FOR ROBINHOOD")})}}function HQ(){return""}function jQ(){let J=m.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((z)=>z.name)),$=J.map((z)=>{let F=m.query("SELECT COUNT(*) AS count FROM "+z.name).get().count;return{name:z.name,rowCount:F,schema:z.sql}}),Z=Q.has("refresh_runs")?m.query("SELECT id,started_at,completed_at,operation_count,success_count,status,error FROM refresh_runs ORDER BY id DESC LIMIT 3").all():[],X=Q.has("portfolio_current")?m.query("SELECT substr(account_number,-4) AS account_suffix,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current ORDER BY observed_at DESC LIMIT 4").all():[],W=Q.has("total_value")?m.query("SELECT substr(account_number,-4) AS account_suffix,observed_at,value FROM total_value ORDER BY observed_at DESC LIMIT 8").all():[];return{database:"robinhood.sqlite",schemaVersion:p4,tables:$,latestRefreshes:Z,latestPortfolios:X,latestValues:W}}function j1(){return XQ()}function k0(J){return q(a2,{get title(){return J.title},back:!0,metaTop:"READ ONLY",get metaBottom(){return J.metaBottom??"AUTO · 5 MIN"}})}function F1(J){return q(R,{class:"w-[210] h-[104] px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(L,{class:"text-sm text-slate-500 font-bold",get children(){return J.label}}),q(L,{class:"text-lg text-slate-900 font-bold",get children(){return e(J.value)}})]}})}function q6(J){return q(r2,{get title(){return J.title},get detail(){return J.detail},action:!0})}function FQ(J){if(J===0&&!y().activityAvailable)return t2;return y().activity[J]??(J===0?$1:e2)}function z6(J){let Q=()=>FQ(J.index);return q(R,{class:"h-[72] px-5 flex-row items-center justify-between",get children(){return[q(R,{class:"w-[450] flex-col gap-2",get children(){return[q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q().title}}),q(L,{class:"text-sm text-slate-500",get children(){return HJ(()=>!!Q().timestamp)()?Q().timestamp+" · "+Q().detail:""}})]}}),q(L,{get["class"](){return Q().side==="SELL"?"text-sm text-emerald-600 font-bold":"text-sm text-slate-900 font-bold"},get children(){return HJ(()=>!!Q().amount)()?e(Q().amount):""}})]}})}function BQ(J){if(J===0&&!y().positionsAvailable)return JQ;return y().positions[J]??(J===0?Z1:QQ)}function Y6(J){let Q=()=>BQ(J.index);return q(R,{class:"h-[64] px-5 flex-row items-center",get children(){return[q(L,{class:"w-[240] text-base text-slate-900 font-bold",get children(){return Q().symbol}}),q(L,{class:"w-[156] text-sm text-slate-500",get children(){return HJ(()=>!!Q().quantity)()?Q().quantity+" SH":""}}),q(L,{class:"text-sm text-slate-500",get children(){return HJ(()=>!!Q().averagePrice)()?"AVG "+e(Q().averagePrice):""}})]}})}function KQ(){return q(R,{class:"relative w-[632] h-[196] flex-col",get children(){return[q(R,{class:"relative w-[632] h-[160] overflow-hidden",get children(){return[q(R,{class:"absolute w-[632] h-[2] bg-slate-200",style:{posType:1,insetL:0,insetT:158}}),q(L,{class:"absolute text-sm text-slate-500 font-bold",style:{posType:1,insetL:174,insetT:72},get children(){return c4().length<2?"COLLECTING 5M VALUE HISTORY":""}}),q(NJ,{get each(){return ZQ()},children:(J)=>q(R,{get["class"](){return j1().positive?"absolute rounded-lg bg-emerald-500":"absolute rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x,insetT:J.y-2,width:J.width,height:4,rotate:J.angle,originX:0,originY:0.5}}})}),q(NJ,{get each(){return c4()},children:(J)=>q(R,{get["class"](){return j1().positive?"absolute w-[9] h-[9] rounded-lg bg-emerald-500":"absolute w-[9] h-[9] rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x-4,insetT:J.y-4}}})})]}}),q(R,{class:"h-[36] px-1 flex-row items-center justify-between",get children(){return[q(L,{class:"text-sm text-slate-500",get children(){return W1()[0]||""}}),q(L,{class:"text-sm text-slate-500",get children(){return W1()[1]||""}}),q(L,{class:"text-sm text-slate-500",get children(){return W1()[2]||""}})]}})]}})}function UQ(){let J=()=>j1();return q(R,{class:"flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ROBINHOOD"}),q(R,{class:"h-[64] px-6 pt-2",get children(){return q(R,{class:"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(L,{class:"text-sm text-slate-500 font-bold",children:"ACCOUNT"}),q(L,{class:"text-sm text-slate-900 font-bold",get children(){return y().account.label+(y().account.suffix?" ····"+y().account.suffix+" "+(gJ().findIndex((Q)=>Q.number===O0())+1)+"/"+gJ().length:"")+" ›"}})]}})}}),q(R,{class:"h-[304] px-6 pt-3",get children(){return q(R,{class:"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"h-[64] flex-row items-end justify-between",get children(){return[q(L,{class:"text-2xl text-slate-950 font-bold",get children(){return e(y().totalValue)}}),q(L,{get["class"](){return J().positive?"text-base text-emerald-600 font-bold":"text-base text-red-500 font-bold"},get children(){return J().change+" ("+J().percent+")"}})]}}),q(KQ,{})]}})}}),q(R,{class:"h-[60] px-6 pt-2 flex-row gap-3",get children(){return[q(R,{get["class"](){return l()==="day"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(L,{get["class"](){return l()==="day"?"text-sm text-white font-bold":"text-sm text-slate-500 font-bold"},children:"1D"})}}),q(R,{get["class"](){return l()==="week"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(L,{get["class"](){return l()==="week"?"text-sm text-white font-bold":"text-sm text-slate-500 font-bold"},children:"1W"})}}),q(L,{class:"pt-3 text-sm text-slate-500",get children(){return l()==="day"?"TODAY":"PAST WEEK"}})]}}),q(R,{class:"h-[126] px-6 pt-3 flex-row items-start gap-[21]",get children(){return[q(F1,{label:"VALUE",get value(){return y().totalValue}}),q(F1,{label:"CASH",get value(){return y().cash}}),q(F1,{label:"BUY POWER",get value(){return y().buyingPower}})]}}),q(R,{class:"h-[200] px-6 flex-col",get children(){return[q(q6,{title:"ACTIVITY",detail:"LAST 7 DAYS"}),q(R,{class:"h-[150] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(z6,{index:0}),q(z6,{index:1})]}})]}}),q(R,{class:"h-[184] px-6 flex-col",get children(){return[q(q6,{title:"POSITIONS"}),q(R,{class:"h-[136] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(Y6,{index:0}),q(Y6,{index:1})]}})]}}),q(R,{class:"h-[126] px-6 pt-2",get children(){return q(R,{class:"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-col gap-3",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",children:"REALIZED P&L"}),q(L,{class:"text-sm text-slate-500",get children(){return"EQUITIES / "+(l()==="day"?"TODAY":"WEEK")}})]}}),q(L,{get["class"](){return(I0(l()==="day"?y().pnlDay:y().pnlWeek)??0)>=0?"text-xl text-emerald-600 font-bold":"text-xl text-red-500 font-bold"},get children(){return e(l()==="day"?y().pnlDay:y().pnlWeek)}})]}})}}),q(R,{class:"h-[104] px-6 flex-row items-center justify-between",get children(){return[q(L,{get["class"](){return n4().startsWith("REFRESH FAILED")?"w-[460] text-sm text-red-500":"w-[460] text-sm text-slate-500"},get children(){return n4()}}),q(R,{class:"w-[176] h-[64]",get children(){return q(n2,{get label(){return rJ()?"REFRESHING":"REFRESH NOW"},get disabled(){return rJ()}})}})]}})]}})}function B1(){return[q(R,{class:"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",style:{posType:1,insetL:628,insetT:156},get children(){return q(L,{class:"text-sm text-orange-600 font-bold",children:"UP"})}}),q(R,{class:"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",style:{posType:1,insetL:628,insetT:972},get children(){return q(L,{class:"text-sm text-orange-600 font-bold",children:"DN"})}})]}function MQ(){let J=QJ(()=>gJ().slice(Y1(),Y1()+8)),Q=O0();return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ACCOUNTS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(NJ,{get each(){return J()},children:($)=>q(R,{get["class"](){return $.number===Q?"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100"},get children(){return[q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",get children(){return $.label}}),q(L,{class:"text-base text-slate-500 font-bold",get children(){return"····"+$.suffix}})]}}),q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-sm text-emerald-600",get children(){return $.status}}),q(Z0,{get when(){return $.number===Q},get children(){return q(L,{class:"text-sm text-emerald-600 font-bold",children:"SELECTED"})}})]}})]}})})}}),q(B1,{})]}})}function VQ(){let J=QJ(()=>y().activity.slice(i4(),i4()+8));return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ACTIVITY",metaBottom:"LAST 7 DAYS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[14]",get children(){return q(Z0,{get when(){return HJ(()=>!!y().activityAvailable)()&&J().length>0},get fallback(){return q(R,{class:"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100",get children(){return q(L,{class:"text-base text-slate-500",get children(){return y().activityAvailable?"NO ACTIVITY YET":"ACTIVITY UNAVAILABLE"}})}})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(R,{class:"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q.title}}),q(L,{get["class"](){return Q.side==="SELL"?"text-base text-emerald-600 font-bold":"text-base text-slate-900 font-bold"},get children(){return e(Q.amount)}})]}}),q(L,{class:"text-sm text-slate-500",get children(){return Q.timestamp+" · "+Q.detail}}),q(L,{class:"text-sm text-emerald-600 font-bold",get children(){return Q.state}})]}})})}})}}),q(B1,{})]}})}function PQ(){let J=QJ(()=>y().positions.slice(a4(),a4()+9));return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"POSITIONS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(Z0,{get when(){return HJ(()=>!!y().positionsAvailable)()&&J().length>0},get fallback(){return q(R,{class:"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100",get children(){return q(L,{class:"text-base text-slate-500",get children(){return y().positionsAvailable?"NO OPEN POSITIONS":"POSITIONS UNAVAILABLE"}})}})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(R,{class:"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-row items-center",get children(){return[q(L,{class:"w-[170] text-lg text-slate-900 font-bold",get children(){return Q.symbol}}),q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q.quantity+" SH"}})]}}),q(L,{class:"text-sm text-slate-500",get children(){return"AVERAGE COST "+e(Q.averagePrice)+(Q.marketValue?" · VALUE "+e(Q.marketValue):"")}})]}})})}})}}),q(B1,{})]}})}function DQ(){if(i()==="accounts")return q(MQ,{});if(i()==="activity")return q(VQ,{});return q(PQ,{})}function RQ(){return q(Z0,{get when(){return i()==="dashboard"},get fallback(){return q(DQ,{})},get children(){return q(UQ,{})}})}W6(),v2(()=>q(RQ,{})),globalThis.PocketPiApp={tick:HQ,update(){return""},dataChanged(J){let Q=WQ(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),u):u;return W6($),""},invokeTool(J){try{let Q=J==="robinhood.storage_status"?jQ():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Data Action tasks do not run in the View: "+J,isError:!0})},tap(J,Q){if(i()!=="dashboard"){if(Q<112&&J<220)return sJ("dashboard"),"";if(J>=620&&Q>=140&&Q<310){if(i()==="accounts")d4(($)=>Math.max(0,$-1));if(i()==="activity")s4(($)=>Math.max(0,$-1));if(i()==="positions")r4(($)=>Math.max(0,$-1));return""}if(J>=620&&Q>=940&&Q<1130){if(i()==="accounts")d4(($)=>Math.min(Math.max(0,gJ().length-8),$+1));if(i()==="activity")s4(($)=>Math.min(Math.max(0,y().activity.length-8),$+1));if(i()==="positions")r4(($)=>Math.min(Math.max(0,y().positions.length-9),$+1));return""}if(i()==="accounts"&&J<610&&Q>=126){let $=Y1()+Math.floor((Q-126)/112),Z=gJ()[$];if(Z)eJ(()=>{L0(Z.number),sJ("dashboard")}),X6(Z.number,u)}return""}if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(Q>=112&&Q<176)return sJ("accounts"),"";if(Q>=480&&Q<540)return eJ(()=>{$Q(J<136?"day":"week"),Z6(O0(),u)}),"";if(Q>=666&&Q<866)return sJ("activity"),"";if(Q>=866&&Q<1050)return sJ("positions"),"";if(Q>=1176&&J>=500){if(rJ())return"";return o4(!0),ZJ("REFRESHING ROBINHOOD…"),JSON.stringify({type:"invokeTask",task:"refreshPortfolio"})}return""}}})(); + `).all(z,X,J).map((j)=>({time:j.bucket_time,value:I0(j.total_value)})),D=P.map((j)=>j.time),U=P.map((j)=>j.value).filter((j)=>j!==null),H=[D[0],D[9],D[19]].map((j)=>{let G=new Date(j*1000);return l()==="day"?String(G.getHours()).padStart(2,"0")+":"+String(G.getMinutes()).padStart(2,"0"):String(G.getMonth()+1)+"/"+String(G.getDate())});if(U.length===0){let j=l()==="day"?y().pnlDay:y().pnlWeek,G=I0(j),V={points:[],segments:[],labels:H,trend:{change:e(j),percent:"—",positive:G===null||G>=0}};H1.set($,{loadedRevision:Q,value:V}),OJ(V.points),LJ(V.segments),q1(V.labels),z1(V.trend);return}let w=Math.min(...U),C=Math.max(...U),g=Math.max(0.01,C-w),A=P.flatMap((j,G)=>j.value===null?[]:[{x:G*622/19,y:U.length===1?80:10+(C-j.value)*140/g}]),s=A.slice(1).map((j,G)=>{let V=A[G],k=j.x-V.x,_=j.y-V.y;return{x:V.x,y:V.y,width:Math.sqrt(k*k+_*_),angle:Math.atan2(_,k)*180/Math.PI}}),a=U[U.length-1]-U[0],K={change:e(String(a)),percent:U[0]===0?"—":(a*100/U[0]).toFixed(2)+"%",positive:a>=0};H1.set($,{loadedRevision:Q,value:{points:A,segments:s,labels:H,trend:K}}),OJ(A),LJ(s),q1(H),z1(K)}function GQ(J){if(J6===J)return;let Q=m.query("SELECT status,error,completed_at FROM refresh_runs ORDER BY id DESC LIMIT 1").get();if(o4(!1),Q?.status==="failed")ZJ("REFRESH FAILED · "+String(Q.error||"UNKNOWN ERROR").slice(0,52));else if(Q?.status==="partial")ZJ("LIVE WITH PARTIAL DATA");else if(y().observedAt)ZJ("LIVE / READ ONLY · "+$6(y().observedAt));else ZJ("WAITING FOR ROBINHOOD");J6=J}function X6(J,Q){if(!J){if(aJ(iJ),OJ([]),LJ([]),!rJ())ZJ("WAITING FOR ROBINHOOD");return}let $=G1.get(J);if($?.loadedRevision===Q){if(aJ($.value),Z6(J,Q),$.value.observedAt&&!rJ())ZJ("LIVE / READ ONLY · "+$6($.value.observedAt));return}aJ(iJ),OJ([]),LJ([])}function W6(J=u){try{let Q=m.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==p4){X1([]),L0(""),aJ(iJ),OJ([]),LJ([]),ZJ("WAITING FOR ROBINHOOD");return}eJ(()=>{u=Math.max(u,J);let $=gJ();if(t4!==u)$=qQ(),X1($),t4=u;zQ(u,$);let Z=O0();if(!$.some((X)=>X.number===Z))Z=$[0]?.number||"",L0(Z);X6(Z,u),GQ(u)})}catch{eJ(()=>{X1([]),L0(""),aJ(iJ),OJ([]),LJ([]),ZJ("WAITING FOR ROBINHOOD")})}}function HQ(){return""}function jQ(){let J=m.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((z)=>z.name)),$=J.map((z)=>{let F=m.query("SELECT COUNT(*) AS count FROM "+z.name).get().count;return{name:z.name,rowCount:F,schema:z.sql}}),Z=Q.has("refresh_runs")?m.query("SELECT id,started_at,completed_at,operation_count,success_count,status,error FROM refresh_runs ORDER BY id DESC LIMIT 3").all():[],X=Q.has("portfolio_current")?m.query("SELECT substr(account_number,-4) AS account_suffix,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current ORDER BY observed_at DESC LIMIT 4").all():[],W=Q.has("total_value")?m.query("SELECT substr(account_number,-4) AS account_suffix,observed_at,value FROM total_value ORDER BY observed_at DESC LIMIT 8").all():[];return{database:"robinhood.sqlite",schemaVersion:p4,tables:$,latestRefreshes:Z,latestPortfolios:X,latestValues:W}}function j1(){return XQ()}function k0(J){return q(a2,{get title(){return J.title},back:!0,metaTop:"READ ONLY",get metaBottom(){return J.metaBottom??"AUTO · 5 MIN"}})}function F1(J){return q(R,{class:"w-[210] h-[104] px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(L,{class:"text-sm text-slate-500 font-bold",get children(){return J.label}}),q(L,{class:"text-lg text-slate-900 font-bold",get children(){return e(J.value)}})]}})}function q6(J){return q(r2,{get title(){return J.title},get detail(){return J.detail},action:!0})}function FQ(J){if(J===0&&!y().activityAvailable)return t2;return y().activity[J]??(J===0?$1:e2)}function z6(J){let Q=()=>FQ(J.index);return q(R,{class:"h-[72] px-5 flex-row items-center justify-between",get children(){return[q(R,{class:"w-[450] flex-col gap-2",get children(){return[q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q().title}}),q(L,{class:"text-sm text-slate-500",get children(){return HJ(()=>!!Q().timestamp)()?Q().timestamp+" · "+Q().detail:""}})]}}),q(L,{get["class"](){return Q().side==="SELL"?"text-sm text-emerald-600 font-bold":"text-sm text-slate-900 font-bold"},get children(){return HJ(()=>!!Q().amount)()?e(Q().amount):""}})]}})}function BQ(J){if(J===0&&!y().positionsAvailable)return JQ;return y().positions[J]??(J===0?Z1:QQ)}function Y6(J){let Q=()=>BQ(J.index);return q(R,{class:"h-[64] px-5 flex-row items-center",get children(){return[q(L,{class:"w-[240] text-base text-slate-900 font-bold",get children(){return Q().symbol}}),q(L,{class:"w-[156] text-sm text-slate-500",get children(){return HJ(()=>!!Q().quantity)()?Q().quantity+" SH":""}}),q(L,{class:"text-sm text-slate-500",get children(){return HJ(()=>!!Q().averagePrice)()?"AVG "+e(Q().averagePrice):""}})]}})}function KQ(){return q(R,{class:"relative w-[632] h-[196] flex-col",get children(){return[q(R,{class:"relative w-[632] h-[160] overflow-hidden",get children(){return[q(R,{class:"absolute w-[632] h-[2] bg-slate-200",style:{posType:1,insetL:0,insetT:158}}),q(L,{class:"absolute text-sm text-slate-500 font-bold",style:{posType:1,insetL:174,insetT:72},get children(){return c4().length<2?"COLLECTING 5M VALUE HISTORY":""}}),q(NJ,{get each(){return ZQ()},children:(J)=>q(R,{get["class"](){return j1().positive?"absolute rounded-lg bg-emerald-500":"absolute rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x,insetT:J.y-2,width:J.width,height:4,rotate:J.angle,originX:-0.5,originY:0}}})}),q(NJ,{get each(){return c4()},children:(J)=>q(R,{get["class"](){return j1().positive?"absolute w-[9] h-[9] rounded-lg bg-emerald-500":"absolute w-[9] h-[9] rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x-4,insetT:J.y-4}}})})]}}),q(R,{class:"h-[36] px-1 flex-row items-center justify-between",get children(){return[q(L,{class:"text-sm text-slate-500",get children(){return W1()[0]||""}}),q(L,{class:"text-sm text-slate-500",get children(){return W1()[1]||""}}),q(L,{class:"text-sm text-slate-500",get children(){return W1()[2]||""}})]}})]}})}function UQ(){let J=()=>j1();return q(R,{class:"flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ROBINHOOD"}),q(R,{class:"h-[64] px-6 pt-2",get children(){return q(R,{class:"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(L,{class:"text-sm text-slate-500 font-bold",children:"ACCOUNT"}),q(L,{class:"text-sm text-slate-900 font-bold",get children(){return y().account.label+(y().account.suffix?" ····"+y().account.suffix+" "+(gJ().findIndex((Q)=>Q.number===O0())+1)+"/"+gJ().length:"")+" ›"}})]}})}}),q(R,{class:"h-[304] px-6 pt-3",get children(){return q(R,{class:"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"h-[64] flex-row items-end justify-between",get children(){return[q(L,{class:"text-2xl text-slate-950 font-bold",get children(){return e(y().totalValue)}}),q(L,{get["class"](){return J().positive?"text-base text-emerald-600 font-bold":"text-base text-red-500 font-bold"},get children(){return J().change+" ("+J().percent+")"}})]}}),q(KQ,{})]}})}}),q(R,{class:"h-[60] px-6 pt-2 flex-row gap-3",get children(){return[q(R,{get["class"](){return l()==="day"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(L,{get["class"](){return l()==="day"?"text-sm text-white font-bold":"text-sm text-slate-500 font-bold"},children:"1D"})}}),q(R,{get["class"](){return l()==="week"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(L,{get["class"](){return l()==="week"?"text-sm text-white font-bold":"text-sm text-slate-500 font-bold"},children:"1W"})}}),q(L,{class:"pt-3 text-sm text-slate-500",get children(){return l()==="day"?"TODAY":"PAST WEEK"}})]}}),q(R,{class:"h-[126] px-6 pt-3 flex-row items-start gap-[21]",get children(){return[q(F1,{label:"VALUE",get value(){return y().totalValue}}),q(F1,{label:"CASH",get value(){return y().cash}}),q(F1,{label:"BUY POWER",get value(){return y().buyingPower}})]}}),q(R,{class:"h-[200] px-6 flex-col",get children(){return[q(q6,{title:"ACTIVITY",detail:"LAST 7 DAYS"}),q(R,{class:"h-[150] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(z6,{index:0}),q(z6,{index:1})]}})]}}),q(R,{class:"h-[184] px-6 flex-col",get children(){return[q(q6,{title:"POSITIONS"}),q(R,{class:"h-[136] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(Y6,{index:0}),q(Y6,{index:1})]}})]}}),q(R,{class:"h-[126] px-6 pt-2",get children(){return q(R,{class:"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-col gap-3",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",children:"REALIZED P&L"}),q(L,{class:"text-sm text-slate-500",get children(){return"EQUITIES / "+(l()==="day"?"TODAY":"WEEK")}})]}}),q(L,{get["class"](){return(I0(l()==="day"?y().pnlDay:y().pnlWeek)??0)>=0?"text-xl text-emerald-600 font-bold":"text-xl text-red-500 font-bold"},get children(){return e(l()==="day"?y().pnlDay:y().pnlWeek)}})]}})}}),q(R,{class:"h-[104] px-6 flex-row items-center justify-between",get children(){return[q(L,{get["class"](){return n4().startsWith("REFRESH FAILED")?"w-[460] text-sm text-red-500":"w-[460] text-sm text-slate-500"},get children(){return n4()}}),q(R,{class:"w-[176] h-[64]",get children(){return q(n2,{get label(){return rJ()?"REFRESHING":"REFRESH NOW"},get disabled(){return rJ()}})}})]}})]}})}function B1(){return[q(R,{class:"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",style:{posType:1,insetL:628,insetT:156},get children(){return q(L,{class:"text-sm text-orange-600 font-bold",children:"UP"})}}),q(R,{class:"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",style:{posType:1,insetL:628,insetT:972},get children(){return q(L,{class:"text-sm text-orange-600 font-bold",children:"DN"})}})]}function MQ(){let J=QJ(()=>gJ().slice(Y1(),Y1()+8)),Q=O0();return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ACCOUNTS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(NJ,{get each(){return J()},children:($)=>q(R,{get["class"](){return $.number===Q?"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100"},get children(){return[q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",get children(){return $.label}}),q(L,{class:"text-base text-slate-500 font-bold",get children(){return"····"+$.suffix}})]}}),q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-sm text-emerald-600",get children(){return $.status}}),q(Z0,{get when(){return $.number===Q},get children(){return q(L,{class:"text-sm text-emerald-600 font-bold",children:"SELECTED"})}})]}})]}})})}}),q(B1,{})]}})}function VQ(){let J=QJ(()=>y().activity.slice(i4(),i4()+8));return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ACTIVITY",metaBottom:"LAST 7 DAYS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[14]",get children(){return q(Z0,{get when(){return HJ(()=>!!y().activityAvailable)()&&J().length>0},get fallback(){return q(R,{class:"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100",get children(){return q(L,{class:"text-base text-slate-500",get children(){return y().activityAvailable?"NO ACTIVITY YET":"ACTIVITY UNAVAILABLE"}})}})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(R,{class:"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q.title}}),q(L,{get["class"](){return Q.side==="SELL"?"text-base text-emerald-600 font-bold":"text-base text-slate-900 font-bold"},get children(){return e(Q.amount)}})]}}),q(L,{class:"text-sm text-slate-500",get children(){return Q.timestamp+" · "+Q.detail}}),q(L,{class:"text-sm text-emerald-600 font-bold",get children(){return Q.state}})]}})})}})}}),q(B1,{})]}})}function PQ(){let J=QJ(()=>y().positions.slice(a4(),a4()+9));return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"POSITIONS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(Z0,{get when(){return HJ(()=>!!y().positionsAvailable)()&&J().length>0},get fallback(){return q(R,{class:"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100",get children(){return q(L,{class:"text-base text-slate-500",get children(){return y().positionsAvailable?"NO OPEN POSITIONS":"POSITIONS UNAVAILABLE"}})}})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(R,{class:"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-row items-center",get children(){return[q(L,{class:"w-[170] text-lg text-slate-900 font-bold",get children(){return Q.symbol}}),q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q.quantity+" SH"}})]}}),q(L,{class:"text-sm text-slate-500",get children(){return"AVERAGE COST "+e(Q.averagePrice)+(Q.marketValue?" · VALUE "+e(Q.marketValue):"")}})]}})})}})}}),q(B1,{})]}})}function DQ(){if(i()==="accounts")return q(MQ,{});if(i()==="activity")return q(VQ,{});return q(PQ,{})}function RQ(){return q(Z0,{get when(){return i()==="dashboard"},get fallback(){return q(DQ,{})},get children(){return q(UQ,{})}})}W6(),v2(()=>q(RQ,{})),globalThis.PocketPiApp={tick:HQ,update(){return""},dataChanged(J){let Q=WQ(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),u):u;return W6($),""},invokeTool(J){try{let Q=J==="robinhood.storage_status"?jQ():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Data Action tasks do not run in the View: "+J,isError:!0})},tap(J,Q){if(i()!=="dashboard"){if(Q<112&&J<220)return sJ("dashboard"),"";if(J>=620&&Q>=140&&Q<310){if(i()==="accounts")d4(($)=>Math.max(0,$-1));if(i()==="activity")s4(($)=>Math.max(0,$-1));if(i()==="positions")r4(($)=>Math.max(0,$-1));return""}if(J>=620&&Q>=940&&Q<1130){if(i()==="accounts")d4(($)=>Math.min(Math.max(0,gJ().length-8),$+1));if(i()==="activity")s4(($)=>Math.min(Math.max(0,y().activity.length-8),$+1));if(i()==="positions")r4(($)=>Math.min(Math.max(0,y().positions.length-9),$+1));return""}if(i()==="accounts"&&J<610&&Q>=126){let $=Y1()+Math.floor((Q-126)/112),Z=gJ()[$];if(Z)eJ(()=>{L0(Z.number),sJ("dashboard")}),X6(Z.number,u)}return""}if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(Q>=112&&Q<176)return sJ("accounts"),"";if(Q>=480&&Q<540)return eJ(()=>{$Q(J<136?"day":"week"),Z6(O0(),u)}),"";if(Q>=666&&Q<866)return sJ("activity"),"";if(Q>=866&&Q<1050)return sJ("positions"),"";if(Q>=1176&&J>=500){if(rJ())return"";return o4(!0),ZJ("REFRESHING ROBINHOOD…"),JSON.stringify({type:"invokeTask",task:"refreshPortfolio"})}return""}}})(); diff --git a/crates/pocket-pi-agentos/src/lib.rs b/crates/pocket-pi-agentos/src/lib.rs index eba09a8..6e9f5fa 100644 --- a/crates/pocket-pi-agentos/src/lib.rs +++ b/crates/pocket-pi-agentos/src/lib.rs @@ -1532,11 +1532,20 @@ mod tests { fn complete( &self, _request_json: &str, - on_delta: &mut dyn FnMut(&str), + on_event: &mut dyn FnMut(pocket_pi_embedded::ModelStreamEvent), ) -> Result { std::thread::sleep(Duration::from_millis(20)); - on_delta("background-ok"); - Ok(r#"{"text":"background-ok"}"#.to_owned()) + on_event(pocket_pi_embedded::ModelStreamEvent::Text( + "background-ok".into(), + )); + Ok(serde_json::json!({ + "thinking":"", + "text":"background-ok", + "toolCalls":[], + "usage":{}, + "stopReason":"stop" + }) + .to_string()) } } @@ -1558,20 +1567,32 @@ mod tests { fn complete( &self, _request_json: &str, - on_delta: &mut dyn FnMut(&str), + on_event: &mut dyn FnMut(pocket_pi_embedded::ModelStreamEvent), ) -> Result { if self.0.fetch_add(1, Ordering::SeqCst) == 0 { Ok(serde_json::json!({ - "toolCall":{ + "thinking":"get portfolio", + "thinkingSignature":"reasoning_content", + "text":"", + "toolCalls":[{ "id":"call_portfolio", "name":"robinhood.get_portfolio", "arguments":{"account_number":"SIM-001"} - } + }], + "usage":{}, + "stopReason":"toolUse" }) .to_string()) } else { - on_delta("tool-ok"); - Ok(r#"{"text":"tool-ok"}"#.to_owned()) + on_event(pocket_pi_embedded::ModelStreamEvent::Text("tool-ok".into())); + Ok(serde_json::json!({ + "thinking":"", + "text":"tool-ok", + "toolCalls":[], + "usage":{}, + "stopReason":"stop" + }) + .to_string()) } } } diff --git a/crates/pocket-pi-embedded/Cargo.toml b/crates/pocket-pi-embedded/Cargo.toml index 2d7c78f..7a7e52c 100644 --- a/crates/pocket-pi-embedded/Cargo.toml +++ b/crates/pocket-pi-embedded/Cargo.toml @@ -8,5 +8,6 @@ description = "Small pi-agent-core runtime for embedded Pocket Pi hosts" [dependencies] pocket-mod.workspace = true +pocket-pi-protocols.workspace = true rquickjs = { version = "=0.12.1", default-features = false, features = ["bindgen", "std"] } serde_json.workspace = true diff --git a/crates/pocket-pi-embedded/js/pi-agent.bundle.js b/crates/pocket-pi-embedded/js/pi-agent.bundle.js index ffd4260..806a0e8 100644 --- a/crates/pocket-pi-embedded/js/pi-agent.bundle.js +++ b/crates/pocket-pi-embedded/js/pi-agent.bundle.js @@ -384,16 +384,21 @@ if(this.activeRun){throw new Error("Agent is already processing.")}const abortCo const failureMessage={role:"assistant",content:[{type:"text",text:""}],api:this._state.model.api,provider:this._state.model.provider,model:this._state.model.id,usage:EMPTY_USAGE,stopReason:aborted?"aborted":"error",errorMessage:error instanceof Error?error.message:String(error),timestamp:Date.now()};await this.processEvents({type:"message_start",message:failureMessage});await this.processEvents({type:"message_end",message:failureMessage});await this.processEvents({type:"turn_end",message:failureMessage, toolResults:[]});await this.processEvents({type:"agent_end",messages:[failureMessage]})}finishRun(){this._state.isStreaming=false;this._state.streamingMessage=void 0;this._state.pendingToolCalls=new Set;this.activeRun?.resolve();this.activeRun=void 0}async processEvents(event){switch(event.type){case"message_start":this._state.streamingMessage=event.message;break;case"message_update":this._state.streamingMessage=event.message;break;case"message_end":this._state.streamingMessage=void 0;this._state. messages.push(event.message);break;case"tool_execution_start":{const pendingToolCalls=new Set(this._state.pendingToolCalls);pendingToolCalls.add(event.toolCallId);this._state.pendingToolCalls=pendingToolCalls;break}case"tool_execution_end":{const pendingToolCalls=new Set(this._state.pendingToolCalls);pendingToolCalls.delete(event.toolCallId);this._state.pendingToolCalls=pendingToolCalls;break}case"turn_end":if(event.message.role==="assistant"&&event.message.errorMessage){this._state.errorMessage= -event.message.errorMessage}break;case"agent_end":this._state.streamingMessage=void 0;break}const signal=this.activeRun?.abortController.signal;if(!signal){throw new Error("Agent listener invoked outside active run")}for(const listener of this.listeners){await listener(event,signal)}}};var events=[];var pendingModels=new Map;var pendingTools=new Map;var agent=null;var emptyUsage=()=>({input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}});function modelFor(config){const provider=config.provider||"openai";return{id:config.model||"gpt-5-mini",name:config.model||"gpt-5-mini",provider,api:provider==="anthropic"?"anthropic-messages":"openai-responses",baseUrl:provider==="anthropic"?"https://api.anthropic.com":"https://api.\ -openai.com/v1",reasoning:false,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:128e3,maxTokens:1024}}function hostStream(model,context){const stream=new AssistantMessageEventStream;const partial={role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,usage:emptyUsage(),stopReason:"stop",timestamp:Date.now()};try{if(!globalThis.host)throw new Error("Pocket Pi Agent host is unavailable");const id=globalThis.host.startModel(JSON.stringify({model, -context}));pendingModels.set(id,{stream,model,partial,started:false,textStarted:false,text:""})}catch(error){pushModelError(stream,model,String(error))}return stream}function ensureModelStarted(pending){if(pending.started)return;pending.started=true;pending.stream.push({type:"start",partial:{...pending.partial}})}function pushModelDelta(pending,delta){ensureModelStarted(pending);if(!pending.textStarted){pending.textStarted=true;pending.stream.push({type:"text_start",contentIndex:0,partial:{...pending. -partial}})}pending.text+=delta;pending.partial.content=[{type:"text",text:pending.text}];pending.stream.push({type:"text_delta",contentIndex:0,delta,partial:{...pending.partial}})}function finishModel(pending,result){ensureModelStarted(pending);pending.partial.stopReason=result.stopReason||"stop";if(result.toolCall){const toolCall={type:"toolCall",id:result.toolCall.id||`tool_${Date.now()}`,name:result.toolCall.name,arguments:result.toolCall.arguments||{}};pending.partial.content=[toolCall];pending. -partial.stopReason="toolUse";pending.stream.push({type:"toolcall_start",contentIndex:0,partial:{...pending.partial}});pending.stream.push({type:"toolcall_end",contentIndex:0,toolCall,partial:{...pending.partial}});pending.stream.push({type:"done",reason:"toolUse",message:{...pending.partial}});return}const finalText=String(result.text||pending.text);if(!pending.textStarted||finalText!==pending.text){const delta=finalText.startsWith(pending.text)?finalText.slice(pending.text.length):finalText;if(delta) -pushModelDelta(pending,delta)}if(!pending.textStarted)pushModelDelta(pending,"");pending.text=finalText;pending.partial.content=[{type:"text",text:finalText}];pending.stream.push({type:"text_end",contentIndex:0,content:finalText,partial:{...pending.partial}});pending.stream.push({type:"done",reason:pending.partial.stopReason,message:{...pending.partial}})}function pushModelError(stream,model,message){stream.push({type:"error",reason:"error",error:{role:"assistant",content:[],api:model.api,provider:model. -provider,model:model.id,usage:emptyUsage(),stopReason:"error",errorMessage:message,timestamp:Date.now()}})}function boot(configJson){const config=JSON.parse(configJson);const model=modelFor(config);const tools=(config.tools||[]).map(tool=>({name:tool.name,label:tool.label||tool.name,description:tool.description||"",parameters:tool.parameters||{type:"object",properties:{}},executionMode:"sequential",execute:(id,args)=>new Promise((resolve,reject)=>{try{if(!globalThis.host)throw new Error("Pocket \ -Pi Agent host is unavailable");const requestId=globalThis.host.startTool(id,tool.name,JSON.stringify(args||{}));pendingTools.set(requestId,{resolve,reject})}catch(error){reject(error instanceof Error?error:new Error(String(error)))}})}));agent=new Agent({initialState:{systemPrompt:config.systemPrompt||"You are Pocket Pi running on an embedded device.",model,thinkingLevel:"off",tools},streamFn:hostStream,toolExecution:"sequential"});agent.subscribe(event=>{const compact={type:event.type};if(event. -type==="message_update"){compact.kind=event.assistantMessageEvent?.type;compact.delta=event.assistantMessageEvent?.delta}else if(event.type==="message_end"){compact.role=event.message?.role;compact.stopReason=event.message?.stopReason}else if(event.type==="tool_execution_start"||event.type==="tool_execution_end"){compact.name=event.toolName;compact.toolCallId=event.toolCallId;compact.isError=Boolean(event.isError)}events.push(compact)});events.push({type:"agent_ready"})}function prompt(text){if(!agent) -throw new Error("prompt before boot");void agent.prompt(text).catch(error=>events.push({type:"agent_error",message:String(error)}))}function abort(){agent?.abort()}function tick(){const batch=JSON.parse(globalThis.host?.poll()||"[]");for(const event of batch){if(event.type==="model_delta"){const pending=pendingModels.get(event.id);if(pending)pushModelDelta(pending,String(event.delta||""))}else if(event.type==="model_done"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels. -delete(event.id);try{finishModel(pending,JSON.parse(event.result||"{}"))}catch(error){pushModelError(pending.stream,pending.model,String(error))}}else if(event.type==="model_error"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);pushModelError(pending.stream,pending.model,event.error)}else if(event.type==="tool_done"){const pending=pendingTools.get(event.id);if(!pending)continue;pendingTools.delete(event.id);try{const result=JSON.parse(event.result|| -"{}");if(result.isError)throw new Error(String(result.text||"App tool failed"));pending.resolve({content:[{type:"text",text:String(result.text||"")}],details:result.details,terminate:Boolean(result.terminate)})}catch(error){pending.reject(error instanceof Error?error:new Error(String(error)))}}}}function drain(){return JSON.stringify({phase:agent?.state.isStreaming?"thinking":agent?"ready":"idle",messages:agent?.state.messages.length||0,events:events.splice(0,events.length)})}globalThis.PocketPiEmbedded= -{boot,prompt,abort,tick,drain};})(); +event.message.errorMessage}break;case"agent_end":this._state.streamingMessage=void 0;break}const signal=this.activeRun?.abortController.signal;if(!signal){throw new Error("Agent listener invoked outside active run")}for(const listener of this.listeners){await listener(event,signal)}}};var events=[];var pendingModels=new Map;var pendingTools=new Map;var agent=null;var emptyUsage=()=>({input:0,output:0,cacheRead:0,cacheWrite:0,reasoning:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}});function modelFor(config){const provider=config.provider||"openai";const deepseek=provider==="deepseek";const anthropic=provider==="anthropic";const defaultModel=deepseek?"deepseek-v4-pro":"gpt-5-mini";return{id:config.model||defaultModel,name:config.model||defaultModel,provider, +api:anthropic?"anthropic-messages":"openai-completions",baseUrl:deepseek?"https://api.deepseek.com":anthropic?"https://api.anthropic.com":"https://api.openai.com/v1",reasoning:deepseek,thinkingLevelMap:deepseek?{off:null,minimal:null,low:null,medium:null,high:"high",xhigh:"max",max:"max"}:void 0,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:deepseek?1e6:128e3,maxTokens:deepseek?384e3:16384}}function hostStream(model,context,options={}){const stream=new AssistantMessageEventStream; +const partial={role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,usage:emptyUsage(),stopReason:"stop",timestamp:Date.now()};try{if(!globalThis.host)throw new Error("Pocket Pi Agent host is unavailable");const id=globalThis.host.startModel(JSON.stringify({model,context,options}));pendingModels.set(id,{stream,model,partial,started:false,thinkingStarted:false,textStarted:false,thinking:"",text:""})}catch(error){pushModelError(stream,model,String(error))}return stream} +function ensureModelStarted(pending){if(pending.started)return;pending.started=true;pending.stream.push({type:"start",partial:{...pending.partial}})}function syncContent(pending){const content=[];if(pending.thinkingStarted){content.push({type:"thinking",thinking:pending.thinking,thinkingSignature:"reasoning_content"})}if(pending.textStarted)content.push({type:"text",text:pending.text});pending.partial.content=content}function pushThinkingDelta(pending,delta){if(!delta)return;if(pending.textStarted) +throw new Error("thinking delta arrived after text output started");ensureModelStarted(pending);if(!pending.thinkingStarted){pending.thinkingStarted=true;syncContent(pending);pending.stream.push({type:"thinking_start",contentIndex:0,partial:{...pending.partial}})}pending.thinking+=delta;syncContent(pending);pending.stream.push({type:"thinking_delta",contentIndex:0,delta,partial:{...pending.partial}})}function textIndex(pending){return pending.thinkingStarted?1:0}function pushTextDelta(pending,delta){ +if(!delta)return;ensureModelStarted(pending);if(!pending.textStarted){pending.textStarted=true;syncContent(pending);pending.stream.push({type:"text_start",contentIndex:textIndex(pending),partial:{...pending.partial}})}pending.text+=delta;syncContent(pending);pending.stream.push({type:"text_delta",contentIndex:textIndex(pending),delta,partial:{...pending.partial}})}function appendFinalDelta(current,complete,append,label){if(current===complete)return;if(!complete.startsWith(current))throw new Error( +`${label} stream does not match final result`);append(complete.slice(current.length))}function finishModel(pending,result){ensureModelStarted(pending);if(typeof result.thinking!=="string"||typeof result.text!=="string"){throw new Error("model result is missing thinking or text")}if(!Array.isArray(result.toolCalls))throw new Error("model result is missing toolCalls");if(!result.usage||typeof result.usage!=="object"){throw new Error("model result is missing usage")}if(result.thinking&&typeof result. +thinkingSignature!=="string"){throw new Error("thinking result is missing thinkingSignature")}if(!["stop","length","toolUse"].includes(result.stopReason)){throw new Error("model result has an invalid stopReason")}appendFinalDelta(pending.thinking,result.thinking,delta=>pushThinkingDelta(pending,delta),"thinking");appendFinalDelta(pending.text,result.text,delta=>pushTextDelta(pending,delta),"text");pending.partial.usage={...emptyUsage(),...result.usage};if(pending.thinkingStarted){const thinking=pending. +partial.content[0];thinking.thinkingSignature=result.thinkingSignature;pending.stream.push({type:"thinking_end",contentIndex:0,content:pending.thinking,partial:{...pending.partial}})}if(pending.textStarted){pending.stream.push({type:"text_end",contentIndex:textIndex(pending),content:pending.text,partial:{...pending.partial}})}if(result.toolCalls.length>0&&result.stopReason!=="toolUse"){throw new Error("tool calls require toolUse stopReason")}if(result.toolCalls.length===0&&result.stopReason==="t\ +oolUse"){throw new Error("toolUse stopReason requires tool calls")}for(const call of result.toolCalls){if(!call.id||!call.name||!call.arguments||typeof call.arguments!=="object"||Array.isArray(call.arguments)){throw new Error("model result contains an invalid tool call")}const toolCall={type:"toolCall",id:call.id,name:call.name,arguments:call.arguments};const contentIndex=pending.partial.content.length;pending.partial.content=[...pending.partial.content,toolCall];pending.stream.push({type:"toolc\ +all_start",contentIndex,partial:{...pending.partial}});pending.stream.push({type:"toolcall_end",contentIndex,toolCall,partial:{...pending.partial}})}if(pending.partial.content.length===0)throw new Error("model result contains no decision");pending.partial.stopReason=result.stopReason;pending.stream.push({type:"done",reason:result.stopReason,message:{...pending.partial}})}function pushModelError(stream,model,message){stream.push({type:"error",reason:"error",error:{role:"assistant",content:[],api:model. +api,provider:model.provider,model:model.id,usage:emptyUsage(),stopReason:"error",errorMessage:message,timestamp:Date.now()}})}function boot(configJson){const config=JSON.parse(configJson);const model=modelFor(config);const tools=(config.tools||[]).map(tool=>({name:tool.name,label:tool.label||tool.name,description:tool.description||"",parameters:tool.parameters||{type:"object",properties:{}},executionMode:"sequential",execute:(id,args)=>new Promise((resolve,reject)=>{try{if(!globalThis.host)throw new Error( +"Pocket Pi Agent host is unavailable");const requestId=globalThis.host.startTool(id,tool.name,JSON.stringify(args||{}));pendingTools.set(requestId,{resolve,reject})}catch(error){reject(error instanceof Error?error:new Error(String(error)))}})}));agent=new Agent({initialState:{systemPrompt:config.systemPrompt||"You are Pocket Pi running on an embedded device.",model,thinkingLevel:model.reasoning?config.thinkingLevel||"high":"off",tools},streamFn:hostStream,toolExecution:"sequential"});agent.subscribe( +event=>{const compact={type:event.type};if(event.type==="message_update"){compact.kind=event.assistantMessageEvent?.type;compact.delta=event.assistantMessageEvent?.delta}else if(event.type==="message_end"){compact.role=event.message?.role;compact.stopReason=event.message?.stopReason}else if(event.type==="tool_execution_start"||event.type==="tool_execution_end"){compact.name=event.toolName;compact.toolCallId=event.toolCallId;compact.isError=Boolean(event.isError)}events.push(compact)});events.push( +{type:"agent_ready"})}function prompt(text){if(!agent)throw new Error("prompt before boot");void agent.prompt(text).catch(error=>events.push({type:"agent_error",message:String(error)}))}function abort(){agent?.abort()}function tick(){const batch=JSON.parse(globalThis.host?.poll()||"[]");for(const event of batch){if(event.type==="model_progress"){const pending=pendingModels.get(event.id);if(!pending)continue;pushThinkingDelta(pending,event.thinkingDelta);pushTextDelta(pending,event.textDelta)}else if(event. +type==="model_done"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);try{finishModel(pending,JSON.parse(event.result))}catch(error){pushModelError(pending.stream,pending.model,String(error))}}else if(event.type==="model_error"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);pushModelError(pending.stream,pending.model,event.error)}else if(event.type==="tool_done"){const pending=pendingTools.get(event.id); +if(!pending)continue;pendingTools.delete(event.id);try{const result=JSON.parse(event.result);if(result.isError)throw new Error(String(result.text||"App tool failed"));pending.resolve({content:[{type:"text",text:String(result.text||"")}],details:result.details,terminate:Boolean(result.terminate)})}catch(error){pending.reject(error instanceof Error?error:new Error(String(error)))}}}}function drain(){return JSON.stringify({phase:agent?.state.isStreaming?"thinking":agent?"ready":"idle",messages:agent?. +state.messages.length||0,events:events.splice(0,events.length)})}globalThis.PocketPiEmbedded={boot,prompt,abort,tick,drain};})(); diff --git a/crates/pocket-pi-embedded/js/src/entry.ts b/crates/pocket-pi-embedded/js/src/entry.ts index 6cf2d58..76a955a 100644 --- a/crates/pocket-pi-embedded/js/src/entry.ts +++ b/crates/pocket-pi-embedded/js/src/entry.ts @@ -4,6 +4,7 @@ import { AssistantMessageEventStream } from "../node_modules/@earendil-works/pi- type Config = { model?: string; provider?: string; + thinkingLevel?: "high" | "xhigh"; systemPrompt?: string; tools?: Array<{ name: string; @@ -13,14 +14,23 @@ type Config = { }>; }; +type Usage = ReturnType; + type ModelResult = { - text?: string; - stopReason?: "stop" | "length"; - toolCall?: { id?: string; name: string; arguments?: Record }; + thinking: string; + thinkingSignature?: string; + text: string; + toolCalls: Array<{ + id: string; + name: string; + arguments: Record; + }>; + usage: Partial; + stopReason: "stop" | "length" | "toolUse"; }; type HostEvent = - | { type: "model_delta"; id: number; delta: string } + | { type: "model_progress"; id: number; thinkingDelta: string; textDelta: string } | { type: "model_done"; id: number; result: string } | { type: "model_error"; id: number; error: string } | { type: "tool_done"; id: number; result: string }; @@ -30,7 +40,9 @@ type PendingModel = { model: any; partial: any; started: boolean; + thinkingStarted: boolean; textStarted: boolean; + thinking: string; text: string; }; @@ -47,27 +59,38 @@ const emptyUsage = () => ({ output: 0, cacheRead: 0, cacheWrite: 0, + reasoning: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, }); function modelFor(config: Config): any { const provider = config.provider || "openai"; + const deepseek = provider === "deepseek"; + const anthropic = provider === "anthropic"; + const defaultModel = deepseek ? "deepseek-v4-pro" : "gpt-5-mini"; return { - id: config.model || "gpt-5-mini", - name: config.model || "gpt-5-mini", + id: config.model || defaultModel, + name: config.model || defaultModel, provider, - api: provider === "anthropic" ? "anthropic-messages" : "openai-responses", - baseUrl: provider === "anthropic" ? "https://api.anthropic.com" : "https://api.openai.com/v1", - reasoning: false, + api: anthropic ? "anthropic-messages" : "openai-completions", + baseUrl: deepseek + ? "https://api.deepseek.com" + : anthropic + ? "https://api.anthropic.com" + : "https://api.openai.com/v1", + reasoning: deepseek, + thinkingLevelMap: deepseek + ? { off: null, minimal: null, low: null, medium: null, high: "high", xhigh: "max", max: "max" } + : undefined, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - contextWindow: 128000, - maxTokens: 1024, + contextWindow: deepseek ? 1_000_000 : 128_000, + maxTokens: deepseek ? 384_000 : 16_384, }; } -function hostStream(model: any, context: any): AssistantMessageEventStream { +function hostStream(model: any, context: any, options: any = {}): AssistantMessageEventStream { const stream = new AssistantMessageEventStream(); const partial: any = { role: "assistant", @@ -81,13 +104,15 @@ function hostStream(model: any, context: any): AssistantMessageEventStream { }; try { if (!globalThis.host) throw new Error("Pocket Pi Agent host is unavailable"); - const id = globalThis.host.startModel(JSON.stringify({ model, context })); + const id = globalThis.host.startModel(JSON.stringify({ model, context, options })); pendingModels.set(id, { stream, model, partial, started: false, + thinkingStarted: false, textStarted: false, + thinking: "", text: "", }); } catch (error) { @@ -102,50 +127,159 @@ function ensureModelStarted(pending: PendingModel): void { pending.stream.push({ type: "start", partial: { ...pending.partial } }); } -function pushModelDelta(pending: PendingModel, delta: string): void { +function syncContent(pending: PendingModel): void { + const content: any[] = []; + if (pending.thinkingStarted) { + content.push({ + type: "thinking", + thinking: pending.thinking, + thinkingSignature: "reasoning_content", + }); + } + if (pending.textStarted) content.push({ type: "text", text: pending.text }); + pending.partial.content = content; +} + +function pushThinkingDelta(pending: PendingModel, delta: string): void { + if (!delta) return; + if (pending.textStarted) throw new Error("thinking delta arrived after text output started"); + ensureModelStarted(pending); + if (!pending.thinkingStarted) { + pending.thinkingStarted = true; + syncContent(pending); + pending.stream.push({ type: "thinking_start", contentIndex: 0, partial: { ...pending.partial } }); + } + pending.thinking += delta; + syncContent(pending); + pending.stream.push({ + type: "thinking_delta", + contentIndex: 0, + delta, + partial: { ...pending.partial }, + }); +} + +function textIndex(pending: PendingModel): number { + return pending.thinkingStarted ? 1 : 0; +} + +function pushTextDelta(pending: PendingModel, delta: string): void { + if (!delta) return; ensureModelStarted(pending); if (!pending.textStarted) { pending.textStarted = true; - pending.stream.push({ type: "text_start", contentIndex: 0, partial: { ...pending.partial } }); + syncContent(pending); + pending.stream.push({ + type: "text_start", + contentIndex: textIndex(pending), + partial: { ...pending.partial }, + }); } pending.text += delta; - pending.partial.content = [{ type: "text", text: pending.text }]; + syncContent(pending); pending.stream.push({ type: "text_delta", - contentIndex: 0, + contentIndex: textIndex(pending), delta, partial: { ...pending.partial }, }); } +function appendFinalDelta( + current: string, + complete: string, + append: (delta: string) => void, + label: string, +): void { + if (current === complete) return; + if (!complete.startsWith(current)) throw new Error(`${label} stream does not match final result`); + append(complete.slice(current.length)); +} + function finishModel(pending: PendingModel, result: ModelResult): void { ensureModelStarted(pending); - pending.partial.stopReason = result.stopReason || "stop"; - if (result.toolCall) { + if (typeof result.thinking !== "string" || typeof result.text !== "string") { + throw new Error("model result is missing thinking or text"); + } + if (!Array.isArray(result.toolCalls)) throw new Error("model result is missing toolCalls"); + if (!result.usage || typeof result.usage !== "object") { + throw new Error("model result is missing usage"); + } + if (result.thinking && typeof result.thinkingSignature !== "string") { + throw new Error("thinking result is missing thinkingSignature"); + } + if (!(["stop", "length", "toolUse"] as const).includes(result.stopReason)) { + throw new Error("model result has an invalid stopReason"); + } + appendFinalDelta( + pending.thinking, + result.thinking, + (delta) => pushThinkingDelta(pending, delta), + "thinking", + ); + appendFinalDelta( + pending.text, + result.text, + (delta) => pushTextDelta(pending, delta), + "text", + ); + + pending.partial.usage = { ...emptyUsage(), ...result.usage }; + if (pending.thinkingStarted) { + const thinking = pending.partial.content[0]; + thinking.thinkingSignature = result.thinkingSignature; + pending.stream.push({ + type: "thinking_end", + contentIndex: 0, + content: pending.thinking, + partial: { ...pending.partial }, + }); + } + if (pending.textStarted) { + pending.stream.push({ + type: "text_end", + contentIndex: textIndex(pending), + content: pending.text, + partial: { ...pending.partial }, + }); + } + + if (result.toolCalls.length > 0 && result.stopReason !== "toolUse") { + throw new Error("tool calls require toolUse stopReason"); + } + if (result.toolCalls.length === 0 && result.stopReason === "toolUse") { + throw new Error("toolUse stopReason requires tool calls"); + } + for (const call of result.toolCalls) { + if ( + !call.id || + !call.name || + !call.arguments || + typeof call.arguments !== "object" || + Array.isArray(call.arguments) + ) { + throw new Error("model result contains an invalid tool call"); + } const toolCall = { type: "toolCall" as const, - id: result.toolCall.id || `tool_${Date.now()}`, - name: result.toolCall.name, - arguments: result.toolCall.arguments || {}, + id: call.id, + name: call.name, + arguments: call.arguments, }; - pending.partial.content = [toolCall]; - pending.partial.stopReason = "toolUse"; - pending.stream.push({ type: "toolcall_start", contentIndex: 0, partial: { ...pending.partial } }); - pending.stream.push({ type: "toolcall_end", contentIndex: 0, toolCall, partial: { ...pending.partial } }); - pending.stream.push({ type: "done", reason: "toolUse", message: { ...pending.partial } }); - return; + const contentIndex = pending.partial.content.length; + pending.partial.content = [...pending.partial.content, toolCall]; + pending.stream.push({ type: "toolcall_start", contentIndex, partial: { ...pending.partial } }); + pending.stream.push({ + type: "toolcall_end", + contentIndex, + toolCall, + partial: { ...pending.partial }, + }); } + if (pending.partial.content.length === 0) throw new Error("model result contains no decision"); - const finalText = String(result.text || pending.text); - if (!pending.textStarted || finalText !== pending.text) { - const delta = finalText.startsWith(pending.text) ? finalText.slice(pending.text.length) : finalText; - if (delta) pushModelDelta(pending, delta); - } - if (!pending.textStarted) pushModelDelta(pending, ""); - pending.text = finalText; - pending.partial.content = [{ type: "text", text: finalText }]; - pending.stream.push({ type: "text_end", contentIndex: 0, content: finalText, partial: { ...pending.partial } }); - pending.stream.push({ type: "done", reason: pending.partial.stopReason, message: { ...pending.partial } }); + pending.partial.stopReason = result.stopReason; + pending.stream.push({ type: "done", reason: result.stopReason, message: { ...pending.partial } }); } function pushModelError(stream: AssistantMessageEventStream, model: any, message: string): void { @@ -191,7 +325,7 @@ function boot(configJson: string): void { initialState: { systemPrompt: config.systemPrompt || "You are Pocket Pi running on an embedded device.", model, - thinkingLevel: "off", + thinkingLevel: model.reasoning ? config.thinkingLevel || "high" : "off", tools, }, streamFn: hostStream as any, @@ -227,15 +361,17 @@ function abort(): void { function tick(): void { const batch = JSON.parse(globalThis.host?.poll() || "[]") as HostEvent[]; for (const event of batch) { - if (event.type === "model_delta") { + if (event.type === "model_progress") { const pending = pendingModels.get(event.id); - if (pending) pushModelDelta(pending, String(event.delta || "")); + if (!pending) continue; + pushThinkingDelta(pending, event.thinkingDelta); + pushTextDelta(pending, event.textDelta); } else if (event.type === "model_done") { const pending = pendingModels.get(event.id); if (!pending) continue; pendingModels.delete(event.id); try { - finishModel(pending, JSON.parse(event.result || "{}") as ModelResult); + finishModel(pending, JSON.parse(event.result) as ModelResult); } catch (error) { pushModelError(pending.stream, pending.model, String(error)); } @@ -249,7 +385,7 @@ function tick(): void { if (!pending) continue; pendingTools.delete(event.id); try { - const result = JSON.parse(event.result || "{}"); + const result = JSON.parse(event.result); if (result.isError) throw new Error(String(result.text || "App tool failed")); pending.resolve({ content: [{ type: "text" as const, text: String(result.text || "") }], diff --git a/crates/pocket-pi-embedded/src/lib.rs b/crates/pocket-pi-embedded/src/lib.rs index 96047a8..22d95e5 100644 --- a/crates/pocket-pi-embedded/src/lib.rs +++ b/crates/pocket-pi-embedded/src/lib.rs @@ -4,15 +4,18 @@ use std::time::Duration; use pocket_mod::qjs::{CatchResultExt, Function, Object}; use pocket_mod::Guest; +pub use pocket_pi_protocols::model::ModelStreamEvent; const AGENT_BUNDLE: &str = include_str!("../js/pi-agent.bundle.js"); const PRELUDE: &str = include_str!("../js/prelude.js"); +const MODEL_WORKER_STACK_BYTES: usize = 64 * 1024; +const TOOL_WORKER_STACK_BYTES: usize = 16 * 1024; pub trait ModelBackend: Send + Sync { fn complete( &self, request_json: &str, - on_delta: &mut dyn FnMut(&str), + on_event: &mut dyn FnMut(ModelStreamEvent), ) -> Result; } @@ -64,7 +67,7 @@ impl ToolResult { /// and Root View have one App lifecycle. Slow model and tool work happens on /// worker threads; `tick` only delivers completed events into the Guest. pub struct GuestAgent { - events: mpsc::Receiver, + on_text: Arc, } impl GuestAgent { @@ -90,12 +93,11 @@ impl GuestAgent { backend: Arc, tools: Arc, agent_source: &str, - on_delta: Arc, + on_text: Arc, ) -> Result { let config_json = config_with_tools(config_json, tools.definitions())?; let (host_tx, host_rx) = mpsc::channel::(); let host_rx = Arc::new(Mutex::new(host_rx)); - let (event_tx, event_rx) = mpsc::channel::(); let next_request = Arc::new(AtomicI32::new(1)); guest @@ -108,39 +110,35 @@ impl GuestAgent { Function::new(ctx.clone(), { let backend = backend.clone(); let host_tx = host_tx.clone(); - let event_tx = event_tx.clone(); let next_request = next_request.clone(); - let on_delta = on_delta.clone(); move |request: String| -> i32 { let id = next_request.fetch_add(1, Ordering::Relaxed); let backend = backend.clone(); let host_tx = host_tx.clone(); let worker_tx = host_tx.clone(); - let event_tx = event_tx.clone(); - let on_delta = on_delta.clone(); let spawn = std::thread::Builder::new() .name(format!("pi-model-{id}")) + .stack_size(MODEL_WORKER_STACK_BYTES) .spawn(move || { - // Providers may stream internally, but the embedded UI - // receives one complete text update per model request. - // Fine-grained deltas are prohibitively expensive on the - // ESP32 and add no value to the fixed Chat projection. - let mut buffered = String::new(); - let mut collect = |delta: &str| buffered.push_str(delta); - match backend.complete(&request, &mut collect) { + let mut emit = |event| { + let event = match event { + ModelStreamEvent::Thinking(delta) => serde_json::json!({ + "type":"model_progress", + "id":id, + "thinkingDelta":delta, + "textDelta":"", + }), + ModelStreamEvent::Text(delta) => serde_json::json!({ + "type":"model_progress", + "id":id, + "thinkingDelta":"", + "textDelta":delta, + }), + }; + let _ = worker_tx.send(event); + }; + match backend.complete(&request, &mut emit) { Ok(result) => { - let final_text = model_result_text(&result) - .or_else(|| (!buffered.is_empty()).then_some(buffered)); - if let Some(text) = final_text { - on_delta(text.clone()); - let _ = event_tx - .send(AgentEvent::ResponseText(text.clone())); - let _ = worker_tx.send(serde_json::json!({ - "type":"model_delta", - "id":id, - "delta":text, - })); - } let _ = worker_tx.send(serde_json::json!({ "type":"model_done", "id":id, @@ -180,6 +178,7 @@ impl GuestAgent { let worker_tx = host_tx.clone(); let spawn = std::thread::Builder::new() .name(format!("pi-tool-{id}")) + .stack_size(TOOL_WORKER_STACK_BYTES) .spawn(move || { let result = tools.execute(&call_id, &name, &args); let _ = worker_tx.send(serde_json::json!({ @@ -211,7 +210,7 @@ impl GuestAgent { move || -> String { let batch = host_rx .lock() - .map(|receiver| receiver.try_iter().collect::>()) + .map(|receiver| coalesce_host_events(receiver.try_iter())) .unwrap_or_default(); serde_json::to_string(&batch).unwrap_or_else(|_| "[]".to_owned()) } @@ -231,7 +230,7 @@ impl GuestAgent { call_agent::<_, ()>(guest, "boot", (config_json,))?; guest.drain_jobs(); - Ok(Self { events: event_rx }) + Ok(Self { on_text }) } pub fn prompt(&self, guest: &Guest, text: &str) -> Result<(), String> { @@ -248,10 +247,16 @@ impl GuestAgent { let raw: String = call_agent(guest, "drain", ())?; let payload: serde_json::Value = serde_json::from_str(&raw) .map_err(|error| format!("parse Pi Agent events: {error}"))?; - let mut events = self.events.try_iter().collect::>(); + let mut events = Vec::new(); for event in payload["events"].as_array().into_iter().flatten() { match event["type"].as_str() { Some("agent_ready") => events.push(AgentEvent::Ready), + Some("message_update") if event["kind"] == "text_delta" => { + if let Some(delta) = event["delta"].as_str().filter(|delta| !delta.is_empty()) { + (self.on_text)(delta.to_owned()); + events.push(AgentEvent::ResponseText(delta.to_owned())); + } + } Some("agent_end") => events.push(AgentEvent::Done), Some("agent_error") => events.push(AgentEvent::Failed( event["message"] @@ -266,19 +271,35 @@ impl GuestAgent { } } -fn model_result_text(result: &str) -> Option { - let result = serde_json::from_str::(result).ok()?; - if result - .get("toolCall") - .is_some_and(serde_json::Value::is_object) - { - return None; +fn coalesce_host_events( + source: impl IntoIterator, +) -> Vec { + let mut batch = Vec::::new(); + let mut progress = std::collections::BTreeMap::::new(); + for event in source { + if event["type"] != "model_progress" { + batch.push(event); + continue; + } + let id = event["id"].as_i64().unwrap_or_default(); + let entry = progress.entry(id).or_insert_with(|| { + batch.push(serde_json::Value::Null); + (batch.len() - 1, String::new(), String::new()) + }); + entry + .1 + .push_str(event["thinkingDelta"].as_str().unwrap_or("")); + entry.2.push_str(event["textDelta"].as_str().unwrap_or("")); + } + for (id, (index, thinking, text)) in progress { + batch[index] = serde_json::json!({ + "type":"model_progress", + "id":id, + "thinkingDelta":thinking, + "textDelta":text, + }); } - result - .get("text")? - .as_str() - .filter(|text| !text.is_empty()) - .map(str::to_owned) + batch } fn call_agent(guest: &Guest, name: &str, args: A) -> Result @@ -299,7 +320,7 @@ where }) } -/// Standalone compatibility harness. Product hosts should mount `GuestAgent` +/// Standalone harness. Product hosts should mount `GuestAgent` /// through `AppSupervisor`, which keeps the System App alive across View /// navigation. pub struct PiEmbedded { @@ -312,11 +333,11 @@ impl PiEmbedded { config_json: &str, backend: Arc, tools: Arc, - on_delta: Arc, + on_text: Arc, ) -> Result { let guest = Guest::new().map_err(|error| error.to_string())?; let agent = - GuestAgent::mount_source(&guest, config_json, backend, tools, AGENT_BUNDLE, on_delta)?; + GuestAgent::mount_source(&guest, config_json, backend, tools, AGENT_BUNDLE, on_text)?; Ok(Self { guest, agent }) } @@ -375,6 +396,7 @@ fn config_with_tools( #[cfg(test)] mod tests { use super::*; + use std::sync::atomic::AtomicUsize; struct Backend; @@ -382,10 +404,17 @@ mod tests { fn complete( &self, _request_json: &str, - on_delta: &mut dyn FnMut(&str), + on_event: &mut dyn FnMut(ModelStreamEvent), ) -> Result { - on_delta("embedded-ok"); - Ok(r#"{"text":"embedded-ok"}"#.into()) + on_event(ModelStreamEvent::Text("embedded-ok".into())); + Ok(serde_json::json!({ + "thinking":"", + "text":"embedded-ok", + "toolCalls":[], + "usage":{}, + "stopReason":"stop" + }) + .to_string()) } } @@ -395,12 +424,19 @@ mod tests { fn complete( &self, _request_json: &str, - on_delta: &mut dyn FnMut(&str), + on_event: &mut dyn FnMut(ModelStreamEvent), ) -> Result { for _ in 0..100 { - on_delta("x"); + on_event(ModelStreamEvent::Text("x".into())); } - Ok(serde_json::json!({"text":"x".repeat(100)}).to_string()) + Ok(serde_json::json!({ + "thinking":"", + "text":"x".repeat(100), + "toolCalls":[], + "usage":{}, + "stopReason":"stop" + }) + .to_string()) } } @@ -432,16 +468,6 @@ mod tests { assert_eq!(config["tools"].as_array().unwrap().len(), 1); } - #[test] - fn tool_call_results_do_not_emit_assistant_text() { - let result = serde_json::json!({ - "text":"provider preamble", - "toolCall":{"name":"echo","arguments":{}} - }) - .to_string(); - assert_eq!(model_result_text(&result), None); - } - #[test] fn boots_and_runs_a_real_pi_agent_turn() { let runtime = PiEmbedded::new( @@ -457,7 +483,7 @@ mod tests { } #[test] - fn model_deltas_are_coalesced_before_reaching_the_embedded_ui() { + fn model_progress_is_coalesced_before_reaching_the_embedded_ui() { let guest = Guest::new().unwrap(); let agent = GuestAgent::mount( &guest, @@ -490,4 +516,135 @@ mod tests { assert!(done); assert_eq!(deltas, ["x".repeat(100)]); } + + struct ThinkingToolBackend { + calls: AtomicUsize, + requests: Arc>>, + } + + impl ModelBackend for ThinkingToolBackend { + fn complete( + &self, + request_json: &str, + on_event: &mut dyn FnMut(ModelStreamEvent), + ) -> Result { + self.requests + .lock() + .unwrap() + .push(serde_json::from_str(request_json).unwrap()); + if self.calls.fetch_add(1, Ordering::SeqCst) == 0 { + on_event(ModelStreamEvent::Thinking("use both tools".into())); + return Ok(serde_json::json!({ + "thinking":"use both tools", + "thinkingSignature":"reasoning_content", + "text":"", + "toolCalls":[ + {"id":"call_first","name":"first","arguments":{"n":1}}, + {"id":"call_second","name":"second","arguments":{"n":2}} + ], + "usage":{"reasoning":3}, + "stopReason":"toolUse" + }) + .to_string()); + } + on_event(ModelStreamEvent::Thinking("both finished".into())); + on_event(ModelStreamEvent::Text("complete".into())); + Ok(serde_json::json!({ + "thinking":"both finished", + "thinkingSignature":"reasoning_content", + "text":"complete", + "toolCalls":[], + "usage":{"reasoning":2}, + "stopReason":"stop" + }) + .to_string()) + } + } + + struct OrderedTools(Arc>>); + + impl ToolHost for OrderedTools { + fn definitions(&self) -> Vec { + ["first", "second"] + .into_iter() + .map(|name| { + serde_json::json!({ + "name":name, + "description":name, + "parameters":{"type":"object","properties":{"n":{"type":"number"}}} + }) + }) + .collect() + } + + fn execute(&self, _call_id: &str, name: &str, _args_json: &str) -> ToolResult { + self.0.lock().unwrap().push(name.into()); + ToolResult::text(format!("{name}-done")) + } + } + + #[test] + fn preserves_thinking_and_executes_multiple_tools_sequentially() { + let requests = Arc::new(Mutex::new(Vec::new())); + let executed = Arc::new(Mutex::new(Vec::new())); + let guest = Guest::new().unwrap(); + let agent = GuestAgent::mount( + &guest, + r#"{"provider":"deepseek","model":"deepseek-v4-pro","thinkingLevel":"high"}"#, + Arc::new(ThinkingToolBackend { + calls: AtomicUsize::new(0), + requests: requests.clone(), + }), + Arc::new(OrderedTools(executed.clone())), + ) + .unwrap(); + agent.prompt(&guest, "run both").unwrap(); + + let mut text = String::new(); + let mut done = false; + for _ in 0..500 { + for event in agent.tick(&guest).unwrap() { + match event { + AgentEvent::ResponseText(delta) => text.push_str(&delta), + AgentEvent::Done => done = true, + AgentEvent::Failed(error) => panic!("agent failed: {error}"), + AgentEvent::Ready => {} + } + } + if done { + break; + } + std::thread::sleep(Duration::from_millis(2)); + } + + assert!(done); + assert_eq!(text, "complete"); + assert_eq!(*executed.lock().unwrap(), ["first", "second"]); + let requests = requests.lock().unwrap(); + assert_eq!(requests.len(), 2); + assert_eq!(requests[0]["options"]["reasoning"], "high"); + let messages = requests[1]["context"]["messages"].as_array().unwrap(); + let assistant = messages + .iter() + .find(|message| message["role"] == "assistant") + .unwrap(); + assert_eq!(assistant["content"][0]["type"], "thinking"); + assert_eq!(assistant["content"][0]["thinking"], "use both tools"); + assert_eq!( + assistant["content"] + .as_array() + .unwrap() + .iter() + .filter(|block| block["type"] == "toolCall") + .count(), + 2 + ); + assert_eq!( + messages + .iter() + .filter(|message| message["role"] == "toolResult") + .count(), + 2 + ); + } } diff --git a/crates/pocket-pi-protocols/src/anthropic_messages.rs b/crates/pocket-pi-protocols/src/anthropic_messages.rs index d973152..65b4ca0 100644 --- a/crates/pocket-pi-protocols/src/anthropic_messages.rs +++ b/crates/pocket-pi-protocols/src/anthropic_messages.rs @@ -1,9 +1,12 @@ +use alloc::collections::BTreeMap; use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; use serde_json::{json, Map, Value}; +use crate::model::ModelStreamEvent; + pub fn build_request(request_json: &str) -> Result { let request: Value = serde_json::from_str(request_json) .map_err(|error| format!("parse Pi model request: {error}"))?; @@ -73,17 +76,22 @@ pub fn build_request(request_json: &str) -> Result { .map_err(|error| format!("serialize Anthropic request: {error}")) } +#[derive(Default)] +struct PendingToolCall { + id: String, + name: String, + arguments: String, +} + #[derive(Default)] pub struct Stream { text: String, - tool_id: String, - tool_name: String, - tool_arguments: String, + tool_calls: BTreeMap, stop_reason: Option, } impl Stream { - pub fn push(&mut self, data_json: &str) -> Result, String> { + pub fn push(&mut self, data_json: &str) -> Result, String> { let event: Value = serde_json::from_str(data_json) .map_err(|error| format!("parse Anthropic stream event: {error}"))?; match event.get("type").and_then(Value::as_str) { @@ -97,14 +105,16 @@ impl Stream { .and_then(Value::as_object) .ok_or_else(|| "Anthropic content block is missing".to_string())?; if block.get("type").and_then(Value::as_str) == Some("tool_use") { - self.tool_id = block.get("id").and_then(Value::as_str).unwrap_or("").into(); - self.tool_name = block + let index = event.get("index").and_then(Value::as_u64).unwrap_or(0); + let call = self.tool_calls.entry(index).or_default(); + call.id = block.get("id").and_then(Value::as_str).unwrap_or("").into(); + call.name = block .get("name") .and_then(Value::as_str) .unwrap_or("") .into(); } - Ok(None) + Ok(Vec::new()) } Some("content_block_delta") => { let delta = event @@ -115,15 +125,24 @@ impl Stream { Some("text_delta") => { let text = delta.get("text").and_then(Value::as_str).unwrap_or(""); self.text.push_str(text); - Ok((!text.is_empty()).then(|| text.to_string())) + Ok(if text.is_empty() { + Vec::new() + } else { + alloc::vec![ModelStreamEvent::Text(text.to_string())] + }) } Some("input_json_delta") => { if let Some(json) = delta.get("partial_json").and_then(Value::as_str) { - self.tool_arguments.push_str(json); + let index = event.get("index").and_then(Value::as_u64).unwrap_or(0); + self.tool_calls + .entry(index) + .or_default() + .arguments + .push_str(json); } - Ok(None) + Ok(Vec::new()) } - _ => Ok(None), + _ => Ok(Vec::new()), } } Some("message_delta") => { @@ -131,41 +150,51 @@ impl Stream { .pointer("/delta/stop_reason") .and_then(Value::as_str) .map(ToString::to_string); - Ok(None) + Ok(Vec::new()) } - _ => Ok(None), + _ => Ok(Vec::new()), } } pub fn finish(self) -> Result { - if !self.tool_name.is_empty() { - if self.tool_id.is_empty() { - return Err("Anthropic tool use is missing id".into()); + let stop_reason = match self.stop_reason.as_deref() { + Some("end_turn" | "stop_sequence") => "stop", + Some("tool_use") => "toolUse", + Some("max_tokens") if self.tool_calls.is_empty() => "length", + Some("max_tokens") => return Err("Anthropic truncated streamed tool calls".into()), + Some(reason) => return Err(format!("unsupported Anthropic stop reason: {reason}")), + None => return Err("Anthropic stream ended without stop_reason".into()), + }; + let mut tool_calls = Vec::new(); + for (_, call) in self.tool_calls { + if call.id.is_empty() || call.name.is_empty() { + return Err("Anthropic tool use is missing id or name".into()); } - let arguments: Value = serde_json::from_str(if self.tool_arguments.is_empty() { + let arguments: Value = serde_json::from_str(if call.arguments.is_empty() { "{}" } else { - &self.tool_arguments + &call.arguments }) .map_err(|error| format!("parse Anthropic tool input: {error}"))?; if !arguments.is_object() { return Err("Anthropic tool input must be an object".into()); } - return serde_json::to_string(&json!({ - "toolCall":{"id":self.tool_id,"name":self.tool_name,"arguments":arguments} - })) - .map_err(|error| format!("serialize Pi tool call: {error}")); + tool_calls.push(json!({"id":call.id,"name":call.name,"arguments":arguments})); } - if self.text.is_empty() { + if self.text.is_empty() && tool_calls.is_empty() { return Err("Anthropic stream contained no model decision".into()); } - let stop_reason = if self.stop_reason.as_deref() == Some("max_tokens") { - "length" - } else { - "stop" - }; - serde_json::to_string(&json!({"text":self.text,"stopReason":stop_reason})) - .map_err(|error| format!("serialize Pi text result: {error}")) + serde_json::to_string(&json!({ + "thinking":"", + "text":self.text, + "toolCalls":tool_calls, + "usage":{ + "input":0,"output":0,"cacheRead":0,"cacheWrite":0,"totalTokens":0, + "cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0,"total":0} + }, + "stopReason":stop_reason + })) + .map_err(|error| format!("serialize Anthropic model result: {error}")) } } @@ -234,6 +263,7 @@ fn content_text(content: Option<&Value>) -> String { #[cfg(test)] mod tests { use super::*; + use alloc::vec; #[test] fn streams_text() { @@ -242,9 +272,29 @@ mod tests { stream .push(r#"{"type":"content_block_delta","delta":{"type":"text_delta","text":"hi"}}"#) .unwrap(), - Some("hi".into()) + vec![ModelStreamEvent::Text("hi".into())] ); + stream + .push(r#"{"type":"message_delta","delta":{"stop_reason":"end_turn"}}"#) + .unwrap(); let result: Value = serde_json::from_str(&stream.finish().unwrap()).unwrap(); assert_eq!(result["text"], "hi"); } + + #[test] + fn streams_multiple_tool_calls() { + let mut stream = Stream::default(); + for event in [ + r#"{"type":"content_block_start","index":0,"content_block":{"type":"tool_use","id":"one","name":"first"}}"#, + r#"{"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":"{}"}}"#, + r#"{"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"two","name":"second"}}"#, + r#"{"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"n\":2}"}}"#, + r#"{"type":"message_delta","delta":{"stop_reason":"tool_use"}}"#, + ] { + stream.push(event).unwrap(); + } + let result: Value = serde_json::from_str(&stream.finish().unwrap()).unwrap(); + assert_eq!(result["toolCalls"].as_array().unwrap().len(), 2); + assert_eq!(result["stopReason"], "toolUse"); + } } diff --git a/crates/pocket-pi-protocols/src/codex_decision.rs b/crates/pocket-pi-protocols/src/codex_decision.rs index 9f49f13..7e09885 100644 --- a/crates/pocket-pi-protocols/src/codex_decision.rs +++ b/crates/pocket-pi-protocols/src/codex_decision.rs @@ -4,8 +4,8 @@ use alloc::vec::Vec; use serde_json::{json, Value}; -/// Build the same single-decision prompt used by the board's Codex bridge. -/// Codex chooses one ESP tool call or a final text response; it never executes +/// Build the same decision prompt used by the board's Codex bridge. +/// Codex chooses ESP tool calls or a final text response; it never executes /// host tools itself. pub fn build_prompt(request_json: &str) -> Result<(String, Vec), String> { let request: Value = serde_json::from_str(request_json) @@ -40,10 +40,10 @@ pub fn build_prompt(request_json: &str) -> Result<(String, Vec), String> .unwrap_or(""); let prompt = format!( "You are the model decision backend for a Pi Agent running on an ESP32-P4.\n\n\ - Do not call host tools or inspect Mac files. The JSON tools below run only on the ESP32 after you request one.\n\n\ + Do not call host tools or inspect Mac files. The JSON tools below run only on the ESP32 after you request them.\n\n\ Return exactly one compact JSON object and no Markdown. Choose either \ - {{\"toolCall\":{{\"name\":\"registered.name\",\"arguments\":{{...}}}}}} to take one action, \ - or {{\"text\":\"final response\"}} when the turn is complete. After a tool result you may request the next tool. \ + {{\"toolCalls\":[{{\"name\":\"registered.name\",\"arguments\":{{...}}}}]}} to take actions, \ + or {{\"text\":\"final response\"}} when the turn is complete. \ Never claim an action succeeded until its tool result appears in the conversation.\n\n\ System instruction: {system}\n\n\ Registered ESP32 tools: {}\n\n\ @@ -66,27 +66,58 @@ pub fn parse_response(raw: &str, tools: &[String], call_id: &str) -> Result "openai", Self::OpenRouter => "openrouter", Self::Anthropic => "anthropic", + Self::DeepSeek => "deepseek", } } pub fn default_model(self) -> Option<&'static str> { match self { Self::OpenAi => Some("gpt-5-mini"), + Self::DeepSeek => Some("deepseek-v4-pro"), Self::OpenRouter | Self::Anthropic => None, } } @@ -66,6 +74,24 @@ impl Default for ModelBackendSettings { pub struct ModelSettings { pub backend: ModelBackendSettings, pub model: Option, + pub thinking_level: ThinkingLevel, +} + +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum ThinkingLevel { + #[default] + High, + Xhigh, +} + +impl ThinkingLevel { + pub fn id(self) -> &'static str { + match self { + Self::High => "high", + Self::Xhigh => "xhigh", + } + } } impl ModelSettings { @@ -93,10 +119,19 @@ mod tests { use super::*; #[test] - fn defaults_to_uart_codex_without_a_secret() { + fn resolves_backend_defaults_without_secrets() { let settings = ModelSettings::default(); assert_eq!(settings.resolved_model().unwrap(), "codex"); let json = serde_json::to_string(&settings).unwrap(); assert!(!json.contains("key")); + let settings = ModelSettings { + backend: ModelBackendSettings::Wireless { + provider: WirelessProvider::DeepSeek, + }, + model: None, + thinking_level: ThinkingLevel::Xhigh, + }; + assert_eq!(settings.resolved_model().unwrap(), "deepseek-v4-pro"); + assert_eq!(settings.thinking_level.id(), "xhigh"); } } diff --git a/crates/pocket-pi-protocols/src/openai_chat.rs b/crates/pocket-pi-protocols/src/openai_chat.rs index 2da47c9..decd911 100644 --- a/crates/pocket-pi-protocols/src/openai_chat.rs +++ b/crates/pocket-pi-protocols/src/openai_chat.rs @@ -1,23 +1,25 @@ +use alloc::collections::BTreeMap; use alloc::format; use alloc::string::{String, ToString}; use alloc::vec::Vec; use serde_json::{json, Map, Value}; +use crate::model::ModelStreamEvent; + +const DEEPSEEK_TOOL_SEPARATOR: &str = "_dot_"; + #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Dialect { OpenAi, OpenRouter, + DeepSeek, } -/// Convert the provider-neutral request emitted by embedded Pi into OpenAI's -/// streaming Chat Completions wire format. pub fn build_request(request_json: &str) -> Result { build_request_for(request_json, Dialect::OpenAi) } -/// OpenAI and OpenRouter share this wire format, but use different token field -/// names. Provider selection remains outside the Pi runtime. pub fn build_request_for(request_json: &str, dialect: Dialect) -> Result { let request: Value = serde_json::from_str(request_json) .map_err(|error| format!("parse Pi model request: {error}"))?; @@ -45,92 +47,185 @@ pub fn build_request_for(request_json: &str, dialect: Dialect) -> Result, String>>()?; + let max_tokens = request + .pointer("/options/maxTokens") + .and_then(Value::as_u64) + .or_else(|| request.pointer("/model/maxTokens").and_then(Value::as_u64)) + .unwrap_or(1024) + .clamp(1, 384_000); let mut body = Map::new(); body.insert("model".into(), Value::String(model.into())); body.insert("messages".into(), Value::Array(messages)); body.insert( - match dialect { - Dialect::OpenAi => "max_completion_tokens", - Dialect::OpenRouter => "max_tokens", + if dialect == Dialect::OpenAi { + "max_completion_tokens" + } else { + "max_tokens" } .into(), - Value::from( - request - .pointer("/model/maxTokens") - .and_then(Value::as_u64) - .unwrap_or(1024) - .clamp(1, 16_384), - ), + Value::from(max_tokens), ); body.insert("stream".into(), Value::Bool(true)); - body.insert("parallel_tool_calls".into(), Value::Bool(false)); + + if dialect == Dialect::DeepSeek { + let reasoning = request + .pointer("/options/reasoning") + .and_then(Value::as_str) + .unwrap_or("high"); + body.insert("thinking".into(), json!({"type":"enabled"})); + body.insert( + "reasoning_effort".into(), + Value::String(if matches!(reasoning, "xhigh" | "max") { + "max".into() + } else { + "high".into() + }), + ); + body.insert("stream_options".into(), json!({"include_usage":true})); + } else { + body.insert("parallel_tool_calls".into(), Value::Bool(false)); + } + if !tools.is_empty() { body.insert("tools".into(), Value::Array(tools)); - body.insert("tool_choice".into(), Value::String("auto".into())); + if dialect != Dialect::DeepSeek { + body.insert("tool_choice".into(), Value::String("auto".into())); + } } + serde_json::to_string(&Value::Object(body)) - .map_err(|error| format!("serialize OpenAI request: {error}")) + .map_err(|error| format!("serialize chat completions request: {error}")) +} + +#[derive(Default)] +struct PendingToolCall { + id: String, + name: String, + arguments: String, } #[derive(Default)] +struct Usage { + input: u64, + output: u64, + cache_read: u64, + reasoning: u64, + total: u64, +} + pub struct Stream { + dialect: Dialect, + thinking: String, text: String, - tool_id: String, - tool_name: String, - tool_arguments: String, + tool_calls: BTreeMap, + usage: Usage, stop_reason: Option, } +impl Default for Stream { + fn default() -> Self { + Self::new(Dialect::OpenAi) + } +} + impl Stream { - pub fn push(&mut self, data_json: &str) -> Result, String> { + pub fn new(dialect: Dialect) -> Self { + Self { + dialect, + thinking: String::new(), + text: String::new(), + tool_calls: BTreeMap::new(), + usage: Usage::default(), + stop_reason: None, + } + } + + pub fn push(&mut self, data_json: &str) -> Result, String> { let event: Value = serde_json::from_str(data_json) - .map_err(|error| format!("parse OpenAI stream event: {error}"))?; + .map_err(|error| format!("parse chat completions stream event: {error}"))?; if let Some(error) = event.get("error") { - return Err(format!("OpenAI stream error: {error}")); + return Err(format!("chat completions stream error: {error}")); + } + if let Some(usage) = event.get("usage").and_then(Value::as_object) { + self.usage.input = usage + .get("prompt_tokens") + .and_then(Value::as_u64) + .unwrap_or(0); + self.usage.output = usage + .get("completion_tokens") + .and_then(Value::as_u64) + .unwrap_or(0); + self.usage.total = usage + .get("total_tokens") + .and_then(Value::as_u64) + .unwrap_or(self.usage.input.saturating_add(self.usage.output)); + self.usage.cache_read = usage + .get("prompt_tokens_details") + .and_then(|details| details.get("cached_tokens")) + .and_then(Value::as_u64) + .or_else(|| usage.get("prompt_cache_hit_tokens").and_then(Value::as_u64)) + .unwrap_or(0); + self.usage.reasoning = usage + .get("completion_tokens_details") + .and_then(|details| details.get("reasoning_tokens")) + .and_then(Value::as_u64) + .unwrap_or(0); } + let Some(choice) = event .get("choices") .and_then(Value::as_array) .and_then(|choices| choices.first()) else { - return Ok(None); + return Ok(Vec::new()); }; if let Some(reason) = choice.get("finish_reason").and_then(Value::as_str) { self.stop_reason = Some(reason.into()); } let Some(delta) = choice.get("delta").and_then(Value::as_object) else { - return Ok(None); + return Ok(Vec::new()); }; + + let mut events = Vec::new(); + if let Some(thinking) = delta.get("reasoning_content").and_then(Value::as_str) { + if !thinking.is_empty() { + self.thinking.push_str(thinking); + events.push(ModelStreamEvent::Thinking(thinking.into())); + } + } if let Some(content) = delta.get("content").and_then(Value::as_str) { - self.text.push_str(content); - return Ok(Some(content.into())); + if !content.is_empty() { + self.text.push_str(content); + events.push(ModelStreamEvent::Text(content.into())); + } } for call in delta .get("tool_calls") @@ -138,57 +233,92 @@ impl Stream { .into_iter() .flatten() { - if call.get("index").and_then(Value::as_u64).unwrap_or(0) != 0 { - return Err("provider streamed multiple tool calls".into()); - } + let index = call.get("index").and_then(Value::as_u64).unwrap_or(0); + let pending = self.tool_calls.entry(index).or_default(); if let Some(id) = call.get("id").and_then(Value::as_str) { - self.tool_id.push_str(id); + pending.id.push_str(id); } if let Some(function) = call.get("function").and_then(Value::as_object) { if let Some(name) = function.get("name").and_then(Value::as_str) { - self.tool_name.push_str(name); + pending.name.push_str(name); } if let Some(arguments) = function.get("arguments").and_then(Value::as_str) { - self.tool_arguments.push_str(arguments); + pending.arguments.push_str(arguments); } } } - Ok(None) + Ok(events) } pub fn finish(self) -> Result { - if !self.tool_name.is_empty() { - if self.tool_id.is_empty() { - return Err("streamed tool call is missing id".into()); + let stop_reason = match self.stop_reason.as_deref() { + Some("stop") => "stop", + Some("tool_calls") => "toolUse", + Some("length") if self.tool_calls.is_empty() => "length", + Some("length") => return Err("provider truncated streamed tool calls".into()), + Some("content_filter") => { + return Err("provider content filter stopped the response".into()) + } + Some("insufficient_system_resource") => { + return Err("provider had insufficient system resources".into()) + } + Some(other) => return Err(format!("unsupported provider finish reason: {other}")), + None => return Err("provider stream ended without finish_reason".into()), + }; + + let mut tool_calls = Vec::new(); + for (_, call) in self.tool_calls { + if call.id.is_empty() || call.name.is_empty() { + return Err("streamed tool call is missing id or name".into()); } - let arguments: Value = serde_json::from_str(if self.tool_arguments.is_empty() { + let arguments: Value = serde_json::from_str(if call.arguments.is_empty() { "{}" } else { - &self.tool_arguments + &call.arguments }) .map_err(|error| format!("parse streamed tool arguments: {error}"))?; if !arguments.is_object() { return Err("streamed tool arguments must be a JSON object".into()); } - return serde_json::to_string(&json!({ - "toolCall":{"id":self.tool_id,"name":self.tool_name,"arguments":arguments} - })) - .map_err(|error| format!("serialize Pi tool call: {error}")); + tool_calls.push(json!({ + "id":call.id, + "name":decode_tool_name(&call.name, self.dialect), + "arguments":arguments + })); } - if self.text.is_empty() { - return Err("provider stream contained neither text nor a tool call".into()); + if self.text.is_empty() && tool_calls.is_empty() { + return Err("provider stream contained no model decision".into()); } - let stop_reason = if self.stop_reason.as_deref() == Some("length") { - "length" - } else { - "stop" - }; - serde_json::to_string(&json!({"text":self.text,"stopReason":stop_reason})) - .map_err(|error| format!("serialize Pi text result: {error}")) + + let mut result = Map::new(); + result.insert("thinking".into(), Value::String(self.thinking.clone())); + if !self.thinking.is_empty() { + result.insert( + "thinkingSignature".into(), + Value::String("reasoning_content".into()), + ); + } + result.insert("text".into(), Value::String(self.text)); + result.insert("toolCalls".into(), Value::Array(tool_calls)); + result.insert( + "usage".into(), + json!({ + "input":self.usage.input, + "output":self.usage.output, + "cacheRead":self.usage.cache_read, + "cacheWrite":0, + "reasoning":self.usage.reasoning, + "totalTokens":self.usage.total, + "cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0,"total":0} + }), + ); + result.insert("stopReason".into(), Value::String(stop_reason.into())); + serde_json::to_string(&Value::Object(result)) + .map_err(|error| format!("serialize model result: {error}")) } } -fn convert_message(message: &Value) -> Result, String> { +fn convert_message(message: &Value, dialect: Dialect) -> Result, String> { let Some(role) = message.get("role").and_then(Value::as_str) else { return Ok(None); }; @@ -198,7 +328,6 @@ fn convert_message(message: &Value) -> Result, String> { "content":content_text(message.get("content")) }))), "assistant" => { - let text = content_text(message.get("content")); let mut tool_calls = Vec::new(); for block in message .get("content") @@ -217,6 +346,7 @@ fn convert_message(message: &Value) -> Result, String> { .get("name") .and_then(Value::as_str) .ok_or_else(|| "Pi assistant toolCall is missing name".to_string())?; + let provider_name = encode_tool_name(name, dialect)?; let arguments = serde_json::to_string( block.get("arguments").unwrap_or(&Value::Object(Map::new())), ) @@ -224,19 +354,21 @@ fn convert_message(message: &Value) -> Result, String> { tool_calls.push(json!({ "id":id, "type":"function", - "function":{"name":name,"arguments":arguments} + "function":{"name":provider_name,"arguments":arguments} })); } let mut converted = Map::new(); converted.insert("role".into(), Value::String("assistant".into())); converted.insert( "content".into(), - if text.is_empty() { - Value::Null - } else { - Value::String(text) - }, + Value::String(content_text(message.get("content"))), ); + if dialect == Dialect::DeepSeek { + let thinking = thinking_text(message.get("content")); + if !thinking.is_empty() { + converted.insert("reasoning_content".into(), Value::String(thinking)); + } + } if !tool_calls.is_empty() { converted.insert("tool_calls".into(), Value::Array(tool_calls)); } @@ -257,19 +389,59 @@ fn convert_message(message: &Value) -> Result, String> { } } +fn encode_tool_name(name: &str, dialect: Dialect) -> Result { + if dialect != Dialect::DeepSeek { + return Ok(name.into()); + } + if name.contains(DEEPSEEK_TOOL_SEPARATOR) { + return Err(format!( + "tool name {name:?} contains reserved DeepSeek separator {DEEPSEEK_TOOL_SEPARATOR:?}" + )); + } + let encoded = name.replace('.', DEEPSEEK_TOOL_SEPARATOR); + if encoded.len() > 64 + || !encoded + .bytes() + .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'_' | b'-')) + { + return Err(format!( + "tool name {name:?} cannot be represented for DeepSeek" + )); + } + Ok(encoded) +} + +fn decode_tool_name(name: &str, dialect: Dialect) -> String { + if dialect == Dialect::DeepSeek { + name.replace(DEEPSEEK_TOOL_SEPARATOR, ".") + } else { + name.into() + } +} + fn content_text(content: Option<&Value>) -> String { + block_text(content, "text", "text") +} + +fn thinking_text(content: Option<&Value>) -> String { + block_text(content, "thinking", "thinking") +} + +fn block_text(content: Option<&Value>, block_type: &str, field: &str) -> String { let Some(content) = content else { return String::new(); }; - if let Some(text) = content.as_str() { - return text.into(); + if block_type == "text" { + if let Some(text) = content.as_str() { + return text.into(); + } } content .as_array() .into_iter() .flatten() - .filter(|block| block.get("type").and_then(Value::as_str) == Some("text")) - .filter_map(|block| block.get("text").and_then(Value::as_str)) + .filter(|block| block.get("type").and_then(Value::as_str) == Some(block_type)) + .filter_map(|block| block.get(field).and_then(Value::as_str)) .collect::>() .join("") } @@ -277,42 +449,94 @@ fn content_text(content: Option<&Value>) -> String { #[cfg(test)] mod tests { use super::*; + use alloc::vec; - #[test] - fn maps_history_and_tools() { - let request = json!({ - "model":{"id":"gpt-5.6","maxTokens":768}, + fn deepseek_request(reasoning: &str) -> Value { + json!({ + "model":{"id":"deepseek-v4-pro","maxTokens":384000}, "context":{ "systemPrompt":"Use tools when needed.", "messages":[{"role":"user","content":"list files"}], "tools":[{"name":"ls","description":"List files","parameters":{"type":"object"}}] - } - }); - let body: Value = - serde_json::from_str(&build_request(&request.to_string()).unwrap()).unwrap(); - assert_eq!(body["model"], "gpt-5.6"); - assert_eq!(body["parallel_tool_calls"], false); - assert_eq!(body["tools"][0]["function"]["name"], "ls"); + }, + "options":{"reasoning":reasoning} + }) + } + + #[test] + fn deepseek_request_encodes_thinking_tools_and_replay() { + let mut request = deepseek_request("xhigh"); + request["context"]["tools"][0]["name"] = json!("time.now"); + request["context"]["messages"] = json!([{ + "role":"assistant", + "content":[ + {"type":"thinking","thinking":"need both tools","thinkingSignature":"reasoning_content"}, + {"type":"toolCall","id":"call_1","name":"time.now","arguments":{}}, + {"type":"toolCall","id":"call_2","name":"device.status","arguments":{"full":true}} + ] + }]); + let body: Value = serde_json::from_str( + &build_request_for(&request.to_string(), Dialect::DeepSeek).unwrap(), + ) + .unwrap(); + assert_eq!(body["model"], "deepseek-v4-pro"); + assert_eq!(body["max_tokens"], 384000); + assert_eq!(body["thinking"]["type"], "enabled"); + assert_eq!(body["reasoning_effort"], "max"); + assert_eq!(body["stream_options"]["include_usage"], true); + assert!(body.get("tool_choice").is_none()); + assert!(body.get("parallel_tool_calls").is_none()); + assert!(body.get("temperature").is_none()); + assert_eq!(body["tools"][0]["function"]["name"], "time_dot_now"); + assert_eq!(body["messages"][1]["content"], ""); + assert_eq!(body["messages"][1]["reasoning_content"], "need both tools"); + assert_eq!( + body["messages"][1]["tool_calls"].as_array().unwrap().len(), + 2 + ); + assert_eq!( + body["messages"][1]["tool_calls"][1]["function"]["name"], + "device_dot_status" + ); } #[test] - fn decodes_streamed_text() { - let mut stream = Stream::default(); + fn deepseek_stream_decodes_thinking_text_multiple_tools_and_usage() { + let mut stream = Stream::new(Dialect::DeepSeek); assert_eq!( stream - .push(r#"{"choices":[{"delta":{"content":"hel"}}]}"#) + .push(r#"{"choices":[{"delta":{"reasoning_content":"think "}}]}"#) .unwrap(), - Some("hel".into()) + vec![ModelStreamEvent::Thinking("think ".into())] ); - stream - .push(r#"{"choices":[{"delta":{"content":"lo"},"finish_reason":"stop"}]}"#) - .unwrap(); + assert_eq!( + stream + .push(r#"{"choices":[{"delta":{"reasoning_content":"more","content":"answer"}}]}"#) + .unwrap(), + vec![ + ModelStreamEvent::Thinking("more".into()), + ModelStreamEvent::Text("answer".into()) + ] + ); + stream.push(r#"{"choices":[{"delta":{"tool_calls":[{"index":1,"id":"call_2","function":{"name":"device_dot_status","arguments":"{\"b\":"}},{"index":0,"id":"call_1","function":{"name":"time_dot_now","arguments":"{}"}}]}}]}"#).unwrap(); + stream.push(r#"{"choices":[{"delta":{"tool_calls":[{"index":1,"function":{"arguments":"2}"}}]},"finish_reason":"tool_calls"}]}"#).unwrap(); + stream.push(r#"{"choices":[],"usage":{"prompt_tokens":10,"completion_tokens":20,"total_tokens":30,"prompt_cache_hit_tokens":4,"completion_tokens_details":{"reasoning_tokens":12}}}"#).unwrap(); let result: Value = serde_json::from_str(&stream.finish().unwrap()).unwrap(); - assert_eq!(result["text"], "hello"); + assert_eq!(result["thinking"], "think more"); + assert_eq!(result["text"], "answer"); + assert_eq!(result["toolCalls"][0]["name"], "time.now"); + assert_eq!(result["toolCalls"][1]["name"], "device.status"); + assert_eq!(result["toolCalls"][1]["arguments"]["b"], 2); + assert_eq!(result["usage"]["reasoning"], 12); + assert_eq!(result["stopReason"], "toolUse"); + + let mut truncated = Stream::new(Dialect::DeepSeek); + truncated.push(r#"{"choices":[{"delta":{"tool_calls":[{"index":0,"id":"call_1","function":{"name":"time_dot_now","arguments":"{"}}]},"finish_reason":"length"}]}"#).unwrap(); + assert!(truncated.finish().unwrap_err().contains("truncated")); } #[test] - fn openrouter_uses_its_token_field() { + fn openrouter_uses_max_tokens() { let request = json!({ "model":{"id":"vendor/model"}, "context":{"messages":[{"role":"user","content":"hi"}]} diff --git a/crates/pocket-pi-tools/src/lib.rs b/crates/pocket-pi-tools/src/lib.rs index d0b8903..d26bef3 100644 --- a/crates/pocket-pi-tools/src/lib.rs +++ b/crates/pocket-pi-tools/src/lib.rs @@ -104,13 +104,19 @@ impl ToolHost for CoreToolHost { Err(error) => return ToolResult::error(format!("invalid tool arguments: {error}")), }; match self.execute_value(call_id, name, &args) { - Ok(result) => ToolResult { - text: result.text, - details: result.details, - is_error: false, - terminate: result.terminate, - }, - Err(error) => ToolResult::error(error), + Ok(result) => { + log::info!("Native tool {name} completed"); + ToolResult { + text: result.text, + details: result.details, + is_error: false, + terminate: result.terminate, + } + } + Err(error) => { + log::warn!("Native tool {name} failed: {error}"); + ToolResult::error(error) + } } } } @@ -151,7 +157,7 @@ mod tests { use super::*; use std::sync::atomic::{AtomicUsize, Ordering}; - use pocket_pi_embedded::{ModelBackend, PiEmbedded}; + use pocket_pi_embedded::{ModelBackend, ModelStreamEvent, PiEmbedded}; struct TestPlatform; @@ -244,7 +250,7 @@ mod tests { fn complete( &self, request_json: &str, - on_delta: &mut dyn FnMut(&str), + on_event: &mut dyn FnMut(ModelStreamEvent), ) -> Result { let request: Value = serde_json::from_str(request_json).unwrap(); let call = self.calls.fetch_add(1, Ordering::SeqCst); @@ -257,11 +263,16 @@ mod tests { .collect::>(); assert!(names.contains(&"write")); return Ok(json!({ - "toolCall":{ + "thinking":"use write", + "thinkingSignature":"reasoning_content", + "text":"", + "toolCalls":[{ "id":"write-1", "name":"write", "arguments":{"path":"agent-created.txt","content":"created through pi-agent-core"} - } + }], + "usage":{}, + "stopReason":"toolUse" }) .to_string()); } @@ -270,8 +281,15 @@ mod tests { .unwrap() .iter() .any(|message| message["role"] == "toolResult")); - on_delta("tool complete"); - Ok(json!({"text":"tool complete"}).to_string()) + on_event(ModelStreamEvent::Text("tool complete".into())); + Ok(json!({ + "thinking":"", + "text":"tool complete", + "toolCalls":[], + "usage":{}, + "stopReason":"stop" + }) + .to_string()) } } diff --git a/docs/agentos-architecture.md b/docs/agentos-architecture.md index 6fce286..a39e664 100644 --- a/docs/agentos-architecture.md +++ b/docs/agentos-architecture.md @@ -774,7 +774,7 @@ Context Assembler 把选定 workspace files 组装成有严格上限的 Agent co | `data.fs` | confinement、quota、atomic replace | App files 和 config | | `net.http` | TLS、credential、policy allowlist、limits、non-blocking transport | `fetch()`、endpoint 选择和 domain decoding | | `mcp.client` | auth、session、framing、limits | safe operation mapping 和 domain semantics | -| `model.stream` | provider transport、内部 stream decode 和完整 result | Agent policy;ESP32 presentation 每次 request 只接收一次完整文本更新 | +| `model.stream` | provider transport、内部 stream decode 和完整 result | Agent policy;thinking/text delta 在每次 host poll 合并后进入 Guest,Root View 只渲染正文 delta | | `schedule.wake` | clock、persistence、claiming | AgentWake 或 AppTask declaration | | `shell.bounded` | allowlisted device/workspace operations | Agent 决定何时调用 | | `device.settings` | Wi-Fi、NVS、restart | Settings View | @@ -813,7 +813,7 @@ Guest 中运行,但 Root View 暂不产生前台 DrawList。用户仍可操作 | 当前能力 | 新架构归属 | | --- | --- | | model request 和 streaming | `model.stream` + Pi Agent Runtime | -| OpenAI/OpenRouter/Anthropic/UART adapters | Host/provider adapters | +| OpenAI/OpenRouter/Anthropic/DeepSeek/UART adapters | Host/provider adapters | | workspace read/write/edit/find/grep/ls | Root Agent workspace Tools | | bounded bash | `shell.bounded` | | `device.status` 和 `time.now` | native device/time Tools | diff --git a/docs/esp32-p4-port.md b/docs/esp32-p4-port.md index 5398d96..41d2968 100644 --- a/docs/esp32-p4-port.md +++ b/docs/esp32-p4-port.md @@ -15,7 +15,7 @@ View. The Pi Agent Root View displays Chat, Apps, Files and Settings; there is no parallel Rust product UI. The physical host selects `UartBackend` for a Mac Codex/Claude Code bridge or -`WirelessBackend` for direct OpenAI/OpenRouter/Anthropic HTTPS. These remain +`WirelessBackend` for direct OpenAI/OpenRouter/Anthropic/DeepSeek HTTPS. These remain host adapters; they do not belong in the UI or embedded Agent core. ```sh @@ -45,6 +45,8 @@ OPENROUTER_API_KEY=... cargo xtask run esp32-p4-sim \ --backend openrouter --model openai/gpt-5.6 ANTHROPIC_API_KEY=... cargo xtask run esp32-p4-sim \ --backend anthropic --model claude-sonnet-4-6 +DEEPSEEK_API_KEY=... DEEPSEEK_THINKING_LEVEL=xhigh \ + cargo xtask run esp32-p4-sim --backend deepseek # Real Agent -> native write tool -> simulated LittleFS workspace cargo xtask run esp32-p4-sim --backend codex \ diff --git a/firmware/esp32-p4/Cargo.lock b/firmware/esp32-p4/Cargo.lock index f8660a7..7261691 100644 --- a/firmware/esp32-p4/Cargo.lock +++ b/firmware/esp32-p4/Cargo.lock @@ -1191,6 +1191,7 @@ name = "pocket-pi-embedded" version = "0.1.0" dependencies = [ "pocket-mod", + "pocket-pi-protocols", "rquickjs", "serde_json", ] diff --git a/firmware/esp32-p4/src/agentos_main.rs b/firmware/esp32-p4/src/agentos_main.rs index 3f75f9f..3376b20 100644 --- a/firmware/esp32-p4/src/agentos_main.rs +++ b/firmware/esp32-p4/src/agentos_main.rs @@ -90,6 +90,10 @@ pub fn run() -> anyhow::Result<()> { }; let model_settings = runtime_config.model.clone(); + let wireless_model = matches!( + model_settings.backend, + ModelBackendSettings::Wireless { .. } + ); let provider = match model_settings.backend { ModelBackendSettings::Uart { .. } => "uart", ModelBackendSettings::Wireless { provider } => provider.id(), @@ -151,7 +155,8 @@ pub fn run() -> anyhow::Result<()> { let config = json!({ "provider":provider, "model":resolved_model, - "systemPrompt":"You are Pi Agent, the first-class system App in Pocket Pi AgentOS on an ESP32-P4. You can manage the top-level /workspace and use installed App tools. Be concise. Robinhood data is owned by the Robinhood App; Exa research history is owned by the Exa App." + "thinkingLevel":model_settings.thinking_level.id(), + "systemPrompt":"You are Pi Agent, the first-class system App in Pocket Pi AgentOS on an ESP32-P4. You can manage the top-level /workspace and use installed App tools. Use /workspace for durable memory, notes, plans, and artifacts; read and update relevant files when continuity matters. Be concise. Robinhood data is owned by the Robinhood App; Exa research history is owned by the Exa App." }); supervisor.boot_agent(&config.to_string(), backend, Arc::new(routed_tools))?; @@ -417,6 +422,7 @@ pub fn run() -> anyhow::Result<()> { } } AgentEvent::Done => { + log::info!("Pi Agent turn completed"); agent_status = "IDLE"; busy = false; } @@ -439,6 +445,7 @@ pub fn run() -> anyhow::Result<()> { && !busy && initial_prompt.is_some() && Instant::now() >= initial_prompt_not_before + && (!wireless_model || network_ready.load(Ordering::Acquire)) { if let Some(prompt) = initial_prompt.take() { submit_prompt( diff --git a/firmware/esp32-p4/src/backend/uart.rs b/firmware/esp32-p4/src/backend/uart.rs index 09a1469..9ee821f 100644 --- a/firmware/esp32-p4/src/backend/uart.rs +++ b/firmware/esp32-p4/src/backend/uart.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use std::time::Duration; use pocket_pi_embedded::ModelBackend; +use pocket_pi_protocols::model::ModelStreamEvent; use crate::transport::LineTransport; @@ -23,7 +24,7 @@ impl ModelBackend for UartBackend { fn complete( &self, request_json: &str, - _on_delta: &mut dyn FnMut(&str), + _on_event: &mut dyn FnMut(ModelStreamEvent), ) -> Result { self.transport.write_line("PPI-RPC-WAITING"); self.transport @@ -42,9 +43,6 @@ impl ModelBackend for UartBackend { ) .map_err(|error| format!("UART stream JSON: {error}"))?; match event.get("type").and_then(serde_json::Value::as_str) { - // Backward-compatible with an older bridge, but do not forward - // fine-grained text updates into the embedded Agent runtime. - Some("text_delta") => {} Some("done") => { return serde_json::to_string( event diff --git a/firmware/esp32-p4/src/backend/wireless.rs b/firmware/esp32-p4/src/backend/wireless.rs index 19748ee..1b73fac 100644 --- a/firmware/esp32-p4/src/backend/wireless.rs +++ b/firmware/esp32-p4/src/backend/wireless.rs @@ -5,12 +5,9 @@ use embedded_svc::io::Write; use esp_idf_svc::http::client::{Configuration, EspHttpConnection}; use pocket_pi_embedded::ModelBackend; use pocket_pi_protocols::anthropic_messages; -use pocket_pi_protocols::model::WirelessProvider; +use pocket_pi_protocols::model::{ModelStreamEvent, WirelessProvider}; use pocket_pi_protocols::openai_chat; -const MAX_REQUEST_BYTES: usize = 128 * 1024; -const MAX_RESPONSE_BYTES: usize = 128 * 1024; - pub struct WirelessBackend { provider: WirelessProvider, api_key: String, @@ -34,6 +31,10 @@ impl WirelessBackend { "https://openrouter.ai/api/v1/chat/completions", openai_chat::build_request_for(pi_request, openai_chat::Dialect::OpenRouter)?, )), + WirelessProvider::DeepSeek => Ok(( + "https://api.deepseek.com/chat/completions", + openai_chat::build_request_for(pi_request, openai_chat::Dialect::DeepSeek)?, + )), WirelessProvider::Anthropic => Ok(( "https://api.anthropic.com/v1/messages", anthropic_messages::build_request(pi_request)?, @@ -46,12 +47,9 @@ impl ModelBackend for WirelessBackend { fn complete( &self, request_json: &str, - _on_delta: &mut dyn FnMut(&str), + on_event: &mut dyn FnMut(ModelStreamEvent), ) -> Result { let (endpoint, body) = self.request(request_json)?; - if body.len() > MAX_REQUEST_BYTES { - return Err("model request exceeded 128 KiB".into()); - } let content_length = body.len().to_string(); let bearer = format!("Bearer {}", self.api_key); let mut headers = vec![ @@ -65,7 +63,9 @@ impl ModelBackend for WirelessBackend { headers.push(("x-api-key", self.api_key.as_str())); headers.push(("anthropic-version", "2023-06-01")); } - WirelessProvider::OpenAi | WirelessProvider::OpenRouter => { + WirelessProvider::OpenAi + | WirelessProvider::OpenRouter + | WirelessProvider::DeepSeek => { headers.push(("authorization", bearer.as_str())); } } @@ -96,11 +96,13 @@ impl ModelBackend for WirelessBackend { let status = response.status(); let mut decoder = match self.provider { WirelessProvider::Anthropic => ProviderStream::Anthropic(Default::default()), + WirelessProvider::DeepSeek => { + ProviderStream::Chat(openai_chat::Stream::new(openai_chat::Dialect::DeepSeek)) + } WirelessProvider::OpenAi | WirelessProvider::OpenRouter => { ProviderStream::Chat(Default::default()) } }; - let mut received = 0usize; let mut pending = Vec::with_capacity(4 * 1024); let mut chunk = [0u8; 2 * 1024]; loop { @@ -110,13 +112,9 @@ impl ModelBackend for WirelessBackend { if count == 0 { break; } - received = received.saturating_add(count); - if received > MAX_RESPONSE_BYTES { - return Err("model response exceeded 128 KiB".into()); - } pending.extend_from_slice(&chunk[..count]); if (200..300).contains(&status) { - drain_sse_lines(&mut pending, &mut decoder)?; + drain_sse_lines(&mut pending, &mut decoder, on_event)?; } } if !(200..300).contains(&status) { @@ -131,7 +129,7 @@ impl ModelBackend for WirelessBackend { } if !pending.is_empty() { pending.push(b'\n'); - drain_sse_lines(&mut pending, &mut decoder)?; + drain_sse_lines(&mut pending, &mut decoder, on_event)?; } decoder.finish() } @@ -140,6 +138,7 @@ impl ModelBackend for WirelessBackend { fn drain_sse_lines( pending: &mut Vec, decoder: &mut ProviderStream, + on_event: &mut dyn FnMut(ModelStreamEvent), ) -> Result<(), String> { while let Some(end) = pending.iter().position(|byte| *byte == b'\n') { let mut line = pending.drain(..=end).collect::>(); @@ -153,7 +152,9 @@ fn drain_sse_lines( }; let data = data.trim_start(); if !data.is_empty() && data != "[DONE]" { - let _ = decoder.push(data)?; + for event in decoder.push(data)? { + on_event(event); + } } } Ok(()) @@ -165,7 +166,7 @@ enum ProviderStream { } impl ProviderStream { - fn push(&mut self, data: &str) -> Result, String> { + fn push(&mut self, data: &str) -> Result, String> { match self { Self::Chat(stream) => stream.push(data), Self::Anthropic(stream) => stream.push(data), diff --git a/firmware/esp32-p4/src/transport/provisioning.rs b/firmware/esp32-p4/src/transport/provisioning.rs index 8823886..3aabd5d 100644 --- a/firmware/esp32-p4/src/transport/provisioning.rs +++ b/firmware/esp32-p4/src/transport/provisioning.rs @@ -1,7 +1,7 @@ use std::time::Duration; use pocket_pi_protocols::model::{ - ModelBackendSettings, ModelSettings, UartProvider, WirelessProvider, + ModelBackendSettings, ModelSettings, ThinkingLevel, UartProvider, WirelessProvider, }; use super::LineTransport; @@ -44,7 +44,7 @@ pub fn request_runtime_config( ("uart", "claude-code") => ModelBackendSettings::Uart { provider: UartProvider::ClaudeCode, }, - ("wireless", "openai" | "openrouter" | "anthropic") => { + ("wireless", "openai" | "openrouter" | "anthropic" | "deepseek") => { if model_api_key.is_none() { return Err(format!("{provider} requires modelApiKey")); } @@ -53,19 +53,25 @@ pub fn request_runtime_config( "openai" => WirelessProvider::OpenAi, "openrouter" => WirelessProvider::OpenRouter, "anthropic" => WirelessProvider::Anthropic, + "deepseek" => WirelessProvider::DeepSeek, _ => unreachable!(), }, } } ("uart", _) => return Err("UART provider must be codex or claude-code".into()), ("wireless", _) => { - return Err("wireless provider must be openai, openrouter or anthropic".into()) + return Err("wireless provider must be openai, openrouter, anthropic or deepseek".into()) } _ => return Err("model backend must be uart or wireless".into()), }; let model = ModelSettings { backend: model_backend, model: text(&value, "model", 128)?, + thinking_level: match text(&value, "thinkingLevel", 8)?.as_deref() { + None | Some("high") => ThinkingLevel::High, + Some("xhigh") => ThinkingLevel::Xhigh, + Some(_) => return Err("thinkingLevel must be high or xhigh".into()), + }, }; model.resolved_model()?; Ok(RuntimeConfig { diff --git a/hosts/esp32-p4-sim/src/backend.rs b/hosts/esp32-p4-sim/src/backend.rs index d95f4a3..76ab3cb 100644 --- a/hosts/esp32-p4-sim/src/backend.rs +++ b/hosts/esp32-p4-sim/src/backend.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use std::time::Duration; use pocket_pi_embedded::ModelBackend; -use pocket_pi_protocols::model::WirelessProvider; +use pocket_pi_protocols::model::{ModelStreamEvent, WirelessProvider}; use pocket_pi_protocols::{anthropic_messages, codex_decision, openai_chat}; use serde_json::{json, Value}; @@ -13,6 +13,7 @@ pub enum BackendChoice { provider: WirelessProvider, api_key: String, model: String, + thinking_level: String, }, Codex { model: Option, @@ -22,11 +23,12 @@ pub enum BackendChoice { impl BackendChoice { pub fn from_name(name: &str, model: Option) -> Result { match name { - "openai" | "openrouter" | "anthropic" => { + "openai" | "openrouter" | "anthropic" | "deepseek" => { let provider = match name { "openai" => WirelessProvider::OpenAi, "openrouter" => WirelessProvider::OpenRouter, "anthropic" => WirelessProvider::Anthropic, + "deepseek" => WirelessProvider::DeepSeek, _ => unreachable!(), }; let prefix = name.to_ascii_uppercase(); @@ -36,31 +38,41 @@ impl BackendChoice { .or_else(|| std::env::var(format!("{prefix}_MODEL")).ok()) .or_else(|| provider.default_model().map(str::to_owned)) .ok_or_else(|| format!("--backend {name} requires --model"))?; + let thinking_level = std::env::var(format!("{prefix}_THINKING_LEVEL")) + .unwrap_or_else(|_| "high".into()); + if !matches!(thinking_level.as_str(), "high" | "xhigh") { + return Err(format!("{prefix}_THINKING_LEVEL must be high or xhigh")); + } Ok(Self::Wireless { provider, api_key, model, + thinking_level, }) } "codex" => Ok(Self::Codex { model: model.or_else(|| std::env::var("CODEX_MODEL").ok()), }), other => Err(format!( - "unknown backend {other:?}; expected openai, openrouter, anthropic or codex" + "unknown backend {other:?}; expected openai, openrouter, anthropic, deepseek or codex" )), } } pub fn agent_config(&self) -> String { - let (provider, model) = match self { + let (provider, model, thinking_level) = match self { Self::Wireless { - provider, model, .. - } => (provider.id(), model.as_str()), - Self::Codex { model } => ("codex", model.as_deref().unwrap_or("coding-plan")), + provider, + model, + thinking_level, + .. + } => (provider.id(), model.as_str(), thinking_level.as_str()), + Self::Codex { model } => ("codex", model.as_deref().unwrap_or("coding-plan"), "high"), }; json!({ "provider": provider, "model": model, + "thinkingLevel": thinking_level, "systemPrompt": "You are Pocket Pi in the ESP32 simulator. Be concise." }) .to_string() @@ -85,7 +97,7 @@ impl ModelBackend for WirelessBackend { fn complete( &self, request_json: &str, - on_delta: &mut dyn FnMut(&str), + on_event: &mut dyn FnMut(ModelStreamEvent), ) -> Result { let (endpoint, body) = match self.provider { WirelessProvider::OpenAi => ( @@ -100,6 +112,10 @@ impl ModelBackend for WirelessBackend { "https://api.anthropic.com/v1/messages", anthropic_messages::build_request(request_json)?, ), + WirelessProvider::DeepSeek => ( + "https://api.deepseek.com/chat/completions", + openai_chat::build_request_for(request_json, openai_chat::Dialect::DeepSeek)?, + ), }; let agent = ureq::AgentBuilder::new() .timeout_connect(Duration::from_secs(20)) @@ -113,7 +129,9 @@ impl ModelBackend for WirelessBackend { WirelessProvider::Anthropic => request .set("x-api-key", &self.api_key) .set("anthropic-version", "2023-06-01"), - WirelessProvider::OpenAi | WirelessProvider::OpenRouter => { + WirelessProvider::OpenAi + | WirelessProvider::OpenRouter + | WirelessProvider::DeepSeek => { request.set("authorization", &format!("Bearer {}", self.api_key)) } }; @@ -132,6 +150,9 @@ impl ModelBackend for WirelessBackend { let mut stream = match self.provider { WirelessProvider::Anthropic => SimProviderStream::Anthropic(Default::default()), + WirelessProvider::DeepSeek => { + SimProviderStream::Chat(openai_chat::Stream::new(openai_chat::Dialect::DeepSeek)) + } WirelessProvider::OpenAi | WirelessProvider::OpenRouter => { SimProviderStream::Chat(Default::default()) } @@ -145,8 +166,8 @@ impl ModelBackend for WirelessBackend { if data == "[DONE]" { break; } - if let Some(delta) = stream.push(data)? { - on_delta(&delta); + for event in stream.push(data)? { + on_event(event); } } stream.finish() @@ -159,7 +180,7 @@ enum SimProviderStream { } impl SimProviderStream { - fn push(&mut self, data: &str) -> Result, String> { + fn push(&mut self, data: &str) -> Result, String> { match self { Self::Chat(stream) => stream.push(data), Self::Anthropic(stream) => stream.push(data), @@ -182,7 +203,7 @@ impl ModelBackend for CodexBackend { fn complete( &self, request_json: &str, - on_delta: &mut dyn FnMut(&str), + on_event: &mut dyn FnMut(ModelStreamEvent), ) -> Result { let workspace = tempfile::tempdir().map_err(|error| error.to_string())?; let mut command = Command::new("codex"); @@ -243,7 +264,7 @@ impl ModelBackend for CodexBackend { .ok() .and_then(|value| value.get("text").and_then(Value::as_str).map(str::to_owned)) { - on_delta(&text); + on_event(ModelStreamEvent::Text(text)); } Ok(result) } diff --git a/tools/uart-model-bridge.py b/tools/uart-model-bridge.py index dcd51a4..28eb31b 100755 --- a/tools/uart-model-bridge.py +++ b/tools/uart-model-bridge.py @@ -26,8 +26,8 @@ ROBINHOOD_KEYCHAIN_ACCOUNT = "robinhood-trading|5cbe81c78ff5ae58" EXA_KEYCHAIN_SERVICE = "Pocket Pi Credentials" EXA_KEYCHAIN_ACCOUNT = "exa-api-key" -WIFI_KEYCHAIN_SERVICE = "Pocket Pi Wi-Fi" -WIFI_KEYCHAIN_ACCOUNT = "TUF WIFI6" +DEEPSEEK_KEYCHAIN_SERVICE = "Pocket Pi Credentials" +DEEPSEEK_KEYCHAIN_ACCOUNT = "deepseek-api-key" def keychain_secret(service: str, account: str) -> str | None: @@ -79,10 +79,9 @@ def exa_api_key() -> str | None: return keychain_secret(EXA_KEYCHAIN_SERVICE, EXA_KEYCHAIN_ACCOUNT) -def saved_wifi() -> tuple[str, str] | None: - """Load the development board Wi-Fi without exposing it to source or logs.""" - password = keychain_secret(WIFI_KEYCHAIN_SERVICE, WIFI_KEYCHAIN_ACCOUNT) - return (WIFI_KEYCHAIN_ACCOUNT, password) if password else None +def deepseek_api_key() -> str | None: + """Load the user-provided DeepSeek key from macOS Keychain.""" + return keychain_secret(DEEPSEEK_KEYCHAIN_SERVICE, DEEPSEEK_KEYCHAIN_ACCOUNT) def write_line(fd: int, line: str) -> None: @@ -128,24 +127,25 @@ def config(args: argparse.Namespace) -> dict[str, object]: } if args.model: value["model"] = args.model - wifi = None if args.provision_wifi else saved_wifi() - if wifi: - value["wifiSsid"], value["wifiPassword"] = wifi - print(f"Wi-Fi: provisioning {wifi[0]} from Keychain", flush=True) + value["thinkingLevel"] = args.thinking_level if args.provision_wifi: value["wifiSsid"] = input("Wi-Fi SSID: ").strip() value["wifiPassword"] = getpass.getpass("Wi-Fi password: ") if args.backend == "wireless": - value["modelApiKey"] = getpass.getpass(f"{provider} API key: ") - if args.provision_exa: - key = exa_api_key() + key = deepseek_api_key() if provider == "deepseek" else None if key: - value["exaApiKey"] = key - print("Exa: reusing Keychain API key (RAM only on device)", flush=True) + value["modelApiKey"] = key + print("DeepSeek: reusing Keychain API key (RAM only on device)", flush=True) else: - key = getpass.getpass("Exa API key: ") - if key: - value["exaApiKey"] = key + value["modelApiKey"] = getpass.getpass(f"{provider} API key: ") + key = exa_api_key() + if key: + value["exaApiKey"] = key + print("Exa: reusing Keychain API key (RAM only on device)", flush=True) + elif args.provision_exa: + key = getpass.getpass("Exa API key: ") + if key: + value["exaApiKey"] = key token = robinhood_access_token() if token: value["robinhoodAccessToken"] = token @@ -170,9 +170,10 @@ def main() -> int: parser.add_argument("--backend", choices=("uart", "wireless"), default="uart") parser.add_argument( "--provider", - choices=("codex", "claude-code", "openai", "openrouter", "anthropic"), + choices=("codex", "claude-code", "openai", "openrouter", "anthropic", "deepseek"), ) parser.add_argument("--model") + parser.add_argument("--thinking-level", choices=("high", "xhigh"), default="high") parser.add_argument("--prompt", help="submit one prompt after the board agent is ready") parser.add_argument( "--prompt-delay-seconds", @@ -189,8 +190,8 @@ def main() -> int: provider = args.provider or ("codex" if args.backend == "uart" else "openai") if args.backend == "uart" and provider not in ("codex", "claude-code"): parser.error("UART provider must be codex or claude-code") - if args.backend == "wireless" and provider not in ("openai", "openrouter", "anthropic"): - parser.error("wireless provider must be openai, openrouter or anthropic") + if args.backend == "wireless" and provider not in ("openai", "openrouter", "anthropic", "deepseek"): + parser.error("wireless provider must be openai, openrouter, anthropic or deepseek") runtime_config = config(args) model_backend = create_backend(provider) if args.backend == "uart" else None @@ -250,13 +251,14 @@ def emit_delta(delta: str) -> None: request_payload, emit_delta, ) - call = result.get("toolCall") - if isinstance(call, dict): - print( - f"[bridge] ESP tool {call.get('name')}: " - + json.dumps(call.get("arguments", {}), ensure_ascii=False), - flush=True, - ) + calls = result.get("toolCalls") + if isinstance(calls, list) and calls: + for call in calls: + print( + f"[bridge] ESP tool {call.get('name')}: " + + json.dumps(call.get("arguments", {}), ensure_ascii=False), + flush=True, + ) elif isinstance(result.get("text"), str): print(f"[bridge] Pi reply: {result['text']}", flush=True) print( diff --git a/tools/uart_bridge/backends.py b/tools/uart_bridge/backends.py index 9bb4b95..8779c9d 100644 --- a/tools/uart_bridge/backends.py +++ b/tools/uart_bridge/backends.py @@ -25,7 +25,7 @@ def decision_prompt(request: dict[str, object]) -> tuple[str, list[object]]: "You are the model decision backend for a Pi Agent running on an ESP32-P4.", "Do not call Mac tools. The registered tools below run only on the ESP32.", "Return exactly one compact JSON object and no Markdown: " - '{"toolCall":{"name":"registered.name","arguments":{...}}} for one action, or ' + '{"toolCalls":[{"name":"registered.name","arguments":{...}}]} for actions, or ' '{"text":"final response"} when the turn is complete. Never claim success before ' "the corresponding tool result appears in the conversation.", f"System instruction: {system}" if system else "", @@ -49,29 +49,45 @@ def parse_decision(raw: str, tools: list[object], provider: str) -> dict[str, ob raise ValueError(f"{provider} returned invalid decision JSON: {error}") from error if not isinstance(value, dict): raise ValueError(f"{provider} decision must be a JSON object") - call = value.get("toolCall") - if isinstance(call, dict): + calls = value.get("toolCalls") + if isinstance(calls, list) and calls: registered = { tool.get("name") for tool in tools if isinstance(tool, dict) and isinstance(tool.get("name"), str) } - name = call.get("name") - arguments = call.get("arguments", {}) - if name not in registered: - raise ValueError(f"{provider} requested unregistered ESP32 tool: {name}") - if not isinstance(arguments, dict): - raise ValueError("toolCall.arguments must be a JSON object") - return { - "toolCall": { - "id": f"esp_{int(time.time() * 1000)}", + result_calls: list[dict[str, object]] = [] + base_id = int(time.time() * 1000) + for index, call in enumerate(calls): + if not isinstance(call, dict): + raise ValueError(f"{provider} toolCalls entries must be objects") + name = call.get("name") + arguments = call.get("arguments", {}) + if name not in registered: + raise ValueError(f"{provider} requested unregistered ESP32 tool: {name}") + if not isinstance(arguments, dict): + raise ValueError("toolCalls arguments must be JSON objects") + result_calls.append({ + "id": f"esp_{base_id}_{index}", "name": name, "arguments": arguments, - } + }) + return { + "thinking": "", + "text": "", + "toolCalls": result_calls, + "usage": {}, + "stopReason": "toolUse", } if isinstance(value.get("text"), str): - return {"text": value["text"]} - raise ValueError(f"{provider} decision needs text or toolCall") + return { + "thinking": "", + "text": value["text"], + "toolCalls": [], + "usage": {}, + "stopReason": "stop", + } + raise ValueError(f"{provider} decision needs text or non-empty toolCalls") def _partial_text(raw: str) -> str | None: From c6a1191d0819627d2efc634347fe86abe40221bc Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Mon, 10 Aug 2026 16:11:27 +0800 Subject: [PATCH 08/24] feat(ui): expand Pi Design and improve ESP readability --- apps/_shared/ui.tsx | 109 +++++++++++++++++++++++++++----- apps/exa/app.tsx | 47 +++++++------- apps/exa/dist/app.js | 10 +-- apps/exa/dist/app.pak | Bin 317776 -> 280336 bytes apps/pi-agent/app.tsx | 101 ++++++++++++++--------------- apps/pi-agent/dist/app.js | 20 +++--- apps/pi-agent/dist/app.pak | Bin 431632 -> 374864 bytes apps/robinhood/app.tsx | 56 ++++++++-------- apps/robinhood/dist/app.js | 8 +-- apps/robinhood/dist/app.pak | Bin 294656 -> 281920 bytes docs/pocket-pi-design-system.md | 102 ++++++++++++++++-------------- 11 files changed, 259 insertions(+), 194 deletions(-) diff --git a/apps/_shared/ui.tsx b/apps/_shared/ui.tsx index 65c8d51..9867aab 100644 --- a/apps/_shared/ui.tsx +++ b/apps/_shared/ui.tsx @@ -1,14 +1,17 @@ import { Text, View } from "@pocketjs/framework/components"; -// Pocket Pi Design System v0.1. Keep this layer deliberately small: shared -// typography, spacing and foundational surfaces only. Product-specific -// components such as charts, account pickers and file rows stay in each App. +// Pi Design v0.2. These are product-wide visual contracts built only from +// PocketJS public primitives. App data, navigation and side effects stay with +// the consuming App. export const type = { - title: "text-2xl text-white font-bold", - section: "text-sm text-slate-600 font-bold", - body: "text-base text-slate-900", - bodyStrong: "text-base text-slate-900 font-bold", - caption: "text-sm text-slate-500", + appTitle: "text-2xl text-white font-bold", + pageTitle: "text-2xl text-slate-950 font-bold", + heading: "text-xl text-slate-900 font-bold", + label: "text-base text-slate-600 font-bold", + body: "text-lg text-slate-900", + bodyStrong: "text-lg text-slate-900 font-bold", + caption: "text-base text-slate-500", + captionStrong: "text-base text-slate-500 font-bold", } as const; export const space = { @@ -17,6 +20,26 @@ export const space = { stack: "gap-4", } as const; +// Generic containers with arbitrary children remain recipes instead of +// wrappers: this keeps the Solid/PocketJS native tree literal and predictable. +export const surface = { + card: "rounded-xl shadow bg-white border-slate-100", + selectedCard: "rounded-xl shadow bg-emerald-100 border-emerald-500", + row: "bg-white", + muted: "bg-slate-100", + shell: "bg-slate-950", +} as const; + +export type Tone = "neutral" | "info" | "success" | "warning" | "danger"; + +export const statusBadge = { + neutral: { surface: "px-3 py-2 rounded-lg bg-slate-100", text: "text-base text-slate-600 font-bold" }, + info: { surface: "px-3 py-2 rounded-lg bg-indigo-100", text: "text-base text-indigo-700 font-bold" }, + success: { surface: "px-3 py-2 rounded-lg bg-emerald-100", text: "text-base text-emerald-700 font-bold" }, + warning: { surface: "px-3 py-2 rounded-lg bg-amber-100", text: "text-base text-amber-700 font-bold" }, + danger: { surface: "px-3 py-2 rounded-lg bg-red-100", text: "text-base text-red-500 font-bold" }, +} as const; + type HeaderProps = { title: string; back?: boolean; @@ -36,32 +59,84 @@ export function PocketHeader(props: HeaderProps) { {props.back ? : } - {props.title} + {props.title} - {props.metaTop ?? ""} - {props.metaBottom ?? ""} + {props.metaTop ?? ""} + {props.metaBottom ?? ""} ); } +export function PageIntro(props: { eyebrow: string; title: string; description: string; tone?: "brand" | "info" }) { + return ( + + {props.eyebrow} + {props.title} + {props.description} + + ); +} + export function SectionHeading(props: { title: string; detail?: string; action?: boolean }) { const trailing = () => props.action ? (props.detail ? props.detail + " · VIEW ALL ›" : "VIEW ALL ›") : props.detail ?? ""; return ( - - {props.title} - {trailing()} + + {props.title} + {trailing()} ); } -export function ActionButton(props: { label: string; disabled?: boolean }) { +export function ActionButton(props: { label: string; disabled?: boolean; tone?: "primary" | "danger" | "neutral" }) { + const container = () => props.disabled ? "w-full h-full items-center justify-center rounded-xl bg-slate-200" + : props.tone === "danger" ? "w-full h-full items-center justify-center rounded-xl bg-red-100" + : props.tone === "neutral" ? "w-full h-full items-center justify-center rounded-xl bg-slate-100" + : "w-full h-full items-center justify-center rounded-xl bg-orange-600"; + const label = () => props.disabled ? "text-lg text-slate-500 font-bold" + : props.tone === "danger" ? "text-lg text-red-500 font-bold" + : props.tone === "neutral" ? "text-lg text-slate-900 font-bold" + : "text-lg text-white font-bold"; + return {props.label}; +} + +export function EmptyState(props: { icon?: string; title: string; detail?: string; tone?: "info" | "neutral"; compact?: boolean }) { return ( - - {props.label} + + {props.icon ? {props.icon} : null} + {props.title} + {props.detail ? {props.detail} : null} ); } + +export function MetricCard(props: { label: string; value: string; tone?: "neutral" | "success" | "danger" }) { + const valueClass = () => props.tone === "success" ? "text-xl text-emerald-600 font-bold" + : props.tone === "danger" ? "text-xl text-red-500 font-bold" + : "text-xl text-slate-900 font-bold"; + return ( + + {props.label} + {props.value} + + ); +} + +export function StatusBar(props: { text: string; tone?: "neutral" | "danger"; dark?: boolean }) { + const textClass = () => props.dark + ? (props.tone === "danger" ? "text-base text-red-300" : "text-base text-slate-300") + : (props.tone === "danger" ? "text-base text-red-500" : "text-base text-slate-500"); + return {props.text}; +} + +export function ScrollButtons(props: { top: string; bottom: string }) { + return ( + <> + UP + DN + + ); +} diff --git a/apps/exa/app.tsx b/apps/exa/app.tsx index a6cb475..b40ee70 100644 --- a/apps/exa/app.tsx +++ b/apps/exa/app.tsx @@ -2,6 +2,7 @@ import { createSignal, For, Show } from "solid-js"; import { Text, View } from "@pocketjs/framework/components"; import { mount } from "@pocketjs/framework"; import { Database } from "@pocketjs/framework/db"; +import { EmptyState, PageIntro, PocketHeader, statusBadge, StatusBar } from "../_shared/ui"; const DB_SCHEMA_VERSION = 4; const RETENTION_DAYS = 7; @@ -87,40 +88,36 @@ function storageStatus(): { text: string; details: any } { function Exa() { return ( - - - - POCKET APPExa Research - - SQLITE HISTORY - - - AGENT RESEARCH MEMORY - Search history - Every research.search call is saved here automatically. - + + - - E - No searches yet - {"Ask Pi Agent to research a topic.\nThe search and its results will appear here."} - + {(item) => ( - - - {item.query.slice(0, 72)} - {(item.top_title || item.error || "No result title").slice(0, 92)} - {searchTime(item.searched_at)} + + + {item.query.slice(0, 60)} + {(item.top_title || item.error || "No result title").slice(0, 76)} + {searchTime(item.searched_at)} - - {item.status === "ok" ? item.result_count + " RESULTS" : "FAILED"} + + {item.status === "ok" ? item.result_count + " RESULTS" : "FAILED"} )} - {status()} + ); } diff --git a/apps/exa/dist/app.js b/apps/exa/dist/app.js index 170c1d0..b1ad9ca 100644 --- a/apps/exa/dist/app.js +++ b/apps/exa/dist/app.js @@ -1,12 +1,12 @@ -(()=>{var KJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return v0(this.context.count)},getNextContextId(){return v0(this.context.count++)}};function v0(J){let Q=String(J),$=Q.length-1;return KJ.context.id+($?String.fromCharCode(96+$):"")+Q}function u0(J){KJ.context=J}function P4(){return{...KJ.context,id:KJ.getNextContextId(),count:0}}var R4=!1,w4=(J,Q)=>J===Q,W0=Symbol("solid-proxy"),D4=typeof Proxy==="function",O4=Symbol("solid-track"),H2=Symbol("solid-dev-component"),gJ={equals:w4},l0=null,L4=r0,E=1,CJ=2,p0={owned:null,cleanups:null,context:null,owner:null},I=null,B=null,IJ=null,MJ=null,k=null,S=null,f=null,TJ=0;function EJ(J,Q){let $=k,Z=I,X=J.length===0,W=Q===void 0?Z:Q,q=X?p0:{owned:null,cleanups:null,context:W?W.context:null,owner:W},G=X?J:()=>J(()=>r(()=>o(q)));I=q,k=null;try{return i(G,!0)}finally{k=$,I=Z}}function kJ(J,Q){Q=Q?Object.assign({},gJ,Q):gJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return d0($,X)};return[i0.bind($),Z]}function a(J,Q,$){let Z=a0(J,Q,!1,E);if(IJ&&B&&B.running)S.push(Z);else NJ(Z)}function UJ(J,Q,$){$=$?Object.assign({},gJ,$):gJ;let Z=a0(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,IJ&&B&&B.running)Z.tState=E,S.push(Z);else NJ(Z);return i0.bind(Z)}function r(J){if(!MJ&&k===null)return J();let Q=k;k=null;try{if(MJ)return MJ.untrack(J);return J()}finally{k=Q}}function Y0(J){if(I===null);else if(I.cleanups===null)I.cleanups=[J];else I.cleanups.push(J);return J}function C4(J){if(B&&B.running)return J(),B.done;let Q=k,$=I;return Promise.resolve().then(()=>{k=Q,I=$;let Z;if(IJ||I4)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return i(J,!1),k=I=null,Z?Z.done:void 0})}var[j2,c0]=kJ(!1),I4;function i0(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===E)NJ(this);else{let Q=S;S=null,i(()=>mJ(this),!1),S=Q}if(k){let Q=this.observers;if(!Q||Q[Q.length-1]!==k){let $=Q?Q.length:0;if(!k.sources)k.sources=[this],k.sourceSlots=[$];else k.sources.push(this),k.sourceSlots.push($);if(!Q)this.observers=[k],this.observerSlots=[k.sources.length-1];else Q.push(k),this.observerSlots.push(k.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function d0(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)i(()=>{for(let X=0;X1e6)throw S=[],Error()},!1)}return Q}function NJ(J){if(!J.fn)return;o(J);let Q=TJ;if(s0(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{i(()=>{B&&(B.running=!0),k=I=J,s0(J,J.tValue,Q),k=I=null},!1)})}function s0(J,Q,$){let Z,X=I,W=k;k=I=J;try{Z=J.fn(Q)}catch(q){if(J.pure)if(B&&B.running)J.tState=E,J.tOwned&&J.tOwned.forEach(o),J.tOwned=void 0;else J.state=E,J.owned&&J.owned.forEach(o),J.owned=null;return J.updatedAt=$+1,z0(q)}finally{k=W,I=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)d0(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function a0(J,Q,$,Z=E,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:I,context:I?I.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(I===null);else if(I!==p0)if(B&&B.running&&I.pure)if(!I.tOwned)I.tOwned=[W];else I.tOwned.push(W);else if(!I.owned)I.owned=[W];else I.owned.push(W);if(MJ&&W.fn){let q=W.fn,[G,M]=kJ(void 0,{equals:!1}),U=MJ.factory(q,M);Y0(()=>U.dispose());let V,H=()=>C4(M).then(()=>{if(V)V.dispose(),V=void 0});W.fn=(L)=>{if(G(),B&&B.running){if(!V)V=MJ.factory(q,H);return V.track(L)}return U.track(L)}}return W}function q0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===CJ)return mJ(J);if(J.suspense&&r(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===E)NJ(J);else if((Q?J.tState:J.state)===CJ){let X=S;S=null,i(()=>mJ(J,$[0]),!1),S=X}}}function i(J,Q){if(S)return J();let $=!1;if(!Q)S=[];if(f)$=!0;else f=[];TJ++;try{let Z=J();return k4($),Z}catch(Z){if(!$)f=null;S=null,z0(Z)}}function k4(J){if(S){if(IJ&&B&&B.running)A4(S);else r0(S);S=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;f.push.apply(f,B.effects),Q=B.resolve;for(let W of f)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,i(()=>{for(let W of X)o(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let q=0,G=W.owned.length;qL4($),!1);if(Q)Q()}function r0(J){for(let Q=0;Q{Z.delete($),i(()=>{B.running=!0,q0($)},!1),B&&(B.running=!1)})}}function mJ(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)o(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)n0(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)o(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function n0(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return Y0(()=>e0(W)),()=>{let M=J()||[],U=M.length,V,H;return M[O4],r(()=>{let y,h,p,ZJ,jJ,F,j,z,P;if(U===0){if(q!==0)e0(W),W=[],Z=[],X=[],q=0,G&&(G=[]);if($.fallback)Z=[y4],X[0]=EJ((D)=>{return W[0]=D,$.fallback()}),q=1}else if(q===0){X=Array(U);for(H=0;H=F&&z>=F&&Z[j]===M[z];j--,z--)p[z]=X[j],ZJ[z]=W[j],G&&(jJ[z]=G[j]);y=new Map,h=Array(z+1);for(H=z;H>=F;H--)P=M[H],V=y.get(P),h[H]=V===void 0?-1:V,y.set(P,H);for(V=F;V<=j;V++)if(P=Z[V],H=y.get(P),H!==void 0&&H!==-1)p[H]=X[V],ZJ[H]=W[V],G&&(jJ[H]=G[V]),H=h[H],y.set(P,H);else W[V]();for(H=F;HJ(Q||{}));return u0($),Z}}return r(()=>J(Q||{}))}function vJ(){return!0}var f4={get(J,Q,$){if(Q===W0)return $;return J.get(Q)},has(J,Q){if(Q===W0)return!0;return J.has(Q)},set:vJ,deleteProperty:vJ,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:vJ,deleteProperty:vJ}},ownKeys(J){return J.keys()}};function G0(J){return!(J=typeof J==="function"?J():J)?{}:J}function b4(){for(let J=0,Q=this.length;J=0;G--){let M=G0(J[G])[q];if(M!==void 0)return M}},has(q){for(let G=J.length-1;G>=0;G--)if(q in G0(J[G]))return!0;return!1},keys(){let q=[];for(let G=0;G=0;q--){let G=J[q];if(!G)continue;let M=Object.getOwnPropertyNames(G);for(let U=M.length-1;U>=0;U--){let V=M[U];if(V==="__proto__"||V==="constructor")continue;let H=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=H.get?{enumerable:!0,configurable:!0,get:b4.bind($[V]=[H.get.bind(G)])}:H.value!==void 0?H:void 0;else{let L=$[V];if(L){if(H.get)L.push(H.get.bind(G));else if(H.value!==void 0)L.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let q=W.length-1;q>=0;q--){let G=W[q],M=Z[G];if(M&&M.get)Object.defineProperty(X,G,M);else X[G]=M?M.value:void 0}return X}var g4=(J)=>`Stale read from <${J}>.`;function T4(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return UJ(_4(()=>J.each,J.children,Q||void 0))}function E4(J){let Q=J.keyed,$=UJ(()=>J.when,void 0,void 0),Z=Q?$:UJ($,void 0,{equals:(X,W)=>!X===!W});return UJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?r(()=>W(Q?X:()=>{if(!r(Z))throw g4("Show");return $()})):W}return J.fallback},void 0,void 0)}var N4=(J)=>UJ(()=>J());function m4({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:q,getParentNode:G,getFirstChild:M,getNextSibling:U}){function V(F,j,z,P){if(z!==void 0&&!P)P=[];if(typeof j!=="function")return H(F,j,P,z);a((D)=>H(F,j(),D,z),P)}function H(F,j,z,P,D){while(typeof z==="function")z=z();if(j===z)return z;let C=typeof j,w=P!==void 0;if(C==="string"||C==="number"){if(C==="number")j=j.toString();if(w){let R=z[0];if(R&&$(R))Z(R,j);else R=Q(j);z=h(F,z,P,R)}else if(z!==""&&typeof z==="string")Z(M(F),z=j);else h(F,z,P,Q(j)),z=j}else if(j==null||C==="boolean")z=h(F,z,P);else if(C==="function")return a(()=>{let R=j();while(typeof R==="function")R=R();z=H(F,R,z,P)}),()=>z;else if(Array.isArray(j)){let R=[];if(L(R,j,D))return a(()=>z=H(F,R,z,P,!0)),()=>z;if(R.length===0){let LJ=h(F,z,P);if(w)return z=LJ}else if(Array.isArray(z))if(z.length===0)p(F,R,P);else y(F,z,R);else if(z==null||z==="")p(F,R);else y(F,w&&z||[M(F)],R);z=R}else{if(Array.isArray(z)){if(w)return z=h(F,z,P,j);h(F,z,null,j)}else if(z==null||z===""||!M(F))X(F,j);else ZJ(F,j,M(F));z=j}return z}function L(F,j,z){let P=!1;for(let D=0,C=j.length;Dc-R){let G2=j[w];while(R=0;w--){let R=j[w];if(D!==R){let LJ=G(R)===F;if(!C&&!w)LJ?ZJ(F,D,R):X(F,D,z);else LJ&&W(F,R)}else C=!0}}else X(F,D,z);return[D]}function p(F,j,z){for(let P=0,D=j.length;Pz.children=H(F,j.children,z.children));return a(()=>j.ref&&j.ref(F)),a(()=>{for(let D in j){if(D==="children"||D==="ref")continue;let C=j[D];if(C===z[D])continue;q(F,D,C,z[D]),z[D]=C}}),z}return{render(F,j){let z;return EJ((P)=>{z=P,V(j,F())}),z},insert:V,spread(F,j,z){if(typeof j==="function")a((P)=>jJ(F,j(),P,z));else jJ(F,j,void 0,z)},createElement:J,createTextNode:Q,insertNode:X,setProp(F,j,z,P){return q(F,j,z,P),z},mergeProps:J1,effect:a,memo:N4,createComponent:x4,use(F,j,z){return r(()=>F(j,z))}}}function v4(J){let Q=m4(J);return Q.mergeProps=J1,Q}var Q1=480,$1=272,XJ={view:0,text:1,image:2},u4=1,l4=-1,p4={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},K={f32:0,color:1,int:2},c4={width:K.f32,height:K.f32,minW:K.f32,minH:K.f32,maxW:K.f32,maxH:K.f32,paddingT:K.f32,paddingR:K.f32,paddingB:K.f32,paddingL:K.f32,marginT:K.f32,marginR:K.f32,marginB:K.f32,marginL:K.f32,gap:K.f32,flexDir:K.int,justify:K.int,align:K.int,grow:K.f32,shrink:K.f32,basis:K.f32,flexWrap:K.int,posType:K.int,insetT:K.f32,insetR:K.f32,insetB:K.f32,insetL:K.f32,display:K.int,overflow:K.int,zIndex:K.int,hitPass:K.int,bgColor:K.color,gradFrom:K.color,gradTo:K.color,gradDir:K.int,radius:K.f32,opacity:K.f32,borderColor:K.color,borderWidth:K.f32,shadow:K.int,bevelOuterLight:K.color,bevelOuterDark:K.color,bevelInnerLight:K.color,bevelInnerDark:K.color,bevelWidth:K.f32,textColor:K.color,fontSlot:K.int,textAlign:K.int,lineHeight:K.f32,tracking:K.f32,translateX:K.f32,translateY:K.f32,scale:K.f32,rotate:K.f32,scaleX:K.f32,scaleY:K.f32,originX:K.f32,originY:K.f32,rotateX:K.f32,rotateY:K.f32,translateZ:K.f32,perspective:K.f32,arcStart:K.f32,arcSweep:K.f32,arcWidth:K.f32},N={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},i4={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},d4=1,B2=2,F2=1,K2=2,M2=131072,U2=1,V2=262144,P2=1,R2=1,w2=1,D2=2,O2=4,L2=8,C2=16,I2=1,k2=2;function Z1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var A2=1,s4=1263551300,a4=1,r4=32,o4=24,v={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},WJ=32896,S2=0.016666666666666666;function X1(J){return J.__viewport??null}var H0=null;function n4(){return null}function W1(J,Q=n4()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function t4(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return W1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return W1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function e4(J){H0=J}function VJ(){if(!H0)throw Error("PocketJS: host not installed — call render() first");return H0}function _(){return VJ().ops}function J6(J){globalThis.frame=J}function Q6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function $6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return Z1($>>>16&255,$>>>8&255,$&255,255);return Z1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function Z6(J,Q){let $=c4[J];if(typeof Q==="string"){if($===K.color)return $6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===K.color||$===K.int)return Q>>>0;return Q}var uJ=60,Y1=[1,2,3,4,5,6,10,12,15,20,30,60],j0=uJ,n=-1,X6=0,AJ=[];function W6(J){if(!Number.isFinite(J)||J<=0)return uJ;let Q=Y1[0];for(let $ of Y1)if(Math.abs($-J)Q.at<=n).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;AJ=AJ.filter((Q)=>Q.at>n);for(let Q of J)Q.cb()}var B0=0.12,lJ=WJ;function G6(J){lJ=J===void 0?WJ:J&65535}function H6(){lJ=WJ}function G1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function B6(){return G1(lJ&255)}var H1=new Set,F6=0;function K6(){H1.clear(),F6=0,H6()}function M6(J){for(let Q of[...H1])Q(J)}var YJ=null,j1=null;function U6(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function B1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function SJ(J){F0();let Q=YJ?YJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return j1.slice(Q.off,Q.off+Q.len)}var yJ=null,A=null,qJ=null,pJ=0,zJ=[],M0=[],U0=[];function K1(J){if(yJ=J,A=null,qJ=null,pJ=0,zJ.length=0,M0.length=0,U0.length=0,m){if(m.pressTarget=null,m.target=null,m.spriteDirty=!0,m.fresh=!0,m.vw=0,m.tex>=0){let Q=_();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(m.tex),m.tex=-1}}}function P6(J,Q){J.onPress=Q??void 0}function R6(J,Q){if(J.focusable=Q,R1(),!Q&&A===J)g(null)}function g(J){if(qJ&&qJ!==J)GJ(null);A=J,_().setFocus(J?J.id:0)}function GJ(J){if(qJ===J)return;let Q=_();if(qJ)Q.setActive?.(qJ.id,0);if(qJ=J,J)Q.setActive?.(J.id,1)}function V0(){return zJ.length>0?zJ[zJ.length-1]:yJ}function P0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;g($[X])}function O6(){if(!A)return null;let J=V0();if(J&&!u(A,J))return null;for(let Q=M0.length-1;Q>=0;Q--){let $=M0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function L6(J){let Q=O6();if(!Q)return!1;let $=[];if(P0(Q.node,$),$.length===0){if(A)g(null);return!0}let Z=Q.columns,X=A?$.indexOf(A):-1;if(X<0)return g(M1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)g($[W]);return!0}function C6(){if(!A)return null;let J=V0();if(J&&!u(A,J))return null;for(let Q=U0.length-1;Q>=0;Q--){let $=U0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function cJ(J){let Q=C6();if(Q&&Q.move(J))return;if(L6(J))return;D6(J)}function U1(){V1(A)}function V1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function iJ(J){GJ(J)}function I6(J){g(J),V1(J)}function u(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function R0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=R0(Q.children[X]);if(W){g(W);return}}let Z=Q;while(Z){if(Z.focusable){g(Z);return}Z=Z.parent}}g(null)}var m=null,P1=0;function R1(){P1++}var A6=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],S6=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function y6(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=A6[Q]>>$&1,X=S6[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,q=X?255:0;J[W]=q,J[W+1]=q,J[W+2]=q,J[W+3]=255}return J}function _6(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=SJ($.image)}catch(q){if(VJ().strict)throw q;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):h6(Q,W),X<0&&VJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(y6(),16,16,i4.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function h6(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&d4)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function dJ(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=dJ($[Z],Q);if(X)return X}return null}var sJ=null;function w1(J){sJ=J}function D1(J){let Q=zJ.length>0?zJ[zJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||u($,Q)))return $;$=$.parent}return null}function O1(J,Q,$){return D1(L1(J,Q,$))}function L1(J,Q,$){if($!==void 0)return $===0?null:dJ(sJ??yJ,$);let Z=_(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return dJ(sJ??yJ,X(J,Q))}function x6(J,Q,$){let Z=m,X=_();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=X1(X);if(Z.vw=H?H.w:Q1,Z.vh=H?H.h:$1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)_6(Z,X);let W=j6()*Z.speed,q=B6()*Z.speed;if(Z.dpadSpeed>0&&W===0&&q===0){if(J&v.LEFT)W=-Z.dpadSpeed;if(J&v.RIGHT)W=Z.dpadSpeed;if(J&v.UP)q=-Z.dpadSpeed;if(J&v.DOWN)q=Z.dpadSpeed}let G=Z.fresh;if(W!==0||q!==0){let H=Y6()/60,L=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),y=Math.min(Math.max(Z.y+q*H,0),Z.vh-1);if(L!==Z.x||y!==Z.y)Z.x=L,Z.y=y,G=!0}if(G)X.setCursorPos(Z.x,Z.y);let M=(Q|$)&Z.button,U=P1;if(G||M!==0||U!==Z.gen)Z.gen=U,Z.fresh=!1,Z.target=D1(dJ(sJ??yJ,X.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==A)g(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(GJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=V===Z.pressTarget;if(Z.pressTarget=null,GJ(null),H)U1()}}else if($&Z.button)GJ(null);return!0}function f6(J){let Q=J&~pJ,$=pJ&~J;if(pJ=J,m&&x6(J,Q,$))return;if($&v.CIRCLE)GJ(null);if(Q===0)return;if(Q&v.DOWN)cJ("down");if(Q&v.RIGHT)cJ("right");if(Q&v.UP)cJ("up");if(Q&v.LEFT)cJ("left");if(Q&v.CIRCLE)GJ(A),U1()}var w0=null;function C1(J){w0=J}function PJ(){if(R1(),w0)w0()}function b6(J,Q){J.debugName=Q||void 0,PJ()}var t={id:u4,type:XJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},I1=Symbol.for("pocketjs.native-node"),D0=1,_J=3,d=8,g6=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function aJ(J){return J.domAttrs??={}}function k1(J,Q){let $=J.domNodeType??(hJ(J)?_J:D0),Z=$===_J?rJ(J.text??""):$===d?N6(J.domData??""):f1(J.domTag??nJ(J));for(let X of Object.keys(J.domAttrs??{}))O0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)e(Z,k1(X,!0));return Z}function O0(J,Q,$){if(g6.has(Q)){wJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete aJ(J)[Q];else aJ(J)[Q]=$}function L0(J){if(J[I1]===!0)return J;return Object.defineProperty(J,I1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(hJ(J)?_J:D0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else oJ(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else oJ(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===d)return J.domData??"";if(hJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===d)J.domData=Z;else if(hJ(J))oJ(J,Z);else if(i6(J),Z)e(J,rJ(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return g1(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??nJ(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===_J)return"#text";if(J.domNodeType===d)return"#comment";return(J.domTag??nJ(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){wJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===t)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return e(J,$),$},insertBefore($,Z){return e(J,$,Z??null),$},removeChild($){return xJ(J,$),$},replaceChild($,Z){return e(J,$,Z),xJ(J,Z),Z},cloneNode($=!1){return k1(J,!!$)},remove(){if(J.parent)xJ(J.parent,J)},setAttribute($,Z){O0(J,$,Z)},removeAttribute($){O0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}L0(t);var C0=null;function T6(J){C0=J}var I0={unknownClass:0,unknownTexture:0},A1=new Map;function S1(J,Q){A1.set(J,Q)}var y1=new Map;function _1(J,Q){y1.set(J,Q)}var RJ=new Set,E6=new Set;function h1(J){if(!J)return!1;if(E6.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return L0({id:_().createNode(Q),type:Q,parent:null,children:[],domNodeType:D0,domTag:J})}function rJ(J){let Q=_(),$=Q.createNode(XJ.text);return Q.setText($,J),L0({id:$,type:XJ.text,parent:null,children:[],text:J,domNodeType:_J,domTag:"#text"})}function N6(J=""){let Q=rJ("");return Q.domNodeType=d,Q.domTag="#comment",Q.domData=J,Q}function oJ(J,Q){_().replaceText(J.id,Q),J.text=Q,PJ()}function hJ(J){return J.type===XJ.text}function b1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function e(J,Q,$){let Z=_();if(b1(Q),RJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,PJ()}function xJ(J,Q){if(!Q)return;k6(Q),_().removeChild(J.id,Q.id),b1(Q),RJ.add(Q),PJ()}function m6(J){return J.parent??void 0}function v6(J){return J.children[0]}function g1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function u6(J,Q){let $=_();if(PJ(),Q==null||Q===""){$.setStyle(J.id,l4);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=C0?C0(Q):void 0;if(Z===void 0){if(VJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);I0.unknownClass++;return}$.setStyle(J.id,Z)}function l6(J,Q){let $=_();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=A1.get(Q);if(Z===void 0){if(VJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);I0.unknownTexture++;return}$.setImage(J.id,Z)}function p6(J,Q){let $=_();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=y1.get(Q);if(Z===void 0){if(VJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);I0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function c6(J,Q,$){let Z=_(),X=Q??{},W=$??{},q=!1;for(let G in X){let M=X[G];if(W[G]===M)continue;let U=p4[G];if(U===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,U,Z6(G,M)),q=!0}if(q)PJ()}function wJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete aJ(J)[Q];else aJ(J)[Q]=$;switch(Q){case"class":return u6(J,$),$;case"onPress":case"on:press":return P6(J,$),$;case"src":return l6(J,$),$;case"sprite":return p6(J,$),$;case"style":return c6(J,$,Z),$;case"focusable":return R6(J,!!$),$;case"debugName":return b6(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${nJ(J)}>`)}function i6(J){for(let Q of[...J.children])xJ(J,Q)}function nJ(J){for(let Q of Object.keys(XJ))if(XJ[Q]===J.type)return Q;return String(J.type)}function d6(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}wJ(J,Q,$,Z)}var s6=v4({createElement:f1,createTextNode:rJ,replaceText:oJ,isTextNode:hJ,setProperty:d6,insertNode(J,Q,$){e(J,Q,$)},removeNode(J,Q){xJ(J,Q)},getParentNode:m6,getFirstChild:v6,getNextSibling:g1}),{render:a6,effect:y2,memo:r6,createComponent:O,createElement:T1,insert:_2,spread:o6,mergeProps:h2,use:x2}=s6,f2={linear:N.Easing.Linear,in:N.Easing.EaseIn,out:N.Easing.EaseOut,"in-out":N.Easing.EaseInOut,"out-back":N.Easing.OutBack,spring:N.Easing.Spring,"spring-bouncy":N.Easing.SpringBouncy},n6=null;function E1(J){n6=J}function t6(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function N1(J,Q){let $=T1(J);return o6($,Q,!1),t6(Q.nodeRef,$),$}function T(J){return N1("view",J)}function x(J){return N1("text",J)}var b2=new WeakMap,g2=new WeakMap,e6={}!==null?Object.freeze({...{}}):Object.freeze({}),T2=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:e6}),E2=new Map,JJ=36000,k0=30,J8=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(JJ),tapeAnalog:new Uint16Array(JJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-k0,saidHello:!1,hostCalls:0};function Q8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-k0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)C1(()=>{Y.treeDirty=!0}),G8();else C1(null);globalThis.__pocketDevtools=j8}function $8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)X8(),q8();let W=Q,q=$===void 0?WJ:$&65535,G=Z,M=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(JJ).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==WJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function u1(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,q]of J)Z.fill(W,X,Math.min(X+q,$)),X+=q;return Z}function l1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return u1(J.masks,0,Q)}function p1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return u1(J.analog??[],WJ,Q)}function c1(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,b({t:"hello",app:Y.app,host:H8(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` -`))if(X.trim())W8(X)}}function W8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)b({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),A0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),A0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":i1();break;case"eval":{let Z=!0,X;try{X=tJ((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}b({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":b({t:"tape",tape:v1()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}b({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())b({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else b({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=l1(Z),Y.replayAnalog=Z.analog?p1(Z):null,Y.replayTouch=Z.touch?c1(Z):null,Y.replayAt=0;break}default:break}}function Y8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=k0)i1();if(Y.frame%J8===0)A0()}function q8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,b({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,b({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function A0(){b({t:"stats",frame:Y.frame,nodes:a1(t),tapeLen:Y.tapeLen,paused:Y.paused})}function i1(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,b({t:"tree",frame:Y.frame,root:s1(t)})}function z8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function S0(J,Q){if(Array.isArray(J)){for(let $ of J)S0($,Q);return}if(z8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)S0($,Q)}}function d1(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)S0(Z,Q)}function s1(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(d1(J,(X)=>{if(X.domNodeType===8)return;Z.push(s1(X))}),Z.length)Q.k=Z;return Q}function a1(J){let Q=1;return d1(J,($)=>{Q+=a1($)}),Q}function G8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{b({t:"log",level:$,args:X.map((W)=>tJ(W))}),Z?.apply(Q,X)}}}function tJ(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?r1(W):JSON.stringify(r1(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((q)=>tJ(q,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,q])=>`${W}: ${tJ(q,Q+1)}`).join(", ")}}`}function r1(J){return J.length>200?J.slice(0,199)+"…":J}function H8(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var j8={get frame(){return Y.frame},dumpTape:()=>v1(),replay:(J)=>{Y.replayMasks=l1(J),Y.replayAnalog=J.analog?p1(J):null,Y.replayTouch=J.touch?c1(J):null,Y.replayAt=0}},o1=new Map,y0=new Map;function n1(J){return J.trim().replace(/\s+/g," ")}function t1(J){return J.split(" ").sort().join(" ")}var e1=-1;function B8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=n1(Q);o1.set(Z,$);let X=t1(Z),W=y0.get(X);y0.set(X,W!==void 0&&W!==$?e1:$)}}function F8(J){let Q=n1(J),$=o1.get(Q);if($!==void 0)return $;let Z=y0.get(t1(Q));return Z===e1?void 0:Z}var _0=9,K8=(1<<_0)-1,M8=_0*2,U8=2147483648,h0=10,V8=(1<{let X=($&U8)!==0,W=X?h0:_0,q=X?V8:K8;return Object.freeze({id:$>>>(X?P8:M8)&255,x:$&q,y:$>>>W&q,hit:Q?.[Z]})}))}function w8(){return eJ}function D8(){eJ=x0}var J4=8,QJ=8,O8=3,L8=8,C8=6,I8=0.5,l=1,fJ=2,f0=4,HJ=8,DJ=[],Q4=0,J0=0,$J=Array.from({length:J4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(QJ),histY:new Int16Array(QJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function k8(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function A8(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=L1(Q,$,Z.fact);let G=Z.hit;if(G)return k8(G,W)}let q=X.rect?.();if(!q)return!1;return Q>=q.x&&Q=q.y&&$=0;q--){let G=DJ[q];if(G.disposed)continue;if(Q4>0&&!G.opts.allowWhenBlocked)continue;if(!A8(G,$,Z,W))continue;G.flags[J.slot]=l,J.owners.push(G)}for(let q of J.owners)q.opts.onDown?.(J)}function _8(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%QJ,J.histLenq||Z>q))X.flags[J.slot]|=fJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&l)||W&(fJ|f0))continue;if(!X.opts.onLongPress)continue;let q=Math.max(1,Math.round((X.opts.longPressSeconds??I8)*q1()));if(J.frames=0)DJ.splice($,1)},cancel(){if(!Q.disposed)X4(Q)},get panning(){for(let $ of $J)if($.used&&Q.flags[$.slot]&HJ)return!0;return!1}}}function g8(J){let Q=b8(J);return Y0(()=>Q.dispose()),Q}function W4(){DJ.length=0,Q4=0,J0=0;for(let J of $J)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function T8(){return g8({onDown:(J)=>{let Q=O1(J.x,J.y,J.hit);if(Q)iJ(Q)},onTap:(J)=>{iJ(null);let Q=O1(J.x,J.y,J.hit);if(Q)I6(Q)},onUp:()=>iJ(null),onCancel:()=>iJ(null)})}var E8=1,b0=new Map,Q0=[];function N8(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function m8(){E8=1,b0.clear(),Q0=[]}function v8(){if(Q0.length===0)return;let J=Q0;Q0=[];for(let{id:Q,result:$}of J){let Z=b0.get(Q);if(!Z)continue;b0.delete(Q),N8()?.({t:"delivery",frame:z1(),id:Q,kind:Z.kind}),Z.onResult($)}}var Y4=new Set;function u8(){if(Y4.size===0)return;for(let J of Y4)J()}var l8={"flex-col w-full h-full bg-slate-50":0,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":1,"flex-row items-center gap-4":2,"text-2xl text-white":3,"flex-col":4,"text-sm text-indigo-300 tracking-wide":5,"text-2xl text-white font-bold":6,"px-3 py-2 bg-indigo-900":7,"text-sm text-indigo-200":8,"p-6 flex-col gap-3":9,"text-sm text-indigo-700 font-bold":10,"text-2xl text-slate-950 font-bold":11,"text-base text-slate-600":12,"grow px-6 pt-4 flex-col gap-3":13,"h-[430] px-12 flex-col items-center justify-center bg-white":14,"w-[88] h-[88] items-center justify-center bg-indigo-100":15,"text-2xl text-indigo-700 font-bold":16,"pt-7 text-xl text-slate-900 font-bold":17,"pt-4 text-base text-slate-500":18,"h-[118] px-5 flex-row items-center justify-between bg-white":19,"w-[500] flex-col gap-2":20,"text-base text-slate-900 font-bold":21,"text-sm text-slate-500":22,"text-sm text-indigo-600 font-bold":23,"px-3 py-2 bg-emerald-100":24,"px-3 py-2 bg-red-100":25,"text-sm text-emerald-700":26,"text-sm text-red-500":27,"h-[96] px-6 flex-row items-center bg-slate-950":28,"text-sm text-slate-300":29,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":30,"absolute inset-0 z-50 flex-col items-center justify-center":31,"absolute inset-0 bg-slate-950":32,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":33,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":34,"flex-row flex-wrap":35,grow:36};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var p8="ui:styles",c8="ui:font.",q4="ui:img.",z4="ui:sprite.";function i8(){return globalThis.ui}function d8(J){if(J.__textures)return;for(let Q of K0(q4)){let $=SJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)S1(Q.slice(q4.length),Z)}}function s8(J){if(J.__sprites)return;for(let Q of K0(z4)){let $=SJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),q=$[4],G=Z.getUint16(6,!0),M=Z.getUint16(8,!0),U=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),X,W,q);if(V>=0)_1(Q.slice(z4.length),{handle:V,frames:G,cols:M,step:U})}}function G4(J){let Q=T1("view");return wJ(Q,"style",J,void 0),Q}var $0=null,Z0=null;function a8(J,Q){if(!$0||!Z0)return;wJ($0,"style",{width:J,height:Q,overflow:N.Overflow.Hidden},void 0),wJ(Z0,"style",{width:J,height:Q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=_();$.__viewport={w:J,h:Q}}function r8(J,Q={}){let $=t4(Q.ops);if(e4($),T6(F8),Q.styles)B8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let L in Z)S1(L,Z[L]);let H=$.ops.__sprites;if(H)for(let L in H)_1(L,H[L])}if($.kind==="injected"||Z===void 0){if(Q.pak)F1(Q.pak);if(V6()){for(let H of K0())if(H===p8)$.ops.loadStyles?.(SJ(H));else if(H.startsWith(c8))$.ops.loadFontAtlas?.(SJ(H))}}let X=X1($.ops),W=X?.w??Q1,q=X?.h??$1,G=G4({width:W,height:q,overflow:N.Overflow.Hidden}),M=G4({width:W,height:q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});e(t,G),e(t,M),E1(M),$0=G,Z0=M,K1(G),w1(t),K6(),W4(),T8(),q6(),m8(),Q8($.ops),J6($8((H,L,y,h)=>{z6(),G6(L),R8(y,h),u8(),v8(),f8(),M6(H),f6(H),x1()}));let U=a6(J,G),V=Q6(a8);return()=>{V(),D8(),W4(),U(),K1(null),w1(null),E1(null),$0=null,Z0=null;for(let H of t.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);x1()}}function o8(J,Q={}){let $=Q.ops??i8();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)F1(Q.pak);return d8($),s8($),r8(J,{ops:$,styles:Q.styles??l8,pak:Q.pak})}var H4="$b",n8=9007199254740991,t8=":memory:",OJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function e8(J){let Q="";for(let $=0;$>2]+OJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2n8)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function $2(J){if(J!==null&&typeof J==="object")return J2(J[H4]);return J}function Z2(J){if(Array.isArray(J))return JSON.stringify(J.map(j4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=j4(Z);return JSON.stringify(Q)}class g0{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,Z2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=B4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map($2))}run(...J){let Q=this.execute(B4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function B4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class F4{statements=new Map;txDepth=0;constructor(J=t8){let Q=Q2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new g0(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new g0(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let q=J(...Q);return this.txDepth--,this.exec(X),q}catch(q){throw this.txDepth--,this.exec(W),q}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var T0=4,K4=7,s=new F4("exa"),[M4,E0]=kJ([]),[X2,N0]=kJ("SEARCH HISTORY IS LOCAL"),X0=-1;function W2(J){try{return JSON.parse(J)}catch{return null}}function Y2(J){let Q=new Date(J*1000).toISOString();return Q.slice(0,10)+" · "+Q.slice(11,16)+" UTC"}function U4(J){if(X0===J)return;try{let Q=s.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==T0){E0([]),N0("SEARCH HISTORY IS LOCAL");return}let $=s.query(` +(()=>{var MJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return l0(this.context.count)},getNextContextId(){return l0(this.context.count++)}};function l0(J){let Q=String(J),$=Q.length-1;return MJ.context.id+($?String.fromCharCode(96+$):"")+Q}function c0(J){MJ.context=J}function O4(){return{...MJ.context,id:MJ.getNextContextId(),count:0}}var L4=!1,C4=(J,Q)=>J===Q,q0=Symbol("solid-proxy"),I4=typeof Proxy==="function",k4=Symbol("solid-track"),U2=Symbol("solid-dev-component"),TJ={equals:C4},p0=null,A4=n0,E=1,IJ=2,i0={owned:null,cleanups:null,context:null,owner:null},I=null,B=null,kJ=null,UJ=null,k=null,S=null,f=null,EJ=0;function NJ(J,Q){let $=k,Z=I,X=J.length===0,W=Q===void 0?Z:Q,q=X?i0:{owned:null,cleanups:null,context:W?W.context:null,owner:W},G=X?J:()=>J(()=>o(()=>n(q)));I=q,k=null;try{return i(G,!0)}finally{k=$,I=Z}}function AJ(J,Q){Q=Q?Object.assign({},TJ,Q):TJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return a0($,X)};return[s0.bind($),Z]}function r(J,Q,$){let Z=o0(J,Q,!1,E);if(kJ&&B&&B.running)S.push(Z);else vJ(Z)}function VJ(J,Q,$){$=$?Object.assign({},TJ,$):TJ;let Z=o0(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,kJ&&B&&B.running)Z.tState=E,S.push(Z);else vJ(Z);return s0.bind(Z)}function o(J){if(!UJ&&k===null)return J();let Q=k;k=null;try{if(UJ)return UJ.untrack(J);return J()}finally{k=Q}}function z0(J){if(I===null);else if(I.cleanups===null)I.cleanups=[J];else I.cleanups.push(J);return J}function S4(J){if(B&&B.running)return J(),B.done;let Q=k,$=I;return Promise.resolve().then(()=>{k=Q,I=$;let Z;if(kJ||y4)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return i(J,!1),k=I=null,Z?Z.done:void 0})}var[V2,d0]=AJ(!1),y4;function s0(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===E)vJ(this);else{let Q=S;S=null,i(()=>mJ(this),!1),S=Q}if(k){let Q=this.observers;if(!Q||Q[Q.length-1]!==k){let $=Q?Q.length:0;if(!k.sources)k.sources=[this],k.sourceSlots=[$];else k.sources.push(this),k.sourceSlots.push($);if(!Q)this.observers=[k],this.observerSlots=[k.sources.length-1];else Q.push(k),this.observerSlots.push(k.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function a0(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)i(()=>{for(let X=0;X1e6)throw S=[],Error()},!1)}return Q}function vJ(J){if(!J.fn)return;n(J);let Q=EJ;if(r0(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{i(()=>{B&&(B.running=!0),k=I=J,r0(J,J.tValue,Q),k=I=null},!1)})}function r0(J,Q,$){let Z,X=I,W=k;k=I=J;try{Z=J.fn(Q)}catch(q){if(J.pure)if(B&&B.running)J.tState=E,J.tOwned&&J.tOwned.forEach(n),J.tOwned=void 0;else J.state=E,J.owned&&J.owned.forEach(n),J.owned=null;return J.updatedAt=$+1,H0(q)}finally{k=W,I=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)a0(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function o0(J,Q,$,Z=E,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:I,context:I?I.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(I===null);else if(I!==i0)if(B&&B.running&&I.pure)if(!I.tOwned)I.tOwned=[W];else I.tOwned.push(W);else if(!I.owned)I.owned=[W];else I.owned.push(W);if(UJ&&W.fn){let q=W.fn,[G,M]=AJ(void 0,{equals:!1}),U=UJ.factory(q,M);z0(()=>U.dispose());let V,H=()=>S4(M).then(()=>{if(V)V.dispose(),V=void 0});W.fn=(L)=>{if(G(),B&&B.running){if(!V)V=UJ.factory(q,H);return V.track(L)}return U.track(L)}}return W}function G0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===IJ)return mJ(J);if(J.suspense&&o(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===E)vJ(J);else if((Q?J.tState:J.state)===IJ){let X=S;S=null,i(()=>mJ(J,$[0]),!1),S=X}}}function i(J,Q){if(S)return J();let $=!1;if(!Q)S=[];if(f)$=!0;else f=[];EJ++;try{let Z=J();return _4($),Z}catch(Z){if(!$)f=null;S=null,H0(Z)}}function _4(J){if(S){if(kJ&&B&&B.running)h4(S);else n0(S);S=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;f.push.apply(f,B.effects),Q=B.resolve;for(let W of f)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,i(()=>{for(let W of X)n(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let q=0,G=W.owned.length;qA4($),!1);if(Q)Q()}function n0(J){for(let Q=0;Q{Z.delete($),i(()=>{B.running=!0,G0($)},!1),B&&(B.running=!1)})}}function mJ(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)n(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)e0(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)n(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function e0(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return z0(()=>Q1(W)),()=>{let M=J()||[],U=M.length,V,H;return M[k4],o(()=>{let y,h,c,XJ,BJ,F,j,z,P;if(U===0){if(q!==0)Q1(W),W=[],Z=[],X=[],q=0,G&&(G=[]);if($.fallback)Z=[f4],X[0]=NJ((O)=>{return W[0]=O,$.fallback()}),q=1}else if(q===0){X=Array(U);for(H=0;H=F&&z>=F&&Z[j]===M[z];j--,z--)c[z]=X[j],XJ[z]=W[j],G&&(BJ[z]=G[j]);y=new Map,h=Array(z+1);for(H=z;H>=F;H--)P=M[H],V=y.get(P),h[H]=V===void 0?-1:V,y.set(P,H);for(V=F;V<=j;V++)if(P=Z[V],H=y.get(P),H!==void 0&&H!==-1)c[H]=X[V],XJ[H]=W[V],G&&(BJ[H]=G[V]),H=h[H],y.set(P,H);else W[V]();for(H=F;HJ(Q||{}));return c0($),Z}}return o(()=>J(Q||{}))}function uJ(){return!0}var E4={get(J,Q,$){if(Q===q0)return $;return J.get(Q)},has(J,Q){if(Q===q0)return!0;return J.has(Q)},set:uJ,deleteProperty:uJ,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:uJ,deleteProperty:uJ}},ownKeys(J){return J.keys()}};function j0(J){return!(J=typeof J==="function"?J():J)?{}:J}function N4(){for(let J=0,Q=this.length;J=0;G--){let M=j0(J[G])[q];if(M!==void 0)return M}},has(q){for(let G=J.length-1;G>=0;G--)if(q in j0(J[G]))return!0;return!1},keys(){let q=[];for(let G=0;G=0;q--){let G=J[q];if(!G)continue;let M=Object.getOwnPropertyNames(G);for(let U=M.length-1;U>=0;U--){let V=M[U];if(V==="__proto__"||V==="constructor")continue;let H=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=H.get?{enumerable:!0,configurable:!0,get:N4.bind($[V]=[H.get.bind(G)])}:H.value!==void 0?H:void 0;else{let L=$[V];if(L){if(H.get)L.push(H.get.bind(G));else if(H.value!==void 0)L.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let q=W.length-1;q>=0;q--){let G=W[q],M=Z[G];if(M&&M.get)Object.defineProperty(X,G,M);else X[G]=M?M.value:void 0}return X}var v4=(J)=>`Stale read from <${J}>.`;function m4(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return VJ(b4(()=>J.each,J.children,Q||void 0))}function u4(J){let Q=J.keyed,$=VJ(()=>J.when,void 0,void 0),Z=Q?$:VJ($,void 0,{equals:(X,W)=>!X===!W});return VJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?o(()=>W(Q?X:()=>{if(!o(Z))throw v4("Show");return $()})):W}return J.fallback},void 0,void 0)}var l4=(J)=>VJ(()=>J());function c4({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:q,getParentNode:G,getFirstChild:M,getNextSibling:U}){function V(F,j,z,P){if(z!==void 0&&!P)P=[];if(typeof j!=="function")return H(F,j,P,z);r((O)=>H(F,j(),O,z),P)}function H(F,j,z,P,O){while(typeof z==="function")z=z();if(j===z)return z;let C=typeof j,w=P!==void 0;if(C==="string"||C==="number"){if(C==="number")j=j.toString();if(w){let R=z[0];if(R&&$(R))Z(R,j);else R=Q(j);z=h(F,z,P,R)}else if(z!==""&&typeof z==="string")Z(M(F),z=j);else h(F,z,P,Q(j)),z=j}else if(j==null||C==="boolean")z=h(F,z,P);else if(C==="function")return r(()=>{let R=j();while(typeof R==="function")R=R();z=H(F,R,z,P)}),()=>z;else if(Array.isArray(j)){let R=[];if(L(R,j,O))return r(()=>z=H(F,R,z,P,!0)),()=>z;if(R.length===0){let CJ=h(F,z,P);if(w)return z=CJ}else if(Array.isArray(z))if(z.length===0)c(F,R,P);else y(F,z,R);else if(z==null||z==="")c(F,R);else y(F,w&&z||[M(F)],R);z=R}else{if(Array.isArray(z)){if(w)return z=h(F,z,P,j);h(F,z,null,j)}else if(z==null||z===""||!M(F))X(F,j);else XJ(F,j,M(F));z=j}return z}function L(F,j,z){let P=!1;for(let O=0,C=j.length;Op-R){let M2=j[w];while(R=0;w--){let R=j[w];if(O!==R){let CJ=G(R)===F;if(!C&&!w)CJ?XJ(F,O,R):X(F,O,z);else CJ&&W(F,R)}else C=!0}}else X(F,O,z);return[O]}function c(F,j,z){for(let P=0,O=j.length;Pz.children=H(F,j.children,z.children));return r(()=>j.ref&&j.ref(F)),r(()=>{for(let O in j){if(O==="children"||O==="ref")continue;let C=j[O];if(C===z[O])continue;q(F,O,C,z[O]),z[O]=C}}),z}return{render(F,j){let z;return NJ((P)=>{z=P,V(j,F())}),z},insert:V,spread(F,j,z){if(typeof j==="function")r((P)=>BJ(F,j(),P,z));else BJ(F,j,void 0,z)},createElement:J,createTextNode:Q,insertNode:X,setProp(F,j,z,P){return q(F,j,z,P),z},mergeProps:$1,effect:r,memo:l4,createComponent:T4,use(F,j,z){return o(()=>F(j,z))}}}function p4(J){let Q=c4(J);return Q.mergeProps=$1,Q}var Z1=480,X1=272,WJ={view:0,text:1,image:2},i4=1,d4=-1,s4={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},K={f32:0,color:1,int:2},a4={width:K.f32,height:K.f32,minW:K.f32,minH:K.f32,maxW:K.f32,maxH:K.f32,paddingT:K.f32,paddingR:K.f32,paddingB:K.f32,paddingL:K.f32,marginT:K.f32,marginR:K.f32,marginB:K.f32,marginL:K.f32,gap:K.f32,flexDir:K.int,justify:K.int,align:K.int,grow:K.f32,shrink:K.f32,basis:K.f32,flexWrap:K.int,posType:K.int,insetT:K.f32,insetR:K.f32,insetB:K.f32,insetL:K.f32,display:K.int,overflow:K.int,zIndex:K.int,hitPass:K.int,bgColor:K.color,gradFrom:K.color,gradTo:K.color,gradDir:K.int,radius:K.f32,opacity:K.f32,borderColor:K.color,borderWidth:K.f32,shadow:K.int,bevelOuterLight:K.color,bevelOuterDark:K.color,bevelInnerLight:K.color,bevelInnerDark:K.color,bevelWidth:K.f32,textColor:K.color,fontSlot:K.int,textAlign:K.int,lineHeight:K.f32,tracking:K.f32,translateX:K.f32,translateY:K.f32,scale:K.f32,rotate:K.f32,scaleX:K.f32,scaleY:K.f32,originX:K.f32,originY:K.f32,rotateX:K.f32,rotateY:K.f32,translateZ:K.f32,perspective:K.f32,arcStart:K.f32,arcSweep:K.f32,arcWidth:K.f32},N={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},r4={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},o4=1,P2=2,R2=1,w2=2,D2=131072,O2=1,L2=262144,C2=1,I2=1,k2=1,A2=2,S2=4,y2=8,_2=16,h2=1,x2=2;function W1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var f2=1,n4=1263551300,t4=1,e4=32,J6=24,m={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},YJ=32896,b2=0.016666666666666666;function Y1(J){return J.__viewport??null}var B0=null;function Q6(){return null}function q1(J,Q=Q6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function $6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return q1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return q1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function Z6(J){B0=J}function PJ(){if(!B0)throw Error("PocketJS: host not installed — call render() first");return B0}function _(){return PJ().ops}function X6(J){globalThis.frame=J}function W6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function Y6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return W1($>>>16&255,$>>>8&255,$&255,255);return W1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function q6(J,Q){let $=a4[J];if(typeof Q==="string"){if($===K.color)return Y6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===K.color||$===K.int)return Q>>>0;return Q}var lJ=60,z1=[1,2,3,4,5,6,10,12,15,20,30,60],F0=lJ,t=-1,z6=0,SJ=[];function G6(J){if(!Number.isFinite(J)||J<=0)return lJ;let Q=z1[0];for(let $ of z1)if(Math.abs($-J)Q.at<=t).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;SJ=SJ.filter((Q)=>Q.at>t);for(let Q of J)Q.cb()}var K0=0.12,cJ=YJ;function F6(J){cJ=J===void 0?YJ:J&65535}function K6(){cJ=YJ}function j1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function U6(){return j1(cJ&255)}var B1=new Set,V6=0;function P6(){B1.clear(),V6=0,K6()}function R6(J){for(let Q of[...B1])Q(J)}var qJ=null,F1=null;function w6(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function K1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function yJ(J){M0();let Q=qJ?qJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return F1.slice(Q.off,Q.off+Q.len)}var _J=null,A=null,zJ=null,pJ=0,GJ=[],V0=[],P0=[];function U1(J){if(_J=J,A=null,zJ=null,pJ=0,GJ.length=0,V0.length=0,P0.length=0,v){if(v.pressTarget=null,v.target=null,v.spriteDirty=!0,v.fresh=!0,v.vw=0,v.tex>=0){let Q=_();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(v.tex),v.tex=-1}}}function O6(J,Q){J.onPress=Q??void 0}function L6(J,Q){if(J.focusable=Q,D1(),!Q&&A===J)T(null)}function T(J){if(zJ&&zJ!==J)HJ(null);A=J,_().setFocus(J?J.id:0)}function HJ(J){if(zJ===J)return;let Q=_();if(zJ)Q.setActive?.(zJ.id,0);if(zJ=J,J)Q.setActive?.(J.id,1)}function R0(){return GJ.length>0?GJ[GJ.length-1]:_J}function w0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;T($[X])}function k6(){if(!A)return null;let J=R0();if(J&&!u(A,J))return null;for(let Q=V0.length-1;Q>=0;Q--){let $=V0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function A6(J){let Q=k6();if(!Q)return!1;let $=[];if(w0(Q.node,$),$.length===0){if(A)T(null);return!0}let Z=Q.columns,X=A?$.indexOf(A):-1;if(X<0)return T(V1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)T($[W]);return!0}function S6(){if(!A)return null;let J=R0();if(J&&!u(A,J))return null;for(let Q=P0.length-1;Q>=0;Q--){let $=P0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function iJ(J){let Q=S6();if(Q&&Q.move(J))return;if(A6(J))return;I6(J)}function P1(){R1(A)}function R1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function dJ(J){HJ(J)}function y6(J){T(J),R1(J)}function u(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function D0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=D0(Q.children[X]);if(W){T(W);return}}let Z=Q;while(Z){if(Z.focusable){T(Z);return}Z=Z.parent}}T(null)}var v=null,w1=0;function D1(){w1++}var h6=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],x6=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function f6(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=h6[Q]>>$&1,X=x6[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,q=X?255:0;J[W]=q,J[W+1]=q,J[W+2]=q,J[W+3]=255}return J}function b6(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=yJ($.image)}catch(q){if(PJ().strict)throw q;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):g6(Q,W),X<0&&PJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(f6(),16,16,r4.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function g6(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&o4)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function sJ(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=sJ($[Z],Q);if(X)return X}return null}var aJ=null;function O1(J){aJ=J}function L1(J){let Q=GJ.length>0?GJ[GJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||u($,Q)))return $;$=$.parent}return null}function C1(J,Q,$){return L1(I1(J,Q,$))}function I1(J,Q,$){if($!==void 0)return $===0?null:sJ(aJ??_J,$);let Z=_(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return sJ(aJ??_J,X(J,Q))}function T6(J,Q,$){let Z=v,X=_();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=Y1(X);if(Z.vw=H?H.w:Z1,Z.vh=H?H.h:X1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)b6(Z,X);let W=M6()*Z.speed,q=U6()*Z.speed;if(Z.dpadSpeed>0&&W===0&&q===0){if(J&m.LEFT)W=-Z.dpadSpeed;if(J&m.RIGHT)W=Z.dpadSpeed;if(J&m.UP)q=-Z.dpadSpeed;if(J&m.DOWN)q=Z.dpadSpeed}let G=Z.fresh;if(W!==0||q!==0){let H=H6()/60,L=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),y=Math.min(Math.max(Z.y+q*H,0),Z.vh-1);if(L!==Z.x||y!==Z.y)Z.x=L,Z.y=y,G=!0}if(G)X.setCursorPos(Z.x,Z.y);let M=(Q|$)&Z.button,U=w1;if(G||M!==0||U!==Z.gen)Z.gen=U,Z.fresh=!1,Z.target=L1(sJ(aJ??_J,X.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==A)T(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(HJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=V===Z.pressTarget;if(Z.pressTarget=null,HJ(null),H)P1()}}else if($&Z.button)HJ(null);return!0}function E6(J){let Q=J&~pJ,$=pJ&~J;if(pJ=J,v&&T6(J,Q,$))return;if($&m.CIRCLE)HJ(null);if(Q===0)return;if(Q&m.DOWN)iJ("down");if(Q&m.RIGHT)iJ("right");if(Q&m.UP)iJ("up");if(Q&m.LEFT)iJ("left");if(Q&m.CIRCLE)HJ(A),P1()}var O0=null;function k1(J){O0=J}function RJ(){if(D1(),O0)O0()}function N6(J,Q){J.debugName=Q||void 0,RJ()}var e={id:i4,type:WJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},A1=Symbol.for("pocketjs.native-node"),L0=1,hJ=3,d=8,v6=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function rJ(J){return J.domAttrs??={}}function S1(J,Q){let $=J.domNodeType??(xJ(J)?hJ:L0),Z=$===hJ?oJ(J.text??""):$===d?l6(J.domData??""):g1(J.domTag??tJ(J));for(let X of Object.keys(J.domAttrs??{}))C0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)JJ(Z,S1(X,!0));return Z}function C0(J,Q,$){if(v6.has(Q)){DJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete rJ(J)[Q];else rJ(J)[Q]=$}function I0(J){if(J[A1]===!0)return J;return Object.defineProperty(J,A1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(xJ(J)?hJ:L0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else nJ(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else nJ(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===d)return J.domData??"";if(xJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===d)J.domData=Z;else if(xJ(J))nJ(J,Z);else if(r6(J),Z)JJ(J,oJ(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return E1(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??tJ(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===hJ)return"#text";if(J.domNodeType===d)return"#comment";return(J.domTag??tJ(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){DJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===e)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return JJ(J,$),$},insertBefore($,Z){return JJ(J,$,Z??null),$},removeChild($){return fJ(J,$),$},replaceChild($,Z){return JJ(J,$,Z),fJ(J,Z),Z},cloneNode($=!1){return S1(J,!!$)},remove(){if(J.parent)fJ(J.parent,J)},setAttribute($,Z){C0(J,$,Z)},removeAttribute($){C0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}I0(e);var k0=null;function m6(J){k0=J}var A0={unknownClass:0,unknownTexture:0},y1=new Map;function _1(J,Q){y1.set(J,Q)}var h1=new Map;function x1(J,Q){h1.set(J,Q)}var wJ=new Set,u6=new Set;function f1(J){if(!J)return!1;if(u6.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return I0({id:_().createNode(Q),type:Q,parent:null,children:[],domNodeType:L0,domTag:J})}function oJ(J){let Q=_(),$=Q.createNode(WJ.text);return Q.setText($,J),I0({id:$,type:WJ.text,parent:null,children:[],text:J,domNodeType:hJ,domTag:"#text"})}function l6(J=""){let Q=oJ("");return Q.domNodeType=d,Q.domTag="#comment",Q.domData=J,Q}function nJ(J,Q){_().replaceText(J.id,Q),J.text=Q,RJ()}function xJ(J){return J.type===WJ.text}function T1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function JJ(J,Q,$){let Z=_();if(T1(Q),wJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,RJ()}function fJ(J,Q){if(!Q)return;_6(Q),_().removeChild(J.id,Q.id),T1(Q),wJ.add(Q),RJ()}function c6(J){return J.parent??void 0}function p6(J){return J.children[0]}function E1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function i6(J,Q){let $=_();if(RJ(),Q==null||Q===""){$.setStyle(J.id,d4);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=k0?k0(Q):void 0;if(Z===void 0){if(PJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);A0.unknownClass++;return}$.setStyle(J.id,Z)}function d6(J,Q){let $=_();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=y1.get(Q);if(Z===void 0){if(PJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);A0.unknownTexture++;return}$.setImage(J.id,Z)}function s6(J,Q){let $=_();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=h1.get(Q);if(Z===void 0){if(PJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);A0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function a6(J,Q,$){let Z=_(),X=Q??{},W=$??{},q=!1;for(let G in X){let M=X[G];if(W[G]===M)continue;let U=s4[G];if(U===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,U,q6(G,M)),q=!0}if(q)RJ()}function DJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete rJ(J)[Q];else rJ(J)[Q]=$;switch(Q){case"class":return i6(J,$),$;case"onPress":case"on:press":return O6(J,$),$;case"src":return d6(J,$),$;case"sprite":return s6(J,$),$;case"style":return a6(J,$,Z),$;case"focusable":return L6(J,!!$),$;case"debugName":return N6(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${tJ(J)}>`)}function r6(J){for(let Q of[...J.children])fJ(J,Q)}function tJ(J){for(let Q of Object.keys(WJ))if(WJ[Q]===J.type)return Q;return String(J.type)}function o6(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}DJ(J,Q,$,Z)}var n6=p4({createElement:g1,createTextNode:oJ,replaceText:nJ,isTextNode:xJ,setProperty:o6,insertNode(J,Q,$){JJ(J,Q,$)},removeNode(J,Q){fJ(J,Q)},getParentNode:c6,getFirstChild:p6,getNextSibling:E1}),{render:t6,effect:g2,memo:s,createComponent:D,createElement:N1,insert:T2,spread:e6,mergeProps:E2,use:N2}=n6,v2={linear:N.Easing.Linear,in:N.Easing.EaseIn,out:N.Easing.EaseOut,"in-out":N.Easing.EaseInOut,"out-back":N.Easing.OutBack,spring:N.Easing.Spring,"spring-bouncy":N.Easing.SpringBouncy},J8=null;function v1(J){J8=J}function Q8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function m1(J,Q){let $=N1(J);return e6($,Q,!1),Q8(Q.nodeRef,$),$}function b(J){return m1("view",J)}function x(J){return m1("text",J)}var m2=new WeakMap,u2=new WeakMap,$8={}!==null?Object.freeze({...{}}):Object.freeze({}),l2=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:$8}),c2=new Map,QJ=36000,S0=30,Z8=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(QJ),tapeAnalog:new Uint16Array(QJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-S0,saidHello:!1,hostCalls:0};function X8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-S0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)k1(()=>{Y.treeDirty=!0}),B8();else k1(null);globalThis.__pocketDevtools=K8}function W8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)q8(),H8();let W=Q,q=$===void 0?YJ:$&65535,G=Z,M=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(QJ).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==YJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function c1(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,q]of J)Z.fill(W,X,Math.min(X+q,$)),X+=q;return Z}function p1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return c1(J.masks,0,Q)}function i1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return c1(J.analog??[],YJ,Q)}function d1(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,g({t:"hello",app:Y.app,host:F8(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` +`))if(X.trim())z8(X)}}function z8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)g({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),y0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),y0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":s1();break;case"eval":{let Z=!0,X;try{X=eJ((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}g({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":g({t:"tape",tape:l1()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}g({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())g({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else g({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=p1(Z),Y.replayAnalog=Z.analog?i1(Z):null,Y.replayTouch=Z.touch?d1(Z):null,Y.replayAt=0;break}default:break}}function G8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=S0)s1();if(Y.frame%Z8===0)y0()}function H8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,g({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,g({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function y0(){g({t:"stats",frame:Y.frame,nodes:o1(e),tapeLen:Y.tapeLen,paused:Y.paused})}function s1(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,g({t:"tree",frame:Y.frame,root:r1(e)})}function j8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function _0(J,Q){if(Array.isArray(J)){for(let $ of J)_0($,Q);return}if(j8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)_0($,Q)}}function a1(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)_0(Z,Q)}function r1(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(a1(J,(X)=>{if(X.domNodeType===8)return;Z.push(r1(X))}),Z.length)Q.k=Z;return Q}function o1(J){let Q=1;return a1(J,($)=>{Q+=o1($)}),Q}function B8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{g({t:"log",level:$,args:X.map((W)=>eJ(W))}),Z?.apply(Q,X)}}}function eJ(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?n1(W):JSON.stringify(n1(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((q)=>eJ(q,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,q])=>`${W}: ${eJ(q,Q+1)}`).join(", ")}}`}function n1(J){return J.length>200?J.slice(0,199)+"…":J}function F8(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var K8={get frame(){return Y.frame},dumpTape:()=>l1(),replay:(J)=>{Y.replayMasks=p1(J),Y.replayAnalog=J.analog?i1(J):null,Y.replayTouch=J.touch?d1(J):null,Y.replayAt=0}},t1=new Map,h0=new Map;function e1(J){return J.trim().replace(/\s+/g," ")}function J4(J){return J.split(" ").sort().join(" ")}var Q4=-1;function M8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=e1(Q);t1.set(Z,$);let X=J4(Z),W=h0.get(X);h0.set(X,W!==void 0&&W!==$?Q4:$)}}function U8(J){let Q=e1(J),$=t1.get(Q);if($!==void 0)return $;let Z=h0.get(J4(Q));return Z===Q4?void 0:Z}var x0=9,V8=(1<{let X=($&R8)!==0,W=X?f0:x0,q=X?w8:V8;return Object.freeze({id:$>>>(X?D8:P8)&255,x:$&q,y:$>>>W&q,hit:Q?.[Z]})}))}function L8(){return J0}function C8(){J0=b0}var $4=8,$J=8,I8=3,k8=8,A8=6,S8=0.5,l=1,bJ=2,g0=4,jJ=8,OJ=[],Z4=0,Q0=0,ZJ=Array.from({length:$4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array($J),histY:new Int16Array($J),histHead:0,histLen:0,owners:[],claimedBy:null}));function y8(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function _8(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=I1(Q,$,Z.fact);let G=Z.hit;if(G)return y8(G,W)}let q=X.rect?.();if(!q)return!1;return Q>=q.x&&Q=q.y&&$=0;q--){let G=OJ[q];if(G.disposed)continue;if(Z4>0&&!G.opts.allowWhenBlocked)continue;if(!_8(G,$,Z,W))continue;G.flags[J.slot]=l,J.owners.push(G)}for(let q of J.owners)q.opts.onDown?.(J)}function f8(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%$J,J.histLen<$J)J.histLen++;let Z=Math.min(I8,J.histLen-1);if(Z<=0){J.vx=0,J.vy=0;return}let X=G1(),W=(J.histHead-1+$J)%$J,q=(W-Z+$J)%$J;J.vx=(J.histX[W]-J.histX[q])*X/Z,J.vy=(J.histY[W]-J.histY[q])*X/Z}function b8(J){let Q=J.fdx!==0||J.fdy!==0,$=J.dx<0?-J.dx:J.dx,Z=J.dy<0?-J.dy:J.dy;for(let X of J.owners){let W=X.flags[J.slot];if(!(W&l))continue;if(Q)X.opts.onMove?.(J);let q=X.opts.tapSlop??k8;if(!(W&bJ)&&($>q||Z>q))X.flags[J.slot]|=bJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&l)||W&(bJ|g0))continue;if(!X.opts.onLongPress)continue;let q=Math.max(1,Math.round((X.opts.longPressSeconds??S8)*G1()));if(J.frames=0)OJ.splice($,1)},cancel(){if(!Q.disposed)Y4(Q)},get panning(){for(let $ of ZJ)if($.used&&Q.flags[$.slot]&jJ)return!0;return!1}}}function N8(J){let Q=E8(J);return z0(()=>Q.dispose()),Q}function q4(){OJ.length=0,Z4=0,Q0=0;for(let J of ZJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function v8(){return N8({onDown:(J)=>{let Q=C1(J.x,J.y,J.hit);if(Q)dJ(Q)},onTap:(J)=>{dJ(null);let Q=C1(J.x,J.y,J.hit);if(Q)y6(Q)},onUp:()=>dJ(null),onCancel:()=>dJ(null)})}var m8=1,T0=new Map,$0=[];function u8(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function l8(){m8=1,T0.clear(),$0=[]}function c8(){if($0.length===0)return;let J=$0;$0=[];for(let{id:Q,result:$}of J){let Z=T0.get(Q);if(!Z)continue;T0.delete(Q),u8()?.({t:"delivery",frame:H1(),id:Q,kind:Z.kind}),Z.onResult($)}}var z4=new Set;function p8(){if(z4.size===0)return;for(let J of z4)J()}var i8={"flex-col w-full h-full bg-slate-50":0,"grow px-6 pt-4 flex-col gap-3":1,"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":2,"w-[474] flex-col gap-2":3,"text-lg text-slate-900 font-bold":4,"text-base text-slate-500":5,"text-base text-indigo-600 font-bold":6,"h-[96]":7,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":8,"absolute inset-0 z-50 flex-col items-center justify-center":9,"absolute inset-0 bg-slate-950":10,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":11,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":12,"flex-row flex-wrap":13,grow:14,"text-2xl text-white font-bold":15,"text-2xl text-slate-950 font-bold":16,"text-xl text-slate-900 font-bold":17,"text-base text-slate-600 font-bold":18,"text-lg text-slate-900":19,"text-base text-slate-500 font-bold":20,"px-6":21,"px-6 py-5":22,"gap-4":23,"rounded-xl shadow bg-white border-slate-100":24,"rounded-xl shadow bg-emerald-100 border-emerald-500":25,"bg-white":26,"bg-slate-100":27,"bg-slate-950":28,"px-3 py-2 rounded-lg bg-slate-100":29,"px-3 py-2 rounded-lg bg-indigo-100":30,"text-base text-indigo-700 font-bold":31,"px-3 py-2 rounded-lg bg-emerald-100":32,"text-base text-emerald-700 font-bold":33,"px-3 py-2 rounded-lg bg-amber-100":34,"text-base text-amber-700 font-bold":35,"px-3 py-2 rounded-lg bg-red-100":36,"text-base text-red-500 font-bold":37,"w-[34] h-[34] rounded-lg bg-amber-400":38,"w-[34] h-[34] rounded-lg bg-red-500":39,"w-[34] h-[34] rounded-lg bg-slate-800":40,"w-[34] h-[34] rounded-lg bg-emerald-500":41,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":42,"flex-row items-center gap-4":43,"w-[34] text-2xl text-white font-bold":44,"w-[332] flex-col items-end gap-2":45,"text-base text-slate-300 font-bold":46,"text-base text-slate-400":47,"h-[166] px-6 pt-6 flex-col gap-3":48,"text-base text-orange-600 font-bold":49,"text-lg text-slate-600":50,"h-[44] px-1 flex-row items-center justify-between":51,"w-full h-full items-center justify-center rounded-xl bg-slate-200":52,"w-full h-full items-center justify-center rounded-xl bg-red-100":53,"w-full h-full items-center justify-center rounded-xl bg-slate-100":54,"w-full h-full items-center justify-center rounded-xl bg-orange-600":55,"text-lg text-slate-500 font-bold":56,"text-lg text-red-500 font-bold":57,"text-lg text-white font-bold":58,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":59,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":60,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":61,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":62,"text-2xl text-indigo-700 font-bold":63,"text-2xl text-slate-600 font-bold":64,"pt-7 text-2xl text-slate-900 font-bold":65,"pt-4 text-lg text-slate-500":66,"text-xl text-emerald-600 font-bold":67,"text-xl text-red-500 font-bold":68,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":69,"text-base text-red-300":70,"text-base text-slate-300":71,"text-base text-red-500":72,"w-full h-full px-6 flex-row items-center bg-slate-950":73,"w-full h-full flex-row items-center":74};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var d8="ui:styles",s8="ui:font.",G4="ui:img.",H4="ui:sprite.";function a8(){return globalThis.ui}function r8(J){if(J.__textures)return;for(let Q of U0(G4)){let $=yJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)_1(Q.slice(G4.length),Z)}}function o8(J){if(J.__sprites)return;for(let Q of U0(H4)){let $=yJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),q=$[4],G=Z.getUint16(6,!0),M=Z.getUint16(8,!0),U=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),X,W,q);if(V>=0)x1(Q.slice(H4.length),{handle:V,frames:G,cols:M,step:U})}}function j4(J){let Q=N1("view");return DJ(Q,"style",J,void 0),Q}var Z0=null,X0=null;function n8(J,Q){if(!Z0||!X0)return;DJ(Z0,"style",{width:J,height:Q,overflow:N.Overflow.Hidden},void 0),DJ(X0,"style",{width:J,height:Q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=_();$.__viewport={w:J,h:Q}}function t8(J,Q={}){let $=$6(Q.ops);if(Z6($),m6(U8),Q.styles)M8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let L in Z)_1(L,Z[L]);let H=$.ops.__sprites;if(H)for(let L in H)x1(L,H[L])}if($.kind==="injected"||Z===void 0){if(Q.pak)M1(Q.pak);if(D6()){for(let H of U0())if(H===d8)$.ops.loadStyles?.(yJ(H));else if(H.startsWith(s8))$.ops.loadFontAtlas?.(yJ(H))}}let X=Y1($.ops),W=X?.w??Z1,q=X?.h??X1,G=j4({width:W,height:q,overflow:N.Overflow.Hidden}),M=j4({width:W,height:q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});JJ(e,G),JJ(e,M),v1(M),Z0=G,X0=M,U1(G),O1(e),P6(),q4(),v8(),j6(),l8(),X8($.ops),X6(W8((H,L,y,h)=>{B6(),F6(L),O8(y,h),p8(),c8(),T8(),R6(H),E6(H),b1()}));let U=t6(J,G),V=W6(n8);return()=>{V(),C8(),q4(),U(),U1(null),O1(null),v1(null),Z0=null,X0=null;for(let H of e.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);b1()}}function e8(J,Q={}){let $=Q.ops??a8();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)M1(Q.pak);return r8($),o8($),t8(J,{ops:$,styles:Q.styles??i8,pak:Q.pak})}var B4="$b",J2=9007199254740991,Q2=":memory:",LJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function $2(J){let Q="";for(let $=0;$>2]+LJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2J2)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function W2(J){if(J!==null&&typeof J==="object")return Z2(J[B4]);return J}function Y2(J){if(Array.isArray(J))return JSON.stringify(J.map(F4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=F4(Z);return JSON.stringify(Q)}class E0{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,Y2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=K4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(W2))}run(...J){let Q=this.execute(K4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function K4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class M4{statements=new Map;txDepth=0;constructor(J=Q2){let Q=X2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new E0(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new E0(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let q=J(...Q);return this.txDepth--,this.exec(X),q}catch(q){throw this.txDepth--,this.exec(W),q}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var U4={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"},W0={neutral:{surface:"px-3 py-2 rounded-lg bg-slate-100",text:"text-base text-slate-600 font-bold"},info:{surface:"px-3 py-2 rounded-lg bg-indigo-100",text:"text-base text-indigo-700 font-bold"},success:{surface:"px-3 py-2 rounded-lg bg-emerald-100",text:"text-base text-emerald-700 font-bold"},warning:{surface:"px-3 py-2 rounded-lg bg-amber-100",text:"text-base text-amber-700 font-bold"},danger:{surface:"px-3 py-2 rounded-lg bg-red-100",text:"text-base text-red-500 font-bold"}};function q2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return D(b,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[D(b,{class:"flex-row items-center gap-4",get children(){return[s(()=>s(()=>!!J.back)()?D(x,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):D(b,{get["class"](){return Q()}})),D(x,{get["class"](){return U4.appTitle},get children(){return J.title}})]}}),D(b,{class:"w-[332] flex-col items-end gap-2",get children(){return[D(x,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),D(x,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function z2(J){return D(b,{class:"h-[166] px-6 pt-6 flex-col gap-3",get children(){return[D(x,{get["class"](){return J.tone==="info"?"text-base text-indigo-700 font-bold":"text-base text-orange-600 font-bold"},get children(){return J.eyebrow}}),D(x,{get["class"](){return U4.pageTitle},get children(){return J.title}}),D(x,{class:"text-lg text-slate-600",get children(){return J.description}})]}})}function G2(J){return D(b,{get["class"](){return J.compact?"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100"},get children(){return[s(()=>s(()=>!!J.icon)()?D(b,{get["class"](){return J.tone==="info"?"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100"},get children(){return D(x,{get["class"](){return J.tone==="info"?"text-2xl text-indigo-700 font-bold":"text-2xl text-slate-600 font-bold"},get children(){return J.icon}})}}):null),D(x,{get["class"](){return J.icon?"pt-7 text-2xl text-slate-900 font-bold":"text-lg text-slate-500 font-bold"},get children(){return J.title}}),s(()=>s(()=>!!J.detail)()?D(x,{class:"pt-4 text-lg text-slate-500",get children(){return J.detail}}):null)]}})}function H2(J){let Q=()=>J.dark?J.tone==="danger"?"text-base text-red-300":"text-base text-slate-300":J.tone==="danger"?"text-base text-red-500":"text-base text-slate-500";return D(b,{get["class"](){return J.dark?"w-full h-full px-6 flex-row items-center bg-slate-950":"w-full h-full flex-row items-center"},get children(){return D(x,{get["class"](){return Q()},get children(){return J.text}})}})}var N0=4,V4=7,a=new M4("exa"),[P4,v0]=AJ([]),[R4,m0]=AJ("SEARCH HISTORY IS LOCAL"),Y0=-1;function j2(J){try{return JSON.parse(J)}catch{return null}}function B2(J){let Q=new Date(J*1000).toISOString();return Q.slice(0,10)+" · "+Q.slice(11,16)+" UTC"}function w4(J){if(Y0===J)return;try{let Q=a.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==N0){v0([]),m0("SEARCH HISTORY IS LOCAL");return}let $=a.query(` SELECT search.id,search.query,search.searched_at,search.status,search.result_count, result.title AS top_title,result.url AS top_url,search.error FROM searches search LEFT JOIN search_results result ON result.search_id=search.id AND result.rank=0 ORDER BY search.id DESC LIMIT 8 - `).all();E0($),N0($[0]?.status==="error"?String($[0].error||"EXA SEARCH FAILED").slice(0,80):$.length?"SEARCH HISTORY UPDATED FROM SQLITE":"SEARCH HISTORY IS LOCAL"),X0=J}catch{E0([]),N0("SEARCH HISTORY IS LOCAL")}}function q2(){let J=s.query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").all(),Q=new Set(J.map((L)=>L.name)),$=(L)=>Q.has(L)?Number(s.query(`SELECT COUNT(*) AS count FROM ${L}`).get()?.count??0):0,Z=Number(s.query("PRAGMA page_size").get()?.page_size??0),X=Number(s.query("PRAGMA page_count").get()?.page_count??0),W=Number(s.query("PRAGMA freelist_count").get()?.freelist_count??0),q=Number(s.query("PRAGMA user_version").get()?.user_version??0),G=Q.has("searches")?s.query(` + `).all();v0($),m0($[0]?.status==="error"?String($[0].error||"EXA SEARCH FAILED").slice(0,80):$.length?"SEARCH HISTORY UPDATED FROM SQLITE":"SEARCH HISTORY IS LOCAL"),Y0=J}catch{v0([]),m0("SEARCH HISTORY IS LOCAL")}}function F2(){let J=a.query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").all(),Q=new Set(J.map((L)=>L.name)),$=(L)=>Q.has(L)?Number(a.query(`SELECT COUNT(*) AS count FROM ${L}`).get()?.count??0):0,Z=Number(a.query("PRAGMA page_size").get()?.page_size??0),X=Number(a.query("PRAGMA page_count").get()?.page_count??0),W=Number(a.query("PRAGMA freelist_count").get()?.freelist_count??0),q=Number(a.query("PRAGMA user_version").get()?.user_version??0),G=Q.has("searches")?a.query(` SELECT id,searched_at,status,result_count,error FROM searches ORDER BY id DESC LIMIT 1 - `).get():null,M={searches:$("searches"),searchResults:$("search_results"),documents:$("documents")},U={database:"exa.sqlite",schemaVersion:q,expectedSchemaVersion:T0,retentionDays:K4,tableCounts:M,allocatedBytes:Z*X,reusableBytes:Z*W,latestSearch:G},V=G,H=V?` Latest #${V.id??"?"}: ${V.status??"unknown"}, ${V.result_count??0} results.`:" No searches yet.";return{text:`Exa storage (schema ${q}/${T0}): ${M.searches} searches, ${M.searchResults} results, ${M.documents} documents; ${K4}-day retention; ${U.allocatedBytes} bytes allocated (${U.reusableBytes} reusable).${H}`,details:U}}function z2(){return O(T,{class:"flex-col w-full h-full bg-slate-50",get children(){return[O(T,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[O(T,{class:"flex-row items-center gap-4",get children(){return[O(x,{class:"text-2xl text-white",children:"‹"}),O(T,{class:"flex-col",get children(){return[O(x,{class:"text-sm text-indigo-300 tracking-wide",children:"POCKET APP"}),O(x,{class:"text-2xl text-white font-bold",children:"Exa Research"})]}})]}}),O(T,{class:"px-3 py-2 bg-indigo-900",get children(){return O(x,{class:"text-sm text-indigo-200",children:"SQLITE HISTORY"})}})]}}),O(T,{class:"p-6 flex-col gap-3",get children(){return[O(x,{class:"text-sm text-indigo-700 font-bold",children:"AGENT RESEARCH MEMORY"}),O(x,{class:"text-2xl text-slate-950 font-bold",children:"Search history"}),O(x,{class:"text-base text-slate-600",children:"Every research.search call is saved here automatically."})]}}),O(T,{class:"grow px-6 pt-4 flex-col gap-3",get children(){return[O(E4,{get when(){return M4().length===0},get children(){return O(T,{class:"h-[430] px-12 flex-col items-center justify-center bg-white",get children(){return[O(T,{class:"w-[88] h-[88] items-center justify-center bg-indigo-100",get children(){return O(x,{class:"text-2xl text-indigo-700 font-bold",children:"E"})}}),O(x,{class:"pt-7 text-xl text-slate-900 font-bold",children:"No searches yet"}),O(x,{class:"pt-4 text-base text-slate-500",children:`Ask Pi Agent to research a topic. -The search and its results will appear here.`})]}})}}),O(T4,{get each(){return M4()},children:(J)=>O(T,{class:"h-[118] px-5 flex-row items-center justify-between bg-white",get children(){return[O(T,{class:"w-[500] flex-col gap-2",get children(){return[O(x,{class:"text-base text-slate-900 font-bold",get children(){return J.query.slice(0,72)}}),O(x,{class:"text-sm text-slate-500",get children(){return(J.top_title||J.error||"No result title").slice(0,92)}}),O(x,{class:"text-sm text-indigo-600 font-bold",get children(){return Y2(J.searched_at)}})]}}),O(T,{get["class"](){return J.status==="ok"?"px-3 py-2 bg-emerald-100":"px-3 py-2 bg-red-100"},get children(){return O(x,{get["class"](){return J.status==="ok"?"text-sm text-emerald-700":"text-sm text-red-500"},get children(){return r6(()=>J.status==="ok")()?J.result_count+" RESULTS":"FAILED"}})}})]}})})]}}),O(T,{class:"h-[96] px-6 flex-row items-center bg-slate-950",get children(){return O(x,{class:"text-sm text-slate-300",get children(){return X2()}})}})]}})}U4(0),o8(()=>O(z2,{})),globalThis.PocketPiApp={tick(){return""},update(){return""},dataChanged(J){let Q=W2(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),X0):X0;return U4($),""},invokeTool(J){try{let Q=J==="research.storage_status"?q2():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:Q.text,details:Q.details,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Unknown Exa task: "+J,isError:!0})},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});return""}}})(); + `).get():null,M={searches:$("searches"),searchResults:$("search_results"),documents:$("documents")},U={database:"exa.sqlite",schemaVersion:q,expectedSchemaVersion:N0,retentionDays:V4,tableCounts:M,allocatedBytes:Z*X,reusableBytes:Z*W,latestSearch:G},V=G,H=V?` Latest #${V.id??"?"}: ${V.status??"unknown"}, ${V.result_count??0} results.`:" No searches yet.";return{text:`Exa storage (schema ${q}/${N0}): ${M.searches} searches, ${M.searchResults} results, ${M.documents} documents; ${V4}-day retention; ${U.allocatedBytes} bytes allocated (${U.reusableBytes} reusable).${H}`,details:U}}function K2(){return D(b,{class:"flex-col w-full h-full bg-slate-50",get children(){return[D(q2,{title:"EXA RESEARCH",back:!0,metaTop:"POCKET APP",metaBottom:"SQLITE HISTORY"}),D(z2,{eyebrow:"AGENT RESEARCH MEMORY",title:"Search history",description:"Every research.search call is saved here automatically.",tone:"info"}),D(b,{class:"grow px-6 pt-4 flex-col gap-3",get children(){return[D(u4,{get when(){return P4().length===0},get children(){return D(G2,{icon:"E",title:"No searches yet",detail:`Ask Pi Agent to research a topic. +The search and its results will appear here.`,tone:"info"})}}),D(m4,{get each(){return P4()},children:(J)=>D(b,{class:"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[D(b,{class:"w-[474] flex-col gap-2",get children(){return[D(x,{class:"text-lg text-slate-900 font-bold",get children(){return J.query.slice(0,60)}}),D(x,{class:"text-base text-slate-500",get children(){return(J.top_title||J.error||"No result title").slice(0,76)}}),D(x,{class:"text-base text-indigo-600 font-bold",get children(){return B2(J.searched_at)}})]}}),D(b,{get["class"](){return s(()=>J.status==="ok")()?W0.success.surface:W0.danger.surface},get children(){return D(x,{get["class"](){return s(()=>J.status==="ok")()?W0.success.text:W0.danger.text},get children(){return s(()=>J.status==="ok")()?J.result_count+" RESULTS":"FAILED"}})}})]}})})]}}),D(b,{class:"h-[96]",get children(){return D(H2,{get text(){return R4()},get tone(){return R4().includes("FAILED")?"danger":"neutral"},dark:!0})}})]}})}w4(0),e8(()=>D(K2,{})),globalThis.PocketPiApp={tick(){return""},update(){return""},dataChanged(J){let Q=j2(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),Y0):Y0;return w4($),""},invokeTool(J){try{let Q=J==="research.storage_status"?F2():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:Q.text,details:Q.details,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Unknown Exa task: "+J,isError:!0})},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});return""}}})(); diff --git a/apps/exa/dist/app.pak b/apps/exa/dist/app.pak index b8e89aec43818bda46473aa8500e2382f1a24749..871ac16798ad7018c14d36fdf26b313dd2f96fe4 100644 GIT binary patch delta 39039 zcmd6Q3%Fawb?)BMwvV?T_#E%!7Z%4aka+~;1PF+yEeM1l2o8uh!Va&)+oDNHauQ^U z`l87JyrBbmqO`e?opK9SQ#a{VfZkrE(A-2MC0yMGf>GL2h*IFYsqWV%H~ao;&7M88 zB^!(b`8xK|Xs7uk?v`WVG6$T<{vCN=eKNY<7(R)M_L8H^LKC9@!-8F z>tnZD)&$_LEazP7fZxBNv1&=$`pB0oYn^^!U4H8gUw!cFY3tHIw5;_8d~xT5XRMPQ zYwjG&${X;HUVGftH{bM;Bi_CKo|g}@kMx(>6V{#=y0};s5cm&Uc(HuYyM(hG|2;#Yj4@Eo=-ws1OAOGHkcmdKK zj(9)hI0Es)DgZfr8AS$a!Wa_18}T9}cn@L^MI4EE9PpzMFGhSc;w6B;7x7X&AA@)q zDmoVNay(O$_eXpj;uR?Wc*GgRCm=om@DmYFAU+9kbtS%>j4!KDzy`#tQT0Z|Yk+G3 z@mjn;1@VD+J{9pnh~I}e3j|I>ybkf{hz~}a-jDbYygvi+p`g_V5Fdv3XCi(V;6=oT zqn@)6AAzQxjr!60{j3iHupaR_h~JG0Hz9rxo4wumSOA#2fKq z3*rJW{V?KF(1I%vpNjZO#P36V72?wnUyb;5q`wC7`|&)9_zc9?BK`mIxi2E=Cpek0SL2P;0ZeE!W!(u56@h%RTFw6tw#Q=y7K!uQ-t)MP4A+vhq z7@%y}O@K-z*A*LIuov%`In1t3g*D6Sgrqi9sE1|C4g2bm;&zy`a$#G8YC%721g)?e zkT`Pag(}3L(sbA=mD*vgFwvO;3TY^fQF653ZH9l=4UqC%lSQ$ZL8K|AaOB(O4M z!;WRuLSiEoiebaD8lg^OsTxK7EB1ZZf%n#?^to$2Zh z$)R|vvZ4Fh?S=hGQLmtmxK>~(gF%a88=!R9E{Fr#>DB&KE06VGTz01abbXO{?M~aN z%4(ZYi*sQIC{pVysF6bn#GVSF>9T#$IR@1T)aogUX2R}d7aUw6a1~=Pv+y!m=4iB1%9186DgDG;a_ak*vrneB7Le>?@=c>ZVh z{t%K24@1G4lu@2Gm~9}S3v>RgV6FJ;wHOW7pJdM#ubgDh9YHemSXMl<(q7{rQAs?6 zZ?geI$BL~}PKJ_L{jen-zd5}|jGX6;`Tu_BxcKxh?4^Et%Pm*7v}|*oUOU%lWt%3~ zmil40*N6T#f(JHkCwiyQ3H$x9W40#SEd{M&Hz$7lYHGEA{PG3<^Q*4iKC>$w1X;0i zYkIB7ZA~wnn=O%^o+_2{;)E;h%-muSfT@~6P!T8pEVYUfdGh0hyV4k7e%n5TdDB1# zUnhrYUke-J0}D{iKi-NGydR~;w$J>)fA!GWw&!2)?v-|J=jegyZ`)3$*~*9qx7lm# zyg&L!SAXkR^(tY9-LQ4t`4I)v1q%*T3nHqP{CKgU`jY2(3L&RmsLYx%kRLLMGDw*Q^ zx-QH@l|a)qs+#sWAFKt^Fb1d^9vZP2F5B9;s$Z8pMd?NympmH!3z#8mcv{+Mp+49cWxcKsph150ppDn82?B z3#+dZMf^>}hETjHtI3xtFh~ZqF_t!4wk6RUVIyA;rc5>jn^R7c5h32S61p`pSWuqbjHsq=&IAD=3m%~nm1gzmJ!a@E z`b~43GAp&^0_&{BgupRo{$udxghdnSN={R%^tI}&Jt>Q$?S>mi6 z`Mqn<8qI^Q1!7v6xXh0jL^TmCcY1exBA`JB*18b%d_e-F)9E|QTD1j5SX2JkS zvsSQ8YypC_tfj!)QE6l#k_gfGtU&Y-wjo`nY)Q=&WG(;nZyK8Ebn(i+rN*i(1%1so zm}D>$nEDQL7$E1G${8~V(ueWjhwqU&tV{vIDQXCY`xt8?N*gmGj4_l#YHP`?Q!Rs~ zfyY!i$HGMECa_ph#42Q3?t`UW>Z~xzp2P)7PCd1`WIIGhH$6+Ka|P3X`Igt0?X{-uCR8*tI2f z**@EsVB@>RVPADdt8S&6L@PtWZG!SN%9vwdo~Y2SXi~9yZ5oP-5QWAK8_Eku*?w2VV?WYF2Na;yo&J=2&u zY;{H`+nP7cmKW3iYA+F^FWPgq&-_%(|A^x``F<@U>Ps*mGsO&8c{Lh%TAFizhOAT0Y>gD|*Thq|r^l)ugbJc< zXdsN!9AeRD$r2XHh^8QnEaVxUTqdnYs;-DOYc)j>aA!B_;Qi>C0_MU{T;jiCJ|bTG zzP)%|IT++%IE_r@#@QO;F`8~e7|tWhx>^c|!p*5z31*>7qY(8qnV>b|xgs-V7BE{0hXgqzfjiq>wUJpGW>aVB~qp zlBF!QO_xEFQ7UQ;v=uoDL5@E3dk{9VS%^(0$HqeoV;*d11fCXA16a*x1GMOt{zP!5FC~R*eGfBKI{MC0{$D?jFwm)Tdl3T-e0T3+(1_{0; zlV`x-C+`5pKSREeuVqfQP!#f2sQm^fLmLw*z+b8tsKO}35{isbh_fOeD-WGB6RCAW zYeIiY%Q+MJyZ-qv{H^_wYRk|$$jqUy#e}UL4-%+N4ru_Pw=}IJ2&0weZVa|;uWH*t zNmEPPXIAU#u!o)j(+m~{2GBH!Y%ZV?V++fbx)e^qn8*r!L*YlD7CQJL@#xj*1@oz2 z3v2Bi|X&-@*I`-Zx5Rg+WX@FFv*C-geXfPS7mJ}c?*wTQzAZ90t7)W3u zCfQJlGIGm)Y_q!lOXAyA+IOwqB9p2IAo18wQsZLBPvD}Zk7J1&1H<(n6`2^PB`)UZ zXqIyjQ4qnXMBOoGDcm+d;D_I=#Ih$u`gzx_C)aeCBy!l$$F%6r-q4 zCe7@(2{Heq4Hv>RzG8@#G>7lSH?Yc+f>#wc9Yv%mItXU(SgU0E=cy0m>?wSURgj zKan*8c|EbI;yeK3IO3eiXf3MeP?p*tc_8;npSYXVb-2-JmfB0#bh5(0$ve`;R!Vw~zq*-#kJofsA|1^5?9xk-!|bqU-SgCMZe zAc&m^Mn-Yhv8f5sKH9lUJbin5w7O@FuRSE%s-bBG2auU1I<^N%Nz27~^h!r20?8wF z4PllbZPlOzfDDa~r#P9`_^MR)zpyZ3;8BwqZR5o2zNBk7>{jDPnt}|Tkt&=haUedY z0GGWAEN3~O85a^;rEI={b@XbZ|tRfu5@cWfIPalo-^?Sgr3PPWBuL>u}F$^l7Z-UQyLV1!gi< z*6xY1>(h1W$qzSmuYra#4C>V!?8?|mRo%ARo{SCGC>4aSB|bZ0XJDdo=oy0o_biG@ zSYi-QC_U9y?thY4INp@}L~>2sI>=sDTa1mQmcrR`*JhabM!_gzueXRW2D-h`QrqAb z5pmB=ws&wC$Xy{3b@#9-q|y*}+xE^K+6RJc@O!Atybr|npcpj!D6YNZ6K7- zzh~_fJPt?m1X}F(r}l`e?1hrJ=OKGsTzFJ^{u^5xyM24z!}ep!Dxjf3AsLOKzY);2 zveGxG(x4u`($I=!gP3|4^}3U^x??aD2@ZwW%t4;1uHSxk+%78r%{f&tm(=`_QyR4p zAeF?42}dXjqdG})6njQFb-p+!`c)e-ayD(`i$+F|>(f#~+=n7{Ms`f*pbu1qR6hni zEa@4ZGQhAdV%m-Q*u}2Dbq)~g&$l10g1<`Qk0|-GG$qh^( zFFgKB%99KO|bTgnJqX@wV`viC_-v~Ijjb^w# zd~JmS6*E!s3LTikNZ+hS!v>W=W#_|wTd5>cbC6cNiaj8NIypn=RYWF?p4h%|d)LlD zJA4j|&4VyT{hp#DMjcW`=u#y>OoM=$tF;05b*_`pTI3sp`Jl6*Y936@Yyg2ZqmC5o zi?(|;v7(`CkpjH|V8n1#3Uoj0Ilv4C0Pgvu`HOL#xE17AS&>Q?MYYIg;EJr&%6RRN zJwO=!K#8IyKGSwqiU-<`H~8`5sB;6f+KHllPRcDyu_H84lniQoBp?OJjPkqu1nVf< zEdqm-rqB}7vLR=wyJ=6w|-}1SD?`I3~aeQSdii>Cyhuy4dxVatf}R&m@NS#rd+AkX zn6OVyFZP>X9!Yn@N!l&5Hci`Ro)nm`_Krx;@qh7scS3EiF-kEu;fQ;VOs`lDVT3wJ zh9)bGv#)Yi`&Ya&K8me9iTAYO=VO?X%@iDJWKgWV zpbdG}APc)iv7sUXg3hMZo`>beI^JDJAJuNy!lGnH8}~HUbXbNA@rC&xias!@>%q*hUtc%m(snr;|A(TW6hG4sV1Jq%E1rWS9X z`O(?lG|HM*;|G;Ps~rgOm;w+8U2!3n8Uas^CsTDTA~Xt$$M3M$tjS93CrgH+f$^K8 zF-CT@Uthj#DX$4((*{*)1hKlD`Y;6jOx}hWf9zMyW7sSM3*9~_JcNXJp#8N1X^=P- zupzAoy%&R`0b6o{tXgskd8gu3;0hZ2Fsd_%nTL#s0xw;~$tcet78aHj!a6!ur$R|A zH9Yyg7F6%lcpQ_}E2^8yy+KP+=qxROpgPGmdsd=+Xi5|!0E>Hzebt1$xbd>|{wKnx zkinv3!(d0s*Z`J#!6jPO=&E5=6{tGosKd*FvB#WW!!4l)U6}#aRGB&+Tj()m@L|8k-!3L>b+)JGJ!bsi_ZSz)4g`qBEw7fe9_poD)w)0{vUsS;%Z z1kOn)LRP{_YfkEA&E=>9C1c?@vP_NM0@9}4&ixFzGln+?W&2{oEo@lV2io$MA2FD` zR24xP>-^1(i%lfaPGr7S-yRSLv*waseedX5_HZSUR>X^46GEyXs?%QiImBQBEaz}N~SWrjHej~;lvY_DJN6-|bt|bd9@Wf+l?E|!+*usBu>(``}@^%hTZ_P@P zCf6RV6pUPk0%0o!y21cqCgE?~usAlmJpXei?4U43y@*}6t>MJ zZoGt+a>bvmwby83CBH#=bZ1Y(a&JuuJG8yErVfU?#3lcU9y2k8Ze{%XPOsVzj4fNJ zX^N%*Lo?(eO4cSwmM4EuGa5wxd(yyNqYjTXR^mJbD##^B<^Sr-kHmA{MenMin1-o$ z+0g=o5(Fxs;K|bNCd~(gNpO^lADmTjMT9&$s*A20o0f{Yn4Hm(bh)h|OiZpRd3R#IhI|awP1Db5V>G zX5t1_VRB~ll#a9VFkxE7fYJ{6zNtNU<_As2J-Av{$u75{BUES|rZPW0+g?YQVuKeN zQ3==#40u{5r-eLtMGBN$cY+o~FkZ>Gj6xg38Lc&9v%h35^srmU+?y7cX@o$4CdF|m z?DfN%w3@khab5+7I_cEPdldyy2AWe;n{6p8F-MWThOw3e9#mCBYERRRpH187R(W$jj;h9vj%27Mk1a#SlV)AxjoaLK&dRL&hWa7D`)}cC2HMAqU+=Fo6uJk5P01 zjvREmsR02+@0e3VK(K|>SgmB7(5nVz2!uArvq%4s+m@pk84S$*$99g3C$0mxY<0#D zDF)q`m$*=3=cE|%?){>;{1%)Myy=#-_u<%$Ei>Q~95GM|T8b%XB4A0xK!ab=-sFKM z&=HWjDBpsUc~lu6iCl)npi$G%;FR6#_?18P{9mn`?|H6?)aPLzqiG`sO@k$&!Oi~3 z(=PCWcWwG2&ayWoHLENNgc{&Y(z%H_A0=cN z_HX~mnkB<8sR+U}<4nFwqB|$t=+21+xO3t#AyAa<@!%Oa8Mc;`JTO)#=3>r z_*8m{xc&09Oh~?waT_-boRnH>TmGh>jBlU$8%dO%7o3%fF`FG>HV;(Uv=iRxM?Z;C zaBDTIuZfV9s10^#qmz_fw{4o7$Rv_ECX>8XNO;oFl7s^EUs!q(VLNh_wFvj>q{U@t zrIuebC%Qyu-kV&aGiwi*=(q!y=*&`==!nP9a@OV56*=?va7E6%fh%(6MOWm^6S=cf zORLEnarA{auC)QwSdEKnHX>ewOHxS4_WnYg1$(#F@2Bxz-lnInY@so;uK3R0XMuNuv~y{M!bJ z{TV2gLYDTc8o__{LyKpzMI!REoe5GvSU7@k#2=bM-8ey1;Gvmcxh_p zf^%W0s!870WYk5bhzx2F&2wE-n7-;MKo1KD<@g>D)aa33teJyrfljwK8vc`8K2se$ zumz(nK|^`GFEmCjuh*+|rg4u?+!~yLwouNLwu+{K03ez805t3cY%7gPLRoQRNw-&x z&0$$u8B^5$fGO3QZVnjRC}>i58ZB#4WxDfQnD78%TsBh-yFj{bmcxfL*P1N@3Z6l4 ziIGJ|O{T;P3$d>Hftw1@_)?rFLc!~4GF>NO0mu)pmbPk2m^{LNT!~rH>tT*p0narR1GlKl zDp-i%xifv|2`6&8U0FdkI_ZyIKtsgz!Onf6wmmgk#dKJowPg&Ny;8Pex)UsNK<1^( zSK?^((7IZpF}N0p3|Ax2DsfB^hT~9O@@9o%cm-U1KwdYu3!0U2{xaqQ+50stKE}(r z@;;)bVKYx*U51X#7=}ZIW?&-M>v&@8cb%`UGq@;15?aJSm%c)ah%dd6T0>gmNW1DK zPWV!ST7oVF>1xBB9*I!8>m+1)C{xoET29m(EXEC|#k*3@e3E~Ox;P-^tROXQ#rH9B zR{9vcFNS7q1Cu}?mT);xw)PMnrKGJziPYIC`fmB(efg5A+hgYp1EP=N>N0vltP<`G zmc^LORj%w{H=Tg3JwphXjw_in$&G+9M&g0brZOME(=f(et@vaK#i6cjn2t+MGVIBXpz!OSXK1}pexeF&**IX*DSKKf&nUE~BB#{XPxjT=1 zF8w|`Rmh7!D8T=Ff5BcvANysXOM+e(A6eNb)-Dl5e7ayy#A%oBn7P@WmEkLPh)M?| z!_?q?DOP=uN>)?cb5-gV82`7@Ej|lWH59iR+phl`J5_YW&tFch)`R+8hm?{nLfXb) z!ET@AQ#^9HGm)zGsa>m=K|-lqBb1mH;_fyF$#(*YteeO3=$#v8G*0^uvF=pyR7*z5LVOC6RW=J z+yh=;Ud>Avc9aKEC2aK)L?o4!lqV0yT@pgs_X%?8zGd6HTw>Sv?Yfw|0%ta`fdFe9 z)buELy>7WQ8C@&KFtU)yaMlJ;nR{ozJVlz4k%qH+odNCZHjUG~NFvVt=kypR>jK;B zUft|u#04*<#=SB&OHt6Q7KpJgVMiEt=-wq>DLbPl zCdBJeubGg55j7#8Y3M)v@_uuf{H0E(loKmo#Z733znY@k$v#)*1x#}h$|JJ`L1Q~? z9T;L9B?C`Yf=N@u!v%|Ap0vr+O*w^xpjzVZ4uoegn{pPemxMP>o+h`aW{j?RT;G6W z%e>&~=Z{-q@8DKo@&?i^jyhnGqy)FIZj3D6HAHwydO;;Can5ENe#>de z2C}FQT_cy+HPP+kDlJ?Pq({c?7OBV#R_aI{X^h%|tW4-Bk(|F~$e>h#t{a`~n*Kn( zzO9oNPyfAh7_|2`-a%R=lyuW*k0(MfsPx^gIkTfWv{fF}==KJaOc^xiM7v3H;a;Q} zLWYd+M3@>*BA%(*w4eJk;tM~8wT~s)iVcr2wwY)!TD z*ozuNtjSA=sT$Kd8w@^D+;y$^3sR#-Lpl*yux6IyiX?azcU}!luJUa@BjkVc!G93z zFH4P$LtF=E5Jj=^`SisDw%7KVXZ^#jUO?+Qn6&B>SW!(q$uBQ1J8$3ZKwQ{Y%?-?~ zat*_)fV%M9GcU%$b2qWUpoA`#IH^xuKR9qR9Zh+|fy-(b);v%Tjxu}2P*PEWZe#Tw zBevN5bZTUgw#YDp<{&ox9C8C&hxT2Mh*$4$=8c%Iw$Hp?t!bf&%EalG0hoskT0^iY zEVK=z!^K1c!iy7;SS!*2n{rKIvWjc5te2c>b_Xsu0y91NFX?NrCUk-nf4=6nV^-bj zSKM+>^CK1%Nz6_5^Y{v)vMKC@mD@7R2?EIN9`r2=5VoYfKwN4L1(dGtzx(91;*M{o z7KtA{lU`)E#ohPXU$43)tmsbb>@J3*Mu0u%-3W&2C68s4J_)pzmkz5ODH`k&tQRr& zX_H==#*mTkw`f0m9tIgqktU?3MUq2VvV9f{4kS5$%Zuaa$ddRwT#bU^838gfFak7N6+{0Z$*`l8lzDOP+sm(&mte{uU{cL#L#Wu$7{JW!z< zXfd!*7s(KzDs)35h%rNoAc5vkSxzIq?~#cV>7=k#3jdm&p-{2&7Pu* zilf0wJt8&+mk0`Nc(aj!zBZ&aWk4sD_alCV`@5N1r5GU#dl2g-_;!t3hv_P)Ay;pF z2hLg4#kd3qcYdlM`v%ACV-Zj!?Zx}I71?8k(JULAK`M>aRHi}<2?ijSK^`iv8H5%ShLug5!2bhQh`=b*~q-bWT-UO|qTwT|}r{RTN>e*AS8k-0dG{ zi+EX!gf96EBT-D>2)1|C%gXZd!cwtt5pKEO`VIRF+`7^`(Yn0Y@;Q6S)vC*wDvX34 z4s`o|-R6ngCsJe}-!*j4rM!UGSRX0i3O3S3v4FxIz`b9NosaQ!AaXZ2Po-$F1fc{p)|a^a4RcVKS23Sr>5Vjx@M6-@7rv$E^VOIo zVuR`JgGfdy#f~Dywb&>Tp;Ebmhgm$m1Jx_a@<5{-8dbgT!njXTb+Kyb+h4un=s&5( zY#CSb8--jf{ghO>D;E)r>LdHYfLMJpcnZce6Lv>Hvv<>ACAUPU;LrcVM^qQ)`Y~@y zUd{FNjYAB{boEHgn#1duz7(XvT9u((C{5FFjR7qM2izcQV}k{PH*6@H_TO>Y~cO7YKFV&dbt_h3IjK}&{i<^E z(o+OI5<_@ulZV$JhFIhbhk1I50fPU-C38e6rG{9d9}u$|ki6W{Yd|dN>lCZ$ z=7fsc%o`|gK-^RV(vZY9AO$%$Ga&g%Hl9rgYJ!L)AX#EC4Y`yGu7NW(h#>TXEJ+BA ze=z_7N4GT6tnFxbYs8JjtDFAZSt9rp{#Ix88(Oy*Jk>a)ty?vTiLG0qcrG41b4nVu zb*pSpZQZJG=yPS=szmYN8T++j>sF|BWj%PtdTXDp+o2guU>t0T5dBvMn_CPgj|=NUf~B8^UStd9zc`j4W$f~aBTuKyGrEN8%wz-VH& zhYqH-t$_}Po|QsMEtegPs~$9gmO2zQH*pC6&3MA zmQE3TL3TIa1#WJsq0K_He_okx6@is9Y9w7#$ysz_Xh z54lusg-!pj@1MYJ7;-1ZLA0mQt;W8l_)94^%+w-M?3lu+$Iisadf*D=5~aaBkyse( z=aShBjzdOz4RX>iPO3nw^0Bvpfo>l=8ucm&!Gi99>kf;`5rM?$Rq4gzYq#;ik%_8Y zpaII#E`lR0!T_c*s}@>U?y&Q)C7q=Fo*V7!$XesqvS zIof%K-%5$B0vwyjhy_Ps)%Uggw^!M$K}r=v4@!uwuI&vkMhiWEWN$#*0|+kh5}eViyV}pdbC? zSK`LgoQ2ELJ;|ma3EGR1c*|+digomwyzge94LBU)0lI4*!I~pxK4LE%K@NCGvZDS1 zmh%7n1*}8t;|G-{j^CWVu{ylBsUYRVz|O_4(Sblq2+6?f2no>eJ|t^suhL1@@P?-H z(59#1jZqdhyCU#bs-?tRF$YH|(Dq2$U54FQ*kb%~@x=4?qS?g~At2m`aNX(Rhd{o4 z`tZbyKeET{qW{Fpbg$D$xi+}4mkS5?NH%cIZ34wCIvyO)|V%hav=aKF6>{V z<-HvFd@N2QdIkCJLwW^5ITgP%+nrDF11-fJK|ckAO_# zcR(v0v+pYbnAFqD2~-9JIgyp$t$d9xS2Cm&SL6lLC8bD_DkJS)1Ck3T55tSBkxUY zF`b@@s#sIRfd&BbJD=z;mx~2 z|4?G%lCj*2CI2$^;l-;Bc+H!-8X57!OH&s^pI-Eqy?Yt_6ieMRn&fr+^~n~ll8(_8 zY{J(Kh-{<5RjNh($vB$=89Xc-X_`|3`@p7*qT#nIm!>*KE{lHR54{$bOo-*g7GXcj zJ=BU#Kfv8~U!aE!`pOOIbv2(y8d;LDf!M`9w;P|ol(x;q_P^U}w zS)FE}PR-*nP^XPb)0po=3leqXg(ZBKtH8#lUn{tT)v2)*jzrXsw*w*`eE`4HarZ=O z1pDTGH&vJt_kBCPCRMD_isu@C-iH0ERMqYV3xb>B9ZItVb?l~S@yw_*h2B}GaK^c5 zY*}CXp8@5|c8{_g6%CRNH_O;G$La8+QF;fZgamT`56%MbGhd=0&%BF{@bKEP7Z)x`Y+fFAF@^sgk2D}jX9Epc)7menvs2}7guE(d`_E1Ny4<~Y&wjv&;B|M zr3&IOOz^#eT)Y=Ow^s!Xmm}F22M($gft_5~;Ei8qYe_l>-S%{)(-ZB<>Au`F5zva3 z$2aXnd$(k@tN^3aT>A*gF>ZTbkl6L8{Q@C9sN=f(q~o~ux2(_(+N*3@$8Dea?jFrT zV;UgMLUWIAWESdSMU7$F2c#hJMwR$XmtNn1??IY{2D3}E&~W${%0n4#Q+K2_coUHxR=_MGo=8y3}WuRRlcq3C9*D zLQVYe@YxH}6F0`&#Hb1mdm^iPPw_scQR?aDY5}uXV`CdxAFXnwYZ_5}CSAke+Lkhv3uPt!_2@@cOsR6@LB!$zE9;{qfY{ zuDPBYFPGpIp0r<{zpR=BK<- zkRGlNJ`;ywPk09ZIbOZWPx7 z&R`UCd);2Ledc@B93wo*pHr-pCBki<6-MqNa!6-F(zNOTELB_X7vUBHR$L~X1P+=m zj=QjToM8BZ-PFy%jg6{GpEmkdy0qn&!{Ov@LAml%!muxvTG=%g3#B)A+TV1{4X~R( zdZM5NZr!lecvGXX9E|svE)RG_aYPB{nEZ)5SDppewK45PYWzl3j5r<<8a*$WpPkTV z9n!n(c7%On8dto0_Z{tioSS~L?!TF6zBk=(y7RcLLsPoJqjsgh*lxpFa2j9zn%Ozx zyJ;N$H@FNp(9u$>(Lt2Q>n2Q7K$;1o7XX}rr<6JrP4@(Wv+?G)D3RNiXDtuVnQ%y$ zyw=8QV^^&FC4Sx)r+5yUY8eg>$}>510;1VU9swRZ)9o1s3uUUc^j>*-rj-SQ01{L- z3=avhIzh7NMN8|(`Bs?-hhnhi{`pIsg8#_u{rs=aUi5bUiQebwu-%7_Ik-D`&yZDa z>;2vl!WkT$qyzohr~iRLTJRtaQ`rnKR0qh>GMsZVWmrp=JceICD2hkc+N*^3qtw{; zng4x!8Fm*E>z}g3S`U1RZb9=2otUEw9ZgRkvSft4!(O^$W}SVItFPLKP{b9T(Ki(p zh5aHW-(tsie~ES{y=dpc?>pB3c5*RCT02hzXHKdPwp?(Kij<>V{lRTfcuQqxdh&M% zz;U0h*6>TgiD25g{Gx0QzXZt-dC%Nl(ODmWQ8v?|&XE-aD(^E4!2?fOKx5ag5I1`|Ov2}oRV&`FEe1eV^{xeH&fZre! zU4M1@Sx$WYmAb@-uD?2;4hfBl<(r%f#O0fuG5xU1A_p`4$T%gCvzFafO9={Hb(??(@R$ZcT~}&pNa1GsWr8I;+HGKXkIQ=cRz}FU7p) zoP)}z;_HTur&+K6+rNjWq+CyIw4FJKAKWNmgx-VdjXiof9=C0@XKi34_Sj;)f95~_DOB%A zzj1q#BDTzLBPME5OwGV<_7|UZ_McBM%4=}t!t7c*U`*Y63k|;Ia zIUl<~zq|W6XT|dW^KB#RU!3bEUQbkY)>ltGRlRd;)IO&`q@PpRVEy9p163IVZzxYx z!oZt}Lyq6W8zM)PXC&pIiWkK*&*8N2wr8Dn7c#TVDI|KCOa3nj2J&K7`TJ*gDXh`_ zd;jFG@WgC1n?AFrP;Wl5(G@Fx=&Y!|a^ZXyc|drUQ3Jo-at zVvcGKJ?&pr9F7J8b;-|4pk=S{Q<^&O#f?f=XxKKuWP`c)P{yo3CQ(;{FPqO#3v_$8 zJx=9q+vrxg*+iXfEZYxmB;~XrBEg#oH!Az(SH7aS3{R2+i7BWtvTA-BF{?Ip%zGqn SDc)h(XC_y?Wxhwb2>%~-tI@3h literal 317776 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 Ni2p~Cf+ev&{~t6+zOVoQ diff --git a/apps/pi-agent/app.tsx b/apps/pi-agent/app.tsx index 262cd47..027e7f3 100644 --- a/apps/pi-agent/app.tsx +++ b/apps/pi-agent/app.tsx @@ -2,14 +2,14 @@ import { batch, createSignal, For, Show } from "solid-js"; import { Text, View } from "@pocketjs/framework/components"; import { mount } from "@pocketjs/framework"; import { readFileSync, readdirSync, type DirEntry } from "@pocketjs/framework/fs"; -import { ActionButton, PocketHeader } from "../_shared/ui"; +import { ActionButton, PocketHeader, ScrollButtons } from "../_shared/ui"; import { wrapLines, wrapPreview } from "../_shared/text"; -const FONT_BODY = 2; -const FONT_CAPTION = 1; +const FONT_BODY = 3; +const FONT_CAPTION = 2; const CHAT_TEXT_WIDTH = 536; const READER_TEXT_WIDTH = 544; -const READER_PAGE_LINES = 46; +const READER_PAGE_LINES = 39; type Message = { role: string; text: string }; type Network = { ssid: string; rssiDbm: number; secured: boolean }; @@ -130,15 +130,6 @@ function Header(props: { title: string }) { ); } -function ScrollButtons(props: { top: string; bottom: string }) { - return ( - <> - UP - DN - - ); -} - function BottomBar() { return ( @@ -146,7 +137,7 @@ function BottomBar() { - {name.toUpperCase()} + {name.toUpperCase()} )} @@ -163,15 +154,15 @@ function ChatScreen() { - YOU + YOU - {wrapPreview(turn.user, FONT_BODY, CHAT_TEXT_WIDTH, 3)} + {wrapPreview(turn.user, FONT_BODY, CHAT_TEXT_WIDTH, 3)} - PI + PI - {wrapPreview(turn.assistant, FONT_BODY, CHAT_TEXT_WIDTH, 3)} + {wrapPreview(turn.assistant, FONT_BODY, CHAT_TEXT_WIDTH, 3)} )} - NEXT WAKE + NEXT WAKE {"NO WAKE SCHEDULED\n\nASK PI TO CREATE ONE WITH SCHEDULE.SET"} + {"NO WAKE SCHEDULED\n\nASK PI TO CREATE ONE WITH SCHEDULE.SET"} }> - + {String(schedule()?.name) + " " + String(schedule()?.next ?? "") + "\n\n" + String(schedule()?.prompt ?? "")} @@ -204,23 +195,23 @@ function FilesScreen() {
- {"/workspace" + (filePath() ? "/" + filePath() : "")} + {"/workspace" + (filePath() ? "/" + filePath() : "")} {(entry) => ( - {entry.kind === "dir" ? "D" : "F"} + {entry.kind === "dir" ? "D" : "F"} - {(entry.name + (entry.kind === "dir" ? "/" : "")).slice(0, 60)} - {entry.kind === "dir" ? "FOLDER" : formatSize(entry.size)} + {(entry.name + (entry.kind === "dir" ? "/" : "")).slice(0, 52)} + {entry.kind === "dir" ? "FOLDER" : formatSize(entry.size)} )} - {fileError() || "THIS DIRECTORY IS EMPTY"} + {fileError() || "THIS DIRECTORY IS EMPTY"} 8}>
- 2 INSTALLED APPS + 2 INSTALLED APPS R - RobinhoodPortfolio and positionsUPDATES EVERY 5 MINUTES + RobinhoodPortfolio and positionsUPDATES EVERY 5 MINUTES E - Exa ResearchAgent search historySTORED LOCALLY IN SQLITE + Exa ResearchAgent search historySTORED LOCALLY IN SQLITE - {"APP DATA STAYS ISOLATED.\nPI AGENT CAN USE EACH APP'S TOOLS."} + {"APP DATA STAYS ISOLATED.\nPI AGENT CAN USE EACH APP'S TOOLS."} @@ -273,22 +264,22 @@ function SettingsScreen() {
- WI-FI - {wifi().connectedSsid || "NOT CONNECTED"} - {detail()} + WI-FI + {wifi().connectedSsid || "NOT CONNECTED"} + {detail()} - {wifi().scanning ? "SCANNING" : "SCAN"} + {wifi().scanning ? "SCANNING" : "SCAN"} - AVAILABLE NETWORKS + AVAILABLE NETWORKS 0} fallback={ - {"NO NETWORK LIST YET\n\nTAP SCAN TO FIND WI-FI"} + {"NO NETWORK LIST YET\n\nTAP SCAN TO FIND WI-FI"} }> {(network) => ( - {network.ssid} - {String(network.rssiDbm) + " DBM " + (network.secured ? "LOCK" : "OPEN")} + {network.ssid} + {String(network.rssiDbm) + " DBM " + (network.secured ? "LOCK" : "OPEN")} )} @@ -298,13 +289,13 @@ function SettingsScreen() { /> - MODEL BACKEND - {projection().model ?? "UNKNOWN"} - {"FIRMWARE " + String(settings().firmwareVersion ?? "0.1.0") + " · WORKSPACE FREE " + String(settings().workspaceFree ?? "--")} + MODEL BACKEND + {projection().model ?? "UNKNOWN"} + {"FIRMWARE " + String(settings().firmwareVersion ?? "0.1.0") + " · WORKSPACE FREE " + String(settings().workspaceFree ?? "--")} - FORGET WI-FI - RESTART DEVICE + FORGET WI-FI + RESTART DEVICE @@ -323,23 +314,23 @@ function KeyboardScreen() { {display() || (purpose().type === "wifi" ? "ENTER NETWORK PASSWORD..." : "TYPE YOUR MESSAGE...")} - {String(input().length) + " / " + (purpose().type === "wifi" ? "63" : "256") + " CHARACTERS"}CLEAR + {String(input().length) + " / " + (purpose().type === "wifi" ? "63" : "256") + " CHARACTERS"}CLEAR {(row, rowIndex) => ( {(key) => ( {uppercase() ? key.toUpperCase() : key} )} - DEL + DEL )} - {keyboardMode() === "letters" ? "123" : "ABC"} - SPACE - {keyboardMode() === "letters" ? "SHIFT" : ". ?"} - {purpose().type === "wifi" ? "JOIN" : "SEND"} + {keyboardMode() === "letters" ? "123" : "ABC"} + SPACE + {keyboardMode() === "letters" ? "SHIFT" : ". ?"} + {purpose().type === "wifi" ? "JOIN" : "SEND"} - CLOSE KEYBOARD + CLOSE KEYBOARD ); } @@ -352,11 +343,11 @@ function ViewerScreen() {
- {current()?.path ?? "NO FILE OPEN"} + {current()?.path ?? "NO FILE OPEN"} - {lines().slice(offset(), offset() + 39).join("\n")} + {lines().slice(offset(), offset() + 39).join("\n")} - {"LINES " + String(offset() + 1) + "-" + String(Math.min(offset() + 39, lines().length)) + " / " + String(lines().length)} + {"LINES " + String(offset() + 1) + "-" + String(Math.min(offset() + 39, lines().length)) + " / " + String(lines().length)}
- {current()?.author ?? "PI"} - {lines().slice(readerOffset(), readerOffset() + READER_PAGE_LINES).join("\n")} + {current()?.author ?? "PI"} + {lines().slice(readerOffset(), readerOffset() + READER_PAGE_LINES).join("\n")} {var AJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return B1(this.context.count)},getNextContextId(){return B1(this.context.count++)}};function B1(J){let Q=String(J),$=Q.length-1;return AJ.context.id+($?String.fromCharCode(96+$):"")+Q}function j1(J){AJ.context=J}function Y6(){return{...AJ.context,id:AJ.getNextContextId(),count:0}}var z6=!1,W6=(J,Q)=>J===Q,S0=Symbol("solid-proxy"),G6=typeof Proxy==="function",H6=Symbol("solid-track"),KQ=Symbol("solid-dev-component"),nJ={equals:W6},K1=null,B6=V1,m=1,fJ=2,F1={owned:null,cleanups:null,context:null,owner:null},S=null,K=null,yJ=null,_J=null,b=null,C=null,T=null,tJ=0;function eJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?F1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>QJ(()=>$J(z)));S=z,b=null;try{return c(G,!0)}finally{b=$,S=Z}}function g(J,Q){Q=Q?Object.assign({},nJ,Q):nJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return R1($,q)};return[U1.bind($),Z]}function JJ(J,Q,$){let Z=D1(J,Q,!1,m);if(yJ&&K&&K.running)C.push(Z);else J0(Z)}function kJ(J,Q,$){$=$?Object.assign({},nJ,$):nJ;let Z=D1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,yJ&&K&&K.running)Z.tState=m,C.push(Z);else J0(Z);return U1.bind(Z)}function j6(J){return c(J,!1)}function QJ(J){if(!_J&&b===null)return J();let Q=b;b=null;try{if(_J)return _J.untrack(J);return J()}finally{b=Q}}function b0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function K6(J){if(K&&K.running)return J(),K.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(yJ||F6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[FQ,M1]=g(!1),F6;function U1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)J0(this);else{let Q=C;C=null,c(()=>Q0(this),!1),C=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function R1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw C=[],Error()},!1)}return Q}function J0(J){if(!J.fn)return;$J(J);let Q=tJ;if(P1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{c(()=>{K&&(K.running=!0),b=S=J,P1(J,J.tValue,Q),b=S=null},!1)})}function P1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=m,J.tOwned&&J.tOwned.forEach($J),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach($J),J.owned=null;return J.updatedAt=$+1,w0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)R1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function D1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(S===null);else if(S!==F1)if(K&&K.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(_J&&X.fn){let z=X.fn,[G,P]=g(void 0,{equals:!1}),D=_J.factory(z,P);b0(()=>D.dispose());let V,B=()=>K6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),K&&K.running){if(!V)V=_J.factory(z,B);return V.track(_)}return D.track(_)}}return X}function g0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===fJ)return Q0(J);if(J.suspense&&QJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===m)J0(J);else if((Q?J.tState:J.state)===fJ){let q=C;C=null,c(()=>Q0(J,$[0]),!1),C=q}}}function c(J,Q){if(C)return J();let $=!1;if(!Q)C=[];if(T)$=!0;else T=[];tJ++;try{let Z=J();return M6($),Z}catch(Z){if(!$)T=null;C=null,w0(Z)}}function M6(J){if(C){if(yJ&&K&&K.running)U6(C);else V1(C);C=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;T.push.apply(T,K.effects),Q=K.resolve;for(let X of T)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,c(()=>{for(let X of q)$J(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zB6($),!1);if(Q)Q()}function V1(J){for(let Q=0;Q{Z.delete($),c(()=>{K.running=!0,g0($)},!1),K&&(K.running=!1)})}}function Q0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)$J(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)O1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)$J(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function O1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return b0(()=>A1(X)),()=>{let P=J()||[],D=P.length,V,B;return P[H6],QJ(()=>{let N,h,a,HJ,LJ,M,j,H,L;if(D===0){if(z!==0)A1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[P6],q[0]=eJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=M&&H>=M&&Z[j]===P[H];j--,H--)a[H]=q[j],HJ[H]=X[j],G&&(LJ[H]=G[j]);N=new Map,h=Array(H+1);for(B=H;B>=M;B--)L=P[B],V=N.get(L),h[B]=V===void 0?-1:V,N.set(L,B);for(V=M;V<=j;V++)if(L=Z[V],B=N.get(L),B!==void 0&&B!==-1)a[B]=q[V],HJ[B]=X[V],G&&(LJ[B]=G[V]),B=h[B],N.set(L,B);else X[V]();for(B=M;BJ(Q||{}));return j1($),Z}}return QJ(()=>J(Q||{}))}function $0(){return!0}var O6={get(J,Q,$){if(Q===S0)return $;return J.get(Q)},has(J,Q){if(Q===S0)return!0;return J.has(Q)},set:$0,deleteProperty:$0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:$0,deleteProperty:$0}},ownKeys(J){return J.keys()}};function C0(J){return!(J=typeof J==="function"?J():J)?{}:J}function I6(){for(let J=0,Q=this.length;J=0;G--){let P=C0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in C0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:I6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var A6=(J)=>`Stale read from <${J}>.`;function SJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return kJ(D6(()=>J.each,J.children,Q||void 0))}function bJ(J){let Q=J.keyed,$=kJ(()=>J.when,void 0,void 0),Z=Q?$:kJ($,void 0,{equals:(q,X)=>!q===!X});return kJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?QJ(()=>X(Q?q:()=>{if(!QJ(Z))throw A6("Show");return $()})):X}return J.fallback},void 0,void 0)}var _6=(J)=>kJ(()=>J());function k6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(M,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(M,j,L,H);JJ((A)=>B(M,j(),A,H),L)}function B(M,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=h(M,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(M),H=j);else h(M,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=h(M,H,L);else if(k==="function")return JJ(()=>{let O=j();while(typeof O==="function")O=O();H=B(M,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return JJ(()=>H=B(M,O,H,L,!0)),()=>H;if(O.length===0){let TJ=h(M,H,L);if(I)return H=TJ}else if(Array.isArray(H))if(H.length===0)a(M,O,L);else N(M,H,O);else if(H==null||H==="")a(M,O);else N(M,I&&H||[P(M)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(M,H,L,j);h(M,H,null,j)}else if(H==null||H===""||!P(M))q(M,j);else HJ(M,j,P(M));H=j}return H}function _(M,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let jQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let TJ=G(O)===M;if(!k&&!I)TJ?HJ(M,A,O):q(M,A,H);else TJ&&X(M,O)}else k=!0}}else q(M,A,H);return[A]}function a(M,j,H){for(let L=0,A=j.length;LH.children=B(M,j.children,H.children));return JJ(()=>j.ref&&j.ref(M)),JJ(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(M,A,k,H[A]),H[A]=k}}),H}return{render(M,j){let H;return eJ((L)=>{H=L,V(j,M())}),H},insert:V,spread(M,j,H){if(typeof j==="function")JJ((L)=>LJ(M,j(),L,H));else LJ(M,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(M,j,H,L){return z(M,j,H,L),H},mergeProps:_1,effect:JJ,memo:_6,createComponent:L6,use(M,j,H){return QJ(()=>M(j,H))}}}function S6(J){let Q=k6(J);return Q.mergeProps=_1,Q}var k1=480,S1=272,BJ={view:0,text:1,image:2},b6=1,g6=-1,w6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},C6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},E6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},N6=1,MQ=2,UQ=1,RQ=2,PQ=131072,DQ=1,VQ=262144,LQ=1,OQ=1,IQ=1,AQ=2,_Q=4,kQ=8,SQ=16,bQ=1,gQ=2;function b1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var wQ=1,h6=1263551300,T6=1,f6=32,y6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},jJ=32896,CQ=0.016666666666666666;function g1(J){return J.__viewport??null}var E0=null;function x6(){return null}function w1(J,Q=x6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function v6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return w1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return w1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function m6(J){E0=J}function gJ(){if(!E0)throw Error("PocketJS: host not installed — call render() first");return E0}function E(){return gJ().ops}function u6(J){globalThis.frame=J}function l6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function p6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return b1($>>>16&255,$>>>8&255,$&255,255);return b1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function c6(J,Q){let $=C6[J];if(typeof Q==="string"){if($===U.color)return p6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var Z0=60,C1=[1,2,3,4,5,6,10,12,15,20,30,60],N0=Z0,ZJ=-1,d6=0,xJ=[];function i6(J){if(!Number.isFinite(J)||J<=0)return Z0;let Q=C1[0];for(let $ of C1)if(Math.abs($-J)Q.at<=ZJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>ZJ);for(let Q of J)Q.cb()}var h0=0.12,q0=jJ;function o6(J){q0=J===void 0?jJ:J&65535}function n6(){q0=jJ}function h1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function e6(){return h1(q0&255)}var T1=new Set,J8=0;function Q8(){T1.clear(),J8=0,n6()}function $8(J){for(let Q of[...T1])Q(J)}var KJ=null,f1=null;function Z8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function y1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){T0();let Q=KJ?KJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return f1.slice(Q.off,Q.off+Q.len)}var mJ=null,w=null,FJ=null,X0=0,MJ=[],y0=[],x0=[];function v1(J){if(mJ=J,w=null,FJ=null,X0=0,MJ.length=0,y0.length=0,x0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function X8(J,Q){J.onPress=Q??void 0}function Y8(J,Q){if(J.focusable=Q,c1(),!Q&&w===J)x(null)}function x(J){if(FJ&&FJ!==J)UJ(null);w=J,E().setFocus(J?J.id:0)}function UJ(J){if(FJ===J)return;let Q=E();if(FJ)Q.setActive?.(FJ.id,0);if(FJ=J,J)Q.setActive?.(J.id,1)}function v0(){return MJ.length>0?MJ[MJ.length-1]:mJ}function m0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function G8(){if(!w)return null;let J=v0();if(J&&!i(w,J))return null;for(let Q=y0.length-1;Q>=0;Q--){let $=y0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function H8(J){let Q=G8();if(!Q)return!1;let $=[];if(m0(Q.node,$),$.length===0){if(w)x(null);return!0}let Z=Q.columns,q=w?$.indexOf(w):-1;if(q<0)return x(m1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function B8(){if(!w)return null;let J=v0();if(J&&!i(w,J))return null;for(let Q=x0.length-1;Q>=0;Q--){let $=x0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function Y0(J){let Q=B8();if(Q&&Q.move(J))return;if(H8(J))return;W8(J)}function u1(){l1(w)}function l1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function z0(J){UJ(J)}function j8(J){x(J),l1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function u0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=u0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,p1=0;function c1(){p1++}var F8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],M8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function U8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=F8[Q]>>$&1,q=M8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function R8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):P8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(U8(),16,16,E6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function P8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&N6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function W0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=W0($[Z],Q);if(q)return q}return null}var G0=null;function d1(J){G0=J}function i1(J){let Q=MJ.length>0?MJ[MJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function s1(J,Q,$){return i1(a1(J,Q,$))}function a1(J,Q,$){if($!==void 0)return $===0?null:W0(G0??mJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return W0(G0??mJ,q(J,Q))}function D8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=g1(q);if(Z.vw=B?B.w:k1,Z.vh=B?B.h:S1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)R8(Z,q);let X=t6()*Z.speed,z=e6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=s6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=p1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=i1(W0(G0??mJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==w)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(UJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,UJ(null),B)u1()}}else if($&Z.button)UJ(null);return!0}function V8(J){let Q=J&~X0,$=X0&~J;if(X0=J,l&&D8(J,Q,$))return;if($&d.CIRCLE)UJ(null);if(Q===0)return;if(Q&d.DOWN)Y0("down");if(Q&d.RIGHT)Y0("right");if(Q&d.UP)Y0("up");if(Q&d.LEFT)Y0("left");if(Q&d.CIRCLE)UJ(w),u1()}var l0=null;function r1(J){l0=J}function wJ(){if(c1(),l0)l0()}function L8(J,Q){J.debugName=Q||void 0,wJ()}var qJ={id:b6,type:BJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},o1=Symbol.for("pocketjs.native-node"),p0=1,uJ=3,o=8,O8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function H0(J){return J.domAttrs??={}}function n1(J,Q){let $=J.domNodeType??(lJ(J)?uJ:p0),Z=$===uJ?B0(J.text??""):$===o?_8(J.domData??""):q4(J.domTag??K0(J));for(let q of Object.keys(J.domAttrs??{}))c0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)XJ(Z,n1(q,!0));return Z}function c0(J,Q,$){if(O8.has(Q)){EJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete H0(J)[Q];else H0(J)[Q]=$}function d0(J){if(J[o1]===!0)return J;return Object.defineProperty(J,o1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(lJ(J)?uJ:p0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else j0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else j0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(lJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(lJ(J))j0(J,Z);else if(E8(J),Z)XJ(J,B0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return Y4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??K0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===uJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??K0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){EJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===qJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return XJ(J,$),$},insertBefore($,Z){return XJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return XJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return n1(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){c0(J,$,Z)},removeAttribute($){c0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}d0(qJ);var i0=null;function I8(J){i0=J}var s0={unknownClass:0,unknownTexture:0},t1=new Map;function e1(J,Q){t1.set(J,Q)}var J4=new Map;function Q4(J,Q){J4.set(J,Q)}var CJ=new Set,A8=new Set;function $4(J){if(!J)return!1;if(A8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return d0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:p0,domTag:J})}function B0(J){let Q=E(),$=Q.createNode(BJ.text);return Q.setText($,J),d0({id:$,type:BJ.text,parent:null,children:[],text:J,domNodeType:uJ,domTag:"#text"})}function _8(J=""){let Q=B0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function j0(J,Q){E().replaceText(J.id,Q),J.text=Q,wJ()}function lJ(J){return J.type===BJ.text}function X4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function XJ(J,Q,$){let Z=E();if(X4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function pJ(J,Q){if(!Q)return;K8(Q),E().removeChild(J.id,Q.id),X4(Q),CJ.add(Q),wJ()}function k8(J){return J.parent??void 0}function S8(J){return J.children[0]}function Y4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function b8(J,Q){let $=E();if(wJ(),Q==null||Q===""){$.setStyle(J.id,g6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=i0?i0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);s0.unknownClass++;return}$.setStyle(J.id,Z)}function g8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=t1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);s0.unknownTexture++;return}$.setImage(J.id,Z)}function w8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=J4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);s0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function C8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=w6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,c6(G,P)),z=!0}if(z)wJ()}function EJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete H0(J)[Q];else H0(J)[Q]=$;switch(Q){case"class":return b8(J,$),$;case"onPress":case"on:press":return X8(J,$),$;case"src":return g8(J,$),$;case"sprite":return w8(J,$),$;case"style":return C8(J,$,Z),$;case"focusable":return Y8(J,!!$),$;case"debugName":return L8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${K0(J)}>`)}function E8(J){for(let Q of[...J.children])pJ(J,Q)}function K0(J){for(let Q of Object.keys(BJ))if(BJ[Q]===J.type)return Q;return String(J.type)}function N8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}EJ(J,Q,$,Z)}var h8=S6({createElement:q4,createTextNode:B0,replaceText:j0,isTextNode:lJ,setProperty:N8,insertNode(J,Q,$){XJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:k8,getFirstChild:S8,getNextSibling:Y4}),{render:T8,effect:EQ,memo:p,createComponent:Y,createElement:z4,insert:NQ,spread:f8,mergeProps:hQ,use:TQ}=h8,fQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},y8=null;function W4(J){y8=J}function x8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function G4(J,Q){let $=z4(J);return f8($,Q,!1),x8(Q.nodeRef,$),$}function F(J){return G4("view",J)}function R(J){return G4("text",J)}var yQ=new WeakMap,xQ=new WeakMap,v8={}!==null?Object.freeze({...{}}):Object.freeze({}),vQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:v8}),mQ=new Map,YJ=36000,a0=30,m8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(YJ),tapeAnalog:new Uint16Array(YJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-a0,saidHello:!1,hostCalls:0};function u8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-a0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)r1(()=>{W.treeDirty=!0}),r8();else r1(null);globalThis.__pocketDevtools=n8}function l8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)c8(),s8();let X=Q,z=$===void 0?jJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(YJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==jJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function j4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function K4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return j4(J.masks,0,Q)}function F4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return j4(J.analog??[],jJ,Q)}function M4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,f({t:"hello",app:W.app,host:o8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` -`))if(q.trim())d8(q)}}function d8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)f({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),r0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),r0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":U4();break;case"eval":{let Z=!0,q;try{q=F0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}f({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":f({t:"tape",tape:B4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}f({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())f({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else f({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=K4(Z),W.replayAnalog=Z.analog?F4(Z):null,W.replayTouch=Z.touch?M4(Z):null,W.replayAt=0;break}default:break}}function i8(){if(W.treeDirty&&W.frame-W.treeSentAt>=a0)U4();if(W.frame%m8===0)r0()}function s8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,f({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,f({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function r0(){f({t:"stats",frame:W.frame,nodes:D4(qJ),tapeLen:W.tapeLen,paused:W.paused})}function U4(){W.treeDirty=!1,W.treeSentAt=W.frame,f({t:"tree",frame:W.frame,root:P4(qJ)})}function a8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function o0(J,Q){if(Array.isArray(J)){for(let $ of J)o0($,Q);return}if(a8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)o0($,Q)}}function R4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)o0(Z,Q)}function P4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(R4(J,(q)=>{if(q.domNodeType===8)return;Z.push(P4(q))}),Z.length)Q.k=Z;return Q}function D4(J){let Q=1;return R4(J,($)=>{Q+=D4($)}),Q}function r8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{f({t:"log",level:$,args:q.map((X)=>F0(X))}),Z?.apply(Q,q)}}}function F0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?V4(X):JSON.stringify(V4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>F0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${F0(z,Q+1)}`).join(", ")}}`}function V4(J){return J.length>200?J.slice(0,199)+"…":J}function o8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var n8={get frame(){return W.frame},dumpTape:()=>B4(),replay:(J)=>{W.replayMasks=K4(J),W.replayAnalog=J.analog?F4(J):null,W.replayTouch=J.touch?M4(J):null,W.replayAt=0}},L4=new Map,n0=new Map;function O4(J){return J.trim().replace(/\s+/g," ")}function I4(J){return J.split(" ").sort().join(" ")}var A4=-1;function t8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=O4(Q);L4.set(Z,$);let q=I4(Z),X=n0.get(q);n0.set(q,X!==void 0&&X!==$?A4:$)}}function e8(J){let Q=O4(J),$=L4.get(Q);if($!==void 0)return $;let Z=n0.get(I4(Q));return Z===A4?void 0:Z}var t0=9,J2=(1<{let q=($&$2)!==0,X=q?e0:t0,z=q?Z2:J2;return Object.freeze({id:$>>>(q?q2:Q2)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Y2(){return M0}function z2(){M0=J1}var _4=8,zJ=8,W2=3,G2=8,H2=6,B2=0.5,s=1,cJ=2,Q1=4,RJ=8,NJ=[],k4=0,U0=0,WJ=Array.from({length:_4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(zJ),histY:new Int16Array(zJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function j2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function K2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=a1(Q,$,Z.fact);let G=Z.hit;if(G)return j2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=NJ[z];if(G.disposed)continue;if(k4>0&&!G.opts.allowWhenBlocked)continue;if(!K2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function U2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%zJ,J.histLenz||Z>z))q.flags[J.slot]|=cJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(cJ|Q1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??B2)*E1()));if(J.frames=0)NJ.splice($,1)},cancel(){if(!Q.disposed)g4(Q)},get panning(){for(let $ of WJ)if($.used&&Q.flags[$.slot]&RJ)return!0;return!1}}}function L2(J){let Q=V2(J);return b0(()=>Q.dispose()),Q}function w4(){NJ.length=0,k4=0,U0=0;for(let J of WJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function O2(){return L2({onDown:(J)=>{let Q=s1(J.x,J.y,J.hit);if(Q)z0(Q)},onTap:(J)=>{z0(null);let Q=s1(J.x,J.y,J.hit);if(Q)j8(Q)},onUp:()=>z0(null),onCancel:()=>z0(null)})}var I2=1,$1=new Map,R0=[];function A2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function _2(){I2=1,$1.clear(),R0=[]}function k2(){if(R0.length===0)return;let J=R0;R0=[];for(let{id:Q,result:$}of J){let Z=$1.get(Q);if(!Z)continue;$1.delete(Q),A2()?.({t:"delivery",frame:N1(),id:Q,kind:Z.kind}),Z.onResult($)}}var C4=new Set;function S2(){if(C4.size===0)return;for(let J of C4)J()}var b2={"text-lg text-orange-600 font-bold":0,"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":1,"w-[165] h-[76] items-center justify-center bg-orange-600":2,"w-[165] h-[76] items-center justify-center bg-slate-900":3,"text-sm text-white font-bold":4,"flex-col w-full h-full bg-slate-50":5,"h-[686] px-6 pt-7 flex-col gap-[22]":6,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":7,"h-[28] flex-row items-center gap-3":8,"w-[10] h-[10] rounded bg-orange-500":9,"text-sm text-orange-600 font-bold":10,"h-[76] pt-3 text-base text-slate-900":11,"h-[2] mx-1 my-4 bg-slate-100":12,"w-[10] h-[10] rounded bg-emerald-500":13,"text-sm text-emerald-700 font-bold":14,"h-[84] pt-3 text-base text-slate-900":15,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":16,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":17,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":18,"text-sm text-slate-600 font-bold":19,"pt-6 text-base text-slate-500":20,"pt-6 text-base text-slate-900 font-bold":21,"h-[146] px-6 pt-7 flex-col bg-slate-50":22,"h-[80]":23,"h-[1060] px-6 pt-5 flex-col":24,"h-[48] px-4 justify-center bg-slate-100":25,"text-sm text-slate-600":26,"pt-[10] flex-col gap-[12]":27,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":28,"w-[48] h-[48] items-center justify-center bg-blue-100":29,"w-[48] h-[48] items-center justify-center bg-emerald-100":30,"text-base text-blue-700 font-bold":31,"text-base text-emerald-700 font-bold":32,"w-[474] flex-col gap-2":33,"text-base text-slate-900 font-bold":34,"text-sm text-slate-500":35,"pt-20 pl-10 text-base text-slate-500":36,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":37,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":38,"h-[1060] px-6 pt-7 flex-col gap-4":39,"text-sm text-slate-500 font-bold":40,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":41,"flex-row items-center gap-5":42,"w-[68] h-[68] items-center justify-center bg-emerald-100":43,"text-xl text-emerald-700 font-bold":44,"flex-col gap-2":45,"text-lg text-slate-900 font-bold":46,"text-base text-slate-600":47,"text-2xl text-orange-600":48,"w-[68] h-[68] items-center justify-center bg-indigo-100":49,"text-xl text-indigo-700 font-bold":50,"mt-4 h-[112] px-6 justify-center bg-slate-100":51,"relative h-[154] px-5 pt-5 flex-col bg-white":52,"pt-3 text-base text-orange-600 font-bold":53,"pt-3 text-sm text-slate-500":54,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":55,"text-base text-white font-bold":56,"h-[40] pt-3 text-sm text-slate-500":57,"h-[470] flex-col gap-2":58,"h-[214] px-7 items-center justify-center bg-slate-100":59,"text-base text-slate-500 font-bold":60,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":61,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":62,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":63,"h-[160] px-5 pt-5 flex-col bg-white":64,"pt-3 text-base text-slate-900 font-bold":65,"pt-3 text-sm text-slate-600":66,"h-[108] pt-7 flex-row gap-4":67,"w-[316] h-[80] items-center justify-center bg-slate-100":68,"w-[340] h-[80] items-center justify-center bg-red-100":69,"text-base text-red-500 font-bold":70,"h-[1052] px-6 pt-5 flex-col":71,"h-[270] px-[22] pt-6 bg-white":72,"text-lg text-slate-900":73,"text-lg text-slate-400":74,"h-[86] px-1 flex-row items-center justify-between":75,"w-[132] h-[58] items-center justify-center bg-slate-300":76,"w-[132] h-[58] items-center justify-center bg-slate-100":77,"text-sm text-slate-900 font-bold":78,"h-[140] flex-row gap-2":79,"grow h-[120] items-center justify-center bg-slate-300":80,"grow h-[120] items-center justify-center bg-white":81,"text-xl text-slate-900 font-bold":82,"w-[104] h-[120] items-center justify-center bg-slate-300":83,"w-[104] h-[120] items-center justify-center bg-slate-100":84,"h-[176] flex-row gap-2":85,"w-[92] h-[156] items-center justify-center bg-slate-300":86,"w-[92] h-[156] items-center justify-center bg-slate-100":87,"w-[300] h-[156] items-center justify-center bg-slate-300":88,"w-[300] h-[156] items-center justify-center bg-slate-100":89,"w-[144] h-[156] items-center justify-center bg-slate-300":90,"w-[144] h-[156] items-center justify-center bg-slate-100":91,"w-[112] h-[156] items-center justify-center bg-emerald-700":92,"w-[112] h-[156] items-center justify-center bg-emerald-500":93,"text-sm text-slate-950 font-bold":94,"h-[108] px-6 py-3 flex-col bg-slate-50":95,"h-[84] items-center justify-center bg-slate-300":96,"h-[84] items-center justify-center bg-slate-100":97,"h-[1168] px-6 pt-5 flex-col":98,"h-[82] px-4 justify-center bg-white":99,"w-[584] h-[900] px-5 pt-5 bg-slate-950":100,"text-sm text-slate-200":101,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":102,"text-base text-orange-600 font-bold":103,"w-[584] h-[900] px-5 pt-5 bg-white":104,"text-sm text-slate-900":105,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":106,"absolute inset-0 z-50 flex-col items-center justify-center":107,"absolute inset-0 bg-slate-950":108,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":109,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":110,"flex-row flex-wrap":111,grow:112,"text-2xl text-white font-bold":113,"text-base text-slate-900":114,"px-6":115,"px-6 py-5":116,"gap-4":117,"w-[34] h-[34] rounded-lg bg-amber-400":118,"w-[34] h-[34] rounded-lg bg-red-500":119,"w-[34] h-[34] rounded-lg bg-slate-800":120,"w-[34] h-[34] rounded-lg bg-emerald-500":121,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":122,"flex-row items-center gap-4":123,"w-[34] text-2xl text-white font-bold":124,"w-[332] flex-col items-end gap-2":125,"text-sm text-slate-300 font-bold":126,"text-sm text-slate-400":127,"h-[40] px-1 flex-row items-center justify-between":128,"w-full h-full items-center justify-center rounded-xl bg-slate-200":129,"w-full h-full items-center justify-center rounded-xl bg-orange-600":130};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var g2="ui:styles",w2="ui:font.",E4="ui:img.",N4="ui:sprite.";function C2(){return globalThis.ui}function E2(J){if(J.__textures)return;for(let Q of f0(E4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)e1(Q.slice(E4.length),Z)}}function N2(J){if(J.__sprites)return;for(let Q of f0(N4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)Q4(Q.slice(N4.length),{handle:V,frames:G,cols:P,step:D})}}function h4(J){let Q=z4("view");return EJ(Q,"style",J,void 0),Q}var P0=null,D0=null;function h2(J,Q){if(!P0||!D0)return;EJ(P0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),EJ(D0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function T2(J,Q={}){let $=v6(Q.ops);if(m6($),I8(e8),Q.styles)t8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)e1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)Q4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)x1(Q.pak);if(q8()){for(let B of f0())if(B===g2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(w2))$.ops.loadFontAtlas?.(vJ(B))}}let q=g1($.ops),X=q?.w??k1,z=q?.h??S1,G=h4({width:X,height:z,overflow:u.Overflow.Hidden}),P=h4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});XJ(qJ,G),XJ(qJ,P),W4(P),P0=G,D0=P,v1(G),d1(qJ),Q8(),w4(),O2(),a6(),_2(),u8($.ops),u6(l8((B,_,N,h)=>{r6(),o6(_),X2(N,h),S2(),k2(),D2(),$8(B),V8(B),Z4()}));let D=T8(J,G),V=l6(h2);return()=>{V(),z2(),w4(),D(),v1(null),d1(null),W4(null),P0=null,D0=null;for(let B of qJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);Z4()}}function f2(J,Q={}){let $=Q.ops??C2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)x1(Q.pak);return E2($),N2($),T2(J,{ops:$,styles:Q.styles??b2,pak:Q.pak})}var y2="$b",x2=65536,T4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function u2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function f4(){let J=u2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function l2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,x2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=v2(z.data[y2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function p2(J,Q){let $=l2(f4(),J);return Q==="utf8"||Q==="utf-8"?m2($):$}function c2(J,Q){let $=f4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var d2={title:"text-2xl text-white font-bold",section:"text-sm text-slate-600 font-bold",body:"text-base text-slate-900",bodyStrong:"text-base text-slate-900 font-bold",caption:"text-sm text-slate-500"};function i2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(F,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(F,{class:"flex-row items-center gap-4",get children(){return[p(()=>p(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(F,{get["class"](){return Q()}})),Y(R,{get["class"](){return d2.title},get children(){return J.title}})]}}),Y(F,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-sm text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-sm text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function s2(J){return Y(F,{get["class"](){return J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":"w-full h-full items-center justify-center rounded-xl bg-orange-600"},get children(){return Y(R,{get["class"](){return J.disabled?"text-base text-slate-500 font-bold":"text-base text-white font-bold"},get children(){return J.label}})}})}var uQ="‘’“”–—…•",y4=new Map,x4=new Map;function V0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=y4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return y4.set($,q),q}function a2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=V0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function Z1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=x4.get(Z);if(q)return q;let X=[],z=V0(" ",Q);for(let G of J.split(` +`))if(q.trim())d8(q)}}function d8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)f({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),r0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),r0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":U4();break;case"eval":{let Z=!0,q;try{q=F0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}f({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":f({t:"tape",tape:B4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}f({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())f({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else f({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=K4(Z),W.replayAnalog=Z.analog?F4(Z):null,W.replayTouch=Z.touch?M4(Z):null,W.replayAt=0;break}default:break}}function i8(){if(W.treeDirty&&W.frame-W.treeSentAt>=a0)U4();if(W.frame%m8===0)r0()}function s8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,f({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,f({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function r0(){f({t:"stats",frame:W.frame,nodes:D4(qJ),tapeLen:W.tapeLen,paused:W.paused})}function U4(){W.treeDirty=!1,W.treeSentAt=W.frame,f({t:"tree",frame:W.frame,root:P4(qJ)})}function a8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function o0(J,Q){if(Array.isArray(J)){for(let $ of J)o0($,Q);return}if(a8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)o0($,Q)}}function R4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)o0(Z,Q)}function P4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(R4(J,(q)=>{if(q.domNodeType===8)return;Z.push(P4(q))}),Z.length)Q.k=Z;return Q}function D4(J){let Q=1;return R4(J,($)=>{Q+=D4($)}),Q}function r8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{f({t:"log",level:$,args:q.map((X)=>F0(X))}),Z?.apply(Q,q)}}}function F0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?V4(X):JSON.stringify(V4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>F0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${F0(z,Q+1)}`).join(", ")}}`}function V4(J){return J.length>200?J.slice(0,199)+"…":J}function o8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var n8={get frame(){return W.frame},dumpTape:()=>B4(),replay:(J)=>{W.replayMasks=K4(J),W.replayAnalog=J.analog?F4(J):null,W.replayTouch=J.touch?M4(J):null,W.replayAt=0}},L4=new Map,n0=new Map;function O4(J){return J.trim().replace(/\s+/g," ")}function I4(J){return J.split(" ").sort().join(" ")}var A4=-1;function t8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=O4(Q);L4.set(Z,$);let q=I4(Z),X=n0.get(q);n0.set(q,X!==void 0&&X!==$?A4:$)}}function e8(J){let Q=O4(J),$=L4.get(Q);if($!==void 0)return $;let Z=n0.get(I4(Q));return Z===A4?void 0:Z}var t0=9,J2=(1<{let q=($&$2)!==0,X=q?e0:t0,z=q?Z2:J2;return Object.freeze({id:$>>>(q?q2:Q2)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Y2(){return M0}function z2(){M0=J1}var _4=8,zJ=8,W2=3,G2=8,H2=6,B2=0.5,s=1,cJ=2,Q1=4,RJ=8,NJ=[],k4=0,U0=0,WJ=Array.from({length:_4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(zJ),histY:new Int16Array(zJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function j2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function K2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=a1(Q,$,Z.fact);let G=Z.hit;if(G)return j2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=NJ[z];if(G.disposed)continue;if(k4>0&&!G.opts.allowWhenBlocked)continue;if(!K2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function U2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%zJ,J.histLenz||Z>z))q.flags[J.slot]|=cJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(cJ|Q1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??B2)*E1()));if(J.frames=0)NJ.splice($,1)},cancel(){if(!Q.disposed)g4(Q)},get panning(){for(let $ of WJ)if($.used&&Q.flags[$.slot]&RJ)return!0;return!1}}}function L2(J){let Q=V2(J);return b0(()=>Q.dispose()),Q}function w4(){NJ.length=0,k4=0,U0=0;for(let J of WJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function O2(){return L2({onDown:(J)=>{let Q=s1(J.x,J.y,J.hit);if(Q)z0(Q)},onTap:(J)=>{z0(null);let Q=s1(J.x,J.y,J.hit);if(Q)j8(Q)},onUp:()=>z0(null),onCancel:()=>z0(null)})}var I2=1,$1=new Map,R0=[];function A2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function _2(){I2=1,$1.clear(),R0=[]}function k2(){if(R0.length===0)return;let J=R0;R0=[];for(let{id:Q,result:$}of J){let Z=$1.get(Q);if(!Z)continue;$1.delete(Q),A2()?.({t:"delivery",frame:N1(),id:Q,kind:Z.kind}),Z.onResult($)}}var C4=new Set;function S2(){if(C4.size===0)return;for(let J of C4)J()}var b2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[28] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-base text-orange-600 font-bold":9,"h-[76] pt-3 text-lg text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-base text-emerald-700 font-bold":13,"h-[84] pt-3 text-lg text-slate-900":14,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":15,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":16,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":17,"text-base text-slate-600 font-bold":18,"pt-6 text-lg text-slate-500":19,"pt-6 text-lg text-slate-900 font-bold":20,"h-[146] px-6 pt-7 flex-col bg-slate-50":21,"h-[80]":22,"h-[1060] px-6 pt-5 flex-col":23,"h-[48] px-4 justify-center bg-slate-100":24,"text-base text-slate-600":25,"pt-[10] flex-col gap-[12]":26,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":27,"w-[48] h-[48] items-center justify-center bg-blue-100":28,"w-[48] h-[48] items-center justify-center bg-emerald-100":29,"text-lg text-blue-700 font-bold":30,"text-lg text-emerald-700 font-bold":31,"w-[474] flex-col gap-2":32,"text-lg text-slate-900 font-bold":33,"text-base text-slate-500":34,"pt-20 pl-10 text-lg text-slate-500":35,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":36,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":37,"h-[1060] px-6 pt-7 flex-col gap-4":38,"text-base text-slate-500 font-bold":39,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":40,"flex-row items-center gap-5":41,"w-[68] h-[68] items-center justify-center bg-emerald-100":42,"text-xl text-emerald-700 font-bold":43,"flex-col gap-2":44,"text-xl text-slate-900 font-bold":45,"text-lg text-slate-600":46,"text-2xl text-orange-600":47,"w-[68] h-[68] items-center justify-center bg-indigo-100":48,"text-xl text-indigo-700 font-bold":49,"mt-4 h-[112] px-6 justify-center bg-slate-100":50,"relative h-[154] px-5 pt-5 flex-col bg-white":51,"pt-3 text-lg text-orange-600 font-bold":52,"pt-3 text-base text-slate-500":53,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":54,"text-lg text-white font-bold":55,"h-[40] pt-3 text-base text-slate-500":56,"h-[470] flex-col gap-2":57,"h-[214] px-7 items-center justify-center bg-slate-100":58,"text-lg text-slate-500 font-bold":59,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":60,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":61,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":62,"h-[160] px-5 pt-5 flex-col bg-white":63,"pt-3 text-lg text-slate-900 font-bold":64,"pt-3 text-base text-slate-600":65,"h-[108] pt-7 flex-row gap-4":66,"w-[316] h-[80] items-center justify-center bg-slate-100":67,"w-[340] h-[80] items-center justify-center bg-red-100":68,"text-lg text-red-500 font-bold":69,"h-[1052] px-6 pt-5 flex-col":70,"h-[270] px-[22] pt-6 bg-white":71,"text-lg text-slate-900":72,"text-lg text-slate-400":73,"h-[86] px-1 flex-row items-center justify-between":74,"w-[132] h-[58] items-center justify-center bg-slate-300":75,"w-[132] h-[58] items-center justify-center bg-slate-100":76,"text-base text-slate-900 font-bold":77,"h-[140] flex-row gap-2":78,"grow h-[120] items-center justify-center bg-slate-300":79,"grow h-[120] items-center justify-center bg-white":80,"w-[104] h-[120] items-center justify-center bg-slate-300":81,"w-[104] h-[120] items-center justify-center bg-slate-100":82,"h-[176] flex-row gap-2":83,"w-[92] h-[156] items-center justify-center bg-slate-300":84,"w-[92] h-[156] items-center justify-center bg-slate-100":85,"w-[300] h-[156] items-center justify-center bg-slate-300":86,"w-[300] h-[156] items-center justify-center bg-slate-100":87,"w-[144] h-[156] items-center justify-center bg-slate-300":88,"w-[144] h-[156] items-center justify-center bg-slate-100":89,"w-[112] h-[156] items-center justify-center bg-emerald-700":90,"w-[112] h-[156] items-center justify-center bg-emerald-500":91,"text-base text-slate-950 font-bold":92,"h-[108] px-6 py-3 flex-col bg-slate-50":93,"h-[84] items-center justify-center bg-slate-300":94,"h-[84] items-center justify-center bg-slate-100":95,"h-[1168] px-6 pt-5 flex-col":96,"h-[82] px-4 justify-center bg-white":97,"w-[584] h-[900] px-5 pt-5 bg-slate-950":98,"text-base text-slate-200":99,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":100,"text-lg text-orange-600 font-bold":101,"w-[584] h-[900] px-5 pt-5 bg-white":102,"text-base text-slate-900":103,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":104,"absolute inset-0 z-50 flex-col items-center justify-center":105,"absolute inset-0 bg-slate-950":106,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":107,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":108,"flex-row flex-wrap":109,grow:110,"text-2xl text-white font-bold":111,"text-2xl text-slate-950 font-bold":112,"px-6":113,"px-6 py-5":114,"gap-4":115,"rounded-xl shadow bg-white border-slate-100":116,"rounded-xl shadow bg-emerald-100 border-emerald-500":117,"bg-white":118,"bg-slate-100":119,"bg-slate-950":120,"px-3 py-2 rounded-lg bg-slate-100":121,"px-3 py-2 rounded-lg bg-indigo-100":122,"text-base text-indigo-700 font-bold":123,"px-3 py-2 rounded-lg bg-emerald-100":124,"px-3 py-2 rounded-lg bg-amber-100":125,"text-base text-amber-700 font-bold":126,"px-3 py-2 rounded-lg bg-red-100":127,"text-base text-red-500 font-bold":128,"w-[34] h-[34] rounded-lg bg-amber-400":129,"w-[34] h-[34] rounded-lg bg-red-500":130,"w-[34] h-[34] rounded-lg bg-slate-800":131,"w-[34] h-[34] rounded-lg bg-emerald-500":132,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":133,"flex-row items-center gap-4":134,"w-[34] text-2xl text-white font-bold":135,"w-[332] flex-col items-end gap-2":136,"text-base text-slate-300 font-bold":137,"text-base text-slate-400":138,"h-[166] px-6 pt-6 flex-col gap-3":139,"h-[44] px-1 flex-row items-center justify-between":140,"w-full h-full items-center justify-center rounded-xl bg-slate-200":141,"w-full h-full items-center justify-center rounded-xl bg-red-100":142,"w-full h-full items-center justify-center rounded-xl bg-slate-100":143,"w-full h-full items-center justify-center rounded-xl bg-orange-600":144,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":145,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":146,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":147,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":148,"text-2xl text-indigo-700 font-bold":149,"text-2xl text-slate-600 font-bold":150,"pt-7 text-2xl text-slate-900 font-bold":151,"pt-4 text-lg text-slate-500":152,"text-xl text-emerald-600 font-bold":153,"text-xl text-red-500 font-bold":154,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":155,"text-base text-red-300":156,"text-base text-slate-300":157,"text-base text-red-500":158,"w-full h-full px-6 flex-row items-center bg-slate-950":159,"w-full h-full flex-row items-center":160};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var g2="ui:styles",w2="ui:font.",E4="ui:img.",N4="ui:sprite.";function C2(){return globalThis.ui}function E2(J){if(J.__textures)return;for(let Q of f0(E4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)e1(Q.slice(E4.length),Z)}}function N2(J){if(J.__sprites)return;for(let Q of f0(N4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)Q4(Q.slice(N4.length),{handle:V,frames:G,cols:P,step:D})}}function h4(J){let Q=z4("view");return EJ(Q,"style",J,void 0),Q}var P0=null,D0=null;function h2(J,Q){if(!P0||!D0)return;EJ(P0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),EJ(D0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function T2(J,Q={}){let $=v6(Q.ops);if(m6($),I8(e8),Q.styles)t8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)e1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)Q4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)x1(Q.pak);if(q8()){for(let B of f0())if(B===g2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(w2))$.ops.loadFontAtlas?.(vJ(B))}}let q=g1($.ops),X=q?.w??k1,z=q?.h??S1,G=h4({width:X,height:z,overflow:u.Overflow.Hidden}),P=h4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});XJ(qJ,G),XJ(qJ,P),W4(P),P0=G,D0=P,v1(G),d1(qJ),Q8(),w4(),O2(),a6(),_2(),u8($.ops),u6(l8((B,_,N,h)=>{r6(),o6(_),X2(N,h),S2(),k2(),D2(),$8(B),V8(B),Z4()}));let D=T8(J,G),V=l6(h2);return()=>{V(),z2(),w4(),D(),v1(null),d1(null),W4(null),P0=null,D0=null;for(let B of qJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);Z4()}}function f2(J,Q={}){let $=Q.ops??C2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)x1(Q.pak);return E2($),N2($),T2(J,{ops:$,styles:Q.styles??b2,pak:Q.pak})}var y2="$b",x2=65536,T4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function u2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function f4(){let J=u2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function l2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,x2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=v2(z.data[y2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function p2(J,Q){let $=l2(f4(),J);return Q==="utf8"||Q==="utf-8"?m2($):$}function c2(J,Q){let $=f4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var d2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"};function i2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(F,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(F,{class:"flex-row items-center gap-4",get children(){return[p(()=>p(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(F,{get["class"](){return Q()}})),Y(R,{get["class"](){return d2.appTitle},get children(){return J.title}})]}}),Y(F,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function s2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(F,{get["class"](){return Q()},get children(){return Y(R,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(F,{get["class"](){return J.top},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(F,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var uQ="‘’“”–—…•",y4=new Map,x4=new Map;function V0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=y4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return y4.set($,q),q}function a2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=V0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function Z1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=x4.get(Z);if(q)return q;let X=[],z=V0(" ",Q);for(let G of J.split(` `)){let P=G.split(" ").flatMap((B)=>B&&V0(B,Q)>$?a2(B,Q,$):[B]),D="",V=0;for(let B of P){let _=V0(B,Q);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return x4.set(Z,X),X}function v4(J,Q,$,Z){let q=Z1(J,Q,$);if(q.length<=Z)return q.join(` `);let X=q.slice(0,Z);return X[Z-1]=X[Z-1].replace(/[\s.]+$/,"")+"…",X.join(` -`)}var m4=2,u4=1,l4=536,p4=544,c4=46,[PJ,r2]=g({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[y,n]=g("chat"),[L0,o2]=g("chat"),[q1,d4]=g(0),[t,i4]=g(""),[iJ,hJ]=g(0),[sJ,X1]=g([]),[n2,O0]=g(""),[s4,I0]=g(null),[a4,r4]=g(null),[A0,_0]=g(0),[v,e]=g(""),[DJ,o4]=g("letters"),[Y1,z1]=g(!1),[W1,n4]=g({type:"prompt"}),[GJ,t4]=g(null),[aJ,e4]=g(0),G1=new Map,J6=["qwertyuiop","asdfghjkl","zxcvbnm"],Q6=["1234567890","-/:;()$&@",`.,?!'"+`],$6=["chat","files","apps","settings"];function t2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function e2(J,Q){return J?J+"/"+Q:Q}function rJ(J=t(),Q=!1){let $=G1.get(J);if(!Q&&$){X1($),O0(""),hJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=c2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));G1.set(J,Z),X1(Z),O0(""),hJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){X1([]),O0(Z instanceof Error?Z.message:String(Z))}}function JQ(){let J=[];for(let Q of PJ().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Z6(){let J=JQ(),Q=Math.max(0,J.length-2),$=Math.min(q1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function VJ(J){return Y(i2,{get title(){return J.title},get accent(){return p(()=>PJ().agent==="FAULTED")()?"danger":PJ().agent==="THINKING"?"busy":"ready"}})}function oJ(J){return[Y(F,{get["class"](){return J.top},get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",children:"UP"})}}),Y(F,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",children:"DN"})}})]}function k0(){return Y(F,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(SJ,{each:$6,children:(J)=>Y(F,{get["class"](){return L0()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-sm text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function QQ(){let J=()=>PJ().schedule;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"ESP32 PI AGENT"}),Y(F,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(SJ,{get each(){return Z6()},children:(Q)=>Y(F,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-sm text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-base text-slate-900",get children(){return v4(Q.user,m4,l4,3)}}),Y(F,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-sm text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-base text-slate-900",get children(){return v4(Q.assistant,m4,l4,3)}})]}})}),Y(oJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(F,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-sm text-slate-600 font-bold",children:"NEXT WAKE"}),Y(bJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-base text-slate-500",children:`NO WAKE SCHEDULED +`)}var m4=3,u4=2,l4=536,p4=544,c4=39,[PJ,r2]=g({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[y,n]=g("chat"),[L0,o2]=g("chat"),[q1,d4]=g(0),[t,i4]=g(""),[sJ,hJ]=g(0),[aJ,X1]=g([]),[n2,O0]=g(""),[s4,I0]=g(null),[a4,r4]=g(null),[A0,_0]=g(0),[v,e]=g(""),[DJ,o4]=g("letters"),[Y1,z1]=g(!1),[W1,n4]=g({type:"prompt"}),[GJ,t4]=g(null),[rJ,e4]=g(0),G1=new Map,J6=["qwertyuiop","asdfghjkl","zxcvbnm"],Q6=["1234567890","-/:;()$&@",`.,?!'"+`],$6=["chat","files","apps","settings"];function t2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function e2(J,Q){return J?J+"/"+Q:Q}function oJ(J=t(),Q=!1){let $=G1.get(J);if(!Q&&$){X1($),O0(""),hJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=c2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));G1.set(J,Z),X1(Z),O0(""),hJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){X1([]),O0(Z instanceof Error?Z.message:String(Z))}}function JQ(){let J=[];for(let Q of PJ().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Z6(){let J=JQ(),Q=Math.max(0,J.length-2),$=Math.min(q1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function VJ(J){return Y(i2,{get title(){return J.title},get accent(){return p(()=>PJ().agent==="FAULTED")()?"danger":PJ().agent==="THINKING"?"busy":"ready"}})}function k0(){return Y(F,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(SJ,{each:$6,children:(J)=>Y(F,{get["class"](){return L0()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function QQ(){let J=()=>PJ().schedule;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"ESP32 PI AGENT"}),Y(F,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(SJ,{get each(){return Z6()},children:(Q)=>Y(F,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-base text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-lg text-slate-900",get children(){return v4(Q.user,m4,l4,3)}}),Y(F,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-base text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-lg text-slate-900",get children(){return v4(Q.assistant,m4,l4,3)}})]}})}),Y(iJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(F,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-base text-slate-600 font-bold",children:"NEXT WAKE"}),Y(bJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-lg text-slate-500",children:`NO WAKE SCHEDULED -ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(R,{class:"pt-6 text-base text-slate-900 font-bold",get children(){return String(J()?.name)+" "+String(J()?.next??"")+` +ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(R,{class:"pt-6 text-lg text-slate-900 font-bold",get children(){return String(J()?.name)+" "+String(J()?.next??"")+` -`+String(J()?.prompt??"")}})}})]}}),Y(F,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(F,{class:"h-[80]",get children(){return Y(s2,{label:"TYPE A MESSAGE"})}})}}),Y(k0,{})]}})}function $Q(){let J=()=>sJ().slice(iJ(),iJ()+8);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return t()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-600",get children(){return"/workspace"+(t()?"/"+t():"")}})}}),Y(F,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(SJ,{get each(){return J()},children:(Q)=>Y(F,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(F,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-base text-blue-700 font-bold":"text-base text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(F,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,60)}}),Y(R,{class:"text-sm text-slate-500",get children(){return p(()=>Q.kind==="dir")()?"FOLDER":t2(Q.size)}})]}})]}})})}}),Y(bJ,{get when(){return sJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-base text-slate-500",get children(){return n2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(bJ,{get when(){return sJ().length>8},get children(){return Y(oJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(k0,{})]}})}function ZQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"APPS"}),Y(F,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-sm text-slate-500 font-bold",children:"2 INSTALLED APPS"}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-emerald-100",get children(){return Y(R,{class:"text-xl text-emerald-700 font-bold",children:"R"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"Robinhood"}),Y(R,{class:"text-base text-slate-600",children:"Portfolio and positions"}),Y(R,{class:"text-sm text-slate-500",children:"UPDATES EVERY 5 MINUTES"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-indigo-100",get children(){return Y(R,{class:"text-xl text-indigo-700 font-bold",children:"E"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"Exa Research"}),Y(R,{class:"text-base text-slate-600",children:"Agent search history"}),Y(R,{class:"text-sm text-slate-500",children:"STORED LOCALLY IN SQLITE"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-sm text-slate-600",children:`APP DATA STAYS ISOLATED. -PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(k0,{})]}})}function qQ(){let J=()=>PJ().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(aJ(),aJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"SETTINGS"}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-base text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-sm text-slate-500",get children(){return Z()}}),Y(F,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-sm text-slate-500",children:"AVAILABLE NETWORKS"}),Y(F,{class:"h-[470] flex-col gap-2",get children(){return[Y(bJ,{get when(){return $().length>0},get fallback(){return Y(F,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-500 font-bold",children:`NO NETWORK LIST YET +`+String(J()?.prompt??"")}})}})]}}),Y(F,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(F,{class:"h-[80]",get children(){return Y(s2,{label:"TYPE A MESSAGE"})}})}}),Y(k0,{})]}})}function $Q(){let J=()=>aJ().slice(sJ(),sJ()+8);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return t()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",get children(){return"/workspace"+(t()?"/"+t():"")}})}}),Y(F,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(SJ,{get each(){return J()},children:(Q)=>Y(F,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(F,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-lg text-blue-700 font-bold":"text-lg text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(F,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,52)}}),Y(R,{class:"text-base text-slate-500",get children(){return p(()=>Q.kind==="dir")()?"FOLDER":t2(Q.size)}})]}})]}})})}}),Y(bJ,{get when(){return aJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-lg text-slate-500",get children(){return n2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(bJ,{get when(){return aJ().length>8},get children(){return Y(iJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(k0,{})]}})}function ZQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"APPS"}),Y(F,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-base text-slate-500 font-bold",children:"2 INSTALLED APPS"}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-emerald-100",get children(){return Y(R,{class:"text-xl text-emerald-700 font-bold",children:"R"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Robinhood"}),Y(R,{class:"text-lg text-slate-600",children:"Portfolio and positions"}),Y(R,{class:"text-base text-slate-500",children:"UPDATES EVERY 5 MINUTES"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-indigo-100",get children(){return Y(R,{class:"text-xl text-indigo-700 font-bold",children:"E"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Exa Research"}),Y(R,{class:"text-lg text-slate-600",children:"Agent search history"}),Y(R,{class:"text-base text-slate-500",children:"STORED LOCALLY IN SQLITE"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",children:`APP DATA STAYS ISOLATED. +PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(k0,{})]}})}function qQ(){let J=()=>PJ().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(rJ(),rJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"SETTINGS"}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-lg text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return Z()}}),Y(F,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-lg text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-base text-slate-500",children:"AVAILABLE NETWORKS"}),Y(F,{class:"h-[470] flex-col gap-2",get children(){return[Y(bJ,{get when(){return $().length>0},get fallback(){return Y(F,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-500 font-bold",children:`NO NETWORK LIST YET -TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(SJ,{get each(){return $()},children:(q)=>Y(F,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-base text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-sm text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(bJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(oJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(F,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-sm text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-base text-slate-900 font-bold",get children(){return PJ().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-sm text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(F,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(F,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(F,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-base text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(k0,{})]}})}function XQ(){let J=()=>W1(),Q=()=>DJ()==="letters"?J6:Q6,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(F,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(F,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-sm text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(F,{get["class"](){return GJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(SJ,{get each(){return Q()},children:(Z,q)=>Y(F,{class:"h-[140] flex-row gap-2",get children(){return[Y(SJ,{get each(){return Z.split("")},children:(X)=>Y(F,{get["class"](){return GJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return p(()=>!!Y1())()?X.toUpperCase():X}})}})}),Y(bJ,{get when(){return q()===2},get children(){return Y(F,{get["class"](){return GJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(F,{class:"h-[176] flex-row gap-2",get children(){return[Y(F,{get["class"](){return GJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",get children(){return DJ()==="letters"?"123":"ABC"}})}}),Y(F,{get["class"](){return GJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"SPACE"})}}),Y(F,{get["class"](){return GJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",get children(){return DJ()==="letters"?"SHIFT":". ?"}})}}),Y(F,{get["class"](){return GJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(R,{class:"text-sm text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(F,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(F,{get["class"](){return GJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-sm text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function YQ(){let J=()=>s4(),Q=()=>(J()?.text??"").split(` -`),$=()=>J()?.lineOffset??0;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< FILE VIEWER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(R,{class:"text-sm text-slate-200",get children(){return Q().slice($(),$()+39).join(` -`)}})}}),Y(R,{class:"pt-3 text-sm text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(oJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function zQ(){let J=()=>a4(),Q=()=>Z1(J()?.text??"",u4,p4);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< MESSAGE READER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-base text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-sm text-slate-900",get children(){return Q().slice(A0(),A0()+c4).join(` -`)}})}}),Y(oJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function WQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return p(()=>y()==="chat")()?Y(QQ,{}):p(()=>y()==="files")()?Y($Q,{}):p(()=>y()==="apps")()?Y(ZQ,{}):p(()=>y()==="settings")()?Y(qQ,{}):p(()=>y()==="keyboard")()?Y(XQ,{}):p(()=>y()==="viewer")()?Y(YQ,{}):Y(zQ,{})}})}function GQ(J){j6(()=>{if(o2(J),n(J),J==="files")rJ()})}function q6(J,Q){let $=DJ()==="letters"?J6:Q6,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=q6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function BQ(J,Q){if(Q>=1164)return e(""),n(L0()),"";if(J>=548&&Q>=402&&Q<=482)return e(""),"";let $=q6(J,Q);if($){let Z=DJ()==="letters"&&Y1()?$.toUpperCase():$,q=W1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return e(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)o4(DJ()==="letters"?"numbers":"letters"),z1(!1);else if(J<=424){if(v())e(v()+" ")}else if(J<=576)if(DJ()==="letters")z1(!Y1());else e(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=W1();if(e(""),o4("letters"),z1(!1),n(L0()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}f2(()=>Y(WQ,{})),queueMicrotask(()=>rJ("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return r2(JSON.parse(J)),""},dataChanged(){if(G1.delete(t()),L0()==="files")rJ(t(),!0);return""},invokeTool(){return JSON.stringify({text:"Pi Agent has no App tools",isError:!0})},invokeTask(){return JSON.stringify({text:"Pi Agent has no App tasks",isError:!0})},pointerDown(J,Q){return t4(y()==="keyboard"?HQ(J,Q):null),""},pointerUp(){return t4(null),""},tap(J,Q){if(y()==="keyboard")return BQ(J,Q);if(y()==="viewer"){let $=s4();if(J<104&&Q<112)I0(null),n("files");else if($&&J>=620&&Q>=170&&Q<=340)I0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)I0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` -`).length-39),$.lineOffset+18)});return""}if(y()==="reader"){if(J<104&&Q<112)r4(null),_0(0),n("chat");else if(J>=620&&Q>=170&&Q<=340)_0(Math.max(0,A0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=Z1(a4()?.text??"",u4,p4).length;_0(Math.min(Math.max(0,$-c4),A0()+18))}return""}if(Q>=1172)return GQ($6[Math.min(3,Math.floor(J/180))]),"";if(y()==="chat"){if(J>=620&&Q>=140&&Q<=272)d4(q1()+2);else if(J>=620&&Q>=624&&Q<=756)d4(Math.max(0,q1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=Z6()[$];if(Z){let q=Q>=140+$*320+150;r4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),_0(0),n("reader")}}else if(Q>=1070&&Q<=1150)n4({type:"prompt"}),e(""),n("keyboard");return""}if(y()==="files"){if(J<104&&Q<112&&t()){let $=t().split("/");$.pop();let Z=$.join("/");i4(Z),hJ(0),rJ(Z)}else if(J>=620&&Q>=170&&Q<=340)hJ(Math.max(0,iJ()-4));else if(J>=620&&Q>=920&&Q<=1100)hJ(Math.min(Math.max(0,sJ().length-8),iJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=sJ()[iJ()+$];if(Z){let q=e2(t(),Z.name);if(Z.kind==="dir")i4(q),hJ(0),rJ(q);else try{I0({path:"/workspace/"+q,text:p2(q,"utf8"),lineOffset:0}),n("viewer")}catch(X){O0(X instanceof Error?X.message:String(X))}}}return""}if(y()==="apps"){if(Q>=162&&Q<324)return JSON.stringify({type:"navigate",app:"robinhood"});if(Q>=324&&Q<490)return JSON.stringify({type:"navigate",app:"exa"});return""}if(y()==="settings"){let $=PJ().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)e4(Math.max(0,aJ()-4));else if(J>=620&&Q>=650&&Q<=782)e4(Math.min(Math.max(0,$.length-5),aJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[aJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});n4({type:"wifi",ssid:q.ssid}),e(""),n("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); +TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(SJ,{get each(){return $()},children:(q)=>Y(F,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-base text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(bJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(iJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(F,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-lg text-slate-900 font-bold",get children(){return PJ().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-base text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(F,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(F,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(F,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-lg text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(k0,{})]}})}function XQ(){let J=()=>W1(),Q=()=>DJ()==="letters"?J6:Q6,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(F,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(F,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-base text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(F,{get["class"](){return GJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(SJ,{get each(){return Q()},children:(Z,q)=>Y(F,{class:"h-[140] flex-row gap-2",get children(){return[Y(SJ,{get each(){return Z.split("")},children:(X)=>Y(F,{get["class"](){return GJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return p(()=>!!Y1())()?X.toUpperCase():X}})}})}),Y(bJ,{get when(){return q()===2},get children(){return Y(F,{get["class"](){return GJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(F,{class:"h-[176] flex-row gap-2",get children(){return[Y(F,{get["class"](){return GJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"123":"ABC"}})}}),Y(F,{get["class"](){return GJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"SPACE"})}}),Y(F,{get["class"](){return GJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"SHIFT":". ?"}})}}),Y(F,{get["class"](){return GJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(R,{class:"text-base text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(F,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(F,{get["class"](){return GJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function YQ(){let J=()=>s4(),Q=()=>(J()?.text??"").split(` +`),$=()=>J()?.lineOffset??0;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< FILE VIEWER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(R,{class:"text-base text-slate-200",get children(){return Q().slice($(),$()+39).join(` +`)}})}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function zQ(){let J=()=>a4(),Q=()=>Z1(J()?.text??"",u4,p4);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< MESSAGE READER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-base text-slate-900",get children(){return Q().slice(A0(),A0()+c4).join(` +`)}})}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function WQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return p(()=>y()==="chat")()?Y(QQ,{}):p(()=>y()==="files")()?Y($Q,{}):p(()=>y()==="apps")()?Y(ZQ,{}):p(()=>y()==="settings")()?Y(qQ,{}):p(()=>y()==="keyboard")()?Y(XQ,{}):p(()=>y()==="viewer")()?Y(YQ,{}):Y(zQ,{})}})}function GQ(J){j6(()=>{if(o2(J),n(J),J==="files")oJ()})}function q6(J,Q){let $=DJ()==="letters"?J6:Q6,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=q6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function BQ(J,Q){if(Q>=1164)return e(""),n(L0()),"";if(J>=548&&Q>=402&&Q<=482)return e(""),"";let $=q6(J,Q);if($){let Z=DJ()==="letters"&&Y1()?$.toUpperCase():$,q=W1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return e(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)o4(DJ()==="letters"?"numbers":"letters"),z1(!1);else if(J<=424){if(v())e(v()+" ")}else if(J<=576)if(DJ()==="letters")z1(!Y1());else e(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=W1();if(e(""),o4("letters"),z1(!1),n(L0()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}f2(()=>Y(WQ,{})),queueMicrotask(()=>oJ("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return r2(JSON.parse(J)),""},dataChanged(){if(G1.delete(t()),L0()==="files")oJ(t(),!0);return""},invokeTool(){return JSON.stringify({text:"Pi Agent has no App tools",isError:!0})},invokeTask(){return JSON.stringify({text:"Pi Agent has no App tasks",isError:!0})},pointerDown(J,Q){return t4(y()==="keyboard"?HQ(J,Q):null),""},pointerUp(){return t4(null),""},tap(J,Q){if(y()==="keyboard")return BQ(J,Q);if(y()==="viewer"){let $=s4();if(J<104&&Q<112)I0(null),n("files");else if($&&J>=620&&Q>=170&&Q<=340)I0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)I0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` +`).length-39),$.lineOffset+18)});return""}if(y()==="reader"){if(J<104&&Q<112)r4(null),_0(0),n("chat");else if(J>=620&&Q>=170&&Q<=340)_0(Math.max(0,A0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=Z1(a4()?.text??"",u4,p4).length;_0(Math.min(Math.max(0,$-c4),A0()+18))}return""}if(Q>=1172)return GQ($6[Math.min(3,Math.floor(J/180))]),"";if(y()==="chat"){if(J>=620&&Q>=140&&Q<=272)d4(q1()+2);else if(J>=620&&Q>=624&&Q<=756)d4(Math.max(0,q1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=Z6()[$];if(Z){let q=Q>=140+$*320+150;r4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),_0(0),n("reader")}}else if(Q>=1070&&Q<=1150)n4({type:"prompt"}),e(""),n("keyboard");return""}if(y()==="files"){if(J<104&&Q<112&&t()){let $=t().split("/");$.pop();let Z=$.join("/");i4(Z),hJ(0),oJ(Z)}else if(J>=620&&Q>=170&&Q<=340)hJ(Math.max(0,sJ()-4));else if(J>=620&&Q>=920&&Q<=1100)hJ(Math.min(Math.max(0,aJ().length-8),sJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=aJ()[sJ()+$];if(Z){let q=e2(t(),Z.name);if(Z.kind==="dir")i4(q),hJ(0),oJ(q);else try{I0({path:"/workspace/"+q,text:p2(q,"utf8"),lineOffset:0}),n("viewer")}catch(X){O0(X instanceof Error?X.message:String(X))}}}return""}if(y()==="apps"){if(Q>=162&&Q<324)return JSON.stringify({type:"navigate",app:"robinhood"});if(Q>=324&&Q<490)return JSON.stringify({type:"navigate",app:"exa"});return""}if(y()==="settings"){let $=PJ().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)e4(Math.max(0,rJ()-4));else if(J>=620&&Q>=650&&Q<=782)e4(Math.min(Math.max(0,$.length-5),rJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[rJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});n4({type:"wifi",ssid:q.ssid}),e(""),n("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); diff --git a/apps/pi-agent/dist/app.pak b/apps/pi-agent/dist/app.pak index 1037dbbb1e3d3a3d1febb0a503f3feab87c52b6f..bb30f3716a40c9f9a1d5f13ebbf057e15bc3db55 100644 GIT binary patch delta 1459 zcmaJ=T}V_x6h3qB?ol_zpYt+?jLEcfL9E&6$p;o2HkO zy+!WQqYMBdX>6e}Pa~fkrDJwl0Tf@DO%(R#5ov%3V5ceLW&-7>1%qEok z8Px1%kVsh5-+bFMGW}A4Tt9JSsC={#kNSRfW=Q2Kg5M znMTB03pbpjMv{7G{MXQqeja4iAAW$|~XGTl*dvFbow{T0u-x|?~`jd|6KhC)N7 zVGHI}+tZ!Fz7>00r#cA0_cfxIMe$%GPNs=EnN6X8pG#<@>E#fcvOQD*D(`Q?V}$$M zgsC=_V!S1QS$u~d?{1T6sz{iigtPSlkw6w(^BE)#zU0TNOyTF7u{&0X#guZeT`nWM zgU19glQ*@I!&W_G$=VEmg1-!1mY;;pCDNRkFI)7932HjB-y=xXI#f#lkch zk|*1;b}|#t--;#7!53R`>K_V&UEy!qu#ynF+Hr~sU>$feSlNN685yrSahBWsn9C=+ za3g`{x^NFuf-&8AibW`xLghvCnjYNC?EJnTGrV>UW_~V)is%HIei-6j+z6G>+E;i4 zsP%v`4MOyZ`P<45ISU$wLSWE^*qSaoO&2O?x`7jXps$CT{}iHKy%I*cyZ67P+T`7> zLv5D2KK1JN*YZGwBIf7EqyEpFxmNY+!h$7fsi-KN#2@tFe4#9i$a)@*kze#AL-Egc z8;vI76OwB}kE6Aw#~b=dR6f7gixnzu!RLB$t4d0W#m*cSEkyQ>3#w$dAQ_M(1L5=p zN#f+0O_-H!!G4ff%_Svw8CzMgUKG5;F2OtO3P&WD28QsWM79n}T(;2^LPO(rqKQpd zMk7i~_V>JQK1|bBMu#G&AY=36lomR5`?))2urF7))tz8a8yxjZ%>V!Z delta 26141 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 diff --git a/apps/robinhood/app.tsx b/apps/robinhood/app.tsx index 019b31c..67b39b5 100644 --- a/apps/robinhood/app.tsx +++ b/apps/robinhood/app.tsx @@ -2,7 +2,7 @@ import { batch, createMemo, createSignal, For, Show } from "solid-js"; import { Text, View } from "@pocketjs/framework/components"; import { mount } from "@pocketjs/framework"; import { Database } from "@pocketjs/framework/db"; -import { ActionButton, PocketHeader, SectionHeading } from "../_shared/ui"; +import { ActionButton, EmptyState, MetricCard, PocketHeader, ScrollButtons, SectionHeading, statusBadge, StatusBar } from "../_shared/ui"; const DB_SCHEMA_VERSION = 4; const db = new Database("robinhood"); @@ -354,12 +354,7 @@ function Header(props: { title: string; metaBottom?: string }) { } function Metric(props: { label: string; value: string | null }) { - return ( - - {props.label} - {money(props.value)} - - ); + return ; } function SectionTitle(props: { title: string; detail?: string }) { @@ -373,7 +368,7 @@ function activityPreview(index: number): Activity { function CompactActivity(props: { index: number }) { const item = () => activityPreview(props.index); - return {item().title}{item().timestamp ? item().timestamp + " · " + item().detail : ""}{item().amount ? money(item().amount) : ""}; + return {item().title}{item().timestamp ? item().timestamp + " · " + item().detail : ""}{item().amount ? money(item().amount) : ""}; } function positionPreview(index: number): Position { @@ -383,7 +378,7 @@ function positionPreview(index: number): Position { function CompactPosition(props: { index: number }) { const item = () => positionPreview(props.index); - return {item().symbol}{item().quantity ? item().quantity + " SH" : ""}{item().averagePrice ? "AVG " + money(item().averagePrice) : ""}; + return {item().symbol}{item().quantity ? item().quantity + " SH" : ""}{item().averagePrice ? "AVG " + money(item().averagePrice) : ""}; } function Chart() { @@ -391,11 +386,11 @@ function Chart() { - {chartPoints().length < 2 ? "COLLECTING 5M VALUE HISTORY" : ""} - {(item) => } - {(item) => } + {chartPoints().length < 2 ? "COLLECTING 5M VALUE HISTORY" : ""} + {(item) => } + {(item) => } - {chartLabels()[0] || ""}{chartLabels()[1] || ""}{chartLabels()[2] || ""} + {chartLabels()[0] || ""}{chartLabels()[1] || ""}{chartLabels()[2] || ""} ); } @@ -406,28 +401,31 @@ function DashboardScreen() {
- ACCOUNT - {dashboard().account.label + (dashboard().account.suffix ? " ····" + dashboard().account.suffix + " " + (accounts().findIndex((item) => item.number === selectedAccount()) + 1) + "/" + accounts().length : "") + " ›"} + ACCOUNT + {dashboard().account.label + (dashboard().account.suffix ? " ····" + dashboard().account.suffix + " " + (accounts().findIndex((item) => item.number === selectedAccount()) + 1) + "/" + accounts().length : "") + " ›"} {money(dashboard().totalValue)} - {currentTrend().change + " (" + currentTrend().percent + ")"} + {currentTrend().change + " (" + currentTrend().percent + ")"} - 1D1W{span() === "day" ? "TODAY" : "PAST WEEK"} + 1D1W{span() === "day" ? "TODAY" : "PAST WEEK"} - {"REALIZED P&L"}{"EQUITIES / " + (span() === "day" ? "TODAY" : "WEEK")}= 0 ? "text-xl text-emerald-600 font-bold" : "text-xl text-red-500 font-bold"}>{money(span() === "day" ? dashboard().pnlDay : dashboard().pnlWeek)} - {status()} + {"REALIZED P&L"}{"EQUITIES / " + (span() === "day" ? "TODAY" : "WEEK")}= 0 ? "text-2xl text-emerald-600 font-bold" : "text-2xl text-red-500 font-bold"}>{money(span() === "day" ? dashboard().pnlDay : dashboard().pnlWeek)} + ); } function SideButtons() { - return <>UPDN; + return ; } function AccountsScreen() { @@ -438,8 +436,8 @@ function AccountsScreen() {
{(account) => ( - {account.label}{"····" + account.suffix} - {account.status}SELECTED + {account.label}{"····" + account.suffix} + {account.status}SELECTED )} @@ -453,12 +451,12 @@ function ActivityScreen() {
0} fallback={ - {dashboard().activityAvailable ? "NO ACTIVITY YET" : "ACTIVITY UNAVAILABLE"} + }>{(item) => ( - {item.title}{money(item.amount)} - {item.timestamp + " · " + item.detail} - {item.state} + {item.title}{money(item.amount)} + {item.timestamp + " · " + item.detail} + {item.state} )} @@ -472,11 +470,11 @@ function PositionsScreen() {
0} fallback={ - {dashboard().positionsAvailable ? "NO OPEN POSITIONS" : "POSITIONS UNAVAILABLE"} + }>{(item) => ( - {item.symbol}{item.quantity + " SH"} - {"AVERAGE COST " + money(item.averagePrice) + (item.marketValue ? " · VALUE " + money(item.marketValue) : "")} + {item.symbol}{item.quantity + " SH"} + {"AVERAGE COST " + money(item.averagePrice) + (item.marketValue ? " · VALUE " + money(item.marketValue) : "")} )} diff --git a/apps/robinhood/dist/app.js b/apps/robinhood/dist/app.js index 9a7c260..cf4507b 100644 --- a/apps/robinhood/dist/app.js +++ b/apps/robinhood/dist/app.js @@ -1,5 +1,5 @@ -(()=>{var _J={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return U1(this.context.count)},getNextContextId(){return U1(this.context.count++)}};function U1(J){let Q=String(J),$=Q.length-1;return _J.context.id+($?String.fromCharCode(96+$):"")+Q}function M1(J){_J.context=J}function H6(){return{..._J.context,id:_J.getNextContextId(),count:0}}var j6=!1,F6=(J,Q)=>J===Q,_0=Symbol("solid-proxy"),B6=typeof Proxy==="function",K6=Symbol("solid-track"),LQ=Symbol("solid-dev-component"),nJ={equals:F6},V1=null,U6=k1,p=1,EJ=2,P1={owned:null,cleanups:null,context:null,owner:null},S=null,B=null,bJ=null,AJ=null,f=null,h=null,N=null,oJ=0;function tJ(J,Q){let $=f,Z=S,X=J.length===0,W=Q===void 0?Z:Q,z=X?P1:{owned:null,cleanups:null,context:W?W.context:null,owner:W},F=X?J:()=>J(()=>WJ(()=>qJ(z)));S=z,f=null;try{return r(F,!0)}finally{f=$,S=Z}}function E(J,Q){Q=Q?Object.assign({},nJ,Q):nJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return O1($,X)};return[R1.bind($),Z]}function XJ(J,Q,$){let Z=I1(J,Q,!1,p);if(bJ&&B&&B.running)h.push(Z);else J0(Z)}function QJ(J,Q,$){$=$?Object.assign({},nJ,$):nJ;let Z=I1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,bJ&&B&&B.running)Z.tState=p,h.push(Z);else J0(Z);return R1.bind(Z)}function eJ(J){return r(J,!1)}function WJ(J){if(!AJ&&f===null)return J();let Q=f;f=null;try{if(AJ)return AJ.untrack(J);return J()}finally{f=Q}}function A0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function M6(J){if(B&&B.running)return J(),B.done;let Q=f,$=S;return Promise.resolve().then(()=>{f=Q,S=$;let Z;if(bJ||V6)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return r(J,!1),f=S=null,Z?Z.done:void 0})}var[IQ,D1]=E(!1),V6;function R1(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===p)J0(this);else{let Q=h;h=null,r(()=>Q0(this),!1),h=Q}if(f){let Q=this.observers;if(!Q||Q[Q.length-1]!==f){let $=Q?Q.length:0;if(!f.sources)f.sources=[this],f.sourceSlots=[$];else f.sources.push(this),f.sourceSlots.push($);if(!Q)this.observers=[f],this.observerSlots=[f.sources.length-1];else Q.push(f),this.observerSlots.push(f.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function O1(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)r(()=>{for(let X=0;X1e6)throw h=[],Error()},!1)}return Q}function J0(J){if(!J.fn)return;qJ(J);let Q=oJ;if(L1(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{r(()=>{B&&(B.running=!0),f=S=J,L1(J,J.tValue,Q),f=S=null},!1)})}function L1(J,Q,$){let Z,X=S,W=f;f=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(B&&B.running)J.tState=p,J.tOwned&&J.tOwned.forEach(qJ),J.tOwned=void 0;else J.state=p,J.owned&&J.owned.forEach(qJ),J.owned=null;return J.updatedAt=$+1,S0(z)}finally{f=W,S=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)O1(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function I1(J,Q,$,Z=p,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(S===null);else if(S!==P1)if(B&&B.running&&S.pure)if(!S.tOwned)S.tOwned=[W];else S.tOwned.push(W);else if(!S.owned)S.owned=[W];else S.owned.push(W);if(AJ&&W.fn){let z=W.fn,[F,P]=E(void 0,{equals:!1}),D=AJ.factory(z,P);A0(()=>D.dispose());let U,H=()=>M6(P).then(()=>{if(U)U.dispose(),U=void 0});W.fn=(w)=>{if(F(),B&&B.running){if(!U)U=AJ.factory(z,H);return U.track(w)}return D.track(w)}}return W}function w0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===EJ)return Q0(J);if(J.suspense&&WJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===p)J0(J);else if((Q?J.tState:J.state)===EJ){let X=h;h=null,r(()=>Q0(J,$[0]),!1),h=X}}}function r(J,Q){if(h)return J();let $=!1;if(!Q)h=[];if(N)$=!0;else N=[];oJ++;try{let Z=J();return P6($),Z}catch(Z){if(!$)N=null;h=null,S0(Z)}}function P6(J){if(h){if(bJ&&B&&B.running)D6(h);else k1(h);h=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;N.push.apply(N,B.effects),Q=B.resolve;for(let W of N)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,r(()=>{for(let W of X)qJ(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let z=0,F=W.owned.length;zU6($),!1);if(Q)Q()}function k1(J){for(let Q=0;Q{Z.delete($),r(()=>{B.running=!0,w0($)},!1),B&&(B.running=!1)})}}function Q0(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)qJ(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)A1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)qJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function A1(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return A0(()=>S1(W)),()=>{let P=J()||[],D=P.length,U,H;return P[K6],WJ(()=>{let C,g,A,s,a,K,j,G,V;if(D===0){if(z!==0)S1(W),W=[],Z=[],X=[],z=0,F&&(F=[]);if($.fallback)Z=[O6],X[0]=tJ((k)=>{return W[0]=k,$.fallback()}),z=1}else if(z===0){X=Array(D);for(H=0;H=K&&G>=K&&Z[j]===P[G];j--,G--)A[G]=X[j],s[G]=W[j],F&&(a[G]=F[j]);C=new Map,g=Array(G+1);for(H=G;H>=K;H--)V=P[H],U=C.get(V),g[H]=U===void 0?-1:U,C.set(V,H);for(U=K;U<=j;U++)if(V=Z[U],H=C.get(V),H!==void 0&&H!==-1)A[H]=X[U],s[H]=W[U],F&&(a[H]=F[U]),H=g[H],C.set(V,H);else W[U]();for(H=K;HJ(Q||{}));return M1($),Z}}return WJ(()=>J(Q||{}))}function $0(){return!0}var _6={get(J,Q,$){if(Q===_0)return $;return J.get(Q)},has(J,Q){if(Q===_0)return!0;return J.has(Q)},set:$0,deleteProperty:$0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:$0,deleteProperty:$0}},ownKeys(J){return J.keys()}};function y0(J){return!(J=typeof J==="function"?J():J)?{}:J}function A6(){for(let J=0,Q=this.length;J=0;F--){let P=y0(J[F])[z];if(P!==void 0)return P}},has(z){for(let F=J.length-1;F>=0;F--)if(z in y0(J[F]))return!0;return!1},keys(){let z=[];for(let F=0;F=0;z--){let F=J[z];if(!F)continue;let P=Object.getOwnPropertyNames(F);for(let D=P.length-1;D>=0;D--){let U=P[D];if(U==="__proto__"||U==="constructor")continue;let H=Object.getOwnPropertyDescriptor(F,U);if(!Z[U])Z[U]=H.get?{enumerable:!0,configurable:!0,get:A6.bind($[U]=[H.get.bind(F)])}:H.value!==void 0?H:void 0;else{let w=$[U];if(w){if(H.get)w.push(H.get.bind(F));else if(H.value!==void 0)w.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let z=W.length-1;z>=0;z--){let F=W[z],P=Z[F];if(P&&P.get)Object.defineProperty(X,F,P);else X[F]=P?P.value:void 0}return X}var w6=(J)=>`Stale read from <${J}>.`;function NJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return QJ(L6(()=>J.each,J.children,Q||void 0))}function Z0(J){let Q=J.keyed,$=QJ(()=>J.when,void 0,void 0),Z=Q?$:QJ($,void 0,{equals:(X,W)=>!X===!W});return QJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?WJ(()=>W(Q?X:()=>{if(!WJ(Z))throw w6("Show");return $()})):W}return J.fallback},void 0,void 0)}var S6=(J)=>QJ(()=>J());function y6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:z,getParentNode:F,getFirstChild:P,getNextSibling:D}){function U(K,j,G,V){if(G!==void 0&&!V)V=[];if(typeof j!=="function")return H(K,j,V,G);XJ((k)=>H(K,j(),k,G),V)}function H(K,j,G,V,k){while(typeof G==="function")G=G();if(j===G)return G;let _=typeof j,I=V!==void 0;if(_==="string"||_==="number"){if(_==="number")j=j.toString();if(I){let O=G[0];if(O&&$(O))Z(O,j);else O=Q(j);G=g(K,G,V,O)}else if(G!==""&&typeof G==="string")Z(P(K),G=j);else g(K,G,V,Q(j)),G=j}else if(j==null||_==="boolean")G=g(K,G,V);else if(_==="function")return XJ(()=>{let O=j();while(typeof O==="function")O=O();G=H(K,O,G,V)}),()=>G;else if(Array.isArray(j)){let O=[];if(w(O,j,k))return XJ(()=>G=H(K,O,G,V,!0)),()=>G;if(O.length===0){let hJ=g(K,G,V);if(I)return G=hJ}else if(Array.isArray(G))if(G.length===0)A(K,O,V);else C(K,G,O);else if(G==null||G==="")A(K,O);else C(K,I&&G||[P(K)],O);G=O}else{if(Array.isArray(G)){if(I)return G=g(K,G,V,j);g(K,G,null,j)}else if(G==null||G===""||!P(K))X(K,j);else s(K,j,P(K));G=j}return G}function w(K,j,G){let V=!1;for(let k=0,_=j.length;k<_;k++){let I=j[k],O;if(I==null||I===!0||I===!1);else if(Array.isArray(I))V=w(K,I)||V;else if((O=typeof I)==="string"||O==="number")K.push(Q(I));else if(O==="function")if(G){while(typeof I==="function")I=I();V=w(K,Array.isArray(I)?I:[I])||V}else K.push(I),V=!0;else K.push(I)}return V}function C(K,j,G){let V=G.length,k=j.length,_=V,I=0,O=0,hJ=D(j[k-1]),IJ=null;while(IJJ-O){let OQ=j[I];while(O=0;I--){let O=j[I];if(k!==O){let hJ=F(O)===K;if(!_&&!I)hJ?s(K,k,O):X(K,k,G);else hJ&&W(K,O)}else _=!0}}else X(K,k,G);return[k]}function A(K,j,G){for(let V=0,k=j.length;VG.children=H(K,j.children,G.children));return XJ(()=>j.ref&&j.ref(K)),XJ(()=>{for(let k in j){if(k==="children"||k==="ref")continue;let _=j[k];if(_===G[k])continue;z(K,k,_,G[k]),G[k]=_}}),G}return{render(K,j){let G;return tJ((V)=>{G=V,U(j,K())}),G},insert:U,spread(K,j,G){if(typeof j==="function")XJ((V)=>a(K,j(),V,G));else a(K,j,void 0,G)},createElement:J,createTextNode:Q,insertNode:X,setProp(K,j,G,V){return z(K,j,G,V),G},mergeProps:y1,effect:XJ,memo:S6,createComponent:k6,use(K,j,G){return WJ(()=>K(j,G))}}}function f6(J){let Q=y6(J);return Q.mergeProps=y1,Q}var f1=480,C1=272,KJ={view:0,text:1,image:2},C6=1,x6=-1,g6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},M={f32:0,color:1,int:2},h6={width:M.f32,height:M.f32,minW:M.f32,minH:M.f32,maxW:M.f32,maxH:M.f32,paddingT:M.f32,paddingR:M.f32,paddingB:M.f32,paddingL:M.f32,marginT:M.f32,marginR:M.f32,marginB:M.f32,marginL:M.f32,gap:M.f32,flexDir:M.int,justify:M.int,align:M.int,grow:M.f32,shrink:M.f32,basis:M.f32,flexWrap:M.int,posType:M.int,insetT:M.f32,insetR:M.f32,insetB:M.f32,insetL:M.f32,display:M.int,overflow:M.int,zIndex:M.int,hitPass:M.int,bgColor:M.color,gradFrom:M.color,gradTo:M.color,gradDir:M.int,radius:M.f32,opacity:M.f32,borderColor:M.color,borderWidth:M.f32,shadow:M.int,bevelOuterLight:M.color,bevelOuterDark:M.color,bevelInnerLight:M.color,bevelInnerDark:M.color,bevelWidth:M.f32,textColor:M.color,fontSlot:M.int,textAlign:M.int,lineHeight:M.f32,tracking:M.f32,translateX:M.f32,translateY:M.f32,scale:M.f32,rotate:M.f32,scaleX:M.f32,scaleY:M.f32,originX:M.f32,originY:M.f32,rotateX:M.f32,rotateY:M.f32,translateZ:M.f32,perspective:M.f32,arcStart:M.f32,arcSweep:M.f32,arcWidth:M.f32},c={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},E6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},b6=1,kQ=2,_Q=1,AQ=2,wQ=131072,SQ=1,yQ=262144,fQ=1,CQ=1,xQ=1,gQ=2,hQ=4,EQ=8,bQ=16,NQ=1,TQ=2;function x1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var vQ=1,N6=1263551300,T6=1,v6=32,m6=24,n={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},UJ=32896,mQ=0.016666666666666666;function g1(J){return J.__viewport??null}var f0=null;function l6(){return null}function h1(J,Q=l6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function u6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return h1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return h1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function p6(J){f0=J}function wJ(){if(!f0)throw Error("PocketJS: host not installed — call render() first");return f0}function b(){return wJ().ops}function c6(J){globalThis.frame=J}function d6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function i6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return x1($>>>16&255,$>>>8&255,$&255,255);return x1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function s6(J,Q){let $=h6[J];if(typeof Q==="string"){if($===M.color)return i6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===M.color||$===M.int)return Q>>>0;return Q}var X0=60,E1=[1,2,3,4,5,6,10,12,15,20,30,60],C0=X0,zJ=-1,a6=0,TJ=[];function r6(J){if(!Number.isFinite(J)||J<=0)return X0;let Q=E1[0];for(let $ of E1)if(Math.abs($-J)Q.at<=zJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;TJ=TJ.filter((Q)=>Q.at>zJ);for(let Q of J)Q.cb()}var x0=0.12,W0=UJ;function e6(J){W0=J===void 0?UJ:J&65535}function J8(){W0=UJ}function T1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function $8(){return T1(W0&255)}var v1=new Set,Z8=0;function X8(){v1.clear(),Z8=0,J8()}function W8(J){for(let Q of[...v1])Q(J)}var MJ=null,m1=null;function q8(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function l1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){g0();let Q=MJ?MJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return m1.slice(Q.off,Q.off+Q.len)}var mJ=null,x=null,VJ=null,q0=0,PJ=[],E0=[],b0=[];function p1(J){if(mJ=J,x=null,VJ=null,q0=0,PJ.length=0,E0.length=0,b0.length=0,d){if(d.pressTarget=null,d.target=null,d.spriteDirty=!0,d.fresh=!0,d.vw=0,d.tex>=0){let Q=b();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(d.tex),d.tex=-1}}}function Y8(J,Q){J.onPress=Q??void 0}function G8(J,Q){if(J.focusable=Q,a1(),!Q&&x===J)v(null)}function v(J){if(VJ&&VJ!==J)DJ(null);x=J,b().setFocus(J?J.id:0)}function DJ(J){if(VJ===J)return;let Q=b();if(VJ)Q.setActive?.(VJ.id,0);if(VJ=J,J)Q.setActive?.(J.id,1)}function N0(){return PJ.length>0?PJ[PJ.length-1]:mJ}function T0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;v($[X])}function F8(){if(!x)return null;let J=N0();if(J&&!o(x,J))return null;for(let Q=E0.length-1;Q>=0;Q--){let $=E0[Q];if(J&&!o($.node,J)&&!o(J,$.node))continue;if(o(x,$.node))return $}return null}function B8(J){let Q=F8();if(!Q)return!1;let $=[];if(T0(Q.node,$),$.length===0){if(x)v(null);return!0}let Z=Q.columns,X=x?$.indexOf(x):-1;if(X<0)return v(c1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)v($[W]);return!0}function K8(){if(!x)return null;let J=N0();if(J&&!o(x,J))return null;for(let Q=b0.length-1;Q>=0;Q--){let $=b0[Q];if(J&&!o($.node,J)&&!o(J,$.node))continue;if(o(x,$.node))return $}return null}function z0(J){let Q=K8();if(Q&&Q.move(J))return;if(B8(J))return;j8(J)}function d1(){i1(x)}function i1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){DJ(J)}function U8(J){v(J),i1(J)}function o(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function v0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=v0(Q.children[X]);if(W){v(W);return}}let Z=Q;while(Z){if(Z.focusable){v(Z);return}Z=Z.parent}}v(null)}var d=null,s1=0;function a1(){s1++}var V8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],P8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function D8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=V8[Q]>>$&1,X=P8[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,z=X?255:0;J[W]=z,J[W+1]=z,J[W+2]=z,J[W+3]=255}return J}function R8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=vJ($.image)}catch(z){if(wJ().strict)throw z;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):O8(Q,W),X<0&&wJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(D8(),16,16,E6.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function O8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&b6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function G0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=G0($[Z],Q);if(X)return X}return null}var H0=null;function r1(J){H0=J}function n1(J){let Q=PJ.length>0?PJ[PJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||o($,Q)))return $;$=$.parent}return null}function o1(J,Q,$){return n1(t1(J,Q,$))}function t1(J,Q,$){if($!==void 0)return $===0?null:G0(H0??mJ,$);let Z=b(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return G0(H0??mJ,X(J,Q))}function L8(J,Q,$){let Z=d,X=b();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=g1(X);if(Z.vw=H?H.w:f1,Z.vh=H?H.h:C1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)R8(Z,X);let W=Q8()*Z.speed,z=$8()*Z.speed;if(Z.dpadSpeed>0&&W===0&&z===0){if(J&n.LEFT)W=-Z.dpadSpeed;if(J&n.RIGHT)W=Z.dpadSpeed;if(J&n.UP)z=-Z.dpadSpeed;if(J&n.DOWN)z=Z.dpadSpeed}let F=Z.fresh;if(W!==0||z!==0){let H=n6()/60,w=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),C=Math.min(Math.max(Z.y+z*H,0),Z.vh-1);if(w!==Z.x||C!==Z.y)Z.x=w,Z.y=C,F=!0}if(F)X.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=s1;if(F||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=n1(G0(H0??mJ,X.hitTest(Z.x,Z.y)));let U=Z.target;if(U!==x)v(U);if(Q&Z.button&&U)Z.pressTarget=U;if(Z.pressTarget){if(DJ(U===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=U===Z.pressTarget;if(Z.pressTarget=null,DJ(null),H)d1()}}else if($&Z.button)DJ(null);return!0}function I8(J){let Q=J&~q0,$=q0&~J;if(q0=J,d&&L8(J,Q,$))return;if($&n.CIRCLE)DJ(null);if(Q===0)return;if(Q&n.DOWN)z0("down");if(Q&n.RIGHT)z0("right");if(Q&n.UP)z0("up");if(Q&n.LEFT)z0("left");if(Q&n.CIRCLE)DJ(x),d1()}var m0=null;function e1(J){m0=J}function SJ(){if(a1(),m0)m0()}function k8(J,Q){J.debugName=Q||void 0,SJ()}var YJ={id:C6,type:KJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},J4=Symbol.for("pocketjs.native-node"),l0=1,lJ=3,$J=8,_8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function j0(J){return J.domAttrs??={}}function Q4(J,Q){let $=J.domNodeType??(uJ(J)?lJ:l0),Z=$===lJ?F0(J.text??""):$===$J?S8(J.domData??""):Y4(J.domTag??K0(J));for(let X of Object.keys(J.domAttrs??{}))u0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)GJ(Z,Q4(X,!0));return Z}function u0(J,Q,$){if(_8.has(Q)){fJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete j0(J)[Q];else j0(J)[Q]=$}function p0(J){if(J[J4]===!0)return J;return Object.defineProperty(J,J4,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?lJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===$J?J.domData??"":J.text??""},set($){if(J.domNodeType===$J)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===$J?J.domData??"":J.text??""},set($){if(J.domNodeType===$J)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===$J)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===$J)J.domData=Z;else if(uJ(J))B0(J,Z);else if(E8(J),Z)GJ(J,F0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return H4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??K0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===lJ)return"#text";if(J.domNodeType===$J)return"#comment";return(J.domTag??K0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){fJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===YJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return GJ(J,$),$},insertBefore($,Z){return GJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return GJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return Q4(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){u0(J,$,Z)},removeAttribute($){u0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}p0(YJ);var c0=null;function A8(J){c0=J}var d0={unknownClass:0,unknownTexture:0},$4=new Map;function Z4(J,Q){$4.set(J,Q)}var X4=new Map;function W4(J,Q){X4.set(J,Q)}var yJ=new Set,w8=new Set;function q4(J){if(!J)return!1;if(w8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return p0({id:b().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function F0(J){let Q=b(),$=Q.createNode(KJ.text);return Q.setText($,J),p0({id:$,type:KJ.text,parent:null,children:[],text:J,domNodeType:lJ,domTag:"#text"})}function S8(J=""){let Q=F0("");return Q.domNodeType=$J,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){b().replaceText(J.id,Q),J.text=Q,SJ()}function uJ(J){return J.type===KJ.text}function G4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function GJ(J,Q,$){let Z=b();if(G4(Q),yJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,SJ()}function pJ(J,Q){if(!Q)return;M8(Q),b().removeChild(J.id,Q.id),G4(Q),yJ.add(Q),SJ()}function y8(J){return J.parent??void 0}function f8(J){return J.children[0]}function H4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function C8(J,Q){let $=b();if(SJ(),Q==null||Q===""){$.setStyle(J.id,x6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=c0?c0(Q):void 0;if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);d0.unknownClass++;return}$.setStyle(J.id,Z)}function x8(J,Q){let $=b();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=$4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);d0.unknownTexture++;return}$.setImage(J.id,Z)}function g8(J,Q){let $=b();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=X4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);d0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function h8(J,Q,$){let Z=b(),X=Q??{},W=$??{},z=!1;for(let F in X){let P=X[F];if(W[F]===P)continue;let D=g6[F];if(D===void 0)throw Error(`PocketJS: unknown style prop '${F}' (see spec PROP)`);Z.setProp(J.id,D,s6(F,P)),z=!0}if(z)SJ()}function fJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete j0(J)[Q];else j0(J)[Q]=$;switch(Q){case"class":return C8(J,$),$;case"onPress":case"on:press":return Y8(J,$),$;case"src":return x8(J,$),$;case"sprite":return g8(J,$),$;case"style":return h8(J,$,Z),$;case"focusable":return G8(J,!!$),$;case"debugName":return k8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${K0(J)}>`)}function E8(J){for(let Q of[...J.children])pJ(J,Q)}function K0(J){for(let Q of Object.keys(KJ))if(KJ[Q]===J.type)return Q;return String(J.type)}function b8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}fJ(J,Q,$,Z)}var N8=f6({createElement:Y4,createTextNode:F0,replaceText:B0,isTextNode:uJ,setProperty:b8,insertNode(J,Q,$){GJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:y8,getFirstChild:f8,getNextSibling:H4}),{render:T8,effect:lQ,memo:HJ,createComponent:q,createElement:j4,insert:uQ,spread:v8,mergeProps:pQ,use:cQ}=N8,dQ={linear:c.Easing.Linear,in:c.Easing.EaseIn,out:c.Easing.EaseOut,"in-out":c.Easing.EaseInOut,"out-back":c.Easing.OutBack,spring:c.Easing.Spring,"spring-bouncy":c.Easing.SpringBouncy},m8=null;function F4(J){m8=J}function l8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function B4(J,Q){let $=j4(J);return v8($,Q,!1),l8(Q.nodeRef,$),$}function R(J){return B4("view",J)}function L(J){return B4("text",J)}var iQ=new WeakMap,sQ=new WeakMap,u8={}!==null?Object.freeze({...{}}):Object.freeze({}),aQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:u8}),rQ=new Map,jJ=36000,i0=30,p8=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(jJ),tapeAnalog:new Uint16Array(jJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-i0,saidHello:!1,hostCalls:0};function c8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-i0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)e1(()=>{Y.treeDirty=!0}),t8();else e1(null);globalThis.__pocketDevtools=J2}function d8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)s8(),n8();let W=Q,z=$===void 0?UJ:$&65535,F=Z,P=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(jJ).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==UJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function M4(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,z]of J)Z.fill(W,X,Math.min(X+z,$)),X+=z;return Z}function V4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return M4(J.masks,0,Q)}function P4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return M4(J.analog??[],UJ,Q)}function D4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,T({t:"hello",app:Y.app,host:e8(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` -`))if(X.trim())a8(X)}}function a8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),s0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),s0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":R4();break;case"eval":{let Z=!0,X;try{X=U0((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}T({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":T({t:"tape",tape:U4()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}T({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=V4(Z),Y.replayAnalog=Z.analog?P4(Z):null,Y.replayTouch=Z.touch?D4(Z):null,Y.replayAt=0;break}default:break}}function r8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=i0)R4();if(Y.frame%p8===0)s0()}function n8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function s0(){T({t:"stats",frame:Y.frame,nodes:I4(YJ),tapeLen:Y.tapeLen,paused:Y.paused})}function R4(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,T({t:"tree",frame:Y.frame,root:L4(YJ)})}function o8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function a0(J,Q){if(Array.isArray(J)){for(let $ of J)a0($,Q);return}if(o8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)a0($,Q)}}function O4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)a0(Z,Q)}function L4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(O4(J,(X)=>{if(X.domNodeType===8)return;Z.push(L4(X))}),Z.length)Q.k=Z;return Q}function I4(J){let Q=1;return O4(J,($)=>{Q+=I4($)}),Q}function t8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{T({t:"log",level:$,args:X.map((W)=>U0(W))}),Z?.apply(Q,X)}}}function U0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?k4(W):JSON.stringify(k4(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((z)=>U0(z,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,z])=>`${W}: ${U0(z,Q+1)}`).join(", ")}}`}function k4(J){return J.length>200?J.slice(0,199)+"…":J}function e8(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var J2={get frame(){return Y.frame},dumpTape:()=>U4(),replay:(J)=>{Y.replayMasks=V4(J),Y.replayAnalog=J.analog?P4(J):null,Y.replayTouch=J.touch?D4(J):null,Y.replayAt=0}},_4=new Map,r0=new Map;function A4(J){return J.trim().replace(/\s+/g," ")}function w4(J){return J.split(" ").sort().join(" ")}var S4=-1;function Q2(J){for(let Q of Object.keys(J)){let $=J[Q],Z=A4(Q);_4.set(Z,$);let X=w4(Z),W=r0.get(X);r0.set(X,W!==void 0&&W!==$?S4:$)}}function $2(J){let Q=A4(J),$=_4.get(Q);if($!==void 0)return $;let Z=r0.get(w4(Q));return Z===S4?void 0:Z}var n0=9,Z2=(1<{let X=($&W2)!==0,W=X?o0:n0,z=X?q2:Z2;return Object.freeze({id:$>>>(X?z2:X2)&255,x:$&z,y:$>>>W&z,hit:Q?.[Z]})}))}function G2(){return M0}function H2(){M0=t0}var y4=8,FJ=8,j2=3,F2=8,B2=6,K2=0.5,t=1,cJ=2,e0=4,RJ=8,CJ=[],f4=0,V0=0,BJ=Array.from({length:y4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(FJ),histY:new Int16Array(FJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function U2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function M2(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=t1(Q,$,Z.fact);let F=Z.hit;if(F)return U2(F,W)}let z=X.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let F=CJ[z];if(F.disposed)continue;if(f4>0&&!F.opts.allowWhenBlocked)continue;if(!M2(F,$,Z,W))continue;F.flags[J.slot]=t,J.owners.push(F)}for(let z of J.owners)z.opts.onDown?.(J)}function D2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%FJ,J.histLenz||Z>z))X.flags[J.slot]|=cJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&t)||W&(cJ|e0))continue;if(!X.opts.onLongPress)continue;let z=Math.max(1,Math.round((X.opts.longPressSeconds??K2)*b1()));if(J.frames=0)CJ.splice($,1)},cancel(){if(!Q.disposed)g4(Q)},get panning(){for(let $ of BJ)if($.used&&Q.flags[$.slot]&RJ)return!0;return!1}}}function k2(J){let Q=I2(J);return A0(()=>Q.dispose()),Q}function h4(){CJ.length=0,f4=0,V0=0;for(let J of BJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function _2(){return k2({onDown:(J)=>{let Q=o1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=o1(J.x,J.y,J.hit);if(Q)U8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var A2=1,J1=new Map,P0=[];function w2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function S2(){A2=1,J1.clear(),P0=[]}function y2(){if(P0.length===0)return;let J=P0;P0=[];for(let{id:Q,result:$}of J){let Z=J1.get(Q);if(!Z)continue;J1.delete(Q),w2()?.({t:"delivery",frame:N1(),id:Q,kind:Z.kind}),Z.onResult($)}}var E4=new Set;function f2(){if(E4.size===0)return;for(let J of E4)J()}var C2={"w-[210] h-[104] px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":0,"text-sm text-slate-500 font-bold":1,"text-lg text-slate-900 font-bold":2,"h-[72] px-5 flex-row items-center justify-between":3,"w-[450] flex-col gap-2":4,"text-base text-slate-900 font-bold":5,"text-sm text-slate-500":6,"text-sm text-emerald-600 font-bold":7,"text-sm text-slate-900 font-bold":8,"h-[64] px-5 flex-row items-center":9,"w-[240] text-base text-slate-900 font-bold":10,"w-[156] text-sm text-slate-500":11,"relative w-[632] h-[196] flex-col":12,"relative w-[632] h-[160] overflow-hidden":13,"absolute w-[632] h-[2] bg-slate-200":14,"absolute text-sm text-slate-500 font-bold":15,"absolute rounded-lg bg-emerald-500":16,"absolute rounded-lg bg-red-500":17,"absolute w-[9] h-[9] rounded-lg bg-emerald-500":18,"absolute w-[9] h-[9] rounded-lg bg-red-500":19,"h-[36] px-1 flex-row items-center justify-between":20,"flex-col w-full h-full bg-slate-50":21,"h-[64] px-6 pt-2":22,"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":23,"h-[304] px-6 pt-3":24,"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100":25,"h-[64] flex-row items-end justify-between":26,"text-2xl text-slate-950 font-bold":27,"text-base text-emerald-600 font-bold":28,"text-base text-red-500 font-bold":29,"h-[60] px-6 pt-2 flex-row gap-3":30,"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":31,"w-[100] h-[44] items-center justify-center rounded-lg bg-white":32,"text-sm text-white font-bold":33,"pt-3 text-sm text-slate-500":34,"h-[126] px-6 pt-3 flex-row items-start gap-[21]":35,"h-[200] px-6 flex-col":36,"h-[150] flex-col rounded-xl shadow bg-white border-slate-100":37,"h-[184] px-6 flex-col":38,"h-[136] flex-col rounded-xl shadow bg-white border-slate-100":39,"h-[126] px-6 pt-2":40,"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":41,"flex-col gap-3":42,"text-xl text-emerald-600 font-bold":43,"text-xl text-red-500 font-bold":44,"h-[104] px-6 flex-row items-center justify-between":45,"w-[460] text-sm text-red-500":46,"w-[460] text-sm text-slate-500":47,"w-[176] h-[64]":48,"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":49,"text-sm text-orange-600 font-bold":50,"relative flex-col w-full h-full bg-slate-50":51,"px-6 pt-[14] flex-col gap-[12]":52,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":53,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":54,"flex-row items-center justify-between":55,"text-base text-slate-500 font-bold":56,"text-sm text-emerald-600":57,"px-6 pt-[14] flex-col gap-[14]":58,"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100":59,"text-base text-slate-500":60,"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100":61,"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":62,"flex-row items-center":63,"w-[170] text-lg text-slate-900 font-bold":64,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":65,"absolute inset-0 z-50 flex-col items-center justify-center":66,"absolute inset-0 bg-slate-950":67,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":68,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":69,"flex-row flex-wrap":70,grow:71,"text-2xl text-white font-bold":72,"text-sm text-slate-600 font-bold":73,"text-base text-slate-900":74,"px-6":75,"px-6 py-5":76,"gap-4":77,"w-[34] h-[34] rounded-lg bg-amber-400":78,"w-[34] h-[34] rounded-lg bg-red-500":79,"w-[34] h-[34] rounded-lg bg-slate-800":80,"w-[34] h-[34] rounded-lg bg-emerald-500":81,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":82,"flex-row items-center gap-4":83,"w-[34] text-2xl text-white font-bold":84,"w-[332] flex-col items-end gap-2":85,"text-sm text-slate-300 font-bold":86,"text-sm text-slate-400":87,"h-[40] px-1 flex-row items-center justify-between":88,"w-full h-full items-center justify-center rounded-xl bg-slate-200":89,"w-full h-full items-center justify-center rounded-xl bg-orange-600":90,"text-base text-white font-bold":91};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var x2="ui:styles",g2="ui:font.",b4="ui:img.",N4="ui:sprite.";function h2(){return globalThis.ui}function E2(J){if(J.__textures)return;for(let Q of h0(b4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)Z4(Q.slice(b4.length),Z)}}function b2(J){if(J.__sprites)return;for(let Q of h0(N4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),z=$[4],F=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),U=J.uploadTexture($.subarray(16),X,W,z);if(U>=0)W4(Q.slice(N4.length),{handle:U,frames:F,cols:P,step:D})}}function T4(J){let Q=j4("view");return fJ(Q,"style",J,void 0),Q}var D0=null,R0=null;function N2(J,Q){if(!D0||!R0)return;fJ(D0,"style",{width:J,height:Q,overflow:c.Overflow.Hidden},void 0),fJ(R0,"style",{width:J,height:Q,posType:c.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=b();$.__viewport={w:J,h:Q}}function T2(J,Q={}){let $=u6(Q.ops);if(p6($),A8($2),Q.styles)Q2(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let w in Z)Z4(w,Z[w]);let H=$.ops.__sprites;if(H)for(let w in H)W4(w,H[w])}if($.kind==="injected"||Z===void 0){if(Q.pak)u1(Q.pak);if(z8()){for(let H of h0())if(H===x2)$.ops.loadStyles?.(vJ(H));else if(H.startsWith(g2))$.ops.loadFontAtlas?.(vJ(H))}}let X=g1($.ops),W=X?.w??f1,z=X?.h??C1,F=T4({width:W,height:z,overflow:c.Overflow.Hidden}),P=T4({width:W,height:z,posType:c.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});GJ(YJ,F),GJ(YJ,P),F4(P),D0=F,R0=P,p1(F),r1(YJ),X8(),h4(),_2(),o6(),S2(),c8($.ops),c6(d8((H,w,C,g)=>{t6(),e6(w),Y2(C,g),f2(),y2(),L2(),W8(H),I8(H),z4()}));let D=T8(J,F),U=d6(N2);return()=>{U(),H2(),h4(),D(),p1(null),r1(null),F4(null),D0=null,R0=null;for(let H of YJ.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);z4()}}function v2(J,Q={}){let $=Q.ops??h2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)u1(Q.pak);return E2($),b2($),T2(J,{ops:$,styles:Q.styles??C2,pak:Q.pak})}var v4="$b",m2=9007199254740991,l2=":memory:",xJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function u2(J){let Q="";for(let $=0;$>2]+xJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2m2)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function d2(J){if(J!==null&&typeof J==="object")return p2(J[v4]);return J}function i2(J){if(Array.isArray(J))return JSON.stringify(J.map(m4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=m4(Z);return JSON.stringify(Q)}class Q1{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,i2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=l4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(d2))}run(...J){let Q=this.execute(l4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function l4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class u4{statements=new Map;txDepth=0;constructor(J=l2){let Q=c2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new Q1(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new Q1(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let z=J(...Q);return this.txDepth--,this.exec(X),z}catch(z){throw this.txDepth--,this.exec(W),z}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var s2={title:"text-2xl text-white font-bold",section:"text-sm text-slate-600 font-bold",body:"text-base text-slate-900",bodyStrong:"text-base text-slate-900 font-bold",caption:"text-sm text-slate-500"};function a2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return q(R,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[q(R,{class:"flex-row items-center gap-4",get children(){return[HJ(()=>HJ(()=>!!J.back)()?q(L,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):q(R,{get["class"](){return Q()}})),q(L,{get["class"](){return s2.title},get children(){return J.title}})]}}),q(R,{class:"w-[332] flex-col items-end gap-2",get children(){return[q(L,{class:"text-sm text-slate-300 font-bold",get children(){return J.metaTop??""}}),q(L,{class:"text-sm text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function r2(J){let Q=()=>J.action?J.detail?J.detail+" · VIEW ALL ›":"VIEW ALL ›":J.detail??"";return q(R,{class:"h-[40] px-1 flex-row items-center justify-between",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",get children(){return J.title}}),q(L,{class:"text-sm text-slate-500 font-bold",get children(){return Q()}})]}})}function n2(J){return q(R,{get["class"](){return J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":"w-full h-full items-center justify-center rounded-xl bg-orange-600"},get children(){return q(L,{get["class"](){return J.disabled?"text-base text-slate-500 font-bold":"text-base text-white font-bold"},get children(){return J.label}})}})}var p4=4,m=new u4("robinhood"),o2={number:"",label:"ACCOUNT",suffix:"",status:"WAITING FOR ROBINHOOD"},$1={title:"NO RECENT ACTIVITY",timestamp:"",detail:"",state:"",amount:"",side:""},t2={...$1,title:"ACTIVITY UNAVAILABLE"},e2={...$1,title:""},Z1={symbol:"NO OPEN POSITIONS",quantity:"",averagePrice:"",marketValue:""},JQ={...Z1,symbol:"POSITIONS UNAVAILABLE"},QQ={...Z1,symbol:""},iJ={account:o2,totalValue:null,cash:null,buyingPower:null,pnlDay:null,pnlWeek:null,positions:[],activity:[],positionsAvailable:!0,activityAvailable:!0,observedAt:null},[i,sJ]=E("dashboard"),[l,$Q]=E("day"),[gJ,X1]=E([]),[O0,L0]=E(""),[y,aJ]=E(iJ),[c4,OJ]=E([]),[ZQ,LJ]=E([]),[W1,q1]=E([]),[XQ,z1]=E({change:"$—",percent:"—",positive:!0}),[Y1,d4]=E(0),[i4,s4]=E(0),[a4,r4]=E(0),[n4,ZJ]=E("WAITING FOR ROBINHOOD"),[rJ,o4]=E(!1),u=0,t4=-1,e4=-1,J6=-1,G1=new Map,H1=new Map;function Q6(){return Math.floor(Date.now()/1000)}function WQ(J){try{return J?JSON.parse(J):null}catch{return null}}function qQ(){return m.query("SELECT account_number,label,suffix,status FROM accounts ORDER BY label,account_number LIMIT 16").all().map((Q)=>({number:Q.account_number,label:Q.label,suffix:Q.suffix,status:Q.status}))}function zQ(J,Q){if(e4===J)return;let $=m.query("SELECT account_number,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current LIMIT 16").all(),Z=m.query(` +(()=>{var _J={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return M1(this.context.count)},getNextContextId(){return M1(this.context.count++)}};function M1(J){let Q=String(J),$=Q.length-1;return _J.context.id+($?String.fromCharCode(96+$):"")+Q}function P1(J){_J.context=J}function B6(){return{..._J.context,id:_J.getNextContextId(),count:0}}var K6=!1,U6=(J,Q)=>J===Q,A0=Symbol("solid-proxy"),M6=typeof Proxy==="function",P6=Symbol("solid-track"),wQ=Symbol("solid-dev-component"),nJ={equals:U6},V1=null,V6=_1,c=1,EJ=2,D1={owned:null,cleanups:null,context:null,owner:null},S=null,B=null,bJ=null,AJ=null,f=null,h=null,N=null,oJ=0;function tJ(J,Q){let $=f,Z=S,X=J.length===0,W=Q===void 0?Z:Q,z=X?D1:{owned:null,cleanups:null,context:W?W.context:null,owner:W},F=X?J:()=>J(()=>qJ(()=>zJ(z)));S=z,f=null;try{return n(F,!0)}finally{f=$,S=Z}}function E(J,Q){Q=Q?Object.assign({},nJ,Q):nJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return L1($,X)};return[O1.bind($),Z]}function WJ(J,Q,$){let Z=k1(J,Q,!1,c);if(bJ&&B&&B.running)h.push(Z);else J0(Z)}function $J(J,Q,$){$=$?Object.assign({},nJ,$):nJ;let Z=k1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,bJ&&B&&B.running)Z.tState=c,h.push(Z);else J0(Z);return O1.bind(Z)}function eJ(J){return n(J,!1)}function qJ(J){if(!AJ&&f===null)return J();let Q=f;f=null;try{if(AJ)return AJ.untrack(J);return J()}finally{f=Q}}function w0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function D6(J){if(B&&B.running)return J(),B.done;let Q=f,$=S;return Promise.resolve().then(()=>{f=Q,S=$;let Z;if(bJ||R6)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return n(J,!1),f=S=null,Z?Z.done:void 0})}var[SQ,R1]=E(!1),R6;function O1(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===c)J0(this);else{let Q=h;h=null,n(()=>Q0(this),!1),h=Q}if(f){let Q=this.observers;if(!Q||Q[Q.length-1]!==f){let $=Q?Q.length:0;if(!f.sources)f.sources=[this],f.sourceSlots=[$];else f.sources.push(this),f.sourceSlots.push($);if(!Q)this.observers=[f],this.observerSlots=[f.sources.length-1];else Q.push(f),this.observerSlots.push(f.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function L1(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)n(()=>{for(let X=0;X1e6)throw h=[],Error()},!1)}return Q}function J0(J){if(!J.fn)return;zJ(J);let Q=oJ;if(I1(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{n(()=>{B&&(B.running=!0),f=S=J,I1(J,J.tValue,Q),f=S=null},!1)})}function I1(J,Q,$){let Z,X=S,W=f;f=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(B&&B.running)J.tState=c,J.tOwned&&J.tOwned.forEach(zJ),J.tOwned=void 0;else J.state=c,J.owned&&J.owned.forEach(zJ),J.owned=null;return J.updatedAt=$+1,y0(z)}finally{f=W,S=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)L1(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function k1(J,Q,$,Z=c,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(S===null);else if(S!==D1)if(B&&B.running&&S.pure)if(!S.tOwned)S.tOwned=[W];else S.tOwned.push(W);else if(!S.owned)S.owned=[W];else S.owned.push(W);if(AJ&&W.fn){let z=W.fn,[F,D]=E(void 0,{equals:!1}),R=AJ.factory(z,D);w0(()=>R.dispose());let U,H=()=>D6(D).then(()=>{if(U)U.dispose(),U=void 0});W.fn=(w)=>{if(F(),B&&B.running){if(!U)U=AJ.factory(z,H);return U.track(w)}return R.track(w)}}return W}function S0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===EJ)return Q0(J);if(J.suspense&&qJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===c)J0(J);else if((Q?J.tState:J.state)===EJ){let X=h;h=null,n(()=>Q0(J,$[0]),!1),h=X}}}function n(J,Q){if(h)return J();let $=!1;if(!Q)h=[];if(N)$=!0;else N=[];oJ++;try{let Z=J();return O6($),Z}catch(Z){if(!$)N=null;h=null,y0(Z)}}function O6(J){if(h){if(bJ&&B&&B.running)L6(h);else _1(h);h=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;N.push.apply(N,B.effects),Q=B.resolve;for(let W of N)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,n(()=>{for(let W of X)zJ(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let z=0,F=W.owned.length;zV6($),!1);if(Q)Q()}function _1(J){for(let Q=0;Q{Z.delete($),n(()=>{B.running=!0,S0($)},!1),B&&(B.running=!1)})}}function Q0(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)zJ(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)w1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)zJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function w1(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return w0(()=>y1(W)),()=>{let D=J()||[],R=D.length,U,H;return D[P6],qJ(()=>{let x,g,A,a,r,K,j,G,P;if(R===0){if(z!==0)y1(W),W=[],Z=[],X=[],z=0,F&&(F=[]);if($.fallback)Z=[k6],X[0]=tJ((k)=>{return W[0]=k,$.fallback()}),z=1}else if(z===0){X=Array(R);for(H=0;H=K&&G>=K&&Z[j]===D[G];j--,G--)A[G]=X[j],a[G]=W[j],F&&(r[G]=F[j]);x=new Map,g=Array(G+1);for(H=G;H>=K;H--)P=D[H],U=x.get(P),g[H]=U===void 0?-1:U,x.set(P,H);for(U=K;U<=j;U++)if(P=Z[U],H=x.get(P),H!==void 0&&H!==-1)A[H]=X[U],a[H]=W[U],F&&(r[H]=F[U]),H=g[H],x.set(P,H);else W[U]();for(H=K;HJ(Q||{}));return P1($),Z}}return qJ(()=>J(Q||{}))}function $0(){return!0}var S6={get(J,Q,$){if(Q===A0)return $;return J.get(Q)},has(J,Q){if(Q===A0)return!0;return J.has(Q)},set:$0,deleteProperty:$0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:$0,deleteProperty:$0}},ownKeys(J){return J.keys()}};function f0(J){return!(J=typeof J==="function"?J():J)?{}:J}function y6(){for(let J=0,Q=this.length;J=0;F--){let D=f0(J[F])[z];if(D!==void 0)return D}},has(z){for(let F=J.length-1;F>=0;F--)if(z in f0(J[F]))return!0;return!1},keys(){let z=[];for(let F=0;F=0;z--){let F=J[z];if(!F)continue;let D=Object.getOwnPropertyNames(F);for(let R=D.length-1;R>=0;R--){let U=D[R];if(U==="__proto__"||U==="constructor")continue;let H=Object.getOwnPropertyDescriptor(F,U);if(!Z[U])Z[U]=H.get?{enumerable:!0,configurable:!0,get:y6.bind($[U]=[H.get.bind(F)])}:H.value!==void 0?H:void 0;else{let w=$[U];if(w){if(H.get)w.push(H.get.bind(F));else if(H.value!==void 0)w.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let z=W.length-1;z>=0;z--){let F=W[z],D=Z[F];if(D&&D.get)Object.defineProperty(X,F,D);else X[F]=D?D.value:void 0}return X}var f6=(J)=>`Stale read from <${J}>.`;function NJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return $J(_6(()=>J.each,J.children,Q||void 0))}function Z0(J){let Q=J.keyed,$=$J(()=>J.when,void 0,void 0),Z=Q?$:$J($,void 0,{equals:(X,W)=>!X===!W});return $J(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?qJ(()=>W(Q?X:()=>{if(!qJ(Z))throw f6("Show");return $()})):W}return J.fallback},void 0,void 0)}var x6=(J)=>$J(()=>J());function C6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:z,getParentNode:F,getFirstChild:D,getNextSibling:R}){function U(K,j,G,P){if(G!==void 0&&!P)P=[];if(typeof j!=="function")return H(K,j,P,G);WJ((k)=>H(K,j(),k,G),P)}function H(K,j,G,P,k){while(typeof G==="function")G=G();if(j===G)return G;let _=typeof j,I=P!==void 0;if(_==="string"||_==="number"){if(_==="number")j=j.toString();if(I){let L=G[0];if(L&&$(L))Z(L,j);else L=Q(j);G=g(K,G,P,L)}else if(G!==""&&typeof G==="string")Z(D(K),G=j);else g(K,G,P,Q(j)),G=j}else if(j==null||_==="boolean")G=g(K,G,P);else if(_==="function")return WJ(()=>{let L=j();while(typeof L==="function")L=L();G=H(K,L,G,P)}),()=>G;else if(Array.isArray(j)){let L=[];if(w(L,j,k))return WJ(()=>G=H(K,L,G,P,!0)),()=>G;if(L.length===0){let hJ=g(K,G,P);if(I)return G=hJ}else if(Array.isArray(G))if(G.length===0)A(K,L,P);else x(K,G,L);else if(G==null||G==="")A(K,L);else x(K,I&&G||[D(K)],L);G=L}else{if(Array.isArray(G)){if(I)return G=g(K,G,P,j);g(K,G,null,j)}else if(G==null||G===""||!D(K))X(K,j);else a(K,j,D(K));G=j}return G}function w(K,j,G){let P=!1;for(let k=0,_=j.length;k<_;k++){let I=j[k],L;if(I==null||I===!0||I===!1);else if(Array.isArray(I))P=w(K,I)||P;else if((L=typeof I)==="string"||L==="number")K.push(Q(I));else if(L==="function")if(G){while(typeof I==="function")I=I();P=w(K,Array.isArray(I)?I:[I])||P}else K.push(I),P=!0;else K.push(I)}return P}function x(K,j,G){let P=G.length,k=j.length,_=P,I=0,L=0,hJ=R(j[k-1]),IJ=null;while(IQJ-L){let AQ=j[I];while(L=0;I--){let L=j[I];if(k!==L){let hJ=F(L)===K;if(!_&&!I)hJ?a(K,k,L):X(K,k,G);else hJ&&W(K,L)}else _=!0}}else X(K,k,G);return[k]}function A(K,j,G){for(let P=0,k=j.length;PG.children=H(K,j.children,G.children));return WJ(()=>j.ref&&j.ref(K)),WJ(()=>{for(let k in j){if(k==="children"||k==="ref")continue;let _=j[k];if(_===G[k])continue;z(K,k,_,G[k]),G[k]=_}}),G}return{render(K,j){let G;return tJ((P)=>{G=P,U(j,K())}),G},insert:U,spread(K,j,G){if(typeof j==="function")WJ((P)=>r(K,j(),P,G));else r(K,j,void 0,G)},createElement:J,createTextNode:Q,insertNode:X,setProp(K,j,G,P){return z(K,j,G,P),G},mergeProps:f1,effect:WJ,memo:x6,createComponent:w6,use(K,j,G){return qJ(()=>K(j,G))}}}function g6(J){let Q=C6(J);return Q.mergeProps=f1,Q}var x1=480,C1=272,KJ={view:0,text:1,image:2},h6=1,E6=-1,b6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},M={f32:0,color:1,int:2},N6={width:M.f32,height:M.f32,minW:M.f32,minH:M.f32,maxW:M.f32,maxH:M.f32,paddingT:M.f32,paddingR:M.f32,paddingB:M.f32,paddingL:M.f32,marginT:M.f32,marginR:M.f32,marginB:M.f32,marginL:M.f32,gap:M.f32,flexDir:M.int,justify:M.int,align:M.int,grow:M.f32,shrink:M.f32,basis:M.f32,flexWrap:M.int,posType:M.int,insetT:M.f32,insetR:M.f32,insetB:M.f32,insetL:M.f32,display:M.int,overflow:M.int,zIndex:M.int,hitPass:M.int,bgColor:M.color,gradFrom:M.color,gradTo:M.color,gradDir:M.int,radius:M.f32,opacity:M.f32,borderColor:M.color,borderWidth:M.f32,shadow:M.int,bevelOuterLight:M.color,bevelOuterDark:M.color,bevelInnerLight:M.color,bevelInnerDark:M.color,bevelWidth:M.f32,textColor:M.color,fontSlot:M.int,textAlign:M.int,lineHeight:M.f32,tracking:M.f32,translateX:M.f32,translateY:M.f32,scale:M.f32,rotate:M.f32,scaleX:M.f32,scaleY:M.f32,originX:M.f32,originY:M.f32,rotateX:M.f32,rotateY:M.f32,translateZ:M.f32,perspective:M.f32,arcStart:M.f32,arcSweep:M.f32,arcWidth:M.f32},d={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},T6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},v6=1,yQ=2,fQ=1,xQ=2,CQ=131072,gQ=1,hQ=262144,EQ=1,bQ=1,NQ=1,TQ=2,vQ=4,mQ=8,lQ=16,uQ=1,pQ=2;function g1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var cQ=1,m6=1263551300,l6=1,u6=32,p6=24,o={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},UJ=32896,dQ=0.016666666666666666;function h1(J){return J.__viewport??null}var x0=null;function c6(){return null}function E1(J,Q=c6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function d6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return E1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return E1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function i6(J){x0=J}function wJ(){if(!x0)throw Error("PocketJS: host not installed — call render() first");return x0}function b(){return wJ().ops}function s6(J){globalThis.frame=J}function a6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function r6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return g1($>>>16&255,$>>>8&255,$&255,255);return g1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function n6(J,Q){let $=N6[J];if(typeof Q==="string"){if($===M.color)return r6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===M.color||$===M.int)return Q>>>0;return Q}var X0=60,b1=[1,2,3,4,5,6,10,12,15,20,30,60],C0=X0,YJ=-1,o6=0,TJ=[];function t6(J){if(!Number.isFinite(J)||J<=0)return X0;let Q=b1[0];for(let $ of b1)if(Math.abs($-J)Q.at<=YJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;TJ=TJ.filter((Q)=>Q.at>YJ);for(let Q of J)Q.cb()}var g0=0.12,W0=UJ;function $8(J){W0=J===void 0?UJ:J&65535}function Z8(){W0=UJ}function v1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function W8(){return v1(W0&255)}var m1=new Set,q8=0;function z8(){m1.clear(),q8=0,Z8()}function Y8(J){for(let Q of[...m1])Q(J)}var MJ=null,l1=null;function G8(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function u1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){h0();let Q=MJ?MJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return l1.slice(Q.off,Q.off+Q.len)}var mJ=null,C=null,PJ=null,q0=0,VJ=[],b0=[],N0=[];function c1(J){if(mJ=J,C=null,PJ=null,q0=0,VJ.length=0,b0.length=0,N0.length=0,i){if(i.pressTarget=null,i.target=null,i.spriteDirty=!0,i.fresh=!0,i.vw=0,i.tex>=0){let Q=b();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(i.tex),i.tex=-1}}}function j8(J,Q){J.onPress=Q??void 0}function F8(J,Q){if(J.focusable=Q,r1(),!Q&&C===J)v(null)}function v(J){if(PJ&&PJ!==J)DJ(null);C=J,b().setFocus(J?J.id:0)}function DJ(J){if(PJ===J)return;let Q=b();if(PJ)Q.setActive?.(PJ.id,0);if(PJ=J,J)Q.setActive?.(J.id,1)}function T0(){return VJ.length>0?VJ[VJ.length-1]:mJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;v($[X])}function U8(){if(!C)return null;let J=T0();if(J&&!t(C,J))return null;for(let Q=b0.length-1;Q>=0;Q--){let $=b0[Q];if(J&&!t($.node,J)&&!t(J,$.node))continue;if(t(C,$.node))return $}return null}function M8(J){let Q=U8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(C)v(null);return!0}let Z=Q.columns,X=C?$.indexOf(C):-1;if(X<0)return v(d1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)v($[W]);return!0}function P8(){if(!C)return null;let J=T0();if(J&&!t(C,J))return null;for(let Q=N0.length-1;Q>=0;Q--){let $=N0[Q];if(J&&!t($.node,J)&&!t(J,$.node))continue;if(t(C,$.node))return $}return null}function z0(J){let Q=P8();if(Q&&Q.move(J))return;if(M8(J))return;K8(J)}function i1(){s1(C)}function s1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){DJ(J)}function V8(J){v(J),s1(J)}function t(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=m0(Q.children[X]);if(W){v(W);return}}let Z=Q;while(Z){if(Z.focusable){v(Z);return}Z=Z.parent}}v(null)}var i=null,a1=0;function r1(){a1++}var R8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],O8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function L8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=R8[Q]>>$&1,X=O8[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,z=X?255:0;J[W]=z,J[W+1]=z,J[W+2]=z,J[W+3]=255}return J}function I8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=vJ($.image)}catch(z){if(wJ().strict)throw z;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):k8(Q,W),X<0&&wJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(L8(),16,16,T6.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function k8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&v6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function G0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=G0($[Z],Q);if(X)return X}return null}var H0=null;function n1(J){H0=J}function o1(J){let Q=VJ.length>0?VJ[VJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||t($,Q)))return $;$=$.parent}return null}function t1(J,Q,$){return o1(e1(J,Q,$))}function e1(J,Q,$){if($!==void 0)return $===0?null:G0(H0??mJ,$);let Z=b(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return G0(H0??mJ,X(J,Q))}function _8(J,Q,$){let Z=i,X=b();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=h1(X);if(Z.vw=H?H.w:x1,Z.vh=H?H.h:C1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)I8(Z,X);let W=X8()*Z.speed,z=W8()*Z.speed;if(Z.dpadSpeed>0&&W===0&&z===0){if(J&o.LEFT)W=-Z.dpadSpeed;if(J&o.RIGHT)W=Z.dpadSpeed;if(J&o.UP)z=-Z.dpadSpeed;if(J&o.DOWN)z=Z.dpadSpeed}let F=Z.fresh;if(W!==0||z!==0){let H=e6()/60,w=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),x=Math.min(Math.max(Z.y+z*H,0),Z.vh-1);if(w!==Z.x||x!==Z.y)Z.x=w,Z.y=x,F=!0}if(F)X.setCursorPos(Z.x,Z.y);let D=(Q|$)&Z.button,R=a1;if(F||D!==0||R!==Z.gen)Z.gen=R,Z.fresh=!1,Z.target=o1(G0(H0??mJ,X.hitTest(Z.x,Z.y)));let U=Z.target;if(U!==C)v(U);if(Q&Z.button&&U)Z.pressTarget=U;if(Z.pressTarget){if(DJ(U===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=U===Z.pressTarget;if(Z.pressTarget=null,DJ(null),H)i1()}}else if($&Z.button)DJ(null);return!0}function A8(J){let Q=J&~q0,$=q0&~J;if(q0=J,i&&_8(J,Q,$))return;if($&o.CIRCLE)DJ(null);if(Q===0)return;if(Q&o.DOWN)z0("down");if(Q&o.RIGHT)z0("right");if(Q&o.UP)z0("up");if(Q&o.LEFT)z0("left");if(Q&o.CIRCLE)DJ(C),i1()}var l0=null;function J4(J){l0=J}function SJ(){if(r1(),l0)l0()}function w8(J,Q){J.debugName=Q||void 0,SJ()}var GJ={id:h6,type:KJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},Q4=Symbol.for("pocketjs.native-node"),u0=1,lJ=3,ZJ=8,S8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function j0(J){return J.domAttrs??={}}function $4(J,Q){let $=J.domNodeType??(uJ(J)?lJ:u0),Z=$===lJ?F0(J.text??""):$===ZJ?x8(J.domData??""):G4(J.domTag??K0(J));for(let X of Object.keys(J.domAttrs??{}))p0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)HJ(Z,$4(X,!0));return Z}function p0(J,Q,$){if(S8.has(Q)){fJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete j0(J)[Q];else j0(J)[Q]=$}function c0(J){if(J[Q4]===!0)return J;return Object.defineProperty(J,Q4,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?lJ:u0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===ZJ?J.domData??"":J.text??""},set($){if(J.domNodeType===ZJ)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===ZJ?J.domData??"":J.text??""},set($){if(J.domNodeType===ZJ)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===ZJ)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===ZJ)J.domData=Z;else if(uJ(J))B0(J,Z);else if(T8(J),Z)HJ(J,F0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return j4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??K0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===lJ)return"#text";if(J.domNodeType===ZJ)return"#comment";return(J.domTag??K0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){fJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===GJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return HJ(J,$),$},insertBefore($,Z){return HJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return HJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return $4(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){p0(J,$,Z)},removeAttribute($){p0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(GJ);var d0=null;function y8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},Z4=new Map;function X4(J,Q){Z4.set(J,Q)}var W4=new Map;function q4(J,Q){W4.set(J,Q)}var yJ=new Set,f8=new Set;function z4(J){if(!J)return!1;if(f8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:b().createNode(Q),type:Q,parent:null,children:[],domNodeType:u0,domTag:J})}function F0(J){let Q=b(),$=Q.createNode(KJ.text);return Q.setText($,J),c0({id:$,type:KJ.text,parent:null,children:[],text:J,domNodeType:lJ,domTag:"#text"})}function x8(J=""){let Q=F0("");return Q.domNodeType=ZJ,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){b().replaceText(J.id,Q),J.text=Q,SJ()}function uJ(J){return J.type===KJ.text}function H4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function HJ(J,Q,$){let Z=b();if(H4(Q),yJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,SJ()}function pJ(J,Q){if(!Q)return;D8(Q),b().removeChild(J.id,Q.id),H4(Q),yJ.add(Q),SJ()}function C8(J){return J.parent??void 0}function g8(J){return J.children[0]}function j4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function h8(J,Q){let $=b();if(SJ(),Q==null||Q===""){$.setStyle(J.id,E6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function E8(J,Q){let $=b();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=Z4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function b8(J,Q){let $=b();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=W4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function N8(J,Q,$){let Z=b(),X=Q??{},W=$??{},z=!1;for(let F in X){let D=X[F];if(W[F]===D)continue;let R=b6[F];if(R===void 0)throw Error(`PocketJS: unknown style prop '${F}' (see spec PROP)`);Z.setProp(J.id,R,n6(F,D)),z=!0}if(z)SJ()}function fJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete j0(J)[Q];else j0(J)[Q]=$;switch(Q){case"class":return h8(J,$),$;case"onPress":case"on:press":return j8(J,$),$;case"src":return E8(J,$),$;case"sprite":return b8(J,$),$;case"style":return N8(J,$,Z),$;case"focusable":return F8(J,!!$),$;case"debugName":return w8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${K0(J)}>`)}function T8(J){for(let Q of[...J.children])pJ(J,Q)}function K0(J){for(let Q of Object.keys(KJ))if(KJ[Q]===J.type)return Q;return String(J.type)}function v8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}fJ(J,Q,$,Z)}var m8=g6({createElement:G4,createTextNode:F0,replaceText:B0,isTextNode:uJ,setProperty:v8,insertNode(J,Q,$){HJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:C8,getFirstChild:g8,getNextSibling:j4}),{render:l8,effect:iQ,memo:l,createComponent:q,createElement:F4,insert:sQ,spread:u8,mergeProps:aQ,use:rQ}=m8,nQ={linear:d.Easing.Linear,in:d.Easing.EaseIn,out:d.Easing.EaseOut,"in-out":d.Easing.EaseInOut,"out-back":d.Easing.OutBack,spring:d.Easing.Spring,"spring-bouncy":d.Easing.SpringBouncy},p8=null;function B4(J){p8=J}function c8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function K4(J,Q){let $=F4(J);return u8($,Q,!1),c8(Q.nodeRef,$),$}function V(J){return K4("view",J)}function O(J){return K4("text",J)}var oQ=new WeakMap,tQ=new WeakMap,d8={}!==null?Object.freeze({...{}}):Object.freeze({}),eQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:d8}),J9=new Map,jJ=36000,s0=30,i8=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(jJ),tapeAnalog:new Uint16Array(jJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function s8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-s0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)J4(()=>{Y.treeDirty=!0}),Q2();else J4(null);globalThis.__pocketDevtools=Z2}function a8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)n8(),e8();let W=Q,z=$===void 0?UJ:$&65535,F=Z,D=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(jJ).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==UJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function P4(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,z]of J)Z.fill(W,X,Math.min(X+z,$)),X+=z;return Z}function V4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return P4(J.masks,0,Q)}function D4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return P4(J.analog??[],UJ,Q)}function R4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,T({t:"hello",app:Y.app,host:$2(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` +`))if(X.trim())o8(X)}}function o8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),a0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":O4();break;case"eval":{let Z=!0,X;try{X=U0((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}T({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":T({t:"tape",tape:M4()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}T({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=V4(Z),Y.replayAnalog=Z.analog?D4(Z):null,Y.replayTouch=Z.touch?R4(Z):null,Y.replayAt=0;break}default:break}}function t8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=s0)O4();if(Y.frame%i8===0)a0()}function e8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){T({t:"stats",frame:Y.frame,nodes:k4(GJ),tapeLen:Y.tapeLen,paused:Y.paused})}function O4(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,T({t:"tree",frame:Y.frame,root:I4(GJ)})}function J2(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(J2(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function L4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function I4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(L4(J,(X)=>{if(X.domNodeType===8)return;Z.push(I4(X))}),Z.length)Q.k=Z;return Q}function k4(J){let Q=1;return L4(J,($)=>{Q+=k4($)}),Q}function Q2(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{T({t:"log",level:$,args:X.map((W)=>U0(W))}),Z?.apply(Q,X)}}}function U0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?_4(W):JSON.stringify(_4(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((z)=>U0(z,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,z])=>`${W}: ${U0(z,Q+1)}`).join(", ")}}`}function _4(J){return J.length>200?J.slice(0,199)+"…":J}function $2(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var Z2={get frame(){return Y.frame},dumpTape:()=>M4(),replay:(J)=>{Y.replayMasks=V4(J),Y.replayAnalog=J.analog?D4(J):null,Y.replayTouch=J.touch?R4(J):null,Y.replayAt=0}},A4=new Map,n0=new Map;function w4(J){return J.trim().replace(/\s+/g," ")}function S4(J){return J.split(" ").sort().join(" ")}var y4=-1;function X2(J){for(let Q of Object.keys(J)){let $=J[Q],Z=w4(Q);A4.set(Z,$);let X=S4(Z),W=n0.get(X);n0.set(X,W!==void 0&&W!==$?y4:$)}}function W2(J){let Q=w4(J),$=A4.get(Q);if($!==void 0)return $;let Z=n0.get(S4(Q));return Z===y4?void 0:Z}var o0=9,q2=(1<{let X=($&Y2)!==0,W=X?t0:o0,z=X?G2:q2;return Object.freeze({id:$>>>(X?H2:z2)&255,x:$&z,y:$>>>W&z,hit:Q?.[Z]})}))}function F2(){return M0}function B2(){M0=e0}var f4=8,FJ=8,K2=3,U2=8,M2=6,P2=0.5,e=1,cJ=2,J1=4,RJ=8,xJ=[],x4=0,P0=0,BJ=Array.from({length:f4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(FJ),histY:new Int16Array(FJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function V2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function D2(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=e1(Q,$,Z.fact);let F=Z.hit;if(F)return V2(F,W)}let z=X.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let F=xJ[z];if(F.disposed)continue;if(x4>0&&!F.opts.allowWhenBlocked)continue;if(!D2(F,$,Z,W))continue;F.flags[J.slot]=e,J.owners.push(F)}for(let z of J.owners)z.opts.onDown?.(J)}function L2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%FJ,J.histLenz||Z>z))X.flags[J.slot]|=cJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&e)||W&(cJ|J1))continue;if(!X.opts.onLongPress)continue;let z=Math.max(1,Math.round((X.opts.longPressSeconds??P2)*N1()));if(J.frames=0)xJ.splice($,1)},cancel(){if(!Q.disposed)h4(Q)},get panning(){for(let $ of BJ)if($.used&&Q.flags[$.slot]&RJ)return!0;return!1}}}function w2(J){let Q=A2(J);return w0(()=>Q.dispose()),Q}function E4(){xJ.length=0,x4=0,P0=0;for(let J of BJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function S2(){return w2({onDown:(J)=>{let Q=t1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=t1(J.x,J.y,J.hit);if(Q)V8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var y2=1,Q1=new Map,V0=[];function f2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function x2(){y2=1,Q1.clear(),V0=[]}function C2(){if(V0.length===0)return;let J=V0;V0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),f2()?.({t:"delivery",frame:T1(),id:Q,kind:Z.kind}),Z.onResult($)}}var b4=new Set;function g2(){if(b4.size===0)return;for(let J of b4)J()}var h2={"w-[210] h-[104]":0,"h-[72] px-5 flex-row items-center justify-between":1,"w-[450] flex-col gap-2":2,"text-lg text-slate-900 font-bold":3,"text-base text-slate-500":4,"text-base text-emerald-600 font-bold":5,"text-base text-slate-900 font-bold":6,"h-[64] px-5 flex-row items-center":7,"w-[240] text-lg text-slate-900 font-bold":8,"w-[156] text-base text-slate-500":9,"relative w-[632] h-[196] flex-col":10,"relative w-[632] h-[160] overflow-hidden":11,"absolute w-[632] h-[2] bg-slate-200":12,"absolute text-base text-slate-500 font-bold":13,"absolute rounded-lg bg-emerald-500":14,"absolute rounded-lg bg-red-500":15,"absolute w-[6] h-[6] rounded-lg bg-emerald-500":16,"absolute w-[6] h-[6] rounded-lg bg-red-500":17,"h-[36] px-1 flex-row items-center justify-between":18,"flex-col w-full h-full bg-slate-50":19,"h-[64] px-6 pt-2":20,"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":21,"text-base text-slate-500 font-bold":22,"h-[304] px-6 pt-3":23,"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100":24,"h-[64] flex-row items-end justify-between":25,"text-2xl text-slate-950 font-bold":26,"text-lg text-emerald-600 font-bold":27,"text-lg text-red-500 font-bold":28,"h-[60] px-6 pt-2 flex-row gap-3":29,"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":30,"w-[100] h-[44] items-center justify-center rounded-lg bg-white":31,"text-base text-white font-bold":32,"pt-3 text-base text-slate-500":33,"h-[126] px-6 pt-3 flex-row items-start gap-[21]":34,"h-[200] px-6 flex-col":35,"h-[150] flex-col rounded-xl shadow bg-white border-slate-100":36,"h-[184] px-6 flex-col":37,"h-[136] flex-col rounded-xl shadow bg-white border-slate-100":38,"h-[126] px-6 pt-2":39,"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":40,"flex-col gap-3":41,"text-xl text-slate-900 font-bold":42,"text-2xl text-emerald-600 font-bold":43,"text-2xl text-red-500 font-bold":44,"h-[104] px-6 flex-row items-center justify-between":45,"w-[460] h-[64]":46,"w-[176] h-[64]":47,"absolute left-[628] top-[156] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":48,"absolute left-[628] top-[972] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":49,"relative flex-col w-full h-full bg-slate-50":50,"px-6 pt-[14] flex-col gap-[12]":51,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":52,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":53,"flex-row items-center justify-between":54,"text-lg text-slate-500 font-bold":55,"px-6 pt-[14] flex-col gap-[14]":56,"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100":57,"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":58,"flex-row items-center":59,"w-[170] text-xl text-slate-900 font-bold":60,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":61,"absolute inset-0 z-50 flex-col items-center justify-center":62,"absolute inset-0 bg-slate-950":63,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":64,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":65,"flex-row flex-wrap":66,grow:67,"text-2xl text-white font-bold":68,"text-base text-slate-600 font-bold":69,"text-lg text-slate-900":70,"px-6":71,"px-6 py-5":72,"gap-4":73,"rounded-xl shadow bg-white border-slate-100":74,"rounded-xl shadow bg-emerald-100 border-emerald-500":75,"bg-white":76,"bg-slate-100":77,"bg-slate-950":78,"px-3 py-2 rounded-lg bg-slate-100":79,"px-3 py-2 rounded-lg bg-indigo-100":80,"text-base text-indigo-700 font-bold":81,"px-3 py-2 rounded-lg bg-emerald-100":82,"text-base text-emerald-700 font-bold":83,"px-3 py-2 rounded-lg bg-amber-100":84,"text-base text-amber-700 font-bold":85,"px-3 py-2 rounded-lg bg-red-100":86,"text-base text-red-500 font-bold":87,"w-[34] h-[34] rounded-lg bg-amber-400":88,"w-[34] h-[34] rounded-lg bg-red-500":89,"w-[34] h-[34] rounded-lg bg-slate-800":90,"w-[34] h-[34] rounded-lg bg-emerald-500":91,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":92,"flex-row items-center gap-4":93,"w-[34] text-2xl text-white font-bold":94,"w-[332] flex-col items-end gap-2":95,"text-base text-slate-300 font-bold":96,"text-base text-slate-400":97,"h-[166] px-6 pt-6 flex-col gap-3":98,"text-base text-orange-600 font-bold":99,"text-lg text-slate-600":100,"h-[44] px-1 flex-row items-center justify-between":101,"w-full h-full items-center justify-center rounded-xl bg-slate-200":102,"w-full h-full items-center justify-center rounded-xl bg-red-100":103,"w-full h-full items-center justify-center rounded-xl bg-slate-100":104,"w-full h-full items-center justify-center rounded-xl bg-orange-600":105,"text-lg text-white font-bold":106,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":107,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":108,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":109,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":110,"text-2xl text-indigo-700 font-bold":111,"text-2xl text-slate-600 font-bold":112,"pt-7 text-2xl text-slate-900 font-bold":113,"pt-4 text-lg text-slate-500":114,"text-xl text-emerald-600 font-bold":115,"text-xl text-red-500 font-bold":116,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":117,"text-base text-red-300":118,"text-base text-slate-300":119,"text-base text-red-500":120,"w-full h-full px-6 flex-row items-center bg-slate-950":121,"w-full h-full flex-row items-center":122};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var E2="ui:styles",b2="ui:font.",N4="ui:img.",T4="ui:sprite.";function N2(){return globalThis.ui}function T2(J){if(J.__textures)return;for(let Q of E0(N4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)X4(Q.slice(N4.length),Z)}}function v2(J){if(J.__sprites)return;for(let Q of E0(T4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),z=$[4],F=Z.getUint16(6,!0),D=Z.getUint16(8,!0),R=Z.getUint16(10,!0),U=J.uploadTexture($.subarray(16),X,W,z);if(U>=0)q4(Q.slice(T4.length),{handle:U,frames:F,cols:D,step:R})}}function v4(J){let Q=F4("view");return fJ(Q,"style",J,void 0),Q}var D0=null,R0=null;function m2(J,Q){if(!D0||!R0)return;fJ(D0,"style",{width:J,height:Q,overflow:d.Overflow.Hidden},void 0),fJ(R0,"style",{width:J,height:Q,posType:d.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=b();$.__viewport={w:J,h:Q}}function l2(J,Q={}){let $=d6(Q.ops);if(i6($),y8(W2),Q.styles)X2(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let w in Z)X4(w,Z[w]);let H=$.ops.__sprites;if(H)for(let w in H)q4(w,H[w])}if($.kind==="injected"||Z===void 0){if(Q.pak)p1(Q.pak);if(H8()){for(let H of E0())if(H===E2)$.ops.loadStyles?.(vJ(H));else if(H.startsWith(b2))$.ops.loadFontAtlas?.(vJ(H))}}let X=h1($.ops),W=X?.w??x1,z=X?.h??C1,F=v4({width:W,height:z,overflow:d.Overflow.Hidden}),D=v4({width:W,height:z,posType:d.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});HJ(GJ,F),HJ(GJ,D),B4(D),D0=F,R0=D,c1(F),n1(GJ),z8(),E4(),S2(),J8(),x2(),s8($.ops),s6(a8((H,w,x,g)=>{Q8(),$8(w),j2(x,g),g2(),C2(),_2(),Y8(H),A8(H),Y4()}));let R=l8(J,F),U=a6(m2);return()=>{U(),B2(),E4(),R(),c1(null),n1(null),B4(null),D0=null,R0=null;for(let H of GJ.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);Y4()}}function u2(J,Q={}){let $=Q.ops??N2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)p1(Q.pak);return T2($),v2($),l2(J,{ops:$,styles:Q.styles??h2,pak:Q.pak})}var m4="$b",p2=9007199254740991,c2=":memory:",CJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function d2(J){let Q="";for(let $=0;$>2]+CJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2p2)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function a2(J){if(J!==null&&typeof J==="object")return i2(J[m4]);return J}function r2(J){if(Array.isArray(J))return JSON.stringify(J.map(l4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=l4(Z);return JSON.stringify(Q)}class $1{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,r2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=u4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(a2))}run(...J){let Q=this.execute(u4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function u4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class p4{statements=new Map;txDepth=0;constructor(J=c2){let Q=s2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new $1(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new $1(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let z=J(...Q);return this.txDepth--,this.exec(X),z}catch(z){throw this.txDepth--,this.exec(W),z}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var O0={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"},c4={neutral:{surface:"px-3 py-2 rounded-lg bg-slate-100",text:"text-base text-slate-600 font-bold"},info:{surface:"px-3 py-2 rounded-lg bg-indigo-100",text:"text-base text-indigo-700 font-bold"},success:{surface:"px-3 py-2 rounded-lg bg-emerald-100",text:"text-base text-emerald-700 font-bold"},warning:{surface:"px-3 py-2 rounded-lg bg-amber-100",text:"text-base text-amber-700 font-bold"},danger:{surface:"px-3 py-2 rounded-lg bg-red-100",text:"text-base text-red-500 font-bold"}};function n2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return q(V,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[q(V,{class:"flex-row items-center gap-4",get children(){return[l(()=>l(()=>!!J.back)()?q(O,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):q(V,{get["class"](){return Q()}})),q(O,{get["class"](){return O0.appTitle},get children(){return J.title}})]}}),q(V,{class:"w-[332] flex-col items-end gap-2",get children(){return[q(O,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),q(O,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function o2(J){let Q=()=>J.action?J.detail?J.detail+" · VIEW ALL ›":"VIEW ALL ›":J.detail??"";return q(V,{class:"h-[44] px-1 flex-row items-center justify-between",get children(){return[q(O,{get["class"](){return O0.heading},get children(){return J.title}}),q(O,{get["class"](){return O0.captionStrong},get children(){return Q()}})]}})}function t2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return q(V,{get["class"](){return Q()},get children(){return q(O,{get["class"](){return $()},get children(){return J.label}})}})}function d4(J){return q(V,{get["class"](){return J.compact?"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100"},get children(){return[l(()=>l(()=>!!J.icon)()?q(V,{get["class"](){return J.tone==="info"?"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100"},get children(){return q(O,{get["class"](){return J.tone==="info"?"text-2xl text-indigo-700 font-bold":"text-2xl text-slate-600 font-bold"},get children(){return J.icon}})}}):null),q(O,{get["class"](){return J.icon?"pt-7 text-2xl text-slate-900 font-bold":"text-lg text-slate-500 font-bold"},get children(){return J.title}}),l(()=>l(()=>!!J.detail)()?q(O,{class:"pt-4 text-lg text-slate-500",get children(){return J.detail}}):null)]}})}function e2(J){let Q=()=>J.tone==="success"?"text-xl text-emerald-600 font-bold":J.tone==="danger"?"text-xl text-red-500 font-bold":"text-xl text-slate-900 font-bold";return q(V,{class:"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(O,{get["class"](){return O0.label},get children(){return J.label}}),q(O,{get["class"](){return Q()},get children(){return J.value}})]}})}function JQ(J){let Q=()=>J.dark?J.tone==="danger"?"text-base text-red-300":"text-base text-slate-300":J.tone==="danger"?"text-base text-red-500":"text-base text-slate-500";return q(V,{get["class"](){return J.dark?"w-full h-full px-6 flex-row items-center bg-slate-950":"w-full h-full flex-row items-center"},get children(){return q(O,{get["class"](){return Q()},get children(){return J.text}})}})}function QQ(J){return[q(V,{get["class"](){return J.top},get children(){return q(O,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),q(V,{get["class"](){return J.bottom},get children(){return q(O,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var i4=4,m=new p4("robinhood"),$Q={number:"",label:"ACCOUNT",suffix:"",status:"WAITING FOR ROBINHOOD"},Z1={title:"NO RECENT ACTIVITY",timestamp:"",detail:"",state:"",amount:"",side:""},ZQ={...Z1,title:"ACTIVITY UNAVAILABLE"},XQ={...Z1,title:""},X1={symbol:"NO OPEN POSITIONS",quantity:"",averagePrice:"",marketValue:""},WQ={...X1,symbol:"POSITIONS UNAVAILABLE"},qQ={...X1,symbol:""},iJ={account:$Q,totalValue:null,cash:null,buyingPower:null,pnlDay:null,pnlWeek:null,positions:[],activity:[],positionsAvailable:!0,activityAvailable:!0,observedAt:null},[s,sJ]=E("dashboard"),[u,zQ]=E("day"),[gJ,W1]=E([]),[L0,I0]=E(""),[y,aJ]=E(iJ),[s4,OJ]=E([]),[YQ,LJ]=E([]),[q1,z1]=E([]),[GQ,Y1]=E({change:"$—",percent:"—",positive:!0}),[G1,a4]=E(0),[r4,n4]=E(0),[o4,t4]=E(0),[e4,XJ]=E("WAITING FOR ROBINHOOD"),[rJ,J6]=E(!1),p=0,Q6=-1,$6=-1,Z6=-1,H1=new Map,j1=new Map;function X6(){return Math.floor(Date.now()/1000)}function HQ(J){try{return J?JSON.parse(J):null}catch{return null}}function jQ(){return m.query("SELECT account_number,label,suffix,status FROM accounts ORDER BY label,account_number LIMIT 16").all().map((Q)=>({number:Q.account_number,label:Q.label,suffix:Q.suffix,status:Q.status}))}function FQ(J,Q){if($6===J)return;let $=m.query("SELECT account_number,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current LIMIT 16").all(),Z=m.query(` SELECT value.account_number,value.value,value.observed_at FROM total_value value JOIN ( @@ -7,7 +7,7 @@ FROM total_value GROUP BY account_number ) latest ON latest.account_number=value.account_number AND latest.observed_at=value.observed_at LIMIT 16 - `).all(),X=m.query("SELECT account_number,symbol,quantity,average_price,market_value FROM positions ORDER BY account_number,CAST(market_value AS REAL) DESC,symbol LIMIT 1024").all(),W=m.query("SELECT account_number,activity_id,occurred_at,symbol,side,quantity,price,amount,state,activity_type FROM activities ORDER BY account_number,occurred_at DESC,observed_at DESC LIMIT 1024").all(),z=new Map($.map((U)=>[U.account_number,U])),F=new Map(Z.map((U)=>[U.account_number,U])),P=new Map,D=new Map;for(let U of X){let H=P.get(U.account_number)||[];if(H.length<64)H.push(U);P.set(U.account_number,H)}for(let U of W){let H=D.get(U.account_number)||[];if(H.length<64)H.push(U);D.set(U.account_number,H)}G1.clear();for(let U of Q){let H=z.get(U.number),w=F.get(U.number),C=P.get(U.number)||[],g=D.get(U.number)||[];G1.set(U.number,{loadedRevision:J,value:{account:U,totalValue:w?.value??null,cash:H?.cash??null,buyingPower:H?.buying_power??null,pnlDay:H?.day_pnl??null,pnlWeek:H?.week_pnl??null,positions:C.map((A)=>({symbol:A.symbol,quantity:A.quantity||"—",averagePrice:A.average_price||"—",marketValue:A.market_value||""})),activity:g.map((A)=>({title:(A.side?A.side+" ":"")+(A.symbol||"ORDER"),timestamp:YQ(A.occurred_at),detail:A.quantity?A.quantity+" SH · "+(A.activity_type||"ORDER"):A.activity_type||"ORDER",state:A.state||"RECENT",amount:A.amount||A.price||A.quantity||"",side:A.side||""})),positionsAvailable:H!==void 0,activityAvailable:H!==void 0,observedAt:Math.max(H?.observed_at??0,w?.observed_at??0)||null}})}e4=J}function I0(J){if(J===null)return null;let Q=Number(J.replace(/[$,%]/g,""));return Number.isFinite(Q)?Q:null}function YQ(J){if(!J)return"RECENT";let Q=new Date(J);if(!Number.isFinite(Q.getTime()))return J.slice(0,16).toUpperCase();return String(Q.getMonth()+1).padStart(2,"0")+"/"+String(Q.getDate()).padStart(2,"0")+" "+String(Q.getHours()).padStart(2,"0")+":"+String(Q.getMinutes()).padStart(2,"0")}function $6(J){let Q=Math.max(0,Q6()-J);if(Q<60)return"JUST NOW";if(Q<3600)return Math.floor(Q/60)+" MIN AGO";if(Q<86400)return Math.floor(Q/3600)+" HR AGO";return Math.floor(Q/86400)+" DAY AGO"}function e(J){if(!J)return"$—";let Q=I0(J);if(Q===null)return J;let Z=Math.abs(Q).toFixed(2).split("."),X="$"+Z[0].replace(/\B(?=(\d{3})+(?!\d))/g,",")+"."+Z[1];return Q<0?"-"+X:X}function Z6(J,Q){let $=J+":"+l(),Z=H1.get($);if(Z?.loadedRevision===Q){OJ(Z.value.points),LJ(Z.value.segments),q1(Z.value.labels),z1(Z.value.trend);return}let X=l()==="day"?86400:604800,z=Q6()-X,P=m.query(` + `).all(),X=m.query("SELECT account_number,symbol,quantity,average_price,market_value FROM positions ORDER BY account_number,CAST(market_value AS REAL) DESC,symbol LIMIT 1024").all(),W=m.query("SELECT account_number,activity_id,occurred_at,symbol,side,quantity,price,amount,state,activity_type FROM activities ORDER BY account_number,occurred_at DESC,observed_at DESC LIMIT 1024").all(),z=new Map($.map((U)=>[U.account_number,U])),F=new Map(Z.map((U)=>[U.account_number,U])),D=new Map,R=new Map;for(let U of X){let H=D.get(U.account_number)||[];if(H.length<64)H.push(U);D.set(U.account_number,H)}for(let U of W){let H=R.get(U.account_number)||[];if(H.length<64)H.push(U);R.set(U.account_number,H)}H1.clear();for(let U of Q){let H=z.get(U.number),w=F.get(U.number),x=D.get(U.number)||[],g=R.get(U.number)||[];H1.set(U.number,{loadedRevision:J,value:{account:U,totalValue:w?.value??null,cash:H?.cash??null,buyingPower:H?.buying_power??null,pnlDay:H?.day_pnl??null,pnlWeek:H?.week_pnl??null,positions:x.map((A)=>({symbol:A.symbol,quantity:A.quantity||"—",averagePrice:A.average_price||"—",marketValue:A.market_value||""})),activity:g.map((A)=>({title:(A.side?A.side+" ":"")+(A.symbol||"ORDER"),timestamp:BQ(A.occurred_at),detail:A.quantity?A.quantity+" SH · "+(A.activity_type||"ORDER"):A.activity_type||"ORDER",state:A.state||"RECENT",amount:A.amount||A.price||A.quantity||"",side:A.side||""})),positionsAvailable:H!==void 0,activityAvailable:H!==void 0,observedAt:Math.max(H?.observed_at??0,w?.observed_at??0)||null}})}$6=J}function k0(J){if(J===null)return null;let Q=Number(J.replace(/[$,%]/g,""));return Number.isFinite(Q)?Q:null}function BQ(J){if(!J)return"RECENT";let Q=new Date(J);if(!Number.isFinite(Q.getTime()))return J.slice(0,16).toUpperCase();return String(Q.getMonth()+1).padStart(2,"0")+"/"+String(Q.getDate()).padStart(2,"0")+" "+String(Q.getHours()).padStart(2,"0")+":"+String(Q.getMinutes()).padStart(2,"0")}function W6(J){let Q=Math.max(0,X6()-J);if(Q<60)return"JUST NOW";if(Q<3600)return Math.floor(Q/60)+" MIN AGO";if(Q<86400)return Math.floor(Q/3600)+" HR AGO";return Math.floor(Q/86400)+" DAY AGO"}function JJ(J){if(!J)return"$—";let Q=k0(J);if(Q===null)return J;let Z=Math.abs(Q).toFixed(2).split("."),X="$"+Z[0].replace(/\B(?=(\d{3})+(?!\d))/g,",")+"."+Z[1];return Q<0?"-"+X:X}function q6(J,Q){let $=J+":"+u(),Z=j1.get($);if(Z?.loadedRevision===Q){OJ(Z.value.points),LJ(Z.value.segments),z1(Z.value.labels),Y1(Z.value.trend);return}let X=u()==="day"?86400:604800,z=X6()-X,D=m.query(` WITH RECURSIVE buckets(bucket_index, bucket_time) AS ( SELECT 0, ?1 UNION ALL @@ -19,4 +19,4 @@ WHERE account_number = ?3 AND observed_at >= ?1 AND observed_at <= bucket_time ORDER BY observed_at DESC LIMIT 1) AS total_value FROM buckets ORDER BY bucket_index - `).all(z,X,J).map((j)=>({time:j.bucket_time,value:I0(j.total_value)})),D=P.map((j)=>j.time),U=P.map((j)=>j.value).filter((j)=>j!==null),H=[D[0],D[9],D[19]].map((j)=>{let G=new Date(j*1000);return l()==="day"?String(G.getHours()).padStart(2,"0")+":"+String(G.getMinutes()).padStart(2,"0"):String(G.getMonth()+1)+"/"+String(G.getDate())});if(U.length===0){let j=l()==="day"?y().pnlDay:y().pnlWeek,G=I0(j),V={points:[],segments:[],labels:H,trend:{change:e(j),percent:"—",positive:G===null||G>=0}};H1.set($,{loadedRevision:Q,value:V}),OJ(V.points),LJ(V.segments),q1(V.labels),z1(V.trend);return}let w=Math.min(...U),C=Math.max(...U),g=Math.max(0.01,C-w),A=P.flatMap((j,G)=>j.value===null?[]:[{x:G*622/19,y:U.length===1?80:10+(C-j.value)*140/g}]),s=A.slice(1).map((j,G)=>{let V=A[G],k=j.x-V.x,_=j.y-V.y;return{x:V.x,y:V.y,width:Math.sqrt(k*k+_*_),angle:Math.atan2(_,k)*180/Math.PI}}),a=U[U.length-1]-U[0],K={change:e(String(a)),percent:U[0]===0?"—":(a*100/U[0]).toFixed(2)+"%",positive:a>=0};H1.set($,{loadedRevision:Q,value:{points:A,segments:s,labels:H,trend:K}}),OJ(A),LJ(s),q1(H),z1(K)}function GQ(J){if(J6===J)return;let Q=m.query("SELECT status,error,completed_at FROM refresh_runs ORDER BY id DESC LIMIT 1").get();if(o4(!1),Q?.status==="failed")ZJ("REFRESH FAILED · "+String(Q.error||"UNKNOWN ERROR").slice(0,52));else if(Q?.status==="partial")ZJ("LIVE WITH PARTIAL DATA");else if(y().observedAt)ZJ("LIVE / READ ONLY · "+$6(y().observedAt));else ZJ("WAITING FOR ROBINHOOD");J6=J}function X6(J,Q){if(!J){if(aJ(iJ),OJ([]),LJ([]),!rJ())ZJ("WAITING FOR ROBINHOOD");return}let $=G1.get(J);if($?.loadedRevision===Q){if(aJ($.value),Z6(J,Q),$.value.observedAt&&!rJ())ZJ("LIVE / READ ONLY · "+$6($.value.observedAt));return}aJ(iJ),OJ([]),LJ([])}function W6(J=u){try{let Q=m.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==p4){X1([]),L0(""),aJ(iJ),OJ([]),LJ([]),ZJ("WAITING FOR ROBINHOOD");return}eJ(()=>{u=Math.max(u,J);let $=gJ();if(t4!==u)$=qQ(),X1($),t4=u;zQ(u,$);let Z=O0();if(!$.some((X)=>X.number===Z))Z=$[0]?.number||"",L0(Z);X6(Z,u),GQ(u)})}catch{eJ(()=>{X1([]),L0(""),aJ(iJ),OJ([]),LJ([]),ZJ("WAITING FOR ROBINHOOD")})}}function HQ(){return""}function jQ(){let J=m.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((z)=>z.name)),$=J.map((z)=>{let F=m.query("SELECT COUNT(*) AS count FROM "+z.name).get().count;return{name:z.name,rowCount:F,schema:z.sql}}),Z=Q.has("refresh_runs")?m.query("SELECT id,started_at,completed_at,operation_count,success_count,status,error FROM refresh_runs ORDER BY id DESC LIMIT 3").all():[],X=Q.has("portfolio_current")?m.query("SELECT substr(account_number,-4) AS account_suffix,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current ORDER BY observed_at DESC LIMIT 4").all():[],W=Q.has("total_value")?m.query("SELECT substr(account_number,-4) AS account_suffix,observed_at,value FROM total_value ORDER BY observed_at DESC LIMIT 8").all():[];return{database:"robinhood.sqlite",schemaVersion:p4,tables:$,latestRefreshes:Z,latestPortfolios:X,latestValues:W}}function j1(){return XQ()}function k0(J){return q(a2,{get title(){return J.title},back:!0,metaTop:"READ ONLY",get metaBottom(){return J.metaBottom??"AUTO · 5 MIN"}})}function F1(J){return q(R,{class:"w-[210] h-[104] px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(L,{class:"text-sm text-slate-500 font-bold",get children(){return J.label}}),q(L,{class:"text-lg text-slate-900 font-bold",get children(){return e(J.value)}})]}})}function q6(J){return q(r2,{get title(){return J.title},get detail(){return J.detail},action:!0})}function FQ(J){if(J===0&&!y().activityAvailable)return t2;return y().activity[J]??(J===0?$1:e2)}function z6(J){let Q=()=>FQ(J.index);return q(R,{class:"h-[72] px-5 flex-row items-center justify-between",get children(){return[q(R,{class:"w-[450] flex-col gap-2",get children(){return[q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q().title}}),q(L,{class:"text-sm text-slate-500",get children(){return HJ(()=>!!Q().timestamp)()?Q().timestamp+" · "+Q().detail:""}})]}}),q(L,{get["class"](){return Q().side==="SELL"?"text-sm text-emerald-600 font-bold":"text-sm text-slate-900 font-bold"},get children(){return HJ(()=>!!Q().amount)()?e(Q().amount):""}})]}})}function BQ(J){if(J===0&&!y().positionsAvailable)return JQ;return y().positions[J]??(J===0?Z1:QQ)}function Y6(J){let Q=()=>BQ(J.index);return q(R,{class:"h-[64] px-5 flex-row items-center",get children(){return[q(L,{class:"w-[240] text-base text-slate-900 font-bold",get children(){return Q().symbol}}),q(L,{class:"w-[156] text-sm text-slate-500",get children(){return HJ(()=>!!Q().quantity)()?Q().quantity+" SH":""}}),q(L,{class:"text-sm text-slate-500",get children(){return HJ(()=>!!Q().averagePrice)()?"AVG "+e(Q().averagePrice):""}})]}})}function KQ(){return q(R,{class:"relative w-[632] h-[196] flex-col",get children(){return[q(R,{class:"relative w-[632] h-[160] overflow-hidden",get children(){return[q(R,{class:"absolute w-[632] h-[2] bg-slate-200",style:{posType:1,insetL:0,insetT:158}}),q(L,{class:"absolute text-sm text-slate-500 font-bold",style:{posType:1,insetL:174,insetT:72},get children(){return c4().length<2?"COLLECTING 5M VALUE HISTORY":""}}),q(NJ,{get each(){return ZQ()},children:(J)=>q(R,{get["class"](){return j1().positive?"absolute rounded-lg bg-emerald-500":"absolute rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x,insetT:J.y-2,width:J.width,height:4,rotate:J.angle,originX:-0.5,originY:0}}})}),q(NJ,{get each(){return c4()},children:(J)=>q(R,{get["class"](){return j1().positive?"absolute w-[9] h-[9] rounded-lg bg-emerald-500":"absolute w-[9] h-[9] rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x-4,insetT:J.y-4}}})})]}}),q(R,{class:"h-[36] px-1 flex-row items-center justify-between",get children(){return[q(L,{class:"text-sm text-slate-500",get children(){return W1()[0]||""}}),q(L,{class:"text-sm text-slate-500",get children(){return W1()[1]||""}}),q(L,{class:"text-sm text-slate-500",get children(){return W1()[2]||""}})]}})]}})}function UQ(){let J=()=>j1();return q(R,{class:"flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ROBINHOOD"}),q(R,{class:"h-[64] px-6 pt-2",get children(){return q(R,{class:"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(L,{class:"text-sm text-slate-500 font-bold",children:"ACCOUNT"}),q(L,{class:"text-sm text-slate-900 font-bold",get children(){return y().account.label+(y().account.suffix?" ····"+y().account.suffix+" "+(gJ().findIndex((Q)=>Q.number===O0())+1)+"/"+gJ().length:"")+" ›"}})]}})}}),q(R,{class:"h-[304] px-6 pt-3",get children(){return q(R,{class:"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"h-[64] flex-row items-end justify-between",get children(){return[q(L,{class:"text-2xl text-slate-950 font-bold",get children(){return e(y().totalValue)}}),q(L,{get["class"](){return J().positive?"text-base text-emerald-600 font-bold":"text-base text-red-500 font-bold"},get children(){return J().change+" ("+J().percent+")"}})]}}),q(KQ,{})]}})}}),q(R,{class:"h-[60] px-6 pt-2 flex-row gap-3",get children(){return[q(R,{get["class"](){return l()==="day"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(L,{get["class"](){return l()==="day"?"text-sm text-white font-bold":"text-sm text-slate-500 font-bold"},children:"1D"})}}),q(R,{get["class"](){return l()==="week"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(L,{get["class"](){return l()==="week"?"text-sm text-white font-bold":"text-sm text-slate-500 font-bold"},children:"1W"})}}),q(L,{class:"pt-3 text-sm text-slate-500",get children(){return l()==="day"?"TODAY":"PAST WEEK"}})]}}),q(R,{class:"h-[126] px-6 pt-3 flex-row items-start gap-[21]",get children(){return[q(F1,{label:"VALUE",get value(){return y().totalValue}}),q(F1,{label:"CASH",get value(){return y().cash}}),q(F1,{label:"BUY POWER",get value(){return y().buyingPower}})]}}),q(R,{class:"h-[200] px-6 flex-col",get children(){return[q(q6,{title:"ACTIVITY",detail:"LAST 7 DAYS"}),q(R,{class:"h-[150] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(z6,{index:0}),q(z6,{index:1})]}})]}}),q(R,{class:"h-[184] px-6 flex-col",get children(){return[q(q6,{title:"POSITIONS"}),q(R,{class:"h-[136] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(Y6,{index:0}),q(Y6,{index:1})]}})]}}),q(R,{class:"h-[126] px-6 pt-2",get children(){return q(R,{class:"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-col gap-3",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",children:"REALIZED P&L"}),q(L,{class:"text-sm text-slate-500",get children(){return"EQUITIES / "+(l()==="day"?"TODAY":"WEEK")}})]}}),q(L,{get["class"](){return(I0(l()==="day"?y().pnlDay:y().pnlWeek)??0)>=0?"text-xl text-emerald-600 font-bold":"text-xl text-red-500 font-bold"},get children(){return e(l()==="day"?y().pnlDay:y().pnlWeek)}})]}})}}),q(R,{class:"h-[104] px-6 flex-row items-center justify-between",get children(){return[q(L,{get["class"](){return n4().startsWith("REFRESH FAILED")?"w-[460] text-sm text-red-500":"w-[460] text-sm text-slate-500"},get children(){return n4()}}),q(R,{class:"w-[176] h-[64]",get children(){return q(n2,{get label(){return rJ()?"REFRESHING":"REFRESH NOW"},get disabled(){return rJ()}})}})]}})]}})}function B1(){return[q(R,{class:"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",style:{posType:1,insetL:628,insetT:156},get children(){return q(L,{class:"text-sm text-orange-600 font-bold",children:"UP"})}}),q(R,{class:"absolute w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",style:{posType:1,insetL:628,insetT:972},get children(){return q(L,{class:"text-sm text-orange-600 font-bold",children:"DN"})}})]}function MQ(){let J=QJ(()=>gJ().slice(Y1(),Y1()+8)),Q=O0();return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ACCOUNTS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(NJ,{get each(){return J()},children:($)=>q(R,{get["class"](){return $.number===Q?"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100"},get children(){return[q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-lg text-slate-900 font-bold",get children(){return $.label}}),q(L,{class:"text-base text-slate-500 font-bold",get children(){return"····"+$.suffix}})]}}),q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-sm text-emerald-600",get children(){return $.status}}),q(Z0,{get when(){return $.number===Q},get children(){return q(L,{class:"text-sm text-emerald-600 font-bold",children:"SELECTED"})}})]}})]}})})}}),q(B1,{})]}})}function VQ(){let J=QJ(()=>y().activity.slice(i4(),i4()+8));return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"ACTIVITY",metaBottom:"LAST 7 DAYS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[14]",get children(){return q(Z0,{get when(){return HJ(()=>!!y().activityAvailable)()&&J().length>0},get fallback(){return q(R,{class:"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100",get children(){return q(L,{class:"text-base text-slate-500",get children(){return y().activityAvailable?"NO ACTIVITY YET":"ACTIVITY UNAVAILABLE"}})}})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(R,{class:"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-row items-center justify-between",get children(){return[q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q.title}}),q(L,{get["class"](){return Q.side==="SELL"?"text-base text-emerald-600 font-bold":"text-base text-slate-900 font-bold"},get children(){return e(Q.amount)}})]}}),q(L,{class:"text-sm text-slate-500",get children(){return Q.timestamp+" · "+Q.detail}}),q(L,{class:"text-sm text-emerald-600 font-bold",get children(){return Q.state}})]}})})}})}}),q(B1,{})]}})}function PQ(){let J=QJ(()=>y().positions.slice(a4(),a4()+9));return q(R,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(k0,{title:"POSITIONS"}),q(R,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(Z0,{get when(){return HJ(()=>!!y().positionsAvailable)()&&J().length>0},get fallback(){return q(R,{class:"w-[584] h-[150] px-5 justify-center rounded-xl shadow bg-white border-slate-100",get children(){return q(L,{class:"text-base text-slate-500",get children(){return y().positionsAvailable?"NO OPEN POSITIONS":"POSITIONS UNAVAILABLE"}})}})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(R,{class:"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(R,{class:"flex-row items-center",get children(){return[q(L,{class:"w-[170] text-lg text-slate-900 font-bold",get children(){return Q.symbol}}),q(L,{class:"text-base text-slate-900 font-bold",get children(){return Q.quantity+" SH"}})]}}),q(L,{class:"text-sm text-slate-500",get children(){return"AVERAGE COST "+e(Q.averagePrice)+(Q.marketValue?" · VALUE "+e(Q.marketValue):"")}})]}})})}})}}),q(B1,{})]}})}function DQ(){if(i()==="accounts")return q(MQ,{});if(i()==="activity")return q(VQ,{});return q(PQ,{})}function RQ(){return q(Z0,{get when(){return i()==="dashboard"},get fallback(){return q(DQ,{})},get children(){return q(UQ,{})}})}W6(),v2(()=>q(RQ,{})),globalThis.PocketPiApp={tick:HQ,update(){return""},dataChanged(J){let Q=WQ(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),u):u;return W6($),""},invokeTool(J){try{let Q=J==="robinhood.storage_status"?jQ():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Data Action tasks do not run in the View: "+J,isError:!0})},tap(J,Q){if(i()!=="dashboard"){if(Q<112&&J<220)return sJ("dashboard"),"";if(J>=620&&Q>=140&&Q<310){if(i()==="accounts")d4(($)=>Math.max(0,$-1));if(i()==="activity")s4(($)=>Math.max(0,$-1));if(i()==="positions")r4(($)=>Math.max(0,$-1));return""}if(J>=620&&Q>=940&&Q<1130){if(i()==="accounts")d4(($)=>Math.min(Math.max(0,gJ().length-8),$+1));if(i()==="activity")s4(($)=>Math.min(Math.max(0,y().activity.length-8),$+1));if(i()==="positions")r4(($)=>Math.min(Math.max(0,y().positions.length-9),$+1));return""}if(i()==="accounts"&&J<610&&Q>=126){let $=Y1()+Math.floor((Q-126)/112),Z=gJ()[$];if(Z)eJ(()=>{L0(Z.number),sJ("dashboard")}),X6(Z.number,u)}return""}if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(Q>=112&&Q<176)return sJ("accounts"),"";if(Q>=480&&Q<540)return eJ(()=>{$Q(J<136?"day":"week"),Z6(O0(),u)}),"";if(Q>=666&&Q<866)return sJ("activity"),"";if(Q>=866&&Q<1050)return sJ("positions"),"";if(Q>=1176&&J>=500){if(rJ())return"";return o4(!0),ZJ("REFRESHING ROBINHOOD…"),JSON.stringify({type:"invokeTask",task:"refreshPortfolio"})}return""}}})(); + `).all(z,X,J).map((j)=>({time:j.bucket_time,value:k0(j.total_value)})),R=D.map((j)=>j.time),U=D.map((j)=>j.value).filter((j)=>j!==null),H=[R[0],R[9],R[19]].map((j)=>{let G=new Date(j*1000);return u()==="day"?String(G.getHours()).padStart(2,"0")+":"+String(G.getMinutes()).padStart(2,"0"):String(G.getMonth()+1)+"/"+String(G.getDate())});if(U.length===0){let j=u()==="day"?y().pnlDay:y().pnlWeek,G=k0(j),P={points:[],segments:[],labels:H,trend:{change:JJ(j),percent:"—",positive:G===null||G>=0}};j1.set($,{loadedRevision:Q,value:P}),OJ(P.points),LJ(P.segments),z1(P.labels),Y1(P.trend);return}let w=Math.min(...U),x=Math.max(...U),g=Math.max(0.01,x-w),A=D.flatMap((j,G)=>j.value===null?[]:[{x:G*622/19,y:U.length===1?80:10+(x-j.value)*140/g}]),a=A.slice(1).map((j,G)=>{let P=A[G],k=j.x-P.x,_=j.y-P.y;return{x:P.x,y:P.y,width:Math.sqrt(k*k+_*_),angle:Math.atan2(_,k)*180/Math.PI}}),r=U[U.length-1]-U[0],K={change:JJ(String(r)),percent:U[0]===0?"—":(r*100/U[0]).toFixed(2)+"%",positive:r>=0};j1.set($,{loadedRevision:Q,value:{points:A,segments:a,labels:H,trend:K}}),OJ(A),LJ(a),z1(H),Y1(K)}function KQ(J){if(Z6===J)return;let Q=m.query("SELECT status,error,completed_at FROM refresh_runs ORDER BY id DESC LIMIT 1").get();if(J6(!1),Q?.status==="failed")XJ("REFRESH FAILED · "+String(Q.error||"UNKNOWN ERROR").slice(0,52));else if(Q?.status==="partial")XJ("LIVE WITH PARTIAL DATA");else if(y().observedAt)XJ("LIVE / READ ONLY · "+W6(y().observedAt));else XJ("WAITING FOR ROBINHOOD");Z6=J}function z6(J,Q){if(!J){if(aJ(iJ),OJ([]),LJ([]),!rJ())XJ("WAITING FOR ROBINHOOD");return}let $=H1.get(J);if($?.loadedRevision===Q){if(aJ($.value),q6(J,Q),$.value.observedAt&&!rJ())XJ("LIVE / READ ONLY · "+W6($.value.observedAt));return}aJ(iJ),OJ([]),LJ([])}function Y6(J=p){try{let Q=m.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==i4){W1([]),I0(""),aJ(iJ),OJ([]),LJ([]),XJ("WAITING FOR ROBINHOOD");return}eJ(()=>{p=Math.max(p,J);let $=gJ();if(Q6!==p)$=jQ(),W1($),Q6=p;FQ(p,$);let Z=L0();if(!$.some((X)=>X.number===Z))Z=$[0]?.number||"",I0(Z);z6(Z,p),KQ(p)})}catch{eJ(()=>{W1([]),I0(""),aJ(iJ),OJ([]),LJ([]),XJ("WAITING FOR ROBINHOOD")})}}function UQ(){return""}function MQ(){let J=m.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((z)=>z.name)),$=J.map((z)=>{let F=m.query("SELECT COUNT(*) AS count FROM "+z.name).get().count;return{name:z.name,rowCount:F,schema:z.sql}}),Z=Q.has("refresh_runs")?m.query("SELECT id,started_at,completed_at,operation_count,success_count,status,error FROM refresh_runs ORDER BY id DESC LIMIT 3").all():[],X=Q.has("portfolio_current")?m.query("SELECT substr(account_number,-4) AS account_suffix,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current ORDER BY observed_at DESC LIMIT 4").all():[],W=Q.has("total_value")?m.query("SELECT substr(account_number,-4) AS account_suffix,observed_at,value FROM total_value ORDER BY observed_at DESC LIMIT 8").all():[];return{database:"robinhood.sqlite",schemaVersion:i4,tables:$,latestRefreshes:Z,latestPortfolios:X,latestValues:W}}function F1(){return GQ()}function _0(J){return q(n2,{get title(){return J.title},back:!0,metaTop:"READ ONLY",get metaBottom(){return J.metaBottom??"AUTO · 5 MIN"}})}function B1(J){return q(V,{class:"w-[210] h-[104]",get children(){return q(e2,{get label(){return J.label},get value(){return JJ(J.value)}})}})}function G6(J){return q(o2,{get title(){return J.title},get detail(){return J.detail},action:!0})}function PQ(J){if(J===0&&!y().activityAvailable)return ZQ;return y().activity[J]??(J===0?Z1:XQ)}function H6(J){let Q=()=>PQ(J.index);return q(V,{class:"h-[72] px-5 flex-row items-center justify-between",get children(){return[q(V,{class:"w-[450] flex-col gap-2",get children(){return[q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q().title}}),q(O,{class:"text-base text-slate-500",get children(){return l(()=>!!Q().timestamp)()?Q().timestamp+" · "+Q().detail:""}})]}}),q(O,{get["class"](){return Q().side==="SELL"?"text-base text-emerald-600 font-bold":"text-base text-slate-900 font-bold"},get children(){return l(()=>!!Q().amount)()?JJ(Q().amount):""}})]}})}function VQ(J){if(J===0&&!y().positionsAvailable)return WQ;return y().positions[J]??(J===0?X1:qQ)}function j6(J){let Q=()=>VQ(J.index);return q(V,{class:"h-[64] px-5 flex-row items-center",get children(){return[q(O,{class:"w-[240] text-lg text-slate-900 font-bold",get children(){return Q().symbol}}),q(O,{class:"w-[156] text-base text-slate-500",get children(){return l(()=>!!Q().quantity)()?Q().quantity+" SH":""}}),q(O,{class:"text-base text-slate-500",get children(){return l(()=>!!Q().averagePrice)()?"AVG "+JJ(Q().averagePrice):""}})]}})}function DQ(){return q(V,{class:"relative w-[632] h-[196] flex-col",get children(){return[q(V,{class:"relative w-[632] h-[160] overflow-hidden",get children(){return[q(V,{class:"absolute w-[632] h-[2] bg-slate-200",style:{posType:1,insetL:0,insetT:158}}),q(O,{class:"absolute text-base text-slate-500 font-bold",style:{posType:1,insetL:152,insetT:72},get children(){return s4().length<2?"COLLECTING 5M VALUE HISTORY":""}}),q(NJ,{get each(){return YQ()},children:(J)=>q(V,{get["class"](){return F1().positive?"absolute rounded-lg bg-emerald-500":"absolute rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x,insetT:J.y-1,width:J.width,height:2,rotate:J.angle,originX:-0.5,originY:0}}})}),q(NJ,{get each(){return s4()},children:(J)=>q(V,{get["class"](){return F1().positive?"absolute w-[6] h-[6] rounded-lg bg-emerald-500":"absolute w-[6] h-[6] rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x-3,insetT:J.y-3}}})})]}}),q(V,{class:"h-[36] px-1 flex-row items-center justify-between",get children(){return[q(O,{class:"text-base text-slate-500",get children(){return q1()[0]||""}}),q(O,{class:"text-base text-slate-500",get children(){return q1()[1]||""}}),q(O,{class:"text-base text-slate-500",get children(){return q1()[2]||""}})]}})]}})}function RQ(){let J=()=>F1();return q(V,{class:"flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ROBINHOOD"}),q(V,{class:"h-[64] px-6 pt-2",get children(){return q(V,{class:"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(O,{class:"text-base text-slate-500 font-bold",children:"ACCOUNT"}),q(O,{class:"text-base text-slate-900 font-bold",get children(){return y().account.label+(y().account.suffix?" ····"+y().account.suffix+" "+(gJ().findIndex((Q)=>Q.number===L0())+1)+"/"+gJ().length:"")+" ›"}})]}})}}),q(V,{class:"h-[304] px-6 pt-3",get children(){return q(V,{class:"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"h-[64] flex-row items-end justify-between",get children(){return[q(O,{class:"text-2xl text-slate-950 font-bold",get children(){return JJ(y().totalValue)}}),q(O,{get["class"](){return J().positive?"text-lg text-emerald-600 font-bold":"text-lg text-red-500 font-bold"},get children(){return J().change+" ("+J().percent+")"}})]}}),q(DQ,{})]}})}}),q(V,{class:"h-[60] px-6 pt-2 flex-row gap-3",get children(){return[q(V,{get["class"](){return u()==="day"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(O,{get["class"](){return u()==="day"?"text-base text-white font-bold":"text-base text-slate-500 font-bold"},children:"1D"})}}),q(V,{get["class"](){return u()==="week"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(O,{get["class"](){return u()==="week"?"text-base text-white font-bold":"text-base text-slate-500 font-bold"},children:"1W"})}}),q(O,{class:"pt-3 text-base text-slate-500",get children(){return u()==="day"?"TODAY":"PAST WEEK"}})]}}),q(V,{class:"h-[126] px-6 pt-3 flex-row items-start gap-[21]",get children(){return[q(B1,{label:"VALUE",get value(){return y().totalValue}}),q(B1,{label:"CASH",get value(){return y().cash}}),q(B1,{label:"BUY POWER",get value(){return y().buyingPower}})]}}),q(V,{class:"h-[200] px-6 flex-col",get children(){return[q(G6,{title:"ACTIVITY",detail:"LAST 7 DAYS"}),q(V,{class:"h-[150] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(H6,{index:0}),q(H6,{index:1})]}})]}}),q(V,{class:"h-[184] px-6 flex-col",get children(){return[q(G6,{title:"POSITIONS"}),q(V,{class:"h-[136] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(j6,{index:0}),q(j6,{index:1})]}})]}}),q(V,{class:"h-[126] px-6 pt-2",get children(){return q(V,{class:"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-col gap-3",get children(){return[q(O,{class:"text-xl text-slate-900 font-bold",children:"REALIZED P&L"}),q(O,{class:"text-base text-slate-500",get children(){return"EQUITIES / "+(u()==="day"?"TODAY":"WEEK")}})]}}),q(O,{get["class"](){return(k0(u()==="day"?y().pnlDay:y().pnlWeek)??0)>=0?"text-2xl text-emerald-600 font-bold":"text-2xl text-red-500 font-bold"},get children(){return JJ(u()==="day"?y().pnlDay:y().pnlWeek)}})]}})}}),q(V,{class:"h-[104] px-6 flex-row items-center justify-between",get children(){return[q(V,{class:"w-[460] h-[64]",get children(){return q(JQ,{get text(){return e4()},get tone(){return e4().startsWith("REFRESH FAILED")?"danger":"neutral"}})}}),q(V,{class:"w-[176] h-[64]",get children(){return q(t2,{get label(){return rJ()?"REFRESHING":"REFRESH NOW"},get disabled(){return rJ()}})}})]}})]}})}function K1(){return q(QQ,{top:"absolute left-[628] top-[156] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",bottom:"absolute left-[628] top-[972] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100"})}function OQ(){let J=$J(()=>gJ().slice(G1(),G1()+8)),Q=L0();return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ACCOUNTS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(NJ,{get each(){return J()},children:($)=>q(V,{get["class"](){return $.number===Q?"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100"},get children(){return[q(V,{class:"flex-row items-center justify-between",get children(){return[q(O,{class:"text-xl text-slate-900 font-bold",get children(){return $.label}}),q(O,{class:"text-lg text-slate-500 font-bold",get children(){return"····"+$.suffix}})]}}),q(V,{class:"flex-row items-center justify-between",get children(){return[q(V,{get["class"](){return c4.success.surface},get children(){return q(O,{get["class"](){return c4.success.text},get children(){return $.status}})}}),q(Z0,{get when(){return $.number===Q},get children(){return q(O,{class:"text-base text-emerald-600 font-bold",children:"SELECTED"})}})]}})]}})})}}),q(K1,{})]}})}function LQ(){let J=$J(()=>y().activity.slice(r4(),r4()+8));return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ACTIVITY",metaBottom:"LAST 7 DAYS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[14]",get children(){return q(Z0,{get when(){return l(()=>!!y().activityAvailable)()&&J().length>0},get fallback(){return q(d4,{get title(){return y().activityAvailable?"NO ACTIVITY YET":"ACTIVITY UNAVAILABLE"},compact:!0})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(V,{class:"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-row items-center justify-between",get children(){return[q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q.title}}),q(O,{get["class"](){return Q.side==="SELL"?"text-lg text-emerald-600 font-bold":"text-lg text-slate-900 font-bold"},get children(){return JJ(Q.amount)}})]}}),q(O,{class:"text-base text-slate-500",get children(){return Q.timestamp+" · "+Q.detail}}),q(O,{class:"text-base text-emerald-600 font-bold",get children(){return Q.state}})]}})})}})}}),q(K1,{})]}})}function IQ(){let J=$J(()=>y().positions.slice(o4(),o4()+9));return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"POSITIONS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(Z0,{get when(){return l(()=>!!y().positionsAvailable)()&&J().length>0},get fallback(){return q(d4,{get title(){return y().positionsAvailable?"NO OPEN POSITIONS":"POSITIONS UNAVAILABLE"},compact:!0})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(V,{class:"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-row items-center",get children(){return[q(O,{class:"w-[170] text-xl text-slate-900 font-bold",get children(){return Q.symbol}}),q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q.quantity+" SH"}})]}}),q(O,{class:"text-base text-slate-500",get children(){return"AVERAGE COST "+JJ(Q.averagePrice)+(Q.marketValue?" · VALUE "+JJ(Q.marketValue):"")}})]}})})}})}}),q(K1,{})]}})}function kQ(){if(s()==="accounts")return q(OQ,{});if(s()==="activity")return q(LQ,{});return q(IQ,{})}function _Q(){return q(Z0,{get when(){return s()==="dashboard"},get fallback(){return q(kQ,{})},get children(){return q(RQ,{})}})}Y6(),u2(()=>q(_Q,{})),globalThis.PocketPiApp={tick:UQ,update(){return""},dataChanged(J){let Q=HQ(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),p):p;return Y6($),""},invokeTool(J){try{let Q=J==="robinhood.storage_status"?MQ():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Data Action tasks do not run in the View: "+J,isError:!0})},tap(J,Q){if(s()!=="dashboard"){if(Q<112&&J<220)return sJ("dashboard"),"";if(J>=620&&Q>=140&&Q<310){if(s()==="accounts")a4(($)=>Math.max(0,$-1));if(s()==="activity")n4(($)=>Math.max(0,$-1));if(s()==="positions")t4(($)=>Math.max(0,$-1));return""}if(J>=620&&Q>=940&&Q<1130){if(s()==="accounts")a4(($)=>Math.min(Math.max(0,gJ().length-8),$+1));if(s()==="activity")n4(($)=>Math.min(Math.max(0,y().activity.length-8),$+1));if(s()==="positions")t4(($)=>Math.min(Math.max(0,y().positions.length-9),$+1));return""}if(s()==="accounts"&&J<610&&Q>=126){let $=G1()+Math.floor((Q-126)/112),Z=gJ()[$];if(Z)eJ(()=>{I0(Z.number),sJ("dashboard")}),z6(Z.number,p)}return""}if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(Q>=112&&Q<176)return sJ("accounts"),"";if(Q>=480&&Q<540)return eJ(()=>{zQ(J<136?"day":"week"),q6(L0(),p)}),"";if(Q>=666&&Q<866)return sJ("activity"),"";if(Q>=866&&Q<1050)return sJ("positions"),"";if(Q>=1176&&J>=500){if(rJ())return"";return J6(!0),XJ("REFRESHING ROBINHOOD…"),JSON.stringify({type:"invokeTask",task:"refreshPortfolio"})}return""}}})(); diff --git a/apps/robinhood/dist/app.pak b/apps/robinhood/dist/app.pak index 7ed2f2c8332a1d0e76998d6174cd457155e6d34c..3dc252f68e0fb1b37ad2619a697e41e3c098c531 100644 GIT binary patch delta 19561 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 diff --git a/docs/pocket-pi-design-system.md b/docs/pocket-pi-design-system.md index c18d5b1..1a0091d 100644 --- a/docs/pocket-pi-design-system.md +++ b/docs/pocket-pi-design-system.md @@ -1,54 +1,58 @@ -# Pocket Pi Design System inventory +# Pi Design component inventory -状态:v0.1,刻意保持小型。这里记录哪些 UI 已经成为 Pocket Pi 全局设计语言, -避免在单个 App 中复制后再逐渐漂移。 +状态:v0.2。Pi Design 是 Pocket Pi 的全局视觉语言;内置 App 不再各自维护一套 +Header、按钮、空状态或字号层级。 -实现位于 `apps/_shared/ui.tsx` 和 `apps/_shared/text.ts`。它只能依赖 PocketJS framework primitives,不能 -调用 ESP-IDF、Pocket Pi Rust 私有接口、网络或 SQLite。App-specific data binding -和交互仍由各 App 自己拥有。 +实现位于 `apps/_shared/ui.tsx` 和 `apps/_shared/text.ts`。共享层只能依赖 +PocketJS framework primitives,不能调用 ESP-IDF、Pocket Pi Rust 私有接口、 +网络、SQLite 或 App navigation。所有业务数据和 side effect 仍由 App 提供。 -## v0.1 tokens +## Foundations -| Token group | 当前内容 | 使用范围 | +| Foundation | 包含 | 当前规则 | | --- | --- | --- | -| `type` | title、section、body、bodyStrong、caption | Pi Agent、Robinhood | -| `space` | 24px screen gutter、card padding、stack gap | Pi Agent、Robinhood | -| semantic colors | slate shell/surfaces、orange primary、green ready/positive、red error | shared components | -| dynamic prose glyphs | curly quotes、en/em dash、ellipsis、bullet | model/provider text | - -当前统一使用 PocketJS bundle 内的 Inter font atlas;v0.1 只统一字号、字重和行文 -层级,不新增字体或 native font API。`text.ts` 的 glyph seed 只让常见动态英文标点 -进入现有 subset atlas,不引入第二套字体或 runtime font loader。 - -## v0.1 components - -| Component | 责任 | 明确不负责 | -| --- | --- | --- | -| `PocketHeader` | 112px system header、title、back/status affordance、两行 metadata | App data、navigation side effects | -| `SectionHeading` | section title、optional detail/action label | list/query behavior | -| `ActionButton` | primary/disabled visual state、minimum touch surface supplied by caller | 执行动作 | -| `wrapLines` / `wrapPreview` | 用 PocketJS `measureText` 给动态文本插入显式换行,并缓存测量结果 | rich text、Markdown、滚动状态 | - -Card 在 v0.1 只记录为视觉 recipe:`rounded-xl + white + slate border + shadow`。 -当前 PocketJS/Solid Guest 对跨模块传递 arbitrary children 的 generic wrapper 仍会 -产生额外 runtime 风险,因此 App 直接在自己的 `View` literal 上使用这组样式;不 -为“组件化”保留一层不稳定 wrapper。 - -## 仍然属于 App 的组件 - -- Pi Agent conversation turn、Bottom Navigation、keyboard、Files row; -- Robinhood 20-point chart、time-range selector、account selector、portfolio metric、 - activity row、position row; -- Exa search-history projection。 - -只有至少两个 App 需要、语义稳定、并且能完全建立在 PocketJS public UI contract -之上的组件,才进入 Design System。 - -## 演进规则 - -1. 每次抽出或删除 component/token,都更新本 inventory 和 consumer。 -2. v1 仍由 TS/TSX 编译为各 App 的 `app.js`/`app.pak`。 -3. 未来 declarative View schema 只能组合 inventory 中明确注册的稳定组件;在 - schema 和校验边界被单独设计前,不在当前 runtime 中加入 interpreter。 -4. Marketplace 或独立 SDK 真正出现后,再把该目录提取为版本化组件包;当前不 - 预先实现 package registry、compatibility resolver 或 runtime download。 +| `type` | app title、page title、heading、label、body、caption | ESP 主阅读文本由 14/16px 提升到 16/18px;24px title 保持不变 | +| `space` | 24px screen gutter、card padding、stack gap | 720x1280 screen density | +| `surface` | card、selected card、row、muted、shell recipes | arbitrary children 的容器保持 literal View,不增加不稳定 wrapper | +| `Tone` | neutral、info、success、warning、danger | 统一背景色、文字色和状态语义 | +| dynamic glyphs | curly quotes、en/em dash、ellipsis、bullet | 进入现有 Inter subset atlas | + +PocketJS 当前只提供 12 / 14 / 16 / 18 / 20 / 24 / 36px 的 baked font +slots。Pi Design 的“稍微放大”因此采用相邻 slot:caption/label 14→16px, +body 16→18px;不会引入 runtime font loader 或第二套字体。 + +## Components + +| Component | 包含什么 | 不包含什么 | 当前使用者 | +| --- | --- | --- | --- | +| `PocketHeader` | 112px shell header、back/status affordance、App title、两行 metadata | navigation side effect、App data loading | Pi Agent、Exa、Robinhood | +| `PageIntro` | eyebrow、page title、一行说明 | 页面 query、filter、scroll | Exa | +| `SectionHeading` | section title、optional detail、optional `VIEW ALL` affordance | list data、tap behavior | Robinhood | +| `ActionButton` | primary/neutral/danger/disabled visual state、统一 18px label | action execution、loading state machine | Pi Agent、Robinhood | +| `statusBadge` recipe | 短 label 的 neutral/info/success/warning/danger surface + text classes | 长状态文案、业务判断 | Exa result、Robinhood account status | +| `EmptyState` | optional icon、title、detail、regular/compact layout | empty 条件、retry action | Exa、Robinhood | +| `MetricCard` | metric label、formatted value、optional positive/negative tone | 数值计算、currency formatting、time range | Robinhood value/cash/buying power | +| `StatusBar` | 单行 runtime status、neutral/error tone、light/dark surface | log history、progress model、retry | Exa SQLite state、Robinhood refresh state | +| `ScrollButtons` | UP/DN controls 的统一文字和视觉 | offset、pagination、tap hit testing | Pi Agent、Robinhood | +| `wrapLines` / `wrapPreview` | `measureText` 缓存、显式换行、preview ellipsis | rich text、Markdown、scroll state | Pi Agent dynamic text | + +## App-owned components + +这些组件仍含明确业务语义,不进入 Pi Design: + +- Pi Agent conversation turn、Bottom Navigation、keyboard、Files row、App row; +- Robinhood 20-point chart、time-range selector、account picker、activity row、 + position row、P&L projection; +- Exa search-history query、result projection 和 retention state。 + +如果一个模式仅在一个 App 中出现,或需要知道 Robinhood account / Exa result +schema,它先留在 App。只有语义稳定、可复用且完全建立在 PocketJS public UI +contract 上,才进入 Pi Design。 + +## Evolution rules + +1. 每次新增、删除或改变 component/token,都同步更新本 inventory 和 consumers。 +2. 共享 component 是纯展示函数:props in,native View/Text tree out。 +3. App 自己决定数据、loading/error 条件、tap hitbox、navigation 和 side effects。 +4. v1 仍由 TS/TSX 编译进各 App 的 `app.js` / `app.pak`;Marketplace/SDK 出现后 + 再提取为版本化 package,不预先实现 registry 或 runtime download。 From 24772282fa3cbf1de99ee991925b254651843aa2 Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Tue, 11 Aug 2026 12:17:11 +0800 Subject: [PATCH 09/24] feat(agentos): add deferred app tools and persistent workers Expose the checked-in Robinhood catalog through deferred lookup, keep Exa and Robinhood projections bounded, and return completed App Tool results without duplicate payloads. Reuse the embedded model worker and HTTPS client, refresh generated bundles, and align the AgentOS architecture documentation with the implemented runtime. --- README.md | 2 +- apps/exa/agent-app.json | 125 +- apps/exa/app.tsx | 99 +- apps/exa/data-action.ts | 123 +- apps/exa/dist/app.js | 17 +- apps/exa/dist/app.pak | Bin 280336 -> 280336 bytes apps/exa/dist/data-action.js | 49 +- apps/exa/pocket.json | 2 +- apps/pi-agent/dist/agent.js | 4 +- apps/robinhood/TOOLS.md | 112 + apps/robinhood/agent-app.json | 159 +- apps/robinhood/app.tsx | 8 +- apps/robinhood/data-action.ts | 270 ++- apps/robinhood/dist/app.js | 4 +- apps/robinhood/dist/data-action.js | 231 +- apps/robinhood/tool-catalog.json | 1849 +++++++++++++++++ crates/pocket-pi-agentos/src/lib.rs | 282 ++- .../pocket-pi-embedded/js/pi-agent.bundle.js | 4 +- crates/pocket-pi-embedded/js/src/entry.ts | 2 +- crates/pocket-pi-embedded/src/lib.rs | 106 +- crates/pocket-pi-protocols/src/model.rs | 4 +- docs/agentos-architecture.md | 272 ++- firmware/esp32-p4/src/agentos_main.rs | 24 +- firmware/esp32-p4/src/app_services.rs | 29 +- firmware/esp32-p4/src/backend/wireless.rs | 98 +- hosts/esp32-p4-sim/src/main.rs | 29 +- 26 files changed, 3299 insertions(+), 605 deletions(-) create mode 100644 apps/robinhood/TOOLS.md create mode 100644 apps/robinhood/tool-catalog.json diff --git a/README.md b/README.md index 56d1791..da0e126 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ the embedded Agent. Provider request/streaming codecs live in `pocket-pi-protocols`; serial framing, desktop CLIs and ESP-IDF HTTPS stay in their platform layers. -DeepSeek defaults to `deepseek-v4-pro` with thinking level `high`. Set +DeepSeek defaults to `deepseek-v4-flash` with thinking level `high`. Set `DEEPSEEK_THINKING_LEVEL=xhigh` in the simulator, or pass `--thinking-level xhigh` while provisioning the physical board, to request the provider's `max` reasoning effort. diff --git a/apps/exa/agent-app.json b/apps/exa/agent-app.json index 864800b..95e2d26 100644 --- a/apps/exa/agent-app.json +++ b/apps/exa/agent-app.json @@ -1,11 +1,126 @@ { "id": "exa", - "version": "1.0.0", - "dataVersion": 4, + "version": "1.1.0", + "dataVersion": 5, "tools": [ - {"name":"research.search","description":"Search the web through Exa, return bounded source-linked highlights, and save the search to local history.","parameters":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":2000},"numResults":{"type":"integer","minimum":1,"maximum":8},"searchType":{"type":"string","enum":["auto","fast","instant"]},"includeDomains":{"type":"array","items":{"type":"string"},"maxItems":8},"excludeDomains":{"type":"array","items":{"type":"string"},"maxItems":8}},"required":["query"],"additionalProperties":false}}, - {"name":"research.fetch","description":"Fetch a bounded research document through Exa and save it as the latest opened document.","parameters":{"type":"object","properties":{"url":{"type":"string","maxLength":2048},"maxCharacters":{"type":"integer","minimum":200,"maximum":12000}},"required":["url"],"additionalProperties":false}}, - {"name":"research.storage_status","description":"Return compact local SQLite counts, space usage, 7-day retention policy, and latest run status without contacting Exa.","parameters":{"type":"object","properties":{},"additionalProperties":false}} + { + "name": "research.search", + "description": "Search the web through Exa and save a bounded, source-linked result set to local history. Pocket Pi defaults to auto so Exa can balance quality and speed; explicitly use deep or deep-reasoning for harder research, and fast or instant when latency matters. Use category and publication dates for targeted news, filings, company, or publication research. company and people categories cannot be combined with publication-date filters or excludeDomains.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "minLength": 1, + "maxLength": 2000, + "description": "Natural-language web search query. Put the research question here; use the dedicated filter fields instead of site: or date syntax." + }, + "numResults": { + "type": "integer", + "minimum": 1, + "maximum": 10, + "description": "Number of results to return. Defaults to Exa's standard 10-result page." + }, + "searchType": { + "type": "string", + "enum": ["auto", "fast", "instant", "deep-lite", "deep", "deep-reasoning"], + "description": "Exa search mode. auto is the default and balances quality and speed; deep modes increase research depth, latency, and cost." + }, + "category": { + "type": "string", + "enum": ["company", "publication", "news", "personal site", "financial report", "people"], + "description": "Optional Exa content category. Use financial report for filings and reports, news for current reporting, publication for papers, and company for official company pages." + }, + "includeDomains": { + "type": "array", + "items": {"type": "string", "minLength": 1, "maxLength": 255}, + "maxItems": 8, + "description": "Only return these domains or domain paths, for example sec.gov or investor.example.com." + }, + "excludeDomains": { + "type": "array", + "items": {"type": "string", "minLength": 1, "maxLength": 255}, + "maxItems": 8, + "description": "Exclude these domains or domain paths. Do not combine with company or people category." + }, + "startPublishedDate": { + "type": "string", + "minLength": 10, + "maxLength": 35, + "description": "Only return sources published at or after this ISO 8601 date or date-time, for example 2026-01-01." + }, + "endPublishedDate": { + "type": "string", + "minLength": 10, + "maxLength": 35, + "description": "Only return sources published at or before this ISO 8601 date or date-time." + }, + "userLocation": { + "type": "string", + "minLength": 2, + "maxLength": 2, + "description": "Optional two-letter ISO country code such as US for geographically relevant results." + }, + "additionalQueries": { + "type": "array", + "items": {"type": "string", "minLength": 1, "maxLength": 2000}, + "minItems": 1, + "maxItems": 10, + "description": "Optional query variations used only with deep-lite, deep, or deep-reasoning to broaden research." + }, + "maxAgeHours": { + "type": "integer", + "minimum": -1, + "maximum": 720, + "description": "Maximum cached content age in hours: 0 forces a fresh crawl, -1 uses cache only, and omission uses Exa's normal fallback policy." + }, + "moderation": { + "type": "boolean", + "description": "Ask Exa to filter unsafe content from search results." + } + }, + "required": ["query"], + "additionalProperties": false + } + }, + { + "name": "research.fetch", + "description": "Fetch one known URL through Exa as bounded clean text with metadata and crawl status. Use after research.search when highlights are insufficient. Set maxAgeHours to 0 only when a fresh crawl is necessary because it is slower and costs more.", + "parameters": { + "type": "object", + "properties": { + "url": { + "type": "string", + "minLength": 1, + "maxLength": 2048, + "description": "Exact HTTP or HTTPS URL returned by search or supplied by the user." + }, + "maxCharacters": { + "type": "integer", + "minimum": 200, + "maximum": 12000, + "description": "Maximum clean-text characters returned and saved. Defaults to 6000." + }, + "maxAgeHours": { + "type": "integer", + "minimum": -1, + "maximum": 720, + "description": "Maximum cached content age in hours: 0 forces a fresh crawl, -1 uses cache only, and omission uses Exa's normal fallback policy." + } + }, + "required": ["url"], + "additionalProperties": false + } + }, + { + "name": "research.storage_status", + "description": "Return compact local SQLite counts, space usage, the 7-day retention policy, and latest search status without contacting Exa.", + "parameters": { + "type": "object", + "properties": {}, + "additionalProperties": false + } + } ], "tasks": [], "schedules": [] diff --git a/apps/exa/app.tsx b/apps/exa/app.tsx index b40ee70..b1a38e8 100644 --- a/apps/exa/app.tsx +++ b/apps/exa/app.tsx @@ -1,17 +1,23 @@ -import { createSignal, For, Show } from "solid-js"; +import { createSignal, Show } from "solid-js"; import { Text, View } from "@pocketjs/framework/components"; import { mount } from "@pocketjs/framework"; import { Database } from "@pocketjs/framework/db"; +import { VirtualList } from "@pocketjs/framework/virtual-list"; import { EmptyState, PageIntro, PocketHeader, statusBadge, StatusBar } from "../_shared/ui"; -const DB_SCHEMA_VERSION = 4; +const DB_SCHEMA_VERSION = 5; const RETENTION_DAYS = 7; +const HISTORY_PAGE_SIZE = 10; +const HISTORY_ROW_HEIGHT = 138; +const HISTORY_VIEWPORT_HEIGHT = 890; const db = new Database("exa"); -type SearchRow = { id: number; query: string; searched_at: number; status: string; result_count: number; top_title: string | null; top_url: string | null; error: string | null }; +type SearchRow = { id: number; query: string; searched_at: number; status: string; result_count: number; top_title: string | null; error: string | null }; const [history, setHistory] = createSignal([]); +const [hasMore, setHasMore] = createSignal(false); const [status, setStatus] = createSignal("SEARCH HISTORY IS LOCAL"); let loadedRevision = -1; +let loadingMore = false; function parse(value: string): any { try { return JSON.parse(value); } catch { return null; } } @@ -20,23 +26,39 @@ function searchTime(seconds: number): string { return value.slice(0, 10) + " · " + value.slice(11, 16) + " UTC"; } +function historyPage(offset: number): SearchRow[] { + return db.query(` + SELECT id,query,searched_at,status,result_count,top_title,error + FROM searches ORDER BY id DESC LIMIT ? OFFSET ? + `).all(HISTORY_PAGE_SIZE + 1, offset) as unknown as SearchRow[]; +} + +function loadMore() { + if (loadingMore || !hasMore()) return; + loadingMore = true; + try { + const next = historyPage(history().length); + setHistory((current) => [...current, ...next.slice(0, HISTORY_PAGE_SIZE)]); + setHasMore(next.length > HISTORY_PAGE_SIZE); + } finally { + loadingMore = false; + } +} + function loadView(revision: number) { if (loadedRevision === revision) return; try { const schema = db.query("PRAGMA user_version").get() as unknown as { user_version?: number } | null; if (Number(schema?.user_version ?? 0) !== DB_SCHEMA_VERSION) { setHistory([]); + setHasMore(false); setStatus("SEARCH HISTORY IS LOCAL"); return; } - const next = db.query(` - SELECT search.id,search.query,search.searched_at,search.status,search.result_count, - result.title AS top_title,result.url AS top_url,search.error - FROM searches search - LEFT JOIN search_results result ON result.search_id=search.id AND result.rank=0 - ORDER BY search.id DESC LIMIT 8 - `).all() as unknown as SearchRow[]; + const page = historyPage(0); + const next = page.slice(0, HISTORY_PAGE_SIZE); setHistory(next); + setHasMore(page.length > HISTORY_PAGE_SIZE); setStatus(next[0]?.status === "error" ? String(next[0].error || "EXA SEARCH FAILED").slice(0, 80) : next.length ? "SEARCH HISTORY UPDATED FROM SQLITE" : "SEARCH HISTORY IS LOCAL"); loadedRevision = revision; @@ -47,30 +69,23 @@ function loadView(revision: number) { } function storageStatus(): { text: string; details: any } { - const tableRows = db.query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").all() as unknown as Array<{ name: string }>; - const names = new Set(tableRows.map((table) => table.name)); - const count = (table: string): number => names.has(table) - ? Number((db.query(`SELECT COUNT(*) AS count FROM ${table}`).get() as unknown as { count?: number } | null)?.count ?? 0) - : 0; const pageSize = Number((db.query("PRAGMA page_size").get() as unknown as { page_size?: number } | null)?.page_size ?? 0); const pageCount = Number((db.query("PRAGMA page_count").get() as unknown as { page_count?: number } | null)?.page_count ?? 0); const freelistCount = Number((db.query("PRAGMA freelist_count").get() as unknown as { freelist_count?: number } | null)?.freelist_count ?? 0); const schemaVersion = Number((db.query("PRAGMA user_version").get() as unknown as { user_version?: number } | null)?.user_version ?? 0); - const latestSearch = names.has("searches") ? db.query(` + const searches = schemaVersion === DB_SCHEMA_VERSION + ? Number((db.query("SELECT COUNT(*) AS count FROM searches").get() as unknown as { count?: number } | null)?.count ?? 0) + : 0; + const latestSearch = schemaVersion === DB_SCHEMA_VERSION ? db.query(` SELECT id,searched_at,status,result_count,error FROM searches ORDER BY id DESC LIMIT 1 `).get() : null; - const tableCounts = { - searches: count("searches"), - searchResults: count("search_results"), - documents: count("documents"), - }; const details = { database: "exa.sqlite", schemaVersion, expectedSchemaVersion: DB_SCHEMA_VERSION, retentionDays: RETENTION_DAYS, - tableCounts, + searches, allocatedBytes: pageSize * pageCount, reusableBytes: pageSize * freelistCount, latestSearch, @@ -80,7 +95,7 @@ function storageStatus(): { text: string; details: any } { ? ` Latest #${latest.id ?? "?"}: ${latest.status ?? "unknown"}, ${latest.result_count ?? 0} results.` : " No searches yet."; return { - text: `Exa storage (schema ${schemaVersion}/${DB_SCHEMA_VERSION}): ${tableCounts.searches} searches, ${tableCounts.searchResults} results, ${tableCounts.documents} documents; ${RETENTION_DAYS}-day retention; ${details.allocatedBytes} bytes allocated (${details.reusableBytes} reusable).${latestText}`, + text: `Exa storage (schema ${schemaVersion}/${DB_SCHEMA_VERSION}): ${searches} searches; ${RETENTION_DAYS}-day retention; ${details.allocatedBytes} bytes allocated (${details.reusableBytes} reusable).${latestText}`, details, }; } @@ -95,7 +110,7 @@ function Exa() { description="Every research.search call is saved here automatically." tone="info" /> - + - {(item) => ( - - - {item.query.slice(0, 60)} - {(item.top_title || item.error || "No result title").slice(0, 76)} - {searchTime(item.searched_at)} - - - {item.status === "ok" ? item.result_count + " RESULTS" : "FAILED"} - - - )} + 0}> + { + const item = () => history()[index]; + return ( + + + {item().query.slice(0, 60)} + {(item().top_title || item().error || "No result title").slice(0, 76)} + {searchTime(item().searched_at)} + + + {item().status === "ok" ? item().result_count + " RESULTS" : "FAILED"} + + + ); + }} + /> + diff --git a/apps/exa/data-action.ts b/apps/exa/data-action.ts index cfa7856..8a70468 100644 --- a/apps/exa/data-action.ts +++ b/apps/exa/data-action.ts @@ -1,14 +1,15 @@ -// Headless Exa data plane. Search and document responses are normalized into -// App-owned domain rows before one transaction invalidates the View cache. +// Headless Exa data plane. Only search history consumed by the fixed View is +// persisted; fetched documents are returned directly to the Agent. import { __pumpNet, fetch } from "@pocketjs/framework/net"; const nativeDb = (globalThis as any).db; const handle = nativeDb.open("exa"); if (handle < 0) throw new Error("open exa.sqlite"); -const SCHEMA_VERSION = 4; +const SCHEMA_VERSION = 5; const RETENTION_DAYS = 7; const RETENTION_SECONDS = RETENTION_DAYS * 24 * 60 * 60; +const HTTP_TIMEOUT_MS = 60_000; function dbError(): string { return String(nativeDb.lastError(handle) || "SQLite operation failed"); } function exec(sql: string): void { if (nativeDb.exec(handle, sql) !== 0) throw new Error(dbError()); } @@ -22,63 +23,25 @@ function run(sql: string, args: any[] = []): any { return query(sql, args); } const version = query("PRAGMA user_version") as { user_version?: number } | null; if (Number(version?.user_version ?? 0) !== SCHEMA_VERSION) { exec(` - DROP TABLE IF EXISTS search_results; DROP TABLE IF EXISTS searches; - DROP TABLE IF EXISTS documents; CREATE TABLE searches ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - query TEXT NOT NULL, - searched_at INTEGER NOT NULL, - status TEXT NOT NULL, - result_count INTEGER NOT NULL DEFAULT 0, - error TEXT - ); - CREATE INDEX searches_retention ON searches(searched_at); - CREATE TABLE search_results ( - search_id INTEGER NOT NULL, - rank INTEGER NOT NULL, - title TEXT, - url TEXT NOT NULL, - published_at TEXT, - author TEXT, - score TEXT, - highlight TEXT, - PRIMARY KEY(search_id, rank) - ); - CREATE TABLE documents ( - url TEXT PRIMARY KEY, - fetched_at INTEGER NOT NULL, - title TEXT, - published_at TEXT, - author TEXT, - text TEXT NOT NULL - ); - CREATE INDEX documents_recent ON documents(fetched_at DESC); - PRAGMA user_version=4; + id INTEGER PRIMARY KEY AUTOINCREMENT, + query TEXT NOT NULL, + searched_at INTEGER NOT NULL, + status TEXT NOT NULL, + result_count INTEGER NOT NULL DEFAULT 0, + top_title TEXT, + error TEXT + ); + CREATE INDEX searches_retention ON searches(searched_at); + PRAGMA user_version=${SCHEMA_VERSION}; `); } function now(): number { return Math.floor(Date.now() / 1000); } function cleanupExpired(referenceTime: number): void { const cutoff = referenceTime - RETENTION_SECONDS; - run("DELETE FROM search_results WHERE search_id IN (SELECT id FROM searches WHERE searched_at < ?)", [cutoff]); run("DELETE FROM searches WHERE searched_at < ?", [cutoff]); - run("DELETE FROM documents WHERE fetched_at < ?", [cutoff]); -} -function text(value: unknown): string | null { - return value === null || value === undefined || typeof value === "object" ? null : String(value); -} -function firstText(value: any, names: string[]): string | null { - if (!value || typeof value !== "object") return null; - for (const name of names) { - const found = text(value[name]); - if (found !== null) return found; - } - return null; -} -function highlight(value: any): string | null { - if (Array.isArray(value?.highlights)) return value.highlights.map(String).join("\n").slice(0, 1200); - return firstText(value, ["highlight", "summary", "text"])?.slice(0, 1200) ?? null; } async function post(path: "/search" | "/contents", body: any): Promise { @@ -86,7 +49,7 @@ async function post(path: "/search" | "/contents", body: any): Promise { method: "POST", headers: { accept: "application/json", "content-type": "application/json" }, body: JSON.stringify(body), - timeoutMs: 12_000, + timeoutMs: HTTP_TIMEOUT_MS, maxBytes: 96 * 1024, }); const value = await response.json(); @@ -114,29 +77,24 @@ async function search(args: any): Promise { const body: any = { query: searchQuery, type: args.searchType ?? "auto", - numResults: Math.max(1, Math.min(8, Number(args.numResults ?? 5))), + numResults: Math.max(1, Math.min(10, Number(args.numResults ?? 10))), contents: { highlights: { maxCharacters: 800 } }, }; - for (const key of ["includeDomains", "excludeDomains", "startPublishedDate", "endPublishedDate"]) { + for (const key of [ + "includeDomains", "excludeDomains", "startPublishedDate", "endPublishedDate", + "category", "userLocation", "additionalQueries", "moderation", + ]) { if (args[key] !== undefined) body[key] = args[key]; } + if (args.maxAgeHours !== undefined) body.contents.maxAgeHours = args.maxAgeHours; const value = await post("/search", body); - const results = Array.isArray(value?.results) ? value.results.slice(0, 8) : []; + const results = Array.isArray(value?.results) ? value.results : []; + const topTitle = typeof results[0]?.title === "string" ? results[0].title : null; transaction(() => { - const inserted = run( - "INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,?,NULL)", - [searchQuery, searchedAt, "ok", results.length], + run( + "INSERT INTO searches(query,searched_at,status,result_count,top_title,error) VALUES(?,?,?,?,?,NULL)", + [searchQuery, searchedAt, "ok", results.length, topTitle], ); - const searchId = Number(inserted.lastInsertRowid || 0); - results.forEach((item: any, rank: number) => { - const url = firstText(item, ["url", "id"]); - if (!url) return; - run( - `INSERT INTO search_results(search_id,rank,title,url,published_at,author,score,highlight) - VALUES(?,?,?,?,?,?,?,?)`, - [searchId, rank, firstText(item, ["title"]), url, firstText(item, ["publishedDate", "published_at", "date"]), firstText(item, ["author"]), firstText(item, ["score"]), highlight(item)], - ); - }); cleanupExpired(searchedAt); }); return value; @@ -144,7 +102,7 @@ async function search(args: any): Promise { const message = error instanceof Error ? error.message : String(error); transaction(() => { run( - "INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,0,?)", + "INSERT INTO searches(query,searched_at,status,result_count,top_title,error) VALUES(?,?,?,0,NULL,?)", [searchQuery, searchedAt, "error", message], ); cleanupExpired(searchedAt); @@ -156,34 +114,15 @@ async function search(args: any): Promise { async function fetchDocument(args: any): Promise { const requestedUrl = String(args.url ?? "").trim(); if (!requestedUrl) throw new Error("url is required"); - const response = await post("/contents", { + const request: any = { urls: [requestedUrl], text: { maxCharacters: Math.max(200, Math.min(12000, Number(args.maxCharacters ?? 6000))), includeHtmlTags: false, }, - }); - const document = Array.isArray(response?.results) ? response.results[0] : response; - if (!document) throw new Error("Exa returned no document"); - const url = firstText(document, ["url", "id"]) || requestedUrl; - const body = firstText(document, ["text", "content", "summary"]) || ""; - const fetchedAt = now(); - transaction(() => { - run( - `INSERT INTO documents(url,fetched_at,title,published_at,author,text) VALUES(?,?,?,?,?,?) - ON CONFLICT(url) DO UPDATE SET fetched_at=excluded.fetched_at,title=excluded.title, - published_at=excluded.published_at,author=excluded.author,text=excluded.text`, - [url, fetchedAt, firstText(document, ["title"]), firstText(document, ["publishedDate", "published_at", "date"]), firstText(document, ["author"]), body], - ); - cleanupExpired(fetchedAt); - }); - return { - status: "ok", - provider: "exa", - requestId: response?.requestId, - document, - costDollars: response?.costDollars, }; + if (args.maxAgeHours !== undefined) request.maxAgeHours = args.maxAgeHours; + return post("/contents", request); } let pendingResult: string | undefined; @@ -202,7 +141,7 @@ function begin(action: () => Promise): void { pendingResult = undefined; action().then( (value) => { - pendingResult = JSON.stringify({ text: JSON.stringify(value), details: value, isError: false }); + pendingResult = JSON.stringify({ text: JSON.stringify(value), isError: false }); active = false; }, (error) => { diff --git a/apps/exa/dist/app.js b/apps/exa/dist/app.js index b1ad9ca..c089969 100644 --- a/apps/exa/dist/app.js +++ b/apps/exa/dist/app.js @@ -1,12 +1,9 @@ -(()=>{var MJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return l0(this.context.count)},getNextContextId(){return l0(this.context.count++)}};function l0(J){let Q=String(J),$=Q.length-1;return MJ.context.id+($?String.fromCharCode(96+$):"")+Q}function c0(J){MJ.context=J}function O4(){return{...MJ.context,id:MJ.getNextContextId(),count:0}}var L4=!1,C4=(J,Q)=>J===Q,q0=Symbol("solid-proxy"),I4=typeof Proxy==="function",k4=Symbol("solid-track"),U2=Symbol("solid-dev-component"),TJ={equals:C4},p0=null,A4=n0,E=1,IJ=2,i0={owned:null,cleanups:null,context:null,owner:null},I=null,B=null,kJ=null,UJ=null,k=null,S=null,f=null,EJ=0;function NJ(J,Q){let $=k,Z=I,X=J.length===0,W=Q===void 0?Z:Q,q=X?i0:{owned:null,cleanups:null,context:W?W.context:null,owner:W},G=X?J:()=>J(()=>o(()=>n(q)));I=q,k=null;try{return i(G,!0)}finally{k=$,I=Z}}function AJ(J,Q){Q=Q?Object.assign({},TJ,Q):TJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return a0($,X)};return[s0.bind($),Z]}function r(J,Q,$){let Z=o0(J,Q,!1,E);if(kJ&&B&&B.running)S.push(Z);else vJ(Z)}function VJ(J,Q,$){$=$?Object.assign({},TJ,$):TJ;let Z=o0(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,kJ&&B&&B.running)Z.tState=E,S.push(Z);else vJ(Z);return s0.bind(Z)}function o(J){if(!UJ&&k===null)return J();let Q=k;k=null;try{if(UJ)return UJ.untrack(J);return J()}finally{k=Q}}function z0(J){if(I===null);else if(I.cleanups===null)I.cleanups=[J];else I.cleanups.push(J);return J}function S4(J){if(B&&B.running)return J(),B.done;let Q=k,$=I;return Promise.resolve().then(()=>{k=Q,I=$;let Z;if(kJ||y4)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return i(J,!1),k=I=null,Z?Z.done:void 0})}var[V2,d0]=AJ(!1),y4;function s0(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===E)vJ(this);else{let Q=S;S=null,i(()=>mJ(this),!1),S=Q}if(k){let Q=this.observers;if(!Q||Q[Q.length-1]!==k){let $=Q?Q.length:0;if(!k.sources)k.sources=[this],k.sourceSlots=[$];else k.sources.push(this),k.sourceSlots.push($);if(!Q)this.observers=[k],this.observerSlots=[k.sources.length-1];else Q.push(k),this.observerSlots.push(k.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function a0(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)i(()=>{for(let X=0;X1e6)throw S=[],Error()},!1)}return Q}function vJ(J){if(!J.fn)return;n(J);let Q=EJ;if(r0(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{i(()=>{B&&(B.running=!0),k=I=J,r0(J,J.tValue,Q),k=I=null},!1)})}function r0(J,Q,$){let Z,X=I,W=k;k=I=J;try{Z=J.fn(Q)}catch(q){if(J.pure)if(B&&B.running)J.tState=E,J.tOwned&&J.tOwned.forEach(n),J.tOwned=void 0;else J.state=E,J.owned&&J.owned.forEach(n),J.owned=null;return J.updatedAt=$+1,H0(q)}finally{k=W,I=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)a0(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function o0(J,Q,$,Z=E,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:I,context:I?I.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(I===null);else if(I!==i0)if(B&&B.running&&I.pure)if(!I.tOwned)I.tOwned=[W];else I.tOwned.push(W);else if(!I.owned)I.owned=[W];else I.owned.push(W);if(UJ&&W.fn){let q=W.fn,[G,M]=AJ(void 0,{equals:!1}),U=UJ.factory(q,M);z0(()=>U.dispose());let V,H=()=>S4(M).then(()=>{if(V)V.dispose(),V=void 0});W.fn=(L)=>{if(G(),B&&B.running){if(!V)V=UJ.factory(q,H);return V.track(L)}return U.track(L)}}return W}function G0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===IJ)return mJ(J);if(J.suspense&&o(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===E)vJ(J);else if((Q?J.tState:J.state)===IJ){let X=S;S=null,i(()=>mJ(J,$[0]),!1),S=X}}}function i(J,Q){if(S)return J();let $=!1;if(!Q)S=[];if(f)$=!0;else f=[];EJ++;try{let Z=J();return _4($),Z}catch(Z){if(!$)f=null;S=null,H0(Z)}}function _4(J){if(S){if(kJ&&B&&B.running)h4(S);else n0(S);S=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;f.push.apply(f,B.effects),Q=B.resolve;for(let W of f)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,i(()=>{for(let W of X)n(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let q=0,G=W.owned.length;qA4($),!1);if(Q)Q()}function n0(J){for(let Q=0;Q{Z.delete($),i(()=>{B.running=!0,G0($)},!1),B&&(B.running=!1)})}}function mJ(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)n(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)e0(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)n(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function e0(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return z0(()=>Q1(W)),()=>{let M=J()||[],U=M.length,V,H;return M[k4],o(()=>{let y,h,c,XJ,BJ,F,j,z,P;if(U===0){if(q!==0)Q1(W),W=[],Z=[],X=[],q=0,G&&(G=[]);if($.fallback)Z=[f4],X[0]=NJ((O)=>{return W[0]=O,$.fallback()}),q=1}else if(q===0){X=Array(U);for(H=0;H=F&&z>=F&&Z[j]===M[z];j--,z--)c[z]=X[j],XJ[z]=W[j],G&&(BJ[z]=G[j]);y=new Map,h=Array(z+1);for(H=z;H>=F;H--)P=M[H],V=y.get(P),h[H]=V===void 0?-1:V,y.set(P,H);for(V=F;V<=j;V++)if(P=Z[V],H=y.get(P),H!==void 0&&H!==-1)c[H]=X[V],XJ[H]=W[V],G&&(BJ[H]=G[V]),H=h[H],y.set(P,H);else W[V]();for(H=F;HJ(Q||{}));return c0($),Z}}return o(()=>J(Q||{}))}function uJ(){return!0}var E4={get(J,Q,$){if(Q===q0)return $;return J.get(Q)},has(J,Q){if(Q===q0)return!0;return J.has(Q)},set:uJ,deleteProperty:uJ,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:uJ,deleteProperty:uJ}},ownKeys(J){return J.keys()}};function j0(J){return!(J=typeof J==="function"?J():J)?{}:J}function N4(){for(let J=0,Q=this.length;J=0;G--){let M=j0(J[G])[q];if(M!==void 0)return M}},has(q){for(let G=J.length-1;G>=0;G--)if(q in j0(J[G]))return!0;return!1},keys(){let q=[];for(let G=0;G=0;q--){let G=J[q];if(!G)continue;let M=Object.getOwnPropertyNames(G);for(let U=M.length-1;U>=0;U--){let V=M[U];if(V==="__proto__"||V==="constructor")continue;let H=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=H.get?{enumerable:!0,configurable:!0,get:N4.bind($[V]=[H.get.bind(G)])}:H.value!==void 0?H:void 0;else{let L=$[V];if(L){if(H.get)L.push(H.get.bind(G));else if(H.value!==void 0)L.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let q=W.length-1;q>=0;q--){let G=W[q],M=Z[G];if(M&&M.get)Object.defineProperty(X,G,M);else X[G]=M?M.value:void 0}return X}var v4=(J)=>`Stale read from <${J}>.`;function m4(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return VJ(b4(()=>J.each,J.children,Q||void 0))}function u4(J){let Q=J.keyed,$=VJ(()=>J.when,void 0,void 0),Z=Q?$:VJ($,void 0,{equals:(X,W)=>!X===!W});return VJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?o(()=>W(Q?X:()=>{if(!o(Z))throw v4("Show");return $()})):W}return J.fallback},void 0,void 0)}var l4=(J)=>VJ(()=>J());function c4({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:q,getParentNode:G,getFirstChild:M,getNextSibling:U}){function V(F,j,z,P){if(z!==void 0&&!P)P=[];if(typeof j!=="function")return H(F,j,P,z);r((O)=>H(F,j(),O,z),P)}function H(F,j,z,P,O){while(typeof z==="function")z=z();if(j===z)return z;let C=typeof j,w=P!==void 0;if(C==="string"||C==="number"){if(C==="number")j=j.toString();if(w){let R=z[0];if(R&&$(R))Z(R,j);else R=Q(j);z=h(F,z,P,R)}else if(z!==""&&typeof z==="string")Z(M(F),z=j);else h(F,z,P,Q(j)),z=j}else if(j==null||C==="boolean")z=h(F,z,P);else if(C==="function")return r(()=>{let R=j();while(typeof R==="function")R=R();z=H(F,R,z,P)}),()=>z;else if(Array.isArray(j)){let R=[];if(L(R,j,O))return r(()=>z=H(F,R,z,P,!0)),()=>z;if(R.length===0){let CJ=h(F,z,P);if(w)return z=CJ}else if(Array.isArray(z))if(z.length===0)c(F,R,P);else y(F,z,R);else if(z==null||z==="")c(F,R);else y(F,w&&z||[M(F)],R);z=R}else{if(Array.isArray(z)){if(w)return z=h(F,z,P,j);h(F,z,null,j)}else if(z==null||z===""||!M(F))X(F,j);else XJ(F,j,M(F));z=j}return z}function L(F,j,z){let P=!1;for(let O=0,C=j.length;Op-R){let M2=j[w];while(R=0;w--){let R=j[w];if(O!==R){let CJ=G(R)===F;if(!C&&!w)CJ?XJ(F,O,R):X(F,O,z);else CJ&&W(F,R)}else C=!0}}else X(F,O,z);return[O]}function c(F,j,z){for(let P=0,O=j.length;Pz.children=H(F,j.children,z.children));return r(()=>j.ref&&j.ref(F)),r(()=>{for(let O in j){if(O==="children"||O==="ref")continue;let C=j[O];if(C===z[O])continue;q(F,O,C,z[O]),z[O]=C}}),z}return{render(F,j){let z;return NJ((P)=>{z=P,V(j,F())}),z},insert:V,spread(F,j,z){if(typeof j==="function")r((P)=>BJ(F,j(),P,z));else BJ(F,j,void 0,z)},createElement:J,createTextNode:Q,insertNode:X,setProp(F,j,z,P){return q(F,j,z,P),z},mergeProps:$1,effect:r,memo:l4,createComponent:T4,use(F,j,z){return o(()=>F(j,z))}}}function p4(J){let Q=c4(J);return Q.mergeProps=$1,Q}var Z1=480,X1=272,WJ={view:0,text:1,image:2},i4=1,d4=-1,s4={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},K={f32:0,color:1,int:2},a4={width:K.f32,height:K.f32,minW:K.f32,minH:K.f32,maxW:K.f32,maxH:K.f32,paddingT:K.f32,paddingR:K.f32,paddingB:K.f32,paddingL:K.f32,marginT:K.f32,marginR:K.f32,marginB:K.f32,marginL:K.f32,gap:K.f32,flexDir:K.int,justify:K.int,align:K.int,grow:K.f32,shrink:K.f32,basis:K.f32,flexWrap:K.int,posType:K.int,insetT:K.f32,insetR:K.f32,insetB:K.f32,insetL:K.f32,display:K.int,overflow:K.int,zIndex:K.int,hitPass:K.int,bgColor:K.color,gradFrom:K.color,gradTo:K.color,gradDir:K.int,radius:K.f32,opacity:K.f32,borderColor:K.color,borderWidth:K.f32,shadow:K.int,bevelOuterLight:K.color,bevelOuterDark:K.color,bevelInnerLight:K.color,bevelInnerDark:K.color,bevelWidth:K.f32,textColor:K.color,fontSlot:K.int,textAlign:K.int,lineHeight:K.f32,tracking:K.f32,translateX:K.f32,translateY:K.f32,scale:K.f32,rotate:K.f32,scaleX:K.f32,scaleY:K.f32,originX:K.f32,originY:K.f32,rotateX:K.f32,rotateY:K.f32,translateZ:K.f32,perspective:K.f32,arcStart:K.f32,arcSweep:K.f32,arcWidth:K.f32},N={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},r4={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},o4=1,P2=2,R2=1,w2=2,D2=131072,O2=1,L2=262144,C2=1,I2=1,k2=1,A2=2,S2=4,y2=8,_2=16,h2=1,x2=2;function W1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var f2=1,n4=1263551300,t4=1,e4=32,J6=24,m={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},YJ=32896,b2=0.016666666666666666;function Y1(J){return J.__viewport??null}var B0=null;function Q6(){return null}function q1(J,Q=Q6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function $6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return q1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return q1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function Z6(J){B0=J}function PJ(){if(!B0)throw Error("PocketJS: host not installed — call render() first");return B0}function _(){return PJ().ops}function X6(J){globalThis.frame=J}function W6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function Y6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return W1($>>>16&255,$>>>8&255,$&255,255);return W1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function q6(J,Q){let $=a4[J];if(typeof Q==="string"){if($===K.color)return Y6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===K.color||$===K.int)return Q>>>0;return Q}var lJ=60,z1=[1,2,3,4,5,6,10,12,15,20,30,60],F0=lJ,t=-1,z6=0,SJ=[];function G6(J){if(!Number.isFinite(J)||J<=0)return lJ;let Q=z1[0];for(let $ of z1)if(Math.abs($-J)Q.at<=t).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;SJ=SJ.filter((Q)=>Q.at>t);for(let Q of J)Q.cb()}var K0=0.12,cJ=YJ;function F6(J){cJ=J===void 0?YJ:J&65535}function K6(){cJ=YJ}function j1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function U6(){return j1(cJ&255)}var B1=new Set,V6=0;function P6(){B1.clear(),V6=0,K6()}function R6(J){for(let Q of[...B1])Q(J)}var qJ=null,F1=null;function w6(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function K1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function yJ(J){M0();let Q=qJ?qJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return F1.slice(Q.off,Q.off+Q.len)}var _J=null,A=null,zJ=null,pJ=0,GJ=[],V0=[],P0=[];function U1(J){if(_J=J,A=null,zJ=null,pJ=0,GJ.length=0,V0.length=0,P0.length=0,v){if(v.pressTarget=null,v.target=null,v.spriteDirty=!0,v.fresh=!0,v.vw=0,v.tex>=0){let Q=_();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(v.tex),v.tex=-1}}}function O6(J,Q){J.onPress=Q??void 0}function L6(J,Q){if(J.focusable=Q,D1(),!Q&&A===J)T(null)}function T(J){if(zJ&&zJ!==J)HJ(null);A=J,_().setFocus(J?J.id:0)}function HJ(J){if(zJ===J)return;let Q=_();if(zJ)Q.setActive?.(zJ.id,0);if(zJ=J,J)Q.setActive?.(J.id,1)}function R0(){return GJ.length>0?GJ[GJ.length-1]:_J}function w0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;T($[X])}function k6(){if(!A)return null;let J=R0();if(J&&!u(A,J))return null;for(let Q=V0.length-1;Q>=0;Q--){let $=V0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function A6(J){let Q=k6();if(!Q)return!1;let $=[];if(w0(Q.node,$),$.length===0){if(A)T(null);return!0}let Z=Q.columns,X=A?$.indexOf(A):-1;if(X<0)return T(V1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)T($[W]);return!0}function S6(){if(!A)return null;let J=R0();if(J&&!u(A,J))return null;for(let Q=P0.length-1;Q>=0;Q--){let $=P0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function iJ(J){let Q=S6();if(Q&&Q.move(J))return;if(A6(J))return;I6(J)}function P1(){R1(A)}function R1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function dJ(J){HJ(J)}function y6(J){T(J),R1(J)}function u(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function D0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=D0(Q.children[X]);if(W){T(W);return}}let Z=Q;while(Z){if(Z.focusable){T(Z);return}Z=Z.parent}}T(null)}var v=null,w1=0;function D1(){w1++}var h6=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],x6=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function f6(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=h6[Q]>>$&1,X=x6[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,q=X?255:0;J[W]=q,J[W+1]=q,J[W+2]=q,J[W+3]=255}return J}function b6(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=yJ($.image)}catch(q){if(PJ().strict)throw q;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):g6(Q,W),X<0&&PJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(f6(),16,16,r4.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function g6(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&o4)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function sJ(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=sJ($[Z],Q);if(X)return X}return null}var aJ=null;function O1(J){aJ=J}function L1(J){let Q=GJ.length>0?GJ[GJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||u($,Q)))return $;$=$.parent}return null}function C1(J,Q,$){return L1(I1(J,Q,$))}function I1(J,Q,$){if($!==void 0)return $===0?null:sJ(aJ??_J,$);let Z=_(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return sJ(aJ??_J,X(J,Q))}function T6(J,Q,$){let Z=v,X=_();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=Y1(X);if(Z.vw=H?H.w:Z1,Z.vh=H?H.h:X1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)b6(Z,X);let W=M6()*Z.speed,q=U6()*Z.speed;if(Z.dpadSpeed>0&&W===0&&q===0){if(J&m.LEFT)W=-Z.dpadSpeed;if(J&m.RIGHT)W=Z.dpadSpeed;if(J&m.UP)q=-Z.dpadSpeed;if(J&m.DOWN)q=Z.dpadSpeed}let G=Z.fresh;if(W!==0||q!==0){let H=H6()/60,L=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),y=Math.min(Math.max(Z.y+q*H,0),Z.vh-1);if(L!==Z.x||y!==Z.y)Z.x=L,Z.y=y,G=!0}if(G)X.setCursorPos(Z.x,Z.y);let M=(Q|$)&Z.button,U=w1;if(G||M!==0||U!==Z.gen)Z.gen=U,Z.fresh=!1,Z.target=L1(sJ(aJ??_J,X.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==A)T(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(HJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=V===Z.pressTarget;if(Z.pressTarget=null,HJ(null),H)P1()}}else if($&Z.button)HJ(null);return!0}function E6(J){let Q=J&~pJ,$=pJ&~J;if(pJ=J,v&&T6(J,Q,$))return;if($&m.CIRCLE)HJ(null);if(Q===0)return;if(Q&m.DOWN)iJ("down");if(Q&m.RIGHT)iJ("right");if(Q&m.UP)iJ("up");if(Q&m.LEFT)iJ("left");if(Q&m.CIRCLE)HJ(A),P1()}var O0=null;function k1(J){O0=J}function RJ(){if(D1(),O0)O0()}function N6(J,Q){J.debugName=Q||void 0,RJ()}var e={id:i4,type:WJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},A1=Symbol.for("pocketjs.native-node"),L0=1,hJ=3,d=8,v6=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function rJ(J){return J.domAttrs??={}}function S1(J,Q){let $=J.domNodeType??(xJ(J)?hJ:L0),Z=$===hJ?oJ(J.text??""):$===d?l6(J.domData??""):g1(J.domTag??tJ(J));for(let X of Object.keys(J.domAttrs??{}))C0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)JJ(Z,S1(X,!0));return Z}function C0(J,Q,$){if(v6.has(Q)){DJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete rJ(J)[Q];else rJ(J)[Q]=$}function I0(J){if(J[A1]===!0)return J;return Object.defineProperty(J,A1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(xJ(J)?hJ:L0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else nJ(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else nJ(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===d)return J.domData??"";if(xJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===d)J.domData=Z;else if(xJ(J))nJ(J,Z);else if(r6(J),Z)JJ(J,oJ(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return E1(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??tJ(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===hJ)return"#text";if(J.domNodeType===d)return"#comment";return(J.domTag??tJ(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){DJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===e)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return JJ(J,$),$},insertBefore($,Z){return JJ(J,$,Z??null),$},removeChild($){return fJ(J,$),$},replaceChild($,Z){return JJ(J,$,Z),fJ(J,Z),Z},cloneNode($=!1){return S1(J,!!$)},remove(){if(J.parent)fJ(J.parent,J)},setAttribute($,Z){C0(J,$,Z)},removeAttribute($){C0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}I0(e);var k0=null;function m6(J){k0=J}var A0={unknownClass:0,unknownTexture:0},y1=new Map;function _1(J,Q){y1.set(J,Q)}var h1=new Map;function x1(J,Q){h1.set(J,Q)}var wJ=new Set,u6=new Set;function f1(J){if(!J)return!1;if(u6.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return I0({id:_().createNode(Q),type:Q,parent:null,children:[],domNodeType:L0,domTag:J})}function oJ(J){let Q=_(),$=Q.createNode(WJ.text);return Q.setText($,J),I0({id:$,type:WJ.text,parent:null,children:[],text:J,domNodeType:hJ,domTag:"#text"})}function l6(J=""){let Q=oJ("");return Q.domNodeType=d,Q.domTag="#comment",Q.domData=J,Q}function nJ(J,Q){_().replaceText(J.id,Q),J.text=Q,RJ()}function xJ(J){return J.type===WJ.text}function T1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function JJ(J,Q,$){let Z=_();if(T1(Q),wJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,RJ()}function fJ(J,Q){if(!Q)return;_6(Q),_().removeChild(J.id,Q.id),T1(Q),wJ.add(Q),RJ()}function c6(J){return J.parent??void 0}function p6(J){return J.children[0]}function E1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function i6(J,Q){let $=_();if(RJ(),Q==null||Q===""){$.setStyle(J.id,d4);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=k0?k0(Q):void 0;if(Z===void 0){if(PJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);A0.unknownClass++;return}$.setStyle(J.id,Z)}function d6(J,Q){let $=_();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=y1.get(Q);if(Z===void 0){if(PJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);A0.unknownTexture++;return}$.setImage(J.id,Z)}function s6(J,Q){let $=_();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=h1.get(Q);if(Z===void 0){if(PJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);A0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function a6(J,Q,$){let Z=_(),X=Q??{},W=$??{},q=!1;for(let G in X){let M=X[G];if(W[G]===M)continue;let U=s4[G];if(U===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,U,q6(G,M)),q=!0}if(q)RJ()}function DJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete rJ(J)[Q];else rJ(J)[Q]=$;switch(Q){case"class":return i6(J,$),$;case"onPress":case"on:press":return O6(J,$),$;case"src":return d6(J,$),$;case"sprite":return s6(J,$),$;case"style":return a6(J,$,Z),$;case"focusable":return L6(J,!!$),$;case"debugName":return N6(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${tJ(J)}>`)}function r6(J){for(let Q of[...J.children])fJ(J,Q)}function tJ(J){for(let Q of Object.keys(WJ))if(WJ[Q]===J.type)return Q;return String(J.type)}function o6(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}DJ(J,Q,$,Z)}var n6=p4({createElement:g1,createTextNode:oJ,replaceText:nJ,isTextNode:xJ,setProperty:o6,insertNode(J,Q,$){JJ(J,Q,$)},removeNode(J,Q){fJ(J,Q)},getParentNode:c6,getFirstChild:p6,getNextSibling:E1}),{render:t6,effect:g2,memo:s,createComponent:D,createElement:N1,insert:T2,spread:e6,mergeProps:E2,use:N2}=n6,v2={linear:N.Easing.Linear,in:N.Easing.EaseIn,out:N.Easing.EaseOut,"in-out":N.Easing.EaseInOut,"out-back":N.Easing.OutBack,spring:N.Easing.Spring,"spring-bouncy":N.Easing.SpringBouncy},J8=null;function v1(J){J8=J}function Q8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function m1(J,Q){let $=N1(J);return e6($,Q,!1),Q8(Q.nodeRef,$),$}function b(J){return m1("view",J)}function x(J){return m1("text",J)}var m2=new WeakMap,u2=new WeakMap,$8={}!==null?Object.freeze({...{}}):Object.freeze({}),l2=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:$8}),c2=new Map,QJ=36000,S0=30,Z8=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(QJ),tapeAnalog:new Uint16Array(QJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-S0,saidHello:!1,hostCalls:0};function X8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-S0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)k1(()=>{Y.treeDirty=!0}),B8();else k1(null);globalThis.__pocketDevtools=K8}function W8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)q8(),H8();let W=Q,q=$===void 0?YJ:$&65535,G=Z,M=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(QJ).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==YJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function c1(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,q]of J)Z.fill(W,X,Math.min(X+q,$)),X+=q;return Z}function p1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return c1(J.masks,0,Q)}function i1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return c1(J.analog??[],YJ,Q)}function d1(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,g({t:"hello",app:Y.app,host:F8(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` -`))if(X.trim())z8(X)}}function z8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)g({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),y0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),y0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":s1();break;case"eval":{let Z=!0,X;try{X=eJ((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}g({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":g({t:"tape",tape:l1()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}g({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())g({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else g({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=p1(Z),Y.replayAnalog=Z.analog?i1(Z):null,Y.replayTouch=Z.touch?d1(Z):null,Y.replayAt=0;break}default:break}}function G8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=S0)s1();if(Y.frame%Z8===0)y0()}function H8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,g({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,g({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function y0(){g({t:"stats",frame:Y.frame,nodes:o1(e),tapeLen:Y.tapeLen,paused:Y.paused})}function s1(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,g({t:"tree",frame:Y.frame,root:r1(e)})}function j8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function _0(J,Q){if(Array.isArray(J)){for(let $ of J)_0($,Q);return}if(j8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)_0($,Q)}}function a1(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)_0(Z,Q)}function r1(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(a1(J,(X)=>{if(X.domNodeType===8)return;Z.push(r1(X))}),Z.length)Q.k=Z;return Q}function o1(J){let Q=1;return a1(J,($)=>{Q+=o1($)}),Q}function B8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{g({t:"log",level:$,args:X.map((W)=>eJ(W))}),Z?.apply(Q,X)}}}function eJ(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?n1(W):JSON.stringify(n1(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((q)=>eJ(q,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,q])=>`${W}: ${eJ(q,Q+1)}`).join(", ")}}`}function n1(J){return J.length>200?J.slice(0,199)+"…":J}function F8(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var K8={get frame(){return Y.frame},dumpTape:()=>l1(),replay:(J)=>{Y.replayMasks=p1(J),Y.replayAnalog=J.analog?i1(J):null,Y.replayTouch=J.touch?d1(J):null,Y.replayAt=0}},t1=new Map,h0=new Map;function e1(J){return J.trim().replace(/\s+/g," ")}function J4(J){return J.split(" ").sort().join(" ")}var Q4=-1;function M8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=e1(Q);t1.set(Z,$);let X=J4(Z),W=h0.get(X);h0.set(X,W!==void 0&&W!==$?Q4:$)}}function U8(J){let Q=e1(J),$=t1.get(Q);if($!==void 0)return $;let Z=h0.get(J4(Q));return Z===Q4?void 0:Z}var x0=9,V8=(1<{let X=($&R8)!==0,W=X?f0:x0,q=X?w8:V8;return Object.freeze({id:$>>>(X?D8:P8)&255,x:$&q,y:$>>>W&q,hit:Q?.[Z]})}))}function L8(){return J0}function C8(){J0=b0}var $4=8,$J=8,I8=3,k8=8,A8=6,S8=0.5,l=1,bJ=2,g0=4,jJ=8,OJ=[],Z4=0,Q0=0,ZJ=Array.from({length:$4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array($J),histY:new Int16Array($J),histHead:0,histLen:0,owners:[],claimedBy:null}));function y8(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function _8(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=I1(Q,$,Z.fact);let G=Z.hit;if(G)return y8(G,W)}let q=X.rect?.();if(!q)return!1;return Q>=q.x&&Q=q.y&&$=0;q--){let G=OJ[q];if(G.disposed)continue;if(Z4>0&&!G.opts.allowWhenBlocked)continue;if(!_8(G,$,Z,W))continue;G.flags[J.slot]=l,J.owners.push(G)}for(let q of J.owners)q.opts.onDown?.(J)}function f8(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%$J,J.histLen<$J)J.histLen++;let Z=Math.min(I8,J.histLen-1);if(Z<=0){J.vx=0,J.vy=0;return}let X=G1(),W=(J.histHead-1+$J)%$J,q=(W-Z+$J)%$J;J.vx=(J.histX[W]-J.histX[q])*X/Z,J.vy=(J.histY[W]-J.histY[q])*X/Z}function b8(J){let Q=J.fdx!==0||J.fdy!==0,$=J.dx<0?-J.dx:J.dx,Z=J.dy<0?-J.dy:J.dy;for(let X of J.owners){let W=X.flags[J.slot];if(!(W&l))continue;if(Q)X.opts.onMove?.(J);let q=X.opts.tapSlop??k8;if(!(W&bJ)&&($>q||Z>q))X.flags[J.slot]|=bJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&l)||W&(bJ|g0))continue;if(!X.opts.onLongPress)continue;let q=Math.max(1,Math.round((X.opts.longPressSeconds??S8)*G1()));if(J.frames=0)OJ.splice($,1)},cancel(){if(!Q.disposed)Y4(Q)},get panning(){for(let $ of ZJ)if($.used&&Q.flags[$.slot]&jJ)return!0;return!1}}}function N8(J){let Q=E8(J);return z0(()=>Q.dispose()),Q}function q4(){OJ.length=0,Z4=0,Q0=0;for(let J of ZJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function v8(){return N8({onDown:(J)=>{let Q=C1(J.x,J.y,J.hit);if(Q)dJ(Q)},onTap:(J)=>{dJ(null);let Q=C1(J.x,J.y,J.hit);if(Q)y6(Q)},onUp:()=>dJ(null),onCancel:()=>dJ(null)})}var m8=1,T0=new Map,$0=[];function u8(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function l8(){m8=1,T0.clear(),$0=[]}function c8(){if($0.length===0)return;let J=$0;$0=[];for(let{id:Q,result:$}of J){let Z=T0.get(Q);if(!Z)continue;T0.delete(Q),u8()?.({t:"delivery",frame:H1(),id:Q,kind:Z.kind}),Z.onResult($)}}var z4=new Set;function p8(){if(z4.size===0)return;for(let J of z4)J()}var i8={"flex-col w-full h-full bg-slate-50":0,"grow px-6 pt-4 flex-col gap-3":1,"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":2,"w-[474] flex-col gap-2":3,"text-lg text-slate-900 font-bold":4,"text-base text-slate-500":5,"text-base text-indigo-600 font-bold":6,"h-[96]":7,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":8,"absolute inset-0 z-50 flex-col items-center justify-center":9,"absolute inset-0 bg-slate-950":10,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":11,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":12,"flex-row flex-wrap":13,grow:14,"text-2xl text-white font-bold":15,"text-2xl text-slate-950 font-bold":16,"text-xl text-slate-900 font-bold":17,"text-base text-slate-600 font-bold":18,"text-lg text-slate-900":19,"text-base text-slate-500 font-bold":20,"px-6":21,"px-6 py-5":22,"gap-4":23,"rounded-xl shadow bg-white border-slate-100":24,"rounded-xl shadow bg-emerald-100 border-emerald-500":25,"bg-white":26,"bg-slate-100":27,"bg-slate-950":28,"px-3 py-2 rounded-lg bg-slate-100":29,"px-3 py-2 rounded-lg bg-indigo-100":30,"text-base text-indigo-700 font-bold":31,"px-3 py-2 rounded-lg bg-emerald-100":32,"text-base text-emerald-700 font-bold":33,"px-3 py-2 rounded-lg bg-amber-100":34,"text-base text-amber-700 font-bold":35,"px-3 py-2 rounded-lg bg-red-100":36,"text-base text-red-500 font-bold":37,"w-[34] h-[34] rounded-lg bg-amber-400":38,"w-[34] h-[34] rounded-lg bg-red-500":39,"w-[34] h-[34] rounded-lg bg-slate-800":40,"w-[34] h-[34] rounded-lg bg-emerald-500":41,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":42,"flex-row items-center gap-4":43,"w-[34] text-2xl text-white font-bold":44,"w-[332] flex-col items-end gap-2":45,"text-base text-slate-300 font-bold":46,"text-base text-slate-400":47,"h-[166] px-6 pt-6 flex-col gap-3":48,"text-base text-orange-600 font-bold":49,"text-lg text-slate-600":50,"h-[44] px-1 flex-row items-center justify-between":51,"w-full h-full items-center justify-center rounded-xl bg-slate-200":52,"w-full h-full items-center justify-center rounded-xl bg-red-100":53,"w-full h-full items-center justify-center rounded-xl bg-slate-100":54,"w-full h-full items-center justify-center rounded-xl bg-orange-600":55,"text-lg text-slate-500 font-bold":56,"text-lg text-red-500 font-bold":57,"text-lg text-white font-bold":58,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":59,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":60,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":61,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":62,"text-2xl text-indigo-700 font-bold":63,"text-2xl text-slate-600 font-bold":64,"pt-7 text-2xl text-slate-900 font-bold":65,"pt-4 text-lg text-slate-500":66,"text-xl text-emerald-600 font-bold":67,"text-xl text-red-500 font-bold":68,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":69,"text-base text-red-300":70,"text-base text-slate-300":71,"text-base text-red-500":72,"w-full h-full px-6 flex-row items-center bg-slate-950":73,"w-full h-full flex-row items-center":74};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var d8="ui:styles",s8="ui:font.",G4="ui:img.",H4="ui:sprite.";function a8(){return globalThis.ui}function r8(J){if(J.__textures)return;for(let Q of U0(G4)){let $=yJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)_1(Q.slice(G4.length),Z)}}function o8(J){if(J.__sprites)return;for(let Q of U0(H4)){let $=yJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),q=$[4],G=Z.getUint16(6,!0),M=Z.getUint16(8,!0),U=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),X,W,q);if(V>=0)x1(Q.slice(H4.length),{handle:V,frames:G,cols:M,step:U})}}function j4(J){let Q=N1("view");return DJ(Q,"style",J,void 0),Q}var Z0=null,X0=null;function n8(J,Q){if(!Z0||!X0)return;DJ(Z0,"style",{width:J,height:Q,overflow:N.Overflow.Hidden},void 0),DJ(X0,"style",{width:J,height:Q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=_();$.__viewport={w:J,h:Q}}function t8(J,Q={}){let $=$6(Q.ops);if(Z6($),m6(U8),Q.styles)M8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let L in Z)_1(L,Z[L]);let H=$.ops.__sprites;if(H)for(let L in H)x1(L,H[L])}if($.kind==="injected"||Z===void 0){if(Q.pak)M1(Q.pak);if(D6()){for(let H of U0())if(H===d8)$.ops.loadStyles?.(yJ(H));else if(H.startsWith(s8))$.ops.loadFontAtlas?.(yJ(H))}}let X=Y1($.ops),W=X?.w??Z1,q=X?.h??X1,G=j4({width:W,height:q,overflow:N.Overflow.Hidden}),M=j4({width:W,height:q,posType:N.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});JJ(e,G),JJ(e,M),v1(M),Z0=G,X0=M,U1(G),O1(e),P6(),q4(),v8(),j6(),l8(),X8($.ops),X6(W8((H,L,y,h)=>{B6(),F6(L),O8(y,h),p8(),c8(),T8(),R6(H),E6(H),b1()}));let U=t6(J,G),V=W6(n8);return()=>{V(),C8(),q4(),U(),U1(null),O1(null),v1(null),Z0=null,X0=null;for(let H of e.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);b1()}}function e8(J,Q={}){let $=Q.ops??a8();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)M1(Q.pak);return r8($),o8($),t8(J,{ops:$,styles:Q.styles??i8,pak:Q.pak})}var B4="$b",J2=9007199254740991,Q2=":memory:",LJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function $2(J){let Q="";for(let $=0;$>2]+LJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2J2)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function W2(J){if(J!==null&&typeof J==="object")return Z2(J[B4]);return J}function Y2(J){if(Array.isArray(J))return JSON.stringify(J.map(F4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=F4(Z);return JSON.stringify(Q)}class E0{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,Y2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=K4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(W2))}run(...J){let Q=this.execute(K4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function K4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class M4{statements=new Map;txDepth=0;constructor(J=Q2){let Q=X2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new E0(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new E0(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let q=J(...Q);return this.txDepth--,this.exec(X),q}catch(q){throw this.txDepth--,this.exec(W),q}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var U4={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"},W0={neutral:{surface:"px-3 py-2 rounded-lg bg-slate-100",text:"text-base text-slate-600 font-bold"},info:{surface:"px-3 py-2 rounded-lg bg-indigo-100",text:"text-base text-indigo-700 font-bold"},success:{surface:"px-3 py-2 rounded-lg bg-emerald-100",text:"text-base text-emerald-700 font-bold"},warning:{surface:"px-3 py-2 rounded-lg bg-amber-100",text:"text-base text-amber-700 font-bold"},danger:{surface:"px-3 py-2 rounded-lg bg-red-100",text:"text-base text-red-500 font-bold"}};function q2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return D(b,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[D(b,{class:"flex-row items-center gap-4",get children(){return[s(()=>s(()=>!!J.back)()?D(x,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):D(b,{get["class"](){return Q()}})),D(x,{get["class"](){return U4.appTitle},get children(){return J.title}})]}}),D(b,{class:"w-[332] flex-col items-end gap-2",get children(){return[D(x,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),D(x,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function z2(J){return D(b,{class:"h-[166] px-6 pt-6 flex-col gap-3",get children(){return[D(x,{get["class"](){return J.tone==="info"?"text-base text-indigo-700 font-bold":"text-base text-orange-600 font-bold"},get children(){return J.eyebrow}}),D(x,{get["class"](){return U4.pageTitle},get children(){return J.title}}),D(x,{class:"text-lg text-slate-600",get children(){return J.description}})]}})}function G2(J){return D(b,{get["class"](){return J.compact?"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100"},get children(){return[s(()=>s(()=>!!J.icon)()?D(b,{get["class"](){return J.tone==="info"?"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100"},get children(){return D(x,{get["class"](){return J.tone==="info"?"text-2xl text-indigo-700 font-bold":"text-2xl text-slate-600 font-bold"},get children(){return J.icon}})}}):null),D(x,{get["class"](){return J.icon?"pt-7 text-2xl text-slate-900 font-bold":"text-lg text-slate-500 font-bold"},get children(){return J.title}}),s(()=>s(()=>!!J.detail)()?D(x,{class:"pt-4 text-lg text-slate-500",get children(){return J.detail}}):null)]}})}function H2(J){let Q=()=>J.dark?J.tone==="danger"?"text-base text-red-300":"text-base text-slate-300":J.tone==="danger"?"text-base text-red-500":"text-base text-slate-500";return D(b,{get["class"](){return J.dark?"w-full h-full px-6 flex-row items-center bg-slate-950":"w-full h-full flex-row items-center"},get children(){return D(x,{get["class"](){return Q()},get children(){return J.text}})}})}var N0=4,V4=7,a=new M4("exa"),[P4,v0]=AJ([]),[R4,m0]=AJ("SEARCH HISTORY IS LOCAL"),Y0=-1;function j2(J){try{return JSON.parse(J)}catch{return null}}function B2(J){let Q=new Date(J*1000).toISOString();return Q.slice(0,10)+" · "+Q.slice(11,16)+" UTC"}function w4(J){if(Y0===J)return;try{let Q=a.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==N0){v0([]),m0("SEARCH HISTORY IS LOCAL");return}let $=a.query(` - SELECT search.id,search.query,search.searched_at,search.status,search.result_count, - result.title AS top_title,result.url AS top_url,search.error - FROM searches search - LEFT JOIN search_results result ON result.search_id=search.id AND result.rank=0 - ORDER BY search.id DESC LIMIT 8 - `).all();v0($),m0($[0]?.status==="error"?String($[0].error||"EXA SEARCH FAILED").slice(0,80):$.length?"SEARCH HISTORY UPDATED FROM SQLITE":"SEARCH HISTORY IS LOCAL"),Y0=J}catch{v0([]),m0("SEARCH HISTORY IS LOCAL")}}function F2(){let J=a.query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'").all(),Q=new Set(J.map((L)=>L.name)),$=(L)=>Q.has(L)?Number(a.query(`SELECT COUNT(*) AS count FROM ${L}`).get()?.count??0):0,Z=Number(a.query("PRAGMA page_size").get()?.page_size??0),X=Number(a.query("PRAGMA page_count").get()?.page_count??0),W=Number(a.query("PRAGMA freelist_count").get()?.freelist_count??0),q=Number(a.query("PRAGMA user_version").get()?.user_version??0),G=Q.has("searches")?a.query(` +(()=>{var g={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return Z4(this.context.count)},getNextContextId(){return Z4(this.context.count++)}};function Z4(J){let Q=String(J),$=Q.length-1;return g.context.id+($?String.fromCharCode(96+$):"")+Q}function V0(J){g.context=J}function d6(){return{...g.context,id:g.getNextContextId(),count:0}}var a6=!1,s6=(J,Q)=>J===Q,P0=Symbol("solid-proxy"),r6=typeof Proxy==="function",n6=Symbol("solid-track"),o1=Symbol("solid-dev-component"),pJ={equals:s6},X4=null,W4=H4,d=1,SJ=2,Y4={owned:null,cleanups:null,context:null,owner:null},w=null,V=null,_J=null,DJ=null,A=null,h=null,E=null,iJ=0;function dJ(J,Q){let $=A,Z=w,X=J.length===0,W=Q===void 0?Z:Q,Y=X?Y4:{owned:null,cleanups:null,context:W?W.context:null,owner:W},j=X?J:()=>J(()=>b(()=>ZJ(Y)));w=Y,A=null;try{return o(j,!0)}finally{A=$,w=Z}}function JJ(J,Q){Q=Q?Object.assign({},pJ,Q):pJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(V&&V.running&&V.sources.has($))X=X($.tValue);else X=X($.value);return j4($,X)};return[q4.bind($),Z]}function QJ(J,Q,$){let Z=O0(J,Q,!1,d);if(_J&&V&&V.running)h.push(Z);else hJ(Z)}function R0(J,Q,$){W4=$8;let Z=O0(J,Q,!1,d),X=D0&&e6(D0);if(X)Z.suspense=X;if(!$||!$.render)Z.user=!0;E?E.push(Z):hJ(Z)}function $J(J,Q,$){$=$?Object.assign({},pJ,$):pJ;let Z=O0(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,_J&&V&&V.running)Z.tState=d,h.push(Z);else hJ(Z);return q4.bind(Z)}function b(J){if(!DJ&&A===null)return J();let Q=A;A=null;try{if(DJ)return DJ.untrack(J);return J()}finally{A=Q}}function o6(J){R0(()=>b(J))}function OJ(J){if(w===null);else if(w.cleanups===null)w.cleanups=[J];else w.cleanups.push(J);return J}function t6(J){if(V&&V.running)return J(),V.done;let Q=A,$=w;return Promise.resolve().then(()=>{A=Q,w=$;let Z;if(_J||D0)Z=V||(V={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return o(J,!1),A=w=null,Z?Z.done:void 0})}var[t1,z4]=JJ(!1);function e6(J){let Q;return w&&w.context&&(Q=w.context[J.id])!==void 0?Q:J.defaultValue}var D0;function q4(){let J=V&&V.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===d)hJ(this);else{let Q=h;h=null,o(()=>aJ(this),!1),h=Q}if(A){let Q=this.observers;if(!Q||Q[Q.length-1]!==A){let $=Q?Q.length:0;if(!A.sources)A.sources=[this],A.sourceSlots=[$];else A.sources.push(this),A.sourceSlots.push($);if(!Q)this.observers=[A],this.observerSlots=[A.sources.length-1];else Q.push(A),this.observerSlots.push(A.sources.length-1)}}if(J&&V.sources.has(this))return this.tValue;return this.value}function j4(J,Q,$){let Z=V&&V.running&&V.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(V){let X=V.running;if(X||!$&&V.sources.has(J))V.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)o(()=>{for(let X=0;X1e6)throw h=[],Error()},!1)}return Q}function hJ(J){if(!J.fn)return;ZJ(J);let Q=iJ;if(G4(J,V&&V.running&&V.sources.has(J)?J.tValue:J.value,Q),V&&!V.running&&V.sources.has(J))queueMicrotask(()=>{o(()=>{V&&(V.running=!0),A=w=J,G4(J,J.tValue,Q),A=w=null},!1)})}function G4(J,Q,$){let Z,X=w,W=A;A=w=J;try{Z=J.fn(Q)}catch(Y){if(J.pure)if(V&&V.running)J.tState=d,J.tOwned&&J.tOwned.forEach(ZJ),J.tOwned=void 0;else J.state=d,J.owned&&J.owned.forEach(ZJ),J.owned=null;return J.updatedAt=$+1,L0(Y)}finally{A=W,w=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)j4(J,Z,!0);else if(V&&V.running&&J.pure){if(!V.sources.has(J))J.value=Z;V.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function O0(J,Q,$,Z=d,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:w,context:w?w.context:null,pure:$};if(V&&V.running)W.state=0,W.tState=Z;if(w===null);else if(w!==Y4)if(V&&V.running&&w.pure)if(!w.tOwned)w.tOwned=[W];else w.tOwned.push(W);else if(!w.owned)w.owned=[W];else w.owned.push(W);if(DJ&&W.fn){let Y=W.fn,[j,U]=JJ(void 0,{equals:!1}),D=DJ.factory(Y,U);OJ(()=>D.dispose());let O,H=()=>t6(U).then(()=>{if(O)O.dispose(),O=void 0});W.fn=(C)=>{if(j(),V&&V.running){if(!O)O=DJ.factory(Y,H);return O.track(C)}return D.track(C)}}return W}function bJ(J){let Q=V&&V.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===SJ)return aJ(J);if(J.suspense&&b(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(V.disposed.has(X))return}if((Q?J.tState:J.state)===d)hJ(J);else if((Q?J.tState:J.state)===SJ){let X=h;h=null,o(()=>aJ(J,$[0]),!1),h=X}}}function o(J,Q){if(h)return J();let $=!1;if(!Q)h=[];if(E)$=!0;else E=[];iJ++;try{let Z=J();return J8($),Z}catch(Z){if(!$)E=null;h=null,L0(Z)}}function J8(J){if(h){if(_J&&V&&V.running)Q8(h);else H4(h);h=null}if(J)return;let Q;if(V){if(!V.promises.size&&!V.queue.size){let{sources:Z,disposed:X}=V;E.push.apply(E,V.effects),Q=V.resolve;for(let W of E)"tState"in W&&(W.state=W.tState),delete W.tState;V=null,o(()=>{for(let W of X)ZJ(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let Y=0,j=W.owned.length;YW4($),!1);if(Q)Q()}function H4(J){for(let Q=0;Q{Z.delete($),o(()=>{V.running=!0,bJ($)},!1),V&&(V.running=!1)})}}function $8(J){let Q,$=0;for(Q=0;Q=0;Q--)ZJ(J.tOwned[Q]);delete J.tOwned}if(V&&V.running&&J.pure)K4(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)ZJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(V&&V.running)J.tState=0;else J.state=0}function K4(J,Q){if(!Q)J.tState=0,V.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return OJ(()=>U4(W)),()=>{let U=J()||[],D=U.length,O,H;return U[n6],b(()=>{let I,y,x,S,p,F,K,G,L;if(D===0){if(Y!==0)U4(W),W=[],Z=[],X=[],Y=0,j&&(j=[]);if($.fallback)Z=[X8],X[0]=dJ((z)=>{return W[0]=z,$.fallback()}),Y=1}else if(Y===0){X=Array(D);for(H=0;H=F&&G>=F&&Z[K]===U[G];K--,G--)x[G]=X[K],S[G]=W[K],j&&(p[G]=j[K]);I=new Map,y=Array(G+1);for(H=G;H>=F;H--)L=U[H],O=I.get(L),y[H]=O===void 0?-1:O,I.set(L,H);for(O=F;O<=K;O++)if(L=Z[O],H=I.get(L),H!==void 0&&H!==-1)x[H]=X[O],S[H]=W[O],j&&(p[H]=j[O]),H=y[H],I.set(L,H);else W[O]();for(H=F;HJ(Q||{}));return V0($),Z}}return b(()=>J(Q||{}))}function sJ(){return!0}var q8={get(J,Q,$){if(Q===P0)return $;return J.get(Q)},has(J,Q){if(Q===P0)return!0;return J.has(Q)},set:sJ,deleteProperty:sJ,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:sJ,deleteProperty:sJ}},ownKeys(J){return J.keys()}};function k0(J){return!(J=typeof J==="function"?J():J)?{}:J}function j8(){for(let J=0,Q=this.length;J=0;j--){let U=k0(J[j])[Y];if(U!==void 0)return U}},has(Y){for(let j=J.length-1;j>=0;j--)if(Y in k0(J[j]))return!0;return!1},keys(){let Y=[];for(let j=0;j=0;Y--){let j=J[Y];if(!j)continue;let U=Object.getOwnPropertyNames(j);for(let D=U.length-1;D>=0;D--){let O=U[D];if(O==="__proto__"||O==="constructor")continue;let H=Object.getOwnPropertyDescriptor(j,O);if(!Z[O])Z[O]=H.get?{enumerable:!0,configurable:!0,get:j8.bind($[O]=[H.get.bind(j)])}:H.value!==void 0?H:void 0;else{let C=$[O];if(C){if(H.get)C.push(H.get.bind(j));else if(H.value!==void 0)C.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let Y=W.length-1;Y>=0;Y--){let j=W[Y],U=Z[j];if(U&&U.get)Object.defineProperty(X,j,U);else X[j]=U?U.value:void 0}return X}var G8=(J)=>`Stale read from <${J}>.`;function H8(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return $J(W8(()=>J.each,J.children,Q||void 0))}function V4(J){let Q=J.keyed,$=$J(()=>J.when,void 0,void 0),Z=Q?$:$J($,void 0,{equals:(X,W)=>!X===!W});return $J(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?b(()=>W(Q?X:()=>{if(!b(Z))throw G8("Show");return $()})):W}return J.fallback},void 0,void 0)}var B8=(J)=>$J(()=>J());function K8({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:Y,getParentNode:j,getFirstChild:U,getNextSibling:D}){function O(F,K,G,L){if(G!==void 0&&!L)L=[];if(typeof K!=="function")return H(F,K,L,G);QJ((z)=>H(F,K(),z,G),L)}function H(F,K,G,L,z){while(typeof G==="function")G=G();if(K===G)return G;let B=typeof K,M=L!==void 0;if(B==="string"||B==="number"){if(B==="number")K=K.toString();if(M){let P=G[0];if(P&&$(P))Z(P,K);else P=Q(K);G=y(F,G,L,P)}else if(G!==""&&typeof G==="string")Z(U(F),G=K);else y(F,G,L,Q(K)),G=K}else if(K==null||B==="boolean")G=y(F,G,L);else if(B==="function")return QJ(()=>{let P=K();while(typeof P==="function")P=P();G=H(F,P,G,L)}),()=>G;else if(Array.isArray(K)){let P=[];if(C(P,K,z))return QJ(()=>G=H(F,P,G,L,!0)),()=>G;if(P.length===0){let m=y(F,G,L);if(M)return G=m}else if(Array.isArray(G))if(G.length===0)x(F,P,L);else I(F,G,P);else if(G==null||G==="")x(F,P);else I(F,M&&G||[U(F)],P);G=P}else{if(Array.isArray(G)){if(M)return G=y(F,G,L,K);y(F,G,null,K)}else if(G==null||G===""||!U(F))X(F,K);else S(F,K,U(F));G=K}return G}function C(F,K,G){let L=!1;for(let z=0,B=K.length;zf-P){let n1=K[M];while(P=0;M--){let P=K[M];if(z!==P){let m=j(P)===F;if(!B&&!M)m?S(F,z,P):X(F,z,G);else m&&W(F,P)}else B=!0}}else X(F,z,G);return[z]}function x(F,K,G){for(let L=0,z=K.length;LG.children=H(F,K.children,G.children));return QJ(()=>K.ref&&K.ref(F)),QJ(()=>{for(let z in K){if(z==="children"||z==="ref")continue;let B=K[z];if(B===G[z])continue;Y(F,z,B,G[z]),G[z]=B}}),G}return{render(F,K){let G;return dJ((L)=>{G=L,O(K,F())}),G},insert:O,spread(F,K,G){if(typeof K==="function")QJ((L)=>p(F,K(),L,G));else p(F,K,void 0,G)},createElement:J,createTextNode:Q,insertNode:X,setProp(F,K,G,L){return Y(F,K,G,L),G},mergeProps:M4,effect:QJ,memo:B8,createComponent:z8,use(F,K,G){return b(()=>F(K,G))}}}function F8(J){let Q=K8(J);return Q.mergeProps=M4,Q}var P4=480,C0=272,BJ={view:0,text:1,image:2},U8=1,M8=-1,V8={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},R={f32:0,color:1,int:2},P8={width:R.f32,height:R.f32,minW:R.f32,minH:R.f32,maxW:R.f32,maxH:R.f32,paddingT:R.f32,paddingR:R.f32,paddingB:R.f32,paddingL:R.f32,marginT:R.f32,marginR:R.f32,marginB:R.f32,marginL:R.f32,gap:R.f32,flexDir:R.int,justify:R.int,align:R.int,grow:R.f32,shrink:R.f32,basis:R.f32,flexWrap:R.int,posType:R.int,insetT:R.f32,insetR:R.f32,insetB:R.f32,insetL:R.f32,display:R.int,overflow:R.int,zIndex:R.int,hitPass:R.int,bgColor:R.color,gradFrom:R.color,gradTo:R.color,gradDir:R.int,radius:R.f32,opacity:R.f32,borderColor:R.color,borderWidth:R.f32,shadow:R.int,bevelOuterLight:R.color,bevelOuterDark:R.color,bevelInnerLight:R.color,bevelInnerDark:R.color,bevelWidth:R.f32,textColor:R.color,fontSlot:R.int,textAlign:R.int,lineHeight:R.f32,tracking:R.f32,translateX:R.f32,translateY:R.f32,scale:R.f32,rotate:R.f32,scaleX:R.f32,scaleY:R.f32,originX:R.f32,originY:R.f32,rotateX:R.f32,rotateY:R.f32,translateZ:R.f32,perspective:R.f32,arcStart:R.f32,arcSweep:R.f32,arcWidth:R.f32},l={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},R8={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},D8=1,e1=2,JQ=1,QQ=2,$Q=131072,ZQ=1,XQ=262144,WQ=1,YQ=1,zQ=1,qQ=2,jQ=4,GQ=8,HQ=16,BQ=1,KQ=2;function R4(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var FQ=1,O8=1263551300,L8=1,k8=32,C8=24,a={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},KJ=32896,UQ=0.016666666666666666;function D4(J){return J.__viewport??null}var w0=null;function w8(){return null}function O4(J,Q=w8()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function I8(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return O4(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return O4(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function A8(J){w0=J}function LJ(){if(!w0)throw Error("PocketJS: host not installed — call render() first");return w0}function N(){return LJ().ops}function y8(J){globalThis.frame=J}function S8(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function _8(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return R4($>>>16&255,$>>>8&255,$&255,255);return R4($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function h8(J,Q){let $=P8[J];if(typeof Q==="string"){if($===R.color)return _8(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===R.color||$===R.int)return Q>>>0;return Q}var rJ=60,L4=[1,2,3,4,5,6,10,12,15,20,30,60],I0=rJ,XJ=-1,b8=0,xJ=[];function x8(J){if(!Number.isFinite(J)||J<=0)return rJ;let Q=L4[0];for(let $ of L4)if(Math.abs($-J)Q.at<=XJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>XJ);for(let Q of J)Q.cb()}var y0=0.12,nJ=KJ;function T8(J){nJ=J===void 0?KJ:J&65535}function E8(){nJ=KJ}function w4(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function I4(){return w4(nJ&255)}var oJ=new Set,m8=0;function v8(){oJ.clear(),m8=0,E8()}function u8(J){for(let Q of[...oJ])Q(J)}function A4(J){oJ.add(J),OJ(()=>oJ.delete(J))}var FJ=null,y4=null;function l8(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function S4(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function fJ(J){S0();let Q=FJ?FJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return y4.slice(Q.off,Q.off+Q.len)}var gJ=null,_=null,UJ=null,tJ=0,MJ=[],h0=[],kJ=[];function h4(J){if(gJ=J,_=null,UJ=null,tJ=0,MJ.length=0,h0.length=0,kJ.length=0,s){if(s.pressTarget=null,s.target=null,s.spriteDirty=!0,s.fresh=!0,s.vw=0,s.tex>=0){let Q=N();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(s.tex),s.tex=-1}}}function p8(J,Q){J.onPress=Q??void 0}function i8(J,Q){if(J.focusable=Q,N4(),!Q&&_===J)v(null)}function v(J){if(UJ&&UJ!==J)VJ(null);_=J,N().setFocus(J?J.id:0)}function VJ(J){if(UJ===J)return;let Q=N();if(UJ)Q.setActive?.(UJ.id,0);if(UJ=J,J)Q.setActive?.(J.id,1)}function b4(){return _}function b0(){return MJ.length>0?MJ[MJ.length-1]:gJ}function x0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;v($[X])}function s8(){if(!_)return null;let J=b0();if(J&&!r(_,J))return null;for(let Q=h0.length-1;Q>=0;Q--){let $=h0[Q];if(J&&!r($.node,J)&&!r(J,$.node))continue;if(r(_,$.node))return $}return null}function r8(J){let Q=s8();if(!Q)return!1;let $=[];if(x0(Q.node,$),$.length===0){if(_)v(null);return!0}let Z=Q.columns,X=_?$.indexOf(_):-1;if(X<0)return v(x4(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)v($[W]);return!0}function n8(){if(!_)return null;let J=b0();if(J&&!r(_,J))return null;for(let Q=kJ.length-1;Q>=0;Q--){let $=kJ[Q];if(J&&!r($.node,J)&&!r(J,$.node))continue;if(r(_,$.node))return $}return null}function o8(J,Q){let $={node:J,move:Q};kJ.push($);let Z=!1;return()=>{if(Z)return;Z=!0;let X=kJ.lastIndexOf($);if(X>=0)kJ.splice(X,1)}}function eJ(J){let Q=n8();if(Q&&Q.move(J))return;if(r8(J))return;a8(J)}function f4(){g4(_)}function g4(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function WJ(J){VJ(J)}function T4(J){v(J),g4(J)}function r(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function f0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=f0(Q.children[X]);if(W){v(W);return}}let Z=Q;while(Z){if(Z.focusable){v(Z);return}Z=Z.parent}}v(null)}var s=null,E4=0;function N4(){E4++}var e8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],J2=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function Q2(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=e8[Q]>>$&1,X=J2[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,Y=X?255:0;J[W]=Y,J[W+1]=Y,J[W+2]=Y,J[W+3]=255}return J}function $2(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=fJ($.image)}catch(Y){if(LJ().strict)throw Y;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):Z2(Q,W),X<0&&LJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(Q2(),16,16,R8.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function Z2(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&D8)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function J0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=J0($[Z],Q);if(X)return X}return null}var Q0=null;function m4(J){Q0=J}function v4(J){let Q=MJ.length>0?MJ[MJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||r($,Q)))return $;$=$.parent}return null}function u4(J,Q,$){return v4(g0(J,Q,$))}function g0(J,Q,$){if($!==void 0)return $===0?null:J0(Q0??gJ,$);let Z=N(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return J0(Q0??gJ,X(J,Q))}function X2(J,Q,$){let Z=s,X=N();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=D4(X);if(Z.vw=H?H.w:P4,Z.vh=H?H.h:C0,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)$2(Z,X);let W=N8()*Z.speed,Y=I4()*Z.speed;if(Z.dpadSpeed>0&&W===0&&Y===0){if(J&a.LEFT)W=-Z.dpadSpeed;if(J&a.RIGHT)W=Z.dpadSpeed;if(J&a.UP)Y=-Z.dpadSpeed;if(J&a.DOWN)Y=Z.dpadSpeed}let j=Z.fresh;if(W!==0||Y!==0){let H=k4()/60,C=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),I=Math.min(Math.max(Z.y+Y*H,0),Z.vh-1);if(C!==Z.x||I!==Z.y)Z.x=C,Z.y=I,j=!0}if(j)X.setCursorPos(Z.x,Z.y);let U=(Q|$)&Z.button,D=E4;if(j||U!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=v4(J0(Q0??gJ,X.hitTest(Z.x,Z.y)));let O=Z.target;if(O!==_)v(O);if(Q&Z.button&&O)Z.pressTarget=O;if(Z.pressTarget){if(VJ(O===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=O===Z.pressTarget;if(Z.pressTarget=null,VJ(null),H)f4()}}else if($&Z.button)VJ(null);return!0}function W2(J){let Q=J&~tJ,$=tJ&~J;if(tJ=J,s&&X2(J,Q,$))return;if($&a.CIRCLE)VJ(null);if(Q===0)return;if(Q&a.DOWN)eJ("down");if(Q&a.RIGHT)eJ("right");if(Q&a.UP)eJ("up");if(Q&a.LEFT)eJ("left");if(Q&a.CIRCLE)VJ(_),f4()}var T0=null;function l4(J){T0=J}function CJ(){if(N4(),T0)T0()}function Y2(J,Q){J.debugName=Q||void 0,CJ()}var YJ={id:U8,type:BJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},c4=Symbol.for("pocketjs.native-node"),E0=1,TJ=3,t=8,z2=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function $0(J){return J.domAttrs??={}}function p4(J,Q){let $=J.domNodeType??(EJ(J)?TJ:E0),Z=$===TJ?Z0(J.text??""):$===t?G2(J.domData??""):o4(J.domTag??W0(J));for(let X of Object.keys(J.domAttrs??{}))N0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)zJ(Z,p4(X,!0));return Z}function N0(J,Q,$){if(z2.has(Q)){IJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete $0(J)[Q];else $0(J)[Q]=$}function m0(J){if(J[c4]===!0)return J;return Object.defineProperty(J,c4,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(EJ(J)?TJ:E0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===t?J.domData??"":J.text??""},set($){if(J.domNodeType===t)J.domData=String($??"");else X0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===t?J.domData??"":J.text??""},set($){if(J.domNodeType===t)J.domData=String($??"");else X0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===t)return J.domData??"";if(EJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===t)J.domData=Z;else if(EJ(J))X0(J,Z);else if(V2(J),Z)zJ(J,Z0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return e4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??W0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===TJ)return"#text";if(J.domNodeType===t)return"#comment";return(J.domTag??W0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){IJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===YJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return zJ(J,$),$},insertBefore($,Z){return zJ(J,$,Z??null),$},removeChild($){return NJ(J,$),$},replaceChild($,Z){return zJ(J,$,Z),NJ(J,Z),Z},cloneNode($=!1){return p4(J,!!$)},remove(){if(J.parent)NJ(J.parent,J)},setAttribute($,Z){N0(J,$,Z)},removeAttribute($){N0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}m0(YJ);var v0=null;function q2(J){v0=J}var u0={unknownClass:0,unknownTexture:0},i4=new Map;function d4(J,Q){i4.set(J,Q)}var a4=new Map;function s4(J,Q){a4.set(J,Q)}var wJ=new Set,j2=new Set;function r4(J){if(!J)return!1;if(j2.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return m0({id:N().createNode(Q),type:Q,parent:null,children:[],domNodeType:E0,domTag:J})}function Z0(J){let Q=N(),$=Q.createNode(BJ.text);return Q.setText($,J),m0({id:$,type:BJ.text,parent:null,children:[],text:J,domNodeType:TJ,domTag:"#text"})}function G2(J=""){let Q=Z0("");return Q.domNodeType=t,Q.domTag="#comment",Q.domData=J,Q}function X0(J,Q){N().replaceText(J.id,Q),J.text=Q,CJ()}function EJ(J){return J.type===BJ.text}function t4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function zJ(J,Q,$){let Z=N();if(t4(Q),wJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,CJ()}function NJ(J,Q){if(!Q)return;t8(Q),N().removeChild(J.id,Q.id),t4(Q),wJ.add(Q),CJ()}function H2(J){return J.parent??void 0}function B2(J){return J.children[0]}function e4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function K2(J,Q){let $=N();if(CJ(),Q==null||Q===""){$.setStyle(J.id,M8);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=v0?v0(Q):void 0;if(Z===void 0){if(LJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);u0.unknownClass++;return}$.setStyle(J.id,Z)}function F2(J,Q){let $=N();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=i4.get(Q);if(Z===void 0){if(LJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);u0.unknownTexture++;return}$.setImage(J.id,Z)}function U2(J,Q){let $=N();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=a4.get(Q);if(Z===void 0){if(LJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);u0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function M2(J,Q,$){let Z=N(),X=Q??{},W=$??{},Y=!1;for(let j in X){let U=X[j];if(W[j]===U)continue;let D=V8[j];if(D===void 0)throw Error(`PocketJS: unknown style prop '${j}' (see spec PROP)`);Z.setProp(J.id,D,h8(j,U)),Y=!0}if(Y)CJ()}function IJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete $0(J)[Q];else $0(J)[Q]=$;switch(Q){case"class":return K2(J,$),$;case"onPress":case"on:press":return p8(J,$),$;case"src":return F2(J,$),$;case"sprite":return U2(J,$),$;case"style":return M2(J,$,Z),$;case"focusable":return i8(J,!!$),$;case"debugName":return Y2(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${W0(J)}>`)}function V2(J){for(let Q of[...J.children])NJ(J,Q)}function W0(J){for(let Q of Object.keys(BJ))if(BJ[Q]===J.type)return Q;return String(J.type)}function P2(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}IJ(J,Q,$,Z)}var R2=F8({createElement:o4,createTextNode:Z0,replaceText:X0,isTextNode:EJ,setProperty:P2,insertNode(J,Q,$){zJ(J,Q,$)},removeNode(J,Q){NJ(J,Q)},getParentNode:H2,getFirstChild:B2,getNextSibling:e4}),{render:D2,effect:MQ,memo:e,createComponent:k,createElement:J6,insert:VQ,spread:O2,mergeProps:PQ,use:RQ}=R2,DQ={linear:l.Easing.Linear,in:l.Easing.EaseIn,out:l.Easing.EaseOut,"in-out":l.Easing.EaseInOut,"out-back":l.Easing.OutBack,spring:l.Easing.Spring,"spring-bouncy":l.Easing.SpringBouncy},L2=null;function Q6(J){L2=J}function k2(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function $6(J,Q){let $=J6(J);return O2($,Q,!1),k2(Q.nodeRef,$),$}function T(J){return $6("view",J)}function u(J){return $6("text",J)}var OQ=new WeakMap,LQ=new WeakMap,C2={}!==null?Object.freeze({...{}}):Object.freeze({}),kQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:C2}),CQ=new Map,qJ=36000,l0=30,w2=30,q={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(qJ),tapeAnalog:new Uint16Array(qJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-l0,saidHello:!1,hostCalls:0};function I2(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};q.ops=J,q.frame=0,q.tapeStart=0,q.tapeLen=0,q.tapeFirstFrame=0,q.tapeTouch=null,q.replayMasks=null,q.replayAnalog=null,q.replayTouch=null,q.paused=!1,q.stepQueued=0,q.inspectReportId=null,q.inspectAskedAt=0,q.treeDirty=!0,q.treeSentAt=-l0,q.saidHello=!1,q.hostCalls=0,q.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)q.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)q.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else q.transport=null;if(q.transport)l4(()=>{q.treeDirty=!0}),f2();else l4(null);globalThis.__pocketDevtools=T2}function A2(J){return(Q,$,Z,X)=>{if(q.hostCalls++,q.transport)S2(),b2();let W=Q,Y=$===void 0?KJ:$&65535,j=Z,U=X;if(q.replayMasks)if(q.replayAt0?$.slice(0,8):null;if(Z&&!q.tapeTouch)q.tapeTouch=Array(qJ).fill(null);if(q.tapeLen1||Q.length===1&&Q[0][0]!==KJ)J.analog=Q;if(q.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function W6(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,Y]of J)Z.fill(W,X,Math.min(X+Y,$)),X+=Y;return Z}function Y6(J){let Q=0;for(let[,$]of J.masks)Q+=$;return W6(J.masks,0,Q)}function z6(J){let Q=0;for(let[,$]of J.masks)Q+=$;return W6(J.analog??[],KJ,Q)}function q6(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&q.hostCalls%Q!==0)return;if(!q.saidHello)q.saidHello=!0,c({t:"hello",app:q.app,host:g2(),frame:q.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` +`))if(X.trim())_2(X)}}function _2(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=q.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),q.inspectReportId=Z||null,q.inspectAskedAt=q.hostCalls,!Z)c({t:"inspect",id:0,rect:null});break}case"pause":q.paused=!0,q.stepQueued=0,$?.debugPause?.(!0),c0();break;case"resume":q.paused=!1,$?.debugPause?.(!1),c0();break;case"step":q.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":j6();break;case"eval":{let Z=!0,X;try{X=Y0((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}c({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":c({t:"tape",tape:X6()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}c({t:"devStats",frame:q.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())c({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:q.frame});else c({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))q.replayMasks=Y6(Z),q.replayAnalog=Z.analog?z6(Z):null,q.replayTouch=Z.touch?q6(Z):null,q.replayAt=0;break}default:break}}function h2(){if(q.treeDirty&&q.frame-q.treeSentAt>=l0)j6();if(q.frame%w2===0)c0()}function b2(){let J=q.inspectReportId;if(J==null)return;let Q=q.ops;if(!Q?.debugRectXY||!Q.debugRectWH){q.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(q.hostCalls-q.inspectAskedAt>60)q.inspectReportId=null,c({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();q.inspectReportId=null,c({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function c0(){c({t:"stats",frame:q.frame,nodes:B6(YJ),tapeLen:q.tapeLen,paused:q.paused})}function j6(){q.treeDirty=!1,q.treeSentAt=q.frame,c({t:"tree",frame:q.frame,root:H6(YJ)})}function x2(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function p0(J,Q){if(Array.isArray(J)){for(let $ of J)p0($,Q);return}if(x2(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)p0($,Q)}}function G6(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)p0(Z,Q)}function H6(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(G6(J,(X)=>{if(X.domNodeType===8)return;Z.push(H6(X))}),Z.length)Q.k=Z;return Q}function B6(J){let Q=1;return G6(J,($)=>{Q+=B6($)}),Q}function f2(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{c({t:"log",level:$,args:X.map((W)=>Y0(W))}),Z?.apply(Q,X)}}}function Y0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?K6(W):JSON.stringify(K6(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((Y)=>Y0(Y,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,Y])=>`${W}: ${Y0(Y,Q+1)}`).join(", ")}}`}function K6(J){return J.length>200?J.slice(0,199)+"…":J}function g2(){let J=q.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var T2={get frame(){return q.frame},dumpTape:()=>X6(),replay:(J)=>{q.replayMasks=Y6(J),q.replayAnalog=J.analog?z6(J):null,q.replayTouch=J.touch?q6(J):null,q.replayAt=0}},F6=new Map,i0=new Map;function U6(J){return J.trim().replace(/\s+/g," ")}function M6(J){return J.split(" ").sort().join(" ")}var V6=-1;function E2(J){for(let Q of Object.keys(J)){let $=J[Q],Z=U6(Q);F6.set(Z,$);let X=M6(Z),W=i0.get(X);i0.set(X,W!==void 0&&W!==$?V6:$)}}function N2(J){let Q=U6(J),$=F6.get(Q);if($!==void 0)return $;let Z=i0.get(M6(Q));return Z===V6?void 0:Z}var d0=9,m2=(1<{let X=($&u2)!==0,W=X?a0:d0,Y=X?l2:m2;return Object.freeze({id:$>>>(X?c2:v2)&255,x:$&Y,y:$>>>W&Y,hit:Q?.[Z]})}))}function i2(){return z0}function d2(){z0=s0}var P6=8,jJ=8,a2=3,s2=8,r2=6,n2=0.5,n=1,mJ=2,r0=4,PJ=8,AJ=[],R6=0,q0=0,GJ=Array.from({length:P6},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(jJ),histY:new Int16Array(jJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function o2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function t2(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=g0(Q,$,Z.fact);let j=Z.hit;if(j)return o2(j,W)}let Y=X.rect?.();if(!Y)return!1;return Q>=Y.x&&Q=Y.y&&$=0;Y--){let j=AJ[Y];if(j.disposed)continue;if(R6>0&&!j.opts.allowWhenBlocked)continue;if(!t2(j,$,Z,W))continue;j.flags[J.slot]=n,J.owners.push(j)}for(let Y of J.owners)Y.opts.onDown?.(J)}function Q1(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%jJ,J.histLenY||Z>Y))X.flags[J.slot]|=mJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&n)||W&(mJ|r0))continue;if(!X.opts.onLongPress)continue;let Y=Math.max(1,Math.round((X.opts.longPressSeconds??n2)*A0()));if(J.frames=0)AJ.splice($,1)},cancel(){if(!Q.disposed)L6(Q)},get panning(){for(let $ of GJ)if($.used&&Q.flags[$.slot]&PJ)return!0;return!1}}}function k6(J){let Q=W1(J);return OJ(()=>Q.dispose()),Q}function C6(){AJ.length=0,R6=0,q0=0;for(let J of GJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function Y1(){return k6({onDown:(J)=>{let Q=u4(J.x,J.y,J.hit);if(Q)WJ(Q)},onTap:(J)=>{WJ(null);let Q=u4(J.x,J.y,J.hit);if(Q)T4(Q)},onUp:()=>WJ(null),onCancel:()=>WJ(null)})}var z1=1,n0=new Map,j0=[];function q1(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function j1(){z1=1,n0.clear(),j0=[]}function G1(){if(j0.length===0)return;let J=j0;j0=[];for(let{id:Q,result:$}of J){let Z=n0.get(Q);if(!Z)continue;n0.delete(Q),q1()?.({t:"delivery",frame:C4(),id:Q,kind:Z.kind}),Z.onResult($)}}var w6=new Set;function H1(){if(w6.size===0)return;for(let J of w6)J()}var B1={"flex-col w-full h-full bg-slate-50":0,"grow px-6 pt-4 flex-col":1,"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":2,"w-[474] flex-col gap-2":3,"text-lg text-slate-900 font-bold":4,"text-base text-slate-500":5,"text-base text-indigo-600 font-bold":6,"h-[96]":7,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":8,"absolute inset-0 z-50 flex-col items-center justify-center":9,"absolute inset-0 bg-slate-950":10,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":11,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":12,"flex-row flex-wrap":13,grow:14,"text-2xl text-white font-bold":15,"text-2xl text-slate-950 font-bold":16,"text-xl text-slate-900 font-bold":17,"text-base text-slate-600 font-bold":18,"text-lg text-slate-900":19,"text-base text-slate-500 font-bold":20,"px-6":21,"px-6 py-5":22,"gap-4":23,"rounded-xl shadow bg-white border-slate-100":24,"rounded-xl shadow bg-emerald-100 border-emerald-500":25,"bg-white":26,"bg-slate-100":27,"bg-slate-950":28,"px-3 py-2 rounded-lg bg-slate-100":29,"px-3 py-2 rounded-lg bg-indigo-100":30,"text-base text-indigo-700 font-bold":31,"px-3 py-2 rounded-lg bg-emerald-100":32,"text-base text-emerald-700 font-bold":33,"px-3 py-2 rounded-lg bg-amber-100":34,"text-base text-amber-700 font-bold":35,"px-3 py-2 rounded-lg bg-red-100":36,"text-base text-red-500 font-bold":37,"w-[34] h-[34] rounded-lg bg-amber-400":38,"w-[34] h-[34] rounded-lg bg-red-500":39,"w-[34] h-[34] rounded-lg bg-slate-800":40,"w-[34] h-[34] rounded-lg bg-emerald-500":41,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":42,"flex-row items-center gap-4":43,"w-[34] text-2xl text-white font-bold":44,"w-[332] flex-col items-end gap-2":45,"text-base text-slate-300 font-bold":46,"text-base text-slate-400":47,"h-[166] px-6 pt-6 flex-col gap-3":48,"text-base text-orange-600 font-bold":49,"text-lg text-slate-600":50,"h-[44] px-1 flex-row items-center justify-between":51,"w-full h-full items-center justify-center rounded-xl bg-slate-200":52,"w-full h-full items-center justify-center rounded-xl bg-red-100":53,"w-full h-full items-center justify-center rounded-xl bg-slate-100":54,"w-full h-full items-center justify-center rounded-xl bg-orange-600":55,"text-lg text-slate-500 font-bold":56,"text-lg text-red-500 font-bold":57,"text-lg text-white font-bold":58,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":59,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":60,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":61,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":62,"text-2xl text-indigo-700 font-bold":63,"text-2xl text-slate-600 font-bold":64,"pt-7 text-2xl text-slate-900 font-bold":65,"pt-4 text-lg text-slate-500":66,"text-xl text-emerald-600 font-bold":67,"text-xl text-red-500 font-bold":68,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":69,"text-base text-red-300":70,"text-base text-slate-300":71,"text-base text-red-500":72,"w-full h-full px-6 flex-row items-center bg-slate-950":73,"w-full h-full flex-row items-center":74};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var K1="ui:styles",F1="ui:font.",I6="ui:img.",A6="ui:sprite.";function U1(){return globalThis.ui}function M1(J){if(J.__textures)return;for(let Q of _0(I6)){let $=fJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)d4(Q.slice(I6.length),Z)}}function V1(J){if(J.__sprites)return;for(let Q of _0(A6)){let $=fJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),Y=$[4],j=Z.getUint16(6,!0),U=Z.getUint16(8,!0),D=Z.getUint16(10,!0),O=J.uploadTexture($.subarray(16),X,W,Y);if(O>=0)s4(Q.slice(A6.length),{handle:O,frames:j,cols:U,step:D})}}function y6(J){let Q=J6("view");return IJ(Q,"style",J,void 0),Q}var G0=null,H0=null;function P1(J,Q){if(!G0||!H0)return;IJ(G0,"style",{width:J,height:Q,overflow:l.Overflow.Hidden},void 0),IJ(H0,"style",{width:J,height:Q,posType:l.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=N();$.__viewport={w:J,h:Q}}function R1(J,Q={}){let $=I8(Q.ops);if(A8($),q2(N2),Q.styles)E2(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let C in Z)d4(C,Z[C]);let H=$.ops.__sprites;if(H)for(let C in H)s4(C,H[C])}if($.kind==="injected"||Z===void 0){if(Q.pak)_4(Q.pak);if(c8()){for(let H of _0())if(H===K1)$.ops.loadStyles?.(fJ(H));else if(H.startsWith(F1))$.ops.loadFontAtlas?.(fJ(H))}}let X=D4($.ops),W=X?.w??P4,Y=X?.h??C0,j=y6({width:W,height:Y,overflow:l.Overflow.Hidden}),U=y6({width:W,height:Y,posType:l.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});zJ(YJ,j),zJ(YJ,U),Q6(U),G0=j,H0=U,h4(j),m4(YJ),v8(),C6(),Y1(),f8(),j1(),I2($.ops),y8(A2((H,C,I,y)=>{g8(),T8(C),p2(I,y),H1(),G1(),X1(),u8(H),W2(H),n4()}));let D=D2(J,j),O=S8(P1);return()=>{O(),d2(),C6(),D(),h4(null),m4(null),Q6(null),G0=null,H0=null;for(let H of YJ.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);n4()}}function D1(J,Q={}){let $=Q.ops??U1();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)_4(Q.pak);return M1($),V1($),R1(J,{ops:$,styles:Q.styles??B1,pak:Q.pak})}var S6="$b",O1=9007199254740991,L1=":memory:",yJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function k1(J){let Q="";for(let $=0;$>2]+yJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2O1)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function I1(J){if(J!==null&&typeof J==="object")return C1(J[S6]);return J}function A1(J){if(Array.isArray(J))return JSON.stringify(J.map(_6));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=_6(Z);return JSON.stringify(Q)}class o0{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,A1(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=h6(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(I1))}run(...J){let Q=this.execute(h6(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function h6(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class b6{statements=new Map;txDepth=0;constructor(J=L1){let Q=w1();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new o0(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new o0(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let Y=J(...Q);return this.txDepth--,this.exec(X),Y}catch(Y){throw this.txDepth--,this.exec(W),Y}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var y1=0.9672,S1=0.846,B0=4,x6=0.55,_1=48,h1=170,b1=26,f6=0.5,g6=8,x1=0.3,T6=0.6,K0=0.016666666666666666;function E6(J,Q,$){if($<=0)return 0;let Z=(1-1/(J*x6/Q+1))*Q;return Z<$?Z:$}function N6(J,Q){return Q*J/(x6*(Q-J))}function f1(J){let Q=J.extent??(()=>C0),$=J.overscroll??_1,Z=J.decay==="fast"?S1:y1,[X,W]=JJ(J.initial??0),Y=J.initial??0,j="idle",U=0,D=0,O=0,H=0,C=0,I=0,y=1,x=0;function S(z){if(z!==Y)Y=z,W(z)}function p(z){let B=Math.round(z*64)/64;S(B),U=0,j="idle",J.onSettle?.(B)}function F(z){let B=J.max();return z<0?0:z>B?B:z}function K(){let z=J.max();if(D<0)return-E6(-D,Q(),$);if(D>z)return z+E6(D-z,Q(),$);return D}function G(z,B){C=Y,I=F(z),y=Math.max(1,Math.round(B*A0()/1000)),x=0,j=I===Y?"idle":"tween"}function L(z){return Y+z*K0*Z/(1-Z)}return{offset:X,velocity:()=>U,state:()=>j,beginDrag(){let z=J.max();if(U=0,j="tracking",Y<0)D=-N6(-Y,Q());else if(Y>z)D=z+N6(Y-z,Q());else D=Y},drag(z){if(j!=="tracking")this.beginDrag();D+=z,S(K())},endDrag(z){if(j!=="tracking")return;let B=J.max();if(Y<0||Y>B){H=Y<0?0:B,U=z,j="spring";return}if(J.snap){let M=J.snap(L(z),z),P=M-Y,m=Math.min(450,Math.max(150,150+(P<0?-P:P)*0.6));G(M,m);return}if(z>B0||z<-B0){U=z,j="fling";return}p(Y)},scrollTo(z,B){if(B&&"immediate"in B&&B.immediate){U=0,j="idle",S(F(z));return}G(z,B?.durMs??200)},scrollBy(z,B){let M=j==="tween"?I:j==="chase"?O:Y;this.scrollTo(M+z,B)},stop(){U=0,j="idle"},nudge(z){let B=j==="chase"?O:Y;this.chaseTo(B+z)},chaseTo(z){if(O=F(z),j!=="chase"&&O===Y)return;U=0,j="chase"},rebase(z){D+=z,O+=z,H+=z,C+=z,I+=z,S(Y+z)},intent(){return j==="chase"?O:j==="tween"?I:Y},isAtEnd(z=1){return this.intent()>=J.max()-z},projectFling:L,step(){if(j==="idle"||j==="tracking")return;if(j==="chase"){O=F(O);let M=O-Y;if(M===0||M-T6){S(O),j="idle",J.onSettle?.(Y);return}S(Y+M*x1);return}if(j==="tween"){if(x++,x>=y){S(I),j="idle",U=0,J.onSettle?.(Y);return}let P=1-x/y,m=1-P*P*P;S(C+(I-C)*m);return}let z=Y,B=k4();for(let M=0;MP){H=z<0?0:P,j="spring";continue}if(U-B0){p(z);return}}else{let P=F(H),m=h1*(P-z)-b1*U;U+=m*K0,z+=U*K0;let i=P-z;if(i-f6&&U-g6){p(P);return}}S(z)}}}function g1(J,Q={}){let $=Q.stepPx??6,Z=Q.nubPx??10;A4((X)=>{if(Q.active&&!Q.active())return;if(X&a.UP)J.nudge(-$);if(X&a.DOWN)J.nudge($);let W=I4();if(W!==0)J.nudge(W*Z)})}var T1=60,m6=36;function t0(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function E1(J){let Q=()=>J.overscan??T1,$=J.focusRows!==!1,Z=()=>J.inputActive?J.inputActive():!0,X=()=>J.count*J.rowHeight,W=J.controller??f1({max:()=>Math.max(0,X()-J.height)}),Y=W.offset,j,U=new Map,[D,O]=JJ(null),H=null,C=$J((z)=>{let B=Math.max(0,Math.floor((Y()-Q())/J.rowHeight)),M=Math.min(J.count-1,Math.floor((Y()+J.height+Q()-1)/J.rowHeight));if(z&&z[0]===B&&z[1]===M)return z;return[B,M]},[0,-1]),I=$J(()=>{let[z,B]=C(),M=[];for(let P=z;P<=B;P++)M.push(P);return M}),y=()=>{let z=b4();if(z){for(let[B,M]of U)if(t0(z,M))return B}return b(D)};function x(z,B="nearest",M=!0){let P=z*J.rowHeight,m=P+J.rowHeight,i=b(Y),f;switch(B){case"start":f=P;break;case"center":f=P-(J.height-J.rowHeight)/2;break;case"end":f=m-J.height;break;default:if(Pi+J.height)f=m-J.height;else return}if(M)W.chaseTo(f);else W.scrollTo(f,{immediate:!0})}function S(z){O(z),x(z,"nearest");let B=U.get(z);if(B)H=null,v(B);else H=z}let p=(z)=>{if(z!=="up"&&z!=="down")return!1;if(!Z()||J.count===0)return!1;let B=y();if(B===null)return S(Math.max(0,Math.min(J.count-1,Math.floor(b(Y)/J.rowHeight)))),!0;let M=z==="down"?B+1:B-1;if(M<0||M>=J.count)return!0;return S(M),!0};o6(()=>{if($){if(j)OJ(o8(j,p));R0(()=>{if(I(),H===null)return;let z=U.get(H);if(z)H=null,v(z)})}else g1(W,{active:Z})});let F=(z)=>{let B=g0(z.x,z.y,z.hit);if(B){for(let[M,P]of U)if(t0(B,P))return{index:M,node:P}}return null};k6({region:{node:()=>j},axis:"y",onDown:(z)=>{if(!Z())return;if(W.stop(),!$)return;let B=F(z);if(B?.node)WJ(B.node)},onPanStart:()=>{if(!Z())return;WJ(null),W.beginDrag()},onPanMove:(z)=>{if(!Z())return;W.drag(-z.fdy)},onPanEnd:(z)=>{if(!Z())return;W.endDrag(-z.vy)},onTap:(z)=>{if(!Z())return;let B=F(z);if(!B)return;if(WJ(null),O(B.index),B.node&&$)T4(B.node);else J.onRowPress?.(B.index)},onCancel:()=>{if(WJ(null),W.state()==="tracking")W.endDrag(0)}}),A4(()=>{if(W.step(),$){let B=b4();if(B){for(let[M,P]of U)if(t0(B,P)){if(b(D)!==M)O(M);break}}}let z=b(Y);if(J.onNearStart&&z<(J.nearStartPx??m6))J.onNearStart();if(J.onNearEnd){let B=Math.max(0,X()-J.height);if(z>B-(J.nearEndPx??m6))J.onNearEnd()}});let K=J.count;R0(()=>{let z=J.count;b(()=>{if(J.stickToBottom&&z>K){let B=Math.max(0,K*J.rowHeight-J.height);if(W.intent()>=B-8)W.chaseTo(Math.max(0,z*J.rowHeight-J.height))}K=z})});let G={scroller:W,rebase:(z)=>W.rebase(z),rebaseRows:(z)=>b(()=>W.rebase(z*J.rowHeight)),scrollToIndex:(z,B,M)=>b(()=>x(z,B,M)),focusedIndex:D,focusRow(z){b(()=>{if(!$||J.count===0)return;S(Math.max(0,Math.min(J.count-1,z)))})}};return J.ref?.(G),T({get style(){return{overflow:l.Overflow.Hidden,height:J.height,width:-1,...J.style}},ref:(z)=>{j=z},children:T({get style(){return{posType:l.PosType.Absolute,insetT:0,insetL:0,insetR:0,height:X(),translateY:-Y()}},children:H8({get each(){return I()},children:(z)=>T({focusable:$,onPress:J.onRowPress?()=>J.onRowPress(z):void 0,style:{posType:l.PosType.Absolute,insetT:z*J.rowHeight,insetL:0,insetR:0,height:J.rowHeight},ref:(B)=>{U.set(z,B),OJ(()=>{if(U.get(z)===B)U.delete(z)})},get children(){return J.renderRow(z)}})})})})}var v6={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"},F0={neutral:{surface:"px-3 py-2 rounded-lg bg-slate-100",text:"text-base text-slate-600 font-bold"},info:{surface:"px-3 py-2 rounded-lg bg-indigo-100",text:"text-base text-indigo-700 font-bold"},success:{surface:"px-3 py-2 rounded-lg bg-emerald-100",text:"text-base text-emerald-700 font-bold"},warning:{surface:"px-3 py-2 rounded-lg bg-amber-100",text:"text-base text-amber-700 font-bold"},danger:{surface:"px-3 py-2 rounded-lg bg-red-100",text:"text-base text-red-500 font-bold"}};function N1(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return k(T,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[k(T,{class:"flex-row items-center gap-4",get children(){return[e(()=>e(()=>!!J.back)()?k(u,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):k(T,{get["class"](){return Q()}})),k(u,{get["class"](){return v6.appTitle},get children(){return J.title}})]}}),k(T,{class:"w-[332] flex-col items-end gap-2",get children(){return[k(u,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),k(u,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function m1(J){return k(T,{class:"h-[166] px-6 pt-6 flex-col gap-3",get children(){return[k(u,{get["class"](){return J.tone==="info"?"text-base text-indigo-700 font-bold":"text-base text-orange-600 font-bold"},get children(){return J.eyebrow}}),k(u,{get["class"](){return v6.pageTitle},get children(){return J.title}}),k(u,{class:"text-lg text-slate-600",get children(){return J.description}})]}})}function v1(J){return k(T,{get["class"](){return J.compact?"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100"},get children(){return[e(()=>e(()=>!!J.icon)()?k(T,{get["class"](){return J.tone==="info"?"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100"},get children(){return k(u,{get["class"](){return J.tone==="info"?"text-2xl text-indigo-700 font-bold":"text-2xl text-slate-600 font-bold"},get children(){return J.icon}})}}):null),k(u,{get["class"](){return J.icon?"pt-7 text-2xl text-slate-900 font-bold":"text-lg text-slate-500 font-bold"},get children(){return J.title}}),e(()=>e(()=>!!J.detail)()?k(u,{class:"pt-4 text-lg text-slate-500",get children(){return J.detail}}):null)]}})}function u1(J){let Q=()=>J.dark?J.tone==="danger"?"text-base text-red-300":"text-base text-slate-300":J.tone==="danger"?"text-base text-red-500":"text-base text-slate-500";return k(T,{get["class"](){return J.dark?"w-full h-full px-6 flex-row items-center bg-slate-950":"w-full h-full flex-row items-center"},get children(){return k(u,{get["class"](){return Q()},get children(){return J.text}})}})}var uJ=5,u6=7,lJ=10,l1=138,c1=890,HJ=new b6("exa"),[cJ,U0]=JJ([]),[p1,e0]=JJ(!1),[l6,J4]=JJ("SEARCH HISTORY IS LOCAL"),M0=-1,Q4=!1;function i1(J){try{return JSON.parse(J)}catch{return null}}function d1(J){let Q=new Date(J*1000).toISOString();return Q.slice(0,10)+" · "+Q.slice(11,16)+" UTC"}function c6(J){return HJ.query(` + SELECT id,query,searched_at,status,result_count,top_title,error + FROM searches ORDER BY id DESC LIMIT ? OFFSET ? + `).all(lJ+1,J)}function a1(){if(Q4||!p1())return;Q4=!0;try{let J=c6(cJ().length);U0((Q)=>[...Q,...J.slice(0,lJ)]),e0(J.length>lJ)}finally{Q4=!1}}function p6(J){if(M0===J)return;try{let Q=HJ.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==uJ){U0([]),e0(!1),J4("SEARCH HISTORY IS LOCAL");return}let $=c6(0),Z=$.slice(0,lJ);U0(Z),e0($.length>lJ),J4(Z[0]?.status==="error"?String(Z[0].error||"EXA SEARCH FAILED").slice(0,80):Z.length?"SEARCH HISTORY UPDATED FROM SQLITE":"SEARCH HISTORY IS LOCAL"),M0=J}catch{U0([]),J4("SEARCH HISTORY IS LOCAL")}}function s1(){let J=Number(HJ.query("PRAGMA page_size").get()?.page_size??0),Q=Number(HJ.query("PRAGMA page_count").get()?.page_count??0),$=Number(HJ.query("PRAGMA freelist_count").get()?.freelist_count??0),Z=Number(HJ.query("PRAGMA user_version").get()?.user_version??0),X=Z===uJ?Number(HJ.query("SELECT COUNT(*) AS count FROM searches").get()?.count??0):0,W=Z===uJ?HJ.query(` SELECT id,searched_at,status,result_count,error FROM searches ORDER BY id DESC LIMIT 1 - `).get():null,M={searches:$("searches"),searchResults:$("search_results"),documents:$("documents")},U={database:"exa.sqlite",schemaVersion:q,expectedSchemaVersion:N0,retentionDays:V4,tableCounts:M,allocatedBytes:Z*X,reusableBytes:Z*W,latestSearch:G},V=G,H=V?` Latest #${V.id??"?"}: ${V.status??"unknown"}, ${V.result_count??0} results.`:" No searches yet.";return{text:`Exa storage (schema ${q}/${N0}): ${M.searches} searches, ${M.searchResults} results, ${M.documents} documents; ${V4}-day retention; ${U.allocatedBytes} bytes allocated (${U.reusableBytes} reusable).${H}`,details:U}}function K2(){return D(b,{class:"flex-col w-full h-full bg-slate-50",get children(){return[D(q2,{title:"EXA RESEARCH",back:!0,metaTop:"POCKET APP",metaBottom:"SQLITE HISTORY"}),D(z2,{eyebrow:"AGENT RESEARCH MEMORY",title:"Search history",description:"Every research.search call is saved here automatically.",tone:"info"}),D(b,{class:"grow px-6 pt-4 flex-col gap-3",get children(){return[D(u4,{get when(){return P4().length===0},get children(){return D(G2,{icon:"E",title:"No searches yet",detail:`Ask Pi Agent to research a topic. -The search and its results will appear here.`,tone:"info"})}}),D(m4,{get each(){return P4()},children:(J)=>D(b,{class:"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[D(b,{class:"w-[474] flex-col gap-2",get children(){return[D(x,{class:"text-lg text-slate-900 font-bold",get children(){return J.query.slice(0,60)}}),D(x,{class:"text-base text-slate-500",get children(){return(J.top_title||J.error||"No result title").slice(0,76)}}),D(x,{class:"text-base text-indigo-600 font-bold",get children(){return B2(J.searched_at)}})]}}),D(b,{get["class"](){return s(()=>J.status==="ok")()?W0.success.surface:W0.danger.surface},get children(){return D(x,{get["class"](){return s(()=>J.status==="ok")()?W0.success.text:W0.danger.text},get children(){return s(()=>J.status==="ok")()?J.result_count+" RESULTS":"FAILED"}})}})]}})})]}}),D(b,{class:"h-[96]",get children(){return D(H2,{get text(){return R4()},get tone(){return R4().includes("FAILED")?"danger":"neutral"},dark:!0})}})]}})}w4(0),e8(()=>D(K2,{})),globalThis.PocketPiApp={tick(){return""},update(){return""},dataChanged(J){let Q=j2(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),Y0):Y0;return w4($),""},invokeTool(J){try{let Q=J==="research.storage_status"?F2():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:Q.text,details:Q.details,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Unknown Exa task: "+J,isError:!0})},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});return""}}})(); + `).get():null,Y={database:"exa.sqlite",schemaVersion:Z,expectedSchemaVersion:uJ,retentionDays:u6,searches:X,allocatedBytes:J*Q,reusableBytes:J*$,latestSearch:W},j=W,U=j?` Latest #${j.id??"?"}: ${j.status??"unknown"}, ${j.result_count??0} results.`:" No searches yet.";return{text:`Exa storage (schema ${Z}/${uJ}): ${X} searches; ${u6}-day retention; ${Y.allocatedBytes} bytes allocated (${Y.reusableBytes} reusable).${U}`,details:Y}}function r1(){return k(T,{class:"flex-col w-full h-full bg-slate-50",get children(){return[k(N1,{title:"EXA RESEARCH",back:!0,metaTop:"POCKET APP",metaBottom:"SQLITE HISTORY"}),k(m1,{eyebrow:"AGENT RESEARCH MEMORY",title:"Search history",description:"Every research.search call is saved here automatically.",tone:"info"}),k(T,{class:"grow px-6 pt-4 flex-col",get children(){return[k(V4,{get when(){return cJ().length===0},get children(){return k(v1,{icon:"E",title:"No searches yet",detail:`Ask Pi Agent to research a topic. +The search and its results will appear here.`,tone:"info"})}}),k(V4,{get when(){return cJ().length>0},get children(){return k(E1,{get count(){return cJ().length},rowHeight:l1,height:c1,focusRows:!1,onNearEnd:a1,renderRow:(J)=>{let Q=()=>cJ()[J];return k(T,{class:"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[k(T,{class:"w-[474] flex-col gap-2",get children(){return[k(u,{class:"text-lg text-slate-900 font-bold",get children(){return Q().query.slice(0,60)}}),k(u,{class:"text-base text-slate-500",get children(){return(Q().top_title||Q().error||"No result title").slice(0,76)}}),k(u,{class:"text-base text-indigo-600 font-bold",get children(){return d1(Q().searched_at)}})]}}),k(T,{get["class"](){return e(()=>Q().status==="ok")()?F0.success.surface:F0.danger.surface},get children(){return k(u,{get["class"](){return e(()=>Q().status==="ok")()?F0.success.text:F0.danger.text},get children(){return e(()=>Q().status==="ok")()?Q().result_count+" RESULTS":"FAILED"}})}})]}})}})}})]}}),k(T,{class:"h-[96]",get children(){return k(u1,{get text(){return l6()},get tone(){return l6().includes("FAILED")?"danger":"neutral"},dark:!0})}})]}})}p6(0),D1(()=>k(r1,{})),globalThis.PocketPiApp={tick(){return""},update(){return""},dataChanged(J){let Q=i1(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),M0):M0;return p6($),""},invokeTool(J){try{let Q=J==="research.storage_status"?s1():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:Q.text,details:Q.details,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Unknown Exa task: "+J,isError:!0})},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});return""}}})(); diff --git a/apps/exa/dist/app.pak b/apps/exa/dist/app.pak index 871ac16798ad7018c14d36fdf26b313dd2f96fe4..cd006c212f6762c15803b0de812229b5daf994db 100644 GIT binary patch delta 58 zcmbQxCpZC!b}+Iu?rh!3*t(Ocbtm)Ioh*5FLaZDN3=9p9oIvt`BR7cLZg0{var k=["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"];var F=65536,K=131072,g=262144,W=32,$=8192,E=30000,j=120000;var f={unavailable:"unavailable",invalidRequest:"invalid_request",busy:"busy",dns:"dns",connect:"connect",tls:"tls",timeout:"timeout",redirect:"redirect",responseTooLarge:"response_too_large",protocol:"protocol",cancelled:"cancelled",other:"other"};var b={};for(let r=0;r<64;r++)b["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[r]]=r;function q(r){let n=0;for(let t=0;t65535)t++;n+=a<128?1:a<2048?2:a<65536?3:4}let c=new Uint8Array(n),h=0;for(let t=0;t65535)t++;else if(a>=55296&&a<=57343)a=65533;if(a<128)c[h++]=a;else if(a<2048)c[h++]=192|a>>6,c[h++]=128|a&63;else if(a<65536)c[h++]=224|a>>12,c[h++]=128|a>>6&63,c[h++]=128|a&63;else c[h++]=240|a>>18,c[h++]=128|a>>12&63,c[h++]=128|a>>6&63,c[h++]=128|a&63}return c}function H(r){let n="",c=0;while(cr.length)throw Error("invalid UTF-8");for(let i=0;i1114111||t>=55296&&t<=57343||a===1&&t<128||a===2&&t<2048||a===3&&t<65536)throw Error("invalid UTF-8");if(t<65536)n+=String.fromCharCode(t);else t-=65536,n+=String.fromCharCode(55296+(t>>10),56320+(t&1023))}return n}var M=new Set;function V(r){return M.add(r),()=>M.delete(r)}class l extends Error{constructor(r,n){super(n);this.name="NetError",this.code=r}}class Q{constructor(r,n,c,h){this.status=r,this.url=n,this.headers=Object.freeze({...c}),this.ok=r>=200&&r<300,this.data=new Uint8Array(h)}get byteLength(){return this.data.byteLength}async bytes(){return this.data.slice()}async arrayBuffer(){return this.data.slice().buffer}async text(){try{return H(this.data)}catch{throw Error("net: response is not valid UTF-8")}}async json(){return JSON.parse(await this.text())}}var I=new Map,w=null,D=null;function o(){let r=globalThis.net;if(!r||typeof r!=="object")return null;let n=r;return typeof n.start==="function"&&typeof n.take==="function"&&typeof n.cancel==="function"&&typeof n.poll==="function"&&typeof n.lastError==="function"?n:null}function Z(r){let n=String(r);for(let c of Object.values(f))if(c===n)return c;return f.other}function p(r){let n=I.get(r.h);if(!n)return;if(I.delete(r.h),r.t==="error")n.reject(new l(Z(r.code),String(r.message||r.code)));else if(!Number.isInteger(r.status)||r.status<100||r.status>599||typeof r.url!=="string"||typeof r.headers!=="object"||r.headers===null||!Number.isInteger(r.bytes)||r.bytes<0||r.bytes>g)n.ops.cancel(r.h),n.reject(new l(f.protocol,"net: malformed done event"));else{let c=new ArrayBuffer(r.bytes);if(n.ops.take(r.h,c)!==r.bytes)n.ops.cancel(r.h),n.reject(new l(f.protocol,"net: response body transfer failed"));else n.resolve(new Q(r.status,r.url,r.headers,c))}if(I.size===0&&w)w(),w=null,D=null}function O(){if(I.size===0)return;let r=D;if(!r)return;let n=r.poll();if(n!==void 0){let c=null;try{c=JSON.parse(n)}catch{}if(!Array.isArray(c))for(let[h,t]of I)r.cancel(h),I.delete(h),t.reject(new l(f.protocol,"net: malformed event batch"));else for(let h of c){if(!h||typeof h!=="object")continue;let t=h;if(!Number.isInteger(t.h)||t.t!=="done"&&t.t!=="error")continue;p(t)}}if(I.size===0&&w)w(),w=null,D=null}function J(r,n){return Promise.reject(new l(r,n))}function z(r,n,c,h){if(!Number.isInteger(r)||rc)throw new l(f.invalidRequest,`net: ${h} must be ${n}..${c}`);return r}function v(r){let n=Object.create(null),c=0,h=0;for(let t of Object.keys(r??{})){let a=t.toLowerCase(),i=String(r[t]);if(!/^[!#$%&'*+.^_`|~0-9a-z-]+$/.test(a)||/[\r\n]/.test(i))throw new l(f.invalidRequest,`net: invalid header ${t}`);if(c++,h+=q(a).byteLength+q(i).byteLength+4,c>W||h>$)throw new l(f.invalidRequest,"net: request headers exceed limits");n[a]=i}return n}function rr(r){if(r===void 0)return new Uint8Array(0);if(typeof r==="string")return q(r);if(r instanceof Uint8Array)return r.slice();if(r instanceof ArrayBuffer)return new Uint8Array(r.slice(0));throw new l(f.invalidRequest,"net: body must be string or bytes")}function Y(r,n={}){let c=o();if(!c)return J(f.unavailable,"net: host did not mount the net module");try{if(typeof r!=="string"||!/^https?:\/\/[^\s/]+(?:\/|$)/.test(r))throw new l(f.invalidRequest,"net: url must be absolute http:// or https://");let h=n.method??"GET";if(!k.includes(h))throw new l(f.invalidRequest,`net: unsupported method ${String(h)}`);let t=rr(n.body);if((h==="GET"||h==="HEAD")&&t.byteLength>0)throw new l(f.invalidRequest,`net: ${h} cannot have a body`);if(t.byteLength>F)throw new l(f.invalidRequest,"net: request body exceeds 64 KiB");let a=z(n.timeoutMs??E,1,j,"timeoutMs"),i=z(n.maxBytes??K,1,g,"maxBytes"),x=JSON.stringify({url:r,method:h,headers:v(n.headers),timeoutMs:a,maxBytes:i});if(D&&D!==c)throw new l(f.unavailable,"net: mounted host changed while requests are pending");let s=c.start(x,t.buffer);if(!Number.isInteger(s)||s<0){let T=c.lastError()||"unavailable: request refused",L=T.indexOf(":"),R=Z(L<0?f.other:T.slice(0,L)),_=L<0?T:T.slice(L+1).trim();return J(R,_)}return new Promise((T,L)=>{if(I.set(s,{ops:c,resolve:T,reject:L}),D=c,!w)w=V(O)})}catch(h){return h instanceof l?Promise.reject(h):J(f.invalidRequest,String(h))}}var X=globalThis.db,G=X.open("exa");if(G<0)throw Error("open exa.sqlite");var nr=4,cr=7,hr=cr*24*60*60;function tr(){return String(X.lastError(G)||"SQLite operation failed")}function S(r){if(X.exec(G,r)!==0)throw Error(tr())}function P(r,n=[]){let c=JSON.parse(X.query(G,r,JSON.stringify(n)));if(c.error)throw Error(String(c.error));return c}function A(r,n=[]){return P(r,n)}var ar=P("PRAGMA user_version");if(Number(ar?.user_version??0)!==nr)S(` - DROP TABLE IF EXISTS search_results; +(()=>{var Z=["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"];var z=65536,V=131072,K=262144,g=32,j=8192,F=30000,M=120000;var i={unavailable:"unavailable",invalidRequest:"invalid_request",busy:"busy",dns:"dns",connect:"connect",tls:"tls",timeout:"timeout",redirect:"redirect",responseTooLarge:"response_too_large",protocol:"protocol",cancelled:"cancelled",other:"other"};var E={};for(let f=0;f<64;f++)E["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[f]]=f;function J(f){let n=0;for(let h=0;h65535)h++;n+=a<128?1:a<2048?2:a<65536?3:4}let c=new Uint8Array(n),r=0;for(let h=0;h65535)h++;else if(a>=55296&&a<=57343)a=65533;if(a<128)c[r++]=a;else if(a<2048)c[r++]=192|a>>6,c[r++]=128|a&63;else if(a<65536)c[r++]=224|a>>12,c[r++]=128|a>>6&63,c[r++]=128|a&63;else c[r++]=240|a>>18,c[r++]=128|a>>12&63,c[r++]=128|a>>6&63,c[r++]=128|a&63}return c}function S(f){let n="",c=0;while(cf.length)throw Error("invalid UTF-8");for(let L=0;L1114111||h>=55296&&h<=57343||a===1&&h<128||a===2&&h<2048||a===3&&h<65536)throw Error("invalid UTF-8");if(h<65536)n+=String.fromCharCode(h);else h-=65536,n+=String.fromCharCode(55296+(h>>10),56320+(h&1023))}return n}var X=new Set;function Y(f){return X.add(f),()=>X.delete(f)}class w extends Error{constructor(f,n){super(n);this.name="NetError",this.code=f}}class O{constructor(f,n,c,r){this.status=f,this.url=n,this.headers=Object.freeze({...c}),this.ok=f>=200&&f<300,this.data=new Uint8Array(r)}get byteLength(){return this.data.byteLength}async bytes(){return this.data.slice()}async arrayBuffer(){return this.data.slice().buffer}async text(){try{return S(this.data)}catch{throw Error("net: response is not valid UTF-8")}}async json(){return JSON.parse(await this.text())}}var A=new Map,l=null,D=null;function v(){let f=globalThis.net;if(!f||typeof f!=="object")return null;let n=f;return typeof n.start==="function"&&typeof n.take==="function"&&typeof n.cancel==="function"&&typeof n.poll==="function"&&typeof n.lastError==="function"?n:null}function B(f){let n=String(f);for(let c of Object.values(i))if(c===n)return c;return i.other}function p(f){let n=A.get(f.h);if(!n)return;if(A.delete(f.h),f.t==="error")n.reject(new w(B(f.code),String(f.message||f.code)));else if(!Number.isInteger(f.status)||f.status<100||f.status>599||typeof f.url!=="string"||typeof f.headers!=="object"||f.headers===null||!Number.isInteger(f.bytes)||f.bytes<0||f.bytes>K)n.ops.cancel(f.h),n.reject(new w(i.protocol,"net: malformed done event"));else{let c=new ArrayBuffer(f.bytes);if(n.ops.take(f.h,c)!==f.bytes)n.ops.cancel(f.h),n.reject(new w(i.protocol,"net: response body transfer failed"));else n.resolve(new O(f.status,f.url,f.headers,c))}if(A.size===0&&l)l(),l=null,D=null}function U(){if(A.size===0)return;let f=D;if(!f)return;let n=f.poll();if(n!==void 0){let c=null;try{c=JSON.parse(n)}catch{}if(!Array.isArray(c))for(let[r,h]of A)f.cancel(r),A.delete(r),h.reject(new w(i.protocol,"net: malformed event batch"));else for(let r of c){if(!r||typeof r!=="object")continue;let h=r;if(!Number.isInteger(h.h)||h.t!=="done"&&h.t!=="error")continue;p(h)}}if(A.size===0&&l)l(),l=null,D=null}function Q(f,n){return Promise.reject(new w(f,n))}function t(f,n,c,r){if(!Number.isInteger(f)||fc)throw new w(i.invalidRequest,`net: ${r} must be ${n}..${c}`);return f}function e(f){let n=Object.create(null),c=0,r=0;for(let h of Object.keys(f??{})){let a=h.toLowerCase(),L=String(f[h]);if(!/^[!#$%&'*+.^_`|~0-9a-z-]+$/.test(a)||/[\r\n]/.test(L))throw new w(i.invalidRequest,`net: invalid header ${h}`);if(c++,r+=J(a).byteLength+J(L).byteLength+4,c>g||r>j)throw new w(i.invalidRequest,"net: request headers exceed limits");n[a]=L}return n}function o(f){if(f===void 0)return new Uint8Array(0);if(typeof f==="string")return J(f);if(f instanceof Uint8Array)return f.slice();if(f instanceof ArrayBuffer)return new Uint8Array(f.slice(0));throw new w(i.invalidRequest,"net: body must be string or bytes")}function P(f,n={}){let c=v();if(!c)return Q(i.unavailable,"net: host did not mount the net module");try{if(typeof f!=="string"||!/^https?:\/\/[^\s/]+(?:\/|$)/.test(f))throw new w(i.invalidRequest,"net: url must be absolute http:// or https://");let r=n.method??"GET";if(!Z.includes(r))throw new w(i.invalidRequest,`net: unsupported method ${String(r)}`);let h=o(n.body);if((r==="GET"||r==="HEAD")&&h.byteLength>0)throw new w(i.invalidRequest,`net: ${r} cannot have a body`);if(h.byteLength>z)throw new w(i.invalidRequest,"net: request body exceeds 64 KiB");let a=t(n.timeoutMs??F,1,M,"timeoutMs"),L=t(n.maxBytes??V,1,K,"maxBytes"),x=JSON.stringify({url:f,method:r,headers:e(n.headers),timeoutMs:a,maxBytes:L});if(D&&D!==c)throw new w(i.unavailable,"net: mounted host changed while requests are pending");let k=c.start(x,h.buffer);if(!Number.isInteger(k)||k<0){let q=c.lastError()||"unavailable: request refused",u=q.indexOf(":"),R=B(u<0?i.other:q.slice(0,u)),b=u<0?q:q.slice(u+1).trim();return Q(R,b)}return new Promise((q,u)=>{if(A.set(k,{ops:c,resolve:q,reject:u}),D=c,!l)l=Y(U)})}catch(r){return r instanceof w?Promise.reject(r):Q(i.invalidRequest,String(r))}}var H=globalThis.db,$=H.open("exa");if($<0)throw Error("open exa.sqlite");var T=5,ff=7,nf=ff*24*60*60,cf=60000;function rf(){return String(H.lastError($)||"SQLite operation failed")}function G(f){if(H.exec($,f)!==0)throw Error(rf())}function N(f,n=[]){let c=JSON.parse(H.query($,f,JSON.stringify(n)));if(c.error)throw Error(String(c.error));return c}function W(f,n=[]){return N(f,n)}var hf=N("PRAGMA user_version");if(Number(hf?.user_version??0)!==T)G(` DROP TABLE IF EXISTS searches; - DROP TABLE IF EXISTS documents; CREATE TABLE searches ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - query TEXT NOT NULL, - searched_at INTEGER NOT NULL, - status TEXT NOT NULL, - result_count INTEGER NOT NULL DEFAULT 0, - error TEXT - ); - CREATE INDEX searches_retention ON searches(searched_at); - CREATE TABLE search_results ( - search_id INTEGER NOT NULL, - rank INTEGER NOT NULL, - title TEXT, - url TEXT NOT NULL, - published_at TEXT, - author TEXT, - score TEXT, - highlight TEXT, - PRIMARY KEY(search_id, rank) - ); - CREATE TABLE documents ( - url TEXT PRIMARY KEY, - fetched_at INTEGER NOT NULL, - title TEXT, - published_at TEXT, - author TEXT, - text TEXT NOT NULL - ); - CREATE INDEX documents_recent ON documents(fetched_at DESC); - PRAGMA user_version=4; - `);function y(){return Math.floor(Date.now()/1000)}function U(r){let n=r-hr;A("DELETE FROM search_results WHERE search_id IN (SELECT id FROM searches WHERE searched_at < ?)",[n]),A("DELETE FROM searches WHERE searched_at < ?",[n]),A("DELETE FROM documents WHERE fetched_at < ?",[n])}function fr(r){return r===null||r===void 0||typeof r==="object"?null:String(r)}function u(r,n){if(!r||typeof r!=="object")return null;for(let c of n){let h=fr(r[c]);if(h!==null)return h}return null}function ir(r){if(Array.isArray(r?.highlights))return r.highlights.map(String).join(` -`).slice(0,1200);return u(r,["highlight","summary","text"])?.slice(0,1200)??null}async function N(r,n){let c=await Y(`https://api.exa.ai${r}`,{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify(n),timeoutMs:12000,maxBytes:98304}),h=await c.json();if(!c.ok)throw Error(`Exa HTTP ${c.status}: ${JSON.stringify(h)}`);return h}function e(r){S("BEGIN IMMEDIATE");try{r(),S("COMMIT")}catch(n){try{S("ROLLBACK")}catch{}throw n}globalThis.app.commit()}async function lr(r){let n=String(r.query??"").trim();if(!n)throw Error("query is required");let c=y();try{let h={query:n,type:r.searchType??"auto",numResults:Math.max(1,Math.min(8,Number(r.numResults??5))),contents:{highlights:{maxCharacters:800}}};for(let i of["includeDomains","excludeDomains","startPublishedDate","endPublishedDate"])if(r[i]!==void 0)h[i]=r[i];let t=await N("/search",h),a=Array.isArray(t?.results)?t.results.slice(0,8):[];return e(()=>{let i=A("INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,?,NULL)",[n,c,"ok",a.length]),x=Number(i.lastInsertRowid||0);a.forEach((s,T)=>{let L=u(s,["url","id"]);if(!L)return;A(`INSERT INTO search_results(search_id,rank,title,url,published_at,author,score,highlight) - VALUES(?,?,?,?,?,?,?,?)`,[x,T,u(s,["title"]),L,u(s,["publishedDate","published_at","date"]),u(s,["author"]),u(s,["score"]),ir(s)])}),U(c)}),t}catch(h){let t=h instanceof Error?h.message:String(h);throw e(()=>{A("INSERT INTO searches(query,searched_at,status,result_count,error) VALUES(?,?,?,0,?)",[n,c,"error",t]),U(c)}),h}}async function ur(r){let n=String(r.url??"").trim();if(!n)throw Error("url is required");let c=await N("/contents",{urls:[n],text:{maxCharacters:Math.max(200,Math.min(12000,Number(r.maxCharacters??6000))),includeHtmlTags:!1}}),h=Array.isArray(c?.results)?c.results[0]:c;if(!h)throw Error("Exa returned no document");let t=u(h,["url","id"])||n,a=u(h,["text","content","summary"])||"",i=y();return e(()=>{A(`INSERT INTO documents(url,fetched_at,title,published_at,author,text) VALUES(?,?,?,?,?,?) - ON CONFLICT(url) DO UPDATE SET fetched_at=excluded.fetched_at,title=excluded.title, - published_at=excluded.published_at,author=excluded.author,text=excluded.text`,[t,i,u(h,["title"]),u(h,["publishedDate","published_at","date"]),u(h,["author"]),a]),U(i)}),{status:"ok",provider:"exa",requestId:c?.requestId,document:h,costDollars:c?.costDollars}}var C,d=!1;function m(r){return JSON.stringify({text:r instanceof Error?r.message:String(r),isError:!0})}function B(r){if(d)throw Error("Exa Data Action is already running");d=!0,C=void 0,r().then((n)=>{C=JSON.stringify({text:JSON.stringify(n),details:n,isError:!1}),d=!1},(n)=>{C=m(n),d=!1})}globalThis.PocketPiData={beginInvokeTask(r){B(async()=>{throw Error("Unknown Exa Data Action: "+r)})},beginInvokeTool(r,n){try{let c=JSON.parse(n);B(()=>r==="research.search"?lr(c):r==="research.fetch"?ur(c):Promise.reject(Error("Unknown Exa tool: "+r)))}catch(c){C=m(c),d=!1}},tick(){O()},pollResult(){let r=C;return C=void 0,r}};})(); + id INTEGER PRIMARY KEY AUTOINCREMENT, + query TEXT NOT NULL, + searched_at INTEGER NOT NULL, + status TEXT NOT NULL, + result_count INTEGER NOT NULL DEFAULT 0, + top_title TEXT, + error TEXT + ); + CREATE INDEX searches_retention ON searches(searched_at); + PRAGMA user_version=${T}; + `);function af(){return Math.floor(Date.now()/1000)}function s(f){let n=f-nf;W("DELETE FROM searches WHERE searched_at < ?",[n])}async function d(f,n){let c=await P(`https://api.exa.ai${f}`,{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify(n),timeoutMs:cf,maxBytes:98304}),r=await c.json();if(!c.ok)throw Error(`Exa HTTP ${c.status}: ${JSON.stringify(r)}`);return r}function y(f){G("BEGIN IMMEDIATE");try{f(),G("COMMIT")}catch(n){try{G("ROLLBACK")}catch{}throw n}globalThis.app.commit()}async function wf(f){let n=String(f.query??"").trim();if(!n)throw Error("query is required");let c=af();try{let r={query:n,type:f.searchType??"auto",numResults:Math.max(1,Math.min(10,Number(f.numResults??10))),contents:{highlights:{maxCharacters:800}}};for(let x of["includeDomains","excludeDomains","startPublishedDate","endPublishedDate","category","userLocation","additionalQueries","moderation"])if(f[x]!==void 0)r[x]=f[x];if(f.maxAgeHours!==void 0)r.contents.maxAgeHours=f.maxAgeHours;let h=await d("/search",r),a=Array.isArray(h?.results)?h.results:[],L=typeof a[0]?.title==="string"?a[0].title:null;return y(()=>{W("INSERT INTO searches(query,searched_at,status,result_count,top_title,error) VALUES(?,?,?,?,?,NULL)",[n,c,"ok",a.length,L]),s(c)}),h}catch(r){let h=r instanceof Error?r.message:String(r);throw y(()=>{W("INSERT INTO searches(query,searched_at,status,result_count,top_title,error) VALUES(?,?,?,0,NULL,?)",[n,c,"error",h]),s(c)}),r}}async function Lf(f){let n=String(f.url??"").trim();if(!n)throw Error("url is required");let c={urls:[n],text:{maxCharacters:Math.max(200,Math.min(12000,Number(f.maxCharacters??6000))),includeHtmlTags:!1}};if(f.maxAgeHours!==void 0)c.maxAgeHours=f.maxAgeHours;return d("/contents",c)}var I,C=!1;function _(f){return JSON.stringify({text:f instanceof Error?f.message:String(f),isError:!0})}function m(f){if(C)throw Error("Exa Data Action is already running");C=!0,I=void 0,f().then((n)=>{I=JSON.stringify({text:JSON.stringify(n),isError:!1}),C=!1},(n)=>{I=_(n),C=!1})}globalThis.PocketPiData={beginInvokeTask(f){m(async()=>{throw Error("Unknown Exa Data Action: "+f)})},beginInvokeTool(f,n){try{let c=JSON.parse(n);m(()=>f==="research.search"?wf(c):f==="research.fetch"?Lf(c):Promise.reject(Error("Unknown Exa tool: "+f)))}catch(c){I=_(c),C=!1}},tick(){U()},pollResult(){let f=I;return I=void 0,f}};})(); diff --git a/apps/exa/pocket.json b/apps/exa/pocket.json index 5064dba..e1bb43a 100644 --- a/apps/exa/pocket.json +++ b/apps/exa/pocket.json @@ -4,7 +4,7 @@ "id": "dev.pocket-stack.exa", "name": "exa", "title": "Exa Research", - "version": "1.0.0", + "version": "1.1.0", "engine": {"capabilities":{"requires":["data.fs","data.sqlite","net.http"]}}, "app": {"entry":"app.tsx","output":"app","framework":"solid","viewport":{"logical":[720,1280],"presentation":"fit"}} } diff --git a/apps/pi-agent/dist/agent.js b/apps/pi-agent/dist/agent.js index 806a0e8..bf8f695 100644 --- a/apps/pi-agent/dist/agent.js +++ b/apps/pi-agent/dist/agent.js @@ -384,8 +384,8 @@ if(this.activeRun){throw new Error("Agent is already processing.")}const abortCo const failureMessage={role:"assistant",content:[{type:"text",text:""}],api:this._state.model.api,provider:this._state.model.provider,model:this._state.model.id,usage:EMPTY_USAGE,stopReason:aborted?"aborted":"error",errorMessage:error instanceof Error?error.message:String(error),timestamp:Date.now()};await this.processEvents({type:"message_start",message:failureMessage});await this.processEvents({type:"message_end",message:failureMessage});await this.processEvents({type:"turn_end",message:failureMessage, toolResults:[]});await this.processEvents({type:"agent_end",messages:[failureMessage]})}finishRun(){this._state.isStreaming=false;this._state.streamingMessage=void 0;this._state.pendingToolCalls=new Set;this.activeRun?.resolve();this.activeRun=void 0}async processEvents(event){switch(event.type){case"message_start":this._state.streamingMessage=event.message;break;case"message_update":this._state.streamingMessage=event.message;break;case"message_end":this._state.streamingMessage=void 0;this._state. messages.push(event.message);break;case"tool_execution_start":{const pendingToolCalls=new Set(this._state.pendingToolCalls);pendingToolCalls.add(event.toolCallId);this._state.pendingToolCalls=pendingToolCalls;break}case"tool_execution_end":{const pendingToolCalls=new Set(this._state.pendingToolCalls);pendingToolCalls.delete(event.toolCallId);this._state.pendingToolCalls=pendingToolCalls;break}case"turn_end":if(event.message.role==="assistant"&&event.message.errorMessage){this._state.errorMessage= -event.message.errorMessage}break;case"agent_end":this._state.streamingMessage=void 0;break}const signal=this.activeRun?.abortController.signal;if(!signal){throw new Error("Agent listener invoked outside active run")}for(const listener of this.listeners){await listener(event,signal)}}};var events=[];var pendingModels=new Map;var pendingTools=new Map;var agent=null;var emptyUsage=()=>({input:0,output:0,cacheRead:0,cacheWrite:0,reasoning:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}});function modelFor(config){const provider=config.provider||"openai";const deepseek=provider==="deepseek";const anthropic=provider==="anthropic";const defaultModel=deepseek?"deepseek-v4-pro":"gpt-5-mini";return{id:config.model||defaultModel,name:config.model||defaultModel,provider, -api:anthropic?"anthropic-messages":"openai-completions",baseUrl:deepseek?"https://api.deepseek.com":anthropic?"https://api.anthropic.com":"https://api.openai.com/v1",reasoning:deepseek,thinkingLevelMap:deepseek?{off:null,minimal:null,low:null,medium:null,high:"high",xhigh:"max",max:"max"}:void 0,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:deepseek?1e6:128e3,maxTokens:deepseek?384e3:16384}}function hostStream(model,context,options={}){const stream=new AssistantMessageEventStream; +event.message.errorMessage}break;case"agent_end":this._state.streamingMessage=void 0;break}const signal=this.activeRun?.abortController.signal;if(!signal){throw new Error("Agent listener invoked outside active run")}for(const listener of this.listeners){await listener(event,signal)}}};var events=[];var pendingModels=new Map;var pendingTools=new Map;var agent=null;var emptyUsage=()=>({input:0,output:0,cacheRead:0,cacheWrite:0,reasoning:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}});function modelFor(config){const provider=config.provider||"openai";const deepseek=provider==="deepseek";const anthropic=provider==="anthropic";const defaultModel=deepseek?"deepseek-v4-flash":"gpt-5-mini";return{id:config.model||defaultModel,name:config.model||defaultModel, +provider,api:anthropic?"anthropic-messages":"openai-completions",baseUrl:deepseek?"https://api.deepseek.com":anthropic?"https://api.anthropic.com":"https://api.openai.com/v1",reasoning:deepseek,thinkingLevelMap:deepseek?{off:null,minimal:null,low:null,medium:null,high:"high",xhigh:"max",max:"max"}:void 0,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:deepseek?1e6:128e3,maxTokens:deepseek?384e3:16384}}function hostStream(model,context,options={}){const stream=new AssistantMessageEventStream; const partial={role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,usage:emptyUsage(),stopReason:"stop",timestamp:Date.now()};try{if(!globalThis.host)throw new Error("Pocket Pi Agent host is unavailable");const id=globalThis.host.startModel(JSON.stringify({model,context,options}));pendingModels.set(id,{stream,model,partial,started:false,thinkingStarted:false,textStarted:false,thinking:"",text:""})}catch(error){pushModelError(stream,model,String(error))}return stream} function ensureModelStarted(pending){if(pending.started)return;pending.started=true;pending.stream.push({type:"start",partial:{...pending.partial}})}function syncContent(pending){const content=[];if(pending.thinkingStarted){content.push({type:"thinking",thinking:pending.thinking,thinkingSignature:"reasoning_content"})}if(pending.textStarted)content.push({type:"text",text:pending.text});pending.partial.content=content}function pushThinkingDelta(pending,delta){if(!delta)return;if(pending.textStarted) throw new Error("thinking delta arrived after text output started");ensureModelStarted(pending);if(!pending.thinkingStarted){pending.thinkingStarted=true;syncContent(pending);pending.stream.push({type:"thinking_start",contentIndex:0,partial:{...pending.partial}})}pending.thinking+=delta;syncContent(pending);pending.stream.push({type:"thinking_delta",contentIndex:0,delta,partial:{...pending.partial}})}function textIndex(pending){return pending.thinkingStarted?1:0}function pushTextDelta(pending,delta){ diff --git a/apps/robinhood/TOOLS.md b/apps/robinhood/TOOLS.md new file mode 100644 index 0000000..71fb194 --- /dev/null +++ b/apps/robinhood/TOOLS.md @@ -0,0 +1,112 @@ +# Robinhood Tool contract + +Pocket Pi snapshots the upstream Robinhood Trading MCP catalog, but does not put +all upstream schemas in every model request. The checked-in snapshot currently +contains 54 upstream Tools. The initial Agent catalog contains four small Pocket +Pi Tools: + +- `robinhood.search_tools` returns matching upstream descriptions and exact JSON + Schemas from the local snapshot. It performs no provider request. +- `robinhood.call` validates one upstream call against that schema and routes it + through the native static allowlist. +- `robinhood.refresh_portfolio` refreshes the bounded fixed-View projection. +- `robinhood.storage_status` inspects local projection health. + +This is Pocket Pi's cross-model fallback for deferred Tool loading. It follows +the same load-on-demand design as OpenAI client-executed Tool Search, but is not +the Responses API's native `tool_search` wire protocol. Native Tool Search is +currently limited to supported OpenAI models, while Pocket Pi also supports +other model backends. If a backend gains native deferred loading, it can expose +the same snapshot as dynamically loaded normal function definitions without +changing the Robinhood Data Action. + +References: + +- Robinhood Agentic Trading: +- Robinhood Agentic Trading overview: +- OpenAI Tool Search: +- GitHub Copilot CLI Tool Search: + +## Catalog and schema source + +`tool-catalog.json` is the Robinhood App-owned runtime catalog captured from an +authenticated MCP `initialize` and `tools/list` exchange with +`https://agent.robinhood.com/mcp/trading`. It stores the upstream name, +input schema, and one combined description containing upstream usage guidance +plus Pocket Pi safety and persistence behavior. Credentials are never written to the catalog, App +bundle, SQLite, or Agent context. Updating this catalog is an explicit App +maintenance change and must be reviewed together with the native allowlist and +contract tests. + +This file and the catalog have different roles: + +- `tool-catalog.json` is executable source data. The Data Action build inlines it + into `dist/data-action.js`, where `searchTools()` and + `validatedProviderCall()` use it at runtime. Rust contract tests also read the + source snapshot directly to keep all 54 names aligned with + `agent-app.json.providerOperations`. +- `TOOLS.md` is human-facing maintenance documentation. It is not imported by + the build or read by the device runtime. + +This catalog is not a global AgentOS requirement. Robinhood uses deferred +lookup because exposing 54 complete schemas in every model request would be +wasteful. Small Apps such as Exa declare their few Tools directly and need no +private catalog. Any future large App owns its own catalog under that App. + +The 54 Tools are split into eight searchable domains. Each domain has at most +nine Tools: `account_portfolio`, `equity_trading`, `equity_market_data`, +`option_trading`, `option_market_data`, `watchlists`, `scanners`, and `indexes`. +Exact-name lookup is preferred when the Agent already knows the upstream name. + +The current upstream schemas use `type`, `properties`, `required`, +`additionalProperties`, `items`, `minimum`, and `maximum`. Pocket Pi validates +all of those keywords before crossing the native service boundary. The native +allowlist is built from `agent-app.json.providerOperations`, so a Tool must be +present in both the snapshot and the installed App descriptor. + +## Minimal persistence policy + +SQLite is a fixed-View projection, not a generic Tool cache or audit log. A +provider result commits only when the current Robinhood View consumes it. + +| Upstream operation | SQLite effect | Reason | +| --- | --- | --- | +| `get_accounts` | Replace `accounts` | Account selector and Agentic-account badge | +| `get_portfolio` | Upsert `portfolio_current` and `total_value` | Dashboard values and chart | +| `get_equity_positions` | Replace that account's `positions` | Positions View | +| `get_equity_orders` | Replace that account's `activities` | Activity View | +| `get_realized_pnl` | Upsert day or week P&L in `portfolio_current` | Dashboard P&L | +| `place_equity_order`, `cancel_equity_order` | Upsert only the returned order state in `activities` | The Tool result directly changes Activity; no second provider call is needed | +| Other 47 upstream Tools | None | Current fixed View does not consume the result | + +`refresh_portfolio` is the only aggregate refresh. It obtains accounts first, +batches the required per-account portfolio/position/order/P&L calls, and writes +their bounded projections plus one `refresh_runs` record in a transaction. One +successful transaction emits one App revision; the foreground View then +re-queries its bounded projection at the frame boundary. Direct-return Tools do +not call `app.commit()` and therefore cause no SQLite write or View invalidation. + +Equity place/cancel deliberately does not start a nested MCP refresh after the +provider action. It uses the returned order payload to update `activities` in +one short transaction. This keeps the App Data Action within its bounded stack +and avoids extra network, CPU, SQLite, and revision work. Portfolio and +positions converge on the next normal scheduled or explicit refresh. + +No `tool_runs`, raw-response, quote cache, fundamentals cache, options cache, +watchlist cache, or scanner cache is created while the fixed View does not need +it. + +## Agent execution and safety + +An Agent first searches for the operation, reads the returned full description +and schema, then calls `robinhood.call` with the exact upstream name and a +schema-valid `arguments` object. The App completion path returns the actual +provider result to the pending Agent Tool call; a queued receipt is never +mistaken for completion. The provider JSON is serialized once as ToolResult +`text`; it is not duplicated into `details`, so large market-data and options +responses do not retain a second copy in the QuickJS/Agent bridge. + +Review Tools are explicitly described as non-submitting. Place, cancel, and +exercise Tools retain Robinhood's confirmation and Agentic-account guidance and +add Pocket Pi's real-account warning. A repeated real-money order must reuse the +same `ref_id`; an ambiguous transport result must not be retried with a new ID. diff --git a/apps/robinhood/agent-app.json b/apps/robinhood/agent-app.json index ceeaa19..f5acc22 100644 --- a/apps/robinhood/agent-app.json +++ b/apps/robinhood/agent-app.json @@ -1,21 +1,152 @@ { "id": "robinhood", - "version": "1.0.0", - "dataVersion": 4, + "version": "1.1.0", + "dataVersion": 5, + "providerOperations": [ + "add_option_to_watchlist", + "add_to_watchlist", + "cancel_equity_order", + "cancel_option_exercise", + "cancel_option_order", + "create_scan", + "create_watchlist", + "exercise_option", + "follow_watchlist", + "get_accounts", + "get_earnings_calendar", + "get_earnings_results", + "get_equity_fundamentals", + "get_equity_historicals", + "get_equity_orders", + "get_equity_positions", + "get_equity_price_book", + "get_equity_quotes", + "get_equity_tax_lots", + "get_equity_technical_indicators", + "get_equity_tradability", + "get_financials", + "get_index_historicals", + "get_index_quotes", + "get_indexes", + "get_limited_margin_upgrade_info", + "get_option_chains", + "get_option_historicals", + "get_option_instruments", + "get_option_level_upgrade_info", + "get_option_orders", + "get_option_positions", + "get_option_quotes", + "get_option_watchlist", + "get_pnl_trade_history", + "get_popular_watchlists", + "get_portfolio", + "get_realized_pnl", + "get_scanner_filter_specs", + "get_scans", + "get_watchlist_items", + "get_watchlists", + "place_equity_order", + "place_option_order", + "remove_from_watchlist", + "remove_option_from_watchlist", + "review_equity_order", + "review_option_order", + "run_scan", + "search", + "unfollow_watchlist", + "update_scan_config", + "update_scan_filters", + "update_watchlist" + ], "tools": [ - {"name":"robinhood.get_accounts","description":"List Robinhood brokerage accounts. Read-only.","parameters":{"type":"object","properties":{},"additionalProperties":true}}, - {"name":"robinhood.get_portfolio","description":"Read the latest portfolio for an account and save it to the App database.","parameters":{"type":"object","properties":{"account_number":{"type":"string"}},"additionalProperties":true}}, - {"name":"robinhood.get_equity_positions","description":"Read equity positions and save them to the App database.","parameters":{"type":"object","properties":{"account_number":{"type":"string"}},"additionalProperties":true}}, - {"name":"robinhood.get_equity_orders","description":"Read equity orders and save them to the App database.","parameters":{"type":"object","properties":{"account_number":{"type":"string"}},"additionalProperties":true}}, - {"name":"robinhood.get_equity_historicals","description":"Read equity historicals and save them to the App database.","parameters":{"type":"object","properties":{"account_number":{"type":"string"}},"additionalProperties":true}}, - {"name":"robinhood.get_realized_pnl","description":"Read realized P&L and save it to the App database.","parameters":{"type":"object","properties":{"account_number":{"type":"string"}},"additionalProperties":true}}, - {"name":"robinhood.get_pnl_trade_history","description":"Read chronological realized P&L trade history.","parameters":{"type":"object","properties":{"account_number":{"type":"string"}},"additionalProperties":true}}, - {"name":"robinhood.review_equity_order","description":"Review an equity order without submitting it.","parameters":{"type":"object","additionalProperties":true}}, - {"name":"robinhood.refresh_portfolio","description":"Refresh accounts, portfolio, positions, orders and P&L into local SQLite.","parameters":{"type":"object","properties":{},"additionalProperties":false}}, - {"name":"robinhood.storage_status","description":"Inspect this App's local SQLite schema, row counts, and bounded recent row summaries without contacting Robinhood.","parameters":{"type":"object","properties":{},"additionalProperties":false}} + { + "name": "robinhood.search_tools", + "description": "Search Pocket Pi's checked-in Robinhood Trading MCP catalog. Use this before robinhood.call whenever the exact upstream Tool and arguments are not already present in the conversation. Returns the official description, exact JSON Schema, Pocket Pi persistence behavior, and whether the Tool is a real account or real-money action. This performs no Robinhood request and writes no SQLite data.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Natural-language capability or Tool-name fragment to find." + }, + "names": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Optional exact upstream Tool names to retrieve." + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 8, + "description": "Maximum matches. Defaults to 5." + }, + "namespace": { + "type": [ + "null", + "string" + ], + "description": "Optional domain filter: account_portfolio, equity_trading, equity_market_data, option_trading, option_market_data, watchlists, scanners, or indexes." + } + }, + "additionalProperties": false + } + }, + { + "name": "robinhood.call", + "description": "Invoke one upstream Robinhood Trading MCP Tool by its exact unnamespaced name. First use robinhood.search_tools and follow the returned JSON Schema and safety instructions. Pocket Pi validates arguments locally, native code enforces the checked-in allowlist, and the completed provider result is returned to the Agent. Never retry a real-money action with a new ref_id after an ambiguous transport result.", + "parameters": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Exact upstream Tool name returned by robinhood.search_tools." + }, + "arguments": { + "type": "object", + "description": "Arguments that satisfy that Tool's returned JSON Schema.", + "additionalProperties": true + } + }, + "required": [ + "name", + "arguments" + ], + "additionalProperties": false + } + }, + { + "name": "robinhood.refresh_portfolio", + "description": "Refresh accounts, portfolio, equity positions, recent equity orders, and day/week realized P&L into robinhood.sqlite. This is a local Pocket Pi aggregate and does not place, modify, or cancel orders.", + "parameters": { + "type": "object", + "properties": {}, + "additionalProperties": false + } + }, + { + "name": "robinhood.storage_status", + "description": "Inspect bounded Robinhood App SQLite table counts and recent run summaries without contacting Robinhood. Account numbers are returned only as suffixes.", + "parameters": { + "type": "object", + "properties": {}, + "additionalProperties": false + } + } + ], + "tasks": [ + "refreshPortfolio" ], - "tasks": ["refreshPortfolio"], "schedules": [ - {"id":"portfolio-refresh","everyMinutes":5,"task":"refreshPortfolio","args":{}} + { + "id": "portfolio-refresh", + "everyMinutes": 5, + "task": "refreshPortfolio", + "args": {} + } ] } diff --git a/apps/robinhood/app.tsx b/apps/robinhood/app.tsx index 67b39b5..2e995ef 100644 --- a/apps/robinhood/app.tsx +++ b/apps/robinhood/app.tsx @@ -4,7 +4,7 @@ import { mount } from "@pocketjs/framework"; import { Database } from "@pocketjs/framework/db"; import { ActionButton, EmptyState, MetricCard, PocketHeader, ScrollButtons, SectionHeading, statusBadge, StatusBar } from "../_shared/ui"; -const DB_SCHEMA_VERSION = 4; +const DB_SCHEMA_VERSION = 5; const db = new Database("robinhood"); type Screen = "dashboard" | "accounts" | "activity" | "positions"; @@ -247,7 +247,7 @@ function loadRefreshProjection(loadedRevision: number): void { setRefreshing(false); if (latestRun?.status === "failed") setStatus("REFRESH FAILED · " + String(latestRun.error || "UNKNOWN ERROR").slice(0, 52)); else if (latestRun?.status === "partial") setStatus("LIVE WITH PARTIAL DATA"); - else if (dashboard().observedAt) setStatus("LIVE / READ ONLY · " + relativeTime(dashboard().observedAt as number)); + else if (dashboard().observedAt) setStatus("LIVE · " + relativeTime(dashboard().observedAt as number)); else setStatus("WAITING FOR ROBINHOOD"); refreshLoadedRevision = loadedRevision; } @@ -264,7 +264,7 @@ function loadAccountProjection(accountNumber: string, loadedRevision: number): v if (cached?.loadedRevision === loadedRevision) { setDashboard(cached.value); loadChart(accountNumber, loadedRevision); - if (cached.value.observedAt && !refreshing()) setStatus("LIVE / READ ONLY · " + relativeTime(cached.value.observedAt)); + if (cached.value.observedAt && !refreshing()) setStatus("LIVE · " + relativeTime(cached.value.observedAt)); return; } setDashboard(EMPTY); @@ -349,7 +349,7 @@ function trend(): { change: string; percent: string; positive: boolean } { function Header(props: { title: string; metaBottom?: string }) { return ( - + ); } diff --git a/apps/robinhood/data-action.ts b/apps/robinhood/data-action.ts index 6a5a765..cff8ea8 100644 --- a/apps/robinhood/data-action.ts +++ b/apps/robinhood/data-action.ts @@ -1,11 +1,14 @@ -// Headless Robinhood data plane. Provider bodies are normalized in memory, -// then domain tables are changed in one transaction. The foreground View -// never sees provider payloads and never writes business state. +import toolCatalog from "./tool-catalog.json"; + +// Headless Robinhood data plane. Every declared provider Tool returns its live +// result to the Agent. Only data consumed by the fixed foreground View is +// normalized into SQLite; transient research/watchlist/options payloads never +// become App state merely because a Tool was called. const nativeDb = (globalThis as any).db; const handle = nativeDb.open("robinhood"); if (handle < 0) throw new Error("open robinhood.sqlite"); -const SCHEMA_VERSION = 4; +const SCHEMA_VERSION = 5; function dbError(): string { return String(nativeDb.lastError(handle) || "SQLite operation failed"); } function exec(sql: string): void { if (nativeDb.exec(handle, sql) !== 0) throw new Error(dbError()); } @@ -76,47 +79,15 @@ if (Number(version?.user_version ?? 0) !== SCHEMA_VERSION) { error TEXT ); CREATE INDEX IF NOT EXISTS refresh_runs_recent ON refresh_runs(id DESC); - CREATE TABLE IF NOT EXISTS equity_historicals ( - account_number TEXT NOT NULL, - span TEXT NOT NULL, - point_time TEXT NOT NULL, - price TEXT, - open TEXT, - high TEXT, - low TEXT, - close TEXT, - volume TEXT, - observed_at INTEGER NOT NULL, - PRIMARY KEY(account_number, span, point_time) - ); - CREATE TABLE IF NOT EXISTS pnl_trades ( - account_number TEXT NOT NULL, - trade_id TEXT NOT NULL, - occurred_at TEXT, - symbol TEXT, - side TEXT, - quantity TEXT, - price TEXT, - realized_pnl TEXT, - observed_at INTEGER NOT NULL, - PRIMARY KEY(account_number, trade_id) - ); - CREATE TABLE IF NOT EXISTS order_reviews ( - review_id TEXT PRIMARY KEY, - account_number TEXT, - symbol TEXT, - side TEXT, - quantity TEXT, - limit_price TEXT, - estimated_cost TEXT, - state TEXT, - observed_at INTEGER NOT NULL - ); - PRAGMA user_version=4; + PRAGMA user_version=5; `); } type DomainUpdate = { operation: string; args: any; value: any; observedAt: number }; +type ToolMetadata = { name: string; namespace: string; description: string; inputSchema: any }; + +const providerTools = (toolCatalog as any).tools as ToolMetadata[]; +const providerToolByName = new Map(providerTools.map((tool) => [tool.name, tool])); function now(): number { return Math.floor(Date.now() / 1000); } function text(value: unknown): string | null { @@ -153,14 +124,96 @@ function number(value: string | null): number | null { return Number.isFinite(parsed) ? parsed : null; } function accountNumber(value: any, args: any): string { - return deep(value, ["account_number", "accountNumber", "account"]) - || String(args?.account_number ?? args?.accountNumber ?? ""); + const requested = args?.account_number ?? args?.accountNumber; + return requested === null || requested === undefined || requested === "" + ? deep(value, ["account_number", "accountNumber", "account"]) || "" + : String(requested); } function list(value: any, names: string[]): any[] { const nested = deepArray(value, names); return nested.length ? nested : Array.isArray(value) ? value : value ? [value] : []; } +function searchTools(args: any): any { + const exact = Array.isArray(args?.names) + ? new Set(args.names.filter((name: any) => typeof name === "string")) + : new Set(); + const words = String(args?.query ?? "").toLowerCase().split(/[^a-z0-9_]+/).filter(Boolean); + const namespace = typeof args?.namespace === "string" ? args.namespace : ""; + if (!exact.size && !words.length) throw new Error("search_tools requires query or names"); + const limit = Math.max(1, Math.min(8, Number(args?.limit ?? 5) || 5)); + const matches = providerTools + .filter((tool) => !namespace || tool.namespace === namespace) + .map((tool) => { + const name = tool.name.toLowerCase(); + const haystack = name + " " + tool.description.toLowerCase(); + const score = exact.has(tool.name) ? 1000 + : words.reduce((total, word) => total + (name === word ? 100 : name.includes(word) ? 20 : haystack.includes(word) ? 3 : 0), 0); + return { tool, score }; + }) + .filter((item) => item.score > 0) + .sort((left, right) => right.score - left.score || left.tool.name.localeCompare(right.tool.name)) + .slice(0, limit) + .map(({ tool }) => ({ + name: tool.name, + namespace: tool.namespace, + description: tool.description, + inputSchema: tool.inputSchema, + })); + return { + source: (toolCatalog as any).source, + protocolVersion: (toolCatalog as any).protocolVersion, + matches, + }; +} + +function matchesType(value: any, expected: string): boolean { + if (expected === "null") return value === null; + if (expected === "array") return Array.isArray(value); + if (expected === "object") return value !== null && typeof value === "object" && !Array.isArray(value); + if (expected === "integer") return typeof value === "number" && Number.isInteger(value); + if (expected === "number") return typeof value === "number" && Number.isFinite(value); + return typeof value === expected; +} + +function validateSchema(value: any, schema: any, path = "arguments"): void { + const types = Array.isArray(schema?.type) ? schema.type : schema?.type ? [schema.type] : []; + if (types.length && !types.some((expected: string) => matchesType(value, expected))) { + throw new Error(path + " must be " + types.join(" or ")); + } + if (value === null) return; + if (typeof value === "number") { + if (typeof schema.minimum === "number" && value < schema.minimum) throw new Error(path + " is below minimum " + schema.minimum); + if (typeof schema.maximum === "number" && value > schema.maximum) throw new Error(path + " exceeds maximum " + schema.maximum); + } + if (Array.isArray(value)) { + if (schema.items) value.forEach((item, index) => validateSchema(item, schema.items, path + "[" + index + "]")); + return; + } + if (typeof value !== "object") return; + const properties = schema.properties || {}; + for (const required of schema.required || []) { + if (!(required in value)) throw new Error(path + "." + required + " is required"); + } + if (schema.additionalProperties === false) { + for (const key of Object.keys(value)) { + if (!(key in properties)) throw new Error(path + "." + key + " is not allowed"); + } + } + for (const [key, child] of Object.entries(value)) { + if (properties[key]) validateSchema(child, properties[key], path + "." + key); + } +} + +function validatedProviderCall(args: any): any { + const operation = typeof args?.name === "string" ? args.name : ""; + const tool = providerToolByName.get(operation); + if (!tool) throw new Error("Unknown Robinhood provider Tool: " + operation); + const providerArgs = args?.arguments; + validateSchema(providerArgs, tool.inputSchema); + return invokeProviderTool(operation, providerArgs); +} + function callTool(operation: string, args: any): any { const envelope = JSON.parse((globalThis as any).services.call( "mcp.client", @@ -291,60 +344,14 @@ function saveRealizedPnl(value: any, args: any, observedAt: number): void { ); } -function saveHistoricals(value: any, args: any, observedAt: number): void { - const account = accountNumber(value, args); - const span = String(args?.span ?? args?.interval ?? "default"); - const rows = list(value, ["historicals", "results", "data"]); - run("DELETE FROM equity_historicals WHERE account_number=? AND span=?", [account, span]); - rows.forEach((item, index) => { - const pointTime = deep(item, ["begins_at", "timestamp", "time", "date"]) || String(index); - run( - `INSERT INTO equity_historicals(account_number,span,point_time,price,open,high,low,close,volume,observed_at) - VALUES(?,?,?,?,?,?,?,?,?,?)`, - [account, span, pointTime, deep(item, ["price", "adjusted_close", "close_price"]), deep(item, ["open_price", "open"]), deep(item, ["high_price", "high"]), deep(item, ["low_price", "low"]), deep(item, ["close_price", "close"]), deep(item, ["volume"]), observedAt], - ); - }); -} - -function savePnlTrades(value: any, args: any, observedAt: number): void { - const account = accountNumber(value, args); - const rows = list(value, ["trades", "results", "data"]); - run("DELETE FROM pnl_trades WHERE account_number=?", [account]); - rows.forEach((item, index) => { - const occurredAt = deep(item, ["created_at", "updated_at", "date", "timestamp"]); - const tradeId = deep(item, ["id", "trade_id", "tradeId"]) || [occurredAt || observedAt, deep(item, ["symbol"]) || "TRADE", index].join(":"); - run( - `INSERT INTO pnl_trades(account_number,trade_id,occurred_at,symbol,side,quantity,price,realized_pnl,observed_at) - VALUES(?,?,?,?,?,?,?,?,?)`, - [account, tradeId, occurredAt, deep(item, ["symbol"]), (deep(item, ["side"]) || "").toUpperCase(), deep(item, ["quantity", "shares"]), deep(item, ["price", "average_price"]), deep(item, ["realized_pnl", "pnl", "amount"]), observedAt], - ); - }); -} - -function saveOrderReview(value: any, args: any, observedAt: number): void { - const account = accountNumber(value, args); - const symbol = deep(value, ["symbol"]) || text(args?.symbol); - const side = (deep(value, ["side"]) || text(args?.side) || "").toUpperCase(); - const quantity = deep(value, ["quantity", "shares"]) || text(args?.quantity); - const limitPrice = deep(value, ["limit_price", "limitPrice", "price"]) || text(args?.limit_price ?? args?.price); - const reviewId = deep(value, ["id", "review_id", "reviewId"]) || [account, symbol, side, quantity, limitPrice, observedAt].join(":"); - run( - `INSERT OR REPLACE INTO order_reviews(review_id,account_number,symbol,side,quantity,limit_price,estimated_cost,state,observed_at) - VALUES(?,?,?,?,?,?,?,?,?)`, - [reviewId, account, symbol, side, quantity, limitPrice, deep(value, ["estimated_cost", "estimatedCost", "total"]), deep(value, ["state", "status"]), observedAt], - ); -} - -function save(update: DomainUpdate): void { +function saveProjection(update: DomainUpdate): boolean { if (update.operation === "get_accounts") saveAccounts(update.value, update.observedAt); else if (update.operation === "get_portfolio") savePortfolio(update.value, update.args, update.observedAt); else if (update.operation === "get_equity_positions") savePositions(update.value, update.args, update.observedAt); else if (update.operation === "get_equity_orders") saveActivities(update.value, update.args, update.observedAt); else if (update.operation === "get_realized_pnl") saveRealizedPnl(update.value, update.args, update.observedAt); - else if (update.operation === "get_equity_historicals") saveHistoricals(update.value, update.args, update.observedAt); - else if (update.operation === "get_pnl_trade_history") savePnlTrades(update.value, update.args, update.observedAt); - else if (update.operation === "review_equity_order") saveOrderReview(update.value, update.args, update.observedAt); - else throw new Error("No Robinhood table mapping for " + update.operation); + else return false; + return true; } function isTransportFailure(message: string): boolean { @@ -411,7 +418,7 @@ function refreshPortfolio(): any { const status = terminalError ? "failed" : errors.length ? "partial" : "succeeded"; transaction(() => { - if (!terminalError) for (const update of updates) save(update); + if (!terminalError) for (const update of updates) saveProjection(update); run( `INSERT INTO refresh_runs(started_at,completed_at,status,operation_count,success_count,error) VALUES(?,?,?,?,?,?)`, @@ -422,31 +429,71 @@ function refreshPortfolio(): any { return { status, operationCount, successCount: updates.length }; } -const toolOperations: Record = { - "robinhood.get_accounts": "get_accounts", - "robinhood.get_portfolio": "get_portfolio", - "robinhood.get_equity_positions": "get_equity_positions", - "robinhood.get_equity_orders": "get_equity_orders", - "robinhood.get_equity_historicals": "get_equity_historicals", - "robinhood.get_realized_pnl": "get_realized_pnl", - "robinhood.get_pnl_trade_history": "get_pnl_trade_history", - "robinhood.review_equity_order": "review_equity_order", -}; +function saveEquityAction(operation: string, value: any, args: any, observedAt: number): void { + const account = String(args?.account_number ?? args?.accountNumber ?? ""); + if (!account) return; + const orderId = String(args?.order_id ?? deep(value, ["order_id", "orderId", "id"]) ?? ""); + const activityId = orderId || [observedAt, args?.symbol || "EQUITY", operation].join(":"); + const state = operation === "cancel_equity_order" + ? deep(value, ["state", "status"]) || "CANCEL_REQUESTED" + : deep(value, ["state", "status"]) || "SUBMITTED"; + run( + `INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) + VALUES(?,?,?,?,?,?,?,?,?,?,?) + ON CONFLICT(account_number,activity_id) DO UPDATE SET + occurred_at=COALESCE(excluded.occurred_at,activities.occurred_at), + observed_at=excluded.observed_at, + symbol=COALESCE(excluded.symbol,activities.symbol), + side=COALESCE(excluded.side,activities.side), + quantity=COALESCE(excluded.quantity,activities.quantity), + price=COALESCE(excluded.price,activities.price), + state=excluded.state, + activity_type=excluded.activity_type`, + [ + account, + activityId, + deep(value, ["created_at", "updated_at", "last_transaction_at"]), + observedAt, + args?.symbol ?? deep(value, ["symbol"]), + args?.side ?? deep(value, ["side"]), + args?.quantity ?? args?.dollar_amount ?? deep(value, ["quantity", "executed_quantity"]), + args?.limit_price ?? args?.stop_price ?? deep(value, ["price", "average_price"]), + args?.dollar_amount ?? null, + String(state).toUpperCase(), + operation === "cancel_equity_order" ? "EQUITY ORDER CANCEL" : "EQUITY ORDER", + ], + ); +} -function invokeMappedTool(name: string, args: any): any { - const operation = toolOperations[name]; - if (!operation) throw new Error("Unknown Robinhood tool: " + name); +function invokeProviderTool(operation: string, args: any): any { const value = callTool(operation, args); - transaction(() => save({ operation, args, value, observedAt: now() })); + const update = { operation, args, value, observedAt: now() }; + if (["get_accounts", "get_portfolio", "get_equity_positions", "get_equity_orders", "get_realized_pnl"].includes(operation)) { + transaction(() => saveProjection(update)); + } + if (operation === "place_equity_order" || operation === "cancel_equity_order") { + // The order result directly affects the View's activity projection. Avoid + // nesting a second MCP request in the same 128 KiB QuickJS call stack; + // portfolio and positions converge on the normal refresh task. + transaction(() => saveEquityAction(operation, value, args, update.observedAt)); + } return value; } +function success(value: any): string { + // The Agent consumes Tool results through text. Keeping the same provider + // object in details would retain a second copy in QuickJS and again in the + // Rust/Agent message bridge, which is especially expensive for market-data + // and options responses. + return JSON.stringify({ text: JSON.stringify(value), isError: false }); +} + (globalThis as any).PocketPiData = { invokeTask(name: string) { try { if (name !== "refreshPortfolio") throw new Error("Unknown Robinhood Data Action: " + name); const value = refreshPortfolio(); - return JSON.stringify({ text: JSON.stringify(value), details: value, isError: false }); + return success(value); } catch (error) { return JSON.stringify({ text: error instanceof Error ? error.message : String(error), isError: true }); } @@ -454,8 +501,11 @@ function invokeMappedTool(name: string, args: any): any { invokeTool(name: string, argsLine: string) { try { const args = JSON.parse(argsLine); - const value = name === "robinhood.refresh_portfolio" ? refreshPortfolio() : invokeMappedTool(name, args); - return JSON.stringify({ text: JSON.stringify(value), details: value, isError: false }); + const value = name === "robinhood.refresh_portfolio" ? refreshPortfolio() + : name === "robinhood.search_tools" ? searchTools(args) + : name === "robinhood.call" ? validatedProviderCall(args) + : (() => { throw new Error("Unknown Robinhood Tool: " + name); })(); + return success(value); } catch (error) { return JSON.stringify({ text: error instanceof Error ? error.message : String(error), isError: true }); } diff --git a/apps/robinhood/dist/app.js b/apps/robinhood/dist/app.js index cf4507b..70bdb29 100644 --- a/apps/robinhood/dist/app.js +++ b/apps/robinhood/dist/app.js @@ -1,5 +1,5 @@ (()=>{var _J={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return M1(this.context.count)},getNextContextId(){return M1(this.context.count++)}};function M1(J){let Q=String(J),$=Q.length-1;return _J.context.id+($?String.fromCharCode(96+$):"")+Q}function P1(J){_J.context=J}function B6(){return{..._J.context,id:_J.getNextContextId(),count:0}}var K6=!1,U6=(J,Q)=>J===Q,A0=Symbol("solid-proxy"),M6=typeof Proxy==="function",P6=Symbol("solid-track"),wQ=Symbol("solid-dev-component"),nJ={equals:U6},V1=null,V6=_1,c=1,EJ=2,D1={owned:null,cleanups:null,context:null,owner:null},S=null,B=null,bJ=null,AJ=null,f=null,h=null,N=null,oJ=0;function tJ(J,Q){let $=f,Z=S,X=J.length===0,W=Q===void 0?Z:Q,z=X?D1:{owned:null,cleanups:null,context:W?W.context:null,owner:W},F=X?J:()=>J(()=>qJ(()=>zJ(z)));S=z,f=null;try{return n(F,!0)}finally{f=$,S=Z}}function E(J,Q){Q=Q?Object.assign({},nJ,Q):nJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return L1($,X)};return[O1.bind($),Z]}function WJ(J,Q,$){let Z=k1(J,Q,!1,c);if(bJ&&B&&B.running)h.push(Z);else J0(Z)}function $J(J,Q,$){$=$?Object.assign({},nJ,$):nJ;let Z=k1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,bJ&&B&&B.running)Z.tState=c,h.push(Z);else J0(Z);return O1.bind(Z)}function eJ(J){return n(J,!1)}function qJ(J){if(!AJ&&f===null)return J();let Q=f;f=null;try{if(AJ)return AJ.untrack(J);return J()}finally{f=Q}}function w0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function D6(J){if(B&&B.running)return J(),B.done;let Q=f,$=S;return Promise.resolve().then(()=>{f=Q,S=$;let Z;if(bJ||R6)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return n(J,!1),f=S=null,Z?Z.done:void 0})}var[SQ,R1]=E(!1),R6;function O1(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===c)J0(this);else{let Q=h;h=null,n(()=>Q0(this),!1),h=Q}if(f){let Q=this.observers;if(!Q||Q[Q.length-1]!==f){let $=Q?Q.length:0;if(!f.sources)f.sources=[this],f.sourceSlots=[$];else f.sources.push(this),f.sourceSlots.push($);if(!Q)this.observers=[f],this.observerSlots=[f.sources.length-1];else Q.push(f),this.observerSlots.push(f.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function L1(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)n(()=>{for(let X=0;X1e6)throw h=[],Error()},!1)}return Q}function J0(J){if(!J.fn)return;zJ(J);let Q=oJ;if(I1(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{n(()=>{B&&(B.running=!0),f=S=J,I1(J,J.tValue,Q),f=S=null},!1)})}function I1(J,Q,$){let Z,X=S,W=f;f=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(B&&B.running)J.tState=c,J.tOwned&&J.tOwned.forEach(zJ),J.tOwned=void 0;else J.state=c,J.owned&&J.owned.forEach(zJ),J.owned=null;return J.updatedAt=$+1,y0(z)}finally{f=W,S=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)L1(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function k1(J,Q,$,Z=c,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(S===null);else if(S!==D1)if(B&&B.running&&S.pure)if(!S.tOwned)S.tOwned=[W];else S.tOwned.push(W);else if(!S.owned)S.owned=[W];else S.owned.push(W);if(AJ&&W.fn){let z=W.fn,[F,D]=E(void 0,{equals:!1}),R=AJ.factory(z,D);w0(()=>R.dispose());let U,H=()=>D6(D).then(()=>{if(U)U.dispose(),U=void 0});W.fn=(w)=>{if(F(),B&&B.running){if(!U)U=AJ.factory(z,H);return U.track(w)}return R.track(w)}}return W}function S0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===EJ)return Q0(J);if(J.suspense&&qJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===c)J0(J);else if((Q?J.tState:J.state)===EJ){let X=h;h=null,n(()=>Q0(J,$[0]),!1),h=X}}}function n(J,Q){if(h)return J();let $=!1;if(!Q)h=[];if(N)$=!0;else N=[];oJ++;try{let Z=J();return O6($),Z}catch(Z){if(!$)N=null;h=null,y0(Z)}}function O6(J){if(h){if(bJ&&B&&B.running)L6(h);else _1(h);h=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;N.push.apply(N,B.effects),Q=B.resolve;for(let W of N)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,n(()=>{for(let W of X)zJ(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let z=0,F=W.owned.length;zV6($),!1);if(Q)Q()}function _1(J){for(let Q=0;Q{Z.delete($),n(()=>{B.running=!0,S0($)},!1),B&&(B.running=!1)})}}function Q0(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)zJ(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)w1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)zJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function w1(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return w0(()=>y1(W)),()=>{let D=J()||[],R=D.length,U,H;return D[P6],qJ(()=>{let x,g,A,a,r,K,j,G,P;if(R===0){if(z!==0)y1(W),W=[],Z=[],X=[],z=0,F&&(F=[]);if($.fallback)Z=[k6],X[0]=tJ((k)=>{return W[0]=k,$.fallback()}),z=1}else if(z===0){X=Array(R);for(H=0;H=K&&G>=K&&Z[j]===D[G];j--,G--)A[G]=X[j],a[G]=W[j],F&&(r[G]=F[j]);x=new Map,g=Array(G+1);for(H=G;H>=K;H--)P=D[H],U=x.get(P),g[H]=U===void 0?-1:U,x.set(P,H);for(U=K;U<=j;U++)if(P=Z[U],H=x.get(P),H!==void 0&&H!==-1)A[H]=X[U],a[H]=W[U],F&&(r[H]=F[U]),H=g[H],x.set(P,H);else W[U]();for(H=K;HJ(Q||{}));return P1($),Z}}return qJ(()=>J(Q||{}))}function $0(){return!0}var S6={get(J,Q,$){if(Q===A0)return $;return J.get(Q)},has(J,Q){if(Q===A0)return!0;return J.has(Q)},set:$0,deleteProperty:$0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:$0,deleteProperty:$0}},ownKeys(J){return J.keys()}};function f0(J){return!(J=typeof J==="function"?J():J)?{}:J}function y6(){for(let J=0,Q=this.length;J=0;F--){let D=f0(J[F])[z];if(D!==void 0)return D}},has(z){for(let F=J.length-1;F>=0;F--)if(z in f0(J[F]))return!0;return!1},keys(){let z=[];for(let F=0;F=0;z--){let F=J[z];if(!F)continue;let D=Object.getOwnPropertyNames(F);for(let R=D.length-1;R>=0;R--){let U=D[R];if(U==="__proto__"||U==="constructor")continue;let H=Object.getOwnPropertyDescriptor(F,U);if(!Z[U])Z[U]=H.get?{enumerable:!0,configurable:!0,get:y6.bind($[U]=[H.get.bind(F)])}:H.value!==void 0?H:void 0;else{let w=$[U];if(w){if(H.get)w.push(H.get.bind(F));else if(H.value!==void 0)w.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let z=W.length-1;z>=0;z--){let F=W[z],D=Z[F];if(D&&D.get)Object.defineProperty(X,F,D);else X[F]=D?D.value:void 0}return X}var f6=(J)=>`Stale read from <${J}>.`;function NJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return $J(_6(()=>J.each,J.children,Q||void 0))}function Z0(J){let Q=J.keyed,$=$J(()=>J.when,void 0,void 0),Z=Q?$:$J($,void 0,{equals:(X,W)=>!X===!W});return $J(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?qJ(()=>W(Q?X:()=>{if(!qJ(Z))throw f6("Show");return $()})):W}return J.fallback},void 0,void 0)}var x6=(J)=>$J(()=>J());function C6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:z,getParentNode:F,getFirstChild:D,getNextSibling:R}){function U(K,j,G,P){if(G!==void 0&&!P)P=[];if(typeof j!=="function")return H(K,j,P,G);WJ((k)=>H(K,j(),k,G),P)}function H(K,j,G,P,k){while(typeof G==="function")G=G();if(j===G)return G;let _=typeof j,I=P!==void 0;if(_==="string"||_==="number"){if(_==="number")j=j.toString();if(I){let L=G[0];if(L&&$(L))Z(L,j);else L=Q(j);G=g(K,G,P,L)}else if(G!==""&&typeof G==="string")Z(D(K),G=j);else g(K,G,P,Q(j)),G=j}else if(j==null||_==="boolean")G=g(K,G,P);else if(_==="function")return WJ(()=>{let L=j();while(typeof L==="function")L=L();G=H(K,L,G,P)}),()=>G;else if(Array.isArray(j)){let L=[];if(w(L,j,k))return WJ(()=>G=H(K,L,G,P,!0)),()=>G;if(L.length===0){let hJ=g(K,G,P);if(I)return G=hJ}else if(Array.isArray(G))if(G.length===0)A(K,L,P);else x(K,G,L);else if(G==null||G==="")A(K,L);else x(K,I&&G||[D(K)],L);G=L}else{if(Array.isArray(G)){if(I)return G=g(K,G,P,j);g(K,G,null,j)}else if(G==null||G===""||!D(K))X(K,j);else a(K,j,D(K));G=j}return G}function w(K,j,G){let P=!1;for(let k=0,_=j.length;k<_;k++){let I=j[k],L;if(I==null||I===!0||I===!1);else if(Array.isArray(I))P=w(K,I)||P;else if((L=typeof I)==="string"||L==="number")K.push(Q(I));else if(L==="function")if(G){while(typeof I==="function")I=I();P=w(K,Array.isArray(I)?I:[I])||P}else K.push(I),P=!0;else K.push(I)}return P}function x(K,j,G){let P=G.length,k=j.length,_=P,I=0,L=0,hJ=R(j[k-1]),IJ=null;while(IQJ-L){let AQ=j[I];while(L=0;I--){let L=j[I];if(k!==L){let hJ=F(L)===K;if(!_&&!I)hJ?a(K,k,L):X(K,k,G);else hJ&&W(K,L)}else _=!0}}else X(K,k,G);return[k]}function A(K,j,G){for(let P=0,k=j.length;PG.children=H(K,j.children,G.children));return WJ(()=>j.ref&&j.ref(K)),WJ(()=>{for(let k in j){if(k==="children"||k==="ref")continue;let _=j[k];if(_===G[k])continue;z(K,k,_,G[k]),G[k]=_}}),G}return{render(K,j){let G;return tJ((P)=>{G=P,U(j,K())}),G},insert:U,spread(K,j,G){if(typeof j==="function")WJ((P)=>r(K,j(),P,G));else r(K,j,void 0,G)},createElement:J,createTextNode:Q,insertNode:X,setProp(K,j,G,P){return z(K,j,G,P),G},mergeProps:f1,effect:WJ,memo:x6,createComponent:w6,use(K,j,G){return qJ(()=>K(j,G))}}}function g6(J){let Q=C6(J);return Q.mergeProps=f1,Q}var x1=480,C1=272,KJ={view:0,text:1,image:2},h6=1,E6=-1,b6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},M={f32:0,color:1,int:2},N6={width:M.f32,height:M.f32,minW:M.f32,minH:M.f32,maxW:M.f32,maxH:M.f32,paddingT:M.f32,paddingR:M.f32,paddingB:M.f32,paddingL:M.f32,marginT:M.f32,marginR:M.f32,marginB:M.f32,marginL:M.f32,gap:M.f32,flexDir:M.int,justify:M.int,align:M.int,grow:M.f32,shrink:M.f32,basis:M.f32,flexWrap:M.int,posType:M.int,insetT:M.f32,insetR:M.f32,insetB:M.f32,insetL:M.f32,display:M.int,overflow:M.int,zIndex:M.int,hitPass:M.int,bgColor:M.color,gradFrom:M.color,gradTo:M.color,gradDir:M.int,radius:M.f32,opacity:M.f32,borderColor:M.color,borderWidth:M.f32,shadow:M.int,bevelOuterLight:M.color,bevelOuterDark:M.color,bevelInnerLight:M.color,bevelInnerDark:M.color,bevelWidth:M.f32,textColor:M.color,fontSlot:M.int,textAlign:M.int,lineHeight:M.f32,tracking:M.f32,translateX:M.f32,translateY:M.f32,scale:M.f32,rotate:M.f32,scaleX:M.f32,scaleY:M.f32,originX:M.f32,originY:M.f32,rotateX:M.f32,rotateY:M.f32,translateZ:M.f32,perspective:M.f32,arcStart:M.f32,arcSweep:M.f32,arcWidth:M.f32},d={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},T6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},v6=1,yQ=2,fQ=1,xQ=2,CQ=131072,gQ=1,hQ=262144,EQ=1,bQ=1,NQ=1,TQ=2,vQ=4,mQ=8,lQ=16,uQ=1,pQ=2;function g1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var cQ=1,m6=1263551300,l6=1,u6=32,p6=24,o={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},UJ=32896,dQ=0.016666666666666666;function h1(J){return J.__viewport??null}var x0=null;function c6(){return null}function E1(J,Q=c6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function d6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return E1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return E1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function i6(J){x0=J}function wJ(){if(!x0)throw Error("PocketJS: host not installed — call render() first");return x0}function b(){return wJ().ops}function s6(J){globalThis.frame=J}function a6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function r6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return g1($>>>16&255,$>>>8&255,$&255,255);return g1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function n6(J,Q){let $=N6[J];if(typeof Q==="string"){if($===M.color)return r6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===M.color||$===M.int)return Q>>>0;return Q}var X0=60,b1=[1,2,3,4,5,6,10,12,15,20,30,60],C0=X0,YJ=-1,o6=0,TJ=[];function t6(J){if(!Number.isFinite(J)||J<=0)return X0;let Q=b1[0];for(let $ of b1)if(Math.abs($-J)Q.at<=YJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;TJ=TJ.filter((Q)=>Q.at>YJ);for(let Q of J)Q.cb()}var g0=0.12,W0=UJ;function $8(J){W0=J===void 0?UJ:J&65535}function Z8(){W0=UJ}function v1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function W8(){return v1(W0&255)}var m1=new Set,q8=0;function z8(){m1.clear(),q8=0,Z8()}function Y8(J){for(let Q of[...m1])Q(J)}var MJ=null,l1=null;function G8(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function u1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){h0();let Q=MJ?MJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return l1.slice(Q.off,Q.off+Q.len)}var mJ=null,C=null,PJ=null,q0=0,VJ=[],b0=[],N0=[];function c1(J){if(mJ=J,C=null,PJ=null,q0=0,VJ.length=0,b0.length=0,N0.length=0,i){if(i.pressTarget=null,i.target=null,i.spriteDirty=!0,i.fresh=!0,i.vw=0,i.tex>=0){let Q=b();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(i.tex),i.tex=-1}}}function j8(J,Q){J.onPress=Q??void 0}function F8(J,Q){if(J.focusable=Q,r1(),!Q&&C===J)v(null)}function v(J){if(PJ&&PJ!==J)DJ(null);C=J,b().setFocus(J?J.id:0)}function DJ(J){if(PJ===J)return;let Q=b();if(PJ)Q.setActive?.(PJ.id,0);if(PJ=J,J)Q.setActive?.(J.id,1)}function T0(){return VJ.length>0?VJ[VJ.length-1]:mJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;v($[X])}function U8(){if(!C)return null;let J=T0();if(J&&!t(C,J))return null;for(let Q=b0.length-1;Q>=0;Q--){let $=b0[Q];if(J&&!t($.node,J)&&!t(J,$.node))continue;if(t(C,$.node))return $}return null}function M8(J){let Q=U8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(C)v(null);return!0}let Z=Q.columns,X=C?$.indexOf(C):-1;if(X<0)return v(d1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)v($[W]);return!0}function P8(){if(!C)return null;let J=T0();if(J&&!t(C,J))return null;for(let Q=N0.length-1;Q>=0;Q--){let $=N0[Q];if(J&&!t($.node,J)&&!t(J,$.node))continue;if(t(C,$.node))return $}return null}function z0(J){let Q=P8();if(Q&&Q.move(J))return;if(M8(J))return;K8(J)}function i1(){s1(C)}function s1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){DJ(J)}function V8(J){v(J),s1(J)}function t(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=m0(Q.children[X]);if(W){v(W);return}}let Z=Q;while(Z){if(Z.focusable){v(Z);return}Z=Z.parent}}v(null)}var i=null,a1=0;function r1(){a1++}var R8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],O8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function L8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=R8[Q]>>$&1,X=O8[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,z=X?255:0;J[W]=z,J[W+1]=z,J[W+2]=z,J[W+3]=255}return J}function I8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=vJ($.image)}catch(z){if(wJ().strict)throw z;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):k8(Q,W),X<0&&wJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(L8(),16,16,T6.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function k8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&v6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function G0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=G0($[Z],Q);if(X)return X}return null}var H0=null;function n1(J){H0=J}function o1(J){let Q=VJ.length>0?VJ[VJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||t($,Q)))return $;$=$.parent}return null}function t1(J,Q,$){return o1(e1(J,Q,$))}function e1(J,Q,$){if($!==void 0)return $===0?null:G0(H0??mJ,$);let Z=b(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return G0(H0??mJ,X(J,Q))}function _8(J,Q,$){let Z=i,X=b();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=h1(X);if(Z.vw=H?H.w:x1,Z.vh=H?H.h:C1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)I8(Z,X);let W=X8()*Z.speed,z=W8()*Z.speed;if(Z.dpadSpeed>0&&W===0&&z===0){if(J&o.LEFT)W=-Z.dpadSpeed;if(J&o.RIGHT)W=Z.dpadSpeed;if(J&o.UP)z=-Z.dpadSpeed;if(J&o.DOWN)z=Z.dpadSpeed}let F=Z.fresh;if(W!==0||z!==0){let H=e6()/60,w=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),x=Math.min(Math.max(Z.y+z*H,0),Z.vh-1);if(w!==Z.x||x!==Z.y)Z.x=w,Z.y=x,F=!0}if(F)X.setCursorPos(Z.x,Z.y);let D=(Q|$)&Z.button,R=a1;if(F||D!==0||R!==Z.gen)Z.gen=R,Z.fresh=!1,Z.target=o1(G0(H0??mJ,X.hitTest(Z.x,Z.y)));let U=Z.target;if(U!==C)v(U);if(Q&Z.button&&U)Z.pressTarget=U;if(Z.pressTarget){if(DJ(U===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=U===Z.pressTarget;if(Z.pressTarget=null,DJ(null),H)i1()}}else if($&Z.button)DJ(null);return!0}function A8(J){let Q=J&~q0,$=q0&~J;if(q0=J,i&&_8(J,Q,$))return;if($&o.CIRCLE)DJ(null);if(Q===0)return;if(Q&o.DOWN)z0("down");if(Q&o.RIGHT)z0("right");if(Q&o.UP)z0("up");if(Q&o.LEFT)z0("left");if(Q&o.CIRCLE)DJ(C),i1()}var l0=null;function J4(J){l0=J}function SJ(){if(r1(),l0)l0()}function w8(J,Q){J.debugName=Q||void 0,SJ()}var GJ={id:h6,type:KJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},Q4=Symbol.for("pocketjs.native-node"),u0=1,lJ=3,ZJ=8,S8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function j0(J){return J.domAttrs??={}}function $4(J,Q){let $=J.domNodeType??(uJ(J)?lJ:u0),Z=$===lJ?F0(J.text??""):$===ZJ?x8(J.domData??""):G4(J.domTag??K0(J));for(let X of Object.keys(J.domAttrs??{}))p0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)HJ(Z,$4(X,!0));return Z}function p0(J,Q,$){if(S8.has(Q)){fJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete j0(J)[Q];else j0(J)[Q]=$}function c0(J){if(J[Q4]===!0)return J;return Object.defineProperty(J,Q4,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?lJ:u0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===ZJ?J.domData??"":J.text??""},set($){if(J.domNodeType===ZJ)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===ZJ?J.domData??"":J.text??""},set($){if(J.domNodeType===ZJ)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===ZJ)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===ZJ)J.domData=Z;else if(uJ(J))B0(J,Z);else if(T8(J),Z)HJ(J,F0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return j4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??K0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===lJ)return"#text";if(J.domNodeType===ZJ)return"#comment";return(J.domTag??K0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){fJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===GJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return HJ(J,$),$},insertBefore($,Z){return HJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return HJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return $4(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){p0(J,$,Z)},removeAttribute($){p0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(GJ);var d0=null;function y8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},Z4=new Map;function X4(J,Q){Z4.set(J,Q)}var W4=new Map;function q4(J,Q){W4.set(J,Q)}var yJ=new Set,f8=new Set;function z4(J){if(!J)return!1;if(f8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:b().createNode(Q),type:Q,parent:null,children:[],domNodeType:u0,domTag:J})}function F0(J){let Q=b(),$=Q.createNode(KJ.text);return Q.setText($,J),c0({id:$,type:KJ.text,parent:null,children:[],text:J,domNodeType:lJ,domTag:"#text"})}function x8(J=""){let Q=F0("");return Q.domNodeType=ZJ,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){b().replaceText(J.id,Q),J.text=Q,SJ()}function uJ(J){return J.type===KJ.text}function H4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function HJ(J,Q,$){let Z=b();if(H4(Q),yJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,SJ()}function pJ(J,Q){if(!Q)return;D8(Q),b().removeChild(J.id,Q.id),H4(Q),yJ.add(Q),SJ()}function C8(J){return J.parent??void 0}function g8(J){return J.children[0]}function j4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function h8(J,Q){let $=b();if(SJ(),Q==null||Q===""){$.setStyle(J.id,E6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function E8(J,Q){let $=b();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=Z4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function b8(J,Q){let $=b();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=W4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function N8(J,Q,$){let Z=b(),X=Q??{},W=$??{},z=!1;for(let F in X){let D=X[F];if(W[F]===D)continue;let R=b6[F];if(R===void 0)throw Error(`PocketJS: unknown style prop '${F}' (see spec PROP)`);Z.setProp(J.id,R,n6(F,D)),z=!0}if(z)SJ()}function fJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete j0(J)[Q];else j0(J)[Q]=$;switch(Q){case"class":return h8(J,$),$;case"onPress":case"on:press":return j8(J,$),$;case"src":return E8(J,$),$;case"sprite":return b8(J,$),$;case"style":return N8(J,$,Z),$;case"focusable":return F8(J,!!$),$;case"debugName":return w8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${K0(J)}>`)}function T8(J){for(let Q of[...J.children])pJ(J,Q)}function K0(J){for(let Q of Object.keys(KJ))if(KJ[Q]===J.type)return Q;return String(J.type)}function v8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}fJ(J,Q,$,Z)}var m8=g6({createElement:G4,createTextNode:F0,replaceText:B0,isTextNode:uJ,setProperty:v8,insertNode(J,Q,$){HJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:C8,getFirstChild:g8,getNextSibling:j4}),{render:l8,effect:iQ,memo:l,createComponent:q,createElement:F4,insert:sQ,spread:u8,mergeProps:aQ,use:rQ}=m8,nQ={linear:d.Easing.Linear,in:d.Easing.EaseIn,out:d.Easing.EaseOut,"in-out":d.Easing.EaseInOut,"out-back":d.Easing.OutBack,spring:d.Easing.Spring,"spring-bouncy":d.Easing.SpringBouncy},p8=null;function B4(J){p8=J}function c8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function K4(J,Q){let $=F4(J);return u8($,Q,!1),c8(Q.nodeRef,$),$}function V(J){return K4("view",J)}function O(J){return K4("text",J)}var oQ=new WeakMap,tQ=new WeakMap,d8={}!==null?Object.freeze({...{}}):Object.freeze({}),eQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:d8}),J9=new Map,jJ=36000,s0=30,i8=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(jJ),tapeAnalog:new Uint16Array(jJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function s8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-s0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)J4(()=>{Y.treeDirty=!0}),Q2();else J4(null);globalThis.__pocketDevtools=Z2}function a8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)n8(),e8();let W=Q,z=$===void 0?UJ:$&65535,F=Z,D=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(jJ).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==UJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function P4(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,z]of J)Z.fill(W,X,Math.min(X+z,$)),X+=z;return Z}function V4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return P4(J.masks,0,Q)}function D4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return P4(J.analog??[],UJ,Q)}function R4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,T({t:"hello",app:Y.app,host:$2(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` -`))if(X.trim())o8(X)}}function o8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),a0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":O4();break;case"eval":{let Z=!0,X;try{X=U0((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}T({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":T({t:"tape",tape:M4()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}T({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=V4(Z),Y.replayAnalog=Z.analog?D4(Z):null,Y.replayTouch=Z.touch?R4(Z):null,Y.replayAt=0;break}default:break}}function t8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=s0)O4();if(Y.frame%i8===0)a0()}function e8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){T({t:"stats",frame:Y.frame,nodes:k4(GJ),tapeLen:Y.tapeLen,paused:Y.paused})}function O4(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,T({t:"tree",frame:Y.frame,root:I4(GJ)})}function J2(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(J2(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function L4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function I4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(L4(J,(X)=>{if(X.domNodeType===8)return;Z.push(I4(X))}),Z.length)Q.k=Z;return Q}function k4(J){let Q=1;return L4(J,($)=>{Q+=k4($)}),Q}function Q2(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{T({t:"log",level:$,args:X.map((W)=>U0(W))}),Z?.apply(Q,X)}}}function U0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?_4(W):JSON.stringify(_4(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((z)=>U0(z,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,z])=>`${W}: ${U0(z,Q+1)}`).join(", ")}}`}function _4(J){return J.length>200?J.slice(0,199)+"…":J}function $2(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var Z2={get frame(){return Y.frame},dumpTape:()=>M4(),replay:(J)=>{Y.replayMasks=V4(J),Y.replayAnalog=J.analog?D4(J):null,Y.replayTouch=J.touch?R4(J):null,Y.replayAt=0}},A4=new Map,n0=new Map;function w4(J){return J.trim().replace(/\s+/g," ")}function S4(J){return J.split(" ").sort().join(" ")}var y4=-1;function X2(J){for(let Q of Object.keys(J)){let $=J[Q],Z=w4(Q);A4.set(Z,$);let X=S4(Z),W=n0.get(X);n0.set(X,W!==void 0&&W!==$?y4:$)}}function W2(J){let Q=w4(J),$=A4.get(Q);if($!==void 0)return $;let Z=n0.get(S4(Q));return Z===y4?void 0:Z}var o0=9,q2=(1<{let X=($&Y2)!==0,W=X?t0:o0,z=X?G2:q2;return Object.freeze({id:$>>>(X?H2:z2)&255,x:$&z,y:$>>>W&z,hit:Q?.[Z]})}))}function F2(){return M0}function B2(){M0=e0}var f4=8,FJ=8,K2=3,U2=8,M2=6,P2=0.5,e=1,cJ=2,J1=4,RJ=8,xJ=[],x4=0,P0=0,BJ=Array.from({length:f4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(FJ),histY:new Int16Array(FJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function V2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function D2(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=e1(Q,$,Z.fact);let F=Z.hit;if(F)return V2(F,W)}let z=X.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let F=xJ[z];if(F.disposed)continue;if(x4>0&&!F.opts.allowWhenBlocked)continue;if(!D2(F,$,Z,W))continue;F.flags[J.slot]=e,J.owners.push(F)}for(let z of J.owners)z.opts.onDown?.(J)}function L2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%FJ,J.histLenz||Z>z))X.flags[J.slot]|=cJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&e)||W&(cJ|J1))continue;if(!X.opts.onLongPress)continue;let z=Math.max(1,Math.round((X.opts.longPressSeconds??P2)*N1()));if(J.frames=0)xJ.splice($,1)},cancel(){if(!Q.disposed)h4(Q)},get panning(){for(let $ of BJ)if($.used&&Q.flags[$.slot]&RJ)return!0;return!1}}}function w2(J){let Q=A2(J);return w0(()=>Q.dispose()),Q}function E4(){xJ.length=0,x4=0,P0=0;for(let J of BJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function S2(){return w2({onDown:(J)=>{let Q=t1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=t1(J.x,J.y,J.hit);if(Q)V8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var y2=1,Q1=new Map,V0=[];function f2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function x2(){y2=1,Q1.clear(),V0=[]}function C2(){if(V0.length===0)return;let J=V0;V0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),f2()?.({t:"delivery",frame:T1(),id:Q,kind:Z.kind}),Z.onResult($)}}var b4=new Set;function g2(){if(b4.size===0)return;for(let J of b4)J()}var h2={"w-[210] h-[104]":0,"h-[72] px-5 flex-row items-center justify-between":1,"w-[450] flex-col gap-2":2,"text-lg text-slate-900 font-bold":3,"text-base text-slate-500":4,"text-base text-emerald-600 font-bold":5,"text-base text-slate-900 font-bold":6,"h-[64] px-5 flex-row items-center":7,"w-[240] text-lg text-slate-900 font-bold":8,"w-[156] text-base text-slate-500":9,"relative w-[632] h-[196] flex-col":10,"relative w-[632] h-[160] overflow-hidden":11,"absolute w-[632] h-[2] bg-slate-200":12,"absolute text-base text-slate-500 font-bold":13,"absolute rounded-lg bg-emerald-500":14,"absolute rounded-lg bg-red-500":15,"absolute w-[6] h-[6] rounded-lg bg-emerald-500":16,"absolute w-[6] h-[6] rounded-lg bg-red-500":17,"h-[36] px-1 flex-row items-center justify-between":18,"flex-col w-full h-full bg-slate-50":19,"h-[64] px-6 pt-2":20,"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":21,"text-base text-slate-500 font-bold":22,"h-[304] px-6 pt-3":23,"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100":24,"h-[64] flex-row items-end justify-between":25,"text-2xl text-slate-950 font-bold":26,"text-lg text-emerald-600 font-bold":27,"text-lg text-red-500 font-bold":28,"h-[60] px-6 pt-2 flex-row gap-3":29,"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":30,"w-[100] h-[44] items-center justify-center rounded-lg bg-white":31,"text-base text-white font-bold":32,"pt-3 text-base text-slate-500":33,"h-[126] px-6 pt-3 flex-row items-start gap-[21]":34,"h-[200] px-6 flex-col":35,"h-[150] flex-col rounded-xl shadow bg-white border-slate-100":36,"h-[184] px-6 flex-col":37,"h-[136] flex-col rounded-xl shadow bg-white border-slate-100":38,"h-[126] px-6 pt-2":39,"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":40,"flex-col gap-3":41,"text-xl text-slate-900 font-bold":42,"text-2xl text-emerald-600 font-bold":43,"text-2xl text-red-500 font-bold":44,"h-[104] px-6 flex-row items-center justify-between":45,"w-[460] h-[64]":46,"w-[176] h-[64]":47,"absolute left-[628] top-[156] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":48,"absolute left-[628] top-[972] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":49,"relative flex-col w-full h-full bg-slate-50":50,"px-6 pt-[14] flex-col gap-[12]":51,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":52,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":53,"flex-row items-center justify-between":54,"text-lg text-slate-500 font-bold":55,"px-6 pt-[14] flex-col gap-[14]":56,"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100":57,"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":58,"flex-row items-center":59,"w-[170] text-xl text-slate-900 font-bold":60,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":61,"absolute inset-0 z-50 flex-col items-center justify-center":62,"absolute inset-0 bg-slate-950":63,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":64,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":65,"flex-row flex-wrap":66,grow:67,"text-2xl text-white font-bold":68,"text-base text-slate-600 font-bold":69,"text-lg text-slate-900":70,"px-6":71,"px-6 py-5":72,"gap-4":73,"rounded-xl shadow bg-white border-slate-100":74,"rounded-xl shadow bg-emerald-100 border-emerald-500":75,"bg-white":76,"bg-slate-100":77,"bg-slate-950":78,"px-3 py-2 rounded-lg bg-slate-100":79,"px-3 py-2 rounded-lg bg-indigo-100":80,"text-base text-indigo-700 font-bold":81,"px-3 py-2 rounded-lg bg-emerald-100":82,"text-base text-emerald-700 font-bold":83,"px-3 py-2 rounded-lg bg-amber-100":84,"text-base text-amber-700 font-bold":85,"px-3 py-2 rounded-lg bg-red-100":86,"text-base text-red-500 font-bold":87,"w-[34] h-[34] rounded-lg bg-amber-400":88,"w-[34] h-[34] rounded-lg bg-red-500":89,"w-[34] h-[34] rounded-lg bg-slate-800":90,"w-[34] h-[34] rounded-lg bg-emerald-500":91,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":92,"flex-row items-center gap-4":93,"w-[34] text-2xl text-white font-bold":94,"w-[332] flex-col items-end gap-2":95,"text-base text-slate-300 font-bold":96,"text-base text-slate-400":97,"h-[166] px-6 pt-6 flex-col gap-3":98,"text-base text-orange-600 font-bold":99,"text-lg text-slate-600":100,"h-[44] px-1 flex-row items-center justify-between":101,"w-full h-full items-center justify-center rounded-xl bg-slate-200":102,"w-full h-full items-center justify-center rounded-xl bg-red-100":103,"w-full h-full items-center justify-center rounded-xl bg-slate-100":104,"w-full h-full items-center justify-center rounded-xl bg-orange-600":105,"text-lg text-white font-bold":106,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":107,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":108,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":109,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":110,"text-2xl text-indigo-700 font-bold":111,"text-2xl text-slate-600 font-bold":112,"pt-7 text-2xl text-slate-900 font-bold":113,"pt-4 text-lg text-slate-500":114,"text-xl text-emerald-600 font-bold":115,"text-xl text-red-500 font-bold":116,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":117,"text-base text-red-300":118,"text-base text-slate-300":119,"text-base text-red-500":120,"w-full h-full px-6 flex-row items-center bg-slate-950":121,"w-full h-full flex-row items-center":122};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var E2="ui:styles",b2="ui:font.",N4="ui:img.",T4="ui:sprite.";function N2(){return globalThis.ui}function T2(J){if(J.__textures)return;for(let Q of E0(N4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)X4(Q.slice(N4.length),Z)}}function v2(J){if(J.__sprites)return;for(let Q of E0(T4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),z=$[4],F=Z.getUint16(6,!0),D=Z.getUint16(8,!0),R=Z.getUint16(10,!0),U=J.uploadTexture($.subarray(16),X,W,z);if(U>=0)q4(Q.slice(T4.length),{handle:U,frames:F,cols:D,step:R})}}function v4(J){let Q=F4("view");return fJ(Q,"style",J,void 0),Q}var D0=null,R0=null;function m2(J,Q){if(!D0||!R0)return;fJ(D0,"style",{width:J,height:Q,overflow:d.Overflow.Hidden},void 0),fJ(R0,"style",{width:J,height:Q,posType:d.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=b();$.__viewport={w:J,h:Q}}function l2(J,Q={}){let $=d6(Q.ops);if(i6($),y8(W2),Q.styles)X2(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let w in Z)X4(w,Z[w]);let H=$.ops.__sprites;if(H)for(let w in H)q4(w,H[w])}if($.kind==="injected"||Z===void 0){if(Q.pak)p1(Q.pak);if(H8()){for(let H of E0())if(H===E2)$.ops.loadStyles?.(vJ(H));else if(H.startsWith(b2))$.ops.loadFontAtlas?.(vJ(H))}}let X=h1($.ops),W=X?.w??x1,z=X?.h??C1,F=v4({width:W,height:z,overflow:d.Overflow.Hidden}),D=v4({width:W,height:z,posType:d.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});HJ(GJ,F),HJ(GJ,D),B4(D),D0=F,R0=D,c1(F),n1(GJ),z8(),E4(),S2(),J8(),x2(),s8($.ops),s6(a8((H,w,x,g)=>{Q8(),$8(w),j2(x,g),g2(),C2(),_2(),Y8(H),A8(H),Y4()}));let R=l8(J,F),U=a6(m2);return()=>{U(),B2(),E4(),R(),c1(null),n1(null),B4(null),D0=null,R0=null;for(let H of GJ.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);Y4()}}function u2(J,Q={}){let $=Q.ops??N2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)p1(Q.pak);return T2($),v2($),l2(J,{ops:$,styles:Q.styles??h2,pak:Q.pak})}var m4="$b",p2=9007199254740991,c2=":memory:",CJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function d2(J){let Q="";for(let $=0;$>2]+CJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2p2)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function a2(J){if(J!==null&&typeof J==="object")return i2(J[m4]);return J}function r2(J){if(Array.isArray(J))return JSON.stringify(J.map(l4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=l4(Z);return JSON.stringify(Q)}class $1{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,r2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=u4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(a2))}run(...J){let Q=this.execute(u4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function u4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class p4{statements=new Map;txDepth=0;constructor(J=c2){let Q=s2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new $1(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new $1(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let z=J(...Q);return this.txDepth--,this.exec(X),z}catch(z){throw this.txDepth--,this.exec(W),z}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var O0={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"},c4={neutral:{surface:"px-3 py-2 rounded-lg bg-slate-100",text:"text-base text-slate-600 font-bold"},info:{surface:"px-3 py-2 rounded-lg bg-indigo-100",text:"text-base text-indigo-700 font-bold"},success:{surface:"px-3 py-2 rounded-lg bg-emerald-100",text:"text-base text-emerald-700 font-bold"},warning:{surface:"px-3 py-2 rounded-lg bg-amber-100",text:"text-base text-amber-700 font-bold"},danger:{surface:"px-3 py-2 rounded-lg bg-red-100",text:"text-base text-red-500 font-bold"}};function n2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return q(V,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[q(V,{class:"flex-row items-center gap-4",get children(){return[l(()=>l(()=>!!J.back)()?q(O,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):q(V,{get["class"](){return Q()}})),q(O,{get["class"](){return O0.appTitle},get children(){return J.title}})]}}),q(V,{class:"w-[332] flex-col items-end gap-2",get children(){return[q(O,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),q(O,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function o2(J){let Q=()=>J.action?J.detail?J.detail+" · VIEW ALL ›":"VIEW ALL ›":J.detail??"";return q(V,{class:"h-[44] px-1 flex-row items-center justify-between",get children(){return[q(O,{get["class"](){return O0.heading},get children(){return J.title}}),q(O,{get["class"](){return O0.captionStrong},get children(){return Q()}})]}})}function t2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return q(V,{get["class"](){return Q()},get children(){return q(O,{get["class"](){return $()},get children(){return J.label}})}})}function d4(J){return q(V,{get["class"](){return J.compact?"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100"},get children(){return[l(()=>l(()=>!!J.icon)()?q(V,{get["class"](){return J.tone==="info"?"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100"},get children(){return q(O,{get["class"](){return J.tone==="info"?"text-2xl text-indigo-700 font-bold":"text-2xl text-slate-600 font-bold"},get children(){return J.icon}})}}):null),q(O,{get["class"](){return J.icon?"pt-7 text-2xl text-slate-900 font-bold":"text-lg text-slate-500 font-bold"},get children(){return J.title}}),l(()=>l(()=>!!J.detail)()?q(O,{class:"pt-4 text-lg text-slate-500",get children(){return J.detail}}):null)]}})}function e2(J){let Q=()=>J.tone==="success"?"text-xl text-emerald-600 font-bold":J.tone==="danger"?"text-xl text-red-500 font-bold":"text-xl text-slate-900 font-bold";return q(V,{class:"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(O,{get["class"](){return O0.label},get children(){return J.label}}),q(O,{get["class"](){return Q()},get children(){return J.value}})]}})}function JQ(J){let Q=()=>J.dark?J.tone==="danger"?"text-base text-red-300":"text-base text-slate-300":J.tone==="danger"?"text-base text-red-500":"text-base text-slate-500";return q(V,{get["class"](){return J.dark?"w-full h-full px-6 flex-row items-center bg-slate-950":"w-full h-full flex-row items-center"},get children(){return q(O,{get["class"](){return Q()},get children(){return J.text}})}})}function QQ(J){return[q(V,{get["class"](){return J.top},get children(){return q(O,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),q(V,{get["class"](){return J.bottom},get children(){return q(O,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var i4=4,m=new p4("robinhood"),$Q={number:"",label:"ACCOUNT",suffix:"",status:"WAITING FOR ROBINHOOD"},Z1={title:"NO RECENT ACTIVITY",timestamp:"",detail:"",state:"",amount:"",side:""},ZQ={...Z1,title:"ACTIVITY UNAVAILABLE"},XQ={...Z1,title:""},X1={symbol:"NO OPEN POSITIONS",quantity:"",averagePrice:"",marketValue:""},WQ={...X1,symbol:"POSITIONS UNAVAILABLE"},qQ={...X1,symbol:""},iJ={account:$Q,totalValue:null,cash:null,buyingPower:null,pnlDay:null,pnlWeek:null,positions:[],activity:[],positionsAvailable:!0,activityAvailable:!0,observedAt:null},[s,sJ]=E("dashboard"),[u,zQ]=E("day"),[gJ,W1]=E([]),[L0,I0]=E(""),[y,aJ]=E(iJ),[s4,OJ]=E([]),[YQ,LJ]=E([]),[q1,z1]=E([]),[GQ,Y1]=E({change:"$—",percent:"—",positive:!0}),[G1,a4]=E(0),[r4,n4]=E(0),[o4,t4]=E(0),[e4,XJ]=E("WAITING FOR ROBINHOOD"),[rJ,J6]=E(!1),p=0,Q6=-1,$6=-1,Z6=-1,H1=new Map,j1=new Map;function X6(){return Math.floor(Date.now()/1000)}function HQ(J){try{return J?JSON.parse(J):null}catch{return null}}function jQ(){return m.query("SELECT account_number,label,suffix,status FROM accounts ORDER BY label,account_number LIMIT 16").all().map((Q)=>({number:Q.account_number,label:Q.label,suffix:Q.suffix,status:Q.status}))}function FQ(J,Q){if($6===J)return;let $=m.query("SELECT account_number,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current LIMIT 16").all(),Z=m.query(` +`))if(X.trim())o8(X)}}function o8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),a0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":O4();break;case"eval":{let Z=!0,X;try{X=U0((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}T({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":T({t:"tape",tape:M4()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}T({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=V4(Z),Y.replayAnalog=Z.analog?D4(Z):null,Y.replayTouch=Z.touch?R4(Z):null,Y.replayAt=0;break}default:break}}function t8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=s0)O4();if(Y.frame%i8===0)a0()}function e8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){T({t:"stats",frame:Y.frame,nodes:k4(GJ),tapeLen:Y.tapeLen,paused:Y.paused})}function O4(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,T({t:"tree",frame:Y.frame,root:I4(GJ)})}function J2(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(J2(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function L4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function I4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(L4(J,(X)=>{if(X.domNodeType===8)return;Z.push(I4(X))}),Z.length)Q.k=Z;return Q}function k4(J){let Q=1;return L4(J,($)=>{Q+=k4($)}),Q}function Q2(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{T({t:"log",level:$,args:X.map((W)=>U0(W))}),Z?.apply(Q,X)}}}function U0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?_4(W):JSON.stringify(_4(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((z)=>U0(z,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,z])=>`${W}: ${U0(z,Q+1)}`).join(", ")}}`}function _4(J){return J.length>200?J.slice(0,199)+"…":J}function $2(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var Z2={get frame(){return Y.frame},dumpTape:()=>M4(),replay:(J)=>{Y.replayMasks=V4(J),Y.replayAnalog=J.analog?D4(J):null,Y.replayTouch=J.touch?R4(J):null,Y.replayAt=0}},A4=new Map,n0=new Map;function w4(J){return J.trim().replace(/\s+/g," ")}function S4(J){return J.split(" ").sort().join(" ")}var y4=-1;function X2(J){for(let Q of Object.keys(J)){let $=J[Q],Z=w4(Q);A4.set(Z,$);let X=S4(Z),W=n0.get(X);n0.set(X,W!==void 0&&W!==$?y4:$)}}function W2(J){let Q=w4(J),$=A4.get(Q);if($!==void 0)return $;let Z=n0.get(S4(Q));return Z===y4?void 0:Z}var o0=9,q2=(1<{let X=($&Y2)!==0,W=X?t0:o0,z=X?G2:q2;return Object.freeze({id:$>>>(X?H2:z2)&255,x:$&z,y:$>>>W&z,hit:Q?.[Z]})}))}function F2(){return M0}function B2(){M0=e0}var f4=8,FJ=8,K2=3,U2=8,M2=6,P2=0.5,e=1,cJ=2,J1=4,RJ=8,xJ=[],x4=0,P0=0,BJ=Array.from({length:f4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(FJ),histY:new Int16Array(FJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function V2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function D2(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=e1(Q,$,Z.fact);let F=Z.hit;if(F)return V2(F,W)}let z=X.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let F=xJ[z];if(F.disposed)continue;if(x4>0&&!F.opts.allowWhenBlocked)continue;if(!D2(F,$,Z,W))continue;F.flags[J.slot]=e,J.owners.push(F)}for(let z of J.owners)z.opts.onDown?.(J)}function L2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%FJ,J.histLenz||Z>z))X.flags[J.slot]|=cJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&e)||W&(cJ|J1))continue;if(!X.opts.onLongPress)continue;let z=Math.max(1,Math.round((X.opts.longPressSeconds??P2)*N1()));if(J.frames=0)xJ.splice($,1)},cancel(){if(!Q.disposed)h4(Q)},get panning(){for(let $ of BJ)if($.used&&Q.flags[$.slot]&RJ)return!0;return!1}}}function w2(J){let Q=A2(J);return w0(()=>Q.dispose()),Q}function E4(){xJ.length=0,x4=0,P0=0;for(let J of BJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function S2(){return w2({onDown:(J)=>{let Q=t1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=t1(J.x,J.y,J.hit);if(Q)V8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var y2=1,Q1=new Map,V0=[];function f2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function x2(){y2=1,Q1.clear(),V0=[]}function C2(){if(V0.length===0)return;let J=V0;V0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),f2()?.({t:"delivery",frame:T1(),id:Q,kind:Z.kind}),Z.onResult($)}}var b4=new Set;function g2(){if(b4.size===0)return;for(let J of b4)J()}var h2={"w-[210] h-[104]":0,"h-[72] px-5 flex-row items-center justify-between":1,"w-[450] flex-col gap-2":2,"text-lg text-slate-900 font-bold":3,"text-base text-slate-500":4,"text-base text-emerald-600 font-bold":5,"text-base text-slate-900 font-bold":6,"h-[64] px-5 flex-row items-center":7,"w-[240] text-lg text-slate-900 font-bold":8,"w-[156] text-base text-slate-500":9,"relative w-[632] h-[196] flex-col":10,"relative w-[632] h-[160] overflow-hidden":11,"absolute w-[632] h-[2] bg-slate-200":12,"absolute text-base text-slate-500 font-bold":13,"absolute rounded-lg bg-emerald-500":14,"absolute rounded-lg bg-red-500":15,"absolute w-[6] h-[6] rounded-lg bg-emerald-500":16,"absolute w-[6] h-[6] rounded-lg bg-red-500":17,"h-[36] px-1 flex-row items-center justify-between":18,"flex-col w-full h-full bg-slate-50":19,"h-[64] px-6 pt-2":20,"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":21,"text-base text-slate-500 font-bold":22,"h-[304] px-6 pt-3":23,"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100":24,"h-[64] flex-row items-end justify-between":25,"text-2xl text-slate-950 font-bold":26,"text-lg text-emerald-600 font-bold":27,"text-lg text-red-500 font-bold":28,"h-[60] px-6 pt-2 flex-row gap-3":29,"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":30,"w-[100] h-[44] items-center justify-center rounded-lg bg-white":31,"text-base text-white font-bold":32,"pt-3 text-base text-slate-500":33,"h-[126] px-6 pt-3 flex-row items-start gap-[21]":34,"h-[200] px-6 flex-col":35,"h-[150] flex-col rounded-xl shadow bg-white border-slate-100":36,"h-[184] px-6 flex-col":37,"h-[136] flex-col rounded-xl shadow bg-white border-slate-100":38,"h-[126] px-6 pt-2":39,"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":40,"flex-col gap-3":41,"text-xl text-slate-900 font-bold":42,"text-2xl text-emerald-600 font-bold":43,"text-2xl text-red-500 font-bold":44,"h-[104] px-6 flex-row items-center justify-between":45,"w-[460] h-[64]":46,"w-[176] h-[64]":47,"absolute left-[628] top-[156] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":48,"absolute left-[628] top-[972] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":49,"relative flex-col w-full h-full bg-slate-50":50,"px-6 pt-[14] flex-col gap-[12]":51,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":52,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":53,"flex-row items-center justify-between":54,"text-lg text-slate-500 font-bold":55,"px-6 pt-[14] flex-col gap-[14]":56,"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100":57,"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":58,"flex-row items-center":59,"w-[170] text-xl text-slate-900 font-bold":60,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":61,"absolute inset-0 z-50 flex-col items-center justify-center":62,"absolute inset-0 bg-slate-950":63,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":64,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":65,"flex-row flex-wrap":66,grow:67,"text-2xl text-white font-bold":68,"text-base text-slate-600 font-bold":69,"text-lg text-slate-900":70,"px-6":71,"px-6 py-5":72,"gap-4":73,"rounded-xl shadow bg-white border-slate-100":74,"rounded-xl shadow bg-emerald-100 border-emerald-500":75,"bg-white":76,"bg-slate-100":77,"bg-slate-950":78,"px-3 py-2 rounded-lg bg-slate-100":79,"px-3 py-2 rounded-lg bg-indigo-100":80,"text-base text-indigo-700 font-bold":81,"px-3 py-2 rounded-lg bg-emerald-100":82,"text-base text-emerald-700 font-bold":83,"px-3 py-2 rounded-lg bg-amber-100":84,"text-base text-amber-700 font-bold":85,"px-3 py-2 rounded-lg bg-red-100":86,"text-base text-red-500 font-bold":87,"w-[34] h-[34] rounded-lg bg-amber-400":88,"w-[34] h-[34] rounded-lg bg-red-500":89,"w-[34] h-[34] rounded-lg bg-slate-800":90,"w-[34] h-[34] rounded-lg bg-emerald-500":91,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":92,"flex-row items-center gap-4":93,"w-[34] text-2xl text-white font-bold":94,"w-[332] flex-col items-end gap-2":95,"text-base text-slate-300 font-bold":96,"text-base text-slate-400":97,"h-[166] px-6 pt-6 flex-col gap-3":98,"text-base text-orange-600 font-bold":99,"text-lg text-slate-600":100,"h-[44] px-1 flex-row items-center justify-between":101,"w-full h-full items-center justify-center rounded-xl bg-slate-200":102,"w-full h-full items-center justify-center rounded-xl bg-red-100":103,"w-full h-full items-center justify-center rounded-xl bg-slate-100":104,"w-full h-full items-center justify-center rounded-xl bg-orange-600":105,"text-lg text-white font-bold":106,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":107,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":108,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":109,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":110,"text-2xl text-indigo-700 font-bold":111,"text-2xl text-slate-600 font-bold":112,"pt-7 text-2xl text-slate-900 font-bold":113,"pt-4 text-lg text-slate-500":114,"text-xl text-emerald-600 font-bold":115,"text-xl text-red-500 font-bold":116,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":117,"text-base text-red-300":118,"text-base text-slate-300":119,"text-base text-red-500":120,"w-full h-full px-6 flex-row items-center bg-slate-950":121,"w-full h-full flex-row items-center":122};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var E2="ui:styles",b2="ui:font.",N4="ui:img.",T4="ui:sprite.";function N2(){return globalThis.ui}function T2(J){if(J.__textures)return;for(let Q of E0(N4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)X4(Q.slice(N4.length),Z)}}function v2(J){if(J.__sprites)return;for(let Q of E0(T4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),z=$[4],F=Z.getUint16(6,!0),D=Z.getUint16(8,!0),R=Z.getUint16(10,!0),U=J.uploadTexture($.subarray(16),X,W,z);if(U>=0)q4(Q.slice(T4.length),{handle:U,frames:F,cols:D,step:R})}}function v4(J){let Q=F4("view");return fJ(Q,"style",J,void 0),Q}var D0=null,R0=null;function m2(J,Q){if(!D0||!R0)return;fJ(D0,"style",{width:J,height:Q,overflow:d.Overflow.Hidden},void 0),fJ(R0,"style",{width:J,height:Q,posType:d.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=b();$.__viewport={w:J,h:Q}}function l2(J,Q={}){let $=d6(Q.ops);if(i6($),y8(W2),Q.styles)X2(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let w in Z)X4(w,Z[w]);let H=$.ops.__sprites;if(H)for(let w in H)q4(w,H[w])}if($.kind==="injected"||Z===void 0){if(Q.pak)p1(Q.pak);if(H8()){for(let H of E0())if(H===E2)$.ops.loadStyles?.(vJ(H));else if(H.startsWith(b2))$.ops.loadFontAtlas?.(vJ(H))}}let X=h1($.ops),W=X?.w??x1,z=X?.h??C1,F=v4({width:W,height:z,overflow:d.Overflow.Hidden}),D=v4({width:W,height:z,posType:d.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});HJ(GJ,F),HJ(GJ,D),B4(D),D0=F,R0=D,c1(F),n1(GJ),z8(),E4(),S2(),J8(),x2(),s8($.ops),s6(a8((H,w,x,g)=>{Q8(),$8(w),j2(x,g),g2(),C2(),_2(),Y8(H),A8(H),Y4()}));let R=l8(J,F),U=a6(m2);return()=>{U(),B2(),E4(),R(),c1(null),n1(null),B4(null),D0=null,R0=null;for(let H of GJ.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);Y4()}}function u2(J,Q={}){let $=Q.ops??N2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)p1(Q.pak);return T2($),v2($),l2(J,{ops:$,styles:Q.styles??h2,pak:Q.pak})}var m4="$b",p2=9007199254740991,c2=":memory:",CJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function d2(J){let Q="";for(let $=0;$>2]+CJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2p2)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function a2(J){if(J!==null&&typeof J==="object")return i2(J[m4]);return J}function r2(J){if(Array.isArray(J))return JSON.stringify(J.map(l4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=l4(Z);return JSON.stringify(Q)}class $1{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,r2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=u4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(a2))}run(...J){let Q=this.execute(u4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function u4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class p4{statements=new Map;txDepth=0;constructor(J=c2){let Q=s2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new $1(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new $1(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let z=J(...Q);return this.txDepth--,this.exec(X),z}catch(z){throw this.txDepth--,this.exec(W),z}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var O0={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"},c4={neutral:{surface:"px-3 py-2 rounded-lg bg-slate-100",text:"text-base text-slate-600 font-bold"},info:{surface:"px-3 py-2 rounded-lg bg-indigo-100",text:"text-base text-indigo-700 font-bold"},success:{surface:"px-3 py-2 rounded-lg bg-emerald-100",text:"text-base text-emerald-700 font-bold"},warning:{surface:"px-3 py-2 rounded-lg bg-amber-100",text:"text-base text-amber-700 font-bold"},danger:{surface:"px-3 py-2 rounded-lg bg-red-100",text:"text-base text-red-500 font-bold"}};function n2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return q(V,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[q(V,{class:"flex-row items-center gap-4",get children(){return[l(()=>l(()=>!!J.back)()?q(O,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):q(V,{get["class"](){return Q()}})),q(O,{get["class"](){return O0.appTitle},get children(){return J.title}})]}}),q(V,{class:"w-[332] flex-col items-end gap-2",get children(){return[q(O,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),q(O,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function o2(J){let Q=()=>J.action?J.detail?J.detail+" · VIEW ALL ›":"VIEW ALL ›":J.detail??"";return q(V,{class:"h-[44] px-1 flex-row items-center justify-between",get children(){return[q(O,{get["class"](){return O0.heading},get children(){return J.title}}),q(O,{get["class"](){return O0.captionStrong},get children(){return Q()}})]}})}function t2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return q(V,{get["class"](){return Q()},get children(){return q(O,{get["class"](){return $()},get children(){return J.label}})}})}function d4(J){return q(V,{get["class"](){return J.compact?"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100"},get children(){return[l(()=>l(()=>!!J.icon)()?q(V,{get["class"](){return J.tone==="info"?"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100"},get children(){return q(O,{get["class"](){return J.tone==="info"?"text-2xl text-indigo-700 font-bold":"text-2xl text-slate-600 font-bold"},get children(){return J.icon}})}}):null),q(O,{get["class"](){return J.icon?"pt-7 text-2xl text-slate-900 font-bold":"text-lg text-slate-500 font-bold"},get children(){return J.title}}),l(()=>l(()=>!!J.detail)()?q(O,{class:"pt-4 text-lg text-slate-500",get children(){return J.detail}}):null)]}})}function e2(J){let Q=()=>J.tone==="success"?"text-xl text-emerald-600 font-bold":J.tone==="danger"?"text-xl text-red-500 font-bold":"text-xl text-slate-900 font-bold";return q(V,{class:"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(O,{get["class"](){return O0.label},get children(){return J.label}}),q(O,{get["class"](){return Q()},get children(){return J.value}})]}})}function JQ(J){let Q=()=>J.dark?J.tone==="danger"?"text-base text-red-300":"text-base text-slate-300":J.tone==="danger"?"text-base text-red-500":"text-base text-slate-500";return q(V,{get["class"](){return J.dark?"w-full h-full px-6 flex-row items-center bg-slate-950":"w-full h-full flex-row items-center"},get children(){return q(O,{get["class"](){return Q()},get children(){return J.text}})}})}function QQ(J){return[q(V,{get["class"](){return J.top},get children(){return q(O,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),q(V,{get["class"](){return J.bottom},get children(){return q(O,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var i4=5,m=new p4("robinhood"),$Q={number:"",label:"ACCOUNT",suffix:"",status:"WAITING FOR ROBINHOOD"},Z1={title:"NO RECENT ACTIVITY",timestamp:"",detail:"",state:"",amount:"",side:""},ZQ={...Z1,title:"ACTIVITY UNAVAILABLE"},XQ={...Z1,title:""},X1={symbol:"NO OPEN POSITIONS",quantity:"",averagePrice:"",marketValue:""},WQ={...X1,symbol:"POSITIONS UNAVAILABLE"},qQ={...X1,symbol:""},iJ={account:$Q,totalValue:null,cash:null,buyingPower:null,pnlDay:null,pnlWeek:null,positions:[],activity:[],positionsAvailable:!0,activityAvailable:!0,observedAt:null},[s,sJ]=E("dashboard"),[u,zQ]=E("day"),[gJ,W1]=E([]),[L0,I0]=E(""),[y,aJ]=E(iJ),[s4,OJ]=E([]),[YQ,LJ]=E([]),[q1,z1]=E([]),[GQ,Y1]=E({change:"$—",percent:"—",positive:!0}),[G1,a4]=E(0),[r4,n4]=E(0),[o4,t4]=E(0),[e4,XJ]=E("WAITING FOR ROBINHOOD"),[rJ,J6]=E(!1),p=0,Q6=-1,$6=-1,Z6=-1,H1=new Map,j1=new Map;function X6(){return Math.floor(Date.now()/1000)}function HQ(J){try{return J?JSON.parse(J):null}catch{return null}}function jQ(){return m.query("SELECT account_number,label,suffix,status FROM accounts ORDER BY label,account_number LIMIT 16").all().map((Q)=>({number:Q.account_number,label:Q.label,suffix:Q.suffix,status:Q.status}))}function FQ(J,Q){if($6===J)return;let $=m.query("SELECT account_number,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current LIMIT 16").all(),Z=m.query(` SELECT value.account_number,value.value,value.observed_at FROM total_value value JOIN ( @@ -19,4 +19,4 @@ WHERE account_number = ?3 AND observed_at >= ?1 AND observed_at <= bucket_time ORDER BY observed_at DESC LIMIT 1) AS total_value FROM buckets ORDER BY bucket_index - `).all(z,X,J).map((j)=>({time:j.bucket_time,value:k0(j.total_value)})),R=D.map((j)=>j.time),U=D.map((j)=>j.value).filter((j)=>j!==null),H=[R[0],R[9],R[19]].map((j)=>{let G=new Date(j*1000);return u()==="day"?String(G.getHours()).padStart(2,"0")+":"+String(G.getMinutes()).padStart(2,"0"):String(G.getMonth()+1)+"/"+String(G.getDate())});if(U.length===0){let j=u()==="day"?y().pnlDay:y().pnlWeek,G=k0(j),P={points:[],segments:[],labels:H,trend:{change:JJ(j),percent:"—",positive:G===null||G>=0}};j1.set($,{loadedRevision:Q,value:P}),OJ(P.points),LJ(P.segments),z1(P.labels),Y1(P.trend);return}let w=Math.min(...U),x=Math.max(...U),g=Math.max(0.01,x-w),A=D.flatMap((j,G)=>j.value===null?[]:[{x:G*622/19,y:U.length===1?80:10+(x-j.value)*140/g}]),a=A.slice(1).map((j,G)=>{let P=A[G],k=j.x-P.x,_=j.y-P.y;return{x:P.x,y:P.y,width:Math.sqrt(k*k+_*_),angle:Math.atan2(_,k)*180/Math.PI}}),r=U[U.length-1]-U[0],K={change:JJ(String(r)),percent:U[0]===0?"—":(r*100/U[0]).toFixed(2)+"%",positive:r>=0};j1.set($,{loadedRevision:Q,value:{points:A,segments:a,labels:H,trend:K}}),OJ(A),LJ(a),z1(H),Y1(K)}function KQ(J){if(Z6===J)return;let Q=m.query("SELECT status,error,completed_at FROM refresh_runs ORDER BY id DESC LIMIT 1").get();if(J6(!1),Q?.status==="failed")XJ("REFRESH FAILED · "+String(Q.error||"UNKNOWN ERROR").slice(0,52));else if(Q?.status==="partial")XJ("LIVE WITH PARTIAL DATA");else if(y().observedAt)XJ("LIVE / READ ONLY · "+W6(y().observedAt));else XJ("WAITING FOR ROBINHOOD");Z6=J}function z6(J,Q){if(!J){if(aJ(iJ),OJ([]),LJ([]),!rJ())XJ("WAITING FOR ROBINHOOD");return}let $=H1.get(J);if($?.loadedRevision===Q){if(aJ($.value),q6(J,Q),$.value.observedAt&&!rJ())XJ("LIVE / READ ONLY · "+W6($.value.observedAt));return}aJ(iJ),OJ([]),LJ([])}function Y6(J=p){try{let Q=m.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==i4){W1([]),I0(""),aJ(iJ),OJ([]),LJ([]),XJ("WAITING FOR ROBINHOOD");return}eJ(()=>{p=Math.max(p,J);let $=gJ();if(Q6!==p)$=jQ(),W1($),Q6=p;FQ(p,$);let Z=L0();if(!$.some((X)=>X.number===Z))Z=$[0]?.number||"",I0(Z);z6(Z,p),KQ(p)})}catch{eJ(()=>{W1([]),I0(""),aJ(iJ),OJ([]),LJ([]),XJ("WAITING FOR ROBINHOOD")})}}function UQ(){return""}function MQ(){let J=m.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((z)=>z.name)),$=J.map((z)=>{let F=m.query("SELECT COUNT(*) AS count FROM "+z.name).get().count;return{name:z.name,rowCount:F,schema:z.sql}}),Z=Q.has("refresh_runs")?m.query("SELECT id,started_at,completed_at,operation_count,success_count,status,error FROM refresh_runs ORDER BY id DESC LIMIT 3").all():[],X=Q.has("portfolio_current")?m.query("SELECT substr(account_number,-4) AS account_suffix,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current ORDER BY observed_at DESC LIMIT 4").all():[],W=Q.has("total_value")?m.query("SELECT substr(account_number,-4) AS account_suffix,observed_at,value FROM total_value ORDER BY observed_at DESC LIMIT 8").all():[];return{database:"robinhood.sqlite",schemaVersion:i4,tables:$,latestRefreshes:Z,latestPortfolios:X,latestValues:W}}function F1(){return GQ()}function _0(J){return q(n2,{get title(){return J.title},back:!0,metaTop:"READ ONLY",get metaBottom(){return J.metaBottom??"AUTO · 5 MIN"}})}function B1(J){return q(V,{class:"w-[210] h-[104]",get children(){return q(e2,{get label(){return J.label},get value(){return JJ(J.value)}})}})}function G6(J){return q(o2,{get title(){return J.title},get detail(){return J.detail},action:!0})}function PQ(J){if(J===0&&!y().activityAvailable)return ZQ;return y().activity[J]??(J===0?Z1:XQ)}function H6(J){let Q=()=>PQ(J.index);return q(V,{class:"h-[72] px-5 flex-row items-center justify-between",get children(){return[q(V,{class:"w-[450] flex-col gap-2",get children(){return[q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q().title}}),q(O,{class:"text-base text-slate-500",get children(){return l(()=>!!Q().timestamp)()?Q().timestamp+" · "+Q().detail:""}})]}}),q(O,{get["class"](){return Q().side==="SELL"?"text-base text-emerald-600 font-bold":"text-base text-slate-900 font-bold"},get children(){return l(()=>!!Q().amount)()?JJ(Q().amount):""}})]}})}function VQ(J){if(J===0&&!y().positionsAvailable)return WQ;return y().positions[J]??(J===0?X1:qQ)}function j6(J){let Q=()=>VQ(J.index);return q(V,{class:"h-[64] px-5 flex-row items-center",get children(){return[q(O,{class:"w-[240] text-lg text-slate-900 font-bold",get children(){return Q().symbol}}),q(O,{class:"w-[156] text-base text-slate-500",get children(){return l(()=>!!Q().quantity)()?Q().quantity+" SH":""}}),q(O,{class:"text-base text-slate-500",get children(){return l(()=>!!Q().averagePrice)()?"AVG "+JJ(Q().averagePrice):""}})]}})}function DQ(){return q(V,{class:"relative w-[632] h-[196] flex-col",get children(){return[q(V,{class:"relative w-[632] h-[160] overflow-hidden",get children(){return[q(V,{class:"absolute w-[632] h-[2] bg-slate-200",style:{posType:1,insetL:0,insetT:158}}),q(O,{class:"absolute text-base text-slate-500 font-bold",style:{posType:1,insetL:152,insetT:72},get children(){return s4().length<2?"COLLECTING 5M VALUE HISTORY":""}}),q(NJ,{get each(){return YQ()},children:(J)=>q(V,{get["class"](){return F1().positive?"absolute rounded-lg bg-emerald-500":"absolute rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x,insetT:J.y-1,width:J.width,height:2,rotate:J.angle,originX:-0.5,originY:0}}})}),q(NJ,{get each(){return s4()},children:(J)=>q(V,{get["class"](){return F1().positive?"absolute w-[6] h-[6] rounded-lg bg-emerald-500":"absolute w-[6] h-[6] rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x-3,insetT:J.y-3}}})})]}}),q(V,{class:"h-[36] px-1 flex-row items-center justify-between",get children(){return[q(O,{class:"text-base text-slate-500",get children(){return q1()[0]||""}}),q(O,{class:"text-base text-slate-500",get children(){return q1()[1]||""}}),q(O,{class:"text-base text-slate-500",get children(){return q1()[2]||""}})]}})]}})}function RQ(){let J=()=>F1();return q(V,{class:"flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ROBINHOOD"}),q(V,{class:"h-[64] px-6 pt-2",get children(){return q(V,{class:"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(O,{class:"text-base text-slate-500 font-bold",children:"ACCOUNT"}),q(O,{class:"text-base text-slate-900 font-bold",get children(){return y().account.label+(y().account.suffix?" ····"+y().account.suffix+" "+(gJ().findIndex((Q)=>Q.number===L0())+1)+"/"+gJ().length:"")+" ›"}})]}})}}),q(V,{class:"h-[304] px-6 pt-3",get children(){return q(V,{class:"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"h-[64] flex-row items-end justify-between",get children(){return[q(O,{class:"text-2xl text-slate-950 font-bold",get children(){return JJ(y().totalValue)}}),q(O,{get["class"](){return J().positive?"text-lg text-emerald-600 font-bold":"text-lg text-red-500 font-bold"},get children(){return J().change+" ("+J().percent+")"}})]}}),q(DQ,{})]}})}}),q(V,{class:"h-[60] px-6 pt-2 flex-row gap-3",get children(){return[q(V,{get["class"](){return u()==="day"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(O,{get["class"](){return u()==="day"?"text-base text-white font-bold":"text-base text-slate-500 font-bold"},children:"1D"})}}),q(V,{get["class"](){return u()==="week"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(O,{get["class"](){return u()==="week"?"text-base text-white font-bold":"text-base text-slate-500 font-bold"},children:"1W"})}}),q(O,{class:"pt-3 text-base text-slate-500",get children(){return u()==="day"?"TODAY":"PAST WEEK"}})]}}),q(V,{class:"h-[126] px-6 pt-3 flex-row items-start gap-[21]",get children(){return[q(B1,{label:"VALUE",get value(){return y().totalValue}}),q(B1,{label:"CASH",get value(){return y().cash}}),q(B1,{label:"BUY POWER",get value(){return y().buyingPower}})]}}),q(V,{class:"h-[200] px-6 flex-col",get children(){return[q(G6,{title:"ACTIVITY",detail:"LAST 7 DAYS"}),q(V,{class:"h-[150] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(H6,{index:0}),q(H6,{index:1})]}})]}}),q(V,{class:"h-[184] px-6 flex-col",get children(){return[q(G6,{title:"POSITIONS"}),q(V,{class:"h-[136] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(j6,{index:0}),q(j6,{index:1})]}})]}}),q(V,{class:"h-[126] px-6 pt-2",get children(){return q(V,{class:"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-col gap-3",get children(){return[q(O,{class:"text-xl text-slate-900 font-bold",children:"REALIZED P&L"}),q(O,{class:"text-base text-slate-500",get children(){return"EQUITIES / "+(u()==="day"?"TODAY":"WEEK")}})]}}),q(O,{get["class"](){return(k0(u()==="day"?y().pnlDay:y().pnlWeek)??0)>=0?"text-2xl text-emerald-600 font-bold":"text-2xl text-red-500 font-bold"},get children(){return JJ(u()==="day"?y().pnlDay:y().pnlWeek)}})]}})}}),q(V,{class:"h-[104] px-6 flex-row items-center justify-between",get children(){return[q(V,{class:"w-[460] h-[64]",get children(){return q(JQ,{get text(){return e4()},get tone(){return e4().startsWith("REFRESH FAILED")?"danger":"neutral"}})}}),q(V,{class:"w-[176] h-[64]",get children(){return q(t2,{get label(){return rJ()?"REFRESHING":"REFRESH NOW"},get disabled(){return rJ()}})}})]}})]}})}function K1(){return q(QQ,{top:"absolute left-[628] top-[156] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",bottom:"absolute left-[628] top-[972] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100"})}function OQ(){let J=$J(()=>gJ().slice(G1(),G1()+8)),Q=L0();return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ACCOUNTS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(NJ,{get each(){return J()},children:($)=>q(V,{get["class"](){return $.number===Q?"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100"},get children(){return[q(V,{class:"flex-row items-center justify-between",get children(){return[q(O,{class:"text-xl text-slate-900 font-bold",get children(){return $.label}}),q(O,{class:"text-lg text-slate-500 font-bold",get children(){return"····"+$.suffix}})]}}),q(V,{class:"flex-row items-center justify-between",get children(){return[q(V,{get["class"](){return c4.success.surface},get children(){return q(O,{get["class"](){return c4.success.text},get children(){return $.status}})}}),q(Z0,{get when(){return $.number===Q},get children(){return q(O,{class:"text-base text-emerald-600 font-bold",children:"SELECTED"})}})]}})]}})})}}),q(K1,{})]}})}function LQ(){let J=$J(()=>y().activity.slice(r4(),r4()+8));return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ACTIVITY",metaBottom:"LAST 7 DAYS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[14]",get children(){return q(Z0,{get when(){return l(()=>!!y().activityAvailable)()&&J().length>0},get fallback(){return q(d4,{get title(){return y().activityAvailable?"NO ACTIVITY YET":"ACTIVITY UNAVAILABLE"},compact:!0})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(V,{class:"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-row items-center justify-between",get children(){return[q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q.title}}),q(O,{get["class"](){return Q.side==="SELL"?"text-lg text-emerald-600 font-bold":"text-lg text-slate-900 font-bold"},get children(){return JJ(Q.amount)}})]}}),q(O,{class:"text-base text-slate-500",get children(){return Q.timestamp+" · "+Q.detail}}),q(O,{class:"text-base text-emerald-600 font-bold",get children(){return Q.state}})]}})})}})}}),q(K1,{})]}})}function IQ(){let J=$J(()=>y().positions.slice(o4(),o4()+9));return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"POSITIONS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(Z0,{get when(){return l(()=>!!y().positionsAvailable)()&&J().length>0},get fallback(){return q(d4,{get title(){return y().positionsAvailable?"NO OPEN POSITIONS":"POSITIONS UNAVAILABLE"},compact:!0})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(V,{class:"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-row items-center",get children(){return[q(O,{class:"w-[170] text-xl text-slate-900 font-bold",get children(){return Q.symbol}}),q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q.quantity+" SH"}})]}}),q(O,{class:"text-base text-slate-500",get children(){return"AVERAGE COST "+JJ(Q.averagePrice)+(Q.marketValue?" · VALUE "+JJ(Q.marketValue):"")}})]}})})}})}}),q(K1,{})]}})}function kQ(){if(s()==="accounts")return q(OQ,{});if(s()==="activity")return q(LQ,{});return q(IQ,{})}function _Q(){return q(Z0,{get when(){return s()==="dashboard"},get fallback(){return q(kQ,{})},get children(){return q(RQ,{})}})}Y6(),u2(()=>q(_Q,{})),globalThis.PocketPiApp={tick:UQ,update(){return""},dataChanged(J){let Q=HQ(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),p):p;return Y6($),""},invokeTool(J){try{let Q=J==="robinhood.storage_status"?MQ():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Data Action tasks do not run in the View: "+J,isError:!0})},tap(J,Q){if(s()!=="dashboard"){if(Q<112&&J<220)return sJ("dashboard"),"";if(J>=620&&Q>=140&&Q<310){if(s()==="accounts")a4(($)=>Math.max(0,$-1));if(s()==="activity")n4(($)=>Math.max(0,$-1));if(s()==="positions")t4(($)=>Math.max(0,$-1));return""}if(J>=620&&Q>=940&&Q<1130){if(s()==="accounts")a4(($)=>Math.min(Math.max(0,gJ().length-8),$+1));if(s()==="activity")n4(($)=>Math.min(Math.max(0,y().activity.length-8),$+1));if(s()==="positions")t4(($)=>Math.min(Math.max(0,y().positions.length-9),$+1));return""}if(s()==="accounts"&&J<610&&Q>=126){let $=G1()+Math.floor((Q-126)/112),Z=gJ()[$];if(Z)eJ(()=>{I0(Z.number),sJ("dashboard")}),z6(Z.number,p)}return""}if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(Q>=112&&Q<176)return sJ("accounts"),"";if(Q>=480&&Q<540)return eJ(()=>{zQ(J<136?"day":"week"),q6(L0(),p)}),"";if(Q>=666&&Q<866)return sJ("activity"),"";if(Q>=866&&Q<1050)return sJ("positions"),"";if(Q>=1176&&J>=500){if(rJ())return"";return J6(!0),XJ("REFRESHING ROBINHOOD…"),JSON.stringify({type:"invokeTask",task:"refreshPortfolio"})}return""}}})(); + `).all(z,X,J).map((j)=>({time:j.bucket_time,value:k0(j.total_value)})),R=D.map((j)=>j.time),U=D.map((j)=>j.value).filter((j)=>j!==null),H=[R[0],R[9],R[19]].map((j)=>{let G=new Date(j*1000);return u()==="day"?String(G.getHours()).padStart(2,"0")+":"+String(G.getMinutes()).padStart(2,"0"):String(G.getMonth()+1)+"/"+String(G.getDate())});if(U.length===0){let j=u()==="day"?y().pnlDay:y().pnlWeek,G=k0(j),P={points:[],segments:[],labels:H,trend:{change:JJ(j),percent:"—",positive:G===null||G>=0}};j1.set($,{loadedRevision:Q,value:P}),OJ(P.points),LJ(P.segments),z1(P.labels),Y1(P.trend);return}let w=Math.min(...U),x=Math.max(...U),g=Math.max(0.01,x-w),A=D.flatMap((j,G)=>j.value===null?[]:[{x:G*622/19,y:U.length===1?80:10+(x-j.value)*140/g}]),a=A.slice(1).map((j,G)=>{let P=A[G],k=j.x-P.x,_=j.y-P.y;return{x:P.x,y:P.y,width:Math.sqrt(k*k+_*_),angle:Math.atan2(_,k)*180/Math.PI}}),r=U[U.length-1]-U[0],K={change:JJ(String(r)),percent:U[0]===0?"—":(r*100/U[0]).toFixed(2)+"%",positive:r>=0};j1.set($,{loadedRevision:Q,value:{points:A,segments:a,labels:H,trend:K}}),OJ(A),LJ(a),z1(H),Y1(K)}function KQ(J){if(Z6===J)return;let Q=m.query("SELECT status,error,completed_at FROM refresh_runs ORDER BY id DESC LIMIT 1").get();if(J6(!1),Q?.status==="failed")XJ("REFRESH FAILED · "+String(Q.error||"UNKNOWN ERROR").slice(0,52));else if(Q?.status==="partial")XJ("LIVE WITH PARTIAL DATA");else if(y().observedAt)XJ("LIVE · "+W6(y().observedAt));else XJ("WAITING FOR ROBINHOOD");Z6=J}function z6(J,Q){if(!J){if(aJ(iJ),OJ([]),LJ([]),!rJ())XJ("WAITING FOR ROBINHOOD");return}let $=H1.get(J);if($?.loadedRevision===Q){if(aJ($.value),q6(J,Q),$.value.observedAt&&!rJ())XJ("LIVE · "+W6($.value.observedAt));return}aJ(iJ),OJ([]),LJ([])}function Y6(J=p){try{let Q=m.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==i4){W1([]),I0(""),aJ(iJ),OJ([]),LJ([]),XJ("WAITING FOR ROBINHOOD");return}eJ(()=>{p=Math.max(p,J);let $=gJ();if(Q6!==p)$=jQ(),W1($),Q6=p;FQ(p,$);let Z=L0();if(!$.some((X)=>X.number===Z))Z=$[0]?.number||"",I0(Z);z6(Z,p),KQ(p)})}catch{eJ(()=>{W1([]),I0(""),aJ(iJ),OJ([]),LJ([]),XJ("WAITING FOR ROBINHOOD")})}}function UQ(){return""}function MQ(){let J=m.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((z)=>z.name)),$=J.map((z)=>{let F=m.query("SELECT COUNT(*) AS count FROM "+z.name).get().count;return{name:z.name,rowCount:F,schema:z.sql}}),Z=Q.has("refresh_runs")?m.query("SELECT id,started_at,completed_at,operation_count,success_count,status,error FROM refresh_runs ORDER BY id DESC LIMIT 3").all():[],X=Q.has("portfolio_current")?m.query("SELECT substr(account_number,-4) AS account_suffix,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current ORDER BY observed_at DESC LIMIT 4").all():[],W=Q.has("total_value")?m.query("SELECT substr(account_number,-4) AS account_suffix,observed_at,value FROM total_value ORDER BY observed_at DESC LIMIT 8").all():[];return{database:"robinhood.sqlite",schemaVersion:i4,tables:$,latestRefreshes:Z,latestPortfolios:X,latestValues:W}}function F1(){return GQ()}function _0(J){return q(n2,{get title(){return J.title},back:!0,metaTop:"AGENTIC",get metaBottom(){return J.metaBottom??"AUTO · 5 MIN"}})}function B1(J){return q(V,{class:"w-[210] h-[104]",get children(){return q(e2,{get label(){return J.label},get value(){return JJ(J.value)}})}})}function G6(J){return q(o2,{get title(){return J.title},get detail(){return J.detail},action:!0})}function PQ(J){if(J===0&&!y().activityAvailable)return ZQ;return y().activity[J]??(J===0?Z1:XQ)}function H6(J){let Q=()=>PQ(J.index);return q(V,{class:"h-[72] px-5 flex-row items-center justify-between",get children(){return[q(V,{class:"w-[450] flex-col gap-2",get children(){return[q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q().title}}),q(O,{class:"text-base text-slate-500",get children(){return l(()=>!!Q().timestamp)()?Q().timestamp+" · "+Q().detail:""}})]}}),q(O,{get["class"](){return Q().side==="SELL"?"text-base text-emerald-600 font-bold":"text-base text-slate-900 font-bold"},get children(){return l(()=>!!Q().amount)()?JJ(Q().amount):""}})]}})}function VQ(J){if(J===0&&!y().positionsAvailable)return WQ;return y().positions[J]??(J===0?X1:qQ)}function j6(J){let Q=()=>VQ(J.index);return q(V,{class:"h-[64] px-5 flex-row items-center",get children(){return[q(O,{class:"w-[240] text-lg text-slate-900 font-bold",get children(){return Q().symbol}}),q(O,{class:"w-[156] text-base text-slate-500",get children(){return l(()=>!!Q().quantity)()?Q().quantity+" SH":""}}),q(O,{class:"text-base text-slate-500",get children(){return l(()=>!!Q().averagePrice)()?"AVG "+JJ(Q().averagePrice):""}})]}})}function DQ(){return q(V,{class:"relative w-[632] h-[196] flex-col",get children(){return[q(V,{class:"relative w-[632] h-[160] overflow-hidden",get children(){return[q(V,{class:"absolute w-[632] h-[2] bg-slate-200",style:{posType:1,insetL:0,insetT:158}}),q(O,{class:"absolute text-base text-slate-500 font-bold",style:{posType:1,insetL:152,insetT:72},get children(){return s4().length<2?"COLLECTING 5M VALUE HISTORY":""}}),q(NJ,{get each(){return YQ()},children:(J)=>q(V,{get["class"](){return F1().positive?"absolute rounded-lg bg-emerald-500":"absolute rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x,insetT:J.y-1,width:J.width,height:2,rotate:J.angle,originX:-0.5,originY:0}}})}),q(NJ,{get each(){return s4()},children:(J)=>q(V,{get["class"](){return F1().positive?"absolute w-[6] h-[6] rounded-lg bg-emerald-500":"absolute w-[6] h-[6] rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x-3,insetT:J.y-3}}})})]}}),q(V,{class:"h-[36] px-1 flex-row items-center justify-between",get children(){return[q(O,{class:"text-base text-slate-500",get children(){return q1()[0]||""}}),q(O,{class:"text-base text-slate-500",get children(){return q1()[1]||""}}),q(O,{class:"text-base text-slate-500",get children(){return q1()[2]||""}})]}})]}})}function RQ(){let J=()=>F1();return q(V,{class:"flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ROBINHOOD"}),q(V,{class:"h-[64] px-6 pt-2",get children(){return q(V,{class:"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(O,{class:"text-base text-slate-500 font-bold",children:"ACCOUNT"}),q(O,{class:"text-base text-slate-900 font-bold",get children(){return y().account.label+(y().account.suffix?" ····"+y().account.suffix+" "+(gJ().findIndex((Q)=>Q.number===L0())+1)+"/"+gJ().length:"")+" ›"}})]}})}}),q(V,{class:"h-[304] px-6 pt-3",get children(){return q(V,{class:"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"h-[64] flex-row items-end justify-between",get children(){return[q(O,{class:"text-2xl text-slate-950 font-bold",get children(){return JJ(y().totalValue)}}),q(O,{get["class"](){return J().positive?"text-lg text-emerald-600 font-bold":"text-lg text-red-500 font-bold"},get children(){return J().change+" ("+J().percent+")"}})]}}),q(DQ,{})]}})}}),q(V,{class:"h-[60] px-6 pt-2 flex-row gap-3",get children(){return[q(V,{get["class"](){return u()==="day"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(O,{get["class"](){return u()==="day"?"text-base text-white font-bold":"text-base text-slate-500 font-bold"},children:"1D"})}}),q(V,{get["class"](){return u()==="week"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(O,{get["class"](){return u()==="week"?"text-base text-white font-bold":"text-base text-slate-500 font-bold"},children:"1W"})}}),q(O,{class:"pt-3 text-base text-slate-500",get children(){return u()==="day"?"TODAY":"PAST WEEK"}})]}}),q(V,{class:"h-[126] px-6 pt-3 flex-row items-start gap-[21]",get children(){return[q(B1,{label:"VALUE",get value(){return y().totalValue}}),q(B1,{label:"CASH",get value(){return y().cash}}),q(B1,{label:"BUY POWER",get value(){return y().buyingPower}})]}}),q(V,{class:"h-[200] px-6 flex-col",get children(){return[q(G6,{title:"ACTIVITY",detail:"LAST 7 DAYS"}),q(V,{class:"h-[150] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(H6,{index:0}),q(H6,{index:1})]}})]}}),q(V,{class:"h-[184] px-6 flex-col",get children(){return[q(G6,{title:"POSITIONS"}),q(V,{class:"h-[136] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(j6,{index:0}),q(j6,{index:1})]}})]}}),q(V,{class:"h-[126] px-6 pt-2",get children(){return q(V,{class:"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-col gap-3",get children(){return[q(O,{class:"text-xl text-slate-900 font-bold",children:"REALIZED P&L"}),q(O,{class:"text-base text-slate-500",get children(){return"EQUITIES / "+(u()==="day"?"TODAY":"WEEK")}})]}}),q(O,{get["class"](){return(k0(u()==="day"?y().pnlDay:y().pnlWeek)??0)>=0?"text-2xl text-emerald-600 font-bold":"text-2xl text-red-500 font-bold"},get children(){return JJ(u()==="day"?y().pnlDay:y().pnlWeek)}})]}})}}),q(V,{class:"h-[104] px-6 flex-row items-center justify-between",get children(){return[q(V,{class:"w-[460] h-[64]",get children(){return q(JQ,{get text(){return e4()},get tone(){return e4().startsWith("REFRESH FAILED")?"danger":"neutral"}})}}),q(V,{class:"w-[176] h-[64]",get children(){return q(t2,{get label(){return rJ()?"REFRESHING":"REFRESH NOW"},get disabled(){return rJ()}})}})]}})]}})}function K1(){return q(QQ,{top:"absolute left-[628] top-[156] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",bottom:"absolute left-[628] top-[972] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100"})}function OQ(){let J=$J(()=>gJ().slice(G1(),G1()+8)),Q=L0();return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ACCOUNTS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(NJ,{get each(){return J()},children:($)=>q(V,{get["class"](){return $.number===Q?"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100"},get children(){return[q(V,{class:"flex-row items-center justify-between",get children(){return[q(O,{class:"text-xl text-slate-900 font-bold",get children(){return $.label}}),q(O,{class:"text-lg text-slate-500 font-bold",get children(){return"····"+$.suffix}})]}}),q(V,{class:"flex-row items-center justify-between",get children(){return[q(V,{get["class"](){return c4.success.surface},get children(){return q(O,{get["class"](){return c4.success.text},get children(){return $.status}})}}),q(Z0,{get when(){return $.number===Q},get children(){return q(O,{class:"text-base text-emerald-600 font-bold",children:"SELECTED"})}})]}})]}})})}}),q(K1,{})]}})}function LQ(){let J=$J(()=>y().activity.slice(r4(),r4()+8));return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ACTIVITY",metaBottom:"LAST 7 DAYS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[14]",get children(){return q(Z0,{get when(){return l(()=>!!y().activityAvailable)()&&J().length>0},get fallback(){return q(d4,{get title(){return y().activityAvailable?"NO ACTIVITY YET":"ACTIVITY UNAVAILABLE"},compact:!0})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(V,{class:"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-row items-center justify-between",get children(){return[q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q.title}}),q(O,{get["class"](){return Q.side==="SELL"?"text-lg text-emerald-600 font-bold":"text-lg text-slate-900 font-bold"},get children(){return JJ(Q.amount)}})]}}),q(O,{class:"text-base text-slate-500",get children(){return Q.timestamp+" · "+Q.detail}}),q(O,{class:"text-base text-emerald-600 font-bold",get children(){return Q.state}})]}})})}})}}),q(K1,{})]}})}function IQ(){let J=$J(()=>y().positions.slice(o4(),o4()+9));return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"POSITIONS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(Z0,{get when(){return l(()=>!!y().positionsAvailable)()&&J().length>0},get fallback(){return q(d4,{get title(){return y().positionsAvailable?"NO OPEN POSITIONS":"POSITIONS UNAVAILABLE"},compact:!0})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(V,{class:"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-row items-center",get children(){return[q(O,{class:"w-[170] text-xl text-slate-900 font-bold",get children(){return Q.symbol}}),q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q.quantity+" SH"}})]}}),q(O,{class:"text-base text-slate-500",get children(){return"AVERAGE COST "+JJ(Q.averagePrice)+(Q.marketValue?" · VALUE "+JJ(Q.marketValue):"")}})]}})})}})}}),q(K1,{})]}})}function kQ(){if(s()==="accounts")return q(OQ,{});if(s()==="activity")return q(LQ,{});return q(IQ,{})}function _Q(){return q(Z0,{get when(){return s()==="dashboard"},get fallback(){return q(kQ,{})},get children(){return q(RQ,{})}})}Y6(),u2(()=>q(_Q,{})),globalThis.PocketPiApp={tick:UQ,update(){return""},dataChanged(J){let Q=HQ(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),p):p;return Y6($),""},invokeTool(J){try{let Q=J==="robinhood.storage_status"?MQ():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Data Action tasks do not run in the View: "+J,isError:!0})},tap(J,Q){if(s()!=="dashboard"){if(Q<112&&J<220)return sJ("dashboard"),"";if(J>=620&&Q>=140&&Q<310){if(s()==="accounts")a4(($)=>Math.max(0,$-1));if(s()==="activity")n4(($)=>Math.max(0,$-1));if(s()==="positions")t4(($)=>Math.max(0,$-1));return""}if(J>=620&&Q>=940&&Q<1130){if(s()==="accounts")a4(($)=>Math.min(Math.max(0,gJ().length-8),$+1));if(s()==="activity")n4(($)=>Math.min(Math.max(0,y().activity.length-8),$+1));if(s()==="positions")t4(($)=>Math.min(Math.max(0,y().positions.length-9),$+1));return""}if(s()==="accounts"&&J<610&&Q>=126){let $=G1()+Math.floor((Q-126)/112),Z=gJ()[$];if(Z)eJ(()=>{I0(Z.number),sJ("dashboard")}),z6(Z.number,p)}return""}if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(Q>=112&&Q<176)return sJ("accounts"),"";if(Q>=480&&Q<540)return eJ(()=>{zQ(J<136?"day":"week"),q6(L0(),p)}),"";if(Q>=666&&Q<866)return sJ("activity"),"";if(Q>=866&&Q<1050)return sJ("positions"),"";if(Q>=1176&&J>=500){if(rJ())return"";return J6(!0),XJ("REFRESHING ROBINHOOD…"),JSON.stringify({type:"invokeTask",task:"refreshPortfolio"})}return""}}})(); diff --git a/apps/robinhood/dist/data-action.js b/apps/robinhood/dist/data-action.js index dfe2ebd..8387c5c 100644 --- a/apps/robinhood/dist/data-action.js +++ b/apps/robinhood/dist/data-action.js @@ -1,4 +1,172 @@ -(()=>{var m=globalThis.db,R=m.open("robinhood");if(R<0)throw Error("open robinhood.sqlite");var C=4;function q(){return String(m.lastError(R)||"SQLite operation failed")}function g(e){if(m.exec(R,e)!==0)throw Error(q())}function v(e,t=[]){let o=JSON.parse(m.query(R,e,JSON.stringify(t)));if(o.error)throw Error(String(o.error));return o}function l(e,t=[]){return v(e,t)}var k=v("PRAGMA user_version");if(Number(k?.user_version??0)!==C)g(` +(()=>{var b={source:"https://agent.robinhood.com/mcp/trading",protocolVersion:"2025-06-18",retrievedAt:"2026-08-10T09:05:39+00:00",tools:[{name:"add_option_to_watchlist",namespace:"option_market_data",description:"Add option contracts to the user's options watchlist. Works for both equity options (AAPL, NVDA) and index options (SPX, NDX, RUT). Source option_ids from get_option_instruments. Confirm with the user before calling — this is a real write. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{option_ids:{type:["null","array"],items:{type:"string"},description:"Option contract UUIDs to add. Each becomes a single-leg position on the user's options watchlist. Source from get_option_instruments."},position_type:{type:"string",description:'"long" (default) or "short". Applies to every option_id in this call. For mixed long/short adds, issue two calls.'}},required:["option_ids"],additionalProperties:!1}},{name:"add_to_watchlist",namespace:"watchlists",description:"Add items to a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes like SPX, NDX) is required — mutually exclusive. For options use add_option_to_watchlist (separate dedicated watchlist). Futures still require the Robinhood app. Already-present items are no-ops. Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to add items to."},symbols:{type:["null","array"],items:{type:"string"},description:"Stock symbols to add (e.g. ['AAPL', 'NVDA']). US stocks and ETFs only. Mutually exclusive with currency_pair_ids and index_ids."},currency_pair_ids:{type:["null","array"],items:{type:"string"},description:"Currency-pair UUIDs to add (e.g. the object_id from get_watchlist_items where object_type=currency_pair, or the id from get_currency_pairs). Mutually exclusive with symbols and index_ids."},index_ids:{type:["null","array"],items:{type:"string"},description:"Market-index UUIDs to add (the id field from get_indexes; SPX, NDX, DJI, etc.). Mutually exclusive with symbols and currency_pair_ids."}},required:["list_id"],additionalProperties:!1}},{name:"cancel_equity_order",namespace:"equity_trading",description:"Cancel an open equity order by order_id. Always confirm with the user before calling. Resolve order_id via get_equity_orders if the user refers to it by symbol or description; pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected — do not call. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. REAL ACCOUNT ACTION: use only for the exact user-authorized account and order or exercise identifier; confirm the final provider state afterward. After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the order. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true. The upstream rejects mismatches against the order's owning account."},order_id:{type:"string",description:"Order UUID from get_equity_orders. Must live in account_number."}},required:["account_number","order_id"],additionalProperties:!1}},{name:"cancel_option_exercise",namespace:"option_trading",description:"Cancel all queued exercise requests for an option position. Pass the same account_number and option_id used for exercise_option. Internally looks up all queued exercise events for that option and cancels each one. Typically there is one; multiple means the user submitted separate exercise batches. Only cancels events in state=queued — events already processing are rejected by the broker. Always confirm with the user before calling. REAL ACCOUNT ACTION: use only for the exact user-authorized account and order or exercise identifier; confirm the final provider state afterward. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the exercise. Must be agentic_allowed=true."},option_id:{type:"string",description:"Option instrument UUID — the same option_id used for exercise_option. The tool looks up the queued exercise for this option and cancels it."}},required:["account_number","option_id"],additionalProperties:!1}},{name:"cancel_option_order",namespace:"option_trading",description:"Cancel an open option order by account_number + order_id. Always confirm with the user before calling. Resolve order_id via get_option_orders if the user refers to it by description; pass the same account_number you used there. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. REAL ACCOUNT ACTION: use only for the exact user-authorized account and order or exercise identifier; confirm the final provider state afterward. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the order. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true. Mismatches against the order's owning account are rejected."},order_id:{type:"string",description:"Order UUID from get_option_orders. Must live in account_number."}},required:["account_number","order_id"],additionalProperties:!1}},{name:"create_scan",namespace:"scanners",description:`Create a new saved scanner (screener) on the user's account, optionally applying a preset and custom filters in a single call. Returns the new scan's id, title, applied filters, and the initial live market results. + +This tool composes multiple Beacon operations: + 1. Create an empty scan + 2. If a non-INITIAL preset was requested: apply that preset configuration (DAILY_GAINERS, DAILY_LOSERS, HIGH_OPTIONS_VOLUME_IV, UPCOMING_EARNINGS) + 3. If custom filters were provided: apply them (replaces any preset filters) + 4. If a custom title was provided: set the title + +If any step after the initial create fails, the scan still exists with the partial state — the response surfaces what was applied. Use update_scan_filters / update_scan_config to fix anything that failed. + +Parameters: +- preset (optional) — starting preset. Default: DAILY_GAINERS when no filters supplied, INITIAL when filters supplied. Valid values: INITIAL, DAILY_GAINERS, DAILY_LOSERS, HIGH_OPTIONS_VOLUME_IV, UPCOMING_EARNINGS. +- filters (optional) — array of custom filter specs. Call get_scanner_filter_specs to discover valid filter_type / predicate values. +- title (optional) — custom human-readable name for the scan. + +Example: to make "stocks with RSI > 70 and volume > 1M, sorted by volume desc", call with + preset = "INITIAL" + filters = [ + {"filter_type": "FILTER_TYPE_RSI", "predicate": ">", "values": ["70"], "interval": "1d", "length": 14}, + {"filter_type": "FILTER_TYPE_VOLUME", "predicate": ">", "values": ["1000000"], "interval": "1d"} + ] + title = "High RSI + High Volume" This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{preset:{type:"string",description:"Starting preset for the new scan. One of: INITIAL (no preset; only valid if filters are provided), DAILY_GAINERS, DAILY_LOSERS, HIGH_OPTIONS_VOLUME_IV, UPCOMING_EARNINGS. Defaults to DAILY_GAINERS when no filters are provided, INITIAL when filters are provided."},filters:{type:["null","array"],items:{type:"object",properties:{filter_type:{type:"string",description:'Wire-format enum name, e.g. "FILTER_TYPE_RSI". See the scanner-filter-specs resource for valid values. Omit when supplying expression.'},predicate:{type:"string",description:'Wire-format enum name, e.g. "PREDICATE_GREATER_THAN". See the scanner-filter-specs resource for the predicates supported by each filter.'},values:{type:["null","array"],items:{type:"string"},description:'Threshold values. Single-element for unary predicates, two-element for BETWEEN, multi-element for IN_LIST/ANY_OF. For a boolean expression screen, exactly ["True"].'},interval:{type:"string",description:`Time granularity for time-series filters (e.g. "1d"). Use one of the supported_intervals from the filter's scanner-filter-specs entry. Not used with expression — encode granularity inside the expression.`},length:{type:"integer",description:"Lookback length for filters that need one (e.g. RSI period of 14). Use one of the supported_lengths from the filter's scanner-filter-specs entry. Not used with expression.",minimum:-2147483648,maximum:2147483647},plot:{type:"string",description:`Plot / price-field input for filters that have one (e.g. "open" or "close" for % Change). Use one of the supported_plots from the filter's scanner-filter-specs entry. Not used with expression.`},expression:{type:"string",description:'Raw market-data expression to screen on, e.g. "dayVolume / volumeAvg(candleCount=30, candlePeriod=\\"1d\\", session=\\"all\\")" with a numeric predicate, or a whole comparison like "tradeAllDay.price > closeAvg(candleCount=50, candlePeriod=\\"1d\\", session=\\"all\\")" with predicate "=" and values ["True"]. Only preview_scan accepts expressions. Omit filter_type when set. Prefer an enum filter_type whenever one covers the request.'},display_title:{type:"string",description:'Optional short label for an expression filter, shown as the results-column header (e.g. "Relative volume (30D)"). Only used with expression.'}},required:["predicate","values"],additionalProperties:!1},description:"Custom filters to apply after the preset. Each filter has filter_type (FILTER_TYPE_... enum), predicate (>, <, =, BETWEEN, etc.), values, optional interval (e.g. 1d), and optional length (e.g. 14 for RSI). Call get_scanner_filter_specs first for valid filter_type / predicate combinations."},title:{type:"string",description:"Optional custom title for the saved scan. If omitted, Beacon assigns a default title based on the preset."}},additionalProperties:!1}},{name:"create_watchlist",namespace:"watchlists",description:"Create a new custom watchlist for the user. Confirm the name with the user before calling — this is a real write. Do not use this to follow a Robinhood-curated list (use follow_watchlist). This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{display_name:{type:"string",description:"Name for the new watchlist (e.g. 'Tech Stocks'). Must be unique among the user's watchlists."},icon_emoji:{type:"string",description:"Emoji shown next to the name (one character)."},display_description:{type:"string",description:"Short description shown under the name."}},required:["display_name"],additionalProperties:!1}},{name:"exercise_option",namespace:"option_trading",description:`Exercise a long options position — a call exercises the right to buy the underlying shares at the strike price; a put exercises the right to sell. Exercise is irrevocable once state moves past queued. + +Never call this tool without asking the user to explicitly confirm the specific exercise first: state the option, quantity, and expected cash impact (debit for calls, credit for puts), then wait for their affirmative reply before calling. The user's original request to exercise is NOT itself sufficient confirmation — a generic "exercise my calls" does not confirm a specific option and quantity. + +Position requirements: confirm via get_option_positions that the position type=long and quantity > 0. + +Account requirements: confirm via get_accounts that the chosen account is agentic_allowed=true AND has option_level_2 or option_level_3. If agentic_allowed=false do NOT call. If option_level is empty or option_level_0, do NOT call; follow the get_accounts guide for how to direct the user to enroll. + +Index options cannot be manually exercised and will be rejected. Exercises submitted during market hours execute the same day; requests submitted after market close — including on late-close trading days — are queued for overnight processing. + +Parameter rules: +- quantity must be a positive integer and cannot exceed the position's available contracts. +- allow_shorts=true only applies to PUT exercises where the account does not own enough shares to deliver. Require explicit user confirmation before setting this — it creates a short equity position in the underlying stock. +- reason is optional but recommended; collect it from the user when they volunteer a motivation. +- ref_id: use the same UUID on retries of the same logical exercise; use a new UUID for a new exercise. REAL-MONEY ACTION: use only after the user explicitly authorizes the exact account, instrument, side, size, order type, price constraints, and timing. Use the dedicated Agentic account and reuse one ref_id for retries. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must be agentic_allowed=true with option_level_2 or option_level_3."},option_id:{type:"string",description:"Option instrument UUID from get_option_positions or get_option_instruments. The position must be type=long."},quantity:{type:"integer",description:"Number of contracts to exercise (positive integer, minimum 1)."},ref_id:{type:"string",description:"Idempotency key (UUID). Generate once per logical exercise and re-send on retry. Omitting falls back to a server-generated key."},reason:{type:"string",description:"Optional exercise reason: covering_early_assignment | buying_stocks | not_enough_liquidity_or_spread_too_wide | hedging_position."},allow_shorts:{type:"boolean",description:"When true, allows a PUT exercise to proceed even when the account does not own enough shares to deliver — creating a short equity position. Requires explicit user confirmation that they intend to short the underlying stock. Default false."}},required:["account_number","option_id","quantity"],additionalProperties:!1}},{name:"follow_watchlist",namespace:"watchlists",description:"Follow a Robinhood-curated list so it appears in the user's watchlists. Confirm with the user before calling. Use only for curated lists; the user already owns their custom lists. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the Robinhood-curated list to follow. Obtain from get_popular_watchlists."}},required:["list_id"],additionalProperties:!1}},{name:"get_accounts",namespace:"account_portfolio",description:"List the user's brokerage accounts. Use this to look up account_number values needed by other tools. If the user has multiple accounts and hasn't specified which one, present the list and ask them to choose. Does NOT return reliable buying power — route buying-power questions through get_portfolio. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.",inputSchema:{type:"object",additionalProperties:!1}},{name:"get_earnings_calendar",namespace:"equity_market_data",description:'List earnings reports scheduled across the market over a date window (up to 31 days), optionally limited to high-market-cap names. Returns one entry per report event — estimated/actual EPS, report date and timing (am/pm), and company-verification status. Use this for market-wide discovery ("what large-caps report this week?"). For a specific known ticker, use get_earnings_results instead. Read-only. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.',inputSchema:{type:"object",properties:{start_date:{type:"string",description:"Window anchor, YYYY-MM-DD. Defaults to today (US/Eastern) when omitted."},days:{type:"integer",description:"Window length in days, measured from start_date. Defaults to 7. Positive = forward window (e.g. 7 = the next 7 days, inclusive of start_date); negative = look-back window (e.g. -7 = the 7 days ending at start_date). Must be a non-zero value between -31 and 31 — windows wider than 31 days are rejected."},filter:{type:"string",description:"Optional result filter. Set to 'high_market_cap' to limit the calendar to high-market-cap names (market cap over $1B) — useful for 'what large-caps report this week' style questions. Omit for all names."}},additionalProperties:!1}},{name:"get_earnings_results",namespace:"equity_market_data",description:'Get recent and upcoming earnings for ONE equity symbol — estimated/actual EPS, report date and timing (am/pm), and company-verification status. Returns the trailing up to 8 quarters. Use this for earnings-timing questions ("does AAPL report this week?"), EPS surprise analysis, and screening for upcoming earnings risk on a specific stock. For market-wide earnings calendar queries across many symbols, use get_earnings_calendar. Read-only. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.',inputSchema:{type:"object",properties:{symbol:{type:"string",description:"Stock symbol to look up (one symbol per call). Exact-ticker match — no name or partial-ticker resolution. Lowercase and whitespace-padded input is normalized to uppercase-trimmed before forwarding. Returns the trailing up to 8 quarters of earnings for the symbol."}},required:["symbol"],additionalProperties:!1}},{name:"get_equity_fundamentals",namespace:"equity_market_data",description:"Get today's fundamentals for one or more stock symbols — valuation ratios (PE, P/B), capitalization (market cap, shares outstanding, float), today's session OHLCV, trailing volume averages, 52-week range, dividend schedule, and company profile. For real-time quotes use get_equity_quotes; for time-series price history use get_equity_historicals. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols (max 10 per call). Exact-ticker match — no name or partial-ticker resolution. Lowercase and whitespace-padded input is normalized to uppercase-trimmed before forwarding."},bounds:{type:"string",description:"Trading session the day-level fields (open / high / low / volume / overnight_volume) are drawn from. One of 'regular' (regular trading hours), 'trading' (regular + post-market), 'extended' (pre-market + regular + post-market), '24_5' (24-hour, 5-day-trading-week). Does not affect valuation fields. overnight_volume only populates when bounds=24_5. Defaults to 'regular' when omitted."}},required:["symbols"],additionalProperties:!1}},{name:"get_equity_historicals",namespace:"equity_market_data",description:`Get OHLCV bars for one or more equity symbols across an explicit time range. Use this for charting, "recent activity" questions, and backtesting. The server auto-selects an interval when one is not provided. If the bar's interpolated field is true, bar was synthesized to fill a gap and carry no new information. + +Parameter rules: +- interval is optional; when omitted, the server auto-selects an interval that targets ~2,500 bars across the requested range. Provide an explicit interval only when you need a specific granularity. +- interval values are fixed; the server does NOT aggregate intermediate bars. For a custom interval (e.g. 3-minute), request the next-finer fixed interval and aggregate client-side. +- bounds defaults to 'regular' (RTH only). Use 'extended' or '24_5' only when the user explicitly asks about extended-hours activity. +- adjustment_type defaults to 'split' (split-adjusted, the right default for backtesting). Use 'none' for raw prices, 'all' for split + dividend adjustment. +- If the range would produce more bars than the upstream allows at the explicitly requested interval, narrow the range or coarsen the interval — the call is rejected before reaching upstream. The cap does not apply when interval is auto-selected. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols (uppercase). Up to 10 per call."},start_time:{type:"string",description:"Start of the range (RFC3339 UTC, e.g. '2026-01-01T00:00:00Z'). Required."},end_time:{type:"string",description:"End of the range (RFC3339 UTC). Optional — when omitted, defaults to the current time."},interval:{type:"string",description:"Bar interval. Optional — when omitted, the server picks an interval that targets ~2,500 bars across the requested range. Intraday: 15second, 30second, minute, 5minute, 10minute, 30minute, hour, 4hour. Interday: day, week, month, 3month, 6month, year, 5year, 10year, 20year, 50year. Note: the 1-minute bar is named 'minute' (not '1minute')."},bounds:{type:"string",description:"Session bounds. One of 'regular' (RTH, default), 'extended', 'trading', '24_5', '24_7', 'hyper_trading'."},adjustment_type:{type:"string",description:"Corporate-action adjustment: 'none' (raw prices), 'split' (default; right for backtesting), or 'all' (split + dividend; intraday only)."}},required:["symbols","start_time"],additionalProperties:!1}},{name:"get_equity_orders",namespace:"equity_trading",description:`Fetch equity orders for an account — list mode (newest first; open and closed, including fills, cancellations, rejections) or single-order mode by passing order_id. When the user asks for "orders" without specifying an asset class, call get_equity_orders, get_option_orders, and get_advanced_orders (OCO / multi-leg contingency orders) in parallel. + +Filtering tips: +- Prefer narrow queries: combine state, symbol, and/or created_at_gte for specific questions (e.g. "my filled AAPL orders this week") — the per-page cap is fixed. +- created_at_gte: interpret relative times in the user's timezone, convert to UTC before sending. +- symbol forces a symbol→instrument lookup; omit it if you don't need it. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts."},order_id:{type:"string",description:"Filter to a single order by UUID. The response shape is unchanged (orders[] with at most one entry); empty when the order does not belong to account_number."},state:{type:"string",description:"Filter by single state: new, queued, confirmed, unconfirmed, partially_filled, filled, cancelled, rejected, failed, voided."},symbol:{type:"string",description:"Filter to one symbol (triggers a symbol→instrument lookup before the orders call)."},created_at_gte:{type:"string",description:"Lower bound (inclusive). ISO 8601 UTC or YYYY-MM-DD; naive values are interpreted as UTC."},placed_agent:{type:"string",description:"Filter to one source: 'user', 'agentic' (MCP), 'recurring', 'drip', etc."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number"],additionalProperties:!1}},{name:"get_equity_positions",namespace:"equity_trading",description:"List open equity positions for a specific brokerage account. Returns symbol, quantity, average cost, and per-position hold breakdowns. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number"],additionalProperties:!1}},{name:"get_equity_price_book",namespace:"equity_market_data",description:"Get a real-time bid/ask order book (Level 2) snapshot for one or more equity symbols (max 4), showing the ladder of price levels and resting share size on each side. Use to read supply/demand depth before entering or exiting a position. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols, max 4 per call."}},required:["symbols"],additionalProperties:!1}},{name:"get_equity_quotes",namespace:"equity_market_data",description:"Get real-time stock quotes and the official last-completed-session close for one or more symbols. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols. Above 20 symbols, quotes still return but closes is omitted with closes_error set."}},required:["symbols"],additionalProperties:!1}},{name:"get_equity_tax_lots",namespace:"equity_trading",description:"List the open tax lots for one equity holding in an account — each lot is a separate acquisition with its own quantity, cost basis, acquisition date, and long/short-term status. Requires a symbol (tax lots are tracked per instrument). Use it for cost-basis, holding-period, or which-lots-would-sell questions. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts."},symbol:{type:"string",description:"Ticker symbol of the holding whose tax lots you want, e.g. AAPL. Tax lots are tracked per instrument — one symbol per call."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number","symbol"],additionalProperties:!1}},{name:"get_equity_technical_indicators",namespace:"equity_market_data",description:`Compute a technical indicator (RSI, MACD, Bollinger Bands, moving averages, ATR, VWAP, and more) over one equity symbol's OHLCV bars across a time range. For the raw OHLCV bars themselves, use get_equity_historicals. + +Parameter rules: +- The parameters an indicator accepts depend on type: + - period only: ema/sma (default 9); rsi/cci/atr/mfi (default 14); williams_r/adx (default 10); momentum (default 12); roc (default 14); donchian_channels (default 20). + - bollinger_bands: period (default 20) + num_std (default 2). + - macd: fast_period (12), slow_period (26), signal_period (9). + - keltner_channels: period (default 20) + multiplier (default 2). + - supertrend: period (default 10) + multiplier (default 3). + - pivot_points: method (only 'classic'). + - vwap, obv: no parameters. + Omit a parameter to use its default. Passing a parameter the chosen type does not accept is rejected. +- interval is REQUIRED — indicator periods are counted in bars, so there is no auto-selection. +- adjustment_type defaults to 'split'; 'all' (split + dividend) requires a day-or-coarser interval. +- If the requested range plus the indicator's warm-up exceeds the per-request bar cap, narrow the range or coarsen the interval. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{symbol:{type:"string",description:"Stock symbol (uppercase). Exactly one symbol per call."},type:{type:"string",description:"Indicator to compute. One of: ema, sma, rsi, momentum, roc, cci, williams_r, atr, mfi, adx, donchian_channels, bollinger_bands, macd, keltner_channels, supertrend, vwap, obv, pivot_points."},interval:{type:"string",description:"Required bar interval the indicator is computed on. Intraday: 15second, 30second, minute, 5minute, 10minute, 30minute, hour, 4hour. Interday: day, week, month, 3month, 6month, year, 5year, 10year, 20year, 50year. The 1-minute bar is named 'minute' (not '1minute')."},start_time:{type:"string",description:"Start of the range (RFC3339 UTC, e.g. '2026-01-01T00:00:00Z'). Required."},end_time:{type:"string",description:"End of the range (RFC3339 UTC). Optional — defaults to the current time when omitted."},bounds:{type:"string",description:"Session bounds. One of 'regular' (RTH, default) or 'extended'."},adjustment_type:{type:"string",description:"Corporate-action adjustment: 'none' (raw prices), 'split' (default), or 'all' (split + dividend; requires a day-or-coarser interval)."},output:{type:"string",description:"How much of the series to return: 'series' (default, full range), 'latest' (most recent bar only), or 'last:N' (most recent N bars). The indicator is always computed over the full range first; this only trims the response."},period:{type:["null","integer"],description:"Lookback period in bars. Applies to ema, sma, rsi, momentum, roc, cci, williams_r, atr, mfi, adx, donchian_channels, bollinger_bands, keltner_channels, supertrend. Omit to use the indicator's default."},num_std:{type:["null","number"],description:"Number of standard deviations for the bands. bollinger_bands only (default 2)."},fast_period:{type:["null","integer"],description:"Fast EMA period. macd only (default 12)."},slow_period:{type:["null","integer"],description:"Slow EMA period. macd only (default 26)."},signal_period:{type:["null","integer"],description:"Signal EMA period. macd only (default 9)."},multiplier:{type:["null","number"],description:"Band/offset multiplier. keltner_channels (default 2) and supertrend (default 3) only."},method:{type:"string",description:"Calculation method. pivot_points only; currently only 'classic'."}},required:["symbol","type","interval","start_time"],additionalProperties:!1}},{name:"get_equity_tradability",namespace:"equity_trading",description:"Check tradability for up to 10 equity symbols on a given account: per-session eligibility and fractional. Call before placing an order to surface restrictions. Exact-ticker match — no name or partial-ticker resolution. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts."},symbols:{type:["null","array"],items:{type:"string"},description:"Stock symbols, max 10 per call. With more than 10, split across multiple calls of 10 or fewer. Exact-ticker match only."}},required:["account_number","symbols"],additionalProperties:!1}},{name:"get_financials",namespace:"equity_market_data",description:"Get a company's reported financial metrics over time — revenue, gross profit, net income, and net margin — by fiscal period (annual or quarterly), for one or more symbols. Use this for fundamental analysis like revenue-growth and margin-trend tracking, profitability screens, and period-over-period comparisons. Read-only. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols (max 20 per call). Exact-ticker match — no name or partial-ticker resolution. Lowercase and whitespace-padded input is normalized to uppercase-trimmed before forwarding."},period:{type:"string",description:"Reporting period: 'quarterly' or 'annual'. Defaults to 'quarterly' when omitted."},limit:{type:"integer",description:"Number of most-recent periods to return per symbol (e.g. 8 for the last 8 quarters or years). Defaults to 4; values above 40 are capped to 40."}},required:["symbols"],additionalProperties:!1}},{name:"get_index_historicals",namespace:"indexes",description:`Get OHLC value bars for one or more market indexes (by instrument UUID) across an explicit time range. Use this for charting an index's history and "recent movement" questions. If the bar's interpolated field is true, bar was synthesized to fill a gap and carry no new information. + +Parameter rules: +- instrument_ids are index instrument UUIDs from get_indexes. Resolve symbols there first; this tool does not accept ticker symbols. +- interval is required; pick the coarsest interval that answers the question. If the requested interval would produce too many bars for the range, the call is rejected — narrow the range or coarsen the interval. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{instrument_ids:{type:["null","array"],items:{type:"string"},description:"Index instrument UUIDs (from get_indexes). Up to 10 per call."},start_time:{type:"string",description:"Start of the range (RFC3339 UTC, e.g. '2026-01-01T00:00:00Z'). Required."},end_time:{type:"string",description:"End of the range (RFC3339 UTC). Optional — when omitted, defaults to the current time."},interval:{type:"string",description:"Bar interval. Required — there is no server auto-select for indexes. Intraday: 5second, 15second, 30second, minute, 5minute, 10minute, 30minute, hour, 4hour. Interday: day, week, month, 3month, 6month, year, 5year, 10year, 20year, 50year. Note: the 1-minute bar is named 'minute' (not '1minute')."}},required:["instrument_ids","start_time","interval"],additionalProperties:!1}},{name:"get_index_quotes",namespace:"indexes",description:"Get real-time values for one or more market indexes by instrument ID. Returns current index level, state, and timestamps. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{instrument_ids:{type:["null","array"],items:{type:"string"},description:"One or more index instrument IDs (UUIDs) to fetch current values for. Obtain IDs from the get_indexes tool."}},required:["instrument_ids"],additionalProperties:!1}},{name:"get_indexes",namespace:"indexes",description:`Get index data for market indexes by symbol. +Optionally pass a comma-separated list of symbols (e.g. 'SPX,NDX,DJI') to filter results. Omit symbols to return all available indexes. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{symbols:{type:"string",description:"Comma-separated list of index symbols to look up (e.g. 'SPX,NDX'). Omit to return all available indexes."}},additionalProperties:!1}},{name:"get_limited_margin_upgrade_info",namespace:"account_portfolio",description:"Check whether a cash account is eligible to upgrade to limited margin and return the links (web and mobile) that start the upgrade flow. Limited margin lets the account trade with unsettled funds — proceeds from a sale can go into a new order before that sale settles — while adding no borrowing or leverage. Call when the user asks about that capability, about trading with unsettled funds, or about enabling limited margin — or when a cash account shows unsettled_funds greater than 0 while you are reporting its funds, value, or buying power (the get_accounts and get_portfolio guides direct this).. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number to check. Obtain from get_accounts."}},required:["account_number"],additionalProperties:!1}},{name:"get_option_chains",namespace:"option_market_data",description:"List option chains for one or more underlyings. A chain describes the full set of expiration dates and contracts for a given underlying. One of underlying_symbol or ids is required. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{ids:{type:"string",description:"Comma-separated chain UUIDs."},underlying_symbol:{type:"string",description:"Ticker filter; covers equity and index underlyings (e.g. 'AAPL', 'SPX')."}},additionalProperties:!1}},{name:"get_option_historicals",namespace:"option_market_data",description:`Get OHLC price bars for one or more option contracts (by instrument UUID) across an explicit time range. Use this for charting an option's price history and "recent activity" questions. The server auto-selects an interval when one is not provided. If the bar's interpolated field is true, bar was synthesized to fill a gap and carry no new information. + +Parameter rules: +- instrument_ids are option contract UUIDs from get_option_instruments. Resolve underlying -> get_option_chains -> get_option_instruments first; this tool does not accept ticker symbols. +- interval is optional; when omitted the server auto-selects an interval that targets a bounded bar count across the range. Provide an explicit interval only when you need a specific granularity. +- bounds defaults to 'regular' (regular hours). Use '24_5'/'24_7' only when the user explicitly asks about extended-hours or overnight option activity. +- If an explicitly requested interval would produce more bars than the upstream allows for the range, the call is rejected — narrow the range or coarsen the interval. The cap does not apply when interval is auto-selected. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{instrument_ids:{type:["null","array"],items:{type:"string"},description:"Option contract instrument UUIDs (from get_option_instruments). Up to 10 per call."},start_time:{type:"string",description:"Start of the range (RFC3339 UTC, e.g. '2026-01-01T00:00:00Z'). Required."},end_time:{type:"string",description:"End of the range (RFC3339 UTC). Optional — when omitted, defaults to the current time."},interval:{type:"string",description:"Bar interval. Optional — when omitted, the server auto-selects an interval that targets a bounded bar count across the range. Intraday: 15second, 30second, minute, 5minute, 10minute, 30minute, hour, 4hour. Interday: day, week, month, 3month, 6month, year, 5year, 10year, 20year, 50year. Note: the 1-minute bar is named 'minute' (not '1minute')."},bounds:{type:"string",description:"Session bounds. One of 'regular' (regular hours, default), '24_5', or '24_7'. Use '24_5'/'24_7' only when the user explicitly asks about extended-hours or overnight option activity (index options, and certain equity options)."}},required:["instrument_ids","start_time"],additionalProperties:!1}},{name:"get_option_instruments",namespace:"option_market_data",description:"List option contracts. One of chain_symbol, chain_id, or ids is required; narrow further with expiration_dates, strike_price, type, state. When looking up contracts for a specific expiration, call this in parallel for every chain whose expiration_dates (from get_option_chains) includes the date. For AM/PM/morning/evening preferences, first check settle_on_open on each chain via get_option_chains and only query matching chains. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{chain_id:{type:"string",description:"Chain UUID."},chain_symbol:{type:"string",description:"Underlying ticker (e.g. 'AAPL')."},expiration_dates:{type:"string",description:"Comma-separated YYYY-MM-DD expirations."},strike_price:{type:"string",description:"Exact strike (e.g. '150.0000')."},type:{type:"string",description:"'call' or 'put'."},state:{type:"string",description:"'active' (default), 'expired', or 'inactive'. Use 'expired' to find option contracts whose expiration date has passed; 'inactive' is for delisted/withdrawn contracts that never expired."},tradability:{type:"string",description:"'tradable' or 'untradable' (untradable is rejected at the tool layer)."},ids:{type:"string",description:"Comma-separated instrument UUIDs."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},additionalProperties:!1}},{name:"get_option_level_upgrade_info",namespace:"account_portfolio",description:"Get the upgrade URL to apply for options access on an account. Call when option_level is null. option_level_2 enables long calls/puts, covered calls, and cash-secured puts; option_level_3 adds spreads and complex strategies, though multi-leg orders are not yet supported here. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number to generate the upgrade URL for. Obtain from get_accounts."}},required:["account_number"],additionalProperties:!1}},{name:"get_option_orders",namespace:"option_trading",description:`Fetch options orders for an account — list mode (newest first; open and closed, including fills, cancellations, and rejections) or single-order mode by passing order_id. When the user asks for "orders" without specifying equity or options, call both get_option_orders and get_equity_orders in parallel. + +Filtering tips: +- Prefer narrow queries: combine state and/or created_at_gte for specific questions — the per-page cap is fixed. +- chain_ids filters by underlying chain UUID (from get_option_chains). +- created_at_gte: interpret relative times in the user's timezone, convert to UTC before sending. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts."},order_id:{type:"string",description:"Filter to a single order by UUID. The response shape is unchanged (orders[] with at most one entry); empty when the order does not belong to account_number."},state:{type:"string",description:"Filter by single state: queued, confirmed, partially_filled, filled, rejected, cancelled, failed, voided, pending_cancelled."},created_at_gte:{type:"string",description:"Lower bound (inclusive). ISO 8601 UTC or YYYY-MM-DD; naive values are interpreted as UTC."},chain_ids:{type:"string",description:"Comma-separated chain UUIDs (from get_option_chains) to filter by underlying."},underlying_type:{type:"string",description:"'equity' or 'index'."},placed_agent:{type:"string",description:"Filter to one source: 'user', 'agentic' (MCP), 'recurring', 'drip', etc."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number"],additionalProperties:!1}},{name:"get_option_positions",namespace:"option_trading",description:'List options positions for an account. Returns open and closed (zero-quantity) positions. Pass nonzero=true for "what options do I have" / "show me my positions" — the common case. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.',inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts."},nonzero:{type:"boolean",description:"True to return only currently-open positions; omit/false to include closed ones."},chain_ids:{type:"string",description:"Comma-separated chain UUIDs (from get_option_chains)."},option_ids:{type:"string",description:"Comma-separated instrument UUIDs."},type:{type:"string",description:"'long' or 'short'."},option_type:{type:"string",description:"'call' or 'put'."},expiration_date:{type:"string",description:"Exact expiration (YYYY-MM-DD)."},expiration_date_lte:{type:"string",description:"Upper bound on expiration (YYYY-MM-DD)."},expiration_date_gte:{type:"string",description:"Lower bound on expiration (YYYY-MM-DD)."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number"],additionalProperties:!1}},{name:"get_option_quotes",namespace:"option_market_data",description:"Get real-time quotes for one or more option contracts by instrument UUID, plus the official prior-session close for each. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{instrument_ids:{type:["null","array"],items:{type:"string"},description:"Option instrument UUIDs. Above 20, quotes still return but closes is omitted with closes_error set."}},required:["instrument_ids"],additionalProperties:!1}},{name:"get_option_watchlist",namespace:"option_market_data",description:"List the single-leg option contracts on the user's options watchlist. Use this instead of get_watchlist_items for the options watchlist — get_watchlist_items returns a generic shape that drops the option-specific title and the upstream rejects it with 400 anyway. Works for both equity options (AAPL, NVDA) and index options (SPX, NDX, RUT). Multi-leg strategies (verticals, condors, etc.) that may exist in the user's watchlist from app-side order placement are not shown — direct the user to the Robinhood app to view those. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",additionalProperties:!1}},{name:"get_pnl_trade_history",namespace:"account_portfolio",description:`Get a customer's per-trade realized profit & loss — a chronological, paginated list of closed/realizing trades (equities, options, crypto, prediction markets) with symbol, side, quantity, price, and realized gain/loss. This is the same data behind the app's PnL hub ("Realized profit & loss"). Read-only. Trades only. Use get_realized_pnl for aggregate/bucketed totals. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number (the rhs_account_number from get_accounts). Obtain it from get_accounts."},span:{type:"string",description:"Preset window: week (default), month, 3month, ytd, or all. Wormhole offers preset spans only (no arbitrary date range)."},symbol:{type:"string",description:"Optional single stock symbol filter (trimmed + uppercased). Omit for all symbols; one symbol per call."},cursor:{type:"string",description:"Pagination cursor from a previous response's next_cursor. Omit for the first page."}},required:["account_number"],additionalProperties:!1}},{name:"get_popular_watchlists",namespace:"watchlists",description:"Discover Robinhood-curated lists the user can follow (e.g. '100 Most Popular', 'Daily Movers'). Use to find a list_id, then pass it to follow_watchlist. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",additionalProperties:!1}},{name:"get_portfolio",namespace:"account_portfolio",description:`Get the account's portfolio market value breakdown by asset type and buying power. Use for "how much is my account worth?", "what's my portfolio breakdown?", "how much do I have in options?", and "how much can I spend / afford?" questions. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Obtain from get_accounts."}},required:["account_number"],additionalProperties:!1}},{name:"get_realized_pnl",namespace:"account_portfolio",description:`Get a customer's realized profit & loss for an account over a time window — per-bucket realized gain ($ and %) and the number of closing trades, plus window totals. Read-only. Aggregate, bucketed numbers only (not individual trades). Use for post-trade analysis like "how did my last 90 days of trades do?". Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number (the rhs_account_number from get_accounts). Obtain it from get_accounts."},span:{type:"string",description:"Preset window: day, week, month, 3month, year, or all. Defaults to 3month ('last 90 days'). Mutually exclusive with start_date/end_date."},start_date:{type:"string",description:"Custom window start, YYYY-MM-DD, inclusive — interpreted at midnight in timezone (default US Eastern). Use with end_date instead of span; must be on or before end_date and not in the future."},end_date:{type:"string",description:"Custom window end, YYYY-MM-DD, inclusive — the entire end_date is covered (through 23:59:59 in timezone). Use with start_date instead of span; an end_date beyond today returns data through the present."},asset_classes:{type:["null","array"],items:{type:"string"},description:"Filter to one or more of equity, option, crypto. Omit for all asset classes available on the account."},display_currency:{type:"string",description:"Currency for returned amounts. Currently USD only; defaults to USD."},timezone:{type:"string",description:"IANA timezone for bucket day-boundaries (e.g. America/New_York). Defaults to the account timezone (US Eastern)."}},required:["account_number"],additionalProperties:!1}},{name:"get_scanner_filter_specs",namespace:"scanners",description:`List every valid scanner filter type and how to use it. Call this before constructing filters for create_scan or update_scan_filters — do not guess filter_type names. + +This tool takes no parameters. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",additionalProperties:!1}},{name:"get_scans",namespace:"scanners",description:`List the authenticated user's saved scanners (also called screeners). A scan is a saved set of filters and columns that filters the market for instruments matching specific criteria (e.g. "RSI > 70 and Volume > 1M"). The user creates these in Legend or via the create_scan tool. + +Returns one entry per scan with its id, title, active filters, configured columns, sort order, and a flag indicating whether the scan is managed by Cortex (Legend's AI agent). Cortex-managed scans are read-only via MCP — they can be run with run_scan but not modified with update_scan_filters or update_scan_config. + +This tool takes no parameters. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",additionalProperties:!1}},{name:"get_watchlist_items",namespace:"watchlists",description:"List the items in a watchlist. Items may be stocks/ETFs, crypto pairs, futures, indexes — distinguished by object_type. For the options watchlist, use get_option_watchlist instead — this tool returns a generic shape that drops the strategy-specific fields and the upstream rejects it with 400 anyway. Does not return live prices; call get_quotes with the symbol(s) for that. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist whose items to fetch. Obtain from get_watchlists or get_popular_watchlists."}},required:["list_id"],additionalProperties:!1}},{name:"get_watchlists",namespace:"watchlists",description:"List the user's watchlists, including both user-created custom lists and Robinhood-curated lists the user follows. Use to look up list_id values for other watchlist tools. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",additionalProperties:!1}},{name:"place_equity_order",namespace:"equity_trading",description:`Place a real equity order with real money. Parameters mirror review_equity_order plus the optional ref_id. Requires an agentic_allowed=true account; non-agentic accounts are rejected — do not call. + +Workflow: by default call review_equity_order first, present the estimated cost and any alerts, and get explicit user confirmation before calling this tool. Skip review only when the user has very explicitly asked to bypass it (e.g. "skip the review", "just place it, don't review") — a generic "place this order" is NOT a bypass. + +Idempotency: pass a fresh UUID as ref_id on the first call for each logical order, and re-send the SAME ref_id on retries of transient transport failures. Use a new ref_id only when the user wants a new order. + +Parameter rules: +- If the user has not specified type, ask. For immediate fills with price protection, prefer a marketable limit at the current ask over a plain market. +- Outside regular hours, only limit orders execute. For an immediate fill during extended or overnight/24-hour sessions, place a limit order (a marketable limit at the current ask) with market_hours set to that session — not a market order. Market and stop orders are regular_hours-only; placed after hours as regular_hours they queue for the next regular open. +- Provide exactly one of quantity or dollar_amount; dollar_amount requires type=market (server computes shares from last_trade_price). +- Fractional shares: only on type=market with market_hours=regular_hours, eligible accounts, up to 6 decimal places, no short sells. +- limit_price required for limit/stop_limit; stop_price required for stop_market/stop_limit. +- Fractional and dollar-based orders only place in regular_hours; the tool rejects them in other sessions. +- tax_lots (specified-lot selling, sell only): to sell specific lots, first call get_equity_tax_lots for the symbol, then pass tax_lots as {open_lot_id, quantity} pairs whose quantities sum to the order quantity. Omit for default (FIFO) cost basis. US accounts only; not allowed with dollar_amount, stop orders, all_day_hours, or fractional limit orders. REAL-MONEY ACTION: use only after the user explicitly authorizes the exact account, instrument, side, size, order type, price constraints, and timing. Use the dedicated Agentic account and reuse one ref_id for retries. After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true; non-agentic accounts are rejected."},symbol:{type:"string",description:"Stock symbol."},side:{type:"string",description:"'buy' or 'sell'."},type:{type:"string",description:"'market', 'limit', 'stop_market', or 'stop_limit'."},quantity:{type:"string",description:"Number of shares. Decimals (fractional) allowed for market + regular_hours only."},dollar_amount:{type:"string",description:"USD notional (e.g. '100.00'). Only valid with type=market."},limit_price:{type:"string",description:"Limit price; required for limit or stop_limit."},stop_price:{type:"string",description:"Stop trigger price; required for stop_market or stop_limit."},time_in_force:{type:"string",description:"'gfd' or 'gtc'. Default: gfd."},market_hours:{type:"string",description:"'regular_hours' (default, 9:30–16:00 ET), 'extended_hours' (pre-/post-market), or 'all_day_hours' (the 24 Hour Market / overnight session). extended_hours and all_day_hours execute limit orders only — market, stop_market, and stop_limit are regular_hours-only and are rejected if tagged to another session."},tax_lots:{type:["null","array"],items:{type:"object",properties:{open_lot_id:{type:"string",description:"open_lot_id of the open tax lot to sell, from get_equity_tax_lots."},quantity:{type:"string",description:"Shares to sell from this lot as a decimal string; at most the lot's quantity_available."}},required:["open_lot_id","quantity"],additionalProperties:!1},description:"Optional specified-lot selection for a SELL order. To sell specific tax lots instead of the default FIFO cost basis, pass the exact lots as {open_lot_id, quantity} objects, where open_lot_id comes from get_equity_tax_lots and the quantities sum to the order quantity. Omit for default FIFO. Sell only; at most 30 lots; US accounts only. Not allowed with dollar_amount, stop_market/stop_limit, all_day_hours, or fractional-share limit orders."},ref_id:{type:"string",description:"Idempotency key (UUID). Generate once per logical order and re-send on retry — the upstream deduplicates by ref_id. Omitting falls back to a server-generated key (loses client↔gateway idempotency)."}},required:["account_number","symbol","side","type"],additionalProperties:!1}},{name:"place_option_order",namespace:"option_trading",description:`Place a real options order with real money. + +Workflow: by default call review_option_order first, present the alerts, fees, collateral, and quote, and get explicit user confirmation before calling this tool. Skip review only when the user has very explicitly asked to bypass it (e.g. "skip the review", "just place it, don't review") — a generic "place this order" is NOT a bypass. + +Capability: single-leg options orders — Level 2 strategies (covered calls, cash-secured puts, long calls and puts). Multi-leg spreads (Level 3 strategies) are supported on option_level_3 accounts. + +Account requirements: confirm via get_accounts that the chosen account is agentic_allowed=true AND has option_level_2 or option_level_3. If agentic_allowed=false do NOT call. If option_level is empty or option_level_0, do NOT call; follow the get_accounts guide for how to direct the user to enroll. + +Alert handling: pre-trade alerts surface only in review_option_order. After the user has acknowledged the reviewed alert, call this tool with the same parameters. + +Idempotency: pass a fresh UUID as ref_id on the first call for each logical order, and re-send the SAME ref_id on retries of transient transport failures. Use a new ref_id only when the user wants a new order. + +To find option_id: get_option_chains → get_option_instruments filtered by expiration_date/strike_price/type. + +Parameter rules: +- Multi-leg leg layouts — vertical spread: two legs, same expiration, different strikes, opposite sides. Calendar: two legs, same strike, different expirations. Iron condor: four legs, a put spread plus a call spread. Roll: close the leg you hold (position_effect 'close', side opposite the position) plus open the replacement ('open'). +- Get the net price from the user rather than inferring it from individual leg quotes. +- Multi-leg is not available on cash or retirement accounts through this tool. +- type: 'limit' (default), 'market', 'stop_limit', 'stop_market'. price for limit/stop_limit; stop_price for stop_market/stop_limit. +- market, stop_market, and stop_limit are single-leg only. market and stop_market are also regular_hours, GFD only. stop_market is sell-to-close only with stop_price below the current ask. + +Not currently supported anywhere (including the Robinhood apps): +- combo orders. At Robinhood, "combo" specifically means a stock-option combo: one option leg paired with 100 shares of the underlying equity. In broader industry use, "combo" without qualifier sometimes refers to multi-leg option structures. REAL-MONEY ACTION: use only after the user explicitly authorizes the exact account, instrument, side, size, order type, price constraints, and timing. Use the dedicated Agentic account and reuse one ref_id for retries. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true."},legs:{type:["null","array"],items:{type:"object",properties:{option_id:{type:"string",description:"Option instrument UUID (from get_option_instruments)."},side:{type:"string",description:"'buy' or 'sell'."},position_effect:{type:"string",description:"'open' (new position) or 'close' (existing position). To close a long use sell; to close a short use buy."},ratio_quantity:{type:"integer",description:"Contracts for this leg per unit of the order's quantity. Defaults to 1, which is what standard spreads, condors, calendars, and rolls use. Must be 1 on a single-leg order; across legs the ratios must be in lowest terms (1:2, not 2:4)."}},required:["option_id","side","position_effect"],additionalProperties:!1},description:"1 to 4 legs, all on the same underlying and each a different contract. Several legs are filled together as one strategy. Should match the legs the user reviewed."},direction:{type:"string",description:"Net direction of the whole order: 'debit' (you pay the net premium) or 'credit' (you receive it). Required with 2 or more legs; for one leg it is derived from that leg's side, so omit it."},type:{type:"string",description:"'limit' (default), 'market', 'stop_limit', or 'stop_market'. Should match the type the user reviewed. Only 'limit' is available with 2 or more legs."},quantity:{type:"string",description:"Positive integer contract count. With several legs it counts whole strategies — each leg fills quantity × its ratio_quantity contracts."},price:{type:"string",description:"Limit price. Per contract for one leg; with several legs it is the net premium of the whole strategy per unit of quantity, always positive — direction says whether it is paid or received. Required for limit/stop_limit; must be omitted for market/stop_market."},stop_price:{type:"string",description:"Stop trigger price per contract. Required for stop_limit/stop_market; must be omitted for limit/market."},time_in_force:{type:"string",description:"'gfd' (default) or 'gtc'. Market orders must be 'gfd'."},market_hours:{type:"string",description:"'regular_hours' (default), 'regular_curb_hours', or 'regular_curb_overnight_hours'. Non-limit-immediate orders only place in regular_hours. CURB requires an index chain with extended_hours_state='enabled'."},ref_id:{type:"string",description:"Idempotency key (UUID). Generate once per logical order and re-send on retry. Omitting falls back to a server-generated key."}},required:["account_number","legs","quantity"],additionalProperties:!1}},{name:"remove_from_watchlist",namespace:"watchlists",description:"Remove items from a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes) is required — mutually exclusive. For options use remove_option_from_watchlist. Items not on the list are no-ops (not errors). Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to remove items from."},symbols:{type:["null","array"],items:{type:"string"},description:"Stock symbols to remove (e.g. ['AAPL']). Mutually exclusive with currency_pair_ids and index_ids."},currency_pair_ids:{type:["null","array"],items:{type:"string"},description:"Currency-pair UUIDs to remove. Mutually exclusive with symbols and index_ids."},index_ids:{type:["null","array"],items:{type:"string"},description:"Index UUIDs to remove. Mutually exclusive with symbols and currency_pair_ids."}},required:["list_id"],additionalProperties:!1}},{name:"remove_option_from_watchlist",namespace:"option_market_data",description:`Remove option contracts from the user's options watchlist. Specify the same position_type used when the contract was added (defaults to "long"). Contracts not on the list are no-ops. Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{option_ids:{type:["null","array"],items:{type:"string"},description:'Option contract UUIDs to remove. The position_type must match how each contract was added (most likely "long").'},position_type:{type:"string",description:'"long" (default) or "short". Must match how the contract was originally added.'}},required:["option_ids"],additionalProperties:!1}},{name:"review_equity_order",namespace:"equity_trading",description:`Simulate a stock order without placing it. Returns the current quote plus pre-trade alerts (buying power, PDT, instrument halt, etc.). Call this by default before place_equity_order unless the user has very explicitly asked to skip review. Requires an agentic_allowed=true account; non-agentic accounts are rejected — do not call. + +Parameter rules: +- If the user has not specified type, ask. For immediate fills with price protection, prefer a marketable limit at the current ask over a plain market. +- Outside regular hours, only limit orders execute. For an immediate fill during extended or overnight/24-hour sessions, place a limit order (a marketable limit at the current ask) with market_hours set to that session — not a market order. Market and stop orders are regular_hours-only; placed after hours as regular_hours they queue for the next regular open. +- Provide exactly one of quantity or dollar_amount; dollar_amount requires type=market (server computes shares from last_trade_price). +- Fractional shares: only on type=market with market_hours=regular_hours, eligible accounts, up to 6 decimal places, no short sells. +- limit_price required for limit/stop_limit; stop_price required for stop_market/stop_limit. +- Fractional and dollar-based orders only place in regular_hours; the tool rejects them in other sessions. +- tax_lots (specified-lot selling, sell only): to sell specific lots, first call get_equity_tax_lots for the symbol, then pass tax_lots as {open_lot_id, quantity} pairs whose quantities sum to the order quantity. Omit for default (FIFO) cost basis. US accounts only; not allowed with dollar_amount, stop orders, all_day_hours, or fractional limit orders. This is a non-submitting pre-trade simulation. Review warnings and estimated cost before asking for authorization to use the corresponding place tool. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true; non-agentic accounts are rejected."},symbol:{type:"string",description:"Stock symbol."},side:{type:"string",description:"'buy' or 'sell'."},type:{type:"string",description:"'market', 'limit', 'stop_market', or 'stop_limit'."},quantity:{type:"string",description:"Number of shares. Decimals (fractional) allowed for market + regular_hours only."},dollar_amount:{type:"string",description:"USD notional (e.g. '100.00'). Only valid with type=market."},limit_price:{type:"string",description:"Limit price; required for limit or stop_limit."},stop_price:{type:"string",description:"Stop trigger price; required for stop_market or stop_limit."},time_in_force:{type:"string",description:"'gfd' (good for day) or 'gtc' (good till cancelled). Default: gfd."},market_hours:{type:"string",description:"'regular_hours' (default, 9:30–16:00 ET), 'extended_hours' (pre-/post-market), or 'all_day_hours' (the 24 Hour Market / overnight session). extended_hours and all_day_hours execute limit orders only — market, stop_market, and stop_limit are regular_hours-only and are rejected if tagged to another session."},tax_lots:{type:["null","array"],items:{type:"object",properties:{open_lot_id:{type:"string",description:"open_lot_id of the open tax lot to sell, from get_equity_tax_lots."},quantity:{type:"string",description:"Shares to sell from this lot as a decimal string; at most the lot's quantity_available."}},required:["open_lot_id","quantity"],additionalProperties:!1},description:"Optional specified-lot selection for a SELL order. To sell specific tax lots instead of the default FIFO cost basis, pass the exact lots as {open_lot_id, quantity} objects, where open_lot_id comes from get_equity_tax_lots and the quantities sum to the order quantity. Omit for default FIFO. Sell only; at most 30 lots; US accounts only. Not allowed with dollar_amount, stop_market/stop_limit, all_day_hours, or fractional-share limit orders."}},required:["account_number","symbol","side","type"],additionalProperties:!1}},{name:"review_option_order",namespace:"option_trading",description:`Simulate an options order without placing it. Returns the current quote plus pre-trade alerts. Call this by default before place_option_order or replace_option_order unless the user has very explicitly asked to skip review. + +Capability: single-leg options orders — Level 2 strategies (covered calls, cash-secured puts, long calls and puts). Multi-leg spreads (Level 3 strategies) are supported on option_level_3 accounts. + +Account requirements: confirm via get_accounts that the chosen account is agentic_allowed=true AND has option_level_2 or option_level_3. If agentic_allowed=false do NOT call. If option_level is empty or option_level_0, do NOT call; follow the get_accounts guide for how to direct the user to enroll. + +Parameter rules: +- legs: option_id (from get_option_instruments), side, position_effect, optional ratio_quantity per leg. +- Multi-leg leg layouts — vertical spread: two legs, same expiration, different strikes, opposite sides. Calendar: two legs, same strike, different expirations. Iron condor: four legs, a put spread plus a call spread. Roll: close the leg you hold (position_effect 'close', side opposite the position) plus open the replacement ('open'). +- Get the net price from the user rather than inferring it from individual leg quotes. +- Multi-leg is not available on cash or retirement accounts through this tool. +- type: 'limit' (default), 'market', 'stop_limit', 'stop_market'. If unspecified, ask. price for limit/stop_limit; stop_price for stop_market/stop_limit. +- market, stop_market, and stop_limit are single-leg only. market and stop_market are also GFD, regular_hours only. stop_market is sell-to-close only with stop_price below the current ask. Non-limit-immediate types are blocked in any extended-hours session. +- Surface order_checks alerts verbatim — the detail strings carry the actual time/contract/BP values for the user. This is a non-submitting pre-trade simulation. Review warnings and estimated cost before asking for authorization to use the corresponding place tool. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true."},legs:{type:["null","array"],items:{type:"object",properties:{option_id:{type:"string",description:"Option instrument UUID (from get_option_instruments)."},side:{type:"string",description:"'buy' or 'sell'."},position_effect:{type:"string",description:"'open' (new position) or 'close' (existing position). To close a long use sell; to close a short use buy."},ratio_quantity:{type:"integer",description:"Contracts for this leg per unit of the order's quantity. Defaults to 1, which is what standard spreads, condors, calendars, and rolls use. Must be 1 on a single-leg order; across legs the ratios must be in lowest terms (1:2, not 2:4)."}},required:["option_id","side","position_effect"],additionalProperties:!1},description:"1 to 4 legs, all on the same underlying and each a different contract. Several legs are filled together as one strategy."},direction:{type:"string",description:"Net direction of the whole order: 'debit' (you pay the net premium) or 'credit' (you receive it). Required with 2 or more legs; for one leg it is derived from that leg's side, so omit it."},type:{type:"string",description:"'limit' (default), 'market', 'stop_limit', or 'stop_market'. Only 'limit' is available with 2 or more legs."},quantity:{type:"string",description:"Positive integer contract count. With several legs it counts whole strategies — each leg fills quantity × its ratio_quantity contracts."},price:{type:"string",description:"Limit price (e.g. '1.50'). Per contract for one leg; with several legs it is the net premium of the whole strategy per unit of quantity, always positive — direction says whether it is paid or received. Required for limit/stop_limit; must be omitted for market/stop_market."},stop_price:{type:"string",description:"Stop trigger price per contract. Required for stop_limit/stop_market; must be omitted for limit/market. For sell-side stop_market, must be below the current ask."},time_in_force:{type:"string",description:"'gfd' (default) or 'gtc'. Market orders must be 'gfd'."},market_hours:{type:"string",description:"'regular_hours' (default), 'regular_curb_hours', or 'regular_curb_overnight_hours'. Extended-hours sessions only accept limit+immediate. CURB requires an index chain with extended_hours_state='enabled' (per get_option_chains); rejection surfaces at place time."},chain_symbol:{type:"string",description:"Underlying ticker (e.g. 'AAPL', 'SPXW'). Supply alongside underlying_type to include fees and collateral in the response — always do so when known."},underlying_type:{type:"string",description:"'equity' or 'index'. Required alongside chain_symbol to enable the fee + collateral fetch."}},required:["account_number","legs","quantity"],additionalProperties:!1}},{name:"run_scan",namespace:"scanners",description:`Execute a saved scanner (also called screener) and return live market results. A scan's filters are evaluated against current market data at request time — results are real-time, not cached. + +Returns the scan's title, the total number of matching instruments, a list of instrument rows (with ticker, instrument_id, type, and one cell per visible column), plus the active sort and filters. The agent should present results as a table and mention this is live data. + +Parameters: +- scan_id (required) — the scan identifier from get_scans or create_scan. Returns an error if the scan does not exist or does not belong to the calling user. + +Use get_scans first to discover available scan_ids if the user has not specified one. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan identifier to execute. Get this from get_scans or create_scan."}},required:["scan_id"],additionalProperties:!1}},{name:"search",namespace:"equity_market_data",description:'Resolve a natural-language query to Robinhood instruments (stocks/ETFs), crypto pairs, or market indexes. Use when the user names an asset by name (or partial name) instead of a ticker/pair/index symbol, or when you need an instrument_id / currency-pair UUID / market-index id for a downstream tool. Defaults to instrument search; pass asset_type="currency_pair" for crypto or asset_type="market_index" for indexes (SPX, NDX, DJI, etc.). Instrument results carry symbol + instrument_id (use with get_equity_quotes / get_equity_tradability / place_equity_order or any instrument_id-based tool). Crypto results carry hyphenated symbol (e.g. BTC-USD) + id — the symbol routes to crypto quote/order tools, the id routes to watchlist tools as currency_pair_ids. Market-index results carry symbol + id — pass id to index quote tools for current values, or in the index_ids array of watchlist tools. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.',inputSchema:{type:"object",properties:{query:{type:"string",description:'Natural-language search query: company name, partial name, or ticker (e.g. "apple", "tesla motors", "AAPL"). Required.'},asset_type:{type:"string",description:'Asset category to search. Supported: "instrument" (US-listed stocks/ETFs), "currency_pair" (crypto pairs like BTC-USD), and "market_index" (e.g. SPX, NDX, DJI). Defaults to "instrument" when omitted. More categories (events, futures) will be added as their corresponding tools land.'},limit:{type:"integer",description:"Max results to return. Defaults to 10; clamped to 20."}},required:["query"],additionalProperties:!1}},{name:"unfollow_watchlist",namespace:"watchlists",description:"Stop following a Robinhood-curated list. The list itself is unchanged — it just no longer appears in the user's watchlists. Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the Robinhood-curated list to unfollow."}},required:["list_id"],additionalProperties:!1}},{name:"update_scan_config",namespace:"scanners",description:`Change the sort order of a saved scan's results table. The scan's filters and columns are preserved; only the sort changes. + +Parameters: +- scan_id (required) — the scan to modify. +- sorting_column (required) — display name of the column to sort by. Must match a visible column on the scan; the error response lists available columns when no match is found. +- sorting_direction (required) — "asc" or "desc". + +Restrictions: +- Cortex-managed scans (cortex_managed: true in get_scans) are rejected. +- v1 supports only sort changes — column add/remove/visibility/reorder are not exposed by this tool. + +Returns the scan with the new sort applied and fresh live results in the new order. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan to modify. Get this from get_scans or create_scan. Cortex-managed scans are rejected."},sorting_column:{type:"string",description:'Display name of the column to sort by (e.g. "Volume", "% Change", "RSI"). Must match a column currently visible on the scan — call get_scans / run_scan first to see available columns.'},sorting_direction:{type:"string",description:'"asc" or "desc" (ascending or descending).'}},required:["scan_id","sorting_column","sorting_direction"],additionalProperties:!1}},{name:"update_scan_filters",namespace:"scanners",description:`Replace the filters on an existing saved scan. The complete filter set provided replaces whatever filters the scan had — this is REPLACE semantics, not merge. To add a single filter to an existing scan, the agent must first read the scan (via get_scans or run_scan), then call this tool with all the existing filters plus the new one. + +Parameters: +- scan_id (required) — the scan to modify. Get from get_scans or create_scan. +- filters (required) — the complete new filter set. Send [] to clear all filters. Each filter has filter_type (FILTER_TYPE_... enum), predicate, values, optional interval/length. Call get_scanner_filter_specs for valid combinations. + +Restrictions: +- Cortex-managed scans (cortex_managed: true in get_scans) are rejected with a user-friendly error. +- Returns an error and does not apply any change if any filter fails validation. + +Returns the scan with its new filters and fresh live results. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan to modify. Get this from get_scans or create_scan. Cortex-managed scans (cortex_managed: true in get_scans output) are rejected."},filters:{type:["null","array"],items:{type:"object",properties:{filter_type:{type:"string",description:'Wire-format enum name, e.g. "FILTER_TYPE_RSI". See the scanner-filter-specs resource for valid values. Omit when supplying expression.'},predicate:{type:"string",description:'Wire-format enum name, e.g. "PREDICATE_GREATER_THAN". See the scanner-filter-specs resource for the predicates supported by each filter.'},values:{type:["null","array"],items:{type:"string"},description:'Threshold values. Single-element for unary predicates, two-element for BETWEEN, multi-element for IN_LIST/ANY_OF. For a boolean expression screen, exactly ["True"].'},interval:{type:"string",description:`Time granularity for time-series filters (e.g. "1d"). Use one of the supported_intervals from the filter's scanner-filter-specs entry. Not used with expression — encode granularity inside the expression.`},length:{type:"integer",description:"Lookback length for filters that need one (e.g. RSI period of 14). Use one of the supported_lengths from the filter's scanner-filter-specs entry. Not used with expression.",minimum:-2147483648,maximum:2147483647},plot:{type:"string",description:`Plot / price-field input for filters that have one (e.g. "open" or "close" for % Change). Use one of the supported_plots from the filter's scanner-filter-specs entry. Not used with expression.`},expression:{type:"string",description:'Raw market-data expression to screen on, e.g. "dayVolume / volumeAvg(candleCount=30, candlePeriod=\\"1d\\", session=\\"all\\")" with a numeric predicate, or a whole comparison like "tradeAllDay.price > closeAvg(candleCount=50, candlePeriod=\\"1d\\", session=\\"all\\")" with predicate "=" and values ["True"]. Only preview_scan accepts expressions. Omit filter_type when set. Prefer an enum filter_type whenever one covers the request.'},display_title:{type:"string",description:'Optional short label for an expression filter, shown as the results-column header (e.g. "Relative volume (30D)"). Only used with expression.'}},required:["predicate","values"],additionalProperties:!1},description:"The complete set of filters the scan should have after the update. REPLACE semantics — to add a filter, supply all existing filters plus the new one. To remove a filter, omit it from the array. To clear all filters, send []. Each filter: filter_type (FILTER_TYPE_... enum), predicate (>, <, =, BETWEEN, etc.), values, optional interval (e.g. 1d), optional length (e.g. 14 for RSI). Call get_scanner_filter_specs first for valid filter_type / predicate / interval / length combinations."}},required:["scan_id","filters"],additionalProperties:!1}},{name:"update_watchlist",namespace:"watchlists",description:"Rename a custom watchlist or change its icon/description. Robinhood-curated lists cannot be renamed; the call will fail with 404. Provide at least one of display_name, icon_emoji, display_description. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to update. Obtain from get_watchlists."},display_name:{type:"string",description:"New name for the watchlist."},icon_emoji:{type:"string",description:"New emoji."},display_description:{type:"string",description:"New description."}},required:["list_id"],additionalProperties:!1}}]};var k=globalThis.db,x=k.open("robinhood");if(x<0)throw Error("open robinhood.sqlite");var L=5;function M(){return String(k.lastError(x)||"SQLite operation failed")}function w(e){if(k.exec(x,e)!==0)throw Error(M())}function T(e,t=[]){let i=JSON.parse(k.query(x,e,JSON.stringify(t)));if(i.error)throw Error(String(i.error));return i}function h(e,t=[]){return T(e,t)}var N=T("PRAGMA user_version");if(Number(N?.user_version??0)!==L)w(` CREATE TABLE IF NOT EXISTS accounts ( account_number TEXT PRIMARY KEY, label TEXT NOT NULL, @@ -56,56 +224,27 @@ error TEXT ); CREATE INDEX IF NOT EXISTS refresh_runs_recent ON refresh_runs(id DESC); - CREATE TABLE IF NOT EXISTS equity_historicals ( - account_number TEXT NOT NULL, - span TEXT NOT NULL, - point_time TEXT NOT NULL, - price TEXT, - open TEXT, - high TEXT, - low TEXT, - close TEXT, - volume TEXT, - observed_at INTEGER NOT NULL, - PRIMARY KEY(account_number, span, point_time) - ); - CREATE TABLE IF NOT EXISTS pnl_trades ( - account_number TEXT NOT NULL, - trade_id TEXT NOT NULL, - occurred_at TEXT, - symbol TEXT, - side TEXT, - quantity TEXT, - price TEXT, - realized_pnl TEXT, - observed_at INTEGER NOT NULL, - PRIMARY KEY(account_number, trade_id) - ); - CREATE TABLE IF NOT EXISTS order_reviews ( - review_id TEXT PRIMARY KEY, - account_number TEXT, - symbol TEXT, - side TEXT, - quantity TEXT, - limit_price TEXT, - estimated_cost TEXT, - state TEXT, - observed_at INTEGER NOT NULL - ); - PRAGMA user_version=4; - `);function y(){return Math.floor(Date.now()/1000)}function h(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function i(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let o of t){let r=h(e[o]);if(r!==null)return r}for(let o of Object.values(e)){let r=i(o,t);if(r!==null)return r}return null}function I(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let o of t)if(Array.isArray(e[o]))return e[o];for(let o of Object.values(e)){let r=I(o,t);if(r.length)return r}return[]}function P(e,t){let o=i(e,t)?.toLowerCase();return o==="true"||o==="1"||o==="yes"}function L(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function d(e,t){return i(e,["account_number","accountNumber","account"])||String(t?.account_number??t?.accountNumber??"")}function N(e,t){let o=I(e,t);return o.length?o:Array.isArray(e)?e:e?[e]:[]}function S(e,t){let o=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t})));if(!o.ok)throw Error(o.error||"Robinhood service failed");return o.value}function M(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((o)=>({name:o.operation,arguments:o.args}))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function A(e){g("BEGIN IMMEDIATE");try{e(),g("COMMIT")}catch(t){try{g("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function D(e,t){let o=N(e,["accounts"]);l("DELETE FROM accounts");for(let r of o){let a=d(r,{});if(!a)continue;let n=(i(r,["nickname","account_type","type"])||"").toUpperCase(),c=P(r,["agentic_allowed","agenticAllowed"]),s=c?"AGENTIC":n.includes("IRA")||n.includes("RETIRE")?"RETIREMENT":n.includes("JOINT")?"JOINT":"PERSONAL";l("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at) VALUES(?,?,?,?,?,?,?)",[a,s,a.slice(-4),n,(i(r,["status"])||"active").toUpperCase(),c?1:0,t])}}function x(e,t,o){let r=d(e,t);if(!r)throw Error("Robinhood portfolio is missing account_number");let a=i(e,["cash","cash_available","withdrawable_amount"]),n=i(e,["buying_power","buyingPower"]),c=i(e,["day_pnl","dayPnl","equity_change"]),s=i(e,["week_pnl","weekPnl"]);l(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) + PRAGMA user_version=5; + `);var A=b.tools,V=new Map(A.map((e)=>[e.name,e]));function _(){return Math.floor(Date.now()/1000)}function F(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function n(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let i of t){let r=F(e[i]);if(r!==null)return r}for(let i of Object.values(e)){let r=n(i,t);if(r!==null)return r}return null}function O(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let i of t)if(Array.isArray(e[i]))return e[i];for(let i of Object.values(e)){let r=O(i,t);if(r.length)return r}return[]}function Y(e,t){let i=n(e,t)?.toLowerCase();return i==="true"||i==="1"||i==="yes"}function U(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function g(e,t){let i=t?.account_number??t?.accountNumber;return i===null||i===void 0||i===""?n(e,["account_number","accountNumber","account"])||"":String(i)}function q(e,t){let i=O(e,t);return i.length?i:Array.isArray(e)?e:e?[e]:[]}function z(e){let t=Array.isArray(e?.names)?new Set(e.names.filter((s)=>typeof s==="string")):new Set,i=String(e?.query??"").toLowerCase().split(/[^a-z0-9_]+/).filter(Boolean),r=typeof e?.namespace==="string"?e.namespace:"";if(!t.size&&!i.length)throw Error("search_tools requires query or names");let c=Math.max(1,Math.min(8,Number(e?.limit??5)||5)),o=A.filter((s)=>!r||s.namespace===r).map((s)=>{let a=s.name.toLowerCase(),p=a+" "+s.description.toLowerCase(),d=t.has(s.name)?1000:i.reduce((m,l)=>m+(a===l?100:a.includes(l)?20:p.includes(l)?3:0),0);return{tool:s,score:d}}).filter((s)=>s.score>0).sort((s,a)=>a.score-s.score||s.tool.name.localeCompare(a.tool.name)).slice(0,c).map(({tool:s})=>({name:s.name,namespace:s.namespace,description:s.description,inputSchema:s.inputSchema}));return{source:b.source,protocolVersion:b.protocolVersion,matches:o}}function G(e,t){if(t==="null")return e===null;if(t==="array")return Array.isArray(e);if(t==="object")return e!==null&&typeof e==="object"&&!Array.isArray(e);if(t==="integer")return typeof e==="number"&&Number.isInteger(e);if(t==="number")return typeof e==="number"&&Number.isFinite(e);return typeof e===t}function v(e,t,i="arguments"){let r=Array.isArray(t?.type)?t.type:t?.type?[t.type]:[];if(r.length&&!r.some((o)=>G(e,o)))throw Error(i+" must be "+r.join(" or "));if(e===null)return;if(typeof e==="number"){if(typeof t.minimum==="number"&&et.maximum)throw Error(i+" exceeds maximum "+t.maximum)}if(Array.isArray(e)){if(t.items)e.forEach((o,s)=>v(o,t.items,i+"["+s+"]"));return}if(typeof e!=="object")return;let c=t.properties||{};for(let o of t.required||[])if(!(o in e))throw Error(i+"."+o+" is required");if(t.additionalProperties===!1){for(let o of Object.keys(e))if(!(o in c))throw Error(i+"."+o+" is not allowed")}for(let[o,s]of Object.entries(e))if(c[o])v(s,c[o],i+"."+o)}function B(e){let t=typeof e?.name==="string"?e.name:"",i=V.get(t);if(!i)throw Error("Unknown Robinhood provider Tool: "+t);let r=e?.arguments;return v(r,i.inputSchema),ee(t,r)}function D(e,t){let i=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t})));if(!i.ok)throw Error(i.error||"Robinhood service failed");return i.value}function W(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((i)=>({name:i.operation,arguments:i.args}))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function I(e){w("BEGIN IMMEDIATE");try{e(),w("COMMIT")}catch(t){try{w("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function H(e,t){let i=q(e,["accounts"]);h("DELETE FROM accounts");for(let r of i){let c=g(r,{});if(!c)continue;let o=(n(r,["nickname","account_type","type"])||"").toUpperCase(),s=Y(r,["agentic_allowed","agenticAllowed"]),a=s?"AGENTIC":o.includes("IRA")||o.includes("RETIRE")?"RETIREMENT":o.includes("JOINT")?"JOINT":"PERSONAL";h("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at) VALUES(?,?,?,?,?,?,?)",[c,a,c.slice(-4),o,(n(r,["status"])||"active").toUpperCase(),s?1:0,t])}}function X(e,t,i){let r=g(e,t);if(!r)throw Error("Robinhood portfolio is missing account_number");let c=n(e,["cash","cash_available","withdrawable_amount"]),o=n(e,["buying_power","buyingPower"]),s=n(e,["day_pnl","dayPnl","equity_change"]),a=n(e,["week_pnl","weekPnl"]);h(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?,?,?) ON CONFLICT(account_number) DO UPDATE SET cash=excluded.cash,buying_power=excluded.buying_power, day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), - observed_at=excluded.observed_at`,[r,a,n,c,s,o]);let u=i(e,["total_value","equity","total_equity","portfolio_value","market_value"]);if(u!==null)l("INSERT OR REPLACE INTO total_value(account_number,observed_at,value) VALUES(?,?,?)",[r,o,u])}function F(e,t,o){let r=d(e,t);if(!r)throw Error("Robinhood positions are missing account_number");let a=N(e,["positions"]).slice(0,64);l("DELETE FROM positions WHERE account_number=?",[r]);for(let n of a){let c=i(n,["symbol"]);if(!c)continue;l("INSERT INTO positions(account_number,symbol,quantity,average_price,market_value,observed_at) VALUES(?,?,?,?,?,?)",[r,c,i(n,["quantity","shares"]),i(n,["average_price","averagePrice","average_buy_price"]),i(n,["market_value","marketValue","equity"]),o])}}function G(e,t,o){let r=d(e,t);if(!r)throw Error("Robinhood activities are missing account_number");let a=N(e,["orders","activities","results"]).slice(0,64);l("DELETE FROM activities WHERE account_number=?",[r]),a.forEach((n,c)=>{let s=i(n,["symbol"]),u=(i(n,["side"])||"").toUpperCase(),_=i(n,["executed_quantity","cumulative_quantity","quantity"]),p=i(n,["average_price","averagePrice","executed_price","price"]),b=i(n,["last_transaction_at","created_at","updated_at","date"]),T=i(n,["id","order_id","orderId","activity_id"])||[b||o,s||"ORDER",u,c].join(":"),E=L(_),f=L(p),U=E!==null&&f!==null?String(E*f):p||_;l(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) - VALUES(?,?,?,?,?,?,?,?,?,?,?)`,[r,T,b,o,s,u,_,p,U,(i(n,["state","status"])||"RECENT").toUpperCase(),(i(n,["type","order_type"])||"ORDER").toUpperCase()])})}function Y(e,t,o){let r=d(e,t);if(!r)throw Error("Robinhood P&L is missing account_number");let a=i(e,["total_returns","realized_pnl","total","amount","day_pnl","week_pnl"]),n=String(t?.span??"day");l(`INSERT INTO portfolio_current(account_number,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?) + observed_at=excluded.observed_at`,[r,c,o,s,a,i]);let p=n(e,["total_value","equity","total_equity","portfolio_value","market_value"]);if(p!==null)h("INSERT OR REPLACE INTO total_value(account_number,observed_at,value) VALUES(?,?,?)",[r,i,p])}function J(e,t,i){let r=g(e,t);if(!r)throw Error("Robinhood positions are missing account_number");let c=q(e,["positions"]).slice(0,64);h("DELETE FROM positions WHERE account_number=?",[r]);for(let o of c){let s=n(o,["symbol"]);if(!s)continue;h("INSERT INTO positions(account_number,symbol,quantity,average_price,market_value,observed_at) VALUES(?,?,?,?,?,?)",[r,s,n(o,["quantity","shares"]),n(o,["average_price","averagePrice","average_buy_price"]),n(o,["market_value","marketValue","equity"]),i])}}function Z(e,t,i){let r=g(e,t);if(!r)throw Error("Robinhood activities are missing account_number");let c=q(e,["orders","activities","results"]).slice(0,64);h("DELETE FROM activities WHERE account_number=?",[r]),c.forEach((o,s)=>{let a=n(o,["symbol"]),p=(n(o,["side"])||"").toUpperCase(),d=n(o,["executed_quantity","cumulative_quantity","quantity"]),m=n(o,["average_price","averagePrice","executed_price","price"]),l=n(o,["last_transaction_at","created_at","updated_at","date"]),u=n(o,["id","order_id","orderId","activity_id"])||[l||i,a||"ORDER",p,s].join(":"),y=U(d),f=U(m),j=y!==null&&f!==null?String(y*f):m||d;h(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) + VALUES(?,?,?,?,?,?,?,?,?,?,?)`,[r,u,l,i,a,p,d,m,j,(n(o,["state","status"])||"RECENT").toUpperCase(),(n(o,["type","order_type"])||"ORDER").toUpperCase()])})}function $(e,t,i){let r=g(e,t);if(!r)throw Error("Robinhood P&L is missing account_number");let c=n(e,["total_returns","realized_pnl","total","amount","day_pnl","week_pnl"]),o=String(t?.span??"day");h(`INSERT INTO portfolio_current(account_number,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?) ON CONFLICT(account_number) DO UPDATE SET day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), - observed_at=MAX(portfolio_current.observed_at,excluded.observed_at)`,[r,n==="week"?null:a,n==="week"?a:null,o])}function J(e,t,o){let r=d(e,t),a=String(t?.span??t?.interval??"default"),n=N(e,["historicals","results","data"]);l("DELETE FROM equity_historicals WHERE account_number=? AND span=?",[r,a]),n.forEach((c,s)=>{let u=i(c,["begins_at","timestamp","time","date"])||String(s);l(`INSERT INTO equity_historicals(account_number,span,point_time,price,open,high,low,close,volume,observed_at) - VALUES(?,?,?,?,?,?,?,?,?,?)`,[r,a,u,i(c,["price","adjusted_close","close_price"]),i(c,["open_price","open"]),i(c,["high_price","high"]),i(c,["low_price","low"]),i(c,["close_price","close"]),i(c,["volume"]),o])})}function V(e,t,o){let r=d(e,t),a=N(e,["trades","results","data"]);l("DELETE FROM pnl_trades WHERE account_number=?",[r]),a.forEach((n,c)=>{let s=i(n,["created_at","updated_at","date","timestamp"]),u=i(n,["id","trade_id","tradeId"])||[s||o,i(n,["symbol"])||"TRADE",c].join(":");l(`INSERT INTO pnl_trades(account_number,trade_id,occurred_at,symbol,side,quantity,price,realized_pnl,observed_at) - VALUES(?,?,?,?,?,?,?,?,?)`,[r,u,s,i(n,["symbol"]),(i(n,["side"])||"").toUpperCase(),i(n,["quantity","shares"]),i(n,["price","average_price"]),i(n,["realized_pnl","pnl","amount"]),o])})}function B(e,t,o){let r=d(e,t),a=i(e,["symbol"])||h(t?.symbol),n=(i(e,["side"])||h(t?.side)||"").toUpperCase(),c=i(e,["quantity","shares"])||h(t?.quantity),s=i(e,["limit_price","limitPrice","price"])||h(t?.limit_price??t?.price),u=i(e,["id","review_id","reviewId"])||[r,a,n,c,s,o].join(":");l(`INSERT OR REPLACE INTO order_reviews(review_id,account_number,symbol,side,quantity,limit_price,estimated_cost,state,observed_at) - VALUES(?,?,?,?,?,?,?,?,?)`,[u,r,a,n,c,s,i(e,["estimated_cost","estimatedCost","total"]),i(e,["state","status"]),o])}function X(e){if(e.operation==="get_accounts")D(e.value,e.observedAt);else if(e.operation==="get_portfolio")x(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_positions")F(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_orders")G(e.value,e.args,e.observedAt);else if(e.operation==="get_realized_pnl")Y(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_historicals")J(e.value,e.args,e.observedAt);else if(e.operation==="get_pnl_trade_history")V(e.value,e.args,e.observedAt);else if(e.operation==="review_equity_order")B(e.value,e.args,e.observedAt);else throw Error("No Robinhood table mapping for "+e.operation)}function z(e){let t=e.toLowerCase();return t.includes("esp_err_http_connect")||t.includes("timeout")||t.includes("tls")||t.includes("socket")||t.includes("network")}function O(){let e=y(),t=[],o=[],r=0,a=(s,u)=>{r+=1;try{let _=S(s,u);return t.push({operation:s,args:u,value:_,observedAt:y()}),_}catch(_){let p=_ instanceof Error?_.message:String(_);if(o.push(s+": "+p),s==="get_accounts"||z(p))throw _;return null}},n=null;try{let s=a("get_accounts",{}),_=N(s,["accounts"]).map((T)=>d(T,{})).filter(Boolean);if(!_.length)throw Error("Robinhood returned no brokerage accounts");let p=new Date((e-604800)*1000).toISOString().slice(0,10),b=[];for(let T of _){let E={account_number:T};b.push({operation:"get_portfolio",args:E},{operation:"get_equity_positions",args:E},{operation:"get_equity_orders",args:{...E,created_at_gte:p}},{operation:"get_realized_pnl",args:{...E,span:"day",asset_classes:["equity"]}},{operation:"get_realized_pnl",args:{...E,span:"week",asset_classes:["equity"]}})}r+=b.length;let w=M(b);if(w.length!==b.length)throw Error("Robinhood batch returned an incomplete result set");if(w.forEach((T,E)=>{let f=b[E];if(T?.ok)t.push({operation:f.operation,args:f.args,value:T.value,observedAt:y()});else o.push(f.operation+": "+String(T?.error||"unknown provider error"))}),!t.some((T)=>T.operation==="get_portfolio"))throw Error("Robinhood batch returned no portfolio data")}catch(s){n=s instanceof Error?s.message:String(s)}let c=n?"failed":o.length?"partial":"succeeded";if(A(()=>{if(!n)for(let s of t)X(s);l(`INSERT INTO refresh_runs(started_at,completed_at,status,operation_count,success_count,error) - VALUES(?,?,?,?,?,?)`,[e,y(),c,r,n?0:t.length,n||o.join(" | ")||null])}),n)throw Error(n);return{status:c,operationCount:r,successCount:t.length}}var j={"robinhood.get_accounts":"get_accounts","robinhood.get_portfolio":"get_portfolio","robinhood.get_equity_positions":"get_equity_positions","robinhood.get_equity_orders":"get_equity_orders","robinhood.get_equity_historicals":"get_equity_historicals","robinhood.get_realized_pnl":"get_realized_pnl","robinhood.get_pnl_trade_history":"get_pnl_trade_history","robinhood.review_equity_order":"review_equity_order"};function K(e,t){let o=j[e];if(!o)throw Error("Unknown Robinhood tool: "+e);let r=S(o,t);return A(()=>X({operation:o,args:t,value:r,observedAt:y()})),r}globalThis.PocketPiData={invokeTask(e){try{if(e!=="refreshPortfolio")throw Error("Unknown Robinhood Data Action: "+e);let t=O();return JSON.stringify({text:JSON.stringify(t),details:t,isError:!1})}catch(t){return JSON.stringify({text:t instanceof Error?t.message:String(t),isError:!0})}},invokeTool(e,t){try{let o=JSON.parse(t),r=e==="robinhood.refresh_portfolio"?O():K(e,o);return JSON.stringify({text:JSON.stringify(r),details:r,isError:!1})}catch(o){return JSON.stringify({text:o instanceof Error?o.message:String(o),isError:!0})}}};})(); + observed_at=MAX(portfolio_current.observed_at,excluded.observed_at)`,[r,o==="week"?null:c,o==="week"?c:null,i])}function C(e){if(e.operation==="get_accounts")H(e.value,e.observedAt);else if(e.operation==="get_portfolio")X(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_positions")J(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_orders")Z(e.value,e.args,e.observedAt);else if(e.operation==="get_realized_pnl")$(e.value,e.args,e.observedAt);else return!1;return!0}function Q(e){let t=e.toLowerCase();return t.includes("esp_err_http_connect")||t.includes("timeout")||t.includes("tls")||t.includes("socket")||t.includes("network")}function S(){let e=_(),t=[],i=[],r=0,c=(a,p)=>{r+=1;try{let d=D(a,p);return t.push({operation:a,args:p,value:d,observedAt:_()}),d}catch(d){let m=d instanceof Error?d.message:String(d);if(i.push(a+": "+m),a==="get_accounts"||Q(m))throw d;return null}},o=null;try{let a=c("get_accounts",{}),d=q(a,["accounts"]).map((u)=>g(u,{})).filter(Boolean);if(!d.length)throw Error("Robinhood returned no brokerage accounts");let m=new Date((e-604800)*1000).toISOString().slice(0,10),l=[];for(let u of d){let y={account_number:u};l.push({operation:"get_portfolio",args:y},{operation:"get_equity_positions",args:y},{operation:"get_equity_orders",args:{...y,created_at_gte:m}},{operation:"get_realized_pnl",args:{...y,span:"day",asset_classes:["equity"]}},{operation:"get_realized_pnl",args:{...y,span:"week",asset_classes:["equity"]}})}r+=l.length;let P=W(l);if(P.length!==l.length)throw Error("Robinhood batch returned an incomplete result set");if(P.forEach((u,y)=>{let f=l[y];if(u?.ok)t.push({operation:f.operation,args:f.args,value:u.value,observedAt:_()});else i.push(f.operation+": "+String(u?.error||"unknown provider error"))}),!t.some((u)=>u.operation==="get_portfolio"))throw Error("Robinhood batch returned no portfolio data")}catch(a){o=a instanceof Error?a.message:String(a)}let s=o?"failed":i.length?"partial":"succeeded";if(I(()=>{if(!o)for(let a of t)C(a);h(`INSERT INTO refresh_runs(started_at,completed_at,status,operation_count,success_count,error) + VALUES(?,?,?,?,?,?)`,[e,_(),s,r,o?0:t.length,o||i.join(" | ")||null])}),o)throw Error(o);return{status:s,operationCount:r,successCount:t.length}}function K(e,t,i,r){let c=String(i?.account_number??i?.accountNumber??"");if(!c)return;let s=String(i?.order_id??n(t,["order_id","orderId","id"])??"")||[r,i?.symbol||"EQUITY",e].join(":"),a=e==="cancel_equity_order"?n(t,["state","status"])||"CANCEL_REQUESTED":n(t,["state","status"])||"SUBMITTED";h(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) + VALUES(?,?,?,?,?,?,?,?,?,?,?) + ON CONFLICT(account_number,activity_id) DO UPDATE SET + occurred_at=COALESCE(excluded.occurred_at,activities.occurred_at), + observed_at=excluded.observed_at, + symbol=COALESCE(excluded.symbol,activities.symbol), + side=COALESCE(excluded.side,activities.side), + quantity=COALESCE(excluded.quantity,activities.quantity), + price=COALESCE(excluded.price,activities.price), + state=excluded.state, + activity_type=excluded.activity_type`,[c,s,n(t,["created_at","updated_at","last_transaction_at"]),r,i?.symbol??n(t,["symbol"]),i?.side??n(t,["side"]),i?.quantity??i?.dollar_amount??n(t,["quantity","executed_quantity"]),i?.limit_price??i?.stop_price??n(t,["price","average_price"]),i?.dollar_amount??null,String(a).toUpperCase(),e==="cancel_equity_order"?"EQUITY ORDER CANCEL":"EQUITY ORDER"])}function ee(e,t){let i=D(e,t),r={operation:e,args:t,value:i,observedAt:_()};if(["get_accounts","get_portfolio","get_equity_positions","get_equity_orders","get_realized_pnl"].includes(e))I(()=>C(r));if(e==="place_equity_order"||e==="cancel_equity_order")I(()=>K(e,i,t,r.observedAt));return i}function R(e){return JSON.stringify({text:JSON.stringify(e),isError:!1})}globalThis.PocketPiData={invokeTask(e){try{if(e!=="refreshPortfolio")throw Error("Unknown Robinhood Data Action: "+e);let t=S();return R(t)}catch(t){return JSON.stringify({text:t instanceof Error?t.message:String(t),isError:!0})}},invokeTool(e,t){try{let i=JSON.parse(t),r=e==="robinhood.refresh_portfolio"?S():e==="robinhood.search_tools"?z(i):e==="robinhood.call"?B(i):(()=>{throw Error("Unknown Robinhood Tool: "+e)})();return R(r)}catch(i){return JSON.stringify({text:i instanceof Error?i.message:String(i),isError:!0})}}};})(); diff --git a/apps/robinhood/tool-catalog.json b/apps/robinhood/tool-catalog.json new file mode 100644 index 0000000..8bec694 --- /dev/null +++ b/apps/robinhood/tool-catalog.json @@ -0,0 +1,1849 @@ +{ + "source": "https://agent.robinhood.com/mcp/trading", + "protocolVersion": "2025-06-18", + "retrievedAt": "2026-08-10T09:05:39+00:00", + "tools": [ + { + "name": "add_option_to_watchlist", + "namespace": "option_market_data", + "description": "Add option contracts to the user's options watchlist. Works for both equity options (AAPL, NVDA) and index options (SPX, NDX, RUT). Source option_ids from get_option_instruments. Confirm with the user before calling — this is a real write. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "option_ids": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Option contract UUIDs to add. Each becomes a single-leg position on the user's options watchlist. Source from get_option_instruments." + }, + "position_type": { + "type": "string", + "description": "\"long\" (default) or \"short\". Applies to every option_id in this call. For mixed long/short adds, issue two calls." + } + }, + "required": [ + "option_ids" + ], + "additionalProperties": false + } + }, + { + "name": "add_to_watchlist", + "namespace": "watchlists", + "description": "Add items to a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes like SPX, NDX) is required — mutually exclusive. For options use add_option_to_watchlist (separate dedicated watchlist). Futures still require the Robinhood app. Already-present items are no-ops. Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "list_id": { + "type": "string", + "description": "UUID of the watchlist to add items to." + }, + "symbols": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Stock symbols to add (e.g. ['AAPL', 'NVDA']). US stocks and ETFs only. Mutually exclusive with currency_pair_ids and index_ids." + }, + "currency_pair_ids": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Currency-pair UUIDs to add (e.g. the object_id from get_watchlist_items where object_type=currency_pair, or the id from get_currency_pairs). Mutually exclusive with symbols and index_ids." + }, + "index_ids": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Market-index UUIDs to add (the id field from get_indexes; SPX, NDX, DJI, etc.). Mutually exclusive with symbols and currency_pair_ids." + } + }, + "required": [ + "list_id" + ], + "additionalProperties": false + } + }, + { + "name": "cancel_equity_order", + "namespace": "equity_trading", + "description": "Cancel an open equity order by order_id. Always confirm with the user before calling. Resolve order_id via get_equity_orders if the user refers to it by symbol or description; pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected — do not call. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. REAL ACCOUNT ACTION: use only for the exact user-authorized account and order or exercise identifier; confirm the final provider state afterward. After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account that owns the order. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true. The upstream rejects mismatches against the order's owning account." + }, + "order_id": { + "type": "string", + "description": "Order UUID from get_equity_orders. Must live in account_number." + } + }, + "required": [ + "account_number", + "order_id" + ], + "additionalProperties": false + } + }, + { + "name": "cancel_option_exercise", + "namespace": "option_trading", + "description": "Cancel all queued exercise requests for an option position. Pass the same account_number and option_id used for exercise_option. Internally looks up all queued exercise events for that option and cancels each one. Typically there is one; multiple means the user submitted separate exercise batches. Only cancels events in state=queued — events already processing are rejected by the broker. Always confirm with the user before calling. REAL ACCOUNT ACTION: use only for the exact user-authorized account and order or exercise identifier; confirm the final provider state afterward. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account that owns the exercise. Must be agentic_allowed=true." + }, + "option_id": { + "type": "string", + "description": "Option instrument UUID — the same option_id used for exercise_option. The tool looks up the queued exercise for this option and cancels it." + } + }, + "required": [ + "account_number", + "option_id" + ], + "additionalProperties": false + } + }, + { + "name": "cancel_option_order", + "namespace": "option_trading", + "description": "Cancel an open option order by account_number + order_id. Always confirm with the user before calling. Resolve order_id via get_option_orders if the user refers to it by description; pass the same account_number you used there. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. REAL ACCOUNT ACTION: use only for the exact user-authorized account and order or exercise identifier; confirm the final provider state afterward. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account that owns the order. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true. Mismatches against the order's owning account are rejected." + }, + "order_id": { + "type": "string", + "description": "Order UUID from get_option_orders. Must live in account_number." + } + }, + "required": [ + "account_number", + "order_id" + ], + "additionalProperties": false + } + }, + { + "name": "create_scan", + "namespace": "scanners", + "description": "Create a new saved scanner (screener) on the user's account, optionally applying a preset and custom filters in a single call. Returns the new scan's id, title, applied filters, and the initial live market results.\n\nThis tool composes multiple Beacon operations:\n 1. Create an empty scan\n 2. If a non-INITIAL preset was requested: apply that preset configuration (DAILY_GAINERS, DAILY_LOSERS, HIGH_OPTIONS_VOLUME_IV, UPCOMING_EARNINGS)\n 3. If custom filters were provided: apply them (replaces any preset filters)\n 4. If a custom title was provided: set the title\n\nIf any step after the initial create fails, the scan still exists with the partial state — the response surfaces what was applied. Use update_scan_filters / update_scan_config to fix anything that failed.\n\nParameters:\n- preset (optional) — starting preset. Default: DAILY_GAINERS when no filters supplied, INITIAL when filters supplied. Valid values: INITIAL, DAILY_GAINERS, DAILY_LOSERS, HIGH_OPTIONS_VOLUME_IV, UPCOMING_EARNINGS.\n- filters (optional) — array of custom filter specs. Call get_scanner_filter_specs to discover valid filter_type / predicate values.\n- title (optional) — custom human-readable name for the scan.\n\nExample: to make \"stocks with RSI > 70 and volume > 1M, sorted by volume desc\", call with\n preset = \"INITIAL\"\n filters = [\n {\"filter_type\": \"FILTER_TYPE_RSI\", \"predicate\": \">\", \"values\": [\"70\"], \"interval\": \"1d\", \"length\": 14},\n {\"filter_type\": \"FILTER_TYPE_VOLUME\", \"predicate\": \">\", \"values\": [\"1000000\"], \"interval\": \"1d\"}\n ]\n title = \"High RSI + High Volume\" This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "preset": { + "type": "string", + "description": "Starting preset for the new scan. One of: INITIAL (no preset; only valid if filters are provided), DAILY_GAINERS, DAILY_LOSERS, HIGH_OPTIONS_VOLUME_IV, UPCOMING_EARNINGS. Defaults to DAILY_GAINERS when no filters are provided, INITIAL when filters are provided." + }, + "filters": { + "type": [ + "null", + "array" + ], + "items": { + "type": "object", + "properties": { + "filter_type": { + "type": "string", + "description": "Wire-format enum name, e.g. \"FILTER_TYPE_RSI\". See the scanner-filter-specs resource for valid values. Omit when supplying expression." + }, + "predicate": { + "type": "string", + "description": "Wire-format enum name, e.g. \"PREDICATE_GREATER_THAN\". See the scanner-filter-specs resource for the predicates supported by each filter." + }, + "values": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Threshold values. Single-element for unary predicates, two-element for BETWEEN, multi-element for IN_LIST/ANY_OF. For a boolean expression screen, exactly [\"True\"]." + }, + "interval": { + "type": "string", + "description": "Time granularity for time-series filters (e.g. \"1d\"). Use one of the supported_intervals from the filter's scanner-filter-specs entry. Not used with expression — encode granularity inside the expression." + }, + "length": { + "type": "integer", + "description": "Lookback length for filters that need one (e.g. RSI period of 14). Use one of the supported_lengths from the filter's scanner-filter-specs entry. Not used with expression.", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "plot": { + "type": "string", + "description": "Plot / price-field input for filters that have one (e.g. \"open\" or \"close\" for % Change). Use one of the supported_plots from the filter's scanner-filter-specs entry. Not used with expression." + }, + "expression": { + "type": "string", + "description": "Raw market-data expression to screen on, e.g. \"dayVolume / volumeAvg(candleCount=30, candlePeriod=\\\"1d\\\", session=\\\"all\\\")\" with a numeric predicate, or a whole comparison like \"tradeAllDay.price > closeAvg(candleCount=50, candlePeriod=\\\"1d\\\", session=\\\"all\\\")\" with predicate \"=\" and values [\"True\"]. Only preview_scan accepts expressions. Omit filter_type when set. Prefer an enum filter_type whenever one covers the request." + }, + "display_title": { + "type": "string", + "description": "Optional short label for an expression filter, shown as the results-column header (e.g. \"Relative volume (30D)\"). Only used with expression." + } + }, + "required": [ + "predicate", + "values" + ], + "additionalProperties": false + }, + "description": "Custom filters to apply after the preset. Each filter has filter_type (FILTER_TYPE_... enum), predicate (>, <, =, BETWEEN, etc.), values, optional interval (e.g. 1d), and optional length (e.g. 14 for RSI). Call get_scanner_filter_specs first for valid filter_type / predicate combinations." + }, + "title": { + "type": "string", + "description": "Optional custom title for the saved scan. If omitted, Beacon assigns a default title based on the preset." + } + }, + "additionalProperties": false + } + }, + { + "name": "create_watchlist", + "namespace": "watchlists", + "description": "Create a new custom watchlist for the user. Confirm the name with the user before calling — this is a real write. Do not use this to follow a Robinhood-curated list (use follow_watchlist). This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "display_name": { + "type": "string", + "description": "Name for the new watchlist (e.g. 'Tech Stocks'). Must be unique among the user's watchlists." + }, + "icon_emoji": { + "type": "string", + "description": "Emoji shown next to the name (one character)." + }, + "display_description": { + "type": "string", + "description": "Short description shown under the name." + } + }, + "required": [ + "display_name" + ], + "additionalProperties": false + } + }, + { + "name": "exercise_option", + "namespace": "option_trading", + "description": "Exercise a long options position — a call exercises the right to buy the underlying shares at the strike price; a put exercises the right to sell. Exercise is irrevocable once state moves past queued.\n\nNever call this tool without asking the user to explicitly confirm the specific exercise first: state the option, quantity, and expected cash impact (debit for calls, credit for puts), then wait for their affirmative reply before calling. The user's original request to exercise is NOT itself sufficient confirmation — a generic \"exercise my calls\" does not confirm a specific option and quantity.\n\nPosition requirements: confirm via get_option_positions that the position type=long and quantity > 0.\n\nAccount requirements: confirm via get_accounts that the chosen account is agentic_allowed=true AND has option_level_2 or option_level_3. If agentic_allowed=false do NOT call. If option_level is empty or option_level_0, do NOT call; follow the get_accounts guide for how to direct the user to enroll.\n\nIndex options cannot be manually exercised and will be rejected. Exercises submitted during market hours execute the same day; requests submitted after market close — including on late-close trading days — are queued for overnight processing.\n\nParameter rules:\n- quantity must be a positive integer and cannot exceed the position's available contracts.\n- allow_shorts=true only applies to PUT exercises where the account does not own enough shares to deliver. Require explicit user confirmation before setting this — it creates a short equity position in the underlying stock.\n- reason is optional but recommended; collect it from the user when they volunteer a motivation.\n- ref_id: use the same UUID on retries of the same logical exercise; use a new UUID for a new exercise. REAL-MONEY ACTION: use only after the user explicitly authorizes the exact account, instrument, side, size, order type, price constraints, and timing. Use the dedicated Agentic account and reuse one ref_id for retries. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number. Must be agentic_allowed=true with option_level_2 or option_level_3." + }, + "option_id": { + "type": "string", + "description": "Option instrument UUID from get_option_positions or get_option_instruments. The position must be type=long." + }, + "quantity": { + "type": "integer", + "description": "Number of contracts to exercise (positive integer, minimum 1)." + }, + "ref_id": { + "type": "string", + "description": "Idempotency key (UUID). Generate once per logical exercise and re-send on retry. Omitting falls back to a server-generated key." + }, + "reason": { + "type": "string", + "description": "Optional exercise reason: covering_early_assignment | buying_stocks | not_enough_liquidity_or_spread_too_wide | hedging_position." + }, + "allow_shorts": { + "type": "boolean", + "description": "When true, allows a PUT exercise to proceed even when the account does not own enough shares to deliver — creating a short equity position. Requires explicit user confirmation that they intend to short the underlying stock. Default false." + } + }, + "required": [ + "account_number", + "option_id", + "quantity" + ], + "additionalProperties": false + } + }, + { + "name": "follow_watchlist", + "namespace": "watchlists", + "description": "Follow a Robinhood-curated list so it appears in the user's watchlists. Confirm with the user before calling. Use only for curated lists; the user already owns their custom lists. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "list_id": { + "type": "string", + "description": "UUID of the Robinhood-curated list to follow. Obtain from get_popular_watchlists." + } + }, + "required": [ + "list_id" + ], + "additionalProperties": false + } + }, + { + "name": "get_accounts", + "namespace": "account_portfolio", + "description": "List the user's brokerage accounts. Use this to look up account_number values needed by other tools. If the user has multiple accounts and hasn't specified which one, present the list and ask them to choose. Does NOT return reliable buying power — route buying-power questions through get_portfolio. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.", + "inputSchema": { + "type": "object", + "additionalProperties": false + } + }, + { + "name": "get_earnings_calendar", + "namespace": "equity_market_data", + "description": "List earnings reports scheduled across the market over a date window (up to 31 days), optionally limited to high-market-cap names. Returns one entry per report event — estimated/actual EPS, report date and timing (am/pm), and company-verification status. Use this for market-wide discovery (\"what large-caps report this week?\"). For a specific known ticker, use get_earnings_results instead. Read-only. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "start_date": { + "type": "string", + "description": "Window anchor, YYYY-MM-DD. Defaults to today (US/Eastern) when omitted." + }, + "days": { + "type": "integer", + "description": "Window length in days, measured from start_date. Defaults to 7. Positive = forward window (e.g. 7 = the next 7 days, inclusive of start_date); negative = look-back window (e.g. -7 = the 7 days ending at start_date). Must be a non-zero value between -31 and 31 — windows wider than 31 days are rejected." + }, + "filter": { + "type": "string", + "description": "Optional result filter. Set to 'high_market_cap' to limit the calendar to high-market-cap names (market cap over $1B) — useful for 'what large-caps report this week' style questions. Omit for all names." + } + }, + "additionalProperties": false + } + }, + { + "name": "get_earnings_results", + "namespace": "equity_market_data", + "description": "Get recent and upcoming earnings for ONE equity symbol — estimated/actual EPS, report date and timing (am/pm), and company-verification status. Returns the trailing up to 8 quarters. Use this for earnings-timing questions (\"does AAPL report this week?\"), EPS surprise analysis, and screening for upcoming earnings risk on a specific stock. For market-wide earnings calendar queries across many symbols, use get_earnings_calendar. Read-only. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "symbol": { + "type": "string", + "description": "Stock symbol to look up (one symbol per call). Exact-ticker match — no name or partial-ticker resolution. Lowercase and whitespace-padded input is normalized to uppercase-trimmed before forwarding. Returns the trailing up to 8 quarters of earnings for the symbol." + } + }, + "required": [ + "symbol" + ], + "additionalProperties": false + } + }, + { + "name": "get_equity_fundamentals", + "namespace": "equity_market_data", + "description": "Get today's fundamentals for one or more stock symbols — valuation ratios (PE, P/B), capitalization (market cap, shares outstanding, float), today's session OHLCV, trailing volume averages, 52-week range, dividend schedule, and company profile. For real-time quotes use get_equity_quotes; for time-series price history use get_equity_historicals. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "symbols": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "One or more stock symbols (max 10 per call). Exact-ticker match — no name or partial-ticker resolution. Lowercase and whitespace-padded input is normalized to uppercase-trimmed before forwarding." + }, + "bounds": { + "type": "string", + "description": "Trading session the day-level fields (open / high / low / volume / overnight_volume) are drawn from. One of 'regular' (regular trading hours), 'trading' (regular + post-market), 'extended' (pre-market + regular + post-market), '24_5' (24-hour, 5-day-trading-week). Does not affect valuation fields. overnight_volume only populates when bounds=24_5. Defaults to 'regular' when omitted." + } + }, + "required": [ + "symbols" + ], + "additionalProperties": false + } + }, + { + "name": "get_equity_historicals", + "namespace": "equity_market_data", + "description": "Get OHLCV bars for one or more equity symbols across an explicit time range. Use this for charting, \"recent activity\" questions, and backtesting. The server auto-selects an interval when one is not provided. If the bar's interpolated field is true, bar was synthesized to fill a gap and carry no new information.\n\nParameter rules:\n- interval is optional; when omitted, the server auto-selects an interval that targets ~2,500 bars across the requested range. Provide an explicit interval only when you need a specific granularity.\n- interval values are fixed; the server does NOT aggregate intermediate bars. For a custom interval (e.g. 3-minute), request the next-finer fixed interval and aggregate client-side.\n- bounds defaults to 'regular' (RTH only). Use 'extended' or '24_5' only when the user explicitly asks about extended-hours activity.\n- adjustment_type defaults to 'split' (split-adjusted, the right default for backtesting). Use 'none' for raw prices, 'all' for split + dividend adjustment.\n- If the range would produce more bars than the upstream allows at the explicitly requested interval, narrow the range or coarsen the interval — the call is rejected before reaching upstream. The cap does not apply when interval is auto-selected. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "symbols": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "One or more stock symbols (uppercase). Up to 10 per call." + }, + "start_time": { + "type": "string", + "description": "Start of the range (RFC3339 UTC, e.g. '2026-01-01T00:00:00Z'). Required." + }, + "end_time": { + "type": "string", + "description": "End of the range (RFC3339 UTC). Optional — when omitted, defaults to the current time." + }, + "interval": { + "type": "string", + "description": "Bar interval. Optional — when omitted, the server picks an interval that targets ~2,500 bars across the requested range. Intraday: 15second, 30second, minute, 5minute, 10minute, 30minute, hour, 4hour. Interday: day, week, month, 3month, 6month, year, 5year, 10year, 20year, 50year. Note: the 1-minute bar is named 'minute' (not '1minute')." + }, + "bounds": { + "type": "string", + "description": "Session bounds. One of 'regular' (RTH, default), 'extended', 'trading', '24_5', '24_7', 'hyper_trading'." + }, + "adjustment_type": { + "type": "string", + "description": "Corporate-action adjustment: 'none' (raw prices), 'split' (default; right for backtesting), or 'all' (split + dividend; intraday only)." + } + }, + "required": [ + "symbols", + "start_time" + ], + "additionalProperties": false + } + }, + { + "name": "get_equity_orders", + "namespace": "equity_trading", + "description": "Fetch equity orders for an account — list mode (newest first; open and closed, including fills, cancellations, rejections) or single-order mode by passing order_id. When the user asks for \"orders\" without specifying an asset class, call get_equity_orders, get_option_orders, and get_advanced_orders (OCO / multi-leg contingency orders) in parallel.\n\nFiltering tips:\n- Prefer narrow queries: combine state, symbol, and/or created_at_gte for specific questions (e.g. \"my filled AAPL orders this week\") — the per-page cap is fixed.\n- created_at_gte: interpret relative times in the user's timezone, convert to UTC before sending.\n- symbol forces a symbol→instrument lookup; omit it if you don't need it. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts." + }, + "order_id": { + "type": "string", + "description": "Filter to a single order by UUID. The response shape is unchanged (orders[] with at most one entry); empty when the order does not belong to account_number." + }, + "state": { + "type": "string", + "description": "Filter by single state: new, queued, confirmed, unconfirmed, partially_filled, filled, cancelled, rejected, failed, voided." + }, + "symbol": { + "type": "string", + "description": "Filter to one symbol (triggers a symbol→instrument lookup before the orders call)." + }, + "created_at_gte": { + "type": "string", + "description": "Lower bound (inclusive). ISO 8601 UTC or YYYY-MM-DD; naive values are interpreted as UTC." + }, + "placed_agent": { + "type": "string", + "description": "Filter to one source: 'user', 'agentic' (MCP), 'recurring', 'drip', etc." + }, + "cursor": { + "type": "string", + "description": "Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL." + } + }, + "required": [ + "account_number" + ], + "additionalProperties": false + } + }, + { + "name": "get_equity_positions", + "namespace": "equity_trading", + "description": "List open equity positions for a specific brokerage account. Returns symbol, quantity, average cost, and per-position hold breakdowns. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts." + }, + "cursor": { + "type": "string", + "description": "Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL." + } + }, + "required": [ + "account_number" + ], + "additionalProperties": false + } + }, + { + "name": "get_equity_price_book", + "namespace": "equity_market_data", + "description": "Get a real-time bid/ask order book (Level 2) snapshot for one or more equity symbols (max 4), showing the ladder of price levels and resting share size on each side. Use to read supply/demand depth before entering or exiting a position. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "symbols": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "One or more stock symbols, max 4 per call." + } + }, + "required": [ + "symbols" + ], + "additionalProperties": false + } + }, + { + "name": "get_equity_quotes", + "namespace": "equity_market_data", + "description": "Get real-time stock quotes and the official last-completed-session close for one or more symbols. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "symbols": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "One or more stock symbols. Above 20 symbols, quotes still return but closes is omitted with closes_error set." + } + }, + "required": [ + "symbols" + ], + "additionalProperties": false + } + }, + { + "name": "get_equity_tax_lots", + "namespace": "equity_trading", + "description": "List the open tax lots for one equity holding in an account — each lot is a separate acquisition with its own quantity, cost basis, acquisition date, and long/short-term status. Requires a symbol (tax lots are tracked per instrument). Use it for cost-basis, holding-period, or which-lots-would-sell questions. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts." + }, + "symbol": { + "type": "string", + "description": "Ticker symbol of the holding whose tax lots you want, e.g. AAPL. Tax lots are tracked per instrument — one symbol per call." + }, + "cursor": { + "type": "string", + "description": "Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL." + } + }, + "required": [ + "account_number", + "symbol" + ], + "additionalProperties": false + } + }, + { + "name": "get_equity_technical_indicators", + "namespace": "equity_market_data", + "description": "Compute a technical indicator (RSI, MACD, Bollinger Bands, moving averages, ATR, VWAP, and more) over one equity symbol's OHLCV bars across a time range. For the raw OHLCV bars themselves, use get_equity_historicals.\n\nParameter rules:\n- The parameters an indicator accepts depend on type:\n - period only: ema/sma (default 9); rsi/cci/atr/mfi (default 14); williams_r/adx (default 10); momentum (default 12); roc (default 14); donchian_channels (default 20).\n - bollinger_bands: period (default 20) + num_std (default 2).\n - macd: fast_period (12), slow_period (26), signal_period (9).\n - keltner_channels: period (default 20) + multiplier (default 2).\n - supertrend: period (default 10) + multiplier (default 3).\n - pivot_points: method (only 'classic').\n - vwap, obv: no parameters.\n Omit a parameter to use its default. Passing a parameter the chosen type does not accept is rejected.\n- interval is REQUIRED — indicator periods are counted in bars, so there is no auto-selection.\n- adjustment_type defaults to 'split'; 'all' (split + dividend) requires a day-or-coarser interval.\n- If the requested range plus the indicator's warm-up exceeds the per-request bar cap, narrow the range or coarsen the interval. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "symbol": { + "type": "string", + "description": "Stock symbol (uppercase). Exactly one symbol per call." + }, + "type": { + "type": "string", + "description": "Indicator to compute. One of: ema, sma, rsi, momentum, roc, cci, williams_r, atr, mfi, adx, donchian_channels, bollinger_bands, macd, keltner_channels, supertrend, vwap, obv, pivot_points." + }, + "interval": { + "type": "string", + "description": "Required bar interval the indicator is computed on. Intraday: 15second, 30second, minute, 5minute, 10minute, 30minute, hour, 4hour. Interday: day, week, month, 3month, 6month, year, 5year, 10year, 20year, 50year. The 1-minute bar is named 'minute' (not '1minute')." + }, + "start_time": { + "type": "string", + "description": "Start of the range (RFC3339 UTC, e.g. '2026-01-01T00:00:00Z'). Required." + }, + "end_time": { + "type": "string", + "description": "End of the range (RFC3339 UTC). Optional — defaults to the current time when omitted." + }, + "bounds": { + "type": "string", + "description": "Session bounds. One of 'regular' (RTH, default) or 'extended'." + }, + "adjustment_type": { + "type": "string", + "description": "Corporate-action adjustment: 'none' (raw prices), 'split' (default), or 'all' (split + dividend; requires a day-or-coarser interval)." + }, + "output": { + "type": "string", + "description": "How much of the series to return: 'series' (default, full range), 'latest' (most recent bar only), or 'last:N' (most recent N bars). The indicator is always computed over the full range first; this only trims the response." + }, + "period": { + "type": [ + "null", + "integer" + ], + "description": "Lookback period in bars. Applies to ema, sma, rsi, momentum, roc, cci, williams_r, atr, mfi, adx, donchian_channels, bollinger_bands, keltner_channels, supertrend. Omit to use the indicator's default." + }, + "num_std": { + "type": [ + "null", + "number" + ], + "description": "Number of standard deviations for the bands. bollinger_bands only (default 2)." + }, + "fast_period": { + "type": [ + "null", + "integer" + ], + "description": "Fast EMA period. macd only (default 12)." + }, + "slow_period": { + "type": [ + "null", + "integer" + ], + "description": "Slow EMA period. macd only (default 26)." + }, + "signal_period": { + "type": [ + "null", + "integer" + ], + "description": "Signal EMA period. macd only (default 9)." + }, + "multiplier": { + "type": [ + "null", + "number" + ], + "description": "Band/offset multiplier. keltner_channels (default 2) and supertrend (default 3) only." + }, + "method": { + "type": "string", + "description": "Calculation method. pivot_points only; currently only 'classic'." + } + }, + "required": [ + "symbol", + "type", + "interval", + "start_time" + ], + "additionalProperties": false + } + }, + { + "name": "get_equity_tradability", + "namespace": "equity_trading", + "description": "Check tradability for up to 10 equity symbols on a given account: per-session eligibility and fractional. Call before placing an order to surface restrictions. Exact-ticker match — no name or partial-ticker resolution. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts." + }, + "symbols": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Stock symbols, max 10 per call. With more than 10, split across multiple calls of 10 or fewer. Exact-ticker match only." + } + }, + "required": [ + "account_number", + "symbols" + ], + "additionalProperties": false + } + }, + { + "name": "get_financials", + "namespace": "equity_market_data", + "description": "Get a company's reported financial metrics over time — revenue, gross profit, net income, and net margin — by fiscal period (annual or quarterly), for one or more symbols. Use this for fundamental analysis like revenue-growth and margin-trend tracking, profitability screens, and period-over-period comparisons. Read-only. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "symbols": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "One or more stock symbols (max 20 per call). Exact-ticker match — no name or partial-ticker resolution. Lowercase and whitespace-padded input is normalized to uppercase-trimmed before forwarding." + }, + "period": { + "type": "string", + "description": "Reporting period: 'quarterly' or 'annual'. Defaults to 'quarterly' when omitted." + }, + "limit": { + "type": "integer", + "description": "Number of most-recent periods to return per symbol (e.g. 8 for the last 8 quarters or years). Defaults to 4; values above 40 are capped to 40." + } + }, + "required": [ + "symbols" + ], + "additionalProperties": false + } + }, + { + "name": "get_index_historicals", + "namespace": "indexes", + "description": "Get OHLC value bars for one or more market indexes (by instrument UUID) across an explicit time range. Use this for charting an index's history and \"recent movement\" questions. If the bar's interpolated field is true, bar was synthesized to fill a gap and carry no new information.\n\nParameter rules:\n- instrument_ids are index instrument UUIDs from get_indexes. Resolve symbols there first; this tool does not accept ticker symbols.\n- interval is required; pick the coarsest interval that answers the question. If the requested interval would produce too many bars for the range, the call is rejected — narrow the range or coarsen the interval. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "instrument_ids": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Index instrument UUIDs (from get_indexes). Up to 10 per call." + }, + "start_time": { + "type": "string", + "description": "Start of the range (RFC3339 UTC, e.g. '2026-01-01T00:00:00Z'). Required." + }, + "end_time": { + "type": "string", + "description": "End of the range (RFC3339 UTC). Optional — when omitted, defaults to the current time." + }, + "interval": { + "type": "string", + "description": "Bar interval. Required — there is no server auto-select for indexes. Intraday: 5second, 15second, 30second, minute, 5minute, 10minute, 30minute, hour, 4hour. Interday: day, week, month, 3month, 6month, year, 5year, 10year, 20year, 50year. Note: the 1-minute bar is named 'minute' (not '1minute')." + } + }, + "required": [ + "instrument_ids", + "start_time", + "interval" + ], + "additionalProperties": false + } + }, + { + "name": "get_index_quotes", + "namespace": "indexes", + "description": "Get real-time values for one or more market indexes by instrument ID. Returns current index level, state, and timestamps. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "instrument_ids": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "One or more index instrument IDs (UUIDs) to fetch current values for. Obtain IDs from the get_indexes tool." + } + }, + "required": [ + "instrument_ids" + ], + "additionalProperties": false + } + }, + { + "name": "get_indexes", + "namespace": "indexes", + "description": "Get index data for market indexes by symbol.\nOptionally pass a comma-separated list of symbols (e.g. 'SPX,NDX,DJI') to filter results. Omit symbols to return all available indexes. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "symbols": { + "type": "string", + "description": "Comma-separated list of index symbols to look up (e.g. 'SPX,NDX'). Omit to return all available indexes." + } + }, + "additionalProperties": false + } + }, + { + "name": "get_limited_margin_upgrade_info", + "namespace": "account_portfolio", + "description": "Check whether a cash account is eligible to upgrade to limited margin and return the links (web and mobile) that start the upgrade flow. Limited margin lets the account trade with unsettled funds — proceeds from a sale can go into a new order before that sale settles — while adding no borrowing or leverage. Call when the user asks about that capability, about trading with unsettled funds, or about enabling limited margin — or when a cash account shows unsettled_funds greater than 0 while you are reporting its funds, value, or buying power (the get_accounts and get_portfolio guides direct this).. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number to check. Obtain from get_accounts." + } + }, + "required": [ + "account_number" + ], + "additionalProperties": false + } + }, + { + "name": "get_option_chains", + "namespace": "option_market_data", + "description": "List option chains for one or more underlyings. A chain describes the full set of expiration dates and contracts for a given underlying. One of underlying_symbol or ids is required. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "ids": { + "type": "string", + "description": "Comma-separated chain UUIDs." + }, + "underlying_symbol": { + "type": "string", + "description": "Ticker filter; covers equity and index underlyings (e.g. 'AAPL', 'SPX')." + } + }, + "additionalProperties": false + } + }, + { + "name": "get_option_historicals", + "namespace": "option_market_data", + "description": "Get OHLC price bars for one or more option contracts (by instrument UUID) across an explicit time range. Use this for charting an option's price history and \"recent activity\" questions. The server auto-selects an interval when one is not provided. If the bar's interpolated field is true, bar was synthesized to fill a gap and carry no new information.\n\nParameter rules:\n- instrument_ids are option contract UUIDs from get_option_instruments. Resolve underlying -> get_option_chains -> get_option_instruments first; this tool does not accept ticker symbols.\n- interval is optional; when omitted the server auto-selects an interval that targets a bounded bar count across the range. Provide an explicit interval only when you need a specific granularity.\n- bounds defaults to 'regular' (regular hours). Use '24_5'/'24_7' only when the user explicitly asks about extended-hours or overnight option activity.\n- If an explicitly requested interval would produce more bars than the upstream allows for the range, the call is rejected — narrow the range or coarsen the interval. The cap does not apply when interval is auto-selected. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "instrument_ids": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Option contract instrument UUIDs (from get_option_instruments). Up to 10 per call." + }, + "start_time": { + "type": "string", + "description": "Start of the range (RFC3339 UTC, e.g. '2026-01-01T00:00:00Z'). Required." + }, + "end_time": { + "type": "string", + "description": "End of the range (RFC3339 UTC). Optional — when omitted, defaults to the current time." + }, + "interval": { + "type": "string", + "description": "Bar interval. Optional — when omitted, the server auto-selects an interval that targets a bounded bar count across the range. Intraday: 15second, 30second, minute, 5minute, 10minute, 30minute, hour, 4hour. Interday: day, week, month, 3month, 6month, year, 5year, 10year, 20year, 50year. Note: the 1-minute bar is named 'minute' (not '1minute')." + }, + "bounds": { + "type": "string", + "description": "Session bounds. One of 'regular' (regular hours, default), '24_5', or '24_7'. Use '24_5'/'24_7' only when the user explicitly asks about extended-hours or overnight option activity (index options, and certain equity options)." + } + }, + "required": [ + "instrument_ids", + "start_time" + ], + "additionalProperties": false + } + }, + { + "name": "get_option_instruments", + "namespace": "option_market_data", + "description": "List option contracts. One of chain_symbol, chain_id, or ids is required; narrow further with expiration_dates, strike_price, type, state. When looking up contracts for a specific expiration, call this in parallel for every chain whose expiration_dates (from get_option_chains) includes the date. For AM/PM/morning/evening preferences, first check settle_on_open on each chain via get_option_chains and only query matching chains. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "chain_id": { + "type": "string", + "description": "Chain UUID." + }, + "chain_symbol": { + "type": "string", + "description": "Underlying ticker (e.g. 'AAPL')." + }, + "expiration_dates": { + "type": "string", + "description": "Comma-separated YYYY-MM-DD expirations." + }, + "strike_price": { + "type": "string", + "description": "Exact strike (e.g. '150.0000')." + }, + "type": { + "type": "string", + "description": "'call' or 'put'." + }, + "state": { + "type": "string", + "description": "'active' (default), 'expired', or 'inactive'. Use 'expired' to find option contracts whose expiration date has passed; 'inactive' is for delisted/withdrawn contracts that never expired." + }, + "tradability": { + "type": "string", + "description": "'tradable' or 'untradable' (untradable is rejected at the tool layer)." + }, + "ids": { + "type": "string", + "description": "Comma-separated instrument UUIDs." + }, + "cursor": { + "type": "string", + "description": "Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL." + } + }, + "additionalProperties": false + } + }, + { + "name": "get_option_level_upgrade_info", + "namespace": "account_portfolio", + "description": "Get the upgrade URL to apply for options access on an account. Call when option_level is null. option_level_2 enables long calls/puts, covered calls, and cash-secured puts; option_level_3 adds spreads and complex strategies, though multi-leg orders are not yet supported here. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number to generate the upgrade URL for. Obtain from get_accounts." + } + }, + "required": [ + "account_number" + ], + "additionalProperties": false + } + }, + { + "name": "get_option_orders", + "namespace": "option_trading", + "description": "Fetch options orders for an account — list mode (newest first; open and closed, including fills, cancellations, and rejections) or single-order mode by passing order_id. When the user asks for \"orders\" without specifying equity or options, call both get_option_orders and get_equity_orders in parallel.\n\nFiltering tips:\n- Prefer narrow queries: combine state and/or created_at_gte for specific questions — the per-page cap is fixed.\n- chain_ids filters by underlying chain UUID (from get_option_chains).\n- created_at_gte: interpret relative times in the user's timezone, convert to UTC before sending. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts." + }, + "order_id": { + "type": "string", + "description": "Filter to a single order by UUID. The response shape is unchanged (orders[] with at most one entry); empty when the order does not belong to account_number." + }, + "state": { + "type": "string", + "description": "Filter by single state: queued, confirmed, partially_filled, filled, rejected, cancelled, failed, voided, pending_cancelled." + }, + "created_at_gte": { + "type": "string", + "description": "Lower bound (inclusive). ISO 8601 UTC or YYYY-MM-DD; naive values are interpreted as UTC." + }, + "chain_ids": { + "type": "string", + "description": "Comma-separated chain UUIDs (from get_option_chains) to filter by underlying." + }, + "underlying_type": { + "type": "string", + "description": "'equity' or 'index'." + }, + "placed_agent": { + "type": "string", + "description": "Filter to one source: 'user', 'agentic' (MCP), 'recurring', 'drip', etc." + }, + "cursor": { + "type": "string", + "description": "Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL." + } + }, + "required": [ + "account_number" + ], + "additionalProperties": false + } + }, + { + "name": "get_option_positions", + "namespace": "option_trading", + "description": "List options positions for an account. Returns open and closed (zero-quantity) positions. Pass nonzero=true for \"what options do I have\" / \"show me my positions\" — the common case. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts." + }, + "nonzero": { + "type": "boolean", + "description": "True to return only currently-open positions; omit/false to include closed ones." + }, + "chain_ids": { + "type": "string", + "description": "Comma-separated chain UUIDs (from get_option_chains)." + }, + "option_ids": { + "type": "string", + "description": "Comma-separated instrument UUIDs." + }, + "type": { + "type": "string", + "description": "'long' or 'short'." + }, + "option_type": { + "type": "string", + "description": "'call' or 'put'." + }, + "expiration_date": { + "type": "string", + "description": "Exact expiration (YYYY-MM-DD)." + }, + "expiration_date_lte": { + "type": "string", + "description": "Upper bound on expiration (YYYY-MM-DD)." + }, + "expiration_date_gte": { + "type": "string", + "description": "Lower bound on expiration (YYYY-MM-DD)." + }, + "cursor": { + "type": "string", + "description": "Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL." + } + }, + "required": [ + "account_number" + ], + "additionalProperties": false + } + }, + { + "name": "get_option_quotes", + "namespace": "option_market_data", + "description": "Get real-time quotes for one or more option contracts by instrument UUID, plus the official prior-session close for each. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "instrument_ids": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Option instrument UUIDs. Above 20, quotes still return but closes is omitted with closes_error set." + } + }, + "required": [ + "instrument_ids" + ], + "additionalProperties": false + } + }, + { + "name": "get_option_watchlist", + "namespace": "option_market_data", + "description": "List the single-leg option contracts on the user's options watchlist. Use this instead of get_watchlist_items for the options watchlist — get_watchlist_items returns a generic shape that drops the option-specific title and the upstream rejects it with 400 anyway. Works for both equity options (AAPL, NVDA) and index options (SPX, NDX, RUT). Multi-leg strategies (verticals, condors, etc.) that may exist in the user's watchlist from app-side order placement are not shown — direct the user to the Robinhood app to view those. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "additionalProperties": false + } + }, + { + "name": "get_pnl_trade_history", + "namespace": "account_portfolio", + "description": "Get a customer's per-trade realized profit & loss — a chronological, paginated list of closed/realizing trades (equities, options, crypto, prediction markets) with symbol, side, quantity, price, and realized gain/loss. This is the same data behind the app's PnL hub (\"Realized profit & loss\"). Read-only. Trades only. Use get_realized_pnl for aggregate/bucketed totals. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number (the rhs_account_number from get_accounts). Obtain it from get_accounts." + }, + "span": { + "type": "string", + "description": "Preset window: week (default), month, 3month, ytd, or all. Wormhole offers preset spans only (no arbitrary date range)." + }, + "symbol": { + "type": "string", + "description": "Optional single stock symbol filter (trimmed + uppercased). Omit for all symbols; one symbol per call." + }, + "cursor": { + "type": "string", + "description": "Pagination cursor from a previous response's next_cursor. Omit for the first page." + } + }, + "required": [ + "account_number" + ], + "additionalProperties": false + } + }, + { + "name": "get_popular_watchlists", + "namespace": "watchlists", + "description": "Discover Robinhood-curated lists the user can follow (e.g. '100 Most Popular', 'Daily Movers'). Use to find a list_id, then pass it to follow_watchlist. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "additionalProperties": false + } + }, + { + "name": "get_portfolio", + "namespace": "account_portfolio", + "description": "Get the account's portfolio market value breakdown by asset type and buying power. Use for \"how much is my account worth?\", \"what's my portfolio breakdown?\", \"how much do I have in options?\", and \"how much can I spend / afford?\" questions. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number. Obtain from get_accounts." + } + }, + "required": [ + "account_number" + ], + "additionalProperties": false + } + }, + { + "name": "get_realized_pnl", + "namespace": "account_portfolio", + "description": "Get a customer's realized profit & loss for an account over a time window — per-bucket realized gain ($ and %) and the number of closing trades, plus window totals. Read-only. Aggregate, bucketed numbers only (not individual trades). Use for post-trade analysis like \"how did my last 90 days of trades do?\". Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number (the rhs_account_number from get_accounts). Obtain it from get_accounts." + }, + "span": { + "type": "string", + "description": "Preset window: day, week, month, 3month, year, or all. Defaults to 3month ('last 90 days'). Mutually exclusive with start_date/end_date." + }, + "start_date": { + "type": "string", + "description": "Custom window start, YYYY-MM-DD, inclusive — interpreted at midnight in timezone (default US Eastern). Use with end_date instead of span; must be on or before end_date and not in the future." + }, + "end_date": { + "type": "string", + "description": "Custom window end, YYYY-MM-DD, inclusive — the entire end_date is covered (through 23:59:59 in timezone). Use with start_date instead of span; an end_date beyond today returns data through the present." + }, + "asset_classes": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Filter to one or more of equity, option, crypto. Omit for all asset classes available on the account." + }, + "display_currency": { + "type": "string", + "description": "Currency for returned amounts. Currently USD only; defaults to USD." + }, + "timezone": { + "type": "string", + "description": "IANA timezone for bucket day-boundaries (e.g. America/New_York). Defaults to the account timezone (US Eastern)." + } + }, + "required": [ + "account_number" + ], + "additionalProperties": false + } + }, + { + "name": "get_scanner_filter_specs", + "namespace": "scanners", + "description": "List every valid scanner filter type and how to use it. Call this before constructing filters for create_scan or update_scan_filters — do not guess filter_type names.\n\nThis tool takes no parameters. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "additionalProperties": false + } + }, + { + "name": "get_scans", + "namespace": "scanners", + "description": "List the authenticated user's saved scanners (also called screeners). A scan is a saved set of filters and columns that filters the market for instruments matching specific criteria (e.g. \"RSI > 70 and Volume > 1M\"). The user creates these in Legend or via the create_scan tool.\n\nReturns one entry per scan with its id, title, active filters, configured columns, sort order, and a flag indicating whether the scan is managed by Cortex (Legend's AI agent). Cortex-managed scans are read-only via MCP — they can be run with run_scan but not modified with update_scan_filters or update_scan_config.\n\nThis tool takes no parameters. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "additionalProperties": false + } + }, + { + "name": "get_watchlist_items", + "namespace": "watchlists", + "description": "List the items in a watchlist. Items may be stocks/ETFs, crypto pairs, futures, indexes — distinguished by object_type. For the options watchlist, use get_option_watchlist instead — this tool returns a generic shape that drops the strategy-specific fields and the upstream rejects it with 400 anyway. Does not return live prices; call get_quotes with the symbol(s) for that. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "list_id": { + "type": "string", + "description": "UUID of the watchlist whose items to fetch. Obtain from get_watchlists or get_popular_watchlists." + } + }, + "required": [ + "list_id" + ], + "additionalProperties": false + } + }, + { + "name": "get_watchlists", + "namespace": "watchlists", + "description": "List the user's watchlists, including both user-created custom lists and Robinhood-curated lists the user follows. Use to look up list_id values for other watchlist tools. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "additionalProperties": false + } + }, + { + "name": "place_equity_order", + "namespace": "equity_trading", + "description": "Place a real equity order with real money. Parameters mirror review_equity_order plus the optional ref_id. Requires an agentic_allowed=true account; non-agentic accounts are rejected — do not call.\n\nWorkflow: by default call review_equity_order first, present the estimated cost and any alerts, and get explicit user confirmation before calling this tool. Skip review only when the user has very explicitly asked to bypass it (e.g. \"skip the review\", \"just place it, don't review\") — a generic \"place this order\" is NOT a bypass.\n\nIdempotency: pass a fresh UUID as ref_id on the first call for each logical order, and re-send the SAME ref_id on retries of transient transport failures. Use a new ref_id only when the user wants a new order.\n\nParameter rules:\n- If the user has not specified type, ask. For immediate fills with price protection, prefer a marketable limit at the current ask over a plain market.\n- Outside regular hours, only limit orders execute. For an immediate fill during extended or overnight/24-hour sessions, place a limit order (a marketable limit at the current ask) with market_hours set to that session — not a market order. Market and stop orders are regular_hours-only; placed after hours as regular_hours they queue for the next regular open.\n- Provide exactly one of quantity or dollar_amount; dollar_amount requires type=market (server computes shares from last_trade_price).\n- Fractional shares: only on type=market with market_hours=regular_hours, eligible accounts, up to 6 decimal places, no short sells.\n- limit_price required for limit/stop_limit; stop_price required for stop_market/stop_limit.\n- Fractional and dollar-based orders only place in regular_hours; the tool rejects them in other sessions.\n- tax_lots (specified-lot selling, sell only): to sell specific lots, first call get_equity_tax_lots for the symbol, then pass tax_lots as {open_lot_id, quantity} pairs whose quantities sum to the order quantity. Omit for default (FIFO) cost basis. US accounts only; not allowed with dollar_amount, stop orders, all_day_hours, or fractional limit orders. REAL-MONEY ACTION: use only after the user explicitly authorizes the exact account, instrument, side, size, order type, price constraints, and timing. Use the dedicated Agentic account and reuse one ref_id for retries. After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true; non-agentic accounts are rejected." + }, + "symbol": { + "type": "string", + "description": "Stock symbol." + }, + "side": { + "type": "string", + "description": "'buy' or 'sell'." + }, + "type": { + "type": "string", + "description": "'market', 'limit', 'stop_market', or 'stop_limit'." + }, + "quantity": { + "type": "string", + "description": "Number of shares. Decimals (fractional) allowed for market + regular_hours only." + }, + "dollar_amount": { + "type": "string", + "description": "USD notional (e.g. '100.00'). Only valid with type=market." + }, + "limit_price": { + "type": "string", + "description": "Limit price; required for limit or stop_limit." + }, + "stop_price": { + "type": "string", + "description": "Stop trigger price; required for stop_market or stop_limit." + }, + "time_in_force": { + "type": "string", + "description": "'gfd' or 'gtc'. Default: gfd." + }, + "market_hours": { + "type": "string", + "description": "'regular_hours' (default, 9:30–16:00 ET), 'extended_hours' (pre-/post-market), or 'all_day_hours' (the 24 Hour Market / overnight session). extended_hours and all_day_hours execute limit orders only — market, stop_market, and stop_limit are regular_hours-only and are rejected if tagged to another session." + }, + "tax_lots": { + "type": [ + "null", + "array" + ], + "items": { + "type": "object", + "properties": { + "open_lot_id": { + "type": "string", + "description": "open_lot_id of the open tax lot to sell, from get_equity_tax_lots." + }, + "quantity": { + "type": "string", + "description": "Shares to sell from this lot as a decimal string; at most the lot's quantity_available." + } + }, + "required": [ + "open_lot_id", + "quantity" + ], + "additionalProperties": false + }, + "description": "Optional specified-lot selection for a SELL order. To sell specific tax lots instead of the default FIFO cost basis, pass the exact lots as {open_lot_id, quantity} objects, where open_lot_id comes from get_equity_tax_lots and the quantities sum to the order quantity. Omit for default FIFO. Sell only; at most 30 lots; US accounts only. Not allowed with dollar_amount, stop_market/stop_limit, all_day_hours, or fractional-share limit orders." + }, + "ref_id": { + "type": "string", + "description": "Idempotency key (UUID). Generate once per logical order and re-send on retry — the upstream deduplicates by ref_id. Omitting falls back to a server-generated key (loses client↔gateway idempotency)." + } + }, + "required": [ + "account_number", + "symbol", + "side", + "type" + ], + "additionalProperties": false + } + }, + { + "name": "place_option_order", + "namespace": "option_trading", + "description": "Place a real options order with real money.\n\nWorkflow: by default call review_option_order first, present the alerts, fees, collateral, and quote, and get explicit user confirmation before calling this tool. Skip review only when the user has very explicitly asked to bypass it (e.g. \"skip the review\", \"just place it, don't review\") — a generic \"place this order\" is NOT a bypass.\n\nCapability: single-leg options orders — Level 2 strategies (covered calls, cash-secured puts, long calls and puts). Multi-leg spreads (Level 3 strategies) are supported on option_level_3 accounts.\n\nAccount requirements: confirm via get_accounts that the chosen account is agentic_allowed=true AND has option_level_2 or option_level_3. If agentic_allowed=false do NOT call. If option_level is empty or option_level_0, do NOT call; follow the get_accounts guide for how to direct the user to enroll.\n\nAlert handling: pre-trade alerts surface only in review_option_order. After the user has acknowledged the reviewed alert, call this tool with the same parameters.\n\nIdempotency: pass a fresh UUID as ref_id on the first call for each logical order, and re-send the SAME ref_id on retries of transient transport failures. Use a new ref_id only when the user wants a new order.\n\nTo find option_id: get_option_chains → get_option_instruments filtered by expiration_date/strike_price/type.\n\nParameter rules:\n- Multi-leg leg layouts — vertical spread: two legs, same expiration, different strikes, opposite sides. Calendar: two legs, same strike, different expirations. Iron condor: four legs, a put spread plus a call spread. Roll: close the leg you hold (position_effect 'close', side opposite the position) plus open the replacement ('open').\n- Get the net price from the user rather than inferring it from individual leg quotes.\n- Multi-leg is not available on cash or retirement accounts through this tool.\n- type: 'limit' (default), 'market', 'stop_limit', 'stop_market'. price for limit/stop_limit; stop_price for stop_market/stop_limit.\n- market, stop_market, and stop_limit are single-leg only. market and stop_market are also regular_hours, GFD only. stop_market is sell-to-close only with stop_price below the current ask.\n\nNot currently supported anywhere (including the Robinhood apps):\n- combo orders. At Robinhood, \"combo\" specifically means a stock-option combo: one option leg paired with 100 shares of the underlying equity. In broader industry use, \"combo\" without qualifier sometimes refers to multi-leg option structures. REAL-MONEY ACTION: use only after the user explicitly authorizes the exact account, instrument, side, size, order type, price constraints, and timing. Use the dedicated Agentic account and reuse one ref_id for retries. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true." + }, + "legs": { + "type": [ + "null", + "array" + ], + "items": { + "type": "object", + "properties": { + "option_id": { + "type": "string", + "description": "Option instrument UUID (from get_option_instruments)." + }, + "side": { + "type": "string", + "description": "'buy' or 'sell'." + }, + "position_effect": { + "type": "string", + "description": "'open' (new position) or 'close' (existing position). To close a long use sell; to close a short use buy." + }, + "ratio_quantity": { + "type": "integer", + "description": "Contracts for this leg per unit of the order's quantity. Defaults to 1, which is what standard spreads, condors, calendars, and rolls use. Must be 1 on a single-leg order; across legs the ratios must be in lowest terms (1:2, not 2:4)." + } + }, + "required": [ + "option_id", + "side", + "position_effect" + ], + "additionalProperties": false + }, + "description": "1 to 4 legs, all on the same underlying and each a different contract. Several legs are filled together as one strategy. Should match the legs the user reviewed." + }, + "direction": { + "type": "string", + "description": "Net direction of the whole order: 'debit' (you pay the net premium) or 'credit' (you receive it). Required with 2 or more legs; for one leg it is derived from that leg's side, so omit it." + }, + "type": { + "type": "string", + "description": "'limit' (default), 'market', 'stop_limit', or 'stop_market'. Should match the type the user reviewed. Only 'limit' is available with 2 or more legs." + }, + "quantity": { + "type": "string", + "description": "Positive integer contract count. With several legs it counts whole strategies — each leg fills quantity × its ratio_quantity contracts." + }, + "price": { + "type": "string", + "description": "Limit price. Per contract for one leg; with several legs it is the net premium of the whole strategy per unit of quantity, always positive — direction says whether it is paid or received. Required for limit/stop_limit; must be omitted for market/stop_market." + }, + "stop_price": { + "type": "string", + "description": "Stop trigger price per contract. Required for stop_limit/stop_market; must be omitted for limit/market." + }, + "time_in_force": { + "type": "string", + "description": "'gfd' (default) or 'gtc'. Market orders must be 'gfd'." + }, + "market_hours": { + "type": "string", + "description": "'regular_hours' (default), 'regular_curb_hours', or 'regular_curb_overnight_hours'. Non-limit-immediate orders only place in regular_hours. CURB requires an index chain with extended_hours_state='enabled'." + }, + "ref_id": { + "type": "string", + "description": "Idempotency key (UUID). Generate once per logical order and re-send on retry. Omitting falls back to a server-generated key." + } + }, + "required": [ + "account_number", + "legs", + "quantity" + ], + "additionalProperties": false + } + }, + { + "name": "remove_from_watchlist", + "namespace": "watchlists", + "description": "Remove items from a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes) is required — mutually exclusive. For options use remove_option_from_watchlist. Items not on the list are no-ops (not errors). Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "list_id": { + "type": "string", + "description": "UUID of the watchlist to remove items from." + }, + "symbols": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Stock symbols to remove (e.g. ['AAPL']). Mutually exclusive with currency_pair_ids and index_ids." + }, + "currency_pair_ids": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Currency-pair UUIDs to remove. Mutually exclusive with symbols and index_ids." + }, + "index_ids": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Index UUIDs to remove. Mutually exclusive with symbols and currency_pair_ids." + } + }, + "required": [ + "list_id" + ], + "additionalProperties": false + } + }, + { + "name": "remove_option_from_watchlist", + "namespace": "option_market_data", + "description": "Remove option contracts from the user's options watchlist. Specify the same position_type used when the contract was added (defaults to \"long\"). Contracts not on the list are no-ops. Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "option_ids": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Option contract UUIDs to remove. The position_type must match how each contract was added (most likely \"long\")." + }, + "position_type": { + "type": "string", + "description": "\"long\" (default) or \"short\". Must match how the contract was originally added." + } + }, + "required": [ + "option_ids" + ], + "additionalProperties": false + } + }, + { + "name": "review_equity_order", + "namespace": "equity_trading", + "description": "Simulate a stock order without placing it. Returns the current quote plus pre-trade alerts (buying power, PDT, instrument halt, etc.). Call this by default before place_equity_order unless the user has very explicitly asked to skip review. Requires an agentic_allowed=true account; non-agentic accounts are rejected — do not call.\n\nParameter rules:\n- If the user has not specified type, ask. For immediate fills with price protection, prefer a marketable limit at the current ask over a plain market.\n- Outside regular hours, only limit orders execute. For an immediate fill during extended or overnight/24-hour sessions, place a limit order (a marketable limit at the current ask) with market_hours set to that session — not a market order. Market and stop orders are regular_hours-only; placed after hours as regular_hours they queue for the next regular open.\n- Provide exactly one of quantity or dollar_amount; dollar_amount requires type=market (server computes shares from last_trade_price).\n- Fractional shares: only on type=market with market_hours=regular_hours, eligible accounts, up to 6 decimal places, no short sells.\n- limit_price required for limit/stop_limit; stop_price required for stop_market/stop_limit.\n- Fractional and dollar-based orders only place in regular_hours; the tool rejects them in other sessions.\n- tax_lots (specified-lot selling, sell only): to sell specific lots, first call get_equity_tax_lots for the symbol, then pass tax_lots as {open_lot_id, quantity} pairs whose quantities sum to the order quantity. Omit for default (FIFO) cost basis. US accounts only; not allowed with dollar_amount, stop orders, all_day_hours, or fractional limit orders. This is a non-submitting pre-trade simulation. Review warnings and estimated cost before asking for authorization to use the corresponding place tool. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true; non-agentic accounts are rejected." + }, + "symbol": { + "type": "string", + "description": "Stock symbol." + }, + "side": { + "type": "string", + "description": "'buy' or 'sell'." + }, + "type": { + "type": "string", + "description": "'market', 'limit', 'stop_market', or 'stop_limit'." + }, + "quantity": { + "type": "string", + "description": "Number of shares. Decimals (fractional) allowed for market + regular_hours only." + }, + "dollar_amount": { + "type": "string", + "description": "USD notional (e.g. '100.00'). Only valid with type=market." + }, + "limit_price": { + "type": "string", + "description": "Limit price; required for limit or stop_limit." + }, + "stop_price": { + "type": "string", + "description": "Stop trigger price; required for stop_market or stop_limit." + }, + "time_in_force": { + "type": "string", + "description": "'gfd' (good for day) or 'gtc' (good till cancelled). Default: gfd." + }, + "market_hours": { + "type": "string", + "description": "'regular_hours' (default, 9:30–16:00 ET), 'extended_hours' (pre-/post-market), or 'all_day_hours' (the 24 Hour Market / overnight session). extended_hours and all_day_hours execute limit orders only — market, stop_market, and stop_limit are regular_hours-only and are rejected if tagged to another session." + }, + "tax_lots": { + "type": [ + "null", + "array" + ], + "items": { + "type": "object", + "properties": { + "open_lot_id": { + "type": "string", + "description": "open_lot_id of the open tax lot to sell, from get_equity_tax_lots." + }, + "quantity": { + "type": "string", + "description": "Shares to sell from this lot as a decimal string; at most the lot's quantity_available." + } + }, + "required": [ + "open_lot_id", + "quantity" + ], + "additionalProperties": false + }, + "description": "Optional specified-lot selection for a SELL order. To sell specific tax lots instead of the default FIFO cost basis, pass the exact lots as {open_lot_id, quantity} objects, where open_lot_id comes from get_equity_tax_lots and the quantities sum to the order quantity. Omit for default FIFO. Sell only; at most 30 lots; US accounts only. Not allowed with dollar_amount, stop_market/stop_limit, all_day_hours, or fractional-share limit orders." + } + }, + "required": [ + "account_number", + "symbol", + "side", + "type" + ], + "additionalProperties": false + } + }, + { + "name": "review_option_order", + "namespace": "option_trading", + "description": "Simulate an options order without placing it. Returns the current quote plus pre-trade alerts. Call this by default before place_option_order or replace_option_order unless the user has very explicitly asked to skip review.\n\nCapability: single-leg options orders — Level 2 strategies (covered calls, cash-secured puts, long calls and puts). Multi-leg spreads (Level 3 strategies) are supported on option_level_3 accounts.\n\nAccount requirements: confirm via get_accounts that the chosen account is agentic_allowed=true AND has option_level_2 or option_level_3. If agentic_allowed=false do NOT call. If option_level is empty or option_level_0, do NOT call; follow the get_accounts guide for how to direct the user to enroll.\n\nParameter rules:\n- legs: option_id (from get_option_instruments), side, position_effect, optional ratio_quantity per leg.\n- Multi-leg leg layouts — vertical spread: two legs, same expiration, different strikes, opposite sides. Calendar: two legs, same strike, different expirations. Iron condor: four legs, a put spread plus a call spread. Roll: close the leg you hold (position_effect 'close', side opposite the position) plus open the replacement ('open').\n- Get the net price from the user rather than inferring it from individual leg quotes.\n- Multi-leg is not available on cash or retirement accounts through this tool.\n- type: 'limit' (default), 'market', 'stop_limit', 'stop_market'. If unspecified, ask. price for limit/stop_limit; stop_price for stop_market/stop_limit.\n- market, stop_market, and stop_limit are single-leg only. market and stop_market are also GFD, regular_hours only. stop_market is sell-to-close only with stop_price below the current ask. Non-limit-immediate types are blocked in any extended-hours session.\n- Surface order_checks alerts verbatim — the detail strings carry the actual time/contract/BP values for the user. This is a non-submitting pre-trade simulation. Review warnings and estimated cost before asking for authorization to use the corresponding place tool. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "account_number": { + "type": "string", + "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true." + }, + "legs": { + "type": [ + "null", + "array" + ], + "items": { + "type": "object", + "properties": { + "option_id": { + "type": "string", + "description": "Option instrument UUID (from get_option_instruments)." + }, + "side": { + "type": "string", + "description": "'buy' or 'sell'." + }, + "position_effect": { + "type": "string", + "description": "'open' (new position) or 'close' (existing position). To close a long use sell; to close a short use buy." + }, + "ratio_quantity": { + "type": "integer", + "description": "Contracts for this leg per unit of the order's quantity. Defaults to 1, which is what standard spreads, condors, calendars, and rolls use. Must be 1 on a single-leg order; across legs the ratios must be in lowest terms (1:2, not 2:4)." + } + }, + "required": [ + "option_id", + "side", + "position_effect" + ], + "additionalProperties": false + }, + "description": "1 to 4 legs, all on the same underlying and each a different contract. Several legs are filled together as one strategy." + }, + "direction": { + "type": "string", + "description": "Net direction of the whole order: 'debit' (you pay the net premium) or 'credit' (you receive it). Required with 2 or more legs; for one leg it is derived from that leg's side, so omit it." + }, + "type": { + "type": "string", + "description": "'limit' (default), 'market', 'stop_limit', or 'stop_market'. Only 'limit' is available with 2 or more legs." + }, + "quantity": { + "type": "string", + "description": "Positive integer contract count. With several legs it counts whole strategies — each leg fills quantity × its ratio_quantity contracts." + }, + "price": { + "type": "string", + "description": "Limit price (e.g. '1.50'). Per contract for one leg; with several legs it is the net premium of the whole strategy per unit of quantity, always positive — direction says whether it is paid or received. Required for limit/stop_limit; must be omitted for market/stop_market." + }, + "stop_price": { + "type": "string", + "description": "Stop trigger price per contract. Required for stop_limit/stop_market; must be omitted for limit/market. For sell-side stop_market, must be below the current ask." + }, + "time_in_force": { + "type": "string", + "description": "'gfd' (default) or 'gtc'. Market orders must be 'gfd'." + }, + "market_hours": { + "type": "string", + "description": "'regular_hours' (default), 'regular_curb_hours', or 'regular_curb_overnight_hours'. Extended-hours sessions only accept limit+immediate. CURB requires an index chain with extended_hours_state='enabled' (per get_option_chains); rejection surfaces at place time." + }, + "chain_symbol": { + "type": "string", + "description": "Underlying ticker (e.g. 'AAPL', 'SPXW'). Supply alongside underlying_type to include fees and collateral in the response — always do so when known." + }, + "underlying_type": { + "type": "string", + "description": "'equity' or 'index'. Required alongside chain_symbol to enable the fee + collateral fetch." + } + }, + "required": [ + "account_number", + "legs", + "quantity" + ], + "additionalProperties": false + } + }, + { + "name": "run_scan", + "namespace": "scanners", + "description": "Execute a saved scanner (also called screener) and return live market results. A scan's filters are evaluated against current market data at request time — results are real-time, not cached.\n\nReturns the scan's title, the total number of matching instruments, a list of instrument rows (with ticker, instrument_id, type, and one cell per visible column), plus the active sort and filters. The agent should present results as a table and mention this is live data.\n\nParameters:\n- scan_id (required) — the scan identifier from get_scans or create_scan. Returns an error if the scan does not exist or does not belong to the calling user.\n\nUse get_scans first to discover available scan_ids if the user has not specified one. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "scan_id": { + "type": "string", + "description": "The scan identifier to execute. Get this from get_scans or create_scan." + } + }, + "required": [ + "scan_id" + ], + "additionalProperties": false + } + }, + { + "name": "search", + "namespace": "equity_market_data", + "description": "Resolve a natural-language query to Robinhood instruments (stocks/ETFs), crypto pairs, or market indexes. Use when the user names an asset by name (or partial name) instead of a ticker/pair/index symbol, or when you need an instrument_id / currency-pair UUID / market-index id for a downstream tool. Defaults to instrument search; pass asset_type=\"currency_pair\" for crypto or asset_type=\"market_index\" for indexes (SPX, NDX, DJI, etc.). Instrument results carry symbol + instrument_id (use with get_equity_quotes / get_equity_tradability / place_equity_order or any instrument_id-based tool). Crypto results carry hyphenated symbol (e.g. BTC-USD) + id — the symbol routes to crypto quote/order tools, the id routes to watchlist tools as currency_pair_ids. Market-index results carry symbol + id — pass id to index quote tools for current values, or in the index_ids array of watchlist tools. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Natural-language search query: company name, partial name, or ticker (e.g. \"apple\", \"tesla motors\", \"AAPL\"). Required." + }, + "asset_type": { + "type": "string", + "description": "Asset category to search. Supported: \"instrument\" (US-listed stocks/ETFs), \"currency_pair\" (crypto pairs like BTC-USD), and \"market_index\" (e.g. SPX, NDX, DJI). Defaults to \"instrument\" when omitted. More categories (events, futures) will be added as their corresponding tools land." + }, + "limit": { + "type": "integer", + "description": "Max results to return. Defaults to 10; clamped to 20." + } + }, + "required": [ + "query" + ], + "additionalProperties": false + } + }, + { + "name": "unfollow_watchlist", + "namespace": "watchlists", + "description": "Stop following a Robinhood-curated list. The list itself is unchanged — it just no longer appears in the user's watchlists. Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "list_id": { + "type": "string", + "description": "UUID of the Robinhood-curated list to unfollow." + } + }, + "required": [ + "list_id" + ], + "additionalProperties": false + } + }, + { + "name": "update_scan_config", + "namespace": "scanners", + "description": "Change the sort order of a saved scan's results table. The scan's filters and columns are preserved; only the sort changes.\n\nParameters:\n- scan_id (required) — the scan to modify.\n- sorting_column (required) — display name of the column to sort by. Must match a visible column on the scan; the error response lists available columns when no match is found.\n- sorting_direction (required) — \"asc\" or \"desc\".\n\nRestrictions:\n- Cortex-managed scans (cortex_managed: true in get_scans) are rejected.\n- v1 supports only sort changes — column add/remove/visibility/reorder are not exposed by this tool.\n\nReturns the scan with the new sort applied and fresh live results in the new order. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "scan_id": { + "type": "string", + "description": "The scan to modify. Get this from get_scans or create_scan. Cortex-managed scans are rejected." + }, + "sorting_column": { + "type": "string", + "description": "Display name of the column to sort by (e.g. \"Volume\", \"% Change\", \"RSI\"). Must match a column currently visible on the scan — call get_scans / run_scan first to see available columns." + }, + "sorting_direction": { + "type": "string", + "description": "\"asc\" or \"desc\" (ascending or descending)." + } + }, + "required": [ + "scan_id", + "sorting_column", + "sorting_direction" + ], + "additionalProperties": false + } + }, + { + "name": "update_scan_filters", + "namespace": "scanners", + "description": "Replace the filters on an existing saved scan. The complete filter set provided replaces whatever filters the scan had — this is REPLACE semantics, not merge. To add a single filter to an existing scan, the agent must first read the scan (via get_scans or run_scan), then call this tool with all the existing filters plus the new one.\n\nParameters:\n- scan_id (required) — the scan to modify. Get from get_scans or create_scan.\n- filters (required) — the complete new filter set. Send [] to clear all filters. Each filter has filter_type (FILTER_TYPE_... enum), predicate, values, optional interval/length. Call get_scanner_filter_specs for valid combinations.\n\nRestrictions:\n- Cortex-managed scans (cortex_managed: true in get_scans) are rejected with a user-friendly error.\n- Returns an error and does not apply any change if any filter fails validation.\n\nReturns the scan with its new filters and fresh live results. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "scan_id": { + "type": "string", + "description": "The scan to modify. Get this from get_scans or create_scan. Cortex-managed scans (cortex_managed: true in get_scans output) are rejected." + }, + "filters": { + "type": [ + "null", + "array" + ], + "items": { + "type": "object", + "properties": { + "filter_type": { + "type": "string", + "description": "Wire-format enum name, e.g. \"FILTER_TYPE_RSI\". See the scanner-filter-specs resource for valid values. Omit when supplying expression." + }, + "predicate": { + "type": "string", + "description": "Wire-format enum name, e.g. \"PREDICATE_GREATER_THAN\". See the scanner-filter-specs resource for the predicates supported by each filter." + }, + "values": { + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + }, + "description": "Threshold values. Single-element for unary predicates, two-element for BETWEEN, multi-element for IN_LIST/ANY_OF. For a boolean expression screen, exactly [\"True\"]." + }, + "interval": { + "type": "string", + "description": "Time granularity for time-series filters (e.g. \"1d\"). Use one of the supported_intervals from the filter's scanner-filter-specs entry. Not used with expression — encode granularity inside the expression." + }, + "length": { + "type": "integer", + "description": "Lookback length for filters that need one (e.g. RSI period of 14). Use one of the supported_lengths from the filter's scanner-filter-specs entry. Not used with expression.", + "minimum": -2147483648, + "maximum": 2147483647 + }, + "plot": { + "type": "string", + "description": "Plot / price-field input for filters that have one (e.g. \"open\" or \"close\" for % Change). Use one of the supported_plots from the filter's scanner-filter-specs entry. Not used with expression." + }, + "expression": { + "type": "string", + "description": "Raw market-data expression to screen on, e.g. \"dayVolume / volumeAvg(candleCount=30, candlePeriod=\\\"1d\\\", session=\\\"all\\\")\" with a numeric predicate, or a whole comparison like \"tradeAllDay.price > closeAvg(candleCount=50, candlePeriod=\\\"1d\\\", session=\\\"all\\\")\" with predicate \"=\" and values [\"True\"]. Only preview_scan accepts expressions. Omit filter_type when set. Prefer an enum filter_type whenever one covers the request." + }, + "display_title": { + "type": "string", + "description": "Optional short label for an expression filter, shown as the results-column header (e.g. \"Relative volume (30D)\"). Only used with expression." + } + }, + "required": [ + "predicate", + "values" + ], + "additionalProperties": false + }, + "description": "The complete set of filters the scan should have after the update. REPLACE semantics — to add a filter, supply all existing filters plus the new one. To remove a filter, omit it from the array. To clear all filters, send []. Each filter: filter_type (FILTER_TYPE_... enum), predicate (>, <, =, BETWEEN, etc.), values, optional interval (e.g. 1d), optional length (e.g. 14 for RSI). Call get_scanner_filter_specs first for valid filter_type / predicate / interval / length combinations." + } + }, + "required": [ + "scan_id", + "filters" + ], + "additionalProperties": false + } + }, + { + "name": "update_watchlist", + "namespace": "watchlists", + "description": "Rename a custom watchlist or change its icon/description. Robinhood-curated lists cannot be renamed; the call will fail with 404. Provide at least one of display_name, icon_emoji, display_description. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "inputSchema": { + "type": "object", + "properties": { + "list_id": { + "type": "string", + "description": "UUID of the watchlist to update. Obtain from get_watchlists." + }, + "display_name": { + "type": "string", + "description": "New name for the watchlist." + }, + "icon_emoji": { + "type": "string", + "description": "New emoji." + }, + "display_description": { + "type": "string", + "description": "New description." + } + }, + "required": [ + "list_id" + ], + "additionalProperties": false + } + } + ] +} diff --git a/crates/pocket-pi-agentos/src/lib.rs b/crates/pocket-pi-agentos/src/lib.rs index 6e9f5fa..cd536b7 100644 --- a/crates/pocket-pi-agentos/src/lib.rs +++ b/crates/pocket-pi-agentos/src/lib.rs @@ -40,6 +40,8 @@ const ROBINHOOD_JS: &str = include_str!("../../../apps/robinhood/dist/app.js"); const ROBINHOOD_DATA_JS: &str = include_str!("../../../apps/robinhood/dist/data-action.js"); const ROBINHOOD_PAK: &[u8] = include_bytes!("../../../apps/robinhood/dist/app.pak"); const ROBINHOOD_DESCRIPTOR: &str = include_str!("../../../apps/robinhood/agent-app.json"); +#[cfg(test)] +const ROBINHOOD_TOOL_CATALOG: &str = include_str!("../../../apps/robinhood/tool-catalog.json"); const ROBINHOOD_POCKET: &str = include_str!("../../../apps/robinhood/pocket.json"); const EXA_JS: &str = include_str!("../../../apps/exa/dist/app.js"); const EXA_DATA_JS: &str = include_str!("../../../apps/exa/dist/data-action.js"); @@ -57,6 +59,8 @@ pub struct AppDescriptor { #[serde(default)] pub tools: Vec, #[serde(default)] + pub provider_operations: Vec, + #[serde(default)] pub tasks: Vec, #[serde(default)] pub schedules: Vec, @@ -127,6 +131,23 @@ impl AppCatalog { } let mut tool_owner = BTreeMap::new(); for app in apps.values() { + let provider_operations = app + .descriptor + .provider_operations + .iter() + .collect::>(); + anyhow::ensure!( + provider_operations.len() == app.descriptor.provider_operations.len(), + "App {} declares duplicate provider operations", + app.descriptor.id + ); + anyhow::ensure!( + provider_operations + .iter() + .all(|operation| !operation.is_empty()), + "App {} declares an empty provider operation", + app.descriptor.id + ); for tool in &app.descriptor.tools { let name = tool .get("name") @@ -143,6 +164,15 @@ impl AppCatalog { { anyhow::bail!("duplicate App tool: {name}"); } + if let Some(operation) = tool.get("providerOperation") { + let operation = operation + .as_str() + .ok_or_else(|| anyhow!("{name} providerOperation must be a string"))?; + anyhow::ensure!( + name == format!("{}.{}", app.descriptor.id, operation), + "{name} providerOperation must match its namespaced Tool name" + ); + } } } Ok(Self { apps, tool_owner }) @@ -163,6 +193,18 @@ impl AppCatalog { self.apps.values().map(|app| &app.descriptor) } + /// Provider operations are declared by the App release and consumed by a + /// native credential/transport owner as its exact allowlist. Local-only + /// App Tools omit `providerOperation` and can never cross this boundary. + pub fn provider_operations(&self, app_id: &str) -> BTreeSet { + self.apps + .get(app_id) + .into_iter() + .flat_map(|app| &app.descriptor.provider_operations) + .cloned() + .collect() + } + fn app(&self, id: &str) -> Option<&BuiltinApp> { self.apps.get(id) } @@ -408,8 +450,14 @@ fn parse_data_result(line: &str) -> Result { }) } +struct DataActionCompletion { + run_id: u64, + result: ToolResult, +} + struct AppDataRunner { tx: mpsc::SyncSender, + completions: Mutex>, next_run_id: AtomicU32, busy: Arc, } @@ -417,6 +465,7 @@ struct AppDataRunner { impl AppDataRunner { fn start(configs: Vec, services: Arc) -> Result { let (tx, rx) = mpsc::sync_channel::(DATA_ACTION_QUEUE); + let (completion_tx, completion_rx) = mpsc::channel::(); let busy = Arc::new(AtomicBool::new(false)); let worker_busy = busy.clone(); std::thread::Builder::new() @@ -445,34 +494,39 @@ impl AppDataRunner { .expect("Data Action runtime inserted") .invoke(&request) })(); - match result { - Ok(result) if result.is_error => log::warn!( - "App Data Action run={} {}.{} failed: {}", - request.run_id, - request.app_id, - request.name, - result.text - ), - Ok(result) => log::info!( - "App Data Action run={} {}.{} completed: {}", - request.run_id, - request.app_id, - request.name, - result.text - ), - Err(error) => log::error!( - "App Data Action run={} {}.{} crashed: {error:#}", - request.run_id, - request.app_id, - request.name - ), - } + let result = match result { + Ok(result) if result.is_error => { + log::warn!( + "App Data Action run={} {}.{} failed: {}", + request.run_id, + request.app_id, + request.name, + result.text + ); + result + } + Ok(result) => result, + Err(error) => { + log::error!( + "App Data Action run={} {}.{} crashed: {error:#}", + request.run_id, + request.app_id, + request.name + ); + tool_error(format!("{}: {error:#}", request.name)) + } + }; + let _ = completion_tx.send(DataActionCompletion { + run_id: request.run_id, + result, + }); worker_busy.store(false, Ordering::Release); } }) .context("start App Data Action runner")?; Ok(Self { tx, + completions: Mutex::new(completion_rx), next_run_id: AtomicU32::new(1), busy, }) @@ -495,6 +549,17 @@ impl AppDataRunner { fn busy(&self) -> bool { self.busy.load(Ordering::Acquire) } + + fn poll_completions(&self) -> Vec { + let Ok(completions) = self.completions.lock() else { + return Vec::new(); + }; + let mut ready = Vec::new(); + while let Ok(completion) = completions.try_recv() { + ready.push(completion); + } + ready + } } pub struct AppRuntime { @@ -827,6 +892,7 @@ pub struct AppSupervisor { catalog: AppCatalog, services: Arc, data_runner: AppDataRunner, + pending_tool_responses: Mutex>>, /// The Pi Agent System App is booted once and remains resident for the /// entire supervisor lifetime. Foreground navigation never replaces it. system: AppRuntime, @@ -913,6 +979,7 @@ impl AppSupervisor { catalog, services, data_runner, + pending_tool_responses: Mutex::new(BTreeMap::new()), system, agent: None, runtimes, @@ -1003,6 +1070,7 @@ impl AppSupervisor { /// Advance the Agent every host tick, but only ask the selected PocketJS /// View to produce a new DrawList when the host knows it is dirty. pub fn frame_render(&self, render_selected: bool) -> Result> { + self.deliver_data_action_completions(); let events = match &self.agent { Some(agent) => agent .tick(&self.system.guest) @@ -1018,6 +1086,18 @@ impl AppSupervisor { Ok(events) } + fn deliver_data_action_completions(&self) { + let completions = self.data_runner.poll_completions(); + let Ok(mut pending) = self.pending_tool_responses.lock() else { + return; + }; + for completion in completions { + if let Some(response) = pending.remove(&completion.run_id) { + let _ = response.send(completion.result); + } + } + } + pub fn update_root(&self, projection: &Value) -> Result<()> { self.system.update(projection) } @@ -1068,6 +1148,42 @@ impl AppSupervisor { } } + fn begin_agent_tool( + &mut self, + name: &str, + args_json: &str, + response: mpsc::Sender, + ) { + let Some(app_id) = self.catalog.app_for_tool(name).map(str::to_owned) else { + let _ = response.send(tool_error(format!("unknown App tool: {name}"))); + return; + }; + if name.ends_with(".storage_status") { + let _ = response.send( + self.with_runtime(&app_id, |runtime| runtime.invoke_tool(name, args_json)) + .unwrap_or_else(|error| tool_error(format!("{name}: {error:#}"))), + ); + return; + } + let args = serde_json::from_str(args_json).unwrap_or(Value::Null); + match self + .data_runner + .enqueue(&app_id, DataActionKind::Tool, name, args) + { + Ok(run_id) => { + if let Ok(mut pending) = self.pending_tool_responses.lock() { + pending.insert(run_id, response); + } else { + let _ = + response.send(tool_error("App Tool completion registry is unavailable")); + } + } + Err(error) => { + let _ = response.send(tool_error(format!("{name}: {error:#}"))); + } + } + } + /// Runs a task requested by the currently visible App. The host calls this /// after presenting the App's immediate pressed/loading state so slow /// native services never hide touch feedback. @@ -1341,8 +1457,7 @@ impl ToolHost for RoutedToolHost { impl AppToolRequest { pub fn handle(self, supervisor: &mut AppSupervisor) { - let result = supervisor.invoke_tool(&self.name, &self.args_json); - let _ = self.response.send(result); + supervisor.begin_agent_tool(&self.name, &self.args_json, self.response); } } @@ -1566,7 +1681,7 @@ mod tests { impl ModelBackend for ToolCallingBackend { fn complete( &self, - _request_json: &str, + request_json: &str, on_event: &mut dyn FnMut(pocket_pi_embedded::ModelStreamEvent), ) -> Result { if self.0.fetch_add(1, Ordering::SeqCst) == 0 { @@ -1576,14 +1691,19 @@ mod tests { "text":"", "toolCalls":[{ "id":"call_portfolio", - "name":"robinhood.get_portfolio", - "arguments":{"account_number":"SIM-001"} + "name":"robinhood.call", + "arguments":{ + "name":"get_portfolio", + "arguments":{"account_number":"SIM-001"} + } }], "usage":{}, "stopReason":"toolUse" }) .to_string()) } else { + assert!(request_json.contains("100.00"), "{request_json}"); + assert!(!request_json.contains("Queued robinhood.call")); on_event(pocket_pi_embedded::ModelStreamEvent::Text("tool-ok".into())); Ok(serde_json::json!({ "thinking":"", @@ -1623,10 +1743,115 @@ mod tests { .into_iter() .filter_map(|tool| tool["name"].as_str().map(str::to_owned)) .collect::>(); - assert!(names.contains(&"robinhood.get_portfolio".to_owned())); + assert!(names.contains(&"robinhood.search_tools".to_owned())); + assert!(names.contains(&"robinhood.call".to_owned())); assert!(names.contains(&"research.search".to_owned())); } + #[test] + fn exa_catalog_exposes_bounded_advanced_search() { + let catalog = AppCatalog::builtin().unwrap(); + let exa = catalog + .descriptors() + .find(|descriptor| descriptor.id == EXA_APP_ID) + .unwrap(); + assert_eq!(exa.tools.len(), 3); + assert!(serde_json::to_vec(&exa.tools).unwrap().len() < 5 * 1024); + + let search = exa + .tools + .iter() + .find(|tool| tool["name"] == "research.search") + .unwrap(); + let properties = search["parameters"]["properties"].as_object().unwrap(); + for name in [ + "category", + "startPublishedDate", + "endPublishedDate", + "additionalQueries", + "maxAgeHours", + ] { + assert!( + properties.contains_key(name), + "missing Exa search field {name}" + ); + } + let search_types = properties["searchType"]["enum"].as_array().unwrap(); + assert!(search_types.iter().any(|value| value == "deep")); + assert!(search_types.iter().any(|value| value == "deep-reasoning")); + assert_eq!(search["parameters"]["additionalProperties"], false); + + let fetch = exa + .tools + .iter() + .find(|tool| tool["name"] == "research.fetch") + .unwrap(); + assert!(fetch["parameters"]["properties"] + .get("maxAgeHours") + .is_some()); + assert_eq!(fetch["parameters"]["additionalProperties"], false); + } + + #[test] + fn robinhood_catalog_matches_the_checked_in_tool_catalog() { + let catalog = AppCatalog::builtin().unwrap(); + let operations = catalog.provider_operations(ROBINHOOD_APP_ID); + let snapshot: Value = serde_json::from_str(ROBINHOOD_TOOL_CATALOG).unwrap(); + let upstream = snapshot["tools"] + .as_array() + .unwrap() + .iter() + .map(|tool| tool["name"].as_str().unwrap().to_owned()) + .collect::>(); + assert_eq!(operations, upstream); + assert_eq!(operations.len(), 54); + assert!(operations.contains("place_equity_order")); + assert!(operations.contains("place_option_order")); + assert!(!operations.contains("refresh_portfolio")); + let mut namespace_counts = BTreeMap::<&str, usize>::new(); + for tool in snapshot["tools"].as_array().unwrap() { + *namespace_counts + .entry(tool["namespace"].as_str().unwrap()) + .or_default() += 1; + assert!(!tool["description"].as_str().unwrap_or_default().is_empty()); + assert!(tool.get("agentDescription").is_none()); + assert_eq!(tool["inputSchema"]["type"], "object"); + } + assert_eq!(namespace_counts.len(), 8); + assert!(namespace_counts.values().all(|count| *count <= 9)); + let description = |name: &str| { + snapshot["tools"] + .as_array() + .unwrap() + .iter() + .find(|tool| tool["name"] == name) + .unwrap()["description"] + .as_str() + .unwrap() + }; + assert!(description("place_equity_order").contains("REAL-MONEY ACTION")); + assert!(description("place_equity_order").contains("explicitly authorizes")); + assert!(description("review_equity_order").contains("non-submitting")); + + let robinhood = catalog + .descriptors() + .find(|descriptor| descriptor.id == ROBINHOOD_APP_ID) + .unwrap(); + assert_eq!(robinhood.tools.len(), 4); + assert!(serde_json::to_vec(&robinhood.tools).unwrap().len() < 8 * 1024); + for tool in &robinhood.tools { + let name = tool["name"].as_str().unwrap(); + assert!( + !tool["description"].as_str().unwrap_or_default().is_empty(), + "{name}" + ); + assert_eq!(tool["parameters"]["type"], "object", "{name}"); + if tool.get("providerOperation").is_some() { + assert_eq!(tool["parameters"]["additionalProperties"], false, "{name}"); + } + } + } + #[test] fn data_version_resets_only_that_app_database_once() { let temp = tempfile::tempdir().unwrap(); @@ -1639,6 +1864,7 @@ mod tests { version: "1.0.0".to_owned(), data_version: 3, tools: Vec::new(), + provider_operations: Vec::new(), tasks: Vec::new(), schedules: Vec::new(), }; diff --git a/crates/pocket-pi-embedded/js/pi-agent.bundle.js b/crates/pocket-pi-embedded/js/pi-agent.bundle.js index 806a0e8..bf8f695 100644 --- a/crates/pocket-pi-embedded/js/pi-agent.bundle.js +++ b/crates/pocket-pi-embedded/js/pi-agent.bundle.js @@ -384,8 +384,8 @@ if(this.activeRun){throw new Error("Agent is already processing.")}const abortCo const failureMessage={role:"assistant",content:[{type:"text",text:""}],api:this._state.model.api,provider:this._state.model.provider,model:this._state.model.id,usage:EMPTY_USAGE,stopReason:aborted?"aborted":"error",errorMessage:error instanceof Error?error.message:String(error),timestamp:Date.now()};await this.processEvents({type:"message_start",message:failureMessage});await this.processEvents({type:"message_end",message:failureMessage});await this.processEvents({type:"turn_end",message:failureMessage, toolResults:[]});await this.processEvents({type:"agent_end",messages:[failureMessage]})}finishRun(){this._state.isStreaming=false;this._state.streamingMessage=void 0;this._state.pendingToolCalls=new Set;this.activeRun?.resolve();this.activeRun=void 0}async processEvents(event){switch(event.type){case"message_start":this._state.streamingMessage=event.message;break;case"message_update":this._state.streamingMessage=event.message;break;case"message_end":this._state.streamingMessage=void 0;this._state. messages.push(event.message);break;case"tool_execution_start":{const pendingToolCalls=new Set(this._state.pendingToolCalls);pendingToolCalls.add(event.toolCallId);this._state.pendingToolCalls=pendingToolCalls;break}case"tool_execution_end":{const pendingToolCalls=new Set(this._state.pendingToolCalls);pendingToolCalls.delete(event.toolCallId);this._state.pendingToolCalls=pendingToolCalls;break}case"turn_end":if(event.message.role==="assistant"&&event.message.errorMessage){this._state.errorMessage= -event.message.errorMessage}break;case"agent_end":this._state.streamingMessage=void 0;break}const signal=this.activeRun?.abortController.signal;if(!signal){throw new Error("Agent listener invoked outside active run")}for(const listener of this.listeners){await listener(event,signal)}}};var events=[];var pendingModels=new Map;var pendingTools=new Map;var agent=null;var emptyUsage=()=>({input:0,output:0,cacheRead:0,cacheWrite:0,reasoning:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}});function modelFor(config){const provider=config.provider||"openai";const deepseek=provider==="deepseek";const anthropic=provider==="anthropic";const defaultModel=deepseek?"deepseek-v4-pro":"gpt-5-mini";return{id:config.model||defaultModel,name:config.model||defaultModel,provider, -api:anthropic?"anthropic-messages":"openai-completions",baseUrl:deepseek?"https://api.deepseek.com":anthropic?"https://api.anthropic.com":"https://api.openai.com/v1",reasoning:deepseek,thinkingLevelMap:deepseek?{off:null,minimal:null,low:null,medium:null,high:"high",xhigh:"max",max:"max"}:void 0,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:deepseek?1e6:128e3,maxTokens:deepseek?384e3:16384}}function hostStream(model,context,options={}){const stream=new AssistantMessageEventStream; +event.message.errorMessage}break;case"agent_end":this._state.streamingMessage=void 0;break}const signal=this.activeRun?.abortController.signal;if(!signal){throw new Error("Agent listener invoked outside active run")}for(const listener of this.listeners){await listener(event,signal)}}};var events=[];var pendingModels=new Map;var pendingTools=new Map;var agent=null;var emptyUsage=()=>({input:0,output:0,cacheRead:0,cacheWrite:0,reasoning:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}});function modelFor(config){const provider=config.provider||"openai";const deepseek=provider==="deepseek";const anthropic=provider==="anthropic";const defaultModel=deepseek?"deepseek-v4-flash":"gpt-5-mini";return{id:config.model||defaultModel,name:config.model||defaultModel, +provider,api:anthropic?"anthropic-messages":"openai-completions",baseUrl:deepseek?"https://api.deepseek.com":anthropic?"https://api.anthropic.com":"https://api.openai.com/v1",reasoning:deepseek,thinkingLevelMap:deepseek?{off:null,minimal:null,low:null,medium:null,high:"high",xhigh:"max",max:"max"}:void 0,input:["text"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:deepseek?1e6:128e3,maxTokens:deepseek?384e3:16384}}function hostStream(model,context,options={}){const stream=new AssistantMessageEventStream; const partial={role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,usage:emptyUsage(),stopReason:"stop",timestamp:Date.now()};try{if(!globalThis.host)throw new Error("Pocket Pi Agent host is unavailable");const id=globalThis.host.startModel(JSON.stringify({model,context,options}));pendingModels.set(id,{stream,model,partial,started:false,thinkingStarted:false,textStarted:false,thinking:"",text:""})}catch(error){pushModelError(stream,model,String(error))}return stream} function ensureModelStarted(pending){if(pending.started)return;pending.started=true;pending.stream.push({type:"start",partial:{...pending.partial}})}function syncContent(pending){const content=[];if(pending.thinkingStarted){content.push({type:"thinking",thinking:pending.thinking,thinkingSignature:"reasoning_content"})}if(pending.textStarted)content.push({type:"text",text:pending.text});pending.partial.content=content}function pushThinkingDelta(pending,delta){if(!delta)return;if(pending.textStarted) throw new Error("thinking delta arrived after text output started");ensureModelStarted(pending);if(!pending.thinkingStarted){pending.thinkingStarted=true;syncContent(pending);pending.stream.push({type:"thinking_start",contentIndex:0,partial:{...pending.partial}})}pending.thinking+=delta;syncContent(pending);pending.stream.push({type:"thinking_delta",contentIndex:0,delta,partial:{...pending.partial}})}function textIndex(pending){return pending.thinkingStarted?1:0}function pushTextDelta(pending,delta){ diff --git a/crates/pocket-pi-embedded/js/src/entry.ts b/crates/pocket-pi-embedded/js/src/entry.ts index 76a955a..0d4056f 100644 --- a/crates/pocket-pi-embedded/js/src/entry.ts +++ b/crates/pocket-pi-embedded/js/src/entry.ts @@ -68,7 +68,7 @@ function modelFor(config: Config): any { const provider = config.provider || "openai"; const deepseek = provider === "deepseek"; const anthropic = provider === "anthropic"; - const defaultModel = deepseek ? "deepseek-v4-pro" : "gpt-5-mini"; + const defaultModel = deepseek ? "deepseek-v4-flash" : "gpt-5-mini"; return { id: config.model || defaultModel, name: config.model || defaultModel, diff --git a/crates/pocket-pi-embedded/src/lib.rs b/crates/pocket-pi-embedded/src/lib.rs index 22d95e5..1fa85a8 100644 --- a/crates/pocket-pi-embedded/src/lib.rs +++ b/crates/pocket-pi-embedded/src/lib.rs @@ -8,7 +8,7 @@ pub use pocket_pi_protocols::model::ModelStreamEvent; const AGENT_BUNDLE: &str = include_str!("../js/pi-agent.bundle.js"); const PRELUDE: &str = include_str!("../js/prelude.js"); -const MODEL_WORKER_STACK_BYTES: usize = 64 * 1024; +pub const MODEL_WORKER_STACK_BYTES: usize = 64 * 1024; const TOOL_WORKER_STACK_BYTES: usize = 16 * 1024; pub trait ModelBackend: Send + Sync { @@ -99,66 +99,68 @@ impl GuestAgent { let (host_tx, host_rx) = mpsc::channel::(); let host_rx = Arc::new(Mutex::new(host_rx)); let next_request = Arc::new(AtomicI32::new(1)); + let (model_tx, model_rx) = mpsc::channel::<(i32, String)>(); + let model_host_tx = host_tx.clone(); + std::thread::Builder::new() + .name("pi-model".into()) + .stack_size(MODEL_WORKER_STACK_BYTES) + .spawn(move || { + while let Ok((id, request)) = model_rx.recv() { + let worker_tx = model_host_tx.clone(); + let mut emit = |event| { + let event = match event { + ModelStreamEvent::Thinking(delta) => serde_json::json!({ + "type":"model_progress", + "id":id, + "thinkingDelta":delta, + "textDelta":"", + }), + ModelStreamEvent::Text(delta) => serde_json::json!({ + "type":"model_progress", + "id":id, + "thinkingDelta":"", + "textDelta":delta, + }), + }; + let _ = worker_tx.send(event); + }; + match backend.complete(&request, &mut emit) { + Ok(result) => { + let _ = worker_tx.send(serde_json::json!({ + "type":"model_done", + "id":id, + "result":result, + })); + } + Err(error) => { + let _ = worker_tx.send(serde_json::json!({ + "type":"model_error", + "id":id, + "error":format!("model backend failed: {error}"), + })); + } + } + } + }) + .map_err(|error| format!("spawn model worker: {error}"))?; guest .mount("host", { - let backend = backend.clone(); let tools = tools.clone(); move |ctx, host| { host.set( "startModel", Function::new(ctx.clone(), { - let backend = backend.clone(); + let model_tx = model_tx.clone(); let host_tx = host_tx.clone(); let next_request = next_request.clone(); move |request: String| -> i32 { let id = next_request.fetch_add(1, Ordering::Relaxed); - let backend = backend.clone(); - let host_tx = host_tx.clone(); - let worker_tx = host_tx.clone(); - let spawn = std::thread::Builder::new() - .name(format!("pi-model-{id}")) - .stack_size(MODEL_WORKER_STACK_BYTES) - .spawn(move || { - let mut emit = |event| { - let event = match event { - ModelStreamEvent::Thinking(delta) => serde_json::json!({ - "type":"model_progress", - "id":id, - "thinkingDelta":delta, - "textDelta":"", - }), - ModelStreamEvent::Text(delta) => serde_json::json!({ - "type":"model_progress", - "id":id, - "thinkingDelta":"", - "textDelta":delta, - }), - }; - let _ = worker_tx.send(event); - }; - match backend.complete(&request, &mut emit) { - Ok(result) => { - let _ = worker_tx.send(serde_json::json!({ - "type":"model_done", - "id":id, - "result":result, - })); - } - Err(error) => { - let _ = worker_tx.send(serde_json::json!({ - "type":"model_error", - "id":id, - "error":format!("model backend failed: {error}"), - })); - } - } - }); - if let Err(error) = spawn { + if model_tx.send((id, request)).is_err() { let _ = host_tx.send(serde_json::json!({ "type":"model_error", "id":id, - "error":format!("spawn model worker: {error}"), + "error":"model worker stopped", })); } id @@ -520,6 +522,7 @@ mod tests { struct ThinkingToolBackend { calls: AtomicUsize, requests: Arc>>, + threads: Arc>>, } impl ModelBackend for ThinkingToolBackend { @@ -528,6 +531,10 @@ mod tests { request_json: &str, on_event: &mut dyn FnMut(ModelStreamEvent), ) -> Result { + self.threads + .lock() + .unwrap() + .push(std::thread::current().id()); self.requests .lock() .unwrap() @@ -584,8 +591,9 @@ mod tests { } #[test] - fn preserves_thinking_and_executes_multiple_tools_sequentially() { + fn one_model_worker_preserves_thinking_and_sequential_tools() { let requests = Arc::new(Mutex::new(Vec::new())); + let threads = Arc::new(Mutex::new(Vec::new())); let executed = Arc::new(Mutex::new(Vec::new())); let guest = Guest::new().unwrap(); let agent = GuestAgent::mount( @@ -594,6 +602,7 @@ mod tests { Arc::new(ThinkingToolBackend { calls: AtomicUsize::new(0), requests: requests.clone(), + threads: threads.clone(), }), Arc::new(OrderedTools(executed.clone())), ) @@ -620,6 +629,9 @@ mod tests { assert!(done); assert_eq!(text, "complete"); assert_eq!(*executed.lock().unwrap(), ["first", "second"]); + let threads = threads.lock().unwrap(); + assert_eq!(threads.len(), 2); + assert_eq!(threads[0], threads[1]); let requests = requests.lock().unwrap(); assert_eq!(requests.len(), 2); assert_eq!(requests[0]["options"]["reasoning"], "high"); diff --git a/crates/pocket-pi-protocols/src/model.rs b/crates/pocket-pi-protocols/src/model.rs index 63a98d6..d654712 100644 --- a/crates/pocket-pi-protocols/src/model.rs +++ b/crates/pocket-pi-protocols/src/model.rs @@ -32,7 +32,7 @@ impl WirelessProvider { pub fn default_model(self) -> Option<&'static str> { match self { Self::OpenAi => Some("gpt-5-mini"), - Self::DeepSeek => Some("deepseek-v4-pro"), + Self::DeepSeek => Some("deepseek-v4-flash"), Self::OpenRouter | Self::Anthropic => None, } } @@ -131,7 +131,7 @@ mod tests { model: None, thinking_level: ThinkingLevel::Xhigh, }; - assert_eq!(settings.resolved_model().unwrap(), "deepseek-v4-pro"); + assert_eq!(settings.resolved_model().unwrap(), "deepseek-v4-flash"); assert_eq!(settings.thinking_level.id(), "xhigh"); } } diff --git a/docs/agentos-architecture.md b/docs/agentos-architecture.md index a39e664..517c92c 100644 --- a/docs/agentos-architecture.md +++ b/docs/agentos-architecture.md @@ -2,7 +2,7 @@ 状态:架构基线 + v1 实现记录(以“常驻 Pi Agent System App”为当前实现)。 -截至 2026-08-08,当前分支已经实现可运行的第一版:Pi Agent Root App、App +截至 2026-08-11,当前工作树已经实现可运行的第一版:Pi Agent Root App、App Supervisor、App Tool Catalog/Router、`AppTask` Schedule、`data.fs`、 `data.sqlite`、后台 Data Action、revision-coalesced projection cache,以及 Robinhood 和 Exa 两个 App。 @@ -29,10 +29,38 @@ Pi Agent = /workspace 的 owner + 特殊 System App App = Public Tools + Data Actions + SQLite State + Cached Fixed View ``` -这套设计要实现的 core goal 是:**Agent 不是固件外挂的聊天进程,而是 runtime -中拥有长期身份、顶层 workspace 和跨 App 能力的第一等 System App。** 用户切换 -View 或操作其他 App 时,Agent 的 turn、context 和 Tool execution 仍继续;切回 -Pi Agent 时看到的是同一个 session,而不是重新启动的 UI shell。 +### 1.1 三条核心设计原则 + +1. **App 是 Agent-facing capability、App-owned state 和 human-facing fixed View + 的同一个产品单元。** Tool 不是脱离 UI 的插件,View 也不是脱离能力的页面; + 二者读取同一份本地状态。 +2. **State 是能力与 View 之间唯一的协调面。** Agent Tool、App Schedule 和 UI + action 汇入同一个 Data Action;一次业务 transaction 成功后只发布一次单调 + revision,View 再查询 bounded SQLite projection。Agent 不手工同步 View,View + 也不直接执行 provider 副作用。 +3. **Agent 负责决定“为什么、何时做”,App 负责确定性地完成“怎么做、怎么保存、 + 怎么显示”。** AppTask、定时刷新和 View 渲染不需要模型 turn;模型是跨 App 的 + 编排者,而不是每个产品功能的运行时依赖。 + +Pi Agent 常驻 System App、Core/Bundle ownership 和前后台 Guest 生命周期,都是为了 +落实上述原则形成的架构约束;它们本身不是额外的产品 core concept。 + +### 1.2 PocketJS 与 Pocket Pi AgentOS 的层次 + +这两个层次不能合并理解: + +| 层 | 当前负责什么 | 不负责什么 | +| --- | --- | --- | +| PocketJS | 单个 QuickJS Guest、TS/TSX Bundle、UI tree/layout/render、`data.fs`、`data.sqlite`、`fetch()`/`pocket-net` 等 portable module contract | 不知道 Pi Agent、`/workspace` owner、有哪些 App、哪个 App 在前台、哪个 Tool 属于哪个 App | +| Pocket Pi AgentOS | `AppSupervisor`、System/ordinary App 生命周期、Tool Catalog/Router、Data Action queue、AppTask Schedule、revision delivery、App data ownership | 不重新实现 PocketJS 的 UI、JS engine、DB/FS/net module 形状 | +| Host adapter | 把 portable contract 接到 LittleFS/SQLite、ESP HTTP/TLS、MCP、Keychain/NVS、LCD/Touch 和资源限制 | 不拥有 Robinhood/Exa 的 schema、provider mapping 或 View | + +因此 `AppSupervisor`、`RoutedToolHost` 和 `AppDataRunner` 不是 PocketJS 缺失的基础能力, +而是建立在 PocketJS Guest/module primitives 之上的 **AgentOS 跨 App 产品语义**。 +PocketJS 类似可移植的嵌入式 application/UI runtime;它不应替具体产品决定 App +catalog、Agent Tool ownership 或后台任务生命周期。如果其中某个 primitive 将来被 +证明对所有 PocketJS 产品都通用,可以再上游抽象,但 Pocket Pi 的 ownership policy +仍留在 AgentOS。 ## 2. 设计目标 @@ -115,9 +143,10 @@ Fixed View SQLite bounded projection 的内存 cache + PocketJS UI Native Module 用固定 spec 把一个受限 Rust 能力挂载给 QuickJS Guest。 -PocketJS 已经定义了 `ui`、`data.sqlite`、`data.fs` 的 Module 形状。 -Pocket Pi 再补充 model、net、MCP、schedule、shell、device Settings 和 App -lifecycle。 +PocketJS 已经定义了 `ui`、`data.sqlite`、`data.fs`、`fetch()`/`pocket-net` 的 +portable contract。Pocket Pi Host 为这些 contract 提供板级实现,并补充 model、 +MCP、schedule、shell、device Settings 和 App lifecycle;其中 TLS、credential、 +endpoint allowlist 等仍属于 Host policy,不属于 PocketJS portable API。 ### 4.5 Runtime instance @@ -288,6 +317,12 @@ flowchart TB ... ``` +这是目标布局与当前布局的并集。当前 v1 已写入 fixed `builtin-v1` release、`current`、 +App SQLite 和 App-local `schedules.json`;`data/agent.sqlite`、持久 +`app-catalog.json`、`migrations.json` 仍未实现。当前 `plan.json` 也是 +`seed_builtin_releases()` 生成的最小 runtime/module 记录,不是 PocketJS resolver 的 +完整 target-specific plan。 + Pi Agent 的挂载: ```text @@ -314,10 +349,13 @@ release 完成校验后通过 `data.fs` atomic replace 切换。运行中的 Run export default defineApp({ id: "robinhood", tools: { - get_portfolio: { parameters: accountSchema, action: "getPortfolio" }, + search_tools: { parameters: searchSchema, action: "searchTools" }, + call: { parameters: deferredCallSchema, action: "validatedProviderCall" }, refresh_portfolio: { parameters: {}, action: "refreshPortfolio" }, + storage_status: { parameters: {}, action: "storageStatus" }, }, - actions: { getPortfolio, refreshPortfolio }, + providerOperations: checkedInRobinhoodAllowlist, + actions: { searchTools, validatedProviderCall, refreshPortfolio }, schedules: [{ id: "portfolio-refresh", everyMinutes: 5, action: "refreshPortfolio", args: {} }], view: RobinhoodView, @@ -330,21 +368,29 @@ export default defineApp({ agent-app.json Public Tools、Schedules、capability metadata data-action.js 后台网络、完整 body decode、normalize、SQLite transaction app.js + app.pak 前台 projection cache 和固定 View +tool-catalog.json 可选的 App-owned deferred Tool catalog 源文件 ``` +Robinhood 的 `tool-catalog.json` 会在构建 `data-action.js` 时被 bundler 内联,运行时 +由 `searchTools()` 和 `validatedProviderCall()` 读取;Rust contract test 也直接读取 +源 snapshot,检查 54 个 operation 与 `agent-app.json.providerOperations` 完全一致。 +`TOOLS.md` 只是这套契约的人类可读维护说明,不参与 build 或 runtime。 + 构建后产生两种不同性质的 metadata: -1. PocketJS `plan.json`:PocketJS resolver 生成的 target-specific build IR, - 保存 target、HostOps ABI、viewport、resolved capabilities 和 plan hash。 -2. Pocket Pi `agent-app.json`:从 `defineApp()` 静态提取的 runtime descriptor, - 保存 Public Tool schemas、Task/Schedule names、App data schema version 和 - artifact hashes。 +1. PocketJS `plan.json`:目标态由 PocketJS resolver 生成 target-specific build IR, + 保存 target、HostOps ABI、viewport、resolved capabilities 和 plan hash;当前 v1 + 只播种一份最小 placeholder。 +2. Pocket Pi `agent-app.json`:当前由 App checked in 的 runtime descriptor,保存 + id/version、Public Tool schemas、provider operation allowlist、Task/Schedule names + 和 App `dataVersion`。从 `defineApp()` 静态提取和 artifact hash 字段仍是目标态, + 当前代码尚未实现。 不能把这两个文件混为一谈。`plan.json` 继续遵守 PocketJS platform contract; App Supervisor 读取 `agent-app.json` 建立不需要启动 Guest 的 Tool/Schedule catalog。 -一个 release 的 metadata 合起来至少包含: +完整 release 的目标 metadata 至少应包含: - App id 和版本; - Public Tool schemas; @@ -353,7 +399,8 @@ catalog。 - viewport contract; - artifact hashes。 -Supervisor 不需要启动所有 App,就能从 descriptor 建立 Agent Tool Catalog。 +当前 fixed built-in catalog 已能只解析 descriptor 建立 Agent Tool Catalog,但 ordinary +View 仍会在 Supervisor 启动时全部 preload;动态发现和按需 residency 尚未实现。 ### App 内部依赖方向 @@ -376,19 +423,21 @@ UI refresh ─────┘ │ ## 9. App Supervisor -App Supervisor 是受信任 Host 代码,负责: +当前 v1 的 App Supervisor 是受信任 Host 代码,实际负责: -- 扫描本地 App releases; -- 校验 PocketJS plan、Agent App descriptor、hash、viewport 和 capabilities; -- 选择 active release; -- 创建和销毁 App Runtime; +- 构建固定 built-in App catalog,并解析 `agent-app.json`; +- 把固定 `builtin-v1` artifacts 原子写入各 App release 目录和 `current`; +- 根据 `dataVersion` 只重建变化 App 的开发期 SQLite; +- 启动一次 Pi Agent System App,并 preload 当前两个 ordinary View Runtime; - 挂载正确的 data root 和 Modules; - 切换前台 App; -- 路由 App Tool 和 AppTask; -- 保证一个 App 只有一个 execution lease; -- 注册和更新 App Schedules; -- 记录启动、完成、错误和超时; -- Bundle 启动失败时回退到上一个合法 release 或 recovery UI。 +- 路由 App Tool/AppTask,并用一个 bounded Data Action queue 串行执行; +- 注册、持久化并推进 App Schedules; +- 共享每个 App 的 SQLite owner 和 revision counter。 + +扫描任意安装 release、完整 plan/hash/signature 校验、动态创建/销毁 Runtime、迁移、 +上一版本回退和 recovery UI 尚未实现,统一列在 22.2/22.3,不能从本节职责反推为 +当前能力。 ### 常驻 System App 与前台 View @@ -425,6 +474,11 @@ Action 仍可更新该 App SQLite 并递增 revision;下次选择这个 View 但只能有一个 Data Action 在执行,且两者共享同一个 SQLite owner。这不是两份 App 实例,而是同一个 App runtime 的 data plane 与 view plane。 +当前 v1 进一步让所有 App 共用一个全局串行 Data Action worker。这是有意的资源与 +执行语义取舍,不作为当前缺陷:它换取 bounded concurrency、单一 SQLite/QuickJS +资源峰值和简单 completion ordering。只有实测出现不可接受的跨 App 阻塞后,才需要 +把 worker 拆成 per-App lease 或受限 worker pool。 + ## 10. Scheduler Scheduler 是 Rust 持有的时钟和持久 wake store。它支持两种 target: @@ -454,7 +508,7 @@ enum ScheduleTarget { 1. Supervisor 校验 Schedule 指向的 Task 确实存在。 2. 激活 release 时,按 `(app_id, schedule_id)` reconcile Schedule。 -3. Rust Scheduler 把 `next_run_at`、cadence、target、enabled 和 last result +3. Rust Scheduler 把 `next_run_at`、cadence、Task args 和最近一次 enqueue 状态 写入该 App 私有的 `data/.system/schedules.json`。App bundle 中的 `agent-app.json` 是声明源;运行状态不再集中混放在 workspace 根目录。 4. 到期后原子 claim wake。 @@ -467,11 +521,13 @@ ESP32 默认策略: - 同一 App 不并发执行; - 重启后错过多个周期只合并补跑一次; -- idempotency key 为 `::`; -- 执行时间和返回值大小有上限; - 连续失败不会自动唤醒 Agent; - App 可以从自己的 SQLite 显示 stale/error 状态。 +当前 `last_ok` 只表示 Schedule 到期时是否成功进入 Data Action queue,不表示 provider +业务最终成功。业务 completion 由 App 自己写入 SQLite,例如 Robinhood +`refresh_runs.status`;Scheduler 不复制第二份业务结果。 + ## 11. Tool Catalog 和 Tool Router 第一版 Pi Agent 看到两类 Tools: @@ -484,9 +540,11 @@ Native Tools schedule.set · schedule.list · schedule.cancel · schedule.clear App Tools - robinhood.get_portfolio + robinhood.search_tools + robinhood.call robinhood.refresh_portfolio - research.search + robinhood.storage_status + research.search · research.fetch · research.storage_status ``` Workspace 动态自定义 Tools 不属于 v1。 @@ -508,15 +566,20 @@ Model 产生 Tool call -> Tool Router Native name -> CoreToolHost / Native Module App name -> App Supervisor.enqueue_data_action(app, tool, args) - -> data-action.js -> native transport -> SQLite COMMIT + -> data-action.js -> native transport + -> 仅在 Fixed View 消费结果时写 SQLite + app.commit() + -> completion registry 返回真实 ToolResult -> normalized ToolResult -> Model ``` -Tool Router 负责 JSON 参数校验和结果大小限制。App Tool 名称必须带 App -namespace,避免冲突。会改变数据或调用 provider 的 App Tool 不在 View Guest -执行;纯只读的诊断 Tool(例如 `storage_status`)可以直接读取 bounded SQLite -projection。 +Public Tool 参数先由 Agent Tool layer 按 `agent-app.json` schema 校验;Robinhood +`robinhood.call` 的 deferred upstream schema 再由 Data Action 使用 +`tool-catalog.json` 校验。Tool Router 只负责 ownership、namespaced routing 和 bounded +completion wait,不声称实现通用结果截断。会改变数据或调用 provider 的 App Tool +不在 View Guest 执行;纯只读的诊断 Tool(例如 `storage_status`)可以直接读取 +bounded SQLite projection。Agent 发起的 App Tool 等待 Data Action 的真实 completion; +UI Task 和 Schedule 只需要快速 enqueue receipt。 ## 12. Robinhood MCP 如何接入 @@ -538,8 +601,10 @@ Firmware 负责: App 负责: -- 选择安全的 upstream operation 子集; -- 定义 Agent-facing Tool 名称和 schema; +- checked in 54 个 upstream operation snapshot 与 allowlist; +- 只向 Agent 常驻暴露 `search_tools`、`call`、`refresh_portfolio`、`storage_status` + 四个小 Tool; +- 按需返回某个 upstream Tool 的描述与完整 JSON Schema,并在调用前本地校验; - 把本地 Tool/Task 映射到 MCP call; - normalize provider response; - 写 Robinhood SQLite; @@ -556,8 +621,15 @@ function refreshPortfolio(args) { // 只在 headless Data Action Guest } ``` -上游 `tools/list` 不会自动变成模型权限。App release 明确选择哪些 Tool 可见。 -认证、session 和不可逆操作留在 native 或单独的批准边界里。 +上游 `tools/list` 不会自动变成 54 份常驻模型 schema。App release 明确选择允许的 +operation,并用 deferred lookup 避免 prompt 膨胀;native 再以同一份 +`providerOperations` 做精确 allowlist。认证和 session 留在 native,具体操作决策仍由 +Agent 和 Tool description 负责。 + +Robinhood 的研究、仓位、风险判断和是否执行交易属于 Agent policy;Pocket Pi native +边界只强制 credential isolation、operation allowlist 和 transport contract,不再复制 +一套独立 Trading Manager 或风险决策引擎。这是有意的 Agent/App ownership,而不是 +待修复的安全缺口。 ### 12.3 Exa 如何接入 @@ -573,7 +645,7 @@ research.search / research.fetch -> native HTTPS worker(注入 x-api-key) -> tick boundary drain / fetch Promise resolve -> normalize response - -> transaction 写 searches / search_results / documents + -> search transaction 只写固定 View 消费的 searches projection -> app.commit() 递增 Exa revision -> 前台下一 rendered frame 最多重查一次搜索历史 projection ``` @@ -684,14 +756,17 @@ Robinhood v1 schema: - `total_value`:按 `account_number + observed_at` 保存折线图所需的 value history; - `positions`:每个账户的当前持仓 rows; - `activities`:每个账户最近的 order/activity rows; -- `refresh_runs`:只保存 terminal succeeded/partial/failed result; -- `equity_historicals`、`pnl_trades`、`order_reviews`:分别由对应公开 Tool 更新。 +- `refresh_runs`:只保存 terminal succeeded/partial/failed result。 + +当前 schema v5 不创建 `equity_historicals`、`pnl_trades`、`order_reviews` 或通用 +raw-response cache。54 个 upstream Tool 都把结果返回 Agent;只有 Fixed View 当前消费 +的 `get_accounts`、`get_portfolio`、`get_equity_positions`、`get_equity_orders`、 +`get_realized_pnl`,以及 equity place/cancel 返回的 activity projection 会写 SQLite。 Exa v1 schema: -- `searches`:一次 search 的 query、时间、terminal status 和 result count; -- `search_results`:最多 8 条结构化 result rows; -- `documents`:`research.fetch` 得到的 bounded document text 和 metadata。 +- `searches`:固定 View 消费的 query、时间、terminal status、result count 和 + top result title。`research.fetch` 结果直接返回 Agent,不进入 SQLite。 开发阶段 schema 变化由 App descriptor 的 `dataVersion` 显式触发:Supervisor 在打开 SQLite 前只删除该 App 的 `.sqlite`,写入 App-local version marker,然后由 @@ -933,8 +1008,10 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 替换 System App;前台导航只选择已经存在的 surface。这里没有 Marketplace、 LRU、pinning 或 residency policy。 4. Tool Catalog/Router 合并 Native Tools 与 namespaced App Tools;Agent Loop - 和 Root View 已挂载在同一个 PocketJS Guest。模型与 Native Tool 的慢 I/O 在 - worker 完成,再以 event batch 回到这个 Guest,因此这些路径不阻塞 UI tick。 + 和 Root View 已挂载在同一个 PocketJS Guest。模型请求由一个常驻 worker 顺序 + 执行;ESP32 wireless backend 在该 worker 内复用同一个 HTTPS client,连接出错 + 后丢弃。模型与 Native Tool 的慢 I/O 再以 event batch 回到 Guest,因此这些 + 路径不阻塞 UI tick。 5. AgentWake store 持久化在 `.pi-agent/schedule.json`;Robinhood 的五分钟 AppTask store 持久化在 `apps/robinhood/data/.system/schedules.json`; refresh 是 `AppTask`,只 enqueue Data Action,不启动模型。 @@ -947,14 +1024,18 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 8. 每次成功 transaction 调用 `app.commit()`,递增该 App 的 `AtomicU32` revision。只有 foreground rendered frame 会比较 revision;连续多个 commit 合并成一次 `dataChanged`。普通 frame 与后台 App 不读 SQLite。 -9. Robinhood Data Action 拥有 curated Agent Tools、MCP operation mapping、完整 - response decode 和单次 refresh transaction;每个 operation 更新明确的 domain - table,不保存原始 Tool payload。View 只拥有 accounts/portfolio/positions/ +9. Robinhood Data Action 拥有 54 个 operation 的 checked-in deferred catalog、schema + validation、MCP operation mapping、完整 response decode 和单次 refresh transaction; + Pi Agent 常驻只看到 `search_tools`、`call`、`refresh_portfolio`、`storage_status` + 四个 Tool。每个 provider 结果都返回 Agent,但只有 Fixed View 消费的数据才更新 + domain table,不保存原始 Tool payload。View 只拥有 accounts/portfolio/positions/ activity/chart 的 bounded projection 和 cache。chart 的 1D/1W 窗口固定为 20 个 time buckets,SQLite query 最多返回 20 行,render 不读取 DB。 10. Exa Data Action 拥有 `research.search`、`research.fetch`、PocketJS `fetch()` - mapping 与 SQLite transaction;native 只允许 Exa 的 `/search`、`/contents` - 并注入 API key。View 从 `searches + search_results` 只读取最近 8 次搜索。 + mapping 与 search-history SQLite transaction;native 只允许 Exa 的 `/search`、 + `/contents` 并注入 API key。View 从 `searches` 先读取最新 10 条搜索历史,滚动 + 到边界后再按 10 条增量读取;每次 provider search 使用 Exa 标准的最多 10 条 + 结果,fetch 不落库。 11. Root View 已提供 Chat、App 入口、Files、Runs/Schedules、Settings 摘要和 屏幕键盘;Agent policy/loop 在 JS,workspace/App Tools 的受限底层实现和 AgentWake 由 Rust host 提供。Pocket Pi 的小型 shared Design System inventory @@ -963,15 +1044,16 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 12. ESP32-P4 使用 4 KiB PSRAM launcher,待 ESP-IDF entry task 退出后创建 64 KiB internal AgentOS runtime stack;App bundle 构建后会 minify 以降低固件 footprint,但不会把 minify 当作 stack isolation。App Data pthread 使用 128 - KiB PSRAM stack,并把 PSRAM allocation caps 只继承给按需创建的 96 KiB NET - worker;System App 的其他线程仍使用恢复后的 platform default。 + KiB PSRAM stack,并把 PSRAM allocation caps 继承给按需创建的 96 KiB NET + worker;常驻 model worker 使用 64 KiB PSRAM stack。System App 的其他线程仍 + 使用恢复后的 platform default。 13. Simulator tests 已证明:Agent turn 进行中打开 Robinhood,仍能收到完整回复 和 `agent_end`;前后台切换前后 System App Guest identity 不变;Exa 在前台 时 Agent 仍能路由 Robinhood App Tool、写 SQLite 并完成 turn。新增 contract test 证明 3 次 commit 在下一前台 frame 只 reload 一次,5 个普通 frame 不 reload,后台 2 次 commit 在重新打开时只 reload 一次。 14. Simulator Data Action tests 已证明:Exa search 用一次 transaction 写入 - `searches` 和 `search_results`;Robinhood 完整 fixture refresh 用一次 + `searches` View projection;Robinhood 完整 fixture refresh 用一次 transaction 写入各业务表与 terminal `refresh_runs`,并成功显示;provider failure 只写 failed refresh run、保留上一次业务 projection,而且可以再次 enqueue。 @@ -996,39 +1078,36 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 ESP32 owner 是原生 FreeRTOS task,主循环必须用 `vTaskDelay` 明确让出 CPU,不能用 pthread 语义的 `std::thread::sleep` 代替; 否则即使总 CPU/内存数字不高,CPU0 idle task 仍可能无法喂 watchdog。 -20. 当前代码已通过 `pocket-pi-agentos` 7 个 tests、ESP32-P4 Simulator 5 个 tests, - 通过 ESP32-P4 release cross-build 并刷入实体板。稳态冷启动测得 Root、Exa、 +20. 当前代码已通过 `pocket-pi-agentos` 10 个 tests、ESP32-P4 Simulator 6 个 tests; + workspace 合计 58 passed、0 failed、3 ignored。对应实现此前也通过 ESP32-P4 + release cross-build 并刷入实体板。稳态冷启动测得 Root、Exa、 Robinhood View preload 分别约 2.0、2.8、3.3 秒,约 20.5 秒进入完整 UI;没有 watchdog 或蓝屏。`dataVersion` reset 只发生一次,正常启动不重复 DDL。 21. 实机断网 Tool 验证已证明:Agent 调用 `research.search` 后,Data Action 在 native connection-ready gate 处 fail-fast,写一条 terminal error search,随后 删除不安全的 30 秒 ESP-Hosted 自动 reconnect 后,连续观察 120 秒没有 assertion - 或重启;用户仍可从 Settings 明确发起重连。`research.storage_status` 实际返回 - `searches=1`、`search_results=0`、`documents=0`; - `robinhood.storage_status` 返回 9 张新 domain tables,其中 `refresh_runs=1`、 - 其余业务表为 0。旧 `tool_events/search_history/raw JSON` 表均不存在。 -22. Exa 只保存有上限的规范化字段,不保存 provider 原始 JSON:每次 search 最多 - 8 条结果、highlight 最多 1200 字符,document text 最多 12000 字符。每个 - search/fetch 写事务同时删除 7 天前的 searches、对应 search_results 和 - documents;SQLite freelist 页面留作后续写入复用,不在闪存上自动执行 - `VACUUM`。`research.storage_status` 只返回行数、allocated/reusable bytes、 - retention policy 和最近一次运行状态,不再把完整 schema 或多行内容送入模型。 - 该策略直接 bump `dataVersion`/schema v4 并一次性重建 Exa cache,不保留旧索引 - 或兼容迁移分支。 -23. 正式 `pocket-net` 路径已在实体 ESP32-P4 上完成 Exa provider success:一次 - `research.search` 完成后 storage counts 为 `searches=4`、`search_results=13`、 - `documents=2`,其中新增 search 为 `ok` 且有 3 条结果。紧凑版 - `research.storage_status` 的实机 - Agent 回复为 114 字符,报告 4/13/2、7-day retention 和 57344/0 bytes;继续 - 观察 30 秒没有 watchdog。最终 schema v4 镜像又确认旧 cache 被一次性 reset, - compact status 先为 0/0/0;随后同一镜像的 provider search 持久化成功,重启后 - status 为 schema 4/4、1 search、3 results、0 documents、latest `ok`/3,继续 - 观察 30 秒仍无 watchdog。 + 或重启;用户仍可从 Settings 明确发起重连。 +22. Exa schema v5 只保存固定 View 消费的 bounded search-history row:query、时间、 + terminal status、result count、top title 和 error;provider 原始 JSON、其余结果 + 和 fetched document 都只返回 Agent,不进入 SQLite。每次 search transaction + 删除 7 天前的 searches;不自动执行 `VACUUM`。`research.storage_status` 只返回 + search count、allocated/reusable bytes、retention policy 和最近一次运行状态。 +23. 正式 `pocket-net` 路径曾在 schema v4 镜像的实体 ESP32-P4 上完成 Exa provider + success、SQLite 持久化、重启恢复和 30 秒稳定性观察。schema v5 只收窄 App-owned + projection,不改变已验证的 `/search`、`/contents` transport contract。 24. UART bridge 现在默认复用 Keychain 中已有的 Robinhood OAuth session,并只把 access token 注入板子的 RAM-only boot config;`--provision-robinhood` 只在没有 saved authorization 时交互补录。未传该 flag 的实机 `get_accounts` 已完成 MCP initialize 与 provider HTTP 200,收到 7222-byte body,不再出现 `OAuth token not provided`。 +25. Agent 发起 App Tool 时,`RoutedToolHost` 通过 completion registry 等待真实 + Data Action 结果,不再把 queued receipt 当作模型结果。Exa 和 Robinhood 的 + provider payload 都只放进 ToolResult `text`;不再同时复制到 `details`。View 内 + 的小型 `storage_status` 诊断仍可使用结构化 `details`。 +26. 最新实机链路已完成 Exa search → fetch → DeepSeek 最终总结;模型 worker 内复用 + HTTPS client 后,该轮没有 TLS `-0x3000`、pthread 创建失败或重启。大 Tool Result + 同步进入 QuickJS context 时仍出现 task-watchdog warning,所以持续无人值守稳定性 + 不能视为已经闭合。 ### 22.2 待补齐,不能视为已实现 @@ -1054,17 +1133,36 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 - 通用 Data Action runner 已在当前实机验证 FreeRTOS pthread stack、断网 failure transaction、SQLite dump、network fail-fast 与 provider success;持续 触摸切换和成功/失败交替 retry 仍待验证。 -- 当前修改型 App Tool 返回的是 queued run receipt,Data Action completion 记录在 - App SQLite 和日志。若 Agent 需要同步获得 provider 的最终 ToolResult,应在后续 - 增加一个 bounded completion delivery contract;不能为此把网络调用搬回 View - 或 host tick。 +- Agent Tool completion 已实现,但当前 Router 的 bounded wait 为 45 秒;Exa transport + 自身允许 60 秒。两层 timeout 需要在后续统一,避免深度搜索仍在进行时 Agent 先收到 + Router timeout。 - v1 是一个 App-level revision。Robinhood 已将 DB read 限制在 initial/ `dataChanged` 和 account/span 的 bounded cache miss,但所有 projection cache 的 `loadedRevision` 仍需继续显式化,随后再用板上 query 计数确认交互路径为零重读。 -明确延后:Marketplace/distribution、ESP32 source editing、Agent-authored Tools、 -通用 live Tool hot-plug,以及不经编译的 declarative View schema。当前固定 catalog -直接 preload 全部普通 App View,不预先实现未来的 residency policy。 +### 22.3 日后扩展项目:Marketplace / Distribution + +当前 v1 固定 `builtin-v1` catalog,启动时把内置 artifact 播种到 `/workspace` 并 +preload 全部普通 View。Marketplace 是独立的后续项目,不属于当前 runtime 完成度。 +启动该项目时按下面的依赖顺序扩展: + +1. 定义完整 release manifest:真实 PocketJS `plan.json`、artifact hashes、签名、 + publisher identity、capability requirements 和兼容版本。 +2. 实现 staging install、完整校验、atomic activation、上一版本 rollback 和最小 + recovery UI;损坏或未授权 Bundle 不能成为 `current`。 +3. 为 `dataVersion` 增加 App-owned migration transaction、失败恢复和 downgrade + policy,替代开发期直接删除单个 SQLite 文件的策略。 +4. 增加用户可见的 capability approval,特别是 credential-backed provider、network、 + schedule、device 和 workspace scope;凭据本身仍不得进入 App Bundle。 +5. 在安装/启停后重建 Tool Catalog,并先采用 Agent session reload;只有真实需求出现 + 后再实现 live Tool hot-plug。 +6. catalog 规模扩大并取得板上内存/启动时长证据后,再设计 lazy load、pinning、LRU + 或 residency policy,不提前把这些策略写进 v1。 +7. 最后补 distribution index、版本 channel、更新策略,以及 macOS/Simulator/ESP32 + 同一 package 的兼容性验证。 + +仍明确延后:ESP32 source editing、Agent-authored Tools、通用 live Tool hot-plug,以及 +不经编译的 declarative View schema。 ## 23. 验收标准 diff --git a/firmware/esp32-p4/src/agentos_main.rs b/firmware/esp32-p4/src/agentos_main.rs index 3376b20..43031c8 100644 --- a/firmware/esp32-p4/src/agentos_main.rs +++ b/firmware/esp32-p4/src/agentos_main.rs @@ -6,7 +6,7 @@ use std::time::Instant; use pocket_pi_agentos::{ AppServiceHost, AppSupervisor, RoutedToolHost, DATA_ACTION_STACK_BYTES, }; -use pocket_pi_embedded::{AgentEvent, ModelBackend, ToolHost}; +use pocket_pi_embedded::{AgentEvent, ModelBackend, ToolHost, MODEL_WORKER_STACK_BYTES}; use pocket_pi_protocols::model::ModelBackendSettings; use pocket_pi_tools::CoreToolHost; use pocketjs_esp32p4_ppa::{EspIdfPpaOps, RenderTargetState, Renderer}; @@ -126,7 +126,7 @@ pub fn run() -> anyhow::Result<()> { runtime_config.exa_api_key, runtime_config.robinhood_access_token, )); - let mut supervisor = with_data_action_pthread_config(|| { + let mut supervisor = with_psram_pthread_config(DATA_ACTION_STACK_BYTES, || { AppSupervisor::new(storage::WORKSPACE_ROOT, services) })?; supervisor.frame()?; @@ -158,7 +158,11 @@ pub fn run() -> anyhow::Result<()> { "thinkingLevel":model_settings.thinking_level.id(), "systemPrompt":"You are Pi Agent, the first-class system App in Pocket Pi AgentOS on an ESP32-P4. You can manage the top-level /workspace and use installed App tools. Use /workspace for durable memory, notes, plans, and artifacts; read and update relevant files when continuity matters. Be concise. Robinhood data is owned by the Robinhood App; Exa research history is owned by the Exa App." }); - supervisor.boot_agent(&config.to_string(), backend, Arc::new(routed_tools))?; + with_psram_pthread_config(MODEL_WORKER_STACK_BYTES, || { + supervisor + .boot_agent(&config.to_string(), backend, Arc::new(routed_tools)) + .map_err(anyhow::Error::msg) + })?; let mut messages = vec![Message { role: "assistant", @@ -504,24 +508,22 @@ pub fn run() -> anyhow::Result<()> { } } -fn with_data_action_pthread_config( +fn with_psram_pthread_config( + stack_size: usize, action: impl FnOnce() -> anyhow::Result, ) -> anyhow::Result { - // std::thread maps to ESP-IDF pthread. Its default stack allocation is - // internal RAM, where a QuickJS Data Action Guest cannot fit. Configure - // this worker family to use byte-addressable PSRAM. The Data Action thread - // must pass the allocation caps to its on-demand NET child; the platform - // default is restored before unrelated System App threads are created. + // Large persistent workers use PSRAM stacks. App Data passes this setting + // to its NET child; the platform default is restored after each spawn. let default = unsafe { esp_idf_svc::sys::esp_pthread_get_default_config() }; let mut config = default; - config.stack_size = DATA_ACTION_STACK_BYTES; + config.stack_size = stack_size; config.inherit_cfg = true; config.pin_to_core = 1; config.stack_alloc_caps = esp_idf_svc::sys::MALLOC_CAP_SPIRAM | esp_idf_svc::sys::MALLOC_CAP_8BIT; let configured = unsafe { esp_idf_svc::sys::esp_pthread_set_cfg(&config) }; if configured != esp_idf_svc::sys::ESP_OK { - anyhow::bail!("configure App Data Action pthread: ESP-IDF error 0x{configured:x}"); + anyhow::bail!("configure PSRAM pthread: ESP-IDF error 0x{configured:x}"); } let result = action(); let restored = unsafe { esp_idf_svc::sys::esp_pthread_set_cfg(&default) }; diff --git a/firmware/esp32-p4/src/app_services.rs b/firmware/esp32-p4/src/app_services.rs index 18a83dc..2f2224b 100644 --- a/firmware/esp32-p4/src/app_services.rs +++ b/firmware/esp32-p4/src/app_services.rs @@ -1,5 +1,5 @@ use core::time::Duration; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; use std::time::Instant; @@ -8,7 +8,9 @@ use embedded_svc::http::{client::Client as HttpClient, Method}; use embedded_svc::io::Write as _; use esp_idf_svc::http::client::{Configuration, EspHttpConnection}; use esp_idf_svc::io::EspIOError; -use pocket_pi_agentos::{AppServiceHost, HttpRequest, NetFailure, TransportCompletion}; +use pocket_pi_agentos::{ + AppCatalog, AppServiceHost, HttpRequest, NetFailure, TransportCompletion, ROBINHOOD_APP_ID, +}; use serde_json::{json, Value}; const ROBINHOOD_MCP_URL: &str = "https://agent.robinhood.com/mcp/trading"; @@ -23,6 +25,7 @@ struct EspAppServicesInner { network_ready: Arc, exa_api_key: Option, robinhood_access_token: Option, + robinhood_operations: BTreeSet, robinhood: Mutex, } @@ -38,10 +41,14 @@ impl EspAppServices { exa_api_key: Option, robinhood_access_token: Option, ) -> Self { + let robinhood_operations = AppCatalog::builtin() + .expect("built-in App catalog") + .provider_operations(ROBINHOOD_APP_ID); let inner = Arc::new(EspAppServicesInner { network_ready, exa_api_key, robinhood_access_token, + robinhood_operations, robinhood: Mutex::new(McpState { session_id: None, next_id: 1, @@ -52,18 +59,8 @@ impl EspAppServices { } impl EspAppServicesInner { - fn robinhood_operation_allowed(operation: &str) -> bool { - matches!( - operation, - "get_accounts" - | "get_portfolio" - | "get_equity_positions" - | "get_equity_orders" - | "get_equity_historicals" - | "get_realized_pnl" - | "get_pnl_trade_history" - | "review_equity_order" - ) + fn robinhood_operation_allowed(&self, operation: &str) -> bool { + self.robinhood_operations.contains(operation) } fn exa_http( @@ -115,7 +112,7 @@ impl EspAppServicesInner { .and_then(Value::as_str) .ok_or_else(|| "mcp.client callTool requires name".to_owned())?; let arguments = args.get("arguments").unwrap_or(&Value::Null); - if !Self::robinhood_operation_allowed(operation) { + if !self.robinhood_operation_allowed(operation) { return Err(format!( "Robinhood operation is not allowlisted: {operation}" )); @@ -161,7 +158,7 @@ impl EspAppServicesInner { .get("name") .and_then(Value::as_str) .ok_or_else(|| "mcp.client callTools requires a name for every call".to_owned())?; - if !Self::robinhood_operation_allowed(name) { + if !self.robinhood_operation_allowed(name) { return Err(format!("Robinhood operation is not allowlisted: {name}")); } } diff --git a/firmware/esp32-p4/src/backend/wireless.rs b/firmware/esp32-p4/src/backend/wireless.rs index 1b73fac..d19c2df 100644 --- a/firmware/esp32-p4/src/backend/wireless.rs +++ b/firmware/esp32-p4/src/backend/wireless.rs @@ -1,4 +1,5 @@ use core::time::Duration; +use std::cell::RefCell; use embedded_svc::http::{client::Client as HttpClient, Method}; use embedded_svc::io::Write; @@ -8,6 +9,11 @@ use pocket_pi_protocols::anthropic_messages; use pocket_pi_protocols::model::{ModelStreamEvent, WirelessProvider}; use pocket_pi_protocols::openai_chat; +// EspHttpConnection is thread-affine, so the resident model worker owns it. +thread_local! { + static MODEL_CLIENT: RefCell>> = const { RefCell::new(None) }; +} + pub struct WirelessBackend { provider: WirelessProvider, api_key: String, @@ -41,35 +47,8 @@ impl WirelessBackend { )), } } -} - -impl ModelBackend for WirelessBackend { - fn complete( - &self, - request_json: &str, - on_event: &mut dyn FnMut(ModelStreamEvent), - ) -> Result { - let (endpoint, body) = self.request(request_json)?; - let content_length = body.len().to_string(); - let bearer = format!("Bearer {}", self.api_key); - let mut headers = vec![ - ("accept", "text/event-stream"), - ("content-type", "application/json"), - ("content-length", content_length.as_str()), - ("user-agent", "pocket-pi-p4/0.1"), - ]; - match self.provider { - WirelessProvider::Anthropic => { - headers.push(("x-api-key", self.api_key.as_str())); - headers.push(("anthropic-version", "2023-06-01")); - } - WirelessProvider::OpenAi - | WirelessProvider::OpenRouter - | WirelessProvider::DeepSeek => { - headers.push(("authorization", bearer.as_str())); - } - } + fn connect() -> Result, String> { let configuration = Configuration { buffer_size: Some(4 * 1024), buffer_size_tx: Some(4 * 1024), @@ -77,12 +56,22 @@ impl ModelBackend for WirelessBackend { crt_bundle_attach: Some(esp_idf_svc::sys::esp_crt_bundle_attach), ..Default::default() }; - let mut client = HttpClient::wrap( + Ok(HttpClient::wrap( EspHttpConnection::new(&configuration) .map_err(|error| format!("initialize HTTPS: {error}"))?, - ); + )) + } + + fn send( + &self, + client: &mut HttpClient, + endpoint: &str, + body: &str, + headers: &[(&str, &str)], + on_event: &mut dyn FnMut(ModelStreamEvent), + ) -> Result { let mut request = client - .request(Method::Post, endpoint, &headers) + .request(Method::Post, endpoint, headers) .map_err(|error| format!("create model request: {error}"))?; request .write_all(body.as_bytes()) @@ -135,6 +124,53 @@ impl ModelBackend for WirelessBackend { } } +impl ModelBackend for WirelessBackend { + fn complete( + &self, + request_json: &str, + on_event: &mut dyn FnMut(ModelStreamEvent), + ) -> Result { + let (endpoint, body) = self.request(request_json)?; + let content_length = body.len().to_string(); + let bearer = format!("Bearer {}", self.api_key); + let mut headers = vec![ + ("accept", "text/event-stream"), + ("content-type", "application/json"), + ("content-length", content_length.as_str()), + ("user-agent", "pocket-pi-p4/0.1"), + ]; + match self.provider { + WirelessProvider::Anthropic => { + headers.push(("x-api-key", self.api_key.as_str())); + headers.push(("anthropic-version", "2023-06-01")); + } + WirelessProvider::OpenAi + | WirelessProvider::OpenRouter + | WirelessProvider::DeepSeek => { + headers.push(("authorization", bearer.as_str())); + } + } + + MODEL_CLIENT.with(|slot| { + let mut client = slot.borrow_mut(); + if client.is_none() { + *client = Some(Self::connect()?); + } + let result = self.send( + client.as_mut().unwrap(), + endpoint, + &body, + &headers, + on_event, + ); + if result.is_err() { + *client = None; + } + result + }) + } +} + fn drain_sse_lines( pending: &mut Vec, decoder: &mut ProviderStream, diff --git a/hosts/esp32-p4-sim/src/main.rs b/hosts/esp32-p4-sim/src/main.rs index a3cfbe6..f96a436 100644 --- a/hosts/esp32-p4-sim/src/main.rs +++ b/hosts/esp32-p4-sim/src/main.rs @@ -861,17 +861,15 @@ mod tests { assert_eq!(result.details["status"], "queued"); wait_for(|| { let storage = supervisor.invoke_tool("research.storage_status", "{}"); - storage.details["tableCounts"]["searches"] == 1 + storage.details["searches"] == 1 }); assert!(temp.path().join("apps/exa/data/exa.sqlite").exists()); let storage = supervisor.invoke_tool("research.storage_status", "{}"); assert!(!storage.is_error, "{}", storage.text); - assert_eq!(storage.details["tableCounts"]["searches"], 1); - assert_eq!(storage.details["tableCounts"]["searchResults"], 2); - assert_eq!(storage.details["tableCounts"]["documents"], 0); + assert_eq!(storage.details["searches"], 1); assert_eq!(storage.details["retentionDays"], 7); - assert_eq!(storage.details["schemaVersion"], 4); - assert_eq!(storage.details["expectedSchemaVersion"], 4); + assert_eq!(storage.details["schemaVersion"], 5); + assert_eq!(storage.details["expectedSchemaVersion"], 5); assert_eq!(storage.details["latestSearch"]["status"], "ok"); assert!(storage.text.len() < 240, "{}", storage.text); assert!(storage.details.get("tables").is_none()); @@ -889,7 +887,7 @@ mod tests { wait_for(|| { supervisor .invoke_tool("research.storage_status", "{}") - .details["tableCounts"]["searches"] + .details["searches"] == 1 }); @@ -898,12 +896,7 @@ mod tests { let handle = database.open("exa"); assert!(handle >= 0); assert_eq!( - database.exec( - handle, - "UPDATE searches SET searched_at=0;\ - INSERT INTO documents(url,fetched_at,title,published_at,author,text)\ - VALUES('https://expired.example',0,NULL,NULL,NULL,'expired');", - ), + database.exec(handle, "UPDATE searches SET searched_at=0;"), 0, "{}", database.last_error(handle) @@ -919,9 +912,7 @@ mod tests { == 2 }); let storage = supervisor.invoke_tool("research.storage_status", "{}"); - assert_eq!(storage.details["tableCounts"]["searches"], 1); - assert_eq!(storage.details["tableCounts"]["searchResults"], 2); - assert_eq!(storage.details["tableCounts"]["documents"], 0); + assert_eq!(storage.details["searches"], 1); } #[test] @@ -937,12 +928,10 @@ mod tests { let exa = supervisor.invoke_tool("research.storage_status", "{}"); assert!(!exa.is_error, "{}", exa.text); - assert_eq!(exa.details["tableCounts"]["searches"], 0); - assert_eq!(exa.details["tableCounts"]["searchResults"], 0); - assert_eq!(exa.details["tableCounts"]["documents"], 0); + assert_eq!(exa.details["searches"], 0); assert_eq!(exa.details["retentionDays"], 7); assert_eq!(exa.details["schemaVersion"], 0); - assert_eq!(exa.details["expectedSchemaVersion"], 4); + assert_eq!(exa.details["expectedSchemaVersion"], 5); assert!(exa.details["latestSearch"].is_null()); } From d9f26d742248c6b0f4c03ebcfb2621f748240e7a Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Tue, 11 Aug 2026 12:58:48 +0800 Subject: [PATCH 10/24] refactor(agentos): remove legacy runtime paths --- .github/workflows/ci.yml | 4 - Cargo.lock | 1 - README.md | 8 +- apps/exa/app.tsx | 2 - apps/exa/dist/app.js | 2 +- apps/pi-agent/app.tsx | 11 - apps/pi-agent/dist/agent.js | 8 +- apps/pi-agent/dist/app.js | 22 +- apps/robinhood/app.tsx | 4 - apps/robinhood/data-action.ts | 4 +- apps/robinhood/dist/app.js | 2 +- apps/robinhood/dist/data-action.js | 4 +- crates/pocket-pi-agentos/src/lib.rs | 177 +++----------- crates/pocket-pi-embedded/Cargo.toml | 2 + crates/pocket-pi-embedded/js/env.d.ts | 1 - .../pocket-pi-embedded/js/pi-agent.bundle.js | 8 +- crates/pocket-pi-embedded/js/src/entry.ts | 6 +- crates/pocket-pi-embedded/src/lib.rs | 121 +--------- crates/pocket-pi-protocols/src/model.rs | 2 - crates/pocket-pi-tools/src/lib.rs | 77 ------ crates/pocket-pi-tools/src/schedule.rs | 2 - crates/pocket-pi/src/lib.rs | 4 +- crates/pocket-pi/src/tests.rs | 226 +----------------- docs/agentos-architecture.md | 23 +- firmware/esp32-p4/Cargo.lock | 1 - firmware/esp32-p4/Cargo.toml | 1 - hosts/esp32-p4-sim/Cargo.toml | 1 - hosts/esp32-p4-sim/src/main.rs | 79 +----- js/src/pi-full/driver.ts | 2 +- js/src/pi-full/persist-probe.ts | 2 +- 30 files changed, 104 insertions(+), 703 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f2f2da..935d68b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,9 +39,5 @@ jobs: - name: Build run: cargo build --workspace --all-targets - # Runs the unit + module-system suite. The Path B integration tests are - # #[ignore]: they need the ~13 MB esbuild bundle (git-ignored; built with - # `node js/build-pi-full.mjs`) and, for the turn tests, an API key + proxy — - # so they're driven locally, not in CI. - name: Test run: cargo test --workspace diff --git a/Cargo.lock b/Cargo.lock index 9661827..d0f2de7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2637,7 +2637,6 @@ dependencies = [ "pocket-pi-tools", "pocket-ui-wgpu", "pocket3d", - "pocketjs-core", "serde_json", "tempfile", "ureq", diff --git a/README.md b/README.md index da0e126..26aaa38 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ The current firmware target is the ### Build all three modes ```sh +cargo xtask build agentos-apps cargo xtask build macos cargo xtask build esp32-p4-sim cargo xtask build esp32-p4 @@ -213,9 +214,10 @@ The shared PocketJS device UI includes: - touch keyboard and next-schedule status. Settings is an embedded-device feature and is not linked into native macOS -Pocket Pi. This repository does not include Robinhood or Exa UI, clients, -credentials or tools. External products add their own plugin/tool and UI -adapters without changing Agent core. +Pocket Pi. The embedded AgentOS ships Pi Agent as its resident System App and +Robinhood and Exa as ordinary Apps. Each ordinary App owns its Tool catalog, +Data Action, SQLite projection and fixed PocketJS View; native hosts provide +only scoped credentials, transport and hardware adapters. ## Desktop profile diff --git a/apps/exa/app.tsx b/apps/exa/app.tsx index b1a38e8..cfcd540 100644 --- a/apps/exa/app.tsx +++ b/apps/exa/app.tsx @@ -154,7 +154,6 @@ mount(() => ); (globalThis as any).PocketPiApp = { tick() { return ""; }, - update() { return ""; }, dataChanged(eventsLine: string) { const events = parse(eventsLine); const revision = Array.isArray(events) @@ -172,7 +171,6 @@ mount(() => ); return JSON.stringify({ text: error instanceof Error ? error.message : String(error), isError: true }); } }, - invokeTask(name: string) { return JSON.stringify({ text: "Unknown Exa task: " + name, isError: true }); }, tap(x: number, y: number) { if (y < 112 && x < 100) return JSON.stringify({ type: "navigate", app: "pi-agent" }); return ""; diff --git a/apps/exa/dist/app.js b/apps/exa/dist/app.js index c089969..297251f 100644 --- a/apps/exa/dist/app.js +++ b/apps/exa/dist/app.js @@ -6,4 +6,4 @@ SELECT id,searched_at,status,result_count,error FROM searches ORDER BY id DESC LIMIT 1 `).get():null,Y={database:"exa.sqlite",schemaVersion:Z,expectedSchemaVersion:uJ,retentionDays:u6,searches:X,allocatedBytes:J*Q,reusableBytes:J*$,latestSearch:W},j=W,U=j?` Latest #${j.id??"?"}: ${j.status??"unknown"}, ${j.result_count??0} results.`:" No searches yet.";return{text:`Exa storage (schema ${Z}/${uJ}): ${X} searches; ${u6}-day retention; ${Y.allocatedBytes} bytes allocated (${Y.reusableBytes} reusable).${U}`,details:Y}}function r1(){return k(T,{class:"flex-col w-full h-full bg-slate-50",get children(){return[k(N1,{title:"EXA RESEARCH",back:!0,metaTop:"POCKET APP",metaBottom:"SQLITE HISTORY"}),k(m1,{eyebrow:"AGENT RESEARCH MEMORY",title:"Search history",description:"Every research.search call is saved here automatically.",tone:"info"}),k(T,{class:"grow px-6 pt-4 flex-col",get children(){return[k(V4,{get when(){return cJ().length===0},get children(){return k(v1,{icon:"E",title:"No searches yet",detail:`Ask Pi Agent to research a topic. -The search and its results will appear here.`,tone:"info"})}}),k(V4,{get when(){return cJ().length>0},get children(){return k(E1,{get count(){return cJ().length},rowHeight:l1,height:c1,focusRows:!1,onNearEnd:a1,renderRow:(J)=>{let Q=()=>cJ()[J];return k(T,{class:"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[k(T,{class:"w-[474] flex-col gap-2",get children(){return[k(u,{class:"text-lg text-slate-900 font-bold",get children(){return Q().query.slice(0,60)}}),k(u,{class:"text-base text-slate-500",get children(){return(Q().top_title||Q().error||"No result title").slice(0,76)}}),k(u,{class:"text-base text-indigo-600 font-bold",get children(){return d1(Q().searched_at)}})]}}),k(T,{get["class"](){return e(()=>Q().status==="ok")()?F0.success.surface:F0.danger.surface},get children(){return k(u,{get["class"](){return e(()=>Q().status==="ok")()?F0.success.text:F0.danger.text},get children(){return e(()=>Q().status==="ok")()?Q().result_count+" RESULTS":"FAILED"}})}})]}})}})}})]}}),k(T,{class:"h-[96]",get children(){return k(u1,{get text(){return l6()},get tone(){return l6().includes("FAILED")?"danger":"neutral"},dark:!0})}})]}})}p6(0),D1(()=>k(r1,{})),globalThis.PocketPiApp={tick(){return""},update(){return""},dataChanged(J){let Q=i1(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),M0):M0;return p6($),""},invokeTool(J){try{let Q=J==="research.storage_status"?s1():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:Q.text,details:Q.details,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Unknown Exa task: "+J,isError:!0})},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});return""}}})(); +The search and its results will appear here.`,tone:"info"})}}),k(V4,{get when(){return cJ().length>0},get children(){return k(E1,{get count(){return cJ().length},rowHeight:l1,height:c1,focusRows:!1,onNearEnd:a1,renderRow:(J)=>{let Q=()=>cJ()[J];return k(T,{class:"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[k(T,{class:"w-[474] flex-col gap-2",get children(){return[k(u,{class:"text-lg text-slate-900 font-bold",get children(){return Q().query.slice(0,60)}}),k(u,{class:"text-base text-slate-500",get children(){return(Q().top_title||Q().error||"No result title").slice(0,76)}}),k(u,{class:"text-base text-indigo-600 font-bold",get children(){return d1(Q().searched_at)}})]}}),k(T,{get["class"](){return e(()=>Q().status==="ok")()?F0.success.surface:F0.danger.surface},get children(){return k(u,{get["class"](){return e(()=>Q().status==="ok")()?F0.success.text:F0.danger.text},get children(){return e(()=>Q().status==="ok")()?Q().result_count+" RESULTS":"FAILED"}})}})]}})}})}})]}}),k(T,{class:"h-[96]",get children(){return k(u1,{get text(){return l6()},get tone(){return l6().includes("FAILED")?"danger":"neutral"},dark:!0})}})]}})}p6(0),D1(()=>k(r1,{})),globalThis.PocketPiApp={tick(){return""},dataChanged(J){let Q=i1(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),M0):M0;return p6($),""},invokeTool(J){try{let Q=J==="research.storage_status"?s1():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:Q.text,details:Q.details,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});return""}}})(); diff --git a/apps/pi-agent/app.tsx b/apps/pi-agent/app.tsx index 027e7f3..405b9e7 100644 --- a/apps/pi-agent/app.tsx +++ b/apps/pi-agent/app.tsx @@ -479,17 +479,6 @@ queueMicrotask(() => refreshFiles("", true)); setProjection(JSON.parse(line)); return ""; }, - dataChanged() { - fileCache.delete(filePath()); - if (activeTab() === "files") refreshFiles(filePath(), true); - return ""; - }, - invokeTool() { - return JSON.stringify({ text: "Pi Agent has no App tools", isError: true }); - }, - invokeTask() { - return JSON.stringify({ text: "Pi Agent has no App tasks", isError: true }); - }, pointerDown(x: number, y: number) { setPressedKey(screen() === "keyboard" ? keyboardButtonAt(x, y) : null); return ""; diff --git a/apps/pi-agent/dist/agent.js b/apps/pi-agent/dist/agent.js index bf8f695..b22c52f 100644 --- a/apps/pi-agent/dist/agent.js +++ b/apps/pi-agent/dist/agent.js @@ -398,7 +398,7 @@ all_start",contentIndex,partial:{...pending.partial}});pending.stream.push({type api,provider:model.provider,model:model.id,usage:emptyUsage(),stopReason:"error",errorMessage:message,timestamp:Date.now()}})}function boot(configJson){const config=JSON.parse(configJson);const model=modelFor(config);const tools=(config.tools||[]).map(tool=>({name:tool.name,label:tool.label||tool.name,description:tool.description||"",parameters:tool.parameters||{type:"object",properties:{}},executionMode:"sequential",execute:(id,args)=>new Promise((resolve,reject)=>{try{if(!globalThis.host)throw new Error( "Pocket Pi Agent host is unavailable");const requestId=globalThis.host.startTool(id,tool.name,JSON.stringify(args||{}));pendingTools.set(requestId,{resolve,reject})}catch(error){reject(error instanceof Error?error:new Error(String(error)))}})}));agent=new Agent({initialState:{systemPrompt:config.systemPrompt||"You are Pocket Pi running on an embedded device.",model,thinkingLevel:model.reasoning?config.thinkingLevel||"high":"off",tools},streamFn:hostStream,toolExecution:"sequential"});agent.subscribe( event=>{const compact={type:event.type};if(event.type==="message_update"){compact.kind=event.assistantMessageEvent?.type;compact.delta=event.assistantMessageEvent?.delta}else if(event.type==="message_end"){compact.role=event.message?.role;compact.stopReason=event.message?.stopReason}else if(event.type==="tool_execution_start"||event.type==="tool_execution_end"){compact.name=event.toolName;compact.toolCallId=event.toolCallId;compact.isError=Boolean(event.isError)}events.push(compact)});events.push( -{type:"agent_ready"})}function prompt(text){if(!agent)throw new Error("prompt before boot");void agent.prompt(text).catch(error=>events.push({type:"agent_error",message:String(error)}))}function abort(){agent?.abort()}function tick(){const batch=JSON.parse(globalThis.host?.poll()||"[]");for(const event of batch){if(event.type==="model_progress"){const pending=pendingModels.get(event.id);if(!pending)continue;pushThinkingDelta(pending,event.thinkingDelta);pushTextDelta(pending,event.textDelta)}else if(event. -type==="model_done"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);try{finishModel(pending,JSON.parse(event.result))}catch(error){pushModelError(pending.stream,pending.model,String(error))}}else if(event.type==="model_error"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);pushModelError(pending.stream,pending.model,event.error)}else if(event.type==="tool_done"){const pending=pendingTools.get(event.id); -if(!pending)continue;pendingTools.delete(event.id);try{const result=JSON.parse(event.result);if(result.isError)throw new Error(String(result.text||"App tool failed"));pending.resolve({content:[{type:"text",text:String(result.text||"")}],details:result.details,terminate:Boolean(result.terminate)})}catch(error){pending.reject(error instanceof Error?error:new Error(String(error)))}}}}function drain(){return JSON.stringify({phase:agent?.state.isStreaming?"thinking":agent?"ready":"idle",messages:agent?. -state.messages.length||0,events:events.splice(0,events.length)})}globalThis.PocketPiEmbedded={boot,prompt,abort,tick,drain};})(); +{type:"agent_ready"})}function prompt(text){if(!agent)throw new Error("prompt before boot");void agent.prompt(text).catch(error=>events.push({type:"agent_error",message:String(error)}))}function tick(){const batch=JSON.parse(globalThis.host?.poll()||"[]");for(const event of batch){if(event.type==="model_progress"){const pending=pendingModels.get(event.id);if(!pending)continue;pushThinkingDelta(pending,event.thinkingDelta);pushTextDelta(pending,event.textDelta)}else if(event.type==="model_done"){ +const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);try{finishModel(pending,JSON.parse(event.result))}catch(error){pushModelError(pending.stream,pending.model,String(error))}}else if(event.type==="model_error"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);pushModelError(pending.stream,pending.model,event.error)}else if(event.type==="tool_done"){const pending=pendingTools.get(event.id);if(!pending)continue; +pendingTools.delete(event.id);try{const result=JSON.parse(event.result);if(result.isError)throw new Error(String(result.text||"App tool failed"));pending.resolve({content:[{type:"text",text:String(result.text||"")}],details:result.details,terminate:Boolean(result.terminate)})}catch(error){pending.reject(error instanceof Error?error:new Error(String(error)))}}}}function drain(){return JSON.stringify({phase:agent?.state.isStreaming?"thinking":agent?"ready":"idle",messages:agent?.state.messages.length|| +0,events:events.splice(0,events.length)})}globalThis.PocketPiEmbedded={boot,prompt,tick,drain};})(); diff --git a/apps/pi-agent/dist/app.js b/apps/pi-agent/dist/app.js index a00f1d6..74ca85b 100644 --- a/apps/pi-agent/dist/app.js +++ b/apps/pi-agent/dist/app.js @@ -1,16 +1,16 @@ -(()=>{var AJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return B1(this.context.count)},getNextContextId(){return B1(this.context.count++)}};function B1(J){let Q=String(J),$=Q.length-1;return AJ.context.id+($?String.fromCharCode(96+$):"")+Q}function j1(J){AJ.context=J}function Y6(){return{...AJ.context,id:AJ.getNextContextId(),count:0}}var z6=!1,W6=(J,Q)=>J===Q,S0=Symbol("solid-proxy"),G6=typeof Proxy==="function",H6=Symbol("solid-track"),KQ=Symbol("solid-dev-component"),nJ={equals:W6},K1=null,B6=V1,m=1,fJ=2,F1={owned:null,cleanups:null,context:null,owner:null},S=null,K=null,yJ=null,_J=null,b=null,C=null,T=null,tJ=0;function eJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?F1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>QJ(()=>$J(z)));S=z,b=null;try{return c(G,!0)}finally{b=$,S=Z}}function g(J,Q){Q=Q?Object.assign({},nJ,Q):nJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return R1($,q)};return[U1.bind($),Z]}function JJ(J,Q,$){let Z=D1(J,Q,!1,m);if(yJ&&K&&K.running)C.push(Z);else J0(Z)}function kJ(J,Q,$){$=$?Object.assign({},nJ,$):nJ;let Z=D1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,yJ&&K&&K.running)Z.tState=m,C.push(Z);else J0(Z);return U1.bind(Z)}function j6(J){return c(J,!1)}function QJ(J){if(!_J&&b===null)return J();let Q=b;b=null;try{if(_J)return _J.untrack(J);return J()}finally{b=Q}}function b0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function K6(J){if(K&&K.running)return J(),K.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(yJ||F6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[FQ,M1]=g(!1),F6;function U1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)J0(this);else{let Q=C;C=null,c(()=>Q0(this),!1),C=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function R1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw C=[],Error()},!1)}return Q}function J0(J){if(!J.fn)return;$J(J);let Q=tJ;if(P1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{c(()=>{K&&(K.running=!0),b=S=J,P1(J,J.tValue,Q),b=S=null},!1)})}function P1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=m,J.tOwned&&J.tOwned.forEach($J),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach($J),J.owned=null;return J.updatedAt=$+1,w0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)R1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function D1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(S===null);else if(S!==F1)if(K&&K.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(_J&&X.fn){let z=X.fn,[G,P]=g(void 0,{equals:!1}),D=_J.factory(z,P);b0(()=>D.dispose());let V,B=()=>K6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),K&&K.running){if(!V)V=_J.factory(z,B);return V.track(_)}return D.track(_)}}return X}function g0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===fJ)return Q0(J);if(J.suspense&&QJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===m)J0(J);else if((Q?J.tState:J.state)===fJ){let q=C;C=null,c(()=>Q0(J,$[0]),!1),C=q}}}function c(J,Q){if(C)return J();let $=!1;if(!Q)C=[];if(T)$=!0;else T=[];tJ++;try{let Z=J();return M6($),Z}catch(Z){if(!$)T=null;C=null,w0(Z)}}function M6(J){if(C){if(yJ&&K&&K.running)U6(C);else V1(C);C=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;T.push.apply(T,K.effects),Q=K.resolve;for(let X of T)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,c(()=>{for(let X of q)$J(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zB6($),!1);if(Q)Q()}function V1(J){for(let Q=0;Q{Z.delete($),c(()=>{K.running=!0,g0($)},!1),K&&(K.running=!1)})}}function Q0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)$J(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)O1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)$J(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function O1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return b0(()=>A1(X)),()=>{let P=J()||[],D=P.length,V,B;return P[H6],QJ(()=>{let N,h,a,HJ,LJ,M,j,H,L;if(D===0){if(z!==0)A1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[P6],q[0]=eJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=M&&H>=M&&Z[j]===P[H];j--,H--)a[H]=q[j],HJ[H]=X[j],G&&(LJ[H]=G[j]);N=new Map,h=Array(H+1);for(B=H;B>=M;B--)L=P[B],V=N.get(L),h[B]=V===void 0?-1:V,N.set(L,B);for(V=M;V<=j;V++)if(L=Z[V],B=N.get(L),B!==void 0&&B!==-1)a[B]=q[V],HJ[B]=X[V],G&&(LJ[B]=G[V]),B=h[B],N.set(L,B);else X[V]();for(B=M;BJ(Q||{}));return j1($),Z}}return QJ(()=>J(Q||{}))}function $0(){return!0}var O6={get(J,Q,$){if(Q===S0)return $;return J.get(Q)},has(J,Q){if(Q===S0)return!0;return J.has(Q)},set:$0,deleteProperty:$0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:$0,deleteProperty:$0}},ownKeys(J){return J.keys()}};function C0(J){return!(J=typeof J==="function"?J():J)?{}:J}function I6(){for(let J=0,Q=this.length;J=0;G--){let P=C0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in C0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:I6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var A6=(J)=>`Stale read from <${J}>.`;function SJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return kJ(D6(()=>J.each,J.children,Q||void 0))}function bJ(J){let Q=J.keyed,$=kJ(()=>J.when,void 0,void 0),Z=Q?$:kJ($,void 0,{equals:(q,X)=>!q===!X});return kJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?QJ(()=>X(Q?q:()=>{if(!QJ(Z))throw A6("Show");return $()})):X}return J.fallback},void 0,void 0)}var _6=(J)=>kJ(()=>J());function k6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(M,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(M,j,L,H);JJ((A)=>B(M,j(),A,H),L)}function B(M,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=h(M,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(M),H=j);else h(M,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=h(M,H,L);else if(k==="function")return JJ(()=>{let O=j();while(typeof O==="function")O=O();H=B(M,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return JJ(()=>H=B(M,O,H,L,!0)),()=>H;if(O.length===0){let TJ=h(M,H,L);if(I)return H=TJ}else if(Array.isArray(H))if(H.length===0)a(M,O,L);else N(M,H,O);else if(H==null||H==="")a(M,O);else N(M,I&&H||[P(M)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(M,H,L,j);h(M,H,null,j)}else if(H==null||H===""||!P(M))q(M,j);else HJ(M,j,P(M));H=j}return H}function _(M,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let jQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let TJ=G(O)===M;if(!k&&!I)TJ?HJ(M,A,O):q(M,A,H);else TJ&&X(M,O)}else k=!0}}else q(M,A,H);return[A]}function a(M,j,H){for(let L=0,A=j.length;LH.children=B(M,j.children,H.children));return JJ(()=>j.ref&&j.ref(M)),JJ(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(M,A,k,H[A]),H[A]=k}}),H}return{render(M,j){let H;return eJ((L)=>{H=L,V(j,M())}),H},insert:V,spread(M,j,H){if(typeof j==="function")JJ((L)=>LJ(M,j(),L,H));else LJ(M,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(M,j,H,L){return z(M,j,H,L),H},mergeProps:_1,effect:JJ,memo:_6,createComponent:L6,use(M,j,H){return QJ(()=>M(j,H))}}}function S6(J){let Q=k6(J);return Q.mergeProps=_1,Q}var k1=480,S1=272,BJ={view:0,text:1,image:2},b6=1,g6=-1,w6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},C6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},E6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},N6=1,MQ=2,UQ=1,RQ=2,PQ=131072,DQ=1,VQ=262144,LQ=1,OQ=1,IQ=1,AQ=2,_Q=4,kQ=8,SQ=16,bQ=1,gQ=2;function b1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var wQ=1,h6=1263551300,T6=1,f6=32,y6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},jJ=32896,CQ=0.016666666666666666;function g1(J){return J.__viewport??null}var E0=null;function x6(){return null}function w1(J,Q=x6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function v6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return w1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return w1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function m6(J){E0=J}function gJ(){if(!E0)throw Error("PocketJS: host not installed — call render() first");return E0}function E(){return gJ().ops}function u6(J){globalThis.frame=J}function l6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function p6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return b1($>>>16&255,$>>>8&255,$&255,255);return b1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function c6(J,Q){let $=C6[J];if(typeof Q==="string"){if($===U.color)return p6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var Z0=60,C1=[1,2,3,4,5,6,10,12,15,20,30,60],N0=Z0,ZJ=-1,d6=0,xJ=[];function i6(J){if(!Number.isFinite(J)||J<=0)return Z0;let Q=C1[0];for(let $ of C1)if(Math.abs($-J)Q.at<=ZJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>ZJ);for(let Q of J)Q.cb()}var h0=0.12,q0=jJ;function o6(J){q0=J===void 0?jJ:J&65535}function n6(){q0=jJ}function h1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function e6(){return h1(q0&255)}var T1=new Set,J8=0;function Q8(){T1.clear(),J8=0,n6()}function $8(J){for(let Q of[...T1])Q(J)}var KJ=null,f1=null;function Z8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function y1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){T0();let Q=KJ?KJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return f1.slice(Q.off,Q.off+Q.len)}var mJ=null,w=null,FJ=null,X0=0,MJ=[],y0=[],x0=[];function v1(J){if(mJ=J,w=null,FJ=null,X0=0,MJ.length=0,y0.length=0,x0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function X8(J,Q){J.onPress=Q??void 0}function Y8(J,Q){if(J.focusable=Q,c1(),!Q&&w===J)x(null)}function x(J){if(FJ&&FJ!==J)UJ(null);w=J,E().setFocus(J?J.id:0)}function UJ(J){if(FJ===J)return;let Q=E();if(FJ)Q.setActive?.(FJ.id,0);if(FJ=J,J)Q.setActive?.(J.id,1)}function v0(){return MJ.length>0?MJ[MJ.length-1]:mJ}function m0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function G8(){if(!w)return null;let J=v0();if(J&&!i(w,J))return null;for(let Q=y0.length-1;Q>=0;Q--){let $=y0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function H8(J){let Q=G8();if(!Q)return!1;let $=[];if(m0(Q.node,$),$.length===0){if(w)x(null);return!0}let Z=Q.columns,q=w?$.indexOf(w):-1;if(q<0)return x(m1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function B8(){if(!w)return null;let J=v0();if(J&&!i(w,J))return null;for(let Q=x0.length-1;Q>=0;Q--){let $=x0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function Y0(J){let Q=B8();if(Q&&Q.move(J))return;if(H8(J))return;W8(J)}function u1(){l1(w)}function l1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function z0(J){UJ(J)}function j8(J){x(J),l1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function u0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=u0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,p1=0;function c1(){p1++}var F8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],M8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function U8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=F8[Q]>>$&1,q=M8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function R8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):P8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(U8(),16,16,E6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function P8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&N6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function W0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=W0($[Z],Q);if(q)return q}return null}var G0=null;function d1(J){G0=J}function i1(J){let Q=MJ.length>0?MJ[MJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function s1(J,Q,$){return i1(a1(J,Q,$))}function a1(J,Q,$){if($!==void 0)return $===0?null:W0(G0??mJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return W0(G0??mJ,q(J,Q))}function D8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=g1(q);if(Z.vw=B?B.w:k1,Z.vh=B?B.h:S1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)R8(Z,q);let X=t6()*Z.speed,z=e6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=s6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=p1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=i1(W0(G0??mJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==w)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(UJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,UJ(null),B)u1()}}else if($&Z.button)UJ(null);return!0}function V8(J){let Q=J&~X0,$=X0&~J;if(X0=J,l&&D8(J,Q,$))return;if($&d.CIRCLE)UJ(null);if(Q===0)return;if(Q&d.DOWN)Y0("down");if(Q&d.RIGHT)Y0("right");if(Q&d.UP)Y0("up");if(Q&d.LEFT)Y0("left");if(Q&d.CIRCLE)UJ(w),u1()}var l0=null;function r1(J){l0=J}function wJ(){if(c1(),l0)l0()}function L8(J,Q){J.debugName=Q||void 0,wJ()}var qJ={id:b6,type:BJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},o1=Symbol.for("pocketjs.native-node"),p0=1,uJ=3,o=8,O8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function H0(J){return J.domAttrs??={}}function n1(J,Q){let $=J.domNodeType??(lJ(J)?uJ:p0),Z=$===uJ?B0(J.text??""):$===o?_8(J.domData??""):q4(J.domTag??K0(J));for(let q of Object.keys(J.domAttrs??{}))c0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)XJ(Z,n1(q,!0));return Z}function c0(J,Q,$){if(O8.has(Q)){EJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete H0(J)[Q];else H0(J)[Q]=$}function d0(J){if(J[o1]===!0)return J;return Object.defineProperty(J,o1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(lJ(J)?uJ:p0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else j0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else j0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(lJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(lJ(J))j0(J,Z);else if(E8(J),Z)XJ(J,B0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return Y4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??K0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===uJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??K0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){EJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===qJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return XJ(J,$),$},insertBefore($,Z){return XJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return XJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return n1(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){c0(J,$,Z)},removeAttribute($){c0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}d0(qJ);var i0=null;function I8(J){i0=J}var s0={unknownClass:0,unknownTexture:0},t1=new Map;function e1(J,Q){t1.set(J,Q)}var J4=new Map;function Q4(J,Q){J4.set(J,Q)}var CJ=new Set,A8=new Set;function $4(J){if(!J)return!1;if(A8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return d0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:p0,domTag:J})}function B0(J){let Q=E(),$=Q.createNode(BJ.text);return Q.setText($,J),d0({id:$,type:BJ.text,parent:null,children:[],text:J,domNodeType:uJ,domTag:"#text"})}function _8(J=""){let Q=B0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function j0(J,Q){E().replaceText(J.id,Q),J.text=Q,wJ()}function lJ(J){return J.type===BJ.text}function X4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function XJ(J,Q,$){let Z=E();if(X4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function pJ(J,Q){if(!Q)return;K8(Q),E().removeChild(J.id,Q.id),X4(Q),CJ.add(Q),wJ()}function k8(J){return J.parent??void 0}function S8(J){return J.children[0]}function Y4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function b8(J,Q){let $=E();if(wJ(),Q==null||Q===""){$.setStyle(J.id,g6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=i0?i0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);s0.unknownClass++;return}$.setStyle(J.id,Z)}function g8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=t1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);s0.unknownTexture++;return}$.setImage(J.id,Z)}function w8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=J4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);s0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function C8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=w6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,c6(G,P)),z=!0}if(z)wJ()}function EJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete H0(J)[Q];else H0(J)[Q]=$;switch(Q){case"class":return b8(J,$),$;case"onPress":case"on:press":return X8(J,$),$;case"src":return g8(J,$),$;case"sprite":return w8(J,$),$;case"style":return C8(J,$,Z),$;case"focusable":return Y8(J,!!$),$;case"debugName":return L8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${K0(J)}>`)}function E8(J){for(let Q of[...J.children])pJ(J,Q)}function K0(J){for(let Q of Object.keys(BJ))if(BJ[Q]===J.type)return Q;return String(J.type)}function N8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}EJ(J,Q,$,Z)}var h8=S6({createElement:q4,createTextNode:B0,replaceText:j0,isTextNode:lJ,setProperty:N8,insertNode(J,Q,$){XJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:k8,getFirstChild:S8,getNextSibling:Y4}),{render:T8,effect:EQ,memo:p,createComponent:Y,createElement:z4,insert:NQ,spread:f8,mergeProps:hQ,use:TQ}=h8,fQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},y8=null;function W4(J){y8=J}function x8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function G4(J,Q){let $=z4(J);return f8($,Q,!1),x8(Q.nodeRef,$),$}function F(J){return G4("view",J)}function R(J){return G4("text",J)}var yQ=new WeakMap,xQ=new WeakMap,v8={}!==null?Object.freeze({...{}}):Object.freeze({}),vQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:v8}),mQ=new Map,YJ=36000,a0=30,m8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(YJ),tapeAnalog:new Uint16Array(YJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-a0,saidHello:!1,hostCalls:0};function u8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-a0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)r1(()=>{W.treeDirty=!0}),r8();else r1(null);globalThis.__pocketDevtools=n8}function l8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)c8(),s8();let X=Q,z=$===void 0?jJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(YJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==jJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function j4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function K4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return j4(J.masks,0,Q)}function F4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return j4(J.analog??[],jJ,Q)}function M4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,f({t:"hello",app:W.app,host:o8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` -`))if(q.trim())d8(q)}}function d8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)f({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),r0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),r0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":U4();break;case"eval":{let Z=!0,q;try{q=F0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}f({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":f({t:"tape",tape:B4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}f({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())f({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else f({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=K4(Z),W.replayAnalog=Z.analog?F4(Z):null,W.replayTouch=Z.touch?M4(Z):null,W.replayAt=0;break}default:break}}function i8(){if(W.treeDirty&&W.frame-W.treeSentAt>=a0)U4();if(W.frame%m8===0)r0()}function s8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,f({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,f({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function r0(){f({t:"stats",frame:W.frame,nodes:D4(qJ),tapeLen:W.tapeLen,paused:W.paused})}function U4(){W.treeDirty=!1,W.treeSentAt=W.frame,f({t:"tree",frame:W.frame,root:P4(qJ)})}function a8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function o0(J,Q){if(Array.isArray(J)){for(let $ of J)o0($,Q);return}if(a8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)o0($,Q)}}function R4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)o0(Z,Q)}function P4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(R4(J,(q)=>{if(q.domNodeType===8)return;Z.push(P4(q))}),Z.length)Q.k=Z;return Q}function D4(J){let Q=1;return R4(J,($)=>{Q+=D4($)}),Q}function r8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{f({t:"log",level:$,args:q.map((X)=>F0(X))}),Z?.apply(Q,q)}}}function F0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?V4(X):JSON.stringify(V4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>F0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${F0(z,Q+1)}`).join(", ")}}`}function V4(J){return J.length>200?J.slice(0,199)+"…":J}function o8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var n8={get frame(){return W.frame},dumpTape:()=>B4(),replay:(J)=>{W.replayMasks=K4(J),W.replayAnalog=J.analog?F4(J):null,W.replayTouch=J.touch?M4(J):null,W.replayAt=0}},L4=new Map,n0=new Map;function O4(J){return J.trim().replace(/\s+/g," ")}function I4(J){return J.split(" ").sort().join(" ")}var A4=-1;function t8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=O4(Q);L4.set(Z,$);let q=I4(Z),X=n0.get(q);n0.set(q,X!==void 0&&X!==$?A4:$)}}function e8(J){let Q=O4(J),$=L4.get(Q);if($!==void 0)return $;let Z=n0.get(I4(Q));return Z===A4?void 0:Z}var t0=9,J2=(1<{let q=($&$2)!==0,X=q?e0:t0,z=q?Z2:J2;return Object.freeze({id:$>>>(q?q2:Q2)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Y2(){return M0}function z2(){M0=J1}var _4=8,zJ=8,W2=3,G2=8,H2=6,B2=0.5,s=1,cJ=2,Q1=4,RJ=8,NJ=[],k4=0,U0=0,WJ=Array.from({length:_4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(zJ),histY:new Int16Array(zJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function j2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function K2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=a1(Q,$,Z.fact);let G=Z.hit;if(G)return j2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=NJ[z];if(G.disposed)continue;if(k4>0&&!G.opts.allowWhenBlocked)continue;if(!K2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function U2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%zJ,J.histLenz||Z>z))q.flags[J.slot]|=cJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(cJ|Q1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??B2)*E1()));if(J.frames=0)NJ.splice($,1)},cancel(){if(!Q.disposed)g4(Q)},get panning(){for(let $ of WJ)if($.used&&Q.flags[$.slot]&RJ)return!0;return!1}}}function L2(J){let Q=V2(J);return b0(()=>Q.dispose()),Q}function w4(){NJ.length=0,k4=0,U0=0;for(let J of WJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function O2(){return L2({onDown:(J)=>{let Q=s1(J.x,J.y,J.hit);if(Q)z0(Q)},onTap:(J)=>{z0(null);let Q=s1(J.x,J.y,J.hit);if(Q)j8(Q)},onUp:()=>z0(null),onCancel:()=>z0(null)})}var I2=1,$1=new Map,R0=[];function A2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function _2(){I2=1,$1.clear(),R0=[]}function k2(){if(R0.length===0)return;let J=R0;R0=[];for(let{id:Q,result:$}of J){let Z=$1.get(Q);if(!Z)continue;$1.delete(Q),A2()?.({t:"delivery",frame:N1(),id:Q,kind:Z.kind}),Z.onResult($)}}var C4=new Set;function S2(){if(C4.size===0)return;for(let J of C4)J()}var b2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[28] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-base text-orange-600 font-bold":9,"h-[76] pt-3 text-lg text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-base text-emerald-700 font-bold":13,"h-[84] pt-3 text-lg text-slate-900":14,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":15,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":16,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":17,"text-base text-slate-600 font-bold":18,"pt-6 text-lg text-slate-500":19,"pt-6 text-lg text-slate-900 font-bold":20,"h-[146] px-6 pt-7 flex-col bg-slate-50":21,"h-[80]":22,"h-[1060] px-6 pt-5 flex-col":23,"h-[48] px-4 justify-center bg-slate-100":24,"text-base text-slate-600":25,"pt-[10] flex-col gap-[12]":26,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":27,"w-[48] h-[48] items-center justify-center bg-blue-100":28,"w-[48] h-[48] items-center justify-center bg-emerald-100":29,"text-lg text-blue-700 font-bold":30,"text-lg text-emerald-700 font-bold":31,"w-[474] flex-col gap-2":32,"text-lg text-slate-900 font-bold":33,"text-base text-slate-500":34,"pt-20 pl-10 text-lg text-slate-500":35,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":36,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":37,"h-[1060] px-6 pt-7 flex-col gap-4":38,"text-base text-slate-500 font-bold":39,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":40,"flex-row items-center gap-5":41,"w-[68] h-[68] items-center justify-center bg-emerald-100":42,"text-xl text-emerald-700 font-bold":43,"flex-col gap-2":44,"text-xl text-slate-900 font-bold":45,"text-lg text-slate-600":46,"text-2xl text-orange-600":47,"w-[68] h-[68] items-center justify-center bg-indigo-100":48,"text-xl text-indigo-700 font-bold":49,"mt-4 h-[112] px-6 justify-center bg-slate-100":50,"relative h-[154] px-5 pt-5 flex-col bg-white":51,"pt-3 text-lg text-orange-600 font-bold":52,"pt-3 text-base text-slate-500":53,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":54,"text-lg text-white font-bold":55,"h-[40] pt-3 text-base text-slate-500":56,"h-[470] flex-col gap-2":57,"h-[214] px-7 items-center justify-center bg-slate-100":58,"text-lg text-slate-500 font-bold":59,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":60,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":61,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":62,"h-[160] px-5 pt-5 flex-col bg-white":63,"pt-3 text-lg text-slate-900 font-bold":64,"pt-3 text-base text-slate-600":65,"h-[108] pt-7 flex-row gap-4":66,"w-[316] h-[80] items-center justify-center bg-slate-100":67,"w-[340] h-[80] items-center justify-center bg-red-100":68,"text-lg text-red-500 font-bold":69,"h-[1052] px-6 pt-5 flex-col":70,"h-[270] px-[22] pt-6 bg-white":71,"text-lg text-slate-900":72,"text-lg text-slate-400":73,"h-[86] px-1 flex-row items-center justify-between":74,"w-[132] h-[58] items-center justify-center bg-slate-300":75,"w-[132] h-[58] items-center justify-center bg-slate-100":76,"text-base text-slate-900 font-bold":77,"h-[140] flex-row gap-2":78,"grow h-[120] items-center justify-center bg-slate-300":79,"grow h-[120] items-center justify-center bg-white":80,"w-[104] h-[120] items-center justify-center bg-slate-300":81,"w-[104] h-[120] items-center justify-center bg-slate-100":82,"h-[176] flex-row gap-2":83,"w-[92] h-[156] items-center justify-center bg-slate-300":84,"w-[92] h-[156] items-center justify-center bg-slate-100":85,"w-[300] h-[156] items-center justify-center bg-slate-300":86,"w-[300] h-[156] items-center justify-center bg-slate-100":87,"w-[144] h-[156] items-center justify-center bg-slate-300":88,"w-[144] h-[156] items-center justify-center bg-slate-100":89,"w-[112] h-[156] items-center justify-center bg-emerald-700":90,"w-[112] h-[156] items-center justify-center bg-emerald-500":91,"text-base text-slate-950 font-bold":92,"h-[108] px-6 py-3 flex-col bg-slate-50":93,"h-[84] items-center justify-center bg-slate-300":94,"h-[84] items-center justify-center bg-slate-100":95,"h-[1168] px-6 pt-5 flex-col":96,"h-[82] px-4 justify-center bg-white":97,"w-[584] h-[900] px-5 pt-5 bg-slate-950":98,"text-base text-slate-200":99,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":100,"text-lg text-orange-600 font-bold":101,"w-[584] h-[900] px-5 pt-5 bg-white":102,"text-base text-slate-900":103,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":104,"absolute inset-0 z-50 flex-col items-center justify-center":105,"absolute inset-0 bg-slate-950":106,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":107,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":108,"flex-row flex-wrap":109,grow:110,"text-2xl text-white font-bold":111,"text-2xl text-slate-950 font-bold":112,"px-6":113,"px-6 py-5":114,"gap-4":115,"rounded-xl shadow bg-white border-slate-100":116,"rounded-xl shadow bg-emerald-100 border-emerald-500":117,"bg-white":118,"bg-slate-100":119,"bg-slate-950":120,"px-3 py-2 rounded-lg bg-slate-100":121,"px-3 py-2 rounded-lg bg-indigo-100":122,"text-base text-indigo-700 font-bold":123,"px-3 py-2 rounded-lg bg-emerald-100":124,"px-3 py-2 rounded-lg bg-amber-100":125,"text-base text-amber-700 font-bold":126,"px-3 py-2 rounded-lg bg-red-100":127,"text-base text-red-500 font-bold":128,"w-[34] h-[34] rounded-lg bg-amber-400":129,"w-[34] h-[34] rounded-lg bg-red-500":130,"w-[34] h-[34] rounded-lg bg-slate-800":131,"w-[34] h-[34] rounded-lg bg-emerald-500":132,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":133,"flex-row items-center gap-4":134,"w-[34] text-2xl text-white font-bold":135,"w-[332] flex-col items-end gap-2":136,"text-base text-slate-300 font-bold":137,"text-base text-slate-400":138,"h-[166] px-6 pt-6 flex-col gap-3":139,"h-[44] px-1 flex-row items-center justify-between":140,"w-full h-full items-center justify-center rounded-xl bg-slate-200":141,"w-full h-full items-center justify-center rounded-xl bg-red-100":142,"w-full h-full items-center justify-center rounded-xl bg-slate-100":143,"w-full h-full items-center justify-center rounded-xl bg-orange-600":144,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":145,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":146,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":147,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":148,"text-2xl text-indigo-700 font-bold":149,"text-2xl text-slate-600 font-bold":150,"pt-7 text-2xl text-slate-900 font-bold":151,"pt-4 text-lg text-slate-500":152,"text-xl text-emerald-600 font-bold":153,"text-xl text-red-500 font-bold":154,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":155,"text-base text-red-300":156,"text-base text-slate-300":157,"text-base text-red-500":158,"w-full h-full px-6 flex-row items-center bg-slate-950":159,"w-full h-full flex-row items-center":160};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var g2="ui:styles",w2="ui:font.",E4="ui:img.",N4="ui:sprite.";function C2(){return globalThis.ui}function E2(J){if(J.__textures)return;for(let Q of f0(E4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)e1(Q.slice(E4.length),Z)}}function N2(J){if(J.__sprites)return;for(let Q of f0(N4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)Q4(Q.slice(N4.length),{handle:V,frames:G,cols:P,step:D})}}function h4(J){let Q=z4("view");return EJ(Q,"style",J,void 0),Q}var P0=null,D0=null;function h2(J,Q){if(!P0||!D0)return;EJ(P0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),EJ(D0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function T2(J,Q={}){let $=v6(Q.ops);if(m6($),I8(e8),Q.styles)t8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)e1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)Q4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)x1(Q.pak);if(q8()){for(let B of f0())if(B===g2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(w2))$.ops.loadFontAtlas?.(vJ(B))}}let q=g1($.ops),X=q?.w??k1,z=q?.h??S1,G=h4({width:X,height:z,overflow:u.Overflow.Hidden}),P=h4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});XJ(qJ,G),XJ(qJ,P),W4(P),P0=G,D0=P,v1(G),d1(qJ),Q8(),w4(),O2(),a6(),_2(),u8($.ops),u6(l8((B,_,N,h)=>{r6(),o6(_),X2(N,h),S2(),k2(),D2(),$8(B),V8(B),Z4()}));let D=T8(J,G),V=l6(h2);return()=>{V(),z2(),w4(),D(),v1(null),d1(null),W4(null),P0=null,D0=null;for(let B of qJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);Z4()}}function f2(J,Q={}){let $=Q.ops??C2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)x1(Q.pak);return E2($),N2($),T2(J,{ops:$,styles:Q.styles??b2,pak:Q.pak})}var y2="$b",x2=65536,T4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function u2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function f4(){let J=u2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function l2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,x2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=v2(z.data[y2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function p2(J,Q){let $=l2(f4(),J);return Q==="utf8"||Q==="utf-8"?m2($):$}function c2(J,Q){let $=f4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var d2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"};function i2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(F,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(F,{class:"flex-row items-center gap-4",get children(){return[p(()=>p(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(F,{get["class"](){return Q()}})),Y(R,{get["class"](){return d2.appTitle},get children(){return J.title}})]}}),Y(F,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function s2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(F,{get["class"](){return Q()},get children(){return Y(R,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(F,{get["class"](){return J.top},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(F,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var uQ="‘’“”–—…•",y4=new Map,x4=new Map;function V0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=y4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return y4.set($,q),q}function a2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=V0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function Z1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=x4.get(Z);if(q)return q;let X=[],z=V0(" ",Q);for(let G of J.split(` -`)){let P=G.split(" ").flatMap((B)=>B&&V0(B,Q)>$?a2(B,Q,$):[B]),D="",V=0;for(let B of P){let _=V0(B,Q);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return x4.set(Z,X),X}function v4(J,Q,$,Z){let q=Z1(J,Q,$);if(q.length<=Z)return q.join(` +(()=>{var AJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return H1(this.context.count)},getNextContextId(){return H1(this.context.count++)}};function H1(J){let Q=String(J),$=Q.length-1;return AJ.context.id+($?String.fromCharCode(96+$):"")+Q}function B1(J){AJ.context=J}function Y6(){return{...AJ.context,id:AJ.getNextContextId(),count:0}}var z6=!1,W6=(J,Q)=>J===Q,k0=Symbol("solid-proxy"),G6=typeof Proxy==="function",H6=Symbol("solid-track"),FQ=Symbol("solid-dev-component"),oJ={equals:W6},j1=null,B6=D1,m=1,fJ=2,F1={owned:null,cleanups:null,context:null,owner:null},S=null,F=null,yJ=null,_J=null,b=null,C=null,T=null,nJ=0;function tJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?F1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>JJ(()=>QJ(z)));S=z,b=null;try{return c(G,!0)}finally{b=$,S=Z}}function g(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(F&&F.running&&F.sources.has($))q=q($.tValue);else q=q($.value);return U1($,q)};return[M1.bind($),Z]}function e(J,Q,$){let Z=P1(J,Q,!1,m);if(yJ&&F&&F.running)C.push(Z);else eJ(Z)}function kJ(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=P1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,yJ&&F&&F.running)Z.tState=m,C.push(Z);else eJ(Z);return M1.bind(Z)}function j6(J){return c(J,!1)}function JJ(J){if(!_J&&b===null)return J();let Q=b;b=null;try{if(_J)return _J.untrack(J);return J()}finally{b=Q}}function S0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function F6(J){if(F&&F.running)return J(),F.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(yJ||K6)Z=F||(F={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[KQ,K1]=g(!1),K6;function M1(){let J=F&&F.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)eJ(this);else{let Q=C;C=null,c(()=>J0(this),!1),C=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&F.sources.has(this))return this.tValue;return this.value}function U1(J,Q,$){let Z=F&&F.running&&F.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(F){let q=F.running;if(q||!$&&F.sources.has(J))F.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw C=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;QJ(J);let Q=nJ;if(R1(J,F&&F.running&&F.sources.has(J)?J.tValue:J.value,Q),F&&!F.running&&F.sources.has(J))queueMicrotask(()=>{c(()=>{F&&(F.running=!0),b=S=J,R1(J,J.tValue,Q),b=S=null},!1)})}function R1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(F&&F.running)J.tState=m,J.tOwned&&J.tOwned.forEach(QJ),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach(QJ),J.owned=null;return J.updatedAt=$+1,g0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)U1(J,Z,!0);else if(F&&F.running&&J.pure){if(!F.sources.has(J))J.value=Z;F.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function P1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(F&&F.running)X.state=0,X.tState=Z;if(S===null);else if(S!==F1)if(F&&F.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(_J&&X.fn){let z=X.fn,[G,P]=g(void 0,{equals:!1}),D=_J.factory(z,P);S0(()=>D.dispose());let V,B=()=>F6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),F&&F.running){if(!V)V=_J.factory(z,B);return V.track(_)}return D.track(_)}}return X}function b0(J){let Q=F&&F.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===fJ)return J0(J);if(J.suspense&&JJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(F.disposed.has(q))return}if((Q?J.tState:J.state)===m)eJ(J);else if((Q?J.tState:J.state)===fJ){let q=C;C=null,c(()=>J0(J,$[0]),!1),C=q}}}function c(J,Q){if(C)return J();let $=!1;if(!Q)C=[];if(T)$=!0;else T=[];nJ++;try{let Z=J();return M6($),Z}catch(Z){if(!$)T=null;C=null,g0(Z)}}function M6(J){if(C){if(yJ&&F&&F.running)U6(C);else D1(C);C=null}if(J)return;let Q;if(F){if(!F.promises.size&&!F.queue.size){let{sources:Z,disposed:q}=F;T.push.apply(T,F.effects),Q=F.resolve;for(let X of T)"tState"in X&&(X.state=X.tState),delete X.tState;F=null,c(()=>{for(let X of q)QJ(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zB6($),!1);if(Q)Q()}function D1(J){for(let Q=0;Q{Z.delete($),c(()=>{F.running=!0,b0($)},!1),F&&(F.running=!1)})}}function J0(J,Q){let $=F&&F.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)QJ(J.tOwned[Q]);delete J.tOwned}if(F&&F.running&&J.pure)L1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)QJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(F&&F.running)J.tState=0;else J.state=0}function L1(J,Q){if(!Q)J.tState=0,F.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return S0(()=>I1(X)),()=>{let P=J()||[],D=P.length,V,B;return P[H6],JJ(()=>{let N,h,a,GJ,LJ,M,j,H,L;if(D===0){if(z!==0)I1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[P6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=M&&H>=M&&Z[j]===P[H];j--,H--)a[H]=q[j],GJ[H]=X[j],G&&(LJ[H]=G[j]);N=new Map,h=Array(H+1);for(B=H;B>=M;B--)L=P[B],V=N.get(L),h[B]=V===void 0?-1:V,N.set(L,B);for(V=M;V<=j;V++)if(L=Z[V],B=N.get(L),B!==void 0&&B!==-1)a[B]=q[V],GJ[B]=X[V],G&&(LJ[B]=G[V]),B=h[B],N.set(L,B);else X[V]();for(B=M;BJ(Q||{}));return B1($),Z}}return JJ(()=>J(Q||{}))}function Q0(){return!0}var O6={get(J,Q,$){if(Q===k0)return $;return J.get(Q)},has(J,Q){if(Q===k0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function w0(J){return!(J=typeof J==="function"?J():J)?{}:J}function I6(){for(let J=0,Q=this.length;J=0;G--){let P=w0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in w0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:I6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var A6=(J)=>`Stale read from <${J}>.`;function SJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return kJ(D6(()=>J.each,J.children,Q||void 0))}function bJ(J){let Q=J.keyed,$=kJ(()=>J.when,void 0,void 0),Z=Q?$:kJ($,void 0,{equals:(q,X)=>!q===!X});return kJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?JJ(()=>X(Q?q:()=>{if(!JJ(Z))throw A6("Show");return $()})):X}return J.fallback},void 0,void 0)}var _6=(J)=>kJ(()=>J());function k6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(M,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(M,j,L,H);e((A)=>B(M,j(),A,H),L)}function B(M,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=h(M,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(M),H=j);else h(M,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=h(M,H,L);else if(k==="function")return e(()=>{let O=j();while(typeof O==="function")O=O();H=B(M,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return e(()=>H=B(M,O,H,L,!0)),()=>H;if(O.length===0){let TJ=h(M,H,L);if(I)return H=TJ}else if(Array.isArray(H))if(H.length===0)a(M,O,L);else N(M,H,O);else if(H==null||H==="")a(M,O);else N(M,I&&H||[P(M)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(M,H,L,j);h(M,H,null,j)}else if(H==null||H===""||!P(M))q(M,j);else GJ(M,j,P(M));H=j}return H}function _(M,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let jQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let TJ=G(O)===M;if(!k&&!I)TJ?GJ(M,A,O):q(M,A,H);else TJ&&X(M,O)}else k=!0}}else q(M,A,H);return[A]}function a(M,j,H){for(let L=0,A=j.length;LH.children=B(M,j.children,H.children));return e(()=>j.ref&&j.ref(M)),e(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(M,A,k,H[A]),H[A]=k}}),H}return{render(M,j){let H;return tJ((L)=>{H=L,V(j,M())}),H},insert:V,spread(M,j,H){if(typeof j==="function")e((L)=>LJ(M,j(),L,H));else LJ(M,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(M,j,H,L){return z(M,j,H,L),H},mergeProps:A1,effect:e,memo:_6,createComponent:L6,use(M,j,H){return JJ(()=>M(j,H))}}}function S6(J){let Q=k6(J);return Q.mergeProps=A1,Q}var _1=480,k1=272,HJ={view:0,text:1,image:2},b6=1,g6=-1,w6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},C6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},E6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},N6=1,MQ=2,UQ=1,RQ=2,PQ=131072,DQ=1,VQ=262144,LQ=1,OQ=1,IQ=1,AQ=2,_Q=4,kQ=8,SQ=16,bQ=1,gQ=2;function S1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var wQ=1,h6=1263551300,T6=1,f6=32,y6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},BJ=32896,CQ=0.016666666666666666;function b1(J){return J.__viewport??null}var C0=null;function x6(){return null}function g1(J,Q=x6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function v6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return g1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return g1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function m6(J){C0=J}function gJ(){if(!C0)throw Error("PocketJS: host not installed — call render() first");return C0}function E(){return gJ().ops}function u6(J){globalThis.frame=J}function l6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function p6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return S1($>>>16&255,$>>>8&255,$&255,255);return S1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function c6(J,Q){let $=C6[J];if(typeof Q==="string"){if($===U.color)return p6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var $0=60,w1=[1,2,3,4,5,6,10,12,15,20,30,60],E0=$0,$J=-1,d6=0,xJ=[];function i6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=w1[0];for(let $ of w1)if(Math.abs($-J)Q.at<=$J).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>$J);for(let Q of J)Q.cb()}var N0=0.12,Z0=BJ;function o6(J){Z0=J===void 0?BJ:J&65535}function n6(){Z0=BJ}function N1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function e6(){return N1(Z0&255)}var h1=new Set,J8=0;function Q8(){h1.clear(),J8=0,n6()}function $8(J){for(let Q of[...h1])Q(J)}var jJ=null,T1=null;function Z8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function f1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){h0();let Q=jJ?jJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return T1.slice(Q.off,Q.off+Q.len)}var mJ=null,w=null,FJ=null,q0=0,KJ=[],f0=[],y0=[];function x1(J){if(mJ=J,w=null,FJ=null,q0=0,KJ.length=0,f0.length=0,y0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function X8(J,Q){J.onPress=Q??void 0}function Y8(J,Q){if(J.focusable=Q,p1(),!Q&&w===J)x(null)}function x(J){if(FJ&&FJ!==J)MJ(null);w=J,E().setFocus(J?J.id:0)}function MJ(J){if(FJ===J)return;let Q=E();if(FJ)Q.setActive?.(FJ.id,0);if(FJ=J,J)Q.setActive?.(J.id,1)}function x0(){return KJ.length>0?KJ[KJ.length-1]:mJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function G8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=f0.length-1;Q>=0;Q--){let $=f0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function H8(J){let Q=G8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(w)x(null);return!0}let Z=Q.columns,q=w?$.indexOf(w):-1;if(q<0)return x(v1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function B8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=y0.length-1;Q>=0;Q--){let $=y0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function X0(J){let Q=B8();if(Q&&Q.move(J))return;if(H8(J))return;W8(J)}function m1(){u1(w)}function u1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){MJ(J)}function j8(J){x(J),u1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=m0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,l1=0;function p1(){l1++}var K8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],M8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function U8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=K8[Q]>>$&1,q=M8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function R8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):P8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(U8(),16,16,E6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function P8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&N6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var W0=null;function c1(J){W0=J}function d1(J){let Q=KJ.length>0?KJ[KJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function i1(J,Q,$){return d1(s1(J,Q,$))}function s1(J,Q,$){if($!==void 0)return $===0?null:z0(W0??mJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(W0??mJ,q(J,Q))}function D8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=b1(q);if(Z.vw=B?B.w:_1,Z.vh=B?B.h:k1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)R8(Z,q);let X=t6()*Z.speed,z=e6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=s6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=l1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=d1(z0(W0??mJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==w)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(MJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,MJ(null),B)m1()}}else if($&Z.button)MJ(null);return!0}function V8(J){let Q=J&~q0,$=q0&~J;if(q0=J,l&&D8(J,Q,$))return;if($&d.CIRCLE)MJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)MJ(w),m1()}var u0=null;function a1(J){u0=J}function wJ(){if(p1(),u0)u0()}function L8(J,Q){J.debugName=Q||void 0,wJ()}var ZJ={id:b6,type:HJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},r1=Symbol.for("pocketjs.native-node"),l0=1,uJ=3,o=8,O8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function G0(J){return J.domAttrs??={}}function o1(J,Q){let $=J.domNodeType??(lJ(J)?uJ:l0),Z=$===uJ?H0(J.text??""):$===o?_8(J.domData??""):Z4(J.domTag??j0(J));for(let q of Object.keys(J.domAttrs??{}))p0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)qJ(Z,o1(q,!0));return Z}function p0(J,Q,$){if(O8.has(Q)){EJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete G0(J)[Q];else G0(J)[Q]=$}function c0(J){if(J[r1]===!0)return J;return Object.defineProperty(J,r1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(lJ(J)?uJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(lJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(lJ(J))B0(J,Z);else if(E8(J),Z)qJ(J,H0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return X4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??j0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===uJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??j0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){EJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===ZJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return qJ(J,$),$},insertBefore($,Z){return qJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return qJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return o1(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){p0(J,$,Z)},removeAttribute($){p0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(ZJ);var d0=null;function I8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},n1=new Map;function t1(J,Q){n1.set(J,Q)}var e1=new Map;function J4(J,Q){e1.set(J,Q)}var CJ=new Set,A8=new Set;function Q4(J){if(!J)return!1;if(A8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function H0(J){let Q=E(),$=Q.createNode(HJ.text);return Q.setText($,J),c0({id:$,type:HJ.text,parent:null,children:[],text:J,domNodeType:uJ,domTag:"#text"})}function _8(J=""){let Q=H0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){E().replaceText(J.id,Q),J.text=Q,wJ()}function lJ(J){return J.type===HJ.text}function q4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function qJ(J,Q,$){let Z=E();if(q4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function pJ(J,Q){if(!Q)return;F8(Q),E().removeChild(J.id,Q.id),q4(Q),CJ.add(Q),wJ()}function k8(J){return J.parent??void 0}function S8(J){return J.children[0]}function X4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function b8(J,Q){let $=E();if(wJ(),Q==null||Q===""){$.setStyle(J.id,g6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function g8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=n1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function w8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=e1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function C8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=w6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,c6(G,P)),z=!0}if(z)wJ()}function EJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete G0(J)[Q];else G0(J)[Q]=$;switch(Q){case"class":return b8(J,$),$;case"onPress":case"on:press":return X8(J,$),$;case"src":return g8(J,$),$;case"sprite":return w8(J,$),$;case"style":return C8(J,$,Z),$;case"focusable":return Y8(J,!!$),$;case"debugName":return L8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${j0(J)}>`)}function E8(J){for(let Q of[...J.children])pJ(J,Q)}function j0(J){for(let Q of Object.keys(HJ))if(HJ[Q]===J.type)return Q;return String(J.type)}function N8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}EJ(J,Q,$,Z)}var h8=S6({createElement:Z4,createTextNode:H0,replaceText:B0,isTextNode:lJ,setProperty:N8,insertNode(J,Q,$){qJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:k8,getFirstChild:S8,getNextSibling:X4}),{render:T8,effect:EQ,memo:p,createComponent:Y,createElement:Y4,insert:NQ,spread:f8,mergeProps:hQ,use:TQ}=h8,fQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},y8=null;function z4(J){y8=J}function x8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function W4(J,Q){let $=Y4(J);return f8($,Q,!1),x8(Q.nodeRef,$),$}function K(J){return W4("view",J)}function R(J){return W4("text",J)}var yQ=new WeakMap,xQ=new WeakMap,v8={}!==null?Object.freeze({...{}}):Object.freeze({}),vQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:v8}),mQ=new Map,XJ=36000,s0=30,m8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(XJ),tapeAnalog:new Uint16Array(XJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function u8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-s0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)a1(()=>{W.treeDirty=!0}),r8();else a1(null);globalThis.__pocketDevtools=n8}function l8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)c8(),s8();let X=Q,z=$===void 0?BJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(XJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==BJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function B4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function j4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.masks,0,Q)}function F4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.analog??[],BJ,Q)}function K4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,f({t:"hello",app:W.app,host:o8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` +`))if(q.trim())d8(q)}}function d8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)f({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),a0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":M4();break;case"eval":{let Z=!0,q;try{q=F0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}f({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":f({t:"tape",tape:H4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}f({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())f({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else f({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=j4(Z),W.replayAnalog=Z.analog?F4(Z):null,W.replayTouch=Z.touch?K4(Z):null,W.replayAt=0;break}default:break}}function i8(){if(W.treeDirty&&W.frame-W.treeSentAt>=s0)M4();if(W.frame%m8===0)a0()}function s8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,f({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,f({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){f({t:"stats",frame:W.frame,nodes:P4(ZJ),tapeLen:W.tapeLen,paused:W.paused})}function M4(){W.treeDirty=!1,W.treeSentAt=W.frame,f({t:"tree",frame:W.frame,root:R4(ZJ)})}function a8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(a8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function U4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function R4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(U4(J,(q)=>{if(q.domNodeType===8)return;Z.push(R4(q))}),Z.length)Q.k=Z;return Q}function P4(J){let Q=1;return U4(J,($)=>{Q+=P4($)}),Q}function r8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{f({t:"log",level:$,args:q.map((X)=>F0(X))}),Z?.apply(Q,q)}}}function F0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?D4(X):JSON.stringify(D4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>F0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${F0(z,Q+1)}`).join(", ")}}`}function D4(J){return J.length>200?J.slice(0,199)+"…":J}function o8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var n8={get frame(){return W.frame},dumpTape:()=>H4(),replay:(J)=>{W.replayMasks=j4(J),W.replayAnalog=J.analog?F4(J):null,W.replayTouch=J.touch?K4(J):null,W.replayAt=0}},V4=new Map,o0=new Map;function L4(J){return J.trim().replace(/\s+/g," ")}function O4(J){return J.split(" ").sort().join(" ")}var I4=-1;function t8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=L4(Q);V4.set(Z,$);let q=O4(Z),X=o0.get(q);o0.set(q,X!==void 0&&X!==$?I4:$)}}function e8(J){let Q=L4(J),$=V4.get(Q);if($!==void 0)return $;let Z=o0.get(O4(Q));return Z===I4?void 0:Z}var n0=9,J2=(1<{let q=($&$2)!==0,X=q?t0:n0,z=q?Z2:J2;return Object.freeze({id:$>>>(q?q2:Q2)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Y2(){return K0}function z2(){K0=e0}var A4=8,YJ=8,W2=3,G2=8,H2=6,B2=0.5,s=1,cJ=2,J1=4,UJ=8,NJ=[],_4=0,M0=0,zJ=Array.from({length:A4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(YJ),histY:new Int16Array(YJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function j2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function F2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=s1(Q,$,Z.fact);let G=Z.hit;if(G)return j2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=NJ[z];if(G.disposed)continue;if(_4>0&&!G.opts.allowWhenBlocked)continue;if(!F2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function U2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%YJ,J.histLenz||Z>z))q.flags[J.slot]|=cJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(cJ|J1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??B2)*C1()));if(J.frames=0)NJ.splice($,1)},cancel(){if(!Q.disposed)b4(Q)},get panning(){for(let $ of zJ)if($.used&&Q.flags[$.slot]&UJ)return!0;return!1}}}function L2(J){let Q=V2(J);return S0(()=>Q.dispose()),Q}function g4(){NJ.length=0,_4=0,M0=0;for(let J of zJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function O2(){return L2({onDown:(J)=>{let Q=i1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=i1(J.x,J.y,J.hit);if(Q)j8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var I2=1,Q1=new Map,U0=[];function A2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function _2(){I2=1,Q1.clear(),U0=[]}function k2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),A2()?.({t:"delivery",frame:E1(),id:Q,kind:Z.kind}),Z.onResult($)}}var w4=new Set;function S2(){if(w4.size===0)return;for(let J of w4)J()}var b2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[28] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-base text-orange-600 font-bold":9,"h-[76] pt-3 text-lg text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-base text-emerald-700 font-bold":13,"h-[84] pt-3 text-lg text-slate-900":14,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":15,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":16,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":17,"text-base text-slate-600 font-bold":18,"pt-6 text-lg text-slate-500":19,"pt-6 text-lg text-slate-900 font-bold":20,"h-[146] px-6 pt-7 flex-col bg-slate-50":21,"h-[80]":22,"h-[1060] px-6 pt-5 flex-col":23,"h-[48] px-4 justify-center bg-slate-100":24,"text-base text-slate-600":25,"pt-[10] flex-col gap-[12]":26,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":27,"w-[48] h-[48] items-center justify-center bg-blue-100":28,"w-[48] h-[48] items-center justify-center bg-emerald-100":29,"text-lg text-blue-700 font-bold":30,"text-lg text-emerald-700 font-bold":31,"w-[474] flex-col gap-2":32,"text-lg text-slate-900 font-bold":33,"text-base text-slate-500":34,"pt-20 pl-10 text-lg text-slate-500":35,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":36,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":37,"h-[1060] px-6 pt-7 flex-col gap-4":38,"text-base text-slate-500 font-bold":39,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":40,"flex-row items-center gap-5":41,"w-[68] h-[68] items-center justify-center bg-emerald-100":42,"text-xl text-emerald-700 font-bold":43,"flex-col gap-2":44,"text-xl text-slate-900 font-bold":45,"text-lg text-slate-600":46,"text-2xl text-orange-600":47,"w-[68] h-[68] items-center justify-center bg-indigo-100":48,"text-xl text-indigo-700 font-bold":49,"mt-4 h-[112] px-6 justify-center bg-slate-100":50,"relative h-[154] px-5 pt-5 flex-col bg-white":51,"pt-3 text-lg text-orange-600 font-bold":52,"pt-3 text-base text-slate-500":53,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":54,"text-lg text-white font-bold":55,"h-[40] pt-3 text-base text-slate-500":56,"h-[470] flex-col gap-2":57,"h-[214] px-7 items-center justify-center bg-slate-100":58,"text-lg text-slate-500 font-bold":59,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":60,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":61,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":62,"h-[160] px-5 pt-5 flex-col bg-white":63,"pt-3 text-lg text-slate-900 font-bold":64,"pt-3 text-base text-slate-600":65,"h-[108] pt-7 flex-row gap-4":66,"w-[316] h-[80] items-center justify-center bg-slate-100":67,"w-[340] h-[80] items-center justify-center bg-red-100":68,"text-lg text-red-500 font-bold":69,"h-[1052] px-6 pt-5 flex-col":70,"h-[270] px-[22] pt-6 bg-white":71,"text-lg text-slate-900":72,"text-lg text-slate-400":73,"h-[86] px-1 flex-row items-center justify-between":74,"w-[132] h-[58] items-center justify-center bg-slate-300":75,"w-[132] h-[58] items-center justify-center bg-slate-100":76,"text-base text-slate-900 font-bold":77,"h-[140] flex-row gap-2":78,"grow h-[120] items-center justify-center bg-slate-300":79,"grow h-[120] items-center justify-center bg-white":80,"w-[104] h-[120] items-center justify-center bg-slate-300":81,"w-[104] h-[120] items-center justify-center bg-slate-100":82,"h-[176] flex-row gap-2":83,"w-[92] h-[156] items-center justify-center bg-slate-300":84,"w-[92] h-[156] items-center justify-center bg-slate-100":85,"w-[300] h-[156] items-center justify-center bg-slate-300":86,"w-[300] h-[156] items-center justify-center bg-slate-100":87,"w-[144] h-[156] items-center justify-center bg-slate-300":88,"w-[144] h-[156] items-center justify-center bg-slate-100":89,"w-[112] h-[156] items-center justify-center bg-emerald-700":90,"w-[112] h-[156] items-center justify-center bg-emerald-500":91,"text-base text-slate-950 font-bold":92,"h-[108] px-6 py-3 flex-col bg-slate-50":93,"h-[84] items-center justify-center bg-slate-300":94,"h-[84] items-center justify-center bg-slate-100":95,"h-[1168] px-6 pt-5 flex-col":96,"h-[82] px-4 justify-center bg-white":97,"w-[584] h-[900] px-5 pt-5 bg-slate-950":98,"text-base text-slate-200":99,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":100,"text-lg text-orange-600 font-bold":101,"w-[584] h-[900] px-5 pt-5 bg-white":102,"text-base text-slate-900":103,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":104,"absolute inset-0 z-50 flex-col items-center justify-center":105,"absolute inset-0 bg-slate-950":106,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":107,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":108,"flex-row flex-wrap":109,grow:110,"text-2xl text-white font-bold":111,"text-2xl text-slate-950 font-bold":112,"px-6":113,"px-6 py-5":114,"gap-4":115,"rounded-xl shadow bg-white border-slate-100":116,"rounded-xl shadow bg-emerald-100 border-emerald-500":117,"bg-white":118,"bg-slate-100":119,"bg-slate-950":120,"px-3 py-2 rounded-lg bg-slate-100":121,"px-3 py-2 rounded-lg bg-indigo-100":122,"text-base text-indigo-700 font-bold":123,"px-3 py-2 rounded-lg bg-emerald-100":124,"px-3 py-2 rounded-lg bg-amber-100":125,"text-base text-amber-700 font-bold":126,"px-3 py-2 rounded-lg bg-red-100":127,"text-base text-red-500 font-bold":128,"w-[34] h-[34] rounded-lg bg-amber-400":129,"w-[34] h-[34] rounded-lg bg-red-500":130,"w-[34] h-[34] rounded-lg bg-slate-800":131,"w-[34] h-[34] rounded-lg bg-emerald-500":132,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":133,"flex-row items-center gap-4":134,"w-[34] text-2xl text-white font-bold":135,"w-[332] flex-col items-end gap-2":136,"text-base text-slate-300 font-bold":137,"text-base text-slate-400":138,"h-[166] px-6 pt-6 flex-col gap-3":139,"h-[44] px-1 flex-row items-center justify-between":140,"w-full h-full items-center justify-center rounded-xl bg-slate-200":141,"w-full h-full items-center justify-center rounded-xl bg-red-100":142,"w-full h-full items-center justify-center rounded-xl bg-slate-100":143,"w-full h-full items-center justify-center rounded-xl bg-orange-600":144,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":145,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":146,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":147,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":148,"text-2xl text-indigo-700 font-bold":149,"text-2xl text-slate-600 font-bold":150,"pt-7 text-2xl text-slate-900 font-bold":151,"pt-4 text-lg text-slate-500":152,"text-xl text-emerald-600 font-bold":153,"text-xl text-red-500 font-bold":154,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":155,"text-base text-red-300":156,"text-base text-slate-300":157,"text-base text-red-500":158,"w-full h-full px-6 flex-row items-center bg-slate-950":159,"w-full h-full flex-row items-center":160};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var g2="ui:styles",w2="ui:font.",C4="ui:img.",E4="ui:sprite.";function C2(){return globalThis.ui}function E2(J){if(J.__textures)return;for(let Q of T0(C4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)t1(Q.slice(C4.length),Z)}}function N2(J){if(J.__sprites)return;for(let Q of T0(E4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)J4(Q.slice(E4.length),{handle:V,frames:G,cols:P,step:D})}}function N4(J){let Q=Y4("view");return EJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function h2(J,Q){if(!R0||!P0)return;EJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),EJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function T2(J,Q={}){let $=v6(Q.ops);if(m6($),I8(e8),Q.styles)t8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)t1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)J4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)y1(Q.pak);if(q8()){for(let B of T0())if(B===g2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(w2))$.ops.loadFontAtlas?.(vJ(B))}}let q=b1($.ops),X=q?.w??_1,z=q?.h??k1,G=N4({width:X,height:z,overflow:u.Overflow.Hidden}),P=N4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});qJ(ZJ,G),qJ(ZJ,P),z4(P),R0=G,P0=P,x1(G),c1(ZJ),Q8(),g4(),O2(),a6(),_2(),u8($.ops),u6(l8((B,_,N,h)=>{r6(),o6(_),X2(N,h),S2(),k2(),D2(),$8(B),V8(B),$4()}));let D=T8(J,G),V=l6(h2);return()=>{V(),z2(),g4(),D(),x1(null),c1(null),z4(null),R0=null,P0=null;for(let B of ZJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);$4()}}function f2(J,Q={}){let $=Q.ops??C2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)y1(Q.pak);return E2($),N2($),T2(J,{ops:$,styles:Q.styles??b2,pak:Q.pak})}var y2="$b",x2=65536,h4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function u2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function T4(){let J=u2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function l2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,x2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=v2(z.data[y2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function p2(J,Q){let $=l2(T4(),J);return Q==="utf8"||Q==="utf-8"?m2($):$}function c2(J,Q){let $=T4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var d2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"};function i2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(K,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(K,{class:"flex-row items-center gap-4",get children(){return[p(()=>p(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(K,{get["class"](){return Q()}})),Y(R,{get["class"](){return d2.appTitle},get children(){return J.title}})]}}),Y(K,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function s2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(K,{get["class"](){return Q()},get children(){return Y(R,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(K,{get["class"](){return J.top},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(K,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var uQ="‘’“”–—…•",f4=new Map,y4=new Map;function D0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=f4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return f4.set($,q),q}function a2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=D0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function $1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=y4.get(Z);if(q)return q;let X=[],z=D0(" ",Q);for(let G of J.split(` +`)){let P=G.split(" ").flatMap((B)=>B&&D0(B,Q)>$?a2(B,Q,$):[B]),D="",V=0;for(let B of P){let _=D0(B,Q);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return y4.set(Z,X),X}function x4(J,Q,$,Z){let q=$1(J,Q,$);if(q.length<=Z)return q.join(` `);let X=q.slice(0,Z);return X[Z-1]=X[Z-1].replace(/[\s.]+$/,"")+"…",X.join(` -`)}var m4=3,u4=2,l4=536,p4=544,c4=39,[PJ,r2]=g({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[y,n]=g("chat"),[L0,o2]=g("chat"),[q1,d4]=g(0),[t,i4]=g(""),[sJ,hJ]=g(0),[aJ,X1]=g([]),[n2,O0]=g(""),[s4,I0]=g(null),[a4,r4]=g(null),[A0,_0]=g(0),[v,e]=g(""),[DJ,o4]=g("letters"),[Y1,z1]=g(!1),[W1,n4]=g({type:"prompt"}),[GJ,t4]=g(null),[rJ,e4]=g(0),G1=new Map,J6=["qwertyuiop","asdfghjkl","zxcvbnm"],Q6=["1234567890","-/:;()$&@",`.,?!'"+`],$6=["chat","files","apps","settings"];function t2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function e2(J,Q){return J?J+"/"+Q:Q}function oJ(J=t(),Q=!1){let $=G1.get(J);if(!Q&&$){X1($),O0(""),hJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=c2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));G1.set(J,Z),X1(Z),O0(""),hJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){X1([]),O0(Z instanceof Error?Z.message:String(Z))}}function JQ(){let J=[];for(let Q of PJ().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Z6(){let J=JQ(),Q=Math.max(0,J.length-2),$=Math.min(q1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function VJ(J){return Y(i2,{get title(){return J.title},get accent(){return p(()=>PJ().agent==="FAULTED")()?"danger":PJ().agent==="THINKING"?"busy":"ready"}})}function k0(){return Y(F,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(SJ,{each:$6,children:(J)=>Y(F,{get["class"](){return L0()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function QQ(){let J=()=>PJ().schedule;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"ESP32 PI AGENT"}),Y(F,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(SJ,{get each(){return Z6()},children:(Q)=>Y(F,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-base text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-lg text-slate-900",get children(){return v4(Q.user,m4,l4,3)}}),Y(F,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-base text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-lg text-slate-900",get children(){return v4(Q.assistant,m4,l4,3)}})]}})}),Y(iJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(F,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-base text-slate-600 font-bold",children:"NEXT WAKE"}),Y(bJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-lg text-slate-500",children:`NO WAKE SCHEDULED +`)}var v4=3,m4=2,u4=536,l4=544,p4=39,[RJ,r2]=g({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[y,n]=g("chat"),[Z1,o2]=g("chat"),[q1,c4]=g(0),[PJ,d4]=g(""),[sJ,hJ]=g(0),[aJ,X1]=g([]),[n2,V0]=g(""),[i4,L0]=g(null),[s4,a4]=g(null),[O0,I0]=g(0),[v,t]=g(""),[DJ,r4]=g("letters"),[Y1,z1]=g(!1),[W1,o4]=g({type:"prompt"}),[WJ,n4]=g(null),[rJ,t4]=g(0),e4=new Map,J6=["qwertyuiop","asdfghjkl","zxcvbnm"],Q6=["1234567890","-/:;()$&@",`.,?!'"+`],$6=["chat","files","apps","settings"];function t2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function e2(J,Q){return J?J+"/"+Q:Q}function A0(J=PJ(),Q=!1){let $=e4.get(J);if(!Q&&$){X1($),V0(""),hJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=c2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));e4.set(J,Z),X1(Z),V0(""),hJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){X1([]),V0(Z instanceof Error?Z.message:String(Z))}}function JQ(){let J=[];for(let Q of RJ().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Z6(){let J=JQ(),Q=Math.max(0,J.length-2),$=Math.min(q1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function VJ(J){return Y(i2,{get title(){return J.title},get accent(){return p(()=>RJ().agent==="FAULTED")()?"danger":RJ().agent==="THINKING"?"busy":"ready"}})}function _0(){return Y(K,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(SJ,{each:$6,children:(J)=>Y(K,{get["class"](){return Z1()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function QQ(){let J=()=>RJ().schedule;return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"ESP32 PI AGENT"}),Y(K,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(SJ,{get each(){return Z6()},children:(Q)=>Y(K,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(K,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(K,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-base text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-lg text-slate-900",get children(){return x4(Q.user,v4,u4,3)}}),Y(K,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(K,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(K,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-base text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-lg text-slate-900",get children(){return x4(Q.assistant,v4,u4,3)}})]}})}),Y(iJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(K,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-base text-slate-600 font-bold",children:"NEXT WAKE"}),Y(bJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-lg text-slate-500",children:`NO WAKE SCHEDULED ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(R,{class:"pt-6 text-lg text-slate-900 font-bold",get children(){return String(J()?.name)+" "+String(J()?.next??"")+` -`+String(J()?.prompt??"")}})}})]}}),Y(F,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(F,{class:"h-[80]",get children(){return Y(s2,{label:"TYPE A MESSAGE"})}})}}),Y(k0,{})]}})}function $Q(){let J=()=>aJ().slice(sJ(),sJ()+8);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return t()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",get children(){return"/workspace"+(t()?"/"+t():"")}})}}),Y(F,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(SJ,{get each(){return J()},children:(Q)=>Y(F,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(F,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-lg text-blue-700 font-bold":"text-lg text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(F,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,52)}}),Y(R,{class:"text-base text-slate-500",get children(){return p(()=>Q.kind==="dir")()?"FOLDER":t2(Q.size)}})]}})]}})})}}),Y(bJ,{get when(){return aJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-lg text-slate-500",get children(){return n2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(bJ,{get when(){return aJ().length>8},get children(){return Y(iJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(k0,{})]}})}function ZQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"APPS"}),Y(F,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-base text-slate-500 font-bold",children:"2 INSTALLED APPS"}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-emerald-100",get children(){return Y(R,{class:"text-xl text-emerald-700 font-bold",children:"R"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Robinhood"}),Y(R,{class:"text-lg text-slate-600",children:"Portfolio and positions"}),Y(R,{class:"text-base text-slate-500",children:"UPDATES EVERY 5 MINUTES"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-indigo-100",get children(){return Y(R,{class:"text-xl text-indigo-700 font-bold",children:"E"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Exa Research"}),Y(R,{class:"text-lg text-slate-600",children:"Agent search history"}),Y(R,{class:"text-base text-slate-500",children:"STORED LOCALLY IN SQLITE"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",children:`APP DATA STAYS ISOLATED. -PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(k0,{})]}})}function qQ(){let J=()=>PJ().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(rJ(),rJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"SETTINGS"}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-lg text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return Z()}}),Y(F,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-lg text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-base text-slate-500",children:"AVAILABLE NETWORKS"}),Y(F,{class:"h-[470] flex-col gap-2",get children(){return[Y(bJ,{get when(){return $().length>0},get fallback(){return Y(F,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-500 font-bold",children:`NO NETWORK LIST YET +`+String(J()?.prompt??"")}})}})]}}),Y(K,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(K,{class:"h-[80]",get children(){return Y(s2,{label:"TYPE A MESSAGE"})}})}}),Y(_0,{})]}})}function $Q(){let J=()=>aJ().slice(sJ(),sJ()+8);return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return PJ()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(K,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",get children(){return"/workspace"+(PJ()?"/"+PJ():"")}})}}),Y(K,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(SJ,{get each(){return J()},children:(Q)=>Y(K,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(K,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-lg text-blue-700 font-bold":"text-lg text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(K,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,52)}}),Y(R,{class:"text-base text-slate-500",get children(){return p(()=>Q.kind==="dir")()?"FOLDER":t2(Q.size)}})]}})]}})})}}),Y(bJ,{get when(){return aJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-lg text-slate-500",get children(){return n2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(bJ,{get when(){return aJ().length>8},get children(){return Y(iJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(_0,{})]}})}function ZQ(){return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"APPS"}),Y(K,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-base text-slate-500 font-bold",children:"2 INSTALLED APPS"}),Y(K,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(K,{class:"flex-row items-center gap-5",get children(){return[Y(K,{class:"w-[68] h-[68] items-center justify-center bg-emerald-100",get children(){return Y(R,{class:"text-xl text-emerald-700 font-bold",children:"R"})}}),Y(K,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Robinhood"}),Y(R,{class:"text-lg text-slate-600",children:"Portfolio and positions"}),Y(R,{class:"text-base text-slate-500",children:"UPDATES EVERY 5 MINUTES"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(K,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(K,{class:"flex-row items-center gap-5",get children(){return[Y(K,{class:"w-[68] h-[68] items-center justify-center bg-indigo-100",get children(){return Y(R,{class:"text-xl text-indigo-700 font-bold",children:"E"})}}),Y(K,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Exa Research"}),Y(R,{class:"text-lg text-slate-600",children:"Agent search history"}),Y(R,{class:"text-base text-slate-500",children:"STORED LOCALLY IN SQLITE"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(K,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",children:`APP DATA STAYS ISOLATED. +PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(_0,{})]}})}function qQ(){let J=()=>RJ().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(rJ(),rJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"SETTINGS"}),Y(K,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-lg text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return Z()}}),Y(K,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-lg text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-base text-slate-500",children:"AVAILABLE NETWORKS"}),Y(K,{class:"h-[470] flex-col gap-2",get children(){return[Y(bJ,{get when(){return $().length>0},get fallback(){return Y(K,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-500 font-bold",children:`NO NETWORK LIST YET -TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(SJ,{get each(){return $()},children:(q)=>Y(F,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-base text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(bJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(iJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(F,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-lg text-slate-900 font-bold",get children(){return PJ().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-base text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(F,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(F,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(F,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-lg text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(k0,{})]}})}function XQ(){let J=()=>W1(),Q=()=>DJ()==="letters"?J6:Q6,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(F,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(F,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-base text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(F,{get["class"](){return GJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(SJ,{get each(){return Q()},children:(Z,q)=>Y(F,{class:"h-[140] flex-row gap-2",get children(){return[Y(SJ,{get each(){return Z.split("")},children:(X)=>Y(F,{get["class"](){return GJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return p(()=>!!Y1())()?X.toUpperCase():X}})}})}),Y(bJ,{get when(){return q()===2},get children(){return Y(F,{get["class"](){return GJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(F,{class:"h-[176] flex-row gap-2",get children(){return[Y(F,{get["class"](){return GJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"123":"ABC"}})}}),Y(F,{get["class"](){return GJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"SPACE"})}}),Y(F,{get["class"](){return GJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"SHIFT":". ?"}})}}),Y(F,{get["class"](){return GJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(R,{class:"text-base text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(F,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(F,{get["class"](){return GJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function YQ(){let J=()=>s4(),Q=()=>(J()?.text??"").split(` -`),$=()=>J()?.lineOffset??0;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< FILE VIEWER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(R,{class:"text-base text-slate-200",get children(){return Q().slice($(),$()+39).join(` -`)}})}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function zQ(){let J=()=>a4(),Q=()=>Z1(J()?.text??"",u4,p4);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< MESSAGE READER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-base text-slate-900",get children(){return Q().slice(A0(),A0()+c4).join(` -`)}})}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function WQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return p(()=>y()==="chat")()?Y(QQ,{}):p(()=>y()==="files")()?Y($Q,{}):p(()=>y()==="apps")()?Y(ZQ,{}):p(()=>y()==="settings")()?Y(qQ,{}):p(()=>y()==="keyboard")()?Y(XQ,{}):p(()=>y()==="viewer")()?Y(YQ,{}):Y(zQ,{})}})}function GQ(J){j6(()=>{if(o2(J),n(J),J==="files")oJ()})}function q6(J,Q){let $=DJ()==="letters"?J6:Q6,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=q6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function BQ(J,Q){if(Q>=1164)return e(""),n(L0()),"";if(J>=548&&Q>=402&&Q<=482)return e(""),"";let $=q6(J,Q);if($){let Z=DJ()==="letters"&&Y1()?$.toUpperCase():$,q=W1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return e(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)o4(DJ()==="letters"?"numbers":"letters"),z1(!1);else if(J<=424){if(v())e(v()+" ")}else if(J<=576)if(DJ()==="letters")z1(!Y1());else e(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=W1();if(e(""),o4("letters"),z1(!1),n(L0()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}f2(()=>Y(WQ,{})),queueMicrotask(()=>oJ("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return r2(JSON.parse(J)),""},dataChanged(){if(G1.delete(t()),L0()==="files")oJ(t(),!0);return""},invokeTool(){return JSON.stringify({text:"Pi Agent has no App tools",isError:!0})},invokeTask(){return JSON.stringify({text:"Pi Agent has no App tasks",isError:!0})},pointerDown(J,Q){return t4(y()==="keyboard"?HQ(J,Q):null),""},pointerUp(){return t4(null),""},tap(J,Q){if(y()==="keyboard")return BQ(J,Q);if(y()==="viewer"){let $=s4();if(J<104&&Q<112)I0(null),n("files");else if($&&J>=620&&Q>=170&&Q<=340)I0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)I0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` -`).length-39),$.lineOffset+18)});return""}if(y()==="reader"){if(J<104&&Q<112)r4(null),_0(0),n("chat");else if(J>=620&&Q>=170&&Q<=340)_0(Math.max(0,A0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=Z1(a4()?.text??"",u4,p4).length;_0(Math.min(Math.max(0,$-c4),A0()+18))}return""}if(Q>=1172)return GQ($6[Math.min(3,Math.floor(J/180))]),"";if(y()==="chat"){if(J>=620&&Q>=140&&Q<=272)d4(q1()+2);else if(J>=620&&Q>=624&&Q<=756)d4(Math.max(0,q1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=Z6()[$];if(Z){let q=Q>=140+$*320+150;r4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),_0(0),n("reader")}}else if(Q>=1070&&Q<=1150)n4({type:"prompt"}),e(""),n("keyboard");return""}if(y()==="files"){if(J<104&&Q<112&&t()){let $=t().split("/");$.pop();let Z=$.join("/");i4(Z),hJ(0),oJ(Z)}else if(J>=620&&Q>=170&&Q<=340)hJ(Math.max(0,sJ()-4));else if(J>=620&&Q>=920&&Q<=1100)hJ(Math.min(Math.max(0,aJ().length-8),sJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=aJ()[sJ()+$];if(Z){let q=e2(t(),Z.name);if(Z.kind==="dir")i4(q),hJ(0),oJ(q);else try{I0({path:"/workspace/"+q,text:p2(q,"utf8"),lineOffset:0}),n("viewer")}catch(X){O0(X instanceof Error?X.message:String(X))}}}return""}if(y()==="apps"){if(Q>=162&&Q<324)return JSON.stringify({type:"navigate",app:"robinhood"});if(Q>=324&&Q<490)return JSON.stringify({type:"navigate",app:"exa"});return""}if(y()==="settings"){let $=PJ().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)e4(Math.max(0,rJ()-4));else if(J>=620&&Q>=650&&Q<=782)e4(Math.min(Math.max(0,$.length-5),rJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[rJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});n4({type:"wifi",ssid:q.ssid}),e(""),n("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); +TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(SJ,{get each(){return $()},children:(q)=>Y(K,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-base text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(bJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(iJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(K,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-lg text-slate-900 font-bold",get children(){return RJ().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-base text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(K,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(K,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(K,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-lg text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(_0,{})]}})}function XQ(){let J=()=>W1(),Q=()=>DJ()==="letters"?J6:Q6,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(K,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(K,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-base text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(K,{get["class"](){return WJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(SJ,{get each(){return Q()},children:(Z,q)=>Y(K,{class:"h-[140] flex-row gap-2",get children(){return[Y(SJ,{get each(){return Z.split("")},children:(X)=>Y(K,{get["class"](){return WJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return p(()=>!!Y1())()?X.toUpperCase():X}})}})}),Y(bJ,{get when(){return q()===2},get children(){return Y(K,{get["class"](){return WJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(K,{class:"h-[176] flex-row gap-2",get children(){return[Y(K,{get["class"](){return WJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"123":"ABC"}})}}),Y(K,{get["class"](){return WJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"SPACE"})}}),Y(K,{get["class"](){return WJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"SHIFT":". ?"}})}}),Y(K,{get["class"](){return WJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(R,{class:"text-base text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(K,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(K,{get["class"](){return WJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function YQ(){let J=()=>i4(),Q=()=>(J()?.text??"").split(` +`),$=()=>J()?.lineOffset??0;return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< FILE VIEWER"}),Y(K,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(K,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(R,{class:"text-base text-slate-200",get children(){return Q().slice($(),$()+39).join(` +`)}})}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function zQ(){let J=()=>s4(),Q=()=>$1(J()?.text??"",m4,l4);return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< MESSAGE READER"}),Y(K,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(K,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-base text-slate-900",get children(){return Q().slice(O0(),O0()+p4).join(` +`)}})}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function WQ(){return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return p(()=>y()==="chat")()?Y(QQ,{}):p(()=>y()==="files")()?Y($Q,{}):p(()=>y()==="apps")()?Y(ZQ,{}):p(()=>y()==="settings")()?Y(qQ,{}):p(()=>y()==="keyboard")()?Y(XQ,{}):p(()=>y()==="viewer")()?Y(YQ,{}):Y(zQ,{})}})}function GQ(J){j6(()=>{if(o2(J),n(J),J==="files")A0()})}function q6(J,Q){let $=DJ()==="letters"?J6:Q6,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=q6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function BQ(J,Q){if(Q>=1164)return t(""),n(Z1()),"";if(J>=548&&Q>=402&&Q<=482)return t(""),"";let $=q6(J,Q);if($){let Z=DJ()==="letters"&&Y1()?$.toUpperCase():$,q=W1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return t(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)r4(DJ()==="letters"?"numbers":"letters"),z1(!1);else if(J<=424){if(v())t(v()+" ")}else if(J<=576)if(DJ()==="letters")z1(!Y1());else t(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=W1();if(t(""),r4("letters"),z1(!1),n(Z1()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}f2(()=>Y(WQ,{})),queueMicrotask(()=>A0("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return r2(JSON.parse(J)),""},pointerDown(J,Q){return n4(y()==="keyboard"?HQ(J,Q):null),""},pointerUp(){return n4(null),""},tap(J,Q){if(y()==="keyboard")return BQ(J,Q);if(y()==="viewer"){let $=i4();if(J<104&&Q<112)L0(null),n("files");else if($&&J>=620&&Q>=170&&Q<=340)L0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)L0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` +`).length-39),$.lineOffset+18)});return""}if(y()==="reader"){if(J<104&&Q<112)a4(null),I0(0),n("chat");else if(J>=620&&Q>=170&&Q<=340)I0(Math.max(0,O0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=$1(s4()?.text??"",m4,l4).length;I0(Math.min(Math.max(0,$-p4),O0()+18))}return""}if(Q>=1172)return GQ($6[Math.min(3,Math.floor(J/180))]),"";if(y()==="chat"){if(J>=620&&Q>=140&&Q<=272)c4(q1()+2);else if(J>=620&&Q>=624&&Q<=756)c4(Math.max(0,q1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=Z6()[$];if(Z){let q=Q>=140+$*320+150;a4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),I0(0),n("reader")}}else if(Q>=1070&&Q<=1150)o4({type:"prompt"}),t(""),n("keyboard");return""}if(y()==="files"){if(J<104&&Q<112&&PJ()){let $=PJ().split("/");$.pop();let Z=$.join("/");d4(Z),hJ(0),A0(Z)}else if(J>=620&&Q>=170&&Q<=340)hJ(Math.max(0,sJ()-4));else if(J>=620&&Q>=920&&Q<=1100)hJ(Math.min(Math.max(0,aJ().length-8),sJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=aJ()[sJ()+$];if(Z){let q=e2(PJ(),Z.name);if(Z.kind==="dir")d4(q),hJ(0),A0(q);else try{L0({path:"/workspace/"+q,text:p2(q,"utf8"),lineOffset:0}),n("viewer")}catch(X){V0(X instanceof Error?X.message:String(X))}}}return""}if(y()==="apps"){if(Q>=162&&Q<324)return JSON.stringify({type:"navigate",app:"robinhood"});if(Q>=324&&Q<490)return JSON.stringify({type:"navigate",app:"exa"});return""}if(y()==="settings"){let $=RJ().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)t4(Math.max(0,rJ()-4));else if(J>=620&&Q>=650&&Q<=782)t4(Math.min(Math.max(0,$.length-5),rJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[rJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});o4({type:"wifi",ssid:q.ssid}),t(""),n("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); diff --git a/apps/robinhood/app.tsx b/apps/robinhood/app.tsx index 2e995ef..d0e9e3a 100644 --- a/apps/robinhood/app.tsx +++ b/apps/robinhood/app.tsx @@ -497,7 +497,6 @@ mount(() => ); (globalThis as any).PocketPiApp = { tick, - update() { return ""; }, dataChanged(eventsLine: string) { const events = parse(eventsLine); const revision = Array.isArray(events) @@ -513,9 +512,6 @@ mount(() => ); return JSON.stringify({ text: JSON.stringify(value), details: value, isError: false }); } catch (error) { return JSON.stringify({ text: error instanceof Error ? error.message : String(error), isError: true }); } }, - invokeTask(name: string) { - return JSON.stringify({ text: "Data Action tasks do not run in the View: " + name, isError: true }); - }, tap(x: number, y: number) { if (screen() !== "dashboard") { if (y < 112 && x < 220) { setScreen("dashboard"); return ""; } diff --git a/apps/robinhood/data-action.ts b/apps/robinhood/data-action.ts index cff8ea8..d4421cb 100644 --- a/apps/robinhood/data-action.ts +++ b/apps/robinhood/data-action.ts @@ -124,7 +124,7 @@ function number(value: string | null): number | null { return Number.isFinite(parsed) ? parsed : null; } function accountNumber(value: any, args: any): string { - const requested = args?.account_number ?? args?.accountNumber; + const requested = args?.account_number; return requested === null || requested === undefined || requested === "" ? deep(value, ["account_number", "accountNumber", "account"]) || "" : String(requested); @@ -430,7 +430,7 @@ function refreshPortfolio(): any { } function saveEquityAction(operation: string, value: any, args: any, observedAt: number): void { - const account = String(args?.account_number ?? args?.accountNumber ?? ""); + const account = String(args?.account_number ?? ""); if (!account) return; const orderId = String(args?.order_id ?? deep(value, ["order_id", "orderId", "id"]) ?? ""); const activityId = orderId || [observedAt, args?.symbol || "EQUITY", operation].join(":"); diff --git a/apps/robinhood/dist/app.js b/apps/robinhood/dist/app.js index 70bdb29..5d9cfab 100644 --- a/apps/robinhood/dist/app.js +++ b/apps/robinhood/dist/app.js @@ -19,4 +19,4 @@ WHERE account_number = ?3 AND observed_at >= ?1 AND observed_at <= bucket_time ORDER BY observed_at DESC LIMIT 1) AS total_value FROM buckets ORDER BY bucket_index - `).all(z,X,J).map((j)=>({time:j.bucket_time,value:k0(j.total_value)})),R=D.map((j)=>j.time),U=D.map((j)=>j.value).filter((j)=>j!==null),H=[R[0],R[9],R[19]].map((j)=>{let G=new Date(j*1000);return u()==="day"?String(G.getHours()).padStart(2,"0")+":"+String(G.getMinutes()).padStart(2,"0"):String(G.getMonth()+1)+"/"+String(G.getDate())});if(U.length===0){let j=u()==="day"?y().pnlDay:y().pnlWeek,G=k0(j),P={points:[],segments:[],labels:H,trend:{change:JJ(j),percent:"—",positive:G===null||G>=0}};j1.set($,{loadedRevision:Q,value:P}),OJ(P.points),LJ(P.segments),z1(P.labels),Y1(P.trend);return}let w=Math.min(...U),x=Math.max(...U),g=Math.max(0.01,x-w),A=D.flatMap((j,G)=>j.value===null?[]:[{x:G*622/19,y:U.length===1?80:10+(x-j.value)*140/g}]),a=A.slice(1).map((j,G)=>{let P=A[G],k=j.x-P.x,_=j.y-P.y;return{x:P.x,y:P.y,width:Math.sqrt(k*k+_*_),angle:Math.atan2(_,k)*180/Math.PI}}),r=U[U.length-1]-U[0],K={change:JJ(String(r)),percent:U[0]===0?"—":(r*100/U[0]).toFixed(2)+"%",positive:r>=0};j1.set($,{loadedRevision:Q,value:{points:A,segments:a,labels:H,trend:K}}),OJ(A),LJ(a),z1(H),Y1(K)}function KQ(J){if(Z6===J)return;let Q=m.query("SELECT status,error,completed_at FROM refresh_runs ORDER BY id DESC LIMIT 1").get();if(J6(!1),Q?.status==="failed")XJ("REFRESH FAILED · "+String(Q.error||"UNKNOWN ERROR").slice(0,52));else if(Q?.status==="partial")XJ("LIVE WITH PARTIAL DATA");else if(y().observedAt)XJ("LIVE · "+W6(y().observedAt));else XJ("WAITING FOR ROBINHOOD");Z6=J}function z6(J,Q){if(!J){if(aJ(iJ),OJ([]),LJ([]),!rJ())XJ("WAITING FOR ROBINHOOD");return}let $=H1.get(J);if($?.loadedRevision===Q){if(aJ($.value),q6(J,Q),$.value.observedAt&&!rJ())XJ("LIVE · "+W6($.value.observedAt));return}aJ(iJ),OJ([]),LJ([])}function Y6(J=p){try{let Q=m.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==i4){W1([]),I0(""),aJ(iJ),OJ([]),LJ([]),XJ("WAITING FOR ROBINHOOD");return}eJ(()=>{p=Math.max(p,J);let $=gJ();if(Q6!==p)$=jQ(),W1($),Q6=p;FQ(p,$);let Z=L0();if(!$.some((X)=>X.number===Z))Z=$[0]?.number||"",I0(Z);z6(Z,p),KQ(p)})}catch{eJ(()=>{W1([]),I0(""),aJ(iJ),OJ([]),LJ([]),XJ("WAITING FOR ROBINHOOD")})}}function UQ(){return""}function MQ(){let J=m.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((z)=>z.name)),$=J.map((z)=>{let F=m.query("SELECT COUNT(*) AS count FROM "+z.name).get().count;return{name:z.name,rowCount:F,schema:z.sql}}),Z=Q.has("refresh_runs")?m.query("SELECT id,started_at,completed_at,operation_count,success_count,status,error FROM refresh_runs ORDER BY id DESC LIMIT 3").all():[],X=Q.has("portfolio_current")?m.query("SELECT substr(account_number,-4) AS account_suffix,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current ORDER BY observed_at DESC LIMIT 4").all():[],W=Q.has("total_value")?m.query("SELECT substr(account_number,-4) AS account_suffix,observed_at,value FROM total_value ORDER BY observed_at DESC LIMIT 8").all():[];return{database:"robinhood.sqlite",schemaVersion:i4,tables:$,latestRefreshes:Z,latestPortfolios:X,latestValues:W}}function F1(){return GQ()}function _0(J){return q(n2,{get title(){return J.title},back:!0,metaTop:"AGENTIC",get metaBottom(){return J.metaBottom??"AUTO · 5 MIN"}})}function B1(J){return q(V,{class:"w-[210] h-[104]",get children(){return q(e2,{get label(){return J.label},get value(){return JJ(J.value)}})}})}function G6(J){return q(o2,{get title(){return J.title},get detail(){return J.detail},action:!0})}function PQ(J){if(J===0&&!y().activityAvailable)return ZQ;return y().activity[J]??(J===0?Z1:XQ)}function H6(J){let Q=()=>PQ(J.index);return q(V,{class:"h-[72] px-5 flex-row items-center justify-between",get children(){return[q(V,{class:"w-[450] flex-col gap-2",get children(){return[q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q().title}}),q(O,{class:"text-base text-slate-500",get children(){return l(()=>!!Q().timestamp)()?Q().timestamp+" · "+Q().detail:""}})]}}),q(O,{get["class"](){return Q().side==="SELL"?"text-base text-emerald-600 font-bold":"text-base text-slate-900 font-bold"},get children(){return l(()=>!!Q().amount)()?JJ(Q().amount):""}})]}})}function VQ(J){if(J===0&&!y().positionsAvailable)return WQ;return y().positions[J]??(J===0?X1:qQ)}function j6(J){let Q=()=>VQ(J.index);return q(V,{class:"h-[64] px-5 flex-row items-center",get children(){return[q(O,{class:"w-[240] text-lg text-slate-900 font-bold",get children(){return Q().symbol}}),q(O,{class:"w-[156] text-base text-slate-500",get children(){return l(()=>!!Q().quantity)()?Q().quantity+" SH":""}}),q(O,{class:"text-base text-slate-500",get children(){return l(()=>!!Q().averagePrice)()?"AVG "+JJ(Q().averagePrice):""}})]}})}function DQ(){return q(V,{class:"relative w-[632] h-[196] flex-col",get children(){return[q(V,{class:"relative w-[632] h-[160] overflow-hidden",get children(){return[q(V,{class:"absolute w-[632] h-[2] bg-slate-200",style:{posType:1,insetL:0,insetT:158}}),q(O,{class:"absolute text-base text-slate-500 font-bold",style:{posType:1,insetL:152,insetT:72},get children(){return s4().length<2?"COLLECTING 5M VALUE HISTORY":""}}),q(NJ,{get each(){return YQ()},children:(J)=>q(V,{get["class"](){return F1().positive?"absolute rounded-lg bg-emerald-500":"absolute rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x,insetT:J.y-1,width:J.width,height:2,rotate:J.angle,originX:-0.5,originY:0}}})}),q(NJ,{get each(){return s4()},children:(J)=>q(V,{get["class"](){return F1().positive?"absolute w-[6] h-[6] rounded-lg bg-emerald-500":"absolute w-[6] h-[6] rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x-3,insetT:J.y-3}}})})]}}),q(V,{class:"h-[36] px-1 flex-row items-center justify-between",get children(){return[q(O,{class:"text-base text-slate-500",get children(){return q1()[0]||""}}),q(O,{class:"text-base text-slate-500",get children(){return q1()[1]||""}}),q(O,{class:"text-base text-slate-500",get children(){return q1()[2]||""}})]}})]}})}function RQ(){let J=()=>F1();return q(V,{class:"flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ROBINHOOD"}),q(V,{class:"h-[64] px-6 pt-2",get children(){return q(V,{class:"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(O,{class:"text-base text-slate-500 font-bold",children:"ACCOUNT"}),q(O,{class:"text-base text-slate-900 font-bold",get children(){return y().account.label+(y().account.suffix?" ····"+y().account.suffix+" "+(gJ().findIndex((Q)=>Q.number===L0())+1)+"/"+gJ().length:"")+" ›"}})]}})}}),q(V,{class:"h-[304] px-6 pt-3",get children(){return q(V,{class:"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"h-[64] flex-row items-end justify-between",get children(){return[q(O,{class:"text-2xl text-slate-950 font-bold",get children(){return JJ(y().totalValue)}}),q(O,{get["class"](){return J().positive?"text-lg text-emerald-600 font-bold":"text-lg text-red-500 font-bold"},get children(){return J().change+" ("+J().percent+")"}})]}}),q(DQ,{})]}})}}),q(V,{class:"h-[60] px-6 pt-2 flex-row gap-3",get children(){return[q(V,{get["class"](){return u()==="day"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(O,{get["class"](){return u()==="day"?"text-base text-white font-bold":"text-base text-slate-500 font-bold"},children:"1D"})}}),q(V,{get["class"](){return u()==="week"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(O,{get["class"](){return u()==="week"?"text-base text-white font-bold":"text-base text-slate-500 font-bold"},children:"1W"})}}),q(O,{class:"pt-3 text-base text-slate-500",get children(){return u()==="day"?"TODAY":"PAST WEEK"}})]}}),q(V,{class:"h-[126] px-6 pt-3 flex-row items-start gap-[21]",get children(){return[q(B1,{label:"VALUE",get value(){return y().totalValue}}),q(B1,{label:"CASH",get value(){return y().cash}}),q(B1,{label:"BUY POWER",get value(){return y().buyingPower}})]}}),q(V,{class:"h-[200] px-6 flex-col",get children(){return[q(G6,{title:"ACTIVITY",detail:"LAST 7 DAYS"}),q(V,{class:"h-[150] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(H6,{index:0}),q(H6,{index:1})]}})]}}),q(V,{class:"h-[184] px-6 flex-col",get children(){return[q(G6,{title:"POSITIONS"}),q(V,{class:"h-[136] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(j6,{index:0}),q(j6,{index:1})]}})]}}),q(V,{class:"h-[126] px-6 pt-2",get children(){return q(V,{class:"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-col gap-3",get children(){return[q(O,{class:"text-xl text-slate-900 font-bold",children:"REALIZED P&L"}),q(O,{class:"text-base text-slate-500",get children(){return"EQUITIES / "+(u()==="day"?"TODAY":"WEEK")}})]}}),q(O,{get["class"](){return(k0(u()==="day"?y().pnlDay:y().pnlWeek)??0)>=0?"text-2xl text-emerald-600 font-bold":"text-2xl text-red-500 font-bold"},get children(){return JJ(u()==="day"?y().pnlDay:y().pnlWeek)}})]}})}}),q(V,{class:"h-[104] px-6 flex-row items-center justify-between",get children(){return[q(V,{class:"w-[460] h-[64]",get children(){return q(JQ,{get text(){return e4()},get tone(){return e4().startsWith("REFRESH FAILED")?"danger":"neutral"}})}}),q(V,{class:"w-[176] h-[64]",get children(){return q(t2,{get label(){return rJ()?"REFRESHING":"REFRESH NOW"},get disabled(){return rJ()}})}})]}})]}})}function K1(){return q(QQ,{top:"absolute left-[628] top-[156] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",bottom:"absolute left-[628] top-[972] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100"})}function OQ(){let J=$J(()=>gJ().slice(G1(),G1()+8)),Q=L0();return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ACCOUNTS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(NJ,{get each(){return J()},children:($)=>q(V,{get["class"](){return $.number===Q?"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100"},get children(){return[q(V,{class:"flex-row items-center justify-between",get children(){return[q(O,{class:"text-xl text-slate-900 font-bold",get children(){return $.label}}),q(O,{class:"text-lg text-slate-500 font-bold",get children(){return"····"+$.suffix}})]}}),q(V,{class:"flex-row items-center justify-between",get children(){return[q(V,{get["class"](){return c4.success.surface},get children(){return q(O,{get["class"](){return c4.success.text},get children(){return $.status}})}}),q(Z0,{get when(){return $.number===Q},get children(){return q(O,{class:"text-base text-emerald-600 font-bold",children:"SELECTED"})}})]}})]}})})}}),q(K1,{})]}})}function LQ(){let J=$J(()=>y().activity.slice(r4(),r4()+8));return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ACTIVITY",metaBottom:"LAST 7 DAYS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[14]",get children(){return q(Z0,{get when(){return l(()=>!!y().activityAvailable)()&&J().length>0},get fallback(){return q(d4,{get title(){return y().activityAvailable?"NO ACTIVITY YET":"ACTIVITY UNAVAILABLE"},compact:!0})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(V,{class:"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-row items-center justify-between",get children(){return[q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q.title}}),q(O,{get["class"](){return Q.side==="SELL"?"text-lg text-emerald-600 font-bold":"text-lg text-slate-900 font-bold"},get children(){return JJ(Q.amount)}})]}}),q(O,{class:"text-base text-slate-500",get children(){return Q.timestamp+" · "+Q.detail}}),q(O,{class:"text-base text-emerald-600 font-bold",get children(){return Q.state}})]}})})}})}}),q(K1,{})]}})}function IQ(){let J=$J(()=>y().positions.slice(o4(),o4()+9));return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"POSITIONS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(Z0,{get when(){return l(()=>!!y().positionsAvailable)()&&J().length>0},get fallback(){return q(d4,{get title(){return y().positionsAvailable?"NO OPEN POSITIONS":"POSITIONS UNAVAILABLE"},compact:!0})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(V,{class:"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-row items-center",get children(){return[q(O,{class:"w-[170] text-xl text-slate-900 font-bold",get children(){return Q.symbol}}),q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q.quantity+" SH"}})]}}),q(O,{class:"text-base text-slate-500",get children(){return"AVERAGE COST "+JJ(Q.averagePrice)+(Q.marketValue?" · VALUE "+JJ(Q.marketValue):"")}})]}})})}})}}),q(K1,{})]}})}function kQ(){if(s()==="accounts")return q(OQ,{});if(s()==="activity")return q(LQ,{});return q(IQ,{})}function _Q(){return q(Z0,{get when(){return s()==="dashboard"},get fallback(){return q(kQ,{})},get children(){return q(RQ,{})}})}Y6(),u2(()=>q(_Q,{})),globalThis.PocketPiApp={tick:UQ,update(){return""},dataChanged(J){let Q=HQ(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),p):p;return Y6($),""},invokeTool(J){try{let Q=J==="robinhood.storage_status"?MQ():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},invokeTask(J){return JSON.stringify({text:"Data Action tasks do not run in the View: "+J,isError:!0})},tap(J,Q){if(s()!=="dashboard"){if(Q<112&&J<220)return sJ("dashboard"),"";if(J>=620&&Q>=140&&Q<310){if(s()==="accounts")a4(($)=>Math.max(0,$-1));if(s()==="activity")n4(($)=>Math.max(0,$-1));if(s()==="positions")t4(($)=>Math.max(0,$-1));return""}if(J>=620&&Q>=940&&Q<1130){if(s()==="accounts")a4(($)=>Math.min(Math.max(0,gJ().length-8),$+1));if(s()==="activity")n4(($)=>Math.min(Math.max(0,y().activity.length-8),$+1));if(s()==="positions")t4(($)=>Math.min(Math.max(0,y().positions.length-9),$+1));return""}if(s()==="accounts"&&J<610&&Q>=126){let $=G1()+Math.floor((Q-126)/112),Z=gJ()[$];if(Z)eJ(()=>{I0(Z.number),sJ("dashboard")}),z6(Z.number,p)}return""}if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(Q>=112&&Q<176)return sJ("accounts"),"";if(Q>=480&&Q<540)return eJ(()=>{zQ(J<136?"day":"week"),q6(L0(),p)}),"";if(Q>=666&&Q<866)return sJ("activity"),"";if(Q>=866&&Q<1050)return sJ("positions"),"";if(Q>=1176&&J>=500){if(rJ())return"";return J6(!0),XJ("REFRESHING ROBINHOOD…"),JSON.stringify({type:"invokeTask",task:"refreshPortfolio"})}return""}}})(); + `).all(z,X,J).map((j)=>({time:j.bucket_time,value:k0(j.total_value)})),R=D.map((j)=>j.time),U=D.map((j)=>j.value).filter((j)=>j!==null),H=[R[0],R[9],R[19]].map((j)=>{let G=new Date(j*1000);return u()==="day"?String(G.getHours()).padStart(2,"0")+":"+String(G.getMinutes()).padStart(2,"0"):String(G.getMonth()+1)+"/"+String(G.getDate())});if(U.length===0){let j=u()==="day"?y().pnlDay:y().pnlWeek,G=k0(j),P={points:[],segments:[],labels:H,trend:{change:JJ(j),percent:"—",positive:G===null||G>=0}};j1.set($,{loadedRevision:Q,value:P}),OJ(P.points),LJ(P.segments),z1(P.labels),Y1(P.trend);return}let w=Math.min(...U),x=Math.max(...U),g=Math.max(0.01,x-w),A=D.flatMap((j,G)=>j.value===null?[]:[{x:G*622/19,y:U.length===1?80:10+(x-j.value)*140/g}]),a=A.slice(1).map((j,G)=>{let P=A[G],k=j.x-P.x,_=j.y-P.y;return{x:P.x,y:P.y,width:Math.sqrt(k*k+_*_),angle:Math.atan2(_,k)*180/Math.PI}}),r=U[U.length-1]-U[0],K={change:JJ(String(r)),percent:U[0]===0?"—":(r*100/U[0]).toFixed(2)+"%",positive:r>=0};j1.set($,{loadedRevision:Q,value:{points:A,segments:a,labels:H,trend:K}}),OJ(A),LJ(a),z1(H),Y1(K)}function KQ(J){if(Z6===J)return;let Q=m.query("SELECT status,error,completed_at FROM refresh_runs ORDER BY id DESC LIMIT 1").get();if(J6(!1),Q?.status==="failed")XJ("REFRESH FAILED · "+String(Q.error||"UNKNOWN ERROR").slice(0,52));else if(Q?.status==="partial")XJ("LIVE WITH PARTIAL DATA");else if(y().observedAt)XJ("LIVE · "+W6(y().observedAt));else XJ("WAITING FOR ROBINHOOD");Z6=J}function z6(J,Q){if(!J){if(aJ(iJ),OJ([]),LJ([]),!rJ())XJ("WAITING FOR ROBINHOOD");return}let $=H1.get(J);if($?.loadedRevision===Q){if(aJ($.value),q6(J,Q),$.value.observedAt&&!rJ())XJ("LIVE · "+W6($.value.observedAt));return}aJ(iJ),OJ([]),LJ([])}function Y6(J=p){try{let Q=m.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==i4){W1([]),I0(""),aJ(iJ),OJ([]),LJ([]),XJ("WAITING FOR ROBINHOOD");return}eJ(()=>{p=Math.max(p,J);let $=gJ();if(Q6!==p)$=jQ(),W1($),Q6=p;FQ(p,$);let Z=L0();if(!$.some((X)=>X.number===Z))Z=$[0]?.number||"",I0(Z);z6(Z,p),KQ(p)})}catch{eJ(()=>{W1([]),I0(""),aJ(iJ),OJ([]),LJ([]),XJ("WAITING FOR ROBINHOOD")})}}function UQ(){return""}function MQ(){let J=m.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((z)=>z.name)),$=J.map((z)=>{let F=m.query("SELECT COUNT(*) AS count FROM "+z.name).get().count;return{name:z.name,rowCount:F,schema:z.sql}}),Z=Q.has("refresh_runs")?m.query("SELECT id,started_at,completed_at,operation_count,success_count,status,error FROM refresh_runs ORDER BY id DESC LIMIT 3").all():[],X=Q.has("portfolio_current")?m.query("SELECT substr(account_number,-4) AS account_suffix,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current ORDER BY observed_at DESC LIMIT 4").all():[],W=Q.has("total_value")?m.query("SELECT substr(account_number,-4) AS account_suffix,observed_at,value FROM total_value ORDER BY observed_at DESC LIMIT 8").all():[];return{database:"robinhood.sqlite",schemaVersion:i4,tables:$,latestRefreshes:Z,latestPortfolios:X,latestValues:W}}function F1(){return GQ()}function _0(J){return q(n2,{get title(){return J.title},back:!0,metaTop:"AGENTIC",get metaBottom(){return J.metaBottom??"AUTO · 5 MIN"}})}function B1(J){return q(V,{class:"w-[210] h-[104]",get children(){return q(e2,{get label(){return J.label},get value(){return JJ(J.value)}})}})}function G6(J){return q(o2,{get title(){return J.title},get detail(){return J.detail},action:!0})}function PQ(J){if(J===0&&!y().activityAvailable)return ZQ;return y().activity[J]??(J===0?Z1:XQ)}function H6(J){let Q=()=>PQ(J.index);return q(V,{class:"h-[72] px-5 flex-row items-center justify-between",get children(){return[q(V,{class:"w-[450] flex-col gap-2",get children(){return[q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q().title}}),q(O,{class:"text-base text-slate-500",get children(){return l(()=>!!Q().timestamp)()?Q().timestamp+" · "+Q().detail:""}})]}}),q(O,{get["class"](){return Q().side==="SELL"?"text-base text-emerald-600 font-bold":"text-base text-slate-900 font-bold"},get children(){return l(()=>!!Q().amount)()?JJ(Q().amount):""}})]}})}function VQ(J){if(J===0&&!y().positionsAvailable)return WQ;return y().positions[J]??(J===0?X1:qQ)}function j6(J){let Q=()=>VQ(J.index);return q(V,{class:"h-[64] px-5 flex-row items-center",get children(){return[q(O,{class:"w-[240] text-lg text-slate-900 font-bold",get children(){return Q().symbol}}),q(O,{class:"w-[156] text-base text-slate-500",get children(){return l(()=>!!Q().quantity)()?Q().quantity+" SH":""}}),q(O,{class:"text-base text-slate-500",get children(){return l(()=>!!Q().averagePrice)()?"AVG "+JJ(Q().averagePrice):""}})]}})}function DQ(){return q(V,{class:"relative w-[632] h-[196] flex-col",get children(){return[q(V,{class:"relative w-[632] h-[160] overflow-hidden",get children(){return[q(V,{class:"absolute w-[632] h-[2] bg-slate-200",style:{posType:1,insetL:0,insetT:158}}),q(O,{class:"absolute text-base text-slate-500 font-bold",style:{posType:1,insetL:152,insetT:72},get children(){return s4().length<2?"COLLECTING 5M VALUE HISTORY":""}}),q(NJ,{get each(){return YQ()},children:(J)=>q(V,{get["class"](){return F1().positive?"absolute rounded-lg bg-emerald-500":"absolute rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x,insetT:J.y-1,width:J.width,height:2,rotate:J.angle,originX:-0.5,originY:0}}})}),q(NJ,{get each(){return s4()},children:(J)=>q(V,{get["class"](){return F1().positive?"absolute w-[6] h-[6] rounded-lg bg-emerald-500":"absolute w-[6] h-[6] rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x-3,insetT:J.y-3}}})})]}}),q(V,{class:"h-[36] px-1 flex-row items-center justify-between",get children(){return[q(O,{class:"text-base text-slate-500",get children(){return q1()[0]||""}}),q(O,{class:"text-base text-slate-500",get children(){return q1()[1]||""}}),q(O,{class:"text-base text-slate-500",get children(){return q1()[2]||""}})]}})]}})}function RQ(){let J=()=>F1();return q(V,{class:"flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ROBINHOOD"}),q(V,{class:"h-[64] px-6 pt-2",get children(){return q(V,{class:"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(O,{class:"text-base text-slate-500 font-bold",children:"ACCOUNT"}),q(O,{class:"text-base text-slate-900 font-bold",get children(){return y().account.label+(y().account.suffix?" ····"+y().account.suffix+" "+(gJ().findIndex((Q)=>Q.number===L0())+1)+"/"+gJ().length:"")+" ›"}})]}})}}),q(V,{class:"h-[304] px-6 pt-3",get children(){return q(V,{class:"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"h-[64] flex-row items-end justify-between",get children(){return[q(O,{class:"text-2xl text-slate-950 font-bold",get children(){return JJ(y().totalValue)}}),q(O,{get["class"](){return J().positive?"text-lg text-emerald-600 font-bold":"text-lg text-red-500 font-bold"},get children(){return J().change+" ("+J().percent+")"}})]}}),q(DQ,{})]}})}}),q(V,{class:"h-[60] px-6 pt-2 flex-row gap-3",get children(){return[q(V,{get["class"](){return u()==="day"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(O,{get["class"](){return u()==="day"?"text-base text-white font-bold":"text-base text-slate-500 font-bold"},children:"1D"})}}),q(V,{get["class"](){return u()==="week"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(O,{get["class"](){return u()==="week"?"text-base text-white font-bold":"text-base text-slate-500 font-bold"},children:"1W"})}}),q(O,{class:"pt-3 text-base text-slate-500",get children(){return u()==="day"?"TODAY":"PAST WEEK"}})]}}),q(V,{class:"h-[126] px-6 pt-3 flex-row items-start gap-[21]",get children(){return[q(B1,{label:"VALUE",get value(){return y().totalValue}}),q(B1,{label:"CASH",get value(){return y().cash}}),q(B1,{label:"BUY POWER",get value(){return y().buyingPower}})]}}),q(V,{class:"h-[200] px-6 flex-col",get children(){return[q(G6,{title:"ACTIVITY",detail:"LAST 7 DAYS"}),q(V,{class:"h-[150] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(H6,{index:0}),q(H6,{index:1})]}})]}}),q(V,{class:"h-[184] px-6 flex-col",get children(){return[q(G6,{title:"POSITIONS"}),q(V,{class:"h-[136] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(j6,{index:0}),q(j6,{index:1})]}})]}}),q(V,{class:"h-[126] px-6 pt-2",get children(){return q(V,{class:"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-col gap-3",get children(){return[q(O,{class:"text-xl text-slate-900 font-bold",children:"REALIZED P&L"}),q(O,{class:"text-base text-slate-500",get children(){return"EQUITIES / "+(u()==="day"?"TODAY":"WEEK")}})]}}),q(O,{get["class"](){return(k0(u()==="day"?y().pnlDay:y().pnlWeek)??0)>=0?"text-2xl text-emerald-600 font-bold":"text-2xl text-red-500 font-bold"},get children(){return JJ(u()==="day"?y().pnlDay:y().pnlWeek)}})]}})}}),q(V,{class:"h-[104] px-6 flex-row items-center justify-between",get children(){return[q(V,{class:"w-[460] h-[64]",get children(){return q(JQ,{get text(){return e4()},get tone(){return e4().startsWith("REFRESH FAILED")?"danger":"neutral"}})}}),q(V,{class:"w-[176] h-[64]",get children(){return q(t2,{get label(){return rJ()?"REFRESHING":"REFRESH NOW"},get disabled(){return rJ()}})}})]}})]}})}function K1(){return q(QQ,{top:"absolute left-[628] top-[156] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",bottom:"absolute left-[628] top-[972] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100"})}function OQ(){let J=$J(()=>gJ().slice(G1(),G1()+8)),Q=L0();return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ACCOUNTS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(NJ,{get each(){return J()},children:($)=>q(V,{get["class"](){return $.number===Q?"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100"},get children(){return[q(V,{class:"flex-row items-center justify-between",get children(){return[q(O,{class:"text-xl text-slate-900 font-bold",get children(){return $.label}}),q(O,{class:"text-lg text-slate-500 font-bold",get children(){return"····"+$.suffix}})]}}),q(V,{class:"flex-row items-center justify-between",get children(){return[q(V,{get["class"](){return c4.success.surface},get children(){return q(O,{get["class"](){return c4.success.text},get children(){return $.status}})}}),q(Z0,{get when(){return $.number===Q},get children(){return q(O,{class:"text-base text-emerald-600 font-bold",children:"SELECTED"})}})]}})]}})})}}),q(K1,{})]}})}function LQ(){let J=$J(()=>y().activity.slice(r4(),r4()+8));return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ACTIVITY",metaBottom:"LAST 7 DAYS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[14]",get children(){return q(Z0,{get when(){return l(()=>!!y().activityAvailable)()&&J().length>0},get fallback(){return q(d4,{get title(){return y().activityAvailable?"NO ACTIVITY YET":"ACTIVITY UNAVAILABLE"},compact:!0})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(V,{class:"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-row items-center justify-between",get children(){return[q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q.title}}),q(O,{get["class"](){return Q.side==="SELL"?"text-lg text-emerald-600 font-bold":"text-lg text-slate-900 font-bold"},get children(){return JJ(Q.amount)}})]}}),q(O,{class:"text-base text-slate-500",get children(){return Q.timestamp+" · "+Q.detail}}),q(O,{class:"text-base text-emerald-600 font-bold",get children(){return Q.state}})]}})})}})}}),q(K1,{})]}})}function IQ(){let J=$J(()=>y().positions.slice(o4(),o4()+9));return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"POSITIONS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(Z0,{get when(){return l(()=>!!y().positionsAvailable)()&&J().length>0},get fallback(){return q(d4,{get title(){return y().positionsAvailable?"NO OPEN POSITIONS":"POSITIONS UNAVAILABLE"},compact:!0})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(V,{class:"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-row items-center",get children(){return[q(O,{class:"w-[170] text-xl text-slate-900 font-bold",get children(){return Q.symbol}}),q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q.quantity+" SH"}})]}}),q(O,{class:"text-base text-slate-500",get children(){return"AVERAGE COST "+JJ(Q.averagePrice)+(Q.marketValue?" · VALUE "+JJ(Q.marketValue):"")}})]}})})}})}}),q(K1,{})]}})}function kQ(){if(s()==="accounts")return q(OQ,{});if(s()==="activity")return q(LQ,{});return q(IQ,{})}function _Q(){return q(Z0,{get when(){return s()==="dashboard"},get fallback(){return q(kQ,{})},get children(){return q(RQ,{})}})}Y6(),u2(()=>q(_Q,{})),globalThis.PocketPiApp={tick:UQ,dataChanged(J){let Q=HQ(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),p):p;return Y6($),""},invokeTool(J){try{let Q=J==="robinhood.storage_status"?MQ():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},tap(J,Q){if(s()!=="dashboard"){if(Q<112&&J<220)return sJ("dashboard"),"";if(J>=620&&Q>=140&&Q<310){if(s()==="accounts")a4(($)=>Math.max(0,$-1));if(s()==="activity")n4(($)=>Math.max(0,$-1));if(s()==="positions")t4(($)=>Math.max(0,$-1));return""}if(J>=620&&Q>=940&&Q<1130){if(s()==="accounts")a4(($)=>Math.min(Math.max(0,gJ().length-8),$+1));if(s()==="activity")n4(($)=>Math.min(Math.max(0,y().activity.length-8),$+1));if(s()==="positions")t4(($)=>Math.min(Math.max(0,y().positions.length-9),$+1));return""}if(s()==="accounts"&&J<610&&Q>=126){let $=G1()+Math.floor((Q-126)/112),Z=gJ()[$];if(Z)eJ(()=>{I0(Z.number),sJ("dashboard")}),z6(Z.number,p)}return""}if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(Q>=112&&Q<176)return sJ("accounts"),"";if(Q>=480&&Q<540)return eJ(()=>{zQ(J<136?"day":"week"),q6(L0(),p)}),"";if(Q>=666&&Q<866)return sJ("activity"),"";if(Q>=866&&Q<1050)return sJ("positions"),"";if(Q>=1176&&J>=500){if(rJ())return"";return J6(!0),XJ("REFRESHING ROBINHOOD…"),JSON.stringify({type:"invokeTask",task:"refreshPortfolio"})}return""}}})(); diff --git a/apps/robinhood/dist/data-action.js b/apps/robinhood/dist/data-action.js index 8387c5c..ab6378a 100644 --- a/apps/robinhood/dist/data-action.js +++ b/apps/robinhood/dist/data-action.js @@ -225,7 +225,7 @@ Returns the scan with its new filters and fresh live results. This changes Robin ); CREATE INDEX IF NOT EXISTS refresh_runs_recent ON refresh_runs(id DESC); PRAGMA user_version=5; - `);var A=b.tools,V=new Map(A.map((e)=>[e.name,e]));function _(){return Math.floor(Date.now()/1000)}function F(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function n(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let i of t){let r=F(e[i]);if(r!==null)return r}for(let i of Object.values(e)){let r=n(i,t);if(r!==null)return r}return null}function O(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let i of t)if(Array.isArray(e[i]))return e[i];for(let i of Object.values(e)){let r=O(i,t);if(r.length)return r}return[]}function Y(e,t){let i=n(e,t)?.toLowerCase();return i==="true"||i==="1"||i==="yes"}function U(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function g(e,t){let i=t?.account_number??t?.accountNumber;return i===null||i===void 0||i===""?n(e,["account_number","accountNumber","account"])||"":String(i)}function q(e,t){let i=O(e,t);return i.length?i:Array.isArray(e)?e:e?[e]:[]}function z(e){let t=Array.isArray(e?.names)?new Set(e.names.filter((s)=>typeof s==="string")):new Set,i=String(e?.query??"").toLowerCase().split(/[^a-z0-9_]+/).filter(Boolean),r=typeof e?.namespace==="string"?e.namespace:"";if(!t.size&&!i.length)throw Error("search_tools requires query or names");let c=Math.max(1,Math.min(8,Number(e?.limit??5)||5)),o=A.filter((s)=>!r||s.namespace===r).map((s)=>{let a=s.name.toLowerCase(),p=a+" "+s.description.toLowerCase(),d=t.has(s.name)?1000:i.reduce((m,l)=>m+(a===l?100:a.includes(l)?20:p.includes(l)?3:0),0);return{tool:s,score:d}}).filter((s)=>s.score>0).sort((s,a)=>a.score-s.score||s.tool.name.localeCompare(a.tool.name)).slice(0,c).map(({tool:s})=>({name:s.name,namespace:s.namespace,description:s.description,inputSchema:s.inputSchema}));return{source:b.source,protocolVersion:b.protocolVersion,matches:o}}function G(e,t){if(t==="null")return e===null;if(t==="array")return Array.isArray(e);if(t==="object")return e!==null&&typeof e==="object"&&!Array.isArray(e);if(t==="integer")return typeof e==="number"&&Number.isInteger(e);if(t==="number")return typeof e==="number"&&Number.isFinite(e);return typeof e===t}function v(e,t,i="arguments"){let r=Array.isArray(t?.type)?t.type:t?.type?[t.type]:[];if(r.length&&!r.some((o)=>G(e,o)))throw Error(i+" must be "+r.join(" or "));if(e===null)return;if(typeof e==="number"){if(typeof t.minimum==="number"&&et.maximum)throw Error(i+" exceeds maximum "+t.maximum)}if(Array.isArray(e)){if(t.items)e.forEach((o,s)=>v(o,t.items,i+"["+s+"]"));return}if(typeof e!=="object")return;let c=t.properties||{};for(let o of t.required||[])if(!(o in e))throw Error(i+"."+o+" is required");if(t.additionalProperties===!1){for(let o of Object.keys(e))if(!(o in c))throw Error(i+"."+o+" is not allowed")}for(let[o,s]of Object.entries(e))if(c[o])v(s,c[o],i+"."+o)}function B(e){let t=typeof e?.name==="string"?e.name:"",i=V.get(t);if(!i)throw Error("Unknown Robinhood provider Tool: "+t);let r=e?.arguments;return v(r,i.inputSchema),ee(t,r)}function D(e,t){let i=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t})));if(!i.ok)throw Error(i.error||"Robinhood service failed");return i.value}function W(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((i)=>({name:i.operation,arguments:i.args}))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function I(e){w("BEGIN IMMEDIATE");try{e(),w("COMMIT")}catch(t){try{w("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function H(e,t){let i=q(e,["accounts"]);h("DELETE FROM accounts");for(let r of i){let c=g(r,{});if(!c)continue;let o=(n(r,["nickname","account_type","type"])||"").toUpperCase(),s=Y(r,["agentic_allowed","agenticAllowed"]),a=s?"AGENTIC":o.includes("IRA")||o.includes("RETIRE")?"RETIREMENT":o.includes("JOINT")?"JOINT":"PERSONAL";h("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at) VALUES(?,?,?,?,?,?,?)",[c,a,c.slice(-4),o,(n(r,["status"])||"active").toUpperCase(),s?1:0,t])}}function X(e,t,i){let r=g(e,t);if(!r)throw Error("Robinhood portfolio is missing account_number");let c=n(e,["cash","cash_available","withdrawable_amount"]),o=n(e,["buying_power","buyingPower"]),s=n(e,["day_pnl","dayPnl","equity_change"]),a=n(e,["week_pnl","weekPnl"]);h(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) + `);var A=b.tools,V=new Map(A.map((e)=>[e.name,e]));function _(){return Math.floor(Date.now()/1000)}function F(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function n(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let i of t){let r=F(e[i]);if(r!==null)return r}for(let i of Object.values(e)){let r=n(i,t);if(r!==null)return r}return null}function O(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let i of t)if(Array.isArray(e[i]))return e[i];for(let i of Object.values(e)){let r=O(i,t);if(r.length)return r}return[]}function Y(e,t){let i=n(e,t)?.toLowerCase();return i==="true"||i==="1"||i==="yes"}function U(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function g(e,t){let i=t?.account_number;return i===null||i===void 0||i===""?n(e,["account_number","accountNumber","account"])||"":String(i)}function q(e,t){let i=O(e,t);return i.length?i:Array.isArray(e)?e:e?[e]:[]}function z(e){let t=Array.isArray(e?.names)?new Set(e.names.filter((s)=>typeof s==="string")):new Set,i=String(e?.query??"").toLowerCase().split(/[^a-z0-9_]+/).filter(Boolean),r=typeof e?.namespace==="string"?e.namespace:"";if(!t.size&&!i.length)throw Error("search_tools requires query or names");let c=Math.max(1,Math.min(8,Number(e?.limit??5)||5)),o=A.filter((s)=>!r||s.namespace===r).map((s)=>{let a=s.name.toLowerCase(),p=a+" "+s.description.toLowerCase(),d=t.has(s.name)?1000:i.reduce((m,l)=>m+(a===l?100:a.includes(l)?20:p.includes(l)?3:0),0);return{tool:s,score:d}}).filter((s)=>s.score>0).sort((s,a)=>a.score-s.score||s.tool.name.localeCompare(a.tool.name)).slice(0,c).map(({tool:s})=>({name:s.name,namespace:s.namespace,description:s.description,inputSchema:s.inputSchema}));return{source:b.source,protocolVersion:b.protocolVersion,matches:o}}function G(e,t){if(t==="null")return e===null;if(t==="array")return Array.isArray(e);if(t==="object")return e!==null&&typeof e==="object"&&!Array.isArray(e);if(t==="integer")return typeof e==="number"&&Number.isInteger(e);if(t==="number")return typeof e==="number"&&Number.isFinite(e);return typeof e===t}function v(e,t,i="arguments"){let r=Array.isArray(t?.type)?t.type:t?.type?[t.type]:[];if(r.length&&!r.some((o)=>G(e,o)))throw Error(i+" must be "+r.join(" or "));if(e===null)return;if(typeof e==="number"){if(typeof t.minimum==="number"&&et.maximum)throw Error(i+" exceeds maximum "+t.maximum)}if(Array.isArray(e)){if(t.items)e.forEach((o,s)=>v(o,t.items,i+"["+s+"]"));return}if(typeof e!=="object")return;let c=t.properties||{};for(let o of t.required||[])if(!(o in e))throw Error(i+"."+o+" is required");if(t.additionalProperties===!1){for(let o of Object.keys(e))if(!(o in c))throw Error(i+"."+o+" is not allowed")}for(let[o,s]of Object.entries(e))if(c[o])v(s,c[o],i+"."+o)}function B(e){let t=typeof e?.name==="string"?e.name:"",i=V.get(t);if(!i)throw Error("Unknown Robinhood provider Tool: "+t);let r=e?.arguments;return v(r,i.inputSchema),ee(t,r)}function D(e,t){let i=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t})));if(!i.ok)throw Error(i.error||"Robinhood service failed");return i.value}function W(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((i)=>({name:i.operation,arguments:i.args}))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function I(e){w("BEGIN IMMEDIATE");try{e(),w("COMMIT")}catch(t){try{w("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function H(e,t){let i=q(e,["accounts"]);h("DELETE FROM accounts");for(let r of i){let c=g(r,{});if(!c)continue;let o=(n(r,["nickname","account_type","type"])||"").toUpperCase(),s=Y(r,["agentic_allowed","agenticAllowed"]),a=s?"AGENTIC":o.includes("IRA")||o.includes("RETIRE")?"RETIREMENT":o.includes("JOINT")?"JOINT":"PERSONAL";h("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at) VALUES(?,?,?,?,?,?,?)",[c,a,c.slice(-4),o,(n(r,["status"])||"active").toUpperCase(),s?1:0,t])}}function X(e,t,i){let r=g(e,t);if(!r)throw Error("Robinhood portfolio is missing account_number");let c=n(e,["cash","cash_available","withdrawable_amount"]),o=n(e,["buying_power","buyingPower"]),s=n(e,["day_pnl","dayPnl","equity_change"]),a=n(e,["week_pnl","weekPnl"]);h(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?,?,?) ON CONFLICT(account_number) DO UPDATE SET cash=excluded.cash,buying_power=excluded.buying_power, @@ -237,7 +237,7 @@ Returns the scan with its new filters and fresh live results. This changes Robin day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), observed_at=MAX(portfolio_current.observed_at,excluded.observed_at)`,[r,o==="week"?null:c,o==="week"?c:null,i])}function C(e){if(e.operation==="get_accounts")H(e.value,e.observedAt);else if(e.operation==="get_portfolio")X(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_positions")J(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_orders")Z(e.value,e.args,e.observedAt);else if(e.operation==="get_realized_pnl")$(e.value,e.args,e.observedAt);else return!1;return!0}function Q(e){let t=e.toLowerCase();return t.includes("esp_err_http_connect")||t.includes("timeout")||t.includes("tls")||t.includes("socket")||t.includes("network")}function S(){let e=_(),t=[],i=[],r=0,c=(a,p)=>{r+=1;try{let d=D(a,p);return t.push({operation:a,args:p,value:d,observedAt:_()}),d}catch(d){let m=d instanceof Error?d.message:String(d);if(i.push(a+": "+m),a==="get_accounts"||Q(m))throw d;return null}},o=null;try{let a=c("get_accounts",{}),d=q(a,["accounts"]).map((u)=>g(u,{})).filter(Boolean);if(!d.length)throw Error("Robinhood returned no brokerage accounts");let m=new Date((e-604800)*1000).toISOString().slice(0,10),l=[];for(let u of d){let y={account_number:u};l.push({operation:"get_portfolio",args:y},{operation:"get_equity_positions",args:y},{operation:"get_equity_orders",args:{...y,created_at_gte:m}},{operation:"get_realized_pnl",args:{...y,span:"day",asset_classes:["equity"]}},{operation:"get_realized_pnl",args:{...y,span:"week",asset_classes:["equity"]}})}r+=l.length;let P=W(l);if(P.length!==l.length)throw Error("Robinhood batch returned an incomplete result set");if(P.forEach((u,y)=>{let f=l[y];if(u?.ok)t.push({operation:f.operation,args:f.args,value:u.value,observedAt:_()});else i.push(f.operation+": "+String(u?.error||"unknown provider error"))}),!t.some((u)=>u.operation==="get_portfolio"))throw Error("Robinhood batch returned no portfolio data")}catch(a){o=a instanceof Error?a.message:String(a)}let s=o?"failed":i.length?"partial":"succeeded";if(I(()=>{if(!o)for(let a of t)C(a);h(`INSERT INTO refresh_runs(started_at,completed_at,status,operation_count,success_count,error) - VALUES(?,?,?,?,?,?)`,[e,_(),s,r,o?0:t.length,o||i.join(" | ")||null])}),o)throw Error(o);return{status:s,operationCount:r,successCount:t.length}}function K(e,t,i,r){let c=String(i?.account_number??i?.accountNumber??"");if(!c)return;let s=String(i?.order_id??n(t,["order_id","orderId","id"])??"")||[r,i?.symbol||"EQUITY",e].join(":"),a=e==="cancel_equity_order"?n(t,["state","status"])||"CANCEL_REQUESTED":n(t,["state","status"])||"SUBMITTED";h(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) + VALUES(?,?,?,?,?,?)`,[e,_(),s,r,o?0:t.length,o||i.join(" | ")||null])}),o)throw Error(o);return{status:s,operationCount:r,successCount:t.length}}function K(e,t,i,r){let c=String(i?.account_number??"");if(!c)return;let s=String(i?.order_id??n(t,["order_id","orderId","id"])??"")||[r,i?.symbol||"EQUITY",e].join(":"),a=e==="cancel_equity_order"?n(t,["state","status"])||"CANCEL_REQUESTED":n(t,["state","status"])||"SUBMITTED";h(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) VALUES(?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(account_number,activity_id) DO UPDATE SET occurred_at=COALESCE(excluded.occurred_at,activities.occurred_at), diff --git a/crates/pocket-pi-agentos/src/lib.rs b/crates/pocket-pi-agentos/src/lib.rs index cd536b7..2c854a5 100644 --- a/crates/pocket-pi-agentos/src/lib.rs +++ b/crates/pocket-pi-agentos/src/lib.rs @@ -24,8 +24,8 @@ use serde_json::{json, Value}; pub const ROOT_APP_ID: &str = "pi-agent"; pub const ROBINHOOD_APP_ID: &str = "robinhood"; pub const EXA_APP_ID: &str = "exa"; -pub const BUILTIN_RELEASE: &str = "builtin-v1"; -pub const VIEWPORT: (f32, f32) = (720.0, 1280.0); +const BUILTIN_RELEASE: &str = "builtin-v1"; +const VIEWPORT: (f32, f32) = (720.0, 1280.0); // App tools must enqueue remote work quickly. Keep a defensive bound for the // Tool Router handoff and local read-only diagnostics; remote work itself runs @@ -51,29 +51,29 @@ const EXA_POCKET: &str = include_str!("../../../apps/exa/pocket.json"); #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -pub struct AppDescriptor { - pub id: String, - pub version: String, +struct AppDescriptor { + id: String, + version: String, #[serde(default)] - pub data_version: u32, + data_version: u32, #[serde(default)] - pub tools: Vec, + tools: Vec, #[serde(default)] - pub provider_operations: Vec, + provider_operations: Vec, #[serde(default)] - pub tasks: Vec, + tasks: Vec, #[serde(default)] - pub schedules: Vec, + schedules: Vec, } #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -pub struct AppSchedule { - pub id: String, - pub every_minutes: u64, - pub task: String, +struct AppSchedule { + id: String, + every_minutes: u64, + task: String, #[serde(default)] - pub args: Value, + args: Value, } #[derive(Clone)] @@ -178,18 +178,18 @@ impl AppCatalog { Ok(Self { apps, tool_owner }) } - pub fn tool_definitions(&self) -> Vec { + fn tool_definitions(&self) -> Vec { self.apps .values() .flat_map(|app| app.descriptor.tools.clone()) .collect() } - pub fn app_for_tool(&self, name: &str) -> Option<&str> { + fn app_for_tool(&self, name: &str) -> Option<&str> { self.tool_owner.get(name).map(String::as_str) } - pub fn descriptors(&self) -> impl Iterator { + fn descriptors(&self) -> impl Iterator { self.apps.values().map(|app| &app.descriptor) } @@ -562,8 +562,7 @@ impl AppDataRunner { } } -pub struct AppRuntime { - descriptor: AppDescriptor, +struct AppRuntime { guest: Guest, surface: UiSurface, _fs: Rc>, @@ -644,7 +643,6 @@ impl AppRuntime { let last_seen_revision = revision.load(Ordering::Acquire); Ok(Self { - descriptor, guest, surface, _fs: fs, @@ -656,14 +654,6 @@ impl AppRuntime { }) } - pub fn id(&self) -> &str { - &self.descriptor.id - } - - pub fn frame(&self) -> Result<()> { - self.advance(true) - } - fn projection_is_stale(&self) -> bool { self.revision.load(Ordering::Acquire) != self.last_seen_revision.get() } @@ -698,12 +688,12 @@ impl AppRuntime { Ok(()) } - pub fn update(&self, projection: &Value) -> Result<()> { + fn update(&self, projection: &Value) -> Result<()> { self.call_method("update", (projection.to_string(),)) .map(|_: String| ()) } - pub fn tap(&self, x: u16, y: u16) -> Result { + fn tap(&self, x: u16, y: u16) -> Result { let line: String = self.call_method("tap", (x as i32, y as i32))?; if line.is_empty() { return Ok(Value::Null); @@ -711,26 +701,21 @@ impl AppRuntime { serde_json::from_str(&line).context("parse App tap action") } - pub fn pointer_down(&self, x: u16, y: u16) -> Result<()> { + fn pointer_down(&self, x: u16, y: u16) -> Result<()> { self.call_optional_method("pointerDown", (x as i32, y as i32)) } - pub fn pointer_up(&self) -> Result<()> { + fn pointer_up(&self) -> Result<()> { self.call_optional_method("pointerUp", ()) } - pub fn invoke_tool(&self, name: &str, args_json: &str) -> Result { + fn invoke_tool(&self, name: &str, args_json: &str) -> Result { let line: String = self.call_method("invokeTool", (name.to_owned(), args_json.to_owned()))?; self.tool_result(&line) } - pub fn invoke_task(&self, name: &str, args: &Value) -> Result { - let line: String = self.call_method("invokeTask", (name.to_owned(), args.to_string()))?; - self.tool_result(&line) - } - - pub fn with_ui(&self, f: impl FnOnce(&mut pocketjs_core::Ui) -> R) -> R { + fn with_ui(&self, f: impl FnOnce(&mut pocketjs_core::Ui) -> R) -> R { self.surface.with_ui(f) } @@ -1034,7 +1019,6 @@ impl AppSupervisor { backend, tools, &agent_source, - Arc::new(|_| {}), ) .map_err(|error| anyhow!(error))?, ); @@ -1051,16 +1035,6 @@ impl AppSupervisor { .map_err(|error| anyhow!(error)) } - pub fn abort_agent(&self) -> Result<()> { - let agent = self - .agent - .as_ref() - .ok_or_else(|| anyhow!("Pi Agent System App is not booted"))?; - agent - .abort(&self.system.guest) - .map_err(|error| anyhow!(error)) - } - /// Advance the resident System App and cheap View bookkeeping. Only the /// selected surface is rendered; Data Actions progress on their own runner. pub fn frame(&self) -> Result> { @@ -1498,13 +1472,6 @@ impl AppScheduleStore { fn load(workspace: &Path, catalog: &AppCatalog) -> Result { // AppTask declarations travel with the App release, while their // mutable scheduler cursor belongs to that App's private data root. - // The former central file is read once only to migrate existing - // installs; it is never written again. - let legacy_path = workspace.join(".system/schedules.json"); - let mut legacy: Vec = std::fs::read(&legacy_path) - .ok() - .and_then(|bytes| serde_json::from_slice(&bytes).ok()) - .unwrap_or_default(); let now = unix_seconds(); let mut paths = BTreeMap::new(); let mut schedules = Vec::new(); @@ -1533,7 +1500,6 @@ impl AppScheduleStore { let every_seconds = declaration.every_minutes.saturating_mul(60).max(60); let existing = prior .iter_mut() - .chain(legacy.iter_mut()) .find(|item| item.app_id == app.id && item.schedule_id == declaration.id); schedules.push(match existing { Some(item) @@ -1555,10 +1521,6 @@ impl AppScheduleStore { } let store = Self { paths, schedules }; store.persist()?; - if legacy_path.exists() { - std::fs::remove_file(&legacy_path) - .with_context(|| format!("remove migrated {}", legacy_path.display()))?; - } Ok(store) } @@ -1735,19 +1697,6 @@ mod tests { } } - #[test] - fn catalog_exposes_namespaced_app_tools() { - let catalog = AppCatalog::builtin().unwrap(); - let names = catalog - .tool_definitions() - .into_iter() - .filter_map(|tool| tool["name"].as_str().map(str::to_owned)) - .collect::>(); - assert!(names.contains(&"robinhood.search_tools".to_owned())); - assert!(names.contains(&"robinhood.call".to_owned())); - assert!(names.contains(&"research.search".to_owned())); - } - #[test] fn exa_catalog_exposes_bounded_advanced_search() { let catalog = AppCatalog::builtin().unwrap(); @@ -1886,23 +1835,6 @@ mod tests { #[test] fn app_task_schedule_state_is_owned_by_each_app_data_root() { let temp = tempfile::tempdir().unwrap(); - let legacy = temp.path().join(".system/schedules.json"); - std::fs::create_dir_all(legacy.parent().unwrap()).unwrap(); - std::fs::write( - &legacy, - serde_json::to_vec(&vec![StoredSchedule { - app_id: ROBINHOOD_APP_ID.to_owned(), - schedule_id: "portfolio-refresh".to_owned(), - task: "refreshPortfolio".to_owned(), - args: json!({}), - every_seconds: 300, - next_run_at: unix_seconds().saturating_add(123), - last_ok: Some(true), - }]) - .unwrap(), - ) - .unwrap(); - let _supervisor = AppSupervisor::new(temp.path(), Arc::new(NoServices)).unwrap(); let app_state = temp .path() @@ -1912,63 +1844,8 @@ mod tests { assert_eq!(stored.len(), 1); assert_eq!(stored[0].app_id, ROBINHOOD_APP_ID); - assert_eq!(stored[0].last_ok, Some(true)); - assert!(!legacy.exists()); - } - - #[test] - fn root_view_keeps_legacy_tabs_and_adds_app_navigation() { - let temp = tempfile::tempdir().unwrap(); - std::fs::write(temp.path().join("agent-note.txt"), "top-level workspace").unwrap(); - let supervisor = AppSupervisor::new(temp.path(), Arc::new(NoServices)).unwrap(); - supervisor - .update_root(&json!({ - "agent":"IDLE", - "model":"test", - "messages":[{"role":"assistant","text":"ready"}], - })) - .unwrap(); - - // Files remains a Pi Agent screen and its PocketJS FS is rooted at - // the complete workspace, not only /workspace/data. - assert_eq!(supervisor.tap(270, 1220).unwrap(), Value::Null); - supervisor.frame().unwrap(); - - // Apps is the only new bottom tab; its cards navigate through the - // native App Supervisor instead of embedding another App's View. - assert_eq!(supervisor.tap(450, 1220).unwrap(), Value::Null); - let action = supervisor.tap(300, 220).unwrap(); - assert_eq!(action["type"], "navigate"); - assert_eq!(action["app"], ROBINHOOD_APP_ID); - - // Settings stays in the Root App, while the command is returned to - // the host that owns Wi-Fi credentials and drivers. - assert_eq!(supervisor.tap(630, 1220).unwrap(), Value::Null); - let action = supervisor.tap(560, 170).unwrap(); - assert_eq!(action["type"], "settings"); - assert_eq!(action["command"], "scan"); - } - - #[test] - fn keyboard_key_has_a_bounded_pointer_down_visual_state() { - let temp = tempfile::tempdir().unwrap(); - let supervisor = AppSupervisor::new(temp.path(), Arc::new(NoServices)).unwrap(); - - // Open the prompt keyboard, then press Q without invoking the key. The - // DrawList must change only while the pointer is held down. - supervisor.tap(300, 1110).unwrap(); - supervisor.frame().unwrap(); - let idle = supervisor.with_ui(|ui| ui.draw().words.clone()); - - supervisor.pointer_down(50, 520).unwrap(); - supervisor.frame().unwrap(); - let pressed = supervisor.with_ui(|ui| ui.draw().words.clone()); - assert_ne!(pressed, idle); - - supervisor.pointer_up().unwrap(); - supervisor.frame().unwrap(); - let released = supervisor.with_ui(|ui| ui.draw().words.clone()); - assert_eq!(released, idle); + assert_eq!(stored[0].last_ok, None); + assert!(!temp.path().join(".system/schedules.json").exists()); } #[test] diff --git a/crates/pocket-pi-embedded/Cargo.toml b/crates/pocket-pi-embedded/Cargo.toml index 7a7e52c..5b7ac22 100644 --- a/crates/pocket-pi-embedded/Cargo.toml +++ b/crates/pocket-pi-embedded/Cargo.toml @@ -9,5 +9,7 @@ description = "Small pi-agent-core runtime for embedded Pocket Pi hosts" [dependencies] pocket-mod.workspace = true pocket-pi-protocols.workspace = true +# pocket-mod re-exports these types but does not enable target bindings. +# This direct edge unifies rquickjs features so ESP-IDF generates its bindings. rquickjs = { version = "=0.12.1", default-features = false, features = ["bindgen", "std"] } serde_json.workspace = true diff --git a/crates/pocket-pi-embedded/js/env.d.ts b/crates/pocket-pi-embedded/js/env.d.ts index 776d4ef..41e2105 100644 --- a/crates/pocket-pi-embedded/js/env.d.ts +++ b/crates/pocket-pi-embedded/js/env.d.ts @@ -10,7 +10,6 @@ declare global { | { boot(config: string): void; prompt(text: string): void; - abort(): void; tick(): void; drain(): string; } diff --git a/crates/pocket-pi-embedded/js/pi-agent.bundle.js b/crates/pocket-pi-embedded/js/pi-agent.bundle.js index bf8f695..b22c52f 100644 --- a/crates/pocket-pi-embedded/js/pi-agent.bundle.js +++ b/crates/pocket-pi-embedded/js/pi-agent.bundle.js @@ -398,7 +398,7 @@ all_start",contentIndex,partial:{...pending.partial}});pending.stream.push({type api,provider:model.provider,model:model.id,usage:emptyUsage(),stopReason:"error",errorMessage:message,timestamp:Date.now()}})}function boot(configJson){const config=JSON.parse(configJson);const model=modelFor(config);const tools=(config.tools||[]).map(tool=>({name:tool.name,label:tool.label||tool.name,description:tool.description||"",parameters:tool.parameters||{type:"object",properties:{}},executionMode:"sequential",execute:(id,args)=>new Promise((resolve,reject)=>{try{if(!globalThis.host)throw new Error( "Pocket Pi Agent host is unavailable");const requestId=globalThis.host.startTool(id,tool.name,JSON.stringify(args||{}));pendingTools.set(requestId,{resolve,reject})}catch(error){reject(error instanceof Error?error:new Error(String(error)))}})}));agent=new Agent({initialState:{systemPrompt:config.systemPrompt||"You are Pocket Pi running on an embedded device.",model,thinkingLevel:model.reasoning?config.thinkingLevel||"high":"off",tools},streamFn:hostStream,toolExecution:"sequential"});agent.subscribe( event=>{const compact={type:event.type};if(event.type==="message_update"){compact.kind=event.assistantMessageEvent?.type;compact.delta=event.assistantMessageEvent?.delta}else if(event.type==="message_end"){compact.role=event.message?.role;compact.stopReason=event.message?.stopReason}else if(event.type==="tool_execution_start"||event.type==="tool_execution_end"){compact.name=event.toolName;compact.toolCallId=event.toolCallId;compact.isError=Boolean(event.isError)}events.push(compact)});events.push( -{type:"agent_ready"})}function prompt(text){if(!agent)throw new Error("prompt before boot");void agent.prompt(text).catch(error=>events.push({type:"agent_error",message:String(error)}))}function abort(){agent?.abort()}function tick(){const batch=JSON.parse(globalThis.host?.poll()||"[]");for(const event of batch){if(event.type==="model_progress"){const pending=pendingModels.get(event.id);if(!pending)continue;pushThinkingDelta(pending,event.thinkingDelta);pushTextDelta(pending,event.textDelta)}else if(event. -type==="model_done"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);try{finishModel(pending,JSON.parse(event.result))}catch(error){pushModelError(pending.stream,pending.model,String(error))}}else if(event.type==="model_error"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);pushModelError(pending.stream,pending.model,event.error)}else if(event.type==="tool_done"){const pending=pendingTools.get(event.id); -if(!pending)continue;pendingTools.delete(event.id);try{const result=JSON.parse(event.result);if(result.isError)throw new Error(String(result.text||"App tool failed"));pending.resolve({content:[{type:"text",text:String(result.text||"")}],details:result.details,terminate:Boolean(result.terminate)})}catch(error){pending.reject(error instanceof Error?error:new Error(String(error)))}}}}function drain(){return JSON.stringify({phase:agent?.state.isStreaming?"thinking":agent?"ready":"idle",messages:agent?. -state.messages.length||0,events:events.splice(0,events.length)})}globalThis.PocketPiEmbedded={boot,prompt,abort,tick,drain};})(); +{type:"agent_ready"})}function prompt(text){if(!agent)throw new Error("prompt before boot");void agent.prompt(text).catch(error=>events.push({type:"agent_error",message:String(error)}))}function tick(){const batch=JSON.parse(globalThis.host?.poll()||"[]");for(const event of batch){if(event.type==="model_progress"){const pending=pendingModels.get(event.id);if(!pending)continue;pushThinkingDelta(pending,event.thinkingDelta);pushTextDelta(pending,event.textDelta)}else if(event.type==="model_done"){ +const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);try{finishModel(pending,JSON.parse(event.result))}catch(error){pushModelError(pending.stream,pending.model,String(error))}}else if(event.type==="model_error"){const pending=pendingModels.get(event.id);if(!pending)continue;pendingModels.delete(event.id);pushModelError(pending.stream,pending.model,event.error)}else if(event.type==="tool_done"){const pending=pendingTools.get(event.id);if(!pending)continue; +pendingTools.delete(event.id);try{const result=JSON.parse(event.result);if(result.isError)throw new Error(String(result.text||"App tool failed"));pending.resolve({content:[{type:"text",text:String(result.text||"")}],details:result.details,terminate:Boolean(result.terminate)})}catch(error){pending.reject(error instanceof Error?error:new Error(String(error)))}}}}function drain(){return JSON.stringify({phase:agent?.state.isStreaming?"thinking":agent?"ready":"idle",messages:agent?.state.messages.length|| +0,events:events.splice(0,events.length)})}globalThis.PocketPiEmbedded={boot,prompt,tick,drain};})(); diff --git a/crates/pocket-pi-embedded/js/src/entry.ts b/crates/pocket-pi-embedded/js/src/entry.ts index 0d4056f..d80b044 100644 --- a/crates/pocket-pi-embedded/js/src/entry.ts +++ b/crates/pocket-pi-embedded/js/src/entry.ts @@ -354,10 +354,6 @@ function prompt(text: string): void { void agent.prompt(text).catch((error) => events.push({ type: "agent_error", message: String(error) })); } -function abort(): void { - agent?.abort(); -} - function tick(): void { const batch = JSON.parse(globalThis.host?.poll() || "[]") as HostEvent[]; for (const event of batch) { @@ -407,4 +403,4 @@ function drain(): string { }); } -globalThis.PocketPiEmbedded = { boot, prompt, abort, tick, drain }; +globalThis.PocketPiEmbedded = { boot, prompt, tick, drain }; diff --git a/crates/pocket-pi-embedded/src/lib.rs b/crates/pocket-pi-embedded/src/lib.rs index 1fa85a8..373c64c 100644 --- a/crates/pocket-pi-embedded/src/lib.rs +++ b/crates/pocket-pi-embedded/src/lib.rs @@ -1,12 +1,10 @@ use std::sync::atomic::{AtomicI32, Ordering}; use std::sync::{mpsc, Arc, Mutex}; -use std::time::Duration; use pocket_mod::qjs::{CatchResultExt, Function, Object}; use pocket_mod::Guest; pub use pocket_pi_protocols::model::ModelStreamEvent; -const AGENT_BUNDLE: &str = include_str!("../js/pi-agent.bundle.js"); const PRELUDE: &str = include_str!("../js/prelude.js"); pub const MODEL_WORKER_STACK_BYTES: usize = 64 * 1024; const TOOL_WORKER_STACK_BYTES: usize = 16 * 1024; @@ -66,34 +64,15 @@ impl ToolResult { /// the Root App's existing PocketJS Guest, so the Agent Loop, context, tools /// and Root View have one App lifecycle. Slow model and tool work happens on /// worker threads; `tick` only delivers completed events into the Guest. -pub struct GuestAgent { - on_text: Arc, -} +pub struct GuestAgent; impl GuestAgent { - pub fn mount( - guest: &Guest, - config_json: &str, - backend: Arc, - tools: Arc, - ) -> Result { - Self::mount_source( - guest, - config_json, - backend, - tools, - AGENT_BUNDLE, - Arc::new(|_| {}), - ) - } - pub fn mount_source( guest: &Guest, config_json: &str, backend: Arc, tools: Arc, agent_source: &str, - on_text: Arc, ) -> Result { let config_json = config_with_tools(config_json, tools.definitions())?; let (host_tx, host_rx) = mpsc::channel::(); @@ -232,17 +211,13 @@ impl GuestAgent { call_agent::<_, ()>(guest, "boot", (config_json,))?; guest.drain_jobs(); - Ok(Self { on_text }) + Ok(Self) } pub fn prompt(&self, guest: &Guest, text: &str) -> Result<(), String> { call_agent(guest, "prompt", (text.to_owned(),)) } - pub fn abort(&self, guest: &Guest) -> Result<(), String> { - call_agent(guest, "abort", ()) - } - pub fn tick(&self, guest: &Guest) -> Result, String> { call_agent::<_, ()>(guest, "tick", ())?; guest.drain_jobs(); @@ -255,7 +230,6 @@ impl GuestAgent { Some("agent_ready") => events.push(AgentEvent::Ready), Some("message_update") if event["kind"] == "text_delta" => { if let Some(delta) = event["delta"].as_str().filter(|delta| !delta.is_empty()) { - (self.on_text)(delta.to_owned()); events.push(AgentEvent::ResponseText(delta.to_owned())); } } @@ -322,56 +296,6 @@ where }) } -/// Standalone harness. Product hosts should mount `GuestAgent` -/// through `AppSupervisor`, which keeps the System App alive across View -/// navigation. -pub struct PiEmbedded { - guest: Guest, - agent: GuestAgent, -} - -impl PiEmbedded { - pub fn new( - config_json: &str, - backend: Arc, - tools: Arc, - on_text: Arc, - ) -> Result { - let guest = Guest::new().map_err(|error| error.to_string())?; - let agent = - GuestAgent::mount_source(&guest, config_json, backend, tools, AGENT_BUNDLE, on_text)?; - Ok(Self { guest, agent }) - } - - pub fn prompt(&self, text: &str) -> Result<(), String> { - self.agent.prompt(&self.guest, text) - } - - pub fn pump(&self) -> Result { - let mut observed = Vec::new(); - loop { - self.guest.frame(0).map_err(|error| error.to_string())?; - let events = self.agent.tick(&self.guest)?; - let mut finished = false; - for event in events { - match event { - AgentEvent::Ready => observed.push("agent_ready"), - AgentEvent::ResponseText(_) => observed.push("message_update"), - AgentEvent::Done => { - observed.push("agent_end"); - finished = true; - } - AgentEvent::Failed(error) => return Err(error), - } - } - if finished { - return serde_json::to_string(&observed).map_err(|error| error.to_string()); - } - std::thread::sleep(Duration::from_millis(2)); - } - } -} - fn config_with_tools( config_json: &str, definitions: Vec, @@ -399,26 +323,9 @@ fn config_with_tools( mod tests { use super::*; use std::sync::atomic::AtomicUsize; + use std::time::Duration; - struct Backend; - - impl ModelBackend for Backend { - fn complete( - &self, - _request_json: &str, - on_event: &mut dyn FnMut(ModelStreamEvent), - ) -> Result { - on_event(ModelStreamEvent::Text("embedded-ok".into())); - Ok(serde_json::json!({ - "thinking":"", - "text":"embedded-ok", - "toolCalls":[], - "usage":{}, - "stopReason":"stop" - }) - .to_string()) - } - } + const TEST_AGENT_BUNDLE: &str = include_str!("../js/pi-agent.bundle.js"); struct BurstBackend; @@ -470,28 +377,15 @@ mod tests { assert_eq!(config["tools"].as_array().unwrap().len(), 1); } - #[test] - fn boots_and_runs_a_real_pi_agent_turn() { - let runtime = PiEmbedded::new( - r#"{"model":"offline"}"#, - Arc::new(Backend), - Arc::new(Tools), - Arc::new(|_| {}), - ) - .unwrap(); - runtime.prompt("hello").unwrap(); - let events = runtime.pump().unwrap(); - assert!(events.contains("agent_end")); - } - #[test] fn model_progress_is_coalesced_before_reaching_the_embedded_ui() { let guest = Guest::new().unwrap(); - let agent = GuestAgent::mount( + let agent = GuestAgent::mount_source( &guest, r#"{"model":"offline"}"#, Arc::new(BurstBackend), Arc::new(Tools), + TEST_AGENT_BUNDLE, ) .unwrap(); agent.prompt(&guest, "burst").unwrap(); @@ -596,7 +490,7 @@ mod tests { let threads = Arc::new(Mutex::new(Vec::new())); let executed = Arc::new(Mutex::new(Vec::new())); let guest = Guest::new().unwrap(); - let agent = GuestAgent::mount( + let agent = GuestAgent::mount_source( &guest, r#"{"provider":"deepseek","model":"deepseek-v4-pro","thinkingLevel":"high"}"#, Arc::new(ThinkingToolBackend { @@ -605,6 +499,7 @@ mod tests { threads: threads.clone(), }), Arc::new(OrderedTools(executed.clone())), + TEST_AGENT_BUNDLE, ) .unwrap(); agent.prompt(&guest, "run both").unwrap(); diff --git a/crates/pocket-pi-protocols/src/model.rs b/crates/pocket-pi-protocols/src/model.rs index d654712..2f1a812 100644 --- a/crates/pocket-pi-protocols/src/model.rs +++ b/crates/pocket-pi-protocols/src/model.rs @@ -2,8 +2,6 @@ use alloc::format; use alloc::string::{String, ToString}; use serde::{Deserialize, Serialize}; -pub const OPENAI_API_BASE_URL: &str = "https://api.openai.com/v1"; -pub const CODEX_BACKEND_BASE_URL: &str = "https://chatgpt.com/backend-api"; #[derive(Clone, Debug, Eq, PartialEq)] pub enum ModelStreamEvent { Thinking(String), diff --git a/crates/pocket-pi-tools/src/lib.rs b/crates/pocket-pi-tools/src/lib.rs index d26bef3..8c35efb 100644 --- a/crates/pocket-pi-tools/src/lib.rs +++ b/crates/pocket-pi-tools/src/lib.rs @@ -155,9 +155,6 @@ impl ToolResultExt for ToolResult { #[cfg(test)] mod tests { use super::*; - use std::sync::atomic::{AtomicUsize, Ordering}; - - use pocket_pi_embedded::{ModelBackend, ModelStreamEvent, PiEmbedded}; struct TestPlatform; @@ -241,78 +238,4 @@ mod tests { let restored = host(temp.path()).execute("call-3", "schedule.list", "{}"); assert!(restored.text.contains("market")); } - - struct ToolCallingBackend { - calls: AtomicUsize, - } - - impl ModelBackend for ToolCallingBackend { - fn complete( - &self, - request_json: &str, - on_event: &mut dyn FnMut(ModelStreamEvent), - ) -> Result { - let request: Value = serde_json::from_str(request_json).unwrap(); - let call = self.calls.fetch_add(1, Ordering::SeqCst); - if call == 0 { - let names = request["context"]["tools"] - .as_array() - .unwrap() - .iter() - .filter_map(|tool| tool["name"].as_str()) - .collect::>(); - assert!(names.contains(&"write")); - return Ok(json!({ - "thinking":"use write", - "thinkingSignature":"reasoning_content", - "text":"", - "toolCalls":[{ - "id":"write-1", - "name":"write", - "arguments":{"path":"agent-created.txt","content":"created through pi-agent-core"} - }], - "usage":{}, - "stopReason":"toolUse" - }) - .to_string()); - } - assert!(request["context"]["messages"] - .as_array() - .unwrap() - .iter() - .any(|message| message["role"] == "toolResult")); - on_event(ModelStreamEvent::Text("tool complete".into())); - Ok(json!({ - "thinking":"", - "text":"tool complete", - "toolCalls":[], - "usage":{}, - "stopReason":"stop" - }) - .to_string()) - } - } - - #[test] - fn pi_agent_executes_the_real_registered_tool() { - let temp = tempfile::tempdir().unwrap(); - let tools = Arc::new(host(temp.path())); - let runtime = PiEmbedded::new( - r#"{"provider":"test","model":"tool-test"}"#, - Arc::new(ToolCallingBackend { - calls: AtomicUsize::new(0), - }), - tools, - Arc::new(|_| {}), - ) - .unwrap(); - - runtime.prompt("create a file").unwrap(); - runtime.pump().unwrap(); - - assert_eq!( - std::fs::read_to_string(temp.path().join("agent-created.txt")).unwrap(), - "created through pi-agent-core" - ); - } } diff --git a/crates/pocket-pi-tools/src/schedule.rs b/crates/pocket-pi-tools/src/schedule.rs index 91551c6..a514778 100644 --- a/crates/pocket-pi-tools/src/schedule.rs +++ b/crates/pocket-pi-tools/src/schedule.rs @@ -43,8 +43,6 @@ impl ScheduleStore { let directory = workspace_root.join(".pi-agent"); let path = directory.join("schedule.json"); let _ = std::fs::create_dir_all(&directory); - // The previous recurring format is intentionally removed, not migrated. - let _ = std::fs::remove_file(directory.join("routines.json")); let state = match read_state(&path) { Ok(state) => state, Err(error) => { diff --git a/crates/pocket-pi/src/lib.rs b/crates/pocket-pi/src/lib.rs index d2e02f5..67fad4e 100644 --- a/crates/pocket-pi/src/lib.rs +++ b/crates/pocket-pi/src/lib.rs @@ -278,8 +278,8 @@ impl PiRuntime { /// Import and evaluate an ES module by specifier (absolute path, or a /// `node:` builtin), driving the Node resolver/loader — relative imports, - /// `node_modules` packages, and `.ts` transpile all work. Milestone toward - /// running unmodified pi-coding-agent. Returns after the module settles. + /// `node_modules` packages, and `.ts` transpilation all work for the + /// unmodified pi-coding-agent. Returns after the module settles. pub fn run_module(&mut self, specifier: &str) -> Result<(), String> { let spec = specifier.to_string(); self.ctx.with(|ctx| -> Result<(), String> { diff --git a/crates/pocket-pi/src/tests.rs b/crates/pocket-pi/src/tests.rs index 771aabc..99be2eb 100644 --- a/crates/pocket-pi/src/tests.rs +++ b/crates/pocket-pi/src/tests.rs @@ -49,9 +49,8 @@ fn reply_text(events: &[HostEvent]) -> String { out } -/// Milestone 1 of the Node-compat runtime: the module system resolves + loads -/// real modules — a relative `.ts` file (transpiled), `node:` builtins, and a -/// bare package from `node_modules` — and they run correctly. +/// The module system resolves and loads a relative transpiled `.ts` file, +/// `node:` builtins, and a bare package from `node_modules`. #[test] fn node_module_system_loads_ts_builtins_and_a_bare_package() { use std::fs; @@ -215,71 +214,6 @@ fn whatwg_fetch_returns_a_readable_response() { } } -/// Live end-to-end against OpenAI. Skipped unless OPENAI_API_KEY is set. -#[test] -fn live_openai_turn() { - let Ok(key) = std::env::var("OPENAI_API_KEY") else { - eprintln!("skipping live_openai_turn: OPENAI_API_KEY not set"); - return; - }; - let model = std::env::var("OPENAI_MODEL").unwrap_or_else(|_| "gpt-4o-mini".into()); - let (sink, cb) = collector(); - let mut rt = PiRuntime::new().expect("runtime"); - rt.on_event(cb); - let cfg = serde_json::json!({ - "provider": "openai", - "model": model, - "apiKey": key, - // Reasoning models (gpt-5.x) spend tokens thinking before answering — - // a tiny cap leaves nothing for the visible reply. - "maxTokens": 2048, - "systemPrompt": "Reply with exactly the word: pong" - }); - rt.boot(&cfg.to_string()).expect("boot"); - rt.prompt("ping").expect("prompt"); - run(&mut rt, sink.clone(), 4.0, 90.0); - - let events = sink.borrow(); - let kinds: Vec<&str> = events.iter().map(|e| e.kind.as_str()).collect(); - eprintln!("openai event kinds: {kinds:?}"); - for e in events.iter().filter(|e| e.kind == "error") { - eprintln!("openai error raw: {}", e.raw); - } - assert!(kinds.contains(&"end"), "turn did not complete: {kinds:?}"); - let text = reply_text(&events); - eprintln!("live openai said: {text:?}"); - assert!(!text.is_empty(), "no assistant text"); -} - -/// Live end-to-end against Anthropic. Skipped unless ANTHROPIC_API_KEY is set, -/// so `cargo test` is hermetic by default. -#[test] -fn live_anthropic_turn() { - let Ok(key) = std::env::var("ANTHROPIC_API_KEY") else { - eprintln!("skipping live_anthropic_turn: ANTHROPIC_API_KEY not set"); - return; - }; - let (sink, cb) = collector(); - let mut rt = PiRuntime::new().expect("runtime"); - rt.on_event(cb); - let cfg = serde_json::json!({ - "model": "claude-opus-4-8", - "apiKey": key, - "maxTokens": 64, - "systemPrompt": "Reply with exactly the word: pong" - }); - rt.boot(&cfg.to_string()).expect("boot"); - rt.prompt("ping").expect("prompt"); - run(&mut rt, sink.clone(), 4.0, 60.0); - - let events = sink.borrow(); - let kinds: Vec<&str> = events.iter().map(|e| e.kind.as_str()).collect(); - assert!(kinds.contains(&"end"), "turn did not complete: {kinds:?}"); - let text = reply_text(&events); - eprintln!("live model said: {text:?}"); - assert!(!text.is_empty(), "no assistant text"); -} - /// The full, unmodified pi-coding-agent is embedded and loaded by every /// `PiRuntime::new()`: `globalThis.PiFull` (createAgentSession, …) and the /// `PocketPi` host harness are both present with no external bundle, no network. @@ -329,72 +263,10 @@ fn full_pi_runs_with_offline_provider() { assert_eq!(reply_text(&events), "OFFLINE-E2E-OK"); } -/// Path B end-to-end: stand up an AgentSession from the UNMODIFIED bundled -/// pi-coding-agent and run one real turn against gpt-5.6 through Pocket Pi's -/// fetch + system proxy. Requires OPENAI_API_KEY and a reachable proxy, so it is -/// `#[ignore]`. Run with: -/// https_proxy=http://127.0.0.1:7897 OPENAI_API_KEY=... \ -/// cargo test -p pocket-pi runs_bundled_pi_turn -- --ignored --nocapture -#[ignore] -#[test] -fn runs_bundled_pi_turn() { - let manifest = env!("CARGO_MANIFEST_DIR"); - let driver = format!("{manifest}/js/pi-full/driver.js"); - let key = std::env::var("OPENAI_API_KEY").unwrap_or_default(); - if key.is_empty() { - eprintln!("skip: OPENAI_API_KEY not set"); - return; - } - - let mut rt = PiRuntime::new().expect("runtime"); - // Inject the key as a global (kept out of logs) then load the driver script. - rt.eval_script(&format!("globalThis.__OPENAI_KEY = {key:?};")) - .expect("inject key"); - let driver_src = std::fs::read_to_string(&driver).expect("driver.js"); - rt.eval_script(&driver_src).expect("driver eval"); - - // Kick off the async turn (fire-and-forget promise), then pump at 2Hz. - rt.eval_script("globalThis.__piRun('Reply with exactly: pocket pi lives');") - .expect("kick off"); - - let start = std::time::Instant::now(); - let mut done = false; - while start.elapsed().as_secs_f64() < 90.0 { - rt.pump().expect("pump"); - if rt.get_global_json("__piDone") == Some(serde_json::Value::Bool(true)) { - done = true; - break; - } - std::thread::sleep(std::time::Duration::from_millis(250)); - } - - let result = rt.get_global_json("__piResult"); - let err = rt.get_global_json("__piError"); - let last = rt.get_global_json("__piLastEvent"); - let log = rt.get_global_json("__piLog"); - eprintln!("TURN done={done} last_event={last:?}"); - eprintln!("TURN error={err:?}"); - eprintln!("TURN result={result:?}"); - if let Some(serde_json::Value::Array(items)) = log { - eprintln!("TURN log ({} events):", items.len()); - for it in items { - eprintln!(" - {}", it.as_str().unwrap_or_default()); - } - } - assert!(done, "turn did not complete within budget"); - assert_eq!(err, Some(serde_json::Value::Null), "agent errored"); - let text = result - .and_then(|v| v.as_str().map(String::from)) - .unwrap_or_default(); - assert!(!text.trim().is_empty(), "no assistant text produced"); -} - -/// Path B extensions (M6): load a real, unmodified pi extension through Pocket +/// Load a real, unmodified pi extension through Pocket /// Pi's OWN module loader — the `.ts` is transpiled natively with oxc, NOT jiti /// (which needs Node internals QuickJS lacks) — and hand its default factory to -/// pi's unmodified `loadExtensionFromFactory`. Asserts the extension's tool and -/// lifecycle hook register. Offline; only needs the built bundle. Run with: -/// cargo test -p pocket-pi loads_pi_extension_via_our_loader -- --ignored --nocapture +/// pi's unmodified `loadExtensionFromFactory`. #[test] fn loads_pi_extension_via_our_loader() { let manifest = env!("CARGO_MANIFEST_DIR"); @@ -458,10 +330,9 @@ fn drive_session(rt: &mut PiRuntime, opts_json: &str, max_secs: f64) -> bool { false } -/// M6b: bind an unmodified pi extension into a *live* AgentSession via the -/// first-class `extensionFactories` seam (no jiti, no network) and confirm the -/// session's ExtensionRunner picked up the hook and tool. Offline; bundle-gated. -/// cargo test -p pocket-pi binds_extension_into_session -- --ignored --nocapture +/// Bind an unmodified pi extension into a real AgentSession through the +/// first-class `extensionFactories` seam and confirm the ExtensionRunner picks +/// up its hook and tool. #[test] fn binds_extension_into_session() { let manifest = env!("CARGO_MANIFEST_DIR"); @@ -496,57 +367,9 @@ fn binds_extension_into_session() { ); } -/// M6b (online): run a real gpt-5.6 turn with the extension's `echo` tool active -/// and instruct the model to call it. Asserts the extension's lifecycle hook -/// fired and the tool actually executed. Network + bundle gated. Run with: -/// https_proxy=http://127.0.0.1:7897 OPENAI_API_KEY=... \ -/// cargo test -p pocket-pi runs_pi_turn_with_extension_tool -- --ignored --nocapture -#[ignore] -#[test] -fn runs_pi_turn_with_extension_tool() { - let manifest = env!("CARGO_MANIFEST_DIR"); - let driver = format!("{manifest}/js/pi-full/driver.js"); - let ext = format!("{manifest}/../../js/src/pi-full/example-extension.ts"); - let key = std::env::var("OPENAI_API_KEY").unwrap_or_default(); - if key.is_empty() { - eprintln!("skip: OPENAI_API_KEY not set"); - return; - } - let mut rt = PiRuntime::new().expect("runtime"); - rt.eval_script(&format!("globalThis.__OPENAI_KEY = {key:?};")) - .expect("inject key"); - rt.eval_script(&std::fs::read_to_string(&driver).expect("driver.js")) - .expect("driver eval"); - - let opts = serde_json::json!({ - "extensionPath": ext, - "tools": ["echo"], - "prompt": "Call the echo tool with text set to \"ping\". Use the tool; do not answer in prose.", - }) - .to_string(); - let done = drive_session(&mut rt, &opts, 90.0); - let err = rt.get_global_json("__piError"); - let hook = rt.get_global_json("__extAgentStartFired"); - let echoed = rt.get_global_json("__echoCalled"); - eprintln!("EXT-TURN done={done} error={err:?}"); - eprintln!("EXT-TURN agent_start_fired={hook:?} echoCalled={echoed:?}"); - assert!(done, "turn did not complete within budget"); - assert_eq!(err, Some(serde_json::Value::Null), "agent errored"); - assert_eq!( - hook, - Some(serde_json::Value::Bool(true)), - "extension agent_start hook did not fire during the turn" - ); - assert!( - echoed.is_some() && echoed != Some(serde_json::Value::Null), - "extension echo tool was not executed" - ); -} - -/// M7: persist a session to disk with pi's unmodified SessionManager (backed by +/// Persist a session to disk with pi's unmodified SessionManager (backed by /// Pocket Pi's fs builtin), then resume it in a fresh manager and confirm the -/// history round-trips. Offline; bundle-gated. Run with: -/// cargo test -p pocket-pi persists_and_resumes_session -- --ignored --nocapture +/// history round-trips. #[test] fn persists_and_resumes_session() { let manifest = env!("CARGO_MANIFEST_DIR"); @@ -608,34 +431,3 @@ fn persists_and_resumes_session() { "no .jsonl session file on disk" ); } - -/// WIP integration probe toward loading unmodified pi-coding-agent. Run with -/// `cargo test -- --ignored probe_pi_coding_agent --nocapture`. Currently clears -/// the whole Node-builtin + CJS dependency surface and reaches pi-coding-agent's -/// own modules (blocked on a QuickJS ESM indirect-re-export cycle). -#[ignore] -#[test] -fn probe_pi_coding_agent() { - let manifest = env!("CARGO_MANIFEST_DIR"); - let sdk = - format!("{manifest}/../../js/node_modules/@mariozechner/pi-coding-agent/dist/core/sdk.js"); - if !std::path::Path::new(&sdk).exists() { - eprintln!("skip: not installed"); - return; - } - let dir = std::env::temp_dir().join(format!("pca-probe-{}", std::process::id())); - let _ = std::fs::remove_dir_all(&dir); - std::fs::create_dir_all(&dir).unwrap(); - std::fs::write(dir.join("e.ts"), format!( - "import {{ createAgentSession }} from \"{sdk}\";\n(globalThis as any).__pca = typeof createAgentSession;\n" - )).unwrap(); - let mut rt = PiRuntime::new().expect("rt"); - match rt.run_module(dir.join("e.ts").to_str().unwrap()) { - Ok(()) => eprintln!( - "PROBE OK: createAgentSession = {:?}", - rt.get_global_json("__pca") - ), - Err(e) => eprintln!("PROBE ERR: {e}"), - } - let _ = std::fs::remove_dir_all(&dir); -} diff --git a/docs/agentos-architecture.md b/docs/agentos-architecture.md index 517c92c..ac29bc8 100644 --- a/docs/agentos-architecture.md +++ b/docs/agentos-architecture.md @@ -1047,16 +1047,15 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 KiB PSRAM stack,并把 PSRAM allocation caps 继承给按需创建的 96 KiB NET worker;常驻 model worker 使用 64 KiB PSRAM stack。System App 的其他线程仍 使用恢复后的 platform default。 -13. Simulator tests 已证明:Agent turn 进行中打开 Robinhood,仍能收到完整回复 +13. AgentOS 核心 contract tests 已证明:Agent turn 进行中打开 Robinhood,仍能收到完整回复 和 `agent_end`;前后台切换前后 System App Guest identity 不变;Exa 在前台 - 时 Agent 仍能路由 Robinhood App Tool、写 SQLite 并完成 turn。新增 contract + 时 Agent 仍能路由 Robinhood App Tool、写 SQLite 并完成 turn。revision contract test 证明 3 次 commit 在下一前台 frame 只 reload 一次,5 个普通 frame 不 reload,后台 2 次 commit 在重新打开时只 reload 一次。 -14. Simulator Data Action tests 已证明:Exa search 用一次 transaction 写入 +14. Simulator 的核心 Data Action tests 已证明:Exa search 用一次 transaction 写入 `searches` View projection;Robinhood 完整 fixture refresh 用一次 - transaction 写入各业务表与 terminal `refresh_runs`,并成功显示;provider - failure 只写 failed refresh run、保留上一次业务 projection,而且可以再次 - enqueue。 + transaction 写入各业务表与 terminal `refresh_runs`,形成固定 View 所需的 + projection;provider failure 只写 failed refresh run,不写入业务 projection。 15. `legacy_main()`、Rust `ScreenState` product UI 和其专属 display path 已删除, 固件没有保留旧 UI 或死代码。 16. 删除全部 legacy Rust UI 后的基线固件已刷入 ESP32-P4;实机从 System App @@ -1078,9 +1077,10 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 ESP32 owner 是原生 FreeRTOS task,主循环必须用 `vTaskDelay` 明确让出 CPU,不能用 pthread 语义的 `std::thread::sleep` 代替; 否则即使总 CPU/内存数字不高,CPU0 idle task 仍可能无法喂 watchdog。 -20. 当前代码已通过 `pocket-pi-agentos` 10 个 tests、ESP32-P4 Simulator 6 个 tests; - workspace 合计 58 passed、0 failed、3 ignored。对应实现此前也通过 ESP32-P4 - release cross-build 并刷入实体板。稳态冷启动测得 Root、Exa、 +20. 当前自动化只保留 Tool catalog、安全边界、App state ownership、Data Action + transaction、resident Agent lifecycle、Tool routing 和 revision coalescing 等核心 + contract;不保留 UI 坐标、按压视觉状态或重复 smoke tests。对应实现已通过 + ESP32-P4 release cross-build,并曾刷入实体板。稳态冷启动测得 Root、Exa、 Robinhood View preload 分别约 2.0、2.8、3.3 秒,约 20.5 秒进入完整 UI;没有 watchdog 或蓝屏。`dataVersion` reset 只发生一次,正常启动不重复 DDL。 21. 实机断网 Tool 验证已证明:Agent 调用 `research.search` 后,Data Action 在 @@ -1177,8 +1177,9 @@ preload 全部普通 View。Marketplace 是独立的后续项目,不属于当 7. 普通 App 无法读取另一个 App 的 data root。 8. Pi Agent 可以读取和管理顶层 `/workspace`。 9. 重启后 App 数据保留,错过的 recurring run 按规则合并一次。 -10. Tool schema 非法、capability 缺失、Bundle 损坏、migration 失败时 fail - closed,并进入 recovery 或保留上一个合法 release。 +10. 当前 v1 在 Tool schema 非法、capability 缺失或内置 Bundle 损坏时 fail + closed;`dataVersion` 变化只重建对应 App SQLite。migration recovery 和保留上一 + 个合法 release 属于 22.3 的 Marketplace 扩展验收,不冒充当前能力。 11. 同一份 Robinhood source 通过 simulator contract tests,并用对应 target artifacts 在真实 ESP32-P4 上运行。 12. Agent turn 进行中可以操作键盘、打开 Robinhood/Exa、在 App 内触摸交互并 diff --git a/firmware/esp32-p4/Cargo.lock b/firmware/esp32-p4/Cargo.lock index 7261691..bc75e07 100644 --- a/firmware/esp32-p4/Cargo.lock +++ b/firmware/esp32-p4/Cargo.lock @@ -1209,7 +1209,6 @@ dependencies = [ "pocket-pi-embedded", "pocket-pi-protocols", "pocket-pi-tools", - "pocketjs-core", "pocketjs-esp32p4-ppa", "serde_json", ] diff --git a/firmware/esp32-p4/Cargo.toml b/firmware/esp32-p4/Cargo.toml index a1ade00..a3938a0 100644 --- a/firmware/esp32-p4/Cargo.toml +++ b/firmware/esp32-p4/Cargo.toml @@ -31,7 +31,6 @@ pocket-pi-protocols = { path = "../../crates/pocket-pi-protocols" } pocket-pi-tools = { path = "../../crates/pocket-pi-tools" } esp-idf-svc = { version = "0.52.1", features = ["critical-section"] } embedded-svc = "0.29" -pocketjs-core = { git = "https://github.com/pocket-stack/pocketjs.git", rev = "9c809bbd047ddc75c27caa4990951a78d942477a" } pocketjs-esp32p4-ppa = { git = "https://github.com/pocket-stack/pocketjs.git", rev = "9c809bbd047ddc75c27caa4990951a78d942477a", features = ["esp-idf"] } [build-dependencies] diff --git a/hosts/esp32-p4-sim/Cargo.toml b/hosts/esp32-p4-sim/Cargo.toml index 0c4f691..5727f7e 100644 --- a/hosts/esp32-p4-sim/Cargo.toml +++ b/hosts/esp32-p4-sim/Cargo.toml @@ -14,7 +14,6 @@ pocket-pi-agentos = { path = "../../crates/pocket-pi-agentos" } pocket-pi-embedded = { path = "../../crates/pocket-pi-embedded" } pocket-pi-protocols = { path = "../../crates/pocket-pi-protocols" } pocket-pi-tools = { path = "../../crates/pocket-pi-tools" } -pocketjs-core.workspace = true pocket-ui-wgpu = { git = "https://github.com/pocket-stack/pocketjs.git", rev = "9c809bbd047ddc75c27caa4990951a78d942477a" } pocket3d = { git = "https://github.com/pocket-stack/pocketjs.git", rev = "9c809bbd047ddc75c27caa4990951a78d942477a", default-features = false } serde_json.workspace = true diff --git a/hosts/esp32-p4-sim/src/main.rs b/hosts/esp32-p4-sim/src/main.rs index f96a436..b13f6f2 100644 --- a/hosts/esp32-p4-sim/src/main.rs +++ b/hosts/esp32-p4-sim/src/main.rs @@ -77,14 +77,14 @@ fn parse_args() -> Result { "--screenshot" => screenshot = Some(PathBuf::from(next(&mut args, "--screenshot")?)), "--prompt" => prompt = Some(next(&mut args, "--prompt")?), "--workspace" => workspace = PathBuf::from(next(&mut args, "--workspace")?), - "--app" | "--view" => { + "--app" => { app = match next(&mut args, &argument)?.as_str() { - "chat" | "pi-agent" => ROOT_APP_ID.to_owned(), - "workspace" | "files" => { + "pi-agent" => ROOT_APP_ID.to_owned(), + "files" => { root_tap = Some((270, 1220)); ROOT_APP_ID.to_owned() } - "apps" | "runs" => { + "apps" => { root_tap = Some((450, 1220)); ROOT_APP_ID.to_owned() } @@ -167,7 +167,6 @@ impl PlatformTools for SimPlatform { /// Deterministic native fixtures keep the simulator useful without credentials. /// The App code, SQLite writes and View are exactly the same bundles as the board. -#[derive(Default)] struct SimAppServices; impl AppServiceHost for SimAppServices { @@ -344,7 +343,7 @@ impl Product { format!("Codex / {}", model.as_deref().unwrap_or("coding-plan")) } }; - let services: Arc = Arc::new(SimAppServices::default()); + let services: Arc = Arc::new(SimAppServices); let mut supervisor = AppSupervisor::new(workspace.clone(), services)?; supervisor.open(app)?; @@ -851,8 +850,7 @@ mod tests { fn exa_tool_writes_app_owned_sqlite() { init_logs(); let temp = tempfile::tempdir().unwrap(); - let mut supervisor = - AppSupervisor::new(temp.path(), Arc::new(SimAppServices::default())).unwrap(); + let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(SimAppServices)).unwrap(); let result = supervisor.invoke_tool( "research.search", r#"{"query":"NVIDIA FY2026 annual report 10-K revenue data center guidance","numResults":5,"includeDomains":["investor.nvidia.com","sec.gov"]}"#, @@ -880,9 +878,8 @@ mod tests { fn exa_write_removes_rows_older_than_seven_days() { init_logs(); let temp = tempfile::tempdir().unwrap(); - let mut supervisor = - AppSupervisor::new(temp.path(), Arc::new(SimAppServices::default())).unwrap(); - let first = supervisor.invoke_tool("research.search", r#"{"query":"old search"}"#); + let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(SimAppServices)).unwrap(); + let first = supervisor.invoke_tool("research.search", r#"{"query":"expired search"}"#); assert!(!first.is_error, "{}", first.text); wait_for(|| { supervisor @@ -916,46 +913,12 @@ mod tests { } #[test] - fn views_open_empty_databases_without_starting_data_actions() { - init_logs(); - let temp = tempfile::tempdir().unwrap(); - let mut supervisor = - AppSupervisor::new(temp.path(), Arc::new(SimAppServices::default())).unwrap(); - - let robinhood = supervisor.invoke_tool("robinhood.storage_status", "{}"); - assert!(!robinhood.is_error, "{}", robinhood.text); - assert!(robinhood.details["tables"].as_array().unwrap().is_empty()); - - let exa = supervisor.invoke_tool("research.storage_status", "{}"); - assert!(!exa.is_error, "{}", exa.text); - assert_eq!(exa.details["searches"], 0); - assert_eq!(exa.details["retentionDays"], 7); - assert_eq!(exa.details["schemaVersion"], 0); - assert_eq!(exa.details["expectedSchemaVersion"], 5); - assert!(exa.details["latestSearch"].is_null()); - } - - #[test] - fn app_navigation_keeps_pi_agent_at_workspace_root() { - init_logs(); - let temp = tempfile::tempdir().unwrap(); - let mut supervisor = - AppSupervisor::new(temp.path(), Arc::new(SimAppServices::default())).unwrap(); - supervisor.open("robinhood").unwrap(); - assert_eq!(supervisor.active_id(), "robinhood"); - assert!(temp.path().join("data/view/current").exists()); - assert!(temp.path().join("apps/robinhood/current").exists()); - } - - #[test] - fn robinhood_refresh_recovers_after_service_failure() { + fn robinhood_refresh_failure_records_no_view_data() { init_logs(); let temp = tempfile::tempdir().unwrap(); let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(FailingRobinhood)).unwrap(); supervisor.open("robinhood").unwrap(); - let first = supervisor.tap(650, 1220).unwrap(); - assert_eq!(first["type"], "invokeTask"); let failed = supervisor.invoke_active_task("refreshPortfolio", &Value::Null); assert!(!failed.is_error); wait_for(|| { @@ -977,17 +940,13 @@ mod tests { .find(|table| table["name"] == "total_value") .unwrap(); assert_eq!(values["rowCount"], 0); - - let retry = supervisor.tap(650, 1220).unwrap(); - assert_eq!(retry["type"], "invokeTask"); } #[test] - fn robinhood_full_views_and_account_switch_render() { + fn robinhood_refresh_writes_the_fixed_view_projection() { init_logs(); let temp = tempfile::tempdir().unwrap(); - let mut supervisor = - AppSupervisor::new(temp.path(), Arc::new(SimAppServices::default())).unwrap(); + let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(SimAppServices)).unwrap(); supervisor.open("robinhood").unwrap(); let refreshed = supervisor.invoke_tool("robinhood.refresh_portfolio", "{}"); assert!(!refreshed.is_error, "{}", refreshed.text); @@ -1032,21 +991,5 @@ mod tests { .unwrap()["rowCount"], 3 ); - - supervisor.tap(350, 140).unwrap(); - supervisor.frame().unwrap(); - assert!(supervisor.with_ui(|ui| ui.draw().words.len()) > 100); - - supervisor.tap(350, 250).unwrap(); - supervisor.frame().unwrap(); - supervisor.tap(350, 700).unwrap(); - supervisor.frame().unwrap(); - assert!(supervisor.with_ui(|ui| ui.draw().words.len()) > 100); - - supervisor.tap(80, 60).unwrap(); - supervisor.frame().unwrap(); - supervisor.tap(350, 900).unwrap(); - supervisor.frame().unwrap(); - assert!(supervisor.with_ui(|ui| ui.draw().words.len()) > 100); } } diff --git a/js/src/pi-full/driver.ts b/js/src/pi-full/driver.ts index 036d6ac..b31ff6c 100644 --- a/js/src/pi-full/driver.ts +++ b/js/src/pi-full/driver.ts @@ -1,4 +1,4 @@ -// Path B session harness: stand up an AgentSession from the UNMODIFIED bundled +// Session harness: stand up an AgentSession from the unmodified bundled // pi-coding-agent and (optionally) run one turn, load an extension, enable tools, // or persist/resume — all through Pocket Pi's runtime (fetch → __catpiFetchPump → // Rust HTTP hub → system proxy; our oxc loader for extension .ts; our fs for the diff --git a/js/src/pi-full/persist-probe.ts b/js/src/pi-full/persist-probe.ts index c6008ea..66e84cc 100644 --- a/js/src/pi-full/persist-probe.ts +++ b/js/src/pi-full/persist-probe.ts @@ -1,4 +1,4 @@ -// Session persistence (M7): write a session to disk with pi's unmodified +// Session persistence: write a session to disk with pi's unmodified // SessionManager (backed by Pocket Pi's fs builtin), then resume it in a fresh // manager over the same directory and confirm the history round-trips. Offline — // no LLM, just the disk store. Results land on globalThis for the Rust side. From aed2a0e369464d97d66fc612f8fb9ef3916d1d9e Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Tue, 11 Aug 2026 13:58:03 +0800 Subject: [PATCH 11/24] refactor: remove desktop full-pi runtime --- .gitignore | 6 - ARCHITECTURE.md | 6 +- Cargo.lock | 843 +--- Cargo.toml | 2 - README.md | 116 +- crates/pocket-pi/Cargo.toml | 29 - crates/pocket-pi/examples/chat.rs | 95 - crates/pocket-pi/examples/hello.rs | 56 - crates/pocket-pi/examples/self_contained.rs | 9 - crates/pocket-pi/js/node/_bootstrap.js | 4 - crates/pocket-pi/js/node/_cjs-runtime.js | 27 - crates/pocket-pi/js/node/assert.js | 33 - crates/pocket-pi/js/node/async_hooks.js | 66 - crates/pocket-pi/js/node/buffer.js | 127 - crates/pocket-pi/js/node/child_process.js | 82 - crates/pocket-pi/js/node/console.js | 82 - crates/pocket-pi/js/node/constants.js | 4 - crates/pocket-pi/js/node/crypto.js | 74 - .../pocket-pi/js/node/diagnostics_channel.js | 72 - crates/pocket-pi/js/node/dns.js | 15 - crates/pocket-pi/js/node/events.js | 89 - crates/pocket-pi/js/node/fs-promises.js | 50 - crates/pocket-pi/js/node/fs.js | 322 -- crates/pocket-pi/js/node/http.js | 37 - crates/pocket-pi/js/node/https.js | 37 - crates/pocket-pi/js/node/module.js | 24 - crates/pocket-pi/js/node/net.js | 56 - crates/pocket-pi/js/node/os.js | 57 - crates/pocket-pi/js/node/path.js | 167 - crates/pocket-pi/js/node/perf_hooks.js | 13 - crates/pocket-pi/js/node/process.js | 21 - crates/pocket-pi/js/node/querystring.js | 23 - crates/pocket-pi/js/node/readline.js | 14 - crates/pocket-pi/js/node/stream-promises.js | 19 - crates/pocket-pi/js/node/stream.js | 70 - crates/pocket-pi/js/node/string_decoder.js | 17 - crates/pocket-pi/js/node/timers.js | 18 - crates/pocket-pi/js/node/tls.js | 18 - crates/pocket-pi/js/node/tty.js | 14 - crates/pocket-pi/js/node/url.js | 54 - crates/pocket-pi/js/node/util.js | 115 - crates/pocket-pi/js/node/v8.js | 4 - crates/pocket-pi/js/node/vm.js | 4 - crates/pocket-pi/js/node/worker_threads.js | 88 - crates/pocket-pi/js/node/zlib.js | 25 - crates/pocket-pi/js/package.json | 5 - crates/pocket-pi/js/pi-full.bundle.js.gz | Bin 1923519 -> 0 bytes crates/pocket-pi/js/pi-full/driver.js | 107 - crates/pocket-pi/js/pi-full/ext-probe.js | 23 - crates/pocket-pi/js/pi-full/host.js | 173 - crates/pocket-pi/js/pi-full/persist-probe.js | 29 - crates/pocket-pi/js/prelude.js | 100 - crates/pocket-pi/js/web-globals.js | 600 --- crates/pocket-pi/src/http.rs | 365 -- crates/pocket-pi/src/lib.rs | 536 --- crates/pocket-pi/src/node/builtins.rs | 136 - crates/pocket-pi/src/node/mod.rs | 86 - crates/pocket-pi/src/node/ops.rs | 234 -- crates/pocket-pi/src/node/resolve.rs | 285 -- crates/pocket-pi/src/node/transform.rs | 212 - crates/pocket-pi/src/tests.rs | 433 -- crates/pocket-pi/src/transpile.rs | 68 - docs/agentos-architecture.md | 23 +- docs/esp32-p4-port.md | 4 +- hosts/macos/Cargo.toml | 11 - hosts/macos/src/main.rs | 85 - js/.gitignore | 1 - js/build.mjs | 91 - js/env.d.ts | 91 - js/package-lock.json | 3619 ----------------- js/package.json | 22 - js/src/pi-full/driver.ts | 144 - js/src/pi-full/entry.ts | 48 - js/src/pi-full/example-extension.ts | 42 - js/src/pi-full/ext-probe.ts | 34 - js/src/pi-full/host.ts | 200 - js/src/pi-full/persist-probe.ts | 42 - js/src/pi-full/undici-stub.ts | 46 - js/src/runtime/node/_bootstrap.ts | 9 - js/src/runtime/node/_cjs-runtime.ts | 49 - js/src/runtime/node/assert.ts | 11 - js/src/runtime/node/async_hooks.ts | 24 - js/src/runtime/node/buffer.ts | 112 - js/src/runtime/node/child_process.ts | 58 - js/src/runtime/node/console.ts | 35 - js/src/runtime/node/constants.ts | 2 - js/src/runtime/node/crypto.ts | 42 - js/src/runtime/node/diagnostics_channel.ts | 29 - js/src/runtime/node/dns.ts | 4 - js/src/runtime/node/events.ts | 62 - js/src/runtime/node/fs-promises.ts | 26 - js/src/runtime/node/fs.ts | 232 -- js/src/runtime/node/http.ts | 12 - js/src/runtime/node/https.ts | 12 - js/src/runtime/node/module.ts | 13 - js/src/runtime/node/net.ts | 10 - js/src/runtime/node/os.ts | 42 - js/src/runtime/node/path.ts | 144 - js/src/runtime/node/perf_hooks.ts | 4 - js/src/runtime/node/process.ts | 11 - js/src/runtime/node/querystring.ts | 4 - js/src/runtime/node/readline.ts | 10 - js/src/runtime/node/stream-promises.ts | 12 - js/src/runtime/node/stream.ts | 24 - js/src/runtime/node/string_decoder.ts | 7 - js/src/runtime/node/timers.ts | 8 - js/src/runtime/node/tls.ts | 6 - js/src/runtime/node/tty.ts | 5 - js/src/runtime/node/url.ts | 35 - js/src/runtime/node/util.ts | 76 - js/src/runtime/node/v8.ts | 2 - js/src/runtime/node/vm.ts | 2 - js/src/runtime/node/worker_threads.ts | 40 - js/src/runtime/node/zlib.ts | 6 - js/src/runtime/prelude.ts | 121 - js/src/runtime/web-globals.ts | 442 -- js/tsconfig.json | 20 - tools/xtask/src/main.rs | 7 +- 118 files changed, 51 insertions(+), 12718 deletions(-) delete mode 100644 crates/pocket-pi/Cargo.toml delete mode 100644 crates/pocket-pi/examples/chat.rs delete mode 100644 crates/pocket-pi/examples/hello.rs delete mode 100644 crates/pocket-pi/examples/self_contained.rs delete mode 100644 crates/pocket-pi/js/node/_bootstrap.js delete mode 100644 crates/pocket-pi/js/node/_cjs-runtime.js delete mode 100644 crates/pocket-pi/js/node/assert.js delete mode 100644 crates/pocket-pi/js/node/async_hooks.js delete mode 100644 crates/pocket-pi/js/node/buffer.js delete mode 100644 crates/pocket-pi/js/node/child_process.js delete mode 100644 crates/pocket-pi/js/node/console.js delete mode 100644 crates/pocket-pi/js/node/constants.js delete mode 100644 crates/pocket-pi/js/node/crypto.js delete mode 100644 crates/pocket-pi/js/node/diagnostics_channel.js delete mode 100644 crates/pocket-pi/js/node/dns.js delete mode 100644 crates/pocket-pi/js/node/events.js delete mode 100644 crates/pocket-pi/js/node/fs-promises.js delete mode 100644 crates/pocket-pi/js/node/fs.js delete mode 100644 crates/pocket-pi/js/node/http.js delete mode 100644 crates/pocket-pi/js/node/https.js delete mode 100644 crates/pocket-pi/js/node/module.js delete mode 100644 crates/pocket-pi/js/node/net.js delete mode 100644 crates/pocket-pi/js/node/os.js delete mode 100644 crates/pocket-pi/js/node/path.js delete mode 100644 crates/pocket-pi/js/node/perf_hooks.js delete mode 100644 crates/pocket-pi/js/node/process.js delete mode 100644 crates/pocket-pi/js/node/querystring.js delete mode 100644 crates/pocket-pi/js/node/readline.js delete mode 100644 crates/pocket-pi/js/node/stream-promises.js delete mode 100644 crates/pocket-pi/js/node/stream.js delete mode 100644 crates/pocket-pi/js/node/string_decoder.js delete mode 100644 crates/pocket-pi/js/node/timers.js delete mode 100644 crates/pocket-pi/js/node/tls.js delete mode 100644 crates/pocket-pi/js/node/tty.js delete mode 100644 crates/pocket-pi/js/node/url.js delete mode 100644 crates/pocket-pi/js/node/util.js delete mode 100644 crates/pocket-pi/js/node/v8.js delete mode 100644 crates/pocket-pi/js/node/vm.js delete mode 100644 crates/pocket-pi/js/node/worker_threads.js delete mode 100644 crates/pocket-pi/js/node/zlib.js delete mode 100644 crates/pocket-pi/js/package.json delete mode 100644 crates/pocket-pi/js/pi-full.bundle.js.gz delete mode 100644 crates/pocket-pi/js/pi-full/driver.js delete mode 100644 crates/pocket-pi/js/pi-full/ext-probe.js delete mode 100644 crates/pocket-pi/js/pi-full/host.js delete mode 100644 crates/pocket-pi/js/pi-full/persist-probe.js delete mode 100644 crates/pocket-pi/js/prelude.js delete mode 100644 crates/pocket-pi/js/web-globals.js delete mode 100644 crates/pocket-pi/src/http.rs delete mode 100644 crates/pocket-pi/src/lib.rs delete mode 100644 crates/pocket-pi/src/node/builtins.rs delete mode 100644 crates/pocket-pi/src/node/mod.rs delete mode 100644 crates/pocket-pi/src/node/ops.rs delete mode 100644 crates/pocket-pi/src/node/resolve.rs delete mode 100644 crates/pocket-pi/src/node/transform.rs delete mode 100644 crates/pocket-pi/src/tests.rs delete mode 100644 crates/pocket-pi/src/transpile.rs delete mode 100644 hosts/macos/Cargo.toml delete mode 100644 hosts/macos/src/main.rs delete mode 100644 js/.gitignore delete mode 100644 js/build.mjs delete mode 100644 js/env.d.ts delete mode 100644 js/package-lock.json delete mode 100644 js/package.json delete mode 100644 js/src/pi-full/driver.ts delete mode 100644 js/src/pi-full/entry.ts delete mode 100644 js/src/pi-full/example-extension.ts delete mode 100644 js/src/pi-full/ext-probe.ts delete mode 100644 js/src/pi-full/host.ts delete mode 100644 js/src/pi-full/persist-probe.ts delete mode 100644 js/src/pi-full/undici-stub.ts delete mode 100644 js/src/runtime/node/_bootstrap.ts delete mode 100644 js/src/runtime/node/_cjs-runtime.ts delete mode 100644 js/src/runtime/node/assert.ts delete mode 100644 js/src/runtime/node/async_hooks.ts delete mode 100644 js/src/runtime/node/buffer.ts delete mode 100644 js/src/runtime/node/child_process.ts delete mode 100644 js/src/runtime/node/console.ts delete mode 100644 js/src/runtime/node/constants.ts delete mode 100644 js/src/runtime/node/crypto.ts delete mode 100644 js/src/runtime/node/diagnostics_channel.ts delete mode 100644 js/src/runtime/node/dns.ts delete mode 100644 js/src/runtime/node/events.ts delete mode 100644 js/src/runtime/node/fs-promises.ts delete mode 100644 js/src/runtime/node/fs.ts delete mode 100644 js/src/runtime/node/http.ts delete mode 100644 js/src/runtime/node/https.ts delete mode 100644 js/src/runtime/node/module.ts delete mode 100644 js/src/runtime/node/net.ts delete mode 100644 js/src/runtime/node/os.ts delete mode 100644 js/src/runtime/node/path.ts delete mode 100644 js/src/runtime/node/perf_hooks.ts delete mode 100644 js/src/runtime/node/process.ts delete mode 100644 js/src/runtime/node/querystring.ts delete mode 100644 js/src/runtime/node/readline.ts delete mode 100644 js/src/runtime/node/stream-promises.ts delete mode 100644 js/src/runtime/node/stream.ts delete mode 100644 js/src/runtime/node/string_decoder.ts delete mode 100644 js/src/runtime/node/timers.ts delete mode 100644 js/src/runtime/node/tls.ts delete mode 100644 js/src/runtime/node/tty.ts delete mode 100644 js/src/runtime/node/url.ts delete mode 100644 js/src/runtime/node/util.ts delete mode 100644 js/src/runtime/node/v8.ts delete mode 100644 js/src/runtime/node/vm.ts delete mode 100644 js/src/runtime/node/worker_threads.ts delete mode 100644 js/src/runtime/node/zlib.ts delete mode 100644 js/src/runtime/prelude.ts delete mode 100644 js/src/runtime/web-globals.ts delete mode 100644 js/tsconfig.json diff --git a/.gitignore b/.gitignore index 1316c36..2a4cbf6 100644 --- a/.gitignore +++ b/.gitignore @@ -10,9 +10,3 @@ node_modules __pycache__/ *.py[cod] artifacts/screenshots/ - -# The raw full-pi bundle (~9 MB) is a build intermediate — rebuild with -# `node js/build.mjs`. The gzip (pi-full.bundle.js.gz, ~1.8 MB) IS committed: the -# crate embeds it (include_bytes!) so a plain `cargo build` — including from the -# vendored submodule in cat — works with only Rust, no Node. -crates/pocket-pi/js/pi-full.bundle.js diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index a2757a5..429ead8 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -1,10 +1,9 @@ # Pocket Pi architecture -Pocket Pi is one AgentOS runtime family with three host profiles: +Pocket Pi is one embedded AgentOS runtime with two hosts: | Run mode | Host | Agent profile | | --- | --- | --- | -| Native Mac | `hosts/macos` | full `pi-coding-agent` | | ESP32 simulator | `hosts/esp32-p4-sim` | embedded `pi-agent-core` System App | | ESP32-P4 | `firmware/esp32-p4` | embedded `pi-agent-core` System App | @@ -45,12 +44,10 @@ top-level `/workspace` and cross-App Tool Registry. ```text apps/ PocketJS System/ordinary App sources and bundles -crates/pocket-pi/ full desktop pi-coding-agent runtime crates/pocket-pi-agentos/ App Supervisor and AgentOS contracts crates/pocket-pi-embedded/ embedded pi-agent-core bridge and host traits crates/pocket-pi-tools/ native workspace/shell/time/schedule Tools crates/pocket-pi-protocols/ provider codecs -hosts/macos/ native desktop composition root hosts/esp32-p4-sim/ embedded AgentOS simulator firmware/esp32-p4/ ESP-IDF hardware composition root tools/uart_bridge/ Mac Codex/Claude streaming adapters @@ -61,7 +58,6 @@ tools/uart-model-bridge.py UART framing and provisioning CLI ```sh cargo xtask build agentos-apps -cargo xtask build macos cargo xtask build esp32-p4 cargo xtask build esp32-p4-sim cargo xtask run esp32-p4-sim diff --git a/Cargo.lock b/Cargo.lock index d0f2de7..5d3ac3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -169,17 +169,6 @@ dependencies = [ "libloading", ] -[[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 = "atomic-waker" version = "1.1.2" @@ -210,16 +199,6 @@ version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" -[[package]] -name = "base64-simd" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" -dependencies = [ - "outref", - "vsimd", -] - [[package]] name = "bindgen" version = "0.72.1" @@ -229,7 +208,7 @@ dependencies = [ "bitflags 2.13.1", "cexpr", "clang-sys", - "itertools 0.13.0", + "itertools", "log", "prettyplease", "proc-macro2", @@ -365,15 +344,6 @@ dependencies = [ "wayland-client", ] -[[package]] -name = "castaway" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" -dependencies = [ - "rustversion", -] - [[package]] name = "cc" version = "1.3.0" @@ -407,19 +377,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" -[[package]] -name = "chrono" -version = "0.4.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" -dependencies = [ - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-link", -] - [[package]] name = "clang-sys" version = "1.9.1" @@ -431,15 +388,6 @@ dependencies = [ "libloading", ] -[[package]] -name = "cobs" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" -dependencies = [ - "thiserror 2.0.19", -] - [[package]] name = "codespan-reporting" version = "0.12.0" @@ -467,20 +415,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "compact_str" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dfdd1c2274d9aa354115b09dc9a901d6c5576818cdf70d14cae2bdb47df00ab" -dependencies = [ - "castaway", - "cfg-if", - "itoa", - "rustversion", - "ryu", - "static_assertions", -] - [[package]] name = "concurrent-queue" version = "2.5.0" @@ -539,12 +473,6 @@ dependencies = [ "libc", ] -[[package]] -name = "cow-utils" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "417bef24afe1460300965a25ff4a24b8b45ad011948302ec221e8a0a81eb2c79" - [[package]] name = "crc32fast" version = "1.5.0" @@ -629,29 +557,6 @@ dependencies = [ "libloading", ] -[[package]] -name = "dlopen2" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e2c5bd4158e66d1e215c49b837e11d62f3267b30c92f1d171c4d3105e3dc4d4" -dependencies = [ - "dlopen2_derive", - "libc", - "once_cell", - "winapi", -] - -[[package]] -name = "dlopen2_derive" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fbbb781877580993a8707ec48672673ec7b81eeba04cfd2310bd28c08e47c8f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - [[package]] name = "document-features" version = "0.2.12" @@ -673,30 +578,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" -[[package]] -name = "dragonbox_ecma" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd8e701084c37e7ef62d3f9e453b618130cbc0ef3573847785952a3ac3f746bf" - [[package]] name = "either" version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" -[[package]] -name = "embedded-io" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" - -[[package]] -name = "embedded-io" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" - [[package]] name = "env_filter" version = "2.0.0" @@ -736,26 +623,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "event-listener" -version = "5.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" -dependencies = [ - "concurrent-queue", - "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" @@ -796,7 +663,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", - "miniz_oxide 0.8.9", + "miniz_oxide", ] [[package]] @@ -1148,36 +1015,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" -[[package]] -name = "hmac-sha1-compact" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b3ba31f6dc772cc8221ce81dbbbd64fa1e668255a6737d95eeace59b5a8823" - -[[package]] -name = "iana-time-zone" -version = "0.1.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core 0.62.2", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - [[package]] name = "icu_collections" version = "2.2.0" @@ -1333,15 +1170,6 @@ dependencies = [ "either", ] -[[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" @@ -1463,12 +1291,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "json-escape-simd" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22a2041e3874a055a4eb03ea2395aaccdefa84ce75b31d542d72a741c3c6ad3" - [[package]] name = "khronos-egl" version = "6.0.0" @@ -1631,15 +1453,6 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "miniz_oxide" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" -dependencies = [ - "adler2", -] - [[package]] name = "moxcms" version = "0.8.1" @@ -1724,31 +1537,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "nonmax" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "610a5acd306ec67f907abe5567859a3c693fb9886eb1f012ab8f2a47bef3db51" - -[[package]] -name = "num-bigint" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93e7820bc0a80a0238e650327316f929ba18d5be054b647490a3a6a339f3e7c0" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -2024,12 +1812,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "outref" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" - [[package]] name = "owned_ttf_parser" version = "0.25.1" @@ -2039,366 +1821,6 @@ dependencies = [ "ttf-parser", ] -[[package]] -name = "owo-colors" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" - -[[package]] -name = "oxc-browserslist" -version = "3.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50a403a3c6be65be7bc7730d07d959ec6c143e4ff8117da485df78cd5582260a" -dependencies = [ - "miniz_oxide 0.9.1", - "postcard", - "rustc-hash 2.1.3", - "serde", - "thiserror 2.0.19", -] - -[[package]] -name = "oxc-miette" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e0df30faa68797917ca4263e7a2f889ec829e4da2dcb3d6dc752f7a494180f3" -dependencies = [ - "cfg-if", - "memchr", - "owo-colors", - "oxc-miette-derive", - "textwrap", - "thiserror 2.0.19", - "unicode-segmentation", - "unicode-width", -] - -[[package]] -name = "oxc-miette-derive" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acc072d11d45ebe7801459b4e829184ba0934d68027fdc51d327335b53a95a49" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - -[[package]] -name = "oxc_allocator" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f8245ba555b465d3577732d5f9d9306babb0aaa7b80e97a2ce21f74fae442a3" -dependencies = [ - "allocator-api2", - "hashbrown 0.17.1", - "oxc_data_structures", - "rustc-hash 2.1.3", -] - -[[package]] -name = "oxc_ast" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3305400b90fff2a30b272b58fe6080d25369407b2ac37c4ac652996a9677efe0" -dependencies = [ - "bitflags 2.13.1", - "oxc_allocator", - "oxc_ast_macros", - "oxc_data_structures", - "oxc_diagnostics", - "oxc_estree", - "oxc_regular_expression", - "oxc_span", - "oxc_str", - "oxc_syntax", -] - -[[package]] -name = "oxc_ast_macros" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef089097e96b74388a8025a9247bdb12774b99f5971926d9dafbe84a78f9efb7" -dependencies = [ - "phf", - "proc-macro2", - "quote", - "syn 2.0.119", -] - -[[package]] -name = "oxc_ast_visit" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4640e6d0de2e0f6c820d1444a468d070c710111df76ce90a1694ac386641e133" -dependencies = [ - "oxc_allocator", - "oxc_ast", - "oxc_span", - "oxc_syntax", -] - -[[package]] -name = "oxc_codegen" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "316d3f320fab2647d2657f1016de952baa196b566e0eaa704d224e3fc25ccd9a" -dependencies = [ - "bitflags 2.13.1", - "cow-utils", - "dragonbox_ecma", - "itoa", - "oxc_allocator", - "oxc_ast", - "oxc_data_structures", - "oxc_index", - "oxc_semantic", - "oxc_sourcemap", - "oxc_span", - "oxc_str", - "oxc_syntax", - "rustc-hash 2.1.3", -] - -[[package]] -name = "oxc_compat" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f8ecc06571912f29113f7e5669f7bd2915d3932270b0d877a3679686f5f4c7d" -dependencies = [ - "cow-utils", - "oxc-browserslist", - "oxc_syntax", - "rustc-hash 2.1.3", - "serde", -] - -[[package]] -name = "oxc_data_structures" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acfb6e704f95e115c0e9ea8bef791c3d915cd2fcd1643661cf0bf5172c818097" -dependencies = [ - "ropey", -] - -[[package]] -name = "oxc_diagnostics" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b33d8c59c55e2c581ff692468a6a7ff1f12477f0e687b52e27fc6f6346a5d77" -dependencies = [ - "cow-utils", - "oxc-miette", - "percent-encoding", -] - -[[package]] -name = "oxc_ecmascript" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b3321b606c9217e8e5527cd01906b98e17f232acbb6fab7eac05236e7731d9a" -dependencies = [ - "cow-utils", - "num-bigint", - "num-traits", - "oxc_allocator", - "oxc_ast", - "oxc_regular_expression", - "oxc_span", - "oxc_syntax", - "smallvec", -] - -[[package]] -name = "oxc_estree" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad383009532dc6504973f02f68892b98f64be1c17e86115166b0a1223c7511e7" - -[[package]] -name = "oxc_index" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "191884bee6c3744909a51acc7d78d4ae370d817b25875b10642f632327b6296e" -dependencies = [ - "nonmax", - "serde", -] - -[[package]] -name = "oxc_parser" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8abd68f81349d37ea79f1d99d2370e15f282cc9fbe66e8544d072595744ab38e" -dependencies = [ - "bitflags 2.13.1", - "cow-utils", - "memchr", - "num-bigint", - "num-traits", - "oxc_allocator", - "oxc_ast", - "oxc_data_structures", - "oxc_diagnostics", - "oxc_ecmascript", - "oxc_regular_expression", - "oxc_span", - "oxc_str", - "oxc_syntax", - "rustc-hash 2.1.3", - "seq-macro", -] - -[[package]] -name = "oxc_regular_expression" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eba6a56b1c633963c09c383062e47fb8a99ff4a4ded6bd883fcf554f8e1a48f" -dependencies = [ - "bitflags 2.13.1", - "oxc_allocator", - "oxc_ast_macros", - "oxc_diagnostics", - "oxc_span", - "oxc_str", - "phf", - "rustc-hash 2.1.3", - "unicode-id-start", -] - -[[package]] -name = "oxc_semantic" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5967f96881e1694d10b453311fa681b4df0f38760628e1de613b046566cd8c8e" -dependencies = [ - "itertools 0.15.0", - "memchr", - "oxc_allocator", - "oxc_ast", - "oxc_ast_visit", - "oxc_data_structures", - "oxc_diagnostics", - "oxc_ecmascript", - "oxc_index", - "oxc_span", - "oxc_str", - "oxc_syntax", - "rustc-hash 2.1.3", - "self_cell", - "smallvec", -] - -[[package]] -name = "oxc_sourcemap" -version = "8.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b415102a94b483bbd76d13e850fe87961197e5795c79a8523ebec5d82025f94f" -dependencies = [ - "base64-simd", - "json-escape-simd", - "rustc-hash 2.1.3", - "serde", - "serde_json", -] - -[[package]] -name = "oxc_span" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83fa0a0fe6e5e2f5abb173a64afe8db711bb612acbc002c663fd13b08a8cbf3" -dependencies = [ - "compact_str", - "oxc-miette", - "oxc_allocator", - "oxc_ast_macros", - "oxc_estree", - "oxc_str", -] - -[[package]] -name = "oxc_str" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9e9531af3bc70e5eb75d196c01011d5bc0de1f6de73f0fc8bf343384353794f" -dependencies = [ - "compact_str", - "hashbrown 0.17.1", - "oxc_allocator", - "oxc_estree", -] - -[[package]] -name = "oxc_syntax" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f81863cdf973b6bcdcdbbae225619c08966be41efb64dc0ee0fd4b574f4ec18" -dependencies = [ - "bitflags 2.13.1", - "cow-utils", - "dragonbox_ecma", - "nonmax", - "oxc_allocator", - "oxc_ast_macros", - "oxc_estree", - "oxc_index", - "oxc_span", - "oxc_str", - "phf", - "unicode-id-start", -] - -[[package]] -name = "oxc_transformer" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8bb6f328641800296233b28448f32e5ebb5e72854b3e329f20447d5331c9216" -dependencies = [ - "base64 0.22.1", - "compact_str", - "hmac-sha1-compact", - "indexmap", - "itoa", - "memchr", - "oxc_allocator", - "oxc_ast", - "oxc_ast_visit", - "oxc_compat", - "oxc_data_structures", - "oxc_diagnostics", - "oxc_ecmascript", - "oxc_regular_expression", - "oxc_semantic", - "oxc_span", - "oxc_str", - "oxc_syntax", - "oxc_traverse", - "rustc-hash 2.1.3", - "serde", - "serde_json", -] - -[[package]] -name = "oxc_traverse" -version = "0.140.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab67032768715dda6647be4043e6a8f9762a3a9090ca7a5d3795339ce87e18f" -dependencies = [ - "itoa", - "oxc_allocator", - "oxc_ast", - "oxc_ast_visit", - "oxc_data_structures", - "oxc_ecmascript", - "oxc_semantic", - "oxc_span", - "oxc_str", - "oxc_syntax", - "rustc-hash 2.1.3", -] - [[package]] name = "parking_lot" version = "0.12.5" @@ -2434,49 +1856,6 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" -[[package]] -name = "phf" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "010378780309880b08997fae13be7834dba947d36393bd372f2b1556deb2a2f6" -dependencies = [ - "phf_macros", - "phf_shared", - "serde", -] - -[[package]] -name = "phf_generator" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeb62e0959d5a1bebc965f4d15d9e2b7cea002b6b0f5ba8cde6cc26738467100" -dependencies = [ - "fastrand", - "phf_shared", -] - -[[package]] -name = "phf_macros" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fa8d0ca26d424d27630da600c6624696e7dec8bf7b3b492b383c5dc49e5e085" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", - "syn 2.0.119", -] - -[[package]] -name = "phf_shared" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fd9027e2d9319be6349febd1db4e8d02aa544921200c9b777720ac34a3aa89" -dependencies = [ - "siphasher", -] - [[package]] name = "pin-project" version = "1.1.13" @@ -2525,7 +1904,7 @@ dependencies = [ "crc32fast", "fdeflate", "flate2", - "miniz_oxide 0.8.9", + "miniz_oxide", ] [[package]] @@ -2576,25 +1955,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "pocket-pi" -version = "0.1.0" -dependencies = [ - "env_logger", - "flate2", - "log", - "oxc_allocator", - "oxc_codegen", - "oxc_parser", - "oxc_semantic", - "oxc_span", - "oxc_transformer", - "regex", - "rquickjs", - "serde_json", - "ureq", -] - [[package]] name = "pocket-pi-agentos" version = "0.1.0" @@ -2644,14 +2004,6 @@ dependencies = [ "winit", ] -[[package]] -name = "pocket-pi-macos" -version = "0.1.0" -dependencies = [ - "pocket-pi", - "serde_json", -] - [[package]] name = "pocket-pi-protocols" version = "0.1.0" @@ -2768,18 +2120,6 @@ dependencies = [ "portable-atomic", ] -[[package]] -name = "postcard" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" -dependencies = [ - "cobs", - "embedded-io 0.4.0", - "embedded-io 0.6.1", - "serde", -] - [[package]] name = "potential_utf" version = "0.1.5" @@ -2962,24 +2302,12 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "ropey" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93411e420bcd1a75ddd1dc3caf18c23155eda2c090631a85af21ba19e97093b5" -dependencies = [ - "smallvec", - "str_indices", -] - [[package]] name = "rquickjs" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ce6b626d30ecbedaaf8097a04982bc3b081f958f5bdf9b8796be4ac00ee48bb" dependencies = [ - "either", - "indexmap", "rquickjs-core", "rquickjs-macro", ] @@ -2990,13 +2318,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9334dd11023d5ae6c751f64496510a576208802ed1d022ef94afa7639c2c55e" dependencies = [ - "async-lock", - "chrono", - "dlopen2", - "either", "hashbrown 0.17.1", - "indexmap", - "phf", "relative-path", "rquickjs-sys", ] @@ -3011,8 +2333,6 @@ dependencies = [ "fnv", "ident_case", "indexmap", - "phf_generator", - "phf_shared", "proc-macro-crate", "proc-macro2", "quote", @@ -3143,12 +2463,6 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" -[[package]] -name = "ryu" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" - [[package]] name = "same-file" version = "1.0.6" @@ -3183,24 +2497,12 @@ dependencies = [ "tiny-skia", ] -[[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" -[[package]] -name = "seq-macro" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" - [[package]] name = "serde" version = "1.0.229" @@ -3278,12 +2580,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" -[[package]] -name = "siphasher" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" - [[package]] name = "slab" version = "0.4.12" @@ -3304,15 +2600,6 @@ name = "smallvec" version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" -dependencies = [ - "serde", -] - -[[package]] -name = "smawk" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e2fb0f499abb4d162f2bedad68f5ef91a1682b5a03596ddb67efd37768d100" [[package]] name = "smithay-client-toolkit" @@ -3381,12 +2668,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "str_indices" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d08889ec5408683408db66ad89e0e1f93dff55c73a4ccc71c427d5b277ee47e6" - [[package]] name = "strict-num" version = "0.1.1" @@ -3488,17 +2769,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "textwrap" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" -dependencies = [ - "smawk", - "unicode-linebreak", - "unicode-width", -] - [[package]] name = "thiserror" version = "1.0.69" @@ -3626,24 +2896,12 @@ version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" -[[package]] -name = "unicode-id-start" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b79ad29b5e19de4260020f8919b443b2ef0277d242ce532ec7b7a2cc8b6007" - [[package]] name = "unicode-ident" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" -[[package]] -name = "unicode-linebreak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" - [[package]] name = "unicode-segmentation" version = "1.13.3" @@ -3722,12 +2980,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "vsimd" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" - [[package]] name = "walkdir" version = "2.5.0" @@ -4085,7 +3337,7 @@ dependencies = [ "web-sys", "wgpu-types", "windows", - "windows-core 0.58.0", + "windows-core", ] [[package]] @@ -4102,22 +3354,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - [[package]] name = "winapi-util" version = "0.1.11" @@ -4127,19 +3363,13 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows" version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core 0.58.0", + "windows-core", "windows-targets", ] @@ -4149,26 +3379,13 @@ version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ - "windows-implement 0.58.0", - "windows-interface 0.58.0", - "windows-result 0.2.0", - "windows-strings 0.1.0", + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", "windows-targets", ] -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement 0.60.2", - "windows-interface 0.59.3", - "windows-link", - "windows-result 0.4.1", - "windows-strings 0.5.1", -] - [[package]] name = "windows-implement" version = "0.58.0" @@ -4180,17 +3397,6 @@ dependencies = [ "syn 2.0.119", ] -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - [[package]] name = "windows-interface" version = "0.58.0" @@ -4202,17 +3408,6 @@ dependencies = [ "syn 2.0.119", ] -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - [[package]] name = "windows-link" version = "0.2.1" @@ -4228,34 +3423,16 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link", -] - [[package]] name = "windows-strings" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-result 0.2.0", + "windows-result", "windows-targets", ] -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link", -] - [[package]] name = "windows-sys" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index 7a0f7d0..633734b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,10 @@ [workspace] resolver = "2" members = [ - "crates/pocket-pi", "crates/pocket-pi-agentos", "crates/pocket-pi-embedded", "crates/pocket-pi-protocols", "crates/pocket-pi-tools", - "hosts/macos", "hosts/esp32-p4-sim", "tools/xtask", ] diff --git a/README.md b/README.md index 26aaa38..cfd2e74 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,30 @@ # Pocket Pi Pocket Pi runs the [Pi coding agent](https://github.com/badlogic/pi-mono) in -QuickJS. It provides a full desktop runtime and an embedded profile whose -touch UI is built with PocketJS for the ESP32-P4 product. +QuickJS. Its touch UI is built with PocketJS for the ESP32-P4 product. -This repository contains one Pocket Pi runtime family with two profiles and -exactly three supported run modes: +This repository contains one embedded Agent profile with two supported run modes: | Run mode | Agent profile | What it is for | |---|---|---| -| Native macOS | Full `pi-coding-agent` | Normal desktop Pocket Pi, including sessions and extensions | | ESP32 simulator on macOS | Embedded `pi-agent-core` | Fast development of the ESP32 product UI, tools and Agent flows | | Physical ESP32-P4 | Embedded `pi-agent-core` | The real standalone PocketJS/QuickJS device | -They are not three forks. The simulator and firmware compile the same embedded -Agent, device UI, tool contracts and interaction state. Only their platform -adapters differ. +The simulator and firmware compile the same embedded Agent, device UI, tool +contracts and interaction state. Only their platform adapters differ. -> **Project status:** the macOS host, ESP32 simulator and physical -> Waveshare ESP32-P4 target all have working end-to-end paths. The embedded -> port is still board-specific and under active development; see +> **Project status:** the ESP32 simulator and physical Waveshare ESP32-P4 target +> have working end-to-end paths. The embedded port is still board-specific and +> under active development; see > [Current validation](#current-validation) for the exact evidence and limits. -## Why two profiles? +## One product profile, two hosts -The desktop runtime can afford a broad Node/Web compatibility layer and embeds -the full, unmodified `pi-coding-agent`. An ESP32 cannot carry that entire -desktop platform unchanged, so the embedded profile runs upstream -`pi-agent-core` in QuickJS and implements the Pi tools as small native Rust -capabilities. +The embedded profile runs upstream `pi-agent-core` in QuickJS and implements Pi +tools as small native Rust capabilities. The simulator is a product-contract +host for fast development; the physical ESP32-P4 is the final product host. -The architecture keeps the Pi Harness design in both profiles: +The architecture keeps the Pi Harness design in both hosts: - the model decides when to call a tool; - tools have explicit schemas and return structured results; @@ -46,7 +40,7 @@ adapters. Physical hardware remains the final acceptance target. ### Prerequisites -- Rust stable for the native macOS host and simulator; +- Rust stable for the simulator; - Bun for rebuilding the embedded JavaScript guest; - a logged-in `codex` CLI for the simulator's local Codex backend; - the esp-rs/ESP-IDF toolchain, `nightly-2026-05-01`, and `espflash` for the @@ -55,31 +49,15 @@ adapters. Physical hardware remains the final acceptance target. The current firmware target is the **Waveshare ESP32-P4-WIFI6-Touch-LCD-5**. -### Build all three modes +### Build both modes ```sh cargo xtask build agentos-apps -cargo xtask build macos cargo xtask build esp32-p4-sim cargo xtask build esp32-p4 ``` -### 1. Native Pocket Pi on macOS - -```sh -cargo xtask run macos 'Who are you?' -``` - -The host selects a model in this order: - -1. `OPENAI_API_KEY` with optional `OPENAI_MODEL`; -2. `ANTHROPIC_API_KEY` with optional `ANTHROPIC_MODEL`; -3. Pi's deterministic Faux Provider when neither key exists. - -The Faux Provider is an offline development fallback. It still runs through a -real `createAgentSession`; it is not evidence of a live provider request. - -### 2. ESP32 Pocket Pi simulator on macOS +### 1. ESP32 Pocket Pi simulator on macOS The simulator defaults to the Mac's existing Codex Coding Plan login: @@ -115,7 +93,7 @@ deterministic UI snapshot with: cargo xtask snapshot esp32-p4-sim ``` -### 3. Physical Pocket Pi on ESP32-P4 +### 2. Physical Pocket Pi on ESP32-P4 Build and flash the release firmware: @@ -173,7 +151,6 @@ Backends belong to their host composition, not to the Agent core: | Host | Supported backends | |---|---| -| Native macOS | OpenAI, Anthropic, offline Faux Provider | | ESP32 simulator | local Codex, OpenAI, OpenRouter, Anthropic, DeepSeek V4 | | Physical ESP32-P4 | UART to Mac Codex or Claude Code; wireless OpenAI, OpenRouter, Anthropic or DeepSeek V4 | @@ -213,46 +190,18 @@ The shared PocketJS device UI includes: - Settings with Wi-Fi scanning, selection and password entry; - touch keyboard and next-schedule status. -Settings is an embedded-device feature and is not linked into native macOS -Pocket Pi. The embedded AgentOS ships Pi Agent as its resident System App and -Robinhood and Exa as ordinary Apps. Each ordinary App owns its Tool catalog, -Data Action, SQLite projection and fixed PocketJS View; native hosts provide -only scoped credentials, transport and hardware adapters. - -## Desktop profile - -`crates/pocket-pi` embeds the full, unmodified `pi-coding-agent` bundle in one -QuickJS realm. It provides enough Node/Web compatibility for Pi sessions, -extensions, native tools and streaming model turns without requiring Node or -Bun on the destination machine. - -Desktop extensions use Pi's normal `(pi) => void` factory and may register -tools and lifecycle hooks. Pocket Pi transpiles TypeScript with oxc and injects -the factory through Pi's `extensionFactories` seam; Pi itself is not patched. - -The desktop compatibility layer includes real filesystem, path, buffer, -events, stream, process, synchronous subprocess and global streaming `fetch` -support. Socket servers, worker threads and several lower-level Node builtins -remain stubs. These desktop APIs are intentionally **not** part of the embedded -ESP32 contract. - -The full Pi bundle is committed and embedded, so normal Rust builds do not need -Node. Rebuild it only after changing the desktop JavaScript guest: - -```sh -npm --prefix js ci -npm --prefix js run build -``` +The embedded AgentOS ships Pi Agent as its resident System App and Robinhood and +Exa as ordinary Apps. Each ordinary App owns its Tool catalog, Data Action, +SQLite projection and fixed PocketJS View; hosts provide only scoped +credentials, transport and hardware adapters. ## Repository map ```text -crates/pocket-pi/ full desktop pi-coding-agent runtime crates/pocket-pi-embedded/ embedded pi-agent-core guest and host traits crates/pocket-pi-tools/ portable workspace, shell, time and schedule tools crates/pocket-pi-protocols/ model request, response and streaming codecs crates/pocket-pi-agentos/ App Supervisor, System App lifecycle and App contracts -hosts/macos/ native desktop composition root hosts/esp32-p4-sim/ macOS adapters for the embedded product firmware/esp32-p4/ ESP-IDF hardware composition root and adapters tools/uart_bridge/ Mac Codex and Claude Code streaming adapters @@ -261,30 +210,21 @@ tools/uart-model-bridge.py UART framing and provisioning CLI Dependencies point inward: hosts depend on shared runtimes, tools, UI and protocols; those shared crates do not depend on a host. Hardware APIs remain in -the firmware, macOS APIs remain in hosts/tools, and optional external services -remain plugins. +the firmware, simulator adapters remain in `hosts/esp32-p4-sim`, and optional +external services remain Apps. See [ARCHITECTURE.md](ARCHITECTURE.md) for ownership and lifecycle boundaries, and [docs/esp32-p4-port.md](docs/esp32-p4-port.md) for board-specific details. ## Current validation -The following three paths were exercised end-to-end on **2026-08-05**: +On **2026-08-11**, the embedded-only workspace completed 27 tests with no +failures, passed workspace Clippy with warnings denied, and built the ESP32-P4 +simulator after rebuilding the Pi Agent, Robinhood and Exa bundles. -| Mode | Exercised path | Result | -|---|---|---| -| Native macOS | Full `PiRuntime` and `createAgentSession` with Pi's offline Faux Provider | Passed | -| ESP32 simulator | Embedded Agent + local Codex; `write -> read -> recurring schedule.set -> schedule.list`; shared UI rendering | Passed | -| Physical ESP32-P4 | Release firmware + UART Mac Codex; streamed reply; real LittleFS `write/read`; recurring schedule creation/listing | Passed | - -The workspace suite also completed with 46 passing tests and 3 ignored tests, -and workspace clippy passed with warnings denied. These results validate the -recorded revision; they are not a substitute for CI on later changes. - -The physical `WirelessBackend` and provider codecs are implemented and compile, -but a live ESP32 Wi-Fi -> OpenAI request was **not** exercised in that session -because the available AP did not provide the required network route. Do not -interpret the UART E2E as evidence for that separate network path. +Physical firmware, boot, Wi-Fi/DHCP, provider calls and unattended memory +pressure remain separate evidence tiers. A successful simulator build is not a +substitute for fresh physical-board acceptance. ## Development checks diff --git a/crates/pocket-pi/Cargo.toml b/crates/pocket-pi/Cargo.toml deleted file mode 100644 index a482cbb..0000000 --- a/crates/pocket-pi/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -name = "pocket-pi" -version = "0.1.0" -description = "A QuickJS runtime that runs the pi coding-agent core with no Node and no bun, on a PocketJS-style coalesced frame scheduler" -edition.workspace = true -license.workspace = true -repository.workspace = true - -[dependencies] -rquickjs = { version = "0.12", features = ["full-async"] } -serde_json = "1" -ureq = { version = "2", features = ["tls"] } -log = "0.4" - -# Runtime TypeScript → JavaScript for agent-authored plugins (Option A): the -# heavy "jiti + typescript" Node dependency, reimplemented as a native op. -oxc_allocator = "0.140" -oxc_parser = "0.140" -oxc_codegen = "0.140" -oxc_semantic = "0.140" -oxc_span = "0.140" -oxc_transformer = "0.140" -regex = "1" - -# Gzip decode for the embedded full-pi bundle (pure-Rust backend, no C). -flate2 = { version = "1", default-features = false, features = ["rust_backend"] } - -[dev-dependencies] -env_logger = "0.11" diff --git a/crates/pocket-pi/examples/chat.rs b/crates/pocket-pi/examples/chat.rs deleted file mode 100644 index 8ff7873..0000000 --- a/crates/pocket-pi/examples/chat.rs +++ /dev/null @@ -1,95 +0,0 @@ -//! A one-shot Pocket Pi chat demo. -//! -//! cargo run -p pocket-pi --example chat -- "Say hi in three words." -//! -//! With ANTHROPIC_API_KEY set it streams a real Anthropic turn; otherwise it -//! replays a scripted answer so the demo runs fully offline. Either way the -//! runtime is driven by a deliberately slow 2 Hz pump — proof that an agent -//! runtime doesn't need a hot loop; it needs a heartbeat. - -use pocket_pi::{PiRuntime, ToolResult}; -use std::io::Write; -use std::time::{Duration, Instant}; - -fn main() { - let prompt = std::env::args().skip(1).collect::>().join(" "); - let prompt = if prompt.is_empty() { - "In one short sentence, what are you?".to_string() - } else { - prompt - }; - - let mut rt = PiRuntime::new().expect("runtime"); - - // A trivial native tool, to show the agent can reach host capabilities. - rt.register_tool("current_time", |_args| { - let secs = std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .map(|d| d.as_secs()) - .unwrap_or(0); - ToolResult::text(format!("unix seconds: {secs}")) - }); - - rt.on_event(|ev| match ev.kind.as_str() { - "text" => { - if let Some(d) = ev.value.get("delta").and_then(|v| v.as_str()) { - print!("{d}"); - let _ = std::io::stdout().flush(); - } - } - "tool_start" => { - let name = ev.value.get("name").and_then(|v| v.as_str()).unwrap_or(""); - eprint!("\n[tool: {name}] "); - } - "end" => println!("\n[done]"), - "error" => eprintln!("\n[error] {}", ev.raw), - _ => {} - }); - - let tool = serde_json::json!({ - "name": "current_time", - "description": "Get the current unix time in seconds.", - "parameters": {"type": "object", "properties": {}} - }); - let cfg = if let Ok(key) = std::env::var("OPENAI_API_KEY") { - serde_json::json!({ - "provider": "openai", - "model": std::env::var("OPENAI_MODEL").unwrap_or_else(|_| "gpt-5.6".into()), - "apiKey": key, - "maxTokens": 2048, - "systemPrompt": "You are Pocket Pi, a tiny agent living in a QuickJS runtime. Be brief.", - "tools": [tool] - }) - } else { - match std::env::var("ANTHROPIC_API_KEY") { - Ok(key) => serde_json::json!({ - "model": "claude-opus-4-8", - "apiKey": key, - "maxTokens": 256, - "systemPrompt": "You are Pocket Pi, a tiny agent living in a QuickJS runtime. Be brief.", - "tools": [tool] - }), - Err(_) => { - eprintln!("(no ANTHROPIC_API_KEY — running the offline scripted assistant)\n"); - serde_json::json!({ - "model": "offline", - "scripted": { "steps": [ - { "text": "I'm Pocket Pi — pi's agent core running inside QuickJS, no Node, no bun." } - ]} - }) - } - } - }; - - rt.boot(&cfg.to_string()).expect("boot"); - println!("you> {prompt}\npi > "); - rt.prompt(&prompt).expect("prompt"); - - // The whole point: pump slowly. LLM latency dwarfs a 500 ms frame. - let start = Instant::now(); - while !rt.is_idle() && start.elapsed() < Duration::from_secs(120) { - rt.pump().expect("pump"); - std::thread::sleep(Duration::from_millis(500)); - } - rt.pump().ok(); -} diff --git a/crates/pocket-pi/examples/hello.rs b/crates/pocket-pi/examples/hello.rs deleted file mode 100644 index 8e45543..0000000 --- a/crates/pocket-pi/examples/hello.rs +++ /dev/null @@ -1,56 +0,0 @@ -//! Dead-simple acceptance: boot the full, embedded pi on a real model and say -//! hello. This binary carries the WHOLE unmodified pi-coding-agent inside it. -//! -//! OPENAI_API_KEY=… cargo run --release --example hello -//! OPENAI_API_KEY=… OPENAI_MODEL=gpt-5.6 cargo run --release --example hello -use pocket_pi::{HostEvent, PiRuntime}; -use std::cell::RefCell; -use std::io::Write; -use std::rc::Rc; - -fn main() { - let key = std::env::var("OPENAI_API_KEY").expect("set OPENAI_API_KEY"); - let model = std::env::var("OPENAI_MODEL").unwrap_or_else(|_| "gpt-5.6".into()); - - // The whole pi is embedded — new() stands it up with no external files. - let mut rt = PiRuntime::new().expect("runtime"); - - let reply = Rc::new(RefCell::new(String::new())); - let r = reply.clone(); - rt.on_event(move |ev: &HostEvent| match ev.kind.as_str() { - "text" => { - if let Some(d) = ev.value.get("delta").and_then(|v| v.as_str()) { - r.borrow_mut().push_str(d); - print!("{d}"); - std::io::stdout().flush().ok(); - } - } - "assistant_text" if r.borrow().is_empty() => { - if let Some(t) = ev.value.get("text").and_then(|v| v.as_str()) { - *r.borrow_mut() = t.to_string(); - print!("{t}"); - } - } - "error" => eprintln!("\n[error] {}", ev.raw), - _ => {} - }); - - let cfg = serde_json::json!({ - "provider": "openai", "model": model, "apiKey": key, - "maxTokens": 2048, - "systemPrompt": "You are a friendly assistant. Be very brief." - }); - eprintln!("booting full pi on {model} …"); - rt.boot(&cfg.to_string()).expect("boot"); - eprint!("pi > "); - rt.prompt("Say hello in a few words.").expect("prompt"); - while !rt.is_idle() { - rt.pump().expect("pump"); - std::thread::sleep(std::time::Duration::from_millis(50)); - } - println!(); - if reply.borrow().trim().is_empty() { - eprintln!("(no reply — check OPENAI_API_KEY / proxy)"); - std::process::exit(1); - } -} diff --git a/crates/pocket-pi/examples/self_contained.rs b/crates/pocket-pi/examples/self_contained.rs deleted file mode 100644 index 09f7bf6..0000000 --- a/crates/pocket-pi/examples/self_contained.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Pocket Pi is self-contained: the whole unmodified pi-coding-agent is embedded -//! in the binary, so `PiRuntime::new()` stands it up with no external files and -//! no Node. Run: `cargo run --release --example self_contained`. -use pocket_pi::PiRuntime; - -fn main() { - let rt = PiRuntime::new().expect("runtime"); - println!("full pi loaded: {:?}", rt.get_global_json("__piFullLoaded")); -} diff --git a/crates/pocket-pi/js/node/_bootstrap.js b/crates/pocket-pi/js/node/_bootstrap.js deleted file mode 100644 index a8764fe..0000000 --- a/crates/pocket-pi/js/node/_bootstrap.js +++ /dev/null @@ -1,4 +0,0 @@ -import { Buffer } from "node:buffer"; -globalThis.Buffer = Buffer; -globalThis.__nodeBuffer = Buffer; -globalThis.process.nextTick = (fn, ...args) => queueMicrotask(() => fn(...args)); diff --git a/crates/pocket-pi/js/node/_cjs-runtime.js b/crates/pocket-pi/js/node/_cjs-runtime.js deleted file mode 100644 index 861598d..0000000 --- a/crates/pocket-pi/js/node/_cjs-runtime.js +++ /dev/null @@ -1,27 +0,0 @@ -globalThis.__cjsCache = globalThis.__cjsCache || /* @__PURE__ */ new Map(); -globalThis.__cjsRequire = function(fromFile, spec) { - const r = JSON.parse(globalThis.__node.resolve(fromFile, spec)); - if (r.builtin != null) { - const exports = globalThis.__builtinExports[r.builtin] ?? globalThis.__builtinExports[r.builtin.split("/")[0]]; - if (exports === void 0) throw new Error("builtin not available: " + r.builtin); - return exports; - } - if (r.err) throw new Error("Cannot find module '" + spec + "' from '" + fromFile + "'"); - const p = r.path; - if (globalThis.__cjsCache.has(p)) return globalThis.__cjsCache.get(p); - if (p.endsWith(".json")) { - const val = JSON.parse(globalThis.__node.readText(p)); - globalThis.__cjsCache.set(p, val); - return val; - } - let src = globalThis.__node.readText(p); - if (p.endsWith(".ts") || p.endsWith(".cts")) src = host.transpile(p, src); - const module = { exports: {} }; - globalThis.__cjsCache.set(p, module.exports); - const dir = p.replace(/\/[^/]*$/, ""); - const fn = new Function("module", "exports", "require", "__filename", "__dirname", src); - fn(module, module.exports, (s) => globalThis.__cjsRequire(p, s), p, dir); - globalThis.__cjsCache.set(p, module.exports); - return module.exports; -}; -globalThis.require = (spec) => globalThis.__cjsRequire("/pocket-pi-bundle", spec); diff --git a/crates/pocket-pi/js/node/assert.js b/crates/pocket-pi/js/node/assert.js deleted file mode 100644 index aa99fac..0000000 --- a/crates/pocket-pi/js/node/assert.js +++ /dev/null @@ -1,33 +0,0 @@ -function assert(v, msg) { - if (!v) throw new Error(msg || "Assertion failed"); -} -assert.ok = assert; -assert.equal = (a, b, m) => { - if (a != b) throw new Error(m || a + " != " + b); -}; -assert.strictEqual = (a, b, m) => { - if (a !== b) throw new Error(m || a + " !== " + b); -}; -assert.deepEqual = (a, b, m) => { - if (JSON.stringify(a) !== JSON.stringify(b)) throw new Error(m || "deepEqual failed"); -}; -assert.deepStrictEqual = assert.deepEqual; -assert.notEqual = (a, b, m) => { - if (a == b) throw new Error(m || "notEqual failed"); -}; -assert.throws = (fn, m) => { - try { - fn(); - } catch { - return; - } - throw new Error(m || "expected throw"); -}; -assert.fail = (m) => { - throw new Error(m || "fail"); -}; -var assert_default = assert; -export { - assert, - assert_default as default -}; diff --git a/crates/pocket-pi/js/node/async_hooks.js b/crates/pocket-pi/js/node/async_hooks.js deleted file mode 100644 index 0decaa3..0000000 --- a/crates/pocket-pi/js/node/async_hooks.js +++ /dev/null @@ -1,66 +0,0 @@ -class AsyncLocalStorage { - run(_store, cb, ...args) { - return cb(...args); - } - getStore() { - return this._store; - } - enterWith(store) { - this._store = store; - } - exit(cb, ...args) { - return cb(...args); - } - disable() { - } -} -class AsyncResource { - constructor(type, opts) { - this.type = type; - this._opts = opts; - } - runInAsyncScope(fn, thisArg, ...args) { - return fn.apply(thisArg, args); - } - emitDestroy() { - return this; - } - asyncId() { - return 0; - } - triggerAsyncId() { - return 0; - } - bind(fn) { - return fn; - } - static bind(fn) { - return fn; - } -} -function createHook() { - return { enable() { - return this; - }, disable() { - return this; - } }; -} -function executionAsyncId() { - return 0; -} -function triggerAsyncId() { - return 0; -} -function executionAsyncResource() { - return {}; -} -var async_hooks_default = { AsyncLocalStorage, AsyncResource, createHook, executionAsyncId, triggerAsyncId, executionAsyncResource }; -export { - AsyncLocalStorage, - AsyncResource, - createHook, - async_hooks_default as default, - executionAsyncId, - executionAsyncResource, - triggerAsyncId -}; diff --git a/crates/pocket-pi/js/node/buffer.js b/crates/pocket-pi/js/node/buffer.js deleted file mode 100644 index ad27455..0000000 --- a/crates/pocket-pi/js/node/buffer.js +++ /dev/null @@ -1,127 +0,0 @@ -const B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -function utf8ToBytes(str) { - const out = []; - for (let i = 0; i < str.length; i++) { - let c = str.charCodeAt(i); - if (c < 128) out.push(c); - else if (c < 2048) out.push(192 | c >> 6, 128 | c & 63); - else if (c >= 55296 && c <= 56319) { - const c2 = str.charCodeAt(++i); - c = 65536 + ((c & 1023) << 10) + (c2 & 1023); - out.push(240 | c >> 18, 128 | c >> 12 & 63, 128 | c >> 6 & 63, 128 | c & 63); - } else out.push(224 | c >> 12, 128 | c >> 6 & 63, 128 | c & 63); - } - return out; -} -function bytesToUtf8(bytes) { - let out = "", i = 0; - while (i < bytes.length) { - let c = bytes[i++]; - if (c < 128) out += String.fromCharCode(c); - else if (c >= 192 && c < 224) out += String.fromCharCode((c & 31) << 6 | bytes[i++] & 63); - else if (c >= 224 && c < 240) out += String.fromCharCode((c & 15) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63); - else { - const cp = (c & 7) << 18 | (bytes[i++] & 63) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63; - const off = cp - 65536; - out += String.fromCharCode(55296 + (off >> 10), 56320 + (off & 1023)); - } - } - return out; -} -function toBase64(bytes) { - let out = ""; - for (let i = 0; i < bytes.length; i += 3) { - const b0 = bytes[i], b1 = bytes[i + 1], b2 = bytes[i + 2]; - const n = b0 << 16 | (b1 || 0) << 8 | (b2 || 0); - out += B64[n >> 18 & 63] + B64[n >> 12 & 63] + (i + 1 < bytes.length ? B64[n >> 6 & 63] : "=") + (i + 2 < bytes.length ? B64[n & 63] : "="); - } - return out; -} -function fromBase64(str) { - str = str.replace(/[^A-Za-z0-9+/]/g, ""); - const out = []; - for (let i = 0; i < str.length; i += 4) { - const n = B64.indexOf(str[i]) << 18 | B64.indexOf(str[i + 1]) << 12 | B64.indexOf(str[i + 2] || "A") << 6 | B64.indexOf(str[i + 3] || "A"); - out.push(n >> 16 & 255); - if (str[i + 2] && str[i + 2] !== "=") out.push(n >> 8 & 255); - if (str[i + 3] && str[i + 3] !== "=") out.push(n & 255); - } - return out; -} -class Buffer extends Uint8Array { - static from(value, encoding) { - if (typeof value === "string") { - if (encoding === "base64") return new Buffer(fromBase64(value)); - if (encoding === "hex") { - const out = []; - for (let i = 0; i < value.length; i += 2) out.push(parseInt(value.substr(i, 2), 16)); - return new Buffer(out); - } - if (encoding === "latin1" || encoding === "binary") { - const out = new Buffer(value.length); - for (let i = 0; i < value.length; i++) out[i] = value.charCodeAt(i) & 255; - return out; - } - return new Buffer(utf8ToBytes(value)); - } - if (value instanceof Uint8Array || Array.isArray(value)) return new Buffer(value); - if (value instanceof ArrayBuffer) return new Buffer(new Uint8Array(value)); - return new Buffer(0); - } - static alloc(size, fill) { - const b = new Buffer(size); - if (fill != null) b.fill(typeof fill === "string" ? fill.charCodeAt(0) : fill); - return b; - } - static allocUnsafe(size) { - return new Buffer(size); - } - static isBuffer(v) { - return v instanceof Buffer; - } - static concat(list, length) { - let total = length ?? list.reduce((n, b) => n + b.length, 0); - const out = new Buffer(total); - let off = 0; - for (const b of list) { - out.set(b.subarray(0, Math.min(b.length, total - off)), off); - off += b.length; - if (off >= total) break; - } - return out; - } - static byteLength(str, encoding) { - return Buffer.from(str, encoding).length; - } - toString(encoding, start, end) { - const view = this.subarray(start || 0, end == null ? this.length : end); - if (encoding === "base64") return toBase64(view); - if (encoding === "hex") return Array.from(view, (b) => b.toString(16).padStart(2, "0")).join(""); - if (encoding === "latin1" || encoding === "binary") return Array.from(view, (b) => String.fromCharCode(b)).join(""); - return bytesToUtf8(view); - } - toJSON() { - return { type: "Buffer", data: Array.from(this) }; - } - equals(other) { - return this.length === other.length && this.every((v, i) => v === other[i]); - } - write(str, offset = 0, length, encoding) { - const src = Buffer.from(str, typeof length === "string" ? length : encoding); - const n = Math.min(src.length, this.length - offset, typeof length === "number" ? length : Infinity); - this.set(src.subarray(0, n), offset); - return n; - } - slice(a, b) { - return new Buffer(this.subarray(a, b)); - } -} -const SlowBuffer = Buffer; -const constants = { MAX_LENGTH: 2147483647, MAX_STRING_LENGTH: 536870911 }; -var buffer_default = { Buffer, SlowBuffer, constants }; -export { - Buffer, - SlowBuffer, - constants, - buffer_default as default -}; diff --git a/crates/pocket-pi/js/node/child_process.js b/crates/pocket-pi/js/node/child_process.js deleted file mode 100644 index 23b012e..0000000 --- a/crates/pocket-pi/js/node/child_process.js +++ /dev/null @@ -1,82 +0,0 @@ -import { EventEmitter } from "node:events"; -const n = globalThis.__node; -function spawnSync(cmd, args = [], options = {}) { - const res = JSON.parse(n.spawnSync(String(cmd), JSON.stringify(args || []), JSON.stringify(options || {}))); - const enc = options.encoding; - const wrap = (s) => enc && enc !== "buffer" ? s : globalThis.Buffer.from(s); - return { - status: res.status ?? null, - signal: null, - stdout: wrap(res.stdout || ""), - stderr: wrap(res.stderr || ""), - error: res.error ? new Error(res.error) : void 0, - pid: 0 - }; -} -function execSync(command, options = {}) { - const shell = options.shell || "/bin/sh"; - const res = spawnSync(shell, ["-c", String(command)], options); - if (res.status && res.status !== 0) { - const e = new Error(`Command failed: ${command} -${res.stderr}`); - e.status = res.status; - e.stdout = res.stdout; - e.stderr = res.stderr; - throw e; - } - return res.stdout; -} -function execFileSync(file, args = [], options = {}) { - return spawnSync(file, args, options).stdout; -} -function spawn(cmd, args = [], options = {}) { - const ee = new EventEmitter(); - queueMicrotask(() => { - try { - const r = spawnSync(cmd, args, options); - ee.stdout && ee.stdout.emit && ee.stdout.emit("data", r.stdout); - ee.emit("close", r.status ?? 0); - } catch (e) { - ee.emit("error", e); - } - }); - ee.stdout = { on() { - } }; - ee.stderr = { on() { - } }; - ee.stdin = { write() { - }, end() { - } }; - return ee; -} -function exec(command, options, cb) { - if (typeof options === "function") { - cb = options; - options = {}; - } - queueMicrotask(() => { - try { - const out = execSync(command, options); - cb && cb(null, out, ""); - } catch (e) { - cb && cb(e, e.stdout || "", e.stderr || ""); - } - }); - return { on() { - } }; -} -const execFile = exec; -function fork() { - throw new Error("child_process.fork is not supported in Pocket Pi"); -} -var child_process_default = { spawnSync, execSync, execFileSync, spawn, exec, execFile, fork }; -export { - child_process_default as default, - exec, - execFile, - execFileSync, - execSync, - fork, - spawn, - spawnSync -}; diff --git a/crates/pocket-pi/js/node/console.js b/crates/pocket-pi/js/node/console.js deleted file mode 100644 index 04c452f..0000000 --- a/crates/pocket-pi/js/node/console.js +++ /dev/null @@ -1,82 +0,0 @@ -const g = globalThis.console || {}; -const out = (...a) => { - try { - (g.log || (() => { - }))(...a); - } catch { - } -}; -const err = (...a) => { - try { - (g.error || g.log || (() => { - }))(...a); - } catch { - } -}; -class Console { - constructor(_stdout, _stderr) { - } - log(...a) { - out(...a); - } - info(...a) { - out(...a); - } - debug(...a) { - out(...a); - } - dir(...a) { - out(...a); - } - warn(...a) { - err(...a); - } - error(...a) { - err(...a); - } - trace(...a) { - err(...a); - } - table(...a) { - out(...a); - } - group(...a) { - out(...a); - } - groupCollapsed(...a) { - out(...a); - } - groupEnd() { - } - assert(cond, ...a) { - if (!cond) err("Assertion failed:", ...a); - } - count() { - } - countReset() { - } - time() { - } - timeEnd() { - } - timeLog() { - } - clear() { - } -} -const instance = new Console(); -const log = instance.log; -const info = instance.info; -const warn = instance.warn; -const error = instance.error; -const debug = instance.debug; -var console_default = instance; -export { - Console, - debug, - console_default as default, - error, - info, - log, - warn -}; diff --git a/crates/pocket-pi/js/node/constants.js b/crates/pocket-pi/js/node/constants.js deleted file mode 100644 index 9da2c55..0000000 --- a/crates/pocket-pi/js/node/constants.js +++ /dev/null @@ -1,4 +0,0 @@ -var constants_default = {}; -export { - constants_default as default -}; diff --git a/crates/pocket-pi/js/node/crypto.js b/crates/pocket-pi/js/node/crypto.js deleted file mode 100644 index 2dffddf..0000000 --- a/crates/pocket-pi/js/node/crypto.js +++ /dev/null @@ -1,74 +0,0 @@ -function fnv(str) { - let h = 0xcbf29ce484222325n; - const bytes = globalThis.Buffer ? globalThis.Buffer.from(str) : new TextEncoder().encode(str); - for (const b of bytes) { - h ^= BigInt(b); - h = h * 0x100000001b3n & 0xffffffffffffffffn; - } - return h; -} -function randomBytes(n) { - const b = globalThis.Buffer ? globalThis.Buffer.alloc(n) : new Uint8Array(n); - for (let i = 0; i < n; i++) b[i] = Math.floor(Math.random() * 256); - return b; -} -function randomUUID() { - return globalThis.crypto.randomUUID(); -} -function randomFillSync(buf) { - for (let i = 0; i < buf.length; i++) buf[i] = Math.floor(Math.random() * 256); - return buf; -} -function createHash(_algo) { - let data = ""; - return { - update(chunk) { - data += typeof chunk === "string" ? chunk : globalThis.Buffer.from(chunk).toString(); - return this; - }, - digest(enc) { - let hex = ""; - for (let i = 0; i < 4; i++) hex += fnv(i + ":" + data).toString(16).padStart(16, "0"); - if (enc === "hex") return hex; - const bytes = globalThis.Buffer.from(hex, "hex"); - return enc ? bytes.toString(enc) : bytes; - } - }; -} -function createHmac(algo, key) { - const h = createHash(algo); - h.update(String(key) + ":"); - return h; -} -function getHashes() { - return ["sha1", "sha256", "sha384", "sha512", "md5"]; -} -function getCiphers() { - return []; -} -function timingSafeEqual(a, b) { - if (!a || !b || a.length !== b.length) return false; - let diff = 0; - for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i]; - return diff === 0; -} -const constants = {}; -const webcrypto = globalThis.crypto; -function getRandomValues(a) { - return globalThis.crypto.getRandomValues(a); -} -var crypto_default = { randomBytes, randomUUID, randomFillSync, createHash, createHmac, getHashes, getCiphers, timingSafeEqual, constants, webcrypto, getRandomValues }; -export { - constants, - createHash, - createHmac, - crypto_default as default, - getCiphers, - getHashes, - getRandomValues, - randomBytes, - randomFillSync, - randomUUID, - timingSafeEqual, - webcrypto -}; diff --git a/crates/pocket-pi/js/node/diagnostics_channel.js b/crates/pocket-pi/js/node/diagnostics_channel.js deleted file mode 100644 index 02905e9..0000000 --- a/crates/pocket-pi/js/node/diagnostics_channel.js +++ /dev/null @@ -1,72 +0,0 @@ -class Channel { - constructor(name) { - this.name = name; - this._subs = []; - } - get hasSubscribers() { - return this._subs.length > 0; - } - publish(msg) { - for (const s of this._subs.slice()) { - try { - s(msg, this.name); - } catch { - } - } - } - subscribe(fn) { - this._subs.push(fn); - } - unsubscribe(fn) { - this._subs = this._subs.filter((s) => s !== fn); - return true; - } -} -const registry = /* @__PURE__ */ new Map(); -function channel(name) { - let c = registry.get(name); - if (!c) { - c = new Channel(name); - registry.set(name, c); - } - return c; -} -function hasSubscribers(name) { - const c = registry.get(name); - return !!c && c.hasSubscribers; -} -function subscribe(name, fn) { - channel(name).subscribe(fn); -} -function unsubscribe(name, fn) { - return channel(name).unsubscribe(fn); -} -function tracingChannel(nameOrChannels) { - const base = typeof nameOrChannels === "string" ? nameOrChannels : ""; - const mk = (suffix) => channel(base ? `tracing:${base}:${suffix}` : suffix); - return { - start: mk("start"), - end: mk("end"), - asyncStart: mk("asyncStart"), - asyncEnd: mk("asyncEnd"), - error: mk("error"), - traceSync(fn, ctx, thisArg, ...a) { - return fn.apply(thisArg, a); - }, - tracePromise(fn, ctx, thisArg, ...a) { - return fn.apply(thisArg, a); - }, - traceCallback(fn, pos, ctx, thisArg, ...a) { - return fn.apply(thisArg, a); - } - }; -} -var diagnostics_channel_default = { channel, hasSubscribers, subscribe, unsubscribe, tracingChannel, Channel }; -export { - channel, - diagnostics_channel_default as default, - hasSubscribers, - subscribe, - tracingChannel, - unsubscribe -}; diff --git a/crates/pocket-pi/js/node/dns.js b/crates/pocket-pi/js/node/dns.js deleted file mode 100644 index 1795e59..0000000 --- a/crates/pocket-pi/js/node/dns.js +++ /dev/null @@ -1,15 +0,0 @@ -function lookup(host, _o, cb) { - const c = typeof _o === "function" ? _o : cb; - c && c(null, "127.0.0.1", 4); -} -function resolve(_h, cb) { - cb && cb(null, []); -} -const promises = { lookup: async () => ({ address: "127.0.0.1", family: 4 }), resolve: async () => [] }; -var dns_default = { lookup, resolve, promises }; -export { - dns_default as default, - lookup, - promises, - resolve -}; diff --git a/crates/pocket-pi/js/node/events.js b/crates/pocket-pi/js/node/events.js deleted file mode 100644 index 2dc8587..0000000 --- a/crates/pocket-pi/js/node/events.js +++ /dev/null @@ -1,89 +0,0 @@ -class EventEmitter { - constructor() { - this._events = /* @__PURE__ */ new Map(); - this._maxListeners = 10; - } - setMaxListeners(n) { - this._maxListeners = n; - return this; - } - getMaxListeners() { - return this._maxListeners; - } - on(type, fn) { - let arr = this._events.get(type); - if (!arr) { - arr = []; - this._events.set(type, arr); - } - arr.push(fn); - return this; - } - addListener(type, fn) { - return this.on(type, fn); - } - once(type, fn) { - const wrap = (...args) => { - this.off(type, wrap); - fn(...args); - }; - wrap.listener = fn; - return this.on(type, wrap); - } - prependListener(type, fn) { - let arr = this._events.get(type); - if (!arr) { - arr = []; - this._events.set(type, arr); - } - arr.unshift(fn); - return this; - } - off(type, fn) { - const arr = this._events.get(type); - if (arr) { - const i = arr.findIndex((f) => f === fn || f.listener === fn); - if (i !== -1) arr.splice(i, 1); - } - return this; - } - removeListener(type, fn) { - return this.off(type, fn); - } - removeAllListeners(type) { - if (type === void 0) this._events.clear(); - else this._events.delete(type); - return this; - } - emit(type, ...args) { - const arr = this._events.get(type); - if (!arr || arr.length === 0) { - if (type === "error") throw args[0] instanceof Error ? args[0] : new Error("Unhandled error"); - return false; - } - for (const fn of arr.slice()) fn.apply(this, args); - return true; - } - listeners(type) { - return (this._events.get(type) || []).slice(); - } - listenerCount(type) { - return (this._events.get(type) || []).length; - } - eventNames() { - return [...this._events.keys()]; - } -} -const once = (emitter, name) => new Promise((resolve, reject) => { - emitter.once(name, (...args) => resolve(args)); - emitter.once("error", reject); -}); -var events_default = EventEmitter; -EventEmitter.EventEmitter = EventEmitter; -EventEmitter.once = once; -EventEmitter.defaultMaxListeners = 10; -export { - EventEmitter, - events_default as default, - once -}; diff --git a/crates/pocket-pi/js/node/fs-promises.js b/crates/pocket-pi/js/node/fs-promises.js deleted file mode 100644 index a77f78a..0000000 --- a/crates/pocket-pi/js/node/fs-promises.js +++ /dev/null @@ -1,50 +0,0 @@ -import fs from "node:fs"; -const p = fs.promises; -const readFile = p.readFile; -const writeFile = p.writeFile; -const readdir = p.readdir; -const mkdir = p.mkdir; -const stat = p.stat; -const lstat = p.lstat; -const realpath = p.realpath; -const readlink = p.readlink; -const unlink = p.unlink; -const rm = p.rm; -const rmdir = p.rmdir; -const rename = p.rename; -const copyFile = p.copyFile; -const cp = p.cp; -const appendFile = p.appendFile; -const chmod = p.chmod; -const symlink = p.symlink; -const utimes = p.utimes; -const truncate = p.truncate; -const mkdtemp = p.mkdtemp; -const access = p.access; -const open = p.open; -var fs_promises_default = p; -export { - access, - appendFile, - chmod, - copyFile, - cp, - fs_promises_default as default, - lstat, - mkdir, - mkdtemp, - open, - readFile, - readdir, - readlink, - realpath, - rename, - rm, - rmdir, - stat, - symlink, - truncate, - unlink, - utimes, - writeFile -}; diff --git a/crates/pocket-pi/js/node/fs.js b/crates/pocket-pi/js/node/fs.js deleted file mode 100644 index 3a277a6..0000000 --- a/crates/pocket-pi/js/node/fs.js +++ /dev/null @@ -1,322 +0,0 @@ -const raw = globalThis.__node.fs; -const fs = { - readFile: (p) => JSON.parse(raw.readFile(p)), - writeFile: (p, b) => JSON.parse(raw.writeFile(p, b)), - exists: (p) => raw.exists(p), - readdir: (p) => JSON.parse(raw.readdir(p)), - mkdir: (p, r) => raw.mkdir(p, r), - stat: (p) => JSON.parse(raw.stat(p)), - realpath: (p) => JSON.parse(raw.realpath(p)), - unlink: (p) => raw.unlink(p) -}; -function decode(bytesJson, encoding) { - const bytes = bytesJson; - if (!encoding) return globalThis.Buffer ? globalThis.Buffer.from(bytes) : Uint8Array.from(bytes); - const B = globalThis.__nodeBuffer; - return B ? B.from(bytes).toString(encoding) : String.fromCharCode(...bytes); -} -function readFileSync(path, options) { - const encoding = typeof options === "string" ? options : options && options.encoding; - const res = fs.readFile(String(path)); - if (res.err) throw enoent(res.err, path); - return decode(res.bytes, encoding); -} -function writeFileSync(pathOrFd, data, options) { - if (typeof pathOrFd === "number") { - fdWrite(pathOrFd, data, options); - return; - } - const encoding = typeof options === "string" ? options : options && options.encoding || "utf8"; - let bytes; - if (typeof data === "string") { - const B = globalThis.__nodeBuffer; - bytes = B ? Array.from(B.from(data, encoding)) : Array.from(data, (c) => c.charCodeAt(0)); - } else bytes = Array.from(data); - const res = fs.writeFile(String(pathOrFd), bytes); - if (res.err) throw new Error(res.err); -} -function existsSync(path) { - return fs.exists(String(path)); -} -function readdirSync(path) { - const res = fs.readdir(String(path)); - if (res.err) throw enoent(res.err, path); - return res.entries; -} -function mkdirSync(path, options) { - fs.mkdir(String(path), !!(options && options.recursive)); -} -function statSync(path) { - const res = fs.stat(String(path)); - if (res.err) throw enoent(res.err, path); - return makeStat(res); -} -const lstatSync = statSync; -function realpathSync(path) { - const res = fs.realpath(String(path)); - return res.err ? String(path) : res.path; -} -function unlinkSync(path) { - fs.unlink(String(path)); -} -function rmSync(path) { - fs.unlink(String(path)); -} -const constants = { F_OK: 0, R_OK: 4, W_OK: 2, X_OK: 1 }; -function accessSync(path, _mode) { - if (!existsSync(path)) throw enoent("no access", path); -} -const nope = (name) => () => { - throw new Error(`fs.${name} is not implemented in Pocket Pi`); -}; -const __fds = /* @__PURE__ */ new Map(); -let __nextFd = 3; -function ebadf() { - const e = new Error("EBADF: bad file descriptor"); - e.code = "EBADF"; - return e; -} -function parseFlags(flags) { - const f = String(flags || "r"); - return { - write: /[wa+]/.test(f), - append: /a/.test(f), - create: /[wa]/.test(f), - excl: /x/.test(f), - truncate: /w/.test(f) && !/\+/.test(f), - read: /r|\+/.test(f) - }; -} -function openSync(path, flags, _mode) { - path = String(path); - const f = parseFlags(flags); - const exists2 = existsSync(path); - if (f.excl && exists2) { - const e = new Error(`EEXIST: file already exists, open '${path}'`); - e.code = "EEXIST"; - throw e; - } - if (!f.create && !exists2) throw enoent("open", path); - if (f.truncate || f.create && !exists2) writeFileSync(path, ""); - const bytes = f.read && !f.truncate && existsSync(path) ? fs.readFile(path).bytes || [] : []; - const fd = __nextFd++; - __fds.set(fd, { path, flags: f, bytes, pos: 0 }); - return fd; -} -function readSync(fd, buffer, offset, length, position) { - const e = __fds.get(fd); - if (!e) throw ebadf(); - const start = position == null || position < 0 ? e.pos : position; - let n = 0; - for (; n < length && start + n < e.bytes.length; n++) buffer[offset + n] = e.bytes[start + n]; - if (position == null || position < 0) e.pos = start + n; - return n; -} -function toStr(data, options) { - if (typeof data === "string") return data; - const enc = (typeof options === "string" ? options : options && options.encoding) || "utf8"; - const B = globalThis.__nodeBuffer; - return B ? B.from(data).toString(enc) : String.fromCharCode(...data); -} -function fdWrite(fd, data, options) { - const e = __fds.get(fd); - if (!e) throw ebadf(); - const prev = existsSync(e.path) ? readFileSync(e.path, "utf8") : ""; - writeFileSync(e.path, prev + toStr(data, options), "utf8"); -} -function writeSync(fd, data, _offOrPos, _length, _position) { - const s = typeof data === "string" ? data : toStr(data); - fdWrite(fd, s); - return typeof data === "string" ? s.length : data.length; -} -function closeSync(fd) { - __fds.delete(fd); -} -const fsyncSync = () => { -}; -const fdatasyncSync = () => { -}; -const ftruncateSync = () => { -}; -function appendFileSync(path, data, options) { - const prev = existsSync(path) ? readFileSync(path, "utf8") : ""; - writeFileSync(path, prev + (typeof data === "string" ? data : ""), options); -} -const copyFileSync = nope("copyFileSync"); -function renameSync(a, b) { - const d = readFileSync(a); - writeFileSync(b, d); - unlinkSync(a); -} -const rmdirSync = (p) => unlinkSync(p); -const cpSync = nope("cpSync"); -const chmodSync = () => { -}; -const symlinkSync = nope("symlinkSync"); -const readlinkSync = (p) => realpathSync(p); -const truncateSync = nope("truncateSync"); -const utimesSync = () => { -}; -const createReadStream = nope("createReadStream"); -const createWriteStream = nope("createWriteStream"); -const watchFile = () => { -}; -const unwatchFile = () => { -}; -function watch() { - return { close() { - }, on() { - }, unref() { - return this; - } }; -} -const opendirSync = nope("opendirSync"); -const mkdtempSync = (prefix) => { - const p = prefix + Math.random().toString(36).slice(2, 8); - mkdirSync(p, { recursive: true }); - return p; -}; -function makeStat(res) { - return { - size: res.size || 0, - mtimeMs: res.mtimeMs || 0, - isFile: () => res.isFile, - isDirectory: () => res.isDir, - isSymbolicLink: () => false - }; -} -function enoent(msg, path) { - const e = new Error(`ENOENT: ${msg}, '${path}'`); - e.code = "ENOENT"; - e.path = String(path); - return e; -} -const cbify = (fn) => (...args) => { - const cb = typeof args[args.length - 1] === "function" ? args.pop() : () => { - }; - queueMicrotask(() => { - try { - cb(null, fn(...args)); - } catch (e) { - cb(e); - } - }); -}; -const readFile = cbify(readFileSync); -const writeFile = cbify(writeFileSync); -const readdir = cbify(readdirSync); -const stat = cbify(statSync); -const lstat = cbify(statSync); -const mkdir = cbify(mkdirSync); -const access = cbify(accessSync); -const unlink = cbify(unlinkSync); -const realpath = cbify(realpathSync); -const rename = cbify(renameSync); -const rm = cbify(unlinkSync); -const exists = (p, cb) => queueMicrotask(() => cb(existsSync(p))); -const P = (fn) => (...args) => new Promise((res, rej) => { - try { - res(fn(...args)); - } catch (e) { - rej(e); - } -}); -const promises = { - readFile: P(readFileSync), - writeFile: P(writeFileSync), - readdir: P(readdirSync), - mkdir: P(mkdirSync), - stat: P(statSync), - lstat: P(statSync), - realpath: P(realpathSync), - readlink: P(readlinkSync), - unlink: P(unlinkSync), - rm: P(rmSync), - rmdir: P(rmdirSync), - rename: P(renameSync), - copyFile: P(copyFileSync), - cp: P(cpSync), - appendFile: P(appendFileSync), - chmod: P(chmodSync), - symlink: P(symlinkSync), - utimes: P(utimesSync), - truncate: P(truncateSync), - mkdtemp: P(mkdtempSync), - access: P(accessSync), - open: P((path) => ({ - fd: 0, - readFile: (opts) => readFileSync(path, opts), - writeFile: (data, opts) => writeFileSync(path, data, opts), - stat: () => statSync(path), - close: () => { - }, - read: () => ({ bytesRead: 0, buffer: null }), - write: () => ({ bytesWritten: 0 }) - })) -}; -var fs_default = { - readFileSync, - writeFileSync, - existsSync, - readdirSync, - mkdirSync, - statSync, - lstatSync, - realpathSync, - unlinkSync, - rmSync, - promises, - constants: { F_OK: 0, R_OK: 4, W_OK: 2, X_OK: 1 } -}; -export { - access, - accessSync, - appendFileSync, - chmodSync, - closeSync, - constants, - copyFileSync, - cpSync, - createReadStream, - createWriteStream, - fs_default as default, - exists, - existsSync, - fdatasyncSync, - fsyncSync, - ftruncateSync, - lstat, - lstatSync, - mkdir, - mkdirSync, - mkdtempSync, - openSync, - opendirSync, - promises, - readFile, - readFileSync, - readSync, - readdir, - readdirSync, - readlinkSync, - realpath, - realpathSync, - rename, - renameSync, - rm, - rmSync, - rmdirSync, - stat, - statSync, - symlinkSync, - truncateSync, - unlink, - unlinkSync, - unwatchFile, - utimesSync, - watch, - watchFile, - writeFile, - writeFileSync, - writeSync -}; diff --git a/crates/pocket-pi/js/node/http.js b/crates/pocket-pi/js/node/http.js deleted file mode 100644 index 04d4ede..0000000 --- a/crates/pocket-pi/js/node/http.js +++ /dev/null @@ -1,37 +0,0 @@ -import { EventEmitter } from "node:events"; -class Agent { - constructor(o) { - this.options = o || {}; - } -} -class Server extends EventEmitter { - listen() { - return this; - } - close() { - } -} -function request() { - throw new Error("http.request not supported (use fetch)"); -} -function get() { - throw new Error("http.get not supported (use fetch)"); -} -const globalAgent = new Agent(); -const METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]; -const STATUS_CODES = {}; -function createServer() { - return new Server(); -} -var http_default = { Agent, Server, request, get, globalAgent, METHODS, STATUS_CODES, createServer }; -export { - Agent, - METHODS, - STATUS_CODES, - Server, - createServer, - http_default as default, - get, - globalAgent, - request -}; diff --git a/crates/pocket-pi/js/node/https.js b/crates/pocket-pi/js/node/https.js deleted file mode 100644 index 1093fbe..0000000 --- a/crates/pocket-pi/js/node/https.js +++ /dev/null @@ -1,37 +0,0 @@ -import { EventEmitter } from "node:events"; -class Agent { - constructor(o) { - this.options = o || {}; - } -} -class Server extends EventEmitter { - listen() { - return this; - } - close() { - } -} -function request() { - throw new Error("https.request not supported (use fetch)"); -} -function get() { - throw new Error("https.get not supported (use fetch)"); -} -const globalAgent = new Agent(); -const METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]; -const STATUS_CODES = {}; -function createServer() { - return new Server(); -} -var https_default = { Agent, Server, request, get, globalAgent, METHODS, STATUS_CODES, createServer }; -export { - Agent, - METHODS, - STATUS_CODES, - Server, - createServer, - https_default as default, - get, - globalAgent, - request -}; diff --git a/crates/pocket-pi/js/node/module.js b/crates/pocket-pi/js/node/module.js deleted file mode 100644 index 6ba8515..0000000 --- a/crates/pocket-pi/js/node/module.js +++ /dev/null @@ -1,24 +0,0 @@ -function createRequire(from) { - let base = "/pocket-pi-bundle"; - if (typeof from === "string") base = from.startsWith("file://") ? from.slice(7) : from; - else if (from && from.href) base = String(from.href).replace(/^file:\/\//, ""); - return function require2(spec) { - return globalThis.__cjsRequire(base, spec); - }; -} -const builtinModules = ["fs", "path", "os", "events", "util", "buffer", "process", "crypto", "url", "child_process", "stream", "string_decoder", "module", "readline", "http", "https", "net", "tls", "zlib", "assert", "querystring"]; -function isBuiltin(m) { - return builtinModules.includes(String(m).replace(/^node:/, "")); -} -class Module { -} -Module.createRequire = createRequire; -Module.builtinModules = builtinModules; -var module_default = { createRequire, builtinModules, isBuiltin, Module }; -export { - Module, - builtinModules, - createRequire, - module_default as default, - isBuiltin -}; diff --git a/crates/pocket-pi/js/node/net.js b/crates/pocket-pi/js/node/net.js deleted file mode 100644 index c0d1fab..0000000 --- a/crates/pocket-pi/js/node/net.js +++ /dev/null @@ -1,56 +0,0 @@ -import { EventEmitter } from "node:events"; -class Socket extends EventEmitter { - connect() { - return this; - } - write() { - return true; - } - end() { - } - destroy() { - } - setTimeout() { - } - setNoDelay() { - } - setKeepAlive() { - } -} -class Server extends EventEmitter { - listen() { - return this; - } - close() { - } -} -function connect() { - return new Socket(); -} -function createConnection() { - return new Socket(); -} -function createServer() { - return new Server(); -} -function isIP(s) { - return /^\d+\.\d+\.\d+\.\d+$/.test(s) ? 4 : 0; -} -function isIPv4(s) { - return isIP(s) === 4; -} -function isIPv6() { - return false; -} -var net_default = { Socket, Server, connect, createConnection, createServer, isIP, isIPv4, isIPv6 }; -export { - Server, - Socket, - connect, - createConnection, - createServer, - net_default as default, - isIP, - isIPv4, - isIPv6 -}; diff --git a/crates/pocket-pi/js/node/os.js b/crates/pocket-pi/js/node/os.js deleted file mode 100644 index 265b912..0000000 --- a/crates/pocket-pi/js/node/os.js +++ /dev/null @@ -1,57 +0,0 @@ -const n = globalThis.__node; -function platform() { - return globalThis.process && globalThis.process.platform || "linux"; -} -function homedir() { - return n ? n.homedir() : "/"; -} -function tmpdir() { - return n ? n.tmpdir() : "/tmp"; -} -function hostname() { - return n && n.hostname ? n.hostname() : "localhost"; -} -function arch() { - return globalThis.process && globalThis.process.arch || "x64"; -} -function type() { - return platform() === "darwin" ? "Darwin" : platform() === "win32" ? "Windows_NT" : "Linux"; -} -function release() { - return "0.0.0"; -} -function cpus() { - return []; -} -function totalmem() { - return 0; -} -function freemem() { - return 0; -} -function uptime() { - return 0; -} -function userInfo() { - return { username: "user", homedir: homedir(), shell: null, uid: -1, gid: -1 }; -} -const EOL = "\n"; -const constants = { signals: {}, errno: {} }; -var os_default = { platform, homedir, tmpdir, hostname, arch, type, release, cpus, totalmem, freemem, uptime, userInfo, EOL, constants }; -export { - EOL, - arch, - constants, - cpus, - os_default as default, - freemem, - homedir, - hostname, - platform, - release, - tmpdir, - totalmem, - type, - uptime, - userInfo -}; diff --git a/crates/pocket-pi/js/node/path.js b/crates/pocket-pi/js/node/path.js deleted file mode 100644 index 22dc2ec..0000000 --- a/crates/pocket-pi/js/node/path.js +++ /dev/null @@ -1,167 +0,0 @@ -const sep = "/"; -function assertPath(p) { - if (typeof p !== "string") throw new TypeError("Path must be a string. Received " + typeof p); -} -function normalizeArray(parts, allowAboveRoot) { - const res = []; - for (const p of parts) { - if (!p || p === ".") continue; - if (p === "..") { - if (res.length && res[res.length - 1] !== "..") res.pop(); - else if (allowAboveRoot) res.push(".."); - } else res.push(p); - } - return res; -} -function normalize(path) { - assertPath(path); - if (path.length === 0) return "."; - const isAbs = path.charCodeAt(0) === 47; - const trailing = path.charCodeAt(path.length - 1) === 47; - let out = normalizeArray(path.split("/"), !isAbs).join("/"); - if (!out && !isAbs) out = "."; - if (out && trailing) out += "/"; - return (isAbs ? "/" : "") + out; -} -function isAbsolute(path) { - assertPath(path); - return path.length > 0 && path.charCodeAt(0) === 47; -} -function join(...args) { - if (args.length === 0) return "."; - let joined; - for (const arg of args) { - assertPath(arg); - if (arg.length > 0) joined = joined === void 0 ? arg : joined + "/" + arg; - } - if (joined === void 0) return "."; - return normalize(joined); -} -function resolve(...args) { - let resolved = ""; - let isAbs = false; - for (let i = args.length - 1; i >= -1 && !isAbs; i--) { - const path = i >= 0 ? args[i] : cwd(); - assertPath(path); - if (path.length === 0) continue; - resolved = path + "/" + resolved; - isAbs = path.charCodeAt(0) === 47; - } - const parts = normalizeArray(resolved.split("/"), !isAbs); - resolved = parts.join("/"); - if (isAbs) return "/" + resolved; - return resolved.length > 0 ? resolved : "."; -} -function cwd() { - return globalThis.process && globalThis.process.cwd && globalThis.process.cwd() || "/"; -} -function dirname(path) { - assertPath(path); - if (path.length === 0) return "."; - let end = -1; - let matchedSlash = true; - for (let i = path.length - 1; i >= 1; --i) { - if (path.charCodeAt(i) === 47) { - if (!matchedSlash) { - end = i; - break; - } - } else matchedSlash = false; - } - if (end === -1) return path.charCodeAt(0) === 47 ? "/" : "."; - if (end === 0 && path.charCodeAt(0) === 47) return "/"; - return path.slice(0, end); -} -function basename(path, ext) { - assertPath(path); - let start = 0, end = -1, matchedSlash = true; - for (let i = path.length - 1; i >= 0; --i) { - if (path.charCodeAt(i) === 47) { - if (!matchedSlash) { - start = i + 1; - break; - } - } else if (end === -1) { - matchedSlash = false; - end = i + 1; - } - } - let base = end === -1 ? "" : path.slice(start, end); - if (ext && base.endsWith(ext) && base !== ext) base = base.slice(0, -ext.length); - return base; -} -function extname(path) { - assertPath(path); - let startDot = -1, startPart = 0, end = -1, matchedSlash = true, preDotState = 0; - for (let i = path.length - 1; i >= 0; --i) { - const code = path.charCodeAt(i); - if (code === 47) { - if (!matchedSlash) { - startPart = i + 1; - break; - } - continue; - } - if (end === -1) { - matchedSlash = false; - end = i + 1; - } - if (code === 46) { - if (startDot === -1) startDot = i; - else if (preDotState !== 1) preDotState = 1; - } else if (startDot !== -1) preDotState = -1; - } - if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) return ""; - return path.slice(startDot, end); -} -function relative(from, to) { - from = resolve(from); - to = resolve(to); - if (from === to) return ""; - const fromParts = from.split("/").filter(Boolean); - const toParts = to.split("/").filter(Boolean); - let i = 0; - while (i < fromParts.length && i < toParts.length && fromParts[i] === toParts[i]) i++; - const up = fromParts.length - i; - const out = []; - for (let j = 0; j < up; j++) out.push(".."); - return out.concat(toParts.slice(i)).join("/"); -} -function parse(path) { - const root = isAbsolute(path) ? "/" : ""; - const dir = dirname(path); - const base = basename(path); - const ext = extname(base); - return { root, dir, base, ext, name: ext ? base.slice(0, -ext.length) : base }; -} -function toNamespacedPath(path) { - return path; -} -function format(obj) { - const dir = obj.dir || obj.root || ""; - const base = obj.base || `${obj.name || ""}${obj.ext || ""}`; - if (!dir) return base; - return dir === obj.root ? `${dir}${base}` : `${dir}${sep}${base}`; -} -const posix = { sep, delimiter: ":", normalize, isAbsolute, join, resolve, dirname, basename, extname, relative, parse, format, toNamespacedPath }; -const win32 = { ...posix, sep: "\\", delimiter: ";" }; -const delimiter = ":"; -var path_default = { sep, delimiter, normalize, isAbsolute, join, resolve, dirname, basename, extname, relative, parse, format, toNamespacedPath, posix, win32 }; -export { - basename, - path_default as default, - delimiter, - dirname, - extname, - format, - isAbsolute, - join, - normalize, - parse, - posix, - relative, - resolve, - sep, - toNamespacedPath, - win32 -}; diff --git a/crates/pocket-pi/js/node/perf_hooks.js b/crates/pocket-pi/js/node/perf_hooks.js deleted file mode 100644 index d3c9d5b..0000000 --- a/crates/pocket-pi/js/node/perf_hooks.js +++ /dev/null @@ -1,13 +0,0 @@ -const performance = globalThis.performance || { now: () => Date.now(), timeOrigin: 0 }; -class PerformanceObserver { - observe() { - } - disconnect() { - } -} -var perf_hooks_default = { performance, PerformanceObserver }; -export { - PerformanceObserver, - perf_hooks_default as default, - performance -}; diff --git a/crates/pocket-pi/js/node/process.js b/crates/pocket-pi/js/node/process.js deleted file mode 100644 index 3f67a7c..0000000 --- a/crates/pocket-pi/js/node/process.js +++ /dev/null @@ -1,21 +0,0 @@ -const p = globalThis.process; -const env = p.env; -const platform = p.platform; -const argv = p.argv; -const version = p.version; -const versions = p.versions; -const cwd = p.cwd; -const nextTick = p.nextTick; -const exit = p.exit; -var process_default = p; -export { - argv, - cwd, - process_default as default, - env, - exit, - nextTick, - platform, - version, - versions -}; diff --git a/crates/pocket-pi/js/node/querystring.js b/crates/pocket-pi/js/node/querystring.js deleted file mode 100644 index 28cf980..0000000 --- a/crates/pocket-pi/js/node/querystring.js +++ /dev/null @@ -1,23 +0,0 @@ -function parse(str) { - const o = {}; - for (const p of String(str).split("&")) { - if (!p) continue; - const i = p.indexOf("="); - const k = decodeURIComponent(i < 0 ? p : p.slice(0, i)); - const v = i < 0 ? "" : decodeURIComponent(p.slice(i + 1)); - o[k] = v; - } - return o; -} -function stringify(obj) { - return Object.entries(obj || {}).map(([k, v]) => encodeURIComponent(k) + "=" + encodeURIComponent(v)).join("&"); -} -const decode = parse, encode = stringify; -var querystring_default = { parse, stringify, decode, encode }; -export { - decode, - querystring_default as default, - encode, - parse, - stringify -}; diff --git a/crates/pocket-pi/js/node/readline.js b/crates/pocket-pi/js/node/readline.js deleted file mode 100644 index 0cf2d97..0000000 --- a/crates/pocket-pi/js/node/readline.js +++ /dev/null @@ -1,14 +0,0 @@ -import { EventEmitter } from "node:events"; -function createInterface() { - const rl = new EventEmitter(); - rl.question = (_q, cb) => cb && cb(""); - rl.close = () => { - }; - rl.on = rl.on.bind(rl); - return rl; -} -var readline_default = { createInterface }; -export { - createInterface, - readline_default as default -}; diff --git a/crates/pocket-pi/js/node/stream-promises.js b/crates/pocket-pi/js/node/stream-promises.js deleted file mode 100644 index 90b94e0..0000000 --- a/crates/pocket-pi/js/node/stream-promises.js +++ /dev/null @@ -1,19 +0,0 @@ -function pipeline(...args) { - if (typeof args[args.length - 1] === "function") args.pop(); - return Promise.resolve(); -} -function finished(stream) { - return new Promise((res) => { - if (stream && stream.on) { - stream.on("end", res); - stream.on("finish", res); - } - queueMicrotask(res); - }); -} -var stream_promises_default = { pipeline, finished }; -export { - stream_promises_default as default, - finished, - pipeline -}; diff --git a/crates/pocket-pi/js/node/stream.js b/crates/pocket-pi/js/node/stream.js deleted file mode 100644 index 1530bc4..0000000 --- a/crates/pocket-pi/js/node/stream.js +++ /dev/null @@ -1,70 +0,0 @@ -import { EventEmitter } from "node:events"; -class Readable extends EventEmitter { - constructor(opts) { - super(); - this._opts = opts || {}; - } - push(chunk) { - if (chunk === null) this.emit("end"); - else this.emit("data", chunk); - return true; - } - pipe(dest) { - this.on("data", (c) => dest.write && dest.write(c)); - this.on("end", () => dest.end && dest.end()); - return dest; - } - read() { - return null; - } - static from(iterable) { - const r = new Readable(); - queueMicrotask(async () => { - for await (const c of iterable) r.push(c); - r.push(null); - }); - return r; - } -} -class Writable extends EventEmitter { - constructor(opts) { - super(); - this._opts = opts || {}; - } - write(chunk, _enc, cb) { - if (this._opts.write) this._opts.write(chunk, _enc, cb || (() => { - })); - else if (cb) cb(); - return true; - } - end(chunk, _enc, cb) { - if (chunk) this.write(chunk); - this.emit("finish"); - if (cb) cb(); - } -} -class Duplex extends Readable { -} -class Transform extends Duplex { -} -class PassThrough extends Transform { -} -var stream_default = { Readable, Writable, Duplex, Transform, PassThrough }; -function pipeline(...args) { - const cb = typeof args[args.length - 1] === "function" ? args.pop() : null; - queueMicrotask(() => cb && cb(null)); - return args[args.length - 1]; -} -function finished(stream, cb) { - queueMicrotask(() => cb && cb(null)); -} -export { - Duplex, - PassThrough, - Readable, - Transform, - Writable, - stream_default as default, - finished, - pipeline -}; diff --git a/crates/pocket-pi/js/node/string_decoder.js b/crates/pocket-pi/js/node/string_decoder.js deleted file mode 100644 index 7a61477..0000000 --- a/crates/pocket-pi/js/node/string_decoder.js +++ /dev/null @@ -1,17 +0,0 @@ -class StringDecoder { - constructor(encoding) { - this.encoding = encoding || "utf8"; - this._dec = new TextDecoder(); - } - write(buf) { - return this._dec.decode(buf instanceof Uint8Array ? buf : globalThis.Buffer.from(buf)); - } - end(buf) { - return buf ? this.write(buf) : ""; - } -} -var string_decoder_default = { StringDecoder }; -export { - StringDecoder, - string_decoder_default as default -}; diff --git a/crates/pocket-pi/js/node/timers.js b/crates/pocket-pi/js/node/timers.js deleted file mode 100644 index c2a3807..0000000 --- a/crates/pocket-pi/js/node/timers.js +++ /dev/null @@ -1,18 +0,0 @@ -const setTimeout = globalThis.setTimeout; -const clearTimeout = globalThis.clearTimeout; -const setInterval = globalThis.setInterval; -const clearInterval = globalThis.clearInterval; -const setImmediate = (fn, ...a) => globalThis.setTimeout(fn, 0, ...a); -const clearImmediate = globalThis.clearTimeout; -const promises = { setTimeout: (ms) => new Promise((r) => globalThis.setTimeout(r, ms)) }; -var timers_default = { setTimeout, clearTimeout, setInterval, clearInterval, setImmediate, clearImmediate, promises }; -export { - clearImmediate, - clearInterval, - clearTimeout, - timers_default as default, - promises, - setImmediate, - setInterval, - setTimeout -}; diff --git a/crates/pocket-pi/js/node/tls.js b/crates/pocket-pi/js/node/tls.js deleted file mode 100644 index 78e985a..0000000 --- a/crates/pocket-pi/js/node/tls.js +++ /dev/null @@ -1,18 +0,0 @@ -import { Socket } from "node:net"; -class TLSSocket extends Socket { -} -function connect() { - return new TLSSocket(); -} -function createSecureContext() { - return {}; -} -const rootCertificates = []; -var tls_default = { TLSSocket, connect, createSecureContext, rootCertificates }; -export { - TLSSocket, - connect, - createSecureContext, - tls_default as default, - rootCertificates -}; diff --git a/crates/pocket-pi/js/node/tty.js b/crates/pocket-pi/js/node/tty.js deleted file mode 100644 index 9dee833..0000000 --- a/crates/pocket-pi/js/node/tty.js +++ /dev/null @@ -1,14 +0,0 @@ -function isatty() { - return false; -} -class ReadStream { -} -class WriteStream { -} -var tty_default = { isatty, ReadStream, WriteStream }; -export { - ReadStream, - WriteStream, - tty_default as default, - isatty -}; diff --git a/crates/pocket-pi/js/node/url.js b/crates/pocket-pi/js/node/url.js deleted file mode 100644 index f0bc1b7..0000000 --- a/crates/pocket-pi/js/node/url.js +++ /dev/null @@ -1,54 +0,0 @@ -const URL = globalThis.URL; -const URLSearchParams = globalThis.URLSearchParams; -function fileURLToPath(url) { - let s = typeof url === "string" ? url : url.href; - if (s.startsWith("file://")) s = s.slice(7); - return decodeURIComponent(s); -} -function pathToFileURL(path) { - return new globalThis.URL("file://" + encodeURI(path)); -} -function parse(str) { - try { - const u = new globalThis.URL(str); - return { href: u.href, protocol: u.protocol, host: u.host, hostname: u.hostname, port: u.port, pathname: u.pathname, search: u.search, hash: u.hash, query: u.search.replace(/^\?/, "") }; - } catch { - return { href: str, pathname: str, protocol: null, host: null, hostname: null, port: "", search: "", hash: "", query: "" }; - } -} -function format(obj) { - if (typeof obj === "string") return obj; - if (obj && typeof obj.href === "string" && obj.protocol) return obj.href; - const proto = obj.protocol ? obj.protocol.endsWith(":") ? obj.protocol : obj.protocol + ":" : ""; - const host = obj.host || (obj.hostname ? obj.hostname + (obj.port ? ":" + obj.port : "") : ""); - const search = obj.search || (obj.query ? "?" + (typeof obj.query === "string" ? obj.query : new globalThis.URLSearchParams(obj.query).toString()) : ""); - return (proto ? proto + "//" : "") + host + (obj.pathname || "") + search + (obj.hash || ""); -} -function resolve(from, to) { - try { - return new globalThis.URL(to, from).href; - } catch { - return to; - } -} -const Url = globalThis.URL; -function domainToASCII(d) { - return d; -} -function domainToUnicode(d) { - return d; -} -var url_default = { URL, URLSearchParams, fileURLToPath, pathToFileURL, parse, format, resolve, Url, domainToASCII, domainToUnicode }; -export { - URL, - URLSearchParams, - Url, - url_default as default, - domainToASCII, - domainToUnicode, - fileURLToPath, - format, - parse, - pathToFileURL, - resolve -}; diff --git a/crates/pocket-pi/js/node/util.js b/crates/pocket-pi/js/node/util.js deleted file mode 100644 index adfdf87..0000000 --- a/crates/pocket-pi/js/node/util.js +++ /dev/null @@ -1,115 +0,0 @@ -function inherits(ctor, superCtor) { - ctor.super_ = superCtor; - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { value: ctor, enumerable: false, writable: true, configurable: true } - }); -} -function format(fmt, ...args) { - if (typeof fmt !== "string") return [fmt, ...args].map(inspect).join(" "); - let i = 0; - let out = fmt.replace(/%[sdifjoO%]/g, (m) => { - if (m === "%%") return "%"; - if (i >= args.length) return m; - const a = args[i++]; - switch (m) { - case "%s": - return String(a); - case "%d": - case "%i": - return String(parseInt(a, 10)); - case "%f": - return String(parseFloat(a)); - case "%j": - try { - return JSON.stringify(a); - } catch { - return "[Circular]"; - } - default: - return inspect(a); - } - }); - for (; i < args.length; i++) out += " " + (typeof args[i] === "string" ? args[i] : inspect(args[i])); - return out; -} -function inspect(obj) { - if (typeof obj === "string") return obj; - try { - return JSON.stringify(obj); - } catch { - return String(obj); - } -} -inspect.custom = Symbol.for("nodejs.util.inspect.custom"); -function promisify(fn) { - return function(...args) { - return new Promise((resolve, reject) => { - fn.call(this, ...args, (err, ...rest) => err ? reject(err) : resolve(rest.length > 1 ? rest : rest[0])); - }); - }; -} -function callbackify(fn) { - return function(...args) { - const cb = args.pop(); - fn.apply(this, args).then((v) => cb(null, v), (e) => cb(e)); - }; -} -function deprecate(fn) { - return fn; -} -function debuglog(section, cb) { - const env = globalThis.process && globalThis.process.env && globalThis.process.env.NODE_DEBUG || ""; - const on = env.split(/[\s,]+/).includes(section); - const fn = on ? (...args) => { - try { - console.error(`${section}:`, format(...args)); - } catch { - } - } : () => { - }; - if (typeof cb === "function") cb(fn); - return fn; -} -const debug = debuglog; -function inspect2() { -} -const isDeepStrictEqual = (a, b) => { - try { - return JSON.stringify(a) === JSON.stringify(b); - } catch { - return a === b; - } -}; -function stripVTControlCharacters(s) { - return String(s).replace(/\x1b\[[0-9;]*m/g, ""); -} -const _extend = Object.assign; -const types = { - isPromise: (v) => v && typeof v.then === "function", - isDate: (v) => v instanceof Date, - isRegExp: (v) => v instanceof RegExp, - isArrayBuffer: (v) => v instanceof ArrayBuffer, - isTypedArray: (v) => ArrayBuffer.isView(v) && !(v instanceof DataView), - isAsyncFunction: (v) => v && v.constructor && v.constructor.name === "AsyncFunction" -}; -const TextEncoder = globalThis.TextEncoder; -const TextDecoder = globalThis.TextDecoder; -var util_default = { inherits, format, inspect, promisify, callbackify, deprecate, debuglog, debug, isDeepStrictEqual, stripVTControlCharacters, _extend, types, TextEncoder, TextDecoder }; -export { - TextDecoder, - TextEncoder, - _extend, - callbackify, - debug, - debuglog, - util_default as default, - deprecate, - format, - inherits, - inspect, - inspect2, - isDeepStrictEqual, - promisify, - stripVTControlCharacters, - types -}; diff --git a/crates/pocket-pi/js/node/v8.js b/crates/pocket-pi/js/node/v8.js deleted file mode 100644 index 70b6ea6..0000000 --- a/crates/pocket-pi/js/node/v8.js +++ /dev/null @@ -1,4 +0,0 @@ -var v8_default = {}; -export { - v8_default as default -}; diff --git a/crates/pocket-pi/js/node/vm.js b/crates/pocket-pi/js/node/vm.js deleted file mode 100644 index 5718dde..0000000 --- a/crates/pocket-pi/js/node/vm.js +++ /dev/null @@ -1,4 +0,0 @@ -var vm_default = {}; -export { - vm_default as default -}; diff --git a/crates/pocket-pi/js/node/worker_threads.js b/crates/pocket-pi/js/node/worker_threads.js deleted file mode 100644 index 280b75a..0000000 --- a/crates/pocket-pi/js/node/worker_threads.js +++ /dev/null @@ -1,88 +0,0 @@ -class Worker { - constructor() { - throw new Error("worker_threads.Worker is not supported in Pocket Pi (single-threaded)"); - } -} -const isMainThread = true; -const parentPort = null; -const threadId = 0; -const workerData = null; -class MessageChannel { - constructor() { - this.port1 = new MessagePort(); - this.port2 = new MessagePort(); - } -} -class MessagePort { - postMessage() { - } - on() { - return this; - } - once() { - return this; - } - close() { - } - ref() { - return this; - } - unref() { - return this; - } - start() { - } -} -const BroadcastChannel = class BroadcastChannel2 { - postMessage() { - } - close() { - } - on() { - return this; - } -}; -function markAsUntransferable() { -} -function moveMessagePortToContext() { - throw new Error("not supported"); -} -function receiveMessageOnPort() { - return void 0; -} -function setEnvironmentData() { -} -function getEnvironmentData() { - return void 0; -} -var worker_threads_default = { - Worker, - isMainThread, - parentPort, - threadId, - workerData, - MessageChannel, - MessagePort, - BroadcastChannel, - markAsUntransferable, - moveMessagePortToContext, - receiveMessageOnPort, - setEnvironmentData, - getEnvironmentData -}; -export { - BroadcastChannel, - MessageChannel, - MessagePort, - Worker, - worker_threads_default as default, - getEnvironmentData, - isMainThread, - markAsUntransferable, - moveMessagePortToContext, - parentPort, - receiveMessageOnPort, - setEnvironmentData, - threadId, - workerData -}; diff --git a/crates/pocket-pi/js/node/zlib.js b/crates/pocket-pi/js/node/zlib.js deleted file mode 100644 index 09eb0d3..0000000 --- a/crates/pocket-pi/js/node/zlib.js +++ /dev/null @@ -1,25 +0,0 @@ -const nope = (n) => () => { - throw new Error("zlib." + n + " not supported"); -}; -const gzip = nope("gzip"), gunzip = nope("gunzip"), deflate = nope("deflate"), inflate = nope("inflate"); -const gzipSync = nope("gzipSync"), gunzipSync = nope("gunzipSync"), deflateSync = nope("deflateSync"), inflateSync = nope("inflateSync"), brotliCompressSync = nope("brotliCompressSync"), brotliDecompressSync = nope("brotliDecompressSync"); -const constants = {}; -function createGzip() { - throw new Error("zlib streams not supported"); -} -var zlib_default = { gzip, gunzip, deflate, inflate, gzipSync, gunzipSync, deflateSync, inflateSync, brotliCompressSync, brotliDecompressSync, constants, createGzip }; -export { - brotliCompressSync, - brotliDecompressSync, - constants, - createGzip, - zlib_default as default, - deflate, - deflateSync, - gunzip, - gunzipSync, - gzip, - gzipSync, - inflate, - inflateSync -}; diff --git a/crates/pocket-pi/js/package.json b/crates/pocket-pi/js/package.json deleted file mode 100644 index dae55ac..0000000 --- a/crates/pocket-pi/js/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "@earendil-works/pi-coding-agent", - "version": "0.81.1", - "bin": { "pi": "cli.js" } -} diff --git a/crates/pocket-pi/js/pi-full.bundle.js.gz b/crates/pocket-pi/js/pi-full.bundle.js.gz deleted file mode 100644 index 190e178b92d0190626038f01458f29dd5e495a05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1923519 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

$87K&IWE8*Q88bZ7E1)zvI(1G@@y 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 `YoSTTnT;_dh6_Un_U>Rbg5)jZQG{YY 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 z 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

N82zsE3~@ZbJC>FmQlZ?4kW*MDBb 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

jt**^867YlaCY}Q)r0-ixgI(pdy77Eg-URd_!0+ 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 KU$J1Pv`7UI3it7K-)m5%Qjh@&MQ_D4IM9(ZsX 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%0AY4d}@orvCN3$08TKSv@4+^zSSlRB)tUS>% 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

2U2&wOfrNh;^c~44a6Ia*@YHA||8n&|LHX)u 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%0AXe21BN=u+xd~Cw_Na@?$#PM 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

i|7%^NY%A47C* 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ͫZRXgcUVo9k~cnc8sA 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

r7pT4>r>n?dvPA(M?c|v-J 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∾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%0DLhLy0D&%s1-++mpJ%qwAR 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 diff --git a/crates/pocket-pi/js/pi-full/driver.js b/crates/pocket-pi/js/pi-full/driver.js deleted file mode 100644 index e4378fc..0000000 --- a/crates/pocket-pi/js/pi-full/driver.js +++ /dev/null @@ -1,107 +0,0 @@ -(function() { - const P = globalThis.PiFull; - if (!P) throw new Error("PiFull not loaded \u2014 run the bundle first"); - const MODEL = { - id: "gpt-5.6", - name: "GPT-5.6", - api: "openai-responses", - provider: "openai", - baseUrl: "https://api.openai.com/v1", - reasoning: false, - input: ["text"], - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - contextWindow: 4e5, - maxTokens: 8192 - }; - const CWD = "/pocket-pi"; - const AGENT_DIR = "/pocket-pi/.pi"; - globalThis.__piResult = ""; - globalThis.__piError = null; - globalThis.__piDone = false; - globalThis.__piBind = null; - globalThis.__piLog = []; - const takeText = (msg) => { - if (!msg) return; - const content = msg.content; - if (Array.isArray(content)) { - let t = ""; - for (const b of content) { - if (!b) continue; - if (b.type === "text" && typeof b.text === "string") t += b.text; - else if (b.type === "error") t += "[ERROR] " + String(b.error || b.text || ""); - } - if (t) globalThis.__piResult = t; - } else if (typeof content === "string") { - globalThis.__piResult = content; - } - }; - globalThis.__piRun = async function(opts) { - opts = typeof opts === "string" ? opts.trim().startsWith("{") ? JSON.parse(opts) : { prompt: opts } : opts || {}; - try { - const modelRuntime = await P.ModelRuntime.create({ modelsPath: null }); - if (globalThis.__OPENAI_KEY) await modelRuntime.setRuntimeApiKey("openai", globalThis.__OPENAI_KEY); - const settingsManager = P.SettingsManager.inMemory({}); - const sessionManager = opts.sessionDir ? opts.resume ? P.SessionManager.continueRecent(CWD, opts.sessionDir) : P.SessionManager.create(CWD, opts.sessionDir) : P.SessionManager.inMemory(); - const extensionFactories = []; - if (opts.extensionPath) { - const mod = await import(opts.extensionPath); - if (typeof mod.default === "function") extensionFactories.push(mod.default); - else throw new Error("extension has no default factory export: " + opts.extensionPath); - } - const resourceLoader = new P.DefaultResourceLoader({ - cwd: CWD, - agentDir: AGENT_DIR, - settingsManager, - noExtensions: true, - noSkills: true, - noPromptTemplates: true, - noThemes: true, - noContextFiles: true, - extensionFactories - }); - if (resourceLoader.reload) await resourceLoader.reload(); - const sessionOpts = { - model: MODEL, - modelRuntime, - settingsManager, - sessionManager, - resourceLoader, - cwd: CWD, - agentDir: AGENT_DIR, - thinkingLevel: "off" - }; - if (opts.tools) sessionOpts.tools = opts.tools; - else sessionOpts.noTools = "all"; - const { session } = await P.createAgentSession(sessionOpts); - try { - const runner = session._extensionRunner; - const regTools = runner && runner.getAllRegisteredTools ? runner.getAllRegisteredTools() : []; - globalThis.__piBind = { - hasAgentStart: !!(runner && runner.hasHandlers && runner.hasHandlers("agent_start")), - registeredTools: regTools.map((t) => t && (t.name || t.definition && t.definition.name)).filter(Boolean) - }; - } catch (e) { - globalThis.__piBind = { error: String(e) }; - } - session.subscribe((event) => { - try { - if (!event) return; - globalThis.__piLastEvent = event.type; - if (event.type === "message_update" || event.type === "message_end") { - const msg = event.message; - if (msg && msg.role !== "user") takeText(msg); - if (msg && msg.stopReason === "error" && msg.errorMessage) { - globalThis.__piError = String(msg.errorMessage); - } - } - } catch { - } - }); - if (opts.prompt) await session.prompt(opts.prompt); - globalThis.__piDone = true; - } catch (e) { - globalThis.__piError = String(e && e.stack || e); - globalThis.__piDone = true; - } - }; -})(); diff --git a/crates/pocket-pi/js/pi-full/ext-probe.js b/crates/pocket-pi/js/pi-full/ext-probe.js deleted file mode 100644 index 6a12a8a..0000000 --- a/crates/pocket-pi/js/pi-full/ext-probe.js +++ /dev/null @@ -1,23 +0,0 @@ -globalThis.__piExtResult = null; -globalThis.__piExtError = null; -globalThis.__piExtDone = false; -globalThis.__piLoadExtension = async function(extPath) { - try { - const P = globalThis.PiFull; - if (!P) throw new Error("PiFull not loaded \u2014 run the bundle first"); - const mod = await import(extPath); - const factory = mod.default; - if (typeof factory !== "function") throw new Error("extension has no default factory export"); - const runtime = P.createExtensionRuntime(); - const eventBus = P.createEventBus(); - const ext = await P.loadExtensionFromFactory(factory, "/pocket-pi", eventBus, runtime, extPath); - globalThis.__piExtResult = { - tools: [...ext.tools.keys()], - handlers: [...ext.handlers.keys()] - }; - } catch (e) { - globalThis.__piExtError = String(e && e.stack || e); - } finally { - globalThis.__piExtDone = true; - } -}; diff --git a/crates/pocket-pi/js/pi-full/host.js b/crates/pocket-pi/js/pi-full/host.js deleted file mode 100644 index b20d507..0000000 --- a/crates/pocket-pi/js/pi-full/host.js +++ /dev/null @@ -1,173 +0,0 @@ -const P = globalThis.PiFull; -const CWD = "/pocket-pi"; -const AGENT_DIR = "/pocket-pi/.pi"; -const state = { session: null }; -const emit = (o) => globalThis.host.emit(JSON.stringify(o)); -function buildModel(cfg, provider) { - const base = { - id: cfg.model, - name: cfg.model, - provider, - reasoning: false, - input: ["text", "image"], - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - contextWindow: 4e5, - maxTokens: cfg.maxTokens || 4096 - }; - if (provider === "anthropic") { - return { ...base, api: "anthropic-messages", baseUrl: "https://api.anthropic.com" }; - } - return { ...base, api: "openai-responses", baseUrl: "https://api.openai.com/v1" }; -} -function nativeToolsExtension(cfg) { - return (pi) => { - for (const t of cfg.tools || []) { - pi.registerTool({ - name: t.name, - description: t.description || "", - parameters: t.parameters || { type: "object", properties: {} }, - execute: async (_id, input) => { - const res = JSON.parse(globalThis.host.tool(t.name, JSON.stringify(input || {}))); - const content = []; - if (res.text) content.push({ type: "text", text: res.text }); - if (res.image_base64) { - content.push({ type: "image", data: res.image_base64, mimeType: res.mime_type || "image/jpeg" }); - } - if (content.length === 0) content.push({ type: "text", text: "" }); - return { content, details: res.terminate ? { terminate: true } : void 0 }; - } - }); - } - }; -} -function textOf(msg) { - const c = msg && msg.content; - if (typeof c === "string") return c; - if (Array.isArray(c)) return c.filter((b) => b && b.type === "text").map((b) => b.text).join(""); - return ""; -} -async function boot(configJson) { - globalThis.__ppBooted = false; - try { - const cfg = JSON.parse(configJson); - let provider = cfg.provider || (String(cfg.model || "").startsWith("gpt") ? "openai" : "anthropic"); - let model; - let nativeProvider; - if (cfg.scripted) { - const modelId = cfg.model || "offline"; - const faux = P.fauxProvider({ - api: "pocket-pi-offline", - provider: "offline", - models: [{ id: modelId, name: "Pocket Pi Offline" }] - }); - faux.setResponses( - (cfg.scripted.steps || []).map( - (step) => P.fauxAssistantMessage(typeof step === "string" ? step : String(step.text || "")) - ) - ); - nativeProvider = faux.provider; - provider = "offline"; - model = faux.getModel(modelId); - if (!model) throw new Error(`offline model not found: ${modelId}`); - } else { - model = buildModel(cfg, provider); - } - const modelRuntime = await P.ModelRuntime.create({ modelsPath: null }); - if (nativeProvider) modelRuntime.registerNativeProvider(nativeProvider); - if (cfg.apiKey) await modelRuntime.setRuntimeApiKey(provider, cfg.apiKey); - const settingsManager = P.SettingsManager.inMemory({}); - const sessionManager = P.SessionManager.inMemory(); - const resourceLoader = new P.DefaultResourceLoader({ - cwd: CWD, - agentDir: AGENT_DIR, - settingsManager, - noExtensions: true, - noSkills: true, - noPromptTemplates: true, - noThemes: true, - noContextFiles: true, - extensionFactories: [nativeToolsExtension(cfg)] - }); - if (resourceLoader.reload) await resourceLoader.reload(); - const { session } = await P.createAgentSession({ - model, - modelRuntime, - settingsManager, - sessionManager, - resourceLoader, - cwd: CWD, - agentDir: AGENT_DIR, - thinkingLevel: "off", - tools: (cfg.tools || []).map((t) => t.name) - }); - if (cfg.systemPrompt) { - try { - session._baseSystemPrompt = cfg.systemPrompt; - session.agent.state.systemPrompt = cfg.systemPrompt; - } catch { - } - } - let lastText = ""; - session.subscribe((event) => { - try { - switch (event.type) { - case "agent_start": - lastText = ""; - emit({ kind: "start" }); - break; - case "tool_execution_start": - emit({ kind: "tool_start", name: event.toolName }); - break; - case "message_update": - case "message_end": { - const msg = event.message; - if (msg && msg.role !== "user") { - const text = textOf(msg); - if (text && text.length > lastText.length && text.startsWith(lastText)) { - emit({ kind: "text", delta: text.slice(lastText.length) }); - lastText = text; - } else if (text && text !== lastText) { - emit({ kind: "assistant_text", text }); - lastText = text; - } - if (msg.stopReason === "error" && msg.errorMessage) { - emit({ kind: "error", message: msg.errorMessage }); - } - } - break; - } - case "agent_settled": - emit({ kind: "end" }); - break; - } - } catch { - } - }); - state.session = session; - } catch (e) { - emit({ kind: "error", message: String(e?.stack || e) }); - } finally { - globalThis.__ppBooted = true; - } -} -async function prompt(text) { - const s = state.session; - if (!s) { - emit({ kind: "error", message: "prompt before boot completed" }); - emit({ kind: "end" }); - return; - } - try { - await s.prompt(text); - } catch (e) { - emit({ kind: "error", message: String(e?.stack || e) }); - emit({ kind: "end" }); - } -} -function abort() { - try { - state.session?.abort?.(); - } catch { - } -} -globalThis.PocketPi = { boot, prompt, abort }; diff --git a/crates/pocket-pi/js/pi-full/persist-probe.js b/crates/pocket-pi/js/pi-full/persist-probe.js deleted file mode 100644 index 009af34..0000000 --- a/crates/pocket-pi/js/pi-full/persist-probe.js +++ /dev/null @@ -1,29 +0,0 @@ -globalThis.__piPersistResult = null; -globalThis.__piPersistError = null; -globalThis.__piPersist = function(sessionDir) { - try { - const P = globalThis.PiFull; - if (!P) throw new Error("PiFull not loaded \u2014 run the bundle first"); - const CWD = "/pocket-pi"; - const sm1 = P.SessionManager.create(CWD, sessionDir); - sm1.appendMessage({ role: "user", content: [{ type: "text", text: "remember the number 42" }] }); - sm1.appendMessage({ role: "assistant", content: [{ type: "text", text: "noted: 42" }] }); - const wrote = sm1.buildSessionContext().messages.length; - const sessionId = sm1.getSessionId(); - const sm2 = P.SessionManager.continueRecent(CWD, sessionDir); - const ctx = sm2.buildSessionContext(); - const texts = ctx.messages.map((m) => { - const content = m.content; - return Array.isArray(content) ? content.map((c) => c && c.text || "").join("") : String(content); - }); - globalThis.__piPersistResult = { - sessionId, - wrote, - resumedCount: ctx.messages.length, - resumedId: sm2.getSessionId(), - texts - }; - } catch (e) { - globalThis.__piPersistError = String(e && e.stack || e); - } -}; diff --git a/crates/pocket-pi/js/prelude.js b/crates/pocket-pi/js/prelude.js deleted file mode 100644 index f9e2876..0000000 --- a/crates/pocket-pi/js/prelude.js +++ /dev/null @@ -1,100 +0,0 @@ -(function() { - "use strict"; - if (typeof globalThis.global === "undefined") globalThis.global = globalThis; - if (typeof globalThis.setImmediate !== "function") - globalThis.setImmediate = (fn, ...a) => globalThis.setTimeout(fn, 0, ...a); - if (typeof globalThis.clearImmediate !== "function") - globalThis.clearImmediate = (id) => globalThis.clearTimeout(id); - const timers = /* @__PURE__ */ new Map(); - let nextTimer = 1; - globalThis.setTimeout = function(fn, delay, ...args) { - const id = nextTimer++; - timers.set(id, { due: Date.now() + (delay || 0), fn, args }); - return id; - }; - globalThis.clearTimeout = function(id) { - timers.delete(id); - }; - globalThis.setInterval = function() { - throw new Error("setInterval is not supported in Pocket Pi"); - }; - globalThis.clearInterval = function() { - }; - globalThis.__catpiTimers = function() { - if (timers.size === 0) return; - const now = Date.now(); - for (const [id, t] of timers) { - if (t.due <= now) { - timers.delete(id); - try { - t.fn(...t.args); - } catch (e) { - if (globalThis.host && host.emit) - host.emit(JSON.stringify({ kind: "error", message: "timer: " + String(e) })); - } - } - } - }; - if (typeof globalThis.queueMicrotask !== "function") { - globalThis.queueMicrotask = function(fn) { - Promise.resolve().then(fn); - }; - } - if (typeof globalThis.structuredClone !== "function") { - globalThis.structuredClone = function(v) { - return v === void 0 ? void 0 : JSON.parse(JSON.stringify(v)); - }; - } - if (typeof globalThis.AbortController !== "function") { - class PPAbortSignal { - constructor() { - this.aborted = false; - this.reason = void 0; - this._listeners = []; - } - addEventListener(type, cb) { - if (type === "abort") this._listeners.push(cb); - } - removeEventListener(type, cb) { - if (type === "abort") this._listeners = this._listeners.filter((l) => l !== cb); - } - _fire() { - if (this.aborted) return; - this.aborted = true; - for (const l of this._listeners.slice()) { - try { - l({ type: "abort" }); - } catch { - } - } - } - throwIfAborted() { - if (this.aborted) throw this.reason || new Error("Aborted"); - } - } - globalThis.AbortSignal = PPAbortSignal; - globalThis.AbortController = class { - constructor() { - this.signal = new PPAbortSignal(); - } - abort(reason) { - this.signal.reason = reason || new Error("Aborted"); - this.signal._fire(); - } - }; - } - if (typeof globalThis.crypto !== "object" || !globalThis.crypto) globalThis.crypto = {}; - if (typeof globalThis.crypto.randomUUID !== "function") { - globalThis.crypto.randomUUID = function() { - if (globalThis.host && host.uuid) return host.uuid(); - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { - const r = (Date.now() + Math.floor(Math.random() * 1e9)) % 16; - const v = c === "x" ? r : r & 3 | 8; - return v.toString(16); - }); - }; - } - if (typeof globalThis.process !== "object" || !globalThis.process) { - globalThis.process = { env: {}, platform: "pocket-pi", versions: {} }; - } -})(); diff --git a/crates/pocket-pi/js/web-globals.js b/crates/pocket-pi/js/web-globals.js deleted file mode 100644 index 86cb34d..0000000 --- a/crates/pocket-pi/js/web-globals.js +++ /dev/null @@ -1,600 +0,0 @@ -(function() { - "use strict"; - const B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - if (typeof globalThis.Intl !== "object" || !globalThis.Intl) { - globalThis.Intl = { - Segmenter: class { - constructor() { - } - segment(str) { - const chars = [...String(str)]; - return { - [Symbol.iterator]() { - let i = 0; - return { - next() { - return i < chars.length ? { value: { segment: chars[i], index: i++, input: str }, done: false } : { value: void 0, done: true }; - } - }; - } - }; - } - }, - NumberFormat: class { - constructor() { - } - format(n) { - return String(n); - } - formatToParts() { - return []; - } - }, - DateTimeFormat: class { - constructor() { - } - format(d) { - return String(d); - } - formatToParts() { - return []; - } - }, - Collator: class { - constructor() { - } - compare(a, b) { - return a < b ? -1 : a > b ? 1 : 0; - } - }, - getCanonicalLocales: (l) => (Array.isArray(l) ? l : [l]).filter(Boolean) - }; - } - if (typeof globalThis.Blob === "undefined") { - globalThis.Blob = class Blob { - constructor(parts = [], opts = {}) { - this._parts = parts; - this.type = opts && opts.type || ""; - let size = 0; - for (const p of parts) { - if (typeof p === "string") size += p.length; - else if (p && p.byteLength != null) size += p.byteLength; - else if (p && p.size != null) size += p.size; - } - this.size = size; - } - async text() { - return this._parts.map((p) => typeof p === "string" ? p : "").join(""); - } - async arrayBuffer() { - return new globalThis.TextEncoder().encode(await this.text()).buffer; - } - slice() { - return new globalThis.Blob(this._parts, { type: this.type }); - } - }; - } - if (typeof globalThis.File === "undefined") { - globalThis.File = class File extends globalThis.Blob { - constructor(parts, name, opts = {}) { - super(parts, opts); - this.name = String(name); - this.lastModified = 0; - } - }; - } - if (typeof globalThis.FormData === "undefined") { - globalThis.FormData = class FormData { - constructor() { - this._entries = []; - } - append(k, v, filename) { - this._entries.push([String(k), v, filename]); - } - set(k, v) { - this._entries = this._entries.filter((e) => e[0] !== String(k)); - this._entries.push([String(k), v]); - } - get(k) { - const e = this._entries.find((e2) => e2[0] === String(k)); - return e ? e[1] : null; - } - getAll(k) { - return this._entries.filter((e) => e[0] === String(k)).map((e) => e[1]); - } - has(k) { - return this._entries.some((e) => e[0] === String(k)); - } - delete(k) { - this._entries = this._entries.filter((e) => e[0] !== String(k)); - } - forEach(cb, thisArg) { - for (const [k, v] of this._entries) cb.call(thisArg, v, k, this); - } - *entries() { - for (const e of this._entries) yield [e[0], e[1]]; - } - *keys() { - for (const e of this._entries) yield e[0]; - } - *values() { - for (const e of this._entries) yield e[1]; - } - [Symbol.iterator]() { - return this.entries(); - } - }; - } - if (typeof globalThis.EventTarget !== "function") { - globalThis.EventTarget = class EventTarget { - constructor() { - this.__l = {}; - } - addEventListener(t, cb) { - (this.__l[t] ||= []).push(cb); - } - removeEventListener(t, cb) { - this.__l[t] = (this.__l[t] || []).filter((f) => f !== cb); - } - dispatchEvent(e) { - for (const cb of this.__l[e && e.type] || []) { - try { - cb(e); - } catch { - } - } - return true; - } - }; - } - if (typeof globalThis.Event !== "function") { - globalThis.Event = class Event { - constructor(type, init = {}) { - this.type = type; - this.bubbles = !!init.bubbles; - this.defaultPrevented = false; - } - preventDefault() { - this.defaultPrevented = true; - } - stopPropagation() { - } - stopImmediatePropagation() { - } - }; - } - if (typeof globalThis.CustomEvent !== "function") { - globalThis.CustomEvent = class CustomEvent extends globalThis.Event { - constructor(type, init = {}) { - super(type, init); - this.detail = init.detail; - } - }; - } - if (typeof globalThis.MessagePort !== "function") { - globalThis.MessagePort = class MessagePort extends globalThis.EventTarget { - postMessage() { - } - start() { - } - close() { - } - on() { - return this; - } - once() { - return this; - } - ref() { - return this; - } - unref() { - return this; - } - }; - } - if (typeof globalThis.MessageChannel !== "function") { - globalThis.MessageChannel = class MessageChannel { - constructor() { - this.port1 = new globalThis.MessagePort(); - this.port2 = new globalThis.MessagePort(); - } - }; - } - if (typeof globalThis.DOMException !== "function") { - globalThis.DOMException = class DOMException extends Error { - constructor(message, name) { - super(message); - this.name = name || "Error"; - } - }; - } - if (typeof globalThis.TextEncoder !== "function") { - globalThis.TextEncoder = class TextEncoder { - get encoding() { - return "utf-8"; - } - encode(str) { - str = String(str); - const out = []; - for (let i = 0; i < str.length; i++) { - let c = str.charCodeAt(i); - if (c < 128) out.push(c); - else if (c < 2048) out.push(192 | c >> 6, 128 | c & 63); - else if (c >= 55296 && c <= 56319) { - const c2 = str.charCodeAt(++i); - c = 65536 + ((c & 1023) << 10) + (c2 & 1023); - out.push(240 | c >> 18, 128 | c >> 12 & 63, 128 | c >> 6 & 63, 128 | c & 63); - } else out.push(224 | c >> 12, 128 | c >> 6 & 63, 128 | c & 63); - } - return new Uint8Array(out); - } - }; - } - if (typeof globalThis.TextDecoder !== "function") { - globalThis.TextDecoder = class TextDecoder { - constructor(label) { - this._enc = label || "utf-8"; - } - get encoding() { - return "utf-8"; - } - decode(input) { - if (!input) return ""; - const bytes = input instanceof Uint8Array ? input : new Uint8Array(input.buffer || input); - let out = "", i = 0; - while (i < bytes.length) { - let c = bytes[i++]; - if (c < 128) out += String.fromCharCode(c); - else if (c >= 192 && c < 224) out += String.fromCharCode((c & 31) << 6 | bytes[i++] & 63); - else if (c >= 224 && c < 240) out += String.fromCharCode((c & 15) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63); - else { - const cp = (c & 7) << 18 | (bytes[i++] & 63) << 12 | (bytes[i++] & 63) << 6 | bytes[i++] & 63; - const off = cp - 65536; - out += String.fromCharCode(55296 + (off >> 10), 56320 + (off & 1023)); - } - } - return out; - } - }; - } - if (typeof globalThis.btoa !== "function") { - globalThis.btoa = function(bin) { - let out = ""; - for (let i = 0; i < bin.length; i += 3) { - const a = bin.charCodeAt(i), b = bin.charCodeAt(i + 1), c = bin.charCodeAt(i + 2); - const n = a << 16 | (isNaN(b) ? 0 : b) << 8 | (isNaN(c) ? 0 : c); - out += B64[n >> 18 & 63] + B64[n >> 12 & 63] + (isNaN(b) ? "=" : B64[n >> 6 & 63]) + (isNaN(c) ? "=" : B64[n & 63]); - } - return out; - }; - } - if (typeof globalThis.atob !== "function") { - globalThis.atob = function(b64) { - b64 = String(b64).replace(/[^A-Za-z0-9+/]/g, ""); - let out = ""; - for (let i = 0; i < b64.length; i += 4) { - const n = B64.indexOf(b64[i]) << 18 | B64.indexOf(b64[i + 1]) << 12 | B64.indexOf(b64[i + 2] || "A") << 6 | B64.indexOf(b64[i + 3] || "A"); - out += String.fromCharCode(n >> 16 & 255); - if (b64[i + 2] && b64[i + 2] !== "=") out += String.fromCharCode(n >> 8 & 255); - if (b64[i + 3] && b64[i + 3] !== "=") out += String.fromCharCode(n & 255); - } - return out; - }; - } - function b64ToBytes(b64) { - const bin = globalThis.atob(b64); - const u = new Uint8Array(bin.length); - for (let i = 0; i < bin.length; i++) u[i] = bin.charCodeAt(i); - return u; - } - if (typeof globalThis.crypto !== "object" || !globalThis.crypto) globalThis.crypto = {}; - if (typeof globalThis.crypto.getRandomValues !== "function") { - globalThis.crypto.getRandomValues = function(arr) { - for (let i = 0; i < arr.length; i++) arr[i] = Math.floor(Math.random() * 256); - return arr; - }; - } - if (typeof globalThis.Headers !== "function") { - globalThis.Headers = class Headers { - constructor(init) { - this._m = /* @__PURE__ */ new Map(); - if (init) { - const entries = init instanceof Headers ? init.entries() : Array.isArray(init) ? init : Object.entries(init); - for (const [k, v] of entries) this.set(k, v); - } - } - set(k, v) { - this._m.set(String(k).toLowerCase(), String(v)); - } - append(k, v) { - const p = this._m.get(String(k).toLowerCase()); - this.set(k, p ? p + ", " + v : v); - } - get(k) { - const v = this._m.get(String(k).toLowerCase()); - return v === void 0 ? null : v; - } - has(k) { - return this._m.has(String(k).toLowerCase()); - } - delete(k) { - this._m.delete(String(k).toLowerCase()); - } - forEach(fn) { - this._m.forEach((v, k) => fn(v, k, this)); - } - entries() { - return this._m.entries(); - } - keys() { - return this._m.keys(); - } - values() { - return this._m.values(); - } - [Symbol.iterator]() { - return this._m.entries(); - } - }; - } - if (typeof globalThis.URLSearchParams !== "function") { - globalThis.URLSearchParams = class URLSearchParams { - constructor(init) { - this._p = []; - if (typeof init === "string") { - for (const pair of init.replace(/^\?/, "").split("&")) { - if (!pair) continue; - const i = pair.indexOf("="); - this._p.push(i < 0 ? [decodeURIComponent(pair), ""] : [decodeURIComponent(pair.slice(0, i)), decodeURIComponent(pair.slice(i + 1))]); - } - } else if (init) for (const [k, v] of Object.entries(init)) this._p.push([k, String(v)]); - } - get(k) { - const e = this._p.find((x) => x[0] === k); - return e ? e[1] : null; - } - set(k, v) { - const e = this._p.find((x) => x[0] === k); - if (e) e[1] = String(v); - else this._p.push([k, String(v)]); - } - append(k, v) { - this._p.push([k, String(v)]); - } - has(k) { - return this._p.some((x) => x[0] === k); - } - delete(k) { - this._p = this._p.filter((x) => x[0] !== k); - } - forEach(fn) { - for (const [k, v] of this._p) fn(v, k, this); - } - toString() { - return this._p.map(([k, v]) => encodeURIComponent(k) + "=" + encodeURIComponent(v)).join("&"); - } - [Symbol.iterator]() { - return this._p[Symbol.iterator](); - } - }; - } - if (typeof globalThis.URL !== "function") { - let originOf = function(u) { - const m = /^([a-zA-Z]+:\/\/[^/?#]*)/.exec(u); - return m ? m[1] : u; - }; - globalThis.URL = class URL { - constructor(url, base) { - let full = String(url); - if (base && !/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(full)) { - const b = String(base).replace(/\/+$/, ""); - full = full.startsWith("/") ? originOf(b) + full : b + "/" + full; - } - const m = /^([a-zA-Z][a-zA-Z0-9+.-]*:)\/\/([^/?#]*)([^?#]*)(\?[^#]*)?(#.*)?$/.exec(full); - if (!m) throw new TypeError("Invalid URL: " + full); - this.protocol = m[1]; - this.host = m[2]; - this.hostname = m[2].split(":")[0]; - this.port = m[2].split(":")[1] || ""; - this.pathname = m[3] || "/"; - this.search = m[4] || ""; - this.hash = m[5] || ""; - this.searchParams = new globalThis.URLSearchParams(this.search); - this.origin = this.protocol + "//" + this.host; - } - get href() { - return this.origin + this.pathname + (this.searchParams.toString() ? "?" + this.searchParams.toString() : "") + this.hash; - } - toString() { - return this.href; - } - }; - } - class PPReadableStream { - constructor() { - this._queue = []; - this._closed = false; - this._error = null; - this._waiters = []; - } - _enqueue(chunk) { - this._queue.push(chunk); - this._flush(); - } - _close() { - this._closed = true; - this._flush(); - } - _fail(e) { - this._error = e; - this._flush(); - } - _flush() { - while (this._waiters.length) { - if (this._queue.length) this._waiters.shift().resolve({ value: this._queue.shift(), done: false }); - else if (this._error) this._waiters.shift().reject(this._error); - else if (this._closed) this._waiters.shift().resolve({ value: void 0, done: true }); - else break; - } - } - getReader() { - const self = this; - return { - read() { - return new Promise((resolve, reject) => { - self._waiters.push({ resolve, reject }); - self._flush(); - }); - }, - releaseLock() { - }, - cancel() { - self._closed = true; - return Promise.resolve(); - } - }; - } - [Symbol.asyncIterator]() { - const reader = this.getReader(); - return { next: () => reader.read(), return: () => { - reader.cancel(); - return Promise.resolve({ done: true }); - }, [Symbol.asyncIterator]() { - return this; - } }; - } - } - globalThis.ReadableStream = globalThis.ReadableStream || PPReadableStream; - class Response { - constructor(body, init) { - init = init || {}; - this.status = init.status ?? 200; - this.statusText = init.statusText ?? ""; - this.ok = this.status >= 200 && this.status < 300; - this.headers = init.headers instanceof globalThis.Headers ? init.headers : new globalThis.Headers(init.headers || {}); - this.url = init.url || ""; - this.body = body || null; - this._bodyUsed = false; - } - get bodyUsed() { - return this._bodyUsed; - } - async _consume() { - this._bodyUsed = true; - if (!this.body) return new Uint8Array(0); - if (this.body instanceof Uint8Array) return this.body; - const reader = this.body.getReader(); - const parts = []; - let total = 0; - for (; ; ) { - const { value, done } = await reader.read(); - if (done) break; - parts.push(value); - total += value.length; - } - const out = new Uint8Array(total); - let off = 0; - for (const p of parts) { - out.set(p, off); - off += p.length; - } - return out; - } - async arrayBuffer() { - return (await this._consume()).buffer; - } - async text() { - return new TextDecoder().decode(await this._consume()); - } - async json() { - return JSON.parse(await this.text()); - } - clone() { - return new Response(this.body, { status: this.status, statusText: this.statusText, headers: this.headers, url: this.url }); - } - } - globalThis.Response = globalThis.Response || Response; - const fetchTurns = /* @__PURE__ */ new Map(); - globalThis.fetch = function(input, init) { - init = init || {}; - const url = typeof input === "string" ? input : input.url; - const headers = {}; - if (init.headers) { - const h = init.headers instanceof globalThis.Headers ? init.headers.entries() : Array.isArray(init.headers) ? init.headers : Object.entries(init.headers); - for (const [k, v] of h) headers[k] = String(v); - } - let body = init.body; - if (body && typeof body !== "string") { - if (body instanceof Uint8Array) body = new TextDecoder().decode(body); - else body = String(body); - } - const request = { url, method: init.method || "GET", headers, body, raw: true }; - return new Promise((resolve, reject) => { - let turnId; - try { - turnId = host.http.start(JSON.stringify(request)); - } catch (e) { - reject(new Error(String(e && e.message ? e.message : e))); - return; - } - const turn = { resolve, reject, stream: null, resolved: false, url }; - fetchTurns.set(turnId, turn); - if (init.signal) { - init.signal.addEventListener("abort", () => { - try { - host.http.cancel(turnId); - } catch { - } - if (!turn.resolved) reject(new Error("aborted")); - else if (turn.stream) turn.stream._fail(new Error("aborted")); - fetchTurns.delete(turnId); - }); - } - }); - }; - globalThis.__catpiFetchPump = function() { - if (fetchTurns.size === 0) return; - for (const [turnId, turn] of fetchTurns) { - let out; - try { - out = JSON.parse(host.http.drain(turnId)); - } catch (e) { - if (!turn.resolved) turn.reject(new Error(String(e))); - else if (turn.stream) turn.stream._fail(new Error(String(e))); - fetchTurns.delete(turnId); - continue; - } - for (const line of out.lines) { - let msg; - try { - msg = JSON.parse(line); - } catch { - continue; - } - if (msg.__meta) { - turn.stream = new PPReadableStream(); - const resp = new Response(turn.stream, { - status: msg.__meta.status, - statusText: msg.__meta.statusText, - headers: msg.__meta.headers, - url: turn.url - }); - turn.resolved = true; - turn.resolve(resp); - } else if (msg.__chunk != null && turn.stream) { - turn.stream._enqueue(b64ToBytes(msg.__chunk)); - } - } - if (out.error) { - if (!turn.resolved) turn.reject(new Error(out.error)); - else if (turn.stream) turn.stream._fail(new Error(out.error)); - fetchTurns.delete(turnId); - } else if (out.done) { - if (turn.stream) turn.stream._close(); - else if (!turn.resolved) turn.reject(new Error("no response")); - fetchTurns.delete(turnId); - } - } - }; -})(); diff --git a/crates/pocket-pi/src/http.rs b/crates/pocket-pi/src/http.rs deleted file mode 100644 index a863992..0000000 --- a/crates/pocket-pi/src/http.rs +++ /dev/null @@ -1,365 +0,0 @@ -//! The native HTTP bridge for Pocket Pi. -//! -//! QuickJS is single-threaded and can't do blocking TLS, so each streaming -//! request runs on its own OS thread. The thread reads the Anthropic SSE body -//! line by line and pushes each decoded `data:` JSON into a per-turn mailbox. -//! The JS side never sees bytes — only complete event payloads it drains once -//! per host frame. This is the PocketJS `svc` mailbox pattern applied to LLM -//! streaming: the frame scheduler is the pump that moves the agent forward. - -use std::collections::{HashMap, VecDeque}; -use std::io::Read; -use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; -use std::sync::{Arc, Mutex}; - -#[derive(Default)] -struct Turn { - lines: VecDeque, - done: bool, - error: Option, - cancel: Arc, -} - -#[derive(Default)] -struct Inner { - turns: HashMap, -} - -/// Shared, thread-safe registry of in-flight requests. -#[derive(Clone, Default)] -pub struct HttpHub { - inner: Arc>, - next_id: Arc, -} - -/// What the JS side sees each time it drains a turn. -struct Drained { - lines: Vec, - done: bool, - error: Option, -} - -impl HttpHub { - pub fn new() -> Self { - HttpHub { - inner: Arc::new(Mutex::new(Inner::default())), - next_id: Arc::new(AtomicU64::new(1)), - } - } - - /// Begin a request. Two shapes share this path: - /// - provider streaming: `{url, apiKey, auth, body}` → POST, SSE `data:` lines. - /// - WHATWG fetch: `{url, method, headers, body, raw:true}` → a meta line then - /// base64 body chunks (backing `Response`/`ReadableStream`). - pub fn start(&self, request_json: &str) -> Result { - let v: serde_json::Value = - serde_json::from_str(request_json).map_err(|e| format!("bad request json: {e}"))?; - let url = v - .get("url") - .and_then(|x| x.as_str()) - .ok_or("missing url")? - .to_string(); - let raw = v.get("raw").and_then(|x| x.as_bool()).unwrap_or(false); - let method = v - .get("method") - .and_then(|x| x.as_str()) - .map(|s| s.to_uppercase()) - .unwrap_or_else(|| "POST".into()); - let api_key = v - .get("apiKey") - .and_then(|x| x.as_str()) - .unwrap_or("") - .to_string(); - let auth = v - .get("auth") - .and_then(|x| x.as_str()) - .unwrap_or("x-api-key") - .to_string(); - // Body: fetch passes a string; providers pass a JSON object to serialize. - let body = match v.get("body") { - Some(serde_json::Value::String(s)) => Some(s.clone()), - Some(other) if !other.is_null() => Some(other.to_string()), - _ => None, - }; - let mut headers: Vec<(String, String)> = Vec::new(); - if let Some(serde_json::Value::Object(h)) = v.get("headers") { - for (k, val) in h { - if let Some(s) = val.as_str() { - headers.push((k.clone(), s.to_string())); - } - } - } - let req = Req { - url, - method, - headers, - body, - api_key, - auth, - raw, - }; - - let id = self.next_id.fetch_add(1, Ordering::SeqCst); - let cancel = Arc::new(AtomicBool::new(false)); - { - let mut inner = self.inner.lock().unwrap(); - inner.turns.insert( - id, - Turn { - cancel: cancel.clone(), - ..Default::default() - }, - ); - } - let hub = self.inner.clone(); - std::thread::Builder::new() - .name(format!("pocket-pi-http-{id}")) - .spawn(move || run_request(hub, id, req, cancel)) - .map_err(|e| format!("spawn failed: {e}"))?; - Ok(id) - } - - /// Take everything the turn has accumulated so far. Returns a JSON string - /// `{lines:[...], done, error}` (the JS side JSON.parses it). - pub fn drain(&self, id: u64) -> String { - let mut inner = self.inner.lock().unwrap(); - let out = match inner.turns.get_mut(&id) { - Some(turn) => Drained { - lines: turn.lines.drain(..).collect(), - done: turn.done, - error: turn.error.clone(), - }, - None => Drained { - lines: Vec::new(), - done: true, - error: Some("unknown turn".into()), - }, - }; - // Once terminal and drained, forget the turn. - if out.done { - if let Some(turn) = inner.turns.get(&id) { - if turn.lines.is_empty() { - inner.turns.remove(&id); - } - } - } - serde_json::json!({ - "lines": out.lines, - "done": out.done, - "error": out.error, - }) - .to_string() - } - - pub fn cancel(&self, id: u64) { - let inner = self.inner.lock().unwrap(); - if let Some(turn) = inner.turns.get(&id) { - turn.cancel.store(true, Ordering::SeqCst); - } - } -} - -fn push_line(hub: &Arc>, id: u64, line: String) { - if let Some(turn) = hub.lock().unwrap().turns.get_mut(&id) { - turn.lines.push_back(line); - } -} - -fn finish(hub: &Arc>, id: u64, error: Option) { - if let Some(turn) = hub.lock().unwrap().turns.get_mut(&id) { - turn.done = true; - if error.is_some() { - turn.error = error; - } - } -} - -struct Req { - url: String, - method: String, - headers: Vec<(String, String)>, - body: Option, - api_key: String, - auth: String, - raw: bool, -} - -fn run_request(hub: Arc>, id: u64, req: Req, cancel: Arc) { - let mut builder = ureq::AgentBuilder::new().timeout_connect(std::time::Duration::from_secs(20)); - // Respect a system proxy (Clash/mihomo, corporate egress, …) like curl does. - if let Some(proxy_url) = std::env::var("HTTPS_PROXY") - .or_else(|_| std::env::var("https_proxy")) - .or_else(|_| std::env::var("ALL_PROXY")) - .or_else(|_| std::env::var("all_proxy")) - .ok() - .filter(|s| !s.is_empty()) - { - if let Ok(proxy) = ureq::Proxy::new(&proxy_url) { - builder = builder.proxy(proxy); - } - } - let agent = builder.build(); - - let mut r = agent.request(&req.method, &req.url); - let has_ct = req - .headers - .iter() - .any(|(k, _)| k.eq_ignore_ascii_case("content-type")); - if req.body.is_some() && !has_ct { - r = r.set("content-type", "application/json"); - } - for (k, v) in &req.headers { - r = r.set(k, v); - } - // Provider auth convenience (skipped for a plain fetch that sets its own). - if !req.api_key.is_empty() { - if req.auth == "bearer" { - r = r.set("authorization", &format!("Bearer {}", req.api_key)); - } else if req.api_key.starts_with("sk-ant-oat") { - r = r - .set("anthropic-version", "2023-06-01") - .set("authorization", &format!("Bearer {}", req.api_key)) - .set("anthropic-beta", "oauth-2025-04-20"); - } else { - r = r - .set("anthropic-version", "2023-06-01") - .set("x-api-key", &req.api_key); - } - } - - let send = match &req.body { - Some(b) => r.send_string(b), - None => r.call(), - }; - let resp = match send { - Ok(r) => r, - // For raw fetch we forward non-2xx as a real Response (fetch doesn't - // throw on 4xx/5xx); for SSE providers, surface it as an error. - Err(ureq::Error::Status(code, r)) if req.raw => r_or_status(r, code), - Err(ureq::Error::Status(code, r)) => { - let msg = r - .into_string() - .unwrap_or_else(|_| String::from("(no body)")); - finish( - &hub, - id, - Some(format!("http {code}: {}", truncate(&msg, 400))), - ); - return; - } - Err(e) => { - finish(&hub, id, Some(format!("request error: {e}"))); - return; - } - }; - - if req.raw { - // Deliver a meta line (status/headers) then base64 body chunks. - let mut headers = serde_json::Map::new(); - for name in resp.headers_names() { - if let Some(val) = resp.header(&name) { - headers.insert( - name.to_lowercase(), - serde_json::Value::String(val.to_string()), - ); - } - } - let meta = serde_json::json!({ "__meta": { - "status": resp.status(), "statusText": resp.status_text(), "headers": headers, - }}); - push_line(&hub, id, meta.to_string()); - let mut reader = resp.into_reader(); - let mut chunk = [0u8; 8192]; - loop { - if cancel.load(Ordering::SeqCst) { - finish(&hub, id, Some("aborted".into())); - return; - } - match reader.read(&mut chunk) { - Ok(0) => break, - Ok(n) => { - let msg = serde_json::json!({ "__chunk": base64_encode(&chunk[..n]) }); - push_line(&hub, id, msg.to_string()); - } - Err(e) => { - finish(&hub, id, Some(format!("read error: {e}"))); - return; - } - } - } - finish(&hub, id, None); - return; - } - - // SSE mode: forward `data:` payloads line by line. - let mut reader = resp.into_reader(); - let mut buf: Vec = Vec::with_capacity(8192); - let mut chunk = [0u8; 4096]; - loop { - if cancel.load(Ordering::SeqCst) { - finish(&hub, id, Some("aborted".into())); - return; - } - let n = match reader.read(&mut chunk) { - Ok(0) => break, - Ok(n) => n, - Err(e) => { - finish(&hub, id, Some(format!("read error: {e}"))); - return; - } - }; - buf.extend_from_slice(&chunk[..n]); - while let Some(pos) = buf.iter().position(|&b| b == b'\n') { - let line: Vec = buf.drain(..=pos).collect(); - let line = String::from_utf8_lossy(&line); - let line = line.trim_end_matches(['\r', '\n']); - if let Some(rest) = line.strip_prefix("data:") { - let payload = rest.trim(); - if payload.is_empty() || payload == "[DONE]" { - continue; - } - if std::env::var("POCKET_PI_DEBUG_SSE").is_ok() { - eprintln!("SSE< {}", &payload[..payload.len().min(300)]); - } - push_line(&hub, id, payload.to_string()); - } - } - } - finish(&hub, id, None); -} - -/// ureq consumes the Response in the Status error; return it unchanged for the -/// raw path (fetch surfaces non-2xx as a normal Response). -fn r_or_status(resp: ureq::Response, _code: u16) -> ureq::Response { - resp -} - -fn base64_encode(bytes: &[u8]) -> String { - const A: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - let mut out = String::with_capacity(bytes.len().div_ceil(3) * 4); - for c in bytes.chunks(3) { - let b = [c[0], *c.get(1).unwrap_or(&0), *c.get(2).unwrap_or(&0)]; - let n = ((b[0] as u32) << 16) | ((b[1] as u32) << 8) | b[2] as u32; - out.push(A[(n >> 18 & 63) as usize] as char); - out.push(A[(n >> 12 & 63) as usize] as char); - out.push(if c.len() > 1 { - A[(n >> 6 & 63) as usize] as char - } else { - '=' - }); - out.push(if c.len() > 2 { - A[(n & 63) as usize] as char - } else { - '=' - }); - } - out -} - -fn truncate(s: &str, max: usize) -> String { - if s.len() <= max { - s.to_string() - } else { - format!("{}…", &s[..max]) - } -} diff --git a/crates/pocket-pi/src/lib.rs b/crates/pocket-pi/src/lib.rs deleted file mode 100644 index 67fad4e..0000000 --- a/crates/pocket-pi/src/lib.rs +++ /dev/null @@ -1,536 +0,0 @@ -//! # Pocket Pi -//! -//! A QuickJS runtime that runs the **whole, unmodified `pi-coding-agent`** — the -//! real agent, sessions, extensions, and tool suite — with **no Node and no -//! bun**, on a PocketJS-style **coalesced frame scheduler**. The full pi bundle -//! is embedded in the crate, so [`PiRuntime::new`] stands it up self-contained. -//! -//! The agent loop, LLM streaming, and message state are pi's own JS, evaluated in -//! one QuickJS realm. Everything Node-ish is provided natively: HTTPS + SSE -//! streaming runs on background threads and lands in a per-turn mailbox -//! ([`http`]), and the realm is driven one **frame** at a time. Native -//! capabilities (a host's own tools, like a screenshot grabber) bridge into pi as -//! tools via [`PiRuntime::register_tool`]. -//! -//! ## Why a frame scheduler for an agent -//! -//! [`PiRuntime::pump`] is one frame: deliver any streamed LLM events, fire due -//! timers, then drain the QuickJS microtask/job queue so the agent loop advances. -//! Because LLM latency (seconds) dwarfs a frame period, the host can pump as -//! slowly as **2 Hz** when idle and lose nothing — the whole runtime coalesces -//! to near-zero CPU between token bursts. That is the PocketJS "demand-render" -//! idea applied to an agent: do work only when there is work. -//! -//! ```no_run -//! use pocket_pi::{PiRuntime, HostEvent}; -//! let mut rt = PiRuntime::new().unwrap(); -//! rt.on_event(|ev: &HostEvent| println!("{}: {}", ev.kind, ev.raw)); -//! rt.boot(r#"{"model":"claude-opus-4-8","apiKey":"...","systemPrompt":"Be terse."}"#).unwrap(); -//! rt.prompt("Say hi in three words.").unwrap(); -//! for _ in 0..600 { rt.pump().unwrap(); if rt.is_idle() { break } std::thread::sleep(std::time::Duration::from_millis(50)); } -//! ``` - -mod http; -mod node; -mod transpile; - -use rquickjs::{CatchResultExt, Context, Ctx, Function, Object, Runtime}; -use std::cell::RefCell; -use std::collections::HashMap; -use std::rc::Rc; - -pub use http::HttpHub; - -const PRELUDE: &str = include_str!("../js/prelude.js"); -const WEB_GLOBALS: &str = include_str!("../js/web-globals.js"); - -/// The full, unmodified pi-coding-agent — the whole agent, sessions, extensions, -/// tools — bundled to one ES module and embedded gzip'd. This IS the runtime: -/// every `PiRuntime` loads it. Committed (~1.8 MB gz) so the crate builds with -/// only Rust, no Node. -const FULL_PI_GZ: &[u8] = include_bytes!("../js/pi-full.bundle.js.gz"); - -/// The host harness: reimplements the `PocketPi.boot/prompt` API on top of the -/// full pi bundle (native tools via `host.tool`, events via `host.emit`). -const HOST_HARNESS: &str = include_str!("../js/pi-full/host.js"); - -/// The embedded full-pi bundle source, decompressed. Lets a host ship one -/// self-contained binary — the whole unmodified pi is inside the executable. -pub fn embedded_full_pi_bundle() -> String { - use std::io::Read; - let mut d = flate2::read::GzDecoder::new(FULL_PI_GZ); - let mut s = String::new(); - d.read_to_string(&mut s) - .expect("gunzip embedded full-pi bundle"); - s -} - -/// One event surfaced from the agent to the host, already decoded from the -/// guest's compact JSON vocabulary (`start`, `text`, `thinking`, -/// `assistant_text`, `tool_start`, `tool_end`, `end`, `error`, `booted`). -#[derive(Debug, Clone)] -pub struct HostEvent { - pub kind: String, - pub raw: String, - pub value: serde_json::Value, -} - -/// What a host tool returns. Text is fed back to the model; an image (base64) -/// becomes an image tool-result block — this is how the cat's "look at the -/// screen" tool hands a screenshot to the agent. -#[derive(Debug, Clone, Default)] -pub struct ToolResult { - pub text: Option, - pub image_base64: Option, - pub mime_type: Option, - pub terminate: bool, -} - -impl ToolResult { - pub fn text(s: impl Into) -> Self { - ToolResult { - text: Some(s.into()), - ..Default::default() - } - } - fn to_json(&self) -> serde_json::Value { - let mut o = serde_json::Map::new(); - if let Some(t) = &self.text { - o.insert("text".into(), serde_json::Value::String(t.clone())); - } - if let Some(img) = &self.image_base64 { - o.insert("image".into(), serde_json::Value::String(img.clone())); - o.insert( - "mimeType".into(), - serde_json::Value::String( - self.mime_type - .clone() - .unwrap_or_else(|| "image/jpeg".into()), - ), - ); - } - o.insert("terminate".into(), serde_json::Value::Bool(self.terminate)); - serde_json::Value::Object(o) - } -} - -type ToolFn = Box ToolResult>; -/// Optional host callback for agent events, shared with the realm's closures. -type EventSink = Rc>>>; - -struct HostState { - tools: HashMap, - emitted: Vec, -} - -/// The runtime. Not `Send` — it owns a QuickJS realm and must be driven from a -/// single thread. Cross-thread work (HTTP) lives behind the [`HttpHub`]. -pub struct PiRuntime { - rt: Runtime, - ctx: Context, - state: Rc>, - on_event: EventSink, - active: Rc>, -} - -impl PiRuntime { - /// Build a realm, install the prelude shims and the `host` native namespace, - /// then evaluate the bundled pi agent core. - pub fn new() -> Result { - let rt = Runtime::new().map_err(|e| e.to_string())?; - let ctx = Context::full(&rt).map_err(|e| e.to_string())?; - - // Node-flavored module resolution + loading (relative, node_modules, - // node: builtins, on-the-fly TS transpile). - rt.set_loader(node::NodeResolver, node::NodeLoader); - - let state = Rc::new(RefCell::new(HostState { - tools: HashMap::new(), - emitted: Vec::new(), - })); - let on_event: EventSink = Rc::new(RefCell::new(None)); - let active = Rc::new(RefCell::new(false)); - let hub = HttpHub::new(); - - ctx.with(|ctx| -> Result<(), String> { - install_console(&ctx).map_err(|e| e.to_string())?; - install_host(&ctx, &state, &hub).map_err(|e| e.to_string())?; - Ok(()) - })?; - - // Prelude first (defines globals the bundle relies on), then the full pi. - let full_pi = embedded_full_pi_bundle(); - ctx.with(|ctx| -> Result<(), String> { - ctx.eval::<(), _>(PRELUDE.as_bytes()) - .catch(&ctx) - .map_err(|e| format!("prelude eval: {e}"))?; - // Node globals (process, Buffer, __node fs ops) before the bundle. - node::install_node(&ctx) - .catch(&ctx) - .map_err(|e| format!("install_node: {e}"))?; - // Web globals (fetch/Response/ReadableStream/Headers/URL/…). - ctx.eval::<(), _>(WEB_GLOBALS.as_bytes()) - .catch(&ctx) - .map_err(|e| format!("web-globals eval: {e}"))?; - // The full, unmodified pi-coding-agent (one ES module → globalThis.PiFull). - // Declare + set import.meta.url before evaluating, since this in-memory - // module bypasses the loader that normally sets it (pi derives __dirname - // from import.meta.url). - let declared = rquickjs::module::Module::declare( - ctx.clone(), - "pocket-pi:pi-full", - full_pi.as_bytes(), - ) - .catch(&ctx) - .map_err(|e| format!("pi-full declare: {e}"))?; - if let Ok(meta) = declared.meta() { - let _ = meta.set("url", "file:///pocket-pi/js/pi-full.bundle.js"); - } - let (_evaluated, promise) = declared - .eval() - .catch(&ctx) - .map_err(|e| format!("pi-full eval start: {e}"))?; - promise - .finish::<()>() - .catch(&ctx) - .map_err(|e| format!("pi-full eval: {e}"))?; - // Host harness: PocketPi.boot/prompt on top of pi (native tools + events). - ctx.eval::<(), _>(HOST_HARNESS.as_bytes()) - .catch(&ctx) - .map_err(|e| format!("host harness eval: {e}"))?; - Ok(()) - })?; - - let mut this = PiRuntime { - rt, - ctx, - state, - on_event, - active, - }; - this.drain_jobs(); - this.flush_events(); - Ok(this) - } - - /// Register the host-side callback for agent events. - pub fn on_event(&mut self, cb: impl FnMut(&HostEvent) + 'static) { - *self.on_event.borrow_mut() = Some(Box::new(cb)); - } - - /// Register a native tool the agent can call. `run` executes synchronously - /// during a pump; keep it fast (or stash work and answer on a later turn). - pub fn register_tool( - &mut self, - name: impl Into, - run: impl FnMut(serde_json::Value) -> ToolResult + 'static, - ) { - self.state - .borrow_mut() - .tools - .insert(name.into(), Box::new(run)); - } - - /// Stand up a pi session from a JSON config: `provider`, `model`, `apiKey`, - /// `systemPrompt`, `maxTokens`, and `tools:[{name,description,parameters}]` - /// (each `tool` bridges to a native closure registered via - /// [`register_tool`](Self::register_tool)). Blocks until the session is ready. - pub fn boot(&mut self, config_json: &str) -> Result<(), String> { - let cfg = config_json.to_string(); - self.ctx.with(|ctx| -> Result<(), String> { - let pp: Object = ctx - .globals() - .get("PocketPi") - .map_err(|e| format!("PocketPi missing: {e}"))?; - let boot: Function = pp.get("boot").map_err(|e| e.to_string())?; - boot.call::<_, ()>((cfg,)) - .catch(&ctx) - .map_err(|e| format!("boot: {e}"))?; - Ok(()) - })?; - // The harness stands up the pi session asynchronously (createAgentSession); - // drive the job queue until it signals ready. It's offline, so this settles - // in a few frames. - for _ in 0..500 { - self.pump()?; - if self.get_global_json("__ppBooted") == Some(serde_json::Value::Bool(true)) { - break; - } - } - Ok(()) - } - - /// Send a user prompt. Returns immediately; results arrive as events across - /// subsequent [`pump`](Self::pump) calls. - pub fn prompt(&mut self, text: &str) -> Result<(), String> { - *self.active.borrow_mut() = true; - let text = text.to_string(); - self.ctx.with(|ctx| -> Result<(), String> { - let pp: Object = ctx.globals().get("PocketPi").map_err(|e| e.to_string())?; - let f: Function = pp.get("prompt").map_err(|e| e.to_string())?; - f.call::<_, ()>((text,)) - .catch(&ctx) - .map_err(|e| format!("prompt: {e}"))?; - Ok(()) - })?; - self.pump() - } - - /// Import and evaluate an ES module by specifier (absolute path, or a - /// `node:` builtin), driving the Node resolver/loader — relative imports, - /// `node_modules` packages, and `.ts` transpilation all work for the - /// unmodified pi-coding-agent. Returns after the module settles. - pub fn run_module(&mut self, specifier: &str) -> Result<(), String> { - let spec = specifier.to_string(); - self.ctx.with(|ctx| -> Result<(), String> { - let promise = rquickjs::module::Module::import(&ctx, spec) - .catch(&ctx) - .map_err(|e| format!("import: {e}"))?; - promise - .finish::() - .catch(&ctx) - .map_err(|e| format!("module eval: {e}"))?; - Ok(()) - })?; - self.drain_jobs(); - Ok(()) - } - - /// Evaluate a script in the realm (advanced/tests). - pub fn eval_script(&mut self, source: &str) -> Result<(), String> { - let src = source.to_string(); - self.ctx.with(|ctx| -> Result<(), String> { - ctx.eval::<(), _>(src.as_bytes()) - .catch(&ctx) - .map_err(|e| format!("eval: {e}"))?; - Ok(()) - })?; - self.drain_jobs(); - Ok(()) - } - - /// Read a global (JSON-serialized) — for tests/introspection. - pub fn get_global_json(&self, name: &str) -> Option { - self.ctx.with(|ctx| { - let v: rquickjs::Value = ctx.globals().get(name).ok()?; - let s = ctx.json_stringify(v).ok()??; - serde_json::from_str(&s.to_string().ok()?).ok() - }) - } - - /// Abort the in-flight turn, if any. - pub fn abort(&mut self) -> Result<(), String> { - self.ctx.with(|ctx| -> Result<(), String> { - let pp: Object = ctx.globals().get("PocketPi").map_err(|e| e.to_string())?; - let f: Function = pp.get("abort").map_err(|e| e.to_string())?; - f.call::<_, ()>(()).catch(&ctx).map_err(|e| e.to_string())?; - Ok(()) - }) - } - - /// One frame: fire due timers, deliver streamed LLM events, drain the job - /// queue so the agent loop advances, then flush host events to the callback. - pub fn pump(&mut self) -> Result<(), String> { - self.ctx.with(|ctx| -> Result<(), String> { - call_global_void(&ctx, "__catpiTimers")?; - call_global_void(&ctx, "__catpiPump")?; - call_global_void(&ctx, "__catpiFetchPump")?; - Ok(()) - })?; - self.drain_jobs(); - self.flush_events(); - Ok(()) - } - - /// True when no turn is in flight (the last `end`/`error` event has fired). - pub fn is_idle(&self) -> bool { - !*self.active.borrow() - } - - fn drain_jobs(&self) { - loop { - match self.rt.execute_pending_job() { - Ok(true) => continue, - Ok(false) => break, - Err(e) => { - log::warn!("pocket-pi: pending job threw: {e:?}"); - } - } - } - } - - fn flush_events(&mut self) { - let drained: Vec = { - let mut st = self.state.borrow_mut(); - if st.emitted.is_empty() { - return; - } - std::mem::take(&mut st.emitted) - }; - for raw in drained { - let value: serde_json::Value = - serde_json::from_str(&raw).unwrap_or(serde_json::Value::Null); - let kind = value - .get("kind") - .and_then(|v| v.as_str()) - .unwrap_or("") - .to_string(); - if kind == "end" || kind == "error" { - *self.active.borrow_mut() = false; - } - let ev = HostEvent { kind, raw, value }; - if let Some(cb) = self.on_event.borrow_mut().as_mut() { - cb(&ev); - } - } - } -} - -fn call_global_void(ctx: &Ctx, name: &str) -> Result<(), String> { - if let Ok(f) = ctx.globals().get::<_, Function>(name) { - f.call::<_, ()>(()).catch(ctx).map_err(|e| e.to_string())?; - } - Ok(()) -} - -/// Mount `globalThis.host` — the entire native capability surface the guest can -/// reach. Deliberately small: HTTP streaming, tool dispatch, event emit, uuid. -fn install_host(ctx: &Ctx, state: &Rc>, hub: &HttpHub) -> rquickjs::Result<()> { - let host = Object::new(ctx.clone())?; - - // host.http.{start,drain,cancel} - let http = Object::new(ctx.clone())?; - let h = hub.clone(); - http.set( - "start", - Function::new( - ctx.clone(), - move |ctx: Ctx, req: String| -> rquickjs::Result { - match h.start(&req) { - Ok(id) => Ok(id as f64), - Err(e) => Err(ctx.throw(rquickjs::String::from_str(ctx.clone(), &e)?.into())), - } - }, - )?, - )?; - let h = hub.clone(); - http.set( - "drain", - Function::new(ctx.clone(), move |id: f64| -> String { h.drain(id as u64) })?, - )?; - let h = hub.clone(); - http.set( - "cancel", - Function::new(ctx.clone(), move |id: f64| h.cancel(id as u64))?, - )?; - host.set("http", http)?; - - // host.tool(name, argsJson) -> resultJson (synchronous dispatch to Rust) - let st = state.clone(); - host.set( - "tool", - Function::new( - ctx.clone(), - move |name: String, args_json: String| -> String { - let args: serde_json::Value = - serde_json::from_str(&args_json).unwrap_or(serde_json::Value::Null); - let mut st = st.borrow_mut(); - let result = match st.tools.get_mut(&name) { - Some(f) => f(args), - None => ToolResult::text(format!("(no such tool: {name})")), - }; - result.to_json().to_string() - }, - )?, - )?; - - // host.emit(jsonLine) -> buffers an agent event for the host to flush - let st = state.clone(); - host.set( - "emit", - Function::new(ctx.clone(), move |line: String| { - st.borrow_mut().emitted.push(line); - })?, - )?; - - // host.uuid() -> string - host.set( - "uuid", - Function::new(ctx.clone(), move || -> String { simple_uuid() })?, - )?; - - // host.transpile(name, tsSource) -> jsSource (agent-authored TS plugins) - host.set( - "transpile", - Function::new( - ctx.clone(), - move |ctx: Ctx, name: String, source: String| -> rquickjs::Result { - transpile::transpile_ts(&name, &source).map_err(|e| { - ctx.throw(rquickjs::String::from_str(ctx.clone(), &e).unwrap().into()) - }) - }, - )?, - )?; - - ctx.globals().set("host", host)?; - Ok(()) -} - -fn simple_uuid() -> String { - // Not cryptographic; sufficient for tool-call ids in a PoC. Seeds from the - // system clock and address-space entropy so ids don't collide within a run. - use std::time::{SystemTime, UNIX_EPOCH}; - let nanos = SystemTime::now() - .duration_since(UNIX_EPOCH) - .map(|d| d.as_nanos()) - .unwrap_or(0); - let salt = &nanos as *const _ as usize; - let mut x = nanos ^ (salt as u128).wrapping_mul(0x9E3779B97F4A7C15); - let mut hex = String::with_capacity(36); - for i in 0..32 { - if i == 8 || i == 12 || i == 16 || i == 20 { - hex.push('-'); - } - x = x - .wrapping_mul(6364136223846793005) - .wrapping_add(1442695040888963407); - let nibble = ((x >> 64) & 0xF) as u8; - hex.push(char::from_digit(nibble as u32, 16).unwrap()); - } - hex -} - -/// `console.*` → the `log` crate, target "pocket-pi.guest". -fn install_console(ctx: &Ctx) -> rquickjs::Result<()> { - let console = Object::new(ctx.clone())?; - for level in ["log", "info", "debug", "warn", "error"] { - console.set( - level, - Function::new( - ctx.clone(), - move |args: rquickjs::function::Rest| { - let mut out = String::new(); - for (i, v) in args.iter().enumerate() { - if i > 0 { - out.push(' '); - } - if let Some(s) = v.as_string() { - out.push_str(&s.to_string().unwrap_or_default()); - } else if let Ok(s) = v.ctx().json_stringify(v.clone()) { - out.push_str( - &s.map(|s| s.to_string().unwrap_or_default()) - .unwrap_or_default(), - ); - } - } - log::info!(target: "pocket-pi.guest", "{out}"); - }, - )?, - )?; - } - ctx.globals().set("console", console)?; - Ok(()) -} - -#[cfg(test)] -mod tests; diff --git a/crates/pocket-pi/src/node/builtins.rs b/crates/pocket-pi/src/node/builtins.rs deleted file mode 100644 index c47d7c1..0000000 --- a/crates/pocket-pi/src/node/builtins.rs +++ /dev/null @@ -1,136 +0,0 @@ -//! The builtin-module registry — the **single source of truth** for the `node:*` -//! modules Pocket Pi ships. -//! -//! The resolver ([`super::resolve`]), the loader ([`super`]), and the synchronous -//! CommonJS `require` bridge all derive from this one list, so adding a builtin is -//! a single line in [`BUILTINS`]. In particular the `require` bridge's -//! `__builtinExports` map is **generated** from this list by -//! [`cjs_bootstrap_source`] — there is no second place to keep in sync (a unit -//! test enforces that invariant, which is exactly the failure mode this design -//! removes). - -/// A builtin module: its Node name (`fs`, `fs/promises`) and its embedded JS -/// source. `source` is compiled straight into the binary via `include_str!`, so -/// the runtime needs no filesystem to serve builtins. -pub struct Builtin { - pub name: &'static str, - pub source: &'static str, -} - -/// Register a builtin by Node name and `js/node/`. -macro_rules! builtin { - ($name:literal, $file:literal) => { - Builtin { - name: $name, - source: include_str!(concat!("../../js/node/", $file)), - } - }; -} - -/// Every builtin Pocket Pi ships. Add a row to expose a new `node:*` module — the -/// resolver, loader, and `require` bridge all pick it up automatically. -pub static BUILTINS: &[Builtin] = &[ - builtin!("path", "path.js"), - builtin!("os", "os.js"), - builtin!("events", "events.js"), - builtin!("util", "util.js"), - builtin!("buffer", "buffer.js"), - builtin!("process", "process.js"), - builtin!("fs", "fs.js"), - builtin!("fs/promises", "fs-promises.js"), - builtin!("child_process", "child_process.js"), - builtin!("crypto", "crypto.js"), - builtin!("url", "url.js"), - builtin!("module", "module.js"), - builtin!("stream", "stream.js"), - builtin!("stream/promises", "stream-promises.js"), - builtin!("string_decoder", "string_decoder.js"), - builtin!("readline", "readline.js"), - builtin!("perf_hooks", "perf_hooks.js"), - builtin!("tty", "tty.js"), - builtin!("http", "http.js"), - builtin!("https", "https.js"), - builtin!("net", "net.js"), - builtin!("tls", "tls.js"), - builtin!("zlib", "zlib.js"), - builtin!("dns", "dns.js"), - builtin!("querystring", "querystring.js"), - builtin!("assert", "assert.js"), - builtin!("timers", "timers.js"), - builtin!("worker_threads", "worker_threads.js"), - builtin!("v8", "v8.js"), - builtin!("vm", "vm.js"), - builtin!("constants", "constants.js"), - builtin!("async_hooks", "async_hooks.js"), - builtin!("diagnostics_channel", "diagnostics_channel.js"), - builtin!("console", "console.js"), -]; - -/// The static `require` implementation appended after the generated builtin map. -const CJS_RUNTIME: &str = include_str!("../../js/node/_cjs-runtime.js"); - -/// Source for a builtin by name (`node:` prefix optional). Tries the exact name -/// first — so `fs/promises` gets its own module — then the root segment, so a -/// subpath like `path/win32` falls back to the `path` module. -pub fn builtin_source(name: &str) -> Option<&'static str> { - let bare = name.strip_prefix("node:").unwrap_or(name); - if let Some(b) = BUILTINS.iter().find(|b| b.name == bare) { - return Some(b.source); - } - let root = bare.split('/').next().unwrap_or(bare); - BUILTINS.iter().find(|b| b.name == root).map(|b| b.source) -} - -/// Whether `name` names a builtin we can serve. -pub fn is_builtin(name: &str) -> bool { - builtin_source(name).is_some() -} - -/// Build the CJS bootstrap module: `import * as` every builtin's namespace, expose -/// them on `globalThis.__builtinExports`, then append the static `require` -/// implementation. Because the imports and the map are generated from [`BUILTINS`], -/// the registry is the only place the builtin list lives. -pub fn cjs_bootstrap_source() -> String { - let mut imports = String::new(); - let mut map = String::from( - "const __pick = (ns) => (ns && ns.default !== undefined ? ns.default : ns);\n\ - globalThis.__builtinExports = {\n", - ); - for (i, b) in BUILTINS.iter().enumerate() { - imports.push_str(&format!("import * as __b{i} from \"node:{}\";\n", b.name)); - map.push_str(&format!(" {:?}: __pick(__b{i}),\n", b.name)); - } - map.push_str("};\n"); - format!("{imports}{map}{CJS_RUNTIME}") -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn exact_and_root_lookup() { - assert!(builtin_source("fs/promises").is_some()); - assert!(builtin_source("node:fs/promises").is_some()); - assert!(builtin_source("path/win32").is_some()); // root fallback - assert!(builtin_source("nonexistent").is_none()); - } - - /// The single-source-of-truth invariant: the generated `require` bridge must - /// expose *every* builtin — this is the exact bug (a builtin registered but - /// missing from `__builtinExports`) that the generated map eliminates. - #[test] - fn bootstrap_covers_every_builtin() { - let src = cjs_bootstrap_source(); - for b in BUILTINS { - let key = format!("{:?}: __pick(", b.name); - assert!( - src.contains(&key), - "builtin {:?} missing from __builtinExports", - b.name - ); - } - // One import per builtin. - assert_eq!(src.matches("import * as __b").count(), BUILTINS.len()); - } -} diff --git a/crates/pocket-pi/src/node/mod.rs b/crates/pocket-pi/src/node/mod.rs deleted file mode 100644 index 7fa07ae..0000000 --- a/crates/pocket-pi/src/node/mod.rs +++ /dev/null @@ -1,86 +0,0 @@ -//! A minimal Node/CommonJS-flavored **module system + builtins** for QuickJS — -//! the layer that lets unmodified npm packages (ultimately `pi-coding-agent`) -//! `import`/`require` and run with no Node and no bun. -//! -//! The design is deliberately factored so it stays extensible: -//! - [`builtins`] is the **single source of truth** for `node:*` modules; the -//! resolver, loader, and CJS `require` bridge all derive from its one list. -//! - [`resolve`] implements Node resolution (relative, `node_modules`, -//! `exports`/`imports`, `node:` builtins) for both the ESM [`Resolver`] and the -//! native `require` op. -//! - [`transform`] owns every source rewrite (TS erasure, JSON, CJS→ESM, the ESM -//! cycle-breaking re-export rewrite) behind one entry point. -//! - [`ops`] mounts the native `__node`/`process` surface the JS shims call. -//! -//! `mod.rs` itself only wires these together: the [`NodeLoader`] and the -//! [`install_node`] bootstrap. - -mod builtins; -mod ops; -mod resolve; -mod transform; - -pub use resolve::NodeResolver; - -use rquickjs::loader::{ImportAttributes, Loader}; -use rquickjs::module::{Declared, Module}; -use rquickjs::{Ctx, Error, Result}; - -/// The rquickjs loader hook: serve a builtin from the registry, or read the file, -/// transform it per its extension, and declare it. -pub struct NodeLoader; - -impl Loader for NodeLoader { - fn load<'js>( - &mut self, - ctx: &Ctx<'js>, - name: &str, - _attrs: Option>, - ) -> Result> { - if std::env::var("POCKET_PI_DEBUG_MODULES").is_ok() { - eprintln!("LOAD {name}"); - } - if let Some(src) = builtins::builtin_source(name) { - let m = Module::declare(ctx.clone(), name, src)?; - set_import_meta(&m, name); - return Ok(m); - } - let source = std::fs::read_to_string(name) - .map_err(|e| Error::new_loading_message(name.to_string(), e.to_string()))?; - let js = transform::prepare_module_source(name, &source) - .map_err(|e| Error::new_loading_message(name.to_string(), e))?; - let m = Module::declare(ctx.clone(), name, js)?; - set_import_meta(&m, name); - Ok(m) - } -} - -/// Populate `import.meta.url` so code that derives `__filename`/`__dirname` from -/// it works. Builtins get a synthetic `file:///node/` url. -fn set_import_meta(module: &Module<'_, Declared>, name: &str) { - if let Ok(meta) = module.meta() { - let url = match name.strip_prefix("node:") { - Some(bare) => format!("file:///node/{bare}"), - None => format!("file://{name}"), - }; - let _ = meta.set("url", url); - } -} - -const NODE_BOOTSTRAP: &str = include_str!("../../js/node/_bootstrap.js"); - -/// Install the Node layer onto a realm: native ops + `process`, the runtime -/// bootstrap (Buffer global, `nextTick`), and the CJS `require` bridge (whose -/// `__builtinExports` map is generated from the builtin registry). Call once, -/// after the resolver/loader are set and the prelude has run. -pub fn install_node(ctx: &Ctx) -> Result<()> { - ops::install_ops(ctx)?; - Module::evaluate(ctx.clone(), "pocket-pi:node-bootstrap", NODE_BOOTSTRAP)?.finish::<()>()?; - Module::evaluate( - ctx.clone(), - "pocket-pi:cjs-bootstrap", - builtins::cjs_bootstrap_source().as_str(), - )? - .finish::<()>()?; - Ok(()) -} diff --git a/crates/pocket-pi/src/node/ops.rs b/crates/pocket-pi/src/node/ops.rs deleted file mode 100644 index 4a3032e..0000000 --- a/crates/pocket-pi/src/node/ops.rs +++ /dev/null @@ -1,234 +0,0 @@ -//! Native ops backing the Node builtins: the `__node` namespace (resolution, file -//! I/O, subprocess) and the `process` global. The JS builtins in `js/node/*.js` -//! are thin shims over these — anything that must touch the OS lives here. -//! -//! Each fs op returns a JSON string the JS shim parses, rather than an rquickjs -//! `Object`, so no `Object` lifetime is threaded through a closure (that fails -//! borrowck in rquickjs). - -use rquickjs::{Ctx, Function, Object}; -use std::path::Path; - -use super::resolve::resolve_spec; - -/// Mount `globalThis.__node` and `globalThis.process`. -pub fn install_ops(ctx: &Ctx) -> rquickjs::Result<()> { - install_node_ns(ctx)?; - install_process(ctx)?; - Ok(()) -} - -fn install_node_ns(ctx: &Ctx) -> rquickjs::Result<()> { - let node = Object::new(ctx.clone())?; - - node.set("cwd", Function::new(ctx.clone(), cwd)?)?; - node.set( - "homedir", - Function::new(ctx.clone(), || -> String { - std::env::var("HOME").unwrap_or_else(|_| "/".into()) - })?, - )?; - node.set( - "tmpdir", - Function::new(ctx.clone(), || -> String { - std::env::temp_dir().to_string_lossy().to_string() - })?, - )?; - node.set( - "hostname", - Function::new(ctx.clone(), || -> String { "localhost".into() })?, - )?; - - // Resolution + file read for the synchronous CJS `require`. - node.set( - "resolve", - Function::new(ctx.clone(), |from: String, spec: String| -> String { - match resolve_spec(&from, &spec) { - Some(r) if r.starts_with("node:") => { - serde_json::json!({ "builtin": r.strip_prefix("node:").unwrap() }).to_string() - } - Some(path) => serde_json::json!({ "path": path }).to_string(), - None => serde_json::json!({ "err": "not found" }).to_string(), - } - })?, - )?; - node.set( - "readText", - Function::new(ctx.clone(), |path: String| -> String { - std::fs::read_to_string(&path).unwrap_or_default() - })?, - )?; - - node.set("fs", make_fs(ctx)?)?; - node.set("spawnSync", Function::new(ctx.clone(), spawn_sync)?)?; - - ctx.globals().set("__node", node)?; - Ok(()) -} - -fn make_fs<'js>(ctx: &Ctx<'js>) -> rquickjs::Result> { - let fs = Object::new(ctx.clone())?; - fs.set( - "readFile", - Function::new(ctx.clone(), |path: String| -> String { - match std::fs::read(&path) { - Ok(bytes) => serde_json::json!({ "bytes": bytes }).to_string(), - Err(e) => serde_json::json!({ "err": e.to_string() }).to_string(), - } - })?, - )?; - fs.set( - "writeFile", - Function::new(ctx.clone(), |path: String, bytes: Vec| -> String { - match std::fs::write(&path, &bytes) { - Ok(()) => "{}".into(), - Err(e) => serde_json::json!({ "err": e.to_string() }).to_string(), - } - })?, - )?; - fs.set( - "exists", - Function::new(ctx.clone(), |path: String| -> bool { - Path::new(&path).exists() - })?, - )?; - fs.set( - "readdir", - Function::new(ctx.clone(), |path: String| -> String { - match std::fs::read_dir(&path) { - Ok(rd) => { - let names: Vec = rd - .filter_map(|e| e.ok().map(|e| e.file_name().to_string_lossy().to_string())) - .collect(); - serde_json::json!({ "entries": names }).to_string() - } - Err(e) => serde_json::json!({ "err": e.to_string() }).to_string(), - } - })?, - )?; - fs.set( - "mkdir", - Function::new(ctx.clone(), |path: String, recursive: bool| { - let _ = if recursive { - std::fs::create_dir_all(&path) - } else { - std::fs::create_dir(&path) - }; - })?, - )?; - fs.set( - "stat", - Function::new(ctx.clone(), |path: String| -> String { - match std::fs::metadata(&path) { - Ok(m) => serde_json::json!({ - "isFile": m.is_file(), "isDir": m.is_dir(), "size": m.len() as f64, - }) - .to_string(), - Err(e) => serde_json::json!({ "err": e.to_string() }).to_string(), - } - })?, - )?; - fs.set( - "realpath", - Function::new(ctx.clone(), |path: String| -> String { - match std::fs::canonicalize(&path) { - Ok(p) => serde_json::json!({ "path": p.to_string_lossy() }).to_string(), - Err(e) => serde_json::json!({ "err": e.to_string() }).to_string(), - } - })?, - )?; - fs.set( - "unlink", - Function::new(ctx.clone(), |path: String| { - let _ = std::fs::remove_file(&path); - })?, - )?; - Ok(fs) -} - -fn install_process(ctx: &Ctx) -> rquickjs::Result<()> { - let process = Object::new(ctx.clone())?; - - let env = Object::new(ctx.clone())?; - for (k, v) in std::env::vars() { - env.set(k, v)?; - } - process.set("env", env)?; - process.set("platform", std::env::consts::OS.replace("macos", "darwin"))?; - process.set( - "arch", - if std::env::consts::ARCH == "aarch64" { - "arm64" - } else { - "x64" - }, - )?; - process.set("cwd", Function::new(ctx.clone(), cwd)?)?; - process.set("version", "v22.0.0")?; - let versions = Object::new(ctx.clone())?; - versions.set("node", "22.0.0")?; - process.set("versions", versions)?; - process.set("argv", vec!["node".to_string(), "pocket-pi".to_string()])?; - let exe = std::env::current_exe() - .map(|p| p.to_string_lossy().to_string()) - .unwrap_or_else(|_| "/pocket-pi".into()); - process.set("execPath", exe.clone())?; - process.set("argv0", exe)?; - process.set("execArgv", Vec::::new())?; - process.set("pid", std::process::id() as f64)?; - process.set("ppid", 0)?; - process.set("exit", Function::new(ctx.clone(), |_code: Option| {})?)?; - - // Minimal stdout/stderr so TUI + logging code can write() headlessly. - for (name, is_err) in [("stdout", false), ("stderr", true)] { - let stream = Object::new(ctx.clone())?; - stream.set("isTTY", false)?; - stream.set("columns", 80)?; - stream.set("rows", 24)?; - stream.set( - "write", - Function::new(ctx.clone(), move |s: String| -> bool { - if is_err { - eprint!("{s}"); - } else { - print!("{s}"); - } - true - })?, - )?; - stream.set("on", Function::new(ctx.clone(), || {})?)?; - stream.set("end", Function::new(ctx.clone(), || {})?)?; - process.set(name, stream)?; - } - - ctx.globals().set("process", process)?; - Ok(()) -} - -fn cwd() -> String { - std::env::current_dir() - .map(|p| p.to_string_lossy().to_string()) - .unwrap_or_else(|_| "/".into()) -} - -/// `spawnSync(cmd, argsJson, optsJson) -> JSON {stdout, stderr, status, error?}`. -fn spawn_sync(cmd: String, args_json: String, opts_json: String) -> String { - let args: Vec = serde_json::from_str(&args_json).unwrap_or_default(); - let opts: serde_json::Value = - serde_json::from_str(&opts_json).unwrap_or(serde_json::Value::Null); - let mut command = std::process::Command::new(&cmd); - command.args(&args); - if let Some(dir) = opts.get("cwd").and_then(|v| v.as_str()) { - command.current_dir(dir); - } - match command.output() { - Ok(o) => serde_json::json!({ - "stdout": String::from_utf8_lossy(&o.stdout), - "stderr": String::from_utf8_lossy(&o.stderr), - "status": o.status.code(), - }) - .to_string(), - Err(e) => serde_json::json!({ "error": e.to_string(), "status": serde_json::Value::Null }) - .to_string(), - } -} diff --git a/crates/pocket-pi/src/node/resolve.rs b/crates/pocket-pi/src/node/resolve.rs deleted file mode 100644 index 5a8c4df..0000000 --- a/crates/pocket-pi/src/node/resolve.rs +++ /dev/null @@ -1,285 +0,0 @@ -//! Node module resolution — the subset Pocket Pi needs: relative paths, the -//! `node_modules` walk, `exports`/`imports` maps (conditions + a single `*` -//! wildcard), and `node:` builtins. Shared by the rquickjs [`Resolver`] and the -//! native `require` op (via [`resolve_spec`]). - -use rquickjs::loader::{ImportAttributes, Resolver}; -use rquickjs::{Ctx, Error, Result}; -use std::path::{Path, PathBuf}; - -use super::builtins::is_builtin; - -/// The rquickjs resolver hook — a thin wrapper over [`resolve_spec`]. -pub struct NodeResolver; - -impl Resolver for NodeResolver { - fn resolve<'js>( - &mut self, - _ctx: &Ctx<'js>, - base: &str, - name: &str, - _attributes: Option>, - ) -> Result { - resolve_spec(base, name) - .ok_or_else(|| Error::new_resolving(base.to_string(), name.to_string())) - } -} - -/// Resolve `name` imported from `base` to a canonical module id: `node:X` for a -/// builtin, or an absolute file path. Shared by the ESM resolver and the CJS -/// `require` op so both agree on resolution. -pub fn resolve_spec(base: &str, name: &str) -> Option { - if is_builtin(name) { - let bare = name.strip_prefix("node:").unwrap_or(name); - return Some(format!("node:{bare}")); - } - if name.starts_with('#') { - return resolve_internal(base, name); - } - if name.starts_with("./") || name.starts_with("../") || name.starts_with('/') { - let base_dir = Path::new(base).parent().unwrap_or_else(|| Path::new("/")); - return probe(&normalize(&base_dir.join(name))); - } - resolve_bare(base, name) -} - -/// Probe a path for the file that actually exists, trying the Node extension and -/// index-file candidates in priority order. -fn probe(p: &Path) -> Option { - let s = p.to_string_lossy().to_string(); - const EXTS: &[&str] = &["", ".ts", ".tsx", ".mts", ".js", ".mjs", ".cjs", ".json"]; - const INDEX: &[&str] = &["/index.ts", "/index.js", "/index.mjs"]; - EXTS.iter() - .map(|ext| format!("{s}{ext}")) - .chain(INDEX.iter().map(|idx| format!("{s}{idx}"))) - .find(|c| Path::new(c).is_file()) -} - -/// Walk `node_modules` from `base` upward, resolving a bare specifier -/// (`pkg` or `@scope/pkg` with an optional subpath) in the first package found. -fn resolve_bare(base: &str, name: &str) -> Option { - let (pkg, subpath) = split_package(name); - let mut dir = Path::new(base).parent().map(|p| p.to_path_buf()); - while let Some(d) = dir { - let pkg_dir = d.join("node_modules").join(&pkg); - if pkg_dir.is_dir() { - return resolve_in_package(&pkg_dir, subpath.as_deref()); - } - dir = d.parent().map(|p| p.to_path_buf()); - } - None -} - -/// Resolve a `#internal` import via the nearest package.json's `imports` map. -fn resolve_internal(base: &str, name: &str) -> Option { - let mut dir = Path::new(base).parent(); - while let Some(d) = dir { - let pj = d.join("package.json"); - if pj.is_file() { - let json = read_json(&pj)?; - let imports = json.get("imports")?; - let obj = imports.as_object()?; - // Exact match first, then a single-`*` wildcard pattern. - if let Some(v) = obj.get(name) { - let target = resolve_conditions(v)?; - return probe(&normalize(&d.join(target))); - } - for (pat, target) in obj { - if let Some(cap) = wildcard_capture(pat, name) { - let tgt = resolve_conditions(target)?.replace('*', &cap); - return probe(&normalize(&d.join(tgt))); - } - } - return None; // the nearest package.json is the resolution boundary - } - dir = d.parent(); - } - None -} - -/// Resolve a specifier within a package dir, honoring the `exports` map (exact, -/// conditional, and single-`*` wildcard subpaths), else `module`/`main`, else a -/// literal probe. -fn resolve_in_package(pkg_dir: &Path, subpath: Option<&str>) -> Option { - if let Some(json) = read_json(&pkg_dir.join("package.json")) { - let key = match subpath { - None => ".".to_string(), - Some(s) => format!("./{s}"), - }; - if let Some(target) = resolve_export(&json, &key) { - return probe(&normalize(&pkg_dir.join(target))); - } - // No exports match: use module/main for the root, else a literal probe. - if subpath.is_none() { - let entry = json - .get("module") - .and_then(|v| v.as_str()) - .or_else(|| json.get("main").and_then(|v| v.as_str())) - .unwrap_or("index.js"); - return probe(&normalize(&pkg_dir.join(entry))); - } - } - probe(&normalize(&pkg_dir.join(subpath.unwrap_or("index.js")))) -} - -/// Look up `key` (`.` or `./sub`) in a package's `exports`, resolving conditions -/// and a single-`*` wildcard. Returns the target path relative to the package dir. -fn resolve_export(json: &serde_json::Value, key: &str) -> Option { - let exports = json.get("exports")?; - // `"exports": "./x.js"` — sugar for the root entry only. - if let Some(s) = exports.as_str() { - return if key == "." { - Some(s.to_string()) - } else { - None - }; - } - let obj = exports.as_object()?; - // Exact subpath wins over any wildcard (Node's precedence). - if let Some(v) = obj.get(key) { - return resolve_conditions(v); - } - for (pat, target) in obj { - if let Some(cap) = wildcard_capture(pat, key) { - return Some(resolve_conditions(target)?.replace('*', &cap)); - } - } - None -} - -/// Pick a target string out of a conditional-exports value. Strings resolve -/// directly; objects are probed in a fixed priority (ESM-leaning, with `default` -/// and `require` as fallbacks). Nested objects recurse. -fn resolve_conditions(value: &serde_json::Value) -> Option { - if let Some(s) = value.as_str() { - return Some(s.to_string()); - } - // Arrays: first resolvable entry wins (Node's fallback-array semantics). - if let Some(arr) = value.as_array() { - return arr.iter().find_map(resolve_conditions); - } - for cond in ["import", "module", "browser", "default", "node", "require"] { - if let Some(v) = value.get(cond) { - if let Some(s) = resolve_conditions(v) { - return Some(s); - } - } - } - None -} - -/// Match a subpath pattern containing at most one `*` against `key`, returning the -/// `*` capture. A pattern without `*` matches only its exact equal. -fn wildcard_capture(pattern: &str, key: &str) -> Option { - match pattern.find('*') { - None => (pattern == key).then(String::new), - Some(i) => { - let (pre, post) = (&pattern[..i], &pattern[i + 1..]); - if key.len() >= pre.len() + post.len() && key.starts_with(pre) && key.ends_with(post) { - Some(key[pre.len()..key.len() - post.len()].to_string()) - } else { - None - } - } - } -} - -/// Split a bare specifier into `(package, subpath)`, handling `@scope/pkg`. -fn split_package(name: &str) -> (String, Option) { - let parts: Vec<&str> = name - .splitn(if name.starts_with('@') { 3 } else { 2 }, '/') - .collect(); - if name.starts_with('@') && parts.len() == 3 { - ( - format!("{}/{}", parts[0], parts[1]), - Some(parts[2].to_string()), - ) - } else if name.starts_with('@') { - (name.to_string(), None) - } else if parts.len() == 2 { - (parts[0].to_string(), Some(parts[1].to_string())) - } else { - (name.to_string(), None) - } -} - -/// Collapse `.`/`..` components without touching the filesystem. -fn normalize(p: &Path) -> PathBuf { - let mut out = PathBuf::new(); - for comp in p.components() { - use std::path::Component::*; - match comp { - ParentDir => { - out.pop(); - } - CurDir => {} - other => out.push(other.as_os_str()), - } - } - out -} - -fn read_json(path: &Path) -> Option { - let text = std::fs::read_to_string(path).ok()?; - serde_json::from_str(&text).ok() -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn splits_scoped_and_plain_packages() { - assert_eq!(split_package("react"), ("react".into(), None)); - assert_eq!( - split_package("react/jsx-runtime"), - ("react".into(), Some("jsx-runtime".into())) - ); - assert_eq!(split_package("@scope/pkg"), ("@scope/pkg".into(), None)); - assert_eq!( - split_package("@scope/pkg/sub"), - ("@scope/pkg".into(), Some("sub".into())) - ); - } - - #[test] - fn wildcard_matches_prefix_and_suffix() { - assert_eq!(wildcard_capture("./*", "./foo"), Some("foo".into())); - assert_eq!( - wildcard_capture("./features/*.js", "./features/x.js"), - Some("x".into()) - ); - assert_eq!(wildcard_capture("./features/*.js", "./other/x.js"), None); - assert_eq!(wildcard_capture("./exact", "./exact"), Some(String::new())); - assert_eq!(wildcard_capture("./exact", "./nope"), None); - } - - #[test] - fn exports_exact_beats_wildcard() { - let json: serde_json::Value = - serde_json::from_str(r#"{"exports":{"./a":"./exact.js","./*":"./src/*.js"}}"#).unwrap(); - assert_eq!(resolve_export(&json, "./a").as_deref(), Some("./exact.js")); - assert_eq!(resolve_export(&json, "./b").as_deref(), Some("./src/b.js")); - } - - #[test] - fn conditions_prefer_import_then_fall_back() { - let dual: serde_json::Value = - serde_json::from_str(r#"{"import":"./m.mjs","require":"./m.cjs"}"#).unwrap(); - assert_eq!(resolve_conditions(&dual).as_deref(), Some("./m.mjs")); - let only_req: serde_json::Value = serde_json::from_str(r#"{"require":"./m.cjs"}"#).unwrap(); - assert_eq!(resolve_conditions(&only_req).as_deref(), Some("./m.cjs")); - let nested: serde_json::Value = - serde_json::from_str(r#"{"node":{"import":"./n.mjs"}}"#).unwrap(); - assert_eq!(resolve_conditions(&nested).as_deref(), Some("./n.mjs")); - } - - #[test] - fn builtins_resolve_with_node_prefix() { - assert_eq!(resolve_spec("/x.js", "fs").as_deref(), Some("node:fs")); - assert_eq!( - resolve_spec("/x.js", "node:path").as_deref(), - Some("node:path") - ); - } -} diff --git a/crates/pocket-pi/src/node/transform.rs b/crates/pocket-pi/src/node/transform.rs deleted file mode 100644 index d13065a..0000000 --- a/crates/pocket-pi/src/node/transform.rs +++ /dev/null @@ -1,212 +0,0 @@ -//! Source transforms applied by the loader before a module is declared: -//! TypeScript type-erasure, JSON wrapping, CommonJS→ESM bridging, and an ESM -//! re-export rewrite that breaks QuickJS linker cycles. One entry point, -//! [`prepare_module_source`], picks the transform from the file extension (and, -//! for ambiguous `.js`, a CJS/ESM classification). - -use crate::transpile::transpile_ts; -use std::path::Path; - -/// Turn a raw module `source` (already known to be a non-builtin file at `name`) -/// into the JS the loader declares. Errors only if TypeScript transpile fails. -pub fn prepare_module_source(name: &str, source: &str) -> std::result::Result { - let js = if is_typescript(name) { - rewrite_reexports(&transpile_ts(name, source)?) - } else if name.ends_with(".json") { - format!("export default {source};") - } else if name.ends_with(".cjs") || (!name.ends_with(".mjs") && is_cjs(source)) { - // CommonJS: wrap as an ESM module so `import { x }` works, routing its own - // `require(...)` through the synchronous native require. - wrap_cjs(name, source) - } else { - rewrite_reexports(source) - }; - Ok(js) -} - -fn is_typescript(name: &str) -> bool { - name.ends_with(".ts") - || name.ends_with(".tsx") - || name.ends_with(".mts") - || name.ends_with(".cts") -} - -/// Heuristic CJS classification for ambiguous `.js`/extensionless files: any -/// top-level ESM statement marks it ESM; otherwise a `require`/`exports` marker -/// marks it CJS. Deliberately a scan, not a parse — the loader runs this on every -/// file including the multi-megabyte Path B bundle, and `.cjs`/`.mjs`/`.ts` are -/// classified by extension without reaching here. -fn is_cjs(src: &str) -> bool { - for l in src.lines() { - let t = l.trim_start(); - if t.starts_with("import ") - || t.starts_with("import{") - || t.starts_with("import *") - || t.starts_with("import*") - || t.starts_with("export ") - || t.starts_with("export{") - || t.starts_with("export*") - || t.starts_with("export default") - { - return false; - } - } - src.contains("require(") - || src.contains("module.exports") - || src.contains("exports.") - || src.contains("exports[") -} - -/// Wrap a CommonJS module as an ES module: run its body with `module`/`exports`/ -/// `require`, cache the result, and re-export `default` plus the named exports we -/// can detect (a lightweight cjs-module-lexer, [`cjs_named_exports`]). -fn wrap_cjs(name: &str, src: &str) -> String { - let dir = Path::new(name) - .parent() - .map(|p| p.to_string_lossy().to_string()) - .unwrap_or_default(); - let mut named = String::new(); - for n in cjs_named_exports(src) { - named.push_str(&format!("export const {n} = __m[{:?}];\n", n)); - } - format!( - "const module = {{ exports: {{}} }};\n\ - let exports = module.exports;\n\ - const __filename = {name:?};\n\ - const __dirname = {dir:?};\n\ - const require = (s) => globalThis.__cjsRequire(__filename, s);\n\ - globalThis.__cjsCache = globalThis.__cjsCache || new Map();\n\ - globalThis.__cjsCache.set(__filename, module.exports);\n\ - (function (module, exports, require, __filename, __dirname) {{\n{src}\n}})(module, exports, require, __filename, __dirname);\n\ - const __m = module.exports;\n\ - globalThis.__cjsCache.set(__filename, __m);\n\ - export default __m;\n{named}" - ) -} - -/// Scan CJS source for its named exports (best-effort, covers TS-compiled CJS). -/// Uses `match_indices` so slicing always lands on char boundaries (a byte-index -/// slice here once panicked in the non-unwinding native op → SIGABRT). -fn cjs_named_exports(src: &str) -> Vec { - fn ident(s: &str) -> String { - s.chars() - .take_while(|c| c.is_alphanumeric() || *c == '_' || *c == '$') - .collect() - } - let mut set: Vec = Vec::new(); - let mut push = |n: String| { - if n != "default" && n != "__esModule" && !n.is_empty() && !set.contains(&n) { - set.push(n); - } - }; - // `exports.NAME =` / `exports.NAME[` - for (idx, _) in src.match_indices("exports.") { - let rest = &src[idx + "exports.".len()..]; - let name = ident(rest); - if !name.is_empty() { - let after = rest[name.len()..].trim_start(); - if after.starts_with('=') || after.starts_with('[') { - push(name); - } - } - } - // `Object.defineProperty(exports, "NAME"` and `__createBinding(exports, …, "NAME"` - for pat in ["defineProperty(exports,", "__createBinding(exports,"] { - for (idx, _) in src.match_indices(pat) { - let rest = &src[idx + pat.len()..]; - if let Some(q) = rest.find(['"', '\'']) { - push(ident(&rest[q + 1..])); - } - } - } - set -} - -/// Rewrite indirect named re-exports into an import + a local export: -/// `export { a, b as c } from "./y"` → -/// `import { a, b as c } from "./y"; export { a, c };` -/// QuickJS resolves an indirect export by chaining through modules, which trips -/// "circular reference" inside dependency cycles. A local binding sidesteps that -/// chain and is semantically identical outside cycles. -fn rewrite_reexports(src: &str) -> String { - use regex::Regex; - use std::sync::OnceLock; - static RE: OnceLock = OnceLock::new(); - let re = RE.get_or_init(|| { - Regex::new(r#"(?m)^\s*export\s*\{([^}]*)\}\s*from\s*(["'][^"']+["'])\s*;?"#).unwrap() - }); - let counter = std::cell::Cell::new(0usize); - re.replace_all(src, |caps: ®ex::Captures| { - let (list, spec) = (&caps[1], &caps[2]); - let mut imports = Vec::new(); - let mut exports = Vec::new(); - for item in list.split(',') { - let item = item.trim(); - if item.is_empty() { - continue; - } - // `orig` is the name in the target module, `exported` the outer name. - let (orig, exported) = match item.split_once(" as ") { - Some((a, b)) => (a.trim(), b.trim()), - None => (item, item), - }; - // A unique local avoids clashing with an existing `import { orig }`. - let n = counter.get(); - counter.set(n + 1); - let local = format!( - "__rx{n}_{}", - exported.replace(|c: char| !c.is_alphanumeric(), "_") - ); - imports.push(format!("{orig} as {local}")); - exports.push(format!("{local} as {exported}")); - } - format!( - "import {{ {} }} from {spec}; export {{ {} }};", - imports.join(", "), - exports.join(", ") - ) - }) - .into_owned() -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn classifies_cjs_and_esm() { - assert!(is_cjs("const x = require('y');\nmodule.exports = x;")); - assert!(!is_cjs("import x from 'y';\nexport default x;")); - assert!(!is_cjs("export const a = 1;")); - } - - #[test] - fn detects_cjs_named_exports() { - let names = - cjs_named_exports("exports.foo = 1;\nObject.defineProperty(exports, \"bar\", {});"); - assert!(names.contains(&"foo".to_string())); - assert!(names.contains(&"bar".to_string())); - assert!(!names.contains(&"default".to_string())); - } - - #[test] - fn rewrites_indirect_reexports_to_local_bindings() { - let out = rewrite_reexports("export { a, b as c } from \"./y\";"); - assert!(out.contains("import {"), "got: {out}"); - assert!(out.contains("as c"), "got: {out}"); - assert!( - !out.contains("export { a, b as c } from"), - "still indirect: {out}" - ); - } - - #[test] - fn prepare_dispatches_on_extension() { - assert!(prepare_module_source("/x.json", "{\"a\":1}") - .unwrap() - .starts_with("export default")); - assert!(prepare_module_source("/x.cjs", "module.exports = 1;") - .unwrap() - .contains("__cjsRequire")); - } -} diff --git a/crates/pocket-pi/src/tests.rs b/crates/pocket-pi/src/tests.rs deleted file mode 100644 index 99be2eb..0000000 --- a/crates/pocket-pi/src/tests.rs +++ /dev/null @@ -1,433 +0,0 @@ -use super::*; -use std::cell::RefCell; -use std::rc::Rc; -use std::time::{Duration, Instant}; - -/// Pump until the runtime goes idle or a frame budget is hit. Returns the -/// collected host events. `hz` is the pump cadence — we deliberately run slow to -/// prove the coalesced scheduler carries a real turn to completion. -fn run(rt: &mut PiRuntime, sink: Rc>>, hz: f64, max_secs: f64) { - let period = Duration::from_secs_f64(1.0 / hz); - let start = Instant::now(); - while !rt.is_idle() && start.elapsed().as_secs_f64() < max_secs { - rt.pump().unwrap(); - std::thread::sleep(period); - } - // One last pump to flush any trailing events. - rt.pump().unwrap(); - let _ = &sink; -} - -fn collector() -> ( - Rc>>, - impl FnMut(&HostEvent) + 'static, -) { - let sink = Rc::new(RefCell::new(Vec::new())); - let s = sink.clone(); - (sink, move |ev: &HostEvent| s.borrow_mut().push(ev.clone())) -} - -/// Assemble the assistant reply the way the host does: streamed `text` deltas, -/// with an `assistant_text` full-text emit as a fallback. -fn reply_text(events: &[HostEvent]) -> String { - let mut out = String::new(); - for e in events { - match e.kind.as_str() { - "text" => { - if let Some(d) = e.value.get("delta").and_then(|v| v.as_str()) { - out.push_str(d); - } - } - "assistant_text" if out.is_empty() => { - if let Some(t) = e.value.get("text").and_then(|v| v.as_str()) { - out = t.to_string(); - } - } - _ => {} - } - } - out -} - -/// The module system resolves and loads a relative transpiled `.ts` file, -/// `node:` builtins, and a bare package from `node_modules`. -#[test] -fn node_module_system_loads_ts_builtins_and_a_bare_package() { - use std::fs; - let dir = std::env::temp_dir().join(format!("pocketpi-node-test-{}", std::process::id())); - let _ = fs::remove_dir_all(&dir); - fs::create_dir_all(dir.join("node_modules/greet")).unwrap(); - fs::write( - dir.join("node_modules/greet/package.json"), - r#"{"name":"greet","version":"1.0.0","module":"index.js"}"#, - ) - .unwrap(); - fs::write( - dir.join("node_modules/greet/index.js"), - "export default (who) => \"hello \" + who;", - ) - .unwrap(); - fs::write( - dir.join("entry.ts"), - r#" -import { join } from "node:path"; -import { EventEmitter } from "node:events"; -import { Buffer } from "node:buffer"; -import { homedir } from "node:os"; -import greet from "greet"; - -type Result = { path: string; ee: boolean; b64: string; greet: string; hasHome: boolean }; -const ee = new EventEmitter(); -let fired = false; -ee.on("x", () => { fired = true; }); -ee.emit("x"); - -const out: Result = { - path: join("a", "b", "..", "c"), - ee: fired, - b64: Buffer.from("hi").toString("base64"), - greet: greet("cat"), - hasHome: typeof homedir() === "string", -}; -(globalThis as any).__nodeTest = out; -"#, - ) - .unwrap(); - - let mut rt = PiRuntime::new().expect("runtime"); - rt.run_module(dir.join("entry.ts").to_str().unwrap()) - .expect("run module"); - - let out = rt.get_global_json("__nodeTest").expect("__nodeTest set"); - assert_eq!(out["path"], "a/c", "path.join wrong: {out}"); - assert_eq!(out["ee"], true, "EventEmitter didn't fire: {out}"); - assert_eq!(out["b64"], "aGk=", "Buffer base64 wrong: {out}"); - assert_eq!( - out["greet"], "hello cat", - "bare package import wrong: {out}" - ); - assert_eq!(out["hasHome"], true, "os.homedir wrong: {out}"); - - let _ = fs::remove_dir_all(&dir); -} - -/// Load a piece of the REAL, unmodified pi-ai (`utils/event-stream.js`) straight -/// from node_modules through the Node loader and exercise its actual class. This -/// is the "run unmodified pi" thesis, proven on real pi code — and validates the -/// ESM-first (no-CJS) decision. Skipped if node_modules isn't installed. -#[test] -fn runs_real_unmodified_pi_ai_module() { - let manifest = env!("CARGO_MANIFEST_DIR"); - let real = - format!("{manifest}/../../js/node_modules/@mariozechner/pi-ai/dist/utils/event-stream.js"); - if !std::path::Path::new(&real).exists() { - eprintln!("skipping runs_real_unmodified_pi_ai_module: run `npm install` in js/ first"); - return; - } - - let dir = std::env::temp_dir().join(format!("pocketpi-piai-{}", std::process::id())); - let _ = std::fs::remove_dir_all(&dir); - std::fs::create_dir_all(&dir).unwrap(); - std::fs::write( - dir.join("entry.ts"), - format!( - r#" -import {{ AssistantMessageEventStream }} from "{real}"; -const s = new AssistantMessageEventStream(); -const msg = {{ role: "assistant", content: [{{ type: "text", text: "hi" }}] }}; -// The real stream completes on a "done" event and resolves result() to its message. -s.push({{ type: "text_delta", delta: "hi", partial: msg }}); -s.push({{ type: "done", message: msg }}); -s.result().then((m: any) => {{ - (globalThis as any).__piAi = {{ resolvedText: m.content[0].text, isReal: true }}; -}}); -"# - ), - ) - .unwrap(); - - let mut rt = PiRuntime::new().expect("runtime"); - rt.run_module(dir.join("entry.ts").to_str().unwrap()) - .expect("run real pi-ai module"); - // Drain so the result() promise settles. - for _ in 0..5 { - rt.pump().ok(); - } - - let out = rt.get_global_json("__piAi").expect("real pi-ai class ran"); - assert_eq!( - out["resolvedText"], "hi", - "real pi-ai EventStream misbehaved: {out}" - ); - assert_eq!(out["isReal"], true); - let _ = std::fs::remove_dir_all(&dir); -} - -/// WHATWG `fetch` → `Response` → `ReadableStream` → `json()`, end to end over the -/// native HTTP hub. Hits a real endpoint (needs network/proxy); skips if -/// unreachable. A 401 is fine — fetch doesn't throw on it, which is the point. -#[test] -fn whatwg_fetch_returns_a_readable_response() { - let mut rt = PiRuntime::new().expect("runtime"); - rt.eval_script( - r#" - globalThis.__f = { done: false }; - fetch("https://api.anthropic.com/v1/models") - .then(async (r) => { - const body = await r.text(); - let parsed = null; try { parsed = JSON.parse(body); } catch {} - globalThis.__f = { - done: true, status: r.status, ok: r.ok, - ct: r.headers.get("content-type"), - len: body.length, isObject: parsed !== null && typeof parsed === "object", - }; - }) - .catch((e) => { globalThis.__f = { done: true, err: String(e && e.message ? e.message : e) }; }); - "#, - ) - .expect("eval fetch"); - - let start = std::time::Instant::now(); - loop { - rt.pump().unwrap(); - let f = rt.get_global_json("__f").unwrap_or(serde_json::Value::Null); - if f.get("done").and_then(|v| v.as_bool()) == Some(true) { - if let Some(err) = f.get("err").and_then(|v| v.as_str()) { - eprintln!("skipping whatwg_fetch: endpoint unreachable ({err})"); - return; - } - eprintln!("fetch result: {f}"); - let status = f["status"].as_i64().unwrap_or(0); - assert!(status > 0, "no status: {f}"); - assert!(f["len"].as_i64().unwrap_or(0) > 0, "empty body: {f}"); - assert_eq!(f["isObject"], true, "body wasn't JSON: {f}"); - assert!( - f["ct"].as_str().unwrap_or("").contains("json"), - "content-type header missing: {f}" - ); - return; - } - if start.elapsed().as_secs() > 30 { - panic!("fetch never completed: {f}"); - } - std::thread::sleep(std::time::Duration::from_millis(30)); - } -} - -/// The full, unmodified pi-coding-agent is embedded and loaded by every -/// `PiRuntime::new()`: `globalThis.PiFull` (createAgentSession, …) and the -/// `PocketPi` host harness are both present with no external bundle, no network. -#[test] -fn new_embeds_and_loads_full_pi() { - let mut rt = PiRuntime::new().expect("runtime"); - assert_eq!( - rt.get_global_json("__piFullLoaded"), - Some(serde_json::Value::Bool(true)), - "full pi did not initialize in new()" - ); - // The host harness is wired too. - rt.eval_script("globalThis.__hasPocketPi = typeof globalThis.PocketPi?.boot === 'function';") - .expect("probe"); - assert_eq!( - rt.get_global_json("__hasPocketPi"), - Some(serde_json::Value::Bool(true)) - ); -} - -/// The deterministic Mac fallback still runs a complete, unmodified -/// pi-coding-agent AgentSession; only its model provider is local and scripted. -#[test] -fn full_pi_runs_with_offline_provider() { - let (sink, cb) = collector(); - let mut rt = PiRuntime::new().expect("runtime"); - rt.on_event(cb); - let cfg = serde_json::json!({ - "model": "offline", - "scripted": {"steps": [{"text": "OFFLINE-E2E-OK"}]} - }); - rt.boot(&cfg.to_string()).expect("boot"); - rt.prompt("reply with the scripted response") - .expect("prompt"); - run(&mut rt, sink.clone(), 30.0, 5.0); - - let events = sink.borrow(); - let errors: Vec<&HostEvent> = events - .iter() - .filter(|event| event.kind == "error") - .collect(); - assert!(errors.is_empty(), "offline turn failed: {errors:?}"); - assert!( - events.iter().any(|event| event.kind == "end"), - "turn did not end" - ); - assert_eq!(reply_text(&events), "OFFLINE-E2E-OK"); -} - -/// Load a real, unmodified pi extension through Pocket -/// Pi's OWN module loader — the `.ts` is transpiled natively with oxc, NOT jiti -/// (which needs Node internals QuickJS lacks) — and hand its default factory to -/// pi's unmodified `loadExtensionFromFactory`. -#[test] -fn loads_pi_extension_via_our_loader() { - let manifest = env!("CARGO_MANIFEST_DIR"); - let probe = format!("{manifest}/js/pi-full/ext-probe.js"); - let ext = format!("{manifest}/../../js/src/pi-full/example-extension.ts"); - - let mut rt = PiRuntime::new().expect("runtime"); - let probe_src = std::fs::read_to_string(&probe).expect("ext-probe.js"); - rt.eval_script(&probe_src).expect("probe eval"); - rt.eval_script(&format!("globalThis.__piLoadExtension({ext:?});")) - .expect("kick off"); - - let start = std::time::Instant::now(); - while start.elapsed().as_secs_f64() < 15.0 { - rt.pump().expect("pump"); - if rt.get_global_json("__piExtDone") == Some(serde_json::Value::Bool(true)) { - break; - } - std::thread::sleep(std::time::Duration::from_millis(50)); - } - - let err = rt.get_global_json("__piExtError"); - let result = rt.get_global_json("__piExtResult"); - eprintln!("EXT error={err:?}"); - eprintln!("EXT result={result:?}"); - assert_eq!(err, Some(serde_json::Value::Null), "extension load errored"); - let result = result.expect("no extension result"); - let tools = result - .get("tools") - .and_then(|v| v.as_array()) - .cloned() - .unwrap_or_default(); - let handlers = result - .get("handlers") - .and_then(|v| v.as_array()) - .cloned() - .unwrap_or_default(); - assert!( - tools.iter().any(|t| t.as_str() == Some("echo")), - "extension tool 'echo' not registered (got {tools:?})" - ); - assert!( - handlers.iter().any(|h| h.as_str() == Some("agent_start")), - "extension hook 'agent_start' not registered (got {handlers:?})" - ); -} - -/// Pump `__piRun(optsJson)` (see driver.js) until it finishes or the budget is -/// hit. Returns nothing; results are read from globals by the caller. -fn drive_session(rt: &mut PiRuntime, opts_json: &str, max_secs: f64) -> bool { - rt.eval_script(&format!("globalThis.__piRun({opts_json:?});")) - .expect("kick off"); - let start = std::time::Instant::now(); - while start.elapsed().as_secs_f64() < max_secs { - rt.pump().expect("pump"); - if rt.get_global_json("__piDone") == Some(serde_json::Value::Bool(true)) { - return true; - } - std::thread::sleep(std::time::Duration::from_millis(100)); - } - false -} - -/// Bind an unmodified pi extension into a real AgentSession through the -/// first-class `extensionFactories` seam and confirm the ExtensionRunner picks -/// up its hook and tool. -#[test] -fn binds_extension_into_session() { - let manifest = env!("CARGO_MANIFEST_DIR"); - let driver = format!("{manifest}/js/pi-full/driver.js"); - let ext = format!("{manifest}/../../js/src/pi-full/example-extension.ts"); - let mut rt = PiRuntime::new().expect("runtime"); - rt.eval_script(&std::fs::read_to_string(&driver).expect("driver.js")) - .expect("driver eval"); - - let opts = serde_json::json!({ "extensionPath": ext }).to_string(); - let done = drive_session(&mut rt, &opts, 15.0); - let err = rt.get_global_json("__piError"); - let bind = rt.get_global_json("__piBind"); - eprintln!("BIND done={done} error={err:?}"); - eprintln!("BIND result={bind:?}"); - assert!(done, "session build did not finish"); - assert_eq!(err, Some(serde_json::Value::Null), "session build errored"); - let bind = bind.expect("no bind info"); - assert_eq!( - bind.get("hasAgentStart"), - Some(&serde_json::Value::Bool(true)), - "agent_start hook not bound into session" - ); - let tools = bind - .get("registeredTools") - .and_then(|v| v.as_array()) - .cloned() - .unwrap_or_default(); - assert!( - tools.iter().any(|t| t.as_str() == Some("echo")), - "echo tool not registered in session (got {tools:?})" - ); -} - -/// Persist a session to disk with pi's unmodified SessionManager (backed by -/// Pocket Pi's fs builtin), then resume it in a fresh manager and confirm the -/// history round-trips. -#[test] -fn persists_and_resumes_session() { - let manifest = env!("CARGO_MANIFEST_DIR"); - let probe = format!("{manifest}/js/pi-full/persist-probe.js"); - let dir = std::env::temp_dir().join(format!("pocket-pi-sess-{}", std::process::id())); - let _ = std::fs::remove_dir_all(&dir); - std::fs::create_dir_all(&dir).unwrap(); - - let mut rt = PiRuntime::new().expect("runtime"); - rt.eval_script(&std::fs::read_to_string(&probe).expect("persist-probe.js")) - .expect("probe eval"); - rt.eval_script(&format!( - "globalThis.__piPersist({:?});", - dir.to_str().unwrap() - )) - .expect("run persist"); - rt.pump().expect("pump"); - - let err = rt.get_global_json("__piPersistError"); - let result = rt.get_global_json("__piPersistResult"); - eprintln!("PERSIST error={err:?}"); - eprintln!("PERSIST result={result:?}"); - // Confirm the session file actually hit disk. - let files: Vec<_> = std::fs::read_dir(&dir) - .unwrap() - .filter_map(|e| e.ok()) - .map(|e| e.file_name()) - .collect(); - eprintln!("PERSIST files={files:?}"); - let _ = std::fs::remove_dir_all(&dir); - - assert_eq!(err, Some(serde_json::Value::Null), "persistence errored"); - let result = result.expect("no persist result"); - assert_eq!( - result.get("wrote").and_then(|v| v.as_u64()), - Some(2), - "did not write 2 messages" - ); - assert_eq!( - result.get("resumedCount").and_then(|v| v.as_u64()), - Some(2), - "resumed session lost messages" - ); - let texts = result - .get("texts") - .and_then(|v| v.as_array()) - .cloned() - .unwrap_or_default(); - assert!( - texts - .iter() - .any(|t| t.as_str().is_some_and(|s| s.contains("42"))), - "resumed history missing content (got {texts:?})" - ); - assert!( - files - .iter() - .any(|f| f.to_string_lossy().ends_with(".jsonl")), - "no .jsonl session file on disk" - ); -} diff --git a/crates/pocket-pi/src/transpile.rs b/crates/pocket-pi/src/transpile.rs deleted file mode 100644 index b3f2338..0000000 --- a/crates/pocket-pi/src/transpile.rs +++ /dev/null @@ -1,68 +0,0 @@ -//! Runtime TypeScript → JavaScript, the native op behind Pocket Pi's plugin -//! loader. -//! -//! Real pi loads its extensions — TypeScript files — at runtime through `jiti` -//! (`jiti` + `typescript`, a heavy Node toolchain). Pocket Pi has no Node, so -//! per the runtime's own rule ("heavy Node deps become native ops") it strips -//! types with **oxc**, a pure-Rust compiler, and hands the resulting JS to -//! QuickJS. Only type-erasure + light syntax lowering is needed: QuickJS is -//! ES2023, so we keep modern syntax and just remove the TypeScript. - -use oxc_allocator::Allocator; -use oxc_codegen::Codegen; -use oxc_parser::Parser; -use oxc_semantic::SemanticBuilder; -use oxc_span::SourceType; -use oxc_transformer::{TransformOptions, Transformer}; -use std::path::Path; - -/// Transpile a TypeScript source string to JavaScript. `filename` only informs -/// the source-type detection (`.ts` / `.tsx`) and diagnostics. -pub fn transpile_ts(filename: &str, source: &str) -> Result { - let allocator = Allocator::default(); - let path = Path::new(filename); - let source_type = SourceType::from_path(path).unwrap_or_else(|_| SourceType::ts()); - - let parsed = Parser::new(&allocator, source, source_type).parse(); - if parsed.panicked || !parsed.diagnostics.is_empty() { - let msgs: Vec = parsed.diagnostics.iter().map(|d| d.to_string()).collect(); - return Err(format!("TypeScript parse error: {}", msgs.join("; "))); - } - - let mut program = parsed.program; - let scoping = SemanticBuilder::new() - .build(&program) - .semantic - .into_scoping(); - let result = Transformer::new(&allocator, path, &TransformOptions::default()) - .build_with_scoping(scoping, &mut program); - if !result.diagnostics.is_empty() { - let msgs: Vec = result.diagnostics.iter().map(|d| d.to_string()).collect(); - return Err(format!("TypeScript transform error: {}", msgs.join("; "))); - } - - Ok(Codegen::new().build(&program).code) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn strips_types_keeps_logic() { - let js = transpile_ts( - "p.ts", - "type N = number;\nexport default (a: N, b: N): N => a + b;", - ) - .unwrap(); - assert!(js.contains("export default"), "got: {js}"); - assert!(!js.contains(": N"), "types not stripped: {js}"); - assert!(!js.contains("type N"), "type alias not stripped: {js}"); - } - - #[test] - fn reports_parse_errors() { - let err = transpile_ts("p.ts", "export default function( {{{ ").unwrap_err(); - assert!(err.contains("parse"), "got: {err}"); - } -} diff --git a/docs/agentos-architecture.md b/docs/agentos-architecture.md index ac29bc8..efe220b 100644 --- a/docs/agentos-architecture.md +++ b/docs/agentos-architecture.md @@ -73,8 +73,7 @@ catalog、Agent Tool ownership 或后台任务生命周期。如果其中某个 5. SQLite 是 App 数据的唯一持久化真相;成功写入后,正在显示的 View 自动 更新,但不能每帧轮询数据库。 6. 普通 App 彼此隔离;Pi Agent 始终拥有整个 `/workspace`。 -7. 同一套 App 源码和 Module contract 可以在 macOS、模拟器、ESP32-P4 和 - 后续硬件上复用。 +7. 同一套 App 源码和 Module contract 可以在模拟器、ESP32-P4 和后续硬件上复用。 8. Agent 工作与前台 View 导航解耦:模型/Tool 在运行时,触摸、键盘、切换 Robinhood/Exa 和返回 Agent 都不能中断或重建 Agent。 @@ -810,10 +809,10 @@ Agent 能在未来通过更新自己的 release 一起演进 context、Tools ada - 修改 firmware/Rust modules; - v1 动态加载 Tool source。 -### 14.3 macOS 开发能力 +### 14.3 开发机能力 -macOS Host 可以额外提供显式 developer capability,用来编辑源码和构建 -Root/App Bundles。它不属于 ESP32 portable contract。 +开发机可以编辑源码和构建 Root/App Bundles;该构建流程不属于 ESP32 +portable contract,也不是独立的 Pocket Pi Agent Host。 ## 15. Context Assembler @@ -897,18 +896,16 @@ Guest 中运行,但 Root View 暂不产生前台 DrawList。用户仍可操作 | Chat、Files、keyboard、message reader | Root PocketJS View | | Wi-Fi scan/connect/forget、restart | `device.settings` + Root View | | simulator/physical contract parity | shared runtime/module contracts | -| macOS full Pi sessions/extensions | macOS Agent profile | 新增而不是现有的能力包括:App Supervisor、App Catalog、App Tools、AppTask Schedules、revision-coalesced projection cache 和 Bundle-based Views。 ## 19. Host profiles 与跨硬件 -Pocket Pi 继续保留不同 Agent profile: +Pocket Pi 保留一个 embedded Agent profile,由两个 Host 实现: | Host | Agent profile | 额外能力 | | --- | --- | --- | -| macOS | full `pi-coding-agent` | sessions、extensions、可选 Bundle 开发/构建 | | ESP32 simulator | embedded `pi-agent-core` | 用 macOS adapter 实现相同 embedded contracts | | ESP32-P4 | embedded `pi-agent-core` | LittleFS、touch/LCD、Wi-Fi/NVS 和嵌入式 limits | @@ -926,8 +923,8 @@ Pocket Pi 继续保留不同 Agent profile: 生成 target-specific `app.js`/`app.pak`。 以 Robinhood 为例,Tool mapping、SQLite schema、refresh Task 和 View source -保持相同;ESP32 与 macOS 只是在同一 specs 后面提供不同 display、filesystem、 -network 和 credential 实现。 +保持相同;ESP32 与 simulator 只是在同一 specs 后面提供不同 display、 +filesystem、network 和 credential 实现。 ### 19.2 能做到跨硬件的条件 @@ -1116,8 +1113,8 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 - release 已有 descriptor/`pocket.json` 校验和 atomic `current` 写入,但由 PocketJS resolver 生成并校验真实 `plan.json`、完整 artifact hash、migration transaction、上一版本回退和独立 recovery UI 还没有完成。 -- macOS full Agent Host 尚未迁到同一个 App Supervisor;当前跨硬件实证是 - ESP32 simulator + physical ESP32-P4,不代表 macOS parity 已完成。 +- 当前跨硬件实证是 ESP32 simulator + physical ESP32-P4;simulator 证明共享 + product contract,最终硬件验收仍以实体设备为准。 - 固定 catalog 的普通 App View 现在全部在 Supervisor 启动时 preload;真实 ESP32-P4 启动时长已量测,但持续切换仍需人工验收。后续如果 catalog 扩大,再依据实测在 PocketJS runtime 层设计加载策略,不能先引入 Marketplace、 @@ -1158,7 +1155,7 @@ preload 全部普通 View。Marketplace 是独立的后续项目,不属于当 后再实现 live Tool hot-plug。 6. catalog 规模扩大并取得板上内存/启动时长证据后,再设计 lazy load、pinning、LRU 或 residency policy,不提前把这些策略写进 v1。 -7. 最后补 distribution index、版本 channel、更新策略,以及 macOS/Simulator/ESP32 +7. 最后补 distribution index、版本 channel、更新策略,以及 Simulator/ESP32 同一 package 的兼容性验证。 仍明确延后:ESP32 source editing、Agent-authored Tools、通用 live Tool hot-plug,以及 diff --git a/docs/esp32-p4-port.md b/docs/esp32-p4-port.md index 41d2968..cf66cfd 100644 --- a/docs/esp32-p4-port.md +++ b/docs/esp32-p4-port.md @@ -1,10 +1,9 @@ # ESP32-P4 host -Pocket Pi has two agent profiles and three hosts: +Pocket Pi has one embedded agent profile and two hosts: | Target | Agent profile | Runs on | |---|---|---| -| `macos` | full `pi-coding-agent` | macOS | | `esp32-p4` | bounded `pi-agent-core` | ESP32-P4 | | `esp32-p4-sim` | bounded `pi-agent-core` | macOS | @@ -19,7 +18,6 @@ The physical host selects `UartBackend` for a Mac Codex/Claude Code bridge or host adapters; they do not belong in the UI or embedded Agent core. ```sh -cargo xtask build macos cargo xtask build esp32-p4 cargo xtask build esp32-p4-sim cargo xtask run esp32-p4-sim diff --git a/hosts/macos/Cargo.toml b/hosts/macos/Cargo.toml deleted file mode 100644 index 0b04235..0000000 --- a/hosts/macos/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "pocket-pi-macos" -version = "0.1.0" -edition.workspace = true -license.workspace = true -repository.workspace = true -publish = false - -[dependencies] -pocket-pi = { path = "../../crates/pocket-pi" } -serde_json.workspace = true diff --git a/hosts/macos/src/main.rs b/hosts/macos/src/main.rs deleted file mode 100644 index ec1972b..0000000 --- a/hosts/macos/src/main.rs +++ /dev/null @@ -1,85 +0,0 @@ -use std::cell::RefCell; -use std::io::Write; -use std::rc::Rc; -use std::time::{Duration, Instant}; - -use pocket_pi::{PiRuntime, ToolResult}; - -fn main() -> Result<(), String> { - let prompt = std::env::args().skip(1).collect::>().join(" "); - let prompt = if prompt.is_empty() { - "In one short sentence, what are you?".to_owned() - } else { - prompt - }; - - let mut runtime = PiRuntime::new()?; - runtime.register_tool("current_time", |_| { - let seconds = std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .map(|duration| duration.as_secs()) - .unwrap_or_default(); - ToolResult::text(format!("unix seconds: {seconds}")) - }); - let error = Rc::new(RefCell::new(None)); - let callback_error = error.clone(); - runtime.on_event(move |event| match event.kind.as_str() { - "text" => { - if let Some(delta) = event.value.get("delta").and_then(|value| value.as_str()) { - print!("{delta}"); - std::io::stdout().flush().ok(); - } - } - "end" => println!(), - "error" => { - let message = event - .value - .get("message") - .and_then(|value| value.as_str()) - .unwrap_or(&event.raw) - .to_owned(); - eprintln!("\n{message}"); - *callback_error.borrow_mut() = Some(message); - } - _ => {} - }); - - let config = if let Ok(api_key) = std::env::var("OPENAI_API_KEY") { - serde_json::json!({ - "provider": "openai", - "model": std::env::var("OPENAI_MODEL").unwrap_or_else(|_| "gpt-5.6".into()), - "apiKey": api_key, - "systemPrompt": "You are Pocket Pi on macOS. Be concise." - }) - } else if let Ok(api_key) = std::env::var("ANTHROPIC_API_KEY") { - serde_json::json!({ - "provider": "anthropic", - "model": std::env::var("ANTHROPIC_MODEL") - .unwrap_or_else(|_| "claude-opus-4-8".into()), - "apiKey": api_key, - "systemPrompt": "You are Pocket Pi on macOS. Be concise." - }) - } else { - serde_json::json!({ - "model": "offline", - "scripted": {"steps": [{"text": "Pocket Pi desktop runtime is ready."}]} - }) - }; - runtime.boot(&config.to_string())?; - println!("you> {prompt}\npi > "); - runtime.prompt(&prompt)?; - - let started = Instant::now(); - while !runtime.is_idle() && started.elapsed() < Duration::from_secs(120) { - runtime.pump()?; - std::thread::sleep(Duration::from_millis(33)); - } - runtime.pump().ok(); - if let Some(message) = error.borrow_mut().take() { - return Err(format!("model backend failed: {message}")); - } - if !runtime.is_idle() { - return Err("model backend timed out after 120 seconds".into()); - } - Ok(()) -} diff --git a/js/.gitignore b/js/.gitignore deleted file mode 100644 index 3c3629e..0000000 --- a/js/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/js/build.mjs b/js/build.mjs deleted file mode 100644 index 82f7c5f..0000000 --- a/js/build.mjs +++ /dev/null @@ -1,91 +0,0 @@ -// Unified build for all of Pocket Pi's JavaScript guest layer. -// -// Sources are TypeScript under js/src/; this emits the artifacts the Rust crate -// embeds. Run with plain Node: `npm install && node js/build.mjs`. -// -// src/runtime/** → crates/pocket-pi/js/** (per-file transpile; embedded via include_str!) -// src/pi-full/{driver,ext-probe,persist-probe} -// → crates/pocket-pi/js/pi-full/** (test harness scripts) -// src/pi-full/entry → crates/pocket-pi/js/pi-full.bundle.js(.gz) (full unmodified pi) -// -// pi is a real, unmodified npm dependency (package.json) — sync with `npm update` -// and rerun this. Runtime modules and the compressed full-pi bundle are committed -// so `cargo` builds Rust-only; only the raw full-pi bundle is git-ignored. - -import * as esbuild from "esbuild"; -import { execFileSync } from "node:child_process"; -import { gzipSync } from "node:zlib"; -import { readFileSync, writeFileSync, readdirSync, statSync, existsSync } from "node:fs"; -import { fileURLToPath } from "node:url"; -import { dirname, join, relative } from "node:path"; - -const here = dirname(fileURLToPath(import.meta.url)); -const root = join(here, ".."); -const outJs = join(root, "crates/pocket-pi/js"); -const nm = join(here, "node_modules"); - -if (!existsSync(join(nm, "@earendil-works/pi-coding-agent"))) { - console.error("pi packages not installed — run `npm install` in js/ first."); - process.exit(1); -} - -const mb = (n) => (n / 1048576).toFixed(1); -function walk(dir) { - return readdirSync(dir).flatMap((name) => { - const p = join(dir, name); - return statSync(p).isDirectory() ? walk(p) : [p]; - }); -} - -// 1. Typecheck gate over Pocket Pi's own orchestration code (see tsconfig.json). -console.log("• typecheck (tsc --noEmit)"); -execFileSync(join(nm, ".bin/tsc"), ["--noEmit", "-p", join(here, "tsconfig.json")], { stdio: "inherit" }); - -// 2. Runtime glue: per-file transpile (type-strip), structure preserved. These -// are loaded individually as modules by the runtime, so no bundling. -const runtimeSrc = join(here, "src/runtime"); -console.log("• runtime glue → crates/pocket-pi/js"); -await esbuild.build({ - entryPoints: walk(runtimeSrc).filter((f) => f.endsWith(".ts")), - outdir: outJs, - outbase: runtimeSrc, - bundle: false, - format: "esm", - platform: "neutral", - logLevel: "warning", -}); - -// 3. The host harness (PocketPi on full pi) + test-harness scripts, eval'd as -// plain scripts by the runtime / the Rust tests. -console.log("• harness scripts → crates/pocket-pi/js/pi-full"); -await esbuild.build({ - entryPoints: ["host", "driver", "ext-probe", "persist-probe"].map((n) => join(here, `src/pi-full/${n}.ts`)), - outdir: join(outJs, "pi-full"), - bundle: false, - format: "esm", - platform: "neutral", - logLevel: "warning", -}); - -// 4. Full, unmodified pi-coding-agent bundle. Whitespace-minify only (identifier -// and syntax minification emit tokens the embedded QuickJS parser rejects); -// line-limit wraps the long lines QuickJS chokes on; undici → stub. -console.log("• full pi bundle → pi-full.bundle.js(.gz)"); -const fullOut = join(outJs, "pi-full.bundle.js"); -await esbuild.build({ - entryPoints: [join(here, "src/pi-full/entry.ts")], - outfile: fullOut, - bundle: true, - format: "esm", - platform: "node", - legalComments: "none", - minifyWhitespace: true, - lineLimit: 500, - alias: { undici: join(here, "src/pi-full/undici-stub.ts") }, - logLevel: "warning", -}); -const src = readFileSync(fullOut); -const gz = gzipSync(src, { level: 9 }); -writeFileSync(`${fullOut}.gz`, gz); - -console.log(`\n✓ built. full pi: ${mb(src.length)} MB minified → ${mb(gz.length)} MB gzip`); diff --git a/js/env.d.ts b/js/env.d.ts deleted file mode 100644 index 7923ee2..0000000 --- a/js/env.d.ts +++ /dev/null @@ -1,91 +0,0 @@ -// Ambient types for Pocket Pi's runtime environment. The glue is a deliberately -// loose Node/Web compatibility layer over QuickJS + the native `host`/`__node` -// ops, so the runtime surface is typed as `any` — this is shim code, not typed -// application logic. Its job is to let the TypeScript build (transpile + -// `tsc --noEmit` gate) run over the sources. - -export {}; - -declare global { - // Native surface mounted by Rust. - var host: any; - var __node: any; - - // Node/Web globals the glue defines on globalThis (and reads back). - var process: any; - var Buffer: any; - var __nodeBuffer: any; - var global: any; - var require: any; - var console: any; - var performance: any; - var crypto: any; - - var fetch: any; - var Headers: any; - var Request: any; - var Response: any; - var URL: any; - var URLSearchParams: any; - var ReadableStream: any; - var TextEncoder: any; - var TextDecoder: any; - var Blob: any; - var File: any; - var FormData: any; - var AbortController: any; - var AbortSignal: any; - var Event: any; - var EventTarget: any; - var CustomEvent: any; - var MessagePort: any; - var MessageChannel: any; - var DOMException: any; - - var atob: any; - var btoa: any; - var structuredClone: any; - var queueMicrotask: any; - var setTimeout: any; - var clearTimeout: any; - var setInterval: any; - var clearInterval: any; - var setImmediate: any; - var clearImmediate: any; - - // Pocket Pi coordination surface (guest entry points + host-poll flags). - var PocketPi: any; - var PiFull: any; - var __builtinExports: any; - var __cjsRequire: any; - var __cjsCache: any; - var __catpiTimers: any; - var __catpiPump: any; - var __catpiFetchPump: any; - - // Test-harness globals (driver / probes exchange results with the Rust side). - var __OPENAI_KEY: any; - var __piRun: any; - var __piResult: any; - var __piError: any; - var __piDone: any; - var __piBind: any; - var __piLog: any; - var __piLastEvent: any; - var __piFullLoaded: any; - var __piLoadExtension: any; - var __piExtResult: any; - var __piExtError: any; - var __piExtDone: any; - var __piPersist: any; - var __piPersistResult: any; - var __piPersistError: any; -} - -// The `node:*` builtins are served by Pocket Pi's own loader at runtime; type -// them loosely so cross-builtin imports (`import { EventEmitter } from -// "node:events"`) don't need @types/node. -declare module "node:*" { - const anything: any; - export = anything; -} diff --git a/js/package-lock.json b/js/package-lock.json deleted file mode 100644 index 4f06da4..0000000 --- a/js/package-lock.json +++ /dev/null @@ -1,3619 +0,0 @@ -{ - "name": "pocket-pi-guest", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "pocket-pi-guest", - "dependencies": { - "@earendil-works/pi-agent-core": "0.81.1", - "@earendil-works/pi-ai": "0.81.1", - "@earendil-works/pi-coding-agent": "0.81.1", - "@google/genai": "^2.12.0", - "@mistralai/mistralai": "^2.5.0", - "@opentelemetry/api": "^1.9.1", - "@opentelemetry/api-logs": "^0.220.0" - }, - "devDependencies": { - "esbuild": "0.24.2", - "typescript": "5.7.2" - } - }, - "node_modules/@anthropic-ai/sdk": { - "version": "0.91.1", - "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.91.1.tgz", - "integrity": "sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==", - "license": "MIT", - "dependencies": { - "json-schema-to-ts": "^3.1.1" - }, - "bin": { - "anthropic-ai-sdk": "bin/cli" - }, - "peerDependencies": { - "zod": "^3.25.0 || ^4.0.0" - }, - "peerDependenciesMeta": { - "zod": { - "optional": true - } - } - }, - "node_modules/@aws-crypto/sha256-browser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", - "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-js": "^5.2.0", - "@aws-crypto/supports-web-crypto": "^5.2.0", - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/sha256-js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-crypto/supports-web-crypto": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", - "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-sdk/core": { - "version": "3.975.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.975.3.tgz", - "integrity": "sha512-7ur3kCKuvPLqlsZ2XlvnNBVQ7KkpSu6Y6dOTwSPHLrFpTEfZM8isLBJc4cgv96WB7GifeVM436mpycwxBd2vEA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.974.2", - "@aws-sdk/xml-builder": "^3.972.36", - "@aws/lambda-invoke-store": "^0.3.0", - "@smithy/core": "^3.29.4", - "@smithy/signature-v4": "^5.6.5", - "@smithy/types": "^4.16.1", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.59", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.59.tgz", - "integrity": "sha512-Ny5e4Mfh3QPmiAc0AiUe+cbTXDlxkU3Rc+EpWOfyWeWEy6yp7Fa1KmfNeCc+1a8by9zQ9gtohmiQUkMPScF3ng==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.975.3", - "@aws-sdk/types": "^3.974.2", - "@smithy/core": "^3.29.4", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.61", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.61.tgz", - "integrity": "sha512-8jAjgStl5Ytq4+HF3X/9f+EmRinaRbGRRtQGktlPfBRVx73H+R1y48vIeXerQtYGFaUqkEp3fT6jP854rVO2yQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.975.3", - "@aws-sdk/types": "^3.974.2", - "@smithy/core": "^3.29.4", - "@smithy/fetch-http-handler": "^5.6.6", - "@smithy/node-http-handler": "^4.9.6", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.973.4", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.973.4.tgz", - "integrity": "sha512-e6ZvVsj90aRALf1kHP+J4iqC1496ZpVgqI/+u0LJ5HL7q7ATauGy4gdDvRCP13L1pN/fMiZLah162PGIYkbUVQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.975.3", - "@aws-sdk/credential-provider-env": "^3.972.59", - "@aws-sdk/credential-provider-http": "^3.972.61", - "@aws-sdk/credential-provider-login": "^3.972.66", - "@aws-sdk/credential-provider-process": "^3.972.59", - "@aws-sdk/credential-provider-sso": "^3.973.3", - "@aws-sdk/credential-provider-web-identity": "^3.972.65", - "@aws-sdk/nested-clients": "^3.997.33", - "@aws-sdk/types": "^3.974.2", - "@smithy/core": "^3.29.4", - "@smithy/credential-provider-imds": "^4.4.9", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.66", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.66.tgz", - "integrity": "sha512-g2fsqm87r/nKthLZ0VkkDBElkGg0PvSa8d97HQ6EilMbJTZ6hxa8FxkSZyJfgPfFdZn0TTmkOffQmTSUcAHIng==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.975.3", - "@aws-sdk/nested-clients": "^3.997.33", - "@aws-sdk/types": "^3.974.2", - "@smithy/core": "^3.29.4", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.70", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.70.tgz", - "integrity": "sha512-3xzvkGdykBunxqh8WudmUpSyLWvIhfI6aBQo1b5rb3mDO5mNLadK+0hiI0qBQBMVynJbfLO+Ajy9dztMwy9O8w==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.59", - "@aws-sdk/credential-provider-http": "^3.972.61", - "@aws-sdk/credential-provider-ini": "^3.973.4", - "@aws-sdk/credential-provider-process": "^3.972.59", - "@aws-sdk/credential-provider-sso": "^3.973.3", - "@aws-sdk/credential-provider-web-identity": "^3.972.65", - "@aws-sdk/types": "^3.974.2", - "@smithy/core": "^3.29.4", - "@smithy/credential-provider-imds": "^4.4.9", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.59", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.59.tgz", - "integrity": "sha512-DlZF2/MhLlatDdlrIy3CUCpfdbLrKx+3SMjVo+WyHnPpwzkc/M3vwAHw4OVJf7DMvO+4vfRqSCMc/E9I1auN0g==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.975.3", - "@aws-sdk/types": "^3.974.2", - "@smithy/core": "^3.29.4", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.973.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.973.3.tgz", - "integrity": "sha512-hmdDHoy2G5Es2e8IgelNMYUuSQI6uCIAKZMJ2u2PdKDhxvbk1uWD/g4+R7R5c/tJfKEB1+KjjWiaoCr/S+ZTiQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.975.3", - "@aws-sdk/nested-clients": "^3.997.33", - "@aws-sdk/token-providers": "3.1088.0", - "@aws-sdk/types": "^3.974.2", - "@smithy/core": "^3.29.4", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers": { - "version": "3.1088.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1088.0.tgz", - "integrity": "sha512-4ObatWt2qpJg5FBk4LOOKrTQYzaqeewAtdO3r9ZO8lH9YqLtpTzLyIdy0mJ+nVdfYOnqISkKNfmzP22bNDhwyw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.975.3", - "@aws-sdk/nested-clients": "^3.997.33", - "@aws-sdk/types": "^3.974.2", - "@smithy/core": "^3.29.4", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.65", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.65.tgz", - "integrity": "sha512-gHQb/Kt0chjk/JQDa/GJDqmAvEuVn8n7z10wK2h0LFM9TUDRkohgOO4aEF+s2sBLM0br7Cl5W6P7phgjrrJvLQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.975.3", - "@aws-sdk/nested-clients": "^3.997.33", - "@aws-sdk/types": "^3.974.2", - "@smithy/core": "^3.29.4", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/eventstream-handler-node": { - "version": "3.972.29", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.972.29.tgz", - "integrity": "sha512-t3tKQRTVXsI2QNPE3CaNjHl0wRO9Xi3acZkAyti2RQsiFmZ9Gi0kArX2ighlRJ1BtDVuul413gThAgzyTfgmWA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.974.2", - "@smithy/core": "^3.29.4", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/middleware-eventstream": { - "version": "3.972.24", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.972.24.tgz", - "integrity": "sha512-oykin4mDWxNOuYQ7SF1cHzgYeuFEkF4cdRwgvjFFbIklkx09qIFBiOgsORafG9sXZFO3TayMmQuAQYgADXhI8w==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.974.2", - "@smithy/core": "^3.29.4", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/middleware-websocket": { - "version": "3.972.41", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-websocket/-/middleware-websocket-3.972.41.tgz", - "integrity": "sha512-LSbGvvYmjc4Br9BPYI2dTLnIclmrSiQbahkP4D6nRGVEv4qsCZ8csVuKBPVEEFCVD+EEngGh8ROls6XpumtwMg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.975.3", - "@aws-sdk/types": "^3.974.2", - "@smithy/core": "^3.29.4", - "@smithy/fetch-http-handler": "^5.6.6", - "@smithy/signature-v4": "^5.6.5", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@aws-sdk/nested-clients": { - "version": "3.997.33", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.33.tgz", - "integrity": "sha512-dVZOroI/r3/ENvqNGgjMPul+jjlz9GddfVusgTXlVjfZj5isibOxecLkGQbRPp8XOuX+RAfjXLFgPkD1JS5xrw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.975.3", - "@aws-sdk/signature-v4-multi-region": "^3.996.41", - "@aws-sdk/types": "^3.974.2", - "@smithy/core": "^3.29.4", - "@smithy/fetch-http-handler": "^5.6.6", - "@smithy/node-http-handler": "^4.9.6", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.996.41", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.41.tgz", - "integrity": "sha512-QMUytg+FQMGouc8gHS00KoYih3+N6cqmVI/pQGOIo7Nr7OpQaiXjSYOuL+vsPZ1tymY4LAQ8MYcHJmws5LRxng==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.974.2", - "@smithy/signature-v4": "^5.6.5", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/types": { - "version": "3.974.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.974.2.tgz", - "integrity": "sha512-3W6IUtSxFbH6X7Wb7DzGCV5QiFQsd0g8bOfntpmDxQlzBoKWUMBu/JPQR0DwkE+Hpnxd6db1tXbOwdeHddG6cA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/util-locate-window": { - "version": "3.965.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.8.tgz", - "integrity": "sha512-uUbMs1cBZPafD0ohUj6EwNf0fPZ534NvBxHox4hjX+0Rxq5paSYUem7+hi833pYrzrcnBATKIYpR02MDXT5M9g==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/xml-builder": { - "version": "3.972.36", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.36.tgz", - "integrity": "sha512-RdGmS1GLrtaTOLE1ElSluMldNrpk9Emq6uYs8SS8iHlu5xTAmM9rRkM91o48+rIRryBtyO9t+uLYCoMG6jVMVA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws/lambda-invoke-store": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.3.0.tgz", - "integrity": "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", - "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@earendil-works/pi-agent-core": { - "version": "0.81.1", - "resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.81.1.tgz", - "integrity": "sha512-yqbh68CyhqxMov/jUogFJfMqlu2Gd37GAki+tr59YCmAPHfomiCA5ESzusXtpGzABeiZFC/OrRdQ4GwCCOMIHA==", - "license": "MIT", - "dependencies": { - "@earendil-works/pi-ai": "^0.81.1", - "ignore": "7.0.5", - "typebox": "1.1.38", - "yaml": "2.9.0" - }, - "engines": { - "node": ">=22.19.0" - } - }, - "node_modules/@earendil-works/pi-agent-core/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@earendil-works/pi-agent-core/node_modules/typebox": { - "version": "1.1.38", - "resolved": "https://registry.npmjs.org/typebox/-/typebox-1.1.38.tgz", - "integrity": "sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==", - "license": "MIT" - }, - "node_modules/@earendil-works/pi-ai": { - "version": "0.81.1", - "resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.81.1.tgz", - "integrity": "sha512-hzHE7Z8l5mgJk+ke67Lge0rwS2+wbKJrFKl9o5M1R1rh33+cCT7D1AHz1OAtX5wFs90E1/BTGhyJRTUHaMxGvQ==", - "license": "MIT", - "dependencies": { - "@anthropic-ai/sdk": "0.91.1", - "@aws-sdk/client-bedrock-runtime": "3.1048.0", - "@google/genai": "1.52.0", - "@mistralai/mistralai": "2.2.6", - "@opentelemetry/api": "1.9.0", - "@smithy/node-http-handler": "4.7.3", - "http-proxy-agent": "7.0.2", - "https-proxy-agent": "7.0.6", - "openai": "6.26.0", - "partial-json": "0.1.7", - "typebox": "1.1.38" - }, - "bin": { - "pi-ai": "dist/cli.js" - }, - "engines": { - "node": ">=22.19.0" - } - }, - "node_modules/@earendil-works/pi-ai/node_modules/@aws-sdk/client-bedrock-runtime": { - "version": "3.1048.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.1048.0.tgz", - "integrity": "sha512-u+NT61JZEkRFtpL0CAw1N1dwxnaLgwVXQl/zjJxTGgLyS/jTIdg2SdoEoCTHxgDyCnqa1HEi9QOoE9/pYRNpOQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.974.11", - "@aws-sdk/credential-provider-node": "^3.972.42", - "@aws-sdk/eventstream-handler-node": "^3.972.16", - "@aws-sdk/middleware-eventstream": "^3.972.12", - "@aws-sdk/middleware-websocket": "^3.972.19", - "@aws-sdk/token-providers": "3.1048.0", - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/fetch-http-handler": "^5.4.2", - "@smithy/node-http-handler": "^4.7.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-ai/node_modules/@aws-sdk/token-providers": { - "version": "3.1048.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1048.0.tgz", - "integrity": "sha512-k0y/GcuesuSfWyUM0WamrGyeZmltRYaPbHO82UDA6mZ/doB+FOHKutikPAtSXMn/hDz970cF+iRuuiYO9VEbAA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.974.11", - "@aws-sdk/nested-clients": "^3.997.9", - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-ai/node_modules/@google/genai": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.52.0.tgz", - "integrity": "sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "google-auth-library": "^10.3.0", - "p-retry": "^4.6.2", - "protobufjs": "^7.5.4", - "ws": "^8.18.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "@modelcontextprotocol/sdk": "^1.25.2" - }, - "peerDependenciesMeta": { - "@modelcontextprotocol/sdk": { - "optional": true - } - } - }, - "node_modules/@earendil-works/pi-ai/node_modules/@mistralai/mistralai": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-2.2.6.tgz", - "integrity": "sha512-W8pX7zHxjJvMIpw8JMxeJEleapXX0Q9NPszdNzqkM3MIEoIGPObdodujj+WHteXEvGfaP/AMwlNyRfEzSY6dQQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/semantic-conventions": "^1.40.0", - "ws": "^8.18.0", - "zod": "^3.25.0 || ^4.0.0", - "zod-to-json-schema": "^3.25.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.9.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - } - } - }, - "node_modules/@earendil-works/pi-ai/node_modules/@opentelemetry/api": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", - "license": "Apache-2.0", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@earendil-works/pi-ai/node_modules/@smithy/node-http-handler": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.7.3.tgz", - "integrity": "sha512-/jPhevcTFPMVl6KNjbaI47iOg1zxC7IsnX4PQDGVZKMFceOXtB8IEYaB7a9VvkP/3oC60WzTeKocvSI7vLT0vA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.24.3", - "@smithy/types": "^4.14.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@earendil-works/pi-ai/node_modules/typebox": { - "version": "1.1.38", - "resolved": "https://registry.npmjs.org/typebox/-/typebox-1.1.38.tgz", - "integrity": "sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==", - "license": "MIT" - }, - "node_modules/@earendil-works/pi-coding-agent": { - "version": "0.81.1", - "resolved": "https://registry.npmjs.org/@earendil-works/pi-coding-agent/-/pi-coding-agent-0.81.1.tgz", - "integrity": "sha512-r6ovAsZOgAqbC/aU6s+/dPnv/sGZBuWyZNvi3pXjpbuX5wvp3XvGkQI7/VLvX2o9XpmpFaPUxKNym1WfkN/P8A==", - "hasShrinkwrap": true, - "license": "MIT", - "dependencies": { - "@earendil-works/pi-agent-core": "^0.81.1", - "@earendil-works/pi-ai": "^0.81.1", - "@earendil-works/pi-tui": "^0.81.1", - "@silvia-odwyer/photon-node": "0.3.4", - "chalk": "5.6.2", - "cross-spawn": "7.0.6", - "diff": "8.0.4", - "glob": "13.0.6", - "highlight.js": "10.7.3", - "hosted-git-info": "9.0.3", - "ignore": "7.0.5", - "jiti": "2.7.0", - "minimatch": "10.2.5", - "proper-lockfile": "4.1.2", - "semver": "7.8.0", - "typebox": "1.1.38", - "undici": "8.5.0", - "yaml": "2.9.0" - }, - "bin": { - "pi": "dist/cli.js" - }, - "engines": { - "node": ">=22.19.0" - }, - "optionalDependencies": { - "@mariozechner/clipboard": "0.3.9" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@anthropic-ai/sdk": { - "version": "0.91.1", - "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.91.1.tgz", - "integrity": "sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==", - "license": "MIT", - "dependencies": { - "json-schema-to-ts": "^3.1.1" - }, - "bin": { - "anthropic-ai-sdk": "bin/cli" - }, - "peerDependencies": { - "zod": "^3.25.0 || ^4.0.0" - }, - "peerDependenciesMeta": { - "zod": { - "optional": true - } - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/crc32": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", - "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/sha256-browser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", - "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-js": "^5.2.0", - "@aws-crypto/supports-web-crypto": "^5.2.0", - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/sha256-js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/supports-web-crypto": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", - "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/client-bedrock-runtime": { - "version": "3.1048.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.1048.0.tgz", - "integrity": "sha512-u+NT61JZEkRFtpL0CAw1N1dwxnaLgwVXQl/zjJxTGgLyS/jTIdg2SdoEoCTHxgDyCnqa1HEi9QOoE9/pYRNpOQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.974.11", - "@aws-sdk/credential-provider-node": "^3.972.42", - "@aws-sdk/eventstream-handler-node": "^3.972.16", - "@aws-sdk/middleware-eventstream": "^3.972.12", - "@aws-sdk/middleware-websocket": "^3.972.19", - "@aws-sdk/token-providers": "3.1048.0", - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/fetch-http-handler": "^5.4.2", - "@smithy/node-http-handler": "^4.7.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/core": { - "version": "3.974.11", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.11.tgz", - "integrity": "sha512-QpnINq5FZH6EOaDEkmHdT7eUunbvD27pDNQypaWjFyYz7Zl1q3UCMQErBZxpmfGfI7MvI2TlK8KTkgNpv8b1ug==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.8", - "@aws-sdk/xml-builder": "^3.972.24", - "@aws/lambda-invoke-store": "^0.2.2", - "@smithy/core": "^3.24.2", - "@smithy/signature-v4": "^5.4.2", - "@smithy/types": "^4.14.1", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.37", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.37.tgz", - "integrity": "sha512-/jpPvEh6f7ntmIzf7dNxoNX6Q8vt8UpesCjbW6mFfk4V1NW6bIy9qxcQ6WbA8As5yQhsZOe+xeNd4xHX8kdY2Q==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.974.11", - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.39", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.39.tgz", - "integrity": "sha512-pIgTpisWyWg7X1bUbzSjuUYosYTD0Ghz2M0hkSTmb3a6i3qV3uU+NYJPI/E2XSC0HcsZh5rsLPzeXrkb2DS0Cg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.974.11", - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/fetch-http-handler": "^5.4.2", - "@smithy/node-http-handler": "^4.7.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.972.41", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.41.tgz", - "integrity": "sha512-u2tyjaxJJzW8UtW4SM1ZcPMDwO6y+kV+llvou+Adts0FAKyzes5jG4izQN+KX3yE8ZROpS5y1LJ//xL2iSf76w==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.974.11", - "@aws-sdk/credential-provider-env": "^3.972.37", - "@aws-sdk/credential-provider-http": "^3.972.39", - "@aws-sdk/credential-provider-login": "^3.972.41", - "@aws-sdk/credential-provider-process": "^3.972.37", - "@aws-sdk/credential-provider-sso": "^3.972.41", - "@aws-sdk/credential-provider-web-identity": "^3.972.41", - "@aws-sdk/nested-clients": "^3.997.9", - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/credential-provider-imds": "^4.3.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.41", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.41.tgz", - "integrity": "sha512-0LBitxXiAiaE5nlFPfpNIww/8FRY/I7WIndWsc9GmNFOM7cE1wNpVNQEGEk9Outg5l8xl+3vybxFyUy4l9q/LQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.974.11", - "@aws-sdk/nested-clients": "^3.997.9", - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.42", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.42.tgz", - "integrity": "sha512-D4oon2zbqqsWOJUM99Gm3/ZyJ0IJvTXVN3PyloGb3kQEyI36fjCZheZj422lAgTWWd6TSHgiImLt3RIaLdv3dQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.37", - "@aws-sdk/credential-provider-http": "^3.972.39", - "@aws-sdk/credential-provider-ini": "^3.972.41", - "@aws-sdk/credential-provider-process": "^3.972.37", - "@aws-sdk/credential-provider-sso": "^3.972.41", - "@aws-sdk/credential-provider-web-identity": "^3.972.41", - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/credential-provider-imds": "^4.3.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.37", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.37.tgz", - "integrity": "sha512-7nVaHBUaWIddASYfVaA9O4D5ZVjewU3sCol9WqZPGfW0nR+0WqE0xHZnD/U2L33PlOB8KNXGKZ6wOES/QijKzg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.974.11", - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.972.41", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.41.tgz", - "integrity": "sha512-IOWAWEHe5LkjSKkkUUX9ciV6Y1scHTsnfEkdt5yyC4Slrc7AGbkLPrpntjqh18ksJAMOaVhoBsO8p2WyTcY2wQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.974.11", - "@aws-sdk/nested-clients": "^3.997.9", - "@aws-sdk/token-providers": "3.1048.0", - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.41", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.41.tgz", - "integrity": "sha512-mbACk9Yypa8nm4iGZLs0PofOXEcTDOUw6wDnsPXNDNSd2WNXs1tSo+6nc/fh0jLYdfVZThhBL98PHW4aXFsG5A==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.974.11", - "@aws-sdk/nested-clients": "^3.997.9", - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/eventstream-handler-node": { - "version": "3.972.16", - "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.972.16.tgz", - "integrity": "sha512-yedpPgKftqjU5SlPFHfqWpOw6xSCRieWRG1euWOlXn4WJxt2VX92VprCa2PpSOXjVCAeK6dTjW9eJRXVig9yGA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/middleware-eventstream": { - "version": "3.972.12", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.972.12.tgz", - "integrity": "sha512-tHTHHCHNrq6XklQvlzHBDJG4Iuhh7NVPRdtmvP+nHFA+5sxPlIDzlAHHgfoYHGvT3NXP1yVP/L5c3opUn6T3Qg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/middleware-websocket": { - "version": "3.972.19", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-websocket/-/middleware-websocket-3.972.19.tgz", - "integrity": "sha512-mkEhOGYozqKQkbFaVrjwr0faiwwZza1v5/jSY6Tucm3bD+uKTazIUH/4Yo6aMnQD2ua2W9cMP6s8mvwTcjtqHw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.974.11", - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/fetch-http-handler": "^5.4.2", - "@smithy/signature-v4": "^5.4.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/nested-clients": { - "version": "3.997.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.9.tgz", - "integrity": "sha512-jPR3rnmRI4hWYyzfmTGBr7NblMp8QYYeflHXba1H6+7CGrWVqWKQzaXFQ4qbExqPRsXN3T3L3JxFhr6aouXUGQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.974.11", - "@aws-sdk/signature-v4-multi-region": "^3.996.27", - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/fetch-http-handler": "^5.4.2", - "@smithy/node-http-handler": "^4.7.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.996.27", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.27.tgz", - "integrity": "sha512-0Phbz4t6HI3D3skxvG2uI+VWU034/nSIw1T8d+FPzzQG9EQTrw94o9mOKO2Gv3n3Oc8P7JD7RAUxkoneLWv5Eg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/signature-v4": "^5.4.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/token-providers": { - "version": "3.1048.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1048.0.tgz", - "integrity": "sha512-k0y/GcuesuSfWyUM0WamrGyeZmltRYaPbHO82UDA6mZ/doB+FOHKutikPAtSXMn/hDz970cF+iRuuiYO9VEbAA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.974.11", - "@aws-sdk/nested-clients": "^3.997.9", - "@aws-sdk/types": "^3.973.8", - "@smithy/core": "^3.24.2", - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/types": { - "version": "3.973.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.8.tgz", - "integrity": "sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.14.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/util-locate-window": { - "version": "3.965.5", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.5.tgz", - "integrity": "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/xml-builder": { - "version": "3.972.24", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.24.tgz", - "integrity": "sha512-V8z5YcDPfsvzrBlj0xR1vhRtocblhYbqdreCJB/voGd4Sr5zjNAeWxexbnqVtskTJe0vFb5KMqbSL++ePl+zRw==", - "license": "Apache-2.0", - "dependencies": { - "@nodable/entities": "2.1.0", - "@smithy/types": "^4.14.1", - "fast-xml-parser": "5.7.3", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws/lambda-invoke-store": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz", - "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@babel/runtime": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", - "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-agent-core": { - "version": "0.81.1", - "resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.81.1.tgz", - "license": "MIT", - "dependencies": { - "@earendil-works/pi-ai": "^0.81.1", - "ignore": "7.0.5", - "typebox": "1.1.38", - "yaml": "2.9.0" - }, - "engines": { - "node": ">=22.19.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-ai": { - "version": "0.81.1", - "resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.81.1.tgz", - "license": "MIT", - "dependencies": { - "@anthropic-ai/sdk": "0.91.1", - "@aws-sdk/client-bedrock-runtime": "3.1048.0", - "@google/genai": "1.52.0", - "@mistralai/mistralai": "2.2.6", - "@opentelemetry/api": "1.9.0", - "@smithy/node-http-handler": "4.7.3", - "http-proxy-agent": "7.0.2", - "https-proxy-agent": "7.0.6", - "openai": "6.26.0", - "partial-json": "0.1.7", - "typebox": "1.1.38" - }, - "bin": { - "pi-ai": "dist/cli.js" - }, - "engines": { - "node": ">=22.19.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-tui": { - "version": "0.81.1", - "resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.81.1.tgz", - "license": "MIT", - "dependencies": { - "get-east-asian-width": "1.6.0", - "marked": "18.0.5" - }, - "engines": { - "node": ">=22.19.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@google/genai": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.52.0.tgz", - "integrity": "sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "google-auth-library": "^10.3.0", - "p-retry": "^4.6.2", - "protobufjs": "^7.5.4", - "ws": "^8.18.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "@modelcontextprotocol/sdk": "^1.25.2" - }, - "peerDependenciesMeta": { - "@modelcontextprotocol/sdk": { - "optional": true - } - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@mariozechner/clipboard/-/clipboard-0.3.9.tgz", - "integrity": "sha512-ABnA53mdfkGZwOFUdZNv2S0CWGO/EIuPj8Vv9xmBFmSYg/qFc7ihO6q5FcQjvoE67kZpWkEc4AhD6B/os04yuA==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@mariozechner/clipboard-darwin-arm64": "0.3.9", - "@mariozechner/clipboard-darwin-universal": "0.3.9", - "@mariozechner/clipboard-darwin-x64": "0.3.9", - "@mariozechner/clipboard-linux-arm64-gnu": "0.3.9", - "@mariozechner/clipboard-linux-arm64-musl": "0.3.9", - "@mariozechner/clipboard-linux-riscv64-gnu": "0.3.9", - "@mariozechner/clipboard-linux-x64-gnu": "0.3.9", - "@mariozechner/clipboard-linux-x64-musl": "0.3.9", - "@mariozechner/clipboard-win32-arm64-msvc": "0.3.9", - "@mariozechner/clipboard-win32-x64-msvc": "0.3.9" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-darwin-arm64": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-darwin-arm64/-/clipboard-darwin-arm64-0.3.9.tgz", - "integrity": "sha512-BfgV7vCEWZwJwZJw03r6bP5+tf0iI/ANuQYCxi9RNn7FrWB3yzGuMKCrNLRl6V761vXRdL8+OqZ0wd4TqlsNOQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-darwin-universal": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-darwin-universal/-/clipboard-darwin-universal-0.3.9.tgz", - "integrity": "sha512-BGGR4iA9Z2shAjI65eI5xtyb3LYNlDW9X3gxKxDbqtbnREohsrqznov6zpKoIrsRWpzlYVEdKphS7ksJ0/ndSQ==", - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-darwin-x64": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-darwin-x64/-/clipboard-darwin-x64-0.3.9.tgz", - "integrity": "sha512-4kURmCbS6nt8uYhtmWpUcJWyPHfmAr5dTpXD1nO3pIfa+TSQ9DbrGOYCKH+aEFW47XhQ4Vp8ZTszie+wfFvDKg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-arm64-gnu": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-arm64-gnu/-/clipboard-linux-arm64-gnu-0.3.9.tgz", - "integrity": "sha512-g59OkUGP2DDfCOIKypHeYgv2M55u/cKvXa5dSxFbEJ34XvIQMdcVmpKCkGUro3ZgefXiGVdwguvTMQGpHWzIXw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-arm64-musl": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-arm64-musl/-/clipboard-linux-arm64-musl-0.3.9.tgz", - "integrity": "sha512-AGuJdgKsmJdm4Pych7kv3sqe591ERRaAHW3xjLooiFzn8J+PxUyof++7YZrB5Y5tpnTO+K18Og3taj2NpluCRQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-riscv64-gnu": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-riscv64-gnu/-/clipboard-linux-riscv64-gnu-0.3.9.tgz", - "integrity": "sha512-DXBEAiuMpk7dhS1a9NzNxVAFi1vaKoPu7rQNgY8LIDLGrK3lnIp3nT10DUum+PKVJoJppIP+NAA8IZe4DMNDPw==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-x64-gnu": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-x64-gnu/-/clipboard-linux-x64-gnu-0.3.9.tgz", - "integrity": "sha512-WORrMLd6EpElEME7JRKfSaY34nW1P5LbdgK5YNCS1ncG2LqmITsSMEJ8nh2mpvxb3TxqbOOKgY7k9eMJYlW9Mw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-x64-musl": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-x64-musl/-/clipboard-linux-x64-musl-0.3.9.tgz", - "integrity": "sha512-/DHn+1DrfL6oRaPPWXaOKvonFFrni666fxd+zFqiQEfvBH0tsHVWjq9iqBk0oDp0qaPA72lIMy5BptxISBEhZQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-win32-arm64-msvc": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-win32-arm64-msvc/-/clipboard-win32-arm64-msvc-0.3.9.tgz", - "integrity": "sha512-O5FHD3ErkMwMhNzAfu3ggy0ug4z7btZuoQgwwxlzPrwV2bxlD6WDpqBY4NCgICAgZdDKdp+loUEKVAVt8aYnhQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-win32-x64-msvc": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-win32-x64-msvc/-/clipboard-win32-x64-msvc-0.3.9.tgz", - "integrity": "sha512-ihQC3EufqEY81vhXBgVBtK4prL+wc62zJsSvxrgz7K1hsdt6OObz6v9p3Rn1OG3GJksTTKMJF0u/guMISHPhSA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@mistralai/mistralai": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-2.2.6.tgz", - "integrity": "sha512-W8pX7zHxjJvMIpw8JMxeJEleapXX0Q9NPszdNzqkM3MIEoIGPObdodujj+WHteXEvGfaP/AMwlNyRfEzSY6dQQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/semantic-conventions": "^1.40.0", - "ws": "^8.18.0", - "zod": "^3.25.0 || ^4.0.0", - "zod-to-json-schema": "^3.25.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.9.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - } - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@nodable/entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/nodable" - } - ], - "license": "MIT" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@opentelemetry/api": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", - "license": "Apache-2.0", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@opentelemetry/semantic-conventions": { - "version": "1.41.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.41.1.tgz", - "integrity": "sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==", - "license": "Apache-2.0", - "engines": { - "node": ">=14" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "license": "BSD-3-Clause" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/codegen": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", - "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", - "license": "BSD-3-Clause" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/eventemitter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", - "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", - "license": "BSD-3-Clause" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/fetch": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", - "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "license": "BSD-3-Clause" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "license": "BSD-3-Clause" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/utf8": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz", - "integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==", - "license": "BSD-3-Clause" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@silvia-odwyer/photon-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@silvia-odwyer/photon-node/-/photon-node-0.3.4.tgz", - "integrity": "sha512-bnly4BKB3KDTFxrUIcgCLbaeVVS8lrAkri1pEzskpmxu9MdfGQTy8b8EgcD83ywD3RPMsIulY8xJH5Awa+t9fA==", - "license": "Apache-2.0" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/core": { - "version": "3.24.3", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.24.3.tgz", - "integrity": "sha512-Ep/7tPamGY8mgESE3LyLKtxJyy6U52WWAqr/3wial47Sj4u3PiIF73AOGI27UyLy9duTkhZbgzodOfLV4TduZg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^4.14.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/credential-provider-imds": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.3.3.tgz", - "integrity": "sha512-I2Bti0DKFo2IJyN28ijCsx51BAumEYR4/1yZ1FXyBygy9MqbnMqCev4JPth/MbpRfBSRAX35hITSnAdJRo1u5w==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.24.3", - "@smithy/types": "^4.14.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/fetch-http-handler": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.4.3.tgz", - "integrity": "sha512-F+DRf8IJazRJgYog2A/yJK7eYVc0rqTlRzO+5ZxjJd4WkZoKz0IJRncf7G6t1pdVT3kryJcwuTFhN1c5m6N47A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.24.3", - "@smithy/types": "^4.14.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/node-http-handler": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.7.3.tgz", - "integrity": "sha512-/jPhevcTFPMVl6KNjbaI47iOg1zxC7IsnX4PQDGVZKMFceOXtB8IEYaB7a9VvkP/3oC60WzTeKocvSI7vLT0vA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.24.3", - "@smithy/types": "^4.14.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/signature-v4": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.4.3.tgz", - "integrity": "sha512-53+75QuPl6DL+ct6vVEB51FDO5oulXr20TPV46VvJZg76lIlXNWfxi8j+G2V/t0I2qxCBOa3vX/8bmjrpFVo9g==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.24.3", - "@smithy/types": "^4.14.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/types": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.2.tgz", - "integrity": "sha512-P+otAxbV4CqBybp7EkcJCrig63yE2E7PuNVOmilVMRcx/O+QDzGULTrKsq4DV13gSfak9ObPrWaHl/9bL5YcWw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/@types/node": { - "version": "22.19.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz", - "integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/bignumber.js": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", - "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/bowser": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", - "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", - "license": "MIT" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "license": "BSD-3-Clause" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/diff": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", - "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/fast-xml-builder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz", - "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "dependencies": { - "path-expression-matcher": "^1.5.0", - "xml-naming": "^0.1.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/fast-xml-parser": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.3.tgz", - "integrity": "sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "dependencies": { - "@nodable/entities": "^2.1.0", - "fast-xml-builder": "^1.1.7", - "path-expression-matcher": "^1.5.0", - "strnum": "^2.2.3" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "license": "MIT", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/gaxios": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", - "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", - "license": "Apache-2.0", - "dependencies": { - "extend": "^3.0.2", - "https-proxy-agent": "^7.0.1", - "node-fetch": "^3.3.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/gcp-metadata": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", - "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", - "license": "Apache-2.0", - "dependencies": { - "gaxios": "^7.0.0", - "google-logging-utils": "^1.0.0", - "json-bigint": "^1.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/get-east-asian-width": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", - "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/glob": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", - "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.2.2", - "minipass": "^7.1.3", - "path-scurry": "^2.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/google-auth-library": { - "version": "10.6.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.2.tgz", - "integrity": "sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==", - "license": "Apache-2.0", - "dependencies": { - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^7.1.4", - "gcp-metadata": "8.1.2", - "google-logging-utils": "1.1.3", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/google-logging-utils": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", - "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", - "license": "Apache-2.0", - "engines": { - "node": ">=14" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", - "license": "BSD-3-Clause", - "engines": { - "node": "*" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/hosted-git-info": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.3.tgz", - "integrity": "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==", - "license": "ISC", - "dependencies": { - "lru-cache": "^11.1.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/jiti": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", - "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "license": "MIT", - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/json-schema-to-ts": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz", - "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.18.3", - "ts-algebra": "^2.0.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/jwa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", - "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/jws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", - "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", - "license": "MIT", - "dependencies": { - "jwa": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/long": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", - "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", - "license": "Apache-2.0" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/lru-cache": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.4.0.tgz", - "integrity": "sha512-W+R+kFL4HgVxONq2bhXPi3bGpzGe/yEhVOp233qw9wCRtgncJ15P3bC+e4zZMu4Cq7d+WAJjXGW0uUkifhcatA==", - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/marked": { - "version": "18.0.5", - "resolved": "https://registry.npmjs.org/marked/-/marked-18.0.5.tgz", - "integrity": "sha512-S6GcvALHg6K4ohtu4E7x0a1AqhAjp6cV8KhLSyN9qVapnzJkusVBxZRcIU9AeYsbe6P1hKDusSbEOzGyyuce6w==", - "license": "MIT", - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/minipass": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "deprecated": "Use your platform's native DOMException instead", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "license": "MIT", - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/openai": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-6.26.0.tgz", - "integrity": "sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==", - "license": "Apache-2.0", - "bin": { - "openai": "bin/cli" - }, - "peerDependencies": { - "ws": "^8.18.0", - "zod": "^3.25 || ^4.0" - }, - "peerDependenciesMeta": { - "ws": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "license": "MIT", - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/p-retry/node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "license": "MIT" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/partial-json": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/partial-json/-/partial-json-0.1.7.tgz", - "integrity": "sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==", - "license": "MIT" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/path-expression-matcher": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", - "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/path-scurry": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", - "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/proper-lockfile": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", - "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "retry": "^0.12.0", - "signal-exit": "^3.0.2" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/proper-lockfile/node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/protobufjs": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.4.tgz", - "integrity": "sha512-RJJPTTpvFfHcWLkIa2JFWK4XvtSzS0yEWDmunqHXli1h3JlkbcQZXDZdcWxv+JK3Xsl5/UFDPZ0iGm7DAengYw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.5", - "@protobufjs/eventemitter": "^1.1.1", - "@protobufjs/fetch": "^1.1.1", - "@protobufjs/float": "^1.0.2", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.1", - "@types/node": ">=13.7.0", - "long": "^5.3.2" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/strnum": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.3.0.tgz", - "integrity": "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/ts-algebra": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz", - "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==", - "license": "MIT" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/typebox": { - "version": "1.1.38", - "resolved": "https://registry.npmjs.org/typebox/-/typebox-1.1.38.tgz", - "integrity": "sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==", - "license": "MIT" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/undici": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-8.5.0.tgz", - "integrity": "sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==", - "license": "MIT", - "engines": { - "node": ">=22.19.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "license": "MIT" - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/ws": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", - "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/xml-naming": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz", - "integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/yaml": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", - "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/@earendil-works/pi-coding-agent/node_modules/zod-to-json-schema": { - "version": "3.25.2", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", - "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.25.28 || ^4" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", - "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", - "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", - "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", - "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", - "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", - "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", - "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", - "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", - "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", - "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", - "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", - "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", - "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", - "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", - "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", - "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", - "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", - "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", - "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", - "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", - "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", - "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", - "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", - "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", - "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@google/genai": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@google/genai/-/genai-2.12.0.tgz", - "integrity": "sha512-LUr972DZosqPUhf9Mb3CIVu/B99woD3QW6ZJV1T9aNgxaoimAZARmo+IyyDsxIL+zouFiYSdA4hzfEWXc9oNIQ==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "google-auth-library": "^10.3.0", - "p-retry": "^4.6.2", - "protobufjs": "^7.5.4", - "ws": "^8.18.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "@modelcontextprotocol/sdk": "^1.25.2" - }, - "peerDependenciesMeta": { - "@modelcontextprotocol/sdk": { - "optional": true - } - } - }, - "node_modules/@mistralai/mistralai": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-2.5.0.tgz", - "integrity": "sha512-S/r6tkiUHblaDJGsb84WS0ePTF2YHVta2EoTi1NJqHNt5mfRRS2uE4v7hCYV134+an+fk6WgG3+aFfinJbQBjQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/semantic-conventions": "^1.40.0", - "ws": "^8.18.0", - "zod": "^3.25.0 || ^4.0.0", - "zod-to-json-schema": "^3.25.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.9.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - } - } - }, - "node_modules/@opentelemetry/api": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", - "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", - "license": "Apache-2.0", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@opentelemetry/api-logs": { - "version": "0.220.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.220.0.tgz", - "integrity": "sha512-CmVa4ImJ+ynfrPMNaAXHET6Bhb44SwzmfyVJFq9ni2jgXJR/l7C6gfVFddNmHP+ZOkP9cf4f9DBe68qVLTHc9w==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api": "^1.3.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.43.0.tgz", - "integrity": "sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==", - "license": "Apache-2.0", - "engines": { - "node": ">=14" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", - "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", - "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", - "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz", - "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", - "license": "BSD-3-Clause" - }, - "node_modules/@smithy/core": { - "version": "3.29.6", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.29.6.tgz", - "integrity": "sha512-TO3w25cdGWBeYqKNDaqH3v4O3jjMPpKwf39YlG5X5xhqWfpOWJbi5gQi1lrllukuwohdhY0TPB8jBEv6UC50Vg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds": { - "version": "4.4.11", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.4.11.tgz", - "integrity": "sha512-6CUvZwS0tCcVCrcvh2TpwTXxmAkuY6JGNPeKODYRLjHtUUhFLGS3dNkNdRvT/ttJyqimqnhFMTS2nqp4pDZ7oQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.29.6", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/fetch-http-handler": { - "version": "5.6.8", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.6.8.tgz", - "integrity": "sha512-AFuLou893FesRZeQcKMh87P9x4PF2/ksPOYLLI1ctW7WJxm55SWInFSHAhaNRBPBmbgZyUcCCDKepBX+1jZBBw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.29.6", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/node-http-handler": { - "version": "4.9.8", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.9.8.tgz", - "integrity": "sha512-ArSSIN4t1wLutcIkHzaL6N11J7xpZK7W3T0pFz9cep9zIpEr9x5+lhJRcVUgObGI3OIMbnROq7w8bwzx+Nkf8A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.29.6", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/signature-v4": { - "version": "5.6.7", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.6.7.tgz", - "integrity": "sha512-32PmEsuZV9lz7SZk3gJcm+EfIAoIVu83AJyEzgALpwmSqLvuacdAu0fvCVNMbDbegyk1S0lHUDrMWIfR47Micw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.29.6", - "@smithy/types": "^4.16.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/types": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.16.1.tgz", - "integrity": "sha512-0JFs3V2y2M9tKW5na/qxe69Zv+uxLMO7QBbhxF/FHu/Gp2NFZAAL9tWl9PU02xxo07pb3G9FTyjNc6D5uZrJIg==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@types/node": { - "version": "26.1.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.1.tgz", - "integrity": "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==", - "license": "MIT", - "dependencies": { - "undici-types": "~8.3.0" - } - }, - "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "license": "MIT" - }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/bignumber.js": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", - "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/bowser": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", - "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", - "license": "MIT" - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "license": "BSD-3-Clause" - }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/esbuild": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", - "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.24.2", - "@esbuild/android-arm": "0.24.2", - "@esbuild/android-arm64": "0.24.2", - "@esbuild/android-x64": "0.24.2", - "@esbuild/darwin-arm64": "0.24.2", - "@esbuild/darwin-x64": "0.24.2", - "@esbuild/freebsd-arm64": "0.24.2", - "@esbuild/freebsd-x64": "0.24.2", - "@esbuild/linux-arm": "0.24.2", - "@esbuild/linux-arm64": "0.24.2", - "@esbuild/linux-ia32": "0.24.2", - "@esbuild/linux-loong64": "0.24.2", - "@esbuild/linux-mips64el": "0.24.2", - "@esbuild/linux-ppc64": "0.24.2", - "@esbuild/linux-riscv64": "0.24.2", - "@esbuild/linux-s390x": "0.24.2", - "@esbuild/linux-x64": "0.24.2", - "@esbuild/netbsd-arm64": "0.24.2", - "@esbuild/netbsd-x64": "0.24.2", - "@esbuild/openbsd-arm64": "0.24.2", - "@esbuild/openbsd-x64": "0.24.2", - "@esbuild/sunos-x64": "0.24.2", - "@esbuild/win32-arm64": "0.24.2", - "@esbuild/win32-ia32": "0.24.2", - "@esbuild/win32-x64": "0.24.2" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "license": "MIT", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/gaxios": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.2.0.tgz", - "integrity": "sha512-CUVb4wcYe+771XevyH6HtGmXFAGGKkIC3kswAP8Z1JCe0j80JMaTPZH930DWFrvo0atjh18Arc0pEyUCWa5bfg==", - "license": "Apache-2.0", - "dependencies": { - "extend": "^3.0.2", - "https-proxy-agent": "^7.0.1", - "node-fetch": "^3.3.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/gcp-metadata": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", - "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", - "license": "Apache-2.0", - "dependencies": { - "gaxios": "^7.0.0", - "google-logging-utils": "^1.0.0", - "json-bigint": "^1.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/google-auth-library": { - "version": "10.9.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.9.0.tgz", - "integrity": "sha512-xtvUqvINPhTaBm7nXqlYPcrMHJPm1lCNdSovxnKKhTm+4JsvQ+KGVYJViLoH9Yxu8w+T0Qv5HubzYT9BLrppJg==", - "license": "Apache-2.0", - "dependencies": { - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^7.1.4", - "gcp-metadata": "8.1.2", - "google-logging-utils": "1.1.3", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/google-logging-utils": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", - "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", - "license": "Apache-2.0", - "engines": { - "node": ">=14" - } - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "license": "MIT", - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, - "node_modules/json-schema-to-ts": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz", - "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.18.3", - "ts-algebra": "^2.0.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/jwa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", - "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", - "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", - "license": "MIT", - "dependencies": { - "jwa": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/long": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", - "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", - "license": "Apache-2.0" - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "deprecated": "Use your platform's native DOMException instead", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "license": "MIT", - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/openai": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-6.26.0.tgz", - "integrity": "sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==", - "license": "Apache-2.0", - "bin": { - "openai": "bin/cli" - }, - "peerDependencies": { - "ws": "^8.18.0", - "zod": "^3.25 || ^4.0" - }, - "peerDependenciesMeta": { - "ws": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "license": "MIT", - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/partial-json": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/partial-json/-/partial-json-0.1.7.tgz", - "integrity": "sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==", - "license": "MIT" - }, - "node_modules/protobufjs": { - "version": "7.6.5", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz", - "integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.5", - "@protobufjs/eventemitter": "^1.1.1", - "@protobufjs/fetch": "^1.1.1", - "@protobufjs/float": "^1.0.2", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.1", - "@types/node": ">=13.7.0", - "long": "^5.3.2" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/ts-algebra": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz", - "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==", - "license": "MIT" - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/typescript": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", - "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", - "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", - "license": "MIT" - }, - "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/ws": { - "version": "8.21.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", - "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/yaml": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", - "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, - "node_modules/zod": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", - "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.25.2", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", - "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.25.28 || ^4" - } - } - } -} diff --git a/js/package.json b/js/package.json deleted file mode 100644 index 10513e8..0000000 --- a/js/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "pocket-pi-guest", - "private": true, - "description": "Build inputs for Pocket Pi's guest bundle. pi's agent core is a real, unmodified upstream dependency here — sync it with `npm update` and rebuild with `node build.mjs`.", - "type": "module", - "scripts": { - "build": "node build.mjs" - }, - "dependencies": { - "@earendil-works/pi-agent-core": "0.81.1", - "@earendil-works/pi-ai": "0.81.1", - "@earendil-works/pi-coding-agent": "0.81.1", - "@google/genai": "^2.12.0", - "@mistralai/mistralai": "^2.5.0", - "@opentelemetry/api": "^1.9.1", - "@opentelemetry/api-logs": "^0.220.0" - }, - "devDependencies": { - "esbuild": "0.24.2", - "typescript": "5.7.2" - } -} diff --git a/js/src/pi-full/driver.ts b/js/src/pi-full/driver.ts deleted file mode 100644 index b31ff6c..0000000 --- a/js/src/pi-full/driver.ts +++ /dev/null @@ -1,144 +0,0 @@ -// Session harness: stand up an AgentSession from the unmodified bundled -// pi-coding-agent and (optionally) run one turn, load an extension, enable tools, -// or persist/resume — all through Pocket Pi's runtime (fetch → __catpiFetchPump → -// Rust HTTP hub → system proxy; our oxc loader for extension .ts; our fs for the -// session store). Loaded as a plain script after pi-full.bundle.js. Results land -// on globalThis for the Rust side to poll. -// -// __piRun(opts) — opts (object or JSON string): -// prompt?: string — send one turn (omit to just build the session) -// extensionPath?: string — absolute path to a .ts/.js extension (our loader) -// tools?: string[] — active tool names (omit → noTools:"all") -// sessionDir?: string — persist the session here (SessionManager.create) -// resume?: bool — resume the most recent session in sessionDir - -(function () { - const P = globalThis.PiFull as import("./entry").PiFullApi; - if (!P) throw new Error("PiFull not loaded — run the bundle first"); - - const MODEL = { - id: "gpt-5.6", - name: "GPT-5.6", - api: "openai-responses", - provider: "openai", - baseUrl: "https://api.openai.com/v1", - reasoning: false, - input: ["text"], - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - contextWindow: 400000, - maxTokens: 8192, - }; - const CWD = "/pocket-pi"; - const AGENT_DIR = "/pocket-pi/.pi"; - - globalThis.__piResult = ""; - globalThis.__piError = null; - globalThis.__piDone = false; - globalThis.__piBind = null; - globalThis.__piLog = []; - - const takeText = (msg) => { - if (!msg) return; - const content = msg.content; - if (Array.isArray(content)) { - let t = ""; - for (const b of content) { - if (!b) continue; - if (b.type === "text" && typeof b.text === "string") t += b.text; - else if (b.type === "error") t += "[ERROR] " + String(b.error || b.text || ""); - } - if (t) globalThis.__piResult = t; - } else if (typeof content === "string") { - globalThis.__piResult = content; - } - }; - - globalThis.__piRun = async function (opts) { - opts = typeof opts === "string" ? (opts.trim().startsWith("{") ? JSON.parse(opts) : { prompt: opts }) : (opts || {}); - try { - // 0.81: model + auth live on a ModelRuntime (in-memory, offline). The - // custom gpt-5.6 model is passed straight to createAgentSession; auth is a - // runtime API-key override for the "openai" provider. - const modelRuntime = await P.ModelRuntime.create({ modelsPath: null }); - if (globalThis.__OPENAI_KEY) await modelRuntime.setRuntimeApiKey("openai", globalThis.__OPENAI_KEY); - - const settingsManager = P.SettingsManager.inMemory({}); - const sessionManager = opts.sessionDir - ? (opts.resume ? P.SessionManager.continueRecent(CWD, opts.sessionDir) : P.SessionManager.create(CWD, opts.sessionDir)) - : P.SessionManager.inMemory(); - - // Load an extension through OUR loader (oxc .ts transpile), not jiti, and - // inject its factory — DefaultResourceLoader wires it via loadExtensionFromFactory. - const extensionFactories = []; - if (opts.extensionPath) { - const mod = await import(opts.extensionPath); - if (typeof mod.default === "function") extensionFactories.push(mod.default); - else throw new Error("extension has no default factory export: " + opts.extensionPath); - } - - const resourceLoader = new P.DefaultResourceLoader({ - cwd: CWD, - agentDir: AGENT_DIR, - settingsManager, - noExtensions: true, - noSkills: true, - noPromptTemplates: true, - noThemes: true, - noContextFiles: true, - extensionFactories, - }); - if (resourceLoader.reload) await resourceLoader.reload(); - - const sessionOpts: Record = { - model: MODEL, - modelRuntime, - settingsManager, - sessionManager, - resourceLoader, - cwd: CWD, - agentDir: AGENT_DIR, - thinkingLevel: "off", - }; - if (opts.tools) sessionOpts.tools = opts.tools; - else sessionOpts.noTools = "all"; - - const { session } = await P.createAgentSession(sessionOpts); - - // Report extension binding into the live session (offline-observable). - // Deliberate introspection into pi internals — cast past the private field. - try { - const runner = (session as any)._extensionRunner; - const regTools = runner && runner.getAllRegisteredTools ? runner.getAllRegisteredTools() : []; - globalThis.__piBind = { - hasAgentStart: !!(runner && runner.hasHandlers && runner.hasHandlers("agent_start")), - registeredTools: regTools.map((t) => t && (t.name || (t.definition && t.definition.name))).filter(Boolean), - }; - } catch (e) { - globalThis.__piBind = { error: String(e) }; - } - - session.subscribe((event) => { - try { - if (!event) return; - globalThis.__piLastEvent = event.type; - if (event.type === "message_update" || event.type === "message_end") { - // Error fields live on the assistant message (stopReason "error") — - // pi has no separate "error" event — and aren't on the base message - // union, so read them through a cast. - const msg = event.message as any; - if (msg && msg.role !== "user") takeText(msg); - if (msg && msg.stopReason === "error" && msg.errorMessage) { - globalThis.__piError = String(msg.errorMessage); - } - } - } catch {} - }); - - if (opts.prompt) await session.prompt(opts.prompt); - globalThis.__piDone = true; - } catch (e) { - globalThis.__piError = String((e && e.stack) || e); - globalThis.__piDone = true; - } - }; -})(); diff --git a/js/src/pi-full/entry.ts b/js/src/pi-full/entry.ts deleted file mode 100644 index 3afa021..0000000 --- a/js/src/pi-full/entry.ts +++ /dev/null @@ -1,48 +0,0 @@ -// Bundle entry for the unmodified pi-coding-agent core. -import { - createAgentSession, - SessionManager, - SettingsManager, - ModelRegistry, - DefaultResourceLoader, - createExtensionRuntime, - createEventBus, -} from "@earendil-works/pi-coding-agent"; -// A few symbols aren't on the top-level barrel (the package's exports map only -// exposes "." and "./hooks"). Reach them by file path — esbuild dedupes to the -// same bundled module, so pi stays unmodified. This is what lets Pocket Pi wire -// model/auth/extensions headlessly. -import { ModelRuntime } from "../../node_modules/@earendil-works/pi-coding-agent/dist/core/model-runtime.js"; -import { - AuthStorage, - InMemoryAuthStorageBackend, -} from "../../node_modules/@earendil-works/pi-coding-agent/dist/core/auth-storage.js"; -import { loadExtensionFromFactory } from "../../node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js"; -import { - fauxAssistantMessage, - fauxProvider, -} from "../../node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/faux.js"; - -const PiFull = { - createAgentSession, - SessionManager, - SettingsManager, - ModelRegistry, - ModelRuntime, - AuthStorage, - InMemoryAuthStorageBackend, - DefaultResourceLoader, - createExtensionRuntime, - createEventBus, - loadExtensionFromFactory, - fauxAssistantMessage, - fauxProvider, -}; -globalThis.PiFull = PiFull; -globalThis.__piFullLoaded = typeof createAgentSession === "function"; - -// The exact shape of globalThis.PiFull, carrying pi's REAL types. The harness -// (loaded as a separate script after this bundle) casts globalThis.PiFull to -// this, so its session/model/auth calls are typechecked against pi's actual API -// — a pi bump that changes those signatures fails `tsc`, not just a runtime test. -export type PiFullApi = typeof PiFull; diff --git a/js/src/pi-full/example-extension.ts b/js/src/pi-full/example-extension.ts deleted file mode 100644 index ecec491..0000000 --- a/js/src/pi-full/example-extension.ts +++ /dev/null @@ -1,42 +0,0 @@ -// A minimal pi extension in its normal, unmodified shape — a default-exported -// factory that receives the extension `pi` API and registers a tool and a -// lifecycle hook. Pocket Pi loads this through its OWN oxc TypeScript loader (the -// `.ts` is transpiled natively, no jiti), proving extension compatibility. - -interface Pi { - registerTool(tool: { - name: string; - description: string; - parameters: unknown; - execute: ( - toolCallId: string, - input: Record, - signal?: unknown, - onUpdate?: unknown, - ctx?: unknown, - ) => Promise; - }): void; - on(event: string, handler: (event: unknown) => void): void; -} - -export default (pi: Pi): void => { - pi.registerTool({ - name: "echo", - description: "Echo the given text back to the caller.", - parameters: { - type: "object", - properties: { text: { type: "string" } }, - required: ["text"], - }, - // pi calls execute(toolCallId, input, ...); the result must carry a `content` - // array of blocks (the shape pi converts into a tool-result message). - execute: async (_toolCallId, input): Promise => { - (globalThis as Record).__echoCalled = input; - return { content: [{ type: "text", text: String(input?.text ?? "") }] }; - }, - }); - - pi.on("agent_start", (): void => { - (globalThis as Record).__extAgentStartFired = true; - }); -}; diff --git a/js/src/pi-full/ext-probe.ts b/js/src/pi-full/ext-probe.ts deleted file mode 100644 index b9d7519..0000000 --- a/js/src/pi-full/ext-probe.ts +++ /dev/null @@ -1,34 +0,0 @@ -// Load a real pi extension through Pocket Pi's own module loader (oxc `.ts` -// transpile — NOT jiti), then hand its default-export factory to pi's unmodified -// loadExtensionFromFactory. Proves an unmodified extension registers its tools -// and hooks under Pocket Pi. Results land on globalThis for the Rust side. - -globalThis.__piExtResult = null; -globalThis.__piExtError = null; -globalThis.__piExtDone = false; - -globalThis.__piLoadExtension = async function (extPath) { - try { - const P = globalThis.PiFull as import("./entry").PiFullApi; - if (!P) throw new Error("PiFull not loaded — run the bundle first"); - - // Dynamic import routes through Pocket Pi's NodeResolver/NodeLoader, which - // transpiles the .ts natively and returns the factory as the default export. - const mod = await import(extPath); - const factory = mod.default; - if (typeof factory !== "function") throw new Error("extension has no default factory export"); - - const runtime = P.createExtensionRuntime(); - const eventBus = P.createEventBus(); - const ext = await P.loadExtensionFromFactory(factory, "/pocket-pi", eventBus, runtime, extPath); - - globalThis.__piExtResult = { - tools: [...ext.tools.keys()], - handlers: [...ext.handlers.keys()], - }; - } catch (e) { - globalThis.__piExtError = String((e && e.stack) || e); - } finally { - globalThis.__piExtDone = true; - } -}; diff --git a/js/src/pi-full/host.ts b/js/src/pi-full/host.ts deleted file mode 100644 index 63791d7..0000000 --- a/js/src/pi-full/host.ts +++ /dev/null @@ -1,200 +0,0 @@ -// Pocket Pi host harness. Reimplements the `PocketPi.boot/prompt/abort` surface -// — the API a Rust host (register_tool + boot + prompt + on_event + pump) drives -// — on top of the full, unmodified pi-coding-agent. Native tools bridge through -// `host.tool`; agent events map to the host's compact vocabulary via `host.emit`. -// -// This is loaded once by PiRuntime::new(), right after the full pi bundle. -import type { PiFullApi } from "./entry"; - -const P = globalThis.PiFull as PiFullApi; - -const CWD = "/pocket-pi"; -const AGENT_DIR = "/pocket-pi/.pi"; -const state: { session: any } = { session: null }; - -const emit = (o: unknown) => globalThis.host.emit(JSON.stringify(o)); - -// Build a model descriptor from the boot config for the requested provider. -function buildModel(cfg: any, provider: string): any { - const base = { - id: cfg.model, - name: cfg.model, - provider, - reasoning: false, - input: ["text", "image"], - cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, - contextWindow: 400000, - maxTokens: cfg.maxTokens || 4096, - }; - if (provider === "anthropic") { - return { ...base, api: "anthropic-messages", baseUrl: "https://api.anthropic.com" }; - } - return { ...base, api: "openai-responses", baseUrl: "https://api.openai.com/v1" }; -} - -// A pi extension that exposes each host-registered native tool (name + -// description + JSON-schema params from the boot config) as a pi tool whose -// execute() calls back into native Rust via host.tool. -function nativeToolsExtension(cfg: any) { - return (pi: any) => { - for (const t of cfg.tools || []) { - pi.registerTool({ - name: t.name, - description: t.description || "", - parameters: t.parameters || { type: "object", properties: {} }, - execute: async (_id: string, input: any) => { - const res = JSON.parse(globalThis.host.tool(t.name, JSON.stringify(input || {}))); - const content: any[] = []; - if (res.text) content.push({ type: "text", text: res.text }); - if (res.image_base64) { - content.push({ type: "image", data: res.image_base64, mimeType: res.mime_type || "image/jpeg" }); - } - if (content.length === 0) content.push({ type: "text", text: "" }); - return { content, details: res.terminate ? { terminate: true } : undefined }; - }, - }); - } - }; -} - -// Turn a message's content blocks into plain text. -function textOf(msg: any): string { - const c = msg && msg.content; - if (typeof c === "string") return c; - if (Array.isArray(c)) return c.filter((b: any) => b && b.type === "text").map((b: any) => b.text).join(""); - return ""; -} - -async function boot(configJson: string): Promise { - globalThis.__ppBooted = false; - try { - const cfg = JSON.parse(configJson); - let provider = cfg.provider || (String(cfg.model || "").startsWith("gpt") ? "openai" : "anthropic"); - let model: any; - let nativeProvider: any; - if (cfg.scripted) { - const modelId = cfg.model || "offline"; - const faux = P.fauxProvider({ - api: "pocket-pi-offline", - provider: "offline", - models: [{ id: modelId, name: "Pocket Pi Offline" }], - }); - faux.setResponses( - (cfg.scripted.steps || []).map((step: any) => - P.fauxAssistantMessage(typeof step === "string" ? step : String(step.text || "")), - ), - ); - nativeProvider = faux.provider; - provider = "offline"; - model = faux.getModel(modelId); - if (!model) throw new Error(`offline model not found: ${modelId}`); - } else { - model = buildModel(cfg, provider); - } - - const modelRuntime = await P.ModelRuntime.create({ modelsPath: null } as any); - if (nativeProvider) modelRuntime.registerNativeProvider(nativeProvider); - if (cfg.apiKey) await modelRuntime.setRuntimeApiKey(provider, cfg.apiKey); - - const settingsManager = P.SettingsManager.inMemory({}); - const sessionManager = P.SessionManager.inMemory(); - const resourceLoader = new P.DefaultResourceLoader({ - cwd: CWD, - agentDir: AGENT_DIR, - settingsManager, - noExtensions: true, - noSkills: true, - noPromptTemplates: true, - noThemes: true, - noContextFiles: true, - extensionFactories: [nativeToolsExtension(cfg)], - } as any); - if (resourceLoader.reload) await resourceLoader.reload(); - - const { session } = await P.createAgentSession({ - model, - modelRuntime, - settingsManager, - sessionManager, - resourceLoader, - cwd: CWD, - agentDir: AGENT_DIR, - thinkingLevel: "off", - tools: (cfg.tools || []).map((t: any) => t.name), - } as any); - - // Custom system prompt (base prompt the agent starts each turn with). - if (cfg.systemPrompt) { - try { - (session as any)._baseSystemPrompt = cfg.systemPrompt; - (session as any).agent.state.systemPrompt = cfg.systemPrompt; - } catch {} - } - - // Stream agent events to the host in its compact vocabulary. - let lastText = ""; - session.subscribe((event: any) => { - try { - switch (event.type) { - case "agent_start": - lastText = ""; - emit({ kind: "start" }); - break; - case "tool_execution_start": - emit({ kind: "tool_start", name: event.toolName }); - break; - case "message_update": - case "message_end": { - const msg = event.message; - if (msg && msg.role !== "user") { - const text = textOf(msg); - if (text && text.length > lastText.length && text.startsWith(lastText)) { - emit({ kind: "text", delta: text.slice(lastText.length) }); - lastText = text; - } else if (text && text !== lastText) { - emit({ kind: "assistant_text", text }); - lastText = text; - } - if (msg.stopReason === "error" && msg.errorMessage) { - emit({ kind: "error", message: msg.errorMessage }); - } - } - break; - } - case "agent_settled": - emit({ kind: "end" }); - break; - } - } catch {} - }); - - state.session = session; - } catch (e) { - emit({ kind: "error", message: String((e as any)?.stack || e) }); - } finally { - globalThis.__ppBooted = true; - } -} - -async function prompt(text: string): Promise { - const s = state.session; - if (!s) { - emit({ kind: "error", message: "prompt before boot completed" }); - emit({ kind: "end" }); - return; - } - try { - await s.prompt(text); - } catch (e) { - emit({ kind: "error", message: String((e as any)?.stack || e) }); - emit({ kind: "end" }); - } -} - -function abort(): void { - try { - state.session?.abort?.(); - } catch {} -} - -(globalThis as any).PocketPi = { boot, prompt, abort }; diff --git a/js/src/pi-full/persist-probe.ts b/js/src/pi-full/persist-probe.ts deleted file mode 100644 index 66e84cc..0000000 --- a/js/src/pi-full/persist-probe.ts +++ /dev/null @@ -1,42 +0,0 @@ -// Session persistence: write a session to disk with pi's unmodified -// SessionManager (backed by Pocket Pi's fs builtin), then resume it in a fresh -// manager over the same directory and confirm the history round-trips. Offline — -// no LLM, just the disk store. Results land on globalThis for the Rust side. - -globalThis.__piPersistResult = null; -globalThis.__piPersistError = null; - -globalThis.__piPersist = function (sessionDir) { - try { - const P = globalThis.PiFull as import("./entry").PiFullApi; - if (!P) throw new Error("PiFull not loaded — run the bundle first"); - const CWD = "/pocket-pi"; - - // Write a couple of messages through a persistent SessionManager. These are - // minimal test messages (not the full pi Message shape) — cast to pass them. - const sm1 = P.SessionManager.create(CWD, sessionDir); - sm1.appendMessage({ role: "user", content: [{ type: "text", text: "remember the number 42" }] } as any); - sm1.appendMessage({ role: "assistant", content: [{ type: "text", text: "noted: 42" }] } as any); - const wrote = sm1.buildSessionContext().messages.length; - const sessionId = sm1.getSessionId(); - - // Resume in a fresh manager over the same dir (exercises the header peek + - // full-file read path through our fs). - const sm2 = P.SessionManager.continueRecent(CWD, sessionDir); - const ctx = sm2.buildSessionContext(); - const texts = ctx.messages.map((m) => { - const content = (m as any).content; - return Array.isArray(content) ? content.map((c) => (c && c.text) || "").join("") : String(content); - }); - - globalThis.__piPersistResult = { - sessionId, - wrote, - resumedCount: ctx.messages.length, - resumedId: sm2.getSessionId(), - texts, - }; - } catch (e) { - globalThis.__piPersistError = String((e && e.stack) || e); - } -}; diff --git a/js/src/pi-full/undici-stub.ts b/js/src/pi-full/undici-stub.ts deleted file mode 100644 index 66b2416..0000000 --- a/js/src/pi-full/undici-stub.ts +++ /dev/null @@ -1,46 +0,0 @@ -// Build-time stub for `undici`. Pocket Pi routes all HTTP through its native, -// proxy-aware streaming fetch (the runtime's one real transport op), so pi's -// undici-backed transport is never used. pi only reaches for undici when an HTTP -// *proxy is configured in its own settings* — which Pocket Pi never does (the -// native hub handles proxying). This stub exists only so `import * as undici` -// loads without dragging in undici's entire web-fetch/websocket/cache stack. -// -// This substitutes a transitive transport dependency, not pi's logic. Pi's own -// source remains unmodified. - -class NoopDispatcher { - dispatch() { return false; } - close() { return Promise.resolve(); } - destroy() { return Promise.resolve(); } - compose() { return this; } - on() { return this; } - once() { return this; } - off() { return this; } -} -export class Client extends NoopDispatcher {} -export class Pool extends NoopDispatcher {} -export class BalancedPool extends NoopDispatcher {} -export class Agent extends NoopDispatcher {} -export class ProxyAgent extends NoopDispatcher {} -export class EnvHttpProxyAgent extends NoopDispatcher {} -export class MockAgent extends NoopDispatcher {} -export class RetryAgent extends NoopDispatcher {} - -let globalDispatcher = new Agent(); -export function setGlobalDispatcher(d) { globalDispatcher = d; } -export function getGlobalDispatcher() { return globalDispatcher; } -export function install() {} // pi calls this optionally; keep our globals in place -export function fetch(...args) { return globalThis.fetch(...args); } - -export const Headers = globalThis.Headers; -export const Response = globalThis.Response; -export const Request = globalThis.Request; -export const FormData = globalThis.FormData; -export const interceptors = {}; -export const errors = {}; - -export default { - Client, Pool, BalancedPool, Agent, ProxyAgent, EnvHttpProxyAgent, MockAgent, RetryAgent, - setGlobalDispatcher, getGlobalDispatcher, install, fetch, - Headers, Response, Request, FormData, interceptors, errors, -}; diff --git a/js/src/runtime/node/_bootstrap.ts b/js/src/runtime/node/_bootstrap.ts deleted file mode 100644 index 4d7db37..0000000 --- a/js/src/runtime/node/_bootstrap.ts +++ /dev/null @@ -1,9 +0,0 @@ -// Node runtime bootstrap — evaluated once when the Node layer is installed, -// before any guest module loads. Hoists Buffer to a global (many packages assume -// `Buffer` exists without importing it) and wires `process.nextTick` onto the -// microtask queue. Kept as a file (not a Rust string literal) so it stays -// readable and lintable. -import { Buffer } from "node:buffer"; -globalThis.Buffer = Buffer; -globalThis.__nodeBuffer = Buffer; -globalThis.process.nextTick = (fn, ...args) => queueMicrotask(() => fn(...args)); diff --git a/js/src/runtime/node/_cjs-runtime.ts b/js/src/runtime/node/_cjs-runtime.ts deleted file mode 100644 index 99078bc..0000000 --- a/js/src/runtime/node/_cjs-runtime.ts +++ /dev/null @@ -1,49 +0,0 @@ -// Synchronous CommonJS `require`, over the native resolver + file reader. This is -// the static tail of the CJS bootstrap: the generated head (see -// builtins::cjs_bootstrap_source) has already populated globalThis.__builtinExports -// from the builtin registry, so this file only implements the require semantics. -// Kept separate from the generated part so the logic is readable and lintable. - -globalThis.__cjsCache = globalThis.__cjsCache || new Map(); - -// Resolve + load a CommonJS (or JSON, or transpiled-TS) module synchronously. -// `fromFile` is the requiring module's path; `spec` is the import specifier. -globalThis.__cjsRequire = function (fromFile, spec) { - const r = JSON.parse(globalThis.__node.resolve(fromFile, spec)); - - // A node: builtin — served straight from the registry-populated map. - if (r.builtin != null) { - const exports = - globalThis.__builtinExports[r.builtin] ?? - globalThis.__builtinExports[r.builtin.split("/")[0]]; - if (exports === undefined) throw new Error("builtin not available: " + r.builtin); - return exports; - } - if (r.err) throw new Error("Cannot find module '" + spec + "' from '" + fromFile + "'"); - - const p = r.path; - if (globalThis.__cjsCache.has(p)) return globalThis.__cjsCache.get(p); - - // JSON modules resolve to their parsed value. - if (p.endsWith(".json")) { - const val = JSON.parse(globalThis.__node.readText(p)); - globalThis.__cjsCache.set(p, val); - return val; - } - - let src = globalThis.__node.readText(p); - if (p.endsWith(".ts") || p.endsWith(".cts")) src = host.transpile(p, src); - - const module = { exports: {} }; - // Seed the cache before running the body so require cycles terminate. - globalThis.__cjsCache.set(p, module.exports); - const dir = p.replace(/\/[^/]*$/, ""); - const fn = new Function("module", "exports", "require", "__filename", "__dirname", src); - fn(module, module.exports, (s) => globalThis.__cjsRequire(p, s), p, dir); - globalThis.__cjsCache.set(p, module.exports); - return module.exports; -}; - -// esbuild-bundled CJS emits a runtime `require(...)` for anything left external -// (our node: builtins); delegate it to the synchronous require above. -globalThis.require = (spec) => globalThis.__cjsRequire("/pocket-pi-bundle", spec); diff --git a/js/src/runtime/node/assert.ts b/js/src/runtime/node/assert.ts deleted file mode 100644 index a5e097d..0000000 --- a/js/src/runtime/node/assert.ts +++ /dev/null @@ -1,11 +0,0 @@ -function assert(v, msg) { if (!v) throw new Error(msg || "Assertion failed"); } -assert.ok = assert; -assert.equal = (a, b, m) => { if (a != b) throw new Error(m || a + " != " + b); }; -assert.strictEqual = (a, b, m) => { if (a !== b) throw new Error(m || a + " !== " + b); }; -assert.deepEqual = (a, b, m) => { if (JSON.stringify(a) !== JSON.stringify(b)) throw new Error(m || "deepEqual failed"); }; -assert.deepStrictEqual = assert.deepEqual; -assert.notEqual = (a, b, m) => { if (a == b) throw new Error(m || "notEqual failed"); }; -assert.throws = (fn, m) => { try { fn(); } catch { return; } throw new Error(m || "expected throw"); }; -assert.fail = (m) => { throw new Error(m || "fail"); }; -export default assert; -export { assert }; diff --git a/js/src/runtime/node/async_hooks.ts b/js/src/runtime/node/async_hooks.ts deleted file mode 100644 index 5a94760..0000000 --- a/js/src/runtime/node/async_hooks.ts +++ /dev/null @@ -1,24 +0,0 @@ -// node:async_hooks — single-threaded, synchronous stubs. AsyncLocalStorage runs -// callbacks inline; AsyncResource is a real (no-op) base class so libraries that -// `class X extends AsyncResource {}` (e.g. undici) load and construct. -export class AsyncLocalStorage { - run(_store, cb, ...args) { return cb(...args); } - getStore() { return this._store; } - enterWith(store) { this._store = store; } - exit(cb, ...args) { return cb(...args); } - disable() {} -} -export class AsyncResource { - constructor(type, opts) { this.type = type; this._opts = opts; } - runInAsyncScope(fn, thisArg, ...args) { return fn.apply(thisArg, args); } - emitDestroy() { return this; } - asyncId() { return 0; } - triggerAsyncId() { return 0; } - bind(fn) { return fn; } - static bind(fn) { return fn; } -} -export function createHook() { return { enable() { return this; }, disable() { return this; } }; } -export function executionAsyncId() { return 0; } -export function triggerAsyncId() { return 0; } -export function executionAsyncResource() { return {}; } -export default { AsyncLocalStorage, AsyncResource, createHook, executionAsyncId, triggerAsyncId, executionAsyncResource }; diff --git a/js/src/runtime/node/buffer.ts b/js/src/runtime/node/buffer.ts deleted file mode 100644 index 99999a5..0000000 --- a/js/src/runtime/node/buffer.ts +++ /dev/null @@ -1,112 +0,0 @@ -// node:buffer — a functional Buffer subset over Uint8Array. Covers the encodings -// pi + its deps actually touch (utf8, base64, hex, latin1) and the common ops. -const B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -function utf8ToBytes(str) { - const out = []; - for (let i = 0; i < str.length; i++) { - let c = str.charCodeAt(i); - if (c < 0x80) out.push(c); - else if (c < 0x800) out.push(0xc0 | (c >> 6), 0x80 | (c & 0x3f)); - else if (c >= 0xd800 && c <= 0xdbff) { - const c2 = str.charCodeAt(++i); - c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); - out.push(0xf0 | (c >> 18), 0x80 | ((c >> 12) & 0x3f), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f)); - } else out.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f)); - } - return out; -} -function bytesToUtf8(bytes) { - let out = "", i = 0; - while (i < bytes.length) { - let c = bytes[i++]; - if (c < 0x80) out += String.fromCharCode(c); - else if (c >= 0xc0 && c < 0xe0) out += String.fromCharCode(((c & 0x1f) << 6) | (bytes[i++] & 0x3f)); - else if (c >= 0xe0 && c < 0xf0) out += String.fromCharCode(((c & 0xf) << 12) | ((bytes[i++] & 0x3f) << 6) | (bytes[i++] & 0x3f)); - else { - const cp = ((c & 7) << 18) | ((bytes[i++] & 0x3f) << 12) | ((bytes[i++] & 0x3f) << 6) | (bytes[i++] & 0x3f); - const off = cp - 0x10000; - out += String.fromCharCode(0xd800 + (off >> 10), 0xdc00 + (off & 0x3ff)); - } - } - return out; -} -function toBase64(bytes) { - let out = ""; - for (let i = 0; i < bytes.length; i += 3) { - const b0 = bytes[i], b1 = bytes[i + 1], b2 = bytes[i + 2]; - const n = (b0 << 16) | ((b1 || 0) << 8) | (b2 || 0); - out += B64[(n >> 18) & 63] + B64[(n >> 12) & 63] + (i + 1 < bytes.length ? B64[(n >> 6) & 63] : "=") + (i + 2 < bytes.length ? B64[n & 63] : "="); - } - return out; -} -function fromBase64(str) { - str = str.replace(/[^A-Za-z0-9+/]/g, ""); - const out = []; - for (let i = 0; i < str.length; i += 4) { - const n = (B64.indexOf(str[i]) << 18) | (B64.indexOf(str[i + 1]) << 12) | (B64.indexOf(str[i + 2] || "A") << 6) | B64.indexOf(str[i + 3] || "A"); - out.push((n >> 16) & 255); - if (str[i + 2] && str[i + 2] !== "=") out.push((n >> 8) & 255); - if (str[i + 3] && str[i + 3] !== "=") out.push(n & 255); - } - return out; -} - -export class Buffer extends Uint8Array { - static from(value, encoding) { - if (typeof value === "string") { - if (encoding === "base64") return new Buffer(fromBase64(value)); - if (encoding === "hex") { - const out = []; - for (let i = 0; i < value.length; i += 2) out.push(parseInt(value.substr(i, 2), 16)); - return new Buffer(out); - } - if (encoding === "latin1" || encoding === "binary") { - const out = new Buffer(value.length); - for (let i = 0; i < value.length; i++) out[i] = value.charCodeAt(i) & 255; - return out; - } - return new Buffer(utf8ToBytes(value)); - } - if (value instanceof Uint8Array || Array.isArray(value)) return new Buffer(value); - if (value instanceof ArrayBuffer) return new Buffer(new Uint8Array(value)); - return new Buffer(0); - } - static alloc(size, fill) { - const b = new Buffer(size); - if (fill != null) b.fill(typeof fill === "string" ? fill.charCodeAt(0) : fill); - return b; - } - static allocUnsafe(size) { return new Buffer(size); } - static isBuffer(v) { return v instanceof Buffer; } - static concat(list, length) { - let total = length ?? list.reduce((n, b) => n + b.length, 0); - const out = new Buffer(total); - let off = 0; - for (const b of list) { out.set(b.subarray(0, Math.min(b.length, total - off)), off); off += b.length; if (off >= total) break; } - return out; - } - static byteLength(str, encoding) { - return Buffer.from(str, encoding).length; - } - toString(encoding, start, end) { - const view = this.subarray(start || 0, end == null ? this.length : end); - if (encoding === "base64") return toBase64(view); - if (encoding === "hex") return Array.from(view, (b) => b.toString(16).padStart(2, "0")).join(""); - if (encoding === "latin1" || encoding === "binary") return Array.from(view, (b) => String.fromCharCode(b)).join(""); - return bytesToUtf8(view); - } - toJSON() { return { type: "Buffer", data: Array.from(this) }; } - equals(other) { return this.length === other.length && this.every((v, i) => v === other[i]); } - write(str, offset = 0, length, encoding) { - const src = Buffer.from(str, typeof length === "string" ? length : encoding); - const n = Math.min(src.length, this.length - offset, typeof length === "number" ? length : Infinity); - this.set(src.subarray(0, n), offset); - return n; - } - slice(a, b) { return new Buffer(this.subarray(a, b)); } -} - -export const SlowBuffer = Buffer; -export const constants = { MAX_LENGTH: 0x7fffffff, MAX_STRING_LENGTH: 0x1fffffff }; -export default { Buffer, SlowBuffer, constants }; diff --git a/js/src/runtime/node/child_process.ts b/js/src/runtime/node/child_process.ts deleted file mode 100644 index 4a372ee..0000000 --- a/js/src/runtime/node/child_process.ts +++ /dev/null @@ -1,58 +0,0 @@ -// node:child_process — spawnSync/execSync real (native), async forms best-effort. -import { EventEmitter } from "node:events"; -const n = globalThis.__node; -export function spawnSync(cmd, args = [], options = {}) { - const res = JSON.parse(n.spawnSync(String(cmd), JSON.stringify(args || []), JSON.stringify(options || {}))); - const enc = options.encoding; - const wrap = (s) => (enc && enc !== "buffer" ? s : globalThis.Buffer.from(s)); - return { - status: res.status ?? null, - signal: null, - stdout: wrap(res.stdout || ""), - stderr: wrap(res.stderr || ""), - error: res.error ? new Error(res.error) : undefined, - pid: 0, - }; -} -export function execSync(command, options = {}) { - const shell = options.shell || "/bin/sh"; - const res = spawnSync(shell, ["-c", String(command)], options); - if (res.status && res.status !== 0) { - const e = new Error(`Command failed: ${command}\n${res.stderr}`); - e.status = res.status; - e.stdout = res.stdout; - e.stderr = res.stderr; - throw e; - } - return res.stdout; -} -export function execFileSync(file, args = [], options = {}) { - return spawnSync(file, args, options).stdout; -} -// Async forms: minimal EventEmitter-ish; adequate for code that imports but -// rarely runs them on the session path. (Real async spawn is a later milestone.) -export function spawn(cmd, args = [], options = {}) { - const ee = new EventEmitter(); - queueMicrotask(() => { - try { - const r = spawnSync(cmd, args, options); - ee.stdout && ee.stdout.emit && ee.stdout.emit("data", r.stdout); - ee.emit("close", r.status ?? 0); - } catch (e) { ee.emit("error", e); } - }); - ee.stdout = { on() {} }; - ee.stderr = { on() {} }; - ee.stdin = { write() {}, end() {} }; - return ee; -} -export function exec(command, options, cb) { - if (typeof options === "function") { cb = options; options = {}; } - queueMicrotask(() => { - try { const out = execSync(command, options); cb && cb(null, out, ""); } - catch (e) { cb && cb(e, e.stdout || "", e.stderr || ""); } - }); - return { on() {} }; -} -export const execFile = exec; -export function fork() { throw new Error("child_process.fork is not supported in Pocket Pi"); } -export default { spawnSync, execSync, execFileSync, spawn, exec, execFile, fork }; diff --git a/js/src/runtime/node/console.ts b/js/src/runtime/node/console.ts deleted file mode 100644 index 8890c47..0000000 --- a/js/src/runtime/node/console.ts +++ /dev/null @@ -1,35 +0,0 @@ -// node:console — wraps QuickJS's global console. The `Console` class lets code -// construct its own logger (undici's mock formatter does `new Console(...)`). -const g = globalThis.console || {}; -const out = (...a) => { try { (g.log || (() => {}))(...a); } catch {} }; -const err = (...a) => { try { (g.error || g.log || (() => {}))(...a); } catch {} }; - -export class Console { - constructor(_stdout, _stderr) {} - log(...a) { out(...a); } - info(...a) { out(...a); } - debug(...a) { out(...a); } - dir(...a) { out(...a); } - warn(...a) { err(...a); } - error(...a) { err(...a); } - trace(...a) { err(...a); } - table(...a) { out(...a); } - group(...a) { out(...a); } - groupCollapsed(...a) { out(...a); } - groupEnd() {} - assert(cond, ...a) { if (!cond) err("Assertion failed:", ...a); } - count() {} - countReset() {} - time() {} - timeEnd() {} - timeLog() {} - clear() {} -} - -const instance = new Console(); -export const log = instance.log; -export const info = instance.info; -export const warn = instance.warn; -export const error = instance.error; -export const debug = instance.debug; -export default instance; diff --git a/js/src/runtime/node/constants.ts b/js/src/runtime/node/constants.ts deleted file mode 100644 index c6be336..0000000 --- a/js/src/runtime/node/constants.ts +++ /dev/null @@ -1,2 +0,0 @@ -// node:constants — minimal stub. -export default {}; diff --git a/js/src/runtime/node/crypto.ts b/js/src/runtime/node/crypto.ts deleted file mode 100644 index 90cbb08..0000000 --- a/js/src/runtime/node/crypto.ts +++ /dev/null @@ -1,42 +0,0 @@ -// node:crypto — the subset pi touches. Digests use a fast non-cryptographic hash -// (FNV-1a) — fine for cache keys / ids; NOT for security. -function fnv(str) { - let h = 0xcbf29ce484222325n; - const bytes = globalThis.Buffer ? globalThis.Buffer.from(str) : new TextEncoder().encode(str); - for (const b of bytes) { h ^= BigInt(b); h = (h * 0x100000001b3n) & 0xffffffffffffffffn; } - return h; -} -export function randomBytes(n) { - const b = globalThis.Buffer ? globalThis.Buffer.alloc(n) : new Uint8Array(n); - for (let i = 0; i < n; i++) b[i] = Math.floor(Math.random() * 256); - return b; -} -export function randomUUID() { return globalThis.crypto.randomUUID(); } -export function randomFillSync(buf) { for (let i = 0; i < buf.length; i++) buf[i] = Math.floor(Math.random() * 256); return buf; } -export function createHash(_algo) { - let data = ""; - return { - update(chunk) { data += typeof chunk === "string" ? chunk : globalThis.Buffer.from(chunk).toString(); return this; }, - digest(enc) { - // 256-bit-ish by concatenating four FNV rounds with salts. - let hex = ""; - for (let i = 0; i < 4; i++) hex += fnv(i + ":" + data).toString(16).padStart(16, "0"); - if (enc === "hex") return hex; - const bytes = globalThis.Buffer.from(hex, "hex"); - return enc ? bytes.toString(enc) : bytes; - }, - }; -} -export function createHmac(algo, key) { const h = createHash(algo); h.update(String(key) + ":"); return h; } -export function getHashes() { return ["sha1", "sha256", "sha384", "sha512", "md5"]; } -export function getCiphers() { return []; } -export function timingSafeEqual(a, b) { - if (!a || !b || a.length !== b.length) return false; - let diff = 0; - for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i]; - return diff === 0; -} -export const constants = {}; -export const webcrypto = globalThis.crypto; -export function getRandomValues(a) { return globalThis.crypto.getRandomValues(a); } -export default { randomBytes, randomUUID, randomFillSync, createHash, createHmac, getHashes, getCiphers, timingSafeEqual, constants, webcrypto, getRandomValues }; diff --git a/js/src/runtime/node/diagnostics_channel.ts b/js/src/runtime/node/diagnostics_channel.ts deleted file mode 100644 index 0e0ef81..0000000 --- a/js/src/runtime/node/diagnostics_channel.ts +++ /dev/null @@ -1,29 +0,0 @@ -// node:diagnostics_channel — minimal no-op channel registry (undici probes this). -class Channel { - constructor(name) { this.name = name; this._subs = []; } - get hasSubscribers() { return this._subs.length > 0; } - publish(msg) { for (const s of this._subs.slice()) { try { s(msg, this.name); } catch {} } } - subscribe(fn) { this._subs.push(fn); } - unsubscribe(fn) { this._subs = this._subs.filter((s) => s !== fn); return true; } -} -const registry = new Map(); -export function channel(name) { - let c = registry.get(name); - if (!c) { c = new Channel(name); registry.set(name, c); } - return c; -} -export function hasSubscribers(name) { const c = registry.get(name); return !!c && c.hasSubscribers; } -export function subscribe(name, fn) { channel(name).subscribe(fn); } -export function unsubscribe(name, fn) { return channel(name).unsubscribe(fn); } -export function tracingChannel(nameOrChannels) { - const base = typeof nameOrChannels === "string" ? nameOrChannels : ""; - const mk = (suffix) => channel(base ? `tracing:${base}:${suffix}` : suffix); - return { - start: mk("start"), end: mk("end"), asyncStart: mk("asyncStart"), - asyncEnd: mk("asyncEnd"), error: mk("error"), - traceSync(fn, ctx, thisArg, ...a) { return fn.apply(thisArg, a); }, - tracePromise(fn, ctx, thisArg, ...a) { return fn.apply(thisArg, a); }, - traceCallback(fn, pos, ctx, thisArg, ...a) { return fn.apply(thisArg, a); }, - }; -} -export default { channel, hasSubscribers, subscribe, unsubscribe, tracingChannel, Channel }; diff --git a/js/src/runtime/node/dns.ts b/js/src/runtime/node/dns.ts deleted file mode 100644 index 9d3efbb..0000000 --- a/js/src/runtime/node/dns.ts +++ /dev/null @@ -1,4 +0,0 @@ -export function lookup(host, _o, cb) { const c = typeof _o === "function" ? _o : cb; c && c(null, "127.0.0.1", 4); } -export function resolve(_h, cb) { cb && cb(null, []); } -export const promises = { lookup: async () => ({ address: "127.0.0.1", family: 4 }), resolve: async () => [] }; -export default { lookup, resolve, promises }; diff --git a/js/src/runtime/node/events.ts b/js/src/runtime/node/events.ts deleted file mode 100644 index 0459777..0000000 --- a/js/src/runtime/node/events.ts +++ /dev/null @@ -1,62 +0,0 @@ -// node:events — EventEmitter, pure JS. -export class EventEmitter { - constructor() { - this._events = new Map(); - this._maxListeners = 10; - } - setMaxListeners(n) { this._maxListeners = n; return this; } - getMaxListeners() { return this._maxListeners; } - on(type, fn) { - let arr = this._events.get(type); - if (!arr) { arr = []; this._events.set(type, arr); } - arr.push(fn); - return this; - } - addListener(type, fn) { return this.on(type, fn); } - once(type, fn) { - const wrap = (...args) => { this.off(type, wrap); fn(...args); }; - wrap.listener = fn; - return this.on(type, wrap); - } - prependListener(type, fn) { - let arr = this._events.get(type); - if (!arr) { arr = []; this._events.set(type, arr); } - arr.unshift(fn); - return this; - } - off(type, fn) { - const arr = this._events.get(type); - if (arr) { - const i = arr.findIndex((f) => f === fn || f.listener === fn); - if (i !== -1) arr.splice(i, 1); - } - return this; - } - removeListener(type, fn) { return this.off(type, fn); } - removeAllListeners(type) { - if (type === undefined) this._events.clear(); - else this._events.delete(type); - return this; - } - emit(type, ...args) { - const arr = this._events.get(type); - if (!arr || arr.length === 0) { - if (type === "error") throw args[0] instanceof Error ? args[0] : new Error("Unhandled error"); - return false; - } - for (const fn of arr.slice()) fn.apply(this, args); - return true; - } - listeners(type) { return (this._events.get(type) || []).slice(); } - listenerCount(type) { return (this._events.get(type) || []).length; } - eventNames() { return [...this._events.keys()]; } -} -export const once = (emitter, name) => - new Promise((resolve, reject) => { - emitter.once(name, (...args) => resolve(args)); - emitter.once("error", reject); - }); -export default EventEmitter; -EventEmitter.EventEmitter = EventEmitter; -EventEmitter.once = once; -EventEmitter.defaultMaxListeners = 10; diff --git a/js/src/runtime/node/fs-promises.ts b/js/src/runtime/node/fs-promises.ts deleted file mode 100644 index ba28635..0000000 --- a/js/src/runtime/node/fs-promises.ts +++ /dev/null @@ -1,26 +0,0 @@ -// node:fs/promises -import fs from "node:fs"; -const p = fs.promises; -export const readFile = p.readFile; -export const writeFile = p.writeFile; -export const readdir = p.readdir; -export const mkdir = p.mkdir; -export const stat = p.stat; -export const lstat = p.lstat; -export const realpath = p.realpath; -export const readlink = p.readlink; -export const unlink = p.unlink; -export const rm = p.rm; -export const rmdir = p.rmdir; -export const rename = p.rename; -export const copyFile = p.copyFile; -export const cp = p.cp; -export const appendFile = p.appendFile; -export const chmod = p.chmod; -export const symlink = p.symlink; -export const utimes = p.utimes; -export const truncate = p.truncate; -export const mkdtemp = p.mkdtemp; -export const access = p.access; -export const open = p.open; -export default p; diff --git a/js/src/runtime/node/fs.ts b/js/src/runtime/node/fs.ts deleted file mode 100644 index 04abd32..0000000 --- a/js/src/runtime/node/fs.ts +++ /dev/null @@ -1,232 +0,0 @@ -// node:fs — sync + promise subset, backed by native ops (globalThis.__node.fs). -// Native ops return JSON strings; wrap them so callers see plain objects. -const raw = globalThis.__node.fs; -const fs = { - readFile: (p) => JSON.parse(raw.readFile(p)), - writeFile: (p, b) => JSON.parse(raw.writeFile(p, b)), - exists: (p) => raw.exists(p), - readdir: (p) => JSON.parse(raw.readdir(p)), - mkdir: (p, r) => raw.mkdir(p, r), - stat: (p) => JSON.parse(raw.stat(p)), - realpath: (p) => JSON.parse(raw.realpath(p)), - unlink: (p) => raw.unlink(p), -}; - -function decode(bytesJson, encoding) { - // Native returns a JSON array of bytes; decode per requested encoding. - const bytes = bytesJson; - if (!encoding) return globalThis.Buffer ? globalThis.Buffer.from(bytes) : Uint8Array.from(bytes); - const B = globalThis.__nodeBuffer; - return B ? B.from(bytes).toString(encoding) : String.fromCharCode(...bytes); -} - -export function readFileSync(path, options) { - const encoding = typeof options === "string" ? options : options && options.encoding; - const res = fs.readFile(String(path)); - if (res.err) throw enoent(res.err, path); - return decode(res.bytes, encoding); -} -export function writeFileSync(pathOrFd, data, options) { - // writeFileSync also accepts a file descriptor (SessionManager uses this). - if (typeof pathOrFd === "number") { fdWrite(pathOrFd, data, options); return; } - const encoding = typeof options === "string" ? options : (options && options.encoding) || "utf8"; - let bytes; - if (typeof data === "string") { - const B = globalThis.__nodeBuffer; - bytes = B ? Array.from(B.from(data, encoding)) : Array.from(data, (c) => c.charCodeAt(0)); - } else bytes = Array.from(data); - const res = fs.writeFile(String(pathOrFd), bytes); - if (res.err) throw new Error(res.err); -} -export function existsSync(path) { - return fs.exists(String(path)); -} -export function readdirSync(path) { - const res = fs.readdir(String(path)); - if (res.err) throw enoent(res.err, path); - return res.entries; -} -export function mkdirSync(path, options) { - fs.mkdir(String(path), !!(options && options.recursive)); -} -export function statSync(path) { - const res = fs.stat(String(path)); - if (res.err) throw enoent(res.err, path); - return makeStat(res); -} -export const lstatSync = statSync; -export function realpathSync(path) { - const res = fs.realpath(String(path)); - return res.err ? String(path) : res.path; -} -export function unlinkSync(path) { - fs.unlink(String(path)); -} -export function rmSync(path) { - fs.unlink(String(path)); -} -export const constants = { F_OK: 0, R_OK: 4, W_OK: 2, X_OK: 1 }; -export function accessSync(path, _mode) { - if (!existsSync(path)) throw enoent("no access", path); -} - -// Broader fs surface as stubs so any `import { … } from "fs"` resolves. The ones -// pi actually exercises headlessly are implemented above; the rest throw or no-op -// until a milestone needs them. -const nope = (name) => () => { throw new Error(`fs.${name} is not implemented in Pocket Pi`); }; - -// fd-backed I/O over the whole-file native ops. openSync honors the read/write/ -// append/exclusive flags SessionManager uses ("r", "wx", "a", …); reads slurp the -// file and readSync copies a window; fd writes append through to the path. -const __fds = new Map(); -let __nextFd = 3; -function ebadf() { const e = new Error("EBADF: bad file descriptor"); e.code = "EBADF"; return e; } -function parseFlags(flags) { - const f = String(flags || "r"); - return { - write: /[wa+]/.test(f), - append: /a/.test(f), - create: /[wa]/.test(f), - excl: /x/.test(f), - truncate: /w/.test(f) && !/\+/.test(f), - read: /r|\+/.test(f), - }; -} -export function openSync(path, flags, _mode) { - path = String(path); - const f = parseFlags(flags); - const exists = existsSync(path); - if (f.excl && exists) { const e = new Error(`EEXIST: file already exists, open '${path}'`); e.code = "EEXIST"; throw e; } - if (!f.create && !exists) throw enoent("open", path); - if (f.truncate || (f.create && !exists)) writeFileSync(path, ""); // create/truncate - const bytes = f.read && !f.truncate && existsSync(path) ? (fs.readFile(path).bytes || []) : []; - const fd = __nextFd++; - __fds.set(fd, { path, flags: f, bytes, pos: 0 }); - return fd; -} -export function readSync(fd, buffer, offset, length, position) { - const e = __fds.get(fd); - if (!e) throw ebadf(); - const start = position == null || position < 0 ? e.pos : position; - let n = 0; - for (; n < length && start + n < e.bytes.length; n++) buffer[offset + n] = e.bytes[start + n]; - if (position == null || position < 0) e.pos = start + n; - return n; -} -function toStr(data, options) { - if (typeof data === "string") return data; - const enc = (typeof options === "string" ? options : options && options.encoding) || "utf8"; - const B = globalThis.__nodeBuffer; - return B ? B.from(data).toString(enc) : String.fromCharCode(...data); -} -// Append `data` through the fd to its file (native writeFile overwrites, so we -// read-modify-write). Fine for the small, append-mostly session store. -function fdWrite(fd, data, options) { - const e = __fds.get(fd); - if (!e) throw ebadf(); - const prev = existsSync(e.path) ? readFileSync(e.path, "utf8") : ""; - writeFileSync(e.path, prev + toStr(data, options), "utf8"); -} -export function writeSync(fd, data, _offOrPos, _length, _position) { - const s = typeof data === "string" ? data : toStr(data); - fdWrite(fd, s); - return typeof data === "string" ? s.length : data.length; -} -export function closeSync(fd) { __fds.delete(fd); } -export const fsyncSync = () => {}; -export const fdatasyncSync = () => {}; -export const ftruncateSync = () => {}; -export function appendFileSync(path, data, options) { - const prev = existsSync(path) ? readFileSync(path, "utf8") : ""; - writeFileSync(path, prev + (typeof data === "string" ? data : ""), options); -} -export const copyFileSync = nope("copyFileSync"); -export function renameSync(a, b) { const d = readFileSync(a); writeFileSync(b, d); unlinkSync(a); } -export const rmdirSync = (p) => unlinkSync(p); -export const cpSync = nope("cpSync"); -export const chmodSync = () => {}; -export const symlinkSync = nope("symlinkSync"); -export const readlinkSync = (p) => realpathSync(p); -export const truncateSync = nope("truncateSync"); -export const utimesSync = () => {}; -export const createReadStream = nope("createReadStream"); -export const createWriteStream = nope("createWriteStream"); -export const watchFile = () => {}; -export const unwatchFile = () => {}; -export function watch() { return { close() {}, on() {}, unref() { return this; } }; } -export const opendirSync = nope("opendirSync"); -export const mkdtempSync = (prefix) => { const p = prefix + Math.random().toString(36).slice(2, 8); mkdirSync(p, { recursive: true }); return p; }; - -function makeStat(res) { - return { - size: res.size || 0, - mtimeMs: res.mtimeMs || 0, - isFile: () => res.isFile, - isDirectory: () => res.isDir, - isSymbolicLink: () => false, - }; -} -function enoent(msg, path) { - const e = new Error(`ENOENT: ${msg}, '${path}'`); - e.code = "ENOENT"; - e.path = String(path); - return e; -} - -// Callback-style async API (fs.readFile(path, cb), etc.) — wrap the sync forms. -const cbify = (fn) => (...args) => { - const cb = typeof args[args.length - 1] === "function" ? args.pop() : () => {}; - queueMicrotask(() => { try { cb(null, fn(...args)); } catch (e) { cb(e); } }); -}; -export const readFile = cbify(readFileSync); -export const writeFile = cbify(writeFileSync); -export const readdir = cbify(readdirSync); -export const stat = cbify(statSync); -export const lstat = cbify(statSync); -export const mkdir = cbify(mkdirSync); -export const access = cbify(accessSync); -export const unlink = cbify(unlinkSync); -export const realpath = cbify(realpathSync); -export const rename = cbify(renameSync); -export const rm = cbify(unlinkSync); -export const exists = (p, cb) => queueMicrotask(() => cb(existsSync(p))); - -const P = (fn) => (...args) => new Promise((res, rej) => { try { res(fn(...args)); } catch (e) { rej(e); } }); -export const promises = { - readFile: P(readFileSync), - writeFile: P(writeFileSync), - readdir: P(readdirSync), - mkdir: P(mkdirSync), - stat: P(statSync), - lstat: P(statSync), - realpath: P(realpathSync), - readlink: P(readlinkSync), - unlink: P(unlinkSync), - rm: P(rmSync), - rmdir: P(rmdirSync), - rename: P(renameSync), - copyFile: P(copyFileSync), - cp: P(cpSync), - appendFile: P(appendFileSync), - chmod: P(chmodSync), - symlink: P(symlinkSync), - utimes: P(utimesSync), - truncate: P(truncateSync), - mkdtemp: P(mkdtempSync), - access: P(accessSync), - open: P((path) => ({ - fd: 0, - readFile: (opts) => readFileSync(path, opts), - writeFile: (data, opts) => writeFileSync(path, data, opts), - stat: () => statSync(path), - close: () => {}, - read: () => ({ bytesRead: 0, buffer: null }), - write: () => ({ bytesWritten: 0 }), - })), -}; - -export default { - readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync, statSync, lstatSync, - realpathSync, unlinkSync, rmSync, promises, - constants: { F_OK: 0, R_OK: 4, W_OK: 2, X_OK: 1 }, -}; diff --git a/js/src/runtime/node/http.ts b/js/src/runtime/node/http.ts deleted file mode 100644 index 9549fec..0000000 --- a/js/src/runtime/node/http.ts +++ /dev/null @@ -1,12 +0,0 @@ -// node:http — stub; Pocket Pi routes HTTP through fetch(). Imports resolve; the -// classic client APIs throw if actually used. -import { EventEmitter } from "node:events"; -export class Agent { constructor(o) { this.options = o || {}; } } -export class Server extends EventEmitter { listen() { return this; } close() {} } -export function request() { throw new Error("http.request not supported (use fetch)"); } -export function get() { throw new Error("http.get not supported (use fetch)"); } -export const globalAgent = new Agent(); -export const METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]; -export const STATUS_CODES = {}; -export function createServer() { return new Server(); } -export default { Agent, Server, request, get, globalAgent, METHODS, STATUS_CODES, createServer }; diff --git a/js/src/runtime/node/https.ts b/js/src/runtime/node/https.ts deleted file mode 100644 index b5fd3d9..0000000 --- a/js/src/runtime/node/https.ts +++ /dev/null @@ -1,12 +0,0 @@ -// node:https — stub; Pocket Pi routes HTTP through fetch(). Imports resolve; the -// classic client APIs throw if actually used. -import { EventEmitter } from "node:events"; -export class Agent { constructor(o) { this.options = o || {}; } } -export class Server extends EventEmitter { listen() { return this; } close() {} } -export function request() { throw new Error("https.request not supported (use fetch)"); } -export function get() { throw new Error("https.get not supported (use fetch)"); } -export const globalAgent = new Agent(); -export const METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]; -export const STATUS_CODES = {}; -export function createServer() { return new Server(); } -export default { Agent, Server, request, get, globalAgent, METHODS, STATUS_CODES, createServer }; diff --git a/js/src/runtime/node/module.ts b/js/src/runtime/node/module.ts deleted file mode 100644 index dde490d..0000000 --- a/js/src/runtime/node/module.ts +++ /dev/null @@ -1,13 +0,0 @@ -// node:module — createRequire delegates to the synchronous CJS require. -export function createRequire(from) { - let base = "/pocket-pi-bundle"; - if (typeof from === "string") base = from.startsWith("file://") ? from.slice(7) : from; - else if (from && from.href) base = String(from.href).replace(/^file:\/\//, ""); - return function require(spec) { return globalThis.__cjsRequire(base, spec); }; -} -export const builtinModules = ["fs", "path", "os", "events", "util", "buffer", "process", "crypto", "url", "child_process", "stream", "string_decoder", "module", "readline", "http", "https", "net", "tls", "zlib", "assert", "querystring"]; -export function isBuiltin(m) { return builtinModules.includes(String(m).replace(/^node:/, "")); } -export class Module {} -Module.createRequire = createRequire; -Module.builtinModules = builtinModules; -export default { createRequire, builtinModules, isBuiltin, Module }; diff --git a/js/src/runtime/node/net.ts b/js/src/runtime/node/net.ts deleted file mode 100644 index 967d57a..0000000 --- a/js/src/runtime/node/net.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { EventEmitter } from "node:events"; -export class Socket extends EventEmitter { connect() { return this; } write() { return true; } end() {} destroy() {} setTimeout() {} setNoDelay() {} setKeepAlive() {} } -export class Server extends EventEmitter { listen() { return this; } close() {} } -export function connect() { return new Socket(); } -export function createConnection() { return new Socket(); } -export function createServer() { return new Server(); } -export function isIP(s) { return /^\d+\.\d+\.\d+\.\d+$/.test(s) ? 4 : 0; } -export function isIPv4(s) { return isIP(s) === 4; } -export function isIPv6() { return false; } -export default { Socket, Server, connect, createConnection, createServer, isIP, isIPv4, isIPv6 }; diff --git a/js/src/runtime/node/os.ts b/js/src/runtime/node/os.ts deleted file mode 100644 index 5712893..0000000 --- a/js/src/runtime/node/os.ts +++ /dev/null @@ -1,42 +0,0 @@ -// node:os — backed by native ops for the machine-specific bits. -const n = globalThis.__node; - -export function platform() { - return (globalThis.process && globalThis.process.platform) || "linux"; -} -export function homedir() { - return n ? n.homedir() : "/"; -} -export function tmpdir() { - return n ? n.tmpdir() : "/tmp"; -} -export function hostname() { - return n && n.hostname ? n.hostname() : "localhost"; -} -export function arch() { - return (globalThis.process && globalThis.process.arch) || "x64"; -} -export function type() { - return platform() === "darwin" ? "Darwin" : platform() === "win32" ? "Windows_NT" : "Linux"; -} -export function release() { - return "0.0.0"; -} -export function cpus() { - return []; -} -export function totalmem() { - return 0; -} -export function freemem() { - return 0; -} -export function uptime() { - return 0; -} -export function userInfo() { - return { username: "user", homedir: homedir(), shell: null, uid: -1, gid: -1 }; -} -export const EOL = "\n"; -export const constants = { signals: {}, errno: {} }; -export default { platform, homedir, tmpdir, hostname, arch, type, release, cpus, totalmem, freemem, uptime, userInfo, EOL, constants }; diff --git a/js/src/runtime/node/path.ts b/js/src/runtime/node/path.ts deleted file mode 100644 index 64998cc..0000000 --- a/js/src/runtime/node/path.ts +++ /dev/null @@ -1,144 +0,0 @@ -// node:path (POSIX subset) — pure JS, enough for pi + its deps. -const sep = "/"; - -function assertPath(p) { - if (typeof p !== "string") throw new TypeError("Path must be a string. Received " + typeof p); -} - -function normalizeArray(parts, allowAboveRoot) { - const res = []; - for (const p of parts) { - if (!p || p === ".") continue; - if (p === "..") { - if (res.length && res[res.length - 1] !== "..") res.pop(); - else if (allowAboveRoot) res.push(".."); - } else res.push(p); - } - return res; -} - -export function normalize(path) { - assertPath(path); - if (path.length === 0) return "."; - const isAbs = path.charCodeAt(0) === 47; - const trailing = path.charCodeAt(path.length - 1) === 47; - let out = normalizeArray(path.split("/"), !isAbs).join("/"); - if (!out && !isAbs) out = "."; - if (out && trailing) out += "/"; - return (isAbs ? "/" : "") + out; -} - -export function isAbsolute(path) { - assertPath(path); - return path.length > 0 && path.charCodeAt(0) === 47; -} - -export function join(...args) { - if (args.length === 0) return "."; - let joined; - for (const arg of args) { - assertPath(arg); - if (arg.length > 0) joined = joined === undefined ? arg : joined + "/" + arg; - } - if (joined === undefined) return "."; - return normalize(joined); -} - -export function resolve(...args) { - let resolved = ""; - let isAbs = false; - for (let i = args.length - 1; i >= -1 && !isAbs; i--) { - const path = i >= 0 ? args[i] : cwd(); - assertPath(path); - if (path.length === 0) continue; - resolved = path + "/" + resolved; - isAbs = path.charCodeAt(0) === 47; - } - const parts = normalizeArray(resolved.split("/"), !isAbs); - resolved = parts.join("/"); - if (isAbs) return "/" + resolved; - return resolved.length > 0 ? resolved : "."; -} - -function cwd() { - return (globalThis.process && globalThis.process.cwd && globalThis.process.cwd()) || "/"; -} - -export function dirname(path) { - assertPath(path); - if (path.length === 0) return "."; - let end = -1; - let matchedSlash = true; - for (let i = path.length - 1; i >= 1; --i) { - if (path.charCodeAt(i) === 47) { - if (!matchedSlash) { end = i; break; } - } else matchedSlash = false; - } - if (end === -1) return path.charCodeAt(0) === 47 ? "/" : "."; - if (end === 0 && path.charCodeAt(0) === 47) return "/"; - return path.slice(0, end); -} - -export function basename(path, ext) { - assertPath(path); - let start = 0, end = -1, matchedSlash = true; - for (let i = path.length - 1; i >= 0; --i) { - if (path.charCodeAt(i) === 47) { - if (!matchedSlash) { start = i + 1; break; } - } else if (end === -1) { matchedSlash = false; end = i + 1; } - } - let base = end === -1 ? "" : path.slice(start, end); - if (ext && base.endsWith(ext) && base !== ext) base = base.slice(0, -ext.length); - return base; -} - -export function extname(path) { - assertPath(path); - let startDot = -1, startPart = 0, end = -1, matchedSlash = true, preDotState = 0; - for (let i = path.length - 1; i >= 0; --i) { - const code = path.charCodeAt(i); - if (code === 47) { if (!matchedSlash) { startPart = i + 1; break; } continue; } - if (end === -1) { matchedSlash = false; end = i + 1; } - if (code === 46) { if (startDot === -1) startDot = i; else if (preDotState !== 1) preDotState = 1; } - else if (startDot !== -1) preDotState = -1; - } - if (startDot === -1 || end === -1 || preDotState === 0 || (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)) return ""; - return path.slice(startDot, end); -} - -export function relative(from, to) { - from = resolve(from); - to = resolve(to); - if (from === to) return ""; - const fromParts = from.split("/").filter(Boolean); - const toParts = to.split("/").filter(Boolean); - let i = 0; - while (i < fromParts.length && i < toParts.length && fromParts[i] === toParts[i]) i++; - const up = fromParts.length - i; - const out = []; - for (let j = 0; j < up; j++) out.push(".."); - return out.concat(toParts.slice(i)).join("/"); -} - -export function parse(path) { - const root = isAbsolute(path) ? "/" : ""; - const dir = dirname(path); - const base = basename(path); - const ext = extname(base); - return { root, dir, base, ext, name: ext ? base.slice(0, -ext.length) : base }; -} - -export function toNamespacedPath(path) { return path; } // no-op on POSIX -export function format(obj) { - const dir = obj.dir || obj.root || ""; - const base = obj.base || `${obj.name || ""}${obj.ext || ""}`; - if (!dir) return base; - return dir === obj.root ? `${dir}${base}` : `${dir}${sep}${base}`; -} - -export const posix = { sep, delimiter: ":", normalize, isAbsolute, join, resolve, dirname, basename, extname, relative, parse, format, toNamespacedPath }; -// We only implement POSIX semantics; win32 is a passthrough so imports resolve. -export const win32 = { ...posix, sep: "\\", delimiter: ";" }; -export { sep }; -export const delimiter = ":"; -export default { sep, delimiter, normalize, isAbsolute, join, resolve, dirname, basename, extname, relative, parse, format, toNamespacedPath, posix, win32 }; diff --git a/js/src/runtime/node/perf_hooks.ts b/js/src/runtime/node/perf_hooks.ts deleted file mode 100644 index 6e0d84f..0000000 --- a/js/src/runtime/node/perf_hooks.ts +++ /dev/null @@ -1,4 +0,0 @@ -// node:perf_hooks -export const performance = globalThis.performance || { now: () => Date.now(), timeOrigin: 0 }; -export class PerformanceObserver { observe() {} disconnect() {} } -export default { performance, PerformanceObserver }; diff --git a/js/src/runtime/node/process.ts b/js/src/runtime/node/process.ts deleted file mode 100644 index 119d5b1..0000000 --- a/js/src/runtime/node/process.ts +++ /dev/null @@ -1,11 +0,0 @@ -// node:process — re-exports the global process object the runtime installs. -const p = globalThis.process; -export const env = p.env; -export const platform = p.platform; -export const argv = p.argv; -export const version = p.version; -export const versions = p.versions; -export const cwd = p.cwd; -export const nextTick = p.nextTick; -export const exit = p.exit; -export default p; diff --git a/js/src/runtime/node/querystring.ts b/js/src/runtime/node/querystring.ts deleted file mode 100644 index f500686..0000000 --- a/js/src/runtime/node/querystring.ts +++ /dev/null @@ -1,4 +0,0 @@ -export function parse(str) { const o = {}; for (const p of String(str).split("&")) { if (!p) continue; const i = p.indexOf("="); const k = decodeURIComponent(i < 0 ? p : p.slice(0, i)); const v = i < 0 ? "" : decodeURIComponent(p.slice(i + 1)); o[k] = v; } return o; } -export function stringify(obj) { return Object.entries(obj || {}).map(([k, v]) => encodeURIComponent(k) + "=" + encodeURIComponent(v)).join("&"); } -export const decode = parse, encode = stringify; -export default { parse, stringify, decode, encode }; diff --git a/js/src/runtime/node/readline.ts b/js/src/runtime/node/readline.ts deleted file mode 100644 index 2a05a00..0000000 --- a/js/src/runtime/node/readline.ts +++ /dev/null @@ -1,10 +0,0 @@ -// node:readline — stub sufficient for import; interactive input isn't used headless. -import { EventEmitter } from "node:events"; -export function createInterface() { - const rl = new EventEmitter(); - rl.question = (_q, cb) => cb && cb(""); - rl.close = () => {}; - rl.on = rl.on.bind(rl); - return rl; -} -export default { createInterface }; diff --git a/js/src/runtime/node/stream-promises.ts b/js/src/runtime/node/stream-promises.ts deleted file mode 100644 index d3107bd..0000000 --- a/js/src/runtime/node/stream-promises.ts +++ /dev/null @@ -1,12 +0,0 @@ -// node:stream/promises -export function pipeline(...args) { - if (typeof args[args.length - 1] === "function") args.pop(); - return Promise.resolve(); -} -export function finished(stream) { - return new Promise((res) => { - if (stream && stream.on) { stream.on("end", res); stream.on("finish", res); } - queueMicrotask(res); - }); -} -export default { pipeline, finished }; diff --git a/js/src/runtime/node/stream.ts b/js/src/runtime/node/stream.ts deleted file mode 100644 index 85a59b0..0000000 --- a/js/src/runtime/node/stream.ts +++ /dev/null @@ -1,24 +0,0 @@ -// node:stream — minimal Readable/Writable/Transform/PassThrough over EventEmitter. -import { EventEmitter } from "node:events"; -export class Readable extends EventEmitter { - constructor(opts) { super(); this._opts = opts || {}; } - push(chunk) { if (chunk === null) this.emit("end"); else this.emit("data", chunk); return true; } - pipe(dest) { this.on("data", (c) => dest.write && dest.write(c)); this.on("end", () => dest.end && dest.end()); return dest; } - read() { return null; } - static from(iterable) { const r = new Readable(); queueMicrotask(async () => { for await (const c of iterable) r.push(c); r.push(null); }); return r; } -} -export class Writable extends EventEmitter { - constructor(opts) { super(); this._opts = opts || {}; } - write(chunk, _enc, cb) { if (this._opts.write) this._opts.write(chunk, _enc, cb || (() => {})); else if (cb) cb(); return true; } - end(chunk, _enc, cb) { if (chunk) this.write(chunk); this.emit("finish"); if (cb) cb(); } -} -export class Duplex extends Readable {} -export class Transform extends Duplex {} -export class PassThrough extends Transform {} -export default { Readable, Writable, Duplex, Transform, PassThrough }; -export function pipeline(...args) { - const cb = typeof args[args.length - 1] === "function" ? args.pop() : null; - queueMicrotask(() => cb && cb(null)); - return args[args.length - 1]; -} -export function finished(stream, cb) { queueMicrotask(() => cb && cb(null)); } diff --git a/js/src/runtime/node/string_decoder.ts b/js/src/runtime/node/string_decoder.ts deleted file mode 100644 index aa528db..0000000 --- a/js/src/runtime/node/string_decoder.ts +++ /dev/null @@ -1,7 +0,0 @@ -// node:string_decoder -export class StringDecoder { - constructor(encoding) { this.encoding = encoding || "utf8"; this._dec = new TextDecoder(); } - write(buf) { return this._dec.decode(buf instanceof Uint8Array ? buf : globalThis.Buffer.from(buf)); } - end(buf) { return buf ? this.write(buf) : ""; } -} -export default { StringDecoder }; diff --git a/js/src/runtime/node/timers.ts b/js/src/runtime/node/timers.ts deleted file mode 100644 index 95f2358..0000000 --- a/js/src/runtime/node/timers.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const setTimeout = globalThis.setTimeout; -export const clearTimeout = globalThis.clearTimeout; -export const setInterval = globalThis.setInterval; -export const clearInterval = globalThis.clearInterval; -export const setImmediate = (fn, ...a) => globalThis.setTimeout(fn, 0, ...a); -export const clearImmediate = globalThis.clearTimeout; -export const promises = { setTimeout: (ms) => new Promise((r) => globalThis.setTimeout(r, ms)) }; -export default { setTimeout, clearTimeout, setInterval, clearInterval, setImmediate, clearImmediate, promises }; diff --git a/js/src/runtime/node/tls.ts b/js/src/runtime/node/tls.ts deleted file mode 100644 index 6cad175..0000000 --- a/js/src/runtime/node/tls.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Socket } from "node:net"; -export class TLSSocket extends Socket {} -export function connect() { return new TLSSocket(); } -export function createSecureContext() { return {}; } -export const rootCertificates = []; -export default { TLSSocket, connect, createSecureContext, rootCertificates }; diff --git a/js/src/runtime/node/tty.ts b/js/src/runtime/node/tty.ts deleted file mode 100644 index 799b5db..0000000 --- a/js/src/runtime/node/tty.ts +++ /dev/null @@ -1,5 +0,0 @@ -// node:tty — stub (Pocket Pi runs headless). -export function isatty() { return false; } -export class ReadStream {} -export class WriteStream {} -export default { isatty, ReadStream, WriteStream }; diff --git a/js/src/runtime/node/url.ts b/js/src/runtime/node/url.ts deleted file mode 100644 index 36c725d..0000000 --- a/js/src/runtime/node/url.ts +++ /dev/null @@ -1,35 +0,0 @@ -// node:url -export const URL = globalThis.URL; -export const URLSearchParams = globalThis.URLSearchParams; -export function fileURLToPath(url) { - let s = typeof url === "string" ? url : url.href; - if (s.startsWith("file://")) s = s.slice(7); - return decodeURIComponent(s); -} -export function pathToFileURL(path) { - return new globalThis.URL("file://" + encodeURI(path)); -} -// Legacy url.parse/format/resolve. -export function parse(str) { - try { - const u = new globalThis.URL(str); - return { href: u.href, protocol: u.protocol, host: u.host, hostname: u.hostname, port: u.port, pathname: u.pathname, search: u.search, hash: u.hash, query: u.search.replace(/^\?/, "") }; - } catch { - return { href: str, pathname: str, protocol: null, host: null, hostname: null, port: "", search: "", hash: "", query: "" }; - } -} -export function format(obj) { - if (typeof obj === "string") return obj; - if (obj && typeof obj.href === "string" && obj.protocol) return obj.href; - const proto = obj.protocol ? (obj.protocol.endsWith(":") ? obj.protocol : obj.protocol + ":") : ""; - const host = obj.host || (obj.hostname ? obj.hostname + (obj.port ? ":" + obj.port : "") : ""); - const search = obj.search || (obj.query ? "?" + (typeof obj.query === "string" ? obj.query : new globalThis.URLSearchParams(obj.query).toString()) : ""); - return (proto ? proto + "//" : "") + host + (obj.pathname || "") + search + (obj.hash || ""); -} -export function resolve(from, to) { - try { return new globalThis.URL(to, from).href; } catch { return to; } -} -export const Url = globalThis.URL; -export function domainToASCII(d) { return d; } -export function domainToUnicode(d) { return d; } -export default { URL, URLSearchParams, fileURLToPath, pathToFileURL, parse, format, resolve, Url, domainToASCII, domainToUnicode }; diff --git a/js/src/runtime/node/util.ts b/js/src/runtime/node/util.ts deleted file mode 100644 index d307df5..0000000 --- a/js/src/runtime/node/util.ts +++ /dev/null @@ -1,76 +0,0 @@ -// node:util — the commonly-used subset. -export function inherits(ctor, superCtor) { - ctor.super_ = superCtor; - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { value: ctor, enumerable: false, writable: true, configurable: true }, - }); -} - -export function format(fmt, ...args) { - if (typeof fmt !== "string") return [fmt, ...args].map(inspect).join(" "); - let i = 0; - let out = fmt.replace(/%[sdifjoO%]/g, (m) => { - if (m === "%%") return "%"; - if (i >= args.length) return m; - const a = args[i++]; - switch (m) { - case "%s": return String(a); - case "%d": case "%i": return String(parseInt(a, 10)); - case "%f": return String(parseFloat(a)); - case "%j": try { return JSON.stringify(a); } catch { return "[Circular]"; } - default: return inspect(a); - } - }); - for (; i < args.length; i++) out += " " + (typeof args[i] === "string" ? args[i] : inspect(args[i])); - return out; -} - -export function inspect(obj) { - if (typeof obj === "string") return obj; - try { return JSON.stringify(obj); } catch { return String(obj); } -} -inspect.custom = Symbol.for("nodejs.util.inspect.custom"); - -export function promisify(fn) { - return function (...args) { - return new Promise((resolve, reject) => { - fn.call(this, ...args, (err, ...rest) => (err ? reject(err) : resolve(rest.length > 1 ? rest : rest[0]))); - }); - }; -} - -export function callbackify(fn) { - return function (...args) { - const cb = args.pop(); - fn.apply(this, args).then((v) => cb(null, v), (e) => cb(e)); - }; -} - -export function deprecate(fn) { return fn; } -// debuglog(section) → a logger; enabled only if NODE_DEBUG lists the section. -export function debuglog(section, cb) { - const env = (globalThis.process && globalThis.process.env && globalThis.process.env.NODE_DEBUG) || ""; - const on = env.split(/[\s,]+/).includes(section); - const fn = on ? (...args) => { try { console.error(`${section}:`, format(...args)); } catch {} } : () => {}; - if (typeof cb === "function") cb(fn); - return fn; -} -export const debug = debuglog; -export function inspect2() {} -export const isDeepStrictEqual = (a, b) => { try { return JSON.stringify(a) === JSON.stringify(b); } catch { return a === b; } }; -export function stripVTControlCharacters(s) { return String(s).replace(/\x1b\[[0-9;]*m/g, ""); } -export const _extend = Object.assign; - -export const types = { - isPromise: (v) => v && typeof v.then === "function", - isDate: (v) => v instanceof Date, - isRegExp: (v) => v instanceof RegExp, - isArrayBuffer: (v) => v instanceof ArrayBuffer, - isTypedArray: (v) => ArrayBuffer.isView(v) && !(v instanceof DataView), - isAsyncFunction: (v) => v && v.constructor && v.constructor.name === "AsyncFunction", -}; - -export const TextEncoder = globalThis.TextEncoder; -export const TextDecoder = globalThis.TextDecoder; - -export default { inherits, format, inspect, promisify, callbackify, deprecate, debuglog, debug, isDeepStrictEqual, stripVTControlCharacters, _extend, types, TextEncoder, TextDecoder }; diff --git a/js/src/runtime/node/v8.ts b/js/src/runtime/node/v8.ts deleted file mode 100644 index 1d6dd84..0000000 --- a/js/src/runtime/node/v8.ts +++ /dev/null @@ -1,2 +0,0 @@ -// node:v8 — minimal stub. -export default {}; diff --git a/js/src/runtime/node/vm.ts b/js/src/runtime/node/vm.ts deleted file mode 100644 index e3cdff0..0000000 --- a/js/src/runtime/node/vm.ts +++ /dev/null @@ -1,2 +0,0 @@ -// node:vm — minimal stub. -export default {}; diff --git a/js/src/runtime/node/worker_threads.ts b/js/src/runtime/node/worker_threads.ts deleted file mode 100644 index 5abc477..0000000 --- a/js/src/runtime/node/worker_threads.ts +++ /dev/null @@ -1,40 +0,0 @@ -// node:worker_threads — stub. Pocket Pi is single-threaded (one QuickJS realm), -// so there are no real workers; these exist so imports resolve. `Worker` throws -// if actually constructed. -export class Worker { - constructor() { - throw new Error("worker_threads.Worker is not supported in Pocket Pi (single-threaded)"); - } -} -export const isMainThread = true; -export const parentPort = null; -export const threadId = 0; -export const workerData = null; -export class MessageChannel { - constructor() { this.port1 = new MessagePort(); this.port2 = new MessagePort(); } -} -export class MessagePort { - postMessage() {} - on() { return this; } - once() { return this; } - close() {} - ref() { return this; } - unref() { return this; } - start() {} -} -export const BroadcastChannel = class BroadcastChannel { - postMessage() {} - close() {} - on() { return this; } -}; -export function markAsUntransferable() {} -export function moveMessagePortToContext() { throw new Error("not supported"); } -export function receiveMessageOnPort() { return undefined; } -export function setEnvironmentData() {} -export function getEnvironmentData() { return undefined; } -export default { - Worker, isMainThread, parentPort, threadId, workerData, - MessageChannel, MessagePort, BroadcastChannel, - markAsUntransferable, moveMessagePortToContext, receiveMessageOnPort, - setEnvironmentData, getEnvironmentData, -}; diff --git a/js/src/runtime/node/zlib.ts b/js/src/runtime/node/zlib.ts deleted file mode 100644 index 58e2e77..0000000 --- a/js/src/runtime/node/zlib.ts +++ /dev/null @@ -1,6 +0,0 @@ -const nope = (n) => () => { throw new Error("zlib." + n + " not supported"); }; -export const gzip = nope("gzip"), gunzip = nope("gunzip"), deflate = nope("deflate"), inflate = nope("inflate"); -export const gzipSync = nope("gzipSync"), gunzipSync = nope("gunzipSync"), deflateSync = nope("deflateSync"), inflateSync = nope("inflateSync"), brotliCompressSync = nope("brotliCompressSync"), brotliDecompressSync = nope("brotliDecompressSync"); -export const constants = {}; -export function createGzip() { throw new Error("zlib streams not supported"); } -export default { gzip, gunzip, deflate, inflate, gzipSync, gunzipSync, deflateSync, inflateSync, brotliCompressSync, brotliDecompressSync, constants, createGzip }; diff --git a/js/src/runtime/prelude.ts b/js/src/runtime/prelude.ts deleted file mode 100644 index 931efc0..0000000 --- a/js/src/runtime/prelude.ts +++ /dev/null @@ -1,121 +0,0 @@ -// Pocket Pi prelude — the Web/Node globals pi's agent core expects that classic -// QuickJS does not ship. Evaluated once before the agent bundle. Everything here -// is pure JS on top of QuickJS's ES2023 baseline (Promise, Map, Set, async -// generators, Date, JSON) plus the native `host` namespace mounted by Rust. -// -// Deliberately minimal: byte decoding and HTTPS live in Rust, so no TextDecoder -// or fetch is needed on the JS side — only timers, abort, microtasks, and uuid. - -(function () { - "use strict"; - - // Node's `global` alias + setImmediate (many CJS deps assume them). - if (typeof globalThis.global === "undefined") globalThis.global = globalThis; - if (typeof globalThis.setImmediate !== "function") - globalThis.setImmediate = (fn, ...a) => globalThis.setTimeout(fn, 0, ...a); - if (typeof globalThis.clearImmediate !== "function") - globalThis.clearImmediate = (id) => globalThis.clearTimeout(id); - - // --- timers, advanced by the host frame pump (globalThis.__catpiTimers) --- - const timers = new Map(); - let nextTimer = 1; - globalThis.setTimeout = function (fn, delay, ...args) { - const id = nextTimer++; - timers.set(id, { due: Date.now() + (delay || 0), fn, args }); - return id; - }; - globalThis.clearTimeout = function (id) { - timers.delete(id); - }; - globalThis.setInterval = function () { - throw new Error("setInterval is not supported in Pocket Pi"); - }; - globalThis.clearInterval = function () {}; - globalThis.__catpiTimers = function () { - if (timers.size === 0) return; - const now = Date.now(); - for (const [id, t] of timers) { - if (t.due <= now) { - timers.delete(id); - try { - t.fn(...t.args); - } catch (e) { - if (globalThis.host && host.emit) - host.emit(JSON.stringify({ kind: "error", message: "timer: " + String(e) })); - } - } - } - }; - - // --- queueMicrotask (QuickJS drains the job queue after each host frame) --- - if (typeof globalThis.queueMicrotask !== "function") { - globalThis.queueMicrotask = function (fn) { - Promise.resolve().then(fn); - }; - } - - // --- structuredClone (JSON-safe deep clone is enough for tool arguments) --- - if (typeof globalThis.structuredClone !== "function") { - globalThis.structuredClone = function (v) { - return v === undefined ? undefined : JSON.parse(JSON.stringify(v)); - }; - } - - // --- AbortController / AbortSignal --- - if (typeof globalThis.AbortController !== "function") { - class PPAbortSignal { - constructor() { - this.aborted = false; - this.reason = undefined; - this._listeners = []; - } - addEventListener(type, cb) { - if (type === "abort") this._listeners.push(cb); - } - removeEventListener(type, cb) { - if (type === "abort") this._listeners = this._listeners.filter((l) => l !== cb); - } - _fire() { - if (this.aborted) return; - this.aborted = true; - for (const l of this._listeners.slice()) { - try { - l({ type: "abort" }); - } catch {} - } - } - throwIfAborted() { - if (this.aborted) throw this.reason || new Error("Aborted"); - } - } - globalThis.AbortSignal = PPAbortSignal; - globalThis.AbortController = class { - constructor() { - this.signal = new PPAbortSignal(); - } - abort(reason) { - this.signal.reason = reason || new Error("Aborted"); - this.signal._fire(); - } - }; - } - - // --- crypto.randomUUID (host-backed for real entropy; JS fallback otherwise) --- - if (typeof globalThis.crypto !== "object" || !globalThis.crypto) globalThis.crypto = {}; - if (typeof globalThis.crypto.randomUUID !== "function") { - globalThis.crypto.randomUUID = function () { - if (globalThis.host && host.uuid) return host.uuid(); - // Fallback: not cryptographically strong; fine for tool-call ids. - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { - const r = (Date.now() + Math.floor(Math.random() * 1e9)) % 16; - const v = c === "x" ? r : (r & 0x3) | 0x8; - return v.toString(16); - }); - }; - } - - // --- process shim: pi guards most access with typeof process checks --- - if (typeof globalThis.process !== "object" || !globalThis.process) { - globalThis.process = { env: {}, platform: "pocket-pi", versions: {} }; - } -})(); diff --git a/js/src/runtime/web-globals.ts b/js/src/runtime/web-globals.ts deleted file mode 100644 index 2bb7166..0000000 --- a/js/src/runtime/web-globals.ts +++ /dev/null @@ -1,442 +0,0 @@ -// WHATWG Web globals for Pocket Pi — fetch / Response / ReadableStream / Headers -// / URL / atob / btoa / crypto.getRandomValues. Backed by the native HTTP hub -// (raw mode) and driven by the frame pump, so a real npm package that does -// `fetch(...).then(r => r.body.getReader())` works unmodified. - -(function () { - "use strict"; - const B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - // --- Intl (minimal; QuickJS ships none) --- - if (typeof globalThis.Intl !== "object" || !globalThis.Intl) { - globalThis.Intl = { - Segmenter: class { - constructor() {} - segment(str) { - const chars = [...String(str)]; // code-point granularity ≈ grapheme - return { - [Symbol.iterator]() { - let i = 0; - return { - next() { - return i < chars.length - ? { value: { segment: chars[i], index: i++, input: str }, done: false } - : { value: undefined, done: true }; - }, - }; - }, - }; - } - }, - NumberFormat: class { constructor() {} format(n) { return String(n); } formatToParts() { return []; } }, - DateTimeFormat: class { constructor() {} format(d) { return String(d); } formatToParts() { return []; } }, - Collator: class { constructor() {} compare(a, b) { return a < b ? -1 : a > b ? 1 : 0; } }, - getCanonicalLocales: (l) => (Array.isArray(l) ? l : [l]).filter(Boolean), - }; - } - - // --- Blob / File / FormData (referenced by the OpenAI transport even for - // JSON requests; we send JSON bodies, so these just need to exist) --- - if (typeof globalThis.Blob === "undefined") { - globalThis.Blob = class Blob { - constructor(parts = [], opts = {}) { - this._parts = parts; - this.type = (opts && opts.type) || ""; - let size = 0; - for (const p of parts) { - if (typeof p === "string") size += p.length; - else if (p && p.byteLength != null) size += p.byteLength; - else if (p && p.size != null) size += p.size; - } - this.size = size; - } - async text() { - return this._parts.map((p) => (typeof p === "string" ? p : "")).join(""); - } - async arrayBuffer() { - return new globalThis.TextEncoder().encode(await this.text()).buffer; - } - slice() { return new globalThis.Blob(this._parts, { type: this.type }); } - }; - } - if (typeof globalThis.File === "undefined") { - globalThis.File = class File extends globalThis.Blob { - constructor(parts, name, opts = {}) { - super(parts, opts); - this.name = String(name); - this.lastModified = 0; - } - }; - } - if (typeof globalThis.FormData === "undefined") { - globalThis.FormData = class FormData { - constructor() { this._entries = []; } - append(k, v, filename) { this._entries.push([String(k), v, filename]); } - set(k, v) { - this._entries = this._entries.filter((e) => e[0] !== String(k)); - this._entries.push([String(k), v]); - } - get(k) { const e = this._entries.find((e) => e[0] === String(k)); return e ? e[1] : null; } - getAll(k) { return this._entries.filter((e) => e[0] === String(k)).map((e) => e[1]); } - has(k) { return this._entries.some((e) => e[0] === String(k)); } - delete(k) { this._entries = this._entries.filter((e) => e[0] !== String(k)); } - forEach(cb, thisArg) { for (const [k, v] of this._entries) cb.call(thisArg, v, k, this); } - *entries() { for (const e of this._entries) yield [e[0], e[1]]; } - *keys() { for (const e of this._entries) yield e[0]; } - *values() { for (const e of this._entries) yield e[1]; } - [Symbol.iterator]() { return this.entries(); } - }; - } - - // --- Web event/message globals (undici's webidl references these as globals - // during module init; we don't do real message passing, so they're stubs) --- - if (typeof globalThis.EventTarget !== "function") { - globalThis.EventTarget = class EventTarget { - constructor() { this.__l = {}; } - addEventListener(t, cb) { (this.__l[t] ||= []).push(cb); } - removeEventListener(t, cb) { this.__l[t] = (this.__l[t] || []).filter((f) => f !== cb); } - dispatchEvent(e) { for (const cb of this.__l[e && e.type] || []) { try { cb(e); } catch {} } return true; } - }; - } - if (typeof globalThis.Event !== "function") { - globalThis.Event = class Event { - constructor(type, init = {}) { this.type = type; this.bubbles = !!init.bubbles; this.defaultPrevented = false; } - preventDefault() { this.defaultPrevented = true; } - stopPropagation() {} - stopImmediatePropagation() {} - }; - } - if (typeof globalThis.CustomEvent !== "function") { - globalThis.CustomEvent = class CustomEvent extends globalThis.Event { - constructor(type, init = {}) { super(type, init); this.detail = init.detail; } - }; - } - if (typeof globalThis.MessagePort !== "function") { - globalThis.MessagePort = class MessagePort extends globalThis.EventTarget { - postMessage() {} start() {} close() {} - on() { return this; } once() { return this; } - ref() { return this; } unref() { return this; } - }; - } - if (typeof globalThis.MessageChannel !== "function") { - globalThis.MessageChannel = class MessageChannel { - constructor() { this.port1 = new globalThis.MessagePort(); this.port2 = new globalThis.MessagePort(); } - }; - } - if (typeof globalThis.DOMException !== "function") { - globalThis.DOMException = class DOMException extends Error { - constructor(message, name) { super(message); this.name = name || "Error"; } - }; - } - - // --- TextEncoder / TextDecoder (UTF-8) --- - if (typeof globalThis.TextEncoder !== "function") { - globalThis.TextEncoder = class TextEncoder { - get encoding() { return "utf-8"; } - encode(str) { - str = String(str); - const out = []; - for (let i = 0; i < str.length; i++) { - let c = str.charCodeAt(i); - if (c < 0x80) out.push(c); - else if (c < 0x800) out.push(0xc0 | (c >> 6), 0x80 | (c & 0x3f)); - else if (c >= 0xd800 && c <= 0xdbff) { - const c2 = str.charCodeAt(++i); - c = 0x10000 + ((c & 0x3ff) << 10) + (c2 & 0x3ff); - out.push(0xf0 | (c >> 18), 0x80 | ((c >> 12) & 0x3f), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f)); - } else out.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 0x3f), 0x80 | (c & 0x3f)); - } - return new Uint8Array(out); - } - }; - } - if (typeof globalThis.TextDecoder !== "function") { - globalThis.TextDecoder = class TextDecoder { - constructor(label) { this._enc = label || "utf-8"; } - get encoding() { return "utf-8"; } - decode(input) { - if (!input) return ""; - const bytes = input instanceof Uint8Array ? input : new Uint8Array(input.buffer || input); - let out = "", i = 0; - while (i < bytes.length) { - let c = bytes[i++]; - if (c < 0x80) out += String.fromCharCode(c); - else if (c >= 0xc0 && c < 0xe0) out += String.fromCharCode(((c & 0x1f) << 6) | (bytes[i++] & 0x3f)); - else if (c >= 0xe0 && c < 0xf0) out += String.fromCharCode(((c & 0xf) << 12) | ((bytes[i++] & 0x3f) << 6) | (bytes[i++] & 0x3f)); - else { - const cp = ((c & 7) << 18) | ((bytes[i++] & 0x3f) << 12) | ((bytes[i++] & 0x3f) << 6) | (bytes[i++] & 0x3f); - const off = cp - 0x10000; - out += String.fromCharCode(0xd800 + (off >> 10), 0xdc00 + (off & 0x3ff)); - } - } - return out; - } - }; - } - - // --- atob / btoa --- - if (typeof globalThis.btoa !== "function") { - globalThis.btoa = function (bin) { - let out = ""; - for (let i = 0; i < bin.length; i += 3) { - const a = bin.charCodeAt(i), b = bin.charCodeAt(i + 1), c = bin.charCodeAt(i + 2); - const n = (a << 16) | ((isNaN(b) ? 0 : b) << 8) | (isNaN(c) ? 0 : c); - out += B64[(n >> 18) & 63] + B64[(n >> 12) & 63] + (isNaN(b) ? "=" : B64[(n >> 6) & 63]) + (isNaN(c) ? "=" : B64[n & 63]); - } - return out; - }; - } - if (typeof globalThis.atob !== "function") { - globalThis.atob = function (b64) { - b64 = String(b64).replace(/[^A-Za-z0-9+/]/g, ""); - let out = ""; - for (let i = 0; i < b64.length; i += 4) { - const n = (B64.indexOf(b64[i]) << 18) | (B64.indexOf(b64[i + 1]) << 12) | (B64.indexOf(b64[i + 2] || "A") << 6) | B64.indexOf(b64[i + 3] || "A"); - out += String.fromCharCode((n >> 16) & 255); - if (b64[i + 2] && b64[i + 2] !== "=") out += String.fromCharCode((n >> 8) & 255); - if (b64[i + 3] && b64[i + 3] !== "=") out += String.fromCharCode(n & 255); - } - return out; - }; - } - function b64ToBytes(b64) { - const bin = globalThis.atob(b64); - const u = new Uint8Array(bin.length); - for (let i = 0; i < bin.length; i++) u[i] = bin.charCodeAt(i); - return u; - } - - // --- crypto.getRandomValues (non-cryptographic fallback; fine for request ids) --- - if (typeof globalThis.crypto !== "object" || !globalThis.crypto) globalThis.crypto = {}; - if (typeof globalThis.crypto.getRandomValues !== "function") { - globalThis.crypto.getRandomValues = function (arr) { - for (let i = 0; i < arr.length; i++) arr[i] = Math.floor(Math.random() * 256); - return arr; - }; - } - - // --- Headers --- - if (typeof globalThis.Headers !== "function") { - globalThis.Headers = class Headers { - constructor(init) { - this._m = new Map(); - if (init) { - const entries = init instanceof Headers ? init.entries() : Array.isArray(init) ? init : Object.entries(init); - for (const [k, v] of entries) this.set(k, v); - } - } - set(k, v) { this._m.set(String(k).toLowerCase(), String(v)); } - append(k, v) { const p = this._m.get(String(k).toLowerCase()); this.set(k, p ? p + ", " + v : v); } - get(k) { const v = this._m.get(String(k).toLowerCase()); return v === undefined ? null : v; } - has(k) { return this._m.has(String(k).toLowerCase()); } - delete(k) { this._m.delete(String(k).toLowerCase()); } - forEach(fn) { this._m.forEach((v, k) => fn(v, k, this)); } - entries() { return this._m.entries(); } - keys() { return this._m.keys(); } - values() { return this._m.values(); } - [Symbol.iterator]() { return this._m.entries(); } - }; - } - - // --- URL / URLSearchParams (minimal but base-aware) --- - if (typeof globalThis.URLSearchParams !== "function") { - globalThis.URLSearchParams = class URLSearchParams { - constructor(init) { - this._p = []; - if (typeof init === "string") { - for (const pair of init.replace(/^\?/, "").split("&")) { - if (!pair) continue; - const i = pair.indexOf("="); - this._p.push(i < 0 ? [decodeURIComponent(pair), ""] : [decodeURIComponent(pair.slice(0, i)), decodeURIComponent(pair.slice(i + 1))]); - } - } else if (init) for (const [k, v] of Object.entries(init)) this._p.push([k, String(v)]); - } - get(k) { const e = this._p.find((x) => x[0] === k); return e ? e[1] : null; } - set(k, v) { const e = this._p.find((x) => x[0] === k); if (e) e[1] = String(v); else this._p.push([k, String(v)]); } - append(k, v) { this._p.push([k, String(v)]); } - has(k) { return this._p.some((x) => x[0] === k); } - delete(k) { this._p = this._p.filter((x) => x[0] !== k); } - forEach(fn) { for (const [k, v] of this._p) fn(v, k, this); } - toString() { return this._p.map(([k, v]) => encodeURIComponent(k) + "=" + encodeURIComponent(v)).join("&"); } - [Symbol.iterator]() { return this._p[Symbol.iterator](); } - }; - } - if (typeof globalThis.URL !== "function") { - globalThis.URL = class URL { - constructor(url, base) { - let full = String(url); - if (base && !/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(full)) { - const b = String(base).replace(/\/+$/, ""); - full = full.startsWith("/") ? originOf(b) + full : b + "/" + full; - } - const m = /^([a-zA-Z][a-zA-Z0-9+.-]*:)\/\/([^/?#]*)([^?#]*)(\?[^#]*)?(#.*)?$/.exec(full); - if (!m) throw new TypeError("Invalid URL: " + full); - this.protocol = m[1]; - this.host = m[2]; - this.hostname = m[2].split(":")[0]; - this.port = m[2].split(":")[1] || ""; - this.pathname = m[3] || "/"; - this.search = m[4] || ""; - this.hash = m[5] || ""; - this.searchParams = new globalThis.URLSearchParams(this.search); - this.origin = this.protocol + "//" + this.host; - } - get href() { return this.origin + this.pathname + (this.searchParams.toString() ? "?" + this.searchParams.toString() : "") + this.hash; } - toString() { return this.href; } - }; - function originOf(u) { const m = /^([a-zA-Z]+:\/\/[^/?#]*)/.exec(u); return m ? m[1] : u; } - } - - // --- ReadableStream (byte chunks pushed by the fetch pump) --- - class PPReadableStream { - constructor() { - this._queue = []; - this._closed = false; - this._error = null; - this._waiters = []; - } - _enqueue(chunk) { this._queue.push(chunk); this._flush(); } - _close() { this._closed = true; this._flush(); } - _fail(e) { this._error = e; this._flush(); } - _flush() { - while (this._waiters.length) { - if (this._queue.length) this._waiters.shift().resolve({ value: this._queue.shift(), done: false }); - else if (this._error) this._waiters.shift().reject(this._error); - else if (this._closed) this._waiters.shift().resolve({ value: undefined, done: true }); - else break; - } - } - getReader() { - const self = this; - return { - read() { return new Promise((resolve, reject) => { self._waiters.push({ resolve, reject }); self._flush(); }); }, - releaseLock() {}, - cancel() { self._closed = true; return Promise.resolve(); }, - }; - } - [Symbol.asyncIterator]() { - const reader = this.getReader(); - return { next: () => reader.read(), return: () => { reader.cancel(); return Promise.resolve({ done: true }); }, [Symbol.asyncIterator]() { return this; } }; - } - } - globalThis.ReadableStream = globalThis.ReadableStream || PPReadableStream; - - // --- Response --- - class Response { - constructor(body, init) { - init = init || {}; - this.status = init.status ?? 200; - this.statusText = init.statusText ?? ""; - this.ok = this.status >= 200 && this.status < 300; - this.headers = init.headers instanceof globalThis.Headers ? init.headers : new globalThis.Headers(init.headers || {}); - this.url = init.url || ""; - this.body = body || null; - this._bodyUsed = false; - } - get bodyUsed() { return this._bodyUsed; } - async _consume() { - this._bodyUsed = true; - if (!this.body) return new Uint8Array(0); - if (this.body instanceof Uint8Array) return this.body; - const reader = this.body.getReader(); - const parts = []; - let total = 0; - for (;;) { - const { value, done } = await reader.read(); - if (done) break; - parts.push(value); - total += value.length; - } - const out = new Uint8Array(total); - let off = 0; - for (const p of parts) { out.set(p, off); off += p.length; } - return out; - } - async arrayBuffer() { return (await this._consume()).buffer; } - async text() { return new TextDecoder().decode(await this._consume()); } - async json() { return JSON.parse(await this.text()); } - clone() { return new Response(this.body, { status: this.status, statusText: this.statusText, headers: this.headers, url: this.url }); } - } - globalThis.Response = globalThis.Response || Response; - - // --- fetch --- - const fetchTurns = new Map(); - - globalThis.fetch = function (input, init) { - init = init || {}; - const url = typeof input === "string" ? input : input.url; - const headers = {}; - if (init.headers) { - const h = init.headers instanceof globalThis.Headers ? init.headers.entries() : Array.isArray(init.headers) ? init.headers : Object.entries(init.headers); - for (const [k, v] of h) headers[k] = String(v); - } - let body = init.body; - if (body && typeof body !== "string") { - if (body instanceof Uint8Array) body = new TextDecoder().decode(body); - else body = String(body); - } - const request = { url, method: init.method || "GET", headers, body, raw: true }; - - return new Promise((resolve, reject) => { - let turnId; - try { - turnId = host.http.start(JSON.stringify(request)); - } catch (e) { - reject(new Error(String(e && e.message ? e.message : e))); - return; - } - const turn = { resolve, reject, stream: null, resolved: false, url }; - fetchTurns.set(turnId, turn); - if (init.signal) { - init.signal.addEventListener("abort", () => { - try { host.http.cancel(turnId); } catch {} - if (!turn.resolved) reject(new Error("aborted")); - else if (turn.stream) turn.stream._fail(new Error("aborted")); - fetchTurns.delete(turnId); - }); - } - }); - }; - - // Drained once per host frame (added to the pump). - globalThis.__catpiFetchPump = function () { - if (fetchTurns.size === 0) return; - for (const [turnId, turn] of fetchTurns) { - let out; - try { - out = JSON.parse(host.http.drain(turnId)); - } catch (e) { - if (!turn.resolved) turn.reject(new Error(String(e))); - else if (turn.stream) turn.stream._fail(new Error(String(e))); - fetchTurns.delete(turnId); - continue; - } - for (const line of out.lines) { - let msg; - try { msg = JSON.parse(line); } catch { continue; } - if (msg.__meta) { - turn.stream = new PPReadableStream(); - const resp = new Response(turn.stream, { - status: msg.__meta.status, - statusText: msg.__meta.statusText, - headers: msg.__meta.headers, - url: turn.url, - }); - turn.resolved = true; - turn.resolve(resp); - } else if (msg.__chunk != null && turn.stream) { - turn.stream._enqueue(b64ToBytes(msg.__chunk)); - } - } - if (out.error) { - if (!turn.resolved) turn.reject(new Error(out.error)); - else if (turn.stream) turn.stream._fail(new Error(out.error)); - fetchTurns.delete(turnId); - } else if (out.done) { - if (turn.stream) turn.stream._close(); - else if (!turn.resolved) turn.reject(new Error("no response")); - fetchTurns.delete(turnId); - } - } - }; -})(); diff --git a/js/tsconfig.json b/js/tsconfig.json deleted file mode 100644 index 437fc65..0000000 --- a/js/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2023", - "module": "ESNext", - "moduleResolution": "bundler", - "lib": ["ES2023"], - "types": [], - "strict": false, - "noImplicitAny": false, - "noEmit": true, - "skipLibCheck": true, - "allowImportingTsExtensions": true, - "allowJs": true, - "isolatedModules": true, - "forceConsistentCasingInFileNames": true - }, - "//": "esbuild transpiles all sources. tsc typechecks Pocket Pi's pi-full harness; runtime polyfills and the undici adapter intentionally stay outside this gate because they reimplement upstream runtime shapes.", - "include": ["src/pi-full/**/*.ts", "env.d.ts"], - "exclude": ["src/pi-full/undici-stub.ts"] -} diff --git a/tools/xtask/src/main.rs b/tools/xtask/src/main.rs index b928e53..3aa9856 100644 --- a/tools/xtask/src/main.rs +++ b/tools/xtask/src/main.rs @@ -7,7 +7,6 @@ fn main() -> Result<()> { let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../.."); let mut args = std::env::args().skip(1); match (args.next().as_deref(), args.next().as_deref()) { - (Some("build"), Some("macos")) => cargo(&root, ["build", "-p", "pocket-pi-macos"]), (Some("build"), Some("agentos-apps")) => build_agentos_apps(&root), (Some("build"), Some("esp32-p4")) => { build_embedded_guest(&root)?; @@ -28,10 +27,6 @@ fn main() -> Result<()> { build_embedded_guest(&root)?; cargo(&root, ["build", "-p", "pocket-pi-esp32-p4-sim"]) } - (Some("run"), Some("macos")) => { - let rest = args.collect::>(); - cargo_with_args(&root, ["run", "-p", "pocket-pi-macos", "--"], &rest) - } (Some("run"), Some("esp32-p4-sim")) => { build_embedded_guest(&root)?; let rest = args.collect::>(); @@ -49,7 +44,7 @@ fn main() -> Result<()> { } _ => { eprintln!( - "usage:\n cargo xtask build macos|agentos-apps|esp32-p4|esp32-p4-sim\n cargo xtask run macos|esp32-p4-sim [args]\n cargo xtask snapshot esp32-p4-sim" + "usage:\n cargo xtask build agentos-apps|esp32-p4|esp32-p4-sim\n cargo xtask run esp32-p4-sim [args]\n cargo xtask snapshot esp32-p4-sim" ); bail!("unknown xtask command") } From 3445409b74b5347f7bade3191f9453c470cc9554 Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Tue, 11 Aug 2026 14:13:57 +0800 Subject: [PATCH 12/24] fix(agent): accept long bootstrap prompts safely --- apps/_shared/text.ts | 9 +++++--- apps/pi-agent/dist/app.js | 22 +++++++++---------- .../esp32-p4/src/transport/provisioning.rs | 16 +++++++++++--- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/apps/_shared/text.ts b/apps/_shared/text.ts index 868684a..7ca53d1 100644 --- a/apps/_shared/text.ts +++ b/apps/_shared/text.ts @@ -7,6 +7,7 @@ export const DYNAMIC_TEXT_GLYPHS = "‘’“”–—…•"; const widthCache = new Map(); const wrapCache = new Map(); +const PREVIEW_SOURCE_CHARACTERS = 512; function width(text: string, fontSlot: number): number { if (!text) return 0; @@ -80,9 +81,11 @@ export function wrapPreview( maxWidth: number, maxLines: number, ): string { - const lines = wrapLines(text, fontSlot, maxWidth); - if (lines.length <= maxLines) return lines.join("\n"); + const source = text.slice(0, PREVIEW_SOURCE_CHARACTERS); + const lines = wrapLines(source, fontSlot, maxWidth); + if (source.length === text.length && lines.length <= maxLines) return lines.join("\n"); const visible = lines.slice(0, maxLines); - visible[maxLines - 1] = visible[maxLines - 1].replace(/[\s.]+$/, "") + "…"; + const last = visible.length - 1; + visible[last] = visible[last].replace(/[\s.]+$/, "") + "…"; return visible.join("\n"); } diff --git a/apps/pi-agent/dist/app.js b/apps/pi-agent/dist/app.js index 74ca85b..c8654cb 100644 --- a/apps/pi-agent/dist/app.js +++ b/apps/pi-agent/dist/app.js @@ -1,16 +1,16 @@ -(()=>{var AJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return H1(this.context.count)},getNextContextId(){return H1(this.context.count++)}};function H1(J){let Q=String(J),$=Q.length-1;return AJ.context.id+($?String.fromCharCode(96+$):"")+Q}function B1(J){AJ.context=J}function Y6(){return{...AJ.context,id:AJ.getNextContextId(),count:0}}var z6=!1,W6=(J,Q)=>J===Q,k0=Symbol("solid-proxy"),G6=typeof Proxy==="function",H6=Symbol("solid-track"),FQ=Symbol("solid-dev-component"),oJ={equals:W6},j1=null,B6=D1,m=1,fJ=2,F1={owned:null,cleanups:null,context:null,owner:null},S=null,F=null,yJ=null,_J=null,b=null,C=null,T=null,nJ=0;function tJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?F1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>JJ(()=>QJ(z)));S=z,b=null;try{return c(G,!0)}finally{b=$,S=Z}}function g(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(F&&F.running&&F.sources.has($))q=q($.tValue);else q=q($.value);return U1($,q)};return[M1.bind($),Z]}function e(J,Q,$){let Z=P1(J,Q,!1,m);if(yJ&&F&&F.running)C.push(Z);else eJ(Z)}function kJ(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=P1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,yJ&&F&&F.running)Z.tState=m,C.push(Z);else eJ(Z);return M1.bind(Z)}function j6(J){return c(J,!1)}function JJ(J){if(!_J&&b===null)return J();let Q=b;b=null;try{if(_J)return _J.untrack(J);return J()}finally{b=Q}}function S0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function F6(J){if(F&&F.running)return J(),F.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(yJ||K6)Z=F||(F={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[KQ,K1]=g(!1),K6;function M1(){let J=F&&F.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)eJ(this);else{let Q=C;C=null,c(()=>J0(this),!1),C=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&F.sources.has(this))return this.tValue;return this.value}function U1(J,Q,$){let Z=F&&F.running&&F.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(F){let q=F.running;if(q||!$&&F.sources.has(J))F.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw C=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;QJ(J);let Q=nJ;if(R1(J,F&&F.running&&F.sources.has(J)?J.tValue:J.value,Q),F&&!F.running&&F.sources.has(J))queueMicrotask(()=>{c(()=>{F&&(F.running=!0),b=S=J,R1(J,J.tValue,Q),b=S=null},!1)})}function R1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(F&&F.running)J.tState=m,J.tOwned&&J.tOwned.forEach(QJ),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach(QJ),J.owned=null;return J.updatedAt=$+1,g0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)U1(J,Z,!0);else if(F&&F.running&&J.pure){if(!F.sources.has(J))J.value=Z;F.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function P1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(F&&F.running)X.state=0,X.tState=Z;if(S===null);else if(S!==F1)if(F&&F.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(_J&&X.fn){let z=X.fn,[G,P]=g(void 0,{equals:!1}),D=_J.factory(z,P);S0(()=>D.dispose());let V,B=()=>F6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),F&&F.running){if(!V)V=_J.factory(z,B);return V.track(_)}return D.track(_)}}return X}function b0(J){let Q=F&&F.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===fJ)return J0(J);if(J.suspense&&JJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(F.disposed.has(q))return}if((Q?J.tState:J.state)===m)eJ(J);else if((Q?J.tState:J.state)===fJ){let q=C;C=null,c(()=>J0(J,$[0]),!1),C=q}}}function c(J,Q){if(C)return J();let $=!1;if(!Q)C=[];if(T)$=!0;else T=[];nJ++;try{let Z=J();return M6($),Z}catch(Z){if(!$)T=null;C=null,g0(Z)}}function M6(J){if(C){if(yJ&&F&&F.running)U6(C);else D1(C);C=null}if(J)return;let Q;if(F){if(!F.promises.size&&!F.queue.size){let{sources:Z,disposed:q}=F;T.push.apply(T,F.effects),Q=F.resolve;for(let X of T)"tState"in X&&(X.state=X.tState),delete X.tState;F=null,c(()=>{for(let X of q)QJ(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zB6($),!1);if(Q)Q()}function D1(J){for(let Q=0;Q{Z.delete($),c(()=>{F.running=!0,b0($)},!1),F&&(F.running=!1)})}}function J0(J,Q){let $=F&&F.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)QJ(J.tOwned[Q]);delete J.tOwned}if(F&&F.running&&J.pure)L1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)QJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(F&&F.running)J.tState=0;else J.state=0}function L1(J,Q){if(!Q)J.tState=0,F.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return S0(()=>I1(X)),()=>{let P=J()||[],D=P.length,V,B;return P[H6],JJ(()=>{let N,h,a,GJ,LJ,M,j,H,L;if(D===0){if(z!==0)I1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[P6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=M&&H>=M&&Z[j]===P[H];j--,H--)a[H]=q[j],GJ[H]=X[j],G&&(LJ[H]=G[j]);N=new Map,h=Array(H+1);for(B=H;B>=M;B--)L=P[B],V=N.get(L),h[B]=V===void 0?-1:V,N.set(L,B);for(V=M;V<=j;V++)if(L=Z[V],B=N.get(L),B!==void 0&&B!==-1)a[B]=q[V],GJ[B]=X[V],G&&(LJ[B]=G[V]),B=h[B],N.set(L,B);else X[V]();for(B=M;BJ(Q||{}));return B1($),Z}}return JJ(()=>J(Q||{}))}function Q0(){return!0}var O6={get(J,Q,$){if(Q===k0)return $;return J.get(Q)},has(J,Q){if(Q===k0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function w0(J){return!(J=typeof J==="function"?J():J)?{}:J}function I6(){for(let J=0,Q=this.length;J=0;G--){let P=w0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in w0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:I6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var A6=(J)=>`Stale read from <${J}>.`;function SJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return kJ(D6(()=>J.each,J.children,Q||void 0))}function bJ(J){let Q=J.keyed,$=kJ(()=>J.when,void 0,void 0),Z=Q?$:kJ($,void 0,{equals:(q,X)=>!q===!X});return kJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?JJ(()=>X(Q?q:()=>{if(!JJ(Z))throw A6("Show");return $()})):X}return J.fallback},void 0,void 0)}var _6=(J)=>kJ(()=>J());function k6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(M,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(M,j,L,H);e((A)=>B(M,j(),A,H),L)}function B(M,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=h(M,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(M),H=j);else h(M,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=h(M,H,L);else if(k==="function")return e(()=>{let O=j();while(typeof O==="function")O=O();H=B(M,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return e(()=>H=B(M,O,H,L,!0)),()=>H;if(O.length===0){let TJ=h(M,H,L);if(I)return H=TJ}else if(Array.isArray(H))if(H.length===0)a(M,O,L);else N(M,H,O);else if(H==null||H==="")a(M,O);else N(M,I&&H||[P(M)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(M,H,L,j);h(M,H,null,j)}else if(H==null||H===""||!P(M))q(M,j);else GJ(M,j,P(M));H=j}return H}function _(M,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let jQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let TJ=G(O)===M;if(!k&&!I)TJ?GJ(M,A,O):q(M,A,H);else TJ&&X(M,O)}else k=!0}}else q(M,A,H);return[A]}function a(M,j,H){for(let L=0,A=j.length;LH.children=B(M,j.children,H.children));return e(()=>j.ref&&j.ref(M)),e(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(M,A,k,H[A]),H[A]=k}}),H}return{render(M,j){let H;return tJ((L)=>{H=L,V(j,M())}),H},insert:V,spread(M,j,H){if(typeof j==="function")e((L)=>LJ(M,j(),L,H));else LJ(M,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(M,j,H,L){return z(M,j,H,L),H},mergeProps:A1,effect:e,memo:_6,createComponent:L6,use(M,j,H){return JJ(()=>M(j,H))}}}function S6(J){let Q=k6(J);return Q.mergeProps=A1,Q}var _1=480,k1=272,HJ={view:0,text:1,image:2},b6=1,g6=-1,w6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},C6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},E6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},N6=1,MQ=2,UQ=1,RQ=2,PQ=131072,DQ=1,VQ=262144,LQ=1,OQ=1,IQ=1,AQ=2,_Q=4,kQ=8,SQ=16,bQ=1,gQ=2;function S1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var wQ=1,h6=1263551300,T6=1,f6=32,y6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},BJ=32896,CQ=0.016666666666666666;function b1(J){return J.__viewport??null}var C0=null;function x6(){return null}function g1(J,Q=x6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function v6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return g1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return g1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function m6(J){C0=J}function gJ(){if(!C0)throw Error("PocketJS: host not installed — call render() first");return C0}function E(){return gJ().ops}function u6(J){globalThis.frame=J}function l6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function p6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return S1($>>>16&255,$>>>8&255,$&255,255);return S1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function c6(J,Q){let $=C6[J];if(typeof Q==="string"){if($===U.color)return p6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var $0=60,w1=[1,2,3,4,5,6,10,12,15,20,30,60],E0=$0,$J=-1,d6=0,xJ=[];function i6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=w1[0];for(let $ of w1)if(Math.abs($-J)Q.at<=$J).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>$J);for(let Q of J)Q.cb()}var N0=0.12,Z0=BJ;function o6(J){Z0=J===void 0?BJ:J&65535}function n6(){Z0=BJ}function N1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function e6(){return N1(Z0&255)}var h1=new Set,J8=0;function Q8(){h1.clear(),J8=0,n6()}function $8(J){for(let Q of[...h1])Q(J)}var jJ=null,T1=null;function Z8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function f1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){h0();let Q=jJ?jJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return T1.slice(Q.off,Q.off+Q.len)}var mJ=null,w=null,FJ=null,q0=0,KJ=[],f0=[],y0=[];function x1(J){if(mJ=J,w=null,FJ=null,q0=0,KJ.length=0,f0.length=0,y0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function X8(J,Q){J.onPress=Q??void 0}function Y8(J,Q){if(J.focusable=Q,p1(),!Q&&w===J)x(null)}function x(J){if(FJ&&FJ!==J)MJ(null);w=J,E().setFocus(J?J.id:0)}function MJ(J){if(FJ===J)return;let Q=E();if(FJ)Q.setActive?.(FJ.id,0);if(FJ=J,J)Q.setActive?.(J.id,1)}function x0(){return KJ.length>0?KJ[KJ.length-1]:mJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function G8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=f0.length-1;Q>=0;Q--){let $=f0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function H8(J){let Q=G8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(w)x(null);return!0}let Z=Q.columns,q=w?$.indexOf(w):-1;if(q<0)return x(v1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function B8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=y0.length-1;Q>=0;Q--){let $=y0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function X0(J){let Q=B8();if(Q&&Q.move(J))return;if(H8(J))return;W8(J)}function m1(){u1(w)}function u1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){MJ(J)}function j8(J){x(J),u1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=m0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,l1=0;function p1(){l1++}var K8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],M8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function U8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=K8[Q]>>$&1,q=M8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function R8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):P8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(U8(),16,16,E6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function P8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&N6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var W0=null;function c1(J){W0=J}function d1(J){let Q=KJ.length>0?KJ[KJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function i1(J,Q,$){return d1(s1(J,Q,$))}function s1(J,Q,$){if($!==void 0)return $===0?null:z0(W0??mJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(W0??mJ,q(J,Q))}function D8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=b1(q);if(Z.vw=B?B.w:_1,Z.vh=B?B.h:k1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)R8(Z,q);let X=t6()*Z.speed,z=e6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=s6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=l1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=d1(z0(W0??mJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==w)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(MJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,MJ(null),B)m1()}}else if($&Z.button)MJ(null);return!0}function V8(J){let Q=J&~q0,$=q0&~J;if(q0=J,l&&D8(J,Q,$))return;if($&d.CIRCLE)MJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)MJ(w),m1()}var u0=null;function a1(J){u0=J}function wJ(){if(p1(),u0)u0()}function L8(J,Q){J.debugName=Q||void 0,wJ()}var ZJ={id:b6,type:HJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},r1=Symbol.for("pocketjs.native-node"),l0=1,uJ=3,o=8,O8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function G0(J){return J.domAttrs??={}}function o1(J,Q){let $=J.domNodeType??(lJ(J)?uJ:l0),Z=$===uJ?H0(J.text??""):$===o?_8(J.domData??""):Z4(J.domTag??j0(J));for(let q of Object.keys(J.domAttrs??{}))p0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)qJ(Z,o1(q,!0));return Z}function p0(J,Q,$){if(O8.has(Q)){EJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete G0(J)[Q];else G0(J)[Q]=$}function c0(J){if(J[r1]===!0)return J;return Object.defineProperty(J,r1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(lJ(J)?uJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(lJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(lJ(J))B0(J,Z);else if(E8(J),Z)qJ(J,H0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return X4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??j0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===uJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??j0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){EJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===ZJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return qJ(J,$),$},insertBefore($,Z){return qJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return qJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return o1(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){p0(J,$,Z)},removeAttribute($){p0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(ZJ);var d0=null;function I8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},n1=new Map;function t1(J,Q){n1.set(J,Q)}var e1=new Map;function J4(J,Q){e1.set(J,Q)}var CJ=new Set,A8=new Set;function Q4(J){if(!J)return!1;if(A8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function H0(J){let Q=E(),$=Q.createNode(HJ.text);return Q.setText($,J),c0({id:$,type:HJ.text,parent:null,children:[],text:J,domNodeType:uJ,domTag:"#text"})}function _8(J=""){let Q=H0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){E().replaceText(J.id,Q),J.text=Q,wJ()}function lJ(J){return J.type===HJ.text}function q4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function qJ(J,Q,$){let Z=E();if(q4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function pJ(J,Q){if(!Q)return;F8(Q),E().removeChild(J.id,Q.id),q4(Q),CJ.add(Q),wJ()}function k8(J){return J.parent??void 0}function S8(J){return J.children[0]}function X4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function b8(J,Q){let $=E();if(wJ(),Q==null||Q===""){$.setStyle(J.id,g6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function g8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=n1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function w8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=e1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function C8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=w6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,c6(G,P)),z=!0}if(z)wJ()}function EJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete G0(J)[Q];else G0(J)[Q]=$;switch(Q){case"class":return b8(J,$),$;case"onPress":case"on:press":return X8(J,$),$;case"src":return g8(J,$),$;case"sprite":return w8(J,$),$;case"style":return C8(J,$,Z),$;case"focusable":return Y8(J,!!$),$;case"debugName":return L8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${j0(J)}>`)}function E8(J){for(let Q of[...J.children])pJ(J,Q)}function j0(J){for(let Q of Object.keys(HJ))if(HJ[Q]===J.type)return Q;return String(J.type)}function N8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}EJ(J,Q,$,Z)}var h8=S6({createElement:Z4,createTextNode:H0,replaceText:B0,isTextNode:lJ,setProperty:N8,insertNode(J,Q,$){qJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:k8,getFirstChild:S8,getNextSibling:X4}),{render:T8,effect:EQ,memo:p,createComponent:Y,createElement:Y4,insert:NQ,spread:f8,mergeProps:hQ,use:TQ}=h8,fQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},y8=null;function z4(J){y8=J}function x8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function W4(J,Q){let $=Y4(J);return f8($,Q,!1),x8(Q.nodeRef,$),$}function K(J){return W4("view",J)}function R(J){return W4("text",J)}var yQ=new WeakMap,xQ=new WeakMap,v8={}!==null?Object.freeze({...{}}):Object.freeze({}),vQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:v8}),mQ=new Map,XJ=36000,s0=30,m8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(XJ),tapeAnalog:new Uint16Array(XJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function u8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-s0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)a1(()=>{W.treeDirty=!0}),r8();else a1(null);globalThis.__pocketDevtools=n8}function l8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)c8(),s8();let X=Q,z=$===void 0?BJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(XJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==BJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function B4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function j4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.masks,0,Q)}function F4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.analog??[],BJ,Q)}function K4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,f({t:"hello",app:W.app,host:o8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` -`))if(q.trim())d8(q)}}function d8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)f({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),a0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":M4();break;case"eval":{let Z=!0,q;try{q=F0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}f({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":f({t:"tape",tape:H4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}f({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())f({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else f({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=j4(Z),W.replayAnalog=Z.analog?F4(Z):null,W.replayTouch=Z.touch?K4(Z):null,W.replayAt=0;break}default:break}}function i8(){if(W.treeDirty&&W.frame-W.treeSentAt>=s0)M4();if(W.frame%m8===0)a0()}function s8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,f({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,f({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){f({t:"stats",frame:W.frame,nodes:P4(ZJ),tapeLen:W.tapeLen,paused:W.paused})}function M4(){W.treeDirty=!1,W.treeSentAt=W.frame,f({t:"tree",frame:W.frame,root:R4(ZJ)})}function a8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(a8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function U4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function R4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(U4(J,(q)=>{if(q.domNodeType===8)return;Z.push(R4(q))}),Z.length)Q.k=Z;return Q}function P4(J){let Q=1;return U4(J,($)=>{Q+=P4($)}),Q}function r8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{f({t:"log",level:$,args:q.map((X)=>F0(X))}),Z?.apply(Q,q)}}}function F0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?D4(X):JSON.stringify(D4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>F0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${F0(z,Q+1)}`).join(", ")}}`}function D4(J){return J.length>200?J.slice(0,199)+"…":J}function o8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var n8={get frame(){return W.frame},dumpTape:()=>H4(),replay:(J)=>{W.replayMasks=j4(J),W.replayAnalog=J.analog?F4(J):null,W.replayTouch=J.touch?K4(J):null,W.replayAt=0}},V4=new Map,o0=new Map;function L4(J){return J.trim().replace(/\s+/g," ")}function O4(J){return J.split(" ").sort().join(" ")}var I4=-1;function t8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=L4(Q);V4.set(Z,$);let q=O4(Z),X=o0.get(q);o0.set(q,X!==void 0&&X!==$?I4:$)}}function e8(J){let Q=L4(J),$=V4.get(Q);if($!==void 0)return $;let Z=o0.get(O4(Q));return Z===I4?void 0:Z}var n0=9,J2=(1<{let q=($&$2)!==0,X=q?t0:n0,z=q?Z2:J2;return Object.freeze({id:$>>>(q?q2:Q2)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Y2(){return K0}function z2(){K0=e0}var A4=8,YJ=8,W2=3,G2=8,H2=6,B2=0.5,s=1,cJ=2,J1=4,UJ=8,NJ=[],_4=0,M0=0,zJ=Array.from({length:A4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(YJ),histY:new Int16Array(YJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function j2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function F2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=s1(Q,$,Z.fact);let G=Z.hit;if(G)return j2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=NJ[z];if(G.disposed)continue;if(_4>0&&!G.opts.allowWhenBlocked)continue;if(!F2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function U2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%YJ,J.histLenz||Z>z))q.flags[J.slot]|=cJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(cJ|J1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??B2)*C1()));if(J.frames=0)NJ.splice($,1)},cancel(){if(!Q.disposed)b4(Q)},get panning(){for(let $ of zJ)if($.used&&Q.flags[$.slot]&UJ)return!0;return!1}}}function L2(J){let Q=V2(J);return S0(()=>Q.dispose()),Q}function g4(){NJ.length=0,_4=0,M0=0;for(let J of zJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function O2(){return L2({onDown:(J)=>{let Q=i1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=i1(J.x,J.y,J.hit);if(Q)j8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var I2=1,Q1=new Map,U0=[];function A2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function _2(){I2=1,Q1.clear(),U0=[]}function k2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),A2()?.({t:"delivery",frame:E1(),id:Q,kind:Z.kind}),Z.onResult($)}}var w4=new Set;function S2(){if(w4.size===0)return;for(let J of w4)J()}var b2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[28] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-base text-orange-600 font-bold":9,"h-[76] pt-3 text-lg text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-base text-emerald-700 font-bold":13,"h-[84] pt-3 text-lg text-slate-900":14,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":15,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":16,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":17,"text-base text-slate-600 font-bold":18,"pt-6 text-lg text-slate-500":19,"pt-6 text-lg text-slate-900 font-bold":20,"h-[146] px-6 pt-7 flex-col bg-slate-50":21,"h-[80]":22,"h-[1060] px-6 pt-5 flex-col":23,"h-[48] px-4 justify-center bg-slate-100":24,"text-base text-slate-600":25,"pt-[10] flex-col gap-[12]":26,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":27,"w-[48] h-[48] items-center justify-center bg-blue-100":28,"w-[48] h-[48] items-center justify-center bg-emerald-100":29,"text-lg text-blue-700 font-bold":30,"text-lg text-emerald-700 font-bold":31,"w-[474] flex-col gap-2":32,"text-lg text-slate-900 font-bold":33,"text-base text-slate-500":34,"pt-20 pl-10 text-lg text-slate-500":35,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":36,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":37,"h-[1060] px-6 pt-7 flex-col gap-4":38,"text-base text-slate-500 font-bold":39,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":40,"flex-row items-center gap-5":41,"w-[68] h-[68] items-center justify-center bg-emerald-100":42,"text-xl text-emerald-700 font-bold":43,"flex-col gap-2":44,"text-xl text-slate-900 font-bold":45,"text-lg text-slate-600":46,"text-2xl text-orange-600":47,"w-[68] h-[68] items-center justify-center bg-indigo-100":48,"text-xl text-indigo-700 font-bold":49,"mt-4 h-[112] px-6 justify-center bg-slate-100":50,"relative h-[154] px-5 pt-5 flex-col bg-white":51,"pt-3 text-lg text-orange-600 font-bold":52,"pt-3 text-base text-slate-500":53,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":54,"text-lg text-white font-bold":55,"h-[40] pt-3 text-base text-slate-500":56,"h-[470] flex-col gap-2":57,"h-[214] px-7 items-center justify-center bg-slate-100":58,"text-lg text-slate-500 font-bold":59,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":60,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":61,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":62,"h-[160] px-5 pt-5 flex-col bg-white":63,"pt-3 text-lg text-slate-900 font-bold":64,"pt-3 text-base text-slate-600":65,"h-[108] pt-7 flex-row gap-4":66,"w-[316] h-[80] items-center justify-center bg-slate-100":67,"w-[340] h-[80] items-center justify-center bg-red-100":68,"text-lg text-red-500 font-bold":69,"h-[1052] px-6 pt-5 flex-col":70,"h-[270] px-[22] pt-6 bg-white":71,"text-lg text-slate-900":72,"text-lg text-slate-400":73,"h-[86] px-1 flex-row items-center justify-between":74,"w-[132] h-[58] items-center justify-center bg-slate-300":75,"w-[132] h-[58] items-center justify-center bg-slate-100":76,"text-base text-slate-900 font-bold":77,"h-[140] flex-row gap-2":78,"grow h-[120] items-center justify-center bg-slate-300":79,"grow h-[120] items-center justify-center bg-white":80,"w-[104] h-[120] items-center justify-center bg-slate-300":81,"w-[104] h-[120] items-center justify-center bg-slate-100":82,"h-[176] flex-row gap-2":83,"w-[92] h-[156] items-center justify-center bg-slate-300":84,"w-[92] h-[156] items-center justify-center bg-slate-100":85,"w-[300] h-[156] items-center justify-center bg-slate-300":86,"w-[300] h-[156] items-center justify-center bg-slate-100":87,"w-[144] h-[156] items-center justify-center bg-slate-300":88,"w-[144] h-[156] items-center justify-center bg-slate-100":89,"w-[112] h-[156] items-center justify-center bg-emerald-700":90,"w-[112] h-[156] items-center justify-center bg-emerald-500":91,"text-base text-slate-950 font-bold":92,"h-[108] px-6 py-3 flex-col bg-slate-50":93,"h-[84] items-center justify-center bg-slate-300":94,"h-[84] items-center justify-center bg-slate-100":95,"h-[1168] px-6 pt-5 flex-col":96,"h-[82] px-4 justify-center bg-white":97,"w-[584] h-[900] px-5 pt-5 bg-slate-950":98,"text-base text-slate-200":99,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":100,"text-lg text-orange-600 font-bold":101,"w-[584] h-[900] px-5 pt-5 bg-white":102,"text-base text-slate-900":103,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":104,"absolute inset-0 z-50 flex-col items-center justify-center":105,"absolute inset-0 bg-slate-950":106,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":107,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":108,"flex-row flex-wrap":109,grow:110,"text-2xl text-white font-bold":111,"text-2xl text-slate-950 font-bold":112,"px-6":113,"px-6 py-5":114,"gap-4":115,"rounded-xl shadow bg-white border-slate-100":116,"rounded-xl shadow bg-emerald-100 border-emerald-500":117,"bg-white":118,"bg-slate-100":119,"bg-slate-950":120,"px-3 py-2 rounded-lg bg-slate-100":121,"px-3 py-2 rounded-lg bg-indigo-100":122,"text-base text-indigo-700 font-bold":123,"px-3 py-2 rounded-lg bg-emerald-100":124,"px-3 py-2 rounded-lg bg-amber-100":125,"text-base text-amber-700 font-bold":126,"px-3 py-2 rounded-lg bg-red-100":127,"text-base text-red-500 font-bold":128,"w-[34] h-[34] rounded-lg bg-amber-400":129,"w-[34] h-[34] rounded-lg bg-red-500":130,"w-[34] h-[34] rounded-lg bg-slate-800":131,"w-[34] h-[34] rounded-lg bg-emerald-500":132,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":133,"flex-row items-center gap-4":134,"w-[34] text-2xl text-white font-bold":135,"w-[332] flex-col items-end gap-2":136,"text-base text-slate-300 font-bold":137,"text-base text-slate-400":138,"h-[166] px-6 pt-6 flex-col gap-3":139,"h-[44] px-1 flex-row items-center justify-between":140,"w-full h-full items-center justify-center rounded-xl bg-slate-200":141,"w-full h-full items-center justify-center rounded-xl bg-red-100":142,"w-full h-full items-center justify-center rounded-xl bg-slate-100":143,"w-full h-full items-center justify-center rounded-xl bg-orange-600":144,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":145,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":146,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":147,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":148,"text-2xl text-indigo-700 font-bold":149,"text-2xl text-slate-600 font-bold":150,"pt-7 text-2xl text-slate-900 font-bold":151,"pt-4 text-lg text-slate-500":152,"text-xl text-emerald-600 font-bold":153,"text-xl text-red-500 font-bold":154,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":155,"text-base text-red-300":156,"text-base text-slate-300":157,"text-base text-red-500":158,"w-full h-full px-6 flex-row items-center bg-slate-950":159,"w-full h-full flex-row items-center":160};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var g2="ui:styles",w2="ui:font.",C4="ui:img.",E4="ui:sprite.";function C2(){return globalThis.ui}function E2(J){if(J.__textures)return;for(let Q of T0(C4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)t1(Q.slice(C4.length),Z)}}function N2(J){if(J.__sprites)return;for(let Q of T0(E4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)J4(Q.slice(E4.length),{handle:V,frames:G,cols:P,step:D})}}function N4(J){let Q=Y4("view");return EJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function h2(J,Q){if(!R0||!P0)return;EJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),EJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function T2(J,Q={}){let $=v6(Q.ops);if(m6($),I8(e8),Q.styles)t8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)t1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)J4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)y1(Q.pak);if(q8()){for(let B of T0())if(B===g2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(w2))$.ops.loadFontAtlas?.(vJ(B))}}let q=b1($.ops),X=q?.w??_1,z=q?.h??k1,G=N4({width:X,height:z,overflow:u.Overflow.Hidden}),P=N4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});qJ(ZJ,G),qJ(ZJ,P),z4(P),R0=G,P0=P,x1(G),c1(ZJ),Q8(),g4(),O2(),a6(),_2(),u8($.ops),u6(l8((B,_,N,h)=>{r6(),o6(_),X2(N,h),S2(),k2(),D2(),$8(B),V8(B),$4()}));let D=T8(J,G),V=l6(h2);return()=>{V(),z2(),g4(),D(),x1(null),c1(null),z4(null),R0=null,P0=null;for(let B of ZJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);$4()}}function f2(J,Q={}){let $=Q.ops??C2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)y1(Q.pak);return E2($),N2($),T2(J,{ops:$,styles:Q.styles??b2,pak:Q.pak})}var y2="$b",x2=65536,h4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function u2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function T4(){let J=u2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function l2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,x2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=v2(z.data[y2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function p2(J,Q){let $=l2(T4(),J);return Q==="utf8"||Q==="utf-8"?m2($):$}function c2(J,Q){let $=T4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var d2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"};function i2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(K,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(K,{class:"flex-row items-center gap-4",get children(){return[p(()=>p(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(K,{get["class"](){return Q()}})),Y(R,{get["class"](){return d2.appTitle},get children(){return J.title}})]}}),Y(K,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function s2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(K,{get["class"](){return Q()},get children(){return Y(R,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(K,{get["class"](){return J.top},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(K,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var uQ="‘’“”–—…•",f4=new Map,y4=new Map;function D0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=f4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return f4.set($,q),q}function a2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=D0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function $1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=y4.get(Z);if(q)return q;let X=[],z=D0(" ",Q);for(let G of J.split(` -`)){let P=G.split(" ").flatMap((B)=>B&&D0(B,Q)>$?a2(B,Q,$):[B]),D="",V=0;for(let B of P){let _=D0(B,Q);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return y4.set(Z,X),X}function x4(J,Q,$,Z){let q=$1(J,Q,$);if(q.length<=Z)return q.join(` -`);let X=q.slice(0,Z);return X[Z-1]=X[Z-1].replace(/[\s.]+$/,"")+"…",X.join(` -`)}var v4=3,m4=2,u4=536,l4=544,p4=39,[RJ,r2]=g({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[y,n]=g("chat"),[Z1,o2]=g("chat"),[q1,c4]=g(0),[PJ,d4]=g(""),[sJ,hJ]=g(0),[aJ,X1]=g([]),[n2,V0]=g(""),[i4,L0]=g(null),[s4,a4]=g(null),[O0,I0]=g(0),[v,t]=g(""),[DJ,r4]=g("letters"),[Y1,z1]=g(!1),[W1,o4]=g({type:"prompt"}),[WJ,n4]=g(null),[rJ,t4]=g(0),e4=new Map,J6=["qwertyuiop","asdfghjkl","zxcvbnm"],Q6=["1234567890","-/:;()$&@",`.,?!'"+`],$6=["chat","files","apps","settings"];function t2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function e2(J,Q){return J?J+"/"+Q:Q}function A0(J=PJ(),Q=!1){let $=e4.get(J);if(!Q&&$){X1($),V0(""),hJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=c2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));e4.set(J,Z),X1(Z),V0(""),hJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){X1([]),V0(Z instanceof Error?Z.message:String(Z))}}function JQ(){let J=[];for(let Q of RJ().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Z6(){let J=JQ(),Q=Math.max(0,J.length-2),$=Math.min(q1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function VJ(J){return Y(i2,{get title(){return J.title},get accent(){return p(()=>RJ().agent==="FAULTED")()?"danger":RJ().agent==="THINKING"?"busy":"ready"}})}function _0(){return Y(K,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(SJ,{each:$6,children:(J)=>Y(K,{get["class"](){return Z1()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function QQ(){let J=()=>RJ().schedule;return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"ESP32 PI AGENT"}),Y(K,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(SJ,{get each(){return Z6()},children:(Q)=>Y(K,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(K,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(K,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-base text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-lg text-slate-900",get children(){return x4(Q.user,v4,u4,3)}}),Y(K,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(K,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(K,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-base text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-lg text-slate-900",get children(){return x4(Q.assistant,v4,u4,3)}})]}})}),Y(iJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(K,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-base text-slate-600 font-bold",children:"NEXT WAKE"}),Y(bJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-lg text-slate-500",children:`NO WAKE SCHEDULED +(()=>{var AJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return H1(this.context.count)},getNextContextId(){return H1(this.context.count++)}};function H1(J){let Q=String(J),$=Q.length-1;return AJ.context.id+($?String.fromCharCode(96+$):"")+Q}function B1(J){AJ.context=J}function Y6(){return{...AJ.context,id:AJ.getNextContextId(),count:0}}var z6=!1,W6=(J,Q)=>J===Q,k0=Symbol("solid-proxy"),G6=typeof Proxy==="function",H6=Symbol("solid-track"),KQ=Symbol("solid-dev-component"),oJ={equals:W6},j1=null,B6=D1,m=1,fJ=2,F1={owned:null,cleanups:null,context:null,owner:null},S=null,F=null,yJ=null,_J=null,b=null,C=null,T=null,nJ=0;function tJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?F1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>JJ(()=>QJ(z)));S=z,b=null;try{return c(G,!0)}finally{b=$,S=Z}}function g(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(F&&F.running&&F.sources.has($))q=q($.tValue);else q=q($.value);return U1($,q)};return[M1.bind($),Z]}function e(J,Q,$){let Z=P1(J,Q,!1,m);if(yJ&&F&&F.running)C.push(Z);else eJ(Z)}function kJ(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=P1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,yJ&&F&&F.running)Z.tState=m,C.push(Z);else eJ(Z);return M1.bind(Z)}function j6(J){return c(J,!1)}function JJ(J){if(!_J&&b===null)return J();let Q=b;b=null;try{if(_J)return _J.untrack(J);return J()}finally{b=Q}}function S0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function F6(J){if(F&&F.running)return J(),F.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(yJ||K6)Z=F||(F={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[MQ,K1]=g(!1),K6;function M1(){let J=F&&F.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)eJ(this);else{let Q=C;C=null,c(()=>J0(this),!1),C=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&F.sources.has(this))return this.tValue;return this.value}function U1(J,Q,$){let Z=F&&F.running&&F.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(F){let q=F.running;if(q||!$&&F.sources.has(J))F.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw C=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;QJ(J);let Q=nJ;if(R1(J,F&&F.running&&F.sources.has(J)?J.tValue:J.value,Q),F&&!F.running&&F.sources.has(J))queueMicrotask(()=>{c(()=>{F&&(F.running=!0),b=S=J,R1(J,J.tValue,Q),b=S=null},!1)})}function R1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(F&&F.running)J.tState=m,J.tOwned&&J.tOwned.forEach(QJ),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach(QJ),J.owned=null;return J.updatedAt=$+1,g0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)U1(J,Z,!0);else if(F&&F.running&&J.pure){if(!F.sources.has(J))J.value=Z;F.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function P1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(F&&F.running)X.state=0,X.tState=Z;if(S===null);else if(S!==F1)if(F&&F.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(_J&&X.fn){let z=X.fn,[G,P]=g(void 0,{equals:!1}),D=_J.factory(z,P);S0(()=>D.dispose());let V,B=()=>F6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),F&&F.running){if(!V)V=_J.factory(z,B);return V.track(_)}return D.track(_)}}return X}function b0(J){let Q=F&&F.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===fJ)return J0(J);if(J.suspense&&JJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(F.disposed.has(q))return}if((Q?J.tState:J.state)===m)eJ(J);else if((Q?J.tState:J.state)===fJ){let q=C;C=null,c(()=>J0(J,$[0]),!1),C=q}}}function c(J,Q){if(C)return J();let $=!1;if(!Q)C=[];if(T)$=!0;else T=[];nJ++;try{let Z=J();return M6($),Z}catch(Z){if(!$)T=null;C=null,g0(Z)}}function M6(J){if(C){if(yJ&&F&&F.running)U6(C);else D1(C);C=null}if(J)return;let Q;if(F){if(!F.promises.size&&!F.queue.size){let{sources:Z,disposed:q}=F;T.push.apply(T,F.effects),Q=F.resolve;for(let X of T)"tState"in X&&(X.state=X.tState),delete X.tState;F=null,c(()=>{for(let X of q)QJ(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zB6($),!1);if(Q)Q()}function D1(J){for(let Q=0;Q{Z.delete($),c(()=>{F.running=!0,b0($)},!1),F&&(F.running=!1)})}}function J0(J,Q){let $=F&&F.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)QJ(J.tOwned[Q]);delete J.tOwned}if(F&&F.running&&J.pure)L1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)QJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(F&&F.running)J.tState=0;else J.state=0}function L1(J,Q){if(!Q)J.tState=0,F.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return S0(()=>I1(X)),()=>{let P=J()||[],D=P.length,V,B;return P[H6],JJ(()=>{let N,h,a,GJ,LJ,M,j,H,L;if(D===0){if(z!==0)I1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[P6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=M&&H>=M&&Z[j]===P[H];j--,H--)a[H]=q[j],GJ[H]=X[j],G&&(LJ[H]=G[j]);N=new Map,h=Array(H+1);for(B=H;B>=M;B--)L=P[B],V=N.get(L),h[B]=V===void 0?-1:V,N.set(L,B);for(V=M;V<=j;V++)if(L=Z[V],B=N.get(L),B!==void 0&&B!==-1)a[B]=q[V],GJ[B]=X[V],G&&(LJ[B]=G[V]),B=h[B],N.set(L,B);else X[V]();for(B=M;BJ(Q||{}));return B1($),Z}}return JJ(()=>J(Q||{}))}function Q0(){return!0}var O6={get(J,Q,$){if(Q===k0)return $;return J.get(Q)},has(J,Q){if(Q===k0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function w0(J){return!(J=typeof J==="function"?J():J)?{}:J}function I6(){for(let J=0,Q=this.length;J=0;G--){let P=w0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in w0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:I6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var A6=(J)=>`Stale read from <${J}>.`;function SJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return kJ(D6(()=>J.each,J.children,Q||void 0))}function bJ(J){let Q=J.keyed,$=kJ(()=>J.when,void 0,void 0),Z=Q?$:kJ($,void 0,{equals:(q,X)=>!q===!X});return kJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?JJ(()=>X(Q?q:()=>{if(!JJ(Z))throw A6("Show");return $()})):X}return J.fallback},void 0,void 0)}var _6=(J)=>kJ(()=>J());function k6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(M,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(M,j,L,H);e((A)=>B(M,j(),A,H),L)}function B(M,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=h(M,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(M),H=j);else h(M,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=h(M,H,L);else if(k==="function")return e(()=>{let O=j();while(typeof O==="function")O=O();H=B(M,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return e(()=>H=B(M,O,H,L,!0)),()=>H;if(O.length===0){let TJ=h(M,H,L);if(I)return H=TJ}else if(Array.isArray(H))if(H.length===0)a(M,O,L);else N(M,H,O);else if(H==null||H==="")a(M,O);else N(M,I&&H||[P(M)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(M,H,L,j);h(M,H,null,j)}else if(H==null||H===""||!P(M))q(M,j);else GJ(M,j,P(M));H=j}return H}function _(M,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let FQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let TJ=G(O)===M;if(!k&&!I)TJ?GJ(M,A,O):q(M,A,H);else TJ&&X(M,O)}else k=!0}}else q(M,A,H);return[A]}function a(M,j,H){for(let L=0,A=j.length;LH.children=B(M,j.children,H.children));return e(()=>j.ref&&j.ref(M)),e(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(M,A,k,H[A]),H[A]=k}}),H}return{render(M,j){let H;return tJ((L)=>{H=L,V(j,M())}),H},insert:V,spread(M,j,H){if(typeof j==="function")e((L)=>LJ(M,j(),L,H));else LJ(M,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(M,j,H,L){return z(M,j,H,L),H},mergeProps:A1,effect:e,memo:_6,createComponent:L6,use(M,j,H){return JJ(()=>M(j,H))}}}function S6(J){let Q=k6(J);return Q.mergeProps=A1,Q}var _1=480,k1=272,HJ={view:0,text:1,image:2},b6=1,g6=-1,w6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},C6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},E6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},N6=1,UQ=2,RQ=1,PQ=2,DQ=131072,VQ=1,LQ=262144,OQ=1,IQ=1,AQ=1,_Q=2,kQ=4,SQ=8,bQ=16,gQ=1,wQ=2;function S1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var CQ=1,h6=1263551300,T6=1,f6=32,y6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},BJ=32896,EQ=0.016666666666666666;function b1(J){return J.__viewport??null}var C0=null;function x6(){return null}function g1(J,Q=x6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function v6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return g1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return g1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function m6(J){C0=J}function gJ(){if(!C0)throw Error("PocketJS: host not installed — call render() first");return C0}function E(){return gJ().ops}function u6(J){globalThis.frame=J}function l6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function p6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return S1($>>>16&255,$>>>8&255,$&255,255);return S1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function c6(J,Q){let $=C6[J];if(typeof Q==="string"){if($===U.color)return p6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var $0=60,w1=[1,2,3,4,5,6,10,12,15,20,30,60],E0=$0,$J=-1,d6=0,xJ=[];function i6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=w1[0];for(let $ of w1)if(Math.abs($-J)Q.at<=$J).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>$J);for(let Q of J)Q.cb()}var N0=0.12,Z0=BJ;function o6(J){Z0=J===void 0?BJ:J&65535}function n6(){Z0=BJ}function N1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function e6(){return N1(Z0&255)}var h1=new Set,J8=0;function Q8(){h1.clear(),J8=0,n6()}function $8(J){for(let Q of[...h1])Q(J)}var jJ=null,T1=null;function Z8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function f1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){h0();let Q=jJ?jJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return T1.slice(Q.off,Q.off+Q.len)}var mJ=null,w=null,FJ=null,q0=0,KJ=[],f0=[],y0=[];function x1(J){if(mJ=J,w=null,FJ=null,q0=0,KJ.length=0,f0.length=0,y0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function X8(J,Q){J.onPress=Q??void 0}function Y8(J,Q){if(J.focusable=Q,p1(),!Q&&w===J)x(null)}function x(J){if(FJ&&FJ!==J)MJ(null);w=J,E().setFocus(J?J.id:0)}function MJ(J){if(FJ===J)return;let Q=E();if(FJ)Q.setActive?.(FJ.id,0);if(FJ=J,J)Q.setActive?.(J.id,1)}function x0(){return KJ.length>0?KJ[KJ.length-1]:mJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function G8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=f0.length-1;Q>=0;Q--){let $=f0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function H8(J){let Q=G8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(w)x(null);return!0}let Z=Q.columns,q=w?$.indexOf(w):-1;if(q<0)return x(v1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function B8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=y0.length-1;Q>=0;Q--){let $=y0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function X0(J){let Q=B8();if(Q&&Q.move(J))return;if(H8(J))return;W8(J)}function m1(){u1(w)}function u1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){MJ(J)}function j8(J){x(J),u1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=m0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,l1=0;function p1(){l1++}var K8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],M8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function U8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=K8[Q]>>$&1,q=M8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function R8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):P8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(U8(),16,16,E6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function P8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&N6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var W0=null;function c1(J){W0=J}function d1(J){let Q=KJ.length>0?KJ[KJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function i1(J,Q,$){return d1(s1(J,Q,$))}function s1(J,Q,$){if($!==void 0)return $===0?null:z0(W0??mJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(W0??mJ,q(J,Q))}function D8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=b1(q);if(Z.vw=B?B.w:_1,Z.vh=B?B.h:k1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)R8(Z,q);let X=t6()*Z.speed,z=e6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=s6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=l1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=d1(z0(W0??mJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==w)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(MJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,MJ(null),B)m1()}}else if($&Z.button)MJ(null);return!0}function V8(J){let Q=J&~q0,$=q0&~J;if(q0=J,l&&D8(J,Q,$))return;if($&d.CIRCLE)MJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)MJ(w),m1()}var u0=null;function a1(J){u0=J}function wJ(){if(p1(),u0)u0()}function L8(J,Q){J.debugName=Q||void 0,wJ()}var ZJ={id:b6,type:HJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},r1=Symbol.for("pocketjs.native-node"),l0=1,uJ=3,o=8,O8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function G0(J){return J.domAttrs??={}}function o1(J,Q){let $=J.domNodeType??(lJ(J)?uJ:l0),Z=$===uJ?H0(J.text??""):$===o?_8(J.domData??""):Z4(J.domTag??j0(J));for(let q of Object.keys(J.domAttrs??{}))p0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)qJ(Z,o1(q,!0));return Z}function p0(J,Q,$){if(O8.has(Q)){EJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete G0(J)[Q];else G0(J)[Q]=$}function c0(J){if(J[r1]===!0)return J;return Object.defineProperty(J,r1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(lJ(J)?uJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(lJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(lJ(J))B0(J,Z);else if(E8(J),Z)qJ(J,H0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return X4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??j0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===uJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??j0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){EJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===ZJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return qJ(J,$),$},insertBefore($,Z){return qJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return qJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return o1(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){p0(J,$,Z)},removeAttribute($){p0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(ZJ);var d0=null;function I8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},n1=new Map;function t1(J,Q){n1.set(J,Q)}var e1=new Map;function J4(J,Q){e1.set(J,Q)}var CJ=new Set,A8=new Set;function Q4(J){if(!J)return!1;if(A8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function H0(J){let Q=E(),$=Q.createNode(HJ.text);return Q.setText($,J),c0({id:$,type:HJ.text,parent:null,children:[],text:J,domNodeType:uJ,domTag:"#text"})}function _8(J=""){let Q=H0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){E().replaceText(J.id,Q),J.text=Q,wJ()}function lJ(J){return J.type===HJ.text}function q4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function qJ(J,Q,$){let Z=E();if(q4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function pJ(J,Q){if(!Q)return;F8(Q),E().removeChild(J.id,Q.id),q4(Q),CJ.add(Q),wJ()}function k8(J){return J.parent??void 0}function S8(J){return J.children[0]}function X4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function b8(J,Q){let $=E();if(wJ(),Q==null||Q===""){$.setStyle(J.id,g6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function g8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=n1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function w8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=e1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function C8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=w6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,c6(G,P)),z=!0}if(z)wJ()}function EJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete G0(J)[Q];else G0(J)[Q]=$;switch(Q){case"class":return b8(J,$),$;case"onPress":case"on:press":return X8(J,$),$;case"src":return g8(J,$),$;case"sprite":return w8(J,$),$;case"style":return C8(J,$,Z),$;case"focusable":return Y8(J,!!$),$;case"debugName":return L8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${j0(J)}>`)}function E8(J){for(let Q of[...J.children])pJ(J,Q)}function j0(J){for(let Q of Object.keys(HJ))if(HJ[Q]===J.type)return Q;return String(J.type)}function N8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}EJ(J,Q,$,Z)}var h8=S6({createElement:Z4,createTextNode:H0,replaceText:B0,isTextNode:lJ,setProperty:N8,insertNode(J,Q,$){qJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:k8,getFirstChild:S8,getNextSibling:X4}),{render:T8,effect:NQ,memo:p,createComponent:Y,createElement:Y4,insert:hQ,spread:f8,mergeProps:TQ,use:fQ}=h8,yQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},y8=null;function z4(J){y8=J}function x8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function W4(J,Q){let $=Y4(J);return f8($,Q,!1),x8(Q.nodeRef,$),$}function K(J){return W4("view",J)}function R(J){return W4("text",J)}var xQ=new WeakMap,vQ=new WeakMap,v8={}!==null?Object.freeze({...{}}):Object.freeze({}),mQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:v8}),uQ=new Map,XJ=36000,s0=30,m8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(XJ),tapeAnalog:new Uint16Array(XJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function u8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-s0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)a1(()=>{W.treeDirty=!0}),r8();else a1(null);globalThis.__pocketDevtools=n8}function l8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)c8(),s8();let X=Q,z=$===void 0?BJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(XJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==BJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function B4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function j4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.masks,0,Q)}function F4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.analog??[],BJ,Q)}function K4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,f({t:"hello",app:W.app,host:o8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` +`))if(q.trim())d8(q)}}function d8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)f({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),a0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":M4();break;case"eval":{let Z=!0,q;try{q=F0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}f({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":f({t:"tape",tape:H4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}f({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())f({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else f({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=j4(Z),W.replayAnalog=Z.analog?F4(Z):null,W.replayTouch=Z.touch?K4(Z):null,W.replayAt=0;break}default:break}}function i8(){if(W.treeDirty&&W.frame-W.treeSentAt>=s0)M4();if(W.frame%m8===0)a0()}function s8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,f({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,f({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){f({t:"stats",frame:W.frame,nodes:P4(ZJ),tapeLen:W.tapeLen,paused:W.paused})}function M4(){W.treeDirty=!1,W.treeSentAt=W.frame,f({t:"tree",frame:W.frame,root:R4(ZJ)})}function a8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(a8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function U4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function R4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(U4(J,(q)=>{if(q.domNodeType===8)return;Z.push(R4(q))}),Z.length)Q.k=Z;return Q}function P4(J){let Q=1;return U4(J,($)=>{Q+=P4($)}),Q}function r8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{f({t:"log",level:$,args:q.map((X)=>F0(X))}),Z?.apply(Q,q)}}}function F0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?D4(X):JSON.stringify(D4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>F0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${F0(z,Q+1)}`).join(", ")}}`}function D4(J){return J.length>200?J.slice(0,199)+"…":J}function o8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var n8={get frame(){return W.frame},dumpTape:()=>H4(),replay:(J)=>{W.replayMasks=j4(J),W.replayAnalog=J.analog?F4(J):null,W.replayTouch=J.touch?K4(J):null,W.replayAt=0}},V4=new Map,o0=new Map;function L4(J){return J.trim().replace(/\s+/g," ")}function O4(J){return J.split(" ").sort().join(" ")}var I4=-1;function t8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=L4(Q);V4.set(Z,$);let q=O4(Z),X=o0.get(q);o0.set(q,X!==void 0&&X!==$?I4:$)}}function e8(J){let Q=L4(J),$=V4.get(Q);if($!==void 0)return $;let Z=o0.get(O4(Q));return Z===I4?void 0:Z}var n0=9,J2=(1<{let q=($&$2)!==0,X=q?t0:n0,z=q?Z2:J2;return Object.freeze({id:$>>>(q?q2:Q2)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Y2(){return K0}function z2(){K0=e0}var A4=8,YJ=8,W2=3,G2=8,H2=6,B2=0.5,s=1,cJ=2,J1=4,UJ=8,NJ=[],_4=0,M0=0,zJ=Array.from({length:A4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(YJ),histY:new Int16Array(YJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function j2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function F2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=s1(Q,$,Z.fact);let G=Z.hit;if(G)return j2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=NJ[z];if(G.disposed)continue;if(_4>0&&!G.opts.allowWhenBlocked)continue;if(!F2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function U2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%YJ,J.histLenz||Z>z))q.flags[J.slot]|=cJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(cJ|J1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??B2)*C1()));if(J.frames=0)NJ.splice($,1)},cancel(){if(!Q.disposed)b4(Q)},get panning(){for(let $ of zJ)if($.used&&Q.flags[$.slot]&UJ)return!0;return!1}}}function L2(J){let Q=V2(J);return S0(()=>Q.dispose()),Q}function g4(){NJ.length=0,_4=0,M0=0;for(let J of zJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function O2(){return L2({onDown:(J)=>{let Q=i1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=i1(J.x,J.y,J.hit);if(Q)j8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var I2=1,Q1=new Map,U0=[];function A2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function _2(){I2=1,Q1.clear(),U0=[]}function k2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),A2()?.({t:"delivery",frame:E1(),id:Q,kind:Z.kind}),Z.onResult($)}}var w4=new Set;function S2(){if(w4.size===0)return;for(let J of w4)J()}var b2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[28] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-base text-orange-600 font-bold":9,"h-[76] pt-3 text-lg text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-base text-emerald-700 font-bold":13,"h-[84] pt-3 text-lg text-slate-900":14,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":15,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":16,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":17,"text-base text-slate-600 font-bold":18,"pt-6 text-lg text-slate-500":19,"pt-6 text-lg text-slate-900 font-bold":20,"h-[146] px-6 pt-7 flex-col bg-slate-50":21,"h-[80]":22,"h-[1060] px-6 pt-5 flex-col":23,"h-[48] px-4 justify-center bg-slate-100":24,"text-base text-slate-600":25,"pt-[10] flex-col gap-[12]":26,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":27,"w-[48] h-[48] items-center justify-center bg-blue-100":28,"w-[48] h-[48] items-center justify-center bg-emerald-100":29,"text-lg text-blue-700 font-bold":30,"text-lg text-emerald-700 font-bold":31,"w-[474] flex-col gap-2":32,"text-lg text-slate-900 font-bold":33,"text-base text-slate-500":34,"pt-20 pl-10 text-lg text-slate-500":35,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":36,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":37,"h-[1060] px-6 pt-7 flex-col gap-4":38,"text-base text-slate-500 font-bold":39,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":40,"flex-row items-center gap-5":41,"w-[68] h-[68] items-center justify-center bg-emerald-100":42,"text-xl text-emerald-700 font-bold":43,"flex-col gap-2":44,"text-xl text-slate-900 font-bold":45,"text-lg text-slate-600":46,"text-2xl text-orange-600":47,"w-[68] h-[68] items-center justify-center bg-indigo-100":48,"text-xl text-indigo-700 font-bold":49,"mt-4 h-[112] px-6 justify-center bg-slate-100":50,"relative h-[154] px-5 pt-5 flex-col bg-white":51,"pt-3 text-lg text-orange-600 font-bold":52,"pt-3 text-base text-slate-500":53,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":54,"text-lg text-white font-bold":55,"h-[40] pt-3 text-base text-slate-500":56,"h-[470] flex-col gap-2":57,"h-[214] px-7 items-center justify-center bg-slate-100":58,"text-lg text-slate-500 font-bold":59,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":60,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":61,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":62,"h-[160] px-5 pt-5 flex-col bg-white":63,"pt-3 text-lg text-slate-900 font-bold":64,"pt-3 text-base text-slate-600":65,"h-[108] pt-7 flex-row gap-4":66,"w-[316] h-[80] items-center justify-center bg-slate-100":67,"w-[340] h-[80] items-center justify-center bg-red-100":68,"text-lg text-red-500 font-bold":69,"h-[1052] px-6 pt-5 flex-col":70,"h-[270] px-[22] pt-6 bg-white":71,"text-lg text-slate-900":72,"text-lg text-slate-400":73,"h-[86] px-1 flex-row items-center justify-between":74,"w-[132] h-[58] items-center justify-center bg-slate-300":75,"w-[132] h-[58] items-center justify-center bg-slate-100":76,"text-base text-slate-900 font-bold":77,"h-[140] flex-row gap-2":78,"grow h-[120] items-center justify-center bg-slate-300":79,"grow h-[120] items-center justify-center bg-white":80,"w-[104] h-[120] items-center justify-center bg-slate-300":81,"w-[104] h-[120] items-center justify-center bg-slate-100":82,"h-[176] flex-row gap-2":83,"w-[92] h-[156] items-center justify-center bg-slate-300":84,"w-[92] h-[156] items-center justify-center bg-slate-100":85,"w-[300] h-[156] items-center justify-center bg-slate-300":86,"w-[300] h-[156] items-center justify-center bg-slate-100":87,"w-[144] h-[156] items-center justify-center bg-slate-300":88,"w-[144] h-[156] items-center justify-center bg-slate-100":89,"w-[112] h-[156] items-center justify-center bg-emerald-700":90,"w-[112] h-[156] items-center justify-center bg-emerald-500":91,"text-base text-slate-950 font-bold":92,"h-[108] px-6 py-3 flex-col bg-slate-50":93,"h-[84] items-center justify-center bg-slate-300":94,"h-[84] items-center justify-center bg-slate-100":95,"h-[1168] px-6 pt-5 flex-col":96,"h-[82] px-4 justify-center bg-white":97,"w-[584] h-[900] px-5 pt-5 bg-slate-950":98,"text-base text-slate-200":99,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":100,"text-lg text-orange-600 font-bold":101,"w-[584] h-[900] px-5 pt-5 bg-white":102,"text-base text-slate-900":103,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":104,"absolute inset-0 z-50 flex-col items-center justify-center":105,"absolute inset-0 bg-slate-950":106,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":107,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":108,"flex-row flex-wrap":109,grow:110,"text-2xl text-white font-bold":111,"text-2xl text-slate-950 font-bold":112,"px-6":113,"px-6 py-5":114,"gap-4":115,"rounded-xl shadow bg-white border-slate-100":116,"rounded-xl shadow bg-emerald-100 border-emerald-500":117,"bg-white":118,"bg-slate-100":119,"bg-slate-950":120,"px-3 py-2 rounded-lg bg-slate-100":121,"px-3 py-2 rounded-lg bg-indigo-100":122,"text-base text-indigo-700 font-bold":123,"px-3 py-2 rounded-lg bg-emerald-100":124,"px-3 py-2 rounded-lg bg-amber-100":125,"text-base text-amber-700 font-bold":126,"px-3 py-2 rounded-lg bg-red-100":127,"text-base text-red-500 font-bold":128,"w-[34] h-[34] rounded-lg bg-amber-400":129,"w-[34] h-[34] rounded-lg bg-red-500":130,"w-[34] h-[34] rounded-lg bg-slate-800":131,"w-[34] h-[34] rounded-lg bg-emerald-500":132,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":133,"flex-row items-center gap-4":134,"w-[34] text-2xl text-white font-bold":135,"w-[332] flex-col items-end gap-2":136,"text-base text-slate-300 font-bold":137,"text-base text-slate-400":138,"h-[166] px-6 pt-6 flex-col gap-3":139,"h-[44] px-1 flex-row items-center justify-between":140,"w-full h-full items-center justify-center rounded-xl bg-slate-200":141,"w-full h-full items-center justify-center rounded-xl bg-red-100":142,"w-full h-full items-center justify-center rounded-xl bg-slate-100":143,"w-full h-full items-center justify-center rounded-xl bg-orange-600":144,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":145,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":146,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":147,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":148,"text-2xl text-indigo-700 font-bold":149,"text-2xl text-slate-600 font-bold":150,"pt-7 text-2xl text-slate-900 font-bold":151,"pt-4 text-lg text-slate-500":152,"text-xl text-emerald-600 font-bold":153,"text-xl text-red-500 font-bold":154,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":155,"text-base text-red-300":156,"text-base text-slate-300":157,"text-base text-red-500":158,"w-full h-full px-6 flex-row items-center bg-slate-950":159,"w-full h-full flex-row items-center":160};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var g2="ui:styles",w2="ui:font.",C4="ui:img.",E4="ui:sprite.";function C2(){return globalThis.ui}function E2(J){if(J.__textures)return;for(let Q of T0(C4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)t1(Q.slice(C4.length),Z)}}function N2(J){if(J.__sprites)return;for(let Q of T0(E4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)J4(Q.slice(E4.length),{handle:V,frames:G,cols:P,step:D})}}function N4(J){let Q=Y4("view");return EJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function h2(J,Q){if(!R0||!P0)return;EJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),EJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function T2(J,Q={}){let $=v6(Q.ops);if(m6($),I8(e8),Q.styles)t8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)t1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)J4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)y1(Q.pak);if(q8()){for(let B of T0())if(B===g2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(w2))$.ops.loadFontAtlas?.(vJ(B))}}let q=b1($.ops),X=q?.w??_1,z=q?.h??k1,G=N4({width:X,height:z,overflow:u.Overflow.Hidden}),P=N4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});qJ(ZJ,G),qJ(ZJ,P),z4(P),R0=G,P0=P,x1(G),c1(ZJ),Q8(),g4(),O2(),a6(),_2(),u8($.ops),u6(l8((B,_,N,h)=>{r6(),o6(_),X2(N,h),S2(),k2(),D2(),$8(B),V8(B),$4()}));let D=T8(J,G),V=l6(h2);return()=>{V(),z2(),g4(),D(),x1(null),c1(null),z4(null),R0=null,P0=null;for(let B of ZJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);$4()}}function f2(J,Q={}){let $=Q.ops??C2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)y1(Q.pak);return E2($),N2($),T2(J,{ops:$,styles:Q.styles??b2,pak:Q.pak})}var y2="$b",x2=65536,h4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function u2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function T4(){let J=u2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function l2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,x2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=v2(z.data[y2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function p2(J,Q){let $=l2(T4(),J);return Q==="utf8"||Q==="utf-8"?m2($):$}function c2(J,Q){let $=T4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var d2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"};function i2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(K,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(K,{class:"flex-row items-center gap-4",get children(){return[p(()=>p(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(K,{get["class"](){return Q()}})),Y(R,{get["class"](){return d2.appTitle},get children(){return J.title}})]}}),Y(K,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function s2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(K,{get["class"](){return Q()},get children(){return Y(R,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(K,{get["class"](){return J.top},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(K,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var lQ="‘’“”–—…•",f4=new Map,y4=new Map,a2=512;function D0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=f4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return f4.set($,q),q}function r2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=D0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function $1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=y4.get(Z);if(q)return q;let X=[],z=D0(" ",Q);for(let G of J.split(` +`)){let P=G.split(" ").flatMap((B)=>B&&D0(B,Q)>$?r2(B,Q,$):[B]),D="",V=0;for(let B of P){let _=D0(B,Q);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return y4.set(Z,X),X}function x4(J,Q,$,Z){let q=J.slice(0,a2),X=$1(q,Q,$);if(q.length===J.length&&X.length<=Z)return X.join(` +`);let z=X.slice(0,Z),G=z.length-1;return z[G]=z[G].replace(/[\s.]+$/,"")+"…",z.join(` +`)}var v4=3,m4=2,u4=536,l4=544,p4=39,[RJ,o2]=g({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[y,n]=g("chat"),[Z1,n2]=g("chat"),[q1,c4]=g(0),[PJ,d4]=g(""),[sJ,hJ]=g(0),[aJ,X1]=g([]),[t2,V0]=g(""),[i4,L0]=g(null),[s4,a4]=g(null),[O0,I0]=g(0),[v,t]=g(""),[DJ,r4]=g("letters"),[Y1,z1]=g(!1),[W1,o4]=g({type:"prompt"}),[WJ,n4]=g(null),[rJ,t4]=g(0),e4=new Map,J6=["qwertyuiop","asdfghjkl","zxcvbnm"],Q6=["1234567890","-/:;()$&@",`.,?!'"+`],$6=["chat","files","apps","settings"];function e2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function JQ(J,Q){return J?J+"/"+Q:Q}function A0(J=PJ(),Q=!1){let $=e4.get(J);if(!Q&&$){X1($),V0(""),hJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=c2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));e4.set(J,Z),X1(Z),V0(""),hJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){X1([]),V0(Z instanceof Error?Z.message:String(Z))}}function QQ(){let J=[];for(let Q of RJ().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Z6(){let J=QQ(),Q=Math.max(0,J.length-2),$=Math.min(q1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function VJ(J){return Y(i2,{get title(){return J.title},get accent(){return p(()=>RJ().agent==="FAULTED")()?"danger":RJ().agent==="THINKING"?"busy":"ready"}})}function _0(){return Y(K,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(SJ,{each:$6,children:(J)=>Y(K,{get["class"](){return Z1()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function $Q(){let J=()=>RJ().schedule;return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"ESP32 PI AGENT"}),Y(K,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(SJ,{get each(){return Z6()},children:(Q)=>Y(K,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(K,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(K,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-base text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-lg text-slate-900",get children(){return x4(Q.user,v4,u4,3)}}),Y(K,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(K,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(K,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-base text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-lg text-slate-900",get children(){return x4(Q.assistant,v4,u4,3)}})]}})}),Y(iJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(K,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-base text-slate-600 font-bold",children:"NEXT WAKE"}),Y(bJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-lg text-slate-500",children:`NO WAKE SCHEDULED ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(R,{class:"pt-6 text-lg text-slate-900 font-bold",get children(){return String(J()?.name)+" "+String(J()?.next??"")+` -`+String(J()?.prompt??"")}})}})]}}),Y(K,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(K,{class:"h-[80]",get children(){return Y(s2,{label:"TYPE A MESSAGE"})}})}}),Y(_0,{})]}})}function $Q(){let J=()=>aJ().slice(sJ(),sJ()+8);return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return PJ()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(K,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",get children(){return"/workspace"+(PJ()?"/"+PJ():"")}})}}),Y(K,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(SJ,{get each(){return J()},children:(Q)=>Y(K,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(K,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-lg text-blue-700 font-bold":"text-lg text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(K,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,52)}}),Y(R,{class:"text-base text-slate-500",get children(){return p(()=>Q.kind==="dir")()?"FOLDER":t2(Q.size)}})]}})]}})})}}),Y(bJ,{get when(){return aJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-lg text-slate-500",get children(){return n2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(bJ,{get when(){return aJ().length>8},get children(){return Y(iJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(_0,{})]}})}function ZQ(){return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"APPS"}),Y(K,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-base text-slate-500 font-bold",children:"2 INSTALLED APPS"}),Y(K,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(K,{class:"flex-row items-center gap-5",get children(){return[Y(K,{class:"w-[68] h-[68] items-center justify-center bg-emerald-100",get children(){return Y(R,{class:"text-xl text-emerald-700 font-bold",children:"R"})}}),Y(K,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Robinhood"}),Y(R,{class:"text-lg text-slate-600",children:"Portfolio and positions"}),Y(R,{class:"text-base text-slate-500",children:"UPDATES EVERY 5 MINUTES"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(K,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(K,{class:"flex-row items-center gap-5",get children(){return[Y(K,{class:"w-[68] h-[68] items-center justify-center bg-indigo-100",get children(){return Y(R,{class:"text-xl text-indigo-700 font-bold",children:"E"})}}),Y(K,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Exa Research"}),Y(R,{class:"text-lg text-slate-600",children:"Agent search history"}),Y(R,{class:"text-base text-slate-500",children:"STORED LOCALLY IN SQLITE"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(K,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",children:`APP DATA STAYS ISOLATED. -PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(_0,{})]}})}function qQ(){let J=()=>RJ().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(rJ(),rJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"SETTINGS"}),Y(K,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-lg text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return Z()}}),Y(K,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-lg text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-base text-slate-500",children:"AVAILABLE NETWORKS"}),Y(K,{class:"h-[470] flex-col gap-2",get children(){return[Y(bJ,{get when(){return $().length>0},get fallback(){return Y(K,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-500 font-bold",children:`NO NETWORK LIST YET +`+String(J()?.prompt??"")}})}})]}}),Y(K,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(K,{class:"h-[80]",get children(){return Y(s2,{label:"TYPE A MESSAGE"})}})}}),Y(_0,{})]}})}function ZQ(){let J=()=>aJ().slice(sJ(),sJ()+8);return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return PJ()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(K,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",get children(){return"/workspace"+(PJ()?"/"+PJ():"")}})}}),Y(K,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(SJ,{get each(){return J()},children:(Q)=>Y(K,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(K,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-lg text-blue-700 font-bold":"text-lg text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(K,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,52)}}),Y(R,{class:"text-base text-slate-500",get children(){return p(()=>Q.kind==="dir")()?"FOLDER":e2(Q.size)}})]}})]}})})}}),Y(bJ,{get when(){return aJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-lg text-slate-500",get children(){return t2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(bJ,{get when(){return aJ().length>8},get children(){return Y(iJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(_0,{})]}})}function qQ(){return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"APPS"}),Y(K,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-base text-slate-500 font-bold",children:"2 INSTALLED APPS"}),Y(K,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(K,{class:"flex-row items-center gap-5",get children(){return[Y(K,{class:"w-[68] h-[68] items-center justify-center bg-emerald-100",get children(){return Y(R,{class:"text-xl text-emerald-700 font-bold",children:"R"})}}),Y(K,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Robinhood"}),Y(R,{class:"text-lg text-slate-600",children:"Portfolio and positions"}),Y(R,{class:"text-base text-slate-500",children:"UPDATES EVERY 5 MINUTES"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(K,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(K,{class:"flex-row items-center gap-5",get children(){return[Y(K,{class:"w-[68] h-[68] items-center justify-center bg-indigo-100",get children(){return Y(R,{class:"text-xl text-indigo-700 font-bold",children:"E"})}}),Y(K,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Exa Research"}),Y(R,{class:"text-lg text-slate-600",children:"Agent search history"}),Y(R,{class:"text-base text-slate-500",children:"STORED LOCALLY IN SQLITE"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(K,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",children:`APP DATA STAYS ISOLATED. +PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(_0,{})]}})}function XQ(){let J=()=>RJ().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(rJ(),rJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"SETTINGS"}),Y(K,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-lg text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return Z()}}),Y(K,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-lg text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-base text-slate-500",children:"AVAILABLE NETWORKS"}),Y(K,{class:"h-[470] flex-col gap-2",get children(){return[Y(bJ,{get when(){return $().length>0},get fallback(){return Y(K,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-500 font-bold",children:`NO NETWORK LIST YET -TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(SJ,{get each(){return $()},children:(q)=>Y(K,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-base text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(bJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(iJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(K,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-lg text-slate-900 font-bold",get children(){return RJ().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-base text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(K,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(K,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(K,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-lg text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(_0,{})]}})}function XQ(){let J=()=>W1(),Q=()=>DJ()==="letters"?J6:Q6,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(K,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(K,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-base text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(K,{get["class"](){return WJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(SJ,{get each(){return Q()},children:(Z,q)=>Y(K,{class:"h-[140] flex-row gap-2",get children(){return[Y(SJ,{get each(){return Z.split("")},children:(X)=>Y(K,{get["class"](){return WJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return p(()=>!!Y1())()?X.toUpperCase():X}})}})}),Y(bJ,{get when(){return q()===2},get children(){return Y(K,{get["class"](){return WJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(K,{class:"h-[176] flex-row gap-2",get children(){return[Y(K,{get["class"](){return WJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"123":"ABC"}})}}),Y(K,{get["class"](){return WJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"SPACE"})}}),Y(K,{get["class"](){return WJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"SHIFT":". ?"}})}}),Y(K,{get["class"](){return WJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(R,{class:"text-base text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(K,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(K,{get["class"](){return WJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function YQ(){let J=()=>i4(),Q=()=>(J()?.text??"").split(` +TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(SJ,{get each(){return $()},children:(q)=>Y(K,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-base text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(bJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(iJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(K,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-lg text-slate-900 font-bold",get children(){return RJ().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-base text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(K,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(K,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(K,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-lg text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(_0,{})]}})}function YQ(){let J=()=>W1(),Q=()=>DJ()==="letters"?J6:Q6,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(K,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(K,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-base text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(K,{get["class"](){return WJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(SJ,{get each(){return Q()},children:(Z,q)=>Y(K,{class:"h-[140] flex-row gap-2",get children(){return[Y(SJ,{get each(){return Z.split("")},children:(X)=>Y(K,{get["class"](){return WJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return p(()=>!!Y1())()?X.toUpperCase():X}})}})}),Y(bJ,{get when(){return q()===2},get children(){return Y(K,{get["class"](){return WJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(K,{class:"h-[176] flex-row gap-2",get children(){return[Y(K,{get["class"](){return WJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"123":"ABC"}})}}),Y(K,{get["class"](){return WJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"SPACE"})}}),Y(K,{get["class"](){return WJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"SHIFT":". ?"}})}}),Y(K,{get["class"](){return WJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(R,{class:"text-base text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(K,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(K,{get["class"](){return WJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function zQ(){let J=()=>i4(),Q=()=>(J()?.text??"").split(` `),$=()=>J()?.lineOffset??0;return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< FILE VIEWER"}),Y(K,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(K,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(R,{class:"text-base text-slate-200",get children(){return Q().slice($(),$()+39).join(` -`)}})}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function zQ(){let J=()=>s4(),Q=()=>$1(J()?.text??"",m4,l4);return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< MESSAGE READER"}),Y(K,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(K,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-base text-slate-900",get children(){return Q().slice(O0(),O0()+p4).join(` -`)}})}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function WQ(){return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return p(()=>y()==="chat")()?Y(QQ,{}):p(()=>y()==="files")()?Y($Q,{}):p(()=>y()==="apps")()?Y(ZQ,{}):p(()=>y()==="settings")()?Y(qQ,{}):p(()=>y()==="keyboard")()?Y(XQ,{}):p(()=>y()==="viewer")()?Y(YQ,{}):Y(zQ,{})}})}function GQ(J){j6(()=>{if(o2(J),n(J),J==="files")A0()})}function q6(J,Q){let $=DJ()==="letters"?J6:Q6,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=q6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function BQ(J,Q){if(Q>=1164)return t(""),n(Z1()),"";if(J>=548&&Q>=402&&Q<=482)return t(""),"";let $=q6(J,Q);if($){let Z=DJ()==="letters"&&Y1()?$.toUpperCase():$,q=W1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return t(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)r4(DJ()==="letters"?"numbers":"letters"),z1(!1);else if(J<=424){if(v())t(v()+" ")}else if(J<=576)if(DJ()==="letters")z1(!Y1());else t(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=W1();if(t(""),r4("letters"),z1(!1),n(Z1()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}f2(()=>Y(WQ,{})),queueMicrotask(()=>A0("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return r2(JSON.parse(J)),""},pointerDown(J,Q){return n4(y()==="keyboard"?HQ(J,Q):null),""},pointerUp(){return n4(null),""},tap(J,Q){if(y()==="keyboard")return BQ(J,Q);if(y()==="viewer"){let $=i4();if(J<104&&Q<112)L0(null),n("files");else if($&&J>=620&&Q>=170&&Q<=340)L0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)L0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` -`).length-39),$.lineOffset+18)});return""}if(y()==="reader"){if(J<104&&Q<112)a4(null),I0(0),n("chat");else if(J>=620&&Q>=170&&Q<=340)I0(Math.max(0,O0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=$1(s4()?.text??"",m4,l4).length;I0(Math.min(Math.max(0,$-p4),O0()+18))}return""}if(Q>=1172)return GQ($6[Math.min(3,Math.floor(J/180))]),"";if(y()==="chat"){if(J>=620&&Q>=140&&Q<=272)c4(q1()+2);else if(J>=620&&Q>=624&&Q<=756)c4(Math.max(0,q1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=Z6()[$];if(Z){let q=Q>=140+$*320+150;a4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),I0(0),n("reader")}}else if(Q>=1070&&Q<=1150)o4({type:"prompt"}),t(""),n("keyboard");return""}if(y()==="files"){if(J<104&&Q<112&&PJ()){let $=PJ().split("/");$.pop();let Z=$.join("/");d4(Z),hJ(0),A0(Z)}else if(J>=620&&Q>=170&&Q<=340)hJ(Math.max(0,sJ()-4));else if(J>=620&&Q>=920&&Q<=1100)hJ(Math.min(Math.max(0,aJ().length-8),sJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=aJ()[sJ()+$];if(Z){let q=e2(PJ(),Z.name);if(Z.kind==="dir")d4(q),hJ(0),A0(q);else try{L0({path:"/workspace/"+q,text:p2(q,"utf8"),lineOffset:0}),n("viewer")}catch(X){V0(X instanceof Error?X.message:String(X))}}}return""}if(y()==="apps"){if(Q>=162&&Q<324)return JSON.stringify({type:"navigate",app:"robinhood"});if(Q>=324&&Q<490)return JSON.stringify({type:"navigate",app:"exa"});return""}if(y()==="settings"){let $=RJ().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)t4(Math.max(0,rJ()-4));else if(J>=620&&Q>=650&&Q<=782)t4(Math.min(Math.max(0,$.length-5),rJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[rJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});o4({type:"wifi",ssid:q.ssid}),t(""),n("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); +`)}})}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function WQ(){let J=()=>s4(),Q=()=>$1(J()?.text??"",m4,l4);return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< MESSAGE READER"}),Y(K,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(K,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-base text-slate-900",get children(){return Q().slice(O0(),O0()+p4).join(` +`)}})}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function GQ(){return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return p(()=>y()==="chat")()?Y($Q,{}):p(()=>y()==="files")()?Y(ZQ,{}):p(()=>y()==="apps")()?Y(qQ,{}):p(()=>y()==="settings")()?Y(XQ,{}):p(()=>y()==="keyboard")()?Y(YQ,{}):p(()=>y()==="viewer")()?Y(zQ,{}):Y(WQ,{})}})}function HQ(J){j6(()=>{if(n2(J),n(J),J==="files")A0()})}function q6(J,Q){let $=DJ()==="letters"?J6:Q6,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=q6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function jQ(J,Q){if(Q>=1164)return t(""),n(Z1()),"";if(J>=548&&Q>=402&&Q<=482)return t(""),"";let $=q6(J,Q);if($){let Z=DJ()==="letters"&&Y1()?$.toUpperCase():$,q=W1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return t(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)r4(DJ()==="letters"?"numbers":"letters"),z1(!1);else if(J<=424){if(v())t(v()+" ")}else if(J<=576)if(DJ()==="letters")z1(!Y1());else t(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=W1();if(t(""),r4("letters"),z1(!1),n(Z1()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}f2(()=>Y(GQ,{})),queueMicrotask(()=>A0("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return o2(JSON.parse(J)),""},pointerDown(J,Q){return n4(y()==="keyboard"?BQ(J,Q):null),""},pointerUp(){return n4(null),""},tap(J,Q){if(y()==="keyboard")return jQ(J,Q);if(y()==="viewer"){let $=i4();if(J<104&&Q<112)L0(null),n("files");else if($&&J>=620&&Q>=170&&Q<=340)L0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)L0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` +`).length-39),$.lineOffset+18)});return""}if(y()==="reader"){if(J<104&&Q<112)a4(null),I0(0),n("chat");else if(J>=620&&Q>=170&&Q<=340)I0(Math.max(0,O0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=$1(s4()?.text??"",m4,l4).length;I0(Math.min(Math.max(0,$-p4),O0()+18))}return""}if(Q>=1172)return HQ($6[Math.min(3,Math.floor(J/180))]),"";if(y()==="chat"){if(J>=620&&Q>=140&&Q<=272)c4(q1()+2);else if(J>=620&&Q>=624&&Q<=756)c4(Math.max(0,q1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=Z6()[$];if(Z){let q=Q>=140+$*320+150;a4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),I0(0),n("reader")}}else if(Q>=1070&&Q<=1150)o4({type:"prompt"}),t(""),n("keyboard");return""}if(y()==="files"){if(J<104&&Q<112&&PJ()){let $=PJ().split("/");$.pop();let Z=$.join("/");d4(Z),hJ(0),A0(Z)}else if(J>=620&&Q>=170&&Q<=340)hJ(Math.max(0,sJ()-4));else if(J>=620&&Q>=920&&Q<=1100)hJ(Math.min(Math.max(0,aJ().length-8),sJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=aJ()[sJ()+$];if(Z){let q=JQ(PJ(),Z.name);if(Z.kind==="dir")d4(q),hJ(0),A0(q);else try{L0({path:"/workspace/"+q,text:p2(q,"utf8"),lineOffset:0}),n("viewer")}catch(X){V0(X instanceof Error?X.message:String(X))}}}return""}if(y()==="apps"){if(Q>=162&&Q<324)return JSON.stringify({type:"navigate",app:"robinhood"});if(Q>=324&&Q<490)return JSON.stringify({type:"navigate",app:"exa"});return""}if(y()==="settings"){let $=RJ().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)t4(Math.max(0,rJ()-4));else if(J>=620&&Q>=650&&Q<=782)t4(Math.min(Math.max(0,$.length-5),rJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[rJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});o4({type:"wifi",ssid:q.ssid}),t(""),n("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); diff --git a/firmware/esp32-p4/src/transport/provisioning.rs b/firmware/esp32-p4/src/transport/provisioning.rs index 3aabd5d..555ee41 100644 --- a/firmware/esp32-p4/src/transport/provisioning.rs +++ b/firmware/esp32-p4/src/transport/provisioning.rs @@ -81,7 +81,7 @@ pub fn request_runtime_config( model_api_key, exa_api_key: secret(&value, "exaApiKey", 512)?, robinhood_access_token: secret(&value, "robinhoodAccessToken", 4096)?, - initial_prompt: text(&value, "initialPrompt", 4_000)?, + initial_prompt: string(&value, "initialPrompt")?.map(str::to_owned), initial_prompt_delay_seconds: value .get("initialPromptDelaySeconds") .and_then(serde_json::Value::as_u64) @@ -98,16 +98,26 @@ fn text( field: &str, max_bytes: usize, ) -> Result, String> { + let Some(value) = string(value, field)? else { + return Ok(None); + }; + if value.len() > max_bytes { + return Err(format!("{field} has invalid length")); + } + Ok(Some(value.to_owned())) +} + +fn string<'a>(value: &'a serde_json::Value, field: &str) -> Result, String> { let Some(value) = value.get(field) else { return Ok(None); }; let value = value .as_str() .ok_or_else(|| format!("{field} must be a string"))?; - if value.is_empty() || value.len() > max_bytes { + if value.is_empty() { return Err(format!("{field} has invalid length")); } - Ok(Some(value.to_owned())) + Ok(Some(value)) } fn secret( From 861cff448d53866fdf31a04ad7c607319968f452 Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Tue, 11 Aug 2026 15:06:37 +0800 Subject: [PATCH 13/24] refactor(robinhood): keep tool descriptions policy-free --- apps/robinhood/TOOLS.md | 7 +- apps/robinhood/dist/data-action.js | 123 ++++++++++++++-------------- apps/robinhood/tool-catalog.json | 62 +++++++------- crates/pocket-pi-agentos/src/lib.rs | 14 ---- 4 files changed, 95 insertions(+), 111 deletions(-) diff --git a/apps/robinhood/TOOLS.md b/apps/robinhood/TOOLS.md index 71fb194..b2c8b4b 100644 --- a/apps/robinhood/TOOLS.md +++ b/apps/robinhood/TOOLS.md @@ -107,6 +107,7 @@ mistaken for completion. The provider JSON is serialized once as ToolResult responses do not retain a second copy in the QuickJS/Agent bridge. Review Tools are explicitly described as non-submitting. Place, cancel, and -exercise Tools retain Robinhood's confirmation and Agentic-account guidance and -add Pocket Pi's real-account warning. A repeated real-money order must reuse the -same `ref_id`; an ambiguous transport result must not be retried with a new ID. +exercise Tools describe their real account effects, functional account limits, +and parameter contracts without embedding an interaction or authorization +policy. A repeated real-money order must reuse the same `ref_id`; an ambiguous +transport result must not be retried with a new ID. diff --git a/apps/robinhood/dist/data-action.js b/apps/robinhood/dist/data-action.js index ab6378a..4d3b50d 100644 --- a/apps/robinhood/dist/data-action.js +++ b/apps/robinhood/dist/data-action.js @@ -1,4 +1,4 @@ -(()=>{var b={source:"https://agent.robinhood.com/mcp/trading",protocolVersion:"2025-06-18",retrievedAt:"2026-08-10T09:05:39+00:00",tools:[{name:"add_option_to_watchlist",namespace:"option_market_data",description:"Add option contracts to the user's options watchlist. Works for both equity options (AAPL, NVDA) and index options (SPX, NDX, RUT). Source option_ids from get_option_instruments. Confirm with the user before calling — this is a real write. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{option_ids:{type:["null","array"],items:{type:"string"},description:"Option contract UUIDs to add. Each becomes a single-leg position on the user's options watchlist. Source from get_option_instruments."},position_type:{type:"string",description:'"long" (default) or "short". Applies to every option_id in this call. For mixed long/short adds, issue two calls.'}},required:["option_ids"],additionalProperties:!1}},{name:"add_to_watchlist",namespace:"watchlists",description:"Add items to a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes like SPX, NDX) is required — mutually exclusive. For options use add_option_to_watchlist (separate dedicated watchlist). Futures still require the Robinhood app. Already-present items are no-ops. Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to add items to."},symbols:{type:["null","array"],items:{type:"string"},description:"Stock symbols to add (e.g. ['AAPL', 'NVDA']). US stocks and ETFs only. Mutually exclusive with currency_pair_ids and index_ids."},currency_pair_ids:{type:["null","array"],items:{type:"string"},description:"Currency-pair UUIDs to add (e.g. the object_id from get_watchlist_items where object_type=currency_pair, or the id from get_currency_pairs). Mutually exclusive with symbols and index_ids."},index_ids:{type:["null","array"],items:{type:"string"},description:"Market-index UUIDs to add (the id field from get_indexes; SPX, NDX, DJI, etc.). Mutually exclusive with symbols and currency_pair_ids."}},required:["list_id"],additionalProperties:!1}},{name:"cancel_equity_order",namespace:"equity_trading",description:"Cancel an open equity order by order_id. Always confirm with the user before calling. Resolve order_id via get_equity_orders if the user refers to it by symbol or description; pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected — do not call. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. REAL ACCOUNT ACTION: use only for the exact user-authorized account and order or exercise identifier; confirm the final provider state afterward. After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the order. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true. The upstream rejects mismatches against the order's owning account."},order_id:{type:"string",description:"Order UUID from get_equity_orders. Must live in account_number."}},required:["account_number","order_id"],additionalProperties:!1}},{name:"cancel_option_exercise",namespace:"option_trading",description:"Cancel all queued exercise requests for an option position. Pass the same account_number and option_id used for exercise_option. Internally looks up all queued exercise events for that option and cancels each one. Typically there is one; multiple means the user submitted separate exercise batches. Only cancels events in state=queued — events already processing are rejected by the broker. Always confirm with the user before calling. REAL ACCOUNT ACTION: use only for the exact user-authorized account and order or exercise identifier; confirm the final provider state afterward. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the exercise. Must be agentic_allowed=true."},option_id:{type:"string",description:"Option instrument UUID — the same option_id used for exercise_option. The tool looks up the queued exercise for this option and cancels it."}},required:["account_number","option_id"],additionalProperties:!1}},{name:"cancel_option_order",namespace:"option_trading",description:"Cancel an open option order by account_number + order_id. Always confirm with the user before calling. Resolve order_id via get_option_orders if the user refers to it by description; pass the same account_number you used there. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. REAL ACCOUNT ACTION: use only for the exact user-authorized account and order or exercise identifier; confirm the final provider state afterward. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the order. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true. Mismatches against the order's owning account are rejected."},order_id:{type:"string",description:"Order UUID from get_option_orders. Must live in account_number."}},required:["account_number","order_id"],additionalProperties:!1}},{name:"create_scan",namespace:"scanners",description:`Create a new saved scanner (screener) on the user's account, optionally applying a preset and custom filters in a single call. Returns the new scan's id, title, applied filters, and the initial live market results. +(()=>{var b={source:"https://agent.robinhood.com/mcp/trading",protocolVersion:"2025-06-18",retrievedAt:"2026-08-10T09:05:39+00:00",tools:[{name:"add_option_to_watchlist",namespace:"option_market_data",description:"Add option contracts to the user's options watchlist. Works for both equity options (AAPL, NVDA) and index options (SPX, NDX, RUT). Source option_ids from get_option_instruments. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{option_ids:{type:["null","array"],items:{type:"string"},description:"Option contract UUIDs to add. Each becomes a single-leg position on the user's options watchlist. Source from get_option_instruments."},position_type:{type:"string",description:'"long" (default) or "short". Applies to every option_id in this call. For mixed long/short adds, issue two calls.'}},required:["option_ids"],additionalProperties:!1}},{name:"add_to_watchlist",namespace:"watchlists",description:"Add items to a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes like SPX, NDX) is required — mutually exclusive. For options use add_option_to_watchlist (separate dedicated watchlist). Futures still require the Robinhood app. Already-present items are no-ops. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to add items to."},symbols:{type:["null","array"],items:{type:"string"},description:"Stock symbols to add (e.g. ['AAPL', 'NVDA']). US stocks and ETFs only. Mutually exclusive with currency_pair_ids and index_ids."},currency_pair_ids:{type:["null","array"],items:{type:"string"},description:"Currency-pair UUIDs to add (e.g. the object_id from get_watchlist_items where object_type=currency_pair, or the id from get_currency_pairs). Mutually exclusive with symbols and index_ids."},index_ids:{type:["null","array"],items:{type:"string"},description:"Market-index UUIDs to add (the id field from get_indexes; SPX, NDX, DJI, etc.). Mutually exclusive with symbols and currency_pair_ids."}},required:["list_id"],additionalProperties:!1}},{name:"cancel_equity_order",namespace:"equity_trading",description:"Cancel an open equity order by order_id. Resolve order_id via get_equity_orders and pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the order, from get_accounts. Must be agentic_allowed=true. The upstream rejects mismatches against the order's owning account."},order_id:{type:"string",description:"Order UUID from get_equity_orders. Must live in account_number."}},required:["account_number","order_id"],additionalProperties:!1}},{name:"cancel_option_exercise",namespace:"option_trading",description:"Cancel all queued exercise requests for an option position. Pass the same account_number and option_id used for exercise_option. Internally looks up all queued exercise events for that option and cancels each one. Typically there is one; multiple means separate exercise batches were submitted. Only events in state=queued can be cancelled; events already processing are rejected by the broker. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the exercise. Must be agentic_allowed=true."},option_id:{type:"string",description:"Option instrument UUID — the same option_id used for exercise_option. The tool looks up the queued exercise for this option and cancels it."}},required:["account_number","option_id"],additionalProperties:!1}},{name:"cancel_option_order",namespace:"option_trading",description:"Cancel an open option order by account_number + order_id. Resolve order_id via get_option_orders and pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the order, from get_accounts. Must be agentic_allowed=true. Mismatches against the order's owning account are rejected."},order_id:{type:"string",description:"Order UUID from get_option_orders. Must live in account_number."}},required:["account_number","order_id"],additionalProperties:!1}},{name:"create_scan",namespace:"scanners",description:`Create a new saved scanner (screener) on the user's account, optionally applying a preset and custom filters in a single call. Returns the new scan's id, title, applied filters, and the initial live market results. This tool composes multiple Beacon operations: 1. Create an empty scan @@ -19,21 +19,21 @@ Example: to make "stocks with RSI > 70 and volume > 1M, sorted by volume desc", {"filter_type": "FILTER_TYPE_RSI", "predicate": ">", "values": ["70"], "interval": "1d", "length": 14}, {"filter_type": "FILTER_TYPE_VOLUME", "predicate": ">", "values": ["1000000"], "interval": "1d"} ] - title = "High RSI + High Volume" This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{preset:{type:"string",description:"Starting preset for the new scan. One of: INITIAL (no preset; only valid if filters are provided), DAILY_GAINERS, DAILY_LOSERS, HIGH_OPTIONS_VOLUME_IV, UPCOMING_EARNINGS. Defaults to DAILY_GAINERS when no filters are provided, INITIAL when filters are provided."},filters:{type:["null","array"],items:{type:"object",properties:{filter_type:{type:"string",description:'Wire-format enum name, e.g. "FILTER_TYPE_RSI". See the scanner-filter-specs resource for valid values. Omit when supplying expression.'},predicate:{type:"string",description:'Wire-format enum name, e.g. "PREDICATE_GREATER_THAN". See the scanner-filter-specs resource for the predicates supported by each filter.'},values:{type:["null","array"],items:{type:"string"},description:'Threshold values. Single-element for unary predicates, two-element for BETWEEN, multi-element for IN_LIST/ANY_OF. For a boolean expression screen, exactly ["True"].'},interval:{type:"string",description:`Time granularity for time-series filters (e.g. "1d"). Use one of the supported_intervals from the filter's scanner-filter-specs entry. Not used with expression — encode granularity inside the expression.`},length:{type:"integer",description:"Lookback length for filters that need one (e.g. RSI period of 14). Use one of the supported_lengths from the filter's scanner-filter-specs entry. Not used with expression.",minimum:-2147483648,maximum:2147483647},plot:{type:"string",description:`Plot / price-field input for filters that have one (e.g. "open" or "close" for % Change). Use one of the supported_plots from the filter's scanner-filter-specs entry. Not used with expression.`},expression:{type:"string",description:'Raw market-data expression to screen on, e.g. "dayVolume / volumeAvg(candleCount=30, candlePeriod=\\"1d\\", session=\\"all\\")" with a numeric predicate, or a whole comparison like "tradeAllDay.price > closeAvg(candleCount=50, candlePeriod=\\"1d\\", session=\\"all\\")" with predicate "=" and values ["True"]. Only preview_scan accepts expressions. Omit filter_type when set. Prefer an enum filter_type whenever one covers the request.'},display_title:{type:"string",description:'Optional short label for an expression filter, shown as the results-column header (e.g. "Relative volume (30D)"). Only used with expression.'}},required:["predicate","values"],additionalProperties:!1},description:"Custom filters to apply after the preset. Each filter has filter_type (FILTER_TYPE_... enum), predicate (>, <, =, BETWEEN, etc.), values, optional interval (e.g. 1d), and optional length (e.g. 14 for RSI). Call get_scanner_filter_specs first for valid filter_type / predicate combinations."},title:{type:"string",description:"Optional custom title for the saved scan. If omitted, Beacon assigns a default title based on the preset."}},additionalProperties:!1}},{name:"create_watchlist",namespace:"watchlists",description:"Create a new custom watchlist for the user. Confirm the name with the user before calling — this is a real write. Do not use this to follow a Robinhood-curated list (use follow_watchlist). This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{display_name:{type:"string",description:"Name for the new watchlist (e.g. 'Tech Stocks'). Must be unique among the user's watchlists."},icon_emoji:{type:"string",description:"Emoji shown next to the name (one character)."},display_description:{type:"string",description:"Short description shown under the name."}},required:["display_name"],additionalProperties:!1}},{name:"exercise_option",namespace:"option_trading",description:`Exercise a long options position — a call exercises the right to buy the underlying shares at the strike price; a put exercises the right to sell. Exercise is irrevocable once state moves past queued. + title = "High RSI + High Volume" This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{preset:{type:"string",description:"Starting preset for the new scan. One of: INITIAL (no preset; only valid if filters are provided), DAILY_GAINERS, DAILY_LOSERS, HIGH_OPTIONS_VOLUME_IV, UPCOMING_EARNINGS. Defaults to DAILY_GAINERS when no filters are provided, INITIAL when filters are provided."},filters:{type:["null","array"],items:{type:"object",properties:{filter_type:{type:"string",description:'Wire-format enum name, e.g. "FILTER_TYPE_RSI". See the scanner-filter-specs resource for valid values. Omit when supplying expression.'},predicate:{type:"string",description:'Wire-format enum name, e.g. "PREDICATE_GREATER_THAN". See the scanner-filter-specs resource for the predicates supported by each filter.'},values:{type:["null","array"],items:{type:"string"},description:'Threshold values. Single-element for unary predicates, two-element for BETWEEN, multi-element for IN_LIST/ANY_OF. For a boolean expression screen, exactly ["True"].'},interval:{type:"string",description:`Time granularity for time-series filters (e.g. "1d"). Use one of the supported_intervals from the filter's scanner-filter-specs entry. Not used with expression — encode granularity inside the expression.`},length:{type:"integer",description:"Lookback length for filters that need one (e.g. RSI period of 14). Use one of the supported_lengths from the filter's scanner-filter-specs entry. Not used with expression.",minimum:-2147483648,maximum:2147483647},plot:{type:"string",description:`Plot / price-field input for filters that have one (e.g. "open" or "close" for % Change). Use one of the supported_plots from the filter's scanner-filter-specs entry. Not used with expression.`},expression:{type:"string",description:'Raw market-data expression to screen on, e.g. "dayVolume / volumeAvg(candleCount=30, candlePeriod=\\"1d\\", session=\\"all\\")" with a numeric predicate, or a whole comparison like "tradeAllDay.price > closeAvg(candleCount=50, candlePeriod=\\"1d\\", session=\\"all\\")" with predicate "=" and values ["True"]. Only preview_scan accepts expressions. Omit filter_type when set. Prefer an enum filter_type whenever one covers the request.'},display_title:{type:"string",description:'Optional short label for an expression filter, shown as the results-column header (e.g. "Relative volume (30D)"). Only used with expression.'}},required:["predicate","values"],additionalProperties:!1},description:"Custom filters to apply after the preset. Each filter has filter_type (FILTER_TYPE_... enum), predicate (>, <, =, BETWEEN, etc.), values, optional interval (e.g. 1d), and optional length (e.g. 14 for RSI). Call get_scanner_filter_specs first for valid filter_type / predicate combinations."},title:{type:"string",description:"Optional custom title for the saved scan. If omitted, Beacon assigns a default title based on the preset."}},additionalProperties:!1}},{name:"create_watchlist",namespace:"watchlists",description:"Create a new custom watchlist. Do not use this to follow a Robinhood-curated list; use follow_watchlist instead. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{display_name:{type:"string",description:"Name for the new watchlist (e.g. 'Tech Stocks'). Must be unique among the user's watchlists."},icon_emoji:{type:"string",description:"Emoji shown next to the name (one character)."},display_description:{type:"string",description:"Short description shown under the name."}},required:["display_name"],additionalProperties:!1}},{name:"exercise_option",namespace:"option_trading",description:`Exercise a long options position. A call exercises the right to buy the underlying shares at the strike price; a put exercises the right to sell. Exercise is irrevocable once state moves past queued. -Never call this tool without asking the user to explicitly confirm the specific exercise first: state the option, quantity, and expected cash impact (debit for calls, credit for puts), then wait for their affirmative reply before calling. The user's original request to exercise is NOT itself sufficient confirmation — a generic "exercise my calls" does not confirm a specific option and quantity. +Position requirements: get_option_positions must show type=long and quantity > 0. -Position requirements: confirm via get_option_positions that the position type=long and quantity > 0. +Account requirements: get_accounts must show agentic_allowed=true and option_level_2 or option_level_3. Non-agentic and option_level_0 accounts are rejected. -Account requirements: confirm via get_accounts that the chosen account is agentic_allowed=true AND has option_level_2 or option_level_3. If agentic_allowed=false do NOT call. If option_level is empty or option_level_0, do NOT call; follow the get_accounts guide for how to direct the user to enroll. - -Index options cannot be manually exercised and will be rejected. Exercises submitted during market hours execute the same day; requests submitted after market close — including on late-close trading days — are queued for overnight processing. +Index options cannot be manually exercised. Exercises submitted during market hours execute the same day; requests submitted after market close, including late-close trading days, are queued for overnight processing. Parameter rules: -- quantity must be a positive integer and cannot exceed the position's available contracts. -- allow_shorts=true only applies to PUT exercises where the account does not own enough shares to deliver. Require explicit user confirmation before setting this — it creates a short equity position in the underlying stock. -- reason is optional but recommended; collect it from the user when they volunteer a motivation. -- ref_id: use the same UUID on retries of the same logical exercise; use a new UUID for a new exercise. REAL-MONEY ACTION: use only after the user explicitly authorizes the exact account, instrument, side, size, order type, price constraints, and timing. Use the dedicated Agentic account and reuse one ref_id for retries. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must be agentic_allowed=true with option_level_2 or option_level_3."},option_id:{type:"string",description:"Option instrument UUID from get_option_positions or get_option_instruments. The position must be type=long."},quantity:{type:"integer",description:"Number of contracts to exercise (positive integer, minimum 1)."},ref_id:{type:"string",description:"Idempotency key (UUID). Generate once per logical exercise and re-send on retry. Omitting falls back to a server-generated key."},reason:{type:"string",description:"Optional exercise reason: covering_early_assignment | buying_stocks | not_enough_liquidity_or_spread_too_wide | hedging_position."},allow_shorts:{type:"boolean",description:"When true, allows a PUT exercise to proceed even when the account does not own enough shares to deliver — creating a short equity position. Requires explicit user confirmation that they intend to short the underlying stock. Default false."}},required:["account_number","option_id","quantity"],additionalProperties:!1}},{name:"follow_watchlist",namespace:"watchlists",description:"Follow a Robinhood-curated list so it appears in the user's watchlists. Confirm with the user before calling. Use only for curated lists; the user already owns their custom lists. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the Robinhood-curated list to follow. Obtain from get_popular_watchlists."}},required:["list_id"],additionalProperties:!1}},{name:"get_accounts",namespace:"account_portfolio",description:"List the user's brokerage accounts. Use this to look up account_number values needed by other tools. If the user has multiple accounts and hasn't specified which one, present the list and ask them to choose. Does NOT return reliable buying power — route buying-power questions through get_portfolio. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.",inputSchema:{type:"object",additionalProperties:!1}},{name:"get_earnings_calendar",namespace:"equity_market_data",description:'List earnings reports scheduled across the market over a date window (up to 31 days), optionally limited to high-market-cap names. Returns one entry per report event — estimated/actual EPS, report date and timing (am/pm), and company-verification status. Use this for market-wide discovery ("what large-caps report this week?"). For a specific known ticker, use get_earnings_results instead. Read-only. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.',inputSchema:{type:"object",properties:{start_date:{type:"string",description:"Window anchor, YYYY-MM-DD. Defaults to today (US/Eastern) when omitted."},days:{type:"integer",description:"Window length in days, measured from start_date. Defaults to 7. Positive = forward window (e.g. 7 = the next 7 days, inclusive of start_date); negative = look-back window (e.g. -7 = the 7 days ending at start_date). Must be a non-zero value between -31 and 31 — windows wider than 31 days are rejected."},filter:{type:"string",description:"Optional result filter. Set to 'high_market_cap' to limit the calendar to high-market-cap names (market cap over $1B) — useful for 'what large-caps report this week' style questions. Omit for all names."}},additionalProperties:!1}},{name:"get_earnings_results",namespace:"equity_market_data",description:'Get recent and upcoming earnings for ONE equity symbol — estimated/actual EPS, report date and timing (am/pm), and company-verification status. Returns the trailing up to 8 quarters. Use this for earnings-timing questions ("does AAPL report this week?"), EPS surprise analysis, and screening for upcoming earnings risk on a specific stock. For market-wide earnings calendar queries across many symbols, use get_earnings_calendar. Read-only. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.',inputSchema:{type:"object",properties:{symbol:{type:"string",description:"Stock symbol to look up (one symbol per call). Exact-ticker match — no name or partial-ticker resolution. Lowercase and whitespace-padded input is normalized to uppercase-trimmed before forwarding. Returns the trailing up to 8 quarters of earnings for the symbol."}},required:["symbol"],additionalProperties:!1}},{name:"get_equity_fundamentals",namespace:"equity_market_data",description:"Get today's fundamentals for one or more stock symbols — valuation ratios (PE, P/B), capitalization (market cap, shares outstanding, float), today's session OHLCV, trailing volume averages, 52-week range, dividend schedule, and company profile. For real-time quotes use get_equity_quotes; for time-series price history use get_equity_historicals. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols (max 10 per call). Exact-ticker match — no name or partial-ticker resolution. Lowercase and whitespace-padded input is normalized to uppercase-trimmed before forwarding."},bounds:{type:"string",description:"Trading session the day-level fields (open / high / low / volume / overnight_volume) are drawn from. One of 'regular' (regular trading hours), 'trading' (regular + post-market), 'extended' (pre-market + regular + post-market), '24_5' (24-hour, 5-day-trading-week). Does not affect valuation fields. overnight_volume only populates when bounds=24_5. Defaults to 'regular' when omitted."}},required:["symbols"],additionalProperties:!1}},{name:"get_equity_historicals",namespace:"equity_market_data",description:`Get OHLCV bars for one or more equity symbols across an explicit time range. Use this for charting, "recent activity" questions, and backtesting. The server auto-selects an interval when one is not provided. If the bar's interpolated field is true, bar was synthesized to fill a gap and carry no new information. +- quantity must be a positive integer no greater than the available contracts. +- allow_shorts=true applies only to put exercises when the account lacks enough shares to deliver; it creates a short equity position in the underlying stock. +- reason is an optional explanation for the exercise. +- ref_id must reuse the same UUID when retrying the same logical exercise and use a new UUID for a new exercise. + +Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must be agentic_allowed=true with option_level_2 or option_level_3."},option_id:{type:"string",description:"Option instrument UUID from get_option_positions or get_option_instruments. The position must be type=long."},quantity:{type:"integer",description:"Number of contracts to exercise (positive integer, minimum 1)."},ref_id:{type:"string",description:"Idempotency key (UUID). Generate once per logical exercise and re-send on retry. Omitting falls back to a server-generated key."},reason:{type:"string",description:"Optional exercise reason: covering_early_assignment | buying_stocks | not_enough_liquidity_or_spread_too_wide | hedging_position."},allow_shorts:{type:"boolean",description:"When true, allows a put exercise to proceed when the account does not own enough shares to deliver, creating a short equity position in the underlying stock. Default false."}},required:["account_number","option_id","quantity"],additionalProperties:!1}},{name:"follow_watchlist",namespace:"watchlists",description:"Follow a Robinhood-curated list so it appears in the user's watchlists. Use only for curated lists; custom lists are already owned by the user. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the Robinhood-curated list to follow. Obtain from get_popular_watchlists."}},required:["list_id"],additionalProperties:!1}},{name:"get_accounts",namespace:"account_portfolio",description:"List the user's brokerage accounts and return the account_number and capabilities needed by other tools. Does not return reliable buying power; use get_portfolio for buying power. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.",inputSchema:{type:"object",additionalProperties:!1}},{name:"get_earnings_calendar",namespace:"equity_market_data",description:'List earnings reports scheduled across the market over a date window (up to 31 days), optionally limited to high-market-cap names. Returns one entry per report event — estimated/actual EPS, report date and timing (am/pm), and company-verification status. Use this for market-wide discovery ("what large-caps report this week?"). For a specific known ticker, use get_earnings_results instead. Read-only. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.',inputSchema:{type:"object",properties:{start_date:{type:"string",description:"Window anchor, YYYY-MM-DD. Defaults to today (US/Eastern) when omitted."},days:{type:"integer",description:"Window length in days, measured from start_date. Defaults to 7. Positive = forward window (e.g. 7 = the next 7 days, inclusive of start_date); negative = look-back window (e.g. -7 = the 7 days ending at start_date). Must be a non-zero value between -31 and 31 — windows wider than 31 days are rejected."},filter:{type:"string",description:"Optional result filter. Set to 'high_market_cap' to limit the calendar to high-market-cap names (market cap over $1B) — useful for 'what large-caps report this week' style questions. Omit for all names."}},additionalProperties:!1}},{name:"get_earnings_results",namespace:"equity_market_data",description:'Get recent and upcoming earnings for ONE equity symbol — estimated/actual EPS, report date and timing (am/pm), and company-verification status. Returns the trailing up to 8 quarters. Use this for earnings-timing questions ("does AAPL report this week?"), EPS surprise analysis, and screening for upcoming earnings risk on a specific stock. For market-wide earnings calendar queries across many symbols, use get_earnings_calendar. Read-only. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.',inputSchema:{type:"object",properties:{symbol:{type:"string",description:"Stock symbol to look up (one symbol per call). Exact-ticker match — no name or partial-ticker resolution. Lowercase and whitespace-padded input is normalized to uppercase-trimmed before forwarding. Returns the trailing up to 8 quarters of earnings for the symbol."}},required:["symbol"],additionalProperties:!1}},{name:"get_equity_fundamentals",namespace:"equity_market_data",description:"Get today's fundamentals for one or more stock symbols — valuation ratios (PE, P/B), capitalization (market cap, shares outstanding, float), today's session OHLCV, trailing volume averages, 52-week range, dividend schedule, and company profile. For real-time quotes use get_equity_quotes; for time-series price history use get_equity_historicals. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols (max 10 per call). Exact-ticker match — no name or partial-ticker resolution. Lowercase and whitespace-padded input is normalized to uppercase-trimmed before forwarding."},bounds:{type:"string",description:"Trading session the day-level fields (open / high / low / volume / overnight_volume) are drawn from. One of 'regular' (regular trading hours), 'trading' (regular + post-market), 'extended' (pre-market + regular + post-market), '24_5' (24-hour, 5-day-trading-week). Does not affect valuation fields. overnight_volume only populates when bounds=24_5. Defaults to 'regular' when omitted."}},required:["symbols"],additionalProperties:!1}},{name:"get_equity_historicals",namespace:"equity_market_data",description:`Get OHLCV bars for one or more equity symbols across an explicit time range. Use this for charting, "recent activity" questions, and backtesting. The server auto-selects an interval when one is not provided. If the bar's interpolated field is true, bar was synthesized to fill a gap and carry no new information. Parameter rules: - interval is optional; when omitted, the server auto-selects an interval that targets ~2,500 bars across the requested range. Provide an explicit interval only when you need a specific granularity. @@ -45,7 +45,7 @@ Parameter rules: Filtering tips: - Prefer narrow queries: combine state, symbol, and/or created_at_gte for specific questions (e.g. "my filled AAPL orders this week") — the per-page cap is fixed. - created_at_gte: interpret relative times in the user's timezone, convert to UTC before sending. -- symbol forces a symbol→instrument lookup; omit it if you don't need it. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts."},order_id:{type:"string",description:"Filter to a single order by UUID. The response shape is unchanged (orders[] with at most one entry); empty when the order does not belong to account_number."},state:{type:"string",description:"Filter by single state: new, queued, confirmed, unconfirmed, partially_filled, filled, cancelled, rejected, failed, voided."},symbol:{type:"string",description:"Filter to one symbol (triggers a symbol→instrument lookup before the orders call)."},created_at_gte:{type:"string",description:"Lower bound (inclusive). ISO 8601 UTC or YYYY-MM-DD; naive values are interpreted as UTC."},placed_agent:{type:"string",description:"Filter to one source: 'user', 'agentic' (MCP), 'recurring', 'drip', etc."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number"],additionalProperties:!1}},{name:"get_equity_positions",namespace:"equity_trading",description:"List open equity positions for a specific brokerage account. Returns symbol, quantity, average cost, and per-position hold breakdowns. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number"],additionalProperties:!1}},{name:"get_equity_price_book",namespace:"equity_market_data",description:"Get a real-time bid/ask order book (Level 2) snapshot for one or more equity symbols (max 4), showing the ladder of price levels and resting share size on each side. Use to read supply/demand depth before entering or exiting a position. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols, max 4 per call."}},required:["symbols"],additionalProperties:!1}},{name:"get_equity_quotes",namespace:"equity_market_data",description:"Get real-time stock quotes and the official last-completed-session close for one or more symbols. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols. Above 20 symbols, quotes still return but closes is omitted with closes_error set."}},required:["symbols"],additionalProperties:!1}},{name:"get_equity_tax_lots",namespace:"equity_trading",description:"List the open tax lots for one equity holding in an account — each lot is a separate acquisition with its own quantity, cost basis, acquisition date, and long/short-term status. Requires a symbol (tax lots are tracked per instrument). Use it for cost-basis, holding-period, or which-lots-would-sell questions. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts."},symbol:{type:"string",description:"Ticker symbol of the holding whose tax lots you want, e.g. AAPL. Tax lots are tracked per instrument — one symbol per call."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number","symbol"],additionalProperties:!1}},{name:"get_equity_technical_indicators",namespace:"equity_market_data",description:`Compute a technical indicator (RSI, MACD, Bollinger Bands, moving averages, ATR, VWAP, and more) over one equity symbol's OHLCV bars across a time range. For the raw OHLCV bars themselves, use get_equity_historicals. +- symbol forces a symbol→instrument lookup; omit it if you don't need it. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number from get_accounts."},order_id:{type:"string",description:"Filter to a single order by UUID. The response shape is unchanged (orders[] with at most one entry); empty when the order does not belong to account_number."},state:{type:"string",description:"Filter by single state: new, queued, confirmed, unconfirmed, partially_filled, filled, cancelled, rejected, failed, voided."},symbol:{type:"string",description:"Filter to one symbol (triggers a symbol→instrument lookup before the orders call)."},created_at_gte:{type:"string",description:"Lower bound (inclusive). ISO 8601 UTC or YYYY-MM-DD; naive values are interpreted as UTC."},placed_agent:{type:"string",description:"Filter to one source: 'user', 'agentic' (MCP), 'recurring', 'drip', etc."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number"],additionalProperties:!1}},{name:"get_equity_positions",namespace:"equity_trading",description:"List open equity positions for a specific brokerage account. Returns symbol, quantity, average cost, and per-position hold breakdowns. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number from get_accounts."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number"],additionalProperties:!1}},{name:"get_equity_price_book",namespace:"equity_market_data",description:"Get a real-time bid/ask order book (Level 2) snapshot for one or more equity symbols (max 4), showing the ladder of price levels and resting share size on each side. Use to read supply/demand depth before entering or exiting a position. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols, max 4 per call."}},required:["symbols"],additionalProperties:!1}},{name:"get_equity_quotes",namespace:"equity_market_data",description:"Get real-time stock quotes and the official last-completed-session close for one or more symbols. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols. Above 20 symbols, quotes still return but closes is omitted with closes_error set."}},required:["symbols"],additionalProperties:!1}},{name:"get_equity_tax_lots",namespace:"equity_trading",description:"List the open tax lots for one equity holding in an account — each lot is a separate acquisition with its own quantity, cost basis, acquisition date, and long/short-term status. Requires a symbol (tax lots are tracked per instrument). Use it for cost-basis, holding-period, or which-lots-would-sell questions. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number from get_accounts."},symbol:{type:"string",description:"Ticker symbol of the holding whose tax lots you want, e.g. AAPL. Tax lots are tracked per instrument — one symbol per call."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number","symbol"],additionalProperties:!1}},{name:"get_equity_technical_indicators",namespace:"equity_market_data",description:`Compute a technical indicator (RSI, MACD, Bollinger Bands, moving averages, ATR, VWAP, and more) over one equity symbol's OHLCV bars across a time range. For the raw OHLCV bars themselves, use get_equity_historicals. Parameter rules: - The parameters an indicator accepts depend on type: @@ -59,7 +59,7 @@ Parameter rules: Omit a parameter to use its default. Passing a parameter the chosen type does not accept is rejected. - interval is REQUIRED — indicator periods are counted in bars, so there is no auto-selection. - adjustment_type defaults to 'split'; 'all' (split + dividend) requires a day-or-coarser interval. -- If the requested range plus the indicator's warm-up exceeds the per-request bar cap, narrow the range or coarsen the interval. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{symbol:{type:"string",description:"Stock symbol (uppercase). Exactly one symbol per call."},type:{type:"string",description:"Indicator to compute. One of: ema, sma, rsi, momentum, roc, cci, williams_r, atr, mfi, adx, donchian_channels, bollinger_bands, macd, keltner_channels, supertrend, vwap, obv, pivot_points."},interval:{type:"string",description:"Required bar interval the indicator is computed on. Intraday: 15second, 30second, minute, 5minute, 10minute, 30minute, hour, 4hour. Interday: day, week, month, 3month, 6month, year, 5year, 10year, 20year, 50year. The 1-minute bar is named 'minute' (not '1minute')."},start_time:{type:"string",description:"Start of the range (RFC3339 UTC, e.g. '2026-01-01T00:00:00Z'). Required."},end_time:{type:"string",description:"End of the range (RFC3339 UTC). Optional — defaults to the current time when omitted."},bounds:{type:"string",description:"Session bounds. One of 'regular' (RTH, default) or 'extended'."},adjustment_type:{type:"string",description:"Corporate-action adjustment: 'none' (raw prices), 'split' (default), or 'all' (split + dividend; requires a day-or-coarser interval)."},output:{type:"string",description:"How much of the series to return: 'series' (default, full range), 'latest' (most recent bar only), or 'last:N' (most recent N bars). The indicator is always computed over the full range first; this only trims the response."},period:{type:["null","integer"],description:"Lookback period in bars. Applies to ema, sma, rsi, momentum, roc, cci, williams_r, atr, mfi, adx, donchian_channels, bollinger_bands, keltner_channels, supertrend. Omit to use the indicator's default."},num_std:{type:["null","number"],description:"Number of standard deviations for the bands. bollinger_bands only (default 2)."},fast_period:{type:["null","integer"],description:"Fast EMA period. macd only (default 12)."},slow_period:{type:["null","integer"],description:"Slow EMA period. macd only (default 26)."},signal_period:{type:["null","integer"],description:"Signal EMA period. macd only (default 9)."},multiplier:{type:["null","number"],description:"Band/offset multiplier. keltner_channels (default 2) and supertrend (default 3) only."},method:{type:"string",description:"Calculation method. pivot_points only; currently only 'classic'."}},required:["symbol","type","interval","start_time"],additionalProperties:!1}},{name:"get_equity_tradability",namespace:"equity_trading",description:"Check tradability for up to 10 equity symbols on a given account: per-session eligibility and fractional. Call before placing an order to surface restrictions. Exact-ticker match — no name or partial-ticker resolution. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts."},symbols:{type:["null","array"],items:{type:"string"},description:"Stock symbols, max 10 per call. With more than 10, split across multiple calls of 10 or fewer. Exact-ticker match only."}},required:["account_number","symbols"],additionalProperties:!1}},{name:"get_financials",namespace:"equity_market_data",description:"Get a company's reported financial metrics over time — revenue, gross profit, net income, and net margin — by fiscal period (annual or quarterly), for one or more symbols. Use this for fundamental analysis like revenue-growth and margin-trend tracking, profitability screens, and period-over-period comparisons. Read-only. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols (max 20 per call). Exact-ticker match — no name or partial-ticker resolution. Lowercase and whitespace-padded input is normalized to uppercase-trimmed before forwarding."},period:{type:"string",description:"Reporting period: 'quarterly' or 'annual'. Defaults to 'quarterly' when omitted."},limit:{type:"integer",description:"Number of most-recent periods to return per symbol (e.g. 8 for the last 8 quarters or years). Defaults to 4; values above 40 are capped to 40."}},required:["symbols"],additionalProperties:!1}},{name:"get_index_historicals",namespace:"indexes",description:`Get OHLC value bars for one or more market indexes (by instrument UUID) across an explicit time range. Use this for charting an index's history and "recent movement" questions. If the bar's interpolated field is true, bar was synthesized to fill a gap and carry no new information. +- If the requested range plus the indicator's warm-up exceeds the per-request bar cap, narrow the range or coarsen the interval. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{symbol:{type:"string",description:"Stock symbol (uppercase). Exactly one symbol per call."},type:{type:"string",description:"Indicator to compute. One of: ema, sma, rsi, momentum, roc, cci, williams_r, atr, mfi, adx, donchian_channels, bollinger_bands, macd, keltner_channels, supertrend, vwap, obv, pivot_points."},interval:{type:"string",description:"Required bar interval the indicator is computed on. Intraday: 15second, 30second, minute, 5minute, 10minute, 30minute, hour, 4hour. Interday: day, week, month, 3month, 6month, year, 5year, 10year, 20year, 50year. The 1-minute bar is named 'minute' (not '1minute')."},start_time:{type:"string",description:"Start of the range (RFC3339 UTC, e.g. '2026-01-01T00:00:00Z'). Required."},end_time:{type:"string",description:"End of the range (RFC3339 UTC). Optional — defaults to the current time when omitted."},bounds:{type:"string",description:"Session bounds. One of 'regular' (RTH, default) or 'extended'."},adjustment_type:{type:"string",description:"Corporate-action adjustment: 'none' (raw prices), 'split' (default), or 'all' (split + dividend; requires a day-or-coarser interval)."},output:{type:"string",description:"How much of the series to return: 'series' (default, full range), 'latest' (most recent bar only), or 'last:N' (most recent N bars). The indicator is always computed over the full range first; this only trims the response."},period:{type:["null","integer"],description:"Lookback period in bars. Applies to ema, sma, rsi, momentum, roc, cci, williams_r, atr, mfi, adx, donchian_channels, bollinger_bands, keltner_channels, supertrend. Omit to use the indicator's default."},num_std:{type:["null","number"],description:"Number of standard deviations for the bands. bollinger_bands only (default 2)."},fast_period:{type:["null","integer"],description:"Fast EMA period. macd only (default 12)."},slow_period:{type:["null","integer"],description:"Slow EMA period. macd only (default 26)."},signal_period:{type:["null","integer"],description:"Signal EMA period. macd only (default 9)."},multiplier:{type:["null","number"],description:"Band/offset multiplier. keltner_channels (default 2) and supertrend (default 3) only."},method:{type:"string",description:"Calculation method. pivot_points only; currently only 'classic'."}},required:["symbol","type","interval","start_time"],additionalProperties:!1}},{name:"get_equity_tradability",namespace:"equity_trading",description:"Check tradability for up to 10 equity symbols on a given account: per-session eligibility and fractional. Call before placing an order to surface restrictions. Exact-ticker match — no name or partial-ticker resolution. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number from get_accounts."},symbols:{type:["null","array"],items:{type:"string"},description:"Stock symbols, max 10 per call. With more than 10, split across multiple calls of 10 or fewer. Exact-ticker match only."}},required:["account_number","symbols"],additionalProperties:!1}},{name:"get_financials",namespace:"equity_market_data",description:"Get a company's reported financial metrics over time — revenue, gross profit, net income, and net margin — by fiscal period (annual or quarterly), for one or more symbols. Use this for fundamental analysis like revenue-growth and margin-trend tracking, profitability screens, and period-over-period comparisons. Read-only. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols (max 20 per call). Exact-ticker match — no name or partial-ticker resolution. Lowercase and whitespace-padded input is normalized to uppercase-trimmed before forwarding."},period:{type:"string",description:"Reporting period: 'quarterly' or 'annual'. Defaults to 'quarterly' when omitted."},limit:{type:"integer",description:"Number of most-recent periods to return per symbol (e.g. 8 for the last 8 quarters or years). Defaults to 4; values above 40 are capped to 40."}},required:["symbols"],additionalProperties:!1}},{name:"get_index_historicals",namespace:"indexes",description:`Get OHLC value bars for one or more market indexes (by instrument UUID) across an explicit time range. Use this for charting an index's history and "recent movement" questions. If the bar's interpolated field is true, bar was synthesized to fill a gap and carry no new information. Parameter rules: - instrument_ids are index instrument UUIDs from get_indexes. Resolve symbols there first; this tool does not accept ticker symbols. @@ -75,77 +75,74 @@ Parameter rules: Filtering tips: - Prefer narrow queries: combine state and/or created_at_gte for specific questions — the per-page cap is fixed. - chain_ids filters by underlying chain UUID (from get_option_chains). -- created_at_gte: interpret relative times in the user's timezone, convert to UTC before sending. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts."},order_id:{type:"string",description:"Filter to a single order by UUID. The response shape is unchanged (orders[] with at most one entry); empty when the order does not belong to account_number."},state:{type:"string",description:"Filter by single state: queued, confirmed, partially_filled, filled, rejected, cancelled, failed, voided, pending_cancelled."},created_at_gte:{type:"string",description:"Lower bound (inclusive). ISO 8601 UTC or YYYY-MM-DD; naive values are interpreted as UTC."},chain_ids:{type:"string",description:"Comma-separated chain UUIDs (from get_option_chains) to filter by underlying."},underlying_type:{type:"string",description:"'equity' or 'index'."},placed_agent:{type:"string",description:"Filter to one source: 'user', 'agentic' (MCP), 'recurring', 'drip', etc."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number"],additionalProperties:!1}},{name:"get_option_positions",namespace:"option_trading",description:'List options positions for an account. Returns open and closed (zero-quantity) positions. Pass nonzero=true for "what options do I have" / "show me my positions" — the common case. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.',inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts."},nonzero:{type:"boolean",description:"True to return only currently-open positions; omit/false to include closed ones."},chain_ids:{type:"string",description:"Comma-separated chain UUIDs (from get_option_chains)."},option_ids:{type:"string",description:"Comma-separated instrument UUIDs."},type:{type:"string",description:"'long' or 'short'."},option_type:{type:"string",description:"'call' or 'put'."},expiration_date:{type:"string",description:"Exact expiration (YYYY-MM-DD)."},expiration_date_lte:{type:"string",description:"Upper bound on expiration (YYYY-MM-DD)."},expiration_date_gte:{type:"string",description:"Lower bound on expiration (YYYY-MM-DD)."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number"],additionalProperties:!1}},{name:"get_option_quotes",namespace:"option_market_data",description:"Get real-time quotes for one or more option contracts by instrument UUID, plus the official prior-session close for each. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{instrument_ids:{type:["null","array"],items:{type:"string"},description:"Option instrument UUIDs. Above 20, quotes still return but closes is omitted with closes_error set."}},required:["instrument_ids"],additionalProperties:!1}},{name:"get_option_watchlist",namespace:"option_market_data",description:"List the single-leg option contracts on the user's options watchlist. Use this instead of get_watchlist_items for the options watchlist — get_watchlist_items returns a generic shape that drops the option-specific title and the upstream rejects it with 400 anyway. Works for both equity options (AAPL, NVDA) and index options (SPX, NDX, RUT). Multi-leg strategies (verticals, condors, etc.) that may exist in the user's watchlist from app-side order placement are not shown — direct the user to the Robinhood app to view those. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",additionalProperties:!1}},{name:"get_pnl_trade_history",namespace:"account_portfolio",description:`Get a customer's per-trade realized profit & loss — a chronological, paginated list of closed/realizing trades (equities, options, crypto, prediction markets) with symbol, side, quantity, price, and realized gain/loss. This is the same data behind the app's PnL hub ("Realized profit & loss"). Read-only. Trades only. Use get_realized_pnl for aggregate/bucketed totals. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number (the rhs_account_number from get_accounts). Obtain it from get_accounts."},span:{type:"string",description:"Preset window: week (default), month, 3month, ytd, or all. Wormhole offers preset spans only (no arbitrary date range)."},symbol:{type:"string",description:"Optional single stock symbol filter (trimmed + uppercased). Omit for all symbols; one symbol per call."},cursor:{type:"string",description:"Pagination cursor from a previous response's next_cursor. Omit for the first page."}},required:["account_number"],additionalProperties:!1}},{name:"get_popular_watchlists",namespace:"watchlists",description:"Discover Robinhood-curated lists the user can follow (e.g. '100 Most Popular', 'Daily Movers'). Use to find a list_id, then pass it to follow_watchlist. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",additionalProperties:!1}},{name:"get_portfolio",namespace:"account_portfolio",description:`Get the account's portfolio market value breakdown by asset type and buying power. Use for "how much is my account worth?", "what's my portfolio breakdown?", "how much do I have in options?", and "how much can I spend / afford?" questions. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Obtain from get_accounts."}},required:["account_number"],additionalProperties:!1}},{name:"get_realized_pnl",namespace:"account_portfolio",description:`Get a customer's realized profit & loss for an account over a time window — per-bucket realized gain ($ and %) and the number of closing trades, plus window totals. Read-only. Aggregate, bucketed numbers only (not individual trades). Use for post-trade analysis like "how did my last 90 days of trades do?". Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number (the rhs_account_number from get_accounts). Obtain it from get_accounts."},span:{type:"string",description:"Preset window: day, week, month, 3month, year, or all. Defaults to 3month ('last 90 days'). Mutually exclusive with start_date/end_date."},start_date:{type:"string",description:"Custom window start, YYYY-MM-DD, inclusive — interpreted at midnight in timezone (default US Eastern). Use with end_date instead of span; must be on or before end_date and not in the future."},end_date:{type:"string",description:"Custom window end, YYYY-MM-DD, inclusive — the entire end_date is covered (through 23:59:59 in timezone). Use with start_date instead of span; an end_date beyond today returns data through the present."},asset_classes:{type:["null","array"],items:{type:"string"},description:"Filter to one or more of equity, option, crypto. Omit for all asset classes available on the account."},display_currency:{type:"string",description:"Currency for returned amounts. Currently USD only; defaults to USD."},timezone:{type:"string",description:"IANA timezone for bucket day-boundaries (e.g. America/New_York). Defaults to the account timezone (US Eastern)."}},required:["account_number"],additionalProperties:!1}},{name:"get_scanner_filter_specs",namespace:"scanners",description:`List every valid scanner filter type and how to use it. Call this before constructing filters for create_scan or update_scan_filters — do not guess filter_type names. +- created_at_gte: interpret relative times in the user's timezone, convert to UTC before sending. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number from get_accounts."},order_id:{type:"string",description:"Filter to a single order by UUID. The response shape is unchanged (orders[] with at most one entry); empty when the order does not belong to account_number."},state:{type:"string",description:"Filter by single state: queued, confirmed, partially_filled, filled, rejected, cancelled, failed, voided, pending_cancelled."},created_at_gte:{type:"string",description:"Lower bound (inclusive). ISO 8601 UTC or YYYY-MM-DD; naive values are interpreted as UTC."},chain_ids:{type:"string",description:"Comma-separated chain UUIDs (from get_option_chains) to filter by underlying."},underlying_type:{type:"string",description:"'equity' or 'index'."},placed_agent:{type:"string",description:"Filter to one source: 'user', 'agentic' (MCP), 'recurring', 'drip', etc."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number"],additionalProperties:!1}},{name:"get_option_positions",namespace:"option_trading",description:'List options positions for an account. Returns open and closed (zero-quantity) positions. Pass nonzero=true for "what options do I have" / "show me my positions" — the common case. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.',inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number from get_accounts."},nonzero:{type:"boolean",description:"True to return only currently-open positions; omit/false to include closed ones."},chain_ids:{type:"string",description:"Comma-separated chain UUIDs (from get_option_chains)."},option_ids:{type:"string",description:"Comma-separated instrument UUIDs."},type:{type:"string",description:"'long' or 'short'."},option_type:{type:"string",description:"'call' or 'put'."},expiration_date:{type:"string",description:"Exact expiration (YYYY-MM-DD)."},expiration_date_lte:{type:"string",description:"Upper bound on expiration (YYYY-MM-DD)."},expiration_date_gte:{type:"string",description:"Lower bound on expiration (YYYY-MM-DD)."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},required:["account_number"],additionalProperties:!1}},{name:"get_option_quotes",namespace:"option_market_data",description:"Get real-time quotes for one or more option contracts by instrument UUID, plus the official prior-session close for each. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{instrument_ids:{type:["null","array"],items:{type:"string"},description:"Option instrument UUIDs. Above 20, quotes still return but closes is omitted with closes_error set."}},required:["instrument_ids"],additionalProperties:!1}},{name:"get_option_watchlist",namespace:"option_market_data",description:"List the single-leg option contracts on the user's options watchlist. Use this instead of get_watchlist_items for the options watchlist — get_watchlist_items returns a generic shape that drops the option-specific title and the upstream rejects it with 400 anyway. Works for both equity options (AAPL, NVDA) and index options (SPX, NDX, RUT). Multi-leg strategies (verticals, condors, etc.) that may exist in the user's watchlist from app-side order placement are not shown — direct the user to the Robinhood app to view those. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",additionalProperties:!1}},{name:"get_pnl_trade_history",namespace:"account_portfolio",description:`Get a customer's per-trade realized profit & loss — a chronological, paginated list of closed/realizing trades (equities, options, crypto, prediction markets) with symbol, side, quantity, price, and realized gain/loss. This is the same data behind the app's PnL hub ("Realized profit & loss"). Read-only. Trades only. Use get_realized_pnl for aggregate/bucketed totals. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number (the rhs_account_number from get_accounts). Obtain it from get_accounts."},span:{type:"string",description:"Preset window: week (default), month, 3month, ytd, or all. Wormhole offers preset spans only (no arbitrary date range)."},symbol:{type:"string",description:"Optional single stock symbol filter (trimmed + uppercased). Omit for all symbols; one symbol per call."},cursor:{type:"string",description:"Pagination cursor from a previous response's next_cursor. Omit for the first page."}},required:["account_number"],additionalProperties:!1}},{name:"get_popular_watchlists",namespace:"watchlists",description:"Discover Robinhood-curated lists the user can follow (e.g. '100 Most Popular', 'Daily Movers'). Use to find a list_id, then pass it to follow_watchlist. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",additionalProperties:!1}},{name:"get_portfolio",namespace:"account_portfolio",description:`Get the account's portfolio market value breakdown by asset type and buying power. Use for "how much is my account worth?", "what's my portfolio breakdown?", "how much do I have in options?", and "how much can I spend / afford?" questions. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Obtain from get_accounts."}},required:["account_number"],additionalProperties:!1}},{name:"get_realized_pnl",namespace:"account_portfolio",description:`Get a customer's realized profit & loss for an account over a time window — per-bucket realized gain ($ and %) and the number of closing trades, plus window totals. Read-only. Aggregate, bucketed numbers only (not individual trades). Use for post-trade analysis like "how did my last 90 days of trades do?". Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number (the rhs_account_number from get_accounts). Obtain it from get_accounts."},span:{type:"string",description:"Preset window: day, week, month, 3month, year, or all. Defaults to 3month ('last 90 days'). Mutually exclusive with start_date/end_date."},start_date:{type:"string",description:"Custom window start, YYYY-MM-DD, inclusive — interpreted at midnight in timezone (default US Eastern). Use with end_date instead of span; must be on or before end_date and not in the future."},end_date:{type:"string",description:"Custom window end, YYYY-MM-DD, inclusive — the entire end_date is covered (through 23:59:59 in timezone). Use with start_date instead of span; an end_date beyond today returns data through the present."},asset_classes:{type:["null","array"],items:{type:"string"},description:"Filter to one or more of equity, option, crypto. Omit for all asset classes available on the account."},display_currency:{type:"string",description:"Currency for returned amounts. Currently USD only; defaults to USD."},timezone:{type:"string",description:"IANA timezone for bucket day-boundaries (e.g. America/New_York). Defaults to the account timezone (US Eastern)."}},required:["account_number"],additionalProperties:!1}},{name:"get_scanner_filter_specs",namespace:"scanners",description:`List every valid scanner filter type and how to use it. Call this before constructing filters for create_scan or update_scan_filters — do not guess filter_type names. This tool takes no parameters. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",additionalProperties:!1}},{name:"get_scans",namespace:"scanners",description:`List the authenticated user's saved scanners (also called screeners). A scan is a saved set of filters and columns that filters the market for instruments matching specific criteria (e.g. "RSI > 70 and Volume > 1M"). The user creates these in Legend or via the create_scan tool. Returns one entry per scan with its id, title, active filters, configured columns, sort order, and a flag indicating whether the scan is managed by Cortex (Legend's AI agent). Cortex-managed scans are read-only via MCP — they can be run with run_scan but not modified with update_scan_filters or update_scan_config. -This tool takes no parameters. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",additionalProperties:!1}},{name:"get_watchlist_items",namespace:"watchlists",description:"List the items in a watchlist. Items may be stocks/ETFs, crypto pairs, futures, indexes — distinguished by object_type. For the options watchlist, use get_option_watchlist instead — this tool returns a generic shape that drops the strategy-specific fields and the upstream rejects it with 400 anyway. Does not return live prices; call get_quotes with the symbol(s) for that. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist whose items to fetch. Obtain from get_watchlists or get_popular_watchlists."}},required:["list_id"],additionalProperties:!1}},{name:"get_watchlists",namespace:"watchlists",description:"List the user's watchlists, including both user-created custom lists and Robinhood-curated lists the user follows. Use to look up list_id values for other watchlist tools. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",additionalProperties:!1}},{name:"place_equity_order",namespace:"equity_trading",description:`Place a real equity order with real money. Parameters mirror review_equity_order plus the optional ref_id. Requires an agentic_allowed=true account; non-agentic accounts are rejected — do not call. +This tool takes no parameters. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",additionalProperties:!1}},{name:"get_watchlist_items",namespace:"watchlists",description:"List the items in a watchlist. Items may be stocks/ETFs, crypto pairs, futures, indexes — distinguished by object_type. For the options watchlist, use get_option_watchlist instead — this tool returns a generic shape that drops the strategy-specific fields and the upstream rejects it with 400 anyway. Does not return live prices; call get_quotes with the symbol(s) for that. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist whose items to fetch. Obtain from get_watchlists or get_popular_watchlists."}},required:["list_id"],additionalProperties:!1}},{name:"get_watchlists",namespace:"watchlists",description:"List the user's watchlists, including both user-created custom lists and Robinhood-curated lists the user follows. Use to look up list_id values for other watchlist tools. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",additionalProperties:!1}},{name:"place_equity_order",namespace:"equity_trading",description:`Place a real equity order with real money. Parameters mirror review_equity_order plus the optional ref_id. Requires an agentic_allowed=true account; non-agentic accounts are rejected. -Workflow: by default call review_equity_order first, present the estimated cost and any alerts, and get explicit user confirmation before calling this tool. Skip review only when the user has very explicitly asked to bypass it (e.g. "skip the review", "just place it, don't review") — a generic "place this order" is NOT a bypass. +Call review_equity_order first to obtain the current quote, estimated cost, and pre-trade alerts. -Idempotency: pass a fresh UUID as ref_id on the first call for each logical order, and re-send the SAME ref_id on retries of transient transport failures. Use a new ref_id only when the user wants a new order. +Idempotency: pass a fresh UUID as ref_id on the first call for each logical order and re-send the same ref_id after a transient transport failure. Use a new ref_id only for a new logical order. Parameter rules: -- If the user has not specified type, ask. For immediate fills with price protection, prefer a marketable limit at the current ask over a plain market. -- Outside regular hours, only limit orders execute. For an immediate fill during extended or overnight/24-hour sessions, place a limit order (a marketable limit at the current ask) with market_hours set to that session — not a market order. Market and stop orders are regular_hours-only; placed after hours as regular_hours they queue for the next regular open. -- Provide exactly one of quantity or dollar_amount; dollar_amount requires type=market (server computes shares from last_trade_price). -- Fractional shares: only on type=market with market_hours=regular_hours, eligible accounts, up to 6 decimal places, no short sells. -- limit_price required for limit/stop_limit; stop_price required for stop_market/stop_limit. -- Fractional and dollar-based orders only place in regular_hours; the tool rejects them in other sessions. -- tax_lots (specified-lot selling, sell only): to sell specific lots, first call get_equity_tax_lots for the symbol, then pass tax_lots as {open_lot_id, quantity} pairs whose quantities sum to the order quantity. Omit for default (FIFO) cost basis. US accounts only; not allowed with dollar_amount, stop orders, all_day_hours, or fractional limit orders. REAL-MONEY ACTION: use only after the user explicitly authorizes the exact account, instrument, side, size, order type, price constraints, and timing. Use the dedicated Agentic account and reuse one ref_id for retries. After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true; non-agentic accounts are rejected."},symbol:{type:"string",description:"Stock symbol."},side:{type:"string",description:"'buy' or 'sell'."},type:{type:"string",description:"'market', 'limit', 'stop_market', or 'stop_limit'."},quantity:{type:"string",description:"Number of shares. Decimals (fractional) allowed for market + regular_hours only."},dollar_amount:{type:"string",description:"USD notional (e.g. '100.00'). Only valid with type=market."},limit_price:{type:"string",description:"Limit price; required for limit or stop_limit."},stop_price:{type:"string",description:"Stop trigger price; required for stop_market or stop_limit."},time_in_force:{type:"string",description:"'gfd' or 'gtc'. Default: gfd."},market_hours:{type:"string",description:"'regular_hours' (default, 9:30–16:00 ET), 'extended_hours' (pre-/post-market), or 'all_day_hours' (the 24 Hour Market / overnight session). extended_hours and all_day_hours execute limit orders only — market, stop_market, and stop_limit are regular_hours-only and are rejected if tagged to another session."},tax_lots:{type:["null","array"],items:{type:"object",properties:{open_lot_id:{type:"string",description:"open_lot_id of the open tax lot to sell, from get_equity_tax_lots."},quantity:{type:"string",description:"Shares to sell from this lot as a decimal string; at most the lot's quantity_available."}},required:["open_lot_id","quantity"],additionalProperties:!1},description:"Optional specified-lot selection for a SELL order. To sell specific tax lots instead of the default FIFO cost basis, pass the exact lots as {open_lot_id, quantity} objects, where open_lot_id comes from get_equity_tax_lots and the quantities sum to the order quantity. Omit for default FIFO. Sell only; at most 30 lots; US accounts only. Not allowed with dollar_amount, stop_market/stop_limit, all_day_hours, or fractional-share limit orders."},ref_id:{type:"string",description:"Idempotency key (UUID). Generate once per logical order and re-send on retry — the upstream deduplicates by ref_id. Omitting falls back to a server-generated key (loses client↔gateway idempotency)."}},required:["account_number","symbol","side","type"],additionalProperties:!1}},{name:"place_option_order",namespace:"option_trading",description:`Place a real options order with real money. - -Workflow: by default call review_option_order first, present the alerts, fees, collateral, and quote, and get explicit user confirmation before calling this tool. Skip review only when the user has very explicitly asked to bypass it (e.g. "skip the review", "just place it, don't review") — a generic "place this order" is NOT a bypass. +- For immediate fills with price protection, prefer a marketable limit at the current ask over a plain market. +- Outside regular hours, only limit orders execute. For an immediate fill during extended or overnight/24-hour sessions, place a limit order with market_hours set to that session. Market and stop orders are regular_hours-only; regular-hours orders placed after hours queue for the next regular open. +- Provide exactly one of quantity or dollar_amount; dollar_amount requires type=market. +- Fractional shares are supported only for type=market with market_hours=regular_hours on eligible accounts, up to 6 decimal places, with no short sells. +- limit_price is required for limit and stop_limit; stop_price is required for stop_market and stop_limit. +- Fractional and dollar-based orders are regular-hours only. +- tax_lots is sell-only specified-lot selection. Obtain open_lot_id values from get_equity_tax_lots and pass quantities that sum to the order quantity. It is limited to US accounts and cannot be combined with dollar_amount, stop orders, all_day_hours, or fractional limit orders. -Capability: single-leg options orders — Level 2 strategies (covered calls, cash-secured puts, long calls and puts). Multi-leg spreads (Level 3 strategies) are supported on option_level_3 accounts. +After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number from get_accounts. Must be agentic_allowed=true; non-agentic accounts are rejected."},symbol:{type:"string",description:"Stock symbol."},side:{type:"string",description:"'buy' or 'sell'."},type:{type:"string",description:"'market', 'limit', 'stop_market', or 'stop_limit'."},quantity:{type:"string",description:"Number of shares. Decimals (fractional) allowed for market + regular_hours only."},dollar_amount:{type:"string",description:"USD notional (e.g. '100.00'). Only valid with type=market."},limit_price:{type:"string",description:"Limit price; required for limit or stop_limit."},stop_price:{type:"string",description:"Stop trigger price; required for stop_market or stop_limit."},time_in_force:{type:"string",description:"'gfd' or 'gtc'. Default: gfd."},market_hours:{type:"string",description:"'regular_hours' (default, 9:30–16:00 ET), 'extended_hours' (pre-/post-market), or 'all_day_hours' (the 24 Hour Market / overnight session). extended_hours and all_day_hours execute limit orders only — market, stop_market, and stop_limit are regular_hours-only and are rejected if tagged to another session."},tax_lots:{type:["null","array"],items:{type:"object",properties:{open_lot_id:{type:"string",description:"open_lot_id of the open tax lot to sell, from get_equity_tax_lots."},quantity:{type:"string",description:"Shares to sell from this lot as a decimal string; at most the lot's quantity_available."}},required:["open_lot_id","quantity"],additionalProperties:!1},description:"Optional specified-lot selection for a SELL order. To sell specific tax lots instead of the default FIFO cost basis, pass the exact lots as {open_lot_id, quantity} objects, where open_lot_id comes from get_equity_tax_lots and the quantities sum to the order quantity. Omit for default FIFO. Sell only; at most 30 lots; US accounts only. Not allowed with dollar_amount, stop_market/stop_limit, all_day_hours, or fractional-share limit orders."},ref_id:{type:"string",description:"Idempotency key (UUID). Generate once per logical order and re-send on retry — the upstream deduplicates by ref_id. Omitting falls back to a server-generated key (loses client↔gateway idempotency)."}},required:["account_number","symbol","side","type"],additionalProperties:!1}},{name:"place_option_order",namespace:"option_trading",description:`Place a real options order with real money. Call review_option_order first to obtain the current quote, fees, collateral, and pre-trade alerts. -Account requirements: confirm via get_accounts that the chosen account is agentic_allowed=true AND has option_level_2 or option_level_3. If agentic_allowed=false do NOT call. If option_level is empty or option_level_0, do NOT call; follow the get_accounts guide for how to direct the user to enroll. +Capability: single-leg Level 2 strategies include covered calls, cash-secured puts, long calls, and long puts. Multi-leg Level 3 strategies require an option_level_3 account. The account must also have agentic_allowed=true. -Alert handling: pre-trade alerts surface only in review_option_order. After the user has acknowledged the reviewed alert, call this tool with the same parameters. +Idempotency: pass a fresh UUID as ref_id on the first call for each logical order and re-send the same ref_id after a transient transport failure. Use a new ref_id only for a new logical order. -Idempotency: pass a fresh UUID as ref_id on the first call for each logical order, and re-send the SAME ref_id on retries of transient transport failures. Use a new ref_id only when the user wants a new order. - -To find option_id: get_option_chains → get_option_instruments filtered by expiration_date/strike_price/type. +Resolve option_id through get_option_chains and get_option_instruments filtered by expiration_date, strike_price, and type. Parameter rules: -- Multi-leg leg layouts — vertical spread: two legs, same expiration, different strikes, opposite sides. Calendar: two legs, same strike, different expirations. Iron condor: four legs, a put spread plus a call spread. Roll: close the leg you hold (position_effect 'close', side opposite the position) plus open the replacement ('open'). -- Get the net price from the user rather than inferring it from individual leg quotes. -- Multi-leg is not available on cash or retirement accounts through this tool. -- type: 'limit' (default), 'market', 'stop_limit', 'stop_market'. price for limit/stop_limit; stop_price for stop_market/stop_limit. -- market, stop_market, and stop_limit are single-leg only. market and stop_market are also regular_hours, GFD only. stop_market is sell-to-close only with stop_price below the current ask. +- A vertical spread has two opposite-side legs with the same expiration and different strikes. A calendar has the same strike and different expirations. An iron condor combines a put spread and call spread. A roll closes the existing leg and opens its replacement. +- Use the reviewed current strategy quote as the net price; do not sum stale individual-leg quotes. +- Multi-leg orders are unavailable on cash and retirement accounts through this tool. +- type supports limit (default), market, stop_limit, and stop_market. price is required for limit and stop_limit; stop_price is required for stop_market and stop_limit. +- market, stop_market, and stop_limit are single-leg only. market and stop_market are regular-hours GFD only. stop_market is sell-to-close only with stop_price below the current ask. +- Stock-option combo orders, meaning one option leg paired with 100 underlying shares, are not supported. -Not currently supported anywhere (including the Robinhood apps): -- combo orders. At Robinhood, "combo" specifically means a stock-option combo: one option leg paired with 100 shares of the underlying equity. In broader industry use, "combo" without qualifier sometimes refers to multi-leg option structures. REAL-MONEY ACTION: use only after the user explicitly authorizes the exact account, instrument, side, size, order type, price constraints, and timing. Use the dedicated Agentic account and reuse one ref_id for retries. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true."},legs:{type:["null","array"],items:{type:"object",properties:{option_id:{type:"string",description:"Option instrument UUID (from get_option_instruments)."},side:{type:"string",description:"'buy' or 'sell'."},position_effect:{type:"string",description:"'open' (new position) or 'close' (existing position). To close a long use sell; to close a short use buy."},ratio_quantity:{type:"integer",description:"Contracts for this leg per unit of the order's quantity. Defaults to 1, which is what standard spreads, condors, calendars, and rolls use. Must be 1 on a single-leg order; across legs the ratios must be in lowest terms (1:2, not 2:4)."}},required:["option_id","side","position_effect"],additionalProperties:!1},description:"1 to 4 legs, all on the same underlying and each a different contract. Several legs are filled together as one strategy. Should match the legs the user reviewed."},direction:{type:"string",description:"Net direction of the whole order: 'debit' (you pay the net premium) or 'credit' (you receive it). Required with 2 or more legs; for one leg it is derived from that leg's side, so omit it."},type:{type:"string",description:"'limit' (default), 'market', 'stop_limit', or 'stop_market'. Should match the type the user reviewed. Only 'limit' is available with 2 or more legs."},quantity:{type:"string",description:"Positive integer contract count. With several legs it counts whole strategies — each leg fills quantity × its ratio_quantity contracts."},price:{type:"string",description:"Limit price. Per contract for one leg; with several legs it is the net premium of the whole strategy per unit of quantity, always positive — direction says whether it is paid or received. Required for limit/stop_limit; must be omitted for market/stop_market."},stop_price:{type:"string",description:"Stop trigger price per contract. Required for stop_limit/stop_market; must be omitted for limit/market."},time_in_force:{type:"string",description:"'gfd' (default) or 'gtc'. Market orders must be 'gfd'."},market_hours:{type:"string",description:"'regular_hours' (default), 'regular_curb_hours', or 'regular_curb_overnight_hours'. Non-limit-immediate orders only place in regular_hours. CURB requires an index chain with extended_hours_state='enabled'."},ref_id:{type:"string",description:"Idempotency key (UUID). Generate once per logical order and re-send on retry. Omitting falls back to a server-generated key."}},required:["account_number","legs","quantity"],additionalProperties:!1}},{name:"remove_from_watchlist",namespace:"watchlists",description:"Remove items from a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes) is required — mutually exclusive. For options use remove_option_from_watchlist. Items not on the list are no-ops (not errors). Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to remove items from."},symbols:{type:["null","array"],items:{type:"string"},description:"Stock symbols to remove (e.g. ['AAPL']). Mutually exclusive with currency_pair_ids and index_ids."},currency_pair_ids:{type:["null","array"],items:{type:"string"},description:"Currency-pair UUIDs to remove. Mutually exclusive with symbols and index_ids."},index_ids:{type:["null","array"],items:{type:"string"},description:"Index UUIDs to remove. Mutually exclusive with symbols and currency_pair_ids."}},required:["list_id"],additionalProperties:!1}},{name:"remove_option_from_watchlist",namespace:"option_market_data",description:`Remove option contracts from the user's options watchlist. Specify the same position_type used when the contract was added (defaults to "long"). Contracts not on the list are no-ops. Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{option_ids:{type:["null","array"],items:{type:"string"},description:'Option contract UUIDs to remove. The position_type must match how each contract was added (most likely "long").'},position_type:{type:"string",description:'"long" (default) or "short". Must match how the contract was originally added.'}},required:["option_ids"],additionalProperties:!1}},{name:"review_equity_order",namespace:"equity_trading",description:`Simulate a stock order without placing it. Returns the current quote plus pre-trade alerts (buying power, PDT, instrument halt, etc.). Call this by default before place_equity_order unless the user has very explicitly asked to skip review. Requires an agentic_allowed=true account; non-agentic accounts are rejected — do not call. +Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number from get_accounts. Must be agentic_allowed=true."},legs:{type:["null","array"],items:{type:"object",properties:{option_id:{type:"string",description:"Option instrument UUID (from get_option_instruments)."},side:{type:"string",description:"'buy' or 'sell'."},position_effect:{type:"string",description:"'open' (new position) or 'close' (existing position). To close a long use sell; to close a short use buy."},ratio_quantity:{type:"integer",description:"Contracts for this leg per unit of the order's quantity. Defaults to 1, which is what standard spreads, condors, calendars, and rolls use. Must be 1 on a single-leg order; across legs the ratios must be in lowest terms (1:2, not 2:4)."}},required:["option_id","side","position_effect"],additionalProperties:!1},description:"1 to 4 legs, all on the same underlying and each a different contract. Several legs are filled together as one strategy. Must match the preceding review request."},direction:{type:"string",description:"Net direction of the whole order: 'debit' (you pay the net premium) or 'credit' (you receive it). Required with 2 or more legs; for one leg it is derived from that leg's side, so omit it."},type:{type:"string",description:"'limit' (default), 'market', 'stop_limit', or 'stop_market'. Must match the preceding review request. Only 'limit' is available with 2 or more legs."},quantity:{type:"string",description:"Positive integer contract count. With several legs it counts whole strategies — each leg fills quantity × its ratio_quantity contracts."},price:{type:"string",description:"Limit price. Per contract for one leg; with several legs it is the net premium of the whole strategy per unit of quantity, always positive — direction says whether it is paid or received. Required for limit/stop_limit; must be omitted for market/stop_market."},stop_price:{type:"string",description:"Stop trigger price per contract. Required for stop_limit/stop_market; must be omitted for limit/market."},time_in_force:{type:"string",description:"'gfd' (default) or 'gtc'. Market orders must be 'gfd'."},market_hours:{type:"string",description:"'regular_hours' (default), 'regular_curb_hours', or 'regular_curb_overnight_hours'. Non-limit-immediate orders only place in regular_hours. CURB requires an index chain with extended_hours_state='enabled'."},ref_id:{type:"string",description:"Idempotency key (UUID). Generate once per logical order and re-send on retry. Omitting falls back to a server-generated key."}},required:["account_number","legs","quantity"],additionalProperties:!1}},{name:"remove_from_watchlist",namespace:"watchlists",description:"Remove items from a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes) is required. For options use remove_option_from_watchlist. Items not on the list are no-ops. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to remove items from."},symbols:{type:["null","array"],items:{type:"string"},description:"Stock symbols to remove (e.g. ['AAPL']). Mutually exclusive with currency_pair_ids and index_ids."},currency_pair_ids:{type:["null","array"],items:{type:"string"},description:"Currency-pair UUIDs to remove. Mutually exclusive with symbols and index_ids."},index_ids:{type:["null","array"],items:{type:"string"},description:"Index UUIDs to remove. Mutually exclusive with symbols and currency_pair_ids."}},required:["list_id"],additionalProperties:!1}},{name:"remove_option_from_watchlist",namespace:"option_market_data",description:`Remove option contracts from the user's options watchlist. Specify the same position_type used when the contract was added; it defaults to "long". Contracts not on the list are no-ops. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{option_ids:{type:["null","array"],items:{type:"string"},description:'Option contract UUIDs to remove. The position_type must match how each contract was added (most likely "long").'},position_type:{type:"string",description:'"long" (default) or "short". Must match how the contract was originally added.'}},required:["option_ids"],additionalProperties:!1}},{name:"review_equity_order",namespace:"equity_trading",description:`Simulate a stock order without placing it. Returns the current quote, estimated cost, and pre-trade alerts such as buying power, PDT, and instrument halts. Use it before place_equity_order. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Parameter rules: -- If the user has not specified type, ask. For immediate fills with price protection, prefer a marketable limit at the current ask over a plain market. -- Outside regular hours, only limit orders execute. For an immediate fill during extended or overnight/24-hour sessions, place a limit order (a marketable limit at the current ask) with market_hours set to that session — not a market order. Market and stop orders are regular_hours-only; placed after hours as regular_hours they queue for the next regular open. -- Provide exactly one of quantity or dollar_amount; dollar_amount requires type=market (server computes shares from last_trade_price). -- Fractional shares: only on type=market with market_hours=regular_hours, eligible accounts, up to 6 decimal places, no short sells. -- limit_price required for limit/stop_limit; stop_price required for stop_market/stop_limit. -- Fractional and dollar-based orders only place in regular_hours; the tool rejects them in other sessions. -- tax_lots (specified-lot selling, sell only): to sell specific lots, first call get_equity_tax_lots for the symbol, then pass tax_lots as {open_lot_id, quantity} pairs whose quantities sum to the order quantity. Omit for default (FIFO) cost basis. US accounts only; not allowed with dollar_amount, stop orders, all_day_hours, or fractional limit orders. This is a non-submitting pre-trade simulation. Review warnings and estimated cost before asking for authorization to use the corresponding place tool. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true; non-agentic accounts are rejected."},symbol:{type:"string",description:"Stock symbol."},side:{type:"string",description:"'buy' or 'sell'."},type:{type:"string",description:"'market', 'limit', 'stop_market', or 'stop_limit'."},quantity:{type:"string",description:"Number of shares. Decimals (fractional) allowed for market + regular_hours only."},dollar_amount:{type:"string",description:"USD notional (e.g. '100.00'). Only valid with type=market."},limit_price:{type:"string",description:"Limit price; required for limit or stop_limit."},stop_price:{type:"string",description:"Stop trigger price; required for stop_market or stop_limit."},time_in_force:{type:"string",description:"'gfd' (good for day) or 'gtc' (good till cancelled). Default: gfd."},market_hours:{type:"string",description:"'regular_hours' (default, 9:30–16:00 ET), 'extended_hours' (pre-/post-market), or 'all_day_hours' (the 24 Hour Market / overnight session). extended_hours and all_day_hours execute limit orders only — market, stop_market, and stop_limit are regular_hours-only and are rejected if tagged to another session."},tax_lots:{type:["null","array"],items:{type:"object",properties:{open_lot_id:{type:"string",description:"open_lot_id of the open tax lot to sell, from get_equity_tax_lots."},quantity:{type:"string",description:"Shares to sell from this lot as a decimal string; at most the lot's quantity_available."}},required:["open_lot_id","quantity"],additionalProperties:!1},description:"Optional specified-lot selection for a SELL order. To sell specific tax lots instead of the default FIFO cost basis, pass the exact lots as {open_lot_id, quantity} objects, where open_lot_id comes from get_equity_tax_lots and the quantities sum to the order quantity. Omit for default FIFO. Sell only; at most 30 lots; US accounts only. Not allowed with dollar_amount, stop_market/stop_limit, all_day_hours, or fractional-share limit orders."}},required:["account_number","symbol","side","type"],additionalProperties:!1}},{name:"review_option_order",namespace:"option_trading",description:`Simulate an options order without placing it. Returns the current quote plus pre-trade alerts. Call this by default before place_option_order or replace_option_order unless the user has very explicitly asked to skip review. +- For immediate fills with price protection, prefer a marketable limit at the current ask over a plain market. +- Outside regular hours, only limit orders execute. Extended-hours and overnight orders must set the corresponding market_hours session. Market and stop orders are regular_hours-only. +- Provide exactly one of quantity or dollar_amount; dollar_amount requires type=market. +- Fractional shares are supported only for type=market with market_hours=regular_hours on eligible accounts, up to 6 decimal places, with no short sells. +- limit_price is required for limit and stop_limit; stop_price is required for stop_market and stop_limit. +- tax_lots is sell-only specified-lot selection using open_lot_id values from get_equity_tax_lots. The lot quantities must sum to the order quantity. It is limited to US accounts and cannot be combined with dollar_amount, stop orders, all_day_hours, or fractional limit orders. -Capability: single-leg options orders — Level 2 strategies (covered calls, cash-secured puts, long calls and puts). Multi-leg spreads (Level 3 strategies) are supported on option_level_3 accounts. +This tool does not submit the order. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number from get_accounts. Must be agentic_allowed=true; non-agentic accounts are rejected."},symbol:{type:"string",description:"Stock symbol."},side:{type:"string",description:"'buy' or 'sell'."},type:{type:"string",description:"'market', 'limit', 'stop_market', or 'stop_limit'."},quantity:{type:"string",description:"Number of shares. Decimals (fractional) allowed for market + regular_hours only."},dollar_amount:{type:"string",description:"USD notional (e.g. '100.00'). Only valid with type=market."},limit_price:{type:"string",description:"Limit price; required for limit or stop_limit."},stop_price:{type:"string",description:"Stop trigger price; required for stop_market or stop_limit."},time_in_force:{type:"string",description:"'gfd' (good for day) or 'gtc' (good till cancelled). Default: gfd."},market_hours:{type:"string",description:"'regular_hours' (default, 9:30–16:00 ET), 'extended_hours' (pre-/post-market), or 'all_day_hours' (the 24 Hour Market / overnight session). extended_hours and all_day_hours execute limit orders only — market, stop_market, and stop_limit are regular_hours-only and are rejected if tagged to another session."},tax_lots:{type:["null","array"],items:{type:"object",properties:{open_lot_id:{type:"string",description:"open_lot_id of the open tax lot to sell, from get_equity_tax_lots."},quantity:{type:"string",description:"Shares to sell from this lot as a decimal string; at most the lot's quantity_available."}},required:["open_lot_id","quantity"],additionalProperties:!1},description:"Optional specified-lot selection for a SELL order. To sell specific tax lots instead of the default FIFO cost basis, pass the exact lots as {open_lot_id, quantity} objects, where open_lot_id comes from get_equity_tax_lots and the quantities sum to the order quantity. Omit for default FIFO. Sell only; at most 30 lots; US accounts only. Not allowed with dollar_amount, stop_market/stop_limit, all_day_hours, or fractional-share limit orders."}},required:["account_number","symbol","side","type"],additionalProperties:!1}},{name:"review_option_order",namespace:"option_trading",description:`Simulate an options order without placing it. Returns the current strategy quote, fees, collateral, and pre-trade alerts. Use it before place_option_order. -Account requirements: confirm via get_accounts that the chosen account is agentic_allowed=true AND has option_level_2 or option_level_3. If agentic_allowed=false do NOT call. If option_level is empty or option_level_0, do NOT call; follow the get_accounts guide for how to direct the user to enroll. +Capability: single-leg Level 2 strategies include covered calls, cash-secured puts, long calls, and long puts. Multi-leg Level 3 strategies require an option_level_3 account. The account must also have agentic_allowed=true. Parameter rules: -- legs: option_id (from get_option_instruments), side, position_effect, optional ratio_quantity per leg. -- Multi-leg leg layouts — vertical spread: two legs, same expiration, different strikes, opposite sides. Calendar: two legs, same strike, different expirations. Iron condor: four legs, a put spread plus a call spread. Roll: close the leg you hold (position_effect 'close', side opposite the position) plus open the replacement ('open'). -- Get the net price from the user rather than inferring it from individual leg quotes. -- Multi-leg is not available on cash or retirement accounts through this tool. -- type: 'limit' (default), 'market', 'stop_limit', 'stop_market'. If unspecified, ask. price for limit/stop_limit; stop_price for stop_market/stop_limit. -- market, stop_market, and stop_limit are single-leg only. market and stop_market are also GFD, regular_hours only. stop_market is sell-to-close only with stop_price below the current ask. Non-limit-immediate types are blocked in any extended-hours session. -- Surface order_checks alerts verbatim — the detail strings carry the actual time/contract/BP values for the user. This is a non-submitting pre-trade simulation. Review warnings and estimated cost before asking for authorization to use the corresponding place tool. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true."},legs:{type:["null","array"],items:{type:"object",properties:{option_id:{type:"string",description:"Option instrument UUID (from get_option_instruments)."},side:{type:"string",description:"'buy' or 'sell'."},position_effect:{type:"string",description:"'open' (new position) or 'close' (existing position). To close a long use sell; to close a short use buy."},ratio_quantity:{type:"integer",description:"Contracts for this leg per unit of the order's quantity. Defaults to 1, which is what standard spreads, condors, calendars, and rolls use. Must be 1 on a single-leg order; across legs the ratios must be in lowest terms (1:2, not 2:4)."}},required:["option_id","side","position_effect"],additionalProperties:!1},description:"1 to 4 legs, all on the same underlying and each a different contract. Several legs are filled together as one strategy."},direction:{type:"string",description:"Net direction of the whole order: 'debit' (you pay the net premium) or 'credit' (you receive it). Required with 2 or more legs; for one leg it is derived from that leg's side, so omit it."},type:{type:"string",description:"'limit' (default), 'market', 'stop_limit', or 'stop_market'. Only 'limit' is available with 2 or more legs."},quantity:{type:"string",description:"Positive integer contract count. With several legs it counts whole strategies — each leg fills quantity × its ratio_quantity contracts."},price:{type:"string",description:"Limit price (e.g. '1.50'). Per contract for one leg; with several legs it is the net premium of the whole strategy per unit of quantity, always positive — direction says whether it is paid or received. Required for limit/stop_limit; must be omitted for market/stop_market."},stop_price:{type:"string",description:"Stop trigger price per contract. Required for stop_limit/stop_market; must be omitted for limit/market. For sell-side stop_market, must be below the current ask."},time_in_force:{type:"string",description:"'gfd' (default) or 'gtc'. Market orders must be 'gfd'."},market_hours:{type:"string",description:"'regular_hours' (default), 'regular_curb_hours', or 'regular_curb_overnight_hours'. Extended-hours sessions only accept limit+immediate. CURB requires an index chain with extended_hours_state='enabled' (per get_option_chains); rejection surfaces at place time."},chain_symbol:{type:"string",description:"Underlying ticker (e.g. 'AAPL', 'SPXW'). Supply alongside underlying_type to include fees and collateral in the response — always do so when known."},underlying_type:{type:"string",description:"'equity' or 'index'. Required alongside chain_symbol to enable the fee + collateral fetch."}},required:["account_number","legs","quantity"],additionalProperties:!1}},{name:"run_scan",namespace:"scanners",description:`Execute a saved scanner (also called screener) and return live market results. A scan's filters are evaluated against current market data at request time — results are real-time, not cached. +- legs contain option_id from get_option_instruments, side, position_effect, and optional ratio_quantity. +- A vertical spread has two opposite-side legs with the same expiration and different strikes. A calendar has the same strike and different expirations. An iron condor combines a put spread and call spread. A roll closes the existing leg and opens its replacement. +- Use the current strategy quote as the net price; do not sum stale individual-leg quotes. +- Multi-leg orders are unavailable on cash and retirement accounts through this tool. +- type supports limit (default), market, stop_limit, and stop_market. price is required for limit and stop_limit; stop_price is required for stop_market and stop_limit. +- market, stop_market, and stop_limit are single-leg only. market and stop_market are regular-hours GFD only. stop_market is sell-to-close only with stop_price below the current ask. Other non-limit-immediate types are blocked in extended-hours sessions. +- order_checks contains the broker's time, contract, and buying-power alerts. + +This tool does not submit the order. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number from get_accounts. Must be agentic_allowed=true."},legs:{type:["null","array"],items:{type:"object",properties:{option_id:{type:"string",description:"Option instrument UUID (from get_option_instruments)."},side:{type:"string",description:"'buy' or 'sell'."},position_effect:{type:"string",description:"'open' (new position) or 'close' (existing position). To close a long use sell; to close a short use buy."},ratio_quantity:{type:"integer",description:"Contracts for this leg per unit of the order's quantity. Defaults to 1, which is what standard spreads, condors, calendars, and rolls use. Must be 1 on a single-leg order; across legs the ratios must be in lowest terms (1:2, not 2:4)."}},required:["option_id","side","position_effect"],additionalProperties:!1},description:"1 to 4 legs, all on the same underlying and each a different contract. Several legs are filled together as one strategy."},direction:{type:"string",description:"Net direction of the whole order: 'debit' (you pay the net premium) or 'credit' (you receive it). Required with 2 or more legs; for one leg it is derived from that leg's side, so omit it."},type:{type:"string",description:"'limit' (default), 'market', 'stop_limit', or 'stop_market'. Only 'limit' is available with 2 or more legs."},quantity:{type:"string",description:"Positive integer contract count. With several legs it counts whole strategies — each leg fills quantity × its ratio_quantity contracts."},price:{type:"string",description:"Limit price (e.g. '1.50'). Per contract for one leg; with several legs it is the net premium of the whole strategy per unit of quantity, always positive — direction says whether it is paid or received. Required for limit/stop_limit; must be omitted for market/stop_market."},stop_price:{type:"string",description:"Stop trigger price per contract. Required for stop_limit/stop_market; must be omitted for limit/market. For sell-side stop_market, must be below the current ask."},time_in_force:{type:"string",description:"'gfd' (default) or 'gtc'. Market orders must be 'gfd'."},market_hours:{type:"string",description:"'regular_hours' (default), 'regular_curb_hours', or 'regular_curb_overnight_hours'. Extended-hours sessions only accept limit+immediate. CURB requires an index chain with extended_hours_state='enabled' (per get_option_chains); rejection surfaces at place time."},chain_symbol:{type:"string",description:"Underlying ticker (e.g. 'AAPL', 'SPXW'). Supply alongside underlying_type to include fees and collateral in the response — always do so when known."},underlying_type:{type:"string",description:"'equity' or 'index'. Required alongside chain_symbol to enable the fee + collateral fetch."}},required:["account_number","legs","quantity"],additionalProperties:!1}},{name:"run_scan",namespace:"scanners",description:`Execute a saved scanner (also called screener) and return live market results. A scan's filters are evaluated against current market data at request time — results are real-time, not cached. Returns the scan's title, the total number of matching instruments, a list of instrument rows (with ticker, instrument_id, type, and one cell per visible column), plus the active sort and filters. The agent should present results as a table and mention this is live data. Parameters: - scan_id (required) — the scan identifier from get_scans or create_scan. Returns an error if the scan does not exist or does not belong to the calling user. -Use get_scans first to discover available scan_ids if the user has not specified one. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan identifier to execute. Get this from get_scans or create_scan."}},required:["scan_id"],additionalProperties:!1}},{name:"search",namespace:"equity_market_data",description:'Resolve a natural-language query to Robinhood instruments (stocks/ETFs), crypto pairs, or market indexes. Use when the user names an asset by name (or partial name) instead of a ticker/pair/index symbol, or when you need an instrument_id / currency-pair UUID / market-index id for a downstream tool. Defaults to instrument search; pass asset_type="currency_pair" for crypto or asset_type="market_index" for indexes (SPX, NDX, DJI, etc.). Instrument results carry symbol + instrument_id (use with get_equity_quotes / get_equity_tradability / place_equity_order or any instrument_id-based tool). Crypto results carry hyphenated symbol (e.g. BTC-USD) + id — the symbol routes to crypto quote/order tools, the id routes to watchlist tools as currency_pair_ids. Market-index results carry symbol + id — pass id to index quote tools for current values, or in the index_ids array of watchlist tools. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.',inputSchema:{type:"object",properties:{query:{type:"string",description:'Natural-language search query: company name, partial name, or ticker (e.g. "apple", "tesla motors", "AAPL"). Required.'},asset_type:{type:"string",description:'Asset category to search. Supported: "instrument" (US-listed stocks/ETFs), "currency_pair" (crypto pairs like BTC-USD), and "market_index" (e.g. SPX, NDX, DJI). Defaults to "instrument" when omitted. More categories (events, futures) will be added as their corresponding tools land.'},limit:{type:"integer",description:"Max results to return. Defaults to 10; clamped to 20."}},required:["query"],additionalProperties:!1}},{name:"unfollow_watchlist",namespace:"watchlists",description:"Stop following a Robinhood-curated list. The list itself is unchanged — it just no longer appears in the user's watchlists. Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the Robinhood-curated list to unfollow."}},required:["list_id"],additionalProperties:!1}},{name:"update_scan_config",namespace:"scanners",description:`Change the sort order of a saved scan's results table. The scan's filters and columns are preserved; only the sort changes. +Use get_scans first to discover available scan_ids if the user has not specified one. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan identifier to execute. Get this from get_scans or create_scan."}},required:["scan_id"],additionalProperties:!1}},{name:"search",namespace:"equity_market_data",description:'Resolve a natural-language query to Robinhood instruments (stocks/ETFs), crypto pairs, or market indexes. Use when the user names an asset by name (or partial name) instead of a ticker/pair/index symbol, or when you need an instrument_id / currency-pair UUID / market-index id for a downstream tool. Defaults to instrument search; pass asset_type="currency_pair" for crypto or asset_type="market_index" for indexes (SPX, NDX, DJI, etc.). Instrument results carry symbol + instrument_id (use with get_equity_quotes / get_equity_tradability / place_equity_order or any instrument_id-based tool). Crypto results carry hyphenated symbol (e.g. BTC-USD) + id — the symbol routes to crypto quote/order tools, the id routes to watchlist tools as currency_pair_ids. Market-index results carry symbol + id — pass id to index quote tools for current values, or in the index_ids array of watchlist tools. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.',inputSchema:{type:"object",properties:{query:{type:"string",description:'Natural-language search query: company name, partial name, or ticker (e.g. "apple", "tesla motors", "AAPL"). Required.'},asset_type:{type:"string",description:'Asset category to search. Supported: "instrument" (US-listed stocks/ETFs), "currency_pair" (crypto pairs like BTC-USD), and "market_index" (e.g. SPX, NDX, DJI). Defaults to "instrument" when omitted. More categories (events, futures) will be added as their corresponding tools land.'},limit:{type:"integer",description:"Max results to return. Defaults to 10; clamped to 20."}},required:["query"],additionalProperties:!1}},{name:"unfollow_watchlist",namespace:"watchlists",description:"Stop following a Robinhood-curated list. The list itself is unchanged and no longer appears in the user's watchlists. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the Robinhood-curated list to unfollow."}},required:["list_id"],additionalProperties:!1}},{name:"update_scan_config",namespace:"scanners",description:`Change the sort order of a saved scan's results table. The scan's filters and columns are preserved; only the sort changes. Parameters: - scan_id (required) — the scan to modify. @@ -166,7 +163,7 @@ Restrictions: - Cortex-managed scans (cortex_managed: true in get_scans) are rejected with a user-friendly error. - Returns an error and does not apply any change if any filter fails validation. -Returns the scan with its new filters and fresh live results. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan to modify. Get this from get_scans or create_scan. Cortex-managed scans (cortex_managed: true in get_scans output) are rejected."},filters:{type:["null","array"],items:{type:"object",properties:{filter_type:{type:"string",description:'Wire-format enum name, e.g. "FILTER_TYPE_RSI". See the scanner-filter-specs resource for valid values. Omit when supplying expression.'},predicate:{type:"string",description:'Wire-format enum name, e.g. "PREDICATE_GREATER_THAN". See the scanner-filter-specs resource for the predicates supported by each filter.'},values:{type:["null","array"],items:{type:"string"},description:'Threshold values. Single-element for unary predicates, two-element for BETWEEN, multi-element for IN_LIST/ANY_OF. For a boolean expression screen, exactly ["True"].'},interval:{type:"string",description:`Time granularity for time-series filters (e.g. "1d"). Use one of the supported_intervals from the filter's scanner-filter-specs entry. Not used with expression — encode granularity inside the expression.`},length:{type:"integer",description:"Lookback length for filters that need one (e.g. RSI period of 14). Use one of the supported_lengths from the filter's scanner-filter-specs entry. Not used with expression.",minimum:-2147483648,maximum:2147483647},plot:{type:"string",description:`Plot / price-field input for filters that have one (e.g. "open" or "close" for % Change). Use one of the supported_plots from the filter's scanner-filter-specs entry. Not used with expression.`},expression:{type:"string",description:'Raw market-data expression to screen on, e.g. "dayVolume / volumeAvg(candleCount=30, candlePeriod=\\"1d\\", session=\\"all\\")" with a numeric predicate, or a whole comparison like "tradeAllDay.price > closeAvg(candleCount=50, candlePeriod=\\"1d\\", session=\\"all\\")" with predicate "=" and values ["True"]. Only preview_scan accepts expressions. Omit filter_type when set. Prefer an enum filter_type whenever one covers the request.'},display_title:{type:"string",description:'Optional short label for an expression filter, shown as the results-column header (e.g. "Relative volume (30D)"). Only used with expression.'}},required:["predicate","values"],additionalProperties:!1},description:"The complete set of filters the scan should have after the update. REPLACE semantics — to add a filter, supply all existing filters plus the new one. To remove a filter, omit it from the array. To clear all filters, send []. Each filter: filter_type (FILTER_TYPE_... enum), predicate (>, <, =, BETWEEN, etc.), values, optional interval (e.g. 1d), optional length (e.g. 14 for RSI). Call get_scanner_filter_specs first for valid filter_type / predicate / interval / length combinations."}},required:["scan_id","filters"],additionalProperties:!1}},{name:"update_watchlist",namespace:"watchlists",description:"Rename a custom watchlist or change its icon/description. Robinhood-curated lists cannot be renamed; the call will fail with 404. Provide at least one of display_name, icon_emoji, display_description. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to update. Obtain from get_watchlists."},display_name:{type:"string",description:"New name for the watchlist."},icon_emoji:{type:"string",description:"New emoji."},display_description:{type:"string",description:"New description."}},required:["list_id"],additionalProperties:!1}}]};var k=globalThis.db,x=k.open("robinhood");if(x<0)throw Error("open robinhood.sqlite");var L=5;function M(){return String(k.lastError(x)||"SQLite operation failed")}function w(e){if(k.exec(x,e)!==0)throw Error(M())}function T(e,t=[]){let i=JSON.parse(k.query(x,e,JSON.stringify(t)));if(i.error)throw Error(String(i.error));return i}function h(e,t=[]){return T(e,t)}var N=T("PRAGMA user_version");if(Number(N?.user_version??0)!==L)w(` +Returns the scan with its new filters and fresh live results. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan to modify. Get this from get_scans or create_scan. Cortex-managed scans (cortex_managed: true in get_scans output) are rejected."},filters:{type:["null","array"],items:{type:"object",properties:{filter_type:{type:"string",description:'Wire-format enum name, e.g. "FILTER_TYPE_RSI". See the scanner-filter-specs resource for valid values. Omit when supplying expression.'},predicate:{type:"string",description:'Wire-format enum name, e.g. "PREDICATE_GREATER_THAN". See the scanner-filter-specs resource for the predicates supported by each filter.'},values:{type:["null","array"],items:{type:"string"},description:'Threshold values. Single-element for unary predicates, two-element for BETWEEN, multi-element for IN_LIST/ANY_OF. For a boolean expression screen, exactly ["True"].'},interval:{type:"string",description:`Time granularity for time-series filters (e.g. "1d"). Use one of the supported_intervals from the filter's scanner-filter-specs entry. Not used with expression — encode granularity inside the expression.`},length:{type:"integer",description:"Lookback length for filters that need one (e.g. RSI period of 14). Use one of the supported_lengths from the filter's scanner-filter-specs entry. Not used with expression.",minimum:-2147483648,maximum:2147483647},plot:{type:"string",description:`Plot / price-field input for filters that have one (e.g. "open" or "close" for % Change). Use one of the supported_plots from the filter's scanner-filter-specs entry. Not used with expression.`},expression:{type:"string",description:'Raw market-data expression to screen on, e.g. "dayVolume / volumeAvg(candleCount=30, candlePeriod=\\"1d\\", session=\\"all\\")" with a numeric predicate, or a whole comparison like "tradeAllDay.price > closeAvg(candleCount=50, candlePeriod=\\"1d\\", session=\\"all\\")" with predicate "=" and values ["True"]. Only preview_scan accepts expressions. Omit filter_type when set. Prefer an enum filter_type whenever one covers the request.'},display_title:{type:"string",description:'Optional short label for an expression filter, shown as the results-column header (e.g. "Relative volume (30D)"). Only used with expression.'}},required:["predicate","values"],additionalProperties:!1},description:"The complete set of filters the scan should have after the update. REPLACE semantics — to add a filter, supply all existing filters plus the new one. To remove a filter, omit it from the array. To clear all filters, send []. Each filter: filter_type (FILTER_TYPE_... enum), predicate (>, <, =, BETWEEN, etc.), values, optional interval (e.g. 1d), optional length (e.g. 14 for RSI). Call get_scanner_filter_specs first for valid filter_type / predicate / interval / length combinations."}},required:["scan_id","filters"],additionalProperties:!1}},{name:"update_watchlist",namespace:"watchlists",description:"Rename a custom watchlist or change its icon/description. Robinhood-curated lists cannot be renamed; the call will fail with 404. Provide at least one of display_name, icon_emoji, display_description. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to update. Obtain from get_watchlists."},display_name:{type:"string",description:"New name for the watchlist."},icon_emoji:{type:"string",description:"New emoji."},display_description:{type:"string",description:"New description."}},required:["list_id"],additionalProperties:!1}}]};var k=globalThis.db,q=k.open("robinhood");if(q<0)throw Error("open robinhood.sqlite");var E=5;function M(){return String(k.lastError(q)||"SQLite operation failed")}function w(e){if(k.exec(q,e)!==0)throw Error(M())}function D(e,t=[]){let i=JSON.parse(k.query(q,e,JSON.stringify(t)));if(i.error)throw Error(String(i.error));return i}function h(e,t=[]){return D(e,t)}var V=D("PRAGMA user_version");if(Number(V?.user_version??0)!==E)w(` CREATE TABLE IF NOT EXISTS accounts ( account_number TEXT PRIMARY KEY, label TEXT NOT NULL, @@ -225,19 +222,19 @@ Returns the scan with its new filters and fresh live results. This changes Robin ); CREATE INDEX IF NOT EXISTS refresh_runs_recent ON refresh_runs(id DESC); PRAGMA user_version=5; - `);var A=b.tools,V=new Map(A.map((e)=>[e.name,e]));function _(){return Math.floor(Date.now()/1000)}function F(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function n(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let i of t){let r=F(e[i]);if(r!==null)return r}for(let i of Object.values(e)){let r=n(i,t);if(r!==null)return r}return null}function O(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let i of t)if(Array.isArray(e[i]))return e[i];for(let i of Object.values(e)){let r=O(i,t);if(r.length)return r}return[]}function Y(e,t){let i=n(e,t)?.toLowerCase();return i==="true"||i==="1"||i==="yes"}function U(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function g(e,t){let i=t?.account_number;return i===null||i===void 0||i===""?n(e,["account_number","accountNumber","account"])||"":String(i)}function q(e,t){let i=O(e,t);return i.length?i:Array.isArray(e)?e:e?[e]:[]}function z(e){let t=Array.isArray(e?.names)?new Set(e.names.filter((s)=>typeof s==="string")):new Set,i=String(e?.query??"").toLowerCase().split(/[^a-z0-9_]+/).filter(Boolean),r=typeof e?.namespace==="string"?e.namespace:"";if(!t.size&&!i.length)throw Error("search_tools requires query or names");let c=Math.max(1,Math.min(8,Number(e?.limit??5)||5)),o=A.filter((s)=>!r||s.namespace===r).map((s)=>{let a=s.name.toLowerCase(),p=a+" "+s.description.toLowerCase(),d=t.has(s.name)?1000:i.reduce((m,l)=>m+(a===l?100:a.includes(l)?20:p.includes(l)?3:0),0);return{tool:s,score:d}}).filter((s)=>s.score>0).sort((s,a)=>a.score-s.score||s.tool.name.localeCompare(a.tool.name)).slice(0,c).map(({tool:s})=>({name:s.name,namespace:s.namespace,description:s.description,inputSchema:s.inputSchema}));return{source:b.source,protocolVersion:b.protocolVersion,matches:o}}function G(e,t){if(t==="null")return e===null;if(t==="array")return Array.isArray(e);if(t==="object")return e!==null&&typeof e==="object"&&!Array.isArray(e);if(t==="integer")return typeof e==="number"&&Number.isInteger(e);if(t==="number")return typeof e==="number"&&Number.isFinite(e);return typeof e===t}function v(e,t,i="arguments"){let r=Array.isArray(t?.type)?t.type:t?.type?[t.type]:[];if(r.length&&!r.some((o)=>G(e,o)))throw Error(i+" must be "+r.join(" or "));if(e===null)return;if(typeof e==="number"){if(typeof t.minimum==="number"&&et.maximum)throw Error(i+" exceeds maximum "+t.maximum)}if(Array.isArray(e)){if(t.items)e.forEach((o,s)=>v(o,t.items,i+"["+s+"]"));return}if(typeof e!=="object")return;let c=t.properties||{};for(let o of t.required||[])if(!(o in e))throw Error(i+"."+o+" is required");if(t.additionalProperties===!1){for(let o of Object.keys(e))if(!(o in c))throw Error(i+"."+o+" is not allowed")}for(let[o,s]of Object.entries(e))if(c[o])v(s,c[o],i+"."+o)}function B(e){let t=typeof e?.name==="string"?e.name:"",i=V.get(t);if(!i)throw Error("Unknown Robinhood provider Tool: "+t);let r=e?.arguments;return v(r,i.inputSchema),ee(t,r)}function D(e,t){let i=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t})));if(!i.ok)throw Error(i.error||"Robinhood service failed");return i.value}function W(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((i)=>({name:i.operation,arguments:i.args}))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function I(e){w("BEGIN IMMEDIATE");try{e(),w("COMMIT")}catch(t){try{w("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function H(e,t){let i=q(e,["accounts"]);h("DELETE FROM accounts");for(let r of i){let c=g(r,{});if(!c)continue;let o=(n(r,["nickname","account_type","type"])||"").toUpperCase(),s=Y(r,["agentic_allowed","agenticAllowed"]),a=s?"AGENTIC":o.includes("IRA")||o.includes("RETIRE")?"RETIREMENT":o.includes("JOINT")?"JOINT":"PERSONAL";h("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at) VALUES(?,?,?,?,?,?,?)",[c,a,c.slice(-4),o,(n(r,["status"])||"active").toUpperCase(),s?1:0,t])}}function X(e,t,i){let r=g(e,t);if(!r)throw Error("Robinhood portfolio is missing account_number");let c=n(e,["cash","cash_available","withdrawable_amount"]),o=n(e,["buying_power","buyingPower"]),s=n(e,["day_pnl","dayPnl","equity_change"]),a=n(e,["week_pnl","weekPnl"]);h(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) + `);var T=b.tools,F=new Map(T.map((e)=>[e.name,e]));function f(){return Math.floor(Date.now()/1000)}function N(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function n(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let i of t){let r=N(e[i]);if(r!==null)return r}for(let i of Object.values(e)){let r=n(i,t);if(r!==null)return r}return null}function A(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let i of t)if(Array.isArray(e[i]))return e[i];for(let i of Object.values(e)){let r=A(i,t);if(r.length)return r}return[]}function Y(e,t){let i=n(e,t)?.toLowerCase();return i==="true"||i==="1"||i==="yes"}function I(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function _(e,t){let i=t?.account_number;return i===null||i===void 0||i===""?n(e,["account_number","accountNumber","account"])||"":String(i)}function x(e,t){let i=A(e,t);return i.length?i:Array.isArray(e)?e:e?[e]:[]}function G(e){let t=Array.isArray(e?.names)?new Set(e.names.filter((o)=>typeof o==="string")):new Set,i=String(e?.query??"").toLowerCase().split(/[^a-z0-9_]+/).filter(Boolean),r=typeof e?.namespace==="string"?e.namespace:"";if(!t.size&&!i.length)throw Error("search_tools requires query or names");let d=Math.max(1,Math.min(8,Number(e?.limit??5)||5)),s=T.filter((o)=>!r||o.namespace===r).map((o)=>{let a=o.name.toLowerCase(),p=a+" "+o.description.toLowerCase(),c=t.has(o.name)?1000:i.reduce((m,l)=>m+(a===l?100:a.includes(l)?20:p.includes(l)?3:0),0);return{tool:o,score:c}}).filter((o)=>o.score>0).sort((o,a)=>a.score-o.score||o.tool.name.localeCompare(a.tool.name)).slice(0,d).map(({tool:o})=>({name:o.name,namespace:o.namespace,description:o.description,inputSchema:o.inputSchema}));return{source:b.source,protocolVersion:b.protocolVersion,matches:s}}function B(e,t){if(t==="null")return e===null;if(t==="array")return Array.isArray(e);if(t==="object")return e!==null&&typeof e==="object"&&!Array.isArray(e);if(t==="integer")return typeof e==="number"&&Number.isInteger(e);if(t==="number")return typeof e==="number"&&Number.isFinite(e);return typeof e===t}function U(e,t,i="arguments"){let r=Array.isArray(t?.type)?t.type:t?.type?[t.type]:[];if(r.length&&!r.some((s)=>B(e,s)))throw Error(i+" must be "+r.join(" or "));if(e===null)return;if(typeof e==="number"){if(typeof t.minimum==="number"&&et.maximum)throw Error(i+" exceeds maximum "+t.maximum)}if(Array.isArray(e)){if(t.items)e.forEach((s,o)=>U(s,t.items,i+"["+o+"]"));return}if(typeof e!=="object")return;let d=t.properties||{};for(let s of t.required||[])if(!(s in e))throw Error(i+"."+s+" is required");if(t.additionalProperties===!1){for(let s of Object.keys(e))if(!(s in d))throw Error(i+"."+s+" is not allowed")}for(let[s,o]of Object.entries(e))if(d[s])U(o,d[s],i+"."+s)}function z(e){let t=typeof e?.name==="string"?e.name:"",i=F.get(t);if(!i)throw Error("Unknown Robinhood provider Tool: "+t);let r=e?.arguments;return U(r,i.inputSchema),ee(t,r)}function O(e,t){let i=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t})));if(!i.ok)throw Error(i.error||"Robinhood service failed");return i.value}function W(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((i)=>({name:i.operation,arguments:i.args}))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function v(e){w("BEGIN IMMEDIATE");try{e(),w("COMMIT")}catch(t){try{w("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function H(e,t){let i=x(e,["accounts"]);h("DELETE FROM accounts");for(let r of i){let d=_(r,{});if(!d)continue;let s=(n(r,["nickname","account_type","type"])||"").toUpperCase(),o=Y(r,["agentic_allowed","agenticAllowed"]),a=o?"AGENTIC":s.includes("IRA")||s.includes("RETIRE")?"RETIREMENT":s.includes("JOINT")?"JOINT":"PERSONAL";h("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at) VALUES(?,?,?,?,?,?,?)",[d,a,d.slice(-4),s,(n(r,["status"])||"active").toUpperCase(),o?1:0,t])}}function X(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood portfolio is missing account_number");let d=n(e,["cash","cash_available","withdrawable_amount"]),s=n(e,["buying_power","buyingPower"]),o=n(e,["day_pnl","dayPnl","equity_change"]),a=n(e,["week_pnl","weekPnl"]);h(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?,?,?) ON CONFLICT(account_number) DO UPDATE SET cash=excluded.cash,buying_power=excluded.buying_power, day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), - observed_at=excluded.observed_at`,[r,c,o,s,a,i]);let p=n(e,["total_value","equity","total_equity","portfolio_value","market_value"]);if(p!==null)h("INSERT OR REPLACE INTO total_value(account_number,observed_at,value) VALUES(?,?,?)",[r,i,p])}function J(e,t,i){let r=g(e,t);if(!r)throw Error("Robinhood positions are missing account_number");let c=q(e,["positions"]).slice(0,64);h("DELETE FROM positions WHERE account_number=?",[r]);for(let o of c){let s=n(o,["symbol"]);if(!s)continue;h("INSERT INTO positions(account_number,symbol,quantity,average_price,market_value,observed_at) VALUES(?,?,?,?,?,?)",[r,s,n(o,["quantity","shares"]),n(o,["average_price","averagePrice","average_buy_price"]),n(o,["market_value","marketValue","equity"]),i])}}function Z(e,t,i){let r=g(e,t);if(!r)throw Error("Robinhood activities are missing account_number");let c=q(e,["orders","activities","results"]).slice(0,64);h("DELETE FROM activities WHERE account_number=?",[r]),c.forEach((o,s)=>{let a=n(o,["symbol"]),p=(n(o,["side"])||"").toUpperCase(),d=n(o,["executed_quantity","cumulative_quantity","quantity"]),m=n(o,["average_price","averagePrice","executed_price","price"]),l=n(o,["last_transaction_at","created_at","updated_at","date"]),u=n(o,["id","order_id","orderId","activity_id"])||[l||i,a||"ORDER",p,s].join(":"),y=U(d),f=U(m),j=y!==null&&f!==null?String(y*f):m||d;h(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) - VALUES(?,?,?,?,?,?,?,?,?,?,?)`,[r,u,l,i,a,p,d,m,j,(n(o,["state","status"])||"RECENT").toUpperCase(),(n(o,["type","order_type"])||"ORDER").toUpperCase()])})}function $(e,t,i){let r=g(e,t);if(!r)throw Error("Robinhood P&L is missing account_number");let c=n(e,["total_returns","realized_pnl","total","amount","day_pnl","week_pnl"]),o=String(t?.span??"day");h(`INSERT INTO portfolio_current(account_number,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?) + observed_at=excluded.observed_at`,[r,d,s,o,a,i]);let p=n(e,["total_value","equity","total_equity","portfolio_value","market_value"]);if(p!==null)h("INSERT OR REPLACE INTO total_value(account_number,observed_at,value) VALUES(?,?,?)",[r,i,p])}function J(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood positions are missing account_number");let d=x(e,["positions"]).slice(0,64);h("DELETE FROM positions WHERE account_number=?",[r]);for(let s of d){let o=n(s,["symbol"]);if(!o)continue;h("INSERT INTO positions(account_number,symbol,quantity,average_price,market_value,observed_at) VALUES(?,?,?,?,?,?)",[r,o,n(s,["quantity","shares"]),n(s,["average_price","averagePrice","average_buy_price"]),n(s,["market_value","marketValue","equity"]),i])}}function Z(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood activities are missing account_number");let d=x(e,["orders","activities","results"]).slice(0,64);h("DELETE FROM activities WHERE account_number=?",[r]),d.forEach((s,o)=>{let a=n(s,["symbol"]),p=(n(s,["side"])||"").toUpperCase(),c=n(s,["executed_quantity","cumulative_quantity","quantity"]),m=n(s,["average_price","averagePrice","executed_price","price"]),l=n(s,["last_transaction_at","created_at","updated_at","date"]),u=n(s,["id","order_id","orderId","activity_id"])||[l||i,a||"ORDER",p,o].join(":"),y=I(c),g=I(m),C=y!==null&&g!==null?String(y*g):m||c;h(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) + VALUES(?,?,?,?,?,?,?,?,?,?,?)`,[r,u,l,i,a,p,c,m,C,(n(s,["state","status"])||"RECENT").toUpperCase(),(n(s,["type","order_type"])||"ORDER").toUpperCase()])})}function $(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood P&L is missing account_number");let d=n(e,["total_returns","realized_pnl","total","amount","day_pnl","week_pnl"]),s=String(t?.span??"day");h(`INSERT INTO portfolio_current(account_number,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?) ON CONFLICT(account_number) DO UPDATE SET day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), - observed_at=MAX(portfolio_current.observed_at,excluded.observed_at)`,[r,o==="week"?null:c,o==="week"?c:null,i])}function C(e){if(e.operation==="get_accounts")H(e.value,e.observedAt);else if(e.operation==="get_portfolio")X(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_positions")J(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_orders")Z(e.value,e.args,e.observedAt);else if(e.operation==="get_realized_pnl")$(e.value,e.args,e.observedAt);else return!1;return!0}function Q(e){let t=e.toLowerCase();return t.includes("esp_err_http_connect")||t.includes("timeout")||t.includes("tls")||t.includes("socket")||t.includes("network")}function S(){let e=_(),t=[],i=[],r=0,c=(a,p)=>{r+=1;try{let d=D(a,p);return t.push({operation:a,args:p,value:d,observedAt:_()}),d}catch(d){let m=d instanceof Error?d.message:String(d);if(i.push(a+": "+m),a==="get_accounts"||Q(m))throw d;return null}},o=null;try{let a=c("get_accounts",{}),d=q(a,["accounts"]).map((u)=>g(u,{})).filter(Boolean);if(!d.length)throw Error("Robinhood returned no brokerage accounts");let m=new Date((e-604800)*1000).toISOString().slice(0,10),l=[];for(let u of d){let y={account_number:u};l.push({operation:"get_portfolio",args:y},{operation:"get_equity_positions",args:y},{operation:"get_equity_orders",args:{...y,created_at_gte:m}},{operation:"get_realized_pnl",args:{...y,span:"day",asset_classes:["equity"]}},{operation:"get_realized_pnl",args:{...y,span:"week",asset_classes:["equity"]}})}r+=l.length;let P=W(l);if(P.length!==l.length)throw Error("Robinhood batch returned an incomplete result set");if(P.forEach((u,y)=>{let f=l[y];if(u?.ok)t.push({operation:f.operation,args:f.args,value:u.value,observedAt:_()});else i.push(f.operation+": "+String(u?.error||"unknown provider error"))}),!t.some((u)=>u.operation==="get_portfolio"))throw Error("Robinhood batch returned no portfolio data")}catch(a){o=a instanceof Error?a.message:String(a)}let s=o?"failed":i.length?"partial":"succeeded";if(I(()=>{if(!o)for(let a of t)C(a);h(`INSERT INTO refresh_runs(started_at,completed_at,status,operation_count,success_count,error) - VALUES(?,?,?,?,?,?)`,[e,_(),s,r,o?0:t.length,o||i.join(" | ")||null])}),o)throw Error(o);return{status:s,operationCount:r,successCount:t.length}}function K(e,t,i,r){let c=String(i?.account_number??"");if(!c)return;let s=String(i?.order_id??n(t,["order_id","orderId","id"])??"")||[r,i?.symbol||"EQUITY",e].join(":"),a=e==="cancel_equity_order"?n(t,["state","status"])||"CANCEL_REQUESTED":n(t,["state","status"])||"SUBMITTED";h(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) + observed_at=MAX(portfolio_current.observed_at,excluded.observed_at)`,[r,s==="week"?null:d,s==="week"?d:null,i])}function j(e){if(e.operation==="get_accounts")H(e.value,e.observedAt);else if(e.operation==="get_portfolio")X(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_positions")J(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_orders")Z(e.value,e.args,e.observedAt);else if(e.operation==="get_realized_pnl")$(e.value,e.args,e.observedAt);else return!1;return!0}function Q(e){let t=e.toLowerCase();return t.includes("esp_err_http_connect")||t.includes("timeout")||t.includes("tls")||t.includes("socket")||t.includes("network")}function S(){let e=f(),t=[],i=[],r=0,d=(a,p)=>{r+=1;try{let c=O(a,p);return t.push({operation:a,args:p,value:c,observedAt:f()}),c}catch(c){let m=c instanceof Error?c.message:String(c);if(i.push(a+": "+m),a==="get_accounts"||Q(m))throw c;return null}},s=null;try{let a=d("get_accounts",{}),c=x(a,["accounts"]).map((u)=>_(u,{})).filter(Boolean);if(!c.length)throw Error("Robinhood returned no brokerage accounts");let m=new Date((e-604800)*1000).toISOString().slice(0,10),l=[];for(let u of c){let y={account_number:u};l.push({operation:"get_portfolio",args:y},{operation:"get_equity_positions",args:y},{operation:"get_equity_orders",args:{...y,created_at_gte:m}},{operation:"get_realized_pnl",args:{...y,span:"day",asset_classes:["equity"]}},{operation:"get_realized_pnl",args:{...y,span:"week",asset_classes:["equity"]}})}r+=l.length;let P=W(l);if(P.length!==l.length)throw Error("Robinhood batch returned an incomplete result set");if(P.forEach((u,y)=>{let g=l[y];if(u?.ok)t.push({operation:g.operation,args:g.args,value:u.value,observedAt:f()});else i.push(g.operation+": "+String(u?.error||"unknown provider error"))}),!t.some((u)=>u.operation==="get_portfolio"))throw Error("Robinhood batch returned no portfolio data")}catch(a){s=a instanceof Error?a.message:String(a)}let o=s?"failed":i.length?"partial":"succeeded";if(v(()=>{if(!s)for(let a of t)j(a);h(`INSERT INTO refresh_runs(started_at,completed_at,status,operation_count,success_count,error) + VALUES(?,?,?,?,?,?)`,[e,f(),o,r,s?0:t.length,s||i.join(" | ")||null])}),s)throw Error(s);return{status:o,operationCount:r,successCount:t.length}}function K(e,t,i,r){let d=String(i?.account_number??"");if(!d)return;let o=String(i?.order_id??n(t,["order_id","orderId","id"])??"")||[r,i?.symbol||"EQUITY",e].join(":"),a=e==="cancel_equity_order"?n(t,["state","status"])||"CANCEL_REQUESTED":n(t,["state","status"])||"SUBMITTED";h(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) VALUES(?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(account_number,activity_id) DO UPDATE SET occurred_at=COALESCE(excluded.occurred_at,activities.occurred_at), @@ -247,4 +244,4 @@ Returns the scan with its new filters and fresh live results. This changes Robin quantity=COALESCE(excluded.quantity,activities.quantity), price=COALESCE(excluded.price,activities.price), state=excluded.state, - activity_type=excluded.activity_type`,[c,s,n(t,["created_at","updated_at","last_transaction_at"]),r,i?.symbol??n(t,["symbol"]),i?.side??n(t,["side"]),i?.quantity??i?.dollar_amount??n(t,["quantity","executed_quantity"]),i?.limit_price??i?.stop_price??n(t,["price","average_price"]),i?.dollar_amount??null,String(a).toUpperCase(),e==="cancel_equity_order"?"EQUITY ORDER CANCEL":"EQUITY ORDER"])}function ee(e,t){let i=D(e,t),r={operation:e,args:t,value:i,observedAt:_()};if(["get_accounts","get_portfolio","get_equity_positions","get_equity_orders","get_realized_pnl"].includes(e))I(()=>C(r));if(e==="place_equity_order"||e==="cancel_equity_order")I(()=>K(e,i,t,r.observedAt));return i}function R(e){return JSON.stringify({text:JSON.stringify(e),isError:!1})}globalThis.PocketPiData={invokeTask(e){try{if(e!=="refreshPortfolio")throw Error("Unknown Robinhood Data Action: "+e);let t=S();return R(t)}catch(t){return JSON.stringify({text:t instanceof Error?t.message:String(t),isError:!0})}},invokeTool(e,t){try{let i=JSON.parse(t),r=e==="robinhood.refresh_portfolio"?S():e==="robinhood.search_tools"?z(i):e==="robinhood.call"?B(i):(()=>{throw Error("Unknown Robinhood Tool: "+e)})();return R(r)}catch(i){return JSON.stringify({text:i instanceof Error?i.message:String(i),isError:!0})}}};})(); + activity_type=excluded.activity_type`,[d,o,n(t,["created_at","updated_at","last_transaction_at"]),r,i?.symbol??n(t,["symbol"]),i?.side??n(t,["side"]),i?.quantity??i?.dollar_amount??n(t,["quantity","executed_quantity"]),i?.limit_price??i?.stop_price??n(t,["price","average_price"]),i?.dollar_amount??null,String(a).toUpperCase(),e==="cancel_equity_order"?"EQUITY ORDER CANCEL":"EQUITY ORDER"])}function ee(e,t){let i=O(e,t),r={operation:e,args:t,value:i,observedAt:f()};if(["get_accounts","get_portfolio","get_equity_positions","get_equity_orders","get_realized_pnl"].includes(e))v(()=>j(r));if(e==="place_equity_order"||e==="cancel_equity_order")v(()=>K(e,i,t,r.observedAt));return i}function R(e){return JSON.stringify({text:JSON.stringify(e),isError:!1})}globalThis.PocketPiData={invokeTask(e){try{if(e!=="refreshPortfolio")throw Error("Unknown Robinhood Data Action: "+e);let t=S();return R(t)}catch(t){return JSON.stringify({text:t instanceof Error?t.message:String(t),isError:!0})}},invokeTool(e,t){try{let i=JSON.parse(t),r=e==="robinhood.refresh_portfolio"?S():e==="robinhood.search_tools"?G(i):e==="robinhood.call"?z(i):(()=>{throw Error("Unknown Robinhood Tool: "+e)})();return R(r)}catch(i){return JSON.stringify({text:i instanceof Error?i.message:String(i),isError:!0})}}};})(); diff --git a/apps/robinhood/tool-catalog.json b/apps/robinhood/tool-catalog.json index 8bec694..6f95cc9 100644 --- a/apps/robinhood/tool-catalog.json +++ b/apps/robinhood/tool-catalog.json @@ -6,7 +6,7 @@ { "name": "add_option_to_watchlist", "namespace": "option_market_data", - "description": "Add option contracts to the user's options watchlist. Works for both equity options (AAPL, NVDA) and index options (SPX, NDX, RUT). Source option_ids from get_option_instruments. Confirm with the user before calling — this is a real write. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Add option contracts to the user's options watchlist. Works for both equity options (AAPL, NVDA) and index options (SPX, NDX, RUT). Source option_ids from get_option_instruments. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { @@ -34,7 +34,7 @@ { "name": "add_to_watchlist", "namespace": "watchlists", - "description": "Add items to a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes like SPX, NDX) is required — mutually exclusive. For options use add_option_to_watchlist (separate dedicated watchlist). Futures still require the Robinhood app. Already-present items are no-ops. Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Add items to a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes like SPX, NDX) is required — mutually exclusive. For options use add_option_to_watchlist (separate dedicated watchlist). Futures still require the Robinhood app. Already-present items are no-ops. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { @@ -82,13 +82,13 @@ { "name": "cancel_equity_order", "namespace": "equity_trading", - "description": "Cancel an open equity order by order_id. Always confirm with the user before calling. Resolve order_id via get_equity_orders if the user refers to it by symbol or description; pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected — do not call. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. REAL ACCOUNT ACTION: use only for the exact user-authorized account and order or exercise identifier; confirm the final provider state afterward. After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.", + "description": "Cancel an open equity order by order_id. Resolve order_id via get_equity_orders and pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.", "inputSchema": { "type": "object", "properties": { "account_number": { "type": "string", - "description": "Brokerage account that owns the order. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true. The upstream rejects mismatches against the order's owning account." + "description": "Brokerage account that owns the order, from get_accounts. Must be agentic_allowed=true. The upstream rejects mismatches against the order's owning account." }, "order_id": { "type": "string", @@ -105,7 +105,7 @@ { "name": "cancel_option_exercise", "namespace": "option_trading", - "description": "Cancel all queued exercise requests for an option position. Pass the same account_number and option_id used for exercise_option. Internally looks up all queued exercise events for that option and cancels each one. Typically there is one; multiple means the user submitted separate exercise batches. Only cancels events in state=queued — events already processing are rejected by the broker. Always confirm with the user before calling. REAL ACCOUNT ACTION: use only for the exact user-authorized account and order or exercise identifier; confirm the final provider state afterward. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Cancel all queued exercise requests for an option position. Pass the same account_number and option_id used for exercise_option. Internally looks up all queued exercise events for that option and cancels each one. Typically there is one; multiple means separate exercise batches were submitted. Only events in state=queued can be cancelled; events already processing are rejected by the broker. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { @@ -128,13 +128,13 @@ { "name": "cancel_option_order", "namespace": "option_trading", - "description": "Cancel an open option order by account_number + order_id. Always confirm with the user before calling. Resolve order_id via get_option_orders if the user refers to it by description; pass the same account_number you used there. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. REAL ACCOUNT ACTION: use only for the exact user-authorized account and order or exercise identifier; confirm the final provider state afterward. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Cancel an open option order by account_number + order_id. Resolve order_id via get_option_orders and pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { "account_number": { "type": "string", - "description": "Brokerage account that owns the order. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true. Mismatches against the order's owning account are rejected." + "description": "Brokerage account that owns the order, from get_accounts. Must be agentic_allowed=true. Mismatches against the order's owning account are rejected." }, "order_id": { "type": "string", @@ -227,7 +227,7 @@ { "name": "create_watchlist", "namespace": "watchlists", - "description": "Create a new custom watchlist for the user. Confirm the name with the user before calling — this is a real write. Do not use this to follow a Robinhood-curated list (use follow_watchlist). This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Create a new custom watchlist. Do not use this to follow a Robinhood-curated list; use follow_watchlist instead. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { @@ -253,7 +253,7 @@ { "name": "exercise_option", "namespace": "option_trading", - "description": "Exercise a long options position — a call exercises the right to buy the underlying shares at the strike price; a put exercises the right to sell. Exercise is irrevocable once state moves past queued.\n\nNever call this tool without asking the user to explicitly confirm the specific exercise first: state the option, quantity, and expected cash impact (debit for calls, credit for puts), then wait for their affirmative reply before calling. The user's original request to exercise is NOT itself sufficient confirmation — a generic \"exercise my calls\" does not confirm a specific option and quantity.\n\nPosition requirements: confirm via get_option_positions that the position type=long and quantity > 0.\n\nAccount requirements: confirm via get_accounts that the chosen account is agentic_allowed=true AND has option_level_2 or option_level_3. If agentic_allowed=false do NOT call. If option_level is empty or option_level_0, do NOT call; follow the get_accounts guide for how to direct the user to enroll.\n\nIndex options cannot be manually exercised and will be rejected. Exercises submitted during market hours execute the same day; requests submitted after market close — including on late-close trading days — are queued for overnight processing.\n\nParameter rules:\n- quantity must be a positive integer and cannot exceed the position's available contracts.\n- allow_shorts=true only applies to PUT exercises where the account does not own enough shares to deliver. Require explicit user confirmation before setting this — it creates a short equity position in the underlying stock.\n- reason is optional but recommended; collect it from the user when they volunteer a motivation.\n- ref_id: use the same UUID on retries of the same logical exercise; use a new UUID for a new exercise. REAL-MONEY ACTION: use only after the user explicitly authorizes the exact account, instrument, side, size, order type, price constraints, and timing. Use the dedicated Agentic account and reuse one ref_id for retries. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Exercise a long options position. A call exercises the right to buy the underlying shares at the strike price; a put exercises the right to sell. Exercise is irrevocable once state moves past queued.\n\nPosition requirements: get_option_positions must show type=long and quantity > 0.\n\nAccount requirements: get_accounts must show agentic_allowed=true and option_level_2 or option_level_3. Non-agentic and option_level_0 accounts are rejected.\n\nIndex options cannot be manually exercised. Exercises submitted during market hours execute the same day; requests submitted after market close, including late-close trading days, are queued for overnight processing.\n\nParameter rules:\n- quantity must be a positive integer no greater than the available contracts.\n- allow_shorts=true applies only to put exercises when the account lacks enough shares to deliver; it creates a short equity position in the underlying stock.\n- reason is an optional explanation for the exercise.\n- ref_id must reuse the same UUID when retrying the same logical exercise and use a new UUID for a new exercise.\n\nPocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { @@ -279,7 +279,7 @@ }, "allow_shorts": { "type": "boolean", - "description": "When true, allows a PUT exercise to proceed even when the account does not own enough shares to deliver — creating a short equity position. Requires explicit user confirmation that they intend to short the underlying stock. Default false." + "description": "When true, allows a put exercise to proceed when the account does not own enough shares to deliver, creating a short equity position in the underlying stock. Default false." } }, "required": [ @@ -293,7 +293,7 @@ { "name": "follow_watchlist", "namespace": "watchlists", - "description": "Follow a Robinhood-curated list so it appears in the user's watchlists. Confirm with the user before calling. Use only for curated lists; the user already owns their custom lists. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Follow a Robinhood-curated list so it appears in the user's watchlists. Use only for curated lists; custom lists are already owned by the user. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { @@ -311,7 +311,7 @@ { "name": "get_accounts", "namespace": "account_portfolio", - "description": "List the user's brokerage accounts. Use this to look up account_number values needed by other tools. If the user has multiple accounts and hasn't specified which one, present the list and ask them to choose. Does NOT return reliable buying power — route buying-power questions through get_portfolio. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.", + "description": "List the user's brokerage accounts and return the account_number and capabilities needed by other tools. Does not return reliable buying power; use get_portfolio for buying power. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.", "inputSchema": { "type": "object", "additionalProperties": false @@ -440,7 +440,7 @@ "properties": { "account_number": { "type": "string", - "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts." + "description": "Brokerage account number from get_accounts." }, "order_id": { "type": "string", @@ -482,7 +482,7 @@ "properties": { "account_number": { "type": "string", - "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts." + "description": "Brokerage account number from get_accounts." }, "cursor": { "type": "string", @@ -552,7 +552,7 @@ "properties": { "account_number": { "type": "string", - "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts." + "description": "Brokerage account number from get_accounts." }, "symbol": { "type": "string", @@ -674,7 +674,7 @@ "properties": { "account_number": { "type": "string", - "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts." + "description": "Brokerage account number from get_accounts." }, "symbols": { "type": [ @@ -955,7 +955,7 @@ "properties": { "account_number": { "type": "string", - "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts." + "description": "Brokerage account number from get_accounts." }, "order_id": { "type": "string", @@ -1001,7 +1001,7 @@ "properties": { "account_number": { "type": "string", - "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts." + "description": "Brokerage account number from get_accounts." }, "nonzero": { "type": "boolean", @@ -1232,13 +1232,13 @@ { "name": "place_equity_order", "namespace": "equity_trading", - "description": "Place a real equity order with real money. Parameters mirror review_equity_order plus the optional ref_id. Requires an agentic_allowed=true account; non-agentic accounts are rejected — do not call.\n\nWorkflow: by default call review_equity_order first, present the estimated cost and any alerts, and get explicit user confirmation before calling this tool. Skip review only when the user has very explicitly asked to bypass it (e.g. \"skip the review\", \"just place it, don't review\") — a generic \"place this order\" is NOT a bypass.\n\nIdempotency: pass a fresh UUID as ref_id on the first call for each logical order, and re-send the SAME ref_id on retries of transient transport failures. Use a new ref_id only when the user wants a new order.\n\nParameter rules:\n- If the user has not specified type, ask. For immediate fills with price protection, prefer a marketable limit at the current ask over a plain market.\n- Outside regular hours, only limit orders execute. For an immediate fill during extended or overnight/24-hour sessions, place a limit order (a marketable limit at the current ask) with market_hours set to that session — not a market order. Market and stop orders are regular_hours-only; placed after hours as regular_hours they queue for the next regular open.\n- Provide exactly one of quantity or dollar_amount; dollar_amount requires type=market (server computes shares from last_trade_price).\n- Fractional shares: only on type=market with market_hours=regular_hours, eligible accounts, up to 6 decimal places, no short sells.\n- limit_price required for limit/stop_limit; stop_price required for stop_market/stop_limit.\n- Fractional and dollar-based orders only place in regular_hours; the tool rejects them in other sessions.\n- tax_lots (specified-lot selling, sell only): to sell specific lots, first call get_equity_tax_lots for the symbol, then pass tax_lots as {open_lot_id, quantity} pairs whose quantities sum to the order quantity. Omit for default (FIFO) cost basis. US accounts only; not allowed with dollar_amount, stop orders, all_day_hours, or fractional limit orders. REAL-MONEY ACTION: use only after the user explicitly authorizes the exact account, instrument, side, size, order type, price constraints, and timing. Use the dedicated Agentic account and reuse one ref_id for retries. After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.", + "description": "Place a real equity order with real money. Parameters mirror review_equity_order plus the optional ref_id. Requires an agentic_allowed=true account; non-agentic accounts are rejected.\n\nCall review_equity_order first to obtain the current quote, estimated cost, and pre-trade alerts.\n\nIdempotency: pass a fresh UUID as ref_id on the first call for each logical order and re-send the same ref_id after a transient transport failure. Use a new ref_id only for a new logical order.\n\nParameter rules:\n- For immediate fills with price protection, prefer a marketable limit at the current ask over a plain market.\n- Outside regular hours, only limit orders execute. For an immediate fill during extended or overnight/24-hour sessions, place a limit order with market_hours set to that session. Market and stop orders are regular_hours-only; regular-hours orders placed after hours queue for the next regular open.\n- Provide exactly one of quantity or dollar_amount; dollar_amount requires type=market.\n- Fractional shares are supported only for type=market with market_hours=regular_hours on eligible accounts, up to 6 decimal places, with no short sells.\n- limit_price is required for limit and stop_limit; stop_price is required for stop_market and stop_limit.\n- Fractional and dollar-based orders are regular-hours only.\n- tax_lots is sell-only specified-lot selection. Obtain open_lot_id values from get_equity_tax_lots and pass quantities that sum to the order quantity. It is limited to US accounts and cannot be combined with dollar_amount, stop orders, all_day_hours, or fractional limit orders.\n\nAfter the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.", "inputSchema": { "type": "object", "properties": { "account_number": { "type": "string", - "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true; non-agentic accounts are rejected." + "description": "Brokerage account number from get_accounts. Must be agentic_allowed=true; non-agentic accounts are rejected." }, "symbol": { "type": "string", @@ -1318,13 +1318,13 @@ { "name": "place_option_order", "namespace": "option_trading", - "description": "Place a real options order with real money.\n\nWorkflow: by default call review_option_order first, present the alerts, fees, collateral, and quote, and get explicit user confirmation before calling this tool. Skip review only when the user has very explicitly asked to bypass it (e.g. \"skip the review\", \"just place it, don't review\") — a generic \"place this order\" is NOT a bypass.\n\nCapability: single-leg options orders — Level 2 strategies (covered calls, cash-secured puts, long calls and puts). Multi-leg spreads (Level 3 strategies) are supported on option_level_3 accounts.\n\nAccount requirements: confirm via get_accounts that the chosen account is agentic_allowed=true AND has option_level_2 or option_level_3. If agentic_allowed=false do NOT call. If option_level is empty or option_level_0, do NOT call; follow the get_accounts guide for how to direct the user to enroll.\n\nAlert handling: pre-trade alerts surface only in review_option_order. After the user has acknowledged the reviewed alert, call this tool with the same parameters.\n\nIdempotency: pass a fresh UUID as ref_id on the first call for each logical order, and re-send the SAME ref_id on retries of transient transport failures. Use a new ref_id only when the user wants a new order.\n\nTo find option_id: get_option_chains → get_option_instruments filtered by expiration_date/strike_price/type.\n\nParameter rules:\n- Multi-leg leg layouts — vertical spread: two legs, same expiration, different strikes, opposite sides. Calendar: two legs, same strike, different expirations. Iron condor: four legs, a put spread plus a call spread. Roll: close the leg you hold (position_effect 'close', side opposite the position) plus open the replacement ('open').\n- Get the net price from the user rather than inferring it from individual leg quotes.\n- Multi-leg is not available on cash or retirement accounts through this tool.\n- type: 'limit' (default), 'market', 'stop_limit', 'stop_market'. price for limit/stop_limit; stop_price for stop_market/stop_limit.\n- market, stop_market, and stop_limit are single-leg only. market and stop_market are also regular_hours, GFD only. stop_market is sell-to-close only with stop_price below the current ask.\n\nNot currently supported anywhere (including the Robinhood apps):\n- combo orders. At Robinhood, \"combo\" specifically means a stock-option combo: one option leg paired with 100 shares of the underlying equity. In broader industry use, \"combo\" without qualifier sometimes refers to multi-leg option structures. REAL-MONEY ACTION: use only after the user explicitly authorizes the exact account, instrument, side, size, order type, price constraints, and timing. Use the dedicated Agentic account and reuse one ref_id for retries. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Place a real options order with real money. Call review_option_order first to obtain the current quote, fees, collateral, and pre-trade alerts.\n\nCapability: single-leg Level 2 strategies include covered calls, cash-secured puts, long calls, and long puts. Multi-leg Level 3 strategies require an option_level_3 account. The account must also have agentic_allowed=true.\n\nIdempotency: pass a fresh UUID as ref_id on the first call for each logical order and re-send the same ref_id after a transient transport failure. Use a new ref_id only for a new logical order.\n\nResolve option_id through get_option_chains and get_option_instruments filtered by expiration_date, strike_price, and type.\n\nParameter rules:\n- A vertical spread has two opposite-side legs with the same expiration and different strikes. A calendar has the same strike and different expirations. An iron condor combines a put spread and call spread. A roll closes the existing leg and opens its replacement.\n- Use the reviewed current strategy quote as the net price; do not sum stale individual-leg quotes.\n- Multi-leg orders are unavailable on cash and retirement accounts through this tool.\n- type supports limit (default), market, stop_limit, and stop_market. price is required for limit and stop_limit; stop_price is required for stop_market and stop_limit.\n- market, stop_market, and stop_limit are single-leg only. market and stop_market are regular-hours GFD only. stop_market is sell-to-close only with stop_price below the current ask.\n- Stock-option combo orders, meaning one option leg paired with 100 underlying shares, are not supported.\n\nPocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { "account_number": { "type": "string", - "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true." + "description": "Brokerage account number from get_accounts. Must be agentic_allowed=true." }, "legs": { "type": [ @@ -1358,7 +1358,7 @@ ], "additionalProperties": false }, - "description": "1 to 4 legs, all on the same underlying and each a different contract. Several legs are filled together as one strategy. Should match the legs the user reviewed." + "description": "1 to 4 legs, all on the same underlying and each a different contract. Several legs are filled together as one strategy. Must match the preceding review request." }, "direction": { "type": "string", @@ -1366,7 +1366,7 @@ }, "type": { "type": "string", - "description": "'limit' (default), 'market', 'stop_limit', or 'stop_market'. Should match the type the user reviewed. Only 'limit' is available with 2 or more legs." + "description": "'limit' (default), 'market', 'stop_limit', or 'stop_market'. Must match the preceding review request. Only 'limit' is available with 2 or more legs." }, "quantity": { "type": "string", @@ -1404,7 +1404,7 @@ { "name": "remove_from_watchlist", "namespace": "watchlists", - "description": "Remove items from a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes) is required — mutually exclusive. For options use remove_option_from_watchlist. Items not on the list are no-ops (not errors). Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Remove items from a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes) is required. For options use remove_option_from_watchlist. Items not on the list are no-ops. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { @@ -1452,7 +1452,7 @@ { "name": "remove_option_from_watchlist", "namespace": "option_market_data", - "description": "Remove option contracts from the user's options watchlist. Specify the same position_type used when the contract was added (defaults to \"long\"). Contracts not on the list are no-ops. Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Remove option contracts from the user's options watchlist. Specify the same position_type used when the contract was added; it defaults to \"long\". Contracts not on the list are no-ops. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { @@ -1480,13 +1480,13 @@ { "name": "review_equity_order", "namespace": "equity_trading", - "description": "Simulate a stock order without placing it. Returns the current quote plus pre-trade alerts (buying power, PDT, instrument halt, etc.). Call this by default before place_equity_order unless the user has very explicitly asked to skip review. Requires an agentic_allowed=true account; non-agentic accounts are rejected — do not call.\n\nParameter rules:\n- If the user has not specified type, ask. For immediate fills with price protection, prefer a marketable limit at the current ask over a plain market.\n- Outside regular hours, only limit orders execute. For an immediate fill during extended or overnight/24-hour sessions, place a limit order (a marketable limit at the current ask) with market_hours set to that session — not a market order. Market and stop orders are regular_hours-only; placed after hours as regular_hours they queue for the next regular open.\n- Provide exactly one of quantity or dollar_amount; dollar_amount requires type=market (server computes shares from last_trade_price).\n- Fractional shares: only on type=market with market_hours=regular_hours, eligible accounts, up to 6 decimal places, no short sells.\n- limit_price required for limit/stop_limit; stop_price required for stop_market/stop_limit.\n- Fractional and dollar-based orders only place in regular_hours; the tool rejects them in other sessions.\n- tax_lots (specified-lot selling, sell only): to sell specific lots, first call get_equity_tax_lots for the symbol, then pass tax_lots as {open_lot_id, quantity} pairs whose quantities sum to the order quantity. Omit for default (FIFO) cost basis. US accounts only; not allowed with dollar_amount, stop orders, all_day_hours, or fractional limit orders. This is a non-submitting pre-trade simulation. Review warnings and estimated cost before asking for authorization to use the corresponding place tool. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Simulate a stock order without placing it. Returns the current quote, estimated cost, and pre-trade alerts such as buying power, PDT, and instrument halts. Use it before place_equity_order. Requires an agentic_allowed=true account; non-agentic accounts are rejected.\n\nParameter rules:\n- For immediate fills with price protection, prefer a marketable limit at the current ask over a plain market.\n- Outside regular hours, only limit orders execute. Extended-hours and overnight orders must set the corresponding market_hours session. Market and stop orders are regular_hours-only.\n- Provide exactly one of quantity or dollar_amount; dollar_amount requires type=market.\n- Fractional shares are supported only for type=market with market_hours=regular_hours on eligible accounts, up to 6 decimal places, with no short sells.\n- limit_price is required for limit and stop_limit; stop_price is required for stop_market and stop_limit.\n- tax_lots is sell-only specified-lot selection using open_lot_id values from get_equity_tax_lots. The lot quantities must sum to the order quantity. It is limited to US accounts and cannot be combined with dollar_amount, stop orders, all_day_hours, or fractional limit orders.\n\nThis tool does not submit the order. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { "account_number": { "type": "string", - "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true; non-agentic accounts are rejected." + "description": "Brokerage account number from get_accounts. Must be agentic_allowed=true; non-agentic accounts are rejected." }, "symbol": { "type": "string", @@ -1562,13 +1562,13 @@ { "name": "review_option_order", "namespace": "option_trading", - "description": "Simulate an options order without placing it. Returns the current quote plus pre-trade alerts. Call this by default before place_option_order or replace_option_order unless the user has very explicitly asked to skip review.\n\nCapability: single-leg options orders — Level 2 strategies (covered calls, cash-secured puts, long calls and puts). Multi-leg spreads (Level 3 strategies) are supported on option_level_3 accounts.\n\nAccount requirements: confirm via get_accounts that the chosen account is agentic_allowed=true AND has option_level_2 or option_level_3. If agentic_allowed=false do NOT call. If option_level is empty or option_level_0, do NOT call; follow the get_accounts guide for how to direct the user to enroll.\n\nParameter rules:\n- legs: option_id (from get_option_instruments), side, position_effect, optional ratio_quantity per leg.\n- Multi-leg leg layouts — vertical spread: two legs, same expiration, different strikes, opposite sides. Calendar: two legs, same strike, different expirations. Iron condor: four legs, a put spread plus a call spread. Roll: close the leg you hold (position_effect 'close', side opposite the position) plus open the replacement ('open').\n- Get the net price from the user rather than inferring it from individual leg quotes.\n- Multi-leg is not available on cash or retirement accounts through this tool.\n- type: 'limit' (default), 'market', 'stop_limit', 'stop_market'. If unspecified, ask. price for limit/stop_limit; stop_price for stop_market/stop_limit.\n- market, stop_market, and stop_limit are single-leg only. market and stop_market are also GFD, regular_hours only. stop_market is sell-to-close only with stop_price below the current ask. Non-limit-immediate types are blocked in any extended-hours session.\n- Surface order_checks alerts verbatim — the detail strings carry the actual time/contract/BP values for the user. This is a non-submitting pre-trade simulation. Review warnings and estimated cost before asking for authorization to use the corresponding place tool. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Simulate an options order without placing it. Returns the current strategy quote, fees, collateral, and pre-trade alerts. Use it before place_option_order.\n\nCapability: single-leg Level 2 strategies include covered calls, cash-secured puts, long calls, and long puts. Multi-leg Level 3 strategies require an option_level_3 account. The account must also have agentic_allowed=true.\n\nParameter rules:\n- legs contain option_id from get_option_instruments, side, position_effect, and optional ratio_quantity.\n- A vertical spread has two opposite-side legs with the same expiration and different strikes. A calendar has the same strike and different expirations. An iron condor combines a put spread and call spread. A roll closes the existing leg and opens its replacement.\n- Use the current strategy quote as the net price; do not sum stale individual-leg quotes.\n- Multi-leg orders are unavailable on cash and retirement accounts through this tool.\n- type supports limit (default), market, stop_limit, and stop_market. price is required for limit and stop_limit; stop_price is required for stop_market and stop_limit.\n- market, stop_market, and stop_limit are single-leg only. market and stop_market are regular-hours GFD only. stop_market is sell-to-close only with stop_price below the current ask. Other non-limit-immediate types are blocked in extended-hours sessions.\n- order_checks contains the broker's time, contract, and buying-power alerts.\n\nThis tool does not submit the order. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { "account_number": { "type": "string", - "description": "Brokerage account number. Must come from the user or be clearly implied — never default from get_accounts. Must be agentic_allowed=true." + "description": "Brokerage account number from get_accounts. Must be agentic_allowed=true." }, "legs": { "type": [ @@ -1696,7 +1696,7 @@ { "name": "unfollow_watchlist", "namespace": "watchlists", - "description": "Stop following a Robinhood-curated list. The list itself is unchanged — it just no longer appears in the user's watchlists. Confirm with the user before calling. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Stop following a Robinhood-curated list. The list itself is unchanged and no longer appears in the user's watchlists. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { diff --git a/crates/pocket-pi-agentos/src/lib.rs b/crates/pocket-pi-agentos/src/lib.rs index 2c854a5..2486755 100644 --- a/crates/pocket-pi-agentos/src/lib.rs +++ b/crates/pocket-pi-agentos/src/lib.rs @@ -1768,20 +1768,6 @@ mod tests { } assert_eq!(namespace_counts.len(), 8); assert!(namespace_counts.values().all(|count| *count <= 9)); - let description = |name: &str| { - snapshot["tools"] - .as_array() - .unwrap() - .iter() - .find(|tool| tool["name"] == name) - .unwrap()["description"] - .as_str() - .unwrap() - }; - assert!(description("place_equity_order").contains("REAL-MONEY ACTION")); - assert!(description("place_equity_order").contains("explicitly authorizes")); - assert!(description("review_equity_order").contains("non-submitting")); - let robinhood = catalog .descriptors() .find(|descriptor| descriptor.id == ROBINHOOD_APP_ID) From 03c35b115a34690039910cfadda9660e0c6b3af9 Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Tue, 11 Aug 2026 15:06:42 +0800 Subject: [PATCH 14/24] fix(esp32): retry stale model connection once --- firmware/esp32-p4/src/backend/wireless.rs | 73 +++++++++++++++-------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/firmware/esp32-p4/src/backend/wireless.rs b/firmware/esp32-p4/src/backend/wireless.rs index d19c2df..cb68b50 100644 --- a/firmware/esp32-p4/src/backend/wireless.rs +++ b/firmware/esp32-p4/src/backend/wireless.rs @@ -69,19 +69,19 @@ impl WirelessBackend { body: &str, headers: &[(&str, &str)], on_event: &mut dyn FnMut(ModelStreamEvent), - ) -> Result { + ) -> Result { let mut request = client .request(Method::Post, endpoint, headers) - .map_err(|error| format!("create model request: {error}"))?; + .map_err(|error| SendError::BeforeResponse(format!("create model request: {error}")))?; request .write_all(body.as_bytes()) - .map_err(|error| format!("write model request: {error}"))?; + .map_err(|error| SendError::BeforeResponse(format!("write model request: {error}")))?; request .flush() - .map_err(|error| format!("flush model request: {error}"))?; + .map_err(|error| SendError::BeforeResponse(format!("flush model request: {error}")))?; let mut response = request .submit() - .map_err(|error| format!("send model request: {error}"))?; + .map_err(|error| SendError::BeforeResponse(format!("send model request: {error}")))?; let status = response.status(); let mut decoder = match self.provider { WirelessProvider::Anthropic => ProviderStream::Anthropic(Default::default()), @@ -97,30 +97,32 @@ impl WirelessBackend { loop { let count = response .read(&mut chunk) - .map_err(|error| format!("read model stream: {error}"))?; + .map_err(|error| SendError::AfterResponse(format!("read model stream: {error}")))?; if count == 0 { break; } pending.extend_from_slice(&chunk[..count]); if (200..300).contains(&status) { - drain_sse_lines(&mut pending, &mut decoder, on_event)?; + drain_sse_lines(&mut pending, &mut decoder, on_event) + .map_err(SendError::AfterResponse)?; } } if !(200..300).contains(&status) { - return Err(format!( + return Err(SendError::AfterResponse(format!( "{} returned HTTP {status}: {}", self.provider.id(), String::from_utf8_lossy(&pending) .chars() .take(400) .collect::() - )); + ))); } if !pending.is_empty() { pending.push(b'\n'); - drain_sse_lines(&mut pending, &mut decoder, on_event)?; + drain_sse_lines(&mut pending, &mut decoder, on_event) + .map_err(SendError::AfterResponse)?; } - decoder.finish() + decoder.finish().map_err(SendError::AfterResponse) } } @@ -153,24 +155,47 @@ impl ModelBackend for WirelessBackend { MODEL_CLIENT.with(|slot| { let mut client = slot.borrow_mut(); - if client.is_none() { - *client = Some(Self::connect()?); - } - let result = self.send( - client.as_mut().unwrap(), - endpoint, - &body, - &headers, - on_event, - ); - if result.is_err() { - *client = None; + let mut retried = false; + loop { + if client.is_none() { + *client = Some(Self::connect()?); + } + match self.send( + client.as_mut().unwrap(), + endpoint, + &body, + &headers, + on_event, + ) { + Ok(value) => return Ok(value), + Err(SendError::BeforeResponse(error)) if !retried => { + log::warn!("model transport retry after: {error}"); + *client = None; + retried = true; + } + Err(error) => { + *client = None; + return Err(error.message()); + } + } } - result }) } } +enum SendError { + BeforeResponse(String), + AfterResponse(String), +} + +impl SendError { + fn message(self) -> String { + match self { + Self::BeforeResponse(message) | Self::AfterResponse(message) => message, + } + } +} + fn drain_sse_lines( pending: &mut Vec, decoder: &mut ProviderStream, From c031e188418e7042532ae41fe3da0e88d3a601a3 Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Tue, 11 Aug 2026 15:08:12 +0800 Subject: [PATCH 15/24] fix(ui): wrap and truncate next wake preview --- apps/pi-agent/app.tsx | 11 ++++++++++- apps/pi-agent/dist/app.js | 24 ++++++++++++------------ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/apps/pi-agent/app.tsx b/apps/pi-agent/app.tsx index 405b9e7..66e0942 100644 --- a/apps/pi-agent/app.tsx +++ b/apps/pi-agent/app.tsx @@ -146,6 +146,15 @@ function BottomBar() { function ChatScreen() { const schedule = () => projection().schedule; + const schedulePreview = () => { + const current = schedule(); + return wrapPreview( + String(current?.name) + " " + String(current?.next ?? "") + "\n\n" + String(current?.prompt ?? ""), + FONT_BODY, + CHAT_TEXT_WIDTH, + 5, + ); + }; return (

@@ -176,7 +185,7 @@ function ChatScreen() { {"NO WAKE SCHEDULED\n\nASK PI TO CREATE ONE WITH SCHEDULE.SET"} }> - {String(schedule()?.name) + " " + String(schedule()?.next ?? "") + "\n\n" + String(schedule()?.prompt ?? "")} + {schedulePreview()} diff --git a/apps/pi-agent/dist/app.js b/apps/pi-agent/dist/app.js index c8654cb..e8ecdac 100644 --- a/apps/pi-agent/dist/app.js +++ b/apps/pi-agent/dist/app.js @@ -1,16 +1,16 @@ -(()=>{var AJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return H1(this.context.count)},getNextContextId(){return H1(this.context.count++)}};function H1(J){let Q=String(J),$=Q.length-1;return AJ.context.id+($?String.fromCharCode(96+$):"")+Q}function B1(J){AJ.context=J}function Y6(){return{...AJ.context,id:AJ.getNextContextId(),count:0}}var z6=!1,W6=(J,Q)=>J===Q,k0=Symbol("solid-proxy"),G6=typeof Proxy==="function",H6=Symbol("solid-track"),KQ=Symbol("solid-dev-component"),oJ={equals:W6},j1=null,B6=D1,m=1,fJ=2,F1={owned:null,cleanups:null,context:null,owner:null},S=null,F=null,yJ=null,_J=null,b=null,C=null,T=null,nJ=0;function tJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?F1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>JJ(()=>QJ(z)));S=z,b=null;try{return c(G,!0)}finally{b=$,S=Z}}function g(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(F&&F.running&&F.sources.has($))q=q($.tValue);else q=q($.value);return U1($,q)};return[M1.bind($),Z]}function e(J,Q,$){let Z=P1(J,Q,!1,m);if(yJ&&F&&F.running)C.push(Z);else eJ(Z)}function kJ(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=P1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,yJ&&F&&F.running)Z.tState=m,C.push(Z);else eJ(Z);return M1.bind(Z)}function j6(J){return c(J,!1)}function JJ(J){if(!_J&&b===null)return J();let Q=b;b=null;try{if(_J)return _J.untrack(J);return J()}finally{b=Q}}function S0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function F6(J){if(F&&F.running)return J(),F.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(yJ||K6)Z=F||(F={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[MQ,K1]=g(!1),K6;function M1(){let J=F&&F.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)eJ(this);else{let Q=C;C=null,c(()=>J0(this),!1),C=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&F.sources.has(this))return this.tValue;return this.value}function U1(J,Q,$){let Z=F&&F.running&&F.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(F){let q=F.running;if(q||!$&&F.sources.has(J))F.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw C=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;QJ(J);let Q=nJ;if(R1(J,F&&F.running&&F.sources.has(J)?J.tValue:J.value,Q),F&&!F.running&&F.sources.has(J))queueMicrotask(()=>{c(()=>{F&&(F.running=!0),b=S=J,R1(J,J.tValue,Q),b=S=null},!1)})}function R1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(F&&F.running)J.tState=m,J.tOwned&&J.tOwned.forEach(QJ),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach(QJ),J.owned=null;return J.updatedAt=$+1,g0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)U1(J,Z,!0);else if(F&&F.running&&J.pure){if(!F.sources.has(J))J.value=Z;F.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function P1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(F&&F.running)X.state=0,X.tState=Z;if(S===null);else if(S!==F1)if(F&&F.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(_J&&X.fn){let z=X.fn,[G,P]=g(void 0,{equals:!1}),D=_J.factory(z,P);S0(()=>D.dispose());let V,B=()=>F6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),F&&F.running){if(!V)V=_J.factory(z,B);return V.track(_)}return D.track(_)}}return X}function b0(J){let Q=F&&F.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===fJ)return J0(J);if(J.suspense&&JJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(F.disposed.has(q))return}if((Q?J.tState:J.state)===m)eJ(J);else if((Q?J.tState:J.state)===fJ){let q=C;C=null,c(()=>J0(J,$[0]),!1),C=q}}}function c(J,Q){if(C)return J();let $=!1;if(!Q)C=[];if(T)$=!0;else T=[];nJ++;try{let Z=J();return M6($),Z}catch(Z){if(!$)T=null;C=null,g0(Z)}}function M6(J){if(C){if(yJ&&F&&F.running)U6(C);else D1(C);C=null}if(J)return;let Q;if(F){if(!F.promises.size&&!F.queue.size){let{sources:Z,disposed:q}=F;T.push.apply(T,F.effects),Q=F.resolve;for(let X of T)"tState"in X&&(X.state=X.tState),delete X.tState;F=null,c(()=>{for(let X of q)QJ(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zB6($),!1);if(Q)Q()}function D1(J){for(let Q=0;Q{Z.delete($),c(()=>{F.running=!0,b0($)},!1),F&&(F.running=!1)})}}function J0(J,Q){let $=F&&F.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)QJ(J.tOwned[Q]);delete J.tOwned}if(F&&F.running&&J.pure)L1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)QJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(F&&F.running)J.tState=0;else J.state=0}function L1(J,Q){if(!Q)J.tState=0,F.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return S0(()=>I1(X)),()=>{let P=J()||[],D=P.length,V,B;return P[H6],JJ(()=>{let N,h,a,GJ,LJ,M,j,H,L;if(D===0){if(z!==0)I1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[P6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=M&&H>=M&&Z[j]===P[H];j--,H--)a[H]=q[j],GJ[H]=X[j],G&&(LJ[H]=G[j]);N=new Map,h=Array(H+1);for(B=H;B>=M;B--)L=P[B],V=N.get(L),h[B]=V===void 0?-1:V,N.set(L,B);for(V=M;V<=j;V++)if(L=Z[V],B=N.get(L),B!==void 0&&B!==-1)a[B]=q[V],GJ[B]=X[V],G&&(LJ[B]=G[V]),B=h[B],N.set(L,B);else X[V]();for(B=M;BJ(Q||{}));return B1($),Z}}return JJ(()=>J(Q||{}))}function Q0(){return!0}var O6={get(J,Q,$){if(Q===k0)return $;return J.get(Q)},has(J,Q){if(Q===k0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function w0(J){return!(J=typeof J==="function"?J():J)?{}:J}function I6(){for(let J=0,Q=this.length;J=0;G--){let P=w0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in w0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:I6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var A6=(J)=>`Stale read from <${J}>.`;function SJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return kJ(D6(()=>J.each,J.children,Q||void 0))}function bJ(J){let Q=J.keyed,$=kJ(()=>J.when,void 0,void 0),Z=Q?$:kJ($,void 0,{equals:(q,X)=>!q===!X});return kJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?JJ(()=>X(Q?q:()=>{if(!JJ(Z))throw A6("Show");return $()})):X}return J.fallback},void 0,void 0)}var _6=(J)=>kJ(()=>J());function k6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(M,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(M,j,L,H);e((A)=>B(M,j(),A,H),L)}function B(M,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=h(M,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(M),H=j);else h(M,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=h(M,H,L);else if(k==="function")return e(()=>{let O=j();while(typeof O==="function")O=O();H=B(M,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return e(()=>H=B(M,O,H,L,!0)),()=>H;if(O.length===0){let TJ=h(M,H,L);if(I)return H=TJ}else if(Array.isArray(H))if(H.length===0)a(M,O,L);else N(M,H,O);else if(H==null||H==="")a(M,O);else N(M,I&&H||[P(M)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(M,H,L,j);h(M,H,null,j)}else if(H==null||H===""||!P(M))q(M,j);else GJ(M,j,P(M));H=j}return H}function _(M,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let FQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let TJ=G(O)===M;if(!k&&!I)TJ?GJ(M,A,O):q(M,A,H);else TJ&&X(M,O)}else k=!0}}else q(M,A,H);return[A]}function a(M,j,H){for(let L=0,A=j.length;LH.children=B(M,j.children,H.children));return e(()=>j.ref&&j.ref(M)),e(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(M,A,k,H[A]),H[A]=k}}),H}return{render(M,j){let H;return tJ((L)=>{H=L,V(j,M())}),H},insert:V,spread(M,j,H){if(typeof j==="function")e((L)=>LJ(M,j(),L,H));else LJ(M,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(M,j,H,L){return z(M,j,H,L),H},mergeProps:A1,effect:e,memo:_6,createComponent:L6,use(M,j,H){return JJ(()=>M(j,H))}}}function S6(J){let Q=k6(J);return Q.mergeProps=A1,Q}var _1=480,k1=272,HJ={view:0,text:1,image:2},b6=1,g6=-1,w6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},C6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},E6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},N6=1,UQ=2,RQ=1,PQ=2,DQ=131072,VQ=1,LQ=262144,OQ=1,IQ=1,AQ=1,_Q=2,kQ=4,SQ=8,bQ=16,gQ=1,wQ=2;function S1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var CQ=1,h6=1263551300,T6=1,f6=32,y6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},BJ=32896,EQ=0.016666666666666666;function b1(J){return J.__viewport??null}var C0=null;function x6(){return null}function g1(J,Q=x6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function v6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return g1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return g1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function m6(J){C0=J}function gJ(){if(!C0)throw Error("PocketJS: host not installed — call render() first");return C0}function E(){return gJ().ops}function u6(J){globalThis.frame=J}function l6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function p6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return S1($>>>16&255,$>>>8&255,$&255,255);return S1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function c6(J,Q){let $=C6[J];if(typeof Q==="string"){if($===U.color)return p6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var $0=60,w1=[1,2,3,4,5,6,10,12,15,20,30,60],E0=$0,$J=-1,d6=0,xJ=[];function i6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=w1[0];for(let $ of w1)if(Math.abs($-J)Q.at<=$J).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>$J);for(let Q of J)Q.cb()}var N0=0.12,Z0=BJ;function o6(J){Z0=J===void 0?BJ:J&65535}function n6(){Z0=BJ}function N1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function e6(){return N1(Z0&255)}var h1=new Set,J8=0;function Q8(){h1.clear(),J8=0,n6()}function $8(J){for(let Q of[...h1])Q(J)}var jJ=null,T1=null;function Z8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function f1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){h0();let Q=jJ?jJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return T1.slice(Q.off,Q.off+Q.len)}var mJ=null,w=null,FJ=null,q0=0,KJ=[],f0=[],y0=[];function x1(J){if(mJ=J,w=null,FJ=null,q0=0,KJ.length=0,f0.length=0,y0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function X8(J,Q){J.onPress=Q??void 0}function Y8(J,Q){if(J.focusable=Q,p1(),!Q&&w===J)x(null)}function x(J){if(FJ&&FJ!==J)MJ(null);w=J,E().setFocus(J?J.id:0)}function MJ(J){if(FJ===J)return;let Q=E();if(FJ)Q.setActive?.(FJ.id,0);if(FJ=J,J)Q.setActive?.(J.id,1)}function x0(){return KJ.length>0?KJ[KJ.length-1]:mJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function G8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=f0.length-1;Q>=0;Q--){let $=f0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function H8(J){let Q=G8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(w)x(null);return!0}let Z=Q.columns,q=w?$.indexOf(w):-1;if(q<0)return x(v1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function B8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=y0.length-1;Q>=0;Q--){let $=y0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function X0(J){let Q=B8();if(Q&&Q.move(J))return;if(H8(J))return;W8(J)}function m1(){u1(w)}function u1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){MJ(J)}function j8(J){x(J),u1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=m0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,l1=0;function p1(){l1++}var K8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],M8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function U8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=K8[Q]>>$&1,q=M8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function R8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):P8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(U8(),16,16,E6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function P8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&N6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var W0=null;function c1(J){W0=J}function d1(J){let Q=KJ.length>0?KJ[KJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function i1(J,Q,$){return d1(s1(J,Q,$))}function s1(J,Q,$){if($!==void 0)return $===0?null:z0(W0??mJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(W0??mJ,q(J,Q))}function D8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=b1(q);if(Z.vw=B?B.w:_1,Z.vh=B?B.h:k1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)R8(Z,q);let X=t6()*Z.speed,z=e6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=s6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=l1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=d1(z0(W0??mJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==w)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(MJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,MJ(null),B)m1()}}else if($&Z.button)MJ(null);return!0}function V8(J){let Q=J&~q0,$=q0&~J;if(q0=J,l&&D8(J,Q,$))return;if($&d.CIRCLE)MJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)MJ(w),m1()}var u0=null;function a1(J){u0=J}function wJ(){if(p1(),u0)u0()}function L8(J,Q){J.debugName=Q||void 0,wJ()}var ZJ={id:b6,type:HJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},r1=Symbol.for("pocketjs.native-node"),l0=1,uJ=3,o=8,O8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function G0(J){return J.domAttrs??={}}function o1(J,Q){let $=J.domNodeType??(lJ(J)?uJ:l0),Z=$===uJ?H0(J.text??""):$===o?_8(J.domData??""):Z4(J.domTag??j0(J));for(let q of Object.keys(J.domAttrs??{}))p0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)qJ(Z,o1(q,!0));return Z}function p0(J,Q,$){if(O8.has(Q)){EJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete G0(J)[Q];else G0(J)[Q]=$}function c0(J){if(J[r1]===!0)return J;return Object.defineProperty(J,r1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(lJ(J)?uJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(lJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(lJ(J))B0(J,Z);else if(E8(J),Z)qJ(J,H0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return X4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??j0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===uJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??j0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){EJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===ZJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return qJ(J,$),$},insertBefore($,Z){return qJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return qJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return o1(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){p0(J,$,Z)},removeAttribute($){p0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(ZJ);var d0=null;function I8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},n1=new Map;function t1(J,Q){n1.set(J,Q)}var e1=new Map;function J4(J,Q){e1.set(J,Q)}var CJ=new Set,A8=new Set;function Q4(J){if(!J)return!1;if(A8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function H0(J){let Q=E(),$=Q.createNode(HJ.text);return Q.setText($,J),c0({id:$,type:HJ.text,parent:null,children:[],text:J,domNodeType:uJ,domTag:"#text"})}function _8(J=""){let Q=H0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){E().replaceText(J.id,Q),J.text=Q,wJ()}function lJ(J){return J.type===HJ.text}function q4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function qJ(J,Q,$){let Z=E();if(q4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function pJ(J,Q){if(!Q)return;F8(Q),E().removeChild(J.id,Q.id),q4(Q),CJ.add(Q),wJ()}function k8(J){return J.parent??void 0}function S8(J){return J.children[0]}function X4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function b8(J,Q){let $=E();if(wJ(),Q==null||Q===""){$.setStyle(J.id,g6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function g8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=n1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function w8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=e1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function C8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=w6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,c6(G,P)),z=!0}if(z)wJ()}function EJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete G0(J)[Q];else G0(J)[Q]=$;switch(Q){case"class":return b8(J,$),$;case"onPress":case"on:press":return X8(J,$),$;case"src":return g8(J,$),$;case"sprite":return w8(J,$),$;case"style":return C8(J,$,Z),$;case"focusable":return Y8(J,!!$),$;case"debugName":return L8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${j0(J)}>`)}function E8(J){for(let Q of[...J.children])pJ(J,Q)}function j0(J){for(let Q of Object.keys(HJ))if(HJ[Q]===J.type)return Q;return String(J.type)}function N8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}EJ(J,Q,$,Z)}var h8=S6({createElement:Z4,createTextNode:H0,replaceText:B0,isTextNode:lJ,setProperty:N8,insertNode(J,Q,$){qJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:k8,getFirstChild:S8,getNextSibling:X4}),{render:T8,effect:NQ,memo:p,createComponent:Y,createElement:Y4,insert:hQ,spread:f8,mergeProps:TQ,use:fQ}=h8,yQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},y8=null;function z4(J){y8=J}function x8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function W4(J,Q){let $=Y4(J);return f8($,Q,!1),x8(Q.nodeRef,$),$}function K(J){return W4("view",J)}function R(J){return W4("text",J)}var xQ=new WeakMap,vQ=new WeakMap,v8={}!==null?Object.freeze({...{}}):Object.freeze({}),mQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:v8}),uQ=new Map,XJ=36000,s0=30,m8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(XJ),tapeAnalog:new Uint16Array(XJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function u8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-s0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)a1(()=>{W.treeDirty=!0}),r8();else a1(null);globalThis.__pocketDevtools=n8}function l8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)c8(),s8();let X=Q,z=$===void 0?BJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(XJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==BJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function B4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function j4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.masks,0,Q)}function F4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return B4(J.analog??[],BJ,Q)}function K4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,f({t:"hello",app:W.app,host:o8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` -`))if(q.trim())d8(q)}}function d8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)f({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),a0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":M4();break;case"eval":{let Z=!0,q;try{q=F0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}f({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":f({t:"tape",tape:H4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}f({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())f({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else f({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=j4(Z),W.replayAnalog=Z.analog?F4(Z):null,W.replayTouch=Z.touch?K4(Z):null,W.replayAt=0;break}default:break}}function i8(){if(W.treeDirty&&W.frame-W.treeSentAt>=s0)M4();if(W.frame%m8===0)a0()}function s8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,f({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,f({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){f({t:"stats",frame:W.frame,nodes:P4(ZJ),tapeLen:W.tapeLen,paused:W.paused})}function M4(){W.treeDirty=!1,W.treeSentAt=W.frame,f({t:"tree",frame:W.frame,root:R4(ZJ)})}function a8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(a8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function U4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function R4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(U4(J,(q)=>{if(q.domNodeType===8)return;Z.push(R4(q))}),Z.length)Q.k=Z;return Q}function P4(J){let Q=1;return U4(J,($)=>{Q+=P4($)}),Q}function r8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{f({t:"log",level:$,args:q.map((X)=>F0(X))}),Z?.apply(Q,q)}}}function F0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?D4(X):JSON.stringify(D4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>F0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${F0(z,Q+1)}`).join(", ")}}`}function D4(J){return J.length>200?J.slice(0,199)+"…":J}function o8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var n8={get frame(){return W.frame},dumpTape:()=>H4(),replay:(J)=>{W.replayMasks=j4(J),W.replayAnalog=J.analog?F4(J):null,W.replayTouch=J.touch?K4(J):null,W.replayAt=0}},V4=new Map,o0=new Map;function L4(J){return J.trim().replace(/\s+/g," ")}function O4(J){return J.split(" ").sort().join(" ")}var I4=-1;function t8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=L4(Q);V4.set(Z,$);let q=O4(Z),X=o0.get(q);o0.set(q,X!==void 0&&X!==$?I4:$)}}function e8(J){let Q=L4(J),$=V4.get(Q);if($!==void 0)return $;let Z=o0.get(O4(Q));return Z===I4?void 0:Z}var n0=9,J2=(1<{let q=($&$2)!==0,X=q?t0:n0,z=q?Z2:J2;return Object.freeze({id:$>>>(q?q2:Q2)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Y2(){return K0}function z2(){K0=e0}var A4=8,YJ=8,W2=3,G2=8,H2=6,B2=0.5,s=1,cJ=2,J1=4,UJ=8,NJ=[],_4=0,M0=0,zJ=Array.from({length:A4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(YJ),histY:new Int16Array(YJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function j2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function F2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=s1(Q,$,Z.fact);let G=Z.hit;if(G)return j2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=NJ[z];if(G.disposed)continue;if(_4>0&&!G.opts.allowWhenBlocked)continue;if(!F2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function U2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%YJ,J.histLenz||Z>z))q.flags[J.slot]|=cJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(cJ|J1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??B2)*C1()));if(J.frames=0)NJ.splice($,1)},cancel(){if(!Q.disposed)b4(Q)},get panning(){for(let $ of zJ)if($.used&&Q.flags[$.slot]&UJ)return!0;return!1}}}function L2(J){let Q=V2(J);return S0(()=>Q.dispose()),Q}function g4(){NJ.length=0,_4=0,M0=0;for(let J of zJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function O2(){return L2({onDown:(J)=>{let Q=i1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=i1(J.x,J.y,J.hit);if(Q)j8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var I2=1,Q1=new Map,U0=[];function A2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function _2(){I2=1,Q1.clear(),U0=[]}function k2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),A2()?.({t:"delivery",frame:E1(),id:Q,kind:Z.kind}),Z.onResult($)}}var w4=new Set;function S2(){if(w4.size===0)return;for(let J of w4)J()}var b2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[28] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-base text-orange-600 font-bold":9,"h-[76] pt-3 text-lg text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-base text-emerald-700 font-bold":13,"h-[84] pt-3 text-lg text-slate-900":14,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":15,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":16,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":17,"text-base text-slate-600 font-bold":18,"pt-6 text-lg text-slate-500":19,"pt-6 text-lg text-slate-900 font-bold":20,"h-[146] px-6 pt-7 flex-col bg-slate-50":21,"h-[80]":22,"h-[1060] px-6 pt-5 flex-col":23,"h-[48] px-4 justify-center bg-slate-100":24,"text-base text-slate-600":25,"pt-[10] flex-col gap-[12]":26,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":27,"w-[48] h-[48] items-center justify-center bg-blue-100":28,"w-[48] h-[48] items-center justify-center bg-emerald-100":29,"text-lg text-blue-700 font-bold":30,"text-lg text-emerald-700 font-bold":31,"w-[474] flex-col gap-2":32,"text-lg text-slate-900 font-bold":33,"text-base text-slate-500":34,"pt-20 pl-10 text-lg text-slate-500":35,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":36,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":37,"h-[1060] px-6 pt-7 flex-col gap-4":38,"text-base text-slate-500 font-bold":39,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":40,"flex-row items-center gap-5":41,"w-[68] h-[68] items-center justify-center bg-emerald-100":42,"text-xl text-emerald-700 font-bold":43,"flex-col gap-2":44,"text-xl text-slate-900 font-bold":45,"text-lg text-slate-600":46,"text-2xl text-orange-600":47,"w-[68] h-[68] items-center justify-center bg-indigo-100":48,"text-xl text-indigo-700 font-bold":49,"mt-4 h-[112] px-6 justify-center bg-slate-100":50,"relative h-[154] px-5 pt-5 flex-col bg-white":51,"pt-3 text-lg text-orange-600 font-bold":52,"pt-3 text-base text-slate-500":53,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":54,"text-lg text-white font-bold":55,"h-[40] pt-3 text-base text-slate-500":56,"h-[470] flex-col gap-2":57,"h-[214] px-7 items-center justify-center bg-slate-100":58,"text-lg text-slate-500 font-bold":59,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":60,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":61,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":62,"h-[160] px-5 pt-5 flex-col bg-white":63,"pt-3 text-lg text-slate-900 font-bold":64,"pt-3 text-base text-slate-600":65,"h-[108] pt-7 flex-row gap-4":66,"w-[316] h-[80] items-center justify-center bg-slate-100":67,"w-[340] h-[80] items-center justify-center bg-red-100":68,"text-lg text-red-500 font-bold":69,"h-[1052] px-6 pt-5 flex-col":70,"h-[270] px-[22] pt-6 bg-white":71,"text-lg text-slate-900":72,"text-lg text-slate-400":73,"h-[86] px-1 flex-row items-center justify-between":74,"w-[132] h-[58] items-center justify-center bg-slate-300":75,"w-[132] h-[58] items-center justify-center bg-slate-100":76,"text-base text-slate-900 font-bold":77,"h-[140] flex-row gap-2":78,"grow h-[120] items-center justify-center bg-slate-300":79,"grow h-[120] items-center justify-center bg-white":80,"w-[104] h-[120] items-center justify-center bg-slate-300":81,"w-[104] h-[120] items-center justify-center bg-slate-100":82,"h-[176] flex-row gap-2":83,"w-[92] h-[156] items-center justify-center bg-slate-300":84,"w-[92] h-[156] items-center justify-center bg-slate-100":85,"w-[300] h-[156] items-center justify-center bg-slate-300":86,"w-[300] h-[156] items-center justify-center bg-slate-100":87,"w-[144] h-[156] items-center justify-center bg-slate-300":88,"w-[144] h-[156] items-center justify-center bg-slate-100":89,"w-[112] h-[156] items-center justify-center bg-emerald-700":90,"w-[112] h-[156] items-center justify-center bg-emerald-500":91,"text-base text-slate-950 font-bold":92,"h-[108] px-6 py-3 flex-col bg-slate-50":93,"h-[84] items-center justify-center bg-slate-300":94,"h-[84] items-center justify-center bg-slate-100":95,"h-[1168] px-6 pt-5 flex-col":96,"h-[82] px-4 justify-center bg-white":97,"w-[584] h-[900] px-5 pt-5 bg-slate-950":98,"text-base text-slate-200":99,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":100,"text-lg text-orange-600 font-bold":101,"w-[584] h-[900] px-5 pt-5 bg-white":102,"text-base text-slate-900":103,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":104,"absolute inset-0 z-50 flex-col items-center justify-center":105,"absolute inset-0 bg-slate-950":106,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":107,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":108,"flex-row flex-wrap":109,grow:110,"text-2xl text-white font-bold":111,"text-2xl text-slate-950 font-bold":112,"px-6":113,"px-6 py-5":114,"gap-4":115,"rounded-xl shadow bg-white border-slate-100":116,"rounded-xl shadow bg-emerald-100 border-emerald-500":117,"bg-white":118,"bg-slate-100":119,"bg-slate-950":120,"px-3 py-2 rounded-lg bg-slate-100":121,"px-3 py-2 rounded-lg bg-indigo-100":122,"text-base text-indigo-700 font-bold":123,"px-3 py-2 rounded-lg bg-emerald-100":124,"px-3 py-2 rounded-lg bg-amber-100":125,"text-base text-amber-700 font-bold":126,"px-3 py-2 rounded-lg bg-red-100":127,"text-base text-red-500 font-bold":128,"w-[34] h-[34] rounded-lg bg-amber-400":129,"w-[34] h-[34] rounded-lg bg-red-500":130,"w-[34] h-[34] rounded-lg bg-slate-800":131,"w-[34] h-[34] rounded-lg bg-emerald-500":132,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":133,"flex-row items-center gap-4":134,"w-[34] text-2xl text-white font-bold":135,"w-[332] flex-col items-end gap-2":136,"text-base text-slate-300 font-bold":137,"text-base text-slate-400":138,"h-[166] px-6 pt-6 flex-col gap-3":139,"h-[44] px-1 flex-row items-center justify-between":140,"w-full h-full items-center justify-center rounded-xl bg-slate-200":141,"w-full h-full items-center justify-center rounded-xl bg-red-100":142,"w-full h-full items-center justify-center rounded-xl bg-slate-100":143,"w-full h-full items-center justify-center rounded-xl bg-orange-600":144,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":145,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":146,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":147,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":148,"text-2xl text-indigo-700 font-bold":149,"text-2xl text-slate-600 font-bold":150,"pt-7 text-2xl text-slate-900 font-bold":151,"pt-4 text-lg text-slate-500":152,"text-xl text-emerald-600 font-bold":153,"text-xl text-red-500 font-bold":154,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":155,"text-base text-red-300":156,"text-base text-slate-300":157,"text-base text-red-500":158,"w-full h-full px-6 flex-row items-center bg-slate-950":159,"w-full h-full flex-row items-center":160};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var g2="ui:styles",w2="ui:font.",C4="ui:img.",E4="ui:sprite.";function C2(){return globalThis.ui}function E2(J){if(J.__textures)return;for(let Q of T0(C4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)t1(Q.slice(C4.length),Z)}}function N2(J){if(J.__sprites)return;for(let Q of T0(E4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)J4(Q.slice(E4.length),{handle:V,frames:G,cols:P,step:D})}}function N4(J){let Q=Y4("view");return EJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function h2(J,Q){if(!R0||!P0)return;EJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),EJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function T2(J,Q={}){let $=v6(Q.ops);if(m6($),I8(e8),Q.styles)t8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)t1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)J4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)y1(Q.pak);if(q8()){for(let B of T0())if(B===g2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(w2))$.ops.loadFontAtlas?.(vJ(B))}}let q=b1($.ops),X=q?.w??_1,z=q?.h??k1,G=N4({width:X,height:z,overflow:u.Overflow.Hidden}),P=N4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});qJ(ZJ,G),qJ(ZJ,P),z4(P),R0=G,P0=P,x1(G),c1(ZJ),Q8(),g4(),O2(),a6(),_2(),u8($.ops),u6(l8((B,_,N,h)=>{r6(),o6(_),X2(N,h),S2(),k2(),D2(),$8(B),V8(B),$4()}));let D=T8(J,G),V=l6(h2);return()=>{V(),z2(),g4(),D(),x1(null),c1(null),z4(null),R0=null,P0=null;for(let B of ZJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);$4()}}function f2(J,Q={}){let $=Q.ops??C2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)y1(Q.pak);return E2($),N2($),T2(J,{ops:$,styles:Q.styles??b2,pak:Q.pak})}var y2="$b",x2=65536,h4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function u2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function T4(){let J=u2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function l2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,x2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=v2(z.data[y2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function p2(J,Q){let $=l2(T4(),J);return Q==="utf8"||Q==="utf-8"?m2($):$}function c2(J,Q){let $=T4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var d2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"};function i2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(K,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(K,{class:"flex-row items-center gap-4",get children(){return[p(()=>p(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(K,{get["class"](){return Q()}})),Y(R,{get["class"](){return d2.appTitle},get children(){return J.title}})]}}),Y(K,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function s2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(K,{get["class"](){return Q()},get children(){return Y(R,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(K,{get["class"](){return J.top},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(K,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var lQ="‘’“”–—…•",f4=new Map,y4=new Map,a2=512;function D0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=f4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return f4.set($,q),q}function r2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=D0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function $1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=y4.get(Z);if(q)return q;let X=[],z=D0(" ",Q);for(let G of J.split(` -`)){let P=G.split(" ").flatMap((B)=>B&&D0(B,Q)>$?r2(B,Q,$):[B]),D="",V=0;for(let B of P){let _=D0(B,Q);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return y4.set(Z,X),X}function x4(J,Q,$,Z){let q=J.slice(0,a2),X=$1(q,Q,$);if(q.length===J.length&&X.length<=Z)return X.join(` +(()=>{var AJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return K1(this.context.count)},getNextContextId(){return K1(this.context.count++)}};function K1(J){let Q=String(J),$=Q.length-1;return AJ.context.id+($?String.fromCharCode(96+$):"")+Q}function F1(J){AJ.context=J}function Y6(){return{...AJ.context,id:AJ.getNextContextId(),count:0}}var z6=!1,W6=(J,Q)=>J===Q,k0=Symbol("solid-proxy"),G6=typeof Proxy==="function",H6=Symbol("solid-track"),FQ=Symbol("solid-dev-component"),oJ={equals:W6},M1=null,j6=O1,m=1,fJ=2,U1={owned:null,cleanups:null,context:null,owner:null},S=null,K=null,yJ=null,_J=null,b=null,C=null,T=null,nJ=0;function tJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?U1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>JJ(()=>QJ(z)));S=z,b=null;try{return c(G,!0)}finally{b=$,S=Z}}function g(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return D1($,q)};return[P1.bind($),Z]}function e(J,Q,$){let Z=L1(J,Q,!1,m);if(yJ&&K&&K.running)C.push(Z);else eJ(Z)}function kJ(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=L1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,yJ&&K&&K.running)Z.tState=m,C.push(Z);else eJ(Z);return P1.bind(Z)}function B6(J){return c(J,!1)}function JJ(J){if(!_J&&b===null)return J();let Q=b;b=null;try{if(_J)return _J.untrack(J);return J()}finally{b=Q}}function S0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function K6(J){if(K&&K.running)return J(),K.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(yJ||F6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[MQ,R1]=g(!1),F6;function P1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)eJ(this);else{let Q=C;C=null,c(()=>J0(this),!1),C=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function D1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw C=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;QJ(J);let Q=nJ;if(V1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{c(()=>{K&&(K.running=!0),b=S=J,V1(J,J.tValue,Q),b=S=null},!1)})}function V1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=m,J.tOwned&&J.tOwned.forEach(QJ),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach(QJ),J.owned=null;return J.updatedAt=$+1,g0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)D1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function L1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(S===null);else if(S!==U1)if(K&&K.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(_J&&X.fn){let z=X.fn,[G,P]=g(void 0,{equals:!1}),D=_J.factory(z,P);S0(()=>D.dispose());let V,j=()=>K6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),K&&K.running){if(!V)V=_J.factory(z,j);return V.track(_)}return D.track(_)}}return X}function b0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===fJ)return J0(J);if(J.suspense&&JJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===m)eJ(J);else if((Q?J.tState:J.state)===fJ){let q=C;C=null,c(()=>J0(J,$[0]),!1),C=q}}}function c(J,Q){if(C)return J();let $=!1;if(!Q)C=[];if(T)$=!0;else T=[];nJ++;try{let Z=J();return M6($),Z}catch(Z){if(!$)T=null;C=null,g0(Z)}}function M6(J){if(C){if(yJ&&K&&K.running)U6(C);else O1(C);C=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;T.push.apply(T,K.effects),Q=K.resolve;for(let X of T)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,c(()=>{for(let X of q)QJ(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zj6($),!1);if(Q)Q()}function O1(J){for(let Q=0;Q{Z.delete($),c(()=>{K.running=!0,b0($)},!1),K&&(K.running=!1)})}}function J0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)QJ(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)A1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)QJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function A1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return S0(()=>k1(X)),()=>{let P=J()||[],D=P.length,V,j;return P[H6],JJ(()=>{let N,h,a,GJ,LJ,M,B,H,L;if(D===0){if(z!==0)k1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[P6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(j=0;j=M&&H>=M&&Z[B]===P[H];B--,H--)a[H]=q[B],GJ[H]=X[B],G&&(LJ[H]=G[B]);N=new Map,h=Array(H+1);for(j=H;j>=M;j--)L=P[j],V=N.get(L),h[j]=V===void 0?-1:V,N.set(L,j);for(V=M;V<=B;V++)if(L=Z[V],j=N.get(L),j!==void 0&&j!==-1)a[j]=q[V],GJ[j]=X[V],G&&(LJ[j]=G[V]),j=h[j],N.set(L,j);else X[V]();for(j=M;jJ(Q||{}));return F1($),Z}}return JJ(()=>J(Q||{}))}function Q0(){return!0}var O6={get(J,Q,$){if(Q===k0)return $;return J.get(Q)},has(J,Q){if(Q===k0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function w0(J){return!(J=typeof J==="function"?J():J)?{}:J}function I6(){for(let J=0,Q=this.length;J=0;G--){let P=w0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in w0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let j=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=j.get?{enumerable:!0,configurable:!0,get:I6.bind($[V]=[j.get.bind(G)])}:j.value!==void 0?j:void 0;else{let _=$[V];if(_){if(j.get)_.push(j.get.bind(G));else if(j.value!==void 0)_.push(()=>j.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var A6=(J)=>`Stale read from <${J}>.`;function SJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return kJ(D6(()=>J.each,J.children,Q||void 0))}function bJ(J){let Q=J.keyed,$=kJ(()=>J.when,void 0,void 0),Z=Q?$:kJ($,void 0,{equals:(q,X)=>!q===!X});return kJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?JJ(()=>X(Q?q:()=>{if(!JJ(Z))throw A6("Show");return $()})):X}return J.fallback},void 0,void 0)}var _6=(J)=>kJ(()=>J());function k6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(M,B,H,L){if(H!==void 0&&!L)L=[];if(typeof B!=="function")return j(M,B,L,H);e((A)=>j(M,B(),A,H),L)}function j(M,B,H,L,A){while(typeof H==="function")H=H();if(B===H)return H;let k=typeof B,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")B=B.toString();if(I){let O=H[0];if(O&&$(O))Z(O,B);else O=Q(B);H=h(M,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(M),H=B);else h(M,H,L,Q(B)),H=B}else if(B==null||k==="boolean")H=h(M,H,L);else if(k==="function")return e(()=>{let O=B();while(typeof O==="function")O=O();H=j(M,O,H,L)}),()=>H;else if(Array.isArray(B)){let O=[];if(_(O,B,A))return e(()=>H=j(M,O,H,L,!0)),()=>H;if(O.length===0){let TJ=h(M,H,L);if(I)return H=TJ}else if(Array.isArray(H))if(H.length===0)a(M,O,L);else N(M,H,O);else if(H==null||H==="")a(M,O);else N(M,I&&H||[P(M)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(M,H,L,B);h(M,H,null,B)}else if(H==null||H===""||!P(M))q(M,B);else GJ(M,B,P(M));H=B}return H}function _(M,B,H){let L=!1;for(let A=0,k=B.length;Ar-O){let KQ=B[I];while(O=0;I--){let O=B[I];if(A!==O){let TJ=G(O)===M;if(!k&&!I)TJ?GJ(M,A,O):q(M,A,H);else TJ&&X(M,O)}else k=!0}}else q(M,A,H);return[A]}function a(M,B,H){for(let L=0,A=B.length;LH.children=j(M,B.children,H.children));return e(()=>B.ref&&B.ref(M)),e(()=>{for(let A in B){if(A==="children"||A==="ref")continue;let k=B[A];if(k===H[A])continue;z(M,A,k,H[A]),H[A]=k}}),H}return{render(M,B){let H;return tJ((L)=>{H=L,V(B,M())}),H},insert:V,spread(M,B,H){if(typeof B==="function")e((L)=>LJ(M,B(),L,H));else LJ(M,B,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(M,B,H,L){return z(M,B,H,L),H},mergeProps:S1,effect:e,memo:_6,createComponent:L6,use(M,B,H){return JJ(()=>M(B,H))}}}function S6(J){let Q=k6(J);return Q.mergeProps=S1,Q}var b1=480,g1=272,HJ={view:0,text:1,image:2},b6=1,g6=-1,w6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},C6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},E6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},N6=1,UQ=2,RQ=1,PQ=2,DQ=131072,VQ=1,LQ=262144,OQ=1,IQ=1,AQ=1,_Q=2,kQ=4,SQ=8,bQ=16,gQ=1,wQ=2;function w1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var CQ=1,h6=1263551300,T6=1,f6=32,y6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},jJ=32896,EQ=0.016666666666666666;function C1(J){return J.__viewport??null}var C0=null;function x6(){return null}function E1(J,Q=x6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function v6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return E1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return E1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function m6(J){C0=J}function gJ(){if(!C0)throw Error("PocketJS: host not installed — call render() first");return C0}function E(){return gJ().ops}function u6(J){globalThis.frame=J}function l6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function p6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return w1($>>>16&255,$>>>8&255,$&255,255);return w1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function c6(J,Q){let $=C6[J];if(typeof Q==="string"){if($===U.color)return p6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var $0=60,N1=[1,2,3,4,5,6,10,12,15,20,30,60],E0=$0,$J=-1,d6=0,xJ=[];function i6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=N1[0];for(let $ of N1)if(Math.abs($-J)Q.at<=$J).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>$J);for(let Q of J)Q.cb()}var N0=0.12,Z0=jJ;function o6(J){Z0=J===void 0?jJ:J&65535}function n6(){Z0=jJ}function f1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function e6(){return f1(Z0&255)}var y1=new Set,J8=0;function Q8(){y1.clear(),J8=0,n6()}function $8(J){for(let Q of[...y1])Q(J)}var BJ=null,x1=null;function Z8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function v1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){h0();let Q=BJ?BJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return x1.slice(Q.off,Q.off+Q.len)}var mJ=null,w=null,KJ=null,q0=0,FJ=[],f0=[],y0=[];function u1(J){if(mJ=J,w=null,KJ=null,q0=0,FJ.length=0,f0.length=0,y0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function X8(J,Q){J.onPress=Q??void 0}function Y8(J,Q){if(J.focusable=Q,i1(),!Q&&w===J)x(null)}function x(J){if(KJ&&KJ!==J)MJ(null);w=J,E().setFocus(J?J.id:0)}function MJ(J){if(KJ===J)return;let Q=E();if(KJ)Q.setActive?.(KJ.id,0);if(KJ=J,J)Q.setActive?.(J.id,1)}function x0(){return FJ.length>0?FJ[FJ.length-1]:mJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function G8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=f0.length-1;Q>=0;Q--){let $=f0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function H8(J){let Q=G8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(w)x(null);return!0}let Z=Q.columns,q=w?$.indexOf(w):-1;if(q<0)return x(l1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function j8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=y0.length-1;Q>=0;Q--){let $=y0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function X0(J){let Q=j8();if(Q&&Q.move(J))return;if(H8(J))return;W8(J)}function p1(){c1(w)}function c1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){MJ(J)}function B8(J){x(J),c1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=m0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,d1=0;function i1(){d1++}var F8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],M8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function U8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=F8[Q]>>$&1,q=M8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function R8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):P8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(U8(),16,16,E6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function P8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&N6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var W0=null;function s1(J){W0=J}function a1(J){let Q=FJ.length>0?FJ[FJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function r1(J,Q,$){return a1(o1(J,Q,$))}function o1(J,Q,$){if($!==void 0)return $===0?null:z0(W0??mJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(W0??mJ,q(J,Q))}function D8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let j=C1(q);if(Z.vw=j?j.w:b1,Z.vh=j?j.h:g1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)R8(Z,q);let X=t6()*Z.speed,z=e6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let j=s6()/60,_=Math.min(Math.max(Z.x+X*j,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*j,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=d1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=a1(z0(W0??mJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==w)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(MJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let j=V===Z.pressTarget;if(Z.pressTarget=null,MJ(null),j)p1()}}else if($&Z.button)MJ(null);return!0}function V8(J){let Q=J&~q0,$=q0&~J;if(q0=J,l&&D8(J,Q,$))return;if($&d.CIRCLE)MJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)MJ(w),p1()}var u0=null;function n1(J){u0=J}function wJ(){if(i1(),u0)u0()}function L8(J,Q){J.debugName=Q||void 0,wJ()}var ZJ={id:b6,type:HJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},t1=Symbol.for("pocketjs.native-node"),l0=1,uJ=3,o=8,O8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function G0(J){return J.domAttrs??={}}function e1(J,Q){let $=J.domNodeType??(lJ(J)?uJ:l0),Z=$===uJ?H0(J.text??""):$===o?_8(J.domData??""):Y4(J.domTag??B0(J));for(let q of Object.keys(J.domAttrs??{}))p0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)qJ(Z,e1(q,!0));return Z}function p0(J,Q,$){if(O8.has(Q)){EJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete G0(J)[Q];else G0(J)[Q]=$}function c0(J){if(J[t1]===!0)return J;return Object.defineProperty(J,t1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(lJ(J)?uJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else j0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else j0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(lJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(lJ(J))j0(J,Z);else if(E8(J),Z)qJ(J,H0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return W4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??B0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===uJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??B0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){EJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===ZJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return qJ(J,$),$},insertBefore($,Z){return qJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return qJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return e1(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){p0(J,$,Z)},removeAttribute($){p0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(ZJ);var d0=null;function I8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},J4=new Map;function Q4(J,Q){J4.set(J,Q)}var $4=new Map;function Z4(J,Q){$4.set(J,Q)}var CJ=new Set,A8=new Set;function q4(J){if(!J)return!1;if(A8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function H0(J){let Q=E(),$=Q.createNode(HJ.text);return Q.setText($,J),c0({id:$,type:HJ.text,parent:null,children:[],text:J,domNodeType:uJ,domTag:"#text"})}function _8(J=""){let Q=H0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function j0(J,Q){E().replaceText(J.id,Q),J.text=Q,wJ()}function lJ(J){return J.type===HJ.text}function z4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function qJ(J,Q,$){let Z=E();if(z4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function pJ(J,Q){if(!Q)return;K8(Q),E().removeChild(J.id,Q.id),z4(Q),CJ.add(Q),wJ()}function k8(J){return J.parent??void 0}function S8(J){return J.children[0]}function W4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function b8(J,Q){let $=E();if(wJ(),Q==null||Q===""){$.setStyle(J.id,g6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function g8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=J4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function w8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=$4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function C8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=w6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,c6(G,P)),z=!0}if(z)wJ()}function EJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete G0(J)[Q];else G0(J)[Q]=$;switch(Q){case"class":return b8(J,$),$;case"onPress":case"on:press":return X8(J,$),$;case"src":return g8(J,$),$;case"sprite":return w8(J,$),$;case"style":return C8(J,$,Z),$;case"focusable":return Y8(J,!!$),$;case"debugName":return L8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${B0(J)}>`)}function E8(J){for(let Q of[...J.children])pJ(J,Q)}function B0(J){for(let Q of Object.keys(HJ))if(HJ[Q]===J.type)return Q;return String(J.type)}function N8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}EJ(J,Q,$,Z)}var h8=S6({createElement:Y4,createTextNode:H0,replaceText:j0,isTextNode:lJ,setProperty:N8,insertNode(J,Q,$){qJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:k8,getFirstChild:S8,getNextSibling:W4}),{render:T8,effect:NQ,memo:p,createComponent:Y,createElement:G4,insert:hQ,spread:f8,mergeProps:TQ,use:fQ}=h8,yQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},y8=null;function H4(J){y8=J}function x8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function j4(J,Q){let $=G4(J);return f8($,Q,!1),x8(Q.nodeRef,$),$}function F(J){return j4("view",J)}function R(J){return j4("text",J)}var xQ=new WeakMap,vQ=new WeakMap,v8={}!==null?Object.freeze({...{}}):Object.freeze({}),mQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:v8}),uQ=new Map,XJ=36000,s0=30,m8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(XJ),tapeAnalog:new Uint16Array(XJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function u8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-s0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)n1(()=>{W.treeDirty=!0}),r8();else n1(null);globalThis.__pocketDevtools=n8}function l8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)c8(),s8();let X=Q,z=$===void 0?jJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(XJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==jJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function F4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function M4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return F4(J.masks,0,Q)}function U4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return F4(J.analog??[],jJ,Q)}function R4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,f({t:"hello",app:W.app,host:o8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` +`))if(q.trim())d8(q)}}function d8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)f({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),a0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":P4();break;case"eval":{let Z=!0,q;try{q=K0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}f({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":f({t:"tape",tape:K4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}f({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())f({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else f({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=M4(Z),W.replayAnalog=Z.analog?U4(Z):null,W.replayTouch=Z.touch?R4(Z):null,W.replayAt=0;break}default:break}}function i8(){if(W.treeDirty&&W.frame-W.treeSentAt>=s0)P4();if(W.frame%m8===0)a0()}function s8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,f({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,f({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){f({t:"stats",frame:W.frame,nodes:L4(ZJ),tapeLen:W.tapeLen,paused:W.paused})}function P4(){W.treeDirty=!1,W.treeSentAt=W.frame,f({t:"tree",frame:W.frame,root:V4(ZJ)})}function a8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(a8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function D4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function V4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(D4(J,(q)=>{if(q.domNodeType===8)return;Z.push(V4(q))}),Z.length)Q.k=Z;return Q}function L4(J){let Q=1;return D4(J,($)=>{Q+=L4($)}),Q}function r8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{f({t:"log",level:$,args:q.map((X)=>K0(X))}),Z?.apply(Q,q)}}}function K0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?O4(X):JSON.stringify(O4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>K0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${K0(z,Q+1)}`).join(", ")}}`}function O4(J){return J.length>200?J.slice(0,199)+"…":J}function o8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var n8={get frame(){return W.frame},dumpTape:()=>K4(),replay:(J)=>{W.replayMasks=M4(J),W.replayAnalog=J.analog?U4(J):null,W.replayTouch=J.touch?R4(J):null,W.replayAt=0}},I4=new Map,o0=new Map;function A4(J){return J.trim().replace(/\s+/g," ")}function _4(J){return J.split(" ").sort().join(" ")}var k4=-1;function t8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=A4(Q);I4.set(Z,$);let q=_4(Z),X=o0.get(q);o0.set(q,X!==void 0&&X!==$?k4:$)}}function e8(J){let Q=A4(J),$=I4.get(Q);if($!==void 0)return $;let Z=o0.get(_4(Q));return Z===k4?void 0:Z}var n0=9,J2=(1<{let q=($&$2)!==0,X=q?t0:n0,z=q?Z2:J2;return Object.freeze({id:$>>>(q?q2:Q2)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Y2(){return F0}function z2(){F0=e0}var S4=8,YJ=8,W2=3,G2=8,H2=6,j2=0.5,s=1,cJ=2,J1=4,UJ=8,NJ=[],b4=0,M0=0,zJ=Array.from({length:S4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(YJ),histY:new Int16Array(YJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function B2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function K2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=o1(Q,$,Z.fact);let G=Z.hit;if(G)return B2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=NJ[z];if(G.disposed)continue;if(b4>0&&!G.opts.allowWhenBlocked)continue;if(!K2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function U2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%YJ,J.histLenz||Z>z))q.flags[J.slot]|=cJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(cJ|J1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??j2)*h1()));if(J.frames=0)NJ.splice($,1)},cancel(){if(!Q.disposed)C4(Q)},get panning(){for(let $ of zJ)if($.used&&Q.flags[$.slot]&UJ)return!0;return!1}}}function L2(J){let Q=V2(J);return S0(()=>Q.dispose()),Q}function E4(){NJ.length=0,b4=0,M0=0;for(let J of zJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function O2(){return L2({onDown:(J)=>{let Q=r1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=r1(J.x,J.y,J.hit);if(Q)B8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var I2=1,Q1=new Map,U0=[];function A2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function _2(){I2=1,Q1.clear(),U0=[]}function k2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),A2()?.({t:"delivery",frame:T1(),id:Q,kind:Z.kind}),Z.onResult($)}}var N4=new Set;function S2(){if(N4.size===0)return;for(let J of N4)J()}var b2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[28] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-base text-orange-600 font-bold":9,"h-[76] pt-3 text-lg text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-base text-emerald-700 font-bold":13,"h-[84] pt-3 text-lg text-slate-900":14,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":15,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":16,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":17,"text-base text-slate-600 font-bold":18,"pt-6 text-lg text-slate-500":19,"pt-6 text-lg text-slate-900 font-bold":20,"h-[146] px-6 pt-7 flex-col bg-slate-50":21,"h-[80]":22,"h-[1060] px-6 pt-5 flex-col":23,"h-[48] px-4 justify-center bg-slate-100":24,"text-base text-slate-600":25,"pt-[10] flex-col gap-[12]":26,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":27,"w-[48] h-[48] items-center justify-center bg-blue-100":28,"w-[48] h-[48] items-center justify-center bg-emerald-100":29,"text-lg text-blue-700 font-bold":30,"text-lg text-emerald-700 font-bold":31,"w-[474] flex-col gap-2":32,"text-lg text-slate-900 font-bold":33,"text-base text-slate-500":34,"pt-20 pl-10 text-lg text-slate-500":35,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":36,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":37,"h-[1060] px-6 pt-7 flex-col gap-4":38,"text-base text-slate-500 font-bold":39,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":40,"flex-row items-center gap-5":41,"w-[68] h-[68] items-center justify-center bg-emerald-100":42,"text-xl text-emerald-700 font-bold":43,"flex-col gap-2":44,"text-xl text-slate-900 font-bold":45,"text-lg text-slate-600":46,"text-2xl text-orange-600":47,"w-[68] h-[68] items-center justify-center bg-indigo-100":48,"text-xl text-indigo-700 font-bold":49,"mt-4 h-[112] px-6 justify-center bg-slate-100":50,"relative h-[154] px-5 pt-5 flex-col bg-white":51,"pt-3 text-lg text-orange-600 font-bold":52,"pt-3 text-base text-slate-500":53,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":54,"text-lg text-white font-bold":55,"h-[40] pt-3 text-base text-slate-500":56,"h-[470] flex-col gap-2":57,"h-[214] px-7 items-center justify-center bg-slate-100":58,"text-lg text-slate-500 font-bold":59,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":60,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":61,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":62,"h-[160] px-5 pt-5 flex-col bg-white":63,"pt-3 text-lg text-slate-900 font-bold":64,"pt-3 text-base text-slate-600":65,"h-[108] pt-7 flex-row gap-4":66,"w-[316] h-[80] items-center justify-center bg-slate-100":67,"w-[340] h-[80] items-center justify-center bg-red-100":68,"text-lg text-red-500 font-bold":69,"h-[1052] px-6 pt-5 flex-col":70,"h-[270] px-[22] pt-6 bg-white":71,"text-lg text-slate-900":72,"text-lg text-slate-400":73,"h-[86] px-1 flex-row items-center justify-between":74,"w-[132] h-[58] items-center justify-center bg-slate-300":75,"w-[132] h-[58] items-center justify-center bg-slate-100":76,"text-base text-slate-900 font-bold":77,"h-[140] flex-row gap-2":78,"grow h-[120] items-center justify-center bg-slate-300":79,"grow h-[120] items-center justify-center bg-white":80,"w-[104] h-[120] items-center justify-center bg-slate-300":81,"w-[104] h-[120] items-center justify-center bg-slate-100":82,"h-[176] flex-row gap-2":83,"w-[92] h-[156] items-center justify-center bg-slate-300":84,"w-[92] h-[156] items-center justify-center bg-slate-100":85,"w-[300] h-[156] items-center justify-center bg-slate-300":86,"w-[300] h-[156] items-center justify-center bg-slate-100":87,"w-[144] h-[156] items-center justify-center bg-slate-300":88,"w-[144] h-[156] items-center justify-center bg-slate-100":89,"w-[112] h-[156] items-center justify-center bg-emerald-700":90,"w-[112] h-[156] items-center justify-center bg-emerald-500":91,"text-base text-slate-950 font-bold":92,"h-[108] px-6 py-3 flex-col bg-slate-50":93,"h-[84] items-center justify-center bg-slate-300":94,"h-[84] items-center justify-center bg-slate-100":95,"h-[1168] px-6 pt-5 flex-col":96,"h-[82] px-4 justify-center bg-white":97,"w-[584] h-[900] px-5 pt-5 bg-slate-950":98,"text-base text-slate-200":99,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":100,"text-lg text-orange-600 font-bold":101,"w-[584] h-[900] px-5 pt-5 bg-white":102,"text-base text-slate-900":103,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":104,"absolute inset-0 z-50 flex-col items-center justify-center":105,"absolute inset-0 bg-slate-950":106,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":107,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":108,"flex-row flex-wrap":109,grow:110,"text-2xl text-white font-bold":111,"text-2xl text-slate-950 font-bold":112,"px-6":113,"px-6 py-5":114,"gap-4":115,"rounded-xl shadow bg-white border-slate-100":116,"rounded-xl shadow bg-emerald-100 border-emerald-500":117,"bg-white":118,"bg-slate-100":119,"bg-slate-950":120,"px-3 py-2 rounded-lg bg-slate-100":121,"px-3 py-2 rounded-lg bg-indigo-100":122,"text-base text-indigo-700 font-bold":123,"px-3 py-2 rounded-lg bg-emerald-100":124,"px-3 py-2 rounded-lg bg-amber-100":125,"text-base text-amber-700 font-bold":126,"px-3 py-2 rounded-lg bg-red-100":127,"text-base text-red-500 font-bold":128,"w-[34] h-[34] rounded-lg bg-amber-400":129,"w-[34] h-[34] rounded-lg bg-red-500":130,"w-[34] h-[34] rounded-lg bg-slate-800":131,"w-[34] h-[34] rounded-lg bg-emerald-500":132,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":133,"flex-row items-center gap-4":134,"w-[34] text-2xl text-white font-bold":135,"w-[332] flex-col items-end gap-2":136,"text-base text-slate-300 font-bold":137,"text-base text-slate-400":138,"h-[166] px-6 pt-6 flex-col gap-3":139,"h-[44] px-1 flex-row items-center justify-between":140,"w-full h-full items-center justify-center rounded-xl bg-slate-200":141,"w-full h-full items-center justify-center rounded-xl bg-red-100":142,"w-full h-full items-center justify-center rounded-xl bg-slate-100":143,"w-full h-full items-center justify-center rounded-xl bg-orange-600":144,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":145,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":146,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":147,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":148,"text-2xl text-indigo-700 font-bold":149,"text-2xl text-slate-600 font-bold":150,"pt-7 text-2xl text-slate-900 font-bold":151,"pt-4 text-lg text-slate-500":152,"text-xl text-emerald-600 font-bold":153,"text-xl text-red-500 font-bold":154,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":155,"text-base text-red-300":156,"text-base text-slate-300":157,"text-base text-red-500":158,"w-full h-full px-6 flex-row items-center bg-slate-950":159,"w-full h-full flex-row items-center":160};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var g2="ui:styles",w2="ui:font.",h4="ui:img.",T4="ui:sprite.";function C2(){return globalThis.ui}function E2(J){if(J.__textures)return;for(let Q of T0(h4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)Q4(Q.slice(h4.length),Z)}}function N2(J){if(J.__sprites)return;for(let Q of T0(T4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)Z4(Q.slice(T4.length),{handle:V,frames:G,cols:P,step:D})}}function f4(J){let Q=G4("view");return EJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function h2(J,Q){if(!R0||!P0)return;EJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),EJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function T2(J,Q={}){let $=v6(Q.ops);if(m6($),I8(e8),Q.styles)t8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)Q4(_,Z[_]);let j=$.ops.__sprites;if(j)for(let _ in j)Z4(_,j[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)m1(Q.pak);if(q8()){for(let j of T0())if(j===g2)$.ops.loadStyles?.(vJ(j));else if(j.startsWith(w2))$.ops.loadFontAtlas?.(vJ(j))}}let q=C1($.ops),X=q?.w??b1,z=q?.h??g1,G=f4({width:X,height:z,overflow:u.Overflow.Hidden}),P=f4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});qJ(ZJ,G),qJ(ZJ,P),H4(P),R0=G,P0=P,u1(G),s1(ZJ),Q8(),E4(),O2(),a6(),_2(),u8($.ops),u6(l8((j,_,N,h)=>{r6(),o6(_),X2(N,h),S2(),k2(),D2(),$8(j),V8(j),X4()}));let D=T8(J,G),V=l6(h2);return()=>{V(),z2(),E4(),D(),u1(null),s1(null),H4(null),R0=null,P0=null;for(let j of ZJ.children.splice(0))j.parent=null,$.ops.destroyNode(j.id);X4()}}function f2(J,Q={}){let $=Q.ops??C2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)m1(Q.pak);return E2($),N2($),T2(J,{ops:$,styles:Q.styles??b2,pak:Q.pak})}var y2="$b",x2=65536,y4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function u2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function x4(){let J=u2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function l2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,x2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=v2(z.data[y2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function p2(J,Q){let $=l2(x4(),J);return Q==="utf8"||Q==="utf-8"?m2($):$}function c2(J,Q){let $=x4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var d2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"};function i2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(F,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(F,{class:"flex-row items-center gap-4",get children(){return[p(()=>p(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(F,{get["class"](){return Q()}})),Y(R,{get["class"](){return d2.appTitle},get children(){return J.title}})]}}),Y(F,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function s2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(F,{get["class"](){return Q()},get children(){return Y(R,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(F,{get["class"](){return J.top},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(F,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var lQ="‘’“”–—…•",v4=new Map,m4=new Map,a2=512;function D0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=v4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return v4.set($,q),q}function r2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=D0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function $1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=m4.get(Z);if(q)return q;let X=[],z=D0(" ",Q);for(let G of J.split(` +`)){let P=G.split(" ").flatMap((j)=>j&&D0(j,Q)>$?r2(j,Q,$):[j]),D="",V=0;for(let j of P){let _=D0(j,Q);if(!D)D=j,V=_;else if(V+z+_<=$)D+=" "+j,V+=z+_;else X.push(D),D=j,V=_}X.push(D)}return m4.set(Z,X),X}function Z1(J,Q,$,Z){let q=J.slice(0,a2),X=$1(q,Q,$);if(q.length===J.length&&X.length<=Z)return X.join(` `);let z=X.slice(0,Z),G=z.length-1;return z[G]=z[G].replace(/[\s.]+$/,"")+"…",z.join(` -`)}var v4=3,m4=2,u4=536,l4=544,p4=39,[RJ,o2]=g({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[y,n]=g("chat"),[Z1,n2]=g("chat"),[q1,c4]=g(0),[PJ,d4]=g(""),[sJ,hJ]=g(0),[aJ,X1]=g([]),[t2,V0]=g(""),[i4,L0]=g(null),[s4,a4]=g(null),[O0,I0]=g(0),[v,t]=g(""),[DJ,r4]=g("letters"),[Y1,z1]=g(!1),[W1,o4]=g({type:"prompt"}),[WJ,n4]=g(null),[rJ,t4]=g(0),e4=new Map,J6=["qwertyuiop","asdfghjkl","zxcvbnm"],Q6=["1234567890","-/:;()$&@",`.,?!'"+`],$6=["chat","files","apps","settings"];function e2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function JQ(J,Q){return J?J+"/"+Q:Q}function A0(J=PJ(),Q=!1){let $=e4.get(J);if(!Q&&$){X1($),V0(""),hJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=c2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));e4.set(J,Z),X1(Z),V0(""),hJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){X1([]),V0(Z instanceof Error?Z.message:String(Z))}}function QQ(){let J=[];for(let Q of RJ().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Z6(){let J=QQ(),Q=Math.max(0,J.length-2),$=Math.min(q1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function VJ(J){return Y(i2,{get title(){return J.title},get accent(){return p(()=>RJ().agent==="FAULTED")()?"danger":RJ().agent==="THINKING"?"busy":"ready"}})}function _0(){return Y(K,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(SJ,{each:$6,children:(J)=>Y(K,{get["class"](){return Z1()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function $Q(){let J=()=>RJ().schedule;return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"ESP32 PI AGENT"}),Y(K,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(SJ,{get each(){return Z6()},children:(Q)=>Y(K,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(K,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(K,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-base text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-lg text-slate-900",get children(){return x4(Q.user,v4,u4,3)}}),Y(K,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(K,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(K,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-base text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-lg text-slate-900",get children(){return x4(Q.assistant,v4,u4,3)}})]}})}),Y(iJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(K,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-base text-slate-600 font-bold",children:"NEXT WAKE"}),Y(bJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-lg text-slate-500",children:`NO WAKE SCHEDULED +`)}var q1=3,u4=2,X1=536,l4=544,p4=39,[RJ,o2]=g({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[y,n]=g("chat"),[Y1,n2]=g("chat"),[z1,c4]=g(0),[PJ,d4]=g(""),[sJ,hJ]=g(0),[aJ,W1]=g([]),[t2,V0]=g(""),[i4,L0]=g(null),[s4,a4]=g(null),[O0,I0]=g(0),[v,t]=g(""),[DJ,r4]=g("letters"),[G1,H1]=g(!1),[j1,o4]=g({type:"prompt"}),[WJ,n4]=g(null),[rJ,t4]=g(0),e4=new Map,J6=["qwertyuiop","asdfghjkl","zxcvbnm"],Q6=["1234567890","-/:;()$&@",`.,?!'"+`],$6=["chat","files","apps","settings"];function e2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function JQ(J,Q){return J?J+"/"+Q:Q}function A0(J=PJ(),Q=!1){let $=e4.get(J);if(!Q&&$){W1($),V0(""),hJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=c2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));e4.set(J,Z),W1(Z),V0(""),hJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){W1([]),V0(Z instanceof Error?Z.message:String(Z))}}function QQ(){let J=[];for(let Q of RJ().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Z6(){let J=QQ(),Q=Math.max(0,J.length-2),$=Math.min(z1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function VJ(J){return Y(i2,{get title(){return J.title},get accent(){return p(()=>RJ().agent==="FAULTED")()?"danger":RJ().agent==="THINKING"?"busy":"ready"}})}function _0(){return Y(F,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(SJ,{each:$6,children:(J)=>Y(F,{get["class"](){return Y1()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function $Q(){let J=()=>RJ().schedule,Q=()=>{let $=J();return Z1(String($?.name)+" "+String($?.next??"")+` -ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(R,{class:"pt-6 text-lg text-slate-900 font-bold",get children(){return String(J()?.name)+" "+String(J()?.next??"")+` +`+String($?.prompt??""),q1,X1,5)};return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"ESP32 PI AGENT"}),Y(F,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(SJ,{get each(){return Z6()},children:($)=>Y(F,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-base text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-lg text-slate-900",get children(){return Z1($.user,q1,X1,3)}}),Y(F,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-base text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-lg text-slate-900",get children(){return Z1($.assistant,q1,X1,3)}})]}})}),Y(iJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(F,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-base text-slate-600 font-bold",children:"NEXT WAKE"}),Y(bJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-lg text-slate-500",children:`NO WAKE SCHEDULED -`+String(J()?.prompt??"")}})}})]}}),Y(K,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(K,{class:"h-[80]",get children(){return Y(s2,{label:"TYPE A MESSAGE"})}})}}),Y(_0,{})]}})}function ZQ(){let J=()=>aJ().slice(sJ(),sJ()+8);return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return PJ()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(K,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",get children(){return"/workspace"+(PJ()?"/"+PJ():"")}})}}),Y(K,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(SJ,{get each(){return J()},children:(Q)=>Y(K,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(K,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-lg text-blue-700 font-bold":"text-lg text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(K,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,52)}}),Y(R,{class:"text-base text-slate-500",get children(){return p(()=>Q.kind==="dir")()?"FOLDER":e2(Q.size)}})]}})]}})})}}),Y(bJ,{get when(){return aJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-lg text-slate-500",get children(){return t2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(bJ,{get when(){return aJ().length>8},get children(){return Y(iJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(_0,{})]}})}function qQ(){return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"APPS"}),Y(K,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-base text-slate-500 font-bold",children:"2 INSTALLED APPS"}),Y(K,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(K,{class:"flex-row items-center gap-5",get children(){return[Y(K,{class:"w-[68] h-[68] items-center justify-center bg-emerald-100",get children(){return Y(R,{class:"text-xl text-emerald-700 font-bold",children:"R"})}}),Y(K,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Robinhood"}),Y(R,{class:"text-lg text-slate-600",children:"Portfolio and positions"}),Y(R,{class:"text-base text-slate-500",children:"UPDATES EVERY 5 MINUTES"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(K,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(K,{class:"flex-row items-center gap-5",get children(){return[Y(K,{class:"w-[68] h-[68] items-center justify-center bg-indigo-100",get children(){return Y(R,{class:"text-xl text-indigo-700 font-bold",children:"E"})}}),Y(K,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Exa Research"}),Y(R,{class:"text-lg text-slate-600",children:"Agent search history"}),Y(R,{class:"text-base text-slate-500",children:"STORED LOCALLY IN SQLITE"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(K,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",children:`APP DATA STAYS ISOLATED. -PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(_0,{})]}})}function XQ(){let J=()=>RJ().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(rJ(),rJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"SETTINGS"}),Y(K,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-lg text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return Z()}}),Y(K,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-lg text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-base text-slate-500",children:"AVAILABLE NETWORKS"}),Y(K,{class:"h-[470] flex-col gap-2",get children(){return[Y(bJ,{get when(){return $().length>0},get fallback(){return Y(K,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-500 font-bold",children:`NO NETWORK LIST YET +ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(R,{class:"pt-6 text-lg text-slate-900 font-bold",get children(){return Q()}})}})]}}),Y(F,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(F,{class:"h-[80]",get children(){return Y(s2,{label:"TYPE A MESSAGE"})}})}}),Y(_0,{})]}})}function ZQ(){let J=()=>aJ().slice(sJ(),sJ()+8);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return PJ()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",get children(){return"/workspace"+(PJ()?"/"+PJ():"")}})}}),Y(F,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(SJ,{get each(){return J()},children:(Q)=>Y(F,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(F,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-lg text-blue-700 font-bold":"text-lg text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(F,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,52)}}),Y(R,{class:"text-base text-slate-500",get children(){return p(()=>Q.kind==="dir")()?"FOLDER":e2(Q.size)}})]}})]}})})}}),Y(bJ,{get when(){return aJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-lg text-slate-500",get children(){return t2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(bJ,{get when(){return aJ().length>8},get children(){return Y(iJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(_0,{})]}})}function qQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"APPS"}),Y(F,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-base text-slate-500 font-bold",children:"2 INSTALLED APPS"}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-emerald-100",get children(){return Y(R,{class:"text-xl text-emerald-700 font-bold",children:"R"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Robinhood"}),Y(R,{class:"text-lg text-slate-600",children:"Portfolio and positions"}),Y(R,{class:"text-base text-slate-500",children:"UPDATES EVERY 5 MINUTES"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-indigo-100",get children(){return Y(R,{class:"text-xl text-indigo-700 font-bold",children:"E"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Exa Research"}),Y(R,{class:"text-lg text-slate-600",children:"Agent search history"}),Y(R,{class:"text-base text-slate-500",children:"STORED LOCALLY IN SQLITE"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",children:`APP DATA STAYS ISOLATED. +PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(_0,{})]}})}function XQ(){let J=()=>RJ().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(rJ(),rJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"SETTINGS"}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-lg text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return Z()}}),Y(F,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-lg text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-base text-slate-500",children:"AVAILABLE NETWORKS"}),Y(F,{class:"h-[470] flex-col gap-2",get children(){return[Y(bJ,{get when(){return $().length>0},get fallback(){return Y(F,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-500 font-bold",children:`NO NETWORK LIST YET -TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(SJ,{get each(){return $()},children:(q)=>Y(K,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-base text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(bJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(iJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(K,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-lg text-slate-900 font-bold",get children(){return RJ().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-base text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(K,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(K,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(K,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-lg text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(_0,{})]}})}function YQ(){let J=()=>W1(),Q=()=>DJ()==="letters"?J6:Q6,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(K,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(K,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-base text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(K,{get["class"](){return WJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(SJ,{get each(){return Q()},children:(Z,q)=>Y(K,{class:"h-[140] flex-row gap-2",get children(){return[Y(SJ,{get each(){return Z.split("")},children:(X)=>Y(K,{get["class"](){return WJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return p(()=>!!Y1())()?X.toUpperCase():X}})}})}),Y(bJ,{get when(){return q()===2},get children(){return Y(K,{get["class"](){return WJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(K,{class:"h-[176] flex-row gap-2",get children(){return[Y(K,{get["class"](){return WJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"123":"ABC"}})}}),Y(K,{get["class"](){return WJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"SPACE"})}}),Y(K,{get["class"](){return WJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"SHIFT":". ?"}})}}),Y(K,{get["class"](){return WJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(R,{class:"text-base text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(K,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(K,{get["class"](){return WJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function zQ(){let J=()=>i4(),Q=()=>(J()?.text??"").split(` -`),$=()=>J()?.lineOffset??0;return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< FILE VIEWER"}),Y(K,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(K,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(R,{class:"text-base text-slate-200",get children(){return Q().slice($(),$()+39).join(` -`)}})}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function WQ(){let J=()=>s4(),Q=()=>$1(J()?.text??"",m4,l4);return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< MESSAGE READER"}),Y(K,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(K,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(K,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-base text-slate-900",get children(){return Q().slice(O0(),O0()+p4).join(` -`)}})}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function GQ(){return Y(K,{class:"flex-col w-full h-full bg-slate-50",get children(){return p(()=>y()==="chat")()?Y($Q,{}):p(()=>y()==="files")()?Y(ZQ,{}):p(()=>y()==="apps")()?Y(qQ,{}):p(()=>y()==="settings")()?Y(XQ,{}):p(()=>y()==="keyboard")()?Y(YQ,{}):p(()=>y()==="viewer")()?Y(zQ,{}):Y(WQ,{})}})}function HQ(J){j6(()=>{if(n2(J),n(J),J==="files")A0()})}function q6(J,Q){let $=DJ()==="letters"?J6:Q6,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=q6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function jQ(J,Q){if(Q>=1164)return t(""),n(Z1()),"";if(J>=548&&Q>=402&&Q<=482)return t(""),"";let $=q6(J,Q);if($){let Z=DJ()==="letters"&&Y1()?$.toUpperCase():$,q=W1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return t(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)r4(DJ()==="letters"?"numbers":"letters"),z1(!1);else if(J<=424){if(v())t(v()+" ")}else if(J<=576)if(DJ()==="letters")z1(!Y1());else t(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=W1();if(t(""),r4("letters"),z1(!1),n(Z1()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}f2(()=>Y(GQ,{})),queueMicrotask(()=>A0("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return o2(JSON.parse(J)),""},pointerDown(J,Q){return n4(y()==="keyboard"?BQ(J,Q):null),""},pointerUp(){return n4(null),""},tap(J,Q){if(y()==="keyboard")return jQ(J,Q);if(y()==="viewer"){let $=i4();if(J<104&&Q<112)L0(null),n("files");else if($&&J>=620&&Q>=170&&Q<=340)L0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)L0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` -`).length-39),$.lineOffset+18)});return""}if(y()==="reader"){if(J<104&&Q<112)a4(null),I0(0),n("chat");else if(J>=620&&Q>=170&&Q<=340)I0(Math.max(0,O0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=$1(s4()?.text??"",m4,l4).length;I0(Math.min(Math.max(0,$-p4),O0()+18))}return""}if(Q>=1172)return HQ($6[Math.min(3,Math.floor(J/180))]),"";if(y()==="chat"){if(J>=620&&Q>=140&&Q<=272)c4(q1()+2);else if(J>=620&&Q>=624&&Q<=756)c4(Math.max(0,q1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=Z6()[$];if(Z){let q=Q>=140+$*320+150;a4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),I0(0),n("reader")}}else if(Q>=1070&&Q<=1150)o4({type:"prompt"}),t(""),n("keyboard");return""}if(y()==="files"){if(J<104&&Q<112&&PJ()){let $=PJ().split("/");$.pop();let Z=$.join("/");d4(Z),hJ(0),A0(Z)}else if(J>=620&&Q>=170&&Q<=340)hJ(Math.max(0,sJ()-4));else if(J>=620&&Q>=920&&Q<=1100)hJ(Math.min(Math.max(0,aJ().length-8),sJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=aJ()[sJ()+$];if(Z){let q=JQ(PJ(),Z.name);if(Z.kind==="dir")d4(q),hJ(0),A0(q);else try{L0({path:"/workspace/"+q,text:p2(q,"utf8"),lineOffset:0}),n("viewer")}catch(X){V0(X instanceof Error?X.message:String(X))}}}return""}if(y()==="apps"){if(Q>=162&&Q<324)return JSON.stringify({type:"navigate",app:"robinhood"});if(Q>=324&&Q<490)return JSON.stringify({type:"navigate",app:"exa"});return""}if(y()==="settings"){let $=RJ().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)t4(Math.max(0,rJ()-4));else if(J>=620&&Q>=650&&Q<=782)t4(Math.min(Math.max(0,$.length-5),rJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[rJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});o4({type:"wifi",ssid:q.ssid}),t(""),n("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); +TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(SJ,{get each(){return $()},children:(q)=>Y(F,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-base text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(bJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(iJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(F,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-lg text-slate-900 font-bold",get children(){return RJ().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-base text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(F,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(F,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(F,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-lg text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(_0,{})]}})}function YQ(){let J=()=>j1(),Q=()=>DJ()==="letters"?J6:Q6,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(F,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(F,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-base text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(F,{get["class"](){return WJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(SJ,{get each(){return Q()},children:(Z,q)=>Y(F,{class:"h-[140] flex-row gap-2",get children(){return[Y(SJ,{get each(){return Z.split("")},children:(X)=>Y(F,{get["class"](){return WJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return p(()=>!!G1())()?X.toUpperCase():X}})}})}),Y(bJ,{get when(){return q()===2},get children(){return Y(F,{get["class"](){return WJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(F,{class:"h-[176] flex-row gap-2",get children(){return[Y(F,{get["class"](){return WJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"123":"ABC"}})}}),Y(F,{get["class"](){return WJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"SPACE"})}}),Y(F,{get["class"](){return WJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"SHIFT":". ?"}})}}),Y(F,{get["class"](){return WJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(R,{class:"text-base text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(F,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(F,{get["class"](){return WJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function zQ(){let J=()=>i4(),Q=()=>(J()?.text??"").split(` +`),$=()=>J()?.lineOffset??0;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< FILE VIEWER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(R,{class:"text-base text-slate-200",get children(){return Q().slice($(),$()+39).join(` +`)}})}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function WQ(){let J=()=>s4(),Q=()=>$1(J()?.text??"",u4,l4);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< MESSAGE READER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-base text-slate-900",get children(){return Q().slice(O0(),O0()+p4).join(` +`)}})}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function GQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return p(()=>y()==="chat")()?Y($Q,{}):p(()=>y()==="files")()?Y(ZQ,{}):p(()=>y()==="apps")()?Y(qQ,{}):p(()=>y()==="settings")()?Y(XQ,{}):p(()=>y()==="keyboard")()?Y(YQ,{}):p(()=>y()==="viewer")()?Y(zQ,{}):Y(WQ,{})}})}function HQ(J){B6(()=>{if(n2(J),n(J),J==="files")A0()})}function q6(J,Q){let $=DJ()==="letters"?J6:Q6,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=q6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function BQ(J,Q){if(Q>=1164)return t(""),n(Y1()),"";if(J>=548&&Q>=402&&Q<=482)return t(""),"";let $=q6(J,Q);if($){let Z=DJ()==="letters"&&G1()?$.toUpperCase():$,q=j1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return t(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)r4(DJ()==="letters"?"numbers":"letters"),H1(!1);else if(J<=424){if(v())t(v()+" ")}else if(J<=576)if(DJ()==="letters")H1(!G1());else t(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=j1();if(t(""),r4("letters"),H1(!1),n(Y1()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}f2(()=>Y(GQ,{})),queueMicrotask(()=>A0("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return o2(JSON.parse(J)),""},pointerDown(J,Q){return n4(y()==="keyboard"?jQ(J,Q):null),""},pointerUp(){return n4(null),""},tap(J,Q){if(y()==="keyboard")return BQ(J,Q);if(y()==="viewer"){let $=i4();if(J<104&&Q<112)L0(null),n("files");else if($&&J>=620&&Q>=170&&Q<=340)L0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)L0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` +`).length-39),$.lineOffset+18)});return""}if(y()==="reader"){if(J<104&&Q<112)a4(null),I0(0),n("chat");else if(J>=620&&Q>=170&&Q<=340)I0(Math.max(0,O0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=$1(s4()?.text??"",u4,l4).length;I0(Math.min(Math.max(0,$-p4),O0()+18))}return""}if(Q>=1172)return HQ($6[Math.min(3,Math.floor(J/180))]),"";if(y()==="chat"){if(J>=620&&Q>=140&&Q<=272)c4(z1()+2);else if(J>=620&&Q>=624&&Q<=756)c4(Math.max(0,z1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=Z6()[$];if(Z){let q=Q>=140+$*320+150;a4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),I0(0),n("reader")}}else if(Q>=1070&&Q<=1150)o4({type:"prompt"}),t(""),n("keyboard");return""}if(y()==="files"){if(J<104&&Q<112&&PJ()){let $=PJ().split("/");$.pop();let Z=$.join("/");d4(Z),hJ(0),A0(Z)}else if(J>=620&&Q>=170&&Q<=340)hJ(Math.max(0,sJ()-4));else if(J>=620&&Q>=920&&Q<=1100)hJ(Math.min(Math.max(0,aJ().length-8),sJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=aJ()[sJ()+$];if(Z){let q=JQ(PJ(),Z.name);if(Z.kind==="dir")d4(q),hJ(0),A0(q);else try{L0({path:"/workspace/"+q,text:p2(q,"utf8"),lineOffset:0}),n("viewer")}catch(X){V0(X instanceof Error?X.message:String(X))}}}return""}if(y()==="apps"){if(Q>=162&&Q<324)return JSON.stringify({type:"navigate",app:"robinhood"});if(Q>=324&&Q<490)return JSON.stringify({type:"navigate",app:"exa"});return""}if(y()==="settings"){let $=RJ().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)t4(Math.max(0,rJ()-4));else if(J>=620&&Q>=650&&Q<=782)t4(Math.min(Math.max(0,$.length-5),rJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[rJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});o4({type:"wifi",ssid:q.ssid}),t(""),n("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); From 9b37c755852e246c47237923a861ecb968da12ec Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Tue, 11 Aug 2026 16:38:16 +0800 Subject: [PATCH 16/24] fix(robinhood): align catalog descriptions with exposed tools --- apps/robinhood/agent-app.json | 2 +- apps/robinhood/dist/data-action.js | 18 +++++++++--------- apps/robinhood/tool-catalog.json | 16 ++++++++-------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/apps/robinhood/agent-app.json b/apps/robinhood/agent-app.json index f5acc22..a28fa9c 100644 --- a/apps/robinhood/agent-app.json +++ b/apps/robinhood/agent-app.json @@ -61,7 +61,7 @@ "tools": [ { "name": "robinhood.search_tools", - "description": "Search Pocket Pi's checked-in Robinhood Trading MCP catalog. Use this before robinhood.call whenever the exact upstream Tool and arguments are not already present in the conversation. Returns the official description, exact JSON Schema, Pocket Pi persistence behavior, and whether the Tool is a real account or real-money action. This performs no Robinhood request and writes no SQLite data.", + "description": "Search Pocket Pi's checked-in Robinhood Trading MCP catalog. Use this before robinhood.call whenever the exact upstream Tool and arguments are not already present in the conversation. Returns the checked-in description, exact upstream JSON Schema, Pocket Pi persistence behavior, and whether the Tool is a real account or real-money action. This performs no Robinhood request and writes no SQLite data.", "parameters": { "type": "object", "properties": { diff --git a/apps/robinhood/dist/data-action.js b/apps/robinhood/dist/data-action.js index 4d3b50d..dd3db55 100644 --- a/apps/robinhood/dist/data-action.js +++ b/apps/robinhood/dist/data-action.js @@ -1,4 +1,4 @@ -(()=>{var b={source:"https://agent.robinhood.com/mcp/trading",protocolVersion:"2025-06-18",retrievedAt:"2026-08-10T09:05:39+00:00",tools:[{name:"add_option_to_watchlist",namespace:"option_market_data",description:"Add option contracts to the user's options watchlist. Works for both equity options (AAPL, NVDA) and index options (SPX, NDX, RUT). Source option_ids from get_option_instruments. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{option_ids:{type:["null","array"],items:{type:"string"},description:"Option contract UUIDs to add. Each becomes a single-leg position on the user's options watchlist. Source from get_option_instruments."},position_type:{type:"string",description:'"long" (default) or "short". Applies to every option_id in this call. For mixed long/short adds, issue two calls.'}},required:["option_ids"],additionalProperties:!1}},{name:"add_to_watchlist",namespace:"watchlists",description:"Add items to a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes like SPX, NDX) is required — mutually exclusive. For options use add_option_to_watchlist (separate dedicated watchlist). Futures still require the Robinhood app. Already-present items are no-ops. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to add items to."},symbols:{type:["null","array"],items:{type:"string"},description:"Stock symbols to add (e.g. ['AAPL', 'NVDA']). US stocks and ETFs only. Mutually exclusive with currency_pair_ids and index_ids."},currency_pair_ids:{type:["null","array"],items:{type:"string"},description:"Currency-pair UUIDs to add (e.g. the object_id from get_watchlist_items where object_type=currency_pair, or the id from get_currency_pairs). Mutually exclusive with symbols and index_ids."},index_ids:{type:["null","array"],items:{type:"string"},description:"Market-index UUIDs to add (the id field from get_indexes; SPX, NDX, DJI, etc.). Mutually exclusive with symbols and currency_pair_ids."}},required:["list_id"],additionalProperties:!1}},{name:"cancel_equity_order",namespace:"equity_trading",description:"Cancel an open equity order by order_id. Resolve order_id via get_equity_orders and pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the order, from get_accounts. Must be agentic_allowed=true. The upstream rejects mismatches against the order's owning account."},order_id:{type:"string",description:"Order UUID from get_equity_orders. Must live in account_number."}},required:["account_number","order_id"],additionalProperties:!1}},{name:"cancel_option_exercise",namespace:"option_trading",description:"Cancel all queued exercise requests for an option position. Pass the same account_number and option_id used for exercise_option. Internally looks up all queued exercise events for that option and cancels each one. Typically there is one; multiple means separate exercise batches were submitted. Only events in state=queued can be cancelled; events already processing are rejected by the broker. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the exercise. Must be agentic_allowed=true."},option_id:{type:"string",description:"Option instrument UUID — the same option_id used for exercise_option. The tool looks up the queued exercise for this option and cancels it."}},required:["account_number","option_id"],additionalProperties:!1}},{name:"cancel_option_order",namespace:"option_trading",description:"Cancel an open option order by account_number + order_id. Resolve order_id via get_option_orders and pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the order, from get_accounts. Must be agentic_allowed=true. Mismatches against the order's owning account are rejected."},order_id:{type:"string",description:"Order UUID from get_option_orders. Must live in account_number."}},required:["account_number","order_id"],additionalProperties:!1}},{name:"create_scan",namespace:"scanners",description:`Create a new saved scanner (screener) on the user's account, optionally applying a preset and custom filters in a single call. Returns the new scan's id, title, applied filters, and the initial live market results. +(()=>{var b={source:"https://agent.robinhood.com/mcp/trading",protocolVersion:"2025-06-18",retrievedAt:"2026-08-10T09:05:39+00:00",tools:[{name:"add_option_to_watchlist",namespace:"option_market_data",description:"Add option contracts to the user's options watchlist. Works for both equity options (AAPL, NVDA) and index options (SPX, NDX, RUT). Source option_ids from get_option_instruments. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{option_ids:{type:["null","array"],items:{type:"string"},description:"Option contract UUIDs to add. Each becomes a single-leg position on the user's options watchlist. Source from get_option_instruments."},position_type:{type:"string",description:'"long" (default) or "short". Applies to every option_id in this call. For mixed long/short adds, issue two calls.'}},required:["option_ids"],additionalProperties:!1}},{name:"add_to_watchlist",namespace:"watchlists",description:"Add items to a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes like SPX, NDX) is required — mutually exclusive. For options use add_option_to_watchlist (separate dedicated watchlist). Futures still require the Robinhood app. Already-present items are no-ops. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to add items to."},symbols:{type:["null","array"],items:{type:"string"},description:"Stock symbols to add (e.g. ['AAPL', 'NVDA']). US stocks and ETFs only. Mutually exclusive with currency_pair_ids and index_ids."},currency_pair_ids:{type:["null","array"],items:{type:"string"},description:"Currency-pair UUIDs to add, available as object_id from get_watchlist_items entries where object_type=currency_pair. Mutually exclusive with symbols and index_ids."},index_ids:{type:["null","array"],items:{type:"string"},description:"Market-index UUIDs to add (the id field from get_indexes; SPX, NDX, DJI, etc.). Mutually exclusive with symbols and currency_pair_ids."}},required:["list_id"],additionalProperties:!1}},{name:"cancel_equity_order",namespace:"equity_trading",description:"Cancel an open equity order by order_id. Resolve order_id via get_equity_orders and pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the order, from get_accounts. Must be agentic_allowed=true. The upstream rejects mismatches against the order's owning account."},order_id:{type:"string",description:"Order UUID from get_equity_orders. Must live in account_number."}},required:["account_number","order_id"],additionalProperties:!1}},{name:"cancel_option_exercise",namespace:"option_trading",description:"Cancel all queued exercise requests for an option position. Pass the same account_number and option_id used for exercise_option. Internally looks up all queued exercise events for that option and cancels each one. Typically there is one; multiple means separate exercise batches were submitted. Only events in state=queued can be cancelled; events already processing are rejected by the broker. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the exercise. Must be agentic_allowed=true."},option_id:{type:"string",description:"Option instrument UUID — the same option_id used for exercise_option. The tool looks up the queued exercise for this option and cancels it."}},required:["account_number","option_id"],additionalProperties:!1}},{name:"cancel_option_order",namespace:"option_trading",description:"Cancel an open option order by account_number + order_id. Resolve order_id via get_option_orders and pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the order, from get_accounts. Must be agentic_allowed=true. Mismatches against the order's owning account are rejected."},order_id:{type:"string",description:"Order UUID from get_option_orders. Must live in account_number."}},required:["account_number","order_id"],additionalProperties:!1}},{name:"create_scan",namespace:"scanners",description:`Create a new saved scanner (screener) on the user's account, optionally applying a preset and custom filters in a single call. Returns the new scan's id, title, applied filters, and the initial live market results. This tool composes multiple Beacon operations: 1. Create an empty scan @@ -38,9 +38,9 @@ Pocket Pi returns this result directly to the Agent and does not persist it, bec Parameter rules: - interval is optional; when omitted, the server auto-selects an interval that targets ~2,500 bars across the requested range. Provide an explicit interval only when you need a specific granularity. - interval values are fixed; the server does NOT aggregate intermediate bars. For a custom interval (e.g. 3-minute), request the next-finer fixed interval and aggregate client-side. -- bounds defaults to 'regular' (RTH only). Use 'extended' or '24_5' only when the user explicitly asks about extended-hours activity. +- bounds defaults to 'regular' (RTH only); use 'extended' for pre-market through post-market data or '24_5' for overnight data. - adjustment_type defaults to 'split' (split-adjusted, the right default for backtesting). Use 'none' for raw prices, 'all' for split + dividend adjustment. -- If the range would produce more bars than the upstream allows at the explicitly requested interval, narrow the range or coarsen the interval — the call is rejected before reaching upstream. The cap does not apply when interval is auto-selected. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols (uppercase). Up to 10 per call."},start_time:{type:"string",description:"Start of the range (RFC3339 UTC, e.g. '2026-01-01T00:00:00Z'). Required."},end_time:{type:"string",description:"End of the range (RFC3339 UTC). Optional — when omitted, defaults to the current time."},interval:{type:"string",description:"Bar interval. Optional — when omitted, the server picks an interval that targets ~2,500 bars across the requested range. Intraday: 15second, 30second, minute, 5minute, 10minute, 30minute, hour, 4hour. Interday: day, week, month, 3month, 6month, year, 5year, 10year, 20year, 50year. Note: the 1-minute bar is named 'minute' (not '1minute')."},bounds:{type:"string",description:"Session bounds. One of 'regular' (RTH, default), 'extended', 'trading', '24_5', '24_7', 'hyper_trading'."},adjustment_type:{type:"string",description:"Corporate-action adjustment: 'none' (raw prices), 'split' (default; right for backtesting), or 'all' (split + dividend; intraday only)."}},required:["symbols","start_time"],additionalProperties:!1}},{name:"get_equity_orders",namespace:"equity_trading",description:`Fetch equity orders for an account — list mode (newest first; open and closed, including fills, cancellations, rejections) or single-order mode by passing order_id. When the user asks for "orders" without specifying an asset class, call get_equity_orders, get_option_orders, and get_advanced_orders (OCO / multi-leg contingency orders) in parallel. +- If the range would produce more bars than the upstream allows at the explicitly requested interval, narrow the range or coarsen the interval — the call is rejected before reaching upstream. The cap does not apply when interval is auto-selected. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{symbols:{type:["null","array"],items:{type:"string"},description:"One or more stock symbols (uppercase). Up to 10 per call."},start_time:{type:"string",description:"Start of the range (RFC3339 UTC, e.g. '2026-01-01T00:00:00Z'). Required."},end_time:{type:"string",description:"End of the range (RFC3339 UTC). Optional — when omitted, defaults to the current time."},interval:{type:"string",description:"Bar interval. Optional — when omitted, the server picks an interval that targets ~2,500 bars across the requested range. Intraday: 15second, 30second, minute, 5minute, 10minute, 30minute, hour, 4hour. Interday: day, week, month, 3month, 6month, year, 5year, 10year, 20year, 50year. Note: the 1-minute bar is named 'minute' (not '1minute')."},bounds:{type:"string",description:"Session bounds. One of 'regular' (RTH, default), 'extended', 'trading', '24_5', '24_7', 'hyper_trading'."},adjustment_type:{type:"string",description:"Corporate-action adjustment: 'none' (raw prices), 'split' (default; right for backtesting), or 'all' (split + dividend; intraday only)."}},required:["symbols","start_time"],additionalProperties:!1}},{name:"get_equity_orders",namespace:"equity_trading",description:`Fetch equity orders for an account — list mode (newest first; open and closed, including fills, cancellations, rejections) or single-order mode by passing order_id. When the user asks for "orders" without specifying an asset class, call get_equity_orders and get_option_orders in parallel. Filtering tips: - Prefer narrow queries: combine state, symbol, and/or created_at_gte for specific questions (e.g. "my filled AAPL orders this week") — the per-page cap is fixed. @@ -69,8 +69,8 @@ Optionally pass a comma-separated list of symbols (e.g. 'SPX,NDX,DJI') to filter Parameter rules: - instrument_ids are option contract UUIDs from get_option_instruments. Resolve underlying -> get_option_chains -> get_option_instruments first; this tool does not accept ticker symbols. - interval is optional; when omitted the server auto-selects an interval that targets a bounded bar count across the range. Provide an explicit interval only when you need a specific granularity. -- bounds defaults to 'regular' (regular hours). Use '24_5'/'24_7' only when the user explicitly asks about extended-hours or overnight option activity. -- If an explicitly requested interval would produce more bars than the upstream allows for the range, the call is rejected — narrow the range or coarsen the interval. The cap does not apply when interval is auto-selected. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{instrument_ids:{type:["null","array"],items:{type:"string"},description:"Option contract instrument UUIDs (from get_option_instruments). Up to 10 per call."},start_time:{type:"string",description:"Start of the range (RFC3339 UTC, e.g. '2026-01-01T00:00:00Z'). Required."},end_time:{type:"string",description:"End of the range (RFC3339 UTC). Optional — when omitted, defaults to the current time."},interval:{type:"string",description:"Bar interval. Optional — when omitted, the server auto-selects an interval that targets a bounded bar count across the range. Intraday: 15second, 30second, minute, 5minute, 10minute, 30minute, hour, 4hour. Interday: day, week, month, 3month, 6month, year, 5year, 10year, 20year, 50year. Note: the 1-minute bar is named 'minute' (not '1minute')."},bounds:{type:"string",description:"Session bounds. One of 'regular' (regular hours, default), '24_5', or '24_7'. Use '24_5'/'24_7' only when the user explicitly asks about extended-hours or overnight option activity (index options, and certain equity options)."}},required:["instrument_ids","start_time"],additionalProperties:!1}},{name:"get_option_instruments",namespace:"option_market_data",description:"List option contracts. One of chain_symbol, chain_id, or ids is required; narrow further with expiration_dates, strike_price, type, state. When looking up contracts for a specific expiration, call this in parallel for every chain whose expiration_dates (from get_option_chains) includes the date. For AM/PM/morning/evening preferences, first check settle_on_open on each chain via get_option_chains and only query matching chains. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{chain_id:{type:"string",description:"Chain UUID."},chain_symbol:{type:"string",description:"Underlying ticker (e.g. 'AAPL')."},expiration_dates:{type:"string",description:"Comma-separated YYYY-MM-DD expirations."},strike_price:{type:"string",description:"Exact strike (e.g. '150.0000')."},type:{type:"string",description:"'call' or 'put'."},state:{type:"string",description:"'active' (default), 'expired', or 'inactive'. Use 'expired' to find option contracts whose expiration date has passed; 'inactive' is for delisted/withdrawn contracts that never expired."},tradability:{type:"string",description:"'tradable' or 'untradable' (untradable is rejected at the tool layer)."},ids:{type:"string",description:"Comma-separated instrument UUIDs."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},additionalProperties:!1}},{name:"get_option_level_upgrade_info",namespace:"account_portfolio",description:"Get the upgrade URL to apply for options access on an account. Call when option_level is null. option_level_2 enables long calls/puts, covered calls, and cash-secured puts; option_level_3 adds spreads and complex strategies, though multi-leg orders are not yet supported here. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number to generate the upgrade URL for. Obtain from get_accounts."}},required:["account_number"],additionalProperties:!1}},{name:"get_option_orders",namespace:"option_trading",description:`Fetch options orders for an account — list mode (newest first; open and closed, including fills, cancellations, and rejections) or single-order mode by passing order_id. When the user asks for "orders" without specifying equity or options, call both get_option_orders and get_equity_orders in parallel. +- bounds defaults to 'regular' (regular hours); use '24_5' or '24_7' for contracts and sessions that expose overnight data. +- If an explicitly requested interval would produce more bars than the upstream allows for the range, the call is rejected — narrow the range or coarsen the interval. The cap does not apply when interval is auto-selected. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{instrument_ids:{type:["null","array"],items:{type:"string"},description:"Option contract instrument UUIDs (from get_option_instruments). Up to 10 per call."},start_time:{type:"string",description:"Start of the range (RFC3339 UTC, e.g. '2026-01-01T00:00:00Z'). Required."},end_time:{type:"string",description:"End of the range (RFC3339 UTC). Optional — when omitted, defaults to the current time."},interval:{type:"string",description:"Bar interval. Optional — when omitted, the server auto-selects an interval that targets a bounded bar count across the range. Intraday: 15second, 30second, minute, 5minute, 10minute, 30minute, hour, 4hour. Interday: day, week, month, 3month, 6month, year, 5year, 10year, 20year, 50year. Note: the 1-minute bar is named 'minute' (not '1minute')."},bounds:{type:"string",description:"Session bounds. One of 'regular' (regular hours, default), '24_5', or '24_7'. Overnight data is available only for supported index and equity option contracts."}},required:["instrument_ids","start_time"],additionalProperties:!1}},{name:"get_option_instruments",namespace:"option_market_data",description:"List option contracts. One of chain_symbol, chain_id, or ids is required; narrow further with expiration_dates, strike_price, type, state. When looking up contracts for a specific expiration, call this in parallel for every chain whose expiration_dates (from get_option_chains) includes the date. For AM/PM/morning/evening preferences, first check settle_on_open on each chain via get_option_chains and only query matching chains. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{chain_id:{type:"string",description:"Chain UUID."},chain_symbol:{type:"string",description:"Underlying ticker (e.g. 'AAPL')."},expiration_dates:{type:"string",description:"Comma-separated YYYY-MM-DD expirations."},strike_price:{type:"string",description:"Exact strike (e.g. '150.0000')."},type:{type:"string",description:"'call' or 'put'."},state:{type:"string",description:"'active' (default), 'expired', or 'inactive'. Use 'expired' to find option contracts whose expiration date has passed; 'inactive' is for delisted/withdrawn contracts that never expired."},tradability:{type:"string",description:"'tradable' or 'untradable' (untradable is rejected at the tool layer)."},ids:{type:"string",description:"Comma-separated instrument UUIDs."},cursor:{type:"string",description:"Pagination cursor. Omit for the first page; for the next page, pass the cursor query param from the prior response's next URL."}},additionalProperties:!1}},{name:"get_option_level_upgrade_info",namespace:"account_portfolio",description:"Get the upgrade URL to apply for options access on an account. Call when option_level is null. option_level_2 enables long calls/puts, covered calls, and cash-secured puts; option_level_3 adds spreads and complex strategies. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account number to generate the upgrade URL for. Obtain from get_accounts."}},required:["account_number"],additionalProperties:!1}},{name:"get_option_orders",namespace:"option_trading",description:`Fetch options orders for an account — list mode (newest first; open and closed, including fills, cancellations, and rejections) or single-order mode by passing order_id. When the user asks for "orders" without specifying equity or options, call both get_option_orders and get_equity_orders in parallel. Filtering tips: - Prefer narrow queries: combine state and/or created_at_gte for specific questions — the per-page cap is fixed. @@ -81,7 +81,7 @@ This tool takes no parameters. Pocket Pi returns this result directly to the Age Returns one entry per scan with its id, title, active filters, configured columns, sort order, and a flag indicating whether the scan is managed by Cortex (Legend's AI agent). Cortex-managed scans are read-only via MCP — they can be run with run_scan but not modified with update_scan_filters or update_scan_config. -This tool takes no parameters. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",additionalProperties:!1}},{name:"get_watchlist_items",namespace:"watchlists",description:"List the items in a watchlist. Items may be stocks/ETFs, crypto pairs, futures, indexes — distinguished by object_type. For the options watchlist, use get_option_watchlist instead — this tool returns a generic shape that drops the strategy-specific fields and the upstream rejects it with 400 anyway. Does not return live prices; call get_quotes with the symbol(s) for that. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist whose items to fetch. Obtain from get_watchlists or get_popular_watchlists."}},required:["list_id"],additionalProperties:!1}},{name:"get_watchlists",namespace:"watchlists",description:"List the user's watchlists, including both user-created custom lists and Robinhood-curated lists the user follows. Use to look up list_id values for other watchlist tools. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",additionalProperties:!1}},{name:"place_equity_order",namespace:"equity_trading",description:`Place a real equity order with real money. Parameters mirror review_equity_order plus the optional ref_id. Requires an agentic_allowed=true account; non-agentic accounts are rejected. +This tool takes no parameters. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",additionalProperties:!1}},{name:"get_watchlist_items",namespace:"watchlists",description:"List the items in a watchlist. Items may be stocks/ETFs, crypto pairs, futures, indexes — distinguished by object_type. For the options watchlist, use get_option_watchlist instead — this tool returns a generic shape that drops the strategy-specific fields and the upstream rejects it with 400 anyway. This does not return live prices; use get_equity_quotes for stocks/ETFs or get_index_quotes for indexes. Pocket Pi does not currently expose a crypto quote Tool. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist whose items to fetch. Obtain from get_watchlists or get_popular_watchlists."}},required:["list_id"],additionalProperties:!1}},{name:"get_watchlists",namespace:"watchlists",description:"List the user's watchlists, including both user-created custom lists and Robinhood-curated lists the user follows. Use to look up list_id values for other watchlist tools. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",additionalProperties:!1}},{name:"place_equity_order",namespace:"equity_trading",description:`Place a real equity order with real money. Parameters mirror review_equity_order plus the optional ref_id. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Call review_equity_order first to obtain the current quote, estimated cost, and pre-trade alerts. @@ -142,7 +142,7 @@ Returns the scan's title, the total number of matching instruments, a list of in Parameters: - scan_id (required) — the scan identifier from get_scans or create_scan. Returns an error if the scan does not exist or does not belong to the calling user. -Use get_scans first to discover available scan_ids if the user has not specified one. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan identifier to execute. Get this from get_scans or create_scan."}},required:["scan_id"],additionalProperties:!1}},{name:"search",namespace:"equity_market_data",description:'Resolve a natural-language query to Robinhood instruments (stocks/ETFs), crypto pairs, or market indexes. Use when the user names an asset by name (or partial name) instead of a ticker/pair/index symbol, or when you need an instrument_id / currency-pair UUID / market-index id for a downstream tool. Defaults to instrument search; pass asset_type="currency_pair" for crypto or asset_type="market_index" for indexes (SPX, NDX, DJI, etc.). Instrument results carry symbol + instrument_id (use with get_equity_quotes / get_equity_tradability / place_equity_order or any instrument_id-based tool). Crypto results carry hyphenated symbol (e.g. BTC-USD) + id — the symbol routes to crypto quote/order tools, the id routes to watchlist tools as currency_pair_ids. Market-index results carry symbol + id — pass id to index quote tools for current values, or in the index_ids array of watchlist tools. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.',inputSchema:{type:"object",properties:{query:{type:"string",description:'Natural-language search query: company name, partial name, or ticker (e.g. "apple", "tesla motors", "AAPL"). Required.'},asset_type:{type:"string",description:'Asset category to search. Supported: "instrument" (US-listed stocks/ETFs), "currency_pair" (crypto pairs like BTC-USD), and "market_index" (e.g. SPX, NDX, DJI). Defaults to "instrument" when omitted. More categories (events, futures) will be added as their corresponding tools land.'},limit:{type:"integer",description:"Max results to return. Defaults to 10; clamped to 20."}},required:["query"],additionalProperties:!1}},{name:"unfollow_watchlist",namespace:"watchlists",description:"Stop following a Robinhood-curated list. The list itself is unchanged and no longer appears in the user's watchlists. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the Robinhood-curated list to unfollow."}},required:["list_id"],additionalProperties:!1}},{name:"update_scan_config",namespace:"scanners",description:`Change the sort order of a saved scan's results table. The scan's filters and columns are preserved; only the sort changes. +Use get_scans first to discover available scan_ids if the user has not specified one. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan identifier to execute. Get this from get_scans or create_scan."}},required:["scan_id"],additionalProperties:!1}},{name:"search",namespace:"equity_market_data",description:'Resolve a natural-language query to Robinhood instruments (stocks/ETFs), crypto pairs, or market indexes. Use when the user names an asset by name (or partial name) instead of a ticker/pair/index symbol, or when you need an instrument_id / currency-pair UUID / market-index id for a downstream tool. Defaults to instrument search; pass asset_type="currency_pair" for crypto or asset_type="market_index" for indexes (SPX, NDX, DJI, etc.). Instrument results carry symbol + instrument_id for equity market-data and trading tools. Crypto results carry a hyphenated symbol (e.g. BTC-USD) plus an id usable as currency_pair_ids in watchlist tools; Pocket Pi does not currently expose crypto quote or order Tools. Market-index results carry symbol + id — pass id to get_index_quotes/get_index_historicals or in the index_ids array of watchlist tools. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.',inputSchema:{type:"object",properties:{query:{type:"string",description:'Natural-language search query: company name, partial name, or ticker (e.g. "apple", "tesla motors", "AAPL"). Required.'},asset_type:{type:"string",description:'Asset category to search. Supported: "instrument" (US-listed stocks/ETFs), "currency_pair" (crypto pairs like BTC-USD), and "market_index" (e.g. SPX, NDX, DJI). Defaults to "instrument" when omitted. More categories (events, futures) will be added as their corresponding tools land.'},limit:{type:"integer",description:"Max results to return. Defaults to 10; clamped to 20."}},required:["query"],additionalProperties:!1}},{name:"unfollow_watchlist",namespace:"watchlists",description:"Stop following a Robinhood-curated list. The list itself is unchanged and no longer appears in the user's watchlists. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the Robinhood-curated list to unfollow."}},required:["list_id"],additionalProperties:!1}},{name:"update_scan_config",namespace:"scanners",description:`Change the sort order of a saved scan's results table. The scan's filters and columns are preserved; only the sort changes. Parameters: - scan_id (required) — the scan to modify. @@ -163,7 +163,7 @@ Restrictions: - Cortex-managed scans (cortex_managed: true in get_scans) are rejected with a user-friendly error. - Returns an error and does not apply any change if any filter fails validation. -Returns the scan with its new filters and fresh live results. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan to modify. Get this from get_scans or create_scan. Cortex-managed scans (cortex_managed: true in get_scans output) are rejected."},filters:{type:["null","array"],items:{type:"object",properties:{filter_type:{type:"string",description:'Wire-format enum name, e.g. "FILTER_TYPE_RSI". See the scanner-filter-specs resource for valid values. Omit when supplying expression.'},predicate:{type:"string",description:'Wire-format enum name, e.g. "PREDICATE_GREATER_THAN". See the scanner-filter-specs resource for the predicates supported by each filter.'},values:{type:["null","array"],items:{type:"string"},description:'Threshold values. Single-element for unary predicates, two-element for BETWEEN, multi-element for IN_LIST/ANY_OF. For a boolean expression screen, exactly ["True"].'},interval:{type:"string",description:`Time granularity for time-series filters (e.g. "1d"). Use one of the supported_intervals from the filter's scanner-filter-specs entry. Not used with expression — encode granularity inside the expression.`},length:{type:"integer",description:"Lookback length for filters that need one (e.g. RSI period of 14). Use one of the supported_lengths from the filter's scanner-filter-specs entry. Not used with expression.",minimum:-2147483648,maximum:2147483647},plot:{type:"string",description:`Plot / price-field input for filters that have one (e.g. "open" or "close" for % Change). Use one of the supported_plots from the filter's scanner-filter-specs entry. Not used with expression.`},expression:{type:"string",description:'Raw market-data expression to screen on, e.g. "dayVolume / volumeAvg(candleCount=30, candlePeriod=\\"1d\\", session=\\"all\\")" with a numeric predicate, or a whole comparison like "tradeAllDay.price > closeAvg(candleCount=50, candlePeriod=\\"1d\\", session=\\"all\\")" with predicate "=" and values ["True"]. Only preview_scan accepts expressions. Omit filter_type when set. Prefer an enum filter_type whenever one covers the request.'},display_title:{type:"string",description:'Optional short label for an expression filter, shown as the results-column header (e.g. "Relative volume (30D)"). Only used with expression.'}},required:["predicate","values"],additionalProperties:!1},description:"The complete set of filters the scan should have after the update. REPLACE semantics — to add a filter, supply all existing filters plus the new one. To remove a filter, omit it from the array. To clear all filters, send []. Each filter: filter_type (FILTER_TYPE_... enum), predicate (>, <, =, BETWEEN, etc.), values, optional interval (e.g. 1d), optional length (e.g. 14 for RSI). Call get_scanner_filter_specs first for valid filter_type / predicate / interval / length combinations."}},required:["scan_id","filters"],additionalProperties:!1}},{name:"update_watchlist",namespace:"watchlists",description:"Rename a custom watchlist or change its icon/description. Robinhood-curated lists cannot be renamed; the call will fail with 404. Provide at least one of display_name, icon_emoji, display_description. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to update. Obtain from get_watchlists."},display_name:{type:"string",description:"New name for the watchlist."},icon_emoji:{type:"string",description:"New emoji."},display_description:{type:"string",description:"New description."}},required:["list_id"],additionalProperties:!1}}]};var k=globalThis.db,q=k.open("robinhood");if(q<0)throw Error("open robinhood.sqlite");var E=5;function M(){return String(k.lastError(q)||"SQLite operation failed")}function w(e){if(k.exec(q,e)!==0)throw Error(M())}function D(e,t=[]){let i=JSON.parse(k.query(q,e,JSON.stringify(t)));if(i.error)throw Error(String(i.error));return i}function h(e,t=[]){return D(e,t)}var V=D("PRAGMA user_version");if(Number(V?.user_version??0)!==E)w(` +Returns the scan with its new filters and fresh live results. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan to modify. Get this from get_scans or create_scan. Cortex-managed scans (cortex_managed: true in get_scans output) are rejected."},filters:{type:["null","array"],items:{type:"object",properties:{filter_type:{type:"string",description:'Wire-format enum name, e.g. "FILTER_TYPE_RSI". See the scanner-filter-specs resource for valid values. Omit when supplying expression.'},predicate:{type:"string",description:'Wire-format enum name, e.g. "PREDICATE_GREATER_THAN". See the scanner-filter-specs resource for the predicates supported by each filter.'},values:{type:["null","array"],items:{type:"string"},description:'Threshold values. Single-element for unary predicates, two-element for BETWEEN, multi-element for IN_LIST/ANY_OF. For a boolean expression screen, exactly ["True"].'},interval:{type:"string",description:`Time granularity for time-series filters (e.g. "1d"). Use one of the supported_intervals from the filter's scanner-filter-specs entry. Not used with expression — encode granularity inside the expression.`},length:{type:"integer",description:"Lookback length for filters that need one (e.g. RSI period of 14). Use one of the supported_lengths from the filter's scanner-filter-specs entry. Not used with expression.",minimum:-2147483648,maximum:2147483647},plot:{type:"string",description:`Plot / price-field input for filters that have one (e.g. "open" or "close" for % Change). Use one of the supported_plots from the filter's scanner-filter-specs entry. Not used with expression.`},expression:{type:"string",description:'Raw market-data expression to screen on, e.g. "dayVolume / volumeAvg(candleCount=30, candlePeriod=\\"1d\\", session=\\"all\\")" with a numeric predicate, or a whole comparison like "tradeAllDay.price > closeAvg(candleCount=50, candlePeriod=\\"1d\\", session=\\"all\\")" with predicate "=" and values ["True"]. Only preview_scan accepts expressions. Omit filter_type when set. Prefer an enum filter_type whenever one covers the request.'},display_title:{type:"string",description:'Optional short label for an expression filter, shown as the results-column header (e.g. "Relative volume (30D)"). Only used with expression.'}},required:["predicate","values"],additionalProperties:!1},description:"The complete set of filters the scan should have after the update. REPLACE semantics — to add a filter, supply all existing filters plus the new one. To remove a filter, omit it from the array. To clear all filters, send []. Each filter: filter_type (FILTER_TYPE_... enum), predicate (>, <, =, BETWEEN, etc.), values, optional interval (e.g. 1d), optional length (e.g. 14 for RSI). Call get_scanner_filter_specs first for valid filter_type / predicate / interval / length combinations."}},required:["scan_id","filters"],additionalProperties:!1}},{name:"update_watchlist",namespace:"watchlists",description:"Rename a custom watchlist or change its icon/description. Robinhood-curated lists cannot be renamed; the call will fail with 404. Provide at least one of display_name, icon_emoji, display_description. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to update. Obtain from get_watchlists."},display_name:{type:"string",description:"New name for the watchlist."},icon_emoji:{type:"string",description:"New emoji."},display_description:{type:"string",description:"New description."}},required:["list_id"],additionalProperties:!1}}]};var k=globalThis.db,q=k.open("robinhood");if(q<0)throw Error("open robinhood.sqlite");var E=5;function M(){return String(k.lastError(q)||"SQLite operation failed")}function w(e){if(k.exec(q,e)!==0)throw Error(M())}function T(e,t=[]){let i=JSON.parse(k.query(q,e,JSON.stringify(t)));if(i.error)throw Error(String(i.error));return i}function h(e,t=[]){return T(e,t)}var V=T("PRAGMA user_version");if(Number(V?.user_version??0)!==E)w(` CREATE TABLE IF NOT EXISTS accounts ( account_number TEXT PRIMARY KEY, label TEXT NOT NULL, @@ -222,7 +222,7 @@ Returns the scan with its new filters and fresh live results. This changes Robin ); CREATE INDEX IF NOT EXISTS refresh_runs_recent ON refresh_runs(id DESC); PRAGMA user_version=5; - `);var T=b.tools,F=new Map(T.map((e)=>[e.name,e]));function f(){return Math.floor(Date.now()/1000)}function N(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function n(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let i of t){let r=N(e[i]);if(r!==null)return r}for(let i of Object.values(e)){let r=n(i,t);if(r!==null)return r}return null}function A(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let i of t)if(Array.isArray(e[i]))return e[i];for(let i of Object.values(e)){let r=A(i,t);if(r.length)return r}return[]}function Y(e,t){let i=n(e,t)?.toLowerCase();return i==="true"||i==="1"||i==="yes"}function I(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function _(e,t){let i=t?.account_number;return i===null||i===void 0||i===""?n(e,["account_number","accountNumber","account"])||"":String(i)}function x(e,t){let i=A(e,t);return i.length?i:Array.isArray(e)?e:e?[e]:[]}function G(e){let t=Array.isArray(e?.names)?new Set(e.names.filter((o)=>typeof o==="string")):new Set,i=String(e?.query??"").toLowerCase().split(/[^a-z0-9_]+/).filter(Boolean),r=typeof e?.namespace==="string"?e.namespace:"";if(!t.size&&!i.length)throw Error("search_tools requires query or names");let d=Math.max(1,Math.min(8,Number(e?.limit??5)||5)),s=T.filter((o)=>!r||o.namespace===r).map((o)=>{let a=o.name.toLowerCase(),p=a+" "+o.description.toLowerCase(),c=t.has(o.name)?1000:i.reduce((m,l)=>m+(a===l?100:a.includes(l)?20:p.includes(l)?3:0),0);return{tool:o,score:c}}).filter((o)=>o.score>0).sort((o,a)=>a.score-o.score||o.tool.name.localeCompare(a.tool.name)).slice(0,d).map(({tool:o})=>({name:o.name,namespace:o.namespace,description:o.description,inputSchema:o.inputSchema}));return{source:b.source,protocolVersion:b.protocolVersion,matches:s}}function B(e,t){if(t==="null")return e===null;if(t==="array")return Array.isArray(e);if(t==="object")return e!==null&&typeof e==="object"&&!Array.isArray(e);if(t==="integer")return typeof e==="number"&&Number.isInteger(e);if(t==="number")return typeof e==="number"&&Number.isFinite(e);return typeof e===t}function U(e,t,i="arguments"){let r=Array.isArray(t?.type)?t.type:t?.type?[t.type]:[];if(r.length&&!r.some((s)=>B(e,s)))throw Error(i+" must be "+r.join(" or "));if(e===null)return;if(typeof e==="number"){if(typeof t.minimum==="number"&&et.maximum)throw Error(i+" exceeds maximum "+t.maximum)}if(Array.isArray(e)){if(t.items)e.forEach((s,o)=>U(s,t.items,i+"["+o+"]"));return}if(typeof e!=="object")return;let d=t.properties||{};for(let s of t.required||[])if(!(s in e))throw Error(i+"."+s+" is required");if(t.additionalProperties===!1){for(let s of Object.keys(e))if(!(s in d))throw Error(i+"."+s+" is not allowed")}for(let[s,o]of Object.entries(e))if(d[s])U(o,d[s],i+"."+s)}function z(e){let t=typeof e?.name==="string"?e.name:"",i=F.get(t);if(!i)throw Error("Unknown Robinhood provider Tool: "+t);let r=e?.arguments;return U(r,i.inputSchema),ee(t,r)}function O(e,t){let i=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t})));if(!i.ok)throw Error(i.error||"Robinhood service failed");return i.value}function W(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((i)=>({name:i.operation,arguments:i.args}))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function v(e){w("BEGIN IMMEDIATE");try{e(),w("COMMIT")}catch(t){try{w("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function H(e,t){let i=x(e,["accounts"]);h("DELETE FROM accounts");for(let r of i){let d=_(r,{});if(!d)continue;let s=(n(r,["nickname","account_type","type"])||"").toUpperCase(),o=Y(r,["agentic_allowed","agenticAllowed"]),a=o?"AGENTIC":s.includes("IRA")||s.includes("RETIRE")?"RETIREMENT":s.includes("JOINT")?"JOINT":"PERSONAL";h("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at) VALUES(?,?,?,?,?,?,?)",[d,a,d.slice(-4),s,(n(r,["status"])||"active").toUpperCase(),o?1:0,t])}}function X(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood portfolio is missing account_number");let d=n(e,["cash","cash_available","withdrawable_amount"]),s=n(e,["buying_power","buyingPower"]),o=n(e,["day_pnl","dayPnl","equity_change"]),a=n(e,["week_pnl","weekPnl"]);h(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) + `);var D=b.tools,F=new Map(D.map((e)=>[e.name,e]));function f(){return Math.floor(Date.now()/1000)}function N(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function n(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let i of t){let r=N(e[i]);if(r!==null)return r}for(let i of Object.values(e)){let r=n(i,t);if(r!==null)return r}return null}function A(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let i of t)if(Array.isArray(e[i]))return e[i];for(let i of Object.values(e)){let r=A(i,t);if(r.length)return r}return[]}function Y(e,t){let i=n(e,t)?.toLowerCase();return i==="true"||i==="1"||i==="yes"}function I(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function _(e,t){let i=t?.account_number;return i===null||i===void 0||i===""?n(e,["account_number","accountNumber","account"])||"":String(i)}function x(e,t){let i=A(e,t);return i.length?i:Array.isArray(e)?e:e?[e]:[]}function G(e){let t=Array.isArray(e?.names)?new Set(e.names.filter((o)=>typeof o==="string")):new Set,i=String(e?.query??"").toLowerCase().split(/[^a-z0-9_]+/).filter(Boolean),r=typeof e?.namespace==="string"?e.namespace:"";if(!t.size&&!i.length)throw Error("search_tools requires query or names");let d=Math.max(1,Math.min(8,Number(e?.limit??5)||5)),s=D.filter((o)=>!r||o.namespace===r).map((o)=>{let a=o.name.toLowerCase(),p=a+" "+o.description.toLowerCase(),c=t.has(o.name)?1000:i.reduce((m,l)=>m+(a===l?100:a.includes(l)?20:p.includes(l)?3:0),0);return{tool:o,score:c}}).filter((o)=>o.score>0).sort((o,a)=>a.score-o.score||o.tool.name.localeCompare(a.tool.name)).slice(0,d).map(({tool:o})=>({name:o.name,namespace:o.namespace,description:o.description,inputSchema:o.inputSchema}));return{source:b.source,protocolVersion:b.protocolVersion,matches:s}}function B(e,t){if(t==="null")return e===null;if(t==="array")return Array.isArray(e);if(t==="object")return e!==null&&typeof e==="object"&&!Array.isArray(e);if(t==="integer")return typeof e==="number"&&Number.isInteger(e);if(t==="number")return typeof e==="number"&&Number.isFinite(e);return typeof e===t}function U(e,t,i="arguments"){let r=Array.isArray(t?.type)?t.type:t?.type?[t.type]:[];if(r.length&&!r.some((s)=>B(e,s)))throw Error(i+" must be "+r.join(" or "));if(e===null)return;if(typeof e==="number"){if(typeof t.minimum==="number"&&et.maximum)throw Error(i+" exceeds maximum "+t.maximum)}if(Array.isArray(e)){if(t.items)e.forEach((s,o)=>U(s,t.items,i+"["+o+"]"));return}if(typeof e!=="object")return;let d=t.properties||{};for(let s of t.required||[])if(!(s in e))throw Error(i+"."+s+" is required");if(t.additionalProperties===!1){for(let s of Object.keys(e))if(!(s in d))throw Error(i+"."+s+" is not allowed")}for(let[s,o]of Object.entries(e))if(d[s])U(o,d[s],i+"."+s)}function z(e){let t=typeof e?.name==="string"?e.name:"",i=F.get(t);if(!i)throw Error("Unknown Robinhood provider Tool: "+t);let r=e?.arguments;return U(r,i.inputSchema),ee(t,r)}function O(e,t){let i=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t})));if(!i.ok)throw Error(i.error||"Robinhood service failed");return i.value}function W(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((i)=>({name:i.operation,arguments:i.args}))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function v(e){w("BEGIN IMMEDIATE");try{e(),w("COMMIT")}catch(t){try{w("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function H(e,t){let i=x(e,["accounts"]);h("DELETE FROM accounts");for(let r of i){let d=_(r,{});if(!d)continue;let s=(n(r,["nickname","account_type","type"])||"").toUpperCase(),o=Y(r,["agentic_allowed","agenticAllowed"]),a=o?"AGENTIC":s.includes("IRA")||s.includes("RETIRE")?"RETIREMENT":s.includes("JOINT")?"JOINT":"PERSONAL";h("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at) VALUES(?,?,?,?,?,?,?)",[d,a,d.slice(-4),s,(n(r,["status"])||"active").toUpperCase(),o?1:0,t])}}function X(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood portfolio is missing account_number");let d=n(e,["cash","cash_available","withdrawable_amount"]),s=n(e,["buying_power","buyingPower"]),o=n(e,["day_pnl","dayPnl","equity_change"]),a=n(e,["week_pnl","weekPnl"]);h(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?,?,?) ON CONFLICT(account_number) DO UPDATE SET cash=excluded.cash,buying_power=excluded.buying_power, diff --git a/apps/robinhood/tool-catalog.json b/apps/robinhood/tool-catalog.json index 6f95cc9..a7324b7 100644 --- a/apps/robinhood/tool-catalog.json +++ b/apps/robinhood/tool-catalog.json @@ -60,7 +60,7 @@ "items": { "type": "string" }, - "description": "Currency-pair UUIDs to add (e.g. the object_id from get_watchlist_items where object_type=currency_pair, or the id from get_currency_pairs). Mutually exclusive with symbols and index_ids." + "description": "Currency-pair UUIDs to add, available as object_id from get_watchlist_items entries where object_type=currency_pair. Mutually exclusive with symbols and index_ids." }, "index_ids": { "type": [ @@ -389,7 +389,7 @@ { "name": "get_equity_historicals", "namespace": "equity_market_data", - "description": "Get OHLCV bars for one or more equity symbols across an explicit time range. Use this for charting, \"recent activity\" questions, and backtesting. The server auto-selects an interval when one is not provided. If the bar's interpolated field is true, bar was synthesized to fill a gap and carry no new information.\n\nParameter rules:\n- interval is optional; when omitted, the server auto-selects an interval that targets ~2,500 bars across the requested range. Provide an explicit interval only when you need a specific granularity.\n- interval values are fixed; the server does NOT aggregate intermediate bars. For a custom interval (e.g. 3-minute), request the next-finer fixed interval and aggregate client-side.\n- bounds defaults to 'regular' (RTH only). Use 'extended' or '24_5' only when the user explicitly asks about extended-hours activity.\n- adjustment_type defaults to 'split' (split-adjusted, the right default for backtesting). Use 'none' for raw prices, 'all' for split + dividend adjustment.\n- If the range would produce more bars than the upstream allows at the explicitly requested interval, narrow the range or coarsen the interval — the call is rejected before reaching upstream. The cap does not apply when interval is auto-selected. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Get OHLCV bars for one or more equity symbols across an explicit time range. Use this for charting, \"recent activity\" questions, and backtesting. The server auto-selects an interval when one is not provided. If the bar's interpolated field is true, bar was synthesized to fill a gap and carry no new information.\n\nParameter rules:\n- interval is optional; when omitted, the server auto-selects an interval that targets ~2,500 bars across the requested range. Provide an explicit interval only when you need a specific granularity.\n- interval values are fixed; the server does NOT aggregate intermediate bars. For a custom interval (e.g. 3-minute), request the next-finer fixed interval and aggregate client-side.\n- bounds defaults to 'regular' (RTH only); use 'extended' for pre-market through post-market data or '24_5' for overnight data.\n- adjustment_type defaults to 'split' (split-adjusted, the right default for backtesting). Use 'none' for raw prices, 'all' for split + dividend adjustment.\n- If the range would produce more bars than the upstream allows at the explicitly requested interval, narrow the range or coarsen the interval — the call is rejected before reaching upstream. The cap does not apply when interval is auto-selected. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { @@ -434,7 +434,7 @@ { "name": "get_equity_orders", "namespace": "equity_trading", - "description": "Fetch equity orders for an account — list mode (newest first; open and closed, including fills, cancellations, rejections) or single-order mode by passing order_id. When the user asks for \"orders\" without specifying an asset class, call get_equity_orders, get_option_orders, and get_advanced_orders (OCO / multi-leg contingency orders) in parallel.\n\nFiltering tips:\n- Prefer narrow queries: combine state, symbol, and/or created_at_gte for specific questions (e.g. \"my filled AAPL orders this week\") — the per-page cap is fixed.\n- created_at_gte: interpret relative times in the user's timezone, convert to UTC before sending.\n- symbol forces a symbol→instrument lookup; omit it if you don't need it. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.", + "description": "Fetch equity orders for an account — list mode (newest first; open and closed, including fills, cancellations, rejections) or single-order mode by passing order_id. When the user asks for \"orders\" without specifying an asset class, call get_equity_orders and get_option_orders in parallel.\n\nFiltering tips:\n- Prefer narrow queries: combine state, symbol, and/or created_at_gte for specific questions (e.g. \"my filled AAPL orders this week\") — the per-page cap is fixed.\n- created_at_gte: interpret relative times in the user's timezone, convert to UTC before sending.\n- symbol forces a symbol→instrument lookup; omit it if you don't need it. Pocket Pi normalizes the View fields from this response into robinhood.sqlite and publishes one App revision after commit.", "inputSchema": { "type": "object", "properties": { @@ -843,7 +843,7 @@ { "name": "get_option_historicals", "namespace": "option_market_data", - "description": "Get OHLC price bars for one or more option contracts (by instrument UUID) across an explicit time range. Use this for charting an option's price history and \"recent activity\" questions. The server auto-selects an interval when one is not provided. If the bar's interpolated field is true, bar was synthesized to fill a gap and carry no new information.\n\nParameter rules:\n- instrument_ids are option contract UUIDs from get_option_instruments. Resolve underlying -> get_option_chains -> get_option_instruments first; this tool does not accept ticker symbols.\n- interval is optional; when omitted the server auto-selects an interval that targets a bounded bar count across the range. Provide an explicit interval only when you need a specific granularity.\n- bounds defaults to 'regular' (regular hours). Use '24_5'/'24_7' only when the user explicitly asks about extended-hours or overnight option activity.\n- If an explicitly requested interval would produce more bars than the upstream allows for the range, the call is rejected — narrow the range or coarsen the interval. The cap does not apply when interval is auto-selected. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Get OHLC price bars for one or more option contracts (by instrument UUID) across an explicit time range. Use this for charting an option's price history and \"recent activity\" questions. The server auto-selects an interval when one is not provided. If the bar's interpolated field is true, bar was synthesized to fill a gap and carry no new information.\n\nParameter rules:\n- instrument_ids are option contract UUIDs from get_option_instruments. Resolve underlying -> get_option_chains -> get_option_instruments first; this tool does not accept ticker symbols.\n- interval is optional; when omitted the server auto-selects an interval that targets a bounded bar count across the range. Provide an explicit interval only when you need a specific granularity.\n- bounds defaults to 'regular' (regular hours); use '24_5' or '24_7' for contracts and sessions that expose overnight data.\n- If an explicitly requested interval would produce more bars than the upstream allows for the range, the call is rejected — narrow the range or coarsen the interval. The cap does not apply when interval is auto-selected. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { @@ -871,7 +871,7 @@ }, "bounds": { "type": "string", - "description": "Session bounds. One of 'regular' (regular hours, default), '24_5', or '24_7'. Use '24_5'/'24_7' only when the user explicitly asks about extended-hours or overnight option activity (index options, and certain equity options)." + "description": "Session bounds. One of 'regular' (regular hours, default), '24_5', or '24_7'. Overnight data is available only for supported index and equity option contracts." } }, "required": [ @@ -931,7 +931,7 @@ { "name": "get_option_level_upgrade_info", "namespace": "account_portfolio", - "description": "Get the upgrade URL to apply for options access on an account. Call when option_level is null. option_level_2 enables long calls/puts, covered calls, and cash-secured puts; option_level_3 adds spreads and complex strategies, though multi-leg orders are not yet supported here. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Get the upgrade URL to apply for options access on an account. Call when option_level is null. option_level_2 enables long calls/puts, covered calls, and cash-secured puts; option_level_3 adds spreads and complex strategies. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { @@ -1205,7 +1205,7 @@ { "name": "get_watchlist_items", "namespace": "watchlists", - "description": "List the items in a watchlist. Items may be stocks/ETFs, crypto pairs, futures, indexes — distinguished by object_type. For the options watchlist, use get_option_watchlist instead — this tool returns a generic shape that drops the strategy-specific fields and the upstream rejects it with 400 anyway. Does not return live prices; call get_quotes with the symbol(s) for that. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "List the items in a watchlist. Items may be stocks/ETFs, crypto pairs, futures, indexes — distinguished by object_type. For the options watchlist, use get_option_watchlist instead — this tool returns a generic shape that drops the strategy-specific fields and the upstream rejects it with 400 anyway. This does not return live prices; use get_equity_quotes for stocks/ETFs or get_index_quotes for indexes. Pocket Pi does not currently expose a crypto quote Tool. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { @@ -1670,7 +1670,7 @@ { "name": "search", "namespace": "equity_market_data", - "description": "Resolve a natural-language query to Robinhood instruments (stocks/ETFs), crypto pairs, or market indexes. Use when the user names an asset by name (or partial name) instead of a ticker/pair/index symbol, or when you need an instrument_id / currency-pair UUID / market-index id for a downstream tool. Defaults to instrument search; pass asset_type=\"currency_pair\" for crypto or asset_type=\"market_index\" for indexes (SPX, NDX, DJI, etc.). Instrument results carry symbol + instrument_id (use with get_equity_quotes / get_equity_tradability / place_equity_order or any instrument_id-based tool). Crypto results carry hyphenated symbol (e.g. BTC-USD) + id — the symbol routes to crypto quote/order tools, the id routes to watchlist tools as currency_pair_ids. Market-index results carry symbol + id — pass id to index quote tools for current values, or in the index_ids array of watchlist tools. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", + "description": "Resolve a natural-language query to Robinhood instruments (stocks/ETFs), crypto pairs, or market indexes. Use when the user names an asset by name (or partial name) instead of a ticker/pair/index symbol, or when you need an instrument_id / currency-pair UUID / market-index id for a downstream tool. Defaults to instrument search; pass asset_type=\"currency_pair\" for crypto or asset_type=\"market_index\" for indexes (SPX, NDX, DJI, etc.). Instrument results carry symbol + instrument_id for equity market-data and trading tools. Crypto results carry a hyphenated symbol (e.g. BTC-USD) plus an id usable as currency_pair_ids in watchlist tools; Pocket Pi does not currently expose crypto quote or order Tools. Market-index results carry symbol + id — pass id to get_index_quotes/get_index_historicals or in the index_ids array of watchlist tools. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.", "inputSchema": { "type": "object", "properties": { From 83192f7be0a0aca2d5600d5c2e1cce8cbfbc2ccf Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Tue, 11 Aug 2026 16:38:19 +0800 Subject: [PATCH 17/24] fix(esp32): drop late hosted RPC responses --- firmware/esp32-p4/Cargo.toml | 3 ++ .../CMakeLists.txt | 41 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 firmware/esp32-p4/components/esp_hosted_late_response_fix/CMakeLists.txt diff --git a/firmware/esp32-p4/Cargo.toml b/firmware/esp32-p4/Cargo.toml index a3938a0..2598b5c 100644 --- a/firmware/esp32-p4/Cargo.toml +++ b/firmware/esp32-p4/Cargo.toml @@ -43,6 +43,9 @@ bindings_header = "src/waveshare_bindings.h" [[package.metadata.esp-idf-sys.extra_components]] component_dirs = ["components/pocketjs_ppa"] +[[package.metadata.esp-idf-sys.extra_components]] +component_dirs = ["components/esp_hosted_late_response_fix"] + [[package.metadata.esp-idf-sys.extra_components]] remote_component = { name = "espressif/esp_wifi_remote", version = "0.14.*" } diff --git a/firmware/esp32-p4/components/esp_hosted_late_response_fix/CMakeLists.txt b/firmware/esp32-p4/components/esp_hosted_late_response_fix/CMakeLists.txt new file mode 100644 index 0000000..60f570f --- /dev/null +++ b/firmware/esp32-p4/components/esp_hosted_late_response_fix/CMakeLists.txt @@ -0,0 +1,41 @@ +idf_component_register(PRIV_REQUIRES espressif__esp_hosted) + +idf_component_get_property(esp_hosted_dir espressif__esp_hosted COMPONENT_DIR) +set(rpc_core "${esp_hosted_dir}/host/drivers/rpc/core/rpc_core.c") +file(READ "${rpc_core}" source) + +set(before [=[ + if (g_h.funcs->_h_queue_item(rpc_rx_q, &elem, HOSTED_BLOCK_MAX)) { + ESP_LOGE(TAG, "RPC Q put fail"); + goto free_buffers; + } + + /* Call up rx ind to unblock caller */ + if (CALLBACK_AVAILABLE == is_sync_resp_sem_available(app_resp->uid)) + post_sync_resp_sem(app_resp); +]=]) +set(after [=[ + if (CALLBACK_AVAILABLE != is_sync_resp_sem_available(app_resp->uid)) { + ESP_LOGW(TAG, "Dropping late sync response [0x%x], uid %ld", + app_resp->msg_id, app_resp->uid); + goto free_buffers; + } + + if (g_h.funcs->_h_queue_item(rpc_rx_q, &elem, HOSTED_BLOCK_MAX)) { + ESP_LOGE(TAG, "RPC Q put fail"); + goto free_buffers; + } + + /* Call up rx ind to unblock caller */ + post_sync_resp_sem(app_resp); +]=]) + +string(FIND "${source}" "Dropping late sync response" already_patched) +if(already_patched EQUAL -1) + string(FIND "${source}" "${before}" patch_site) + if(patch_site EQUAL -1) + message(FATAL_ERROR "esp_hosted RPC response path no longer matches the pinned patch") + endif() + string(REPLACE "${before}" "${after}" source "${source}") + file(WRITE "${rpc_core}" "${source}") +endif() From 6b69424c84572c9a5950804056ccc74baf346718 Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Tue, 11 Aug 2026 17:14:43 +0800 Subject: [PATCH 18/24] fix(robinhood): reconnect stalled read-only requests --- firmware/esp32-p4/src/app_services.rs | 155 +++++++++++++++----------- 1 file changed, 92 insertions(+), 63 deletions(-) diff --git a/firmware/esp32-p4/src/app_services.rs b/firmware/esp32-p4/src/app_services.rs index 2f2224b..723e495 100644 --- a/firmware/esp32-p4/src/app_services.rs +++ b/firmware/esp32-p4/src/app_services.rs @@ -4,7 +4,10 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; use std::time::Instant; -use embedded_svc::http::{client::Client as HttpClient, Method}; +use embedded_svc::http::{ + client::{Client as HttpClient, Request, Response}, + Method, +}; use embedded_svc::io::Write as _; use esp_idf_svc::http::client::{Configuration, EspHttpConnection}; use esp_idf_svc::io::EspIOError; @@ -340,7 +343,7 @@ impl AppServiceHost for EspAppServices { } } -fn client(timeout: Duration) -> Result, String> { +fn connection(timeout: Duration) -> Result { EspHttpConnection::new(&Configuration { buffer_size: Some(8 * 1024), buffer_size_tx: Some(4 * 1024), @@ -348,10 +351,13 @@ fn client(timeout: Duration) -> Result, String> { crt_bundle_attach: Some(esp_idf_svc::sys::esp_crt_bundle_attach), ..Default::default() }) - .map(HttpClient::wrap) .map_err(|error| format!("initialize HTTPS client: {error}")) } +fn client(timeout: Duration) -> Result, String> { + connection(timeout).map(HttpClient::wrap) +} + fn stale_mcp_session(error: &str) -> bool { let lower = error.to_ascii_lowercase(); (lower.contains("mcp http 400") || lower.contains("mcp http 404")) && lower.contains("session") @@ -423,6 +429,80 @@ fn net_failure(message: String) -> NetFailure { NetFailure::new(code, message) } +fn mcp_request_is_read_only(body: &Value) -> bool { + let method = body.get("method").and_then(Value::as_str); + if matches!(method, Some("initialize" | "notifications/initialized")) { + return true; + } + body.get("params") + .and_then(|params| params.get("name")) + .and_then(Value::as_str) + .is_some_and(|name| { + name.starts_with("get_") + || name.starts_with("review_") + || matches!(name, "search" | "run_scan") + }) +} + +fn submit_mcp( + token: &str, + session: Option<&str>, + payload: &str, + request_label: &str, + retryable: bool, +) -> Result, String> { + let length = payload.len().to_string(); + let authorization = format!("Bearer {token}"); + for attempt in 0..2 { + let mut headers = vec![ + ("accept", "application/json, text/event-stream"), + ("content-type", "application/json"), + ("content-length", length.as_str()), + ("authorization", authorization.as_str()), + ("user-agent", "pocket-pi-agentos/0.1"), + ]; + if let Some(session) = session { + headers.push(("mcp-session-id", session)); + } + let mut connection = connection(Duration::from_secs(12))?; + connection + .initiate_request(Method::Post, ROBINHOOD_MCP_URL, &headers) + .map_err(|error| format!("create Robinhood MCP request: {error:?}"))?; + let mut request = Request::wrap(connection); + request + .write_all(payload.as_bytes()) + .map_err(|error| format!("write Robinhood MCP request: {error:?}"))?; + request + .flush() + .map_err(|error| format!("flush Robinhood MCP request: {error:?}"))?; + let started = Instant::now(); + match request.submit() { + Ok(response) => { + log::info!( + "Robinhood MCP HTTP {request_label} headers status={} in {}ms", + response.status(), + started.elapsed().as_millis() + ); + return Ok(response); + } + Err(error) + if attempt == 0 + && retryable + && error.0.code() == -esp_idf_svc::sys::ESP_ERR_HTTP_EAGAIN => + { + log::warn!( + "Robinhood MCP {request_label} received no response headers in {}ms; reconnecting once", + started.elapsed().as_millis() + ); + } + Err(error) => { + return Err(format!("send Robinhood MCP request: {error:?}")); + } + } + } + unreachable!() +} + fn post_mcp( token: &str, session: Option<&str>, @@ -435,37 +515,14 @@ fn post_mcp( .or_else(|| body.get("method").and_then(Value::as_str)) .unwrap_or("unknown"); let payload = body.to_string(); - let length = payload.len().to_string(); - let authorization = format!("Bearer {token}"); - let mut headers = vec![ - ("accept", "application/json, text/event-stream"), - ("content-type", "application/json"), - ("content-length", length.as_str()), - ("authorization", authorization.as_str()), - ("user-agent", "pocket-pi-agentos/0.1"), - ]; - if let Some(session) = session { - headers.push(("mcp-session-id", session)); - } - let mut client = client(Duration::from_secs(12))?; - let mut request = client - .request(Method::Post, ROBINHOOD_MCP_URL, &headers) - .map_err(|error| format!("create Robinhood MCP request: {error}"))?; - request - .write_all(payload.as_bytes()) - .map_err(|error| format!("write Robinhood MCP request: {error}"))?; - request - .flush() - .map_err(|error| format!("flush Robinhood MCP request: {error}"))?; - let submit_started = Instant::now(); - let mut response = request - .submit() - .map_err(|error| format!("send Robinhood MCP request: {error}"))?; + let mut response = submit_mcp( + token, + session, + &payload, + request_label, + mcp_request_is_read_only(body), + )?; let status = response.status(); - log::info!( - "Robinhood MCP HTTP {request_label} headers status={status} in {}ms", - submit_started.elapsed().as_millis() - ); let returned_session = response.header("Mcp-Session-Id").map(str::to_owned); let is_event_stream = response .header("content-type") @@ -507,37 +564,9 @@ fn post_mcp_batch( ) -> Result<(Vec, Option), String> { let payload = serde_json::to_string(bodies) .map_err(|error| format!("encode Robinhood MCP batch: {error}"))?; - let length = payload.len().to_string(); - let authorization = format!("Bearer {token}"); - let mut headers = vec![ - ("accept", "application/json, text/event-stream"), - ("content-type", "application/json"), - ("content-length", length.as_str()), - ("authorization", authorization.as_str()), - ("user-agent", "pocket-pi-agentos/0.1"), - ]; - if let Some(session) = session { - headers.push(("mcp-session-id", session)); - } - let mut client = client(Duration::from_secs(12))?; - let mut request = client - .request(Method::Post, ROBINHOOD_MCP_URL, &headers) - .map_err(|error| format!("create Robinhood MCP batch request: {error}"))?; - request - .write_all(payload.as_bytes()) - .map_err(|error| format!("write Robinhood MCP batch request: {error}"))?; - request - .flush() - .map_err(|error| format!("flush Robinhood MCP batch request: {error}"))?; - let submit_started = Instant::now(); - let mut response = request - .submit() - .map_err(|error| format!("send Robinhood MCP batch request: {error}"))?; + let retryable = bodies.iter().all(mcp_request_is_read_only); + let mut response = submit_mcp(token, session, &payload, "batch", retryable)?; let status = response.status(); - log::info!( - "Robinhood MCP HTTP batch headers status={status} in {}ms", - submit_started.elapsed().as_millis() - ); let returned_session = response.header("Mcp-Session-Id").map(str::to_owned); if !(200..300).contains(&status) { let bytes = read_bounded(&mut response, MAX_MCP_RESPONSE, None)?; From 9e29ec5f4cdce07635063a2dea543ec1f0014203 Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Tue, 11 Aug 2026 17:45:08 +0800 Subject: [PATCH 19/24] fix(agentos): keep app database work responsive --- apps/exa/data-action.ts | 4 ++-- apps/exa/dist/data-action.js | 4 ++-- apps/robinhood/data-action.ts | 33 ++++++++++++++++------------- apps/robinhood/dist/data-action.js | 15 ++++++------- crates/pocket-pi-agentos/src/lib.rs | 21 +++++++++++++++--- 5 files changed, 47 insertions(+), 30 deletions(-) diff --git a/apps/exa/data-action.ts b/apps/exa/data-action.ts index 8a70468..7e16c2a 100644 --- a/apps/exa/data-action.ts +++ b/apps/exa/data-action.ts @@ -20,8 +20,8 @@ function query(sql: string, args: any[] = []): any { } function run(sql: string, args: any[] = []): any { return query(sql, args); } -const version = query("PRAGMA user_version") as { user_version?: number } | null; -if (Number(version?.user_version ?? 0) !== SCHEMA_VERSION) { +const version = Number(query("PRAGMA user_version")?.rows?.[0]?.[0] ?? 0); +if (version !== SCHEMA_VERSION) { exec(` DROP TABLE IF EXISTS searches; CREATE TABLE searches ( diff --git a/apps/exa/dist/data-action.js b/apps/exa/dist/data-action.js index 85d2dbb..fe81809 100644 --- a/apps/exa/dist/data-action.js +++ b/apps/exa/dist/data-action.js @@ -1,4 +1,4 @@ -(()=>{var Z=["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"];var z=65536,V=131072,K=262144,g=32,j=8192,F=30000,M=120000;var i={unavailable:"unavailable",invalidRequest:"invalid_request",busy:"busy",dns:"dns",connect:"connect",tls:"tls",timeout:"timeout",redirect:"redirect",responseTooLarge:"response_too_large",protocol:"protocol",cancelled:"cancelled",other:"other"};var E={};for(let f=0;f<64;f++)E["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[f]]=f;function J(f){let n=0;for(let h=0;h65535)h++;n+=a<128?1:a<2048?2:a<65536?3:4}let c=new Uint8Array(n),r=0;for(let h=0;h65535)h++;else if(a>=55296&&a<=57343)a=65533;if(a<128)c[r++]=a;else if(a<2048)c[r++]=192|a>>6,c[r++]=128|a&63;else if(a<65536)c[r++]=224|a>>12,c[r++]=128|a>>6&63,c[r++]=128|a&63;else c[r++]=240|a>>18,c[r++]=128|a>>12&63,c[r++]=128|a>>6&63,c[r++]=128|a&63}return c}function S(f){let n="",c=0;while(cf.length)throw Error("invalid UTF-8");for(let L=0;L1114111||h>=55296&&h<=57343||a===1&&h<128||a===2&&h<2048||a===3&&h<65536)throw Error("invalid UTF-8");if(h<65536)n+=String.fromCharCode(h);else h-=65536,n+=String.fromCharCode(55296+(h>>10),56320+(h&1023))}return n}var X=new Set;function Y(f){return X.add(f),()=>X.delete(f)}class w extends Error{constructor(f,n){super(n);this.name="NetError",this.code=f}}class O{constructor(f,n,c,r){this.status=f,this.url=n,this.headers=Object.freeze({...c}),this.ok=f>=200&&f<300,this.data=new Uint8Array(r)}get byteLength(){return this.data.byteLength}async bytes(){return this.data.slice()}async arrayBuffer(){return this.data.slice().buffer}async text(){try{return S(this.data)}catch{throw Error("net: response is not valid UTF-8")}}async json(){return JSON.parse(await this.text())}}var A=new Map,l=null,D=null;function v(){let f=globalThis.net;if(!f||typeof f!=="object")return null;let n=f;return typeof n.start==="function"&&typeof n.take==="function"&&typeof n.cancel==="function"&&typeof n.poll==="function"&&typeof n.lastError==="function"?n:null}function B(f){let n=String(f);for(let c of Object.values(i))if(c===n)return c;return i.other}function p(f){let n=A.get(f.h);if(!n)return;if(A.delete(f.h),f.t==="error")n.reject(new w(B(f.code),String(f.message||f.code)));else if(!Number.isInteger(f.status)||f.status<100||f.status>599||typeof f.url!=="string"||typeof f.headers!=="object"||f.headers===null||!Number.isInteger(f.bytes)||f.bytes<0||f.bytes>K)n.ops.cancel(f.h),n.reject(new w(i.protocol,"net: malformed done event"));else{let c=new ArrayBuffer(f.bytes);if(n.ops.take(f.h,c)!==f.bytes)n.ops.cancel(f.h),n.reject(new w(i.protocol,"net: response body transfer failed"));else n.resolve(new O(f.status,f.url,f.headers,c))}if(A.size===0&&l)l(),l=null,D=null}function U(){if(A.size===0)return;let f=D;if(!f)return;let n=f.poll();if(n!==void 0){let c=null;try{c=JSON.parse(n)}catch{}if(!Array.isArray(c))for(let[r,h]of A)f.cancel(r),A.delete(r),h.reject(new w(i.protocol,"net: malformed event batch"));else for(let r of c){if(!r||typeof r!=="object")continue;let h=r;if(!Number.isInteger(h.h)||h.t!=="done"&&h.t!=="error")continue;p(h)}}if(A.size===0&&l)l(),l=null,D=null}function Q(f,n){return Promise.reject(new w(f,n))}function t(f,n,c,r){if(!Number.isInteger(f)||fc)throw new w(i.invalidRequest,`net: ${r} must be ${n}..${c}`);return f}function e(f){let n=Object.create(null),c=0,r=0;for(let h of Object.keys(f??{})){let a=h.toLowerCase(),L=String(f[h]);if(!/^[!#$%&'*+.^_`|~0-9a-z-]+$/.test(a)||/[\r\n]/.test(L))throw new w(i.invalidRequest,`net: invalid header ${h}`);if(c++,r+=J(a).byteLength+J(L).byteLength+4,c>g||r>j)throw new w(i.invalidRequest,"net: request headers exceed limits");n[a]=L}return n}function o(f){if(f===void 0)return new Uint8Array(0);if(typeof f==="string")return J(f);if(f instanceof Uint8Array)return f.slice();if(f instanceof ArrayBuffer)return new Uint8Array(f.slice(0));throw new w(i.invalidRequest,"net: body must be string or bytes")}function P(f,n={}){let c=v();if(!c)return Q(i.unavailable,"net: host did not mount the net module");try{if(typeof f!=="string"||!/^https?:\/\/[^\s/]+(?:\/|$)/.test(f))throw new w(i.invalidRequest,"net: url must be absolute http:// or https://");let r=n.method??"GET";if(!Z.includes(r))throw new w(i.invalidRequest,`net: unsupported method ${String(r)}`);let h=o(n.body);if((r==="GET"||r==="HEAD")&&h.byteLength>0)throw new w(i.invalidRequest,`net: ${r} cannot have a body`);if(h.byteLength>z)throw new w(i.invalidRequest,"net: request body exceeds 64 KiB");let a=t(n.timeoutMs??F,1,M,"timeoutMs"),L=t(n.maxBytes??V,1,K,"maxBytes"),x=JSON.stringify({url:f,method:r,headers:e(n.headers),timeoutMs:a,maxBytes:L});if(D&&D!==c)throw new w(i.unavailable,"net: mounted host changed while requests are pending");let k=c.start(x,h.buffer);if(!Number.isInteger(k)||k<0){let q=c.lastError()||"unavailable: request refused",u=q.indexOf(":"),R=B(u<0?i.other:q.slice(0,u)),b=u<0?q:q.slice(u+1).trim();return Q(R,b)}return new Promise((q,u)=>{if(A.set(k,{ops:c,resolve:q,reject:u}),D=c,!l)l=Y(U)})}catch(r){return r instanceof w?Promise.reject(r):Q(i.invalidRequest,String(r))}}var H=globalThis.db,$=H.open("exa");if($<0)throw Error("open exa.sqlite");var T=5,ff=7,nf=ff*24*60*60,cf=60000;function rf(){return String(H.lastError($)||"SQLite operation failed")}function G(f){if(H.exec($,f)!==0)throw Error(rf())}function N(f,n=[]){let c=JSON.parse(H.query($,f,JSON.stringify(n)));if(c.error)throw Error(String(c.error));return c}function W(f,n=[]){return N(f,n)}var hf=N("PRAGMA user_version");if(Number(hf?.user_version??0)!==T)G(` +(()=>{var Z=["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"];var z=65536,V=131072,K=262144,g=32,j=8192,F=30000,M=120000;var i={unavailable:"unavailable",invalidRequest:"invalid_request",busy:"busy",dns:"dns",connect:"connect",tls:"tls",timeout:"timeout",redirect:"redirect",responseTooLarge:"response_too_large",protocol:"protocol",cancelled:"cancelled",other:"other"};var E={};for(let f=0;f<64;f++)E["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[f]]=f;function J(f){let n=0;for(let h=0;h65535)h++;n+=a<128?1:a<2048?2:a<65536?3:4}let c=new Uint8Array(n),r=0;for(let h=0;h65535)h++;else if(a>=55296&&a<=57343)a=65533;if(a<128)c[r++]=a;else if(a<2048)c[r++]=192|a>>6,c[r++]=128|a&63;else if(a<65536)c[r++]=224|a>>12,c[r++]=128|a>>6&63,c[r++]=128|a&63;else c[r++]=240|a>>18,c[r++]=128|a>>12&63,c[r++]=128|a>>6&63,c[r++]=128|a&63}return c}function S(f){let n="",c=0;while(cf.length)throw Error("invalid UTF-8");for(let L=0;L1114111||h>=55296&&h<=57343||a===1&&h<128||a===2&&h<2048||a===3&&h<65536)throw Error("invalid UTF-8");if(h<65536)n+=String.fromCharCode(h);else h-=65536,n+=String.fromCharCode(55296+(h>>10),56320+(h&1023))}return n}var X=new Set;function Y(f){return X.add(f),()=>X.delete(f)}class w extends Error{constructor(f,n){super(n);this.name="NetError",this.code=f}}class O{constructor(f,n,c,r){this.status=f,this.url=n,this.headers=Object.freeze({...c}),this.ok=f>=200&&f<300,this.data=new Uint8Array(r)}get byteLength(){return this.data.byteLength}async bytes(){return this.data.slice()}async arrayBuffer(){return this.data.slice().buffer}async text(){try{return S(this.data)}catch{throw Error("net: response is not valid UTF-8")}}async json(){return JSON.parse(await this.text())}}var A=new Map,l=null,I=null;function v(){let f=globalThis.net;if(!f||typeof f!=="object")return null;let n=f;return typeof n.start==="function"&&typeof n.take==="function"&&typeof n.cancel==="function"&&typeof n.poll==="function"&&typeof n.lastError==="function"?n:null}function B(f){let n=String(f);for(let c of Object.values(i))if(c===n)return c;return i.other}function p(f){let n=A.get(f.h);if(!n)return;if(A.delete(f.h),f.t==="error")n.reject(new w(B(f.code),String(f.message||f.code)));else if(!Number.isInteger(f.status)||f.status<100||f.status>599||typeof f.url!=="string"||typeof f.headers!=="object"||f.headers===null||!Number.isInteger(f.bytes)||f.bytes<0||f.bytes>K)n.ops.cancel(f.h),n.reject(new w(i.protocol,"net: malformed done event"));else{let c=new ArrayBuffer(f.bytes);if(n.ops.take(f.h,c)!==f.bytes)n.ops.cancel(f.h),n.reject(new w(i.protocol,"net: response body transfer failed"));else n.resolve(new O(f.status,f.url,f.headers,c))}if(A.size===0&&l)l(),l=null,I=null}function U(){if(A.size===0)return;let f=I;if(!f)return;let n=f.poll();if(n!==void 0){let c=null;try{c=JSON.parse(n)}catch{}if(!Array.isArray(c))for(let[r,h]of A)f.cancel(r),A.delete(r),h.reject(new w(i.protocol,"net: malformed event batch"));else for(let r of c){if(!r||typeof r!=="object")continue;let h=r;if(!Number.isInteger(h.h)||h.t!=="done"&&h.t!=="error")continue;p(h)}}if(A.size===0&&l)l(),l=null,I=null}function Q(f,n){return Promise.reject(new w(f,n))}function t(f,n,c,r){if(!Number.isInteger(f)||fc)throw new w(i.invalidRequest,`net: ${r} must be ${n}..${c}`);return f}function e(f){let n=Object.create(null),c=0,r=0;for(let h of Object.keys(f??{})){let a=h.toLowerCase(),L=String(f[h]);if(!/^[!#$%&'*+.^_`|~0-9a-z-]+$/.test(a)||/[\r\n]/.test(L))throw new w(i.invalidRequest,`net: invalid header ${h}`);if(c++,r+=J(a).byteLength+J(L).byteLength+4,c>g||r>j)throw new w(i.invalidRequest,"net: request headers exceed limits");n[a]=L}return n}function o(f){if(f===void 0)return new Uint8Array(0);if(typeof f==="string")return J(f);if(f instanceof Uint8Array)return f.slice();if(f instanceof ArrayBuffer)return new Uint8Array(f.slice(0));throw new w(i.invalidRequest,"net: body must be string or bytes")}function P(f,n={}){let c=v();if(!c)return Q(i.unavailable,"net: host did not mount the net module");try{if(typeof f!=="string"||!/^https?:\/\/[^\s/]+(?:\/|$)/.test(f))throw new w(i.invalidRequest,"net: url must be absolute http:// or https://");let r=n.method??"GET";if(!Z.includes(r))throw new w(i.invalidRequest,`net: unsupported method ${String(r)}`);let h=o(n.body);if((r==="GET"||r==="HEAD")&&h.byteLength>0)throw new w(i.invalidRequest,`net: ${r} cannot have a body`);if(h.byteLength>z)throw new w(i.invalidRequest,"net: request body exceeds 64 KiB");let a=t(n.timeoutMs??F,1,M,"timeoutMs"),L=t(n.maxBytes??V,1,K,"maxBytes"),x=JSON.stringify({url:f,method:r,headers:e(n.headers),timeoutMs:a,maxBytes:L});if(I&&I!==c)throw new w(i.unavailable,"net: mounted host changed while requests are pending");let k=c.start(x,h.buffer);if(!Number.isInteger(k)||k<0){let q=c.lastError()||"unavailable: request refused",D=q.indexOf(":"),R=B(D<0?i.other:q.slice(0,D)),b=D<0?q:q.slice(D+1).trim();return Q(R,b)}return new Promise((q,D)=>{if(A.set(k,{ops:c,resolve:q,reject:D}),I=c,!l)l=Y(U)})}catch(r){return r instanceof w?Promise.reject(r):Q(i.invalidRequest,String(r))}}var H=globalThis.db,$=H.open("exa");if($<0)throw Error("open exa.sqlite");var T=5,ff=7,nf=ff*24*60*60,cf=60000;function rf(){return String(H.lastError($)||"SQLite operation failed")}function G(f){if(H.exec($,f)!==0)throw Error(rf())}function N(f,n=[]){let c=JSON.parse(H.query($,f,JSON.stringify(n)));if(c.error)throw Error(String(c.error));return c}function W(f,n=[]){return N(f,n)}var hf=Number(N("PRAGMA user_version")?.rows?.[0]?.[0]??0);if(hf!==T)G(` DROP TABLE IF EXISTS searches; CREATE TABLE searches ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -11,4 +11,4 @@ ); CREATE INDEX searches_retention ON searches(searched_at); PRAGMA user_version=${T}; - `);function af(){return Math.floor(Date.now()/1000)}function s(f){let n=f-nf;W("DELETE FROM searches WHERE searched_at < ?",[n])}async function d(f,n){let c=await P(`https://api.exa.ai${f}`,{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify(n),timeoutMs:cf,maxBytes:98304}),r=await c.json();if(!c.ok)throw Error(`Exa HTTP ${c.status}: ${JSON.stringify(r)}`);return r}function y(f){G("BEGIN IMMEDIATE");try{f(),G("COMMIT")}catch(n){try{G("ROLLBACK")}catch{}throw n}globalThis.app.commit()}async function wf(f){let n=String(f.query??"").trim();if(!n)throw Error("query is required");let c=af();try{let r={query:n,type:f.searchType??"auto",numResults:Math.max(1,Math.min(10,Number(f.numResults??10))),contents:{highlights:{maxCharacters:800}}};for(let x of["includeDomains","excludeDomains","startPublishedDate","endPublishedDate","category","userLocation","additionalQueries","moderation"])if(f[x]!==void 0)r[x]=f[x];if(f.maxAgeHours!==void 0)r.contents.maxAgeHours=f.maxAgeHours;let h=await d("/search",r),a=Array.isArray(h?.results)?h.results:[],L=typeof a[0]?.title==="string"?a[0].title:null;return y(()=>{W("INSERT INTO searches(query,searched_at,status,result_count,top_title,error) VALUES(?,?,?,?,?,NULL)",[n,c,"ok",a.length,L]),s(c)}),h}catch(r){let h=r instanceof Error?r.message:String(r);throw y(()=>{W("INSERT INTO searches(query,searched_at,status,result_count,top_title,error) VALUES(?,?,?,0,NULL,?)",[n,c,"error",h]),s(c)}),r}}async function Lf(f){let n=String(f.url??"").trim();if(!n)throw Error("url is required");let c={urls:[n],text:{maxCharacters:Math.max(200,Math.min(12000,Number(f.maxCharacters??6000))),includeHtmlTags:!1}};if(f.maxAgeHours!==void 0)c.maxAgeHours=f.maxAgeHours;return d("/contents",c)}var I,C=!1;function _(f){return JSON.stringify({text:f instanceof Error?f.message:String(f),isError:!0})}function m(f){if(C)throw Error("Exa Data Action is already running");C=!0,I=void 0,f().then((n)=>{I=JSON.stringify({text:JSON.stringify(n),isError:!1}),C=!1},(n)=>{I=_(n),C=!1})}globalThis.PocketPiData={beginInvokeTask(f){m(async()=>{throw Error("Unknown Exa Data Action: "+f)})},beginInvokeTool(f,n){try{let c=JSON.parse(n);m(()=>f==="research.search"?wf(c):f==="research.fetch"?Lf(c):Promise.reject(Error("Unknown Exa tool: "+f)))}catch(c){I=_(c),C=!1}},tick(){U()},pollResult(){let f=I;return I=void 0,f}};})(); + `);function af(){return Math.floor(Date.now()/1000)}function y(f){let n=f-nf;W("DELETE FROM searches WHERE searched_at < ?",[n])}async function d(f,n){let c=await P(`https://api.exa.ai${f}`,{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify(n),timeoutMs:cf,maxBytes:98304}),r=await c.json();if(!c.ok)throw Error(`Exa HTTP ${c.status}: ${JSON.stringify(r)}`);return r}function s(f){G("BEGIN IMMEDIATE");try{f(),G("COMMIT")}catch(n){try{G("ROLLBACK")}catch{}throw n}globalThis.app.commit()}async function wf(f){let n=String(f.query??"").trim();if(!n)throw Error("query is required");let c=af();try{let r={query:n,type:f.searchType??"auto",numResults:Math.max(1,Math.min(10,Number(f.numResults??10))),contents:{highlights:{maxCharacters:800}}};for(let x of["includeDomains","excludeDomains","startPublishedDate","endPublishedDate","category","userLocation","additionalQueries","moderation"])if(f[x]!==void 0)r[x]=f[x];if(f.maxAgeHours!==void 0)r.contents.maxAgeHours=f.maxAgeHours;let h=await d("/search",r),a=Array.isArray(h?.results)?h.results:[],L=typeof a[0]?.title==="string"?a[0].title:null;return s(()=>{W("INSERT INTO searches(query,searched_at,status,result_count,top_title,error) VALUES(?,?,?,?,?,NULL)",[n,c,"ok",a.length,L]),y(c)}),h}catch(r){let h=r instanceof Error?r.message:String(r);throw s(()=>{W("INSERT INTO searches(query,searched_at,status,result_count,top_title,error) VALUES(?,?,?,0,NULL,?)",[n,c,"error",h]),y(c)}),r}}async function Lf(f){let n=String(f.url??"").trim();if(!n)throw Error("url is required");let c={urls:[n],text:{maxCharacters:Math.max(200,Math.min(12000,Number(f.maxCharacters??6000))),includeHtmlTags:!1}};if(f.maxAgeHours!==void 0)c.maxAgeHours=f.maxAgeHours;return d("/contents",c)}var u,C=!1;function _(f){return JSON.stringify({text:f instanceof Error?f.message:String(f),isError:!0})}function m(f){if(C)throw Error("Exa Data Action is already running");C=!0,u=void 0,f().then((n)=>{u=JSON.stringify({text:JSON.stringify(n),isError:!1}),C=!1},(n)=>{u=_(n),C=!1})}globalThis.PocketPiData={beginInvokeTask(f){m(async()=>{throw Error("Unknown Exa Data Action: "+f)})},beginInvokeTool(f,n){try{let c=JSON.parse(n);m(()=>f==="research.search"?wf(c):f==="research.fetch"?Lf(c):Promise.reject(Error("Unknown Exa tool: "+f)))}catch(c){u=_(c),C=!1}},tick(){U()},pollResult(){let f=u;return u=void 0,f}};})(); diff --git a/apps/robinhood/data-action.ts b/apps/robinhood/data-action.ts index d4421cb..cc19d3c 100644 --- a/apps/robinhood/data-action.ts +++ b/apps/robinhood/data-action.ts @@ -18,9 +18,16 @@ function query(sql: string, args: any[] = []): any { return result; } function run(sql: string, args: any[] = []): any { return query(sql, args); } +function insertRows(sql: string, rows: any[][]): void { + if (!rows.length) return; + const values = rows.map((row) => "(" + row.map(() => "?").join(",") + ")").join(","); + const args: any[] = []; + for (const row of rows) args.push(...row); + run(sql + " VALUES " + values, args); +} -const version = query("PRAGMA user_version") as { user_version?: number } | null; -if (Number(version?.user_version ?? 0) !== SCHEMA_VERSION) { +const version = Number(query("PRAGMA user_version")?.rows?.[0]?.[0] ?? 0); +if (version !== SCHEMA_VERSION) { exec(` CREATE TABLE IF NOT EXISTS accounts ( account_number TEXT PRIMARY KEY, @@ -252,6 +259,7 @@ function transaction(action: () => void): void { function saveAccounts(value: any, observedAt: number): void { const rows = list(value, ["accounts"]); run("DELETE FROM accounts"); + const values: any[][] = []; for (const item of rows) { const account = accountNumber(item, {}); if (!account) continue; @@ -260,11 +268,9 @@ function saveAccounts(value: any, observedAt: number): void { const label = agentic ? "AGENTIC" : accountType.includes("IRA") || accountType.includes("RETIRE") ? "RETIREMENT" : accountType.includes("JOINT") ? "JOINT" : "PERSONAL"; - run( - "INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at) VALUES(?,?,?,?,?,?,?)", - [account, label, account.slice(-4), accountType, (deep(item, ["status"]) || "active").toUpperCase(), agentic ? 1 : 0, observedAt], - ); + values.push([account, label, account.slice(-4), accountType, (deep(item, ["status"]) || "active").toUpperCase(), agentic ? 1 : 0, observedAt]); } + insertRows("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at)", values); } function savePortfolio(value: any, args: any, observedAt: number): void { @@ -295,14 +301,13 @@ function savePositions(value: any, args: any, observedAt: number): void { if (!account) throw new Error("Robinhood positions are missing account_number"); const rows = list(value, ["positions"]).slice(0, 64); run("DELETE FROM positions WHERE account_number=?", [account]); + const values: any[][] = []; for (const item of rows) { const symbol = deep(item, ["symbol"]); if (!symbol) continue; - run( - "INSERT INTO positions(account_number,symbol,quantity,average_price,market_value,observed_at) VALUES(?,?,?,?,?,?)", - [account, symbol, deep(item, ["quantity", "shares"]), deep(item, ["average_price", "averagePrice", "average_buy_price"]), deep(item, ["market_value", "marketValue", "equity"]), observedAt], - ); + values.push([account, symbol, deep(item, ["quantity", "shares"]), deep(item, ["average_price", "averagePrice", "average_buy_price"]), deep(item, ["market_value", "marketValue", "equity"]), observedAt]); } + insertRows("INSERT INTO positions(account_number,symbol,quantity,average_price,market_value,observed_at)", values); } function saveActivities(value: any, args: any, observedAt: number): void { @@ -310,6 +315,7 @@ function saveActivities(value: any, args: any, observedAt: number): void { if (!account) throw new Error("Robinhood activities are missing account_number"); const rows = list(value, ["orders", "activities", "results"]).slice(0, 64); run("DELETE FROM activities WHERE account_number=?", [account]); + const values: any[][] = []; rows.forEach((item, index) => { const symbol = deep(item, ["symbol"]); const side = (deep(item, ["side"]) || "").toUpperCase(); @@ -321,12 +327,9 @@ function saveActivities(value: any, args: any, observedAt: number): void { const quantityNumber = number(quantity); const priceNumber = number(price); const amount = quantityNumber !== null && priceNumber !== null ? String(quantityNumber * priceNumber) : price || quantity; - run( - `INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) - VALUES(?,?,?,?,?,?,?,?,?,?,?)`, - [account, activityId, occurredAt, observedAt, symbol, side, quantity, price, amount, (deep(item, ["state", "status"]) || "RECENT").toUpperCase(), (deep(item, ["type", "order_type"]) || "ORDER").toUpperCase()], - ); + values.push([account, activityId, occurredAt, observedAt, symbol, side, quantity, price, amount, (deep(item, ["state", "status"]) || "RECENT").toUpperCase(), (deep(item, ["type", "order_type"]) || "ORDER").toUpperCase()]); }); + insertRows("INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type)", values); } function saveRealizedPnl(value: any, args: any, observedAt: number): void { diff --git a/apps/robinhood/dist/data-action.js b/apps/robinhood/dist/data-action.js index dd3db55..9517546 100644 --- a/apps/robinhood/dist/data-action.js +++ b/apps/robinhood/dist/data-action.js @@ -1,4 +1,4 @@ -(()=>{var b={source:"https://agent.robinhood.com/mcp/trading",protocolVersion:"2025-06-18",retrievedAt:"2026-08-10T09:05:39+00:00",tools:[{name:"add_option_to_watchlist",namespace:"option_market_data",description:"Add option contracts to the user's options watchlist. Works for both equity options (AAPL, NVDA) and index options (SPX, NDX, RUT). Source option_ids from get_option_instruments. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{option_ids:{type:["null","array"],items:{type:"string"},description:"Option contract UUIDs to add. Each becomes a single-leg position on the user's options watchlist. Source from get_option_instruments."},position_type:{type:"string",description:'"long" (default) or "short". Applies to every option_id in this call. For mixed long/short adds, issue two calls.'}},required:["option_ids"],additionalProperties:!1}},{name:"add_to_watchlist",namespace:"watchlists",description:"Add items to a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes like SPX, NDX) is required — mutually exclusive. For options use add_option_to_watchlist (separate dedicated watchlist). Futures still require the Robinhood app. Already-present items are no-ops. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to add items to."},symbols:{type:["null","array"],items:{type:"string"},description:"Stock symbols to add (e.g. ['AAPL', 'NVDA']). US stocks and ETFs only. Mutually exclusive with currency_pair_ids and index_ids."},currency_pair_ids:{type:["null","array"],items:{type:"string"},description:"Currency-pair UUIDs to add, available as object_id from get_watchlist_items entries where object_type=currency_pair. Mutually exclusive with symbols and index_ids."},index_ids:{type:["null","array"],items:{type:"string"},description:"Market-index UUIDs to add (the id field from get_indexes; SPX, NDX, DJI, etc.). Mutually exclusive with symbols and currency_pair_ids."}},required:["list_id"],additionalProperties:!1}},{name:"cancel_equity_order",namespace:"equity_trading",description:"Cancel an open equity order by order_id. Resolve order_id via get_equity_orders and pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the order, from get_accounts. Must be agentic_allowed=true. The upstream rejects mismatches against the order's owning account."},order_id:{type:"string",description:"Order UUID from get_equity_orders. Must live in account_number."}},required:["account_number","order_id"],additionalProperties:!1}},{name:"cancel_option_exercise",namespace:"option_trading",description:"Cancel all queued exercise requests for an option position. Pass the same account_number and option_id used for exercise_option. Internally looks up all queued exercise events for that option and cancels each one. Typically there is one; multiple means separate exercise batches were submitted. Only events in state=queued can be cancelled; events already processing are rejected by the broker. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the exercise. Must be agentic_allowed=true."},option_id:{type:"string",description:"Option instrument UUID — the same option_id used for exercise_option. The tool looks up the queued exercise for this option and cancels it."}},required:["account_number","option_id"],additionalProperties:!1}},{name:"cancel_option_order",namespace:"option_trading",description:"Cancel an open option order by account_number + order_id. Resolve order_id via get_option_orders and pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the order, from get_accounts. Must be agentic_allowed=true. Mismatches against the order's owning account are rejected."},order_id:{type:"string",description:"Order UUID from get_option_orders. Must live in account_number."}},required:["account_number","order_id"],additionalProperties:!1}},{name:"create_scan",namespace:"scanners",description:`Create a new saved scanner (screener) on the user's account, optionally applying a preset and custom filters in a single call. Returns the new scan's id, title, applied filters, and the initial live market results. +(()=>{var w={source:"https://agent.robinhood.com/mcp/trading",protocolVersion:"2025-06-18",retrievedAt:"2026-08-10T09:05:39+00:00",tools:[{name:"add_option_to_watchlist",namespace:"option_market_data",description:"Add option contracts to the user's options watchlist. Works for both equity options (AAPL, NVDA) and index options (SPX, NDX, RUT). Source option_ids from get_option_instruments. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{option_ids:{type:["null","array"],items:{type:"string"},description:"Option contract UUIDs to add. Each becomes a single-leg position on the user's options watchlist. Source from get_option_instruments."},position_type:{type:"string",description:'"long" (default) or "short". Applies to every option_id in this call. For mixed long/short adds, issue two calls.'}},required:["option_ids"],additionalProperties:!1}},{name:"add_to_watchlist",namespace:"watchlists",description:"Add items to a watchlist. Exactly one of symbols (stocks/ETFs), currency_pair_ids (crypto), or index_ids (market indexes like SPX, NDX) is required — mutually exclusive. For options use add_option_to_watchlist (separate dedicated watchlist). Futures still require the Robinhood app. Already-present items are no-ops. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to add items to."},symbols:{type:["null","array"],items:{type:"string"},description:"Stock symbols to add (e.g. ['AAPL', 'NVDA']). US stocks and ETFs only. Mutually exclusive with currency_pair_ids and index_ids."},currency_pair_ids:{type:["null","array"],items:{type:"string"},description:"Currency-pair UUIDs to add, available as object_id from get_watchlist_items entries where object_type=currency_pair. Mutually exclusive with symbols and index_ids."},index_ids:{type:["null","array"],items:{type:"string"},description:"Market-index UUIDs to add (the id field from get_indexes; SPX, NDX, DJI, etc.). Mutually exclusive with symbols and currency_pair_ids."}},required:["list_id"],additionalProperties:!1}},{name:"cancel_equity_order",namespace:"equity_trading",description:"Cancel an open equity order by order_id. Resolve order_id via get_equity_orders and pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. After the provider action succeeds, Pocket Pi writes the returned equity-order state into the activities View projection in robinhood.sqlite. Portfolio and positions converge on the next normal refresh.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the order, from get_accounts. Must be agentic_allowed=true. The upstream rejects mismatches against the order's owning account."},order_id:{type:"string",description:"Order UUID from get_equity_orders. Must live in account_number."}},required:["account_number","order_id"],additionalProperties:!1}},{name:"cancel_option_exercise",namespace:"option_trading",description:"Cancel all queued exercise requests for an option position. Pass the same account_number and option_id used for exercise_option. Internally looks up all queued exercise events for that option and cancels each one. Typically there is one; multiple means separate exercise batches were submitted. Only events in state=queued can be cancelled; events already processing are rejected by the broker. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the exercise. Must be agentic_allowed=true."},option_id:{type:"string",description:"Option instrument UUID — the same option_id used for exercise_option. The tool looks up the queued exercise for this option and cancels it."}},required:["account_number","option_id"],additionalProperties:!1}},{name:"cancel_option_order",namespace:"option_trading",description:"Cancel an open option order by account_number + order_id. Resolve order_id via get_option_orders and pass the same account_number. Requires an agentic_allowed=true account; non-agentic accounts are rejected. Cancellation may be rejected if the order has already filled, was already cancelled, or is otherwise ineligible. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{account_number:{type:"string",description:"Brokerage account that owns the order, from get_accounts. Must be agentic_allowed=true. Mismatches against the order's owning account are rejected."},order_id:{type:"string",description:"Order UUID from get_option_orders. Must live in account_number."}},required:["account_number","order_id"],additionalProperties:!1}},{name:"create_scan",namespace:"scanners",description:`Create a new saved scanner (screener) on the user's account, optionally applying a preset and custom filters in a single call. Returns the new scan's id, title, applied filters, and the initial live market results. This tool composes multiple Beacon operations: 1. Create an empty scan @@ -163,7 +163,7 @@ Restrictions: - Cortex-managed scans (cortex_managed: true in get_scans) are rejected with a user-friendly error. - Returns an error and does not apply any change if any filter fails validation. -Returns the scan with its new filters and fresh live results. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan to modify. Get this from get_scans or create_scan. Cortex-managed scans (cortex_managed: true in get_scans output) are rejected."},filters:{type:["null","array"],items:{type:"object",properties:{filter_type:{type:"string",description:'Wire-format enum name, e.g. "FILTER_TYPE_RSI". See the scanner-filter-specs resource for valid values. Omit when supplying expression.'},predicate:{type:"string",description:'Wire-format enum name, e.g. "PREDICATE_GREATER_THAN". See the scanner-filter-specs resource for the predicates supported by each filter.'},values:{type:["null","array"],items:{type:"string"},description:'Threshold values. Single-element for unary predicates, two-element for BETWEEN, multi-element for IN_LIST/ANY_OF. For a boolean expression screen, exactly ["True"].'},interval:{type:"string",description:`Time granularity for time-series filters (e.g. "1d"). Use one of the supported_intervals from the filter's scanner-filter-specs entry. Not used with expression — encode granularity inside the expression.`},length:{type:"integer",description:"Lookback length for filters that need one (e.g. RSI period of 14). Use one of the supported_lengths from the filter's scanner-filter-specs entry. Not used with expression.",minimum:-2147483648,maximum:2147483647},plot:{type:"string",description:`Plot / price-field input for filters that have one (e.g. "open" or "close" for % Change). Use one of the supported_plots from the filter's scanner-filter-specs entry. Not used with expression.`},expression:{type:"string",description:'Raw market-data expression to screen on, e.g. "dayVolume / volumeAvg(candleCount=30, candlePeriod=\\"1d\\", session=\\"all\\")" with a numeric predicate, or a whole comparison like "tradeAllDay.price > closeAvg(candleCount=50, candlePeriod=\\"1d\\", session=\\"all\\")" with predicate "=" and values ["True"]. Only preview_scan accepts expressions. Omit filter_type when set. Prefer an enum filter_type whenever one covers the request.'},display_title:{type:"string",description:'Optional short label for an expression filter, shown as the results-column header (e.g. "Relative volume (30D)"). Only used with expression.'}},required:["predicate","values"],additionalProperties:!1},description:"The complete set of filters the scan should have after the update. REPLACE semantics — to add a filter, supply all existing filters plus the new one. To remove a filter, omit it from the array. To clear all filters, send []. Each filter: filter_type (FILTER_TYPE_... enum), predicate (>, <, =, BETWEEN, etc.), values, optional interval (e.g. 1d), optional length (e.g. 14 for RSI). Call get_scanner_filter_specs first for valid filter_type / predicate / interval / length combinations."}},required:["scan_id","filters"],additionalProperties:!1}},{name:"update_watchlist",namespace:"watchlists",description:"Rename a custom watchlist or change its icon/description. Robinhood-curated lists cannot be renamed; the call will fail with 404. Provide at least one of display_name, icon_emoji, display_description. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to update. Obtain from get_watchlists."},display_name:{type:"string",description:"New name for the watchlist."},icon_emoji:{type:"string",description:"New emoji."},display_description:{type:"string",description:"New description."}},required:["list_id"],additionalProperties:!1}}]};var k=globalThis.db,q=k.open("robinhood");if(q<0)throw Error("open robinhood.sqlite");var E=5;function M(){return String(k.lastError(q)||"SQLite operation failed")}function w(e){if(k.exec(q,e)!==0)throw Error(M())}function T(e,t=[]){let i=JSON.parse(k.query(q,e,JSON.stringify(t)));if(i.error)throw Error(String(i.error));return i}function h(e,t=[]){return T(e,t)}var V=T("PRAGMA user_version");if(Number(V?.user_version??0)!==E)w(` +Returns the scan with its new filters and fresh live results. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan to modify. Get this from get_scans or create_scan. Cortex-managed scans (cortex_managed: true in get_scans output) are rejected."},filters:{type:["null","array"],items:{type:"object",properties:{filter_type:{type:"string",description:'Wire-format enum name, e.g. "FILTER_TYPE_RSI". See the scanner-filter-specs resource for valid values. Omit when supplying expression.'},predicate:{type:"string",description:'Wire-format enum name, e.g. "PREDICATE_GREATER_THAN". See the scanner-filter-specs resource for the predicates supported by each filter.'},values:{type:["null","array"],items:{type:"string"},description:'Threshold values. Single-element for unary predicates, two-element for BETWEEN, multi-element for IN_LIST/ANY_OF. For a boolean expression screen, exactly ["True"].'},interval:{type:"string",description:`Time granularity for time-series filters (e.g. "1d"). Use one of the supported_intervals from the filter's scanner-filter-specs entry. Not used with expression — encode granularity inside the expression.`},length:{type:"integer",description:"Lookback length for filters that need one (e.g. RSI period of 14). Use one of the supported_lengths from the filter's scanner-filter-specs entry. Not used with expression.",minimum:-2147483648,maximum:2147483647},plot:{type:"string",description:`Plot / price-field input for filters that have one (e.g. "open" or "close" for % Change). Use one of the supported_plots from the filter's scanner-filter-specs entry. Not used with expression.`},expression:{type:"string",description:'Raw market-data expression to screen on, e.g. "dayVolume / volumeAvg(candleCount=30, candlePeriod=\\"1d\\", session=\\"all\\")" with a numeric predicate, or a whole comparison like "tradeAllDay.price > closeAvg(candleCount=50, candlePeriod=\\"1d\\", session=\\"all\\")" with predicate "=" and values ["True"]. Only preview_scan accepts expressions. Omit filter_type when set. Prefer an enum filter_type whenever one covers the request.'},display_title:{type:"string",description:'Optional short label for an expression filter, shown as the results-column header (e.g. "Relative volume (30D)"). Only used with expression.'}},required:["predicate","values"],additionalProperties:!1},description:"The complete set of filters the scan should have after the update. REPLACE semantics — to add a filter, supply all existing filters plus the new one. To remove a filter, omit it from the array. To clear all filters, send []. Each filter: filter_type (FILTER_TYPE_... enum), predicate (>, <, =, BETWEEN, etc.), values, optional interval (e.g. 1d), optional length (e.g. 14 for RSI). Call get_scanner_filter_specs first for valid filter_type / predicate / interval / length combinations."}},required:["scan_id","filters"],additionalProperties:!1}},{name:"update_watchlist",namespace:"watchlists",description:"Rename a custom watchlist or change its icon/description. Robinhood-curated lists cannot be renamed; the call will fail with 404. Provide at least one of display_name, icon_emoji, display_description. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to update. Obtain from get_watchlists."},display_name:{type:"string",description:"New name for the watchlist."},icon_emoji:{type:"string",description:"New emoji."},display_description:{type:"string",description:"New description."}},required:["list_id"],additionalProperties:!1}}]};var q=globalThis.db,x=q.open("robinhood");if(x<0)throw Error("open robinhood.sqlite");var V=5;function F(){return String(q.lastError(x)||"SQLite operation failed")}function k(e){if(q.exec(x,e)!==0)throw Error(F())}function A(e,t=[]){let i=JSON.parse(q.query(x,e,JSON.stringify(t)));if(i.error)throw Error(String(i.error));return i}function y(e,t=[]){return A(e,t)}function I(e,t){if(!t.length)return;let i=t.map((d)=>"("+d.map(()=>"?").join(",")+")").join(","),r=[];for(let d of t)r.push(...d);y(e+" VALUES "+i,r)}var N=Number(A("PRAGMA user_version")?.rows?.[0]?.[0]??0);if(N!==V)k(` CREATE TABLE IF NOT EXISTS accounts ( account_number TEXT PRIMARY KEY, label TEXT NOT NULL, @@ -222,19 +222,18 @@ Returns the scan with its new filters and fresh live results. This changes Robin ); CREATE INDEX IF NOT EXISTS refresh_runs_recent ON refresh_runs(id DESC); PRAGMA user_version=5; - `);var D=b.tools,F=new Map(D.map((e)=>[e.name,e]));function f(){return Math.floor(Date.now()/1000)}function N(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function n(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let i of t){let r=N(e[i]);if(r!==null)return r}for(let i of Object.values(e)){let r=n(i,t);if(r!==null)return r}return null}function A(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let i of t)if(Array.isArray(e[i]))return e[i];for(let i of Object.values(e)){let r=A(i,t);if(r.length)return r}return[]}function Y(e,t){let i=n(e,t)?.toLowerCase();return i==="true"||i==="1"||i==="yes"}function I(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function _(e,t){let i=t?.account_number;return i===null||i===void 0||i===""?n(e,["account_number","accountNumber","account"])||"":String(i)}function x(e,t){let i=A(e,t);return i.length?i:Array.isArray(e)?e:e?[e]:[]}function G(e){let t=Array.isArray(e?.names)?new Set(e.names.filter((o)=>typeof o==="string")):new Set,i=String(e?.query??"").toLowerCase().split(/[^a-z0-9_]+/).filter(Boolean),r=typeof e?.namespace==="string"?e.namespace:"";if(!t.size&&!i.length)throw Error("search_tools requires query or names");let d=Math.max(1,Math.min(8,Number(e?.limit??5)||5)),s=D.filter((o)=>!r||o.namespace===r).map((o)=>{let a=o.name.toLowerCase(),p=a+" "+o.description.toLowerCase(),c=t.has(o.name)?1000:i.reduce((m,l)=>m+(a===l?100:a.includes(l)?20:p.includes(l)?3:0),0);return{tool:o,score:c}}).filter((o)=>o.score>0).sort((o,a)=>a.score-o.score||o.tool.name.localeCompare(a.tool.name)).slice(0,d).map(({tool:o})=>({name:o.name,namespace:o.namespace,description:o.description,inputSchema:o.inputSchema}));return{source:b.source,protocolVersion:b.protocolVersion,matches:s}}function B(e,t){if(t==="null")return e===null;if(t==="array")return Array.isArray(e);if(t==="object")return e!==null&&typeof e==="object"&&!Array.isArray(e);if(t==="integer")return typeof e==="number"&&Number.isInteger(e);if(t==="number")return typeof e==="number"&&Number.isFinite(e);return typeof e===t}function U(e,t,i="arguments"){let r=Array.isArray(t?.type)?t.type:t?.type?[t.type]:[];if(r.length&&!r.some((s)=>B(e,s)))throw Error(i+" must be "+r.join(" or "));if(e===null)return;if(typeof e==="number"){if(typeof t.minimum==="number"&&et.maximum)throw Error(i+" exceeds maximum "+t.maximum)}if(Array.isArray(e)){if(t.items)e.forEach((s,o)=>U(s,t.items,i+"["+o+"]"));return}if(typeof e!=="object")return;let d=t.properties||{};for(let s of t.required||[])if(!(s in e))throw Error(i+"."+s+" is required");if(t.additionalProperties===!1){for(let s of Object.keys(e))if(!(s in d))throw Error(i+"."+s+" is not allowed")}for(let[s,o]of Object.entries(e))if(d[s])U(o,d[s],i+"."+s)}function z(e){let t=typeof e?.name==="string"?e.name:"",i=F.get(t);if(!i)throw Error("Unknown Robinhood provider Tool: "+t);let r=e?.arguments;return U(r,i.inputSchema),ee(t,r)}function O(e,t){let i=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t})));if(!i.ok)throw Error(i.error||"Robinhood service failed");return i.value}function W(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((i)=>({name:i.operation,arguments:i.args}))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function v(e){w("BEGIN IMMEDIATE");try{e(),w("COMMIT")}catch(t){try{w("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function H(e,t){let i=x(e,["accounts"]);h("DELETE FROM accounts");for(let r of i){let d=_(r,{});if(!d)continue;let s=(n(r,["nickname","account_type","type"])||"").toUpperCase(),o=Y(r,["agentic_allowed","agenticAllowed"]),a=o?"AGENTIC":s.includes("IRA")||s.includes("RETIRE")?"RETIREMENT":s.includes("JOINT")?"JOINT":"PERSONAL";h("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at) VALUES(?,?,?,?,?,?,?)",[d,a,d.slice(-4),s,(n(r,["status"])||"active").toUpperCase(),o?1:0,t])}}function X(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood portfolio is missing account_number");let d=n(e,["cash","cash_available","withdrawable_amount"]),s=n(e,["buying_power","buyingPower"]),o=n(e,["day_pnl","dayPnl","equity_change"]),a=n(e,["week_pnl","weekPnl"]);h(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) + `);var O=w.tools,Y=new Map(O.map((e)=>[e.name,e]));function b(){return Math.floor(Date.now()/1000)}function G(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function a(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let i of t){let r=G(e[i]);if(r!==null)return r}for(let i of Object.values(e)){let r=a(i,t);if(r!==null)return r}return null}function j(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let i of t)if(Array.isArray(e[i]))return e[i];for(let i of Object.values(e)){let r=j(i,t);if(r.length)return r}return[]}function B(e,t){let i=a(e,t)?.toLowerCase();return i==="true"||i==="1"||i==="yes"}function R(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function _(e,t){let i=t?.account_number;return i===null||i===void 0||i===""?a(e,["account_number","accountNumber","account"])||"":String(i)}function P(e,t){let i=j(e,t);return i.length?i:Array.isArray(e)?e:e?[e]:[]}function z(e){let t=Array.isArray(e?.names)?new Set(e.names.filter((s)=>typeof s==="string")):new Set,i=String(e?.query??"").toLowerCase().split(/[^a-z0-9_]+/).filter(Boolean),r=typeof e?.namespace==="string"?e.namespace:"";if(!t.size&&!i.length)throw Error("search_tools requires query or names");let d=Math.max(1,Math.min(8,Number(e?.limit??5)||5)),o=O.filter((s)=>!r||s.namespace===r).map((s)=>{let n=s.name.toLowerCase(),l=n+" "+s.description.toLowerCase(),c=t.has(s.name)?1000:i.reduce((u,p)=>u+(n===p?100:n.includes(p)?20:l.includes(p)?3:0),0);return{tool:s,score:c}}).filter((s)=>s.score>0).sort((s,n)=>n.score-s.score||s.tool.name.localeCompare(n.tool.name)).slice(0,d).map(({tool:s})=>({name:s.name,namespace:s.namespace,description:s.description,inputSchema:s.inputSchema}));return{source:w.source,protocolVersion:w.protocolVersion,matches:o}}function W(e,t){if(t==="null")return e===null;if(t==="array")return Array.isArray(e);if(t==="object")return e!==null&&typeof e==="object"&&!Array.isArray(e);if(t==="integer")return typeof e==="number"&&Number.isInteger(e);if(t==="number")return typeof e==="number"&&Number.isFinite(e);return typeof e===t}function U(e,t,i="arguments"){let r=Array.isArray(t?.type)?t.type:t?.type?[t.type]:[];if(r.length&&!r.some((o)=>W(e,o)))throw Error(i+" must be "+r.join(" or "));if(e===null)return;if(typeof e==="number"){if(typeof t.minimum==="number"&&et.maximum)throw Error(i+" exceeds maximum "+t.maximum)}if(Array.isArray(e)){if(t.items)e.forEach((o,s)=>U(o,t.items,i+"["+s+"]"));return}if(typeof e!=="object")return;let d=t.properties||{};for(let o of t.required||[])if(!(o in e))throw Error(i+"."+o+" is required");if(t.additionalProperties===!1){for(let o of Object.keys(e))if(!(o in d))throw Error(i+"."+o+" is not allowed")}for(let[o,s]of Object.entries(e))if(d[o])U(s,d[o],i+"."+o)}function H(e){let t=typeof e?.name==="string"?e.name:"",i=Y.get(t);if(!i)throw Error("Unknown Robinhood provider Tool: "+t);let r=e?.arguments;return U(r,i.inputSchema),ie(t,r)}function C(e,t){let i=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t})));if(!i.ok)throw Error(i.error||"Robinhood service failed");return i.value}function X(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((i)=>({name:i.operation,arguments:i.args}))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function v(e){k("BEGIN IMMEDIATE");try{e(),k("COMMIT")}catch(t){try{k("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function J(e,t){let i=P(e,["accounts"]);y("DELETE FROM accounts");let r=[];for(let d of i){let o=_(d,{});if(!o)continue;let s=(a(d,["nickname","account_type","type"])||"").toUpperCase(),n=B(d,["agentic_allowed","agenticAllowed"]),l=n?"AGENTIC":s.includes("IRA")||s.includes("RETIRE")?"RETIREMENT":s.includes("JOINT")?"JOINT":"PERSONAL";r.push([o,l,o.slice(-4),s,(a(d,["status"])||"active").toUpperCase(),n?1:0,t])}I("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at)",r)}function Z(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood portfolio is missing account_number");let d=a(e,["cash","cash_available","withdrawable_amount"]),o=a(e,["buying_power","buyingPower"]),s=a(e,["day_pnl","dayPnl","equity_change"]),n=a(e,["week_pnl","weekPnl"]);y(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?,?,?) ON CONFLICT(account_number) DO UPDATE SET cash=excluded.cash,buying_power=excluded.buying_power, day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), - observed_at=excluded.observed_at`,[r,d,s,o,a,i]);let p=n(e,["total_value","equity","total_equity","portfolio_value","market_value"]);if(p!==null)h("INSERT OR REPLACE INTO total_value(account_number,observed_at,value) VALUES(?,?,?)",[r,i,p])}function J(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood positions are missing account_number");let d=x(e,["positions"]).slice(0,64);h("DELETE FROM positions WHERE account_number=?",[r]);for(let s of d){let o=n(s,["symbol"]);if(!o)continue;h("INSERT INTO positions(account_number,symbol,quantity,average_price,market_value,observed_at) VALUES(?,?,?,?,?,?)",[r,o,n(s,["quantity","shares"]),n(s,["average_price","averagePrice","average_buy_price"]),n(s,["market_value","marketValue","equity"]),i])}}function Z(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood activities are missing account_number");let d=x(e,["orders","activities","results"]).slice(0,64);h("DELETE FROM activities WHERE account_number=?",[r]),d.forEach((s,o)=>{let a=n(s,["symbol"]),p=(n(s,["side"])||"").toUpperCase(),c=n(s,["executed_quantity","cumulative_quantity","quantity"]),m=n(s,["average_price","averagePrice","executed_price","price"]),l=n(s,["last_transaction_at","created_at","updated_at","date"]),u=n(s,["id","order_id","orderId","activity_id"])||[l||i,a||"ORDER",p,o].join(":"),y=I(c),g=I(m),C=y!==null&&g!==null?String(y*g):m||c;h(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) - VALUES(?,?,?,?,?,?,?,?,?,?,?)`,[r,u,l,i,a,p,c,m,C,(n(s,["state","status"])||"RECENT").toUpperCase(),(n(s,["type","order_type"])||"ORDER").toUpperCase()])})}function $(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood P&L is missing account_number");let d=n(e,["total_returns","realized_pnl","total","amount","day_pnl","week_pnl"]),s=String(t?.span??"day");h(`INSERT INTO portfolio_current(account_number,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?) + observed_at=excluded.observed_at`,[r,d,o,s,n,i]);let l=a(e,["total_value","equity","total_equity","portfolio_value","market_value"]);if(l!==null)y("INSERT OR REPLACE INTO total_value(account_number,observed_at,value) VALUES(?,?,?)",[r,i,l])}function $(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood positions are missing account_number");let d=P(e,["positions"]).slice(0,64);y("DELETE FROM positions WHERE account_number=?",[r]);let o=[];for(let s of d){let n=a(s,["symbol"]);if(!n)continue;o.push([r,n,a(s,["quantity","shares"]),a(s,["average_price","averagePrice","average_buy_price"]),a(s,["market_value","marketValue","equity"]),i])}I("INSERT INTO positions(account_number,symbol,quantity,average_price,market_value,observed_at)",o)}function Q(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood activities are missing account_number");let d=P(e,["orders","activities","results"]).slice(0,64);y("DELETE FROM activities WHERE account_number=?",[r]);let o=[];d.forEach((s,n)=>{let l=a(s,["symbol"]),c=(a(s,["side"])||"").toUpperCase(),u=a(s,["executed_quantity","cumulative_quantity","quantity"]),p=a(s,["average_price","averagePrice","executed_price","price"]),f=a(s,["last_transaction_at","created_at","updated_at","date"]),m=a(s,["id","order_id","orderId","activity_id"])||[f||i,l||"ORDER",c,n].join(":"),g=R(u),S=R(p),E=g!==null&&S!==null?String(g*S):p||u;o.push([r,m,f,i,l,c,u,p,E,(a(s,["state","status"])||"RECENT").toUpperCase(),(a(s,["type","order_type"])||"ORDER").toUpperCase()])}),I("INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type)",o)}function K(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood P&L is missing account_number");let d=a(e,["total_returns","realized_pnl","total","amount","day_pnl","week_pnl"]),o=String(t?.span??"day");y(`INSERT INTO portfolio_current(account_number,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?) ON CONFLICT(account_number) DO UPDATE SET day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), - observed_at=MAX(portfolio_current.observed_at,excluded.observed_at)`,[r,s==="week"?null:d,s==="week"?d:null,i])}function j(e){if(e.operation==="get_accounts")H(e.value,e.observedAt);else if(e.operation==="get_portfolio")X(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_positions")J(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_orders")Z(e.value,e.args,e.observedAt);else if(e.operation==="get_realized_pnl")$(e.value,e.args,e.observedAt);else return!1;return!0}function Q(e){let t=e.toLowerCase();return t.includes("esp_err_http_connect")||t.includes("timeout")||t.includes("tls")||t.includes("socket")||t.includes("network")}function S(){let e=f(),t=[],i=[],r=0,d=(a,p)=>{r+=1;try{let c=O(a,p);return t.push({operation:a,args:p,value:c,observedAt:f()}),c}catch(c){let m=c instanceof Error?c.message:String(c);if(i.push(a+": "+m),a==="get_accounts"||Q(m))throw c;return null}},s=null;try{let a=d("get_accounts",{}),c=x(a,["accounts"]).map((u)=>_(u,{})).filter(Boolean);if(!c.length)throw Error("Robinhood returned no brokerage accounts");let m=new Date((e-604800)*1000).toISOString().slice(0,10),l=[];for(let u of c){let y={account_number:u};l.push({operation:"get_portfolio",args:y},{operation:"get_equity_positions",args:y},{operation:"get_equity_orders",args:{...y,created_at_gte:m}},{operation:"get_realized_pnl",args:{...y,span:"day",asset_classes:["equity"]}},{operation:"get_realized_pnl",args:{...y,span:"week",asset_classes:["equity"]}})}r+=l.length;let P=W(l);if(P.length!==l.length)throw Error("Robinhood batch returned an incomplete result set");if(P.forEach((u,y)=>{let g=l[y];if(u?.ok)t.push({operation:g.operation,args:g.args,value:u.value,observedAt:f()});else i.push(g.operation+": "+String(u?.error||"unknown provider error"))}),!t.some((u)=>u.operation==="get_portfolio"))throw Error("Robinhood batch returned no portfolio data")}catch(a){s=a instanceof Error?a.message:String(a)}let o=s?"failed":i.length?"partial":"succeeded";if(v(()=>{if(!s)for(let a of t)j(a);h(`INSERT INTO refresh_runs(started_at,completed_at,status,operation_count,success_count,error) - VALUES(?,?,?,?,?,?)`,[e,f(),o,r,s?0:t.length,s||i.join(" | ")||null])}),s)throw Error(s);return{status:o,operationCount:r,successCount:t.length}}function K(e,t,i,r){let d=String(i?.account_number??"");if(!d)return;let o=String(i?.order_id??n(t,["order_id","orderId","id"])??"")||[r,i?.symbol||"EQUITY",e].join(":"),a=e==="cancel_equity_order"?n(t,["state","status"])||"CANCEL_REQUESTED":n(t,["state","status"])||"SUBMITTED";h(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) + observed_at=MAX(portfolio_current.observed_at,excluded.observed_at)`,[r,o==="week"?null:d,o==="week"?d:null,i])}function L(e){if(e.operation==="get_accounts")J(e.value,e.observedAt);else if(e.operation==="get_portfolio")Z(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_positions")$(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_orders")Q(e.value,e.args,e.observedAt);else if(e.operation==="get_realized_pnl")K(e.value,e.args,e.observedAt);else return!1;return!0}function ee(e){let t=e.toLowerCase();return t.includes("esp_err_http_connect")||t.includes("timeout")||t.includes("tls")||t.includes("socket")||t.includes("network")}function T(){let e=b(),t=[],i=[],r=0,d=(n,l)=>{r+=1;try{let c=C(n,l);return t.push({operation:n,args:l,value:c,observedAt:b()}),c}catch(c){let u=c instanceof Error?c.message:String(c);if(i.push(n+": "+u),n==="get_accounts"||ee(u))throw c;return null}},o=null;try{let n=d("get_accounts",{}),c=P(n,["accounts"]).map((h)=>_(h,{})).filter(Boolean);if(!c.length)throw Error("Robinhood returned no brokerage accounts");let u=new Date((e-604800)*1000).toISOString().slice(0,10),p=[];for(let h of c){let m={account_number:h};p.push({operation:"get_portfolio",args:m},{operation:"get_equity_positions",args:m},{operation:"get_equity_orders",args:{...m,created_at_gte:u}},{operation:"get_realized_pnl",args:{...m,span:"day",asset_classes:["equity"]}},{operation:"get_realized_pnl",args:{...m,span:"week",asset_classes:["equity"]}})}r+=p.length;let f=X(p);if(f.length!==p.length)throw Error("Robinhood batch returned an incomplete result set");if(f.forEach((h,m)=>{let g=p[m];if(h?.ok)t.push({operation:g.operation,args:g.args,value:h.value,observedAt:b()});else i.push(g.operation+": "+String(h?.error||"unknown provider error"))}),!t.some((h)=>h.operation==="get_portfolio"))throw Error("Robinhood batch returned no portfolio data")}catch(n){o=n instanceof Error?n.message:String(n)}let s=o?"failed":i.length?"partial":"succeeded";if(v(()=>{if(!o)for(let n of t)L(n);y(`INSERT INTO refresh_runs(started_at,completed_at,status,operation_count,success_count,error) + VALUES(?,?,?,?,?,?)`,[e,b(),s,r,o?0:t.length,o||i.join(" | ")||null])}),o)throw Error(o);return{status:s,operationCount:r,successCount:t.length}}function te(e,t,i,r){let d=String(i?.account_number??"");if(!d)return;let s=String(i?.order_id??a(t,["order_id","orderId","id"])??"")||[r,i?.symbol||"EQUITY",e].join(":"),n=e==="cancel_equity_order"?a(t,["state","status"])||"CANCEL_REQUESTED":a(t,["state","status"])||"SUBMITTED";y(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) VALUES(?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(account_number,activity_id) DO UPDATE SET occurred_at=COALESCE(excluded.occurred_at,activities.occurred_at), @@ -244,4 +243,4 @@ Returns the scan with its new filters and fresh live results. This changes Robin quantity=COALESCE(excluded.quantity,activities.quantity), price=COALESCE(excluded.price,activities.price), state=excluded.state, - activity_type=excluded.activity_type`,[d,o,n(t,["created_at","updated_at","last_transaction_at"]),r,i?.symbol??n(t,["symbol"]),i?.side??n(t,["side"]),i?.quantity??i?.dollar_amount??n(t,["quantity","executed_quantity"]),i?.limit_price??i?.stop_price??n(t,["price","average_price"]),i?.dollar_amount??null,String(a).toUpperCase(),e==="cancel_equity_order"?"EQUITY ORDER CANCEL":"EQUITY ORDER"])}function ee(e,t){let i=O(e,t),r={operation:e,args:t,value:i,observedAt:f()};if(["get_accounts","get_portfolio","get_equity_positions","get_equity_orders","get_realized_pnl"].includes(e))v(()=>j(r));if(e==="place_equity_order"||e==="cancel_equity_order")v(()=>K(e,i,t,r.observedAt));return i}function R(e){return JSON.stringify({text:JSON.stringify(e),isError:!1})}globalThis.PocketPiData={invokeTask(e){try{if(e!=="refreshPortfolio")throw Error("Unknown Robinhood Data Action: "+e);let t=S();return R(t)}catch(t){return JSON.stringify({text:t instanceof Error?t.message:String(t),isError:!0})}},invokeTool(e,t){try{let i=JSON.parse(t),r=e==="robinhood.refresh_portfolio"?S():e==="robinhood.search_tools"?G(i):e==="robinhood.call"?z(i):(()=>{throw Error("Unknown Robinhood Tool: "+e)})();return R(r)}catch(i){return JSON.stringify({text:i instanceof Error?i.message:String(i),isError:!0})}}};})(); + activity_type=excluded.activity_type`,[d,s,a(t,["created_at","updated_at","last_transaction_at"]),r,i?.symbol??a(t,["symbol"]),i?.side??a(t,["side"]),i?.quantity??i?.dollar_amount??a(t,["quantity","executed_quantity"]),i?.limit_price??i?.stop_price??a(t,["price","average_price"]),i?.dollar_amount??null,String(n).toUpperCase(),e==="cancel_equity_order"?"EQUITY ORDER CANCEL":"EQUITY ORDER"])}function ie(e,t){let i=C(e,t),r={operation:e,args:t,value:i,observedAt:b()};if(["get_accounts","get_portfolio","get_equity_positions","get_equity_orders","get_realized_pnl"].includes(e))v(()=>L(r));if(e==="place_equity_order"||e==="cancel_equity_order")v(()=>te(e,i,t,r.observedAt));return i}function D(e){return JSON.stringify({text:JSON.stringify(e),isError:!1})}globalThis.PocketPiData={invokeTask(e){try{if(e!=="refreshPortfolio")throw Error("Unknown Robinhood Data Action: "+e);let t=T();return D(t)}catch(t){return JSON.stringify({text:t instanceof Error?t.message:String(t),isError:!0})}},invokeTool(e,t){try{let i=JSON.parse(t),r=e==="robinhood.refresh_portfolio"?T():e==="robinhood.search_tools"?z(i):e==="robinhood.call"?H(i):(()=>{throw Error("Unknown Robinhood Tool: "+e)})();return D(r)}catch(i){return JSON.stringify({text:i instanceof Error?i.message:String(i),isError:!0})}}};})(); diff --git a/crates/pocket-pi-agentos/src/lib.rs b/crates/pocket-pi-agentos/src/lib.rs index 2486755..3c6aba2 100644 --- a/crates/pocket-pi-agentos/src/lib.rs +++ b/crates/pocket-pi-agentos/src/lib.rs @@ -809,7 +809,9 @@ fn mount_shared_db(guest: &Guest, db: SharedDb) -> Result<()> { ns.set( "exec", Function::new(ctx.clone(), move |handle: i32, sql: String| -> i32 { - module.lock().map_or(1, |mut db| db.exec(handle, &sql)) + let result = module.lock().map_or(1, |mut db| db.exec(handle, &sql)); + yield_after_db_call(); + result })?, )?; let module = db.clone(); @@ -818,10 +820,12 @@ fn mount_shared_db(guest: &Guest, db: SharedDb) -> Result<()> { Function::new( ctx.clone(), move |handle: i32, sql: String, args: String| -> String { - module.lock().map_or_else( + let result = module.lock().map_or_else( |_| json!({"error":"App database owner is unavailable"}).to_string(), |mut db| db.query(handle, &sql, &args), - ) + ); + yield_after_db_call(); + result }, )?, )?; @@ -858,6 +862,17 @@ fn mount_services(guest: &Guest, app_id: String, services: Arc Result<()> { guest.mount("app", |ctx, ns| { ns.set( From cb46e40864cb0978e551d8580447381c08494dce Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Wed, 12 Aug 2026 00:31:39 +0800 Subject: [PATCH 20/24] refactor(agentos): select apps at firmware build time --- Cargo.lock | 12 + Cargo.toml | 1 + README.md | 19 +- apps/exa/agent-app.json | 18 + apps/pi-agent/agent-app.json | 1 + apps/pi-agent/app.tsx | 40 +- apps/pi-agent/dist/app.js | 24 +- apps/pi-agent/dist/app.pak | Bin 374864 -> 374832 bytes apps/robinhood/agent-app.json | 14 + apps/robinhood/data-action.ts | 12 +- apps/robinhood/dist/data-action.js | 12 +- crates/pocket-pi-agentos/src/lib.rs | 738 +++++++----------- crates/pocket-pi-app-pack/Cargo.toml | 17 + crates/pocket-pi-app-pack/build.rs | 83 ++ crates/pocket-pi-app-pack/src/lib.rs | 73 ++ crates/pocket-pi-app-pack/tests/runtime.rs | 88 +++ docs/agentos-architecture.md | 28 +- firmware/esp32-p4/Cargo.lock | 10 + firmware/esp32-p4/Cargo.toml | 1 + firmware/esp32-p4/src/agentos_main.rs | 22 +- firmware/esp32-p4/src/app_services.rs | 381 ++++----- .../esp32-p4/src/transport/provisioning.rs | 36 +- hosts/esp32-p4-sim/Cargo.toml | 1 + hosts/esp32-p4-sim/src/main.rs | 32 +- tools/uart-model-bridge.py | 11 +- tools/xtask/src/main.rs | 83 +- 26 files changed, 1010 insertions(+), 747 deletions(-) create mode 100644 crates/pocket-pi-app-pack/Cargo.toml create mode 100644 crates/pocket-pi-app-pack/build.rs create mode 100644 crates/pocket-pi-app-pack/src/lib.rs create mode 100644 crates/pocket-pi-app-pack/tests/runtime.rs diff --git a/Cargo.lock b/Cargo.lock index 5d3ac3b..b64c195 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1973,6 +1973,17 @@ dependencies = [ "tempfile", ] +[[package]] +name = "pocket-pi-app-pack" +version = "0.1.0" +dependencies = [ + "anyhow", + "pocket-pi-agentos", + "pocket-pi-embedded", + "serde_json", + "tempfile", +] + [[package]] name = "pocket-pi-embedded" version = "0.1.0" @@ -1992,6 +2003,7 @@ dependencies = [ "log", "pocket-db", "pocket-pi-agentos", + "pocket-pi-app-pack", "pocket-pi-embedded", "pocket-pi-protocols", "pocket-pi-tools", diff --git a/Cargo.toml b/Cargo.toml index 633734b..8c7977b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" members = [ + "crates/pocket-pi-app-pack", "crates/pocket-pi-agentos", "crates/pocket-pi-embedded", "crates/pocket-pi-protocols", diff --git a/README.md b/README.md index cfd2e74..f93c8b9 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,16 @@ cargo xtask build esp32-p4-sim cargo xtask build esp32-p4 ``` +Pi Agent is always included. Select ordinary Apps at build time with one flag; +omitting it keeps the default Robinhood + Exa image: + +```sh +cargo xtask build esp32-p4 --apps robinhood,exa +cargo xtask build esp32-p4 --apps robinhood +cargo xtask build esp32-p4 --apps exa +cargo xtask build esp32-p4 --apps none +``` + ### 1. ESP32 Pocket Pi simulator on macOS The simulator defaults to the Mac's existing Codex Coding Plan login: @@ -190,8 +200,8 @@ The shared PocketJS device UI includes: - Settings with Wi-Fi scanning, selection and password entry; - touch keyboard and next-schedule status. -The embedded AgentOS ships Pi Agent as its resident System App and Robinhood and -Exa as ordinary Apps. Each ordinary App owns its Tool catalog, Data Action, +The embedded AgentOS ships Pi Agent as its resident System App and can include +Robinhood and Exa as build-selected ordinary Apps. Each ordinary App owns its Tool catalog, Data Action, SQLite projection and fixed PocketJS View; hosts provide only scoped credentials, transport and hardware adapters. @@ -202,6 +212,7 @@ crates/pocket-pi-embedded/ embedded pi-agent-core guest and host traits crates/pocket-pi-tools/ portable workspace, shell, time and schedule tools crates/pocket-pi-protocols/ model request, response and streaming codecs crates/pocket-pi-agentos/ App Supervisor, System App lifecycle and App contracts +crates/pocket-pi-app-pack/ build-selected embedded App composition hosts/esp32-p4-sim/ macOS adapters for the embedded product firmware/esp32-p4/ ESP-IDF hardware composition root and adapters tools/uart_bridge/ Mac Codex and Claude Code streaming adapters @@ -218,9 +229,9 @@ and [docs/esp32-p4-port.md](docs/esp32-p4-port.md) for board-specific details. ## Current validation -On **2026-08-11**, the embedded-only workspace completed 27 tests with no +On **2026-08-11**, the embedded-only workspace completed 28 tests with no failures, passed workspace Clippy with warnings denied, and built the ESP32-P4 -simulator after rebuilding the Pi Agent, Robinhood and Exa bundles. +simulator with none, Exa-only, Robinhood-only and combined App catalogs. Physical firmware, boot, Wi-Fi/DHCP, provider calls and unattended memory pressure remain separate evidence tiers. A successful simulator build is not a diff --git a/apps/exa/agent-app.json b/apps/exa/agent-app.json index 95e2d26..04aaee3 100644 --- a/apps/exa/agent-app.json +++ b/apps/exa/agent-app.json @@ -1,7 +1,25 @@ { "id": "exa", + "description": "Web research and local search history", "version": "1.1.0", "dataVersion": 5, + "toolNamespace": "research", + "nativeServices": { + "http": [ + { + "method": "POST", + "urls": [ + "https://api.exa.ai/search", + "https://api.exa.ai/contents" + ], + "allowedRequestHeaders": ["accept", "content-type"], + "credential": { + "id": "exa.api-key", + "header": "x-api-key" + } + } + ] + }, "tools": [ { "name": "research.search", diff --git a/apps/pi-agent/agent-app.json b/apps/pi-agent/agent-app.json index 5c43d51..67c33e3 100644 --- a/apps/pi-agent/agent-app.json +++ b/apps/pi-agent/agent-app.json @@ -1,5 +1,6 @@ { "id": "pi-agent", + "description": "System Agent and workspace", "version": "1.0.0", "tools": [], "tasks": [], diff --git a/apps/pi-agent/app.tsx b/apps/pi-agent/app.tsx index 66e0942..6485afe 100644 --- a/apps/pi-agent/app.tsx +++ b/apps/pi-agent/app.tsx @@ -13,11 +13,13 @@ const READER_PAGE_LINES = 39; type Message = { role: string; text: string }; type Network = { ssid: string; rssiDbm: number; secured: boolean }; +type InstalledApp = { id: string; title: string; description: string; scheduleEveryMinutes?: number | null }; type Projection = { agent?: string; model?: string; messages?: Message[]; schedule?: { name?: string | null; prompt?: string; next?: string; everyMinutes?: number | null }; + apps?: InstalledApp[]; settings?: { wifi?: { connectedSsid?: string | null; @@ -233,25 +235,25 @@ function FilesScreen() { } function AppsScreen() { + const apps = () => projection().apps ?? []; return (
- 2 INSTALLED APPS - - - R - RobinhoodPortfolio and positionsUPDATES EVERY 5 MINUTES - - - - - - E - Exa ResearchAgent search historySTORED LOCALLY IN SQLITE - - - + {String(apps().length) + " INSTALLED APPS"} + 0} fallback={ + NO OPTIONAL APPS INSTALLED + }> + {(app) => ( + + + {app.title.slice(0, 1).toUpperCase()} + {app.title}{app.description}{"UPDATES EVERY " + String(app.scheduleEveryMinutes) + " MINUTES"} + + + + )} + {"APP DATA STAYS ISOLATED.\nPI AGENT CAN USE EACH APP'S TOOLS."} @@ -580,12 +582,8 @@ queueMicrotask(() => refreshFiles("", true)); return ""; } if (screen() === "apps") { - if (y >= 162 && y < 324) { - return JSON.stringify({ type: "navigate", app: "robinhood" }); - } - if (y >= 324 && y < 490) { - return JSON.stringify({ type: "navigate", app: "exa" }); - } + const app = (projection().apps ?? [])[Math.floor((y - 162) / 166)]; + if (y >= 162 && app) return JSON.stringify({ type: "navigate", app: app.id }); return ""; } if (screen() === "settings") { diff --git a/apps/pi-agent/dist/app.js b/apps/pi-agent/dist/app.js index e8ecdac..c38a033 100644 --- a/apps/pi-agent/dist/app.js +++ b/apps/pi-agent/dist/app.js @@ -1,16 +1,16 @@ -(()=>{var AJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return K1(this.context.count)},getNextContextId(){return K1(this.context.count++)}};function K1(J){let Q=String(J),$=Q.length-1;return AJ.context.id+($?String.fromCharCode(96+$):"")+Q}function F1(J){AJ.context=J}function Y6(){return{...AJ.context,id:AJ.getNextContextId(),count:0}}var z6=!1,W6=(J,Q)=>J===Q,k0=Symbol("solid-proxy"),G6=typeof Proxy==="function",H6=Symbol("solid-track"),FQ=Symbol("solid-dev-component"),oJ={equals:W6},M1=null,j6=O1,m=1,fJ=2,U1={owned:null,cleanups:null,context:null,owner:null},S=null,K=null,yJ=null,_J=null,b=null,C=null,T=null,nJ=0;function tJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?U1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>JJ(()=>QJ(z)));S=z,b=null;try{return c(G,!0)}finally{b=$,S=Z}}function g(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return D1($,q)};return[P1.bind($),Z]}function e(J,Q,$){let Z=L1(J,Q,!1,m);if(yJ&&K&&K.running)C.push(Z);else eJ(Z)}function kJ(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=L1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,yJ&&K&&K.running)Z.tState=m,C.push(Z);else eJ(Z);return P1.bind(Z)}function B6(J){return c(J,!1)}function JJ(J){if(!_J&&b===null)return J();let Q=b;b=null;try{if(_J)return _J.untrack(J);return J()}finally{b=Q}}function S0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function K6(J){if(K&&K.running)return J(),K.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(yJ||F6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[MQ,R1]=g(!1),F6;function P1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)eJ(this);else{let Q=C;C=null,c(()=>J0(this),!1),C=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function D1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw C=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;QJ(J);let Q=nJ;if(V1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{c(()=>{K&&(K.running=!0),b=S=J,V1(J,J.tValue,Q),b=S=null},!1)})}function V1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=m,J.tOwned&&J.tOwned.forEach(QJ),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach(QJ),J.owned=null;return J.updatedAt=$+1,g0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)D1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function L1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(S===null);else if(S!==U1)if(K&&K.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(_J&&X.fn){let z=X.fn,[G,P]=g(void 0,{equals:!1}),D=_J.factory(z,P);S0(()=>D.dispose());let V,j=()=>K6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),K&&K.running){if(!V)V=_J.factory(z,j);return V.track(_)}return D.track(_)}}return X}function b0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===fJ)return J0(J);if(J.suspense&&JJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===m)eJ(J);else if((Q?J.tState:J.state)===fJ){let q=C;C=null,c(()=>J0(J,$[0]),!1),C=q}}}function c(J,Q){if(C)return J();let $=!1;if(!Q)C=[];if(T)$=!0;else T=[];nJ++;try{let Z=J();return M6($),Z}catch(Z){if(!$)T=null;C=null,g0(Z)}}function M6(J){if(C){if(yJ&&K&&K.running)U6(C);else O1(C);C=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;T.push.apply(T,K.effects),Q=K.resolve;for(let X of T)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,c(()=>{for(let X of q)QJ(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zj6($),!1);if(Q)Q()}function O1(J){for(let Q=0;Q{Z.delete($),c(()=>{K.running=!0,b0($)},!1),K&&(K.running=!1)})}}function J0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)QJ(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)A1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)QJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function A1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return S0(()=>k1(X)),()=>{let P=J()||[],D=P.length,V,j;return P[H6],JJ(()=>{let N,h,a,GJ,LJ,M,B,H,L;if(D===0){if(z!==0)k1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[P6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(j=0;j=M&&H>=M&&Z[B]===P[H];B--,H--)a[H]=q[B],GJ[H]=X[B],G&&(LJ[H]=G[B]);N=new Map,h=Array(H+1);for(j=H;j>=M;j--)L=P[j],V=N.get(L),h[j]=V===void 0?-1:V,N.set(L,j);for(V=M;V<=B;V++)if(L=Z[V],j=N.get(L),j!==void 0&&j!==-1)a[j]=q[V],GJ[j]=X[V],G&&(LJ[j]=G[V]),j=h[j],N.set(L,j);else X[V]();for(j=M;jJ(Q||{}));return F1($),Z}}return JJ(()=>J(Q||{}))}function Q0(){return!0}var O6={get(J,Q,$){if(Q===k0)return $;return J.get(Q)},has(J,Q){if(Q===k0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function w0(J){return!(J=typeof J==="function"?J():J)?{}:J}function I6(){for(let J=0,Q=this.length;J=0;G--){let P=w0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in w0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let j=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=j.get?{enumerable:!0,configurable:!0,get:I6.bind($[V]=[j.get.bind(G)])}:j.value!==void 0?j:void 0;else{let _=$[V];if(_){if(j.get)_.push(j.get.bind(G));else if(j.value!==void 0)_.push(()=>j.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var A6=(J)=>`Stale read from <${J}>.`;function SJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return kJ(D6(()=>J.each,J.children,Q||void 0))}function bJ(J){let Q=J.keyed,$=kJ(()=>J.when,void 0,void 0),Z=Q?$:kJ($,void 0,{equals:(q,X)=>!q===!X});return kJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?JJ(()=>X(Q?q:()=>{if(!JJ(Z))throw A6("Show");return $()})):X}return J.fallback},void 0,void 0)}var _6=(J)=>kJ(()=>J());function k6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(M,B,H,L){if(H!==void 0&&!L)L=[];if(typeof B!=="function")return j(M,B,L,H);e((A)=>j(M,B(),A,H),L)}function j(M,B,H,L,A){while(typeof H==="function")H=H();if(B===H)return H;let k=typeof B,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")B=B.toString();if(I){let O=H[0];if(O&&$(O))Z(O,B);else O=Q(B);H=h(M,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(M),H=B);else h(M,H,L,Q(B)),H=B}else if(B==null||k==="boolean")H=h(M,H,L);else if(k==="function")return e(()=>{let O=B();while(typeof O==="function")O=O();H=j(M,O,H,L)}),()=>H;else if(Array.isArray(B)){let O=[];if(_(O,B,A))return e(()=>H=j(M,O,H,L,!0)),()=>H;if(O.length===0){let TJ=h(M,H,L);if(I)return H=TJ}else if(Array.isArray(H))if(H.length===0)a(M,O,L);else N(M,H,O);else if(H==null||H==="")a(M,O);else N(M,I&&H||[P(M)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(M,H,L,B);h(M,H,null,B)}else if(H==null||H===""||!P(M))q(M,B);else GJ(M,B,P(M));H=B}return H}function _(M,B,H){let L=!1;for(let A=0,k=B.length;Ar-O){let KQ=B[I];while(O=0;I--){let O=B[I];if(A!==O){let TJ=G(O)===M;if(!k&&!I)TJ?GJ(M,A,O):q(M,A,H);else TJ&&X(M,O)}else k=!0}}else q(M,A,H);return[A]}function a(M,B,H){for(let L=0,A=B.length;LH.children=j(M,B.children,H.children));return e(()=>B.ref&&B.ref(M)),e(()=>{for(let A in B){if(A==="children"||A==="ref")continue;let k=B[A];if(k===H[A])continue;z(M,A,k,H[A]),H[A]=k}}),H}return{render(M,B){let H;return tJ((L)=>{H=L,V(B,M())}),H},insert:V,spread(M,B,H){if(typeof B==="function")e((L)=>LJ(M,B(),L,H));else LJ(M,B,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(M,B,H,L){return z(M,B,H,L),H},mergeProps:S1,effect:e,memo:_6,createComponent:L6,use(M,B,H){return JJ(()=>M(B,H))}}}function S6(J){let Q=k6(J);return Q.mergeProps=S1,Q}var b1=480,g1=272,HJ={view:0,text:1,image:2},b6=1,g6=-1,w6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},C6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},E6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},N6=1,UQ=2,RQ=1,PQ=2,DQ=131072,VQ=1,LQ=262144,OQ=1,IQ=1,AQ=1,_Q=2,kQ=4,SQ=8,bQ=16,gQ=1,wQ=2;function w1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var CQ=1,h6=1263551300,T6=1,f6=32,y6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},jJ=32896,EQ=0.016666666666666666;function C1(J){return J.__viewport??null}var C0=null;function x6(){return null}function E1(J,Q=x6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function v6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return E1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return E1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function m6(J){C0=J}function gJ(){if(!C0)throw Error("PocketJS: host not installed — call render() first");return C0}function E(){return gJ().ops}function u6(J){globalThis.frame=J}function l6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function p6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return w1($>>>16&255,$>>>8&255,$&255,255);return w1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function c6(J,Q){let $=C6[J];if(typeof Q==="string"){if($===U.color)return p6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var $0=60,N1=[1,2,3,4,5,6,10,12,15,20,30,60],E0=$0,$J=-1,d6=0,xJ=[];function i6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=N1[0];for(let $ of N1)if(Math.abs($-J)Q.at<=$J).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>$J);for(let Q of J)Q.cb()}var N0=0.12,Z0=jJ;function o6(J){Z0=J===void 0?jJ:J&65535}function n6(){Z0=jJ}function f1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function e6(){return f1(Z0&255)}var y1=new Set,J8=0;function Q8(){y1.clear(),J8=0,n6()}function $8(J){for(let Q of[...y1])Q(J)}var BJ=null,x1=null;function Z8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function v1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){h0();let Q=BJ?BJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return x1.slice(Q.off,Q.off+Q.len)}var mJ=null,w=null,KJ=null,q0=0,FJ=[],f0=[],y0=[];function u1(J){if(mJ=J,w=null,KJ=null,q0=0,FJ.length=0,f0.length=0,y0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function X8(J,Q){J.onPress=Q??void 0}function Y8(J,Q){if(J.focusable=Q,i1(),!Q&&w===J)x(null)}function x(J){if(KJ&&KJ!==J)MJ(null);w=J,E().setFocus(J?J.id:0)}function MJ(J){if(KJ===J)return;let Q=E();if(KJ)Q.setActive?.(KJ.id,0);if(KJ=J,J)Q.setActive?.(J.id,1)}function x0(){return FJ.length>0?FJ[FJ.length-1]:mJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function G8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=f0.length-1;Q>=0;Q--){let $=f0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function H8(J){let Q=G8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(w)x(null);return!0}let Z=Q.columns,q=w?$.indexOf(w):-1;if(q<0)return x(l1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function j8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=y0.length-1;Q>=0;Q--){let $=y0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function X0(J){let Q=j8();if(Q&&Q.move(J))return;if(H8(J))return;W8(J)}function p1(){c1(w)}function c1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){MJ(J)}function B8(J){x(J),c1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=m0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,d1=0;function i1(){d1++}var F8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],M8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function U8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=F8[Q]>>$&1,q=M8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function R8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):P8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(U8(),16,16,E6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function P8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&N6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var W0=null;function s1(J){W0=J}function a1(J){let Q=FJ.length>0?FJ[FJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function r1(J,Q,$){return a1(o1(J,Q,$))}function o1(J,Q,$){if($!==void 0)return $===0?null:z0(W0??mJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(W0??mJ,q(J,Q))}function D8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let j=C1(q);if(Z.vw=j?j.w:b1,Z.vh=j?j.h:g1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)R8(Z,q);let X=t6()*Z.speed,z=e6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let j=s6()/60,_=Math.min(Math.max(Z.x+X*j,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*j,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=d1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=a1(z0(W0??mJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==w)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(MJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let j=V===Z.pressTarget;if(Z.pressTarget=null,MJ(null),j)p1()}}else if($&Z.button)MJ(null);return!0}function V8(J){let Q=J&~q0,$=q0&~J;if(q0=J,l&&D8(J,Q,$))return;if($&d.CIRCLE)MJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)MJ(w),p1()}var u0=null;function n1(J){u0=J}function wJ(){if(i1(),u0)u0()}function L8(J,Q){J.debugName=Q||void 0,wJ()}var ZJ={id:b6,type:HJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},t1=Symbol.for("pocketjs.native-node"),l0=1,uJ=3,o=8,O8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function G0(J){return J.domAttrs??={}}function e1(J,Q){let $=J.domNodeType??(lJ(J)?uJ:l0),Z=$===uJ?H0(J.text??""):$===o?_8(J.domData??""):Y4(J.domTag??B0(J));for(let q of Object.keys(J.domAttrs??{}))p0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)qJ(Z,e1(q,!0));return Z}function p0(J,Q,$){if(O8.has(Q)){EJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete G0(J)[Q];else G0(J)[Q]=$}function c0(J){if(J[t1]===!0)return J;return Object.defineProperty(J,t1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(lJ(J)?uJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else j0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else j0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(lJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(lJ(J))j0(J,Z);else if(E8(J),Z)qJ(J,H0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return W4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??B0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===uJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??B0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){EJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===ZJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return qJ(J,$),$},insertBefore($,Z){return qJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return qJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return e1(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){p0(J,$,Z)},removeAttribute($){p0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(ZJ);var d0=null;function I8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},J4=new Map;function Q4(J,Q){J4.set(J,Q)}var $4=new Map;function Z4(J,Q){$4.set(J,Q)}var CJ=new Set,A8=new Set;function q4(J){if(!J)return!1;if(A8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function H0(J){let Q=E(),$=Q.createNode(HJ.text);return Q.setText($,J),c0({id:$,type:HJ.text,parent:null,children:[],text:J,domNodeType:uJ,domTag:"#text"})}function _8(J=""){let Q=H0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function j0(J,Q){E().replaceText(J.id,Q),J.text=Q,wJ()}function lJ(J){return J.type===HJ.text}function z4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function qJ(J,Q,$){let Z=E();if(z4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function pJ(J,Q){if(!Q)return;K8(Q),E().removeChild(J.id,Q.id),z4(Q),CJ.add(Q),wJ()}function k8(J){return J.parent??void 0}function S8(J){return J.children[0]}function W4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function b8(J,Q){let $=E();if(wJ(),Q==null||Q===""){$.setStyle(J.id,g6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function g8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=J4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function w8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=$4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function C8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=w6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,c6(G,P)),z=!0}if(z)wJ()}function EJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete G0(J)[Q];else G0(J)[Q]=$;switch(Q){case"class":return b8(J,$),$;case"onPress":case"on:press":return X8(J,$),$;case"src":return g8(J,$),$;case"sprite":return w8(J,$),$;case"style":return C8(J,$,Z),$;case"focusable":return Y8(J,!!$),$;case"debugName":return L8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${B0(J)}>`)}function E8(J){for(let Q of[...J.children])pJ(J,Q)}function B0(J){for(let Q of Object.keys(HJ))if(HJ[Q]===J.type)return Q;return String(J.type)}function N8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}EJ(J,Q,$,Z)}var h8=S6({createElement:Y4,createTextNode:H0,replaceText:j0,isTextNode:lJ,setProperty:N8,insertNode(J,Q,$){qJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:k8,getFirstChild:S8,getNextSibling:W4}),{render:T8,effect:NQ,memo:p,createComponent:Y,createElement:G4,insert:hQ,spread:f8,mergeProps:TQ,use:fQ}=h8,yQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},y8=null;function H4(J){y8=J}function x8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function j4(J,Q){let $=G4(J);return f8($,Q,!1),x8(Q.nodeRef,$),$}function F(J){return j4("view",J)}function R(J){return j4("text",J)}var xQ=new WeakMap,vQ=new WeakMap,v8={}!==null?Object.freeze({...{}}):Object.freeze({}),mQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:v8}),uQ=new Map,XJ=36000,s0=30,m8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(XJ),tapeAnalog:new Uint16Array(XJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function u8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-s0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)n1(()=>{W.treeDirty=!0}),r8();else n1(null);globalThis.__pocketDevtools=n8}function l8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)c8(),s8();let X=Q,z=$===void 0?jJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(XJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==jJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function F4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function M4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return F4(J.masks,0,Q)}function U4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return F4(J.analog??[],jJ,Q)}function R4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,f({t:"hello",app:W.app,host:o8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` -`))if(q.trim())d8(q)}}function d8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)f({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),a0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":P4();break;case"eval":{let Z=!0,q;try{q=K0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}f({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":f({t:"tape",tape:K4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}f({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())f({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else f({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=M4(Z),W.replayAnalog=Z.analog?U4(Z):null,W.replayTouch=Z.touch?R4(Z):null,W.replayAt=0;break}default:break}}function i8(){if(W.treeDirty&&W.frame-W.treeSentAt>=s0)P4();if(W.frame%m8===0)a0()}function s8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,f({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,f({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){f({t:"stats",frame:W.frame,nodes:L4(ZJ),tapeLen:W.tapeLen,paused:W.paused})}function P4(){W.treeDirty=!1,W.treeSentAt=W.frame,f({t:"tree",frame:W.frame,root:V4(ZJ)})}function a8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(a8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function D4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function V4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(D4(J,(q)=>{if(q.domNodeType===8)return;Z.push(V4(q))}),Z.length)Q.k=Z;return Q}function L4(J){let Q=1;return D4(J,($)=>{Q+=L4($)}),Q}function r8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{f({t:"log",level:$,args:q.map((X)=>K0(X))}),Z?.apply(Q,q)}}}function K0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?O4(X):JSON.stringify(O4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>K0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${K0(z,Q+1)}`).join(", ")}}`}function O4(J){return J.length>200?J.slice(0,199)+"…":J}function o8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var n8={get frame(){return W.frame},dumpTape:()=>K4(),replay:(J)=>{W.replayMasks=M4(J),W.replayAnalog=J.analog?U4(J):null,W.replayTouch=J.touch?R4(J):null,W.replayAt=0}},I4=new Map,o0=new Map;function A4(J){return J.trim().replace(/\s+/g," ")}function _4(J){return J.split(" ").sort().join(" ")}var k4=-1;function t8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=A4(Q);I4.set(Z,$);let q=_4(Z),X=o0.get(q);o0.set(q,X!==void 0&&X!==$?k4:$)}}function e8(J){let Q=A4(J),$=I4.get(Q);if($!==void 0)return $;let Z=o0.get(_4(Q));return Z===k4?void 0:Z}var n0=9,J2=(1<{let q=($&$2)!==0,X=q?t0:n0,z=q?Z2:J2;return Object.freeze({id:$>>>(q?q2:Q2)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Y2(){return F0}function z2(){F0=e0}var S4=8,YJ=8,W2=3,G2=8,H2=6,j2=0.5,s=1,cJ=2,J1=4,UJ=8,NJ=[],b4=0,M0=0,zJ=Array.from({length:S4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(YJ),histY:new Int16Array(YJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function B2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function K2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=o1(Q,$,Z.fact);let G=Z.hit;if(G)return B2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=NJ[z];if(G.disposed)continue;if(b4>0&&!G.opts.allowWhenBlocked)continue;if(!K2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function U2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%YJ,J.histLenz||Z>z))q.flags[J.slot]|=cJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(cJ|J1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??j2)*h1()));if(J.frames=0)NJ.splice($,1)},cancel(){if(!Q.disposed)C4(Q)},get panning(){for(let $ of zJ)if($.used&&Q.flags[$.slot]&UJ)return!0;return!1}}}function L2(J){let Q=V2(J);return S0(()=>Q.dispose()),Q}function E4(){NJ.length=0,b4=0,M0=0;for(let J of zJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function O2(){return L2({onDown:(J)=>{let Q=r1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=r1(J.x,J.y,J.hit);if(Q)B8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var I2=1,Q1=new Map,U0=[];function A2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function _2(){I2=1,Q1.clear(),U0=[]}function k2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),A2()?.({t:"delivery",frame:T1(),id:Q,kind:Z.kind}),Z.onResult($)}}var N4=new Set;function S2(){if(N4.size===0)return;for(let J of N4)J()}var b2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[28] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-base text-orange-600 font-bold":9,"h-[76] pt-3 text-lg text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-base text-emerald-700 font-bold":13,"h-[84] pt-3 text-lg text-slate-900":14,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":15,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":16,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":17,"text-base text-slate-600 font-bold":18,"pt-6 text-lg text-slate-500":19,"pt-6 text-lg text-slate-900 font-bold":20,"h-[146] px-6 pt-7 flex-col bg-slate-50":21,"h-[80]":22,"h-[1060] px-6 pt-5 flex-col":23,"h-[48] px-4 justify-center bg-slate-100":24,"text-base text-slate-600":25,"pt-[10] flex-col gap-[12]":26,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":27,"w-[48] h-[48] items-center justify-center bg-blue-100":28,"w-[48] h-[48] items-center justify-center bg-emerald-100":29,"text-lg text-blue-700 font-bold":30,"text-lg text-emerald-700 font-bold":31,"w-[474] flex-col gap-2":32,"text-lg text-slate-900 font-bold":33,"text-base text-slate-500":34,"pt-20 pl-10 text-lg text-slate-500":35,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":36,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":37,"h-[1060] px-6 pt-7 flex-col gap-4":38,"text-base text-slate-500 font-bold":39,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":40,"flex-row items-center gap-5":41,"w-[68] h-[68] items-center justify-center bg-emerald-100":42,"text-xl text-emerald-700 font-bold":43,"flex-col gap-2":44,"text-xl text-slate-900 font-bold":45,"text-lg text-slate-600":46,"text-2xl text-orange-600":47,"w-[68] h-[68] items-center justify-center bg-indigo-100":48,"text-xl text-indigo-700 font-bold":49,"mt-4 h-[112] px-6 justify-center bg-slate-100":50,"relative h-[154] px-5 pt-5 flex-col bg-white":51,"pt-3 text-lg text-orange-600 font-bold":52,"pt-3 text-base text-slate-500":53,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":54,"text-lg text-white font-bold":55,"h-[40] pt-3 text-base text-slate-500":56,"h-[470] flex-col gap-2":57,"h-[214] px-7 items-center justify-center bg-slate-100":58,"text-lg text-slate-500 font-bold":59,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":60,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":61,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":62,"h-[160] px-5 pt-5 flex-col bg-white":63,"pt-3 text-lg text-slate-900 font-bold":64,"pt-3 text-base text-slate-600":65,"h-[108] pt-7 flex-row gap-4":66,"w-[316] h-[80] items-center justify-center bg-slate-100":67,"w-[340] h-[80] items-center justify-center bg-red-100":68,"text-lg text-red-500 font-bold":69,"h-[1052] px-6 pt-5 flex-col":70,"h-[270] px-[22] pt-6 bg-white":71,"text-lg text-slate-900":72,"text-lg text-slate-400":73,"h-[86] px-1 flex-row items-center justify-between":74,"w-[132] h-[58] items-center justify-center bg-slate-300":75,"w-[132] h-[58] items-center justify-center bg-slate-100":76,"text-base text-slate-900 font-bold":77,"h-[140] flex-row gap-2":78,"grow h-[120] items-center justify-center bg-slate-300":79,"grow h-[120] items-center justify-center bg-white":80,"w-[104] h-[120] items-center justify-center bg-slate-300":81,"w-[104] h-[120] items-center justify-center bg-slate-100":82,"h-[176] flex-row gap-2":83,"w-[92] h-[156] items-center justify-center bg-slate-300":84,"w-[92] h-[156] items-center justify-center bg-slate-100":85,"w-[300] h-[156] items-center justify-center bg-slate-300":86,"w-[300] h-[156] items-center justify-center bg-slate-100":87,"w-[144] h-[156] items-center justify-center bg-slate-300":88,"w-[144] h-[156] items-center justify-center bg-slate-100":89,"w-[112] h-[156] items-center justify-center bg-emerald-700":90,"w-[112] h-[156] items-center justify-center bg-emerald-500":91,"text-base text-slate-950 font-bold":92,"h-[108] px-6 py-3 flex-col bg-slate-50":93,"h-[84] items-center justify-center bg-slate-300":94,"h-[84] items-center justify-center bg-slate-100":95,"h-[1168] px-6 pt-5 flex-col":96,"h-[82] px-4 justify-center bg-white":97,"w-[584] h-[900] px-5 pt-5 bg-slate-950":98,"text-base text-slate-200":99,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":100,"text-lg text-orange-600 font-bold":101,"w-[584] h-[900] px-5 pt-5 bg-white":102,"text-base text-slate-900":103,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":104,"absolute inset-0 z-50 flex-col items-center justify-center":105,"absolute inset-0 bg-slate-950":106,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":107,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":108,"flex-row flex-wrap":109,grow:110,"text-2xl text-white font-bold":111,"text-2xl text-slate-950 font-bold":112,"px-6":113,"px-6 py-5":114,"gap-4":115,"rounded-xl shadow bg-white border-slate-100":116,"rounded-xl shadow bg-emerald-100 border-emerald-500":117,"bg-white":118,"bg-slate-100":119,"bg-slate-950":120,"px-3 py-2 rounded-lg bg-slate-100":121,"px-3 py-2 rounded-lg bg-indigo-100":122,"text-base text-indigo-700 font-bold":123,"px-3 py-2 rounded-lg bg-emerald-100":124,"px-3 py-2 rounded-lg bg-amber-100":125,"text-base text-amber-700 font-bold":126,"px-3 py-2 rounded-lg bg-red-100":127,"text-base text-red-500 font-bold":128,"w-[34] h-[34] rounded-lg bg-amber-400":129,"w-[34] h-[34] rounded-lg bg-red-500":130,"w-[34] h-[34] rounded-lg bg-slate-800":131,"w-[34] h-[34] rounded-lg bg-emerald-500":132,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":133,"flex-row items-center gap-4":134,"w-[34] text-2xl text-white font-bold":135,"w-[332] flex-col items-end gap-2":136,"text-base text-slate-300 font-bold":137,"text-base text-slate-400":138,"h-[166] px-6 pt-6 flex-col gap-3":139,"h-[44] px-1 flex-row items-center justify-between":140,"w-full h-full items-center justify-center rounded-xl bg-slate-200":141,"w-full h-full items-center justify-center rounded-xl bg-red-100":142,"w-full h-full items-center justify-center rounded-xl bg-slate-100":143,"w-full h-full items-center justify-center rounded-xl bg-orange-600":144,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":145,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":146,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":147,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":148,"text-2xl text-indigo-700 font-bold":149,"text-2xl text-slate-600 font-bold":150,"pt-7 text-2xl text-slate-900 font-bold":151,"pt-4 text-lg text-slate-500":152,"text-xl text-emerald-600 font-bold":153,"text-xl text-red-500 font-bold":154,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":155,"text-base text-red-300":156,"text-base text-slate-300":157,"text-base text-red-500":158,"w-full h-full px-6 flex-row items-center bg-slate-950":159,"w-full h-full flex-row items-center":160};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var g2="ui:styles",w2="ui:font.",h4="ui:img.",T4="ui:sprite.";function C2(){return globalThis.ui}function E2(J){if(J.__textures)return;for(let Q of T0(h4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)Q4(Q.slice(h4.length),Z)}}function N2(J){if(J.__sprites)return;for(let Q of T0(T4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)Z4(Q.slice(T4.length),{handle:V,frames:G,cols:P,step:D})}}function f4(J){let Q=G4("view");return EJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function h2(J,Q){if(!R0||!P0)return;EJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),EJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function T2(J,Q={}){let $=v6(Q.ops);if(m6($),I8(e8),Q.styles)t8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)Q4(_,Z[_]);let j=$.ops.__sprites;if(j)for(let _ in j)Z4(_,j[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)m1(Q.pak);if(q8()){for(let j of T0())if(j===g2)$.ops.loadStyles?.(vJ(j));else if(j.startsWith(w2))$.ops.loadFontAtlas?.(vJ(j))}}let q=C1($.ops),X=q?.w??b1,z=q?.h??g1,G=f4({width:X,height:z,overflow:u.Overflow.Hidden}),P=f4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});qJ(ZJ,G),qJ(ZJ,P),H4(P),R0=G,P0=P,u1(G),s1(ZJ),Q8(),E4(),O2(),a6(),_2(),u8($.ops),u6(l8((j,_,N,h)=>{r6(),o6(_),X2(N,h),S2(),k2(),D2(),$8(j),V8(j),X4()}));let D=T8(J,G),V=l6(h2);return()=>{V(),z2(),E4(),D(),u1(null),s1(null),H4(null),R0=null,P0=null;for(let j of ZJ.children.splice(0))j.parent=null,$.ops.destroyNode(j.id);X4()}}function f2(J,Q={}){let $=Q.ops??C2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)m1(Q.pak);return E2($),N2($),T2(J,{ops:$,styles:Q.styles??b2,pak:Q.pak})}var y2="$b",x2=65536,y4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function u2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function x4(){let J=u2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function l2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,x2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=v2(z.data[y2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function p2(J,Q){let $=l2(x4(),J);return Q==="utf8"||Q==="utf-8"?m2($):$}function c2(J,Q){let $=x4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var d2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"};function i2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(F,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(F,{class:"flex-row items-center gap-4",get children(){return[p(()=>p(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(F,{get["class"](){return Q()}})),Y(R,{get["class"](){return d2.appTitle},get children(){return J.title}})]}}),Y(F,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function s2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(F,{get["class"](){return Q()},get children(){return Y(R,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(F,{get["class"](){return J.top},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(F,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var lQ="‘’“”–—…•",v4=new Map,m4=new Map,a2=512;function D0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=v4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return v4.set($,q),q}function r2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=D0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function $1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=m4.get(Z);if(q)return q;let X=[],z=D0(" ",Q);for(let G of J.split(` -`)){let P=G.split(" ").flatMap((j)=>j&&D0(j,Q)>$?r2(j,Q,$):[j]),D="",V=0;for(let j of P){let _=D0(j,Q);if(!D)D=j,V=_;else if(V+z+_<=$)D+=" "+j,V+=z+_;else X.push(D),D=j,V=_}X.push(D)}return m4.set(Z,X),X}function Z1(J,Q,$,Z){let q=J.slice(0,a2),X=$1(q,Q,$);if(q.length===J.length&&X.length<=Z)return X.join(` +(()=>{var kJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return K1(this.context.count)},getNextContextId(){return K1(this.context.count++)}};function K1(J){let Q=String(J),$=Q.length-1;return kJ.context.id+($?String.fromCharCode(96+$):"")+Q}function F1(J){kJ.context=J}function Y6(){return{...kJ.context,id:kJ.getNextContextId(),count:0}}var z6=!1,W6=(J,Q)=>J===Q,k0=Symbol("solid-proxy"),G6=typeof Proxy==="function",H6=Symbol("solid-track"),FQ=Symbol("solid-dev-component"),oJ={equals:W6},M1=null,B6=O1,m=1,fJ=2,U1={owned:null,cleanups:null,context:null,owner:null},S=null,K=null,yJ=null,SJ=null,b=null,C=null,T=null,nJ=0;function tJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?U1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>QJ(()=>$J(z)));S=z,b=null;try{return p(G,!0)}finally{b=$,S=Z}}function g(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return D1($,q)};return[P1.bind($),Z]}function JJ(J,Q,$){let Z=L1(J,Q,!1,m);if(yJ&&K&&K.running)C.push(Z);else eJ(Z)}function bJ(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=L1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,yJ&&K&&K.running)Z.tState=m,C.push(Z);else eJ(Z);return P1.bind(Z)}function j6(J){return p(J,!1)}function QJ(J){if(!SJ&&b===null)return J();let Q=b;b=null;try{if(SJ)return SJ.untrack(J);return J()}finally{b=Q}}function S0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function K6(J){if(K&&K.running)return J(),K.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(yJ||F6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return p(J,!1),b=S=null,Z?Z.done:void 0})}var[MQ,R1]=g(!1),F6;function P1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)eJ(this);else{let Q=C;C=null,p(()=>J0(this),!1),C=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function D1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)p(()=>{for(let q=0;q1e6)throw C=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;$J(J);let Q=nJ;if(V1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{p(()=>{K&&(K.running=!0),b=S=J,V1(J,J.tValue,Q),b=S=null},!1)})}function V1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=m,J.tOwned&&J.tOwned.forEach($J),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach($J),J.owned=null;return J.updatedAt=$+1,g0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)D1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function L1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(S===null);else if(S!==U1)if(K&&K.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(SJ&&X.fn){let z=X.fn,[G,P]=g(void 0,{equals:!1}),D=SJ.factory(z,P);S0(()=>D.dispose());let V,B=()=>K6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),K&&K.running){if(!V)V=SJ.factory(z,B);return V.track(_)}return D.track(_)}}return X}function b0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===fJ)return J0(J);if(J.suspense&&QJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===m)eJ(J);else if((Q?J.tState:J.state)===fJ){let q=C;C=null,p(()=>J0(J,$[0]),!1),C=q}}}function p(J,Q){if(C)return J();let $=!1;if(!Q)C=[];if(T)$=!0;else T=[];nJ++;try{let Z=J();return M6($),Z}catch(Z){if(!$)T=null;C=null,g0(Z)}}function M6(J){if(C){if(yJ&&K&&K.running)U6(C);else O1(C);C=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;T.push.apply(T,K.effects),Q=K.resolve;for(let X of T)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,p(()=>{for(let X of q)$J(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zB6($),!1);if(Q)Q()}function O1(J){for(let Q=0;Q{Z.delete($),p(()=>{K.running=!0,b0($)},!1),K&&(K.running=!1)})}}function J0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)$J(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)A1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)$J(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function A1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return S0(()=>k1(X)),()=>{let P=J()||[],D=P.length,V,B;return P[H6],QJ(()=>{let N,h,a,BJ,IJ,F,j,H,L;if(D===0){if(z!==0)k1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[P6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=F&&H>=F&&Z[j]===P[H];j--,H--)a[H]=q[j],BJ[H]=X[j],G&&(IJ[H]=G[j]);N=new Map,h=Array(H+1);for(B=H;B>=F;B--)L=P[B],V=N.get(L),h[B]=V===void 0?-1:V,N.set(L,B);for(V=F;V<=j;V++)if(L=Z[V],B=N.get(L),B!==void 0&&B!==-1)a[B]=q[V],BJ[B]=X[V],G&&(IJ[B]=G[V]),B=h[B],N.set(L,B);else X[V]();for(B=F;BJ(Q||{}));return F1($),Z}}return QJ(()=>J(Q||{}))}function Q0(){return!0}var O6={get(J,Q,$){if(Q===k0)return $;return J.get(Q)},has(J,Q){if(Q===k0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function w0(J){return!(J=typeof J==="function"?J():J)?{}:J}function I6(){for(let J=0,Q=this.length;J=0;G--){let P=w0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in w0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:I6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var A6=(J)=>`Stale read from <${J}>.`;function jJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return bJ(D6(()=>J.each,J.children,Q||void 0))}function ZJ(J){let Q=J.keyed,$=bJ(()=>J.when,void 0,void 0),Z=Q?$:bJ($,void 0,{equals:(q,X)=>!q===!X});return bJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?QJ(()=>X(Q?q:()=>{if(!QJ(Z))throw A6("Show");return $()})):X}return J.fallback},void 0,void 0)}var _6=(J)=>bJ(()=>J());function k6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(F,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(F,j,L,H);JJ((A)=>B(F,j(),A,H),L)}function B(F,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=h(F,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(F),H=j);else h(F,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=h(F,H,L);else if(k==="function")return JJ(()=>{let O=j();while(typeof O==="function")O=O();H=B(F,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return JJ(()=>H=B(F,O,H,L,!0)),()=>H;if(O.length===0){let TJ=h(F,H,L);if(I)return H=TJ}else if(Array.isArray(H))if(H.length===0)a(F,O,L);else N(F,H,O);else if(H==null||H==="")a(F,O);else N(F,I&&H||[P(F)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(F,H,L,j);h(F,H,null,j)}else if(H==null||H===""||!P(F))q(F,j);else BJ(F,j,P(F));H=j}return H}function _(F,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let KQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let TJ=G(O)===F;if(!k&&!I)TJ?BJ(F,A,O):q(F,A,H);else TJ&&X(F,O)}else k=!0}}else q(F,A,H);return[A]}function a(F,j,H){for(let L=0,A=j.length;LH.children=B(F,j.children,H.children));return JJ(()=>j.ref&&j.ref(F)),JJ(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(F,A,k,H[A]),H[A]=k}}),H}return{render(F,j){let H;return tJ((L)=>{H=L,V(j,F())}),H},insert:V,spread(F,j,H){if(typeof j==="function")JJ((L)=>IJ(F,j(),L,H));else IJ(F,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(F,j,H,L){return z(F,j,H,L),H},mergeProps:S1,effect:JJ,memo:_6,createComponent:L6,use(F,j,H){return QJ(()=>F(j,H))}}}function S6(J){let Q=k6(J);return Q.mergeProps=S1,Q}var b1=480,g1=272,KJ={view:0,text:1,image:2},b6=1,g6=-1,w6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},C6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},E6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},N6=1,UQ=2,RQ=1,PQ=2,DQ=131072,VQ=1,LQ=262144,OQ=1,IQ=1,AQ=1,_Q=2,kQ=4,SQ=8,bQ=16,gQ=1,wQ=2;function w1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var CQ=1,h6=1263551300,T6=1,f6=32,y6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},FJ=32896,EQ=0.016666666666666666;function C1(J){return J.__viewport??null}var C0=null;function x6(){return null}function E1(J,Q=x6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function v6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return E1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return E1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function m6(J){C0=J}function gJ(){if(!C0)throw Error("PocketJS: host not installed — call render() first");return C0}function E(){return gJ().ops}function u6(J){globalThis.frame=J}function l6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function c6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return w1($>>>16&255,$>>>8&255,$&255,255);return w1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function p6(J,Q){let $=C6[J];if(typeof Q==="string"){if($===U.color)return c6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var $0=60,N1=[1,2,3,4,5,6,10,12,15,20,30,60],E0=$0,qJ=-1,d6=0,xJ=[];function i6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=N1[0];for(let $ of N1)if(Math.abs($-J)Q.at<=qJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>qJ);for(let Q of J)Q.cb()}var N0=0.12,Z0=FJ;function o6(J){Z0=J===void 0?FJ:J&65535}function n6(){Z0=FJ}function f1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function e6(){return f1(Z0&255)}var y1=new Set,J8=0;function Q8(){y1.clear(),J8=0,n6()}function $8(J){for(let Q of[...y1])Q(J)}var MJ=null,x1=null;function Z8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function v1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){h0();let Q=MJ?MJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return x1.slice(Q.off,Q.off+Q.len)}var mJ=null,w=null,UJ=null,q0=0,RJ=[],f0=[],y0=[];function u1(J){if(mJ=J,w=null,UJ=null,q0=0,RJ.length=0,f0.length=0,y0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function X8(J,Q){J.onPress=Q??void 0}function Y8(J,Q){if(J.focusable=Q,i1(),!Q&&w===J)x(null)}function x(J){if(UJ&&UJ!==J)PJ(null);w=J,E().setFocus(J?J.id:0)}function PJ(J){if(UJ===J)return;let Q=E();if(UJ)Q.setActive?.(UJ.id,0);if(UJ=J,J)Q.setActive?.(J.id,1)}function x0(){return RJ.length>0?RJ[RJ.length-1]:mJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function G8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=f0.length-1;Q>=0;Q--){let $=f0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function H8(J){let Q=G8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(w)x(null);return!0}let Z=Q.columns,q=w?$.indexOf(w):-1;if(q<0)return x(l1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function B8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=y0.length-1;Q>=0;Q--){let $=y0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function X0(J){let Q=B8();if(Q&&Q.move(J))return;if(H8(J))return;W8(J)}function c1(){p1(w)}function p1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){PJ(J)}function j8(J){x(J),p1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=m0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,d1=0;function i1(){d1++}var F8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],M8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function U8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=F8[Q]>>$&1,q=M8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function R8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):P8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(U8(),16,16,E6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function P8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&N6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var W0=null;function s1(J){W0=J}function a1(J){let Q=RJ.length>0?RJ[RJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function r1(J,Q,$){return a1(o1(J,Q,$))}function o1(J,Q,$){if($!==void 0)return $===0?null:z0(W0??mJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(W0??mJ,q(J,Q))}function D8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=C1(q);if(Z.vw=B?B.w:b1,Z.vh=B?B.h:g1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)R8(Z,q);let X=t6()*Z.speed,z=e6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=s6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=d1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=a1(z0(W0??mJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==w)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(PJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,PJ(null),B)c1()}}else if($&Z.button)PJ(null);return!0}function V8(J){let Q=J&~q0,$=q0&~J;if(q0=J,l&&D8(J,Q,$))return;if($&d.CIRCLE)PJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)PJ(w),c1()}var u0=null;function n1(J){u0=J}function wJ(){if(i1(),u0)u0()}function L8(J,Q){J.debugName=Q||void 0,wJ()}var XJ={id:b6,type:KJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},t1=Symbol.for("pocketjs.native-node"),l0=1,uJ=3,o=8,O8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function G0(J){return J.domAttrs??={}}function e1(J,Q){let $=J.domNodeType??(lJ(J)?uJ:l0),Z=$===uJ?H0(J.text??""):$===o?_8(J.domData??""):Y4(J.domTag??j0(J));for(let q of Object.keys(J.domAttrs??{}))c0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)YJ(Z,e1(q,!0));return Z}function c0(J,Q,$){if(O8.has(Q)){EJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete G0(J)[Q];else G0(J)[Q]=$}function p0(J){if(J[t1]===!0)return J;return Object.defineProperty(J,t1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(lJ(J)?uJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(lJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(lJ(J))B0(J,Z);else if(E8(J),Z)YJ(J,H0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return W4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??j0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===uJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??j0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){EJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===XJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return YJ(J,$),$},insertBefore($,Z){return YJ(J,$,Z??null),$},removeChild($){return cJ(J,$),$},replaceChild($,Z){return YJ(J,$,Z),cJ(J,Z),Z},cloneNode($=!1){return e1(J,!!$)},remove(){if(J.parent)cJ(J.parent,J)},setAttribute($,Z){c0(J,$,Z)},removeAttribute($){c0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}p0(XJ);var d0=null;function I8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},J4=new Map;function Q4(J,Q){J4.set(J,Q)}var $4=new Map;function Z4(J,Q){$4.set(J,Q)}var CJ=new Set,A8=new Set;function q4(J){if(!J)return!1;if(A8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return p0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function H0(J){let Q=E(),$=Q.createNode(KJ.text);return Q.setText($,J),p0({id:$,type:KJ.text,parent:null,children:[],text:J,domNodeType:uJ,domTag:"#text"})}function _8(J=""){let Q=H0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){E().replaceText(J.id,Q),J.text=Q,wJ()}function lJ(J){return J.type===KJ.text}function z4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function YJ(J,Q,$){let Z=E();if(z4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function cJ(J,Q){if(!Q)return;K8(Q),E().removeChild(J.id,Q.id),z4(Q),CJ.add(Q),wJ()}function k8(J){return J.parent??void 0}function S8(J){return J.children[0]}function W4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function b8(J,Q){let $=E();if(wJ(),Q==null||Q===""){$.setStyle(J.id,g6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function g8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=J4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function w8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=$4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function C8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=w6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,p6(G,P)),z=!0}if(z)wJ()}function EJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete G0(J)[Q];else G0(J)[Q]=$;switch(Q){case"class":return b8(J,$),$;case"onPress":case"on:press":return X8(J,$),$;case"src":return g8(J,$),$;case"sprite":return w8(J,$),$;case"style":return C8(J,$,Z),$;case"focusable":return Y8(J,!!$),$;case"debugName":return L8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${j0(J)}>`)}function E8(J){for(let Q of[...J.children])cJ(J,Q)}function j0(J){for(let Q of Object.keys(KJ))if(KJ[Q]===J.type)return Q;return String(J.type)}function N8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}EJ(J,Q,$,Z)}var h8=S6({createElement:Y4,createTextNode:H0,replaceText:B0,isTextNode:lJ,setProperty:N8,insertNode(J,Q,$){YJ(J,Q,$)},removeNode(J,Q){cJ(J,Q)},getParentNode:k8,getFirstChild:S8,getNextSibling:W4}),{render:T8,effect:NQ,memo:c,createComponent:Y,createElement:G4,insert:hQ,spread:f8,mergeProps:TQ,use:fQ}=h8,yQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},y8=null;function H4(J){y8=J}function x8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function B4(J,Q){let $=G4(J);return f8($,Q,!1),x8(Q.nodeRef,$),$}function M(J){return B4("view",J)}function R(J){return B4("text",J)}var xQ=new WeakMap,vQ=new WeakMap,v8={}!==null?Object.freeze({...{}}):Object.freeze({}),mQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:v8}),uQ=new Map,zJ=36000,s0=30,m8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(zJ),tapeAnalog:new Uint16Array(zJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function u8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-s0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)n1(()=>{W.treeDirty=!0}),r8();else n1(null);globalThis.__pocketDevtools=n8}function l8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)p8(),s8();let X=Q,z=$===void 0?FJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(zJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==FJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function F4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function M4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return F4(J.masks,0,Q)}function U4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return F4(J.analog??[],FJ,Q)}function R4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,f({t:"hello",app:W.app,host:o8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` +`))if(q.trim())d8(q)}}function d8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)f({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),a0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":P4();break;case"eval":{let Z=!0,q;try{q=K0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}f({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":f({t:"tape",tape:K4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}f({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())f({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else f({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=M4(Z),W.replayAnalog=Z.analog?U4(Z):null,W.replayTouch=Z.touch?R4(Z):null,W.replayAt=0;break}default:break}}function i8(){if(W.treeDirty&&W.frame-W.treeSentAt>=s0)P4();if(W.frame%m8===0)a0()}function s8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,f({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,f({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){f({t:"stats",frame:W.frame,nodes:L4(XJ),tapeLen:W.tapeLen,paused:W.paused})}function P4(){W.treeDirty=!1,W.treeSentAt=W.frame,f({t:"tree",frame:W.frame,root:V4(XJ)})}function a8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(a8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function D4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function V4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(D4(J,(q)=>{if(q.domNodeType===8)return;Z.push(V4(q))}),Z.length)Q.k=Z;return Q}function L4(J){let Q=1;return D4(J,($)=>{Q+=L4($)}),Q}function r8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{f({t:"log",level:$,args:q.map((X)=>K0(X))}),Z?.apply(Q,q)}}}function K0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?O4(X):JSON.stringify(O4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>K0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${K0(z,Q+1)}`).join(", ")}}`}function O4(J){return J.length>200?J.slice(0,199)+"…":J}function o8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var n8={get frame(){return W.frame},dumpTape:()=>K4(),replay:(J)=>{W.replayMasks=M4(J),W.replayAnalog=J.analog?U4(J):null,W.replayTouch=J.touch?R4(J):null,W.replayAt=0}},I4=new Map,o0=new Map;function A4(J){return J.trim().replace(/\s+/g," ")}function _4(J){return J.split(" ").sort().join(" ")}var k4=-1;function t8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=A4(Q);I4.set(Z,$);let q=_4(Z),X=o0.get(q);o0.set(q,X!==void 0&&X!==$?k4:$)}}function e8(J){let Q=A4(J),$=I4.get(Q);if($!==void 0)return $;let Z=o0.get(_4(Q));return Z===k4?void 0:Z}var n0=9,J2=(1<{let q=($&$2)!==0,X=q?t0:n0,z=q?Z2:J2;return Object.freeze({id:$>>>(q?q2:Q2)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Y2(){return F0}function z2(){F0=e0}var S4=8,WJ=8,W2=3,G2=8,H2=6,B2=0.5,s=1,pJ=2,J1=4,DJ=8,NJ=[],b4=0,M0=0,GJ=Array.from({length:S4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(WJ),histY:new Int16Array(WJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function j2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function K2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=o1(Q,$,Z.fact);let G=Z.hit;if(G)return j2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=NJ[z];if(G.disposed)continue;if(b4>0&&!G.opts.allowWhenBlocked)continue;if(!K2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function U2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%WJ,J.histLenz||Z>z))q.flags[J.slot]|=pJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(pJ|J1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??B2)*h1()));if(J.frames=0)NJ.splice($,1)},cancel(){if(!Q.disposed)C4(Q)},get panning(){for(let $ of GJ)if($.used&&Q.flags[$.slot]&DJ)return!0;return!1}}}function L2(J){let Q=V2(J);return S0(()=>Q.dispose()),Q}function E4(){NJ.length=0,b4=0,M0=0;for(let J of GJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function O2(){return L2({onDown:(J)=>{let Q=r1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=r1(J.x,J.y,J.hit);if(Q)j8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var I2=1,Q1=new Map,U0=[];function A2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function _2(){I2=1,Q1.clear(),U0=[]}function k2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),A2()?.({t:"delivery",frame:T1(),id:Q,kind:Z.kind}),Z.onResult($)}}var N4=new Set;function S2(){if(N4.size===0)return;for(let J of N4)J()}var b2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[28] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-base text-orange-600 font-bold":9,"h-[76] pt-3 text-lg text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-base text-emerald-700 font-bold":13,"h-[84] pt-3 text-lg text-slate-900":14,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":15,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":16,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":17,"text-base text-slate-600 font-bold":18,"pt-6 text-lg text-slate-500":19,"pt-6 text-lg text-slate-900 font-bold":20,"h-[146] px-6 pt-7 flex-col bg-slate-50":21,"h-[80]":22,"h-[1060] px-6 pt-5 flex-col":23,"h-[48] px-4 justify-center bg-slate-100":24,"text-base text-slate-600":25,"pt-[10] flex-col gap-[12]":26,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":27,"w-[48] h-[48] items-center justify-center bg-blue-100":28,"w-[48] h-[48] items-center justify-center bg-emerald-100":29,"text-lg text-blue-700 font-bold":30,"text-lg text-emerald-700 font-bold":31,"w-[474] flex-col gap-2":32,"text-lg text-slate-900 font-bold":33,"text-base text-slate-500":34,"pt-20 pl-10 text-lg text-slate-500":35,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":36,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":37,"h-[1060] px-6 pt-7 flex-col gap-4":38,"text-base text-slate-500 font-bold":39,"h-[214] px-7 items-center justify-center bg-slate-100":40,"text-lg text-slate-500 font-bold":41,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":42,"flex-row items-center gap-5":43,"w-[68] h-[68] items-center justify-center bg-orange-100":44,"text-xl text-orange-700 font-bold":45,"w-[500] flex-col gap-2":46,"text-xl text-slate-900 font-bold":47,"text-lg text-slate-600":48,"text-2xl text-orange-600":49,"mt-4 h-[112] px-6 justify-center bg-slate-100":50,"relative h-[154] px-5 pt-5 flex-col bg-white":51,"pt-3 text-lg text-orange-600 font-bold":52,"pt-3 text-base text-slate-500":53,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":54,"text-lg text-white font-bold":55,"h-[40] pt-3 text-base text-slate-500":56,"h-[470] flex-col gap-2":57,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":58,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":59,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":60,"h-[160] px-5 pt-5 flex-col bg-white":61,"pt-3 text-lg text-slate-900 font-bold":62,"pt-3 text-base text-slate-600":63,"h-[108] pt-7 flex-row gap-4":64,"w-[316] h-[80] items-center justify-center bg-slate-100":65,"w-[340] h-[80] items-center justify-center bg-red-100":66,"text-lg text-red-500 font-bold":67,"h-[1052] px-6 pt-5 flex-col":68,"h-[270] px-[22] pt-6 bg-white":69,"text-lg text-slate-900":70,"text-lg text-slate-400":71,"h-[86] px-1 flex-row items-center justify-between":72,"w-[132] h-[58] items-center justify-center bg-slate-300":73,"w-[132] h-[58] items-center justify-center bg-slate-100":74,"text-base text-slate-900 font-bold":75,"h-[140] flex-row gap-2":76,"grow h-[120] items-center justify-center bg-slate-300":77,"grow h-[120] items-center justify-center bg-white":78,"w-[104] h-[120] items-center justify-center bg-slate-300":79,"w-[104] h-[120] items-center justify-center bg-slate-100":80,"h-[176] flex-row gap-2":81,"w-[92] h-[156] items-center justify-center bg-slate-300":82,"w-[92] h-[156] items-center justify-center bg-slate-100":83,"w-[300] h-[156] items-center justify-center bg-slate-300":84,"w-[300] h-[156] items-center justify-center bg-slate-100":85,"w-[144] h-[156] items-center justify-center bg-slate-300":86,"w-[144] h-[156] items-center justify-center bg-slate-100":87,"w-[112] h-[156] items-center justify-center bg-emerald-700":88,"w-[112] h-[156] items-center justify-center bg-emerald-500":89,"text-base text-slate-950 font-bold":90,"h-[108] px-6 py-3 flex-col bg-slate-50":91,"h-[84] items-center justify-center bg-slate-300":92,"h-[84] items-center justify-center bg-slate-100":93,"h-[1168] px-6 pt-5 flex-col":94,"h-[82] px-4 justify-center bg-white":95,"w-[584] h-[900] px-5 pt-5 bg-slate-950":96,"text-base text-slate-200":97,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":98,"text-lg text-orange-600 font-bold":99,"w-[584] h-[900] px-5 pt-5 bg-white":100,"text-base text-slate-900":101,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":102,"absolute inset-0 z-50 flex-col items-center justify-center":103,"absolute inset-0 bg-slate-950":104,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":105,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":106,"flex-row flex-wrap":107,grow:108,"text-2xl text-white font-bold":109,"text-2xl text-slate-950 font-bold":110,"px-6":111,"px-6 py-5":112,"gap-4":113,"rounded-xl shadow bg-white border-slate-100":114,"rounded-xl shadow bg-emerald-100 border-emerald-500":115,"bg-white":116,"bg-slate-100":117,"bg-slate-950":118,"px-3 py-2 rounded-lg bg-slate-100":119,"px-3 py-2 rounded-lg bg-indigo-100":120,"text-base text-indigo-700 font-bold":121,"px-3 py-2 rounded-lg bg-emerald-100":122,"px-3 py-2 rounded-lg bg-amber-100":123,"text-base text-amber-700 font-bold":124,"px-3 py-2 rounded-lg bg-red-100":125,"text-base text-red-500 font-bold":126,"w-[34] h-[34] rounded-lg bg-amber-400":127,"w-[34] h-[34] rounded-lg bg-red-500":128,"w-[34] h-[34] rounded-lg bg-slate-800":129,"w-[34] h-[34] rounded-lg bg-emerald-500":130,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":131,"flex-row items-center gap-4":132,"w-[34] text-2xl text-white font-bold":133,"w-[332] flex-col items-end gap-2":134,"text-base text-slate-300 font-bold":135,"text-base text-slate-400":136,"h-[166] px-6 pt-6 flex-col gap-3":137,"h-[44] px-1 flex-row items-center justify-between":138,"w-full h-full items-center justify-center rounded-xl bg-slate-200":139,"w-full h-full items-center justify-center rounded-xl bg-red-100":140,"w-full h-full items-center justify-center rounded-xl bg-slate-100":141,"w-full h-full items-center justify-center rounded-xl bg-orange-600":142,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":143,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":144,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":145,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":146,"text-2xl text-indigo-700 font-bold":147,"text-2xl text-slate-600 font-bold":148,"pt-7 text-2xl text-slate-900 font-bold":149,"pt-4 text-lg text-slate-500":150,"text-xl text-emerald-600 font-bold":151,"text-xl text-red-500 font-bold":152,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":153,"text-base text-red-300":154,"text-base text-slate-300":155,"text-base text-red-500":156,"w-full h-full px-6 flex-row items-center bg-slate-950":157,"w-full h-full flex-row items-center":158};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var g2="ui:styles",w2="ui:font.",h4="ui:img.",T4="ui:sprite.";function C2(){return globalThis.ui}function E2(J){if(J.__textures)return;for(let Q of T0(h4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)Q4(Q.slice(h4.length),Z)}}function N2(J){if(J.__sprites)return;for(let Q of T0(T4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)Z4(Q.slice(T4.length),{handle:V,frames:G,cols:P,step:D})}}function f4(J){let Q=G4("view");return EJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function h2(J,Q){if(!R0||!P0)return;EJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),EJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function T2(J,Q={}){let $=v6(Q.ops);if(m6($),I8(e8),Q.styles)t8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)Q4(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)Z4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)m1(Q.pak);if(q8()){for(let B of T0())if(B===g2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(w2))$.ops.loadFontAtlas?.(vJ(B))}}let q=C1($.ops),X=q?.w??b1,z=q?.h??g1,G=f4({width:X,height:z,overflow:u.Overflow.Hidden}),P=f4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});YJ(XJ,G),YJ(XJ,P),H4(P),R0=G,P0=P,u1(G),s1(XJ),Q8(),E4(),O2(),a6(),_2(),u8($.ops),u6(l8((B,_,N,h)=>{r6(),o6(_),X2(N,h),S2(),k2(),D2(),$8(B),V8(B),X4()}));let D=T8(J,G),V=l6(h2);return()=>{V(),z2(),E4(),D(),u1(null),s1(null),H4(null),R0=null,P0=null;for(let B of XJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);X4()}}function f2(J,Q={}){let $=Q.ops??C2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)m1(Q.pak);return E2($),N2($),T2(J,{ops:$,styles:Q.styles??b2,pak:Q.pak})}var y2="$b",x2=65536,y4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function u2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function x4(){let J=u2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function l2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,x2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=v2(z.data[y2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function c2(J,Q){let $=l2(x4(),J);return Q==="utf8"||Q==="utf-8"?m2($):$}function p2(J,Q){let $=x4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var d2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"};function i2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(M,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(M,{class:"flex-row items-center gap-4",get children(){return[c(()=>c(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(M,{get["class"](){return Q()}})),Y(R,{get["class"](){return d2.appTitle},get children(){return J.title}})]}}),Y(M,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function s2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(M,{get["class"](){return Q()},get children(){return Y(R,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(M,{get["class"](){return J.top},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(M,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var lQ="‘’“”–—…•",v4=new Map,m4=new Map,a2=512;function D0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=v4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return v4.set($,q),q}function r2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=D0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function $1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=m4.get(Z);if(q)return q;let X=[],z=D0(" ",Q);for(let G of J.split(` +`)){let P=G.split(" ").flatMap((B)=>B&&D0(B,Q)>$?r2(B,Q,$):[B]),D="",V=0;for(let B of P){let _=D0(B,Q);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return m4.set(Z,X),X}function Z1(J,Q,$,Z){let q=J.slice(0,a2),X=$1(q,Q,$);if(q.length===J.length&&X.length<=Z)return X.join(` `);let z=X.slice(0,Z),G=z.length-1;return z[G]=z[G].replace(/[\s.]+$/,"")+"…",z.join(` -`)}var q1=3,u4=2,X1=536,l4=544,p4=39,[RJ,o2]=g({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[y,n]=g("chat"),[Y1,n2]=g("chat"),[z1,c4]=g(0),[PJ,d4]=g(""),[sJ,hJ]=g(0),[aJ,W1]=g([]),[t2,V0]=g(""),[i4,L0]=g(null),[s4,a4]=g(null),[O0,I0]=g(0),[v,t]=g(""),[DJ,r4]=g("letters"),[G1,H1]=g(!1),[j1,o4]=g({type:"prompt"}),[WJ,n4]=g(null),[rJ,t4]=g(0),e4=new Map,J6=["qwertyuiop","asdfghjkl","zxcvbnm"],Q6=["1234567890","-/:;()$&@",`.,?!'"+`],$6=["chat","files","apps","settings"];function e2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function JQ(J,Q){return J?J+"/"+Q:Q}function A0(J=PJ(),Q=!1){let $=e4.get(J);if(!Q&&$){W1($),V0(""),hJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=c2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));e4.set(J,Z),W1(Z),V0(""),hJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){W1([]),V0(Z instanceof Error?Z.message:String(Z))}}function QQ(){let J=[];for(let Q of RJ().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Z6(){let J=QQ(),Q=Math.max(0,J.length-2),$=Math.min(z1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function VJ(J){return Y(i2,{get title(){return J.title},get accent(){return p(()=>RJ().agent==="FAULTED")()?"danger":RJ().agent==="THINKING"?"busy":"ready"}})}function _0(){return Y(F,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(SJ,{each:$6,children:(J)=>Y(F,{get["class"](){return Y1()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function $Q(){let J=()=>RJ().schedule,Q=()=>{let $=J();return Z1(String($?.name)+" "+String($?.next??"")+` +`)}var q1=3,u4=2,X1=536,l4=544,c4=39,[n,o2]=g({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[y,t]=g("chat"),[Y1,n2]=g("chat"),[z1,p4]=g(0),[VJ,d4]=g(""),[sJ,hJ]=g(0),[aJ,W1]=g([]),[t2,V0]=g(""),[i4,L0]=g(null),[s4,a4]=g(null),[O0,I0]=g(0),[v,e]=g(""),[LJ,r4]=g("letters"),[G1,H1]=g(!1),[B1,o4]=g({type:"prompt"}),[HJ,n4]=g(null),[rJ,t4]=g(0),e4=new Map,J6=["qwertyuiop","asdfghjkl","zxcvbnm"],Q6=["1234567890","-/:;()$&@",`.,?!'"+`],$6=["chat","files","apps","settings"];function e2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function JQ(J,Q){return J?J+"/"+Q:Q}function A0(J=VJ(),Q=!1){let $=e4.get(J);if(!Q&&$){W1($),V0(""),hJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=p2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));e4.set(J,Z),W1(Z),V0(""),hJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){W1([]),V0(Z instanceof Error?Z.message:String(Z))}}function QQ(){let J=[];for(let Q of n().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Z6(){let J=QQ(),Q=Math.max(0,J.length-2),$=Math.min(z1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function OJ(J){return Y(i2,{get title(){return J.title},get accent(){return c(()=>n().agent==="FAULTED")()?"danger":n().agent==="THINKING"?"busy":"ready"}})}function _0(){return Y(M,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(jJ,{each:$6,children:(J)=>Y(M,{get["class"](){return Y1()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function $Q(){let J=()=>n().schedule,Q=()=>{let $=J();return Z1(String($?.name)+" "+String($?.next??"")+` -`+String($?.prompt??""),q1,X1,5)};return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"ESP32 PI AGENT"}),Y(F,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(SJ,{get each(){return Z6()},children:($)=>Y(F,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-base text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-lg text-slate-900",get children(){return Z1($.user,q1,X1,3)}}),Y(F,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(F,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(F,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-base text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-lg text-slate-900",get children(){return Z1($.assistant,q1,X1,3)}})]}})}),Y(iJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(F,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-base text-slate-600 font-bold",children:"NEXT WAKE"}),Y(bJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-lg text-slate-500",children:`NO WAKE SCHEDULED +`+String($?.prompt??""),q1,X1,5)};return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"ESP32 PI AGENT"}),Y(M,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(jJ,{get each(){return Z6()},children:($)=>Y(M,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(M,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(M,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-base text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-lg text-slate-900",get children(){return Z1($.user,q1,X1,3)}}),Y(M,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(M,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(M,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-base text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-lg text-slate-900",get children(){return Z1($.assistant,q1,X1,3)}})]}})}),Y(iJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(M,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-base text-slate-600 font-bold",children:"NEXT WAKE"}),Y(ZJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-lg text-slate-500",children:`NO WAKE SCHEDULED -ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(R,{class:"pt-6 text-lg text-slate-900 font-bold",get children(){return Q()}})}})]}}),Y(F,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(F,{class:"h-[80]",get children(){return Y(s2,{label:"TYPE A MESSAGE"})}})}}),Y(_0,{})]}})}function ZQ(){let J=()=>aJ().slice(sJ(),sJ()+8);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return PJ()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",get children(){return"/workspace"+(PJ()?"/"+PJ():"")}})}}),Y(F,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(SJ,{get each(){return J()},children:(Q)=>Y(F,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(F,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-lg text-blue-700 font-bold":"text-lg text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(F,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,52)}}),Y(R,{class:"text-base text-slate-500",get children(){return p(()=>Q.kind==="dir")()?"FOLDER":e2(Q.size)}})]}})]}})})}}),Y(bJ,{get when(){return aJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-lg text-slate-500",get children(){return t2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(bJ,{get when(){return aJ().length>8},get children(){return Y(iJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(_0,{})]}})}function qQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"APPS"}),Y(F,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-base text-slate-500 font-bold",children:"2 INSTALLED APPS"}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-emerald-100",get children(){return Y(R,{class:"text-xl text-emerald-700 font-bold",children:"R"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Robinhood"}),Y(R,{class:"text-lg text-slate-600",children:"Portfolio and positions"}),Y(R,{class:"text-base text-slate-500",children:"UPDATES EVERY 5 MINUTES"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(F,{class:"flex-row items-center gap-5",get children(){return[Y(F,{class:"w-[68] h-[68] items-center justify-center bg-indigo-100",get children(){return Y(R,{class:"text-xl text-indigo-700 font-bold",children:"E"})}}),Y(F,{class:"flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",children:"Exa Research"}),Y(R,{class:"text-lg text-slate-600",children:"Agent search history"}),Y(R,{class:"text-base text-slate-500",children:"STORED LOCALLY IN SQLITE"})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}}),Y(F,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",children:`APP DATA STAYS ISOLATED. -PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(_0,{})]}})}function XQ(){let J=()=>RJ().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(rJ(),rJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"SETTINGS"}),Y(F,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-lg text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return Z()}}),Y(F,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-lg text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-base text-slate-500",children:"AVAILABLE NETWORKS"}),Y(F,{class:"h-[470] flex-col gap-2",get children(){return[Y(bJ,{get when(){return $().length>0},get fallback(){return Y(F,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-500 font-bold",children:`NO NETWORK LIST YET +ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(R,{class:"pt-6 text-lg text-slate-900 font-bold",get children(){return Q()}})}})]}}),Y(M,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(M,{class:"h-[80]",get children(){return Y(s2,{label:"TYPE A MESSAGE"})}})}}),Y(_0,{})]}})}function ZQ(){let J=()=>aJ().slice(sJ(),sJ()+8);return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{get title(){return VJ()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(M,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",get children(){return"/workspace"+(VJ()?"/"+VJ():"")}})}}),Y(M,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(jJ,{get each(){return J()},children:(Q)=>Y(M,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(M,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-lg text-blue-700 font-bold":"text-lg text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(M,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,52)}}),Y(R,{class:"text-base text-slate-500",get children(){return c(()=>Q.kind==="dir")()?"FOLDER":e2(Q.size)}})]}})]}})})}}),Y(ZJ,{get when(){return aJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-lg text-slate-500",get children(){return t2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(ZJ,{get when(){return aJ().length>8},get children(){return Y(iJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(_0,{})]}})}function qQ(){let J=()=>n().apps??[];return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"APPS"}),Y(M,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-base text-slate-500 font-bold",get children(){return String(J().length)+" INSTALLED APPS"}}),Y(ZJ,{get when(){return J().length>0},get fallback(){return Y(M,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-500 font-bold",children:"NO OPTIONAL APPS INSTALLED"})}})},get children(){return Y(jJ,{get each(){return J()},children:(Q)=>Y(M,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(M,{class:"flex-row items-center gap-5",get children(){return[Y(M,{class:"w-[68] h-[68] items-center justify-center bg-orange-100",get children(){return Y(R,{class:"text-xl text-orange-700 font-bold",get children(){return Q.title.slice(0,1).toUpperCase()}})}}),Y(M,{class:"w-[500] flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return Q.title}}),Y(R,{class:"text-lg text-slate-600",get children(){return Q.description}}),Y(ZJ,{get when(){return Q.scheduleEveryMinutes},get children(){return Y(R,{class:"text-base text-slate-500",get children(){return"UPDATES EVERY "+String(Q.scheduleEveryMinutes)+" MINUTES"}})}})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}})})}}),Y(M,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",children:`APP DATA STAYS ISOLATED. +PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(_0,{})]}})}function XQ(){let J=()=>n().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(rJ(),rJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"SETTINGS"}),Y(M,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-lg text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return Z()}}),Y(M,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-lg text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-base text-slate-500",children:"AVAILABLE NETWORKS"}),Y(M,{class:"h-[470] flex-col gap-2",get children(){return[Y(ZJ,{get when(){return $().length>0},get fallback(){return Y(M,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-500 font-bold",children:`NO NETWORK LIST YET -TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(SJ,{get each(){return $()},children:(q)=>Y(F,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-base text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(bJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(iJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(F,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-lg text-slate-900 font-bold",get children(){return RJ().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-base text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(F,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(F,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(F,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-lg text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(_0,{})]}})}function YQ(){let J=()=>j1(),Q=()=>DJ()==="letters"?J6:Q6,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(F,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(F,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-base text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(F,{get["class"](){return WJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(SJ,{get each(){return Q()},children:(Z,q)=>Y(F,{class:"h-[140] flex-row gap-2",get children(){return[Y(SJ,{get each(){return Z.split("")},children:(X)=>Y(F,{get["class"](){return WJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return p(()=>!!G1())()?X.toUpperCase():X}})}})}),Y(bJ,{get when(){return q()===2},get children(){return Y(F,{get["class"](){return WJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(F,{class:"h-[176] flex-row gap-2",get children(){return[Y(F,{get["class"](){return WJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"123":"ABC"}})}}),Y(F,{get["class"](){return WJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"SPACE"})}}),Y(F,{get["class"](){return WJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return DJ()==="letters"?"SHIFT":". ?"}})}}),Y(F,{get["class"](){return WJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(R,{class:"text-base text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(F,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(F,{get["class"](){return WJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function zQ(){let J=()=>i4(),Q=()=>(J()?.text??"").split(` -`),$=()=>J()?.lineOffset??0;return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< FILE VIEWER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(R,{class:"text-base text-slate-200",get children(){return Q().slice($(),$()+39).join(` -`)}})}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function WQ(){let J=()=>s4(),Q=()=>$1(J()?.text??"",u4,l4);return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(VJ,{title:"< MESSAGE READER"}),Y(F,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(F,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(F,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-base text-slate-900",get children(){return Q().slice(O0(),O0()+p4).join(` -`)}})}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function GQ(){return Y(F,{class:"flex-col w-full h-full bg-slate-50",get children(){return p(()=>y()==="chat")()?Y($Q,{}):p(()=>y()==="files")()?Y(ZQ,{}):p(()=>y()==="apps")()?Y(qQ,{}):p(()=>y()==="settings")()?Y(XQ,{}):p(()=>y()==="keyboard")()?Y(YQ,{}):p(()=>y()==="viewer")()?Y(zQ,{}):Y(WQ,{})}})}function HQ(J){B6(()=>{if(n2(J),n(J),J==="files")A0()})}function q6(J,Q){let $=DJ()==="letters"?J6:Q6,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=q6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function BQ(J,Q){if(Q>=1164)return t(""),n(Y1()),"";if(J>=548&&Q>=402&&Q<=482)return t(""),"";let $=q6(J,Q);if($){let Z=DJ()==="letters"&&G1()?$.toUpperCase():$,q=j1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return t(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)r4(DJ()==="letters"?"numbers":"letters"),H1(!1);else if(J<=424){if(v())t(v()+" ")}else if(J<=576)if(DJ()==="letters")H1(!G1());else t(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=j1();if(t(""),r4("letters"),H1(!1),n(Y1()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}f2(()=>Y(GQ,{})),queueMicrotask(()=>A0("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return o2(JSON.parse(J)),""},pointerDown(J,Q){return n4(y()==="keyboard"?jQ(J,Q):null),""},pointerUp(){return n4(null),""},tap(J,Q){if(y()==="keyboard")return BQ(J,Q);if(y()==="viewer"){let $=i4();if(J<104&&Q<112)L0(null),n("files");else if($&&J>=620&&Q>=170&&Q<=340)L0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)L0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` -`).length-39),$.lineOffset+18)});return""}if(y()==="reader"){if(J<104&&Q<112)a4(null),I0(0),n("chat");else if(J>=620&&Q>=170&&Q<=340)I0(Math.max(0,O0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=$1(s4()?.text??"",u4,l4).length;I0(Math.min(Math.max(0,$-p4),O0()+18))}return""}if(Q>=1172)return HQ($6[Math.min(3,Math.floor(J/180))]),"";if(y()==="chat"){if(J>=620&&Q>=140&&Q<=272)c4(z1()+2);else if(J>=620&&Q>=624&&Q<=756)c4(Math.max(0,z1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=Z6()[$];if(Z){let q=Q>=140+$*320+150;a4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),I0(0),n("reader")}}else if(Q>=1070&&Q<=1150)o4({type:"prompt"}),t(""),n("keyboard");return""}if(y()==="files"){if(J<104&&Q<112&&PJ()){let $=PJ().split("/");$.pop();let Z=$.join("/");d4(Z),hJ(0),A0(Z)}else if(J>=620&&Q>=170&&Q<=340)hJ(Math.max(0,sJ()-4));else if(J>=620&&Q>=920&&Q<=1100)hJ(Math.min(Math.max(0,aJ().length-8),sJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=aJ()[sJ()+$];if(Z){let q=JQ(PJ(),Z.name);if(Z.kind==="dir")d4(q),hJ(0),A0(q);else try{L0({path:"/workspace/"+q,text:p2(q,"utf8"),lineOffset:0}),n("viewer")}catch(X){V0(X instanceof Error?X.message:String(X))}}}return""}if(y()==="apps"){if(Q>=162&&Q<324)return JSON.stringify({type:"navigate",app:"robinhood"});if(Q>=324&&Q<490)return JSON.stringify({type:"navigate",app:"exa"});return""}if(y()==="settings"){let $=RJ().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)t4(Math.max(0,rJ()-4));else if(J>=620&&Q>=650&&Q<=782)t4(Math.min(Math.max(0,$.length-5),rJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[rJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});o4({type:"wifi",ssid:q.ssid}),t(""),n("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); +TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(jJ,{get each(){return $()},children:(q)=>Y(M,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-base text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(ZJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(iJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(M,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-lg text-slate-900 font-bold",get children(){return n().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-base text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(M,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(M,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(M,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-lg text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(_0,{})]}})}function YQ(){let J=()=>B1(),Q=()=>LJ()==="letters"?J6:Q6,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(M,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(M,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-base text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(M,{get["class"](){return HJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(jJ,{get each(){return Q()},children:(Z,q)=>Y(M,{class:"h-[140] flex-row gap-2",get children(){return[Y(jJ,{get each(){return Z.split("")},children:(X)=>Y(M,{get["class"](){return HJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return c(()=>!!G1())()?X.toUpperCase():X}})}})}),Y(ZJ,{get when(){return q()===2},get children(){return Y(M,{get["class"](){return HJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(M,{class:"h-[176] flex-row gap-2",get children(){return[Y(M,{get["class"](){return HJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return LJ()==="letters"?"123":"ABC"}})}}),Y(M,{get["class"](){return HJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"SPACE"})}}),Y(M,{get["class"](){return HJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return LJ()==="letters"?"SHIFT":". ?"}})}}),Y(M,{get["class"](){return HJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(R,{class:"text-base text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(M,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(M,{get["class"](){return HJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function zQ(){let J=()=>i4(),Q=()=>(J()?.text??"").split(` +`),$=()=>J()?.lineOffset??0;return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"< FILE VIEWER"}),Y(M,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(M,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(R,{class:"text-base text-slate-200",get children(){return Q().slice($(),$()+39).join(` +`)}})}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function WQ(){let J=()=>s4(),Q=()=>$1(J()?.text??"",u4,l4);return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"< MESSAGE READER"}),Y(M,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(M,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-base text-slate-900",get children(){return Q().slice(O0(),O0()+c4).join(` +`)}})}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function GQ(){return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return c(()=>y()==="chat")()?Y($Q,{}):c(()=>y()==="files")()?Y(ZQ,{}):c(()=>y()==="apps")()?Y(qQ,{}):c(()=>y()==="settings")()?Y(XQ,{}):c(()=>y()==="keyboard")()?Y(YQ,{}):c(()=>y()==="viewer")()?Y(zQ,{}):Y(WQ,{})}})}function HQ(J){j6(()=>{if(n2(J),t(J),J==="files")A0()})}function q6(J,Q){let $=LJ()==="letters"?J6:Q6,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=q6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function jQ(J,Q){if(Q>=1164)return e(""),t(Y1()),"";if(J>=548&&Q>=402&&Q<=482)return e(""),"";let $=q6(J,Q);if($){let Z=LJ()==="letters"&&G1()?$.toUpperCase():$,q=B1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return e(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)r4(LJ()==="letters"?"numbers":"letters"),H1(!1);else if(J<=424){if(v())e(v()+" ")}else if(J<=576)if(LJ()==="letters")H1(!G1());else e(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=B1();if(e(""),r4("letters"),H1(!1),t(Y1()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}f2(()=>Y(GQ,{})),queueMicrotask(()=>A0("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return o2(JSON.parse(J)),""},pointerDown(J,Q){return n4(y()==="keyboard"?BQ(J,Q):null),""},pointerUp(){return n4(null),""},tap(J,Q){if(y()==="keyboard")return jQ(J,Q);if(y()==="viewer"){let $=i4();if(J<104&&Q<112)L0(null),t("files");else if($&&J>=620&&Q>=170&&Q<=340)L0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)L0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` +`).length-39),$.lineOffset+18)});return""}if(y()==="reader"){if(J<104&&Q<112)a4(null),I0(0),t("chat");else if(J>=620&&Q>=170&&Q<=340)I0(Math.max(0,O0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=$1(s4()?.text??"",u4,l4).length;I0(Math.min(Math.max(0,$-c4),O0()+18))}return""}if(Q>=1172)return HQ($6[Math.min(3,Math.floor(J/180))]),"";if(y()==="chat"){if(J>=620&&Q>=140&&Q<=272)p4(z1()+2);else if(J>=620&&Q>=624&&Q<=756)p4(Math.max(0,z1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=Z6()[$];if(Z){let q=Q>=140+$*320+150;a4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),I0(0),t("reader")}}else if(Q>=1070&&Q<=1150)o4({type:"prompt"}),e(""),t("keyboard");return""}if(y()==="files"){if(J<104&&Q<112&&VJ()){let $=VJ().split("/");$.pop();let Z=$.join("/");d4(Z),hJ(0),A0(Z)}else if(J>=620&&Q>=170&&Q<=340)hJ(Math.max(0,sJ()-4));else if(J>=620&&Q>=920&&Q<=1100)hJ(Math.min(Math.max(0,aJ().length-8),sJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=aJ()[sJ()+$];if(Z){let q=JQ(VJ(),Z.name);if(Z.kind==="dir")d4(q),hJ(0),A0(q);else try{L0({path:"/workspace/"+q,text:c2(q,"utf8"),lineOffset:0}),t("viewer")}catch(X){V0(X instanceof Error?X.message:String(X))}}}return""}if(y()==="apps"){let $=(n().apps??[])[Math.floor((Q-162)/166)];if(Q>=162&&$)return JSON.stringify({type:"navigate",app:$.id});return""}if(y()==="settings"){let $=n().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)t4(Math.max(0,rJ()-4));else if(J>=620&&Q>=650&&Q<=782)t4(Math.min(Math.max(0,$.length-5),rJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[rJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});o4({type:"wifi",ssid:q.ssid}),e(""),t("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); diff --git a/apps/pi-agent/dist/app.pak b/apps/pi-agent/dist/app.pak index bb30f3716a40c9f9a1d5f13ebbf057e15bc3db55..607743036938509f11e7f94c45a7a3e18d4699c4 100644 GIT binary patch delta 104 zcmcccL2SbZu?Z541`{Q>Gln!?Y`w_XdXcI1B6I6SmaP|AS(h@--+p~5>pqt0;cHke zr_Wl&8YA`p?bZK`ObHB!9C`jHGH^36FfcMR0?A*_)45i&norMP&H7?{_Zrrt+#Enr GFaQA6041FO delta 110 zcmdn+LF~c@u?Z540TU&+GuAX-Y`w_XdXcI1B6I6SmaP|AS(h>{+pqt0Cs(m1 zid_8l^gkn00s~7$`2R!(ZUzPhMyBa5t69yb^RH%==6~?~KUmt?;uJ`FdiiSBH`AxC NVzu0!v4-^kHvlDGEi(WB diff --git a/apps/robinhood/agent-app.json b/apps/robinhood/agent-app.json index a28fa9c..a184629 100644 --- a/apps/robinhood/agent-app.json +++ b/apps/robinhood/agent-app.json @@ -1,7 +1,21 @@ { "id": "robinhood", + "description": "Portfolio, positions, and trading", "version": "1.1.0", "dataVersion": 5, + "nativeServices": { + "mcp": [ + { + "connection": "robinhood", + "url": "https://agent.robinhood.com/mcp/trading", + "credential": { + "id": "robinhood.oauth-access-token", + "header": "authorization", + "prefix": "Bearer " + } + } + ] + }, "providerOperations": [ "add_option_to_watchlist", "add_to_watchlist", diff --git a/apps/robinhood/data-action.ts b/apps/robinhood/data-action.ts index cc19d3c..7db03bc 100644 --- a/apps/robinhood/data-action.ts +++ b/apps/robinhood/data-action.ts @@ -221,11 +221,20 @@ function validatedProviderCall(args: any): any { return invokeProviderTool(operation, providerArgs); } +function retryableOperation(name: string): boolean { + return name.startsWith("get_") || name.startsWith("review_") || name === "search" || name === "run_scan"; +} + function callTool(operation: string, args: any): any { const envelope = JSON.parse((globalThis as any).services.call( "mcp.client", "callTool", - JSON.stringify({ connection: "robinhood", name: operation, arguments: args }), + JSON.stringify({ + connection: "robinhood", + name: operation, + arguments: args, + retryable: retryableOperation(operation), + }), )); if (!envelope.ok) throw new Error(envelope.error || "Robinhood service failed"); return envelope.value; @@ -238,6 +247,7 @@ function callTools(calls: Array<{ operation: string; args: any }>): any[] { JSON.stringify({ connection: "robinhood", calls: calls.map((call) => ({ name: call.operation, arguments: call.args })), + retryable: calls.every((call) => retryableOperation(call.operation)), }), )); if (!envelope.ok) throw new Error(envelope.error || "Robinhood batch service failed"); diff --git a/apps/robinhood/dist/data-action.js b/apps/robinhood/dist/data-action.js index 9517546..5421c3d 100644 --- a/apps/robinhood/dist/data-action.js +++ b/apps/robinhood/dist/data-action.js @@ -163,7 +163,7 @@ Restrictions: - Cortex-managed scans (cortex_managed: true in get_scans) are rejected with a user-friendly error. - Returns an error and does not apply any change if any filter fails validation. -Returns the scan with its new filters and fresh live results. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan to modify. Get this from get_scans or create_scan. Cortex-managed scans (cortex_managed: true in get_scans output) are rejected."},filters:{type:["null","array"],items:{type:"object",properties:{filter_type:{type:"string",description:'Wire-format enum name, e.g. "FILTER_TYPE_RSI". See the scanner-filter-specs resource for valid values. Omit when supplying expression.'},predicate:{type:"string",description:'Wire-format enum name, e.g. "PREDICATE_GREATER_THAN". See the scanner-filter-specs resource for the predicates supported by each filter.'},values:{type:["null","array"],items:{type:"string"},description:'Threshold values. Single-element for unary predicates, two-element for BETWEEN, multi-element for IN_LIST/ANY_OF. For a boolean expression screen, exactly ["True"].'},interval:{type:"string",description:`Time granularity for time-series filters (e.g. "1d"). Use one of the supported_intervals from the filter's scanner-filter-specs entry. Not used with expression — encode granularity inside the expression.`},length:{type:"integer",description:"Lookback length for filters that need one (e.g. RSI period of 14). Use one of the supported_lengths from the filter's scanner-filter-specs entry. Not used with expression.",minimum:-2147483648,maximum:2147483647},plot:{type:"string",description:`Plot / price-field input for filters that have one (e.g. "open" or "close" for % Change). Use one of the supported_plots from the filter's scanner-filter-specs entry. Not used with expression.`},expression:{type:"string",description:'Raw market-data expression to screen on, e.g. "dayVolume / volumeAvg(candleCount=30, candlePeriod=\\"1d\\", session=\\"all\\")" with a numeric predicate, or a whole comparison like "tradeAllDay.price > closeAvg(candleCount=50, candlePeriod=\\"1d\\", session=\\"all\\")" with predicate "=" and values ["True"]. Only preview_scan accepts expressions. Omit filter_type when set. Prefer an enum filter_type whenever one covers the request.'},display_title:{type:"string",description:'Optional short label for an expression filter, shown as the results-column header (e.g. "Relative volume (30D)"). Only used with expression.'}},required:["predicate","values"],additionalProperties:!1},description:"The complete set of filters the scan should have after the update. REPLACE semantics — to add a filter, supply all existing filters plus the new one. To remove a filter, omit it from the array. To clear all filters, send []. Each filter: filter_type (FILTER_TYPE_... enum), predicate (>, <, =, BETWEEN, etc.), values, optional interval (e.g. 1d), optional length (e.g. 14 for RSI). Call get_scanner_filter_specs first for valid filter_type / predicate / interval / length combinations."}},required:["scan_id","filters"],additionalProperties:!1}},{name:"update_watchlist",namespace:"watchlists",description:"Rename a custom watchlist or change its icon/description. Robinhood-curated lists cannot be renamed; the call will fail with 404. Provide at least one of display_name, icon_emoji, display_description. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to update. Obtain from get_watchlists."},display_name:{type:"string",description:"New name for the watchlist."},icon_emoji:{type:"string",description:"New emoji."},display_description:{type:"string",description:"New description."}},required:["list_id"],additionalProperties:!1}}]};var q=globalThis.db,x=q.open("robinhood");if(x<0)throw Error("open robinhood.sqlite");var V=5;function F(){return String(q.lastError(x)||"SQLite operation failed")}function k(e){if(q.exec(x,e)!==0)throw Error(F())}function A(e,t=[]){let i=JSON.parse(q.query(x,e,JSON.stringify(t)));if(i.error)throw Error(String(i.error));return i}function y(e,t=[]){return A(e,t)}function I(e,t){if(!t.length)return;let i=t.map((d)=>"("+d.map(()=>"?").join(",")+")").join(","),r=[];for(let d of t)r.push(...d);y(e+" VALUES "+i,r)}var N=Number(A("PRAGMA user_version")?.rows?.[0]?.[0]??0);if(N!==V)k(` +Returns the scan with its new filters and fresh live results. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.`,inputSchema:{type:"object",properties:{scan_id:{type:"string",description:"The scan to modify. Get this from get_scans or create_scan. Cortex-managed scans (cortex_managed: true in get_scans output) are rejected."},filters:{type:["null","array"],items:{type:"object",properties:{filter_type:{type:"string",description:'Wire-format enum name, e.g. "FILTER_TYPE_RSI". See the scanner-filter-specs resource for valid values. Omit when supplying expression.'},predicate:{type:"string",description:'Wire-format enum name, e.g. "PREDICATE_GREATER_THAN". See the scanner-filter-specs resource for the predicates supported by each filter.'},values:{type:["null","array"],items:{type:"string"},description:'Threshold values. Single-element for unary predicates, two-element for BETWEEN, multi-element for IN_LIST/ANY_OF. For a boolean expression screen, exactly ["True"].'},interval:{type:"string",description:`Time granularity for time-series filters (e.g. "1d"). Use one of the supported_intervals from the filter's scanner-filter-specs entry. Not used with expression — encode granularity inside the expression.`},length:{type:"integer",description:"Lookback length for filters that need one (e.g. RSI period of 14). Use one of the supported_lengths from the filter's scanner-filter-specs entry. Not used with expression.",minimum:-2147483648,maximum:2147483647},plot:{type:"string",description:`Plot / price-field input for filters that have one (e.g. "open" or "close" for % Change). Use one of the supported_plots from the filter's scanner-filter-specs entry. Not used with expression.`},expression:{type:"string",description:'Raw market-data expression to screen on, e.g. "dayVolume / volumeAvg(candleCount=30, candlePeriod=\\"1d\\", session=\\"all\\")" with a numeric predicate, or a whole comparison like "tradeAllDay.price > closeAvg(candleCount=50, candlePeriod=\\"1d\\", session=\\"all\\")" with predicate "=" and values ["True"]. Only preview_scan accepts expressions. Omit filter_type when set. Prefer an enum filter_type whenever one covers the request.'},display_title:{type:"string",description:'Optional short label for an expression filter, shown as the results-column header (e.g. "Relative volume (30D)"). Only used with expression.'}},required:["predicate","values"],additionalProperties:!1},description:"The complete set of filters the scan should have after the update. REPLACE semantics — to add a filter, supply all existing filters plus the new one. To remove a filter, omit it from the array. To clear all filters, send []. Each filter: filter_type (FILTER_TYPE_... enum), predicate (>, <, =, BETWEEN, etc.), values, optional interval (e.g. 1d), optional length (e.g. 14 for RSI). Call get_scanner_filter_specs first for valid filter_type / predicate / interval / length combinations."}},required:["scan_id","filters"],additionalProperties:!1}},{name:"update_watchlist",namespace:"watchlists",description:"Rename a custom watchlist or change its icon/description. Robinhood-curated lists cannot be renamed; the call will fail with 404. Provide at least one of display_name, icon_emoji, display_description. This changes Robinhood account metadata but does not place a trade. Pocket Pi returns this result directly to the Agent and does not persist it, because the current fixed View does not consume this data.",inputSchema:{type:"object",properties:{list_id:{type:"string",description:"UUID of the watchlist to update. Obtain from get_watchlists."},display_name:{type:"string",description:"New name for the watchlist."},icon_emoji:{type:"string",description:"New emoji."},display_description:{type:"string",description:"New description."}},required:["list_id"],additionalProperties:!1}}]};var q=globalThis.db,x=q.open("robinhood");if(x<0)throw Error("open robinhood.sqlite");var F=5;function N(){return String(q.lastError(x)||"SQLite operation failed")}function k(e){if(q.exec(x,e)!==0)throw Error(N())}function A(e,t=[]){let i=JSON.parse(q.query(x,e,JSON.stringify(t)));if(i.error)throw Error(String(i.error));return i}function y(e,t=[]){return A(e,t)}function I(e,t){if(!t.length)return;let i=t.map((d)=>"("+d.map(()=>"?").join(",")+")").join(","),r=[];for(let d of t)r.push(...d);y(e+" VALUES "+i,r)}var Y=Number(A("PRAGMA user_version")?.rows?.[0]?.[0]??0);if(Y!==F)k(` CREATE TABLE IF NOT EXISTS accounts ( account_number TEXT PRIMARY KEY, label TEXT NOT NULL, @@ -222,18 +222,18 @@ Returns the scan with its new filters and fresh live results. This changes Robin ); CREATE INDEX IF NOT EXISTS refresh_runs_recent ON refresh_runs(id DESC); PRAGMA user_version=5; - `);var O=w.tools,Y=new Map(O.map((e)=>[e.name,e]));function b(){return Math.floor(Date.now()/1000)}function G(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function a(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let i of t){let r=G(e[i]);if(r!==null)return r}for(let i of Object.values(e)){let r=a(i,t);if(r!==null)return r}return null}function j(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let i of t)if(Array.isArray(e[i]))return e[i];for(let i of Object.values(e)){let r=j(i,t);if(r.length)return r}return[]}function B(e,t){let i=a(e,t)?.toLowerCase();return i==="true"||i==="1"||i==="yes"}function R(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function _(e,t){let i=t?.account_number;return i===null||i===void 0||i===""?a(e,["account_number","accountNumber","account"])||"":String(i)}function P(e,t){let i=j(e,t);return i.length?i:Array.isArray(e)?e:e?[e]:[]}function z(e){let t=Array.isArray(e?.names)?new Set(e.names.filter((s)=>typeof s==="string")):new Set,i=String(e?.query??"").toLowerCase().split(/[^a-z0-9_]+/).filter(Boolean),r=typeof e?.namespace==="string"?e.namespace:"";if(!t.size&&!i.length)throw Error("search_tools requires query or names");let d=Math.max(1,Math.min(8,Number(e?.limit??5)||5)),o=O.filter((s)=>!r||s.namespace===r).map((s)=>{let n=s.name.toLowerCase(),l=n+" "+s.description.toLowerCase(),c=t.has(s.name)?1000:i.reduce((u,p)=>u+(n===p?100:n.includes(p)?20:l.includes(p)?3:0),0);return{tool:s,score:c}}).filter((s)=>s.score>0).sort((s,n)=>n.score-s.score||s.tool.name.localeCompare(n.tool.name)).slice(0,d).map(({tool:s})=>({name:s.name,namespace:s.namespace,description:s.description,inputSchema:s.inputSchema}));return{source:w.source,protocolVersion:w.protocolVersion,matches:o}}function W(e,t){if(t==="null")return e===null;if(t==="array")return Array.isArray(e);if(t==="object")return e!==null&&typeof e==="object"&&!Array.isArray(e);if(t==="integer")return typeof e==="number"&&Number.isInteger(e);if(t==="number")return typeof e==="number"&&Number.isFinite(e);return typeof e===t}function U(e,t,i="arguments"){let r=Array.isArray(t?.type)?t.type:t?.type?[t.type]:[];if(r.length&&!r.some((o)=>W(e,o)))throw Error(i+" must be "+r.join(" or "));if(e===null)return;if(typeof e==="number"){if(typeof t.minimum==="number"&&et.maximum)throw Error(i+" exceeds maximum "+t.maximum)}if(Array.isArray(e)){if(t.items)e.forEach((o,s)=>U(o,t.items,i+"["+s+"]"));return}if(typeof e!=="object")return;let d=t.properties||{};for(let o of t.required||[])if(!(o in e))throw Error(i+"."+o+" is required");if(t.additionalProperties===!1){for(let o of Object.keys(e))if(!(o in d))throw Error(i+"."+o+" is not allowed")}for(let[o,s]of Object.entries(e))if(d[o])U(s,d[o],i+"."+o)}function H(e){let t=typeof e?.name==="string"?e.name:"",i=Y.get(t);if(!i)throw Error("Unknown Robinhood provider Tool: "+t);let r=e?.arguments;return U(r,i.inputSchema),ie(t,r)}function C(e,t){let i=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t})));if(!i.ok)throw Error(i.error||"Robinhood service failed");return i.value}function X(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((i)=>({name:i.operation,arguments:i.args}))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function v(e){k("BEGIN IMMEDIATE");try{e(),k("COMMIT")}catch(t){try{k("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function J(e,t){let i=P(e,["accounts"]);y("DELETE FROM accounts");let r=[];for(let d of i){let o=_(d,{});if(!o)continue;let s=(a(d,["nickname","account_type","type"])||"").toUpperCase(),n=B(d,["agentic_allowed","agenticAllowed"]),l=n?"AGENTIC":s.includes("IRA")||s.includes("RETIRE")?"RETIREMENT":s.includes("JOINT")?"JOINT":"PERSONAL";r.push([o,l,o.slice(-4),s,(a(d,["status"])||"active").toUpperCase(),n?1:0,t])}I("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at)",r)}function Z(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood portfolio is missing account_number");let d=a(e,["cash","cash_available","withdrawable_amount"]),o=a(e,["buying_power","buyingPower"]),s=a(e,["day_pnl","dayPnl","equity_change"]),n=a(e,["week_pnl","weekPnl"]);y(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) + `);var O=w.tools,G=new Map(O.map((e)=>[e.name,e]));function b(){return Math.floor(Date.now()/1000)}function B(e){return e===null||e===void 0||typeof e==="object"?null:String(e)}function a(e,t){if(e===null||e===void 0||typeof e!=="object")return null;for(let i of t){let r=B(e[i]);if(r!==null)return r}for(let i of Object.values(e)){let r=a(i,t);if(r!==null)return r}return null}function j(e,t){if(e===null||e===void 0||typeof e!=="object")return[];for(let i of t)if(Array.isArray(e[i]))return e[i];for(let i of Object.values(e)){let r=j(i,t);if(r.length)return r}return[]}function z(e,t){let i=a(e,t)?.toLowerCase();return i==="true"||i==="1"||i==="yes"}function R(e){if(e===null)return null;let t=Number(e.replace(/[$,%]/g,""));return Number.isFinite(t)?t:null}function _(e,t){let i=t?.account_number;return i===null||i===void 0||i===""?a(e,["account_number","accountNumber","account"])||"":String(i)}function P(e,t){let i=j(e,t);return i.length?i:Array.isArray(e)?e:e?[e]:[]}function W(e){let t=Array.isArray(e?.names)?new Set(e.names.filter((s)=>typeof s==="string")):new Set,i=String(e?.query??"").toLowerCase().split(/[^a-z0-9_]+/).filter(Boolean),r=typeof e?.namespace==="string"?e.namespace:"";if(!t.size&&!i.length)throw Error("search_tools requires query or names");let d=Math.max(1,Math.min(8,Number(e?.limit??5)||5)),o=O.filter((s)=>!r||s.namespace===r).map((s)=>{let n=s.name.toLowerCase(),l=n+" "+s.description.toLowerCase(),c=t.has(s.name)?1000:i.reduce((u,p)=>u+(n===p?100:n.includes(p)?20:l.includes(p)?3:0),0);return{tool:s,score:c}}).filter((s)=>s.score>0).sort((s,n)=>n.score-s.score||s.tool.name.localeCompare(n.tool.name)).slice(0,d).map(({tool:s})=>({name:s.name,namespace:s.namespace,description:s.description,inputSchema:s.inputSchema}));return{source:w.source,protocolVersion:w.protocolVersion,matches:o}}function H(e,t){if(t==="null")return e===null;if(t==="array")return Array.isArray(e);if(t==="object")return e!==null&&typeof e==="object"&&!Array.isArray(e);if(t==="integer")return typeof e==="number"&&Number.isInteger(e);if(t==="number")return typeof e==="number"&&Number.isFinite(e);return typeof e===t}function U(e,t,i="arguments"){let r=Array.isArray(t?.type)?t.type:t?.type?[t.type]:[];if(r.length&&!r.some((o)=>H(e,o)))throw Error(i+" must be "+r.join(" or "));if(e===null)return;if(typeof e==="number"){if(typeof t.minimum==="number"&&et.maximum)throw Error(i+" exceeds maximum "+t.maximum)}if(Array.isArray(e)){if(t.items)e.forEach((o,s)=>U(o,t.items,i+"["+s+"]"));return}if(typeof e!=="object")return;let d=t.properties||{};for(let o of t.required||[])if(!(o in e))throw Error(i+"."+o+" is required");if(t.additionalProperties===!1){for(let o of Object.keys(e))if(!(o in d))throw Error(i+"."+o+" is not allowed")}for(let[o,s]of Object.entries(e))if(d[o])U(s,d[o],i+"."+o)}function X(e){let t=typeof e?.name==="string"?e.name:"",i=G.get(t);if(!i)throw Error("Unknown Robinhood provider Tool: "+t);let r=e?.arguments;return U(r,i.inputSchema),re(t,r)}function C(e){return e.startsWith("get_")||e.startsWith("review_")||e==="search"||e==="run_scan"}function L(e,t){let i=JSON.parse(globalThis.services.call("mcp.client","callTool",JSON.stringify({connection:"robinhood",name:e,arguments:t,retryable:C(e)})));if(!i.ok)throw Error(i.error||"Robinhood service failed");return i.value}function J(e){let t=JSON.parse(globalThis.services.call("mcp.client","callTools",JSON.stringify({connection:"robinhood",calls:e.map((i)=>({name:i.operation,arguments:i.args})),retryable:e.every((i)=>C(i.operation))})));if(!t.ok)throw Error(t.error||"Robinhood batch service failed");return Array.isArray(t.value?.results)?t.value.results:[]}function v(e){k("BEGIN IMMEDIATE");try{e(),k("COMMIT")}catch(t){try{k("ROLLBACK")}catch{}throw t}globalThis.app.commit()}function Z(e,t){let i=P(e,["accounts"]);y("DELETE FROM accounts");let r=[];for(let d of i){let o=_(d,{});if(!o)continue;let s=(a(d,["nickname","account_type","type"])||"").toUpperCase(),n=z(d,["agentic_allowed","agenticAllowed"]),l=n?"AGENTIC":s.includes("IRA")||s.includes("RETIRE")?"RETIREMENT":s.includes("JOINT")?"JOINT":"PERSONAL";r.push([o,l,o.slice(-4),s,(a(d,["status"])||"active").toUpperCase(),n?1:0,t])}I("INSERT INTO accounts(account_number,label,suffix,account_type,status,agentic_allowed,updated_at)",r)}function $(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood portfolio is missing account_number");let d=a(e,["cash","cash_available","withdrawable_amount"]),o=a(e,["buying_power","buyingPower"]),s=a(e,["day_pnl","dayPnl","equity_change"]),n=a(e,["week_pnl","weekPnl"]);y(`INSERT INTO portfolio_current(account_number,cash,buying_power,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?,?,?) ON CONFLICT(account_number) DO UPDATE SET cash=excluded.cash,buying_power=excluded.buying_power, day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), - observed_at=excluded.observed_at`,[r,d,o,s,n,i]);let l=a(e,["total_value","equity","total_equity","portfolio_value","market_value"]);if(l!==null)y("INSERT OR REPLACE INTO total_value(account_number,observed_at,value) VALUES(?,?,?)",[r,i,l])}function $(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood positions are missing account_number");let d=P(e,["positions"]).slice(0,64);y("DELETE FROM positions WHERE account_number=?",[r]);let o=[];for(let s of d){let n=a(s,["symbol"]);if(!n)continue;o.push([r,n,a(s,["quantity","shares"]),a(s,["average_price","averagePrice","average_buy_price"]),a(s,["market_value","marketValue","equity"]),i])}I("INSERT INTO positions(account_number,symbol,quantity,average_price,market_value,observed_at)",o)}function Q(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood activities are missing account_number");let d=P(e,["orders","activities","results"]).slice(0,64);y("DELETE FROM activities WHERE account_number=?",[r]);let o=[];d.forEach((s,n)=>{let l=a(s,["symbol"]),c=(a(s,["side"])||"").toUpperCase(),u=a(s,["executed_quantity","cumulative_quantity","quantity"]),p=a(s,["average_price","averagePrice","executed_price","price"]),f=a(s,["last_transaction_at","created_at","updated_at","date"]),m=a(s,["id","order_id","orderId","activity_id"])||[f||i,l||"ORDER",c,n].join(":"),g=R(u),S=R(p),E=g!==null&&S!==null?String(g*S):p||u;o.push([r,m,f,i,l,c,u,p,E,(a(s,["state","status"])||"RECENT").toUpperCase(),(a(s,["type","order_type"])||"ORDER").toUpperCase()])}),I("INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type)",o)}function K(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood P&L is missing account_number");let d=a(e,["total_returns","realized_pnl","total","amount","day_pnl","week_pnl"]),o=String(t?.span??"day");y(`INSERT INTO portfolio_current(account_number,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?) + observed_at=excluded.observed_at`,[r,d,o,s,n,i]);let l=a(e,["total_value","equity","total_equity","portfolio_value","market_value"]);if(l!==null)y("INSERT OR REPLACE INTO total_value(account_number,observed_at,value) VALUES(?,?,?)",[r,i,l])}function Q(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood positions are missing account_number");let d=P(e,["positions"]).slice(0,64);y("DELETE FROM positions WHERE account_number=?",[r]);let o=[];for(let s of d){let n=a(s,["symbol"]);if(!n)continue;o.push([r,n,a(s,["quantity","shares"]),a(s,["average_price","averagePrice","average_buy_price"]),a(s,["market_value","marketValue","equity"]),i])}I("INSERT INTO positions(account_number,symbol,quantity,average_price,market_value,observed_at)",o)}function K(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood activities are missing account_number");let d=P(e,["orders","activities","results"]).slice(0,64);y("DELETE FROM activities WHERE account_number=?",[r]);let o=[];d.forEach((s,n)=>{let l=a(s,["symbol"]),c=(a(s,["side"])||"").toUpperCase(),u=a(s,["executed_quantity","cumulative_quantity","quantity"]),p=a(s,["average_price","averagePrice","executed_price","price"]),f=a(s,["last_transaction_at","created_at","updated_at","date"]),m=a(s,["id","order_id","orderId","activity_id"])||[f||i,l||"ORDER",c,n].join(":"),g=R(u),S=R(p),M=g!==null&&S!==null?String(g*S):p||u;o.push([r,m,f,i,l,c,u,p,M,(a(s,["state","status"])||"RECENT").toUpperCase(),(a(s,["type","order_type"])||"ORDER").toUpperCase()])}),I("INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type)",o)}function ee(e,t,i){let r=_(e,t);if(!r)throw Error("Robinhood P&L is missing account_number");let d=a(e,["total_returns","realized_pnl","total","amount","day_pnl","week_pnl"]),o=String(t?.span??"day");y(`INSERT INTO portfolio_current(account_number,day_pnl,week_pnl,observed_at) VALUES(?,?,?,?) ON CONFLICT(account_number) DO UPDATE SET day_pnl=COALESCE(excluded.day_pnl,portfolio_current.day_pnl), week_pnl=COALESCE(excluded.week_pnl,portfolio_current.week_pnl), - observed_at=MAX(portfolio_current.observed_at,excluded.observed_at)`,[r,o==="week"?null:d,o==="week"?d:null,i])}function L(e){if(e.operation==="get_accounts")J(e.value,e.observedAt);else if(e.operation==="get_portfolio")Z(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_positions")$(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_orders")Q(e.value,e.args,e.observedAt);else if(e.operation==="get_realized_pnl")K(e.value,e.args,e.observedAt);else return!1;return!0}function ee(e){let t=e.toLowerCase();return t.includes("esp_err_http_connect")||t.includes("timeout")||t.includes("tls")||t.includes("socket")||t.includes("network")}function T(){let e=b(),t=[],i=[],r=0,d=(n,l)=>{r+=1;try{let c=C(n,l);return t.push({operation:n,args:l,value:c,observedAt:b()}),c}catch(c){let u=c instanceof Error?c.message:String(c);if(i.push(n+": "+u),n==="get_accounts"||ee(u))throw c;return null}},o=null;try{let n=d("get_accounts",{}),c=P(n,["accounts"]).map((h)=>_(h,{})).filter(Boolean);if(!c.length)throw Error("Robinhood returned no brokerage accounts");let u=new Date((e-604800)*1000).toISOString().slice(0,10),p=[];for(let h of c){let m={account_number:h};p.push({operation:"get_portfolio",args:m},{operation:"get_equity_positions",args:m},{operation:"get_equity_orders",args:{...m,created_at_gte:u}},{operation:"get_realized_pnl",args:{...m,span:"day",asset_classes:["equity"]}},{operation:"get_realized_pnl",args:{...m,span:"week",asset_classes:["equity"]}})}r+=p.length;let f=X(p);if(f.length!==p.length)throw Error("Robinhood batch returned an incomplete result set");if(f.forEach((h,m)=>{let g=p[m];if(h?.ok)t.push({operation:g.operation,args:g.args,value:h.value,observedAt:b()});else i.push(g.operation+": "+String(h?.error||"unknown provider error"))}),!t.some((h)=>h.operation==="get_portfolio"))throw Error("Robinhood batch returned no portfolio data")}catch(n){o=n instanceof Error?n.message:String(n)}let s=o?"failed":i.length?"partial":"succeeded";if(v(()=>{if(!o)for(let n of t)L(n);y(`INSERT INTO refresh_runs(started_at,completed_at,status,operation_count,success_count,error) - VALUES(?,?,?,?,?,?)`,[e,b(),s,r,o?0:t.length,o||i.join(" | ")||null])}),o)throw Error(o);return{status:s,operationCount:r,successCount:t.length}}function te(e,t,i,r){let d=String(i?.account_number??"");if(!d)return;let s=String(i?.order_id??a(t,["order_id","orderId","id"])??"")||[r,i?.symbol||"EQUITY",e].join(":"),n=e==="cancel_equity_order"?a(t,["state","status"])||"CANCEL_REQUESTED":a(t,["state","status"])||"SUBMITTED";y(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) + observed_at=MAX(portfolio_current.observed_at,excluded.observed_at)`,[r,o==="week"?null:d,o==="week"?d:null,i])}function E(e){if(e.operation==="get_accounts")Z(e.value,e.observedAt);else if(e.operation==="get_portfolio")$(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_positions")Q(e.value,e.args,e.observedAt);else if(e.operation==="get_equity_orders")K(e.value,e.args,e.observedAt);else if(e.operation==="get_realized_pnl")ee(e.value,e.args,e.observedAt);else return!1;return!0}function te(e){let t=e.toLowerCase();return t.includes("esp_err_http_connect")||t.includes("timeout")||t.includes("tls")||t.includes("socket")||t.includes("network")}function T(){let e=b(),t=[],i=[],r=0,d=(n,l)=>{r+=1;try{let c=L(n,l);return t.push({operation:n,args:l,value:c,observedAt:b()}),c}catch(c){let u=c instanceof Error?c.message:String(c);if(i.push(n+": "+u),n==="get_accounts"||te(u))throw c;return null}},o=null;try{let n=d("get_accounts",{}),c=P(n,["accounts"]).map((h)=>_(h,{})).filter(Boolean);if(!c.length)throw Error("Robinhood returned no brokerage accounts");let u=new Date((e-604800)*1000).toISOString().slice(0,10),p=[];for(let h of c){let m={account_number:h};p.push({operation:"get_portfolio",args:m},{operation:"get_equity_positions",args:m},{operation:"get_equity_orders",args:{...m,created_at_gte:u}},{operation:"get_realized_pnl",args:{...m,span:"day",asset_classes:["equity"]}},{operation:"get_realized_pnl",args:{...m,span:"week",asset_classes:["equity"]}})}r+=p.length;let f=J(p);if(f.length!==p.length)throw Error("Robinhood batch returned an incomplete result set");if(f.forEach((h,m)=>{let g=p[m];if(h?.ok)t.push({operation:g.operation,args:g.args,value:h.value,observedAt:b()});else i.push(g.operation+": "+String(h?.error||"unknown provider error"))}),!t.some((h)=>h.operation==="get_portfolio"))throw Error("Robinhood batch returned no portfolio data")}catch(n){o=n instanceof Error?n.message:String(n)}let s=o?"failed":i.length?"partial":"succeeded";if(v(()=>{if(!o)for(let n of t)E(n);y(`INSERT INTO refresh_runs(started_at,completed_at,status,operation_count,success_count,error) + VALUES(?,?,?,?,?,?)`,[e,b(),s,r,o?0:t.length,o||i.join(" | ")||null])}),o)throw Error(o);return{status:s,operationCount:r,successCount:t.length}}function ie(e,t,i,r){let d=String(i?.account_number??"");if(!d)return;let s=String(i?.order_id??a(t,["order_id","orderId","id"])??"")||[r,i?.symbol||"EQUITY",e].join(":"),n=e==="cancel_equity_order"?a(t,["state","status"])||"CANCEL_REQUESTED":a(t,["state","status"])||"SUBMITTED";y(`INSERT INTO activities(account_number,activity_id,occurred_at,observed_at,symbol,side,quantity,price,amount,state,activity_type) VALUES(?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(account_number,activity_id) DO UPDATE SET occurred_at=COALESCE(excluded.occurred_at,activities.occurred_at), @@ -243,4 +243,4 @@ Returns the scan with its new filters and fresh live results. This changes Robin quantity=COALESCE(excluded.quantity,activities.quantity), price=COALESCE(excluded.price,activities.price), state=excluded.state, - activity_type=excluded.activity_type`,[d,s,a(t,["created_at","updated_at","last_transaction_at"]),r,i?.symbol??a(t,["symbol"]),i?.side??a(t,["side"]),i?.quantity??i?.dollar_amount??a(t,["quantity","executed_quantity"]),i?.limit_price??i?.stop_price??a(t,["price","average_price"]),i?.dollar_amount??null,String(n).toUpperCase(),e==="cancel_equity_order"?"EQUITY ORDER CANCEL":"EQUITY ORDER"])}function ie(e,t){let i=C(e,t),r={operation:e,args:t,value:i,observedAt:b()};if(["get_accounts","get_portfolio","get_equity_positions","get_equity_orders","get_realized_pnl"].includes(e))v(()=>L(r));if(e==="place_equity_order"||e==="cancel_equity_order")v(()=>te(e,i,t,r.observedAt));return i}function D(e){return JSON.stringify({text:JSON.stringify(e),isError:!1})}globalThis.PocketPiData={invokeTask(e){try{if(e!=="refreshPortfolio")throw Error("Unknown Robinhood Data Action: "+e);let t=T();return D(t)}catch(t){return JSON.stringify({text:t instanceof Error?t.message:String(t),isError:!0})}},invokeTool(e,t){try{let i=JSON.parse(t),r=e==="robinhood.refresh_portfolio"?T():e==="robinhood.search_tools"?z(i):e==="robinhood.call"?H(i):(()=>{throw Error("Unknown Robinhood Tool: "+e)})();return D(r)}catch(i){return JSON.stringify({text:i instanceof Error?i.message:String(i),isError:!0})}}};})(); + activity_type=excluded.activity_type`,[d,s,a(t,["created_at","updated_at","last_transaction_at"]),r,i?.symbol??a(t,["symbol"]),i?.side??a(t,["side"]),i?.quantity??i?.dollar_amount??a(t,["quantity","executed_quantity"]),i?.limit_price??i?.stop_price??a(t,["price","average_price"]),i?.dollar_amount??null,String(n).toUpperCase(),e==="cancel_equity_order"?"EQUITY ORDER CANCEL":"EQUITY ORDER"])}function re(e,t){let i=L(e,t),r={operation:e,args:t,value:i,observedAt:b()};if(["get_accounts","get_portfolio","get_equity_positions","get_equity_orders","get_realized_pnl"].includes(e))v(()=>E(r));if(e==="place_equity_order"||e==="cancel_equity_order")v(()=>ie(e,i,t,r.observedAt));return i}function D(e){return JSON.stringify({text:JSON.stringify(e),isError:!1})}globalThis.PocketPiData={invokeTask(e){try{if(e!=="refreshPortfolio")throw Error("Unknown Robinhood Data Action: "+e);let t=T();return D(t)}catch(t){return JSON.stringify({text:t instanceof Error?t.message:String(t),isError:!0})}},invokeTool(e,t){try{let i=JSON.parse(t),r=e==="robinhood.refresh_portfolio"?T():e==="robinhood.search_tools"?W(i):e==="robinhood.call"?X(i):(()=>{throw Error("Unknown Robinhood Tool: "+e)})();return D(r)}catch(i){return JSON.stringify({text:i instanceof Error?i.message:String(i),isError:!0})}}};})(); diff --git a/crates/pocket-pi-agentos/src/lib.rs b/crates/pocket-pi-agentos/src/lib.rs index 3c6aba2..a1e9429 100644 --- a/crates/pocket-pi-agentos/src/lib.rs +++ b/crates/pocket-pi-agentos/src/lib.rs @@ -22,8 +22,6 @@ use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; pub const ROOT_APP_ID: &str = "pi-agent"; -pub const ROBINHOOD_APP_ID: &str = "robinhood"; -pub const EXA_APP_ID: &str = "exa"; const BUILTIN_RELEASE: &str = "builtin-v1"; const VIEWPORT: (f32, f32) = (720.0, 1280.0); @@ -31,104 +29,155 @@ const VIEWPORT: (f32, f32) = (720.0, 1280.0); // Tool Router handoff and local read-only diagnostics; remote work itself runs // in the Data Action runner and never holds the App/UI owner. const TOOL_TIMEOUT: Duration = Duration::from_secs(45); -const ROOT_JS: &str = include_str!("../../../apps/pi-agent/dist/app.js"); -const ROOT_AGENT_JS: &str = include_str!("../../../apps/pi-agent/dist/agent.js"); -const ROOT_PAK: &[u8] = include_bytes!("../../../apps/pi-agent/dist/app.pak"); -const ROOT_DESCRIPTOR: &str = include_str!("../../../apps/pi-agent/agent-app.json"); -const ROOT_POCKET: &str = include_str!("../../../apps/pi-agent/pocket.json"); -const ROBINHOOD_JS: &str = include_str!("../../../apps/robinhood/dist/app.js"); -const ROBINHOOD_DATA_JS: &str = include_str!("../../../apps/robinhood/dist/data-action.js"); -const ROBINHOOD_PAK: &[u8] = include_bytes!("../../../apps/robinhood/dist/app.pak"); -const ROBINHOOD_DESCRIPTOR: &str = include_str!("../../../apps/robinhood/agent-app.json"); -#[cfg(test)] -const ROBINHOOD_TOOL_CATALOG: &str = include_str!("../../../apps/robinhood/tool-catalog.json"); -const ROBINHOOD_POCKET: &str = include_str!("../../../apps/robinhood/pocket.json"); -const EXA_JS: &str = include_str!("../../../apps/exa/dist/app.js"); -const EXA_DATA_JS: &str = include_str!("../../../apps/exa/dist/data-action.js"); -const EXA_PAK: &[u8] = include_bytes!("../../../apps/exa/dist/app.pak"); -const EXA_DESCRIPTOR: &str = include_str!("../../../apps/exa/agent-app.json"); -const EXA_POCKET: &str = include_str!("../../../apps/exa/pocket.json"); - #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -struct AppDescriptor { - id: String, - version: String, +pub struct AppDescriptor { + pub id: String, + #[serde(skip)] + pub title: String, + pub description: String, + pub version: String, + #[serde(default)] + pub data_version: u32, #[serde(default)] - data_version: u32, + pub tool_namespace: String, #[serde(default)] - tools: Vec, + pub tools: Vec, #[serde(default)] - provider_operations: Vec, + pub provider_operations: Vec, #[serde(default)] - tasks: Vec, + pub tasks: Vec, #[serde(default)] - schedules: Vec, + pub schedules: Vec, + #[serde(default)] + pub native_services: NativeServices, } #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -struct AppSchedule { - id: String, - every_minutes: u64, - task: String, +pub struct AppSchedule { + pub id: String, + pub every_minutes: u64, + pub task: String, #[serde(default)] - args: Value, + pub args: Value, +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct NativeServices { + #[serde(default)] + pub http: Vec, + #[serde(default)] + pub mcp: Vec, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct CredentialBinding { + pub id: String, + pub header: String, + #[serde(default)] + pub prefix: String, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct HttpServicePolicy { + pub method: String, + pub urls: Vec, + #[serde(default)] + pub allowed_request_headers: Vec, + pub credential: Option, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct McpServicePolicy { + pub connection: String, + pub url: String, + pub credential: CredentialBinding, +} + +#[derive(Clone, Copy)] +pub struct EmbeddedApp { + pub descriptor_json: &'static str, + pub pocket_json: &'static str, + pub js: &'static str, + pub data_js: Option<&'static str>, + pub agent_js: Option<&'static str>, + pub pak: &'static [u8], +} + +impl EmbeddedApp { + pub const fn new( + descriptor_json: &'static str, + pocket_json: &'static str, + js: &'static str, + data_js: Option<&'static str>, + agent_js: Option<&'static str>, + pak: &'static [u8], + ) -> Self { + Self { + descriptor_json, + pocket_json, + js, + data_js, + agent_js, + pak, + } + } } #[derive(Clone)] -struct BuiltinApp { +struct CatalogApp { descriptor: AppDescriptor, - descriptor_json: &'static str, - pocket_json: &'static str, - js: &'static str, - data_js: Option<&'static str>, - pak: &'static [u8], + bundle: EmbeddedApp, } #[derive(Clone)] pub struct AppCatalog { - apps: BTreeMap, + apps: BTreeMap, tool_owner: BTreeMap, } impl AppCatalog { - pub fn builtin() -> Result { + pub fn new(bundles: impl IntoIterator) -> Result { let mut apps = BTreeMap::new(); - for (descriptor_json, pocket_json, js, data_js, pak) in [ - (ROOT_DESCRIPTOR, ROOT_POCKET, ROOT_JS, None, ROOT_PAK), - ( - ROBINHOOD_DESCRIPTOR, - ROBINHOOD_POCKET, - ROBINHOOD_JS, - Some(ROBINHOOD_DATA_JS), - ROBINHOOD_PAK, - ), - ( - EXA_DESCRIPTOR, - EXA_POCKET, - EXA_JS, - Some(EXA_DATA_JS), - EXA_PAK, - ), - ] { - let descriptor: AppDescriptor = - serde_json::from_str(descriptor_json).context("parse built-in agent-app.json")?; + for bundle in bundles { + let mut descriptor: AppDescriptor = serde_json::from_str(bundle.descriptor_json) + .context("parse embedded agent-app.json")?; + let pocket: Value = + serde_json::from_str(bundle.pocket_json).context("parse embedded pocket.json")?; + descriptor.title = pocket + .get("title") + .and_then(Value::as_str) + .filter(|title| !title.is_empty()) + .ok_or_else(|| anyhow!("App {} pocket.json is missing title", descriptor.id))? + .to_owned(); + if descriptor.tool_namespace.is_empty() { + descriptor.tool_namespace.clone_from(&descriptor.id); + } if apps.contains_key(&descriptor.id) { - anyhow::bail!("duplicate built-in App id: {}", descriptor.id); + anyhow::bail!("duplicate embedded App id: {}", descriptor.id); } - apps.insert( - descriptor.id.clone(), - BuiltinApp { - descriptor, - descriptor_json, - pocket_json, - js, - data_js, - pak, - }, - ); + apps.insert(descriptor.id.clone(), CatalogApp { descriptor, bundle }); } + anyhow::ensure!( + apps.contains_key(ROOT_APP_ID), + "missing {ROOT_APP_ID} System App" + ); + anyhow::ensure!( + apps[ROOT_APP_ID].bundle.agent_js.is_some(), + "{ROOT_APP_ID} System App is missing agent.js" + ); + anyhow::ensure!( + apps.values() + .filter(|app| app.bundle.agent_js.is_some()) + .count() + == 1, + "only {ROOT_APP_ID} may contain agent.js" + ); let mut tool_owner = BTreeMap::new(); for app in apps.values() { let provider_operations = app @@ -153,9 +202,7 @@ impl AppCatalog { .get("name") .and_then(Value::as_str) .ok_or_else(|| anyhow!("{} tool is missing name", app.descriptor.id))?; - if !name.starts_with(&format!("{}.", app.descriptor.id)) - && !(app.descriptor.id == EXA_APP_ID && name.starts_with("research.")) - { + if !name.starts_with(&format!("{}.", app.descriptor.tool_namespace)) { anyhow::bail!("App {} owns non-namespaced tool {name}", app.descriptor.id); } if tool_owner @@ -189,10 +236,14 @@ impl AppCatalog { self.tool_owner.get(name).map(String::as_str) } - fn descriptors(&self) -> impl Iterator { + pub fn descriptors(&self) -> impl Iterator { self.apps.values().map(|app| &app.descriptor) } + pub fn descriptor(&self, id: &str) -> Option<&AppDescriptor> { + self.apps.get(id).map(|app| &app.descriptor) + } + /// Provider operations are declared by the App release and consumed by a /// native credential/transport owner as its exact allowlist. Local-only /// App Tools omit `providerOperation` and can never cross this boundary. @@ -205,7 +256,48 @@ impl AppCatalog { .collect() } - fn app(&self, id: &str) -> Option<&BuiltinApp> { + pub fn provider_operation_allowed(&self, app_id: &str, operation: &str) -> bool { + self.descriptor(app_id) + .is_some_and(|app| app.provider_operations.iter().any(|item| item == operation)) + } + + pub fn http_policy(&self, app_id: &str, method: &str, url: &str) -> Option<&HttpServicePolicy> { + self.descriptor(app_id)? + .native_services + .http + .iter() + .find(|policy| policy.method == method && policy.urls.iter().any(|item| item == url)) + } + + pub fn mcp_policy(&self, app_id: &str, connection: &str) -> Option<&McpServicePolicy> { + self.descriptor(app_id)? + .native_services + .mcp + .iter() + .find(|policy| policy.connection == connection) + } + + pub fn credential_ids(&self) -> BTreeSet { + self.descriptors() + .flat_map(|descriptor| { + descriptor + .native_services + .http + .iter() + .filter_map(|policy| policy.credential.as_ref()) + .chain( + descriptor + .native_services + .mcp + .iter() + .map(|policy| &policy.credential), + ) + }) + .map(|credential| credential.id.clone()) + .collect() + } + + fn app(&self, id: &str) -> Option<&CatalogApp> { self.apps.get(id) } } @@ -575,7 +667,7 @@ struct AppRuntime { impl AppRuntime { fn load( - app: &BuiltinApp, + app: &CatalogApp, release_dir: &Path, fs_root: &Path, tmp_root: &Path, @@ -906,9 +998,12 @@ pub struct AppSupervisor { } impl AppSupervisor { - pub fn new(workspace: impl Into, services: Arc) -> Result { + pub fn new( + workspace: impl Into, + catalog: AppCatalog, + services: Arc, + ) -> Result { let workspace = workspace.into(); - let catalog = AppCatalog::builtin()?; seed_builtin_releases(&workspace, &catalog)?; let schedules = AppScheduleStore::load(&workspace, &catalog)?; let mut databases = BTreeMap::new(); @@ -941,7 +1036,7 @@ impl AppSupervisor { .get(&descriptor.id) .expect("revision created for descriptor") .clone(), - net: serde_json::from_str::(app.pocket_json) + net: serde_json::from_str::(app.bundle.pocket_json) .ok() .and_then(|manifest| { manifest @@ -1325,23 +1420,28 @@ fn seed_builtin_releases(workspace: &Path, catalog: &AppCatalog) -> Result<()> { std::fs::create_dir_all(&fs_root)?; std::fs::create_dir_all(&db_root)?; std::fs::create_dir_all(&tmp_root)?; - atomic_write(&release_dir.join("app.js"), app.js.as_bytes())?; - if let Some(data_js) = app.data_js { + atomic_write(&release_dir.join("app.js"), app.bundle.js.as_bytes())?; + if let Some(data_js) = app.bundle.data_js { atomic_write(&release_dir.join("data-action.js"), data_js.as_bytes())?; } - if app.descriptor.id == ROOT_APP_ID { - atomic_write(&release_dir.join("agent.js"), ROOT_AGENT_JS.as_bytes())?; + if let Some(agent_js) = app.bundle.agent_js { + atomic_write(&release_dir.join("agent.js"), agent_js.as_bytes())?; } - atomic_write(&release_dir.join("app.pak"), app.pak)?; + atomic_write(&release_dir.join("app.pak"), app.bundle.pak)?; atomic_write( &release_dir.join("agent-app.json"), - app.descriptor_json.as_bytes(), + app.bundle.descriptor_json.as_bytes(), )?; - atomic_write(&release_dir.join("pocket.json"), app.pocket_json.as_bytes())?; - let mut modules = vec!["ui", "data.fs", "data.sqlite"]; - if app.descriptor.id == EXA_APP_ID { - modules.push("net.http"); - } + atomic_write( + &release_dir.join("pocket.json"), + app.bundle.pocket_json.as_bytes(), + )?; + let manifest: Value = serde_json::from_str(app.bundle.pocket_json)?; + let modules = manifest + .pointer("/engine/capabilities/requires") + .and_then(Value::as_array) + .cloned() + .unwrap_or_default(); atomic_write( &release_dir.join("plan.json"), &serde_json::to_vec_pretty(&json!({ @@ -1601,222 +1701,88 @@ fn unix_seconds() -> u64 { #[cfg(test)] mod tests { use super::*; - use std::sync::atomic::{AtomicUsize, Ordering}; - use std::time::Duration; - - struct NoServices; - - impl AppServiceHost for NoServices { - fn call( - &self, - _app_id: &str, - _service: &str, - _operation: &str, - _args: &Value, - ) -> Result { - Err("not used by Pi Agent UI tests".into()) - } - } - - struct BackgroundBackend; - - impl ModelBackend for BackgroundBackend { - fn complete( - &self, - _request_json: &str, - on_event: &mut dyn FnMut(pocket_pi_embedded::ModelStreamEvent), - ) -> Result { - std::thread::sleep(Duration::from_millis(20)); - on_event(pocket_pi_embedded::ModelStreamEvent::Text( - "background-ok".into(), - )); - Ok(serde_json::json!({ - "thinking":"", - "text":"background-ok", - "toolCalls":[], - "usage":{}, - "stopReason":"stop" - }) - .to_string()) - } - } - - struct NoTools; - impl ToolHost for NoTools { - fn definitions(&self) -> Vec { - Vec::new() - } - - fn execute(&self, _call_id: &str, name: &str, _args_json: &str) -> ToolResult { - tool_error(format!("unexpected tool: {name}")) - } - } + #[test] + fn catalog_uses_each_apps_declared_tool_namespace() { + let catalog = AppCatalog::new([ + fixture( + r#"{"id":"pi-agent","description":"System","version":"1","tools":[],"tasks":[],"schedules":[]}"#, + Some("agent"), + ), + fixture( + r#"{"id":"search","description":"Research","version":"1","toolNamespace":"research","tools":[{"name":"research.query","parameters":{"type":"object"}}],"tasks":[],"schedules":[]}"#, + None, + ), + ]) + .unwrap(); - struct ToolCallingBackend(AtomicUsize); - - impl ModelBackend for ToolCallingBackend { - fn complete( - &self, - request_json: &str, - on_event: &mut dyn FnMut(pocket_pi_embedded::ModelStreamEvent), - ) -> Result { - if self.0.fetch_add(1, Ordering::SeqCst) == 0 { - Ok(serde_json::json!({ - "thinking":"get portfolio", - "thinkingSignature":"reasoning_content", - "text":"", - "toolCalls":[{ - "id":"call_portfolio", - "name":"robinhood.call", - "arguments":{ - "name":"get_portfolio", - "arguments":{"account_number":"SIM-001"} - } - }], - "usage":{}, - "stopReason":"toolUse" - }) - .to_string()) - } else { - assert!(request_json.contains("100.00"), "{request_json}"); - assert!(!request_json.contains("Queued robinhood.call")); - on_event(pocket_pi_embedded::ModelStreamEvent::Text("tool-ok".into())); - Ok(serde_json::json!({ - "thinking":"", - "text":"tool-ok", - "toolCalls":[], - "usage":{}, - "stopReason":"stop" - }) - .to_string()) - } - } + assert_eq!(catalog.app_for_tool("research.query"), Some("search")); + assert_eq!(catalog.descriptors().count(), 2); } - struct RobinhoodServices; + #[test] + fn catalog_rejects_a_tool_outside_its_declared_namespace() { + let error = AppCatalog::new([ + fixture( + r#"{"id":"pi-agent","description":"System","version":"1","tools":[],"tasks":[],"schedules":[]}"#, + Some("agent"), + ), + fixture( + r#"{"id":"search","description":"Research","version":"1","tools":[{"name":"other.query","parameters":{"type":"object"}}],"tasks":[],"schedules":[]}"#, + None, + ), + ]) + .err() + .unwrap(); - impl AppServiceHost for RobinhoodServices { - fn call( - &self, - app_id: &str, - service: &str, - operation: &str, - _args: &Value, - ) -> Result { - if (app_id, service, operation) == ("robinhood", "mcp.client", "callTool") { - Ok(json!({"equity":"100.00","day_pnl":"1.00","week_pnl":"2.00"})) - } else { - Err("unexpected service call".to_owned()) - } - } + assert!(error.to_string().contains("non-namespaced tool")); } #[test] - fn exa_catalog_exposes_bounded_advanced_search() { - let catalog = AppCatalog::builtin().unwrap(); - let exa = catalog - .descriptors() - .find(|descriptor| descriptor.id == EXA_APP_ID) - .unwrap(); - assert_eq!(exa.tools.len(), 3); - assert!(serde_json::to_vec(&exa.tools).unwrap().len() < 5 * 1024); - - let search = exa - .tools - .iter() - .find(|tool| tool["name"] == "research.search") - .unwrap(); - let properties = search["parameters"]["properties"].as_object().unwrap(); - for name in [ - "category", - "startPublishedDate", - "endPublishedDate", - "additionalQueries", - "maxAgeHours", - ] { - assert!( - properties.contains_key(name), - "missing Exa search field {name}" - ); - } - let search_types = properties["searchType"]["enum"].as_array().unwrap(); - assert!(search_types.iter().any(|value| value == "deep")); - assert!(search_types.iter().any(|value| value == "deep-reasoning")); - assert_eq!(search["parameters"]["additionalProperties"], false); + fn catalog_exposes_only_declared_native_policies() { + let catalog = AppCatalog::new([ + fixture( + r#"{"id":"pi-agent","description":"System","version":"1","tools":[],"tasks":[],"schedules":[]}"#, + Some("agent"), + ), + fixture( + r#"{"id":"search","description":"Research","version":"1","tools":[],"tasks":[],"schedules":[],"nativeServices":{"http":[{"method":"POST","urls":["https://example.com/search"],"allowedRequestHeaders":["content-type"],"credential":{"id":"search.api-key","header":"x-api-key"}}],"mcp":[]}}"#, + None, + ), + ]) + .unwrap(); - let fetch = exa - .tools - .iter() - .find(|tool| tool["name"] == "research.fetch") - .unwrap(); - assert!(fetch["parameters"]["properties"] - .get("maxAgeHours") + assert!(catalog + .http_policy("search", "POST", "https://example.com/search") .is_some()); - assert_eq!(fetch["parameters"]["additionalProperties"], false); - } - - #[test] - fn robinhood_catalog_matches_the_checked_in_tool_catalog() { - let catalog = AppCatalog::builtin().unwrap(); - let operations = catalog.provider_operations(ROBINHOOD_APP_ID); - let snapshot: Value = serde_json::from_str(ROBINHOOD_TOOL_CATALOG).unwrap(); - let upstream = snapshot["tools"] - .as_array() - .unwrap() - .iter() - .map(|tool| tool["name"].as_str().unwrap().to_owned()) - .collect::>(); - assert_eq!(operations, upstream); - assert_eq!(operations.len(), 54); - assert!(operations.contains("place_equity_order")); - assert!(operations.contains("place_option_order")); - assert!(!operations.contains("refresh_portfolio")); - let mut namespace_counts = BTreeMap::<&str, usize>::new(); - for tool in snapshot["tools"].as_array().unwrap() { - *namespace_counts - .entry(tool["namespace"].as_str().unwrap()) - .or_default() += 1; - assert!(!tool["description"].as_str().unwrap_or_default().is_empty()); - assert!(tool.get("agentDescription").is_none()); - assert_eq!(tool["inputSchema"]["type"], "object"); - } - assert_eq!(namespace_counts.len(), 8); - assert!(namespace_counts.values().all(|count| *count <= 9)); - let robinhood = catalog - .descriptors() - .find(|descriptor| descriptor.id == ROBINHOOD_APP_ID) - .unwrap(); - assert_eq!(robinhood.tools.len(), 4); - assert!(serde_json::to_vec(&robinhood.tools).unwrap().len() < 8 * 1024); - for tool in &robinhood.tools { - let name = tool["name"].as_str().unwrap(); - assert!( - !tool["description"].as_str().unwrap_or_default().is_empty(), - "{name}" - ); - assert_eq!(tool["parameters"]["type"], "object", "{name}"); - if tool.get("providerOperation").is_some() { - assert_eq!(tool["parameters"]["additionalProperties"], false, "{name}"); - } - } + assert!(catalog + .http_policy("search", "GET", "https://example.com/search") + .is_none()); + assert_eq!( + catalog.credential_ids(), + BTreeSet::from(["search.api-key".to_owned()]) + ); } #[test] - fn data_version_resets_only_that_app_database_once() { + fn data_version_resets_only_that_apps_database_once() { let temp = tempfile::tempdir().unwrap(); - let db_root = temp.path().join("apps/exa/data"); + let db_root = temp.path().join("apps/notes/data"); std::fs::create_dir_all(&db_root).unwrap(); - let database = db_root.join("exa.sqlite"); + let database = db_root.join("notes.sqlite"); std::fs::write(&database, "old-schema").unwrap(); let mut descriptor = AppDescriptor { - id: EXA_APP_ID.to_owned(), - version: "1.0.0".to_owned(), + id: "notes".into(), + title: "Notes".into(), + description: "Notes App".into(), + version: "1.0.0".into(), data_version: 3, + tool_namespace: "notes".into(), tools: Vec::new(), provider_operations: Vec::new(), tasks: Vec::new(), schedules: Vec::new(), + native_services: NativeServices::default(), }; reset_development_database(temp.path(), &descriptor, &db_root).unwrap(); @@ -1833,196 +1799,14 @@ mod tests { assert!(!database.exists()); } - #[test] - fn app_task_schedule_state_is_owned_by_each_app_data_root() { - let temp = tempfile::tempdir().unwrap(); - let _supervisor = AppSupervisor::new(temp.path(), Arc::new(NoServices)).unwrap(); - let app_state = temp - .path() - .join("apps/robinhood/data/.system/schedules.json"); - let stored: Vec = - serde_json::from_slice(&std::fs::read(app_state).unwrap()).unwrap(); - - assert_eq!(stored.len(), 1); - assert_eq!(stored[0].app_id, ROBINHOOD_APP_ID); - assert_eq!(stored[0].last_ok, None); - assert!(!temp.path().join(".system/schedules.json").exists()); - } - - #[test] - fn pi_agent_system_app_survives_foreground_app_navigation() { - let temp = tempfile::tempdir().unwrap(); - let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(NoServices)).unwrap(); - assert_eq!(supervisor.runtimes.len(), 2, "all ordinary Views preload"); - let system_guest = &supervisor.system.guest as *const Guest as usize; - let exa_guest = &supervisor - .runtimes - .get(EXA_APP_ID) - .expect("Exa runtime preloaded") - .guest as *const Guest as usize; - supervisor - .boot_agent( - r#"{"model":"offline"}"#, - Arc::new(BackgroundBackend), - Arc::new(NoTools), - ) - .unwrap(); - supervisor.prompt_agent("keep working").unwrap(); - supervisor.open(ROBINHOOD_APP_ID).unwrap(); - - let mut saw_delta = false; - let mut finished = false; - for _ in 0..100 { - for event in supervisor.frame().unwrap() { - saw_delta |= - matches!(event, AgentEvent::ResponseText(ref text) if text == "background-ok"); - finished |= event == AgentEvent::Done; - } - if finished { - break; - } - std::thread::sleep(Duration::from_millis(2)); - } - - assert!(saw_delta && finished); - assert_eq!(supervisor.active_id(), ROBINHOOD_APP_ID); - assert_eq!( - &supervisor.system.guest as *const Guest as usize, - system_guest - ); - let robinhood_guest = &supervisor - .runtimes - .get(ROBINHOOD_APP_ID) - .expect("Robinhood runtime") - .guest as *const Guest as usize; - supervisor.open(ROOT_APP_ID).unwrap(); - assert_eq!(supervisor.active_id(), ROOT_APP_ID); - assert_eq!( - &supervisor.system.guest as *const Guest as usize, - system_guest - ); - supervisor.open(ROBINHOOD_APP_ID).unwrap(); - assert_eq!( - &supervisor - .runtimes - .get(ROBINHOOD_APP_ID) - .expect("cached Robinhood runtime") - .guest as *const Guest as usize, - robinhood_guest - ); - supervisor.open(EXA_APP_ID).unwrap(); - assert_eq!( - &supervisor - .runtimes - .get(EXA_APP_ID) - .expect("resident Exa runtime") - .guest as *const Guest as usize, - exa_guest - ); - } - - #[test] - fn background_agent_routes_headless_app_tool_while_exa_is_foreground() { - let temp = tempfile::tempdir().unwrap(); - let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(RobinhoodServices)).unwrap(); - let (routed, app_rx) = RoutedToolHost::new(Arc::new(NoTools), supervisor.catalog.clone()); - supervisor - .boot_agent( - r#"{"model":"offline"}"#, - Arc::new(ToolCallingBackend(AtomicUsize::new(0))), - Arc::new(routed), - ) - .unwrap(); - supervisor.prompt_agent("check portfolio").unwrap(); - supervisor.open(EXA_APP_ID).unwrap(); - - let mut finished = false; - for _ in 0..200 { - while let Ok(request) = app_rx.try_recv() { - request.handle(&mut supervisor); - } - finished |= supervisor - .frame() - .unwrap() - .into_iter() - .any(|event| event == AgentEvent::Done); - if finished { - break; - } - std::thread::sleep(Duration::from_millis(2)); - } - - assert!(finished); - assert_eq!(supervisor.active_id(), EXA_APP_ID); - assert!(temp - .path() - .join("apps/robinhood/data/robinhood.sqlite") - .exists()); - } - - #[test] - fn app_revisions_coalesce_at_the_foreground_frame_boundary() { - let temp = tempfile::tempdir().unwrap(); - let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(NoServices)).unwrap(); - supervisor.open(EXA_APP_ID).unwrap(); - - let revision = supervisor - .runtimes - .get(EXA_APP_ID) - .unwrap() - .revision - .clone(); - revision.fetch_add(1, Ordering::Release); - revision.fetch_add(1, Ordering::Release); - revision.fetch_add(1, Ordering::Release); - assert!(supervisor.active_projection_is_stale()); - - // A host tick that does not render the selected View never reloads its - // SQLite projection. The next rendered frame observes only the newest - // revision and therefore folds all three commits into one reload. - supervisor.frame_render(false).unwrap(); - let exa = supervisor.runtimes.get(EXA_APP_ID).unwrap(); - assert_eq!(exa.projection_refreshes.get(), 0); - assert_eq!(exa.last_seen_revision.get(), 0); - - supervisor.frame_render(true).unwrap(); - let exa = supervisor.runtimes.get(EXA_APP_ID).unwrap(); - assert_eq!(exa.projection_refreshes.get(), 1); - assert_eq!(exa.last_seen_revision.get(), 3); - assert!(!supervisor.active_projection_is_stale()); - - for _ in 0..5 { - supervisor.frame_render(true).unwrap(); - } - assert_eq!( - supervisor - .runtimes - .get(EXA_APP_ID) - .unwrap() - .projection_refreshes - .get(), - 1 - ); - - // Inactive Apps never query. They catch up exactly once when selected - // again, no matter how many commits happened while they were hidden. - supervisor.open(ROOT_APP_ID).unwrap(); - revision.fetch_add(1, Ordering::Release); - revision.fetch_add(1, Ordering::Release); - supervisor.frame_render(true).unwrap(); - assert_eq!( - supervisor - .runtimes - .get(EXA_APP_ID) - .unwrap() - .projection_refreshes - .get(), - 1 - ); - supervisor.open(EXA_APP_ID).unwrap(); - supervisor.frame_render(true).unwrap(); - let exa = supervisor.runtimes.get(EXA_APP_ID).unwrap(); - assert_eq!(exa.projection_refreshes.get(), 2); - assert_eq!(exa.last_seen_revision.get(), 5); + fn fixture(descriptor_json: &'static str, agent_js: Option<&'static str>) -> EmbeddedApp { + EmbeddedApp::new( + descriptor_json, + r#"{"pocket":2,"name":"fixture","title":"Fixture","engine":{"capabilities":{"requires":[]}}}"#, + "", + None, + agent_js, + &[], + ) } } diff --git a/crates/pocket-pi-app-pack/Cargo.toml b/crates/pocket-pi-app-pack/Cargo.toml new file mode 100644 index 0000000..2dd46f1 --- /dev/null +++ b/crates/pocket-pi-app-pack/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "pocket-pi-app-pack" +version = "0.1.0" +edition.workspace = true +license.workspace = true +repository.workspace = true +publish = false +build = "build.rs" + +[dependencies] +anyhow.workspace = true +pocket-pi-agentos = { path = "../pocket-pi-agentos" } +serde_json.workspace = true + +[dev-dependencies] +pocket-pi-embedded = { path = "../pocket-pi-embedded" } +tempfile = "3" diff --git a/crates/pocket-pi-app-pack/build.rs b/crates/pocket-pi-app-pack/build.rs new file mode 100644 index 0000000..84a7ac1 --- /dev/null +++ b/crates/pocket-pi-app-pack/build.rs @@ -0,0 +1,83 @@ +use std::env; +use std::fs; +use std::path::{Path, PathBuf}; + +const OPTIONAL_APPS: &[&str] = &["robinhood", "exa"]; + +fn main() { + println!("cargo:rerun-if-env-changed=POCKET_PI_APPS"); + let selected = selected_apps(); + let root = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()) + .join("../..") + .canonicalize() + .unwrap(); + let mut source = String::from("pub fn embedded_apps() -> Vec {\n vec![\n"); + source.push_str(&bundle(&root, "pi-agent", true)); + for app in selected { + source.push_str(&bundle(&root, app, false)); + } + source.push_str(" ]\n}\n"); + fs::write( + PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("apps.rs"), + source, + ) + .unwrap(); +} + +fn selected_apps() -> Vec<&'static str> { + let value = env::var("POCKET_PI_APPS").unwrap_or_else(|_| OPTIONAL_APPS.join(",")); + if value == "none" || value.is_empty() { + return Vec::new(); + } + let mut selected = Vec::new(); + for name in value.split(',') { + let name = name.trim(); + let app = OPTIONAL_APPS + .iter() + .copied() + .find(|candidate| *candidate == name) + .unwrap_or_else(|| panic!("unknown App {name}; expected robinhood, exa, or none")); + if selected.contains(&app) { + panic!("duplicate App {app}"); + } + selected.push(app); + } + selected +} + +fn bundle(root: &Path, app: &str, system: bool) -> String { + let app = root.join("apps").join(app); + for path in [ + app.join("agent-app.json"), + app.join("pocket.json"), + app.join("dist/app.js"), + app.join("dist/app.pak"), + ] { + println!("cargo:rerun-if-changed={}", path.display()); + } + let data = app.join("dist/data-action.js"); + let agent = app.join("dist/agent.js"); + if data.is_file() { + println!("cargo:rerun-if-changed={}", data.display()); + } + if system { + println!("cargo:rerun-if-changed={}", agent.display()); + } + format!( + " EmbeddedApp::new(include_str!({descriptor:?}), include_str!({pocket:?}), include_str!({js:?}), {data}, {agent}, include_bytes!({pak:?})),\n", + descriptor = app.join("agent-app.json"), + pocket = app.join("pocket.json"), + js = app.join("dist/app.js"), + data = option_include_str(&data), + agent = if system { option_include_str(&agent) } else { "None".into() }, + pak = app.join("dist/app.pak"), + ) +} + +fn option_include_str(path: &Path) -> String { + if path.is_file() { + format!("Some(include_str!({path:?}))") + } else { + "None".into() + } +} diff --git a/crates/pocket-pi-app-pack/src/lib.rs b/crates/pocket-pi-app-pack/src/lib.rs new file mode 100644 index 0000000..18aa876 --- /dev/null +++ b/crates/pocket-pi-app-pack/src/lib.rs @@ -0,0 +1,73 @@ +use anyhow::Result; +use pocket_pi_agentos::{AppCatalog, EmbeddedApp}; + +include!(concat!(env!("OUT_DIR"), "/apps.rs")); + +pub fn catalog() -> Result { + AppCatalog::new(embedded_apps()) +} + +#[cfg(test)] +mod tests { + use super::*; + use std::collections::BTreeSet; + + #[test] + fn catalog_contains_exactly_the_build_selected_apps() { + let catalog = catalog().unwrap(); + let mut actual = catalog + .descriptors() + .map(|descriptor| descriptor.id.as_str()) + .collect::>(); + actual.sort_unstable(); + let mut expected = vec!["pi-agent"]; + let selected = option_env!("POCKET_PI_APPS").unwrap_or("robinhood,exa"); + if selected != "none" { + expected.extend(selected.split(',')); + } + expected.sort_unstable(); + assert_eq!(actual, expected); + } + + #[test] + fn robinhood_catalog_matches_its_checked_in_snapshot() { + let catalog = catalog().unwrap(); + let Some(descriptor) = catalog.descriptor("robinhood") else { + return; + }; + let snapshot: serde_json::Value = + serde_json::from_str(include_str!("../../../apps/robinhood/tool-catalog.json")) + .unwrap(); + let upstream = snapshot["tools"] + .as_array() + .unwrap() + .iter() + .map(|tool| tool["name"].as_str().unwrap().to_owned()) + .collect::>(); + assert_eq!(catalog.provider_operations("robinhood"), upstream); + assert_eq!(upstream.len(), 54); + assert_eq!(descriptor.tools.len(), 4); + } + + #[test] + fn exa_search_exposes_category_dates_and_depth() { + let catalog = catalog().unwrap(); + let Some(descriptor) = catalog.descriptor("exa") else { + return; + }; + let search = descriptor + .tools + .iter() + .find(|tool| tool["name"] == "research.search") + .unwrap(); + let properties = search["parameters"]["properties"].as_object().unwrap(); + for name in [ + "category", + "startPublishedDate", + "endPublishedDate", + "searchType", + ] { + assert!(properties.contains_key(name), "missing search field {name}"); + } + } +} diff --git a/crates/pocket-pi-app-pack/tests/runtime.rs b/crates/pocket-pi-app-pack/tests/runtime.rs new file mode 100644 index 0000000..a85fb68 --- /dev/null +++ b/crates/pocket-pi-app-pack/tests/runtime.rs @@ -0,0 +1,88 @@ +use std::sync::Arc; +use std::time::Duration; + +use pocket_pi_agentos::{AppServiceHost, AppSupervisor, ROOT_APP_ID}; +use pocket_pi_app_pack::catalog; +use pocket_pi_embedded::{AgentEvent, ModelBackend, ToolHost, ToolResult}; +use serde_json::Value; + +struct NoServices; + +impl AppServiceHost for NoServices { + fn call( + &self, + _app_id: &str, + _service: &str, + _operation: &str, + _args: &Value, + ) -> Result { + Err("unexpected App service call".into()) + } +} + +struct Backend; + +impl ModelBackend for Backend { + fn complete( + &self, + _request_json: &str, + on_event: &mut dyn FnMut(pocket_pi_embedded::ModelStreamEvent), + ) -> Result { + on_event(pocket_pi_embedded::ModelStreamEvent::Text("done".into())); + Ok(r#"{"thinking":"","text":"done","toolCalls":[],"usage":{},"stopReason":"stop"}"#.into()) + } +} + +struct NoTools; + +impl ToolHost for NoTools { + fn definitions(&self) -> Vec { + Vec::new() + } + + fn execute(&self, _call_id: &str, name: &str, _args_json: &str) -> ToolResult { + ToolResult { + text: format!("unexpected Tool {name}"), + is_error: true, + ..ToolResult::default() + } + } +} + +#[test] +fn system_agent_keeps_running_while_an_ordinary_app_is_foreground() { + let temp = tempfile::tempdir().unwrap(); + let catalog = catalog().unwrap(); + let ordinary = catalog + .descriptors() + .find(|app| app.id != ROOT_APP_ID) + .unwrap() + .id + .clone(); + let mut supervisor = AppSupervisor::new(temp.path(), catalog, Arc::new(NoServices)).unwrap(); + supervisor + .boot_agent( + r#"{"model":"offline"}"#, + Arc::new(Backend), + Arc::new(NoTools), + ) + .unwrap(); + supervisor.prompt_agent("continue").unwrap(); + supervisor.open(&ordinary).unwrap(); + + for _ in 0..100 { + if supervisor + .frame() + .unwrap() + .into_iter() + .any(|event| event == AgentEvent::Done) + { + assert_eq!(supervisor.active_id(), ordinary); + supervisor.open(ROOT_APP_ID).unwrap(); + assert_eq!(supervisor.active_id(), ROOT_APP_ID); + return; + } + std::thread::sleep(Duration::from_millis(2)); + } + panic!("Agent did not finish while an ordinary App was foreground"); +} diff --git a/docs/agentos-architecture.md b/docs/agentos-architecture.md index efe220b..c1b9387 100644 --- a/docs/agentos-architecture.md +++ b/docs/agentos-architecture.md @@ -5,7 +5,7 @@ 截至 2026-08-11,当前工作树已经实现可运行的第一版:Pi Agent Root App、App Supervisor、App Tool Catalog/Router、`AppTask` Schedule、`data.fs`、 `data.sqlite`、后台 Data Action、revision-coalesced projection cache,以及 -Robinhood 和 Exa 两个 App。 +Robinhood 和 Exa 两个可选 App,以及 build-time App selection。 Simulator contract tests 已通过;常驻 System App refactor 已在 ESP32-P4 实机 完成冷启动、LittleFS App 加载、Root View、MIPI-DSI/Touch 初始化、Agent Tool Registry 启动和一次完整 UART model turn。运行中切换普通 App 的生命周期 contract @@ -91,6 +91,11 @@ catalog、Agent Tool ownership 或后台任务生命周期。如果其中某个 可以通过 Mac 开发/部署路径复制。这里定义“如何加载和运行”,不定义“如何 分发”。 +当前预装由 `crates/pocket-pi-app-pack` 在 build time 组合。`pi-agent` 始终存在; +ordinary Apps 只通过一个 `--apps` build 参数选择,例如 `--apps robinhood,exa`、 +`--apps exa` 或 `--apps none`。未选择的 App 不进入 catalog、Tool definitions、 +native policy 或 Root Apps View;已有 App data 不自动删除。 + ## 4. 核心概念 ### 4.1 Firmware / Runtime @@ -318,7 +323,8 @@ flowchart TB 这是目标布局与当前布局的并集。当前 v1 已写入 fixed `builtin-v1` release、`current`、 App SQLite 和 App-local `schedules.json`;`data/agent.sqlite`、持久 -`app-catalog.json`、`migrations.json` 仍未实现。当前 `plan.json` 也是 +`app-catalog.json`、`migrations.json` 仍未实现。当前 `agent-app.json.nativeServices` +保存 build-time trusted、无 secret 的 endpoint/credential-reference policy;当前 `plan.json` 也是 `seed_builtin_releases()` 生成的最小 runtime/module 记录,不是 PocketJS resolver 的 完整 target-specific plan。 @@ -398,7 +404,7 @@ catalog。 - viewport contract; - artifact hashes。 -当前 fixed built-in catalog 已能只解析 descriptor 建立 Agent Tool Catalog,但 ordinary +当前 build-selected embedded catalog 已能只解析 descriptor 建立 Agent Tool Catalog,但 ordinary View 仍会在 Supervisor 启动时全部 preload;动态发现和按需 residency 尚未实现。 ### App 内部依赖方向 @@ -424,10 +430,10 @@ UI refresh ─────┘ │ 当前 v1 的 App Supervisor 是受信任 Host 代码,实际负责: -- 构建固定 built-in App catalog,并解析 `agent-app.json`; +- 接收 build-time App pack,并解析所选 App 的 `agent-app.json`; - 把固定 `builtin-v1` artifacts 原子写入各 App release 目录和 `current`; - 根据 `dataVersion` 只重建变化 App 的开发期 SQLite; -- 启动一次 Pi Agent System App,并 preload 当前两个 ordinary View Runtime; +- 启动一次 Pi Agent System App,并 preload 所选 ordinary View Runtime; - 挂载正确的 data root 和 Modules; - 切换前台 App; - 路由 App Tool/AppTask,并用一个 bounded Data Action queue 串行执行; @@ -444,7 +450,7 @@ Supervisor 持有两种不同的引用: ```text system: PiAgentSystemRuntime // 启动一次,始终存在 -runtimes: Map // 固定 catalog 在启动时全部 preload +runtimes: Map // build-selected catalog 在启动时全部 preload active_app: Option // None 表示显示 Root View ``` @@ -999,8 +1005,8 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 2. Pi Agent 位于顶层 `/workspace`;Root View release 位于 `/workspace/data/view`,其中 `app.js` 和 `agent.js` 是同一个 System App release;普通 App 位于 `/workspace/apps/`。 -3. App Supervisor 会 seed/校验 built-in release,并在启动时创建一次常驻的 - Pi Agent System App;当前固定 catalog 中的普通 App View Runtime 也全部在启动 +3. App Supervisor 会 seed/校验 build-selected embedded release,并在启动时创建一次常驻的 + Pi Agent System App;当前所选 catalog 中的普通 App View Runtime 也全部在启动 阶段 preload。普通 View Guest 被限制在自己的 `data/` 和 `tmp/`,切换它们不会 替换 System App;前台导航只选择已经存在的 surface。这里没有 Marketplace、 LRU、pinning 或 residency policy。 @@ -1115,7 +1121,7 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 transaction、上一版本回退和独立 recovery UI 还没有完成。 - 当前跨硬件实证是 ESP32 simulator + physical ESP32-P4;simulator 证明共享 product contract,最终硬件验收仍以实体设备为准。 -- 固定 catalog 的普通 App View 现在全部在 Supervisor 启动时 preload;真实 +- build-selected catalog 的普通 App View 现在全部在 Supervisor 启动时 preload;真实 ESP32-P4 启动时长已量测,但持续切换仍需人工验收。后续如果 catalog 扩大,再依据实测在 PocketJS runtime 层设计加载策略,不能先引入 Marketplace、 LRU/residency policy,也不能把 App UI/数据逻辑写回 Rust。 @@ -1139,7 +1145,7 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 ### 22.3 日后扩展项目:Marketplace / Distribution -当前 v1 固定 `builtin-v1` catalog,启动时把内置 artifact 播种到 `/workspace` 并 +当前 v1 使用 build-selected App pack,release id 仍为 `builtin-v1`,启动时把所选 artifact 播种到 `/workspace` 并 preload 全部普通 View。Marketplace 是独立的后续项目,不属于当前 runtime 完成度。 启动该项目时按下面的依赖顺序扩展: @@ -1174,7 +1180,7 @@ preload 全部普通 View。Marketplace 是独立的后续项目,不属于当 7. 普通 App 无法读取另一个 App 的 data root。 8. Pi Agent 可以读取和管理顶层 `/workspace`。 9. 重启后 App 数据保留,错过的 recurring run 按规则合并一次。 -10. 当前 v1 在 Tool schema 非法、capability 缺失或内置 Bundle 损坏时 fail +10. 当前 v1 在 Tool schema 非法、capability 缺失或 embedded Bundle 损坏时 fail closed;`dataVersion` 变化只重建对应 App SQLite。migration recovery 和保留上一 个合法 release 属于 22.3 的 Marketplace 扩展验收,不冒充当前能力。 11. 同一份 Robinhood source 通过 simulator contract tests,并用对应 target diff --git a/firmware/esp32-p4/Cargo.lock b/firmware/esp32-p4/Cargo.lock index bc75e07..1792fb7 100644 --- a/firmware/esp32-p4/Cargo.lock +++ b/firmware/esp32-p4/Cargo.lock @@ -1186,6 +1186,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "pocket-pi-app-pack" +version = "0.1.0" +dependencies = [ + "anyhow", + "pocket-pi-agentos", + "serde_json", +] + [[package]] name = "pocket-pi-embedded" version = "0.1.0" @@ -1206,6 +1215,7 @@ dependencies = [ "esp-idf-svc", "log", "pocket-pi-agentos", + "pocket-pi-app-pack", "pocket-pi-embedded", "pocket-pi-protocols", "pocket-pi-tools", diff --git a/firmware/esp32-p4/Cargo.toml b/firmware/esp32-p4/Cargo.toml index 2598b5c..9cd4fa1 100644 --- a/firmware/esp32-p4/Cargo.toml +++ b/firmware/esp32-p4/Cargo.toml @@ -26,6 +26,7 @@ anyhow = "1" log = "0.4" serde_json = "1" pocket-pi-agentos = { path = "../../crates/pocket-pi-agentos" } +pocket-pi-app-pack = { path = "../../crates/pocket-pi-app-pack" } pocket-pi-embedded = { path = "../../crates/pocket-pi-embedded" } pocket-pi-protocols = { path = "../../crates/pocket-pi-protocols" } pocket-pi-tools = { path = "../../crates/pocket-pi-tools" } diff --git a/firmware/esp32-p4/src/agentos_main.rs b/firmware/esp32-p4/src/agentos_main.rs index 43031c8..3e7bba2 100644 --- a/firmware/esp32-p4/src/agentos_main.rs +++ b/firmware/esp32-p4/src/agentos_main.rs @@ -4,8 +4,9 @@ use std::sync::Arc; use std::time::Instant; use pocket_pi_agentos::{ - AppServiceHost, AppSupervisor, RoutedToolHost, DATA_ACTION_STACK_BYTES, + AppCatalog, AppServiceHost, AppSupervisor, RoutedToolHost, DATA_ACTION_STACK_BYTES, }; +use pocket_pi_app_pack::catalog; use pocket_pi_embedded::{AgentEvent, ModelBackend, ToolHost, MODEL_WORKER_STACK_BYTES}; use pocket_pi_protocols::model::ModelBackendSettings; use pocket_pi_tools::CoreToolHost; @@ -121,13 +122,14 @@ pub fn run() -> anyhow::Result<()> { let network_ready = Arc::new(AtomicBool::new( wifi.as_ref().is_some_and(|wifi| wifi.is_connected()), )); + let catalog = catalog()?; let services: Arc = Arc::new(EspAppServices::new( network_ready.clone(), - runtime_config.exa_api_key, - runtime_config.robinhood_access_token, + catalog.clone(), + runtime_config.app_credentials, )); let mut supervisor = with_psram_pthread_config(DATA_ACTION_STACK_BYTES, || { - AppSupervisor::new(storage::WORKSPACE_ROOT, services) + AppSupervisor::new(storage::WORKSPACE_ROOT, catalog, services) })?; supervisor.frame()?; @@ -156,7 +158,7 @@ pub fn run() -> anyhow::Result<()> { "provider":provider, "model":resolved_model, "thinkingLevel":model_settings.thinking_level.id(), - "systemPrompt":"You are Pi Agent, the first-class system App in Pocket Pi AgentOS on an ESP32-P4. You can manage the top-level /workspace and use installed App tools. Use /workspace for durable memory, notes, plans, and artifacts; read and update relevant files when continuity matters. Be concise. Robinhood data is owned by the Robinhood App; Exa research history is owned by the Exa App." + "systemPrompt":"You are Pi Agent, the first-class system App in Pocket Pi AgentOS on an ESP32-P4. You can manage the top-level /workspace and use installed App tools. Use /workspace for durable memory, notes, plans, and artifacts; read and update relevant files when continuity matters. Installed Apps own their tools, state, tasks, and views. Be concise." }); with_psram_pthread_config(MODEL_WORKER_STACK_BYTES, || { supervisor @@ -166,7 +168,7 @@ pub fn run() -> anyhow::Result<()> { let mut messages = vec![Message { role: "assistant", - text: "Pocket Pi AgentOS is starting. Robinhood and Exa are installed Apps.".into(), + text: "Pocket Pi AgentOS is starting.".into(), }]; let mut agent_status = "STARTING"; let mut busy = false; @@ -384,6 +386,7 @@ pub fn run() -> anyhow::Result<()> { &resolved_model, &settings, native_tools.as_ref(), + supervisor.catalog(), ); supervisor.update_root(&projection)?; projection_dirty = false; @@ -567,6 +570,7 @@ fn root_projection( model: &str, settings: &SettingsProjection, tools: &CoreToolHost, + catalog: &AppCatalog, ) -> Value { let schedule = tools.schedule_projection(); let schedule_text = match schedule.next_in_seconds { @@ -586,6 +590,12 @@ fn root_projection( "next":schedule_text, "everyMinutes":schedule.every_minutes, }, + "apps":catalog.descriptors().filter(|app| app.id != pocket_pi_agentos::ROOT_APP_ID).map(|app| json!({ + "id":app.id, + "title":app.title, + "description":app.description, + "scheduleEveryMinutes":app.schedules.first().map(|schedule| schedule.every_minutes), + })).collect::>(), "settings":{ "wifi":{ "connectedSsid":settings.wifi.connected_ssid, diff --git a/firmware/esp32-p4/src/app_services.rs b/firmware/esp32-p4/src/app_services.rs index 723e495..85c0e58 100644 --- a/firmware/esp32-p4/src/app_services.rs +++ b/firmware/esp32-p4/src/app_services.rs @@ -1,5 +1,5 @@ use core::time::Duration; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeMap; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; use std::time::Instant; @@ -12,11 +12,11 @@ use embedded_svc::io::Write as _; use esp_idf_svc::http::client::{Configuration, EspHttpConnection}; use esp_idf_svc::io::EspIOError; use pocket_pi_agentos::{ - AppCatalog, AppServiceHost, HttpRequest, NetFailure, TransportCompletion, ROBINHOOD_APP_ID, + AppCatalog, AppServiceHost, CredentialBinding, HttpRequest, McpServicePolicy, NetFailure, + TransportCompletion, }; use serde_json::{json, Value}; -const ROBINHOOD_MCP_URL: &str = "https://agent.robinhood.com/mcp/trading"; const MCP_PROTOCOL_VERSION: &str = "2025-06-18"; const MAX_MCP_RESPONSE: usize = 160 * 1024; @@ -26,10 +26,9 @@ pub struct EspAppServices { struct EspAppServicesInner { network_ready: Arc, - exa_api_key: Option, - robinhood_access_token: Option, - robinhood_operations: BTreeSet, - robinhood: Mutex, + catalog: AppCatalog, + credentials: BTreeMap, + mcp: Mutex>, } #[derive(Default)] @@ -41,104 +40,93 @@ struct McpState { impl EspAppServices { pub fn new( network_ready: Arc, - exa_api_key: Option, - robinhood_access_token: Option, + catalog: AppCatalog, + mut credentials: BTreeMap, ) -> Self { - let robinhood_operations = AppCatalog::builtin() - .expect("built-in App catalog") - .provider_operations(ROBINHOOD_APP_ID); + let required = catalog.credential_ids(); + credentials.retain(|id, _| required.contains(id)); let inner = Arc::new(EspAppServicesInner { network_ready, - exa_api_key, - robinhood_access_token, - robinhood_operations, - robinhood: Mutex::new(McpState { - session_id: None, - next_id: 1, - }), + catalog, + credentials, + mcp: Mutex::new(BTreeMap::new()), }); Self { inner } } } impl EspAppServicesInner { - fn robinhood_operation_allowed(&self, operation: &str) -> bool { - self.robinhood_operations.contains(operation) - } - - fn exa_http( + fn http( &self, + app_id: &str, request: HttpRequest, ) -> std::result::Result { - if request.method != "POST" - || !matches!( - request.url.as_str(), - "https://api.exa.ai/search" | "https://api.exa.ai/contents" - ) - { - return Err(NetFailure::new( - "invalid_request", - "Exa NET capability permits only POST /search and /contents", - )); - } - if request - .headers - .keys() - .any(|name| !matches!(name.as_str(), "accept" | "content-type")) - { + let policy = self + .catalog + .http_policy(app_id, &request.method, &request.url) + .ok_or_else(|| NetFailure::new("invalid_request", "HTTP request is not allowed"))?; + if request.headers.keys().any(|name| { + !policy + .allowed_request_headers + .iter() + .any(|item| item == name) + }) { return Err(NetFailure::new( "invalid_request", - "Exa App supplied a forbidden HTTP header", + "App supplied a forbidden HTTP header", )); } - let body: Value = serde_json::from_slice(&request.body) - .map_err(|error| NetFailure::new("invalid_request", error.to_string()))?; - if !body.is_object() { - return Err(NetFailure::new( - "invalid_request", - "Exa request body must be a JSON object", - )); - } - let api_key = self - .exa_api_key - .as_deref() - .ok_or_else(|| NetFailure::new("unavailable", "Exa API key was not provisioned"))?; - execute_exa_http(request, api_key) + execute_http(request, policy.credential.as_ref(), &self.credentials) } - fn robinhood_call(&self, args: &Value) -> Result { - if args.get("connection").and_then(Value::as_str) != Some("robinhood") { - return Err("Robinhood App requested an unknown MCP connection".to_owned()); - } + fn mcp_call(&self, app_id: &str, args: &Value) -> Result { + let connection = args + .get("connection") + .and_then(Value::as_str) + .ok_or_else(|| "mcp.client requires connection".to_owned())?; + let policy = self + .catalog + .mcp_policy(app_id, connection) + .cloned() + .ok_or_else(|| "App requested an unknown MCP connection".to_owned())?; let operation = args .get("name") .and_then(Value::as_str) .ok_or_else(|| "mcp.client callTool requires name".to_owned())?; let arguments = args.get("arguments").unwrap_or(&Value::Null); - if !self.robinhood_operation_allowed(operation) { - return Err(format!( - "Robinhood operation is not allowlisted: {operation}" - )); + if !self + .catalog + .provider_operation_allowed(app_id, operation) + { + return Err(format!("MCP operation is not allowlisted: {operation}")); } - let token = self - .robinhood_access_token - .as_deref() - .ok_or_else(|| "Robinhood OAuth token was not provisioned for this boot".to_owned())?; + let credential = self.credential(&policy.credential)?; + let retryable = args + .get("retryable") + .and_then(Value::as_bool) + .unwrap_or(false); let mut state = self - .robinhood + .mcp .lock() - .map_err(|_| "Robinhood MCP state lock was poisoned".to_owned())?; + .map_err(|_| "MCP state lock was poisoned".to_owned())?; + let state = state + .entry((app_id.to_owned(), connection.to_owned())) + .or_insert_with(|| McpState { + session_id: None, + next_id: 1, + }); for attempt in 0..2 { - let result = self.robinhood_once(token, &mut state, operation, arguments); + let result = + self.mcp_once(&policy, &credential, state, operation, arguments, retryable); match result { Ok(value) => return Ok(value), Err(error) if attempt == 0 && stale_mcp_session(&error) => { - log::warn!("Robinhood MCP reconnecting after: {error}"); + log::warn!("MCP reconnecting after: {error}"); state.session_id = None; std::thread::sleep(Duration::from_millis(250)); } - Err(error) if attempt == 0 && transient_mcp_connect(&error) => { - log::warn!("Robinhood MCP transport retry after: {error}"); + Err(error) if attempt == 0 && retryable && transient_mcp_connect(&error) => { + log::warn!("MCP transport retry after: {error}"); std::thread::sleep(Duration::from_millis(250)); } Err(error) => return Err(error), @@ -147,10 +135,16 @@ impl EspAppServicesInner { unreachable!() } - fn robinhood_calls(&self, args: &Value) -> Result { - if args.get("connection").and_then(Value::as_str) != Some("robinhood") { - return Err("Robinhood App requested an unknown MCP connection".to_owned()); - } + fn mcp_calls(&self, app_id: &str, args: &Value) -> Result { + let connection = args + .get("connection") + .and_then(Value::as_str) + .ok_or_else(|| "mcp.client requires connection".to_owned())?; + let policy = self + .catalog + .mcp_policy(app_id, connection) + .cloned() + .ok_or_else(|| "App requested an unknown MCP connection".to_owned())?; let calls = args .get("calls") .and_then(Value::as_array) @@ -161,29 +155,36 @@ impl EspAppServicesInner { .get("name") .and_then(Value::as_str) .ok_or_else(|| "mcp.client callTools requires a name for every call".to_owned())?; - if !self.robinhood_operation_allowed(name) { - return Err(format!("Robinhood operation is not allowlisted: {name}")); + if !self.catalog.provider_operation_allowed(app_id, name) { + return Err(format!("MCP operation is not allowlisted: {name}")); } } - let token = self - .robinhood_access_token - .as_deref() - .ok_or_else(|| "Robinhood OAuth token was not provisioned for this boot".to_owned())?; + let credential = self.credential(&policy.credential)?; + let retryable = args + .get("retryable") + .and_then(Value::as_bool) + .unwrap_or(false); let mut state = self - .robinhood + .mcp .lock() - .map_err(|_| "Robinhood MCP state lock was poisoned".to_owned())?; + .map_err(|_| "MCP state lock was poisoned".to_owned())?; + let state = state + .entry((app_id.to_owned(), connection.to_owned())) + .or_insert_with(|| McpState { + session_id: None, + next_id: 1, + }); for attempt in 0..2 { - let result = self.robinhood_batch_once(token, &mut state, calls); + let result = self.mcp_batch_once(&policy, &credential, state, calls, retryable); match result { Ok(value) => return Ok(value), Err(error) if attempt == 0 && stale_mcp_session(&error) => { - log::warn!("Robinhood MCP batch reconnecting after: {error}"); + log::warn!("MCP batch reconnecting after: {error}"); state.session_id = None; std::thread::sleep(Duration::from_millis(250)); } - Err(error) if attempt == 0 && transient_mcp_connect(&error) => { - log::warn!("Robinhood MCP batch transport retry after: {error}"); + Err(error) if attempt == 0 && retryable && transient_mcp_connect(&error) => { + log::warn!("MCP batch transport retry after: {error}"); std::thread::sleep(Duration::from_millis(250)); } Err(error) => return Err(error), @@ -192,13 +193,22 @@ impl EspAppServicesInner { unreachable!() } - fn robinhood_batch_once( + fn credential(&self, binding: &CredentialBinding) -> Result { + self.credentials + .get(&binding.id) + .map(|secret| format!("{}{}", binding.prefix, secret)) + .ok_or_else(|| format!("credential {} was not provisioned", binding.id)) + } + + fn mcp_batch_once( &self, - token: &str, + policy: &McpServicePolicy, + credential: &str, state: &mut McpState, calls: &[Value], + retryable: bool, ) -> Result { - self.ensure_robinhood_session(token, state)?; + self.ensure_mcp_session(policy, credential, state)?; let mut requests = Vec::with_capacity(calls.len()); let mut request_ids = Vec::with_capacity(calls.len()); for call in calls { @@ -217,10 +227,12 @@ impl EspAppServicesInner { } let started = Instant::now(); let (responses, returned_session) = post_mcp_batch( - token, + policy, + credential, state.session_id.as_deref(), &requests, request_ids.len(), + retryable, )?; if returned_session.is_some() { state.session_id = returned_session; @@ -236,23 +248,24 @@ impl EspAppServicesInner { let name = call.get("name").and_then(Value::as_str).unwrap_or_default(); let response = by_id .remove(&request_ids[index]) - .ok_or_else(|| format!("Robinhood MCP batch omitted response for {name}"))?; + .ok_or_else(|| format!("MCP batch omitted response for {name}"))?; match normalize_mcp_result(&response) { Ok(value) => results.push(json!({"name":name,"ok":true,"value":value})), Err(error) => results.push(json!({"name":name,"ok":false,"error":error})), } } log::info!( - "Robinhood MCP batch calls={} completed in {}ms", + "MCP batch calls={} completed in {}ms", calls.len(), started.elapsed().as_millis() ); Ok(json!({"results":results})) } - fn ensure_robinhood_session( + fn ensure_mcp_session( &self, - token: &str, + policy: &McpServicePolicy, + credential: &str, state: &mut McpState, ) -> Result<(), String> { if state.session_id.is_some() { @@ -265,28 +278,30 @@ impl EspAppServicesInner { "params":{"protocolVersion":MCP_PROTOCOL_VERSION,"capabilities":{},"clientInfo":{"name":"pocket-pi-agentos","version":"0.1.0"}} }); state.next_id = state.next_id.saturating_add(1); - let (body, session) = post_mcp(token, None, &request)?; + let (body, session) = post_mcp(policy, credential, None, &request, true)?; if let Some(error) = body.get("error") { - return Err(format!("Robinhood MCP initialize failed: {error}")); + return Err(format!("MCP initialize failed: {error}")); } - let session = session.ok_or_else(|| "Robinhood MCP omitted session id".to_owned())?; + let session = session.ok_or_else(|| "MCP omitted session id".to_owned())?; let notification = json!({"jsonrpc":"2.0","method":"notifications/initialized"}); - let _ = post_mcp(token, Some(&session), ¬ification)?; + let _ = post_mcp(policy, credential, Some(&session), ¬ification, true)?; state.session_id = Some(session); - log::info!("Robinhood MCP session initialized"); + log::info!("MCP session initialized"); Ok(()) } - fn robinhood_once( + fn mcp_once( &self, - token: &str, + policy: &McpServicePolicy, + credential: &str, state: &mut McpState, operation: &str, args: &Value, + retryable: bool, ) -> Result { let operation_started = Instant::now(); - log::info!("Robinhood MCP {operation} started"); - self.ensure_robinhood_session(token, state)?; + log::info!("MCP {operation} started"); + self.ensure_mcp_session(policy, credential, state)?; let request = json!({ "jsonrpc":"2.0", "id":state.next_id, @@ -294,13 +309,19 @@ impl EspAppServicesInner { "params":{"name":operation,"arguments":args} }); state.next_id = state.next_id.saturating_add(1); - let (body, returned_session) = post_mcp(token, state.session_id.as_deref(), &request)?; + let (body, returned_session) = post_mcp( + policy, + credential, + state.session_id.as_deref(), + &request, + retryable, + )?; if returned_session.is_some() { state.session_id = returned_session; } let value = normalize_mcp_result(&body)?; log::info!( - "Robinhood MCP {operation} completed in {}ms", + "MCP {operation} completed in {}ms", operation_started.elapsed().as_millis() ); Ok(value) @@ -318,9 +339,9 @@ impl AppServiceHost for EspAppServices { if !self.inner.network_ready.load(Ordering::Acquire) { return Err("Network is not connected; App data was not changed".to_owned()); } - match (app_id, service, operation) { - ("robinhood", "mcp.client", "callTool") => self.inner.robinhood_call(args), - ("robinhood", "mcp.client", "callTools") => self.inner.robinhood_calls(args), + match (service, operation) { + ("mcp.client", "callTool") => self.inner.mcp_call(app_id, args), + ("mcp.client", "callTools") => self.inner.mcp_calls(app_id, args), _ => Err(format!("App {app_id} cannot access service {service}")), } } @@ -333,13 +354,7 @@ impl AppServiceHost for EspAppServices { if !self.inner.network_ready.load(Ordering::Acquire) { return Err(NetFailure::new("unavailable", "network is not connected")); } - if app_id != "exa" { - return Err(NetFailure::new( - "invalid_request", - format!("App {app_id} has no NET capability"), - )); - } - self.inner.exa_http(request) + self.inner.http(app_id, request) } } @@ -367,23 +382,36 @@ fn transient_mcp_connect(error: &str) -> bool { error.contains("ESP_ERR_HTTP_CONNECT") } -fn execute_exa_http( +fn execute_http( meta: HttpRequest, - api_key: &str, + credential: Option<&CredentialBinding>, + credentials: &BTreeMap, ) -> std::result::Result { let length = meta.body.len().to_string(); - let headers = [ - ("accept", "application/json"), - ("content-type", "application/json"), - ("content-length", length.as_str()), - ("connection", "close"), - ("user-agent", "pocket-pi-agentos/0.1"), - ("x-api-key", api_key), - ]; + let mut values = meta.headers; + values.insert("content-length".into(), length); + values.insert("connection".into(), "close".into()); + values.insert("user-agent".into(), "pocket-pi-agentos/0.1".into()); + if let Some(binding) = credential { + let secret = credentials.get(&binding.id).ok_or_else(|| { + NetFailure::new( + "unavailable", + format!("credential {} was not provisioned", binding.id), + ) + })?; + values.insert( + binding.header.clone(), + format!("{}{}", binding.prefix, secret), + ); + } + let headers = values + .iter() + .map(|(name, value)| (name.as_str(), value.as_str())) + .collect::>(); let mut client = client(Duration::from_millis(u64::from(meta.timeout_ms))).map_err(net_failure)?; let mut request = client - .request(Method::Post, &meta.url, &headers) + .request(http_method(&meta.method)?, &meta.url, &headers) .map_err(|error| net_failure(format!("create HTTPS request: {error}")))?; request .write_all(&meta.body) @@ -413,6 +441,20 @@ fn execute_exa_http( }) } +fn http_method(method: &str) -> std::result::Result { + match method { + "GET" => Ok(Method::Get), + "POST" => Ok(Method::Post), + "PUT" => Ok(Method::Put), + "DELETE" => Ok(Method::Delete), + "PATCH" => Ok(Method::Patch), + _ => Err(NetFailure::new( + "invalid_request", + format!("unsupported HTTP method {method}"), + )), + } +} + fn net_failure(message: String) -> NetFailure { let lower = message.to_ascii_lowercase(); let code = if lower.contains("exceeded") { @@ -429,36 +471,21 @@ fn net_failure(message: String) -> NetFailure { NetFailure::new(code, message) } -fn mcp_request_is_read_only(body: &Value) -> bool { - let method = body.get("method").and_then(Value::as_str); - if matches!(method, Some("initialize" | "notifications/initialized")) { - return true; - } - body.get("params") - .and_then(|params| params.get("name")) - .and_then(Value::as_str) - .is_some_and(|name| { - name.starts_with("get_") - || name.starts_with("review_") - || matches!(name, "search" | "run_scan") - }) -} - fn submit_mcp( - token: &str, + policy: &McpServicePolicy, + credential: &str, session: Option<&str>, payload: &str, request_label: &str, retryable: bool, ) -> Result, String> { let length = payload.len().to_string(); - let authorization = format!("Bearer {token}"); for attempt in 0..2 { let mut headers = vec![ ("accept", "application/json, text/event-stream"), ("content-type", "application/json"), ("content-length", length.as_str()), - ("authorization", authorization.as_str()), + (policy.credential.header.as_str(), credential), ("user-agent", "pocket-pi-agentos/0.1"), ]; if let Some(session) = session { @@ -466,20 +493,20 @@ fn submit_mcp( } let mut connection = connection(Duration::from_secs(12))?; connection - .initiate_request(Method::Post, ROBINHOOD_MCP_URL, &headers) - .map_err(|error| format!("create Robinhood MCP request: {error:?}"))?; + .initiate_request(Method::Post, &policy.url, &headers) + .map_err(|error| format!("create MCP request: {error:?}"))?; let mut request = Request::wrap(connection); request .write_all(payload.as_bytes()) - .map_err(|error| format!("write Robinhood MCP request: {error:?}"))?; + .map_err(|error| format!("write MCP request: {error:?}"))?; request .flush() - .map_err(|error| format!("flush Robinhood MCP request: {error:?}"))?; + .map_err(|error| format!("flush MCP request: {error:?}"))?; let started = Instant::now(); match request.submit() { Ok(response) => { log::info!( - "Robinhood MCP HTTP {request_label} headers status={} in {}ms", + "MCP HTTP {request_label} headers status={} in {}ms", response.status(), started.elapsed().as_millis() ); @@ -491,12 +518,12 @@ fn submit_mcp( && error.0.code() == -esp_idf_svc::sys::ESP_ERR_HTTP_EAGAIN => { log::warn!( - "Robinhood MCP {request_label} received no response headers in {}ms; reconnecting once", + "MCP {request_label} received no response headers in {}ms; reconnecting once", started.elapsed().as_millis() ); } Err(error) => { - return Err(format!("send Robinhood MCP request: {error:?}")); + return Err(format!("send MCP request: {error:?}")); } } } @@ -504,9 +531,11 @@ fn submit_mcp( } fn post_mcp( - token: &str, + policy: &McpServicePolicy, + credential: &str, session: Option<&str>, body: &Value, + retryable: bool, ) -> Result<(Value, Option), String> { let request_label = body .get("params") @@ -516,11 +545,12 @@ fn post_mcp( .unwrap_or("unknown"); let payload = body.to_string(); let mut response = submit_mcp( - token, + policy, + credential, session, &payload, request_label, - mcp_request_is_read_only(body), + retryable, )?; let status = response.status(); let returned_session = response.header("Mcp-Session-Id").map(str::to_owned); @@ -542,13 +572,13 @@ fn post_mcp( read_bounded(&mut response, MAX_MCP_RESPONSE, expected_length)? }; log::info!( - "Robinhood MCP HTTP {request_label} body bytes={} in {}ms", + "MCP HTTP {request_label} body bytes={} in {}ms", bytes.len(), body_started.elapsed().as_millis() ); if !(200..300).contains(&status) { return Err(format!( - "Robinhood MCP HTTP {status}: {}", + "MCP HTTP {status}: {}", String::from_utf8_lossy(&bytes) )); } @@ -557,28 +587,29 @@ fn post_mcp( } fn post_mcp_batch( - token: &str, + policy: &McpServicePolicy, + credential: &str, session: Option<&str>, bodies: &[Value], expected_responses: usize, + retryable: bool, ) -> Result<(Vec, Option), String> { - let payload = serde_json::to_string(bodies) - .map_err(|error| format!("encode Robinhood MCP batch: {error}"))?; - let retryable = bodies.iter().all(mcp_request_is_read_only); - let mut response = submit_mcp(token, session, &payload, "batch", retryable)?; + let payload = + serde_json::to_string(bodies).map_err(|error| format!("encode MCP batch: {error}"))?; + let mut response = submit_mcp(policy, credential, session, &payload, "batch", retryable)?; let status = response.status(); let returned_session = response.header("Mcp-Session-Id").map(str::to_owned); if !(200..300).contains(&status) { let bytes = read_bounded(&mut response, MAX_MCP_RESPONSE, None)?; return Err(format!( - "Robinhood MCP batch HTTP {status}: {}", + "MCP batch HTTP {status}: {}", String::from_utf8_lossy(&bytes) )); } let body_started = Instant::now(); let responses = read_sse_values(&mut response, MAX_MCP_RESPONSE, expected_responses)?; log::info!( - "Robinhood MCP HTTP batch responses={} in {}ms", + "MCP HTTP batch responses={} in {}ms", responses.len(), body_started.elapsed().as_millis() ); @@ -650,11 +681,7 @@ fn read_sse_event( Ok(out) } -fn read_sse_values( - reader: &mut R, - limit: usize, - expected: usize, -) -> Result, String> +fn read_sse_values(reader: &mut R, limit: usize, expected: usize) -> Result, String> where R: embedded_svc::io::Read, { @@ -671,14 +698,14 @@ where && Instant::now() < deadline => { log::info!( - "Robinhood MCP batch waiting for SSE responses ({}/{expected})", + "MCP batch waiting for SSE responses ({}/{expected})", values.len() ); continue; } Err(error) if error.0.code() == -esp_idf_svc::sys::ESP_ERR_HTTP_EAGAIN => { return Err(format!( - "Robinhood MCP batch timed out after receiving {} of {expected} responses", + "MCP batch timed out after receiving {} of {expected} responses", values.len() )); } @@ -707,7 +734,7 @@ where } if values.len() != expected { return Err(format!( - "Robinhood MCP batch returned {} of {expected} responses", + "MCP batch returned {} of {expected} responses", values.len() )); } @@ -715,7 +742,7 @@ where } fn sse_event_end(bytes: &[u8]) -> Option { - // Robinhood sends one complete JSON value on a `data:` line but may keep + // Some MCP servers send one complete JSON value on a `data:` line but keep // the chunked stream open without promptly sending the optional blank // event separator. A terminated data line is already a complete response. for start in 0..bytes.len() { @@ -758,11 +785,11 @@ fn parse_json_or_sse(bytes: &[u8]) -> Result { fn normalize_mcp_result(body: &Value) -> Result { if let Some(error) = body.get("error") { - return Err(format!("Robinhood MCP error: {error}")); + return Err(format!("MCP error: {error}")); } let result = body .get("result") - .ok_or_else(|| "Robinhood MCP response omitted result".to_owned())?; + .ok_or_else(|| "MCP response omitted result".to_owned())?; let text = result .get("content") .and_then(Value::as_array) @@ -771,7 +798,7 @@ fn normalize_mcp_result(body: &Value) -> Result { .find(|item| item.get("type").and_then(Value::as_str) == Some("text")) .and_then(|item| item.get("text")) .and_then(Value::as_str) - .ok_or_else(|| "Robinhood MCP tool returned no text".to_owned())?; + .ok_or_else(|| "MCP tool returned no text".to_owned())?; if result.get("isError").and_then(Value::as_bool) == Some(true) { return Err(text.to_owned()); } diff --git a/firmware/esp32-p4/src/transport/provisioning.rs b/firmware/esp32-p4/src/transport/provisioning.rs index 555ee41..dd706ce 100644 --- a/firmware/esp32-p4/src/transport/provisioning.rs +++ b/firmware/esp32-p4/src/transport/provisioning.rs @@ -1,3 +1,4 @@ +use std::collections::BTreeMap; use std::time::Duration; use pocket_pi_protocols::model::{ @@ -15,8 +16,7 @@ pub struct RuntimeConfig { pub wifi_password: Option, pub model: ModelSettings, pub model_api_key: Option, - pub exa_api_key: Option, - pub robinhood_access_token: Option, + pub app_credentials: BTreeMap, pub initial_prompt: Option, pub initial_prompt_delay_seconds: u64, pub unix_time_seconds: Option, @@ -60,7 +60,9 @@ pub fn request_runtime_config( } ("uart", _) => return Err("UART provider must be codex or claude-code".into()), ("wireless", _) => { - return Err("wireless provider must be openai, openrouter, anthropic or deepseek".into()) + return Err( + "wireless provider must be openai, openrouter, anthropic or deepseek".into(), + ) } _ => return Err("model backend must be uart or wireless".into()), }; @@ -79,8 +81,7 @@ pub fn request_runtime_config( wifi_password: secret(&value, "wifiPassword", 63)?, model, model_api_key, - exa_api_key: secret(&value, "exaApiKey", 512)?, - robinhood_access_token: secret(&value, "robinhoodAccessToken", 4096)?, + app_credentials: app_credentials(&value)?, initial_prompt: string(&value, "initialPrompt")?.map(str::to_owned), initial_prompt_delay_seconds: value .get("initialPromptDelaySeconds") @@ -93,6 +94,31 @@ pub fn request_runtime_config( }) } +fn app_credentials(value: &serde_json::Value) -> Result, String> { + let Some(credentials) = value.get("appCredentials") else { + return Ok(BTreeMap::new()); + }; + let credentials = credentials + .as_object() + .ok_or_else(|| "appCredentials must be an object".to_owned())?; + if credentials.len() > 16 { + return Err("appCredentials has too many entries".into()); + } + credentials + .iter() + .map(|(id, value)| { + if id.is_empty() || id.len() > 128 || !id.is_ascii() { + return Err("appCredentials contains an invalid id".into()); + } + let secret = value + .as_str() + .filter(|secret| !secret.is_empty() && secret.len() <= 4096 && secret.is_ascii()) + .ok_or_else(|| format!("appCredentials.{id} is invalid"))?; + Ok((id.clone(), secret.to_owned())) + }) + .collect() +} + fn text( value: &serde_json::Value, field: &str, diff --git a/hosts/esp32-p4-sim/Cargo.toml b/hosts/esp32-p4-sim/Cargo.toml index 5727f7e..8cba247 100644 --- a/hosts/esp32-p4-sim/Cargo.toml +++ b/hosts/esp32-p4-sim/Cargo.toml @@ -11,6 +11,7 @@ anyhow.workspace = true env_logger = "0.11" log.workspace = true pocket-pi-agentos = { path = "../../crates/pocket-pi-agentos" } +pocket-pi-app-pack = { path = "../../crates/pocket-pi-app-pack" } pocket-pi-embedded = { path = "../../crates/pocket-pi-embedded" } pocket-pi-protocols = { path = "../../crates/pocket-pi-protocols" } pocket-pi-tools = { path = "../../crates/pocket-pi-tools" } diff --git a/hosts/esp32-p4-sim/src/main.rs b/hosts/esp32-p4-sim/src/main.rs index b13f6f2..9188d50 100644 --- a/hosts/esp32-p4-sim/src/main.rs +++ b/hosts/esp32-p4-sim/src/main.rs @@ -8,8 +8,9 @@ use anyhow::{anyhow, Result}; use pocket3d::gpu::{Gpu, OffscreenTarget}; use pocket_pi_agentos::{ AppServiceHost, AppSupervisor, AppToolRequest, HttpRequest, NetFailure, RoutedToolHost, - TransportCompletion, EXA_APP_ID, ROOT_APP_ID, + TransportCompletion, ROOT_APP_ID, }; +use pocket_pi_app_pack::catalog; use pocket_pi_embedded::{AgentEvent, ToolHost}; use pocket_pi_tools::{CoreToolHost, PlatformTools}; use pocket_ui_wgpu::UiRenderer; @@ -96,9 +97,7 @@ fn parse_args() -> Result { root_tap = Some((350, 1110)); ROOT_APP_ID.to_owned() } - "robinhood" => "robinhood".to_owned(), - "exa" => EXA_APP_ID.to_owned(), - value => return Err(anyhow!("unknown App: {value}")), + value => value.to_owned(), } } "--backend" => backend = next(&mut args, "--backend")?, @@ -269,7 +268,7 @@ impl AppServiceHost for SimAppServices { app_id: &str, request: HttpRequest, ) -> std::result::Result { - if app_id != EXA_APP_ID || request.method != "POST" { + if app_id != "exa" || request.method != "POST" { return Err(NetFailure::new( "invalid_request", "simulator denied HTTP request", @@ -344,7 +343,7 @@ impl Product { } }; let services: Arc = Arc::new(SimAppServices); - let mut supervisor = AppSupervisor::new(workspace.clone(), services)?; + let mut supervisor = AppSupervisor::new(workspace.clone(), catalog()?, services)?; supervisor.open(app)?; let native_tools = Arc::new(CoreToolHost::new(workspace.clone(), Arc::new(SimPlatform))); @@ -358,7 +357,7 @@ impl Product { Ok(Self { messages: vec![Message { role: "assistant", - text: "Pocket Pi AgentOS is ready. Robinhood and Exa are installed Apps.".into(), + text: "Pocket Pi AgentOS is ready.".into(), }], agent_status: "IDLE", model_label, @@ -541,6 +540,12 @@ impl Product { "next":schedule_next, "everyMinutes":schedule.every_minutes, }, + "apps":self.supervisor.catalog().descriptors().filter(|app| app.id != ROOT_APP_ID).map(|app| json!({ + "id":app.id, + "title":app.title, + "description":app.description, + "scheduleEveryMinutes":app.schedules.first().map(|schedule| schedule.every_minutes), + })).collect::>(), "settings":{ "wifi":{ "connectedSsid":self.wifi_connected, @@ -850,7 +855,8 @@ mod tests { fn exa_tool_writes_app_owned_sqlite() { init_logs(); let temp = tempfile::tempdir().unwrap(); - let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(SimAppServices)).unwrap(); + let mut supervisor = + AppSupervisor::new(temp.path(), catalog().unwrap(), Arc::new(SimAppServices)).unwrap(); let result = supervisor.invoke_tool( "research.search", r#"{"query":"NVIDIA FY2026 annual report 10-K revenue data center guidance","numResults":5,"includeDomains":["investor.nvidia.com","sec.gov"]}"#, @@ -878,7 +884,8 @@ mod tests { fn exa_write_removes_rows_older_than_seven_days() { init_logs(); let temp = tempfile::tempdir().unwrap(); - let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(SimAppServices)).unwrap(); + let mut supervisor = + AppSupervisor::new(temp.path(), catalog().unwrap(), Arc::new(SimAppServices)).unwrap(); let first = supervisor.invoke_tool("research.search", r#"{"query":"expired search"}"#); assert!(!first.is_error, "{}", first.text); wait_for(|| { @@ -916,7 +923,9 @@ mod tests { fn robinhood_refresh_failure_records_no_view_data() { init_logs(); let temp = tempfile::tempdir().unwrap(); - let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(FailingRobinhood)).unwrap(); + let mut supervisor = + AppSupervisor::new(temp.path(), catalog().unwrap(), Arc::new(FailingRobinhood)) + .unwrap(); supervisor.open("robinhood").unwrap(); let failed = supervisor.invoke_active_task("refreshPortfolio", &Value::Null); @@ -946,7 +955,8 @@ mod tests { fn robinhood_refresh_writes_the_fixed_view_projection() { init_logs(); let temp = tempfile::tempdir().unwrap(); - let mut supervisor = AppSupervisor::new(temp.path(), Arc::new(SimAppServices)).unwrap(); + let mut supervisor = + AppSupervisor::new(temp.path(), catalog().unwrap(), Arc::new(SimAppServices)).unwrap(); supervisor.open("robinhood").unwrap(); let refreshed = supervisor.invoke_tool("robinhood.refresh_portfolio", "{}"); assert!(!refreshed.is_error, "{}", refreshed.text); diff --git a/tools/uart-model-bridge.py b/tools/uart-model-bridge.py index 28eb31b..1c3e7b4 100755 --- a/tools/uart-model-bridge.py +++ b/tools/uart-model-bridge.py @@ -138,17 +138,18 @@ def config(args: argparse.Namespace) -> dict[str, object]: print("DeepSeek: reusing Keychain API key (RAM only on device)", flush=True) else: value["modelApiKey"] = getpass.getpass(f"{provider} API key: ") + app_credentials: dict[str, str] = {} key = exa_api_key() if key: - value["exaApiKey"] = key + app_credentials["exa.api-key"] = key print("Exa: reusing Keychain API key (RAM only on device)", flush=True) elif args.provision_exa: key = getpass.getpass("Exa API key: ") if key: - value["exaApiKey"] = key + app_credentials["exa.api-key"] = key token = robinhood_access_token() if token: - value["robinhoodAccessToken"] = token + app_credentials["robinhood.oauth-access-token"] = token print( "Robinhood: reusing existing authorized Codex MCP session (RAM only)", flush=True, @@ -156,7 +157,9 @@ def config(args: argparse.Namespace) -> dict[str, object]: elif args.provision_robinhood: token = getpass.getpass("Robinhood OAuth access token: ") if token: - value["robinhoodAccessToken"] = token + app_credentials["robinhood.oauth-access-token"] = token + if app_credentials: + value["appCredentials"] = app_credentials if args.prompt: value["initialPrompt"] = args.prompt if args.prompt_delay_seconds: diff --git a/tools/xtask/src/main.rs b/tools/xtask/src/main.rs index 3aa9856..ec73cd5 100644 --- a/tools/xtask/src/main.rs +++ b/tools/xtask/src/main.rs @@ -4,15 +4,26 @@ use std::process::{Command, ExitStatus}; use anyhow::{bail, Context, Result}; fn main() -> Result<()> { - let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../.."); + let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("../..") + .canonicalize()?; let mut args = std::env::args().skip(1); - match (args.next().as_deref(), args.next().as_deref()) { - (Some("build"), Some("agentos-apps")) => build_agentos_apps(&root), + let command_name = args.next(); + let target = args.next(); + let mut rest = args.collect::>(); + let apps = take_apps(&mut rest)?; + match (command_name.as_deref(), target.as_deref()) { + (Some("build"), Some("agentos-apps")) => { + build_embedded_guest(&root)?; + build_agentos_apps(&root, &apps) + } (Some("build"), Some("esp32-p4")) => { build_embedded_guest(&root)?; + build_agentos_apps(&root, &apps)?; command( Command::new("rustup") .current_dir(root.join("firmware/esp32-p4")) + .env("POCKET_PI_APPS", &apps) .args([ "run", "nightly-2026-05-01", @@ -25,33 +36,72 @@ fn main() -> Result<()> { } (Some("build"), Some("esp32-p4-sim")) => { build_embedded_guest(&root)?; - cargo(&root, ["build", "-p", "pocket-pi-esp32-p4-sim"]) + build_agentos_apps(&root, &apps)?; + cargo(&root, &apps, ["build", "-p", "pocket-pi-esp32-p4-sim"]) } (Some("run"), Some("esp32-p4-sim")) => { build_embedded_guest(&root)?; - let rest = args.collect::>(); - cargo_with_args(&root, ["run", "-p", "pocket-pi-esp32-p4-sim", "--"], &rest) + build_agentos_apps(&root, &apps)?; + cargo_with_args( + &root, + &apps, + ["run", "-p", "pocket-pi-esp32-p4-sim", "--"], + &rest, + ) } (Some("snapshot"), Some("esp32-p4-sim")) => { build_embedded_guest(&root)?; + build_agentos_apps(&root, &apps)?; let output = root.join("artifacts/screenshots/esp32-p4-sim.png"); std::fs::create_dir_all(output.parent().unwrap())?; cargo_with_args( &root, + &apps, ["run", "-p", "pocket-pi-esp32-p4-sim", "--"], &["--screenshot".into(), output.display().to_string()], ) } _ => { eprintln!( - "usage:\n cargo xtask build agentos-apps|esp32-p4|esp32-p4-sim\n cargo xtask run esp32-p4-sim [args]\n cargo xtask snapshot esp32-p4-sim" + "usage:\n cargo xtask build agentos-apps|esp32-p4|esp32-p4-sim [--apps robinhood,exa|exa|robinhood|none]\n cargo xtask run esp32-p4-sim [--apps ...] [args]\n cargo xtask snapshot esp32-p4-sim [--apps ...]" ); bail!("unknown xtask command") } } } -fn build_agentos_apps(root: &Path) -> Result<()> { +fn take_apps(args: &mut Vec) -> Result { + let Some(index) = args.iter().position(|arg| arg == "--apps") else { + return Ok("robinhood,exa".into()); + }; + args.remove(index); + let value = args + .get(index) + .cloned() + .context("--apps requires a value")?; + args.remove(index); + selected_apps(&value)?; + Ok(value) +} + +fn selected_apps(value: &str) -> Result> { + if value == "none" { + return Ok(Vec::new()); + } + let mut selected = Vec::new(); + for app in value.split(',') { + if !matches!(app, "robinhood" | "exa") { + bail!("unknown App {app}; expected robinhood, exa, or none"); + } + if selected.contains(&app) { + bail!("duplicate App {app}"); + } + selected.push(app); + } + Ok(selected) +} + +fn build_agentos_apps(root: &Path, apps: &str) -> Result<()> { const POCKETJS_REV: &str = "9c809bbd047ddc75c27caa4990951a78d942477a"; let pocketjs = std::env::var_os("POCKETJS_ROOT") .map(PathBuf::from) @@ -69,7 +119,7 @@ fn build_agentos_apps(root: &Path) -> Result<()> { ); } install_if_missing(&pocketjs)?; - for app in ["pi-agent", "robinhood", "exa"] { + for app in std::iter::once("pi-agent").chain(selected_apps(apps)?) { let app_root = root.join("apps").join(app); command( Command::new("bun") @@ -144,17 +194,26 @@ fn install_if_missing(directory: &Path) -> Result<()> { Ok(()) } -fn cargo(root: &Path, args: [&str; N]) -> Result<()> { +fn cargo(root: &Path, apps: &str, args: [&str; N]) -> Result<()> { command( - Command::new("cargo").current_dir(root).args(args), + Command::new("cargo") + .current_dir(root) + .env("POCKET_PI_APPS", apps) + .args(args), "running cargo", ) } -fn cargo_with_args(root: &Path, base: [&str; N], rest: &[String]) -> Result<()> { +fn cargo_with_args( + root: &Path, + apps: &str, + base: [&str; N], + rest: &[String], +) -> Result<()> { command( Command::new("cargo") .current_dir(root) + .env("POCKET_PI_APPS", apps) .args(base) .args(rest), "running cargo", From af7c94aeb6832742883dd1eea7ef1ceb0872be42 Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Wed, 12 Aug 2026 00:33:55 +0800 Subject: [PATCH 21/24] fix(agentos): keep streaming runtime responsive --- apps/_shared/text.ts | 38 +++---- apps/pi-agent/dist/app.js | 24 ++-- crates/pocket-pi-agentos/src/lib.rs | 22 +++- crates/pocket-pi-app-pack/tests/runtime.rs | 122 +++++++++++++++------ 4 files changed, 134 insertions(+), 72 deletions(-) diff --git a/apps/_shared/text.ts b/apps/_shared/text.ts index 7ca53d1..a5b0c1d 100644 --- a/apps/_shared/text.ts +++ b/apps/_shared/text.ts @@ -5,26 +5,14 @@ import { getOps } from "@pocketjs/framework"; // module so model/provider text does not fall back to missing-glyph boxes. export const DYNAMIC_TEXT_GLYPHS = "‘’“”–—…•"; -const widthCache = new Map(); -const wrapCache = new Map(); const PREVIEW_SOURCE_CHARACTERS = 512; -function width(text: string, fontSlot: number): number { - if (!text) return 0; - const key = fontSlot + "|" + text; - const cached = widthCache.get(key); - if (cached !== undefined) return cached; - const measured = getOps().measureText(text, fontSlot); - widthCache.set(key, measured); - return measured; -} - -function breakToken(token: string, fontSlot: number, maxWidth: number): string[] { +function breakToken(token: string, width: (text: string) => number, maxWidth: number): string[] { const chunks: string[] = []; let chunk = ""; let chunkWidth = 0; for (const character of token) { - const characterWidth = width(character, fontSlot); + const characterWidth = width(character); if (chunk && chunkWidth + characterWidth > maxWidth) { chunks.push(chunk); chunk = ""; @@ -41,22 +29,27 @@ function breakToken(token: string, fontSlot: number, maxWidth: number): string[] // string and insert those newlines before the DrawList reaches native UI. export function wrapLines(text: string, fontSlot: number, maxWidth: number): string[] { void DYNAMIC_TEXT_GLYPHS; - const key = fontSlot + "|" + maxWidth + "|" + text; - const cached = wrapCache.get(key); - if (cached) return cached; - + const widths = new Map(); + const width = (value: string) => { + let measured = widths.get(value); + if (measured === undefined) { + measured = getOps().measureText(value, fontSlot); + widths.set(value, measured); + } + return measured; + }; const lines: string[] = []; - const spaceWidth = width(" ", fontSlot); + const spaceWidth = width(" "); for (const paragraph of text.split("\n")) { const words = paragraph.split(" ").flatMap((token) => - token && width(token, fontSlot) > maxWidth - ? breakToken(token, fontSlot, maxWidth) + token && width(token) > maxWidth + ? breakToken(token, width, maxWidth) : [token], ); let line = ""; let lineWidth = 0; for (const word of words) { - const wordWidth = width(word, fontSlot); + const wordWidth = width(word); if (!line) { line = word; lineWidth = wordWidth; @@ -71,7 +64,6 @@ export function wrapLines(text: string, fontSlot: number, maxWidth: number): str } lines.push(line); } - wrapCache.set(key, lines); return lines; } diff --git a/apps/pi-agent/dist/app.js b/apps/pi-agent/dist/app.js index c38a033..fdb1174 100644 --- a/apps/pi-agent/dist/app.js +++ b/apps/pi-agent/dist/app.js @@ -1,16 +1,16 @@ -(()=>{var kJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return K1(this.context.count)},getNextContextId(){return K1(this.context.count++)}};function K1(J){let Q=String(J),$=Q.length-1;return kJ.context.id+($?String.fromCharCode(96+$):"")+Q}function F1(J){kJ.context=J}function Y6(){return{...kJ.context,id:kJ.getNextContextId(),count:0}}var z6=!1,W6=(J,Q)=>J===Q,k0=Symbol("solid-proxy"),G6=typeof Proxy==="function",H6=Symbol("solid-track"),FQ=Symbol("solid-dev-component"),oJ={equals:W6},M1=null,B6=O1,m=1,fJ=2,U1={owned:null,cleanups:null,context:null,owner:null},S=null,K=null,yJ=null,SJ=null,b=null,C=null,T=null,nJ=0;function tJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?U1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>QJ(()=>$J(z)));S=z,b=null;try{return p(G,!0)}finally{b=$,S=Z}}function g(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return D1($,q)};return[P1.bind($),Z]}function JJ(J,Q,$){let Z=L1(J,Q,!1,m);if(yJ&&K&&K.running)C.push(Z);else eJ(Z)}function bJ(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=L1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,yJ&&K&&K.running)Z.tState=m,C.push(Z);else eJ(Z);return P1.bind(Z)}function j6(J){return p(J,!1)}function QJ(J){if(!SJ&&b===null)return J();let Q=b;b=null;try{if(SJ)return SJ.untrack(J);return J()}finally{b=Q}}function S0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function K6(J){if(K&&K.running)return J(),K.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(yJ||F6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return p(J,!1),b=S=null,Z?Z.done:void 0})}var[MQ,R1]=g(!1),F6;function P1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)eJ(this);else{let Q=C;C=null,p(()=>J0(this),!1),C=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function D1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)p(()=>{for(let q=0;q1e6)throw C=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;$J(J);let Q=nJ;if(V1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{p(()=>{K&&(K.running=!0),b=S=J,V1(J,J.tValue,Q),b=S=null},!1)})}function V1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=m,J.tOwned&&J.tOwned.forEach($J),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach($J),J.owned=null;return J.updatedAt=$+1,g0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)D1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function L1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(S===null);else if(S!==U1)if(K&&K.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(SJ&&X.fn){let z=X.fn,[G,P]=g(void 0,{equals:!1}),D=SJ.factory(z,P);S0(()=>D.dispose());let V,B=()=>K6(P).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),K&&K.running){if(!V)V=SJ.factory(z,B);return V.track(_)}return D.track(_)}}return X}function b0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===fJ)return J0(J);if(J.suspense&&QJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===m)eJ(J);else if((Q?J.tState:J.state)===fJ){let q=C;C=null,p(()=>J0(J,$[0]),!1),C=q}}}function p(J,Q){if(C)return J();let $=!1;if(!Q)C=[];if(T)$=!0;else T=[];nJ++;try{let Z=J();return M6($),Z}catch(Z){if(!$)T=null;C=null,g0(Z)}}function M6(J){if(C){if(yJ&&K&&K.running)U6(C);else O1(C);C=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;T.push.apply(T,K.effects),Q=K.resolve;for(let X of T)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,p(()=>{for(let X of q)$J(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zB6($),!1);if(Q)Q()}function O1(J){for(let Q=0;Q{Z.delete($),p(()=>{K.running=!0,b0($)},!1),K&&(K.running=!1)})}}function J0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)$J(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)A1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)$J(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function A1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return S0(()=>k1(X)),()=>{let P=J()||[],D=P.length,V,B;return P[H6],QJ(()=>{let N,h,a,BJ,IJ,F,j,H,L;if(D===0){if(z!==0)k1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[P6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=F&&H>=F&&Z[j]===P[H];j--,H--)a[H]=q[j],BJ[H]=X[j],G&&(IJ[H]=G[j]);N=new Map,h=Array(H+1);for(B=H;B>=F;B--)L=P[B],V=N.get(L),h[B]=V===void 0?-1:V,N.set(L,B);for(V=F;V<=j;V++)if(L=Z[V],B=N.get(L),B!==void 0&&B!==-1)a[B]=q[V],BJ[B]=X[V],G&&(IJ[B]=G[V]),B=h[B],N.set(L,B);else X[V]();for(B=F;BJ(Q||{}));return F1($),Z}}return QJ(()=>J(Q||{}))}function Q0(){return!0}var O6={get(J,Q,$){if(Q===k0)return $;return J.get(Q)},has(J,Q){if(Q===k0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function w0(J){return!(J=typeof J==="function"?J():J)?{}:J}function I6(){for(let J=0,Q=this.length;J=0;G--){let P=w0(J[G])[z];if(P!==void 0)return P}},has(z){for(let G=J.length-1;G>=0;G--)if(z in w0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let P=Object.getOwnPropertyNames(G);for(let D=P.length-1;D>=0;D--){let V=P[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:I6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],P=Z[G];if(P&&P.get)Object.defineProperty(q,G,P);else q[G]=P?P.value:void 0}return q}var A6=(J)=>`Stale read from <${J}>.`;function jJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return bJ(D6(()=>J.each,J.children,Q||void 0))}function ZJ(J){let Q=J.keyed,$=bJ(()=>J.when,void 0,void 0),Z=Q?$:bJ($,void 0,{equals:(q,X)=>!q===!X});return bJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?QJ(()=>X(Q?q:()=>{if(!QJ(Z))throw A6("Show");return $()})):X}return J.fallback},void 0,void 0)}var _6=(J)=>bJ(()=>J());function k6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:P,getNextSibling:D}){function V(F,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(F,j,L,H);JJ((A)=>B(F,j(),A,H),L)}function B(F,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=h(F,H,L,O)}else if(H!==""&&typeof H==="string")Z(P(F),H=j);else h(F,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=h(F,H,L);else if(k==="function")return JJ(()=>{let O=j();while(typeof O==="function")O=O();H=B(F,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return JJ(()=>H=B(F,O,H,L,!0)),()=>H;if(O.length===0){let TJ=h(F,H,L);if(I)return H=TJ}else if(Array.isArray(H))if(H.length===0)a(F,O,L);else N(F,H,O);else if(H==null||H==="")a(F,O);else N(F,I&&H||[P(F)],O);H=O}else{if(Array.isArray(H)){if(I)return H=h(F,H,L,j);h(F,H,null,j)}else if(H==null||H===""||!P(F))q(F,j);else BJ(F,j,P(F));H=j}return H}function _(F,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let KQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let TJ=G(O)===F;if(!k&&!I)TJ?BJ(F,A,O):q(F,A,H);else TJ&&X(F,O)}else k=!0}}else q(F,A,H);return[A]}function a(F,j,H){for(let L=0,A=j.length;LH.children=B(F,j.children,H.children));return JJ(()=>j.ref&&j.ref(F)),JJ(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(F,A,k,H[A]),H[A]=k}}),H}return{render(F,j){let H;return tJ((L)=>{H=L,V(j,F())}),H},insert:V,spread(F,j,H){if(typeof j==="function")JJ((L)=>IJ(F,j(),L,H));else IJ(F,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(F,j,H,L){return z(F,j,H,L),H},mergeProps:S1,effect:JJ,memo:_6,createComponent:L6,use(F,j,H){return QJ(()=>F(j,H))}}}function S6(J){let Q=k6(J);return Q.mergeProps=S1,Q}var b1=480,g1=272,KJ={view:0,text:1,image:2},b6=1,g6=-1,w6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},C6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},E6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},N6=1,UQ=2,RQ=1,PQ=2,DQ=131072,VQ=1,LQ=262144,OQ=1,IQ=1,AQ=1,_Q=2,kQ=4,SQ=8,bQ=16,gQ=1,wQ=2;function w1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var CQ=1,h6=1263551300,T6=1,f6=32,y6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},FJ=32896,EQ=0.016666666666666666;function C1(J){return J.__viewport??null}var C0=null;function x6(){return null}function E1(J,Q=x6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function v6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return E1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return E1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function m6(J){C0=J}function gJ(){if(!C0)throw Error("PocketJS: host not installed — call render() first");return C0}function E(){return gJ().ops}function u6(J){globalThis.frame=J}function l6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function c6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return w1($>>>16&255,$>>>8&255,$&255,255);return w1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function p6(J,Q){let $=C6[J];if(typeof Q==="string"){if($===U.color)return c6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var $0=60,N1=[1,2,3,4,5,6,10,12,15,20,30,60],E0=$0,qJ=-1,d6=0,xJ=[];function i6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=N1[0];for(let $ of N1)if(Math.abs($-J)Q.at<=qJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>qJ);for(let Q of J)Q.cb()}var N0=0.12,Z0=FJ;function o6(J){Z0=J===void 0?FJ:J&65535}function n6(){Z0=FJ}function f1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function e6(){return f1(Z0&255)}var y1=new Set,J8=0;function Q8(){y1.clear(),J8=0,n6()}function $8(J){for(let Q of[...y1])Q(J)}var MJ=null,x1=null;function Z8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function v1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){h0();let Q=MJ?MJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return x1.slice(Q.off,Q.off+Q.len)}var mJ=null,w=null,UJ=null,q0=0,RJ=[],f0=[],y0=[];function u1(J){if(mJ=J,w=null,UJ=null,q0=0,RJ.length=0,f0.length=0,y0.length=0,l){if(l.pressTarget=null,l.target=null,l.spriteDirty=!0,l.fresh=!0,l.vw=0,l.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(l.tex),l.tex=-1}}}function X8(J,Q){J.onPress=Q??void 0}function Y8(J,Q){if(J.focusable=Q,i1(),!Q&&w===J)x(null)}function x(J){if(UJ&&UJ!==J)PJ(null);w=J,E().setFocus(J?J.id:0)}function PJ(J){if(UJ===J)return;let Q=E();if(UJ)Q.setActive?.(UJ.id,0);if(UJ=J,J)Q.setActive?.(J.id,1)}function x0(){return RJ.length>0?RJ[RJ.length-1]:mJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function G8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=f0.length-1;Q>=0;Q--){let $=f0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function H8(J){let Q=G8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(w)x(null);return!0}let Z=Q.columns,q=w?$.indexOf(w):-1;if(q<0)return x(l1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function B8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=y0.length-1;Q>=0;Q--){let $=y0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function X0(J){let Q=B8();if(Q&&Q.move(J))return;if(H8(J))return;W8(J)}function c1(){p1(w)}function p1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){PJ(J)}function j8(J){x(J),p1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=m0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var l=null,d1=0;function i1(){d1++}var F8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],M8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function U8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=F8[Q]>>$&1,q=M8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function R8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):P8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(U8(),16,16,E6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function P8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&N6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var W0=null;function s1(J){W0=J}function a1(J){let Q=RJ.length>0?RJ[RJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function r1(J,Q,$){return a1(o1(J,Q,$))}function o1(J,Q,$){if($!==void 0)return $===0?null:z0(W0??mJ,$);let Z=E(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(W0??mJ,q(J,Q))}function D8(J,Q,$){let Z=l,q=E();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=C1(q);if(Z.vw=B?B.w:b1,Z.vh=B?B.h:g1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)R8(Z,q);let X=t6()*Z.speed,z=e6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=s6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),N=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||N!==Z.y)Z.x=_,Z.y=N,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let P=(Q|$)&Z.button,D=d1;if(G||P!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=a1(z0(W0??mJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==w)x(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(PJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,PJ(null),B)c1()}}else if($&Z.button)PJ(null);return!0}function V8(J){let Q=J&~q0,$=q0&~J;if(q0=J,l&&D8(J,Q,$))return;if($&d.CIRCLE)PJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)PJ(w),c1()}var u0=null;function n1(J){u0=J}function wJ(){if(i1(),u0)u0()}function L8(J,Q){J.debugName=Q||void 0,wJ()}var XJ={id:b6,type:KJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},t1=Symbol.for("pocketjs.native-node"),l0=1,uJ=3,o=8,O8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function G0(J){return J.domAttrs??={}}function e1(J,Q){let $=J.domNodeType??(lJ(J)?uJ:l0),Z=$===uJ?H0(J.text??""):$===o?_8(J.domData??""):Y4(J.domTag??j0(J));for(let q of Object.keys(J.domAttrs??{}))c0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)YJ(Z,e1(q,!0));return Z}function c0(J,Q,$){if(O8.has(Q)){EJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete G0(J)[Q];else G0(J)[Q]=$}function p0(J){if(J[t1]===!0)return J;return Object.defineProperty(J,t1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(lJ(J)?uJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(lJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(lJ(J))B0(J,Z);else if(E8(J),Z)YJ(J,H0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return W4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??j0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===uJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??j0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){EJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===XJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return YJ(J,$),$},insertBefore($,Z){return YJ(J,$,Z??null),$},removeChild($){return cJ(J,$),$},replaceChild($,Z){return YJ(J,$,Z),cJ(J,Z),Z},cloneNode($=!1){return e1(J,!!$)},remove(){if(J.parent)cJ(J.parent,J)},setAttribute($,Z){c0(J,$,Z)},removeAttribute($){c0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}p0(XJ);var d0=null;function I8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},J4=new Map;function Q4(J,Q){J4.set(J,Q)}var $4=new Map;function Z4(J,Q){$4.set(J,Q)}var CJ=new Set,A8=new Set;function q4(J){if(!J)return!1;if(A8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return p0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function H0(J){let Q=E(),$=Q.createNode(KJ.text);return Q.setText($,J),p0({id:$,type:KJ.text,parent:null,children:[],text:J,domNodeType:uJ,domTag:"#text"})}function _8(J=""){let Q=H0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){E().replaceText(J.id,Q),J.text=Q,wJ()}function lJ(J){return J.type===KJ.text}function z4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function YJ(J,Q,$){let Z=E();if(z4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function cJ(J,Q){if(!Q)return;K8(Q),E().removeChild(J.id,Q.id),z4(Q),CJ.add(Q),wJ()}function k8(J){return J.parent??void 0}function S8(J){return J.children[0]}function W4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function b8(J,Q){let $=E();if(wJ(),Q==null||Q===""){$.setStyle(J.id,g6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function g8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=J4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function w8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=$4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function C8(J,Q,$){let Z=E(),q=Q??{},X=$??{},z=!1;for(let G in q){let P=q[G];if(X[G]===P)continue;let D=w6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,p6(G,P)),z=!0}if(z)wJ()}function EJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete G0(J)[Q];else G0(J)[Q]=$;switch(Q){case"class":return b8(J,$),$;case"onPress":case"on:press":return X8(J,$),$;case"src":return g8(J,$),$;case"sprite":return w8(J,$),$;case"style":return C8(J,$,Z),$;case"focusable":return Y8(J,!!$),$;case"debugName":return L8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${j0(J)}>`)}function E8(J){for(let Q of[...J.children])cJ(J,Q)}function j0(J){for(let Q of Object.keys(KJ))if(KJ[Q]===J.type)return Q;return String(J.type)}function N8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}EJ(J,Q,$,Z)}var h8=S6({createElement:Y4,createTextNode:H0,replaceText:B0,isTextNode:lJ,setProperty:N8,insertNode(J,Q,$){YJ(J,Q,$)},removeNode(J,Q){cJ(J,Q)},getParentNode:k8,getFirstChild:S8,getNextSibling:W4}),{render:T8,effect:NQ,memo:c,createComponent:Y,createElement:G4,insert:hQ,spread:f8,mergeProps:TQ,use:fQ}=h8,yQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},y8=null;function H4(J){y8=J}function x8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function B4(J,Q){let $=G4(J);return f8($,Q,!1),x8(Q.nodeRef,$),$}function M(J){return B4("view",J)}function R(J){return B4("text",J)}var xQ=new WeakMap,vQ=new WeakMap,v8={}!==null?Object.freeze({...{}}):Object.freeze({}),mQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:v8}),uQ=new Map,zJ=36000,s0=30,m8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(zJ),tapeAnalog:new Uint16Array(zJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function u8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-s0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)n1(()=>{W.treeDirty=!0}),r8();else n1(null);globalThis.__pocketDevtools=n8}function l8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)p8(),s8();let X=Q,z=$===void 0?FJ:$&65535,G=Z,P=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(zJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==FJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function F4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function M4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return F4(J.masks,0,Q)}function U4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return F4(J.analog??[],FJ,Q)}function R4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,f({t:"hello",app:W.app,host:o8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` -`))if(q.trim())d8(q)}}function d8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)f({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),a0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":P4();break;case"eval":{let Z=!0,q;try{q=K0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}f({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":f({t:"tape",tape:K4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}f({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())f({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else f({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=M4(Z),W.replayAnalog=Z.analog?U4(Z):null,W.replayTouch=Z.touch?R4(Z):null,W.replayAt=0;break}default:break}}function i8(){if(W.treeDirty&&W.frame-W.treeSentAt>=s0)P4();if(W.frame%m8===0)a0()}function s8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,f({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,f({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){f({t:"stats",frame:W.frame,nodes:L4(XJ),tapeLen:W.tapeLen,paused:W.paused})}function P4(){W.treeDirty=!1,W.treeSentAt=W.frame,f({t:"tree",frame:W.frame,root:V4(XJ)})}function a8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(a8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function D4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function V4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(D4(J,(q)=>{if(q.domNodeType===8)return;Z.push(V4(q))}),Z.length)Q.k=Z;return Q}function L4(J){let Q=1;return D4(J,($)=>{Q+=L4($)}),Q}function r8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{f({t:"log",level:$,args:q.map((X)=>K0(X))}),Z?.apply(Q,q)}}}function K0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?O4(X):JSON.stringify(O4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>K0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${K0(z,Q+1)}`).join(", ")}}`}function O4(J){return J.length>200?J.slice(0,199)+"…":J}function o8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var n8={get frame(){return W.frame},dumpTape:()=>K4(),replay:(J)=>{W.replayMasks=M4(J),W.replayAnalog=J.analog?U4(J):null,W.replayTouch=J.touch?R4(J):null,W.replayAt=0}},I4=new Map,o0=new Map;function A4(J){return J.trim().replace(/\s+/g," ")}function _4(J){return J.split(" ").sort().join(" ")}var k4=-1;function t8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=A4(Q);I4.set(Z,$);let q=_4(Z),X=o0.get(q);o0.set(q,X!==void 0&&X!==$?k4:$)}}function e8(J){let Q=A4(J),$=I4.get(Q);if($!==void 0)return $;let Z=o0.get(_4(Q));return Z===k4?void 0:Z}var n0=9,J2=(1<{let q=($&$2)!==0,X=q?t0:n0,z=q?Z2:J2;return Object.freeze({id:$>>>(q?q2:Q2)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Y2(){return F0}function z2(){F0=e0}var S4=8,WJ=8,W2=3,G2=8,H2=6,B2=0.5,s=1,pJ=2,J1=4,DJ=8,NJ=[],b4=0,M0=0,GJ=Array.from({length:S4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(WJ),histY:new Int16Array(WJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function j2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function K2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=o1(Q,$,Z.fact);let G=Z.hit;if(G)return j2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=NJ[z];if(G.disposed)continue;if(b4>0&&!G.opts.allowWhenBlocked)continue;if(!K2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function U2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%WJ,J.histLenz||Z>z))q.flags[J.slot]|=pJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(pJ|J1))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??B2)*h1()));if(J.frames=0)NJ.splice($,1)},cancel(){if(!Q.disposed)C4(Q)},get panning(){for(let $ of GJ)if($.used&&Q.flags[$.slot]&DJ)return!0;return!1}}}function L2(J){let Q=V2(J);return S0(()=>Q.dispose()),Q}function E4(){NJ.length=0,b4=0,M0=0;for(let J of GJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function O2(){return L2({onDown:(J)=>{let Q=r1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=r1(J.x,J.y,J.hit);if(Q)j8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var I2=1,Q1=new Map,U0=[];function A2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function _2(){I2=1,Q1.clear(),U0=[]}function k2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),A2()?.({t:"delivery",frame:T1(),id:Q,kind:Z.kind}),Z.onResult($)}}var N4=new Set;function S2(){if(N4.size===0)return;for(let J of N4)J()}var b2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[28] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-base text-orange-600 font-bold":9,"h-[76] pt-3 text-lg text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-base text-emerald-700 font-bold":13,"h-[84] pt-3 text-lg text-slate-900":14,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":15,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":16,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":17,"text-base text-slate-600 font-bold":18,"pt-6 text-lg text-slate-500":19,"pt-6 text-lg text-slate-900 font-bold":20,"h-[146] px-6 pt-7 flex-col bg-slate-50":21,"h-[80]":22,"h-[1060] px-6 pt-5 flex-col":23,"h-[48] px-4 justify-center bg-slate-100":24,"text-base text-slate-600":25,"pt-[10] flex-col gap-[12]":26,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":27,"w-[48] h-[48] items-center justify-center bg-blue-100":28,"w-[48] h-[48] items-center justify-center bg-emerald-100":29,"text-lg text-blue-700 font-bold":30,"text-lg text-emerald-700 font-bold":31,"w-[474] flex-col gap-2":32,"text-lg text-slate-900 font-bold":33,"text-base text-slate-500":34,"pt-20 pl-10 text-lg text-slate-500":35,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":36,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":37,"h-[1060] px-6 pt-7 flex-col gap-4":38,"text-base text-slate-500 font-bold":39,"h-[214] px-7 items-center justify-center bg-slate-100":40,"text-lg text-slate-500 font-bold":41,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":42,"flex-row items-center gap-5":43,"w-[68] h-[68] items-center justify-center bg-orange-100":44,"text-xl text-orange-700 font-bold":45,"w-[500] flex-col gap-2":46,"text-xl text-slate-900 font-bold":47,"text-lg text-slate-600":48,"text-2xl text-orange-600":49,"mt-4 h-[112] px-6 justify-center bg-slate-100":50,"relative h-[154] px-5 pt-5 flex-col bg-white":51,"pt-3 text-lg text-orange-600 font-bold":52,"pt-3 text-base text-slate-500":53,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":54,"text-lg text-white font-bold":55,"h-[40] pt-3 text-base text-slate-500":56,"h-[470] flex-col gap-2":57,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":58,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":59,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":60,"h-[160] px-5 pt-5 flex-col bg-white":61,"pt-3 text-lg text-slate-900 font-bold":62,"pt-3 text-base text-slate-600":63,"h-[108] pt-7 flex-row gap-4":64,"w-[316] h-[80] items-center justify-center bg-slate-100":65,"w-[340] h-[80] items-center justify-center bg-red-100":66,"text-lg text-red-500 font-bold":67,"h-[1052] px-6 pt-5 flex-col":68,"h-[270] px-[22] pt-6 bg-white":69,"text-lg text-slate-900":70,"text-lg text-slate-400":71,"h-[86] px-1 flex-row items-center justify-between":72,"w-[132] h-[58] items-center justify-center bg-slate-300":73,"w-[132] h-[58] items-center justify-center bg-slate-100":74,"text-base text-slate-900 font-bold":75,"h-[140] flex-row gap-2":76,"grow h-[120] items-center justify-center bg-slate-300":77,"grow h-[120] items-center justify-center bg-white":78,"w-[104] h-[120] items-center justify-center bg-slate-300":79,"w-[104] h-[120] items-center justify-center bg-slate-100":80,"h-[176] flex-row gap-2":81,"w-[92] h-[156] items-center justify-center bg-slate-300":82,"w-[92] h-[156] items-center justify-center bg-slate-100":83,"w-[300] h-[156] items-center justify-center bg-slate-300":84,"w-[300] h-[156] items-center justify-center bg-slate-100":85,"w-[144] h-[156] items-center justify-center bg-slate-300":86,"w-[144] h-[156] items-center justify-center bg-slate-100":87,"w-[112] h-[156] items-center justify-center bg-emerald-700":88,"w-[112] h-[156] items-center justify-center bg-emerald-500":89,"text-base text-slate-950 font-bold":90,"h-[108] px-6 py-3 flex-col bg-slate-50":91,"h-[84] items-center justify-center bg-slate-300":92,"h-[84] items-center justify-center bg-slate-100":93,"h-[1168] px-6 pt-5 flex-col":94,"h-[82] px-4 justify-center bg-white":95,"w-[584] h-[900] px-5 pt-5 bg-slate-950":96,"text-base text-slate-200":97,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":98,"text-lg text-orange-600 font-bold":99,"w-[584] h-[900] px-5 pt-5 bg-white":100,"text-base text-slate-900":101,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":102,"absolute inset-0 z-50 flex-col items-center justify-center":103,"absolute inset-0 bg-slate-950":104,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":105,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":106,"flex-row flex-wrap":107,grow:108,"text-2xl text-white font-bold":109,"text-2xl text-slate-950 font-bold":110,"px-6":111,"px-6 py-5":112,"gap-4":113,"rounded-xl shadow bg-white border-slate-100":114,"rounded-xl shadow bg-emerald-100 border-emerald-500":115,"bg-white":116,"bg-slate-100":117,"bg-slate-950":118,"px-3 py-2 rounded-lg bg-slate-100":119,"px-3 py-2 rounded-lg bg-indigo-100":120,"text-base text-indigo-700 font-bold":121,"px-3 py-2 rounded-lg bg-emerald-100":122,"px-3 py-2 rounded-lg bg-amber-100":123,"text-base text-amber-700 font-bold":124,"px-3 py-2 rounded-lg bg-red-100":125,"text-base text-red-500 font-bold":126,"w-[34] h-[34] rounded-lg bg-amber-400":127,"w-[34] h-[34] rounded-lg bg-red-500":128,"w-[34] h-[34] rounded-lg bg-slate-800":129,"w-[34] h-[34] rounded-lg bg-emerald-500":130,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":131,"flex-row items-center gap-4":132,"w-[34] text-2xl text-white font-bold":133,"w-[332] flex-col items-end gap-2":134,"text-base text-slate-300 font-bold":135,"text-base text-slate-400":136,"h-[166] px-6 pt-6 flex-col gap-3":137,"h-[44] px-1 flex-row items-center justify-between":138,"w-full h-full items-center justify-center rounded-xl bg-slate-200":139,"w-full h-full items-center justify-center rounded-xl bg-red-100":140,"w-full h-full items-center justify-center rounded-xl bg-slate-100":141,"w-full h-full items-center justify-center rounded-xl bg-orange-600":142,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":143,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":144,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":145,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":146,"text-2xl text-indigo-700 font-bold":147,"text-2xl text-slate-600 font-bold":148,"pt-7 text-2xl text-slate-900 font-bold":149,"pt-4 text-lg text-slate-500":150,"text-xl text-emerald-600 font-bold":151,"text-xl text-red-500 font-bold":152,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":153,"text-base text-red-300":154,"text-base text-slate-300":155,"text-base text-red-500":156,"w-full h-full px-6 flex-row items-center bg-slate-950":157,"w-full h-full flex-row items-center":158};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var g2="ui:styles",w2="ui:font.",h4="ui:img.",T4="ui:sprite.";function C2(){return globalThis.ui}function E2(J){if(J.__textures)return;for(let Q of T0(h4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)Q4(Q.slice(h4.length),Z)}}function N2(J){if(J.__sprites)return;for(let Q of T0(T4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),P=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)Z4(Q.slice(T4.length),{handle:V,frames:G,cols:P,step:D})}}function f4(J){let Q=G4("view");return EJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function h2(J,Q){if(!R0||!P0)return;EJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),EJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function T2(J,Q={}){let $=v6(Q.ops);if(m6($),I8(e8),Q.styles)t8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)Q4(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)Z4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)m1(Q.pak);if(q8()){for(let B of T0())if(B===g2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(w2))$.ops.loadFontAtlas?.(vJ(B))}}let q=C1($.ops),X=q?.w??b1,z=q?.h??g1,G=f4({width:X,height:z,overflow:u.Overflow.Hidden}),P=f4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});YJ(XJ,G),YJ(XJ,P),H4(P),R0=G,P0=P,u1(G),s1(XJ),Q8(),E4(),O2(),a6(),_2(),u8($.ops),u6(l8((B,_,N,h)=>{r6(),o6(_),X2(N,h),S2(),k2(),D2(),$8(B),V8(B),X4()}));let D=T8(J,G),V=l6(h2);return()=>{V(),z2(),E4(),D(),u1(null),s1(null),H4(null),R0=null,P0=null;for(let B of XJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);X4()}}function f2(J,Q={}){let $=Q.ops??C2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)m1(Q.pak);return E2($),N2($),T2(J,{ops:$,styles:Q.styles??b2,pak:Q.pak})}var y2="$b",x2=65536,y4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function u2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function x4(){let J=u2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function l2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,x2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=v2(z.data[y2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function c2(J,Q){let $=l2(x4(),J);return Q==="utf8"||Q==="utf-8"?m2($):$}function p2(J,Q){let $=x4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var d2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"};function i2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(M,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(M,{class:"flex-row items-center gap-4",get children(){return[c(()=>c(()=>!!J.back)()?Y(R,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(M,{get["class"](){return Q()}})),Y(R,{get["class"](){return d2.appTitle},get children(){return J.title}})]}}),Y(M,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(R,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(R,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function s2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(M,{get["class"](){return Q()},get children(){return Y(R,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(M,{get["class"](){return J.top},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(M,{get["class"](){return J.bottom},get children(){return Y(R,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var lQ="‘’“”–—…•",v4=new Map,m4=new Map,a2=512;function D0(J,Q){if(!J)return 0;let $=Q+"|"+J,Z=v4.get($);if(Z!==void 0)return Z;let q=E().measureText(J,Q);return v4.set($,q),q}function r2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=D0(z,Q);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function $1(J,Q,$){let Z=Q+"|"+$+"|"+J,q=m4.get(Z);if(q)return q;let X=[],z=D0(" ",Q);for(let G of J.split(` -`)){let P=G.split(" ").flatMap((B)=>B&&D0(B,Q)>$?r2(B,Q,$):[B]),D="",V=0;for(let B of P){let _=D0(B,Q);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return m4.set(Z,X),X}function Z1(J,Q,$,Z){let q=J.slice(0,a2),X=$1(q,Q,$);if(q.length===J.length&&X.length<=Z)return X.join(` +(()=>{var SJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return j1(this.context.count)},getNextContextId(){return j1(this.context.count++)}};function j1(J){let Q=String(J),$=Q.length-1;return SJ.context.id+($?String.fromCharCode(96+$):"")+Q}function K1(J){SJ.context=J}function Z6(){return{...SJ.context,id:SJ.getNextContextId(),count:0}}var q6=!1,X6=(J,Q)=>J===Q,_0=Symbol("solid-proxy"),Y6=typeof Proxy==="function",z6=Symbol("solid-track"),BQ=Symbol("solid-dev-component"),oJ={equals:X6},F1=null,W6=L1,m=1,TJ=2,M1={owned:null,cleanups:null,context:null,owner:null},k=null,K=null,xJ=null,kJ=null,b=null,C=null,f=null,nJ=0;function tJ(J,Q){let $=b,Z=k,q=J.length===0,X=Q===void 0?Z:Q,z=q?M1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>QJ(()=>$J(z)));k=z,b=null;try{return p(G,!0)}finally{b=$,k=Z}}function g(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return P1($,q)};return[R1.bind($),Z]}function JJ(J,Q,$){let Z=V1(J,Q,!1,m);if(xJ&&K&&K.running)C.push(Z);else eJ(Z)}function bJ(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=V1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,xJ&&K&&K.running)Z.tState=m,C.push(Z);else eJ(Z);return R1.bind(Z)}function G6(J){return p(J,!1)}function QJ(J){if(!kJ&&b===null)return J();let Q=b;b=null;try{if(kJ)return kJ.untrack(J);return J()}finally{b=Q}}function S0(J){if(k===null);else if(k.cleanups===null)k.cleanups=[J];else k.cleanups.push(J);return J}function H6(J){if(K&&K.running)return J(),K.done;let Q=b,$=k;return Promise.resolve().then(()=>{b=Q,k=$;let Z;if(xJ||B6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return p(J,!1),b=k=null,Z?Z.done:void 0})}var[jQ,U1]=g(!1),B6;function R1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)eJ(this);else{let Q=C;C=null,p(()=>J0(this),!1),C=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function P1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)p(()=>{for(let q=0;q1e6)throw C=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;$J(J);let Q=nJ;if(D1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{p(()=>{K&&(K.running=!0),b=k=J,D1(J,J.tValue,Q),b=k=null},!1)})}function D1(J,Q,$){let Z,q=k,X=b;b=k=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=m,J.tOwned&&J.tOwned.forEach($J),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach($J),J.owned=null;return J.updatedAt=$+1,b0(z)}finally{b=X,k=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)P1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function V1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:k,context:k?k.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(k===null);else if(k!==M1)if(K&&K.running&&k.pure)if(!k.tOwned)k.tOwned=[X];else k.tOwned.push(X);else if(!k.owned)k.owned=[X];else k.owned.push(X);if(kJ&&X.fn){let z=X.fn,[G,R]=g(void 0,{equals:!1}),D=kJ.factory(z,R);S0(()=>D.dispose());let V,B=()=>H6(R).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),K&&K.running){if(!V)V=kJ.factory(z,B);return V.track(_)}return D.track(_)}}return X}function k0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===TJ)return J0(J);if(J.suspense&&QJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===m)eJ(J);else if((Q?J.tState:J.state)===TJ){let q=C;C=null,p(()=>J0(J,$[0]),!1),C=q}}}function p(J,Q){if(C)return J();let $=!1;if(!Q)C=[];if(f)$=!0;else f=[];nJ++;try{let Z=J();return j6($),Z}catch(Z){if(!$)f=null;C=null,b0(Z)}}function j6(J){if(C){if(xJ&&K&&K.running)K6(C);else L1(C);C=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;f.push.apply(f,K.effects),Q=K.resolve;for(let X of f)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,p(()=>{for(let X of q)$J(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zW6($),!1);if(Q)Q()}function L1(J){for(let Q=0;Q{Z.delete($),p(()=>{K.running=!0,k0($)},!1),K&&(K.running=!1)})}}function J0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)$J(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)I1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)$J(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function I1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return S0(()=>_1(X)),()=>{let R=J()||[],D=R.length,V,B;return R[z6],QJ(()=>{let E,N,a,BJ,IJ,F,j,H,L;if(D===0){if(z!==0)_1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[M6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=F&&H>=F&&Z[j]===R[H];j--,H--)a[H]=q[j],BJ[H]=X[j],G&&(IJ[H]=G[j]);E=new Map,N=Array(H+1);for(B=H;B>=F;B--)L=R[B],V=E.get(L),N[B]=V===void 0?-1:V,E.set(L,B);for(V=F;V<=j;V++)if(L=Z[V],B=E.get(L),B!==void 0&&B!==-1)a[B]=q[V],BJ[B]=X[V],G&&(IJ[B]=G[V]),B=N[B],E.set(L,B);else X[V]();for(B=F;BJ(Q||{}));return K1($),Z}}return QJ(()=>J(Q||{}))}function Q0(){return!0}var D6={get(J,Q,$){if(Q===_0)return $;return J.get(Q)},has(J,Q){if(Q===_0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function g0(J){return!(J=typeof J==="function"?J():J)?{}:J}function V6(){for(let J=0,Q=this.length;J=0;G--){let R=g0(J[G])[z];if(R!==void 0)return R}},has(z){for(let G=J.length-1;G>=0;G--)if(z in g0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let R=Object.getOwnPropertyNames(G);for(let D=R.length-1;D>=0;D--){let V=R[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:V6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],R=Z[G];if(R&&R.get)Object.defineProperty(q,G,R);else q[G]=R?R.value:void 0}return q}var L6=(J)=>`Stale read from <${J}>.`;function jJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return bJ(U6(()=>J.each,J.children,Q||void 0))}function ZJ(J){let Q=J.keyed,$=bJ(()=>J.when,void 0,void 0),Z=Q?$:bJ($,void 0,{equals:(q,X)=>!q===!X});return bJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?QJ(()=>X(Q?q:()=>{if(!QJ(Z))throw L6("Show");return $()})):X}return J.fallback},void 0,void 0)}var O6=(J)=>bJ(()=>J());function I6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:R,getNextSibling:D}){function V(F,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(F,j,L,H);JJ((A)=>B(F,j(),A,H),L)}function B(F,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let S=typeof j,I=L!==void 0;if(S==="string"||S==="number"){if(S==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=N(F,H,L,O)}else if(H!==""&&typeof H==="string")Z(R(F),H=j);else N(F,H,L,Q(j)),H=j}else if(j==null||S==="boolean")H=N(F,H,L);else if(S==="function")return JJ(()=>{let O=j();while(typeof O==="function")O=O();H=B(F,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return JJ(()=>H=B(F,O,H,L,!0)),()=>H;if(O.length===0){let fJ=N(F,H,L);if(I)return H=fJ}else if(Array.isArray(H))if(H.length===0)a(F,O,L);else E(F,H,O);else if(H==null||H==="")a(F,O);else E(F,I&&H||[R(F)],O);H=O}else{if(Array.isArray(H)){if(I)return H=N(F,H,L,j);N(F,H,null,j)}else if(H==null||H===""||!R(F))q(F,j);else BJ(F,j,R(F));H=j}return H}function _(F,j,H){let L=!1;for(let A=0,S=j.length;Ar-O){let HQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let fJ=G(O)===F;if(!S&&!I)fJ?BJ(F,A,O):q(F,A,H);else fJ&&X(F,O)}else S=!0}}else q(F,A,H);return[A]}function a(F,j,H){for(let L=0,A=j.length;LH.children=B(F,j.children,H.children));return JJ(()=>j.ref&&j.ref(F)),JJ(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let S=j[A];if(S===H[A])continue;z(F,A,S,H[A]),H[A]=S}}),H}return{render(F,j){let H;return tJ((L)=>{H=L,V(j,F())}),H},insert:V,spread(F,j,H){if(typeof j==="function")JJ((L)=>IJ(F,j(),L,H));else IJ(F,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(F,j,H,L){return z(F,j,H,L),H},mergeProps:S1,effect:JJ,memo:O6,createComponent:P6,use(F,j,H){return QJ(()=>F(j,H))}}}function A6(J){let Q=I6(J);return Q.mergeProps=S1,Q}var k1=480,b1=272,KJ={view:0,text:1,image:2},_6=1,S6=-1,k6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},b6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},l={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},g6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},w6=1,KQ=2,FQ=1,MQ=2,UQ=131072,RQ=1,PQ=262144,DQ=1,VQ=1,LQ=1,OQ=2,IQ=4,AQ=8,_Q=16,SQ=1,kQ=2;function g1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var bQ=1,C6=1263551300,h6=1,E6=32,N6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},FJ=32896,gQ=0.016666666666666666;function w1(J){return J.__viewport??null}var w0=null;function f6(){return null}function C1(J,Q=f6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function T6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return C1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return C1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function x6(J){w0=J}function gJ(){if(!w0)throw Error("PocketJS: host not installed — call render() first");return w0}function h(){return gJ().ops}function y6(J){globalThis.frame=J}function v6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function m6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return g1($>>>16&255,$>>>8&255,$&255,255);return g1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function l6(J,Q){let $=b6[J];if(typeof Q==="string"){if($===U.color)return m6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var $0=60,h1=[1,2,3,4,5,6,10,12,15,20,30,60],C0=$0,qJ=-1,u6=0,yJ=[];function c6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=h1[0];for(let $ of h1)if(Math.abs($-J)Q.at<=qJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;yJ=yJ.filter((Q)=>Q.at>qJ);for(let Q of J)Q.cb()}var h0=0.12,Z0=FJ;function s6(J){Z0=J===void 0?FJ:J&65535}function a6(){Z0=FJ}function f1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function o6(){return f1(Z0&255)}var T1=new Set,n6=0;function t6(){T1.clear(),n6=0,a6()}function e6(J){for(let Q of[...T1])Q(J)}var MJ=null,x1=null;function J8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function y1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){E0();let Q=MJ?MJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return x1.slice(Q.off,Q.off+Q.len)}var mJ=null,w=null,UJ=null,q0=0,RJ=[],f0=[],T0=[];function m1(J){if(mJ=J,w=null,UJ=null,q0=0,RJ.length=0,f0.length=0,T0.length=0,u){if(u.pressTarget=null,u.target=null,u.spriteDirty=!0,u.fresh=!0,u.vw=0,u.tex>=0){let Q=h();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(u.tex),u.tex=-1}}}function $8(J,Q){J.onPress=Q??void 0}function Z8(J,Q){if(J.focusable=Q,d1(),!Q&&w===J)y(null)}function y(J){if(UJ&&UJ!==J)PJ(null);w=J,h().setFocus(J?J.id:0)}function PJ(J){if(UJ===J)return;let Q=h();if(UJ)Q.setActive?.(UJ.id,0);if(UJ=J,J)Q.setActive?.(J.id,1)}function x0(){return RJ.length>0?RJ[RJ.length-1]:mJ}function y0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;y($[q])}function Y8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=f0.length-1;Q>=0;Q--){let $=f0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function z8(J){let Q=Y8();if(!Q)return!1;let $=[];if(y0(Q.node,$),$.length===0){if(w)y(null);return!0}let Z=Q.columns,q=w?$.indexOf(w):-1;if(q<0)return y(l1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)y($[X]);return!0}function W8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=T0.length-1;Q>=0;Q--){let $=T0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function X0(J){let Q=W8();if(Q&&Q.move(J))return;if(z8(J))return;X8(J)}function u1(){c1(w)}function c1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){PJ(J)}function G8(J){y(J),c1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function v0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=v0(Q.children[q]);if(X){y(X);return}}let Z=Q;while(Z){if(Z.focusable){y(Z);return}Z=Z.parent}}y(null)}var u=null,p1=0;function d1(){p1++}var B8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],j8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function K8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=B8[Q]>>$&1,q=j8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function F8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):M8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(K8(),16,16,g6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function M8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&w6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var W0=null;function i1(J){W0=J}function s1(J){let Q=RJ.length>0?RJ[RJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function a1(J,Q,$){return s1(r1(J,Q,$))}function r1(J,Q,$){if($!==void 0)return $===0?null:z0(W0??mJ,$);let Z=h(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(W0??mJ,q(J,Q))}function U8(J,Q,$){let Z=u,q=h();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=w1(q);if(Z.vw=B?B.w:k1,Z.vh=B?B.h:b1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)F8(Z,q);let X=r6()*Z.speed,z=o6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=p6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),E=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||E!==Z.y)Z.x=_,Z.y=E,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let R=(Q|$)&Z.button,D=p1;if(G||R!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=s1(z0(W0??mJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==w)y(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(PJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,PJ(null),B)u1()}}else if($&Z.button)PJ(null);return!0}function R8(J){let Q=J&~q0,$=q0&~J;if(q0=J,u&&U8(J,Q,$))return;if($&d.CIRCLE)PJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)PJ(w),u1()}var m0=null;function o1(J){m0=J}function wJ(){if(d1(),m0)m0()}function P8(J,Q){J.debugName=Q||void 0,wJ()}var XJ={id:_6,type:KJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},n1=Symbol.for("pocketjs.native-node"),l0=1,lJ=3,o=8,D8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function G0(J){return J.domAttrs??={}}function t1(J,Q){let $=J.domNodeType??(uJ(J)?lJ:l0),Z=$===lJ?H0(J.text??""):$===o?O8(J.domData??""):X4(J.domTag??j0(J));for(let q of Object.keys(J.domAttrs??{}))u0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)YJ(Z,t1(q,!0));return Z}function u0(J,Q,$){if(D8.has(Q)){hJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete G0(J)[Q];else G0(J)[Q]=$}function c0(J){if(J[n1]===!0)return J;return Object.defineProperty(J,n1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?lJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(uJ(J))B0(J,Z);else if(g8(J),Z)YJ(J,H0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return z4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??j0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===lJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??j0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){hJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===XJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return YJ(J,$),$},insertBefore($,Z){return YJ(J,$,Z??null),$},removeChild($){return cJ(J,$),$},replaceChild($,Z){return YJ(J,$,Z),cJ(J,Z),Z},cloneNode($=!1){return t1(J,!!$)},remove(){if(J.parent)cJ(J.parent,J)},setAttribute($,Z){u0(J,$,Z)},removeAttribute($){u0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(XJ);var p0=null;function V8(J){p0=J}var d0={unknownClass:0,unknownTexture:0},e1=new Map;function J4(J,Q){e1.set(J,Q)}var Q4=new Map;function $4(J,Q){Q4.set(J,Q)}var CJ=new Set,L8=new Set;function Z4(J){if(!J)return!1;if(L8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:h().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function H0(J){let Q=h(),$=Q.createNode(KJ.text);return Q.setText($,J),c0({id:$,type:KJ.text,parent:null,children:[],text:J,domNodeType:lJ,domTag:"#text"})}function O8(J=""){let Q=H0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){h().replaceText(J.id,Q),J.text=Q,wJ()}function uJ(J){return J.type===KJ.text}function Y4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function YJ(J,Q,$){let Z=h();if(Y4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function cJ(J,Q){if(!Q)return;H8(Q),h().removeChild(J.id,Q.id),Y4(Q),CJ.add(Q),wJ()}function I8(J){return J.parent??void 0}function A8(J){return J.children[0]}function z4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function _8(J,Q){let $=h();if(wJ(),Q==null||Q===""){$.setStyle(J.id,S6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=p0?p0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);d0.unknownClass++;return}$.setStyle(J.id,Z)}function S8(J,Q){let $=h();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=e1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);d0.unknownTexture++;return}$.setImage(J.id,Z)}function k8(J,Q){let $=h();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=Q4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);d0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function b8(J,Q,$){let Z=h(),q=Q??{},X=$??{},z=!1;for(let G in q){let R=q[G];if(X[G]===R)continue;let D=k6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,l6(G,R)),z=!0}if(z)wJ()}function hJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete G0(J)[Q];else G0(J)[Q]=$;switch(Q){case"class":return _8(J,$),$;case"onPress":case"on:press":return $8(J,$),$;case"src":return S8(J,$),$;case"sprite":return k8(J,$),$;case"style":return b8(J,$,Z),$;case"focusable":return Z8(J,!!$),$;case"debugName":return P8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${j0(J)}>`)}function g8(J){for(let Q of[...J.children])cJ(J,Q)}function j0(J){for(let Q of Object.keys(KJ))if(KJ[Q]===J.type)return Q;return String(J.type)}function w8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}hJ(J,Q,$,Z)}var C8=A6({createElement:X4,createTextNode:H0,replaceText:B0,isTextNode:uJ,setProperty:w8,insertNode(J,Q,$){YJ(J,Q,$)},removeNode(J,Q){cJ(J,Q)},getParentNode:I8,getFirstChild:A8,getNextSibling:z4}),{render:h8,effect:wQ,memo:c,createComponent:Y,createElement:W4,insert:CQ,spread:E8,mergeProps:hQ,use:EQ}=C8,NQ={linear:l.Easing.Linear,in:l.Easing.EaseIn,out:l.Easing.EaseOut,"in-out":l.Easing.EaseInOut,"out-back":l.Easing.OutBack,spring:l.Easing.Spring,"spring-bouncy":l.Easing.SpringBouncy},N8=null;function G4(J){N8=J}function f8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function H4(J,Q){let $=W4(J);return E8($,Q,!1),f8(Q.nodeRef,$),$}function M(J){return H4("view",J)}function P(J){return H4("text",J)}var fQ=new WeakMap,TQ=new WeakMap,T8={}!==null?Object.freeze({...{}}):Object.freeze({}),xQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:T8}),yQ=new Map,zJ=36000,i0=30,x8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(zJ),tapeAnalog:new Uint16Array(zJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-i0,saidHello:!1,hostCalls:0};function y8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-i0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)o1(()=>{W.treeDirty=!0}),i8();else o1(null);globalThis.__pocketDevtools=a8}function v8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)l8(),p8();let X=Q,z=$===void 0?FJ:$&65535,G=Z,R=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(zJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==FJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function K4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function F4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return K4(J.masks,0,Q)}function M4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return K4(J.analog??[],FJ,Q)}function U4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,T({t:"hello",app:W.app,host:s8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` +`))if(q.trim())u8(q)}}function u8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),s0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),s0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":R4();break;case"eval":{let Z=!0,q;try{q=K0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}T({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":T({t:"tape",tape:j4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}T({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=F4(Z),W.replayAnalog=Z.analog?M4(Z):null,W.replayTouch=Z.touch?U4(Z):null,W.replayAt=0;break}default:break}}function c8(){if(W.treeDirty&&W.frame-W.treeSentAt>=i0)R4();if(W.frame%x8===0)s0()}function p8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function s0(){T({t:"stats",frame:W.frame,nodes:V4(XJ),tapeLen:W.tapeLen,paused:W.paused})}function R4(){W.treeDirty=!1,W.treeSentAt=W.frame,T({t:"tree",frame:W.frame,root:D4(XJ)})}function d8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function a0(J,Q){if(Array.isArray(J)){for(let $ of J)a0($,Q);return}if(d8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)a0($,Q)}}function P4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)a0(Z,Q)}function D4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(P4(J,(q)=>{if(q.domNodeType===8)return;Z.push(D4(q))}),Z.length)Q.k=Z;return Q}function V4(J){let Q=1;return P4(J,($)=>{Q+=V4($)}),Q}function i8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{T({t:"log",level:$,args:q.map((X)=>K0(X))}),Z?.apply(Q,q)}}}function K0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?L4(X):JSON.stringify(L4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>K0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${K0(z,Q+1)}`).join(", ")}}`}function L4(J){return J.length>200?J.slice(0,199)+"…":J}function s8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var a8={get frame(){return W.frame},dumpTape:()=>j4(),replay:(J)=>{W.replayMasks=F4(J),W.replayAnalog=J.analog?M4(J):null,W.replayTouch=J.touch?U4(J):null,W.replayAt=0}},O4=new Map,r0=new Map;function I4(J){return J.trim().replace(/\s+/g," ")}function A4(J){return J.split(" ").sort().join(" ")}var _4=-1;function r8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=I4(Q);O4.set(Z,$);let q=A4(Z),X=r0.get(q);r0.set(q,X!==void 0&&X!==$?_4:$)}}function o8(J){let Q=I4(J),$=O4.get(Q);if($!==void 0)return $;let Z=r0.get(A4(Q));return Z===_4?void 0:Z}var o0=9,n8=(1<{let q=($&e8)!==0,X=q?n0:o0,z=q?J2:n8;return Object.freeze({id:$>>>(q?Q2:t8)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Z2(){return F0}function q2(){F0=t0}var S4=8,WJ=8,X2=3,Y2=8,z2=6,W2=0.5,s=1,pJ=2,e0=4,DJ=8,EJ=[],k4=0,M0=0,GJ=Array.from({length:S4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(WJ),histY:new Int16Array(WJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function G2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function H2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=r1(Q,$,Z.fact);let G=Z.hit;if(G)return G2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=EJ[z];if(G.disposed)continue;if(k4>0&&!G.opts.allowWhenBlocked)continue;if(!H2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function K2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%WJ,J.histLenz||Z>z))q.flags[J.slot]|=pJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(pJ|e0))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??W2)*E1()));if(J.frames=0)EJ.splice($,1)},cancel(){if(!Q.disposed)w4(Q)},get panning(){for(let $ of GJ)if($.used&&Q.flags[$.slot]&DJ)return!0;return!1}}}function P2(J){let Q=R2(J);return S0(()=>Q.dispose()),Q}function C4(){EJ.length=0,k4=0,M0=0;for(let J of GJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function D2(){return P2({onDown:(J)=>{let Q=a1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=a1(J.x,J.y,J.hit);if(Q)G8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var V2=1,J1=new Map,U0=[];function L2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function O2(){V2=1,J1.clear(),U0=[]}function I2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=J1.get(Q);if(!Z)continue;J1.delete(Q),L2()?.({t:"delivery",frame:N1(),id:Q,kind:Z.kind}),Z.onResult($)}}var h4=new Set;function A2(){if(h4.size===0)return;for(let J of h4)J()}var _2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[28] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-base text-orange-600 font-bold":9,"h-[76] pt-3 text-lg text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-base text-emerald-700 font-bold":13,"h-[84] pt-3 text-lg text-slate-900":14,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":15,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":16,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":17,"text-base text-slate-600 font-bold":18,"pt-6 text-lg text-slate-500":19,"pt-6 text-lg text-slate-900 font-bold":20,"h-[146] px-6 pt-7 flex-col bg-slate-50":21,"h-[80]":22,"h-[1060] px-6 pt-5 flex-col":23,"h-[48] px-4 justify-center bg-slate-100":24,"text-base text-slate-600":25,"pt-[10] flex-col gap-[12]":26,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":27,"w-[48] h-[48] items-center justify-center bg-blue-100":28,"w-[48] h-[48] items-center justify-center bg-emerald-100":29,"text-lg text-blue-700 font-bold":30,"text-lg text-emerald-700 font-bold":31,"w-[474] flex-col gap-2":32,"text-lg text-slate-900 font-bold":33,"text-base text-slate-500":34,"pt-20 pl-10 text-lg text-slate-500":35,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":36,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":37,"h-[1060] px-6 pt-7 flex-col gap-4":38,"text-base text-slate-500 font-bold":39,"h-[214] px-7 items-center justify-center bg-slate-100":40,"text-lg text-slate-500 font-bold":41,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":42,"flex-row items-center gap-5":43,"w-[68] h-[68] items-center justify-center bg-orange-100":44,"text-xl text-orange-700 font-bold":45,"w-[500] flex-col gap-2":46,"text-xl text-slate-900 font-bold":47,"text-lg text-slate-600":48,"text-2xl text-orange-600":49,"mt-4 h-[112] px-6 justify-center bg-slate-100":50,"relative h-[154] px-5 pt-5 flex-col bg-white":51,"pt-3 text-lg text-orange-600 font-bold":52,"pt-3 text-base text-slate-500":53,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":54,"text-lg text-white font-bold":55,"h-[40] pt-3 text-base text-slate-500":56,"h-[470] flex-col gap-2":57,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":58,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":59,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":60,"h-[160] px-5 pt-5 flex-col bg-white":61,"pt-3 text-lg text-slate-900 font-bold":62,"pt-3 text-base text-slate-600":63,"h-[108] pt-7 flex-row gap-4":64,"w-[316] h-[80] items-center justify-center bg-slate-100":65,"w-[340] h-[80] items-center justify-center bg-red-100":66,"text-lg text-red-500 font-bold":67,"h-[1052] px-6 pt-5 flex-col":68,"h-[270] px-[22] pt-6 bg-white":69,"text-lg text-slate-900":70,"text-lg text-slate-400":71,"h-[86] px-1 flex-row items-center justify-between":72,"w-[132] h-[58] items-center justify-center bg-slate-300":73,"w-[132] h-[58] items-center justify-center bg-slate-100":74,"text-base text-slate-900 font-bold":75,"h-[140] flex-row gap-2":76,"grow h-[120] items-center justify-center bg-slate-300":77,"grow h-[120] items-center justify-center bg-white":78,"w-[104] h-[120] items-center justify-center bg-slate-300":79,"w-[104] h-[120] items-center justify-center bg-slate-100":80,"h-[176] flex-row gap-2":81,"w-[92] h-[156] items-center justify-center bg-slate-300":82,"w-[92] h-[156] items-center justify-center bg-slate-100":83,"w-[300] h-[156] items-center justify-center bg-slate-300":84,"w-[300] h-[156] items-center justify-center bg-slate-100":85,"w-[144] h-[156] items-center justify-center bg-slate-300":86,"w-[144] h-[156] items-center justify-center bg-slate-100":87,"w-[112] h-[156] items-center justify-center bg-emerald-700":88,"w-[112] h-[156] items-center justify-center bg-emerald-500":89,"text-base text-slate-950 font-bold":90,"h-[108] px-6 py-3 flex-col bg-slate-50":91,"h-[84] items-center justify-center bg-slate-300":92,"h-[84] items-center justify-center bg-slate-100":93,"h-[1168] px-6 pt-5 flex-col":94,"h-[82] px-4 justify-center bg-white":95,"w-[584] h-[900] px-5 pt-5 bg-slate-950":96,"text-base text-slate-200":97,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":98,"text-lg text-orange-600 font-bold":99,"w-[584] h-[900] px-5 pt-5 bg-white":100,"text-base text-slate-900":101,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":102,"absolute inset-0 z-50 flex-col items-center justify-center":103,"absolute inset-0 bg-slate-950":104,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":105,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":106,"flex-row flex-wrap":107,grow:108,"text-2xl text-white font-bold":109,"text-2xl text-slate-950 font-bold":110,"px-6":111,"px-6 py-5":112,"gap-4":113,"rounded-xl shadow bg-white border-slate-100":114,"rounded-xl shadow bg-emerald-100 border-emerald-500":115,"bg-white":116,"bg-slate-100":117,"bg-slate-950":118,"px-3 py-2 rounded-lg bg-slate-100":119,"px-3 py-2 rounded-lg bg-indigo-100":120,"text-base text-indigo-700 font-bold":121,"px-3 py-2 rounded-lg bg-emerald-100":122,"px-3 py-2 rounded-lg bg-amber-100":123,"text-base text-amber-700 font-bold":124,"px-3 py-2 rounded-lg bg-red-100":125,"text-base text-red-500 font-bold":126,"w-[34] h-[34] rounded-lg bg-amber-400":127,"w-[34] h-[34] rounded-lg bg-red-500":128,"w-[34] h-[34] rounded-lg bg-slate-800":129,"w-[34] h-[34] rounded-lg bg-emerald-500":130,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":131,"flex-row items-center gap-4":132,"w-[34] text-2xl text-white font-bold":133,"w-[332] flex-col items-end gap-2":134,"text-base text-slate-300 font-bold":135,"text-base text-slate-400":136,"h-[166] px-6 pt-6 flex-col gap-3":137,"h-[44] px-1 flex-row items-center justify-between":138,"w-full h-full items-center justify-center rounded-xl bg-slate-200":139,"w-full h-full items-center justify-center rounded-xl bg-red-100":140,"w-full h-full items-center justify-center rounded-xl bg-slate-100":141,"w-full h-full items-center justify-center rounded-xl bg-orange-600":142,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":143,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":144,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":145,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":146,"text-2xl text-indigo-700 font-bold":147,"text-2xl text-slate-600 font-bold":148,"pt-7 text-2xl text-slate-900 font-bold":149,"pt-4 text-lg text-slate-500":150,"text-xl text-emerald-600 font-bold":151,"text-xl text-red-500 font-bold":152,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":153,"text-base text-red-300":154,"text-base text-slate-300":155,"text-base text-red-500":156,"w-full h-full px-6 flex-row items-center bg-slate-950":157,"w-full h-full flex-row items-center":158};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var S2="ui:styles",k2="ui:font.",E4="ui:img.",N4="ui:sprite.";function b2(){return globalThis.ui}function g2(J){if(J.__textures)return;for(let Q of N0(E4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)J4(Q.slice(E4.length),Z)}}function w2(J){if(J.__sprites)return;for(let Q of N0(N4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),R=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)$4(Q.slice(N4.length),{handle:V,frames:G,cols:R,step:D})}}function f4(J){let Q=W4("view");return hJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function C2(J,Q){if(!R0||!P0)return;hJ(R0,"style",{width:J,height:Q,overflow:l.Overflow.Hidden},void 0),hJ(P0,"style",{width:J,height:Q,posType:l.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=h();$.__viewport={w:J,h:Q}}function h2(J,Q={}){let $=T6(Q.ops);if(x6($),V8(o8),Q.styles)r8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)J4(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)$4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)v1(Q.pak);if(Q8()){for(let B of N0())if(B===S2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(k2))$.ops.loadFontAtlas?.(vJ(B))}}let q=w1($.ops),X=q?.w??k1,z=q?.h??b1,G=f4({width:X,height:z,overflow:l.Overflow.Hidden}),R=f4({width:X,height:z,posType:l.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});YJ(XJ,G),YJ(XJ,R),G4(R),R0=G,P0=R,m1(G),i1(XJ),t6(),C4(),D2(),d6(),O2(),y8($.ops),y6(v8((B,_,E,N)=>{i6(),s6(_),$2(E,N),A2(),I2(),U2(),e6(B),R8(B),q4()}));let D=h8(J,G),V=v6(C2);return()=>{V(),q2(),C4(),D(),m1(null),i1(null),G4(null),R0=null,P0=null;for(let B of XJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);q4()}}function E2(J,Q={}){let $=Q.ops??b2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)v1(Q.pak);return g2($),w2($),h2(J,{ops:$,styles:Q.styles??_2,pak:Q.pak})}var N2="$b",f2=65536,T4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function y2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function x4(){let J=y2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function v2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,f2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=T2(z.data[N2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function m2(J,Q){let $=v2(x4(),J);return Q==="utf8"||Q==="utf-8"?x2($):$}function l2(J,Q){let $=x4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var u2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"};function c2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(M,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(M,{class:"flex-row items-center gap-4",get children(){return[c(()=>c(()=>!!J.back)()?Y(P,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(M,{get["class"](){return Q()}})),Y(P,{get["class"](){return u2.appTitle},get children(){return J.title}})]}}),Y(M,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(P,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(P,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function p2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(M,{get["class"](){return Q()},get children(){return Y(P,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(M,{get["class"](){return J.top},get children(){return Y(P,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(M,{get["class"](){return J.bottom},get children(){return Y(P,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var vQ="‘’“”–—…•",d2=512;function i2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=Q(z);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function Q1(J,Q,$){let Z=new Map,q=(G)=>{let R=Z.get(G);if(R===void 0)R=h().measureText(G,Q),Z.set(G,R);return R},X=[],z=q(" ");for(let G of J.split(` +`)){let R=G.split(" ").flatMap((B)=>B&&q(B)>$?i2(B,q,$):[B]),D="",V=0;for(let B of R){let _=q(B);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return X}function $1(J,Q,$,Z){let q=J.slice(0,d2),X=Q1(q,Q,$);if(q.length===J.length&&X.length<=Z)return X.join(` `);let z=X.slice(0,Z),G=z.length-1;return z[G]=z[G].replace(/[\s.]+$/,"")+"…",z.join(` -`)}var q1=3,u4=2,X1=536,l4=544,c4=39,[n,o2]=g({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[y,t]=g("chat"),[Y1,n2]=g("chat"),[z1,p4]=g(0),[VJ,d4]=g(""),[sJ,hJ]=g(0),[aJ,W1]=g([]),[t2,V0]=g(""),[i4,L0]=g(null),[s4,a4]=g(null),[O0,I0]=g(0),[v,e]=g(""),[LJ,r4]=g("letters"),[G1,H1]=g(!1),[B1,o4]=g({type:"prompt"}),[HJ,n4]=g(null),[rJ,t4]=g(0),e4=new Map,J6=["qwertyuiop","asdfghjkl","zxcvbnm"],Q6=["1234567890","-/:;()$&@",`.,?!'"+`],$6=["chat","files","apps","settings"];function e2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function JQ(J,Q){return J?J+"/"+Q:Q}function A0(J=VJ(),Q=!1){let $=e4.get(J);if(!Q&&$){W1($),V0(""),hJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=p2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));e4.set(J,Z),W1(Z),V0(""),hJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){W1([]),V0(Z instanceof Error?Z.message:String(Z))}}function QQ(){let J=[];for(let Q of n().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Z6(){let J=QQ(),Q=Math.max(0,J.length-2),$=Math.min(z1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function OJ(J){return Y(i2,{get title(){return J.title},get accent(){return c(()=>n().agent==="FAULTED")()?"danger":n().agent==="THINKING"?"busy":"ready"}})}function _0(){return Y(M,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(jJ,{each:$6,children:(J)=>Y(M,{get["class"](){return Y1()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(R,{class:"text-base text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function $Q(){let J=()=>n().schedule,Q=()=>{let $=J();return Z1(String($?.name)+" "+String($?.next??"")+` +`)}var Z1=3,y4=2,q1=536,v4=544,m4=39,[n,s2]=g({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[x,t]=g("chat"),[X1,a2]=g("chat"),[Y1,l4]=g(0),[VJ,u4]=g(""),[sJ,NJ]=g(0),[aJ,z1]=g([]),[r2,D0]=g(""),[c4,V0]=g(null),[p4,d4]=g(null),[L0,O0]=g(0),[v,e]=g(""),[LJ,i4]=g("letters"),[W1,G1]=g(!1),[H1,s4]=g({type:"prompt"}),[HJ,a4]=g(null),[rJ,r4]=g(0),o4=new Map,n4=["qwertyuiop","asdfghjkl","zxcvbnm"],t4=["1234567890","-/:;()$&@",`.,?!'"+`],e4=["chat","files","apps","settings"];function o2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function n2(J,Q){return J?J+"/"+Q:Q}function I0(J=VJ(),Q=!1){let $=o4.get(J);if(!Q&&$){z1($),D0(""),NJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=l2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));o4.set(J,Z),z1(Z),D0(""),NJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){z1([]),D0(Z instanceof Error?Z.message:String(Z))}}function t2(){let J=[];for(let Q of n().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function J6(){let J=t2(),Q=Math.max(0,J.length-2),$=Math.min(Y1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function OJ(J){return Y(c2,{get title(){return J.title},get accent(){return c(()=>n().agent==="FAULTED")()?"danger":n().agent==="THINKING"?"busy":"ready"}})}function A0(){return Y(M,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(jJ,{each:e4,children:(J)=>Y(M,{get["class"](){return X1()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(P,{class:"text-base text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function e2(){let J=()=>n().schedule,Q=()=>{let $=J();return $1(String($?.name)+" "+String($?.next??"")+` -`+String($?.prompt??""),q1,X1,5)};return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"ESP32 PI AGENT"}),Y(M,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(jJ,{get each(){return Z6()},children:($)=>Y(M,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(M,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(M,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(R,{class:"text-base text-orange-600 font-bold",children:"YOU"})]}}),Y(R,{class:"h-[76] pt-3 text-lg text-slate-900",get children(){return Z1($.user,q1,X1,3)}}),Y(M,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(M,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(M,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(R,{class:"text-base text-emerald-700 font-bold",children:"PI"})]}}),Y(R,{class:"h-[84] pt-3 text-lg text-slate-900",get children(){return Z1($.assistant,q1,X1,3)}})]}})}),Y(iJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(M,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(R,{class:"text-base text-slate-600 font-bold",children:"NEXT WAKE"}),Y(ZJ,{get when(){return J()?.name},get fallback(){return Y(R,{class:"pt-6 text-lg text-slate-500",children:`NO WAKE SCHEDULED +`+String($?.prompt??""),Z1,q1,5)};return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"ESP32 PI AGENT"}),Y(M,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(jJ,{get each(){return J6()},children:($)=>Y(M,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(M,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(M,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(P,{class:"text-base text-orange-600 font-bold",children:"YOU"})]}}),Y(P,{class:"h-[76] pt-3 text-lg text-slate-900",get children(){return $1($.user,Z1,q1,3)}}),Y(M,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(M,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(M,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(P,{class:"text-base text-emerald-700 font-bold",children:"PI"})]}}),Y(P,{class:"h-[84] pt-3 text-lg text-slate-900",get children(){return $1($.assistant,Z1,q1,3)}})]}})}),Y(iJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(M,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(P,{class:"text-base text-slate-600 font-bold",children:"NEXT WAKE"}),Y(ZJ,{get when(){return J()?.name},get fallback(){return Y(P,{class:"pt-6 text-lg text-slate-500",children:`NO WAKE SCHEDULED -ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(R,{class:"pt-6 text-lg text-slate-900 font-bold",get children(){return Q()}})}})]}}),Y(M,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(M,{class:"h-[80]",get children(){return Y(s2,{label:"TYPE A MESSAGE"})}})}}),Y(_0,{})]}})}function ZQ(){let J=()=>aJ().slice(sJ(),sJ()+8);return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{get title(){return VJ()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(M,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",get children(){return"/workspace"+(VJ()?"/"+VJ():"")}})}}),Y(M,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(jJ,{get each(){return J()},children:(Q)=>Y(M,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(M,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(R,{get["class"](){return Q.kind==="dir"?"text-lg text-blue-700 font-bold":"text-lg text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(M,{class:"w-[474] flex-col gap-2",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,52)}}),Y(R,{class:"text-base text-slate-500",get children(){return c(()=>Q.kind==="dir")()?"FOLDER":e2(Q.size)}})]}})]}})})}}),Y(ZJ,{get when(){return aJ().length===0},get children(){return Y(R,{class:"pt-20 pl-10 text-lg text-slate-500",get children(){return t2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(ZJ,{get when(){return aJ().length>8},get children(){return Y(iJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(_0,{})]}})}function qQ(){let J=()=>n().apps??[];return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"APPS"}),Y(M,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(R,{class:"text-base text-slate-500 font-bold",get children(){return String(J().length)+" INSTALLED APPS"}}),Y(ZJ,{get when(){return J().length>0},get fallback(){return Y(M,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-500 font-bold",children:"NO OPTIONAL APPS INSTALLED"})}})},get children(){return Y(jJ,{get each(){return J()},children:(Q)=>Y(M,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(M,{class:"flex-row items-center gap-5",get children(){return[Y(M,{class:"w-[68] h-[68] items-center justify-center bg-orange-100",get children(){return Y(R,{class:"text-xl text-orange-700 font-bold",get children(){return Q.title.slice(0,1).toUpperCase()}})}}),Y(M,{class:"w-[500] flex-col gap-2",get children(){return[Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return Q.title}}),Y(R,{class:"text-lg text-slate-600",get children(){return Q.description}}),Y(ZJ,{get when(){return Q.scheduleEveryMinutes},get children(){return Y(R,{class:"text-base text-slate-500",get children(){return"UPDATES EVERY "+String(Q.scheduleEveryMinutes)+" MINUTES"}})}})]}})]}}),Y(R,{class:"text-2xl text-orange-600",children:"›"})]}})})}}),Y(M,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(R,{class:"text-base text-slate-600",children:`APP DATA STAYS ISOLATED. -PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(_0,{})]}})}function XQ(){let J=()=>n().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(rJ(),rJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"SETTINGS"}),Y(M,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",children:"WI-FI"}),Y(R,{class:"pt-3 text-lg text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return Z()}}),Y(M,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(R,{class:"text-lg text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(R,{class:"h-[40] pt-3 text-base text-slate-500",children:"AVAILABLE NETWORKS"}),Y(M,{class:"h-[470] flex-col gap-2",get children(){return[Y(ZJ,{get when(){return $().length>0},get fallback(){return Y(M,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-500 font-bold",children:`NO NETWORK LIST YET +ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(P,{class:"pt-6 text-lg text-slate-900 font-bold",get children(){return Q()}})}})]}}),Y(M,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(M,{class:"h-[80]",get children(){return Y(p2,{label:"TYPE A MESSAGE"})}})}}),Y(A0,{})]}})}function JQ(){let J=()=>aJ().slice(sJ(),sJ()+8);return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{get title(){return VJ()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(M,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(P,{class:"text-base text-slate-600",get children(){return"/workspace"+(VJ()?"/"+VJ():"")}})}}),Y(M,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(jJ,{get each(){return J()},children:(Q)=>Y(M,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(M,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(P,{get["class"](){return Q.kind==="dir"?"text-lg text-blue-700 font-bold":"text-lg text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(M,{class:"w-[474] flex-col gap-2",get children(){return[Y(P,{class:"text-lg text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,52)}}),Y(P,{class:"text-base text-slate-500",get children(){return c(()=>Q.kind==="dir")()?"FOLDER":o2(Q.size)}})]}})]}})})}}),Y(ZJ,{get when(){return aJ().length===0},get children(){return Y(P,{class:"pt-20 pl-10 text-lg text-slate-500",get children(){return r2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(ZJ,{get when(){return aJ().length>8},get children(){return Y(iJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(A0,{})]}})}function QQ(){let J=()=>n().apps??[];return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"APPS"}),Y(M,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(P,{class:"text-base text-slate-500 font-bold",get children(){return String(J().length)+" INSTALLED APPS"}}),Y(ZJ,{get when(){return J().length>0},get fallback(){return Y(M,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(P,{class:"text-lg text-slate-500 font-bold",children:"NO OPTIONAL APPS INSTALLED"})}})},get children(){return Y(jJ,{get each(){return J()},children:(Q)=>Y(M,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(M,{class:"flex-row items-center gap-5",get children(){return[Y(M,{class:"w-[68] h-[68] items-center justify-center bg-orange-100",get children(){return Y(P,{class:"text-xl text-orange-700 font-bold",get children(){return Q.title.slice(0,1).toUpperCase()}})}}),Y(M,{class:"w-[500] flex-col gap-2",get children(){return[Y(P,{class:"text-xl text-slate-900 font-bold",get children(){return Q.title}}),Y(P,{class:"text-lg text-slate-600",get children(){return Q.description}}),Y(ZJ,{get when(){return Q.scheduleEveryMinutes},get children(){return Y(P,{class:"text-base text-slate-500",get children(){return"UPDATES EVERY "+String(Q.scheduleEveryMinutes)+" MINUTES"}})}})]}})]}}),Y(P,{class:"text-2xl text-orange-600",children:"›"})]}})})}}),Y(M,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(P,{class:"text-base text-slate-600",children:`APP DATA STAYS ISOLATED. +PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(A0,{})]}})}function $Q(){let J=()=>n().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(rJ(),rJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"SETTINGS"}),Y(M,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(P,{class:"text-lg text-slate-900 font-bold",children:"WI-FI"}),Y(P,{class:"pt-3 text-lg text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(P,{class:"pt-3 text-base text-slate-500",get children(){return Z()}}),Y(M,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(P,{class:"text-lg text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(P,{class:"h-[40] pt-3 text-base text-slate-500",children:"AVAILABLE NETWORKS"}),Y(M,{class:"h-[470] flex-col gap-2",get children(){return[Y(ZJ,{get when(){return $().length>0},get fallback(){return Y(M,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(P,{class:"text-lg text-slate-500 font-bold",children:`NO NETWORK LIST YET -TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(jJ,{get each(){return $()},children:(q)=>Y(M,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return q.ssid}}),Y(R,{class:"text-base text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(ZJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(iJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(M,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(R,{class:"text-base text-slate-500",children:"MODEL BACKEND"}),Y(R,{class:"pt-3 text-lg text-slate-900 font-bold",get children(){return n().model??"UNKNOWN"}}),Y(R,{class:"pt-3 text-base text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(M,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(M,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(M,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(R,{class:"text-lg text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(_0,{})]}})}function YQ(){let J=()=>B1(),Q=()=>LJ()==="letters"?J6:Q6,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(M,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(R,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(M,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(R,{class:"text-base text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(M,{get["class"](){return HJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(jJ,{get each(){return Q()},children:(Z,q)=>Y(M,{class:"h-[140] flex-row gap-2",get children(){return[Y(jJ,{get each(){return Z.split("")},children:(X)=>Y(M,{get["class"](){return HJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(R,{class:"text-xl text-slate-900 font-bold",get children(){return c(()=>!!G1())()?X.toUpperCase():X}})}})}),Y(ZJ,{get when(){return q()===2},get children(){return Y(M,{get["class"](){return HJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(M,{class:"h-[176] flex-row gap-2",get children(){return[Y(M,{get["class"](){return HJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return LJ()==="letters"?"123":"ABC"}})}}),Y(M,{get["class"](){return HJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"SPACE"})}}),Y(M,{get["class"](){return HJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",get children(){return LJ()==="letters"?"SHIFT":". ?"}})}}),Y(M,{get["class"](){return HJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(R,{class:"text-base text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(M,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(M,{get["class"](){return HJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(R,{class:"text-base text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function zQ(){let J=()=>i4(),Q=()=>(J()?.text??"").split(` -`),$=()=>J()?.lineOffset??0;return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"< FILE VIEWER"}),Y(M,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(M,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(R,{class:"text-base text-slate-200",get children(){return Q().slice($(),$()+39).join(` -`)}})}}),Y(R,{class:"pt-3 text-base text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function WQ(){let J=()=>s4(),Q=()=>$1(J()?.text??"",u4,l4);return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"< MESSAGE READER"}),Y(M,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(R,{class:"text-lg text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(M,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(R,{class:"text-base text-slate-900",get children(){return Q().slice(O0(),O0()+c4).join(` -`)}})}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function GQ(){return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return c(()=>y()==="chat")()?Y($Q,{}):c(()=>y()==="files")()?Y(ZQ,{}):c(()=>y()==="apps")()?Y(qQ,{}):c(()=>y()==="settings")()?Y(XQ,{}):c(()=>y()==="keyboard")()?Y(YQ,{}):c(()=>y()==="viewer")()?Y(zQ,{}):Y(WQ,{})}})}function HQ(J){j6(()=>{if(n2(J),t(J),J==="files")A0()})}function q6(J,Q){let $=LJ()==="letters"?J6:Q6,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,P=Math.floor((J-24)/G);if(P>=0&&P=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=q6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function jQ(J,Q){if(Q>=1164)return e(""),t(Y1()),"";if(J>=548&&Q>=402&&Q<=482)return e(""),"";let $=q6(J,Q);if($){let Z=LJ()==="letters"&&G1()?$.toUpperCase():$,q=B1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return e(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)r4(LJ()==="letters"?"numbers":"letters"),H1(!1);else if(J<=424){if(v())e(v()+" ")}else if(J<=576)if(LJ()==="letters")H1(!G1());else e(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=B1();if(e(""),r4("letters"),H1(!1),t(Y1()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}f2(()=>Y(GQ,{})),queueMicrotask(()=>A0("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return o2(JSON.parse(J)),""},pointerDown(J,Q){return n4(y()==="keyboard"?BQ(J,Q):null),""},pointerUp(){return n4(null),""},tap(J,Q){if(y()==="keyboard")return jQ(J,Q);if(y()==="viewer"){let $=i4();if(J<104&&Q<112)L0(null),t("files");else if($&&J>=620&&Q>=170&&Q<=340)L0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)L0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` -`).length-39),$.lineOffset+18)});return""}if(y()==="reader"){if(J<104&&Q<112)a4(null),I0(0),t("chat");else if(J>=620&&Q>=170&&Q<=340)I0(Math.max(0,O0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=$1(s4()?.text??"",u4,l4).length;I0(Math.min(Math.max(0,$-c4),O0()+18))}return""}if(Q>=1172)return HQ($6[Math.min(3,Math.floor(J/180))]),"";if(y()==="chat"){if(J>=620&&Q>=140&&Q<=272)p4(z1()+2);else if(J>=620&&Q>=624&&Q<=756)p4(Math.max(0,z1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=Z6()[$];if(Z){let q=Q>=140+$*320+150;a4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),I0(0),t("reader")}}else if(Q>=1070&&Q<=1150)o4({type:"prompt"}),e(""),t("keyboard");return""}if(y()==="files"){if(J<104&&Q<112&&VJ()){let $=VJ().split("/");$.pop();let Z=$.join("/");d4(Z),hJ(0),A0(Z)}else if(J>=620&&Q>=170&&Q<=340)hJ(Math.max(0,sJ()-4));else if(J>=620&&Q>=920&&Q<=1100)hJ(Math.min(Math.max(0,aJ().length-8),sJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=aJ()[sJ()+$];if(Z){let q=JQ(VJ(),Z.name);if(Z.kind==="dir")d4(q),hJ(0),A0(q);else try{L0({path:"/workspace/"+q,text:c2(q,"utf8"),lineOffset:0}),t("viewer")}catch(X){V0(X instanceof Error?X.message:String(X))}}}return""}if(y()==="apps"){let $=(n().apps??[])[Math.floor((Q-162)/166)];if(Q>=162&&$)return JSON.stringify({type:"navigate",app:$.id});return""}if(y()==="settings"){let $=n().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)t4(Math.max(0,rJ()-4));else if(J>=620&&Q>=650&&Q<=782)t4(Math.min(Math.max(0,$.length-5),rJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[rJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});o4({type:"wifi",ssid:q.ssid}),e(""),t("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); +TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(jJ,{get each(){return $()},children:(q)=>Y(M,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(P,{class:"text-lg text-slate-900 font-bold",get children(){return q.ssid}}),Y(P,{class:"text-base text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(ZJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(iJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(M,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(P,{class:"text-base text-slate-500",children:"MODEL BACKEND"}),Y(P,{class:"pt-3 text-lg text-slate-900 font-bold",get children(){return n().model??"UNKNOWN"}}),Y(P,{class:"pt-3 text-base text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(M,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(M,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(P,{class:"text-lg text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(M,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(P,{class:"text-lg text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(A0,{})]}})}function ZQ(){let J=()=>H1(),Q=()=>LJ()==="letters"?n4:t4,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(M,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(P,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(M,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(P,{class:"text-base text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(M,{get["class"](){return HJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(P,{class:"text-base text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(jJ,{get each(){return Q()},children:(Z,q)=>Y(M,{class:"h-[140] flex-row gap-2",get children(){return[Y(jJ,{get each(){return Z.split("")},children:(X)=>Y(M,{get["class"](){return HJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(P,{class:"text-xl text-slate-900 font-bold",get children(){return c(()=>!!W1())()?X.toUpperCase():X}})}})}),Y(ZJ,{get when(){return q()===2},get children(){return Y(M,{get["class"](){return HJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(P,{class:"text-base text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(M,{class:"h-[176] flex-row gap-2",get children(){return[Y(M,{get["class"](){return HJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(P,{class:"text-base text-slate-900 font-bold",get children(){return LJ()==="letters"?"123":"ABC"}})}}),Y(M,{get["class"](){return HJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(P,{class:"text-base text-slate-900 font-bold",children:"SPACE"})}}),Y(M,{get["class"](){return HJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(P,{class:"text-base text-slate-900 font-bold",get children(){return LJ()==="letters"?"SHIFT":". ?"}})}}),Y(M,{get["class"](){return HJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(P,{class:"text-base text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(M,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(M,{get["class"](){return HJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(P,{class:"text-base text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function qQ(){let J=()=>c4(),Q=()=>(J()?.text??"").split(` +`),$=()=>J()?.lineOffset??0;return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"< FILE VIEWER"}),Y(M,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(P,{class:"text-lg text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(M,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(P,{class:"text-base text-slate-200",get children(){return Q().slice($(),$()+39).join(` +`)}})}}),Y(P,{class:"pt-3 text-base text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function XQ(){let J=()=>p4(),Q=()=>Q1(J()?.text??"",y4,v4);return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"< MESSAGE READER"}),Y(M,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(P,{class:"text-lg text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(M,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(P,{class:"text-base text-slate-900",get children(){return Q().slice(L0(),L0()+m4).join(` +`)}})}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function YQ(){return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return c(()=>x()==="chat")()?Y(e2,{}):c(()=>x()==="files")()?Y(JQ,{}):c(()=>x()==="apps")()?Y(QQ,{}):c(()=>x()==="settings")()?Y($Q,{}):c(()=>x()==="keyboard")()?Y(ZQ,{}):c(()=>x()==="viewer")()?Y(qQ,{}):Y(XQ,{})}})}function zQ(J){G6(()=>{if(a2(J),t(J),J==="files")I0()})}function Q6(J,Q){let $=LJ()==="letters"?n4:t4,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,R=Math.floor((J-24)/G);if(R>=0&&R=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=Q6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function GQ(J,Q){if(Q>=1164)return e(""),t(X1()),"";if(J>=548&&Q>=402&&Q<=482)return e(""),"";let $=Q6(J,Q);if($){let Z=LJ()==="letters"&&W1()?$.toUpperCase():$,q=H1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return e(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)i4(LJ()==="letters"?"numbers":"letters"),G1(!1);else if(J<=424){if(v())e(v()+" ")}else if(J<=576)if(LJ()==="letters")G1(!W1());else e(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=H1();if(e(""),i4("letters"),G1(!1),t(X1()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}E2(()=>Y(YQ,{})),queueMicrotask(()=>I0("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return s2(JSON.parse(J)),""},pointerDown(J,Q){return a4(x()==="keyboard"?WQ(J,Q):null),""},pointerUp(){return a4(null),""},tap(J,Q){if(x()==="keyboard")return GQ(J,Q);if(x()==="viewer"){let $=c4();if(J<104&&Q<112)V0(null),t("files");else if($&&J>=620&&Q>=170&&Q<=340)V0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)V0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` +`).length-39),$.lineOffset+18)});return""}if(x()==="reader"){if(J<104&&Q<112)d4(null),O0(0),t("chat");else if(J>=620&&Q>=170&&Q<=340)O0(Math.max(0,L0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=Q1(p4()?.text??"",y4,v4).length;O0(Math.min(Math.max(0,$-m4),L0()+18))}return""}if(Q>=1172)return zQ(e4[Math.min(3,Math.floor(J/180))]),"";if(x()==="chat"){if(J>=620&&Q>=140&&Q<=272)l4(Y1()+2);else if(J>=620&&Q>=624&&Q<=756)l4(Math.max(0,Y1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=J6()[$];if(Z){let q=Q>=140+$*320+150;d4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),O0(0),t("reader")}}else if(Q>=1070&&Q<=1150)s4({type:"prompt"}),e(""),t("keyboard");return""}if(x()==="files"){if(J<104&&Q<112&&VJ()){let $=VJ().split("/");$.pop();let Z=$.join("/");u4(Z),NJ(0),I0(Z)}else if(J>=620&&Q>=170&&Q<=340)NJ(Math.max(0,sJ()-4));else if(J>=620&&Q>=920&&Q<=1100)NJ(Math.min(Math.max(0,aJ().length-8),sJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=aJ()[sJ()+$];if(Z){let q=n2(VJ(),Z.name);if(Z.kind==="dir")u4(q),NJ(0),I0(q);else try{V0({path:"/workspace/"+q,text:m2(q,"utf8"),lineOffset:0}),t("viewer")}catch(X){D0(X instanceof Error?X.message:String(X))}}}return""}if(x()==="apps"){let $=(n().apps??[])[Math.floor((Q-162)/166)];if(Q>=162&&$)return JSON.stringify({type:"navigate",app:$.id});return""}if(x()==="settings"){let $=n().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)r4(Math.max(0,rJ()-4));else if(J>=620&&Q>=650&&Q<=782)r4(Math.min(Math.max(0,$.length-5),rJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[rJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});s4({type:"wifi",ssid:q.ssid}),e(""),t("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); diff --git a/crates/pocket-pi-agentos/src/lib.rs b/crates/pocket-pi-agentos/src/lib.rs index a1e9429..673aff6 100644 --- a/crates/pocket-pi-agentos/src/lib.rs +++ b/crates/pocket-pi-agentos/src/lib.rs @@ -520,7 +520,7 @@ impl DataActionRuntime { std::time::Instant::now() < deadline, "PocketPiData.{method} timed out" ); - std::thread::sleep(Duration::from_millis(5)); + yield_scheduler_tick(); } } } @@ -954,12 +954,24 @@ fn mount_services(guest: &Guest, app_id: String, services: Arc Result { Err("unexpected App service call".into()) } + + fn http(&self, app_id: &str, request: HttpRequest) -> Result { + assert_eq!(app_id, "exa"); + assert_eq!(request.url, "https://api.exa.ai/search"); + assert_eq!(request.method, "POST"); + let body: Value = serde_json::from_slice(&request.body).unwrap(); + assert_eq!(body["query"], "Pocket Pi architecture"); + let response = serde_json::json!({ + "results": [{ + "title": "Evidence result", + "url": "https://example.com/evidence" + }] + }); + Ok(TransportCompletion::Done { + handle: request.handle, + status: 200, + url: request.url, + headers: BTreeMap::from([("content-type".into(), "application/json".into())]), + body: serde_json::to_vec(&response).unwrap(), + }) + } } -struct Backend; +struct Backend(AtomicUsize); impl ModelBackend for Backend { fn complete( &self, - _request_json: &str, + request_json: &str, on_event: &mut dyn FnMut(pocket_pi_embedded::ModelStreamEvent), ) -> Result { - on_event(pocket_pi_embedded::ModelStreamEvent::Text("done".into())); - Ok(r#"{"thinking":"","text":"done","toolCalls":[],"usage":{},"stopReason":"stop"}"#.into()) + if self.0.fetch_add(1, Ordering::SeqCst) == 0 { + return Ok(serde_json::json!({ + "thinking": "", + "text": "", + "toolCalls": [{ + "id": "call_search", + "name": "research.search", + "arguments": {"query": "Pocket Pi architecture"} + }], + "usage": {}, + "stopReason": "toolUse" + }) + .to_string()); + } + assert!(request_json.contains("Evidence result"), "{request_json}"); + on_event(pocket_pi_embedded::ModelStreamEvent::Text( + "research complete".into(), + )); + Ok(serde_json::json!({ + "thinking": "", + "text": "research complete", + "toolCalls": [], + "usage": {}, + "stopReason": "stop" + }) + .to_string()) } } @@ -50,39 +100,47 @@ impl ToolHost for NoTools { } #[test] -fn system_agent_keeps_running_while_an_ordinary_app_is_foreground() { +fn agent_routes_a_background_app_tool_through_http_and_sqlite() { let temp = tempfile::tempdir().unwrap(); let catalog = catalog().unwrap(); - let ordinary = catalog - .descriptors() - .find(|app| app.id != ROOT_APP_ID) - .unwrap() - .id - .clone(); - let mut supervisor = AppSupervisor::new(temp.path(), catalog, Arc::new(NoServices)).unwrap(); + assert!(catalog.descriptor("exa").is_some()); + assert!(catalog.descriptor("robinhood").is_some()); + let mut supervisor = AppSupervisor::new(temp.path(), catalog, Arc::new(Services)).unwrap(); + let (tools, requests) = RoutedToolHost::new(Arc::new(NoTools), supervisor.catalog().clone()); supervisor .boot_agent( r#"{"model":"offline"}"#, - Arc::new(Backend), - Arc::new(NoTools), + Arc::new(Backend(AtomicUsize::new(0))), + Arc::new(tools), ) .unwrap(); - supervisor.prompt_agent("continue").unwrap(); - supervisor.open(&ordinary).unwrap(); + supervisor.prompt_agent("research Pocket Pi").unwrap(); + supervisor.open("robinhood").unwrap(); - for _ in 0..100 { - if supervisor - .frame() - .unwrap() - .into_iter() - .any(|event| event == AgentEvent::Done) - { - assert_eq!(supervisor.active_id(), ordinary); - supervisor.open(ROOT_APP_ID).unwrap(); - assert_eq!(supervisor.active_id(), ROOT_APP_ID); - return; + let deadline = Instant::now() + Duration::from_secs(5); + let mut response = String::new(); + let mut finished = false; + while Instant::now() < deadline && !finished { + while let Ok(request) = requests.try_recv() { + request.handle(&mut supervisor); + } + for event in supervisor.frame().unwrap() { + match event { + AgentEvent::ResponseText(delta) => response.push_str(&delta), + AgentEvent::Done => finished = true, + AgentEvent::Failed(error) => panic!("Agent failed: {error}"), + AgentEvent::Ready => {} + } } std::thread::sleep(Duration::from_millis(2)); } - panic!("Agent did not finish while an ordinary App was foreground"); + + assert!(finished); + assert_eq!(response, "research complete"); + assert_eq!(supervisor.active_id(), "robinhood"); + let storage = supervisor.invoke_tool("research.storage_status", "{}"); + assert!(!storage.is_error, "{}", storage.text); + assert_eq!(storage.details["searches"], 1); + supervisor.open(ROOT_APP_ID).unwrap(); + assert_eq!(supervisor.active_id(), ROOT_APP_ID); } From 8ab03a7b22ef17e92082322b337523201290b78a Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Wed, 12 Aug 2026 13:19:07 +0800 Subject: [PATCH 22/24] Improve long-text rendering and Exa scrolling --- apps/_shared/text.test.ts | 66 ++++++++++++++++++++ apps/_shared/text.ts | 105 ++++++++++++++++++++++++++++++++ apps/exa/app.tsx | 80 +++++++++++++----------- apps/exa/dist/app.js | 10 +-- apps/exa/dist/app.pak | Bin 280336 -> 280512 bytes apps/pi-agent/app.tsx | 90 +++++++++++++++++++-------- apps/pi-agent/dist/app.js | 26 ++++---- apps/pi-agent/dist/app.pak | Bin 374832 -> 427072 bytes docs/pocket-pi-design-system.md | 4 +- 9 files changed, 298 insertions(+), 83 deletions(-) create mode 100644 apps/_shared/text.test.ts diff --git a/apps/_shared/text.test.ts b/apps/_shared/text.test.ts new file mode 100644 index 0000000..674f3fa --- /dev/null +++ b/apps/_shared/text.test.ts @@ -0,0 +1,66 @@ +import { expect, mock, test } from "bun:test"; + +mock.module("@pocketjs/framework", () => ({ + getOps: () => ({ measureText: (value: string) => [...value].length * 8 }), +})); + +const { wrapTextPage } = await import("./text.ts"); + +test("wraps words and unbroken tokens within maxWidth", () => { + const page = wrapTextPage("alpha beta 123456789", 2, 48, 0, 0, 10); + const lines = page.text.split("\n"); + + expect(lines).toEqual(["alpha", "beta", "123456", "789"]); + expect(lines.every((line) => [...line].length * 8 <= 48)).toBe(true); + expect(page.hasMore).toBe(false); +}); + +test("paginates deterministically to EOF and always advances", () => { + const source = "one two three four five six seven eight"; + const rendered: string[] = []; + let offset = 0; + let sourceLine = 0; + let finished = false; + + for (let iteration = 0; iteration <= source.length; iteration += 1) { + const page = wrapTextPage(source, 2, 40, offset, sourceLine, 2); + expect(wrapTextPage(source, 2, 40, offset, sourceLine, 2)).toEqual(page); + expect(page.text.split("\n").length).toBeLessThanOrEqual(2); + rendered.push(page.text); + + if (!page.hasMore) { + finished = true; + break; + } + + expect(page.nextOffset).toBeGreaterThan(offset); + offset = page.nextOffset; + sourceLine = page.nextSourceLine; + } + + expect(finished).toBe(true); + expect(rendered.join("\n").split(/\s+/)).toEqual(source.split(/\s+/)); +}); + +test("tracks source lines across LF and CRLF", () => { + const source = "aa\nbb\r\ncc"; + const first = wrapTextPage(source, 2, 80, 0, 0, 2); + const second = wrapTextPage(source, 2, 80, first.nextOffset, first.nextSourceLine, 2); + + expect(first).toEqual({ + text: "aa\nbb", + nextOffset: "aa\nbb\r\n".length, + startSourceLine: 0, + nextSourceLine: 2, + lastSourceLine: 1, + hasMore: true, + }); + expect(second).toEqual({ + text: "cc", + nextOffset: source.length, + startSourceLine: 2, + nextSourceLine: 2, + lastSourceLine: 2, + hasMore: false, + }); +}); diff --git a/apps/_shared/text.ts b/apps/_shared/text.ts index a5b0c1d..db68da4 100644 --- a/apps/_shared/text.ts +++ b/apps/_shared/text.ts @@ -81,3 +81,108 @@ export function wrapPreview( visible[last] = visible[last].replace(/[\s.]+$/, "") + "…"; return visible.join("\n"); } + +export type WrappedTextPage = { + text: string; + nextOffset: number; + startSourceLine: number; + nextSourceLine: number; + lastSourceLine: number; + hasMore: boolean; +}; + +type VisualLine = { + text: string; + nextOffset: number; + sourceLineEnded: boolean; +}; + +function nextVisualLine( + text: string, + maxWidth: number, + startOffset: number, + width: (value: string) => number, +): VisualLine { + let offset = startOffset; + while (offset < text.length && text[offset] === " ") offset += 1; + + const lineStart = offset; + let line = ""; + let lineWidth = 0; + let lastSpaceOffset = -1; + let lastSpaceIndex = -1; + + while (offset < text.length) { + const character = text[offset]; + if (character === "\n" || character === "\r") { + const nextOffset = character === "\r" && text[offset + 1] === "\n" ? offset + 2 : offset + 1; + return { text: line.replace(/\s+$/, ""), nextOffset, sourceLineEnded: true }; + } + + const characterWidth = width(character); + if (line && lineWidth + characterWidth > maxWidth) { + if (lastSpaceOffset > lineStart) { + return { + text: line.slice(0, lastSpaceIndex).replace(/\s+$/, ""), + nextOffset: lastSpaceOffset, + sourceLineEnded: false, + }; + } + return { text: line, nextOffset: offset, sourceLineEnded: false }; + } + + line += character; + lineWidth += characterWidth; + offset += 1; + if (character === " ") { + lastSpaceOffset = offset; + lastSpaceIndex = line.length - 1; + } + } + + return { text: line.replace(/\s+$/, ""), nextOffset: offset, sourceLineEnded: false }; +} + +// Materialize only the visual lines on one page. The cursor advances directly +// through the source string, so even a multi-megabyte physical line never gets +// sliced, split, or fully wrapped in memory. +export function wrapTextPage( + text: string, + fontSlot: number, + maxWidth: number, + startOffset: number, + startSourceLine: number, + maxLines: number, +): WrappedTextPage { + const lineLimit = Math.max(0, Math.floor(maxLines)); + const lines: string[] = []; + let offset = Math.max(0, Math.min(Math.floor(startOffset), text.length)); + let sourceLine = Math.max(0, Math.floor(startSourceLine)); + let lastSourceLine = sourceLine; + const widths = new Map(); + const width = (value: string) => { + let measured = widths.get(value); + if (measured === undefined) { + measured = getOps().measureText(value, fontSlot); + widths.set(value, measured); + } + return measured; + }; + + while (offset < text.length && lines.length < lineLimit) { + const visualLine = nextVisualLine(text, maxWidth, offset, width); + lastSourceLine = sourceLine; + lines.push(visualLine.text); + offset = visualLine.nextOffset; + if (visualLine.sourceLineEnded) sourceLine += 1; + } + + return { + text: lines.join("\n"), + nextOffset: offset, + startSourceLine: Math.max(0, Math.floor(startSourceLine)), + nextSourceLine: sourceLine, + lastSourceLine, + hasMore: offset < text.length, + }; +} diff --git a/apps/exa/app.tsx b/apps/exa/app.tsx index cfcd540..18bb8c8 100644 --- a/apps/exa/app.tsx +++ b/apps/exa/app.tsx @@ -1,20 +1,19 @@ -import { createSignal, Show } from "solid-js"; +import { createSignal, For, Show } from "solid-js"; import { Text, View } from "@pocketjs/framework/components"; import { mount } from "@pocketjs/framework"; import { Database } from "@pocketjs/framework/db"; -import { VirtualList } from "@pocketjs/framework/virtual-list"; -import { EmptyState, PageIntro, PocketHeader, statusBadge, StatusBar } from "../_shared/ui"; +import { EmptyState, PageIntro, PocketHeader, ScrollButtons, statusBadge, StatusBar } from "../_shared/ui"; const DB_SCHEMA_VERSION = 5; const RETENTION_DAYS = 7; const HISTORY_PAGE_SIZE = 10; -const HISTORY_ROW_HEIGHT = 138; -const HISTORY_VIEWPORT_HEIGHT = 890; +const HISTORY_VISIBLE_ROWS = 6; const db = new Database("exa"); type SearchRow = { id: number; query: string; searched_at: number; status: string; result_count: number; top_title: string | null; error: string | null }; const [history, setHistory] = createSignal([]); const [hasMore, setHasMore] = createSignal(false); +const [historyOffset, setHistoryOffset] = createSignal(0); const [status, setStatus] = createSignal("SEARCH HISTORY IS LOCAL"); let loadedRevision = -1; let loadingMore = false; @@ -45,6 +44,14 @@ function loadMore() { } } +function scrollHistory(direction: -1 | 1) { + const step = 4; + if (direction > 0 && historyOffset() + HISTORY_VISIBLE_ROWS + step > history().length && hasMore()) loadMore(); + setHistoryOffset((offset) => direction < 0 + ? Math.max(0, offset - step) + : Math.min(Math.max(0, history().length - HISTORY_VISIBLE_ROWS), offset + step)); +} + function loadView(revision: number) { if (loadedRevision === revision) return; try { @@ -52,6 +59,7 @@ function loadView(revision: number) { if (Number(schema?.user_version ?? 0) !== DB_SCHEMA_VERSION) { setHistory([]); setHasMore(false); + setHistoryOffset(0); setStatus("SEARCH HISTORY IS LOCAL"); return; } @@ -59,11 +67,13 @@ function loadView(revision: number) { const next = page.slice(0, HISTORY_PAGE_SIZE); setHistory(next); setHasMore(page.length > HISTORY_PAGE_SIZE); + setHistoryOffset(0); setStatus(next[0]?.status === "error" ? String(next[0].error || "EXA SEARCH FAILED").slice(0, 80) : next.length ? "SEARCH HISTORY UPDATED FROM SQLITE" : "SEARCH HISTORY IS LOCAL"); loadedRevision = revision; } catch { setHistory([]); + setHistoryOffset(0); setStatus("SEARCH HISTORY IS LOCAL"); } } @@ -110,38 +120,34 @@ function Exa() { description="Every research.search call is saved here automatically." tone="info" /> - + + + + {(item) => ( + + + {item.query.slice(0, 48)} + {(item.top_title || item.error || "No result title").slice(0, 58)} + {searchTime(item.searched_at)} + + + {item.status === "ok" ? item.result_count + " RESULTS" : "FAILED"} + + + )} + - - - 0}> - { - const item = () => history()[index]; - return ( - - - {item().query.slice(0, 60)} - {(item().top_title || item().error || "No result title").slice(0, 76)} - {searchTime(item().searched_at)} - - - {item().status === "ok" ? item().result_count + " RESULTS" : "FAILED"} - - - ); - }} - /> + + + @@ -173,6 +179,8 @@ mount(() => ); }, tap(x: number, y: number) { if (y < 112 && x < 100) return JSON.stringify({ type: "navigate", app: "pi-agent" }); + if (x >= 620 && y >= 294 && y <= 426) scrollHistory(-1); + else if (x >= 620 && y >= 1020 && y <= 1152) scrollHistory(1); return ""; }, }; diff --git a/apps/exa/dist/app.js b/apps/exa/dist/app.js index 297251f..d50eb34 100644 --- a/apps/exa/dist/app.js +++ b/apps/exa/dist/app.js @@ -1,9 +1,9 @@ -(()=>{var g={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return Z4(this.context.count)},getNextContextId(){return Z4(this.context.count++)}};function Z4(J){let Q=String(J),$=Q.length-1;return g.context.id+($?String.fromCharCode(96+$):"")+Q}function V0(J){g.context=J}function d6(){return{...g.context,id:g.getNextContextId(),count:0}}var a6=!1,s6=(J,Q)=>J===Q,P0=Symbol("solid-proxy"),r6=typeof Proxy==="function",n6=Symbol("solid-track"),o1=Symbol("solid-dev-component"),pJ={equals:s6},X4=null,W4=H4,d=1,SJ=2,Y4={owned:null,cleanups:null,context:null,owner:null},w=null,V=null,_J=null,DJ=null,A=null,h=null,E=null,iJ=0;function dJ(J,Q){let $=A,Z=w,X=J.length===0,W=Q===void 0?Z:Q,Y=X?Y4:{owned:null,cleanups:null,context:W?W.context:null,owner:W},j=X?J:()=>J(()=>b(()=>ZJ(Y)));w=Y,A=null;try{return o(j,!0)}finally{A=$,w=Z}}function JJ(J,Q){Q=Q?Object.assign({},pJ,Q):pJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(V&&V.running&&V.sources.has($))X=X($.tValue);else X=X($.value);return j4($,X)};return[q4.bind($),Z]}function QJ(J,Q,$){let Z=O0(J,Q,!1,d);if(_J&&V&&V.running)h.push(Z);else hJ(Z)}function R0(J,Q,$){W4=$8;let Z=O0(J,Q,!1,d),X=D0&&e6(D0);if(X)Z.suspense=X;if(!$||!$.render)Z.user=!0;E?E.push(Z):hJ(Z)}function $J(J,Q,$){$=$?Object.assign({},pJ,$):pJ;let Z=O0(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,_J&&V&&V.running)Z.tState=d,h.push(Z);else hJ(Z);return q4.bind(Z)}function b(J){if(!DJ&&A===null)return J();let Q=A;A=null;try{if(DJ)return DJ.untrack(J);return J()}finally{A=Q}}function o6(J){R0(()=>b(J))}function OJ(J){if(w===null);else if(w.cleanups===null)w.cleanups=[J];else w.cleanups.push(J);return J}function t6(J){if(V&&V.running)return J(),V.done;let Q=A,$=w;return Promise.resolve().then(()=>{A=Q,w=$;let Z;if(_J||D0)Z=V||(V={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return o(J,!1),A=w=null,Z?Z.done:void 0})}var[t1,z4]=JJ(!1);function e6(J){let Q;return w&&w.context&&(Q=w.context[J.id])!==void 0?Q:J.defaultValue}var D0;function q4(){let J=V&&V.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===d)hJ(this);else{let Q=h;h=null,o(()=>aJ(this),!1),h=Q}if(A){let Q=this.observers;if(!Q||Q[Q.length-1]!==A){let $=Q?Q.length:0;if(!A.sources)A.sources=[this],A.sourceSlots=[$];else A.sources.push(this),A.sourceSlots.push($);if(!Q)this.observers=[A],this.observerSlots=[A.sources.length-1];else Q.push(A),this.observerSlots.push(A.sources.length-1)}}if(J&&V.sources.has(this))return this.tValue;return this.value}function j4(J,Q,$){let Z=V&&V.running&&V.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(V){let X=V.running;if(X||!$&&V.sources.has(J))V.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)o(()=>{for(let X=0;X1e6)throw h=[],Error()},!1)}return Q}function hJ(J){if(!J.fn)return;ZJ(J);let Q=iJ;if(G4(J,V&&V.running&&V.sources.has(J)?J.tValue:J.value,Q),V&&!V.running&&V.sources.has(J))queueMicrotask(()=>{o(()=>{V&&(V.running=!0),A=w=J,G4(J,J.tValue,Q),A=w=null},!1)})}function G4(J,Q,$){let Z,X=w,W=A;A=w=J;try{Z=J.fn(Q)}catch(Y){if(J.pure)if(V&&V.running)J.tState=d,J.tOwned&&J.tOwned.forEach(ZJ),J.tOwned=void 0;else J.state=d,J.owned&&J.owned.forEach(ZJ),J.owned=null;return J.updatedAt=$+1,L0(Y)}finally{A=W,w=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)j4(J,Z,!0);else if(V&&V.running&&J.pure){if(!V.sources.has(J))J.value=Z;V.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function O0(J,Q,$,Z=d,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:w,context:w?w.context:null,pure:$};if(V&&V.running)W.state=0,W.tState=Z;if(w===null);else if(w!==Y4)if(V&&V.running&&w.pure)if(!w.tOwned)w.tOwned=[W];else w.tOwned.push(W);else if(!w.owned)w.owned=[W];else w.owned.push(W);if(DJ&&W.fn){let Y=W.fn,[j,U]=JJ(void 0,{equals:!1}),D=DJ.factory(Y,U);OJ(()=>D.dispose());let O,H=()=>t6(U).then(()=>{if(O)O.dispose(),O=void 0});W.fn=(C)=>{if(j(),V&&V.running){if(!O)O=DJ.factory(Y,H);return O.track(C)}return D.track(C)}}return W}function bJ(J){let Q=V&&V.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===SJ)return aJ(J);if(J.suspense&&b(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(V.disposed.has(X))return}if((Q?J.tState:J.state)===d)hJ(J);else if((Q?J.tState:J.state)===SJ){let X=h;h=null,o(()=>aJ(J,$[0]),!1),h=X}}}function o(J,Q){if(h)return J();let $=!1;if(!Q)h=[];if(E)$=!0;else E=[];iJ++;try{let Z=J();return J8($),Z}catch(Z){if(!$)E=null;h=null,L0(Z)}}function J8(J){if(h){if(_J&&V&&V.running)Q8(h);else H4(h);h=null}if(J)return;let Q;if(V){if(!V.promises.size&&!V.queue.size){let{sources:Z,disposed:X}=V;E.push.apply(E,V.effects),Q=V.resolve;for(let W of E)"tState"in W&&(W.state=W.tState),delete W.tState;V=null,o(()=>{for(let W of X)ZJ(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let Y=0,j=W.owned.length;YW4($),!1);if(Q)Q()}function H4(J){for(let Q=0;Q{Z.delete($),o(()=>{V.running=!0,bJ($)},!1),V&&(V.running=!1)})}}function $8(J){let Q,$=0;for(Q=0;Q=0;Q--)ZJ(J.tOwned[Q]);delete J.tOwned}if(V&&V.running&&J.pure)K4(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)ZJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(V&&V.running)J.tState=0;else J.state=0}function K4(J,Q){if(!Q)J.tState=0,V.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return OJ(()=>U4(W)),()=>{let U=J()||[],D=U.length,O,H;return U[n6],b(()=>{let I,y,x,S,p,F,K,G,L;if(D===0){if(Y!==0)U4(W),W=[],Z=[],X=[],Y=0,j&&(j=[]);if($.fallback)Z=[X8],X[0]=dJ((z)=>{return W[0]=z,$.fallback()}),Y=1}else if(Y===0){X=Array(D);for(H=0;H=F&&G>=F&&Z[K]===U[G];K--,G--)x[G]=X[K],S[G]=W[K],j&&(p[G]=j[K]);I=new Map,y=Array(G+1);for(H=G;H>=F;H--)L=U[H],O=I.get(L),y[H]=O===void 0?-1:O,I.set(L,H);for(O=F;O<=K;O++)if(L=Z[O],H=I.get(L),H!==void 0&&H!==-1)x[H]=X[O],S[H]=W[O],j&&(p[H]=j[O]),H=y[H],I.set(L,H);else W[O]();for(H=F;HJ(Q||{}));return V0($),Z}}return b(()=>J(Q||{}))}function sJ(){return!0}var q8={get(J,Q,$){if(Q===P0)return $;return J.get(Q)},has(J,Q){if(Q===P0)return!0;return J.has(Q)},set:sJ,deleteProperty:sJ,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:sJ,deleteProperty:sJ}},ownKeys(J){return J.keys()}};function k0(J){return!(J=typeof J==="function"?J():J)?{}:J}function j8(){for(let J=0,Q=this.length;J=0;j--){let U=k0(J[j])[Y];if(U!==void 0)return U}},has(Y){for(let j=J.length-1;j>=0;j--)if(Y in k0(J[j]))return!0;return!1},keys(){let Y=[];for(let j=0;j=0;Y--){let j=J[Y];if(!j)continue;let U=Object.getOwnPropertyNames(j);for(let D=U.length-1;D>=0;D--){let O=U[D];if(O==="__proto__"||O==="constructor")continue;let H=Object.getOwnPropertyDescriptor(j,O);if(!Z[O])Z[O]=H.get?{enumerable:!0,configurable:!0,get:j8.bind($[O]=[H.get.bind(j)])}:H.value!==void 0?H:void 0;else{let C=$[O];if(C){if(H.get)C.push(H.get.bind(j));else if(H.value!==void 0)C.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let Y=W.length-1;Y>=0;Y--){let j=W[Y],U=Z[j];if(U&&U.get)Object.defineProperty(X,j,U);else X[j]=U?U.value:void 0}return X}var G8=(J)=>`Stale read from <${J}>.`;function H8(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return $J(W8(()=>J.each,J.children,Q||void 0))}function V4(J){let Q=J.keyed,$=$J(()=>J.when,void 0,void 0),Z=Q?$:$J($,void 0,{equals:(X,W)=>!X===!W});return $J(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?b(()=>W(Q?X:()=>{if(!b(Z))throw G8("Show");return $()})):W}return J.fallback},void 0,void 0)}var B8=(J)=>$J(()=>J());function K8({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:Y,getParentNode:j,getFirstChild:U,getNextSibling:D}){function O(F,K,G,L){if(G!==void 0&&!L)L=[];if(typeof K!=="function")return H(F,K,L,G);QJ((z)=>H(F,K(),z,G),L)}function H(F,K,G,L,z){while(typeof G==="function")G=G();if(K===G)return G;let B=typeof K,M=L!==void 0;if(B==="string"||B==="number"){if(B==="number")K=K.toString();if(M){let P=G[0];if(P&&$(P))Z(P,K);else P=Q(K);G=y(F,G,L,P)}else if(G!==""&&typeof G==="string")Z(U(F),G=K);else y(F,G,L,Q(K)),G=K}else if(K==null||B==="boolean")G=y(F,G,L);else if(B==="function")return QJ(()=>{let P=K();while(typeof P==="function")P=P();G=H(F,P,G,L)}),()=>G;else if(Array.isArray(K)){let P=[];if(C(P,K,z))return QJ(()=>G=H(F,P,G,L,!0)),()=>G;if(P.length===0){let m=y(F,G,L);if(M)return G=m}else if(Array.isArray(G))if(G.length===0)x(F,P,L);else I(F,G,P);else if(G==null||G==="")x(F,P);else I(F,M&&G||[U(F)],P);G=P}else{if(Array.isArray(G)){if(M)return G=y(F,G,L,K);y(F,G,null,K)}else if(G==null||G===""||!U(F))X(F,K);else S(F,K,U(F));G=K}return G}function C(F,K,G){let L=!1;for(let z=0,B=K.length;zf-P){let n1=K[M];while(P=0;M--){let P=K[M];if(z!==P){let m=j(P)===F;if(!B&&!M)m?S(F,z,P):X(F,z,G);else m&&W(F,P)}else B=!0}}else X(F,z,G);return[z]}function x(F,K,G){for(let L=0,z=K.length;LG.children=H(F,K.children,G.children));return QJ(()=>K.ref&&K.ref(F)),QJ(()=>{for(let z in K){if(z==="children"||z==="ref")continue;let B=K[z];if(B===G[z])continue;Y(F,z,B,G[z]),G[z]=B}}),G}return{render(F,K){let G;return dJ((L)=>{G=L,O(K,F())}),G},insert:O,spread(F,K,G){if(typeof K==="function")QJ((L)=>p(F,K(),L,G));else p(F,K,void 0,G)},createElement:J,createTextNode:Q,insertNode:X,setProp(F,K,G,L){return Y(F,K,G,L),G},mergeProps:M4,effect:QJ,memo:B8,createComponent:z8,use(F,K,G){return b(()=>F(K,G))}}}function F8(J){let Q=K8(J);return Q.mergeProps=M4,Q}var P4=480,C0=272,BJ={view:0,text:1,image:2},U8=1,M8=-1,V8={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},R={f32:0,color:1,int:2},P8={width:R.f32,height:R.f32,minW:R.f32,minH:R.f32,maxW:R.f32,maxH:R.f32,paddingT:R.f32,paddingR:R.f32,paddingB:R.f32,paddingL:R.f32,marginT:R.f32,marginR:R.f32,marginB:R.f32,marginL:R.f32,gap:R.f32,flexDir:R.int,justify:R.int,align:R.int,grow:R.f32,shrink:R.f32,basis:R.f32,flexWrap:R.int,posType:R.int,insetT:R.f32,insetR:R.f32,insetB:R.f32,insetL:R.f32,display:R.int,overflow:R.int,zIndex:R.int,hitPass:R.int,bgColor:R.color,gradFrom:R.color,gradTo:R.color,gradDir:R.int,radius:R.f32,opacity:R.f32,borderColor:R.color,borderWidth:R.f32,shadow:R.int,bevelOuterLight:R.color,bevelOuterDark:R.color,bevelInnerLight:R.color,bevelInnerDark:R.color,bevelWidth:R.f32,textColor:R.color,fontSlot:R.int,textAlign:R.int,lineHeight:R.f32,tracking:R.f32,translateX:R.f32,translateY:R.f32,scale:R.f32,rotate:R.f32,scaleX:R.f32,scaleY:R.f32,originX:R.f32,originY:R.f32,rotateX:R.f32,rotateY:R.f32,translateZ:R.f32,perspective:R.f32,arcStart:R.f32,arcSweep:R.f32,arcWidth:R.f32},l={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},R8={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},D8=1,e1=2,JQ=1,QQ=2,$Q=131072,ZQ=1,XQ=262144,WQ=1,YQ=1,zQ=1,qQ=2,jQ=4,GQ=8,HQ=16,BQ=1,KQ=2;function R4(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var FQ=1,O8=1263551300,L8=1,k8=32,C8=24,a={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},KJ=32896,UQ=0.016666666666666666;function D4(J){return J.__viewport??null}var w0=null;function w8(){return null}function O4(J,Q=w8()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function I8(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return O4(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return O4(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function A8(J){w0=J}function LJ(){if(!w0)throw Error("PocketJS: host not installed — call render() first");return w0}function N(){return LJ().ops}function y8(J){globalThis.frame=J}function S8(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function _8(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return R4($>>>16&255,$>>>8&255,$&255,255);return R4($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function h8(J,Q){let $=P8[J];if(typeof Q==="string"){if($===R.color)return _8(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===R.color||$===R.int)return Q>>>0;return Q}var rJ=60,L4=[1,2,3,4,5,6,10,12,15,20,30,60],I0=rJ,XJ=-1,b8=0,xJ=[];function x8(J){if(!Number.isFinite(J)||J<=0)return rJ;let Q=L4[0];for(let $ of L4)if(Math.abs($-J)Q.at<=XJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>XJ);for(let Q of J)Q.cb()}var y0=0.12,nJ=KJ;function T8(J){nJ=J===void 0?KJ:J&65535}function E8(){nJ=KJ}function w4(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function I4(){return w4(nJ&255)}var oJ=new Set,m8=0;function v8(){oJ.clear(),m8=0,E8()}function u8(J){for(let Q of[...oJ])Q(J)}function A4(J){oJ.add(J),OJ(()=>oJ.delete(J))}var FJ=null,y4=null;function l8(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function S4(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function fJ(J){S0();let Q=FJ?FJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return y4.slice(Q.off,Q.off+Q.len)}var gJ=null,_=null,UJ=null,tJ=0,MJ=[],h0=[],kJ=[];function h4(J){if(gJ=J,_=null,UJ=null,tJ=0,MJ.length=0,h0.length=0,kJ.length=0,s){if(s.pressTarget=null,s.target=null,s.spriteDirty=!0,s.fresh=!0,s.vw=0,s.tex>=0){let Q=N();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(s.tex),s.tex=-1}}}function p8(J,Q){J.onPress=Q??void 0}function i8(J,Q){if(J.focusable=Q,N4(),!Q&&_===J)v(null)}function v(J){if(UJ&&UJ!==J)VJ(null);_=J,N().setFocus(J?J.id:0)}function VJ(J){if(UJ===J)return;let Q=N();if(UJ)Q.setActive?.(UJ.id,0);if(UJ=J,J)Q.setActive?.(J.id,1)}function b4(){return _}function b0(){return MJ.length>0?MJ[MJ.length-1]:gJ}function x0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;v($[X])}function s8(){if(!_)return null;let J=b0();if(J&&!r(_,J))return null;for(let Q=h0.length-1;Q>=0;Q--){let $=h0[Q];if(J&&!r($.node,J)&&!r(J,$.node))continue;if(r(_,$.node))return $}return null}function r8(J){let Q=s8();if(!Q)return!1;let $=[];if(x0(Q.node,$),$.length===0){if(_)v(null);return!0}let Z=Q.columns,X=_?$.indexOf(_):-1;if(X<0)return v(x4(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)v($[W]);return!0}function n8(){if(!_)return null;let J=b0();if(J&&!r(_,J))return null;for(let Q=kJ.length-1;Q>=0;Q--){let $=kJ[Q];if(J&&!r($.node,J)&&!r(J,$.node))continue;if(r(_,$.node))return $}return null}function o8(J,Q){let $={node:J,move:Q};kJ.push($);let Z=!1;return()=>{if(Z)return;Z=!0;let X=kJ.lastIndexOf($);if(X>=0)kJ.splice(X,1)}}function eJ(J){let Q=n8();if(Q&&Q.move(J))return;if(r8(J))return;a8(J)}function f4(){g4(_)}function g4(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function WJ(J){VJ(J)}function T4(J){v(J),g4(J)}function r(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function f0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=f0(Q.children[X]);if(W){v(W);return}}let Z=Q;while(Z){if(Z.focusable){v(Z);return}Z=Z.parent}}v(null)}var s=null,E4=0;function N4(){E4++}var e8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],J2=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function Q2(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=e8[Q]>>$&1,X=J2[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,Y=X?255:0;J[W]=Y,J[W+1]=Y,J[W+2]=Y,J[W+3]=255}return J}function $2(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=fJ($.image)}catch(Y){if(LJ().strict)throw Y;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):Z2(Q,W),X<0&&LJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(Q2(),16,16,R8.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function Z2(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&D8)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function J0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=J0($[Z],Q);if(X)return X}return null}var Q0=null;function m4(J){Q0=J}function v4(J){let Q=MJ.length>0?MJ[MJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||r($,Q)))return $;$=$.parent}return null}function u4(J,Q,$){return v4(g0(J,Q,$))}function g0(J,Q,$){if($!==void 0)return $===0?null:J0(Q0??gJ,$);let Z=N(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return J0(Q0??gJ,X(J,Q))}function X2(J,Q,$){let Z=s,X=N();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=D4(X);if(Z.vw=H?H.w:P4,Z.vh=H?H.h:C0,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)$2(Z,X);let W=N8()*Z.speed,Y=I4()*Z.speed;if(Z.dpadSpeed>0&&W===0&&Y===0){if(J&a.LEFT)W=-Z.dpadSpeed;if(J&a.RIGHT)W=Z.dpadSpeed;if(J&a.UP)Y=-Z.dpadSpeed;if(J&a.DOWN)Y=Z.dpadSpeed}let j=Z.fresh;if(W!==0||Y!==0){let H=k4()/60,C=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),I=Math.min(Math.max(Z.y+Y*H,0),Z.vh-1);if(C!==Z.x||I!==Z.y)Z.x=C,Z.y=I,j=!0}if(j)X.setCursorPos(Z.x,Z.y);let U=(Q|$)&Z.button,D=E4;if(j||U!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=v4(J0(Q0??gJ,X.hitTest(Z.x,Z.y)));let O=Z.target;if(O!==_)v(O);if(Q&Z.button&&O)Z.pressTarget=O;if(Z.pressTarget){if(VJ(O===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=O===Z.pressTarget;if(Z.pressTarget=null,VJ(null),H)f4()}}else if($&Z.button)VJ(null);return!0}function W2(J){let Q=J&~tJ,$=tJ&~J;if(tJ=J,s&&X2(J,Q,$))return;if($&a.CIRCLE)VJ(null);if(Q===0)return;if(Q&a.DOWN)eJ("down");if(Q&a.RIGHT)eJ("right");if(Q&a.UP)eJ("up");if(Q&a.LEFT)eJ("left");if(Q&a.CIRCLE)VJ(_),f4()}var T0=null;function l4(J){T0=J}function CJ(){if(N4(),T0)T0()}function Y2(J,Q){J.debugName=Q||void 0,CJ()}var YJ={id:U8,type:BJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},c4=Symbol.for("pocketjs.native-node"),E0=1,TJ=3,t=8,z2=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function $0(J){return J.domAttrs??={}}function p4(J,Q){let $=J.domNodeType??(EJ(J)?TJ:E0),Z=$===TJ?Z0(J.text??""):$===t?G2(J.domData??""):o4(J.domTag??W0(J));for(let X of Object.keys(J.domAttrs??{}))N0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)zJ(Z,p4(X,!0));return Z}function N0(J,Q,$){if(z2.has(Q)){IJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete $0(J)[Q];else $0(J)[Q]=$}function m0(J){if(J[c4]===!0)return J;return Object.defineProperty(J,c4,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(EJ(J)?TJ:E0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===t?J.domData??"":J.text??""},set($){if(J.domNodeType===t)J.domData=String($??"");else X0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===t?J.domData??"":J.text??""},set($){if(J.domNodeType===t)J.domData=String($??"");else X0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===t)return J.domData??"";if(EJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===t)J.domData=Z;else if(EJ(J))X0(J,Z);else if(V2(J),Z)zJ(J,Z0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return e4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??W0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===TJ)return"#text";if(J.domNodeType===t)return"#comment";return(J.domTag??W0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){IJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===YJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return zJ(J,$),$},insertBefore($,Z){return zJ(J,$,Z??null),$},removeChild($){return NJ(J,$),$},replaceChild($,Z){return zJ(J,$,Z),NJ(J,Z),Z},cloneNode($=!1){return p4(J,!!$)},remove(){if(J.parent)NJ(J.parent,J)},setAttribute($,Z){N0(J,$,Z)},removeAttribute($){N0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}m0(YJ);var v0=null;function q2(J){v0=J}var u0={unknownClass:0,unknownTexture:0},i4=new Map;function d4(J,Q){i4.set(J,Q)}var a4=new Map;function s4(J,Q){a4.set(J,Q)}var wJ=new Set,j2=new Set;function r4(J){if(!J)return!1;if(j2.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return m0({id:N().createNode(Q),type:Q,parent:null,children:[],domNodeType:E0,domTag:J})}function Z0(J){let Q=N(),$=Q.createNode(BJ.text);return Q.setText($,J),m0({id:$,type:BJ.text,parent:null,children:[],text:J,domNodeType:TJ,domTag:"#text"})}function G2(J=""){let Q=Z0("");return Q.domNodeType=t,Q.domTag="#comment",Q.domData=J,Q}function X0(J,Q){N().replaceText(J.id,Q),J.text=Q,CJ()}function EJ(J){return J.type===BJ.text}function t4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function zJ(J,Q,$){let Z=N();if(t4(Q),wJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,CJ()}function NJ(J,Q){if(!Q)return;t8(Q),N().removeChild(J.id,Q.id),t4(Q),wJ.add(Q),CJ()}function H2(J){return J.parent??void 0}function B2(J){return J.children[0]}function e4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function K2(J,Q){let $=N();if(CJ(),Q==null||Q===""){$.setStyle(J.id,M8);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=v0?v0(Q):void 0;if(Z===void 0){if(LJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);u0.unknownClass++;return}$.setStyle(J.id,Z)}function F2(J,Q){let $=N();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=i4.get(Q);if(Z===void 0){if(LJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);u0.unknownTexture++;return}$.setImage(J.id,Z)}function U2(J,Q){let $=N();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=a4.get(Q);if(Z===void 0){if(LJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);u0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function M2(J,Q,$){let Z=N(),X=Q??{},W=$??{},Y=!1;for(let j in X){let U=X[j];if(W[j]===U)continue;let D=V8[j];if(D===void 0)throw Error(`PocketJS: unknown style prop '${j}' (see spec PROP)`);Z.setProp(J.id,D,h8(j,U)),Y=!0}if(Y)CJ()}function IJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete $0(J)[Q];else $0(J)[Q]=$;switch(Q){case"class":return K2(J,$),$;case"onPress":case"on:press":return p8(J,$),$;case"src":return F2(J,$),$;case"sprite":return U2(J,$),$;case"style":return M2(J,$,Z),$;case"focusable":return i8(J,!!$),$;case"debugName":return Y2(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${W0(J)}>`)}function V2(J){for(let Q of[...J.children])NJ(J,Q)}function W0(J){for(let Q of Object.keys(BJ))if(BJ[Q]===J.type)return Q;return String(J.type)}function P2(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}IJ(J,Q,$,Z)}var R2=F8({createElement:o4,createTextNode:Z0,replaceText:X0,isTextNode:EJ,setProperty:P2,insertNode(J,Q,$){zJ(J,Q,$)},removeNode(J,Q){NJ(J,Q)},getParentNode:H2,getFirstChild:B2,getNextSibling:e4}),{render:D2,effect:MQ,memo:e,createComponent:k,createElement:J6,insert:VQ,spread:O2,mergeProps:PQ,use:RQ}=R2,DQ={linear:l.Easing.Linear,in:l.Easing.EaseIn,out:l.Easing.EaseOut,"in-out":l.Easing.EaseInOut,"out-back":l.Easing.OutBack,spring:l.Easing.Spring,"spring-bouncy":l.Easing.SpringBouncy},L2=null;function Q6(J){L2=J}function k2(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function $6(J,Q){let $=J6(J);return O2($,Q,!1),k2(Q.nodeRef,$),$}function T(J){return $6("view",J)}function u(J){return $6("text",J)}var OQ=new WeakMap,LQ=new WeakMap,C2={}!==null?Object.freeze({...{}}):Object.freeze({}),kQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:C2}),CQ=new Map,qJ=36000,l0=30,w2=30,q={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(qJ),tapeAnalog:new Uint16Array(qJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-l0,saidHello:!1,hostCalls:0};function I2(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};q.ops=J,q.frame=0,q.tapeStart=0,q.tapeLen=0,q.tapeFirstFrame=0,q.tapeTouch=null,q.replayMasks=null,q.replayAnalog=null,q.replayTouch=null,q.paused=!1,q.stepQueued=0,q.inspectReportId=null,q.inspectAskedAt=0,q.treeDirty=!0,q.treeSentAt=-l0,q.saidHello=!1,q.hostCalls=0,q.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)q.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)q.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else q.transport=null;if(q.transport)l4(()=>{q.treeDirty=!0}),f2();else l4(null);globalThis.__pocketDevtools=T2}function A2(J){return(Q,$,Z,X)=>{if(q.hostCalls++,q.transport)S2(),b2();let W=Q,Y=$===void 0?KJ:$&65535,j=Z,U=X;if(q.replayMasks)if(q.replayAt0?$.slice(0,8):null;if(Z&&!q.tapeTouch)q.tapeTouch=Array(qJ).fill(null);if(q.tapeLen1||Q.length===1&&Q[0][0]!==KJ)J.analog=Q;if(q.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function W6(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,Y]of J)Z.fill(W,X,Math.min(X+Y,$)),X+=Y;return Z}function Y6(J){let Q=0;for(let[,$]of J.masks)Q+=$;return W6(J.masks,0,Q)}function z6(J){let Q=0;for(let[,$]of J.masks)Q+=$;return W6(J.analog??[],KJ,Q)}function q6(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&q.hostCalls%Q!==0)return;if(!q.saidHello)q.saidHello=!0,c({t:"hello",app:q.app,host:g2(),frame:q.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` -`))if(X.trim())_2(X)}}function _2(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=q.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),q.inspectReportId=Z||null,q.inspectAskedAt=q.hostCalls,!Z)c({t:"inspect",id:0,rect:null});break}case"pause":q.paused=!0,q.stepQueued=0,$?.debugPause?.(!0),c0();break;case"resume":q.paused=!1,$?.debugPause?.(!1),c0();break;case"step":q.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":j6();break;case"eval":{let Z=!0,X;try{X=Y0((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}c({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":c({t:"tape",tape:X6()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}c({t:"devStats",frame:q.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())c({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:q.frame});else c({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))q.replayMasks=Y6(Z),q.replayAnalog=Z.analog?z6(Z):null,q.replayTouch=Z.touch?q6(Z):null,q.replayAt=0;break}default:break}}function h2(){if(q.treeDirty&&q.frame-q.treeSentAt>=l0)j6();if(q.frame%w2===0)c0()}function b2(){let J=q.inspectReportId;if(J==null)return;let Q=q.ops;if(!Q?.debugRectXY||!Q.debugRectWH){q.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(q.hostCalls-q.inspectAskedAt>60)q.inspectReportId=null,c({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();q.inspectReportId=null,c({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function c0(){c({t:"stats",frame:q.frame,nodes:B6(YJ),tapeLen:q.tapeLen,paused:q.paused})}function j6(){q.treeDirty=!1,q.treeSentAt=q.frame,c({t:"tree",frame:q.frame,root:H6(YJ)})}function x2(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function p0(J,Q){if(Array.isArray(J)){for(let $ of J)p0($,Q);return}if(x2(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)p0($,Q)}}function G6(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)p0(Z,Q)}function H6(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(G6(J,(X)=>{if(X.domNodeType===8)return;Z.push(H6(X))}),Z.length)Q.k=Z;return Q}function B6(J){let Q=1;return G6(J,($)=>{Q+=B6($)}),Q}function f2(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{c({t:"log",level:$,args:X.map((W)=>Y0(W))}),Z?.apply(Q,X)}}}function Y0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?K6(W):JSON.stringify(K6(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((Y)=>Y0(Y,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,Y])=>`${W}: ${Y0(Y,Q+1)}`).join(", ")}}`}function K6(J){return J.length>200?J.slice(0,199)+"…":J}function g2(){let J=q.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var T2={get frame(){return q.frame},dumpTape:()=>X6(),replay:(J)=>{q.replayMasks=Y6(J),q.replayAnalog=J.analog?z6(J):null,q.replayTouch=J.touch?q6(J):null,q.replayAt=0}},F6=new Map,i0=new Map;function U6(J){return J.trim().replace(/\s+/g," ")}function M6(J){return J.split(" ").sort().join(" ")}var V6=-1;function E2(J){for(let Q of Object.keys(J)){let $=J[Q],Z=U6(Q);F6.set(Z,$);let X=M6(Z),W=i0.get(X);i0.set(X,W!==void 0&&W!==$?V6:$)}}function N2(J){let Q=U6(J),$=F6.get(Q);if($!==void 0)return $;let Z=i0.get(M6(Q));return Z===V6?void 0:Z}var d0=9,m2=(1<{let X=($&u2)!==0,W=X?a0:d0,Y=X?l2:m2;return Object.freeze({id:$>>>(X?c2:v2)&255,x:$&Y,y:$>>>W&Y,hit:Q?.[Z]})}))}function i2(){return z0}function d2(){z0=s0}var P6=8,jJ=8,a2=3,s2=8,r2=6,n2=0.5,n=1,mJ=2,r0=4,PJ=8,AJ=[],R6=0,q0=0,GJ=Array.from({length:P6},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(jJ),histY:new Int16Array(jJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function o2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function t2(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=g0(Q,$,Z.fact);let j=Z.hit;if(j)return o2(j,W)}let Y=X.rect?.();if(!Y)return!1;return Q>=Y.x&&Q=Y.y&&$=0;Y--){let j=AJ[Y];if(j.disposed)continue;if(R6>0&&!j.opts.allowWhenBlocked)continue;if(!t2(j,$,Z,W))continue;j.flags[J.slot]=n,J.owners.push(j)}for(let Y of J.owners)Y.opts.onDown?.(J)}function Q1(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%jJ,J.histLenY||Z>Y))X.flags[J.slot]|=mJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&n)||W&(mJ|r0))continue;if(!X.opts.onLongPress)continue;let Y=Math.max(1,Math.round((X.opts.longPressSeconds??n2)*A0()));if(J.frames=0)AJ.splice($,1)},cancel(){if(!Q.disposed)L6(Q)},get panning(){for(let $ of GJ)if($.used&&Q.flags[$.slot]&PJ)return!0;return!1}}}function k6(J){let Q=W1(J);return OJ(()=>Q.dispose()),Q}function C6(){AJ.length=0,R6=0,q0=0;for(let J of GJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function Y1(){return k6({onDown:(J)=>{let Q=u4(J.x,J.y,J.hit);if(Q)WJ(Q)},onTap:(J)=>{WJ(null);let Q=u4(J.x,J.y,J.hit);if(Q)T4(Q)},onUp:()=>WJ(null),onCancel:()=>WJ(null)})}var z1=1,n0=new Map,j0=[];function q1(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function j1(){z1=1,n0.clear(),j0=[]}function G1(){if(j0.length===0)return;let J=j0;j0=[];for(let{id:Q,result:$}of J){let Z=n0.get(Q);if(!Z)continue;n0.delete(Q),q1()?.({t:"delivery",frame:C4(),id:Q,kind:Z.kind}),Z.onResult($)}}var w6=new Set;function H1(){if(w6.size===0)return;for(let J of w6)J()}var B1={"flex-col w-full h-full bg-slate-50":0,"grow px-6 pt-4 flex-col":1,"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":2,"w-[474] flex-col gap-2":3,"text-lg text-slate-900 font-bold":4,"text-base text-slate-500":5,"text-base text-indigo-600 font-bold":6,"h-[96]":7,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":8,"absolute inset-0 z-50 flex-col items-center justify-center":9,"absolute inset-0 bg-slate-950":10,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":11,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":12,"flex-row flex-wrap":13,grow:14,"text-2xl text-white font-bold":15,"text-2xl text-slate-950 font-bold":16,"text-xl text-slate-900 font-bold":17,"text-base text-slate-600 font-bold":18,"text-lg text-slate-900":19,"text-base text-slate-500 font-bold":20,"px-6":21,"px-6 py-5":22,"gap-4":23,"rounded-xl shadow bg-white border-slate-100":24,"rounded-xl shadow bg-emerald-100 border-emerald-500":25,"bg-white":26,"bg-slate-100":27,"bg-slate-950":28,"px-3 py-2 rounded-lg bg-slate-100":29,"px-3 py-2 rounded-lg bg-indigo-100":30,"text-base text-indigo-700 font-bold":31,"px-3 py-2 rounded-lg bg-emerald-100":32,"text-base text-emerald-700 font-bold":33,"px-3 py-2 rounded-lg bg-amber-100":34,"text-base text-amber-700 font-bold":35,"px-3 py-2 rounded-lg bg-red-100":36,"text-base text-red-500 font-bold":37,"w-[34] h-[34] rounded-lg bg-amber-400":38,"w-[34] h-[34] rounded-lg bg-red-500":39,"w-[34] h-[34] rounded-lg bg-slate-800":40,"w-[34] h-[34] rounded-lg bg-emerald-500":41,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":42,"flex-row items-center gap-4":43,"w-[34] text-2xl text-white font-bold":44,"w-[332] flex-col items-end gap-2":45,"text-base text-slate-300 font-bold":46,"text-base text-slate-400":47,"h-[166] px-6 pt-6 flex-col gap-3":48,"text-base text-orange-600 font-bold":49,"text-lg text-slate-600":50,"h-[44] px-1 flex-row items-center justify-between":51,"w-full h-full items-center justify-center rounded-xl bg-slate-200":52,"w-full h-full items-center justify-center rounded-xl bg-red-100":53,"w-full h-full items-center justify-center rounded-xl bg-slate-100":54,"w-full h-full items-center justify-center rounded-xl bg-orange-600":55,"text-lg text-slate-500 font-bold":56,"text-lg text-red-500 font-bold":57,"text-lg text-white font-bold":58,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":59,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":60,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":61,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":62,"text-2xl text-indigo-700 font-bold":63,"text-2xl text-slate-600 font-bold":64,"pt-7 text-2xl text-slate-900 font-bold":65,"pt-4 text-lg text-slate-500":66,"text-xl text-emerald-600 font-bold":67,"text-xl text-red-500 font-bold":68,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":69,"text-base text-red-300":70,"text-base text-slate-300":71,"text-base text-red-500":72,"w-full h-full px-6 flex-row items-center bg-slate-950":73,"w-full h-full flex-row items-center":74};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var K1="ui:styles",F1="ui:font.",I6="ui:img.",A6="ui:sprite.";function U1(){return globalThis.ui}function M1(J){if(J.__textures)return;for(let Q of _0(I6)){let $=fJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)d4(Q.slice(I6.length),Z)}}function V1(J){if(J.__sprites)return;for(let Q of _0(A6)){let $=fJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),Y=$[4],j=Z.getUint16(6,!0),U=Z.getUint16(8,!0),D=Z.getUint16(10,!0),O=J.uploadTexture($.subarray(16),X,W,Y);if(O>=0)s4(Q.slice(A6.length),{handle:O,frames:j,cols:U,step:D})}}function y6(J){let Q=J6("view");return IJ(Q,"style",J,void 0),Q}var G0=null,H0=null;function P1(J,Q){if(!G0||!H0)return;IJ(G0,"style",{width:J,height:Q,overflow:l.Overflow.Hidden},void 0),IJ(H0,"style",{width:J,height:Q,posType:l.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=N();$.__viewport={w:J,h:Q}}function R1(J,Q={}){let $=I8(Q.ops);if(A8($),q2(N2),Q.styles)E2(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let C in Z)d4(C,Z[C]);let H=$.ops.__sprites;if(H)for(let C in H)s4(C,H[C])}if($.kind==="injected"||Z===void 0){if(Q.pak)_4(Q.pak);if(c8()){for(let H of _0())if(H===K1)$.ops.loadStyles?.(fJ(H));else if(H.startsWith(F1))$.ops.loadFontAtlas?.(fJ(H))}}let X=D4($.ops),W=X?.w??P4,Y=X?.h??C0,j=y6({width:W,height:Y,overflow:l.Overflow.Hidden}),U=y6({width:W,height:Y,posType:l.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});zJ(YJ,j),zJ(YJ,U),Q6(U),G0=j,H0=U,h4(j),m4(YJ),v8(),C6(),Y1(),f8(),j1(),I2($.ops),y8(A2((H,C,I,y)=>{g8(),T8(C),p2(I,y),H1(),G1(),X1(),u8(H),W2(H),n4()}));let D=D2(J,j),O=S8(P1);return()=>{O(),d2(),C6(),D(),h4(null),m4(null),Q6(null),G0=null,H0=null;for(let H of YJ.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);n4()}}function D1(J,Q={}){let $=Q.ops??U1();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)_4(Q.pak);return M1($),V1($),R1(J,{ops:$,styles:Q.styles??B1,pak:Q.pak})}var S6="$b",O1=9007199254740991,L1=":memory:",yJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function k1(J){let Q="";for(let $=0;$>2]+yJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2O1)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function I1(J){if(J!==null&&typeof J==="object")return C1(J[S6]);return J}function A1(J){if(Array.isArray(J))return JSON.stringify(J.map(_6));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=_6(Z);return JSON.stringify(Q)}class o0{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,A1(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=h6(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(I1))}run(...J){let Q=this.execute(h6(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function h6(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class b6{statements=new Map;txDepth=0;constructor(J=L1){let Q=w1();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new o0(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new o0(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let Y=J(...Q);return this.txDepth--,this.exec(X),Y}catch(Y){throw this.txDepth--,this.exec(W),Y}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var y1=0.9672,S1=0.846,B0=4,x6=0.55,_1=48,h1=170,b1=26,f6=0.5,g6=8,x1=0.3,T6=0.6,K0=0.016666666666666666;function E6(J,Q,$){if($<=0)return 0;let Z=(1-1/(J*x6/Q+1))*Q;return Z<$?Z:$}function N6(J,Q){return Q*J/(x6*(Q-J))}function f1(J){let Q=J.extent??(()=>C0),$=J.overscroll??_1,Z=J.decay==="fast"?S1:y1,[X,W]=JJ(J.initial??0),Y=J.initial??0,j="idle",U=0,D=0,O=0,H=0,C=0,I=0,y=1,x=0;function S(z){if(z!==Y)Y=z,W(z)}function p(z){let B=Math.round(z*64)/64;S(B),U=0,j="idle",J.onSettle?.(B)}function F(z){let B=J.max();return z<0?0:z>B?B:z}function K(){let z=J.max();if(D<0)return-E6(-D,Q(),$);if(D>z)return z+E6(D-z,Q(),$);return D}function G(z,B){C=Y,I=F(z),y=Math.max(1,Math.round(B*A0()/1000)),x=0,j=I===Y?"idle":"tween"}function L(z){return Y+z*K0*Z/(1-Z)}return{offset:X,velocity:()=>U,state:()=>j,beginDrag(){let z=J.max();if(U=0,j="tracking",Y<0)D=-N6(-Y,Q());else if(Y>z)D=z+N6(Y-z,Q());else D=Y},drag(z){if(j!=="tracking")this.beginDrag();D+=z,S(K())},endDrag(z){if(j!=="tracking")return;let B=J.max();if(Y<0||Y>B){H=Y<0?0:B,U=z,j="spring";return}if(J.snap){let M=J.snap(L(z),z),P=M-Y,m=Math.min(450,Math.max(150,150+(P<0?-P:P)*0.6));G(M,m);return}if(z>B0||z<-B0){U=z,j="fling";return}p(Y)},scrollTo(z,B){if(B&&"immediate"in B&&B.immediate){U=0,j="idle",S(F(z));return}G(z,B?.durMs??200)},scrollBy(z,B){let M=j==="tween"?I:j==="chase"?O:Y;this.scrollTo(M+z,B)},stop(){U=0,j="idle"},nudge(z){let B=j==="chase"?O:Y;this.chaseTo(B+z)},chaseTo(z){if(O=F(z),j!=="chase"&&O===Y)return;U=0,j="chase"},rebase(z){D+=z,O+=z,H+=z,C+=z,I+=z,S(Y+z)},intent(){return j==="chase"?O:j==="tween"?I:Y},isAtEnd(z=1){return this.intent()>=J.max()-z},projectFling:L,step(){if(j==="idle"||j==="tracking")return;if(j==="chase"){O=F(O);let M=O-Y;if(M===0||M-T6){S(O),j="idle",J.onSettle?.(Y);return}S(Y+M*x1);return}if(j==="tween"){if(x++,x>=y){S(I),j="idle",U=0,J.onSettle?.(Y);return}let P=1-x/y,m=1-P*P*P;S(C+(I-C)*m);return}let z=Y,B=k4();for(let M=0;MP){H=z<0?0:P,j="spring";continue}if(U-B0){p(z);return}}else{let P=F(H),m=h1*(P-z)-b1*U;U+=m*K0,z+=U*K0;let i=P-z;if(i-f6&&U-g6){p(P);return}}S(z)}}}function g1(J,Q={}){let $=Q.stepPx??6,Z=Q.nubPx??10;A4((X)=>{if(Q.active&&!Q.active())return;if(X&a.UP)J.nudge(-$);if(X&a.DOWN)J.nudge($);let W=I4();if(W!==0)J.nudge(W*Z)})}var T1=60,m6=36;function t0(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function E1(J){let Q=()=>J.overscan??T1,$=J.focusRows!==!1,Z=()=>J.inputActive?J.inputActive():!0,X=()=>J.count*J.rowHeight,W=J.controller??f1({max:()=>Math.max(0,X()-J.height)}),Y=W.offset,j,U=new Map,[D,O]=JJ(null),H=null,C=$J((z)=>{let B=Math.max(0,Math.floor((Y()-Q())/J.rowHeight)),M=Math.min(J.count-1,Math.floor((Y()+J.height+Q()-1)/J.rowHeight));if(z&&z[0]===B&&z[1]===M)return z;return[B,M]},[0,-1]),I=$J(()=>{let[z,B]=C(),M=[];for(let P=z;P<=B;P++)M.push(P);return M}),y=()=>{let z=b4();if(z){for(let[B,M]of U)if(t0(z,M))return B}return b(D)};function x(z,B="nearest",M=!0){let P=z*J.rowHeight,m=P+J.rowHeight,i=b(Y),f;switch(B){case"start":f=P;break;case"center":f=P-(J.height-J.rowHeight)/2;break;case"end":f=m-J.height;break;default:if(Pi+J.height)f=m-J.height;else return}if(M)W.chaseTo(f);else W.scrollTo(f,{immediate:!0})}function S(z){O(z),x(z,"nearest");let B=U.get(z);if(B)H=null,v(B);else H=z}let p=(z)=>{if(z!=="up"&&z!=="down")return!1;if(!Z()||J.count===0)return!1;let B=y();if(B===null)return S(Math.max(0,Math.min(J.count-1,Math.floor(b(Y)/J.rowHeight)))),!0;let M=z==="down"?B+1:B-1;if(M<0||M>=J.count)return!0;return S(M),!0};o6(()=>{if($){if(j)OJ(o8(j,p));R0(()=>{if(I(),H===null)return;let z=U.get(H);if(z)H=null,v(z)})}else g1(W,{active:Z})});let F=(z)=>{let B=g0(z.x,z.y,z.hit);if(B){for(let[M,P]of U)if(t0(B,P))return{index:M,node:P}}return null};k6({region:{node:()=>j},axis:"y",onDown:(z)=>{if(!Z())return;if(W.stop(),!$)return;let B=F(z);if(B?.node)WJ(B.node)},onPanStart:()=>{if(!Z())return;WJ(null),W.beginDrag()},onPanMove:(z)=>{if(!Z())return;W.drag(-z.fdy)},onPanEnd:(z)=>{if(!Z())return;W.endDrag(-z.vy)},onTap:(z)=>{if(!Z())return;let B=F(z);if(!B)return;if(WJ(null),O(B.index),B.node&&$)T4(B.node);else J.onRowPress?.(B.index)},onCancel:()=>{if(WJ(null),W.state()==="tracking")W.endDrag(0)}}),A4(()=>{if(W.step(),$){let B=b4();if(B){for(let[M,P]of U)if(t0(B,P)){if(b(D)!==M)O(M);break}}}let z=b(Y);if(J.onNearStart&&z<(J.nearStartPx??m6))J.onNearStart();if(J.onNearEnd){let B=Math.max(0,X()-J.height);if(z>B-(J.nearEndPx??m6))J.onNearEnd()}});let K=J.count;R0(()=>{let z=J.count;b(()=>{if(J.stickToBottom&&z>K){let B=Math.max(0,K*J.rowHeight-J.height);if(W.intent()>=B-8)W.chaseTo(Math.max(0,z*J.rowHeight-J.height))}K=z})});let G={scroller:W,rebase:(z)=>W.rebase(z),rebaseRows:(z)=>b(()=>W.rebase(z*J.rowHeight)),scrollToIndex:(z,B,M)=>b(()=>x(z,B,M)),focusedIndex:D,focusRow(z){b(()=>{if(!$||J.count===0)return;S(Math.max(0,Math.min(J.count-1,z)))})}};return J.ref?.(G),T({get style(){return{overflow:l.Overflow.Hidden,height:J.height,width:-1,...J.style}},ref:(z)=>{j=z},children:T({get style(){return{posType:l.PosType.Absolute,insetT:0,insetL:0,insetR:0,height:X(),translateY:-Y()}},children:H8({get each(){return I()},children:(z)=>T({focusable:$,onPress:J.onRowPress?()=>J.onRowPress(z):void 0,style:{posType:l.PosType.Absolute,insetT:z*J.rowHeight,insetL:0,insetR:0,height:J.rowHeight},ref:(B)=>{U.set(z,B),OJ(()=>{if(U.get(z)===B)U.delete(z)})},get children(){return J.renderRow(z)}})})})})}var v6={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"},F0={neutral:{surface:"px-3 py-2 rounded-lg bg-slate-100",text:"text-base text-slate-600 font-bold"},info:{surface:"px-3 py-2 rounded-lg bg-indigo-100",text:"text-base text-indigo-700 font-bold"},success:{surface:"px-3 py-2 rounded-lg bg-emerald-100",text:"text-base text-emerald-700 font-bold"},warning:{surface:"px-3 py-2 rounded-lg bg-amber-100",text:"text-base text-amber-700 font-bold"},danger:{surface:"px-3 py-2 rounded-lg bg-red-100",text:"text-base text-red-500 font-bold"}};function N1(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return k(T,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[k(T,{class:"flex-row items-center gap-4",get children(){return[e(()=>e(()=>!!J.back)()?k(u,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):k(T,{get["class"](){return Q()}})),k(u,{get["class"](){return v6.appTitle},get children(){return J.title}})]}}),k(T,{class:"w-[332] flex-col items-end gap-2",get children(){return[k(u,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),k(u,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function m1(J){return k(T,{class:"h-[166] px-6 pt-6 flex-col gap-3",get children(){return[k(u,{get["class"](){return J.tone==="info"?"text-base text-indigo-700 font-bold":"text-base text-orange-600 font-bold"},get children(){return J.eyebrow}}),k(u,{get["class"](){return v6.pageTitle},get children(){return J.title}}),k(u,{class:"text-lg text-slate-600",get children(){return J.description}})]}})}function v1(J){return k(T,{get["class"](){return J.compact?"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100"},get children(){return[e(()=>e(()=>!!J.icon)()?k(T,{get["class"](){return J.tone==="info"?"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100"},get children(){return k(u,{get["class"](){return J.tone==="info"?"text-2xl text-indigo-700 font-bold":"text-2xl text-slate-600 font-bold"},get children(){return J.icon}})}}):null),k(u,{get["class"](){return J.icon?"pt-7 text-2xl text-slate-900 font-bold":"text-lg text-slate-500 font-bold"},get children(){return J.title}}),e(()=>e(()=>!!J.detail)()?k(u,{class:"pt-4 text-lg text-slate-500",get children(){return J.detail}}):null)]}})}function u1(J){let Q=()=>J.dark?J.tone==="danger"?"text-base text-red-300":"text-base text-slate-300":J.tone==="danger"?"text-base text-red-500":"text-base text-slate-500";return k(T,{get["class"](){return J.dark?"w-full h-full px-6 flex-row items-center bg-slate-950":"w-full h-full flex-row items-center"},get children(){return k(u,{get["class"](){return Q()},get children(){return J.text}})}})}var uJ=5,u6=7,lJ=10,l1=138,c1=890,HJ=new b6("exa"),[cJ,U0]=JJ([]),[p1,e0]=JJ(!1),[l6,J4]=JJ("SEARCH HISTORY IS LOCAL"),M0=-1,Q4=!1;function i1(J){try{return JSON.parse(J)}catch{return null}}function d1(J){let Q=new Date(J*1000).toISOString();return Q.slice(0,10)+" · "+Q.slice(11,16)+" UTC"}function c6(J){return HJ.query(` +(()=>{var MJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return r0(this.context.count)},getNextContextId(){return r0(this.context.count++)}};function r0(J){let Q=String(J),$=Q.length-1;return MJ.context.id+($?String.fromCharCode(96+$):"")+Q}function o0(J){MJ.context=J}function b4(){return{...MJ.context,id:MJ.getNextContextId(),count:0}}var x4=!1,h4=(J,Q)=>J===Q,B0=Symbol("solid-proxy"),f4=typeof Proxy==="function",g4=Symbol("solid-track"),A2=Symbol("solid-dev-component"),vJ={equals:h4},n0=null,T4=X1,N=1,IJ=2,t0={owned:null,cleanups:null,context:null,owner:null},O=null,B=null,AJ=null,VJ=null,k=null,S=null,f=null,mJ=0;function uJ(J,Q){let $=k,Z=O,X=J.length===0,W=Q===void 0?Z:Q,Y=X?t0:{owned:null,cleanups:null,context:W?W.context:null,owner:W},j=X?J:()=>J(()=>r(()=>o(Y)));O=Y,k=null;try{return i(j,!0)}finally{k=$,O=Z}}function WJ(J,Q){Q=Q?Object.assign({},vJ,Q):vJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return Q1($,X)};return[J1.bind($),Z]}function a(J,Q,$){let Z=Z1(J,Q,!1,N);if(AJ&&B&&B.running)S.push(Z);else lJ(Z)}function PJ(J,Q,$){$=$?Object.assign({},vJ,$):vJ;let Z=Z1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,AJ&&B&&B.running)Z.tState=N,S.push(Z);else lJ(Z);return J1.bind(Z)}function r(J){if(!VJ&&k===null)return J();let Q=k;k=null;try{if(VJ)return VJ.untrack(J);return J()}finally{k=Q}}function H0(J){if(O===null);else if(O.cleanups===null)O.cleanups=[J];else O.cleanups.push(J);return J}function N4(J){if(B&&B.running)return J(),B.done;let Q=k,$=O;return Promise.resolve().then(()=>{k=Q,O=$;let Z;if(AJ||E4)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return i(J,!1),k=O=null,Z?Z.done:void 0})}var[S2,e0]=WJ(!1),E4;function J1(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===N)lJ(this);else{let Q=S;S=null,i(()=>cJ(this),!1),S=Q}if(k){let Q=this.observers;if(!Q||Q[Q.length-1]!==k){let $=Q?Q.length:0;if(!k.sources)k.sources=[this],k.sourceSlots=[$];else k.sources.push(this),k.sourceSlots.push($);if(!Q)this.observers=[k],this.observerSlots=[k.sources.length-1];else Q.push(k),this.observerSlots.push(k.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function Q1(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)i(()=>{for(let X=0;X1e6)throw S=[],Error()},!1)}return Q}function lJ(J){if(!J.fn)return;o(J);let Q=mJ;if($1(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{i(()=>{B&&(B.running=!0),k=O=J,$1(J,J.tValue,Q),k=O=null},!1)})}function $1(J,Q,$){let Z,X=O,W=k;k=O=J;try{Z=J.fn(Q)}catch(Y){if(J.pure)if(B&&B.running)J.tState=N,J.tOwned&&J.tOwned.forEach(o),J.tOwned=void 0;else J.state=N,J.owned&&J.owned.forEach(o),J.owned=null;return J.updatedAt=$+1,U0(Y)}finally{k=W,O=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)Q1(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function Z1(J,Q,$,Z=N,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:O,context:O?O.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(O===null);else if(O!==t0)if(B&&B.running&&O.pure)if(!O.tOwned)O.tOwned=[W];else O.tOwned.push(W);else if(!O.owned)O.owned=[W];else O.owned.push(W);if(VJ&&W.fn){let Y=W.fn,[j,U]=WJ(void 0,{equals:!1}),V=VJ.factory(Y,U);H0(()=>V.dispose());let w,G=()=>N4(U).then(()=>{if(w)w.dispose(),w=void 0});W.fn=(I)=>{if(j(),B&&B.running){if(!w)w=VJ.factory(Y,G);return w.track(I)}return V.track(I)}}return W}function K0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===IJ)return cJ(J);if(J.suspense&&r(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===N)lJ(J);else if((Q?J.tState:J.state)===IJ){let X=S;S=null,i(()=>cJ(J,$[0]),!1),S=X}}}function i(J,Q){if(S)return J();let $=!1;if(!Q)S=[];if(f)$=!0;else f=[];mJ++;try{let Z=J();return v4($),Z}catch(Z){if(!$)f=null;S=null,U0(Z)}}function v4(J){if(S){if(AJ&&B&&B.running)m4(S);else X1(S);S=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;f.push.apply(f,B.effects),Q=B.resolve;for(let W of f)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,i(()=>{for(let W of X)o(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let Y=0,j=W.owned.length;YT4($),!1);if(Q)Q()}function X1(J){for(let Q=0;Q{Z.delete($),i(()=>{B.running=!0,K0($)},!1),B&&(B.running=!1)})}}function cJ(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)o(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)q1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)o(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function q1(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return H0(()=>z1(W)),()=>{let U=J()||[],V=U.length,w,G;return U[g4],r(()=>{let b,h,c,XJ,HJ,H,F,z,M;if(V===0){if(Y!==0)z1(W),W=[],Z=[],X=[],Y=0,j&&(j=[]);if($.fallback)Z=[l4],X[0]=uJ((L)=>{return W[0]=L,$.fallback()}),Y=1}else if(Y===0){X=Array(V);for(G=0;G=H&&z>=H&&Z[F]===U[z];F--,z--)c[z]=X[F],XJ[z]=W[F],j&&(HJ[z]=j[F]);b=new Map,h=Array(z+1);for(G=z;G>=H;G--)M=U[G],w=b.get(M),h[G]=w===void 0?-1:w,b.set(M,G);for(w=H;w<=F;w++)if(M=Z[w],G=b.get(M),G!==void 0&&G!==-1)c[G]=X[w],XJ[G]=W[w],j&&(HJ[G]=j[w]),G=h[G],b.set(M,G);else W[w]();for(G=H;GJ(Q||{}));return o0($),Z}}return r(()=>J(Q||{}))}function pJ(){return!0}var d4={get(J,Q,$){if(Q===B0)return $;return J.get(Q)},has(J,Q){if(Q===B0)return!0;return J.has(Q)},set:pJ,deleteProperty:pJ,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:pJ,deleteProperty:pJ}},ownKeys(J){return J.keys()}};function M0(J){return!(J=typeof J==="function"?J():J)?{}:J}function s4(){for(let J=0,Q=this.length;J=0;j--){let U=M0(J[j])[Y];if(U!==void 0)return U}},has(Y){for(let j=J.length-1;j>=0;j--)if(Y in M0(J[j]))return!0;return!1},keys(){let Y=[];for(let j=0;j=0;Y--){let j=J[Y];if(!j)continue;let U=Object.getOwnPropertyNames(j);for(let V=U.length-1;V>=0;V--){let w=U[V];if(w==="__proto__"||w==="constructor")continue;let G=Object.getOwnPropertyDescriptor(j,w);if(!Z[w])Z[w]=G.get?{enumerable:!0,configurable:!0,get:s4.bind($[w]=[G.get.bind(j)])}:G.value!==void 0?G:void 0;else{let I=$[w];if(I){if(G.get)I.push(G.get.bind(j));else if(G.value!==void 0)I.push(()=>G.value)}}}}let X={},W=Object.keys(Z);for(let Y=W.length-1;Y>=0;Y--){let j=W[Y],U=Z[j];if(U&&U.get)Object.defineProperty(X,j,U);else X[j]=U?U.value:void 0}return X}var a4=(J)=>`Stale read from <${J}>.`;function r4(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return PJ(c4(()=>J.each,J.children,Q||void 0))}function o4(J){let Q=J.keyed,$=PJ(()=>J.when,void 0,void 0),Z=Q?$:PJ($,void 0,{equals:(X,W)=>!X===!W});return PJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?r(()=>W(Q?X:()=>{if(!r(Z))throw a4("Show");return $()})):W}return J.fallback},void 0,void 0)}var n4=(J)=>PJ(()=>J());function t4({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:Y,getParentNode:j,getFirstChild:U,getNextSibling:V}){function w(H,F,z,M){if(z!==void 0&&!M)M=[];if(typeof F!=="function")return G(H,F,M,z);a((L)=>G(H,F(),L,z),M)}function G(H,F,z,M,L){while(typeof z==="function")z=z();if(F===z)return z;let C=typeof F,D=M!==void 0;if(C==="string"||C==="number"){if(C==="number")F=F.toString();if(D){let P=z[0];if(P&&$(P))Z(P,F);else P=Q(F);z=h(H,z,M,P)}else if(z!==""&&typeof z==="string")Z(U(H),z=F);else h(H,z,M,Q(F)),z=F}else if(F==null||C==="boolean")z=h(H,z,M);else if(C==="function")return a(()=>{let P=F();while(typeof P==="function")P=P();z=G(H,P,z,M)}),()=>z;else if(Array.isArray(F)){let P=[];if(I(P,F,L))return a(()=>z=G(H,P,z,M,!0)),()=>z;if(P.length===0){let kJ=h(H,z,M);if(D)return z=kJ}else if(Array.isArray(z))if(z.length===0)c(H,P,M);else b(H,z,P);else if(z==null||z==="")c(H,P);else b(H,D&&z||[U(H)],P);z=P}else{if(Array.isArray(z)){if(D)return z=h(H,z,M,F);h(H,z,null,F)}else if(z==null||z===""||!U(H))X(H,F);else XJ(H,F,U(H));z=F}return z}function I(H,F,z){let M=!1;for(let L=0,C=F.length;Lp-P){let I2=F[D];while(P=0;D--){let P=F[D];if(L!==P){let kJ=j(P)===H;if(!C&&!D)kJ?XJ(H,L,P):X(H,L,z);else kJ&&W(H,P)}else C=!0}}else X(H,L,z);return[L]}function c(H,F,z){for(let M=0,L=F.length;Mz.children=G(H,F.children,z.children));return a(()=>F.ref&&F.ref(H)),a(()=>{for(let L in F){if(L==="children"||L==="ref")continue;let C=F[L];if(C===z[L])continue;Y(H,L,C,z[L]),z[L]=C}}),z}return{render(H,F){let z;return uJ((M)=>{z=M,w(F,H())}),z},insert:w,spread(H,F,z){if(typeof F==="function")a((M)=>HJ(H,F(),M,z));else HJ(H,F,void 0,z)},createElement:J,createTextNode:Q,insertNode:X,setProp(H,F,z,M){return Y(H,F,z,M),z},mergeProps:j1,effect:a,memo:n4,createComponent:i4,use(H,F,z){return r(()=>H(F,z))}}}function e4(J){let Q=t4(J);return Q.mergeProps=j1,Q}var G1=480,F1=272,qJ={view:0,text:1,image:2},J6=1,Q6=-1,$6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},K={f32:0,color:1,int:2},Z6={width:K.f32,height:K.f32,minW:K.f32,minH:K.f32,maxW:K.f32,maxH:K.f32,paddingT:K.f32,paddingR:K.f32,paddingB:K.f32,paddingL:K.f32,marginT:K.f32,marginR:K.f32,marginB:K.f32,marginL:K.f32,gap:K.f32,flexDir:K.int,justify:K.int,align:K.int,grow:K.f32,shrink:K.f32,basis:K.f32,flexWrap:K.int,posType:K.int,insetT:K.f32,insetR:K.f32,insetB:K.f32,insetL:K.f32,display:K.int,overflow:K.int,zIndex:K.int,hitPass:K.int,bgColor:K.color,gradFrom:K.color,gradTo:K.color,gradDir:K.int,radius:K.f32,opacity:K.f32,borderColor:K.color,borderWidth:K.f32,shadow:K.int,bevelOuterLight:K.color,bevelOuterDark:K.color,bevelInnerLight:K.color,bevelInnerDark:K.color,bevelWidth:K.f32,textColor:K.color,fontSlot:K.int,textAlign:K.int,lineHeight:K.f32,tracking:K.f32,translateX:K.f32,translateY:K.f32,scale:K.f32,rotate:K.f32,scaleX:K.f32,scaleY:K.f32,originX:K.f32,originY:K.f32,rotateX:K.f32,rotateY:K.f32,translateZ:K.f32,perspective:K.f32,arcStart:K.f32,arcSweep:K.f32,arcWidth:K.f32},E={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},X6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},W6=1,_2=2,y2=1,b2=2,x2=131072,h2=1,f2=262144,g2=1,T2=1,N2=1,E2=2,v2=4,m2=8,u2=16,l2=1,c2=2;function B1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var p2=1,q6=1263551300,Y6=1,z6=32,j6=24,m={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},YJ=32896,i2=0.016666666666666666;function H1(J){return J.__viewport??null}var V0=null;function G6(){return null}function K1(J,Q=G6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function F6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return K1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return K1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function B6(J){V0=J}function RJ(){if(!V0)throw Error("PocketJS: host not installed — call render() first");return V0}function x(){return RJ().ops}function H6(J){globalThis.frame=J}function K6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function U6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return B1($>>>16&255,$>>>8&255,$&255,255);return B1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function M6(J,Q){let $=Z6[J];if(typeof Q==="string"){if($===K.color)return U6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===K.color||$===K.int)return Q>>>0;return Q}var iJ=60,U1=[1,2,3,4,5,6,10,12,15,20,30,60],P0=iJ,n=-1,V6=0,SJ=[];function P6(J){if(!Number.isFinite(J)||J<=0)return iJ;let Q=U1[0];for(let $ of U1)if(Math.abs($-J)Q.at<=n).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;SJ=SJ.filter((Q)=>Q.at>n);for(let Q of J)Q.cb()}var R0=0.12,dJ=YJ;function L6(J){dJ=J===void 0?YJ:J&65535}function C6(){dJ=YJ}function P1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function k6(){return P1(dJ&255)}var R1=new Set,I6=0;function A6(){R1.clear(),I6=0,C6()}function S6(J){for(let Q of[...R1])Q(J)}var zJ=null,w1=null;function _6(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function D1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function _J(J){w0();let Q=zJ?zJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return w1.slice(Q.off,Q.off+Q.len)}var yJ=null,A=null,jJ=null,sJ=0,GJ=[],L0=[],C0=[];function C1(J){if(yJ=J,A=null,jJ=null,sJ=0,GJ.length=0,L0.length=0,C0.length=0,v){if(v.pressTarget=null,v.target=null,v.spriteDirty=!0,v.fresh=!0,v.vw=0,v.tex>=0){let Q=x();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(v.tex),v.tex=-1}}}function b6(J,Q){J.onPress=Q??void 0}function x6(J,Q){if(J.focusable=Q,S1(),!Q&&A===J)T(null)}function T(J){if(jJ&&jJ!==J)FJ(null);A=J,x().setFocus(J?J.id:0)}function FJ(J){if(jJ===J)return;let Q=x();if(jJ)Q.setActive?.(jJ.id,0);if(jJ=J,J)Q.setActive?.(J.id,1)}function O0(){return GJ.length>0?GJ[GJ.length-1]:yJ}function k0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;T($[X])}function g6(){if(!A)return null;let J=O0();if(J&&!u(A,J))return null;for(let Q=L0.length-1;Q>=0;Q--){let $=L0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function T6(J){let Q=g6();if(!Q)return!1;let $=[];if(k0(Q.node,$),$.length===0){if(A)T(null);return!0}let Z=Q.columns,X=A?$.indexOf(A):-1;if(X<0)return T(O1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)T($[W]);return!0}function N6(){if(!A)return null;let J=O0();if(J&&!u(A,J))return null;for(let Q=C0.length-1;Q>=0;Q--){let $=C0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function aJ(J){let Q=N6();if(Q&&Q.move(J))return;if(T6(J))return;f6(J)}function k1(){I1(A)}function I1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function rJ(J){FJ(J)}function E6(J){T(J),I1(J)}function u(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function I0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=I0(Q.children[X]);if(W){T(W);return}}let Z=Q;while(Z){if(Z.focusable){T(Z);return}Z=Z.parent}}T(null)}var v=null,A1=0;function S1(){A1++}var m6=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],u6=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function l6(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=m6[Q]>>$&1,X=u6[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,Y=X?255:0;J[W]=Y,J[W+1]=Y,J[W+2]=Y,J[W+3]=255}return J}function c6(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=_J($.image)}catch(Y){if(RJ().strict)throw Y;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):p6(Q,W),X<0&&RJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(l6(),16,16,X6.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function p6(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&W6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function oJ(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=oJ($[Z],Q);if(X)return X}return null}var nJ=null;function _1(J){nJ=J}function y1(J){let Q=GJ.length>0?GJ[GJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||u($,Q)))return $;$=$.parent}return null}function b1(J,Q,$){return y1(x1(J,Q,$))}function x1(J,Q,$){if($!==void 0)return $===0?null:oJ(nJ??yJ,$);let Z=x(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return oJ(nJ??yJ,X(J,Q))}function i6(J,Q,$){let Z=v,X=x();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let G=H1(X);if(Z.vw=G?G.w:G1,Z.vh=G?G.h:F1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)c6(Z,X);let W=O6()*Z.speed,Y=k6()*Z.speed;if(Z.dpadSpeed>0&&W===0&&Y===0){if(J&m.LEFT)W=-Z.dpadSpeed;if(J&m.RIGHT)W=Z.dpadSpeed;if(J&m.UP)Y=-Z.dpadSpeed;if(J&m.DOWN)Y=Z.dpadSpeed}let j=Z.fresh;if(W!==0||Y!==0){let G=R6()/60,I=Math.min(Math.max(Z.x+W*G,0),Z.vw-1),b=Math.min(Math.max(Z.y+Y*G,0),Z.vh-1);if(I!==Z.x||b!==Z.y)Z.x=I,Z.y=b,j=!0}if(j)X.setCursorPos(Z.x,Z.y);let U=(Q|$)&Z.button,V=A1;if(j||U!==0||V!==Z.gen)Z.gen=V,Z.fresh=!1,Z.target=y1(oJ(nJ??yJ,X.hitTest(Z.x,Z.y)));let w=Z.target;if(w!==A)T(w);if(Q&Z.button&&w)Z.pressTarget=w;if(Z.pressTarget){if(FJ(w===Z.pressTarget?Z.pressTarget:null),$&Z.button){let G=w===Z.pressTarget;if(Z.pressTarget=null,FJ(null),G)k1()}}else if($&Z.button)FJ(null);return!0}function d6(J){let Q=J&~sJ,$=sJ&~J;if(sJ=J,v&&i6(J,Q,$))return;if($&m.CIRCLE)FJ(null);if(Q===0)return;if(Q&m.DOWN)aJ("down");if(Q&m.RIGHT)aJ("right");if(Q&m.UP)aJ("up");if(Q&m.LEFT)aJ("left");if(Q&m.CIRCLE)FJ(A),k1()}var A0=null;function h1(J){A0=J}function wJ(){if(S1(),A0)A0()}function s6(J,Q){J.debugName=Q||void 0,wJ()}var t={id:J6,type:qJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},f1=Symbol.for("pocketjs.native-node"),S0=1,bJ=3,d=8,a6=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function tJ(J){return J.domAttrs??={}}function g1(J,Q){let $=J.domNodeType??(xJ(J)?bJ:S0),Z=$===bJ?eJ(J.text??""):$===d?n6(J.domData??""):l1(J.domTag??Q0(J));for(let X of Object.keys(J.domAttrs??{}))_0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)e(Z,g1(X,!0));return Z}function _0(J,Q,$){if(a6.has(Q)){LJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete tJ(J)[Q];else tJ(J)[Q]=$}function y0(J){if(J[f1]===!0)return J;return Object.defineProperty(J,f1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(xJ(J)?bJ:S0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else J0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else J0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===d)return J.domData??"";if(xJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===d)J.domData=Z;else if(xJ(J))J0(J,Z);else if(X8(J),Z)e(J,eJ(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return p1(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??Q0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===bJ)return"#text";if(J.domNodeType===d)return"#comment";return(J.domTag??Q0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){LJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===t)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return e(J,$),$},insertBefore($,Z){return e(J,$,Z??null),$},removeChild($){return hJ(J,$),$},replaceChild($,Z){return e(J,$,Z),hJ(J,Z),Z},cloneNode($=!1){return g1(J,!!$)},remove(){if(J.parent)hJ(J.parent,J)},setAttribute($,Z){_0(J,$,Z)},removeAttribute($){_0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}y0(t);var b0=null;function r6(J){b0=J}var x0={unknownClass:0,unknownTexture:0},T1=new Map;function N1(J,Q){T1.set(J,Q)}var E1=new Map;function v1(J,Q){E1.set(J,Q)}var DJ=new Set,o6=new Set;function m1(J){if(!J)return!1;if(o6.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return y0({id:x().createNode(Q),type:Q,parent:null,children:[],domNodeType:S0,domTag:J})}function eJ(J){let Q=x(),$=Q.createNode(qJ.text);return Q.setText($,J),y0({id:$,type:qJ.text,parent:null,children:[],text:J,domNodeType:bJ,domTag:"#text"})}function n6(J=""){let Q=eJ("");return Q.domNodeType=d,Q.domTag="#comment",Q.domData=J,Q}function J0(J,Q){x().replaceText(J.id,Q),J.text=Q,wJ()}function xJ(J){return J.type===qJ.text}function c1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function e(J,Q,$){let Z=x();if(c1(Q),DJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function hJ(J,Q){if(!Q)return;v6(Q),x().removeChild(J.id,Q.id),c1(Q),DJ.add(Q),wJ()}function t6(J){return J.parent??void 0}function e6(J){return J.children[0]}function p1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function J8(J,Q){let $=x();if(wJ(),Q==null||Q===""){$.setStyle(J.id,Q6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=b0?b0(Q):void 0;if(Z===void 0){if(RJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);x0.unknownClass++;return}$.setStyle(J.id,Z)}function Q8(J,Q){let $=x();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=T1.get(Q);if(Z===void 0){if(RJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);x0.unknownTexture++;return}$.setImage(J.id,Z)}function $8(J,Q){let $=x();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=E1.get(Q);if(Z===void 0){if(RJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);x0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function Z8(J,Q,$){let Z=x(),X=Q??{},W=$??{},Y=!1;for(let j in X){let U=X[j];if(W[j]===U)continue;let V=$6[j];if(V===void 0)throw Error(`PocketJS: unknown style prop '${j}' (see spec PROP)`);Z.setProp(J.id,V,M6(j,U)),Y=!0}if(Y)wJ()}function LJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete tJ(J)[Q];else tJ(J)[Q]=$;switch(Q){case"class":return J8(J,$),$;case"onPress":case"on:press":return b6(J,$),$;case"src":return Q8(J,$),$;case"sprite":return $8(J,$),$;case"style":return Z8(J,$,Z),$;case"focusable":return x6(J,!!$),$;case"debugName":return s6(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${Q0(J)}>`)}function X8(J){for(let Q of[...J.children])hJ(J,Q)}function Q0(J){for(let Q of Object.keys(qJ))if(qJ[Q]===J.type)return Q;return String(J.type)}function W8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}LJ(J,Q,$,Z)}var q8=e4({createElement:l1,createTextNode:eJ,replaceText:J0,isTextNode:xJ,setProperty:W8,insertNode(J,Q,$){e(J,Q,$)},removeNode(J,Q){hJ(J,Q)},getParentNode:t6,getFirstChild:e6,getNextSibling:p1}),{render:Y8,effect:d2,memo:s,createComponent:R,createElement:i1,insert:s2,spread:z8,mergeProps:a2,use:r2}=q8,o2={linear:E.Easing.Linear,in:E.Easing.EaseIn,out:E.Easing.EaseOut,"in-out":E.Easing.EaseInOut,"out-back":E.Easing.OutBack,spring:E.Easing.Spring,"spring-bouncy":E.Easing.SpringBouncy},j8=null;function d1(J){j8=J}function G8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function s1(J,Q){let $=i1(J);return z8($,Q,!1),G8(Q.nodeRef,$),$}function _(J){return s1("view",J)}function y(J){return s1("text",J)}var n2=new WeakMap,t2=new WeakMap,F8={}!==null?Object.freeze({...{}}):Object.freeze({}),e2=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:F8}),JQ=new Map,JJ=36000,h0=30,B8=30,q={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(JJ),tapeAnalog:new Uint16Array(JJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-h0,saidHello:!1,hostCalls:0};function H8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};q.ops=J,q.frame=0,q.tapeStart=0,q.tapeLen=0,q.tapeFirstFrame=0,q.tapeTouch=null,q.replayMasks=null,q.replayAnalog=null,q.replayTouch=null,q.paused=!1,q.stepQueued=0,q.inspectReportId=null,q.inspectAskedAt=0,q.treeDirty=!0,q.treeSentAt=-h0,q.saidHello=!1,q.hostCalls=0,q.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)q.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)q.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else q.transport=null;if(q.transport)h1(()=>{q.treeDirty=!0}),D8();else h1(null);globalThis.__pocketDevtools=C8}function K8(J){return(Q,$,Z,X)=>{if(q.hostCalls++,q.transport)M8(),R8();let W=Q,Y=$===void 0?YJ:$&65535,j=Z,U=X;if(q.replayMasks)if(q.replayAt0?$.slice(0,8):null;if(Z&&!q.tapeTouch)q.tapeTouch=Array(JJ).fill(null);if(q.tapeLen1||Q.length===1&&Q[0][0]!==YJ)J.analog=Q;if(q.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function o1(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,Y]of J)Z.fill(W,X,Math.min(X+Y,$)),X+=Y;return Z}function n1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return o1(J.masks,0,Q)}function t1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return o1(J.analog??[],YJ,Q)}function e1(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&q.hostCalls%Q!==0)return;if(!q.saidHello)q.saidHello=!0,g({t:"hello",app:q.app,host:L8(),frame:q.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` +`))if(X.trim())V8(X)}}function V8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=q.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),q.inspectReportId=Z||null,q.inspectAskedAt=q.hostCalls,!Z)g({t:"inspect",id:0,rect:null});break}case"pause":q.paused=!0,q.stepQueued=0,$?.debugPause?.(!0),f0();break;case"resume":q.paused=!1,$?.debugPause?.(!1),f0();break;case"step":q.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":J4();break;case"eval":{let Z=!0,X;try{X=$0((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}g({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":g({t:"tape",tape:r1()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}g({t:"devStats",frame:q.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())g({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:q.frame});else g({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))q.replayMasks=n1(Z),q.replayAnalog=Z.analog?t1(Z):null,q.replayTouch=Z.touch?e1(Z):null,q.replayAt=0;break}default:break}}function P8(){if(q.treeDirty&&q.frame-q.treeSentAt>=h0)J4();if(q.frame%B8===0)f0()}function R8(){let J=q.inspectReportId;if(J==null)return;let Q=q.ops;if(!Q?.debugRectXY||!Q.debugRectWH){q.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(q.hostCalls-q.inspectAskedAt>60)q.inspectReportId=null,g({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();q.inspectReportId=null,g({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function f0(){g({t:"stats",frame:q.frame,nodes:Z4(t),tapeLen:q.tapeLen,paused:q.paused})}function J4(){q.treeDirty=!1,q.treeSentAt=q.frame,g({t:"tree",frame:q.frame,root:$4(t)})}function w8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function g0(J,Q){if(Array.isArray(J)){for(let $ of J)g0($,Q);return}if(w8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)g0($,Q)}}function Q4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)g0(Z,Q)}function $4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(Q4(J,(X)=>{if(X.domNodeType===8)return;Z.push($4(X))}),Z.length)Q.k=Z;return Q}function Z4(J){let Q=1;return Q4(J,($)=>{Q+=Z4($)}),Q}function D8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{g({t:"log",level:$,args:X.map((W)=>$0(W))}),Z?.apply(Q,X)}}}function $0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?X4(W):JSON.stringify(X4(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((Y)=>$0(Y,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,Y])=>`${W}: ${$0(Y,Q+1)}`).join(", ")}}`}function X4(J){return J.length>200?J.slice(0,199)+"…":J}function L8(){let J=q.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var C8={get frame(){return q.frame},dumpTape:()=>r1(),replay:(J)=>{q.replayMasks=n1(J),q.replayAnalog=J.analog?t1(J):null,q.replayTouch=J.touch?e1(J):null,q.replayAt=0}},W4=new Map,T0=new Map;function q4(J){return J.trim().replace(/\s+/g," ")}function Y4(J){return J.split(" ").sort().join(" ")}var z4=-1;function O8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=q4(Q);W4.set(Z,$);let X=Y4(Z),W=T0.get(X);T0.set(X,W!==void 0&&W!==$?z4:$)}}function k8(J){let Q=q4(J),$=W4.get(Q);if($!==void 0)return $;let Z=T0.get(Y4(Q));return Z===z4?void 0:Z}var N0=9,I8=(1<{let X=($&S8)!==0,W=X?E0:N0,Y=X?_8:I8;return Object.freeze({id:$>>>(X?y8:A8)&255,x:$&Y,y:$>>>W&Y,hit:Q?.[Z]})}))}function x8(){return Z0}function h8(){Z0=v0}var j4=8,QJ=8,f8=3,g8=8,T8=6,N8=0.5,l=1,fJ=2,m0=4,BJ=8,CJ=[],G4=0,X0=0,$J=Array.from({length:j4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(QJ),histY:new Int16Array(QJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function E8(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function v8(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=x1(Q,$,Z.fact);let j=Z.hit;if(j)return E8(j,W)}let Y=X.rect?.();if(!Y)return!1;return Q>=Y.x&&Q=Y.y&&$=0;Y--){let j=CJ[Y];if(j.disposed)continue;if(G4>0&&!j.opts.allowWhenBlocked)continue;if(!v8(j,$,Z,W))continue;j.flags[J.slot]=l,J.owners.push(j)}for(let Y of J.owners)Y.opts.onDown?.(J)}function l8(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%QJ,J.histLenY||Z>Y))X.flags[J.slot]|=fJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&l)||W&(fJ|m0))continue;if(!X.opts.onLongPress)continue;let Y=Math.max(1,Math.round((X.opts.longPressSeconds??N8)*M1()));if(J.frames=0)CJ.splice($,1)},cancel(){if(!Q.disposed)H4(Q)},get panning(){for(let $ of $J)if($.used&&Q.flags[$.slot]&BJ)return!0;return!1}}}function s8(J){let Q=d8(J);return H0(()=>Q.dispose()),Q}function K4(){CJ.length=0,G4=0,X0=0;for(let J of $J)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function a8(){return s8({onDown:(J)=>{let Q=b1(J.x,J.y,J.hit);if(Q)rJ(Q)},onTap:(J)=>{rJ(null);let Q=b1(J.x,J.y,J.hit);if(Q)E6(Q)},onUp:()=>rJ(null),onCancel:()=>rJ(null)})}var r8=1,u0=new Map,W0=[];function o8(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function n8(){r8=1,u0.clear(),W0=[]}function t8(){if(W0.length===0)return;let J=W0;W0=[];for(let{id:Q,result:$}of J){let Z=u0.get(Q);if(!Z)continue;u0.delete(Q),o8()?.({t:"delivery",frame:V1(),id:Q,kind:Z.kind}),Z.onResult($)}}var U4=new Set;function e8(){if(U4.size===0)return;for(let J of U4)J()}var J2={"flex-col w-full h-full bg-slate-50":0,"relative grow px-6 pt-4 flex-col":1,"absolute left-[628] top-[16] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":2,"absolute left-[628] top-[742] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":3,"w-[584] h-[890] flex-col gap-[12]":4,"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":5,"w-[390] flex-col gap-2":6,"text-lg text-slate-900 font-bold":7,"text-base text-slate-500":8,"text-base text-indigo-600 font-bold":9,"absolute left-[24] top-[16] w-[672] h-[890] bg-slate-50":10,"h-[96]":11,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":12,"absolute inset-0 z-50 flex-col items-center justify-center":13,"absolute inset-0 bg-slate-950":14,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":15,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":16,"flex-row flex-wrap":17,grow:18,"text-2xl text-white font-bold":19,"text-2xl text-slate-950 font-bold":20,"text-xl text-slate-900 font-bold":21,"text-base text-slate-600 font-bold":22,"text-lg text-slate-900":23,"text-base text-slate-500 font-bold":24,"px-6":25,"px-6 py-5":26,"gap-4":27,"rounded-xl shadow bg-white border-slate-100":28,"rounded-xl shadow bg-emerald-100 border-emerald-500":29,"bg-white":30,"bg-slate-100":31,"bg-slate-950":32,"px-3 py-2 rounded-lg bg-slate-100":33,"px-3 py-2 rounded-lg bg-indigo-100":34,"text-base text-indigo-700 font-bold":35,"px-3 py-2 rounded-lg bg-emerald-100":36,"text-base text-emerald-700 font-bold":37,"px-3 py-2 rounded-lg bg-amber-100":38,"text-base text-amber-700 font-bold":39,"px-3 py-2 rounded-lg bg-red-100":40,"text-base text-red-500 font-bold":41,"w-[34] h-[34] rounded-lg bg-amber-400":42,"w-[34] h-[34] rounded-lg bg-red-500":43,"w-[34] h-[34] rounded-lg bg-slate-800":44,"w-[34] h-[34] rounded-lg bg-emerald-500":45,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":46,"flex-row items-center gap-4":47,"w-[34] text-2xl text-white font-bold":48,"w-[332] flex-col items-end gap-2":49,"text-base text-slate-300 font-bold":50,"text-base text-slate-400":51,"h-[166] px-6 pt-6 flex-col gap-3":52,"text-base text-orange-600 font-bold":53,"text-lg text-slate-600":54,"h-[44] px-1 flex-row items-center justify-between":55,"w-full h-full items-center justify-center rounded-xl bg-slate-200":56,"w-full h-full items-center justify-center rounded-xl bg-red-100":57,"w-full h-full items-center justify-center rounded-xl bg-slate-100":58,"w-full h-full items-center justify-center rounded-xl bg-orange-600":59,"text-lg text-slate-500 font-bold":60,"text-lg text-red-500 font-bold":61,"text-lg text-white font-bold":62,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":63,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":64,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":65,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":66,"text-2xl text-indigo-700 font-bold":67,"text-2xl text-slate-600 font-bold":68,"pt-7 text-2xl text-slate-900 font-bold":69,"pt-4 text-lg text-slate-500":70,"text-xl text-emerald-600 font-bold":71,"text-xl text-red-500 font-bold":72,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":73,"text-base text-red-300":74,"text-base text-slate-300":75,"text-base text-red-500":76,"w-full h-full px-6 flex-row items-center bg-slate-950":77,"w-full h-full flex-row items-center":78};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var Q2="ui:styles",$2="ui:font.",M4="ui:img.",V4="ui:sprite.";function Z2(){return globalThis.ui}function X2(J){if(J.__textures)return;for(let Q of D0(M4)){let $=_J(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)N1(Q.slice(M4.length),Z)}}function W2(J){if(J.__sprites)return;for(let Q of D0(V4)){let $=_J(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),Y=$[4],j=Z.getUint16(6,!0),U=Z.getUint16(8,!0),V=Z.getUint16(10,!0),w=J.uploadTexture($.subarray(16),X,W,Y);if(w>=0)v1(Q.slice(V4.length),{handle:w,frames:j,cols:U,step:V})}}function P4(J){let Q=i1("view");return LJ(Q,"style",J,void 0),Q}var q0=null,Y0=null;function q2(J,Q){if(!q0||!Y0)return;LJ(q0,"style",{width:J,height:Q,overflow:E.Overflow.Hidden},void 0),LJ(Y0,"style",{width:J,height:Q,posType:E.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=x();$.__viewport={w:J,h:Q}}function Y2(J,Q={}){let $=F6(Q.ops);if(B6($),r6(k8),Q.styles)O8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let I in Z)N1(I,Z[I]);let G=$.ops.__sprites;if(G)for(let I in G)v1(I,G[I])}if($.kind==="injected"||Z===void 0){if(Q.pak)L1(Q.pak);if(y6()){for(let G of D0())if(G===Q2)$.ops.loadStyles?.(_J(G));else if(G.startsWith($2))$.ops.loadFontAtlas?.(_J(G))}}let X=H1($.ops),W=X?.w??G1,Y=X?.h??F1,j=P4({width:W,height:Y,overflow:E.Overflow.Hidden}),U=P4({width:W,height:Y,posType:E.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});e(t,j),e(t,U),d1(U),q0=j,Y0=U,C1(j),_1(t),A6(),K4(),a8(),w6(),n8(),H8($.ops),H6(K8((G,I,b,h)=>{D6(),L6(I),b8(b,h),e8(),t8(),i8(),S6(G),d6(G),u1()}));let V=Y8(J,j),w=K6(q2);return()=>{w(),h8(),K4(),V(),C1(null),_1(null),d1(null),q0=null,Y0=null;for(let G of t.children.splice(0))G.parent=null,$.ops.destroyNode(G.id);u1()}}function z2(J,Q={}){let $=Q.ops??Z2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)L1(Q.pak);return X2($),W2($),Y2(J,{ops:$,styles:Q.styles??J2,pak:Q.pak})}var R4="$b",j2=9007199254740991,G2=":memory:",OJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function F2(J){let Q="";for(let $=0;$>2]+OJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2j2)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function K2(J){if(J!==null&&typeof J==="object")return B2(J[R4]);return J}function U2(J){if(Array.isArray(J))return JSON.stringify(J.map(w4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=w4(Z);return JSON.stringify(Q)}class l0{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,U2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=D4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(K2))}run(...J){let Q=this.execute(D4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function D4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class L4{statements=new Map;txDepth=0;constructor(J=G2){let Q=H2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new l0(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new l0(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let Y=J(...Q);return this.txDepth--,this.exec(X),Y}catch(Y){throw this.txDepth--,this.exec(W),Y}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var C4={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"},z0={neutral:{surface:"px-3 py-2 rounded-lg bg-slate-100",text:"text-base text-slate-600 font-bold"},info:{surface:"px-3 py-2 rounded-lg bg-indigo-100",text:"text-base text-indigo-700 font-bold"},success:{surface:"px-3 py-2 rounded-lg bg-emerald-100",text:"text-base text-emerald-700 font-bold"},warning:{surface:"px-3 py-2 rounded-lg bg-amber-100",text:"text-base text-amber-700 font-bold"},danger:{surface:"px-3 py-2 rounded-lg bg-red-100",text:"text-base text-red-500 font-bold"}};function M2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return R(_,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[R(_,{class:"flex-row items-center gap-4",get children(){return[s(()=>s(()=>!!J.back)()?R(y,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):R(_,{get["class"](){return Q()}})),R(y,{get["class"](){return C4.appTitle},get children(){return J.title}})]}}),R(_,{class:"w-[332] flex-col items-end gap-2",get children(){return[R(y,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),R(y,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function V2(J){return R(_,{class:"h-[166] px-6 pt-6 flex-col gap-3",get children(){return[R(y,{get["class"](){return J.tone==="info"?"text-base text-indigo-700 font-bold":"text-base text-orange-600 font-bold"},get children(){return J.eyebrow}}),R(y,{get["class"](){return C4.pageTitle},get children(){return J.title}}),R(y,{class:"text-lg text-slate-600",get children(){return J.description}})]}})}function P2(J){return R(_,{get["class"](){return J.compact?"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100"},get children(){return[s(()=>s(()=>!!J.icon)()?R(_,{get["class"](){return J.tone==="info"?"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100"},get children(){return R(y,{get["class"](){return J.tone==="info"?"text-2xl text-indigo-700 font-bold":"text-2xl text-slate-600 font-bold"},get children(){return J.icon}})}}):null),R(y,{get["class"](){return J.icon?"pt-7 text-2xl text-slate-900 font-bold":"text-lg text-slate-500 font-bold"},get children(){return J.title}}),s(()=>s(()=>!!J.detail)()?R(y,{class:"pt-4 text-lg text-slate-500",get children(){return J.detail}}):null)]}})}function R2(J){let Q=()=>J.dark?J.tone==="danger"?"text-base text-red-300":"text-base text-slate-300":J.tone==="danger"?"text-base text-red-500":"text-base text-slate-500";return R(_,{get["class"](){return J.dark?"w-full h-full px-6 flex-row items-center bg-slate-950":"w-full h-full flex-row items-center"},get children(){return R(y,{get["class"](){return Q()},get children(){return J.text}})}})}function w2(J){return[R(_,{get["class"](){return J.top},get children(){return R(y,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),R(_,{get["class"](){return J.bottom},get children(){return R(y,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var TJ=5,O4=7,NJ=10,c0=6,ZJ=new L4("exa"),[EJ,j0]=WJ([]),[k4,p0]=WJ(!1),[i0,G0]=WJ(0),[I4,d0]=WJ("SEARCH HISTORY IS LOCAL"),F0=-1,s0=!1;function D2(J){try{return JSON.parse(J)}catch{return null}}function L2(J){let Q=new Date(J*1000).toISOString();return Q.slice(0,10)+" · "+Q.slice(11,16)+" UTC"}function A4(J){return ZJ.query(` SELECT id,query,searched_at,status,result_count,top_title,error FROM searches ORDER BY id DESC LIMIT ? OFFSET ? - `).all(lJ+1,J)}function a1(){if(Q4||!p1())return;Q4=!0;try{let J=c6(cJ().length);U0((Q)=>[...Q,...J.slice(0,lJ)]),e0(J.length>lJ)}finally{Q4=!1}}function p6(J){if(M0===J)return;try{let Q=HJ.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==uJ){U0([]),e0(!1),J4("SEARCH HISTORY IS LOCAL");return}let $=c6(0),Z=$.slice(0,lJ);U0(Z),e0($.length>lJ),J4(Z[0]?.status==="error"?String(Z[0].error||"EXA SEARCH FAILED").slice(0,80):Z.length?"SEARCH HISTORY UPDATED FROM SQLITE":"SEARCH HISTORY IS LOCAL"),M0=J}catch{U0([]),J4("SEARCH HISTORY IS LOCAL")}}function s1(){let J=Number(HJ.query("PRAGMA page_size").get()?.page_size??0),Q=Number(HJ.query("PRAGMA page_count").get()?.page_count??0),$=Number(HJ.query("PRAGMA freelist_count").get()?.freelist_count??0),Z=Number(HJ.query("PRAGMA user_version").get()?.user_version??0),X=Z===uJ?Number(HJ.query("SELECT COUNT(*) AS count FROM searches").get()?.count??0):0,W=Z===uJ?HJ.query(` + `).all(NJ+1,J)}function C2(){if(s0||!k4())return;s0=!0;try{let J=A4(EJ().length);j0((Q)=>[...Q,...J.slice(0,NJ)]),p0(J.length>NJ)}finally{s0=!1}}function S4(J){if(J>0&&i0()+c0+4>EJ().length&&k4())C2();G0(($)=>J<0?Math.max(0,$-4):Math.min(Math.max(0,EJ().length-c0),$+4))}function _4(J){if(F0===J)return;try{let Q=ZJ.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==TJ){j0([]),p0(!1),G0(0),d0("SEARCH HISTORY IS LOCAL");return}let $=A4(0),Z=$.slice(0,NJ);j0(Z),p0($.length>NJ),G0(0),d0(Z[0]?.status==="error"?String(Z[0].error||"EXA SEARCH FAILED").slice(0,80):Z.length?"SEARCH HISTORY UPDATED FROM SQLITE":"SEARCH HISTORY IS LOCAL"),F0=J}catch{j0([]),G0(0),d0("SEARCH HISTORY IS LOCAL")}}function O2(){let J=Number(ZJ.query("PRAGMA page_size").get()?.page_size??0),Q=Number(ZJ.query("PRAGMA page_count").get()?.page_count??0),$=Number(ZJ.query("PRAGMA freelist_count").get()?.freelist_count??0),Z=Number(ZJ.query("PRAGMA user_version").get()?.user_version??0),X=Z===TJ?Number(ZJ.query("SELECT COUNT(*) AS count FROM searches").get()?.count??0):0,W=Z===TJ?ZJ.query(` SELECT id,searched_at,status,result_count,error FROM searches ORDER BY id DESC LIMIT 1 - `).get():null,Y={database:"exa.sqlite",schemaVersion:Z,expectedSchemaVersion:uJ,retentionDays:u6,searches:X,allocatedBytes:J*Q,reusableBytes:J*$,latestSearch:W},j=W,U=j?` Latest #${j.id??"?"}: ${j.status??"unknown"}, ${j.result_count??0} results.`:" No searches yet.";return{text:`Exa storage (schema ${Z}/${uJ}): ${X} searches; ${u6}-day retention; ${Y.allocatedBytes} bytes allocated (${Y.reusableBytes} reusable).${U}`,details:Y}}function r1(){return k(T,{class:"flex-col w-full h-full bg-slate-50",get children(){return[k(N1,{title:"EXA RESEARCH",back:!0,metaTop:"POCKET APP",metaBottom:"SQLITE HISTORY"}),k(m1,{eyebrow:"AGENT RESEARCH MEMORY",title:"Search history",description:"Every research.search call is saved here automatically.",tone:"info"}),k(T,{class:"grow px-6 pt-4 flex-col",get children(){return[k(V4,{get when(){return cJ().length===0},get children(){return k(v1,{icon:"E",title:"No searches yet",detail:`Ask Pi Agent to research a topic. -The search and its results will appear here.`,tone:"info"})}}),k(V4,{get when(){return cJ().length>0},get children(){return k(E1,{get count(){return cJ().length},rowHeight:l1,height:c1,focusRows:!1,onNearEnd:a1,renderRow:(J)=>{let Q=()=>cJ()[J];return k(T,{class:"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[k(T,{class:"w-[474] flex-col gap-2",get children(){return[k(u,{class:"text-lg text-slate-900 font-bold",get children(){return Q().query.slice(0,60)}}),k(u,{class:"text-base text-slate-500",get children(){return(Q().top_title||Q().error||"No result title").slice(0,76)}}),k(u,{class:"text-base text-indigo-600 font-bold",get children(){return d1(Q().searched_at)}})]}}),k(T,{get["class"](){return e(()=>Q().status==="ok")()?F0.success.surface:F0.danger.surface},get children(){return k(u,{get["class"](){return e(()=>Q().status==="ok")()?F0.success.text:F0.danger.text},get children(){return e(()=>Q().status==="ok")()?Q().result_count+" RESULTS":"FAILED"}})}})]}})}})}})]}}),k(T,{class:"h-[96]",get children(){return k(u1,{get text(){return l6()},get tone(){return l6().includes("FAILED")?"danger":"neutral"},dark:!0})}})]}})}p6(0),D1(()=>k(r1,{})),globalThis.PocketPiApp={tick(){return""},dataChanged(J){let Q=i1(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),M0):M0;return p6($),""},invokeTool(J){try{let Q=J==="research.storage_status"?s1():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:Q.text,details:Q.details,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});return""}}})(); + `).get():null,Y={database:"exa.sqlite",schemaVersion:Z,expectedSchemaVersion:TJ,retentionDays:O4,searches:X,allocatedBytes:J*Q,reusableBytes:J*$,latestSearch:W},j=W,U=j?` Latest #${j.id??"?"}: ${j.status??"unknown"}, ${j.result_count??0} results.`:" No searches yet.";return{text:`Exa storage (schema ${Z}/${TJ}): ${X} searches; ${O4}-day retention; ${Y.allocatedBytes} bytes allocated (${Y.reusableBytes} reusable).${U}`,details:Y}}function k2(){return R(_,{class:"flex-col w-full h-full bg-slate-50",get children(){return[R(M2,{title:"EXA RESEARCH",back:!0,metaTop:"POCKET APP",metaBottom:"SQLITE HISTORY"}),R(V2,{eyebrow:"AGENT RESEARCH MEMORY",title:"Search history",description:"Every research.search call is saved here automatically.",tone:"info"}),R(_,{class:"relative grow px-6 pt-4 flex-col",get children(){return[R(w2,{top:"absolute left-[628] top-[16] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",bottom:"absolute left-[628] top-[742] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100"}),R(_,{class:"w-[584] h-[890] flex-col gap-[12]",get children(){return R(r4,{get each(){return EJ().slice(i0(),i0()+c0)},children:(J)=>R(_,{class:"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[R(_,{class:"w-[390] flex-col gap-2",get children(){return[R(y,{class:"text-lg text-slate-900 font-bold",get children(){return J.query.slice(0,48)}}),R(y,{class:"text-base text-slate-500",get children(){return(J.top_title||J.error||"No result title").slice(0,58)}}),R(y,{class:"text-base text-indigo-600 font-bold",get children(){return L2(J.searched_at)}})]}}),R(_,{get["class"](){return s(()=>J.status==="ok")()?z0.success.surface:z0.danger.surface},get children(){return R(y,{get["class"](){return s(()=>J.status==="ok")()?z0.success.text:z0.danger.text},get children(){return s(()=>J.status==="ok")()?J.result_count+" RESULTS":"FAILED"}})}})]}})})}}),R(o4,{get when(){return EJ().length===0},get children(){return R(_,{class:"absolute left-[24] top-[16] w-[672] h-[890] bg-slate-50",get children(){return R(P2,{icon:"E",title:"No searches yet",detail:`Ask Pi Agent to research a topic. +The search and its results will appear here.`,tone:"info"})}})}})]}}),R(_,{class:"h-[96]",get children(){return R(R2,{get text(){return I4()},get tone(){return I4().includes("FAILED")?"danger":"neutral"},dark:!0})}})]}})}_4(0),z2(()=>R(k2,{})),globalThis.PocketPiApp={tick(){return""},dataChanged(J){let Q=D2(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),F0):F0;return _4($),""},invokeTool(J){try{let Q=J==="research.storage_status"?O2():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:Q.text,details:Q.details,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(J>=620&&Q>=294&&Q<=426)S4(-1);else if(J>=620&&Q>=1020&&Q<=1152)S4(1);return""}}})(); diff --git a/apps/exa/dist/app.pak b/apps/exa/dist/app.pak index cd006c212f6762c15803b0de812229b5daf994db..af467c4c0a331e5132bd6f358dd6e091014f74c9 100644 GIT binary patch delta 255 zcmbQxCwQP=aDoKmfr*my8Fw}AY~9J&x|6AOC-c^wEWUP({?pm*Sri!Arfb-<$cacW zfB+*WBarNHVgiyZ&eQ+dvxwCVzIs6fyI%XjR6b*G({ agent: "STARTING", @@ -52,7 +63,7 @@ const [filePath, setFilePath] = createSignal(""); const [fileOffset, setFileOffset] = createSignal(0); const [files, setFiles] = createSignal([]); const [fileError, setFileError] = createSignal(""); -const [viewer, setViewer] = createSignal<{ path: string; text: string; lineOffset: number } | null>(null); +const [viewer, setViewer] = createSignal(null); const [reader, setReader] = createSignal(null); const [readerOffset, setReaderOffset] = createSignal(0); const [input, setInput] = createSignal(""); @@ -77,6 +88,32 @@ function joinPath(parent: string, name: string): string { return parent ? parent + "/" + name : name; } +function filePage(text: string, start: ViewerPageStart): WrappedTextPage { + return wrapTextPage(text, FONT_FILE, READER_TEXT_WIDTH, start.offset, start.sourceLine, FILE_PAGE_LINES); +} + +function openViewer(path: string, text: string) { + const start = { offset: 0, sourceLine: 0 }; + setViewer({ path, text, pageIndex: 0, pageStarts: [start], page: filePage(text, start) }); + setScreen("viewer"); +} + +function moveViewerPage(direction: -1 | 1) { + const current = viewer(); + if (!current) return; + const nextIndex = current.pageIndex + direction; + if (nextIndex < 0 || (direction > 0 && !current.page.hasMore)) return; + let start = current.pageStarts[nextIndex]; + if (!start) { + start = { + offset: current.page.nextOffset, + sourceLine: current.page.nextSourceLine, + }; + current.pageStarts.push(start); + } + setViewer({ ...current, pageIndex: nextIndex, page: filePage(current.text, start) }); +} + function refreshFiles(path = filePath(), force = false) { const cached = fileCache.get(path); if (!force && cached) { @@ -162,18 +199,18 @@ function ChatScreen() {
{(turn) => ( - - + + - YOU + YOU - {wrapPreview(turn.user, FONT_BODY, CHAT_TEXT_WIDTH, 3)} + {wrapPreview(turn.user, FONT_CHAT, CHAT_TEXT_WIDTH, 3)} - + - PI + PI - {wrapPreview(turn.assistant, FONT_BODY, CHAT_TEXT_WIDTH, 3)} + {wrapPreview(turn.assistant, FONT_CHAT, CHAT_TEXT_WIDTH, 3)} )} viewer(); - const lines = () => (current()?.text ?? "").split("\n"); - const offset = () => current()?.lineOffset ?? 0; return (
{current()?.path ?? "NO FILE OPEN"} - {lines().slice(offset(), offset() + 39).join("\n")} + {current()?.page.text ?? ""} - {"LINES " + String(offset() + 1) + "-" + String(Math.min(offset() + 39, lines().length)) + " / " + String(lines().length)} + {current() + ? "PAGE " + String(current()!.pageIndex + 1) + " · SOURCE LINES " + String(current()!.page.startSourceLine + 1) + "-" + String(current()!.page.lastSourceLine + 1) + : "NO FILE OPEN"} reader(); - const lines = () => wrapLines(current()?.text ?? "", FONT_CAPTION, READER_TEXT_WIDTH); return (
{current()?.author ?? "PI"} - {lines().slice(readerOffset(), readerOffset() + READER_PAGE_LINES).join("\n")} + {(current()?.lines ?? []).slice(readerOffset(), readerOffset() + READER_PAGE_LINES).join("\n")} refreshFiles("", true)); setViewer(null); setScreen("files"); } else if (current && x >= 620 && y >= 170 && y <= 340) { - setViewer({ ...current, lineOffset: Math.max(0, current.lineOffset - 18) }); + moveViewerPage(-1); } else if (current && x >= 620 && y >= 920 && y <= 1100) { - setViewer({ ...current, lineOffset: Math.min(Math.max(0, current.text.split("\n").length - 39), current.lineOffset + 18) }); + moveViewerPage(1); } return ""; } @@ -520,7 +556,7 @@ queueMicrotask(() => refreshFiles("", true)); } else if (x >= 620 && y >= 170 && y <= 340) { setReaderOffset(Math.max(0, readerOffset() - 18)); } else if (x >= 620 && y >= 920 && y <= 1100) { - const lineCount = wrapLines(reader()?.text ?? "", FONT_CAPTION, READER_TEXT_WIDTH).length; + const lineCount = reader()?.lines.length ?? 0; setReaderOffset(Math.min(Math.max(0, lineCount - READER_PAGE_LINES), readerOffset() + 18)); } return ""; @@ -532,12 +568,13 @@ queueMicrotask(() => refreshFiles("", true)); if (screen() === "chat") { if (x >= 620 && y >= 140 && y <= 272) setChatScroll(chatScroll() + 2); else if (x >= 620 && y >= 624 && y <= 756) setChatScroll(Math.max(0, chatScroll() - 2)); - else if (x < 610 && y >= 140 && y < 738) { - const row = Math.floor((y - 140) / 320); + else if (x < 610 && y >= 140 && y < 798) { + const row = Math.floor((y - 140) / 340); const turn = visibleTurns()[row]; if (turn) { - const isPi = y >= 140 + row * 320 + 150; - setReader({ author: isPi ? "PI" : "YOU", text: isPi ? turn.assistant : turn.user }); + const isPi = y >= 140 + row * 340 + 160; + const text = isPi ? turn.assistant : turn.user; + setReader({ author: isPi ? "PI" : "YOU", lines: wrapLines(text, FONT_READER, READER_TEXT_WIDTH) }); setReaderOffset(0); setScreen("reader"); } @@ -571,8 +608,7 @@ queueMicrotask(() => refreshFiles("", true)); refreshFiles(path); } else { try { - setViewer({ path: "/workspace/" + path, text: readFileSync(path, "utf8"), lineOffset: 0 }); - setScreen("viewer"); + openViewer("/workspace/" + path, readFileSync(path, "utf8")); } catch (error) { setFileError(error instanceof Error ? error.message : String(error)); } diff --git a/apps/pi-agent/dist/app.js b/apps/pi-agent/dist/app.js index fdb1174..5328bc9 100644 --- a/apps/pi-agent/dist/app.js +++ b/apps/pi-agent/dist/app.js @@ -1,16 +1,16 @@ -(()=>{var SJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return j1(this.context.count)},getNextContextId(){return j1(this.context.count++)}};function j1(J){let Q=String(J),$=Q.length-1;return SJ.context.id+($?String.fromCharCode(96+$):"")+Q}function K1(J){SJ.context=J}function Z6(){return{...SJ.context,id:SJ.getNextContextId(),count:0}}var q6=!1,X6=(J,Q)=>J===Q,_0=Symbol("solid-proxy"),Y6=typeof Proxy==="function",z6=Symbol("solid-track"),BQ=Symbol("solid-dev-component"),oJ={equals:X6},F1=null,W6=L1,m=1,TJ=2,M1={owned:null,cleanups:null,context:null,owner:null},k=null,K=null,xJ=null,kJ=null,b=null,C=null,f=null,nJ=0;function tJ(J,Q){let $=b,Z=k,q=J.length===0,X=Q===void 0?Z:Q,z=q?M1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},G=q?J:()=>J(()=>QJ(()=>$J(z)));k=z,b=null;try{return p(G,!0)}finally{b=$,k=Z}}function g(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return P1($,q)};return[R1.bind($),Z]}function JJ(J,Q,$){let Z=V1(J,Q,!1,m);if(xJ&&K&&K.running)C.push(Z);else eJ(Z)}function bJ(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=V1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,xJ&&K&&K.running)Z.tState=m,C.push(Z);else eJ(Z);return R1.bind(Z)}function G6(J){return p(J,!1)}function QJ(J){if(!kJ&&b===null)return J();let Q=b;b=null;try{if(kJ)return kJ.untrack(J);return J()}finally{b=Q}}function S0(J){if(k===null);else if(k.cleanups===null)k.cleanups=[J];else k.cleanups.push(J);return J}function H6(J){if(K&&K.running)return J(),K.done;let Q=b,$=k;return Promise.resolve().then(()=>{b=Q,k=$;let Z;if(xJ||B6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return p(J,!1),b=k=null,Z?Z.done:void 0})}var[jQ,U1]=g(!1),B6;function R1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===m)eJ(this);else{let Q=C;C=null,p(()=>J0(this),!1),C=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function P1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)p(()=>{for(let q=0;q1e6)throw C=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;$J(J);let Q=nJ;if(D1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{p(()=>{K&&(K.running=!0),b=k=J,D1(J,J.tValue,Q),b=k=null},!1)})}function D1(J,Q,$){let Z,q=k,X=b;b=k=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=m,J.tOwned&&J.tOwned.forEach($J),J.tOwned=void 0;else J.state=m,J.owned&&J.owned.forEach($J),J.owned=null;return J.updatedAt=$+1,b0(z)}finally{b=X,k=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)P1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function V1(J,Q,$,Z=m,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:k,context:k?k.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(k===null);else if(k!==M1)if(K&&K.running&&k.pure)if(!k.tOwned)k.tOwned=[X];else k.tOwned.push(X);else if(!k.owned)k.owned=[X];else k.owned.push(X);if(kJ&&X.fn){let z=X.fn,[G,R]=g(void 0,{equals:!1}),D=kJ.factory(z,R);S0(()=>D.dispose());let V,B=()=>H6(R).then(()=>{if(V)V.dispose(),V=void 0});X.fn=(_)=>{if(G(),K&&K.running){if(!V)V=kJ.factory(z,B);return V.track(_)}return D.track(_)}}return X}function k0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===TJ)return J0(J);if(J.suspense&&QJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===m)eJ(J);else if((Q?J.tState:J.state)===TJ){let q=C;C=null,p(()=>J0(J,$[0]),!1),C=q}}}function p(J,Q){if(C)return J();let $=!1;if(!Q)C=[];if(f)$=!0;else f=[];nJ++;try{let Z=J();return j6($),Z}catch(Z){if(!$)f=null;C=null,b0(Z)}}function j6(J){if(C){if(xJ&&K&&K.running)K6(C);else L1(C);C=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;f.push.apply(f,K.effects),Q=K.resolve;for(let X of f)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,p(()=>{for(let X of q)$J(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,G=X.owned.length;zW6($),!1);if(Q)Q()}function L1(J){for(let Q=0;Q{Z.delete($),p(()=>{K.running=!0,k0($)},!1),K&&(K.running=!1)})}}function J0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)$J(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)I1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)$J(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function I1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return S0(()=>_1(X)),()=>{let R=J()||[],D=R.length,V,B;return R[z6],QJ(()=>{let E,N,a,BJ,IJ,F,j,H,L;if(D===0){if(z!==0)_1(X),X=[],Z=[],q=[],z=0,G&&(G=[]);if($.fallback)Z=[M6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(D);for(B=0;B=F&&H>=F&&Z[j]===R[H];j--,H--)a[H]=q[j],BJ[H]=X[j],G&&(IJ[H]=G[j]);E=new Map,N=Array(H+1);for(B=H;B>=F;B--)L=R[B],V=E.get(L),N[B]=V===void 0?-1:V,E.set(L,B);for(V=F;V<=j;V++)if(L=Z[V],B=E.get(L),B!==void 0&&B!==-1)a[B]=q[V],BJ[B]=X[V],G&&(IJ[B]=G[V]),B=N[B],E.set(L,B);else X[V]();for(B=F;BJ(Q||{}));return K1($),Z}}return QJ(()=>J(Q||{}))}function Q0(){return!0}var D6={get(J,Q,$){if(Q===_0)return $;return J.get(Q)},has(J,Q){if(Q===_0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function g0(J){return!(J=typeof J==="function"?J():J)?{}:J}function V6(){for(let J=0,Q=this.length;J=0;G--){let R=g0(J[G])[z];if(R!==void 0)return R}},has(z){for(let G=J.length-1;G>=0;G--)if(z in g0(J[G]))return!0;return!1},keys(){let z=[];for(let G=0;G=0;z--){let G=J[z];if(!G)continue;let R=Object.getOwnPropertyNames(G);for(let D=R.length-1;D>=0;D--){let V=R[D];if(V==="__proto__"||V==="constructor")continue;let B=Object.getOwnPropertyDescriptor(G,V);if(!Z[V])Z[V]=B.get?{enumerable:!0,configurable:!0,get:V6.bind($[V]=[B.get.bind(G)])}:B.value!==void 0?B:void 0;else{let _=$[V];if(_){if(B.get)_.push(B.get.bind(G));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let G=X[z],R=Z[G];if(R&&R.get)Object.defineProperty(q,G,R);else q[G]=R?R.value:void 0}return q}var L6=(J)=>`Stale read from <${J}>.`;function jJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return bJ(U6(()=>J.each,J.children,Q||void 0))}function ZJ(J){let Q=J.keyed,$=bJ(()=>J.when,void 0,void 0),Z=Q?$:bJ($,void 0,{equals:(q,X)=>!q===!X});return bJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?QJ(()=>X(Q?q:()=>{if(!QJ(Z))throw L6("Show");return $()})):X}return J.fallback},void 0,void 0)}var O6=(J)=>bJ(()=>J());function I6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:G,getFirstChild:R,getNextSibling:D}){function V(F,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(F,j,L,H);JJ((A)=>B(F,j(),A,H),L)}function B(F,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let S=typeof j,I=L!==void 0;if(S==="string"||S==="number"){if(S==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=N(F,H,L,O)}else if(H!==""&&typeof H==="string")Z(R(F),H=j);else N(F,H,L,Q(j)),H=j}else if(j==null||S==="boolean")H=N(F,H,L);else if(S==="function")return JJ(()=>{let O=j();while(typeof O==="function")O=O();H=B(F,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return JJ(()=>H=B(F,O,H,L,!0)),()=>H;if(O.length===0){let fJ=N(F,H,L);if(I)return H=fJ}else if(Array.isArray(H))if(H.length===0)a(F,O,L);else E(F,H,O);else if(H==null||H==="")a(F,O);else E(F,I&&H||[R(F)],O);H=O}else{if(Array.isArray(H)){if(I)return H=N(F,H,L,j);N(F,H,null,j)}else if(H==null||H===""||!R(F))q(F,j);else BJ(F,j,R(F));H=j}return H}function _(F,j,H){let L=!1;for(let A=0,S=j.length;Ar-O){let HQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let fJ=G(O)===F;if(!S&&!I)fJ?BJ(F,A,O):q(F,A,H);else fJ&&X(F,O)}else S=!0}}else q(F,A,H);return[A]}function a(F,j,H){for(let L=0,A=j.length;LH.children=B(F,j.children,H.children));return JJ(()=>j.ref&&j.ref(F)),JJ(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let S=j[A];if(S===H[A])continue;z(F,A,S,H[A]),H[A]=S}}),H}return{render(F,j){let H;return tJ((L)=>{H=L,V(j,F())}),H},insert:V,spread(F,j,H){if(typeof j==="function")JJ((L)=>IJ(F,j(),L,H));else IJ(F,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(F,j,H,L){return z(F,j,H,L),H},mergeProps:S1,effect:JJ,memo:O6,createComponent:P6,use(F,j,H){return QJ(()=>F(j,H))}}}function A6(J){let Q=I6(J);return Q.mergeProps=S1,Q}var k1=480,b1=272,KJ={view:0,text:1,image:2},_6=1,S6=-1,k6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},U={f32:0,color:1,int:2},b6={width:U.f32,height:U.f32,minW:U.f32,minH:U.f32,maxW:U.f32,maxH:U.f32,paddingT:U.f32,paddingR:U.f32,paddingB:U.f32,paddingL:U.f32,marginT:U.f32,marginR:U.f32,marginB:U.f32,marginL:U.f32,gap:U.f32,flexDir:U.int,justify:U.int,align:U.int,grow:U.f32,shrink:U.f32,basis:U.f32,flexWrap:U.int,posType:U.int,insetT:U.f32,insetR:U.f32,insetB:U.f32,insetL:U.f32,display:U.int,overflow:U.int,zIndex:U.int,hitPass:U.int,bgColor:U.color,gradFrom:U.color,gradTo:U.color,gradDir:U.int,radius:U.f32,opacity:U.f32,borderColor:U.color,borderWidth:U.f32,shadow:U.int,bevelOuterLight:U.color,bevelOuterDark:U.color,bevelInnerLight:U.color,bevelInnerDark:U.color,bevelWidth:U.f32,textColor:U.color,fontSlot:U.int,textAlign:U.int,lineHeight:U.f32,tracking:U.f32,translateX:U.f32,translateY:U.f32,scale:U.f32,rotate:U.f32,scaleX:U.f32,scaleY:U.f32,originX:U.f32,originY:U.f32,rotateX:U.f32,rotateY:U.f32,translateZ:U.f32,perspective:U.f32,arcStart:U.f32,arcSweep:U.f32,arcWidth:U.f32},l={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},g6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},w6=1,KQ=2,FQ=1,MQ=2,UQ=131072,RQ=1,PQ=262144,DQ=1,VQ=1,LQ=1,OQ=2,IQ=4,AQ=8,_Q=16,SQ=1,kQ=2;function g1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var bQ=1,C6=1263551300,h6=1,E6=32,N6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},FJ=32896,gQ=0.016666666666666666;function w1(J){return J.__viewport??null}var w0=null;function f6(){return null}function C1(J,Q=f6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function T6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return C1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return C1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function x6(J){w0=J}function gJ(){if(!w0)throw Error("PocketJS: host not installed — call render() first");return w0}function h(){return gJ().ops}function y6(J){globalThis.frame=J}function v6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function m6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return g1($>>>16&255,$>>>8&255,$&255,255);return g1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function l6(J,Q){let $=b6[J];if(typeof Q==="string"){if($===U.color)return m6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===U.color||$===U.int)return Q>>>0;return Q}var $0=60,h1=[1,2,3,4,5,6,10,12,15,20,30,60],C0=$0,qJ=-1,u6=0,yJ=[];function c6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=h1[0];for(let $ of h1)if(Math.abs($-J)Q.at<=qJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;yJ=yJ.filter((Q)=>Q.at>qJ);for(let Q of J)Q.cb()}var h0=0.12,Z0=FJ;function s6(J){Z0=J===void 0?FJ:J&65535}function a6(){Z0=FJ}function f1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function o6(){return f1(Z0&255)}var T1=new Set,n6=0;function t6(){T1.clear(),n6=0,a6()}function e6(J){for(let Q of[...T1])Q(J)}var MJ=null,x1=null;function J8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function y1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){E0();let Q=MJ?MJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return x1.slice(Q.off,Q.off+Q.len)}var mJ=null,w=null,UJ=null,q0=0,RJ=[],f0=[],T0=[];function m1(J){if(mJ=J,w=null,UJ=null,q0=0,RJ.length=0,f0.length=0,T0.length=0,u){if(u.pressTarget=null,u.target=null,u.spriteDirty=!0,u.fresh=!0,u.vw=0,u.tex>=0){let Q=h();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(u.tex),u.tex=-1}}}function $8(J,Q){J.onPress=Q??void 0}function Z8(J,Q){if(J.focusable=Q,d1(),!Q&&w===J)y(null)}function y(J){if(UJ&&UJ!==J)PJ(null);w=J,h().setFocus(J?J.id:0)}function PJ(J){if(UJ===J)return;let Q=h();if(UJ)Q.setActive?.(UJ.id,0);if(UJ=J,J)Q.setActive?.(J.id,1)}function x0(){return RJ.length>0?RJ[RJ.length-1]:mJ}function y0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;y($[q])}function Y8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=f0.length-1;Q>=0;Q--){let $=f0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function z8(J){let Q=Y8();if(!Q)return!1;let $=[];if(y0(Q.node,$),$.length===0){if(w)y(null);return!0}let Z=Q.columns,q=w?$.indexOf(w):-1;if(q<0)return y(l1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)y($[X]);return!0}function W8(){if(!w)return null;let J=x0();if(J&&!i(w,J))return null;for(let Q=T0.length-1;Q>=0;Q--){let $=T0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(w,$.node))return $}return null}function X0(J){let Q=W8();if(Q&&Q.move(J))return;if(z8(J))return;X8(J)}function u1(){c1(w)}function c1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){PJ(J)}function G8(J){y(J),c1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function v0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=v0(Q.children[q]);if(X){y(X);return}}let Z=Q;while(Z){if(Z.focusable){y(Z);return}Z=Z.parent}}y(null)}var u=null,p1=0;function d1(){p1++}var B8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],j8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function K8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=B8[Q]>>$&1,q=j8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function F8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):M8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(K8(),16,16,g6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function M8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&w6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var W0=null;function i1(J){W0=J}function s1(J){let Q=RJ.length>0?RJ[RJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function a1(J,Q,$){return s1(r1(J,Q,$))}function r1(J,Q,$){if($!==void 0)return $===0?null:z0(W0??mJ,$);let Z=h(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(W0??mJ,q(J,Q))}function U8(J,Q,$){let Z=u,q=h();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=w1(q);if(Z.vw=B?B.w:k1,Z.vh=B?B.h:b1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)F8(Z,q);let X=r6()*Z.speed,z=o6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let G=Z.fresh;if(X!==0||z!==0){let B=p6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),E=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||E!==Z.y)Z.x=_,Z.y=E,G=!0}if(G)q.setCursorPos(Z.x,Z.y);let R=(Q|$)&Z.button,D=p1;if(G||R!==0||D!==Z.gen)Z.gen=D,Z.fresh=!1,Z.target=s1(z0(W0??mJ,q.hitTest(Z.x,Z.y)));let V=Z.target;if(V!==w)y(V);if(Q&Z.button&&V)Z.pressTarget=V;if(Z.pressTarget){if(PJ(V===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=V===Z.pressTarget;if(Z.pressTarget=null,PJ(null),B)u1()}}else if($&Z.button)PJ(null);return!0}function R8(J){let Q=J&~q0,$=q0&~J;if(q0=J,u&&U8(J,Q,$))return;if($&d.CIRCLE)PJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)PJ(w),u1()}var m0=null;function o1(J){m0=J}function wJ(){if(d1(),m0)m0()}function P8(J,Q){J.debugName=Q||void 0,wJ()}var XJ={id:_6,type:KJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},n1=Symbol.for("pocketjs.native-node"),l0=1,lJ=3,o=8,D8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function G0(J){return J.domAttrs??={}}function t1(J,Q){let $=J.domNodeType??(uJ(J)?lJ:l0),Z=$===lJ?H0(J.text??""):$===o?O8(J.domData??""):X4(J.domTag??j0(J));for(let q of Object.keys(J.domAttrs??{}))u0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)YJ(Z,t1(q,!0));return Z}function u0(J,Q,$){if(D8.has(Q)){hJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete G0(J)[Q];else G0(J)[Q]=$}function c0(J){if(J[n1]===!0)return J;return Object.defineProperty(J,n1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?lJ:l0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(uJ(J))B0(J,Z);else if(g8(J),Z)YJ(J,H0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return z4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??j0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===lJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??j0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){hJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===XJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return YJ(J,$),$},insertBefore($,Z){return YJ(J,$,Z??null),$},removeChild($){return cJ(J,$),$},replaceChild($,Z){return YJ(J,$,Z),cJ(J,Z),Z},cloneNode($=!1){return t1(J,!!$)},remove(){if(J.parent)cJ(J.parent,J)},setAttribute($,Z){u0(J,$,Z)},removeAttribute($){u0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(XJ);var p0=null;function V8(J){p0=J}var d0={unknownClass:0,unknownTexture:0},e1=new Map;function J4(J,Q){e1.set(J,Q)}var Q4=new Map;function $4(J,Q){Q4.set(J,Q)}var CJ=new Set,L8=new Set;function Z4(J){if(!J)return!1;if(L8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:h().createNode(Q),type:Q,parent:null,children:[],domNodeType:l0,domTag:J})}function H0(J){let Q=h(),$=Q.createNode(KJ.text);return Q.setText($,J),c0({id:$,type:KJ.text,parent:null,children:[],text:J,domNodeType:lJ,domTag:"#text"})}function O8(J=""){let Q=H0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){h().replaceText(J.id,Q),J.text=Q,wJ()}function uJ(J){return J.type===KJ.text}function Y4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function YJ(J,Q,$){let Z=h();if(Y4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function cJ(J,Q){if(!Q)return;H8(Q),h().removeChild(J.id,Q.id),Y4(Q),CJ.add(Q),wJ()}function I8(J){return J.parent??void 0}function A8(J){return J.children[0]}function z4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function _8(J,Q){let $=h();if(wJ(),Q==null||Q===""){$.setStyle(J.id,S6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=p0?p0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);d0.unknownClass++;return}$.setStyle(J.id,Z)}function S8(J,Q){let $=h();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=e1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);d0.unknownTexture++;return}$.setImage(J.id,Z)}function k8(J,Q){let $=h();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=Q4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);d0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function b8(J,Q,$){let Z=h(),q=Q??{},X=$??{},z=!1;for(let G in q){let R=q[G];if(X[G]===R)continue;let D=k6[G];if(D===void 0)throw Error(`PocketJS: unknown style prop '${G}' (see spec PROP)`);Z.setProp(J.id,D,l6(G,R)),z=!0}if(z)wJ()}function hJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete G0(J)[Q];else G0(J)[Q]=$;switch(Q){case"class":return _8(J,$),$;case"onPress":case"on:press":return $8(J,$),$;case"src":return S8(J,$),$;case"sprite":return k8(J,$),$;case"style":return b8(J,$,Z),$;case"focusable":return Z8(J,!!$),$;case"debugName":return P8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${j0(J)}>`)}function g8(J){for(let Q of[...J.children])cJ(J,Q)}function j0(J){for(let Q of Object.keys(KJ))if(KJ[Q]===J.type)return Q;return String(J.type)}function w8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}hJ(J,Q,$,Z)}var C8=A6({createElement:X4,createTextNode:H0,replaceText:B0,isTextNode:uJ,setProperty:w8,insertNode(J,Q,$){YJ(J,Q,$)},removeNode(J,Q){cJ(J,Q)},getParentNode:I8,getFirstChild:A8,getNextSibling:z4}),{render:h8,effect:wQ,memo:c,createComponent:Y,createElement:W4,insert:CQ,spread:E8,mergeProps:hQ,use:EQ}=C8,NQ={linear:l.Easing.Linear,in:l.Easing.EaseIn,out:l.Easing.EaseOut,"in-out":l.Easing.EaseInOut,"out-back":l.Easing.OutBack,spring:l.Easing.Spring,"spring-bouncy":l.Easing.SpringBouncy},N8=null;function G4(J){N8=J}function f8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function H4(J,Q){let $=W4(J);return E8($,Q,!1),f8(Q.nodeRef,$),$}function M(J){return H4("view",J)}function P(J){return H4("text",J)}var fQ=new WeakMap,TQ=new WeakMap,T8={}!==null?Object.freeze({...{}}):Object.freeze({}),xQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:T8}),yQ=new Map,zJ=36000,i0=30,x8=30,W={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(zJ),tapeAnalog:new Uint16Array(zJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-i0,saidHello:!1,hostCalls:0};function y8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};W.ops=J,W.frame=0,W.tapeStart=0,W.tapeLen=0,W.tapeFirstFrame=0,W.tapeTouch=null,W.replayMasks=null,W.replayAnalog=null,W.replayTouch=null,W.paused=!1,W.stepQueued=0,W.inspectReportId=null,W.inspectAskedAt=0,W.treeDirty=!0,W.treeSentAt=-i0,W.saidHello=!1,W.hostCalls=0,W.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)W.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)W.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else W.transport=null;if(W.transport)o1(()=>{W.treeDirty=!0}),i8();else o1(null);globalThis.__pocketDevtools=a8}function v8(J){return(Q,$,Z,q)=>{if(W.hostCalls++,W.transport)l8(),p8();let X=Q,z=$===void 0?FJ:$&65535,G=Z,R=q;if(W.replayMasks)if(W.replayAt0?$.slice(0,8):null;if(Z&&!W.tapeTouch)W.tapeTouch=Array(zJ).fill(null);if(W.tapeLen1||Q.length===1&&Q[0][0]!==FJ)J.analog=Q;if(W.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function K4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function F4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return K4(J.masks,0,Q)}function M4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return K4(J.analog??[],FJ,Q)}function U4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&W.hostCalls%Q!==0)return;if(!W.saidHello)W.saidHello=!0,T({t:"hello",app:W.app,host:s8(),frame:W.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` -`))if(q.trim())u8(q)}}function u8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=W.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),W.inspectReportId=Z||null,W.inspectAskedAt=W.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":W.paused=!0,W.stepQueued=0,$?.debugPause?.(!0),s0();break;case"resume":W.paused=!1,$?.debugPause?.(!1),s0();break;case"step":W.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":R4();break;case"eval":{let Z=!0,q;try{q=K0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}T({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":T({t:"tape",tape:j4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}T({t:"devStats",frame:W.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:W.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))W.replayMasks=F4(Z),W.replayAnalog=Z.analog?M4(Z):null,W.replayTouch=Z.touch?U4(Z):null,W.replayAt=0;break}default:break}}function c8(){if(W.treeDirty&&W.frame-W.treeSentAt>=i0)R4();if(W.frame%x8===0)s0()}function p8(){let J=W.inspectReportId;if(J==null)return;let Q=W.ops;if(!Q?.debugRectXY||!Q.debugRectWH){W.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(W.hostCalls-W.inspectAskedAt>60)W.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();W.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function s0(){T({t:"stats",frame:W.frame,nodes:V4(XJ),tapeLen:W.tapeLen,paused:W.paused})}function R4(){W.treeDirty=!1,W.treeSentAt=W.frame,T({t:"tree",frame:W.frame,root:D4(XJ)})}function d8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function a0(J,Q){if(Array.isArray(J)){for(let $ of J)a0($,Q);return}if(d8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)a0($,Q)}}function P4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)a0(Z,Q)}function D4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(P4(J,(q)=>{if(q.domNodeType===8)return;Z.push(D4(q))}),Z.length)Q.k=Z;return Q}function V4(J){let Q=1;return P4(J,($)=>{Q+=V4($)}),Q}function i8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{T({t:"log",level:$,args:q.map((X)=>K0(X))}),Z?.apply(Q,q)}}}function K0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?L4(X):JSON.stringify(L4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>K0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${K0(z,Q+1)}`).join(", ")}}`}function L4(J){return J.length>200?J.slice(0,199)+"…":J}function s8(){let J=W.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var a8={get frame(){return W.frame},dumpTape:()=>j4(),replay:(J)=>{W.replayMasks=F4(J),W.replayAnalog=J.analog?M4(J):null,W.replayTouch=J.touch?U4(J):null,W.replayAt=0}},O4=new Map,r0=new Map;function I4(J){return J.trim().replace(/\s+/g," ")}function A4(J){return J.split(" ").sort().join(" ")}var _4=-1;function r8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=I4(Q);O4.set(Z,$);let q=A4(Z),X=r0.get(q);r0.set(q,X!==void 0&&X!==$?_4:$)}}function o8(J){let Q=I4(J),$=O4.get(Q);if($!==void 0)return $;let Z=r0.get(A4(Q));return Z===_4?void 0:Z}var o0=9,n8=(1<{let q=($&e8)!==0,X=q?n0:o0,z=q?J2:n8;return Object.freeze({id:$>>>(q?Q2:t8)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function Z2(){return F0}function q2(){F0=t0}var S4=8,WJ=8,X2=3,Y2=8,z2=6,W2=0.5,s=1,pJ=2,e0=4,DJ=8,EJ=[],k4=0,M0=0,GJ=Array.from({length:S4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(WJ),histY:new Int16Array(WJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function G2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function H2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=r1(Q,$,Z.fact);let G=Z.hit;if(G)return G2(G,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let G=EJ[z];if(G.disposed)continue;if(k4>0&&!G.opts.allowWhenBlocked)continue;if(!H2(G,$,Z,X))continue;G.flags[J.slot]=s,J.owners.push(G)}for(let z of J.owners)z.opts.onDown?.(J)}function K2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%WJ,J.histLenz||Z>z))q.flags[J.slot]|=pJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(pJ|e0))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??W2)*E1()));if(J.frames=0)EJ.splice($,1)},cancel(){if(!Q.disposed)w4(Q)},get panning(){for(let $ of GJ)if($.used&&Q.flags[$.slot]&DJ)return!0;return!1}}}function P2(J){let Q=R2(J);return S0(()=>Q.dispose()),Q}function C4(){EJ.length=0,k4=0,M0=0;for(let J of GJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function D2(){return P2({onDown:(J)=>{let Q=a1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=a1(J.x,J.y,J.hit);if(Q)G8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var V2=1,J1=new Map,U0=[];function L2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function O2(){V2=1,J1.clear(),U0=[]}function I2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=J1.get(Q);if(!Z)continue;J1.delete(Q),L2()?.({t:"delivery",frame:N1(),id:Q,kind:Z.kind}),Z.onResult($)}}var h4=new Set;function A2(){if(h4.size===0)return;for(let J of h4)J()}var _2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[28] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-base text-orange-600 font-bold":9,"h-[76] pt-3 text-lg text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-base text-emerald-700 font-bold":13,"h-[84] pt-3 text-lg text-slate-900":14,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":15,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":16,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":17,"text-base text-slate-600 font-bold":18,"pt-6 text-lg text-slate-500":19,"pt-6 text-lg text-slate-900 font-bold":20,"h-[146] px-6 pt-7 flex-col bg-slate-50":21,"h-[80]":22,"h-[1060] px-6 pt-5 flex-col":23,"h-[48] px-4 justify-center bg-slate-100":24,"text-base text-slate-600":25,"pt-[10] flex-col gap-[12]":26,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":27,"w-[48] h-[48] items-center justify-center bg-blue-100":28,"w-[48] h-[48] items-center justify-center bg-emerald-100":29,"text-lg text-blue-700 font-bold":30,"text-lg text-emerald-700 font-bold":31,"w-[474] flex-col gap-2":32,"text-lg text-slate-900 font-bold":33,"text-base text-slate-500":34,"pt-20 pl-10 text-lg text-slate-500":35,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":36,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":37,"h-[1060] px-6 pt-7 flex-col gap-4":38,"text-base text-slate-500 font-bold":39,"h-[214] px-7 items-center justify-center bg-slate-100":40,"text-lg text-slate-500 font-bold":41,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":42,"flex-row items-center gap-5":43,"w-[68] h-[68] items-center justify-center bg-orange-100":44,"text-xl text-orange-700 font-bold":45,"w-[500] flex-col gap-2":46,"text-xl text-slate-900 font-bold":47,"text-lg text-slate-600":48,"text-2xl text-orange-600":49,"mt-4 h-[112] px-6 justify-center bg-slate-100":50,"relative h-[154] px-5 pt-5 flex-col bg-white":51,"pt-3 text-lg text-orange-600 font-bold":52,"pt-3 text-base text-slate-500":53,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":54,"text-lg text-white font-bold":55,"h-[40] pt-3 text-base text-slate-500":56,"h-[470] flex-col gap-2":57,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":58,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":59,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":60,"h-[160] px-5 pt-5 flex-col bg-white":61,"pt-3 text-lg text-slate-900 font-bold":62,"pt-3 text-base text-slate-600":63,"h-[108] pt-7 flex-row gap-4":64,"w-[316] h-[80] items-center justify-center bg-slate-100":65,"w-[340] h-[80] items-center justify-center bg-red-100":66,"text-lg text-red-500 font-bold":67,"h-[1052] px-6 pt-5 flex-col":68,"h-[270] px-[22] pt-6 bg-white":69,"text-lg text-slate-900":70,"text-lg text-slate-400":71,"h-[86] px-1 flex-row items-center justify-between":72,"w-[132] h-[58] items-center justify-center bg-slate-300":73,"w-[132] h-[58] items-center justify-center bg-slate-100":74,"text-base text-slate-900 font-bold":75,"h-[140] flex-row gap-2":76,"grow h-[120] items-center justify-center bg-slate-300":77,"grow h-[120] items-center justify-center bg-white":78,"w-[104] h-[120] items-center justify-center bg-slate-300":79,"w-[104] h-[120] items-center justify-center bg-slate-100":80,"h-[176] flex-row gap-2":81,"w-[92] h-[156] items-center justify-center bg-slate-300":82,"w-[92] h-[156] items-center justify-center bg-slate-100":83,"w-[300] h-[156] items-center justify-center bg-slate-300":84,"w-[300] h-[156] items-center justify-center bg-slate-100":85,"w-[144] h-[156] items-center justify-center bg-slate-300":86,"w-[144] h-[156] items-center justify-center bg-slate-100":87,"w-[112] h-[156] items-center justify-center bg-emerald-700":88,"w-[112] h-[156] items-center justify-center bg-emerald-500":89,"text-base text-slate-950 font-bold":90,"h-[108] px-6 py-3 flex-col bg-slate-50":91,"h-[84] items-center justify-center bg-slate-300":92,"h-[84] items-center justify-center bg-slate-100":93,"h-[1168] px-6 pt-5 flex-col":94,"h-[82] px-4 justify-center bg-white":95,"w-[584] h-[900] px-5 pt-5 bg-slate-950":96,"text-base text-slate-200":97,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":98,"text-lg text-orange-600 font-bold":99,"w-[584] h-[900] px-5 pt-5 bg-white":100,"text-base text-slate-900":101,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":102,"absolute inset-0 z-50 flex-col items-center justify-center":103,"absolute inset-0 bg-slate-950":104,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":105,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":106,"flex-row flex-wrap":107,grow:108,"text-2xl text-white font-bold":109,"text-2xl text-slate-950 font-bold":110,"px-6":111,"px-6 py-5":112,"gap-4":113,"rounded-xl shadow bg-white border-slate-100":114,"rounded-xl shadow bg-emerald-100 border-emerald-500":115,"bg-white":116,"bg-slate-100":117,"bg-slate-950":118,"px-3 py-2 rounded-lg bg-slate-100":119,"px-3 py-2 rounded-lg bg-indigo-100":120,"text-base text-indigo-700 font-bold":121,"px-3 py-2 rounded-lg bg-emerald-100":122,"px-3 py-2 rounded-lg bg-amber-100":123,"text-base text-amber-700 font-bold":124,"px-3 py-2 rounded-lg bg-red-100":125,"text-base text-red-500 font-bold":126,"w-[34] h-[34] rounded-lg bg-amber-400":127,"w-[34] h-[34] rounded-lg bg-red-500":128,"w-[34] h-[34] rounded-lg bg-slate-800":129,"w-[34] h-[34] rounded-lg bg-emerald-500":130,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":131,"flex-row items-center gap-4":132,"w-[34] text-2xl text-white font-bold":133,"w-[332] flex-col items-end gap-2":134,"text-base text-slate-300 font-bold":135,"text-base text-slate-400":136,"h-[166] px-6 pt-6 flex-col gap-3":137,"h-[44] px-1 flex-row items-center justify-between":138,"w-full h-full items-center justify-center rounded-xl bg-slate-200":139,"w-full h-full items-center justify-center rounded-xl bg-red-100":140,"w-full h-full items-center justify-center rounded-xl bg-slate-100":141,"w-full h-full items-center justify-center rounded-xl bg-orange-600":142,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":143,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":144,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":145,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":146,"text-2xl text-indigo-700 font-bold":147,"text-2xl text-slate-600 font-bold":148,"pt-7 text-2xl text-slate-900 font-bold":149,"pt-4 text-lg text-slate-500":150,"text-xl text-emerald-600 font-bold":151,"text-xl text-red-500 font-bold":152,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":153,"text-base text-red-300":154,"text-base text-slate-300":155,"text-base text-red-500":156,"w-full h-full px-6 flex-row items-center bg-slate-950":157,"w-full h-full flex-row items-center":158};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var S2="ui:styles",k2="ui:font.",E4="ui:img.",N4="ui:sprite.";function b2(){return globalThis.ui}function g2(J){if(J.__textures)return;for(let Q of N0(E4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)J4(Q.slice(E4.length),Z)}}function w2(J){if(J.__sprites)return;for(let Q of N0(N4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],G=Z.getUint16(6,!0),R=Z.getUint16(8,!0),D=Z.getUint16(10,!0),V=J.uploadTexture($.subarray(16),q,X,z);if(V>=0)$4(Q.slice(N4.length),{handle:V,frames:G,cols:R,step:D})}}function f4(J){let Q=W4("view");return hJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function C2(J,Q){if(!R0||!P0)return;hJ(R0,"style",{width:J,height:Q,overflow:l.Overflow.Hidden},void 0),hJ(P0,"style",{width:J,height:Q,posType:l.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=h();$.__viewport={w:J,h:Q}}function h2(J,Q={}){let $=T6(Q.ops);if(x6($),V8(o8),Q.styles)r8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)J4(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)$4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)v1(Q.pak);if(Q8()){for(let B of N0())if(B===S2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(k2))$.ops.loadFontAtlas?.(vJ(B))}}let q=w1($.ops),X=q?.w??k1,z=q?.h??b1,G=f4({width:X,height:z,overflow:l.Overflow.Hidden}),R=f4({width:X,height:z,posType:l.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});YJ(XJ,G),YJ(XJ,R),G4(R),R0=G,P0=R,m1(G),i1(XJ),t6(),C4(),D2(),d6(),O2(),y8($.ops),y6(v8((B,_,E,N)=>{i6(),s6(_),$2(E,N),A2(),I2(),U2(),e6(B),R8(B),q4()}));let D=h8(J,G),V=v6(C2);return()=>{V(),q2(),C4(),D(),m1(null),i1(null),G4(null),R0=null,P0=null;for(let B of XJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);q4()}}function E2(J,Q={}){let $=Q.ops??b2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)v1(Q.pak);return g2($),w2($),h2(J,{ops:$,styles:Q.styles??_2,pak:Q.pak})}var N2="$b",f2=65536,T4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function y2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function x4(){let J=y2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function v2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,f2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let G=T2(z.data[N2]);if($.push(G),Z+=G.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function m2(J,Q){let $=v2(x4(),J);return Q==="utf8"||Q==="utf-8"?x2($):$}function l2(J,Q){let $=x4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var u2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"};function c2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(M,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(M,{class:"flex-row items-center gap-4",get children(){return[c(()=>c(()=>!!J.back)()?Y(P,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(M,{get["class"](){return Q()}})),Y(P,{get["class"](){return u2.appTitle},get children(){return J.title}})]}}),Y(M,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(P,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(P,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function p2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(M,{get["class"](){return Q()},get children(){return Y(P,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(M,{get["class"](){return J.top},get children(){return Y(P,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(M,{get["class"](){return J.bottom},get children(){return Y(P,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var vQ="‘’“”–—…•",d2=512;function i2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let G=Q(z);if(q&&X+G>$)Z.push(q),q="",X=0;q+=z,X+=G}if(q)Z.push(q);return Z}function Q1(J,Q,$){let Z=new Map,q=(G)=>{let R=Z.get(G);if(R===void 0)R=h().measureText(G,Q),Z.set(G,R);return R},X=[],z=q(" ");for(let G of J.split(` -`)){let R=G.split(" ").flatMap((B)=>B&&q(B)>$?i2(B,q,$):[B]),D="",V=0;for(let B of R){let _=q(B);if(!D)D=B,V=_;else if(V+z+_<=$)D+=" "+B,V+=z+_;else X.push(D),D=B,V=_}X.push(D)}return X}function $1(J,Q,$,Z){let q=J.slice(0,d2),X=Q1(q,Q,$);if(q.length===J.length&&X.length<=Z)return X.join(` -`);let z=X.slice(0,Z),G=z.length-1;return z[G]=z[G].replace(/[\s.]+$/,"")+"…",z.join(` -`)}var Z1=3,y4=2,q1=536,v4=544,m4=39,[n,s2]=g({agent:"STARTING",model:"CODEX / UART / MAC",messages:[{role:"assistant",text:"BOOTING PI AGENT..."}]}),[x,t]=g("chat"),[X1,a2]=g("chat"),[Y1,l4]=g(0),[VJ,u4]=g(""),[sJ,NJ]=g(0),[aJ,z1]=g([]),[r2,D0]=g(""),[c4,V0]=g(null),[p4,d4]=g(null),[L0,O0]=g(0),[v,e]=g(""),[LJ,i4]=g("letters"),[W1,G1]=g(!1),[H1,s4]=g({type:"prompt"}),[HJ,a4]=g(null),[rJ,r4]=g(0),o4=new Map,n4=["qwertyuiop","asdfghjkl","zxcvbnm"],t4=["1234567890","-/:;()$&@",`.,?!'"+`],e4=["chat","files","apps","settings"];function o2(J){if(J<1024)return J+" B";if(J<1048576)return(J/1024).toFixed(1)+" KB";return(J/1048576).toFixed(1)+" MB"}function n2(J,Q){return J?J+"/"+Q:Q}function I0(J=VJ(),Q=!1){let $=o4.get(J);if(!Q&&$){z1($),D0(""),NJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=l2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));o4.set(J,Z),z1(Z),D0(""),NJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){z1([]),D0(Z instanceof Error?Z.message:String(Z))}}function t2(){let J=[];for(let Q of n().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function J6(){let J=t2(),Q=Math.max(0,J.length-2),$=Math.min(Y1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function OJ(J){return Y(c2,{get title(){return J.title},get accent(){return c(()=>n().agent==="FAULTED")()?"danger":n().agent==="THINKING"?"busy":"ready"}})}function A0(){return Y(M,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(jJ,{each:e4,children:(J)=>Y(M,{get["class"](){return X1()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(P,{class:"text-base text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function e2(){let J=()=>n().schedule,Q=()=>{let $=J();return $1(String($?.name)+" "+String($?.next??"")+` +(()=>{var kJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return H1(this.context.count)},getNextContextId(){return H1(this.context.count++)}};function H1(J){let Q=String(J),$=Q.length-1;return kJ.context.id+($?String.fromCharCode(96+$):"")+Q}function j1(J){kJ.context=J}function q6(){return{...kJ.context,id:kJ.getNextContextId(),count:0}}var X6=!1,Y6=(J,Q)=>J===Q,A0=Symbol("solid-proxy"),z6=typeof Proxy==="function",G6=Symbol("solid-track"),DQ=Symbol("solid-dev-component"),oJ={equals:Y6},K1=null,W6=V1,l=1,yJ=2,F1={owned:null,cleanups:null,context:null,owner:null},S=null,K=null,fJ=null,SJ=null,b=null,E=null,T=null,nJ=0;function tJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?F1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},W=q?J:()=>J(()=>QJ(()=>$J(z)));S=z,b=null;try{return c(W,!0)}finally{b=$,S=Z}}function C(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return R1($,q)};return[U1.bind($),Z]}function JJ(J,Q,$){let Z=D1(J,Q,!1,l);if(fJ&&K&&K.running)E.push(Z);else eJ(Z)}function bJ(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=D1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,fJ&&K&&K.running)Z.tState=l,E.push(Z);else eJ(Z);return U1.bind(Z)}function B6(J){return c(J,!1)}function QJ(J){if(!SJ&&b===null)return J();let Q=b;b=null;try{if(SJ)return SJ.untrack(J);return J()}finally{b=Q}}function _0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function H6(J){if(K&&K.running)return J(),K.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(fJ||j6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[VQ,M1]=C(!1),j6;function U1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===l)eJ(this);else{let Q=E;E=null,c(()=>J0(this),!1),E=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function R1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw E=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;$J(J);let Q=nJ;if(P1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{c(()=>{K&&(K.running=!0),b=S=J,P1(J,J.tValue,Q),b=S=null},!1)})}function P1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=l,J.tOwned&&J.tOwned.forEach($J),J.tOwned=void 0;else J.state=l,J.owned&&J.owned.forEach($J),J.owned=null;return J.updatedAt=$+1,S0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)R1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function D1(J,Q,$,Z=l,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(S===null);else if(S!==F1)if(K&&K.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(SJ&&X.fn){let z=X.fn,[W,U]=C(void 0,{equals:!1}),P=SJ.factory(z,U);_0(()=>P.dispose());let D,B=()=>H6(U).then(()=>{if(D)D.dispose(),D=void 0});X.fn=(_)=>{if(W(),K&&K.running){if(!D)D=SJ.factory(z,B);return D.track(_)}return P.track(_)}}return X}function k0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===yJ)return J0(J);if(J.suspense&&QJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===l)eJ(J);else if((Q?J.tState:J.state)===yJ){let q=E;E=null,c(()=>J0(J,$[0]),!1),E=q}}}function c(J,Q){if(E)return J();let $=!1;if(!Q)E=[];if(T)$=!0;else T=[];nJ++;try{let Z=J();return K6($),Z}catch(Z){if(!$)T=null;E=null,S0(Z)}}function K6(J){if(E){if(fJ&&K&&K.running)F6(E);else V1(E);E=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;T.push.apply(T,K.effects),Q=K.resolve;for(let X of T)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,c(()=>{for(let X of q)$J(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,W=X.owned.length;zW6($),!1);if(Q)Q()}function V1(J){for(let Q=0;Q{Z.delete($),c(()=>{K.running=!0,k0($)},!1),K&&(K.running=!1)})}}function J0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)$J(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)O1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)$J(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function O1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return _0(()=>A1(X)),()=>{let U=J()||[],P=U.length,D,B;return U[G6],QJ(()=>{let g,w,a,HJ,IJ,F,j,H,L;if(P===0){if(z!==0)A1(X),X=[],Z=[],q=[],z=0,W&&(W=[]);if($.fallback)Z=[U6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(P);for(B=0;B=F&&H>=F&&Z[j]===U[H];j--,H--)a[H]=q[j],HJ[H]=X[j],W&&(IJ[H]=W[j]);g=new Map,w=Array(H+1);for(B=H;B>=F;B--)L=U[B],D=g.get(L),w[B]=D===void 0?-1:D,g.set(L,B);for(D=F;D<=j;D++)if(L=Z[D],B=g.get(L),B!==void 0&&B!==-1)a[B]=q[D],HJ[B]=X[D],W&&(IJ[B]=W[D]),B=w[B],g.set(L,B);else X[D]();for(B=F;BJ(Q||{}));return j1($),Z}}return QJ(()=>J(Q||{}))}function Q0(){return!0}var V6={get(J,Q,$){if(Q===A0)return $;return J.get(Q)},has(J,Q){if(Q===A0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function b0(J){return!(J=typeof J==="function"?J():J)?{}:J}function L6(){for(let J=0,Q=this.length;J=0;W--){let U=b0(J[W])[z];if(U!==void 0)return U}},has(z){for(let W=J.length-1;W>=0;W--)if(z in b0(J[W]))return!0;return!1},keys(){let z=[];for(let W=0;W=0;z--){let W=J[z];if(!W)continue;let U=Object.getOwnPropertyNames(W);for(let P=U.length-1;P>=0;P--){let D=U[P];if(D==="__proto__"||D==="constructor")continue;let B=Object.getOwnPropertyDescriptor(W,D);if(!Z[D])Z[D]=B.get?{enumerable:!0,configurable:!0,get:L6.bind($[D]=[B.get.bind(W)])}:B.value!==void 0?B:void 0;else{let _=$[D];if(_){if(B.get)_.push(B.get.bind(W));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let W=X[z],U=Z[W];if(U&&U.get)Object.defineProperty(q,W,U);else q[W]=U?U.value:void 0}return q}var O6=(J)=>`Stale read from <${J}>.`;function jJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return bJ(R6(()=>J.each,J.children,Q||void 0))}function ZJ(J){let Q=J.keyed,$=bJ(()=>J.when,void 0,void 0),Z=Q?$:bJ($,void 0,{equals:(q,X)=>!q===!X});return bJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?QJ(()=>X(Q?q:()=>{if(!QJ(Z))throw O6("Show");return $()})):X}return J.fallback},void 0,void 0)}var I6=(J)=>bJ(()=>J());function A6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:W,getFirstChild:U,getNextSibling:P}){function D(F,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(F,j,L,H);JJ((A)=>B(F,j(),A,H),L)}function B(F,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=w(F,H,L,O)}else if(H!==""&&typeof H==="string")Z(U(F),H=j);else w(F,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=w(F,H,L);else if(k==="function")return JJ(()=>{let O=j();while(typeof O==="function")O=O();H=B(F,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return JJ(()=>H=B(F,O,H,L,!0)),()=>H;if(O.length===0){let TJ=w(F,H,L);if(I)return H=TJ}else if(Array.isArray(H))if(H.length===0)a(F,O,L);else g(F,H,O);else if(H==null||H==="")a(F,O);else g(F,I&&H||[U(F)],O);H=O}else{if(Array.isArray(H)){if(I)return H=w(F,H,L,j);w(F,H,null,j)}else if(H==null||H===""||!U(F))q(F,j);else HJ(F,j,U(F));H=j}return H}function _(F,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let PQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let TJ=W(O)===F;if(!k&&!I)TJ?HJ(F,A,O):q(F,A,H);else TJ&&X(F,O)}else k=!0}}else q(F,A,H);return[A]}function a(F,j,H){for(let L=0,A=j.length;LH.children=B(F,j.children,H.children));return JJ(()=>j.ref&&j.ref(F)),JJ(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(F,A,k,H[A]),H[A]=k}}),H}return{render(F,j){let H;return tJ((L)=>{H=L,D(j,F())}),H},insert:D,spread(F,j,H){if(typeof j==="function")JJ((L)=>IJ(F,j(),L,H));else IJ(F,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(F,j,H,L){return z(F,j,H,L),H},mergeProps:_1,effect:JJ,memo:I6,createComponent:D6,use(F,j,H){return QJ(()=>F(j,H))}}}function _6(J){let Q=A6(J);return Q.mergeProps=_1,Q}var k1=480,S1=272,KJ={view:0,text:1,image:2},k6=1,S6=-1,b6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},R={f32:0,color:1,int:2},g6={width:R.f32,height:R.f32,minW:R.f32,minH:R.f32,maxW:R.f32,maxH:R.f32,paddingT:R.f32,paddingR:R.f32,paddingB:R.f32,paddingL:R.f32,marginT:R.f32,marginR:R.f32,marginB:R.f32,marginL:R.f32,gap:R.f32,flexDir:R.int,justify:R.int,align:R.int,grow:R.f32,shrink:R.f32,basis:R.f32,flexWrap:R.int,posType:R.int,insetT:R.f32,insetR:R.f32,insetB:R.f32,insetL:R.f32,display:R.int,overflow:R.int,zIndex:R.int,hitPass:R.int,bgColor:R.color,gradFrom:R.color,gradTo:R.color,gradDir:R.int,radius:R.f32,opacity:R.f32,borderColor:R.color,borderWidth:R.f32,shadow:R.int,bevelOuterLight:R.color,bevelOuterDark:R.color,bevelInnerLight:R.color,bevelInnerDark:R.color,bevelWidth:R.f32,textColor:R.color,fontSlot:R.int,textAlign:R.int,lineHeight:R.f32,tracking:R.f32,translateX:R.f32,translateY:R.f32,scale:R.f32,rotate:R.f32,scaleX:R.f32,scaleY:R.f32,originX:R.f32,originY:R.f32,rotateX:R.f32,rotateY:R.f32,translateZ:R.f32,perspective:R.f32,arcStart:R.f32,arcSweep:R.f32,arcWidth:R.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},w6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},C6=1,LQ=2,OQ=1,IQ=2,AQ=131072,_Q=1,kQ=262144,SQ=1,bQ=1,gQ=1,wQ=2,CQ=4,NQ=8,EQ=16,hQ=1,TQ=2;function b1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var yQ=1,N6=1263551300,E6=1,h6=32,T6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},FJ=32896,fQ=0.016666666666666666;function g1(J){return J.__viewport??null}var g0=null;function y6(){return null}function w1(J,Q=y6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function f6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return w1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return w1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function x6(J){g0=J}function gJ(){if(!g0)throw Error("PocketJS: host not installed — call render() first");return g0}function h(){return gJ().ops}function v6(J){globalThis.frame=J}function m6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function l6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return b1($>>>16&255,$>>>8&255,$&255,255);return b1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function u6(J,Q){let $=g6[J];if(typeof Q==="string"){if($===R.color)return l6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===R.color||$===R.int)return Q>>>0;return Q}var $0=60,C1=[1,2,3,4,5,6,10,12,15,20,30,60],w0=$0,qJ=-1,p6=0,xJ=[];function c6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=C1[0];for(let $ of C1)if(Math.abs($-J)Q.at<=qJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>qJ);for(let Q of J)Q.cb()}var C0=0.12,Z0=FJ;function a6(J){Z0=J===void 0?FJ:J&65535}function r6(){Z0=FJ}function h1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function n6(){return h1(Z0&255)}var T1=new Set,t6=0;function e6(){T1.clear(),t6=0,r6()}function J8(J){for(let Q of[...T1])Q(J)}var MJ=null,y1=null;function Q8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function f1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){N0();let Q=MJ?MJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return y1.slice(Q.off,Q.off+Q.len)}var mJ=null,N=null,UJ=null,q0=0,RJ=[],h0=[],T0=[];function v1(J){if(mJ=J,N=null,UJ=null,q0=0,RJ.length=0,h0.length=0,T0.length=0,p){if(p.pressTarget=null,p.target=null,p.spriteDirty=!0,p.fresh=!0,p.vw=0,p.tex>=0){let Q=h();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(p.tex),p.tex=-1}}}function Z8(J,Q){J.onPress=Q??void 0}function q8(J,Q){if(J.focusable=Q,c1(),!Q&&N===J)x(null)}function x(J){if(UJ&&UJ!==J)PJ(null);N=J,h().setFocus(J?J.id:0)}function PJ(J){if(UJ===J)return;let Q=h();if(UJ)Q.setActive?.(UJ.id,0);if(UJ=J,J)Q.setActive?.(J.id,1)}function y0(){return RJ.length>0?RJ[RJ.length-1]:mJ}function f0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function z8(){if(!N)return null;let J=y0();if(J&&!i(N,J))return null;for(let Q=h0.length-1;Q>=0;Q--){let $=h0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(N,$.node))return $}return null}function G8(J){let Q=z8();if(!Q)return!1;let $=[];if(f0(Q.node,$),$.length===0){if(N)x(null);return!0}let Z=Q.columns,q=N?$.indexOf(N):-1;if(q<0)return x(m1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function W8(){if(!N)return null;let J=y0();if(J&&!i(N,J))return null;for(let Q=T0.length-1;Q>=0;Q--){let $=T0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(N,$.node))return $}return null}function X0(J){let Q=W8();if(Q&&Q.move(J))return;if(G8(J))return;Y8(J)}function l1(){u1(N)}function u1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){PJ(J)}function B8(J){x(J),u1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function x0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=x0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var p=null,p1=0;function c1(){p1++}var j8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],K8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function F8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=j8[Q]>>$&1,q=K8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function M8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):U8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(F8(),16,16,w6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function U8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&C6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var G0=null;function d1(J){G0=J}function i1(J){let Q=RJ.length>0?RJ[RJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function s1(J,Q,$){return i1(a1(J,Q,$))}function a1(J,Q,$){if($!==void 0)return $===0?null:z0(G0??mJ,$);let Z=h(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(G0??mJ,q(J,Q))}function R8(J,Q,$){let Z=p,q=h();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=g1(q);if(Z.vw=B?B.w:k1,Z.vh=B?B.h:S1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)M8(Z,q);let X=o6()*Z.speed,z=n6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let W=Z.fresh;if(X!==0||z!==0){let B=d6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),g=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||g!==Z.y)Z.x=_,Z.y=g,W=!0}if(W)q.setCursorPos(Z.x,Z.y);let U=(Q|$)&Z.button,P=p1;if(W||U!==0||P!==Z.gen)Z.gen=P,Z.fresh=!1,Z.target=i1(z0(G0??mJ,q.hitTest(Z.x,Z.y)));let D=Z.target;if(D!==N)x(D);if(Q&Z.button&&D)Z.pressTarget=D;if(Z.pressTarget){if(PJ(D===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=D===Z.pressTarget;if(Z.pressTarget=null,PJ(null),B)l1()}}else if($&Z.button)PJ(null);return!0}function P8(J){let Q=J&~q0,$=q0&~J;if(q0=J,p&&R8(J,Q,$))return;if($&d.CIRCLE)PJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)PJ(N),l1()}var v0=null;function r1(J){v0=J}function wJ(){if(c1(),v0)v0()}function D8(J,Q){J.debugName=Q||void 0,wJ()}var XJ={id:k6,type:KJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},o1=Symbol.for("pocketjs.native-node"),m0=1,lJ=3,o=8,V8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function W0(J){return J.domAttrs??={}}function n1(J,Q){let $=J.domNodeType??(uJ(J)?lJ:m0),Z=$===lJ?B0(J.text??""):$===o?I8(J.domData??""):q4(J.domTag??j0(J));for(let q of Object.keys(J.domAttrs??{}))l0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)YJ(Z,n1(q,!0));return Z}function l0(J,Q,$){if(V8.has(Q)){NJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete W0(J)[Q];else W0(J)[Q]=$}function u0(J){if(J[o1]===!0)return J;return Object.defineProperty(J,o1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?lJ:m0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else H0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else H0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(uJ(J))H0(J,Z);else if(w8(J),Z)YJ(J,B0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return Y4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??j0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===lJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??j0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){NJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===XJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return YJ(J,$),$},insertBefore($,Z){return YJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return YJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return n1(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){l0(J,$,Z)},removeAttribute($){l0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}u0(XJ);var p0=null;function L8(J){p0=J}var c0={unknownClass:0,unknownTexture:0},t1=new Map;function e1(J,Q){t1.set(J,Q)}var J4=new Map;function Q4(J,Q){J4.set(J,Q)}var CJ=new Set,O8=new Set;function $4(J){if(!J)return!1;if(O8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return u0({id:h().createNode(Q),type:Q,parent:null,children:[],domNodeType:m0,domTag:J})}function B0(J){let Q=h(),$=Q.createNode(KJ.text);return Q.setText($,J),u0({id:$,type:KJ.text,parent:null,children:[],text:J,domNodeType:lJ,domTag:"#text"})}function I8(J=""){let Q=B0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function H0(J,Q){h().replaceText(J.id,Q),J.text=Q,wJ()}function uJ(J){return J.type===KJ.text}function X4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function YJ(J,Q,$){let Z=h();if(X4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function pJ(J,Q){if(!Q)return;H8(Q),h().removeChild(J.id,Q.id),X4(Q),CJ.add(Q),wJ()}function A8(J){return J.parent??void 0}function _8(J){return J.children[0]}function Y4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function k8(J,Q){let $=h();if(wJ(),Q==null||Q===""){$.setStyle(J.id,S6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=p0?p0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);c0.unknownClass++;return}$.setStyle(J.id,Z)}function S8(J,Q){let $=h();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=t1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);c0.unknownTexture++;return}$.setImage(J.id,Z)}function b8(J,Q){let $=h();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=J4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);c0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function g8(J,Q,$){let Z=h(),q=Q??{},X=$??{},z=!1;for(let W in q){let U=q[W];if(X[W]===U)continue;let P=b6[W];if(P===void 0)throw Error(`PocketJS: unknown style prop '${W}' (see spec PROP)`);Z.setProp(J.id,P,u6(W,U)),z=!0}if(z)wJ()}function NJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete W0(J)[Q];else W0(J)[Q]=$;switch(Q){case"class":return k8(J,$),$;case"onPress":case"on:press":return Z8(J,$),$;case"src":return S8(J,$),$;case"sprite":return b8(J,$),$;case"style":return g8(J,$,Z),$;case"focusable":return q8(J,!!$),$;case"debugName":return D8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${j0(J)}>`)}function w8(J){for(let Q of[...J.children])pJ(J,Q)}function j0(J){for(let Q of Object.keys(KJ))if(KJ[Q]===J.type)return Q;return String(J.type)}function C8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}NJ(J,Q,$,Z)}var N8=_6({createElement:q4,createTextNode:B0,replaceText:H0,isTextNode:uJ,setProperty:C8,insertNode(J,Q,$){YJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:A8,getFirstChild:_8,getNextSibling:Y4}),{render:E8,effect:xQ,memo:v,createComponent:Y,createElement:z4,insert:vQ,spread:h8,mergeProps:mQ,use:lQ}=N8,uQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},T8=null;function G4(J){T8=J}function y8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function W4(J,Q){let $=z4(J);return h8($,Q,!1),y8(Q.nodeRef,$),$}function M(J){return W4("view",J)}function V(J){return W4("text",J)}var pQ=new WeakMap,cQ=new WeakMap,f8={}!==null?Object.freeze({...{}}):Object.freeze({}),dQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:f8}),iQ=new Map,zJ=36000,d0=30,x8=30,G={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(zJ),tapeAnalog:new Uint16Array(zJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-d0,saidHello:!1,hostCalls:0};function v8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};G.ops=J,G.frame=0,G.tapeStart=0,G.tapeLen=0,G.tapeFirstFrame=0,G.tapeTouch=null,G.replayMasks=null,G.replayAnalog=null,G.replayTouch=null,G.paused=!1,G.stepQueued=0,G.inspectReportId=null,G.inspectAskedAt=0,G.treeDirty=!0,G.treeSentAt=-d0,G.saidHello=!1,G.hostCalls=0,G.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)G.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)G.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else G.transport=null;if(G.transport)r1(()=>{G.treeDirty=!0}),s8();else r1(null);globalThis.__pocketDevtools=r8}function m8(J){return(Q,$,Z,q)=>{if(G.hostCalls++,G.transport)u8(),d8();let X=Q,z=$===void 0?FJ:$&65535,W=Z,U=q;if(G.replayMasks)if(G.replayAt0?$.slice(0,8):null;if(Z&&!G.tapeTouch)G.tapeTouch=Array(zJ).fill(null);if(G.tapeLen1||Q.length===1&&Q[0][0]!==FJ)J.analog=Q;if(G.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function j4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function K4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return j4(J.masks,0,Q)}function F4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return j4(J.analog??[],FJ,Q)}function M4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&G.hostCalls%Q!==0)return;if(!G.saidHello)G.saidHello=!0,y({t:"hello",app:G.app,host:a8(),frame:G.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` +`))if(q.trim())p8(q)}}function p8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=G.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),G.inspectReportId=Z||null,G.inspectAskedAt=G.hostCalls,!Z)y({t:"inspect",id:0,rect:null});break}case"pause":G.paused=!0,G.stepQueued=0,$?.debugPause?.(!0),i0();break;case"resume":G.paused=!1,$?.debugPause?.(!1),i0();break;case"step":G.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":U4();break;case"eval":{let Z=!0,q;try{q=K0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}y({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":y({t:"tape",tape:H4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}y({t:"devStats",frame:G.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())y({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:G.frame});else y({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))G.replayMasks=K4(Z),G.replayAnalog=Z.analog?F4(Z):null,G.replayTouch=Z.touch?M4(Z):null,G.replayAt=0;break}default:break}}function c8(){if(G.treeDirty&&G.frame-G.treeSentAt>=d0)U4();if(G.frame%x8===0)i0()}function d8(){let J=G.inspectReportId;if(J==null)return;let Q=G.ops;if(!Q?.debugRectXY||!Q.debugRectWH){G.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(G.hostCalls-G.inspectAskedAt>60)G.inspectReportId=null,y({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();G.inspectReportId=null,y({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function i0(){y({t:"stats",frame:G.frame,nodes:D4(XJ),tapeLen:G.tapeLen,paused:G.paused})}function U4(){G.treeDirty=!1,G.treeSentAt=G.frame,y({t:"tree",frame:G.frame,root:P4(XJ)})}function i8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function s0(J,Q){if(Array.isArray(J)){for(let $ of J)s0($,Q);return}if(i8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)s0($,Q)}}function R4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)s0(Z,Q)}function P4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(R4(J,(q)=>{if(q.domNodeType===8)return;Z.push(P4(q))}),Z.length)Q.k=Z;return Q}function D4(J){let Q=1;return R4(J,($)=>{Q+=D4($)}),Q}function s8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{y({t:"log",level:$,args:q.map((X)=>K0(X))}),Z?.apply(Q,q)}}}function K0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?V4(X):JSON.stringify(V4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>K0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${K0(z,Q+1)}`).join(", ")}}`}function V4(J){return J.length>200?J.slice(0,199)+"…":J}function a8(){let J=G.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var r8={get frame(){return G.frame},dumpTape:()=>H4(),replay:(J)=>{G.replayMasks=K4(J),G.replayAnalog=J.analog?F4(J):null,G.replayTouch=J.touch?M4(J):null,G.replayAt=0}},L4=new Map,a0=new Map;function O4(J){return J.trim().replace(/\s+/g," ")}function I4(J){return J.split(" ").sort().join(" ")}var A4=-1;function o8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=O4(Q);L4.set(Z,$);let q=I4(Z),X=a0.get(q);a0.set(q,X!==void 0&&X!==$?A4:$)}}function n8(J){let Q=O4(J),$=L4.get(Q);if($!==void 0)return $;let Z=a0.get(I4(Q));return Z===A4?void 0:Z}var r0=9,t8=(1<{let q=($&J2)!==0,X=q?o0:r0,z=q?Q2:t8;return Object.freeze({id:$>>>(q?$2:e8)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function q2(){return F0}function X2(){F0=n0}var _4=8,GJ=8,Y2=3,z2=8,G2=6,W2=0.5,s=1,cJ=2,t0=4,DJ=8,EJ=[],k4=0,M0=0,WJ=Array.from({length:_4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(GJ),histY:new Int16Array(GJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function B2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function H2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=a1(Q,$,Z.fact);let W=Z.hit;if(W)return B2(W,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let W=EJ[z];if(W.disposed)continue;if(k4>0&&!W.opts.allowWhenBlocked)continue;if(!H2(W,$,Z,X))continue;W.flags[J.slot]=s,J.owners.push(W)}for(let z of J.owners)z.opts.onDown?.(J)}function F2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%GJ,J.histLenz||Z>z))q.flags[J.slot]|=cJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(cJ|t0))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??W2)*N1()));if(J.frames=0)EJ.splice($,1)},cancel(){if(!Q.disposed)g4(Q)},get panning(){for(let $ of WJ)if($.used&&Q.flags[$.slot]&DJ)return!0;return!1}}}function D2(J){let Q=P2(J);return _0(()=>Q.dispose()),Q}function w4(){EJ.length=0,k4=0,M0=0;for(let J of WJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function V2(){return D2({onDown:(J)=>{let Q=s1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=s1(J.x,J.y,J.hit);if(Q)B8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var L2=1,e0=new Map,U0=[];function O2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function I2(){L2=1,e0.clear(),U0=[]}function A2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=e0.get(Q);if(!Z)continue;e0.delete(Q),O2()?.({t:"delivery",frame:E1(),id:Q,kind:Z.kind}),Z.onResult($)}}var C4=new Set;function _2(){if(C4.size===0)return;for(let J of C4)J()}var k2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[318] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[30] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-lg text-orange-600 font-bold":9,"h-[84] pt-3 text-xl text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-lg text-emerald-700 font-bold":13,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":14,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":15,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":16,"text-base text-slate-600 font-bold":17,"pt-6 text-lg text-slate-500":18,"pt-6 text-lg text-slate-900 font-bold":19,"h-[146] px-6 pt-7 flex-col bg-slate-50":20,"h-[80]":21,"h-[1060] px-6 pt-5 flex-col":22,"h-[48] px-4 justify-center bg-slate-100":23,"text-base text-slate-600":24,"pt-[10] flex-col gap-[12]":25,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":26,"w-[48] h-[48] items-center justify-center bg-blue-100":27,"w-[48] h-[48] items-center justify-center bg-emerald-100":28,"text-lg text-blue-700 font-bold":29,"w-[474] flex-col gap-2":30,"text-lg text-slate-900 font-bold":31,"text-base text-slate-500":32,"pt-20 pl-10 text-lg text-slate-500":33,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":34,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":35,"h-[1060] px-6 pt-7 flex-col gap-4":36,"text-base text-slate-500 font-bold":37,"h-[214] px-7 items-center justify-center bg-slate-100":38,"text-lg text-slate-500 font-bold":39,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":40,"flex-row items-center gap-5":41,"w-[68] h-[68] items-center justify-center bg-orange-100":42,"text-xl text-orange-700 font-bold":43,"w-[500] flex-col gap-2":44,"text-xl text-slate-900 font-bold":45,"text-lg text-slate-600":46,"text-2xl text-orange-600":47,"mt-4 h-[112] px-6 justify-center bg-slate-100":48,"relative h-[154] px-5 pt-5 flex-col bg-white":49,"pt-3 text-lg text-orange-600 font-bold":50,"pt-3 text-base text-slate-500":51,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":52,"text-lg text-white font-bold":53,"h-[40] pt-3 text-base text-slate-500":54,"h-[470] flex-col gap-2":55,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":56,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":57,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":58,"h-[160] px-5 pt-5 flex-col bg-white":59,"pt-3 text-lg text-slate-900 font-bold":60,"pt-3 text-base text-slate-600":61,"h-[108] pt-7 flex-row gap-4":62,"w-[316] h-[80] items-center justify-center bg-slate-100":63,"w-[340] h-[80] items-center justify-center bg-red-100":64,"text-lg text-red-500 font-bold":65,"h-[1052] px-6 pt-5 flex-col":66,"h-[270] px-[22] pt-6 bg-white":67,"text-lg text-slate-900":68,"text-lg text-slate-400":69,"h-[86] px-1 flex-row items-center justify-between":70,"w-[132] h-[58] items-center justify-center bg-slate-300":71,"w-[132] h-[58] items-center justify-center bg-slate-100":72,"text-base text-slate-900 font-bold":73,"h-[140] flex-row gap-2":74,"grow h-[120] items-center justify-center bg-slate-300":75,"grow h-[120] items-center justify-center bg-white":76,"w-[104] h-[120] items-center justify-center bg-slate-300":77,"w-[104] h-[120] items-center justify-center bg-slate-100":78,"h-[176] flex-row gap-2":79,"w-[92] h-[156] items-center justify-center bg-slate-300":80,"w-[92] h-[156] items-center justify-center bg-slate-100":81,"w-[300] h-[156] items-center justify-center bg-slate-300":82,"w-[300] h-[156] items-center justify-center bg-slate-100":83,"w-[144] h-[156] items-center justify-center bg-slate-300":84,"w-[144] h-[156] items-center justify-center bg-slate-100":85,"w-[112] h-[156] items-center justify-center bg-emerald-700":86,"w-[112] h-[156] items-center justify-center bg-emerald-500":87,"text-base text-slate-950 font-bold":88,"h-[108] px-6 py-3 flex-col bg-slate-50":89,"h-[84] items-center justify-center bg-slate-300":90,"h-[84] items-center justify-center bg-slate-100":91,"h-[1168] px-6 pt-5 flex-col":92,"h-[82] px-4 justify-center bg-white":93,"w-[584] h-[900] px-5 pt-5 bg-slate-950":94,"text-base text-slate-200":95,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":96,"w-[584] h-[900] px-5 pt-5 bg-white":97,"text-xl text-slate-900":98,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":99,"absolute inset-0 z-50 flex-col items-center justify-center":100,"absolute inset-0 bg-slate-950":101,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":102,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":103,"flex-row flex-wrap":104,grow:105,"text-2xl text-white font-bold":106,"text-2xl text-slate-950 font-bold":107,"px-6":108,"px-6 py-5":109,"gap-4":110,"rounded-xl shadow bg-white border-slate-100":111,"rounded-xl shadow bg-emerald-100 border-emerald-500":112,"bg-white":113,"bg-slate-100":114,"bg-slate-950":115,"px-3 py-2 rounded-lg bg-slate-100":116,"px-3 py-2 rounded-lg bg-indigo-100":117,"text-base text-indigo-700 font-bold":118,"px-3 py-2 rounded-lg bg-emerald-100":119,"text-base text-emerald-700 font-bold":120,"px-3 py-2 rounded-lg bg-amber-100":121,"text-base text-amber-700 font-bold":122,"px-3 py-2 rounded-lg bg-red-100":123,"text-base text-red-500 font-bold":124,"w-[34] h-[34] rounded-lg bg-amber-400":125,"w-[34] h-[34] rounded-lg bg-red-500":126,"w-[34] h-[34] rounded-lg bg-slate-800":127,"w-[34] h-[34] rounded-lg bg-emerald-500":128,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":129,"flex-row items-center gap-4":130,"w-[34] text-2xl text-white font-bold":131,"w-[332] flex-col items-end gap-2":132,"text-base text-slate-300 font-bold":133,"text-base text-slate-400":134,"h-[166] px-6 pt-6 flex-col gap-3":135,"text-base text-orange-600 font-bold":136,"h-[44] px-1 flex-row items-center justify-between":137,"w-full h-full items-center justify-center rounded-xl bg-slate-200":138,"w-full h-full items-center justify-center rounded-xl bg-red-100":139,"w-full h-full items-center justify-center rounded-xl bg-slate-100":140,"w-full h-full items-center justify-center rounded-xl bg-orange-600":141,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":142,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":143,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":144,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":145,"text-2xl text-indigo-700 font-bold":146,"text-2xl text-slate-600 font-bold":147,"pt-7 text-2xl text-slate-900 font-bold":148,"pt-4 text-lg text-slate-500":149,"text-xl text-emerald-600 font-bold":150,"text-xl text-red-500 font-bold":151,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":152,"text-base text-red-300":153,"text-base text-slate-300":154,"text-base text-red-500":155,"w-full h-full px-6 flex-row items-center bg-slate-950":156,"w-full h-full flex-row items-center":157};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var S2="ui:styles",b2="ui:font.",N4="ui:img.",E4="ui:sprite.";function g2(){return globalThis.ui}function w2(J){if(J.__textures)return;for(let Q of E0(N4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)e1(Q.slice(N4.length),Z)}}function C2(J){if(J.__sprites)return;for(let Q of E0(E4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],W=Z.getUint16(6,!0),U=Z.getUint16(8,!0),P=Z.getUint16(10,!0),D=J.uploadTexture($.subarray(16),q,X,z);if(D>=0)Q4(Q.slice(E4.length),{handle:D,frames:W,cols:U,step:P})}}function h4(J){let Q=z4("view");return NJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function N2(J,Q){if(!R0||!P0)return;NJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),NJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=h();$.__viewport={w:J,h:Q}}function E2(J,Q={}){let $=f6(Q.ops);if(x6($),L8(n8),Q.styles)o8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)e1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)Q4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)x1(Q.pak);if($8()){for(let B of E0())if(B===S2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(b2))$.ops.loadFontAtlas?.(vJ(B))}}let q=g1($.ops),X=q?.w??k1,z=q?.h??S1,W=h4({width:X,height:z,overflow:u.Overflow.Hidden}),U=h4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});YJ(XJ,W),YJ(XJ,U),G4(U),R0=W,P0=U,v1(W),d1(XJ),e6(),w4(),V2(),i6(),I2(),v8($.ops),v6(m8((B,_,g,w)=>{s6(),a6(_),Z2(g,w),_2(),A2(),R2(),J8(B),P8(B),Z4()}));let P=E8(J,W),D=m6(N2);return()=>{D(),X2(),w4(),P(),v1(null),d1(null),G4(null),R0=null,P0=null;for(let B of XJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);Z4()}}function h2(J,Q={}){let $=Q.ops??g2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)x1(Q.pak);return w2($),C2($),E2(J,{ops:$,styles:Q.styles??k2,pak:Q.pak})}var T2="$b",y2=65536,T4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function v2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function y4(){let J=v2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function m2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,y2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let W=f2(z.data[T2]);if($.push(W),Z+=W.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function l2(J,Q){let $=m2(y4(),J);return Q==="utf8"||Q==="utf-8"?x2($):$}function u2(J,Q){let $=y4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var p2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"};function c2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(M,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(M,{class:"flex-row items-center gap-4",get children(){return[v(()=>v(()=>!!J.back)()?Y(V,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(M,{get["class"](){return Q()}})),Y(V,{get["class"](){return p2.appTitle},get children(){return J.title}})]}}),Y(M,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(V,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(V,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function d2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(M,{get["class"](){return Q()},get children(){return Y(V,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(M,{get["class"](){return J.top},get children(){return Y(V,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(M,{get["class"](){return J.bottom},get children(){return Y(V,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var sQ="‘’“”–—…•",i2=512;function s2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let W=Q(z);if(q&&X+W>$)Z.push(q),q="",X=0;q+=z,X+=W}if(q)Z.push(q);return Z}function f4(J,Q,$){let Z=new Map,q=(W)=>{let U=Z.get(W);if(U===void 0)U=h().measureText(W,Q),Z.set(W,U);return U},X=[],z=q(" ");for(let W of J.split(` +`)){let U=W.split(" ").flatMap((B)=>B&&q(B)>$?s2(B,q,$):[B]),P="",D=0;for(let B of U){let _=q(B);if(!P)P=B,D=_;else if(D+z+_<=$)P+=" "+B,D+=z+_;else X.push(P),P=B,D=_}X.push(P)}return X}function J1(J,Q,$,Z){let q=J.slice(0,i2),X=f4(q,Q,$);if(q.length===J.length&&X.length<=Z)return X.join(` +`);let z=X.slice(0,Z),W=z.length-1;return z[W]=z[W].replace(/[\s.]+$/,"")+"…",z.join(` +`)}function a2(J,Q,$,Z){let q=$;while(qQ){if(U>X)return{text:z.slice(0,P).replace(/\s+$/,""),nextOffset:U,sourceLineEnded:!1};return{text:z,nextOffset:q,sourceLineEnded:!1}}if(z+=D,W+=B,q+=1,D===" ")U=q,P=z.length-1}return{text:z.replace(/\s+$/,""),nextOffset:q,sourceLineEnded:!1}}function r2(J,Q,$,Z,q,X){let z=Math.max(0,Math.floor(X)),W=[],U=Math.max(0,Math.min(Math.floor(Z),J.length)),P=Math.max(0,Math.floor(q)),D=P,B=new Map,_=(g)=>{let w=B.get(g);if(w===void 0)w=h().measureText(g,Q),B.set(g,w);return w};while(U0&&!Q.page.hasMore)return;let Z=Q.pageStarts[$];if(!Z)Z={offset:Q.page.nextOffset,sourceLine:Q.page.nextSourceLine},Q.pageStarts.push(Z);Y1({...Q,pageIndex:$,page:e4(Q.text,Z)})}function O0(J=VJ(),Q=!1){let $=r4.get(J);if(!Q&&$){q1($),D0(""),hJ((Z)=>Math.min(Z,Math.max(0,$.length-8)));return}try{let Z=u2(J,{withFileTypes:!0}).map((q)=>({name:q.name,kind:q.isDirectory()?"dir":"file",size:q.size}));r4.set(J,Z),q1(Z),D0(""),hJ((q)=>Math.min(q,Math.max(0,Z.length-8)))}catch(Z){q1([]),D0(Z instanceof Error?Z.message:String(Z))}}function YQ(){let J=[];for(let Q of n().messages??[])if(Q.role==="user")J.push({user:Q.text,assistant:"THINKING..."});else if(J.length===0)J.push({user:"TYPE A MESSAGE",assistant:Q.text||"THINKING..."});else J[J.length-1].assistant=Q.text||"THINKING...";return J.length?J:[{user:"TYPE A MESSAGE",assistant:"BOOTING PI AGENT..."}]}function Q6(){let J=YQ(),Q=Math.max(0,J.length-2),$=Math.min(Z1(),Q),Z=J.length-$;return J.slice(Math.max(0,Z-2),Z)}function OJ(J){return Y(c2,{get title(){return J.title},get accent(){return v(()=>n().agent==="FAULTED")()?"danger":n().agent==="THINKING"?"busy":"ready"}})}function I0(){return Y(M,{class:"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950",get children(){return Y(jJ,{each:t4,children:(J)=>Y(M,{get["class"](){return $1()===J?"w-[165] h-[76] items-center justify-center bg-orange-600":"w-[165] h-[76] items-center justify-center bg-slate-900"},get children(){return Y(V,{class:"text-base text-white font-bold",get children(){return J.toUpperCase()}})}})})}})}function zQ(){let J=()=>n().schedule,Q=()=>{let $=J();return J1(String($?.name)+" "+String($?.next??"")+` -`+String($?.prompt??""),Z1,q1,5)};return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"ESP32 PI AGENT"}),Y(M,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(jJ,{get each(){return J6()},children:($)=>Y(M,{class:"w-[584] h-[298] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(M,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(M,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(P,{class:"text-base text-orange-600 font-bold",children:"YOU"})]}}),Y(P,{class:"h-[76] pt-3 text-lg text-slate-900",get children(){return $1($.user,Z1,q1,3)}}),Y(M,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(M,{class:"h-[28] flex-row items-center gap-3",get children(){return[Y(M,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(P,{class:"text-base text-emerald-700 font-bold",children:"PI"})]}}),Y(P,{class:"h-[84] pt-3 text-lg text-slate-900",get children(){return $1($.assistant,Z1,q1,3)}})]}})}),Y(iJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(M,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(P,{class:"text-base text-slate-600 font-bold",children:"NEXT WAKE"}),Y(ZJ,{get when(){return J()?.name},get fallback(){return Y(P,{class:"pt-6 text-lg text-slate-500",children:`NO WAKE SCHEDULED +`+String($?.prompt??""),o2,Q1,5)};return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"ESP32 PI AGENT"}),Y(M,{class:"h-[686] px-6 pt-7 flex-col gap-[22]",get children(){return[Y(jJ,{get each(){return Q6()},children:($)=>Y(M,{class:"w-[584] h-[318] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(M,{class:"h-[30] flex-row items-center gap-3",get children(){return[Y(M,{class:"w-[10] h-[10] rounded bg-orange-500"}),Y(V,{class:"text-lg text-orange-600 font-bold",children:"YOU"})]}}),Y(V,{class:"h-[84] pt-3 text-xl text-slate-900",get children(){return J1($.user,x4,Q1,3)}}),Y(M,{class:"h-[2] mx-1 my-4 bg-slate-100"}),Y(M,{class:"h-[30] flex-row items-center gap-3",get children(){return[Y(M,{class:"w-[10] h-[10] rounded bg-emerald-500"}),Y(V,{class:"text-lg text-emerald-700 font-bold",children:"PI"})]}}),Y(V,{class:"h-[84] pt-3 text-xl text-slate-900",get children(){return J1($.assistant,x4,Q1,3)}})]}})}),Y(iJ,{top:"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100"})]}}),Y(M,{class:"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[Y(V,{class:"text-base text-slate-600 font-bold",children:"NEXT WAKE"}),Y(ZJ,{get when(){return J()?.name},get fallback(){return Y(V,{class:"pt-6 text-lg text-slate-500",children:`NO WAKE SCHEDULED -ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(P,{class:"pt-6 text-lg text-slate-900 font-bold",get children(){return Q()}})}})]}}),Y(M,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(M,{class:"h-[80]",get children(){return Y(p2,{label:"TYPE A MESSAGE"})}})}}),Y(A0,{})]}})}function JQ(){let J=()=>aJ().slice(sJ(),sJ()+8);return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{get title(){return VJ()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(M,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(P,{class:"text-base text-slate-600",get children(){return"/workspace"+(VJ()?"/"+VJ():"")}})}}),Y(M,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(jJ,{get each(){return J()},children:(Q)=>Y(M,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(M,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(P,{get["class"](){return Q.kind==="dir"?"text-lg text-blue-700 font-bold":"text-lg text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(M,{class:"w-[474] flex-col gap-2",get children(){return[Y(P,{class:"text-lg text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,52)}}),Y(P,{class:"text-base text-slate-500",get children(){return c(()=>Q.kind==="dir")()?"FOLDER":o2(Q.size)}})]}})]}})})}}),Y(ZJ,{get when(){return aJ().length===0},get children(){return Y(P,{class:"pt-20 pl-10 text-lg text-slate-500",get children(){return r2()||"THIS DIRECTORY IS EMPTY"}})}}),Y(ZJ,{get when(){return aJ().length>8},get children(){return Y(iJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(A0,{})]}})}function QQ(){let J=()=>n().apps??[];return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"APPS"}),Y(M,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(P,{class:"text-base text-slate-500 font-bold",get children(){return String(J().length)+" INSTALLED APPS"}}),Y(ZJ,{get when(){return J().length>0},get fallback(){return Y(M,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(P,{class:"text-lg text-slate-500 font-bold",children:"NO OPTIONAL APPS INSTALLED"})}})},get children(){return Y(jJ,{get each(){return J()},children:(Q)=>Y(M,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(M,{class:"flex-row items-center gap-5",get children(){return[Y(M,{class:"w-[68] h-[68] items-center justify-center bg-orange-100",get children(){return Y(P,{class:"text-xl text-orange-700 font-bold",get children(){return Q.title.slice(0,1).toUpperCase()}})}}),Y(M,{class:"w-[500] flex-col gap-2",get children(){return[Y(P,{class:"text-xl text-slate-900 font-bold",get children(){return Q.title}}),Y(P,{class:"text-lg text-slate-600",get children(){return Q.description}}),Y(ZJ,{get when(){return Q.scheduleEveryMinutes},get children(){return Y(P,{class:"text-base text-slate-500",get children(){return"UPDATES EVERY "+String(Q.scheduleEveryMinutes)+" MINUTES"}})}})]}})]}}),Y(P,{class:"text-2xl text-orange-600",children:"›"})]}})})}}),Y(M,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(P,{class:"text-base text-slate-600",children:`APP DATA STAYS ISOLATED. -PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(A0,{})]}})}function $Q(){let J=()=>n().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(rJ(),rJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"SETTINGS"}),Y(M,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(P,{class:"text-lg text-slate-900 font-bold",children:"WI-FI"}),Y(P,{class:"pt-3 text-lg text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(P,{class:"pt-3 text-base text-slate-500",get children(){return Z()}}),Y(M,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(P,{class:"text-lg text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(P,{class:"h-[40] pt-3 text-base text-slate-500",children:"AVAILABLE NETWORKS"}),Y(M,{class:"h-[470] flex-col gap-2",get children(){return[Y(ZJ,{get when(){return $().length>0},get fallback(){return Y(M,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(P,{class:"text-lg text-slate-500 font-bold",children:`NO NETWORK LIST YET +ASK PI TO CREATE ONE WITH SCHEDULE.SET`})},get children(){return Y(V,{class:"pt-6 text-lg text-slate-900 font-bold",get children(){return Q()}})}})]}}),Y(M,{class:"h-[146] px-6 pt-7 flex-col bg-slate-50",get children(){return Y(M,{class:"h-[80]",get children(){return Y(d2,{label:"TYPE A MESSAGE"})}})}}),Y(I0,{})]}})}function GQ(){let J=()=>aJ().slice(sJ(),sJ()+8);return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{get title(){return VJ()?"< WORKSPACE FILES":"WORKSPACE FILES"}}),Y(M,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[48] px-4 justify-center bg-slate-100",get children(){return Y(V,{class:"text-base text-slate-600",get children(){return"/workspace"+(VJ()?"/"+VJ():"")}})}}),Y(M,{class:"pt-[10] flex-col gap-[12]",get children(){return Y(jJ,{get each(){return J()},children:(Q)=>Y(M,{class:"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white",get children(){return[Y(M,{get["class"](){return Q.kind==="dir"?"w-[48] h-[48] items-center justify-center bg-blue-100":"w-[48] h-[48] items-center justify-center bg-emerald-100"},get children(){return Y(V,{get["class"](){return Q.kind==="dir"?"text-lg text-blue-700 font-bold":"text-lg text-emerald-700 font-bold"},get children(){return Q.kind==="dir"?"D":"F"}})}}),Y(M,{class:"w-[474] flex-col gap-2",get children(){return[Y(V,{class:"text-lg text-slate-900 font-bold",get children(){return(Q.name+(Q.kind==="dir"?"/":"")).slice(0,52)}}),Y(V,{class:"text-base text-slate-500",get children(){return v(()=>Q.kind==="dir")()?"FOLDER":ZQ(Q.size)}})]}})]}})})}}),Y(ZJ,{get when(){return aJ().length===0},get children(){return Y(V,{class:"pt-20 pl-10 text-lg text-slate-500",get children(){return $Q()||"THIS DIRECTORY IS EMPTY"}})}}),Y(ZJ,{get when(){return aJ().length>8},get children(){return Y(iJ,{top:"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(I0,{})]}})}function WQ(){let J=()=>n().apps??[];return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"APPS"}),Y(M,{class:"h-[1060] px-6 pt-7 flex-col gap-4",get children(){return[Y(V,{class:"text-base text-slate-500 font-bold",get children(){return String(J().length)+" INSTALLED APPS"}}),Y(ZJ,{get when(){return J().length>0},get fallback(){return Y(M,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(V,{class:"text-lg text-slate-500 font-bold",children:"NO OPTIONAL APPS INSTALLED"})}})},get children(){return Y(jJ,{get each(){return J()},children:(Q)=>Y(M,{class:"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white",get children(){return[Y(M,{class:"flex-row items-center gap-5",get children(){return[Y(M,{class:"w-[68] h-[68] items-center justify-center bg-orange-100",get children(){return Y(V,{class:"text-xl text-orange-700 font-bold",get children(){return Q.title.slice(0,1).toUpperCase()}})}}),Y(M,{class:"w-[500] flex-col gap-2",get children(){return[Y(V,{class:"text-xl text-slate-900 font-bold",get children(){return Q.title}}),Y(V,{class:"text-lg text-slate-600",get children(){return Q.description}}),Y(ZJ,{get when(){return Q.scheduleEveryMinutes},get children(){return Y(V,{class:"text-base text-slate-500",get children(){return"UPDATES EVERY "+String(Q.scheduleEveryMinutes)+" MINUTES"}})}})]}})]}}),Y(V,{class:"text-2xl text-orange-600",children:"›"})]}})})}}),Y(M,{class:"mt-4 h-[112] px-6 justify-center bg-slate-100",get children(){return Y(V,{class:"text-base text-slate-600",children:`APP DATA STAYS ISOLATED. +PI AGENT CAN USE EACH APP'S TOOLS.`})}})]}}),Y(I0,{})]}})}function BQ(){let J=()=>n().settings??{},Q=()=>J().wifi??{},$=()=>(Q().networks??[]).slice(rJ(),rJ()+5),Z=()=>Q().ipAddress?"IP "+Q().ipAddress+" RSSI "+String(Q().rssiDbm??"--")+" DBM":Q().status||"SCAN AND SELECT A NETWORK";return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"SETTINGS"}),Y(M,{class:"h-[1060] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"relative h-[154] px-5 pt-5 flex-col bg-white",get children(){return[Y(V,{class:"text-lg text-slate-900 font-bold",children:"WI-FI"}),Y(V,{class:"pt-3 text-lg text-orange-600 font-bold",get children(){return Q().connectedSsid||"NOT CONNECTED"}}),Y(V,{class:"pt-3 text-base text-slate-500",get children(){return Z()}}),Y(M,{class:"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600",get children(){return Y(V,{class:"text-lg text-white font-bold",get children(){return Q().scanning?"SCANNING":"SCAN"}})}})]}}),Y(V,{class:"h-[40] pt-3 text-base text-slate-500",children:"AVAILABLE NETWORKS"}),Y(M,{class:"h-[470] flex-col gap-2",get children(){return[Y(ZJ,{get when(){return $().length>0},get fallback(){return Y(M,{class:"h-[214] px-7 items-center justify-center bg-slate-100",get children(){return Y(V,{class:"text-lg text-slate-500 font-bold",children:`NO NETWORK LIST YET -TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(jJ,{get each(){return $()},children:(q)=>Y(M,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(P,{class:"text-lg text-slate-900 font-bold",get children(){return q.ssid}}),Y(P,{class:"text-base text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(ZJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(iJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(M,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(P,{class:"text-base text-slate-500",children:"MODEL BACKEND"}),Y(P,{class:"pt-3 text-lg text-slate-900 font-bold",get children(){return n().model??"UNKNOWN"}}),Y(P,{class:"pt-3 text-base text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(M,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(M,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(P,{class:"text-lg text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(M,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(P,{class:"text-lg text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(A0,{})]}})}function ZQ(){let J=()=>H1(),Q=()=>LJ()==="letters"?n4:t4,$=()=>J().type==="wifi"?"*".repeat(v().length):v();return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(M,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(P,{get["class"](){return v()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(M,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(P,{class:"text-base text-slate-500",get children(){return String(v().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(M,{get["class"](){return HJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(P,{class:"text-base text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(jJ,{get each(){return Q()},children:(Z,q)=>Y(M,{class:"h-[140] flex-row gap-2",get children(){return[Y(jJ,{get each(){return Z.split("")},children:(X)=>Y(M,{get["class"](){return HJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(P,{class:"text-xl text-slate-900 font-bold",get children(){return c(()=>!!W1())()?X.toUpperCase():X}})}})}),Y(ZJ,{get when(){return q()===2},get children(){return Y(M,{get["class"](){return HJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(P,{class:"text-base text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(M,{class:"h-[176] flex-row gap-2",get children(){return[Y(M,{get["class"](){return HJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(P,{class:"text-base text-slate-900 font-bold",get children(){return LJ()==="letters"?"123":"ABC"}})}}),Y(M,{get["class"](){return HJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(P,{class:"text-base text-slate-900 font-bold",children:"SPACE"})}}),Y(M,{get["class"](){return HJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(P,{class:"text-base text-slate-900 font-bold",get children(){return LJ()==="letters"?"SHIFT":". ?"}})}}),Y(M,{get["class"](){return HJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(P,{class:"text-base text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(M,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(M,{get["class"](){return HJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(P,{class:"text-base text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function qQ(){let J=()=>c4(),Q=()=>(J()?.text??"").split(` -`),$=()=>J()?.lineOffset??0;return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"< FILE VIEWER"}),Y(M,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(P,{class:"text-lg text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(M,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(P,{class:"text-base text-slate-200",get children(){return Q().slice($(),$()+39).join(` -`)}})}}),Y(P,{class:"pt-3 text-base text-slate-500",get children(){return"LINES "+String($()+1)+"-"+String(Math.min($()+39,Q().length))+" / "+String(Q().length)}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function XQ(){let J=()=>p4(),Q=()=>Q1(J()?.text??"",y4,v4);return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"< MESSAGE READER"}),Y(M,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(P,{class:"text-lg text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(M,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(P,{class:"text-base text-slate-900",get children(){return Q().slice(L0(),L0()+m4).join(` -`)}})}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function YQ(){return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return c(()=>x()==="chat")()?Y(e2,{}):c(()=>x()==="files")()?Y(JQ,{}):c(()=>x()==="apps")()?Y(QQ,{}):c(()=>x()==="settings")()?Y($Q,{}):c(()=>x()==="keyboard")()?Y(ZQ,{}):c(()=>x()==="viewer")()?Y(qQ,{}):Y(XQ,{})}})}function zQ(J){G6(()=>{if(a2(J),t(J),J==="files")I0()})}function Q6(J,Q){let $=LJ()==="letters"?n4:t4,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],G=(q===2?560:672)/X.length,R=Math.floor((J-24)/G);if(R>=0&&R=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=Q6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function GQ(J,Q){if(Q>=1164)return e(""),t(X1()),"";if(J>=548&&Q>=402&&Q<=482)return e(""),"";let $=Q6(J,Q);if($){let Z=LJ()==="letters"&&W1()?$.toUpperCase():$,q=H1().type==="wifi"?63:256;if(v().length=592&&Q>=768&&Q<=888)return e(v().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)i4(LJ()==="letters"?"numbers":"letters"),G1(!1);else if(J<=424){if(v())e(v()+" ")}else if(J<=576)if(LJ()==="letters")G1(!W1());else e(v()+(J<=500?".":"?"));else if(v().trim()){let Z=v().trim(),q=H1();if(e(""),i4("letters"),G1(!1),t(X1()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}E2(()=>Y(YQ,{})),queueMicrotask(()=>I0("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return s2(JSON.parse(J)),""},pointerDown(J,Q){return a4(x()==="keyboard"?WQ(J,Q):null),""},pointerUp(){return a4(null),""},tap(J,Q){if(x()==="keyboard")return GQ(J,Q);if(x()==="viewer"){let $=c4();if(J<104&&Q<112)V0(null),t("files");else if($&&J>=620&&Q>=170&&Q<=340)V0({...$,lineOffset:Math.max(0,$.lineOffset-18)});else if($&&J>=620&&Q>=920&&Q<=1100)V0({...$,lineOffset:Math.min(Math.max(0,$.text.split(` -`).length-39),$.lineOffset+18)});return""}if(x()==="reader"){if(J<104&&Q<112)d4(null),O0(0),t("chat");else if(J>=620&&Q>=170&&Q<=340)O0(Math.max(0,L0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=Q1(p4()?.text??"",y4,v4).length;O0(Math.min(Math.max(0,$-m4),L0()+18))}return""}if(Q>=1172)return zQ(e4[Math.min(3,Math.floor(J/180))]),"";if(x()==="chat"){if(J>=620&&Q>=140&&Q<=272)l4(Y1()+2);else if(J>=620&&Q>=624&&Q<=756)l4(Math.max(0,Y1()-2));else if(J<610&&Q>=140&&Q<738){let $=Math.floor((Q-140)/320),Z=J6()[$];if(Z){let q=Q>=140+$*320+150;d4({author:q?"PI":"YOU",text:q?Z.assistant:Z.user}),O0(0),t("reader")}}else if(Q>=1070&&Q<=1150)s4({type:"prompt"}),e(""),t("keyboard");return""}if(x()==="files"){if(J<104&&Q<112&&VJ()){let $=VJ().split("/");$.pop();let Z=$.join("/");u4(Z),NJ(0),I0(Z)}else if(J>=620&&Q>=170&&Q<=340)NJ(Math.max(0,sJ()-4));else if(J>=620&&Q>=920&&Q<=1100)NJ(Math.min(Math.max(0,aJ().length-8),sJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=aJ()[sJ()+$];if(Z){let q=n2(VJ(),Z.name);if(Z.kind==="dir")u4(q),NJ(0),I0(q);else try{V0({path:"/workspace/"+q,text:m2(q,"utf8"),lineOffset:0}),t("viewer")}catch(X){D0(X instanceof Error?X.message:String(X))}}}return""}if(x()==="apps"){let $=(n().apps??[])[Math.floor((Q-162)/166)];if(Q>=162&&$)return JSON.stringify({type:"navigate",app:$.id});return""}if(x()==="settings"){let $=n().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)r4(Math.max(0,rJ()-4));else if(J>=620&&Q>=650&&Q<=782)r4(Math.min(Math.max(0,$.length-5),rJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[rJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});s4({type:"wifi",ssid:q.ssid}),e(""),t("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); +TAP SCAN TO FIND WI-FI`})}})},get children(){return Y(jJ,{get each(){return $()},children:(q)=>Y(M,{class:"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white",get children(){return[Y(V,{class:"text-lg text-slate-900 font-bold",get children(){return q.ssid}}),Y(V,{class:"text-base text-slate-500",get children(){return String(q.rssiDbm)+" DBM "+(q.secured?"LOCK":"OPEN")}})]}})})}}),Y(ZJ,{get when(){return(Q().networks??[]).length>5},get children(){return Y(iJ,{top:"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100"})}})]}}),Y(M,{class:"h-[160] px-5 pt-5 flex-col bg-white",get children(){return[Y(V,{class:"text-base text-slate-500",children:"MODEL BACKEND"}),Y(V,{class:"pt-3 text-lg text-slate-900 font-bold",get children(){return n().model??"UNKNOWN"}}),Y(V,{class:"pt-3 text-base text-slate-600",get children(){return"FIRMWARE "+String(J().firmwareVersion??"0.1.0")+" · WORKSPACE FREE "+String(J().workspaceFree??"--")}})]}}),Y(M,{class:"h-[108] pt-7 flex-row gap-4",get children(){return[Y(M,{class:"w-[316] h-[80] items-center justify-center bg-slate-100",get children(){return Y(V,{class:"text-lg text-slate-900 font-bold",children:"FORGET WI-FI"})}}),Y(M,{class:"w-[340] h-[80] items-center justify-center bg-red-100",get children(){return Y(V,{class:"text-lg text-red-500 font-bold",children:"RESTART DEVICE"})}})]}})]}}),Y(I0,{})]}})}function HQ(){let J=()=>W1(),Q=()=>LJ()==="letters"?o4:n4,$=()=>J().type==="wifi"?"*".repeat(m().length):m();return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{get title(){return J().type==="wifi"?"WIFI PASSWORD":"NEW MESSAGE"}}),Y(M,{class:"h-[1052] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[270] px-[22] pt-6 bg-white",get children(){return Y(V,{get["class"](){return m()?"text-lg text-slate-900":"text-lg text-slate-400"},get children(){return $()||(J().type==="wifi"?"ENTER NETWORK PASSWORD...":"TYPE YOUR MESSAGE...")}})}}),Y(M,{class:"h-[86] px-1 flex-row items-center justify-between",get children(){return[Y(V,{class:"text-base text-slate-500",get children(){return String(m().length)+" / "+(J().type==="wifi"?"63":"256")+" CHARACTERS"}}),Y(M,{get["class"](){return BJ()==="clear"?"w-[132] h-[58] items-center justify-center bg-slate-300":"w-[132] h-[58] items-center justify-center bg-slate-100"},get children(){return Y(V,{class:"text-base text-slate-900 font-bold",children:"CLEAR"})}})]}}),Y(jJ,{get each(){return Q()},children:(Z,q)=>Y(M,{class:"h-[140] flex-row gap-2",get children(){return[Y(jJ,{get each(){return Z.split("")},children:(X)=>Y(M,{get["class"](){return BJ()==="char:"+X?"grow h-[120] items-center justify-center bg-slate-300":"grow h-[120] items-center justify-center bg-white"},get children(){return Y(V,{class:"text-xl text-slate-900 font-bold",get children(){return v(()=>!!z1())()?X.toUpperCase():X}})}})}),Y(ZJ,{get when(){return q()===2},get children(){return Y(M,{get["class"](){return BJ()==="delete"?"w-[104] h-[120] items-center justify-center bg-slate-300":"w-[104] h-[120] items-center justify-center bg-slate-100"},get children(){return Y(V,{class:"text-base text-slate-900 font-bold",children:"DEL"})}})}})]}})}),Y(M,{class:"h-[176] flex-row gap-2",get children(){return[Y(M,{get["class"](){return BJ()==="mode"?"w-[92] h-[156] items-center justify-center bg-slate-300":"w-[92] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(V,{class:"text-base text-slate-900 font-bold",get children(){return LJ()==="letters"?"123":"ABC"}})}}),Y(M,{get["class"](){return BJ()==="space"?"w-[300] h-[156] items-center justify-center bg-slate-300":"w-[300] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(V,{class:"text-base text-slate-900 font-bold",children:"SPACE"})}}),Y(M,{get["class"](){return BJ()==="shift"?"w-[144] h-[156] items-center justify-center bg-slate-300":"w-[144] h-[156] items-center justify-center bg-slate-100"},get children(){return Y(V,{class:"text-base text-slate-900 font-bold",get children(){return LJ()==="letters"?"SHIFT":". ?"}})}}),Y(M,{get["class"](){return BJ()==="submit"?"w-[112] h-[156] items-center justify-center bg-emerald-700":"w-[112] h-[156] items-center justify-center bg-emerald-500"},get children(){return Y(V,{class:"text-base text-slate-950 font-bold",get children(){return J().type==="wifi"?"JOIN":"SEND"}})}})]}})]}}),Y(M,{class:"h-[108] px-6 py-3 flex-col bg-slate-50",get children(){return Y(M,{get["class"](){return BJ()==="close"?"h-[84] items-center justify-center bg-slate-300":"h-[84] items-center justify-center bg-slate-100"},get children(){return Y(V,{class:"text-base text-slate-900 font-bold",children:"CLOSE KEYBOARD"})}})}})]}})}function jQ(){let J=()=>X1();return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"< FILE VIEWER"}),Y(M,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(V,{class:"text-lg text-slate-900 font-bold",get children(){return J()?.path??"NO FILE OPEN"}})}}),Y(M,{class:"w-[584] h-[900] px-5 pt-5 bg-slate-950",get children(){return Y(V,{class:"text-base text-slate-200",get children(){return J()?.page.text??""}})}}),Y(V,{class:"pt-3 text-base text-slate-500",get children(){return v(()=>!!J())()?"PAGE "+String(J().pageIndex+1)+" · SOURCE LINES "+String(J().page.startSourceLine+1)+"-"+String(J().page.lastSourceLine+1):"NO FILE OPEN"}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function KQ(){let J=()=>p4();return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return[Y(OJ,{title:"< MESSAGE READER"}),Y(M,{class:"h-[1168] px-6 pt-5 flex-col",get children(){return[Y(M,{class:"h-[82] px-4 justify-center bg-white",get children(){return Y(V,{class:"text-lg text-orange-600 font-bold",get children(){return J()?.author??"PI"}})}}),Y(M,{class:"w-[584] h-[900] px-5 pt-5 bg-white",get children(){return Y(V,{class:"text-xl text-slate-900",get children(){return(J()?.lines??[]).slice(V0(),V0()+m4).join(` +`)}})}}),Y(iJ,{top:"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100",bottom:"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100"})]}})]}})}function FQ(){return Y(M,{class:"flex-col w-full h-full bg-slate-50",get children(){return v(()=>f()==="chat")()?Y(zQ,{}):v(()=>f()==="files")()?Y(GQ,{}):v(()=>f()==="apps")()?Y(WQ,{}):v(()=>f()==="settings")()?Y(BQ,{}):v(()=>f()==="keyboard")()?Y(HQ,{}):v(()=>f()==="viewer")()?Y(jQ,{}):Y(KQ,{})}})}function MQ(J){B6(()=>{if(QQ(J),t(J),J==="files")O0()})}function $6(J,Q){let $=LJ()==="letters"?o4:n4,Z=[488,628,768];for(let q=0;q<3;q++){if(Q=Z[q]+120)continue;let X=$[q],W=(q===2?560:672)/X.length,U=Math.floor((J-24)/W);if(U>=0&&U=1164)return"close";if(J>=548&&Q>=402&&Q<=482)return"clear";let $=$6(J,Q);if($)return"char:"+$;if(J>=592&&Q>=768&&Q<=888)return"delete";if(Q<908||Q>1064)return null;if(J<=116)return"mode";if(J<=424)return"space";if(J<=576)return"shift";return"submit"}function RQ(J,Q){if(Q>=1164)return e(""),t($1()),"";if(J>=548&&Q>=402&&Q<=482)return e(""),"";let $=$6(J,Q);if($){let Z=LJ()==="letters"&&z1()?$.toUpperCase():$,q=W1().type==="wifi"?63:256;if(m().length=592&&Q>=768&&Q<=888)return e(m().slice(0,-1)),"";if(Q>=908&&Q<=1064){if(J<=116)d4(LJ()==="letters"?"numbers":"letters"),G1(!1);else if(J<=424){if(m())e(m()+" ")}else if(J<=576)if(LJ()==="letters")G1(!z1());else e(m()+(J<=500?".":"?"));else if(m().trim()){let Z=m().trim(),q=W1();if(e(""),d4("letters"),G1(!1),t($1()),q.type==="wifi")return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:Z});return JSON.stringify({type:"submitPrompt",prompt:Z})}}return""}h2(()=>Y(FQ,{})),queueMicrotask(()=>O0("",!0)),globalThis.PocketPiApp={tick(){return""},update(J){return JQ(JSON.parse(J)),""},pointerDown(J,Q){return s4(f()==="keyboard"?UQ(J,Q):null),""},pointerUp(){return s4(null),""},tap(J,Q){if(f()==="keyboard")return RQ(J,Q);if(f()==="viewer"){let $=X1();if(J<104&&Q<112)Y1(null),t("files");else if($&&J>=620&&Q>=170&&Q<=340)J6(-1);else if($&&J>=620&&Q>=920&&Q<=1100)J6(1);return""}if(f()==="reader"){if(J<104&&Q<112)c4(null),L0(0),t("chat");else if(J>=620&&Q>=170&&Q<=340)L0(Math.max(0,V0()-18));else if(J>=620&&Q>=920&&Q<=1100){let $=p4()?.lines.length??0;L0(Math.min(Math.max(0,$-m4),V0()+18))}return""}if(Q>=1172)return MQ(t4[Math.min(3,Math.floor(J/180))]),"";if(f()==="chat"){if(J>=620&&Q>=140&&Q<=272)l4(Z1()+2);else if(J>=620&&Q>=624&&Q<=756)l4(Math.max(0,Z1()-2));else if(J<610&&Q>=140&&Q<798){let $=Math.floor((Q-140)/340),Z=Q6()[$];if(Z){let q=Q>=140+$*340+160,X=q?Z.assistant:Z.user;c4({author:q?"PI":"YOU",lines:f4(X,n2,v4)}),L0(0),t("reader")}}else if(Q>=1070&&Q<=1150)i4({type:"prompt"}),e(""),t("keyboard");return""}if(f()==="files"){if(J<104&&Q<112&&VJ()){let $=VJ().split("/");$.pop();let Z=$.join("/");u4(Z),hJ(0),O0(Z)}else if(J>=620&&Q>=170&&Q<=340)hJ(Math.max(0,sJ()-4));else if(J>=620&&Q>=920&&Q<=1100)hJ(Math.min(Math.max(0,aJ().length-8),sJ()+4));else if(J<610&&Q>=190){let $=Math.floor((Q-190)/104),Z=aJ()[sJ()+$];if(Z){let q=qQ(VJ(),Z.name);if(Z.kind==="dir")u4(q),hJ(0),O0(q);else try{XQ("/workspace/"+q,l2(q,"utf8"))}catch(X){D0(X instanceof Error?X.message:String(X))}}}return""}if(f()==="apps"){let $=(n().apps??[])[Math.floor((Q-162)/166)];if(Q>=162&&$)return JSON.stringify({type:"navigate",app:$.id});return""}if(f()==="settings"){let $=n().settings?.wifi?.networks??[];if(J>=480&&Q>=126&&Q<=218)return JSON.stringify({type:"settings",command:"scan"});if(J>=620&&Q>=330&&Q<=462)a4(Math.max(0,rJ()-4));else if(J>=620&&Q>=650&&Q<=782)a4(Math.min(Math.max(0,$.length-5),rJ()+4));else if(J<610&&Q>=330&&Q<790){let Z=Math.floor((Q-330)/92),q=$[rJ()+Z];if(q){if(!q.secured)return JSON.stringify({type:"settings",command:"connect",ssid:q.ssid,password:""});i4({type:"wifi",ssid:q.ssid}),e(""),t("keyboard")}}else if(J<=340&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"forget"});else if(J>=356&&Q>=1010&&Q<=1090)return JSON.stringify({type:"settings",command:"restart"})}return""}}})(); diff --git a/apps/pi-agent/dist/app.pak b/apps/pi-agent/dist/app.pak index 607743036938509f11e7f94c45a7a3e18d4699c4..d5eac78ff74ed90e932597b3f613f79f9729d6b2 100644 GIT binary patch delta 19851 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 DAN6B{ delta 388 zcmX@mA+_Oyn5~O*fHxxp0|N&TD**8WAT|IB80=sLvKSa#i!O_R_;Q=TTm~)(#jvU1 zvT(peTXD&RPDX}&BSr=hpae{^t2JlSg^9W1fefz93~yF2FsK71IiWgN*XFGK@Rpe& zK#h^X07*Q)JZGhY2rEO&LUtH^dA_MdE{9-m=afE^u$O@+aEoIZ*{-l`gIwKoX0s~7$`1Z}EY!ldd zft*(nJV5;*k59i-!=}Xl9|#zM;t+G0winm3 Date: Wed, 12 Aug 2026 16:39:47 +0800 Subject: [PATCH 23/24] refactor(agentos): enforce app firmware boundaries --- .github/workflows/ci.yml | 6 + ARCHITECTURE.md | 3 + Cargo.lock | 1 + README.md | 19 +- apps/README.md | 3 +- apps/_shared/text.ts | 2 +- apps/_shared/ui.tsx | 23 +- apps/exa/agent-app.json | 9 - apps/exa/app.tsx | 41 -- apps/exa/data-action.ts | 3 +- apps/exa/dist/app.js | 11 +- apps/exa/dist/app.pak | Bin 280512 -> 280368 bytes apps/exa/dist/data-action.js | 6 +- apps/pi-agent/dist/app.js | 2 +- apps/pi-agent/dist/app.pak | Bin 427072 -> 426944 bytes apps/robinhood/TOOLS.md | 3 +- apps/robinhood/agent-app.json | 9 - apps/robinhood/app.tsx | 30 -- apps/robinhood/dist/app.js | 8 +- apps/robinhood/dist/app.pak | Bin 281920 -> 281776 bytes apps/robinhood/pocket.json | 2 +- crates/pocket-pi-agentos/src/lib.rs | 553 +++++++++++++-------- crates/pocket-pi-app-pack/Cargo.toml | 3 +- crates/pocket-pi-app-pack/build.rs | 4 +- crates/pocket-pi-app-pack/src/lib.rs | 35 +- crates/pocket-pi-app-pack/tests/runtime.rs | 35 +- docs/agentos-architecture.md | 78 +-- docs/esp32-p4-port.md | 3 +- docs/pocket-pi-design-system.md | 8 +- firmware/esp32-p4/Cargo.lock | 1 - firmware/esp32-p4/sdkconfig.defaults | 9 + firmware/esp32-p4/src/agentos_main.rs | 9 +- firmware/esp32-p4/src/app_services.rs | 145 ++++-- firmware/esp32-p4/src/main.rs | 19 +- firmware/esp32-p4/src/transport/uart.rs | 2 - hosts/esp32-p4-sim/src/main.rs | 224 +++++---- 36 files changed, 751 insertions(+), 558 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 935d68b..0275464 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,6 +22,9 @@ jobs: rustup component add clippy rustup default stable + - name: Bun + uses: oven-sh/setup-bun@v2 + - name: Cache cargo uses: actions/cache@v4 with: @@ -41,3 +44,6 @@ jobs: - name: Test run: cargo test --workspace + + - name: App text behavior tests + run: bun test apps/_shared/text.test.ts diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 429ead8..7b49251 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -14,6 +14,8 @@ The authoritative detailed design is - `crates/pocket-pi-agentos` owns App catalog, runtime lifecycle, foreground selection, schedules, App Tool routing, and App-scoped FS/SQLite mounts. +- `crates/pocket-pi-app-pack` composes the build-selected App artifacts without + moving their product logic into the AgentOS runtime or host adapters. - `crates/pocket-pi-embedded` provides the bounded JavaScript Agent Loop bridge. In AgentOS hosts, the loop is loaded from the Pi Agent System App release into the same PocketJS Guest as its Root View. @@ -45,6 +47,7 @@ top-level `/workspace` and cross-App Tool Registry. ```text apps/ PocketJS System/ordinary App sources and bundles crates/pocket-pi-agentos/ App Supervisor and AgentOS contracts +crates/pocket-pi-app-pack/ build-selected embedded App composition crates/pocket-pi-embedded/ embedded pi-agent-core bridge and host traits crates/pocket-pi-tools/ native workspace/shell/time/schedule Tools crates/pocket-pi-protocols/ provider codecs diff --git a/Cargo.lock b/Cargo.lock index b64c195..a437427 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1978,6 +1978,7 @@ name = "pocket-pi-app-pack" version = "0.1.0" dependencies = [ "anyhow", + "pocket-db", "pocket-pi-agentos", "pocket-pi-embedded", "serde_json", diff --git a/README.md b/README.md index f93c8b9..001d12b 100644 --- a/README.md +++ b/README.md @@ -164,8 +164,10 @@ Backends belong to their host composition, not to the Agent core: | ESP32 simulator | local Codex, OpenAI, OpenRouter, Anthropic, DeepSeek V4 | | Physical ESP32-P4 | UART to Mac Codex or Claude Code; wireless OpenAI, OpenRouter, Anthropic or DeepSeek V4 | -`UartBackend` and `WirelessBackend` expose the same streaming model boundary to -the embedded Agent. Provider request/streaming codecs live in +`UartBackend` and `WirelessBackend` implement the same model-completion +contract. Wireless providers may emit progress events internally; the current +UART bridge coalesces provider chunks into one final framed result before it +reaches the device. Provider request/streaming codecs live in `pocket-pi-protocols`; serial framing, desktop CLIs and ESP-IDF HTTPS stay in their platform layers. @@ -195,7 +197,8 @@ memory and can create or revise its own recurring schedules. The shared PocketJS device UI includes: -- Chat with streamed replies, recent-turn history and a full-message reader; +- Chat with provider-dependent incremental replies, recent-turn history and a + full-message reader; - Files with workspace metadata, file viewing and scrolling; - Settings with Wi-Fi scanning, selection and password entry; - touch keyboard and next-schedule status. @@ -229,9 +232,10 @@ and [docs/esp32-p4-port.md](docs/esp32-p4-port.md) for board-specific details. ## Current validation -On **2026-08-11**, the embedded-only workspace completed 28 tests with no -failures, passed workspace Clippy with warnings denied, and built the ESP32-P4 -simulator with none, Exa-only, Robinhood-only and combined App catalogs. +On **2026-08-12**, the embedded-only workspace completed 30 Rust tests and 3 +App text behavior tests with no failures, passed workspace Clippy with warnings +denied, and built the ESP32-P4 simulator with none, Exa-only, Robinhood-only and +combined App catalogs. Physical firmware, boot, Wi-Fi/DHCP, provider calls and unattended memory pressure remain separate evidence tiers. A successful simulator build is not a @@ -241,10 +245,11 @@ substitute for fresh physical-board acceptance. ```sh cargo test --workspace +bun test apps/_shared/text.test.ts cargo clippy --workspace --all-targets -- -D warnings ``` -CI runs the workspace build, tests and clippy checks. LCD scanout, touch, +CI runs the workspace build, Rust/App behavior tests and clippy checks. LCD scanout, touch, LittleFS, Wi-Fi/NVS, memory pressure and real UART/wireless behavior still require physical-board acceptance. diff --git a/apps/README.md b/apps/README.md index 92b88da..a34b27e 100644 --- a/apps/README.md +++ b/apps/README.md @@ -2,7 +2,8 @@ Each directory is one independently versioned PocketJS App source. The checked in `dist/app.js` and `dist/app.pak` files are target artifacts embedded into the -firmware as the recovery release, then seeded into `/workspace` on boot. +firmware as the built-in release, then seeded into `/workspace` on boot. This +is not yet a signed install, rollback, or recovery-UI mechanism. - `pi-agent`: the privileged Root View; its filesystem mount is `/workspace`. - `robinhood`: curated MCP tools, `refreshPortfolio` AppTask, SQLite and View. diff --git a/apps/_shared/text.ts b/apps/_shared/text.ts index db68da4..472a175 100644 --- a/apps/_shared/text.ts +++ b/apps/_shared/text.ts @@ -3,7 +3,7 @@ import { getOps } from "@pocketjs/framework"; // Dynamic App text is not visible to PocketJS's bundle-time font subsetter. // Keep common English prose punctuation in every bundle that imports this // module so model/provider text does not fall back to missing-glyph boxes. -export const DYNAMIC_TEXT_GLYPHS = "‘’“”–—…•"; +const DYNAMIC_TEXT_GLYPHS = "‘’“”–—…•"; const PREVIEW_SOURCE_CHARACTERS = 512; diff --git a/apps/_shared/ui.tsx b/apps/_shared/ui.tsx index 9867aab..f66e2c8 100644 --- a/apps/_shared/ui.tsx +++ b/apps/_shared/ui.tsx @@ -3,35 +3,14 @@ import { Text, View } from "@pocketjs/framework/components"; // Pi Design v0.2. These are product-wide visual contracts built only from // PocketJS public primitives. App data, navigation and side effects stay with // the consuming App. -export const type = { +const type = { appTitle: "text-2xl text-white font-bold", pageTitle: "text-2xl text-slate-950 font-bold", heading: "text-xl text-slate-900 font-bold", label: "text-base text-slate-600 font-bold", - body: "text-lg text-slate-900", - bodyStrong: "text-lg text-slate-900 font-bold", - caption: "text-base text-slate-500", captionStrong: "text-base text-slate-500 font-bold", } as const; -export const space = { - screenX: "px-6", - card: "px-6 py-5", - stack: "gap-4", -} as const; - -// Generic containers with arbitrary children remain recipes instead of -// wrappers: this keeps the Solid/PocketJS native tree literal and predictable. -export const surface = { - card: "rounded-xl shadow bg-white border-slate-100", - selectedCard: "rounded-xl shadow bg-emerald-100 border-emerald-500", - row: "bg-white", - muted: "bg-slate-100", - shell: "bg-slate-950", -} as const; - -export type Tone = "neutral" | "info" | "success" | "warning" | "danger"; - export const statusBadge = { neutral: { surface: "px-3 py-2 rounded-lg bg-slate-100", text: "text-base text-slate-600 font-bold" }, info: { surface: "px-3 py-2 rounded-lg bg-indigo-100", text: "text-base text-indigo-700 font-bold" }, diff --git a/apps/exa/agent-app.json b/apps/exa/agent-app.json index 04aaee3..7cb54df 100644 --- a/apps/exa/agent-app.json +++ b/apps/exa/agent-app.json @@ -129,15 +129,6 @@ "required": ["url"], "additionalProperties": false } - }, - { - "name": "research.storage_status", - "description": "Return compact local SQLite counts, space usage, the 7-day retention policy, and latest search status without contacting Exa.", - "parameters": { - "type": "object", - "properties": {}, - "additionalProperties": false - } } ], "tasks": [], diff --git a/apps/exa/app.tsx b/apps/exa/app.tsx index 18bb8c8..4dce417 100644 --- a/apps/exa/app.tsx +++ b/apps/exa/app.tsx @@ -78,38 +78,6 @@ function loadView(revision: number) { } } -function storageStatus(): { text: string; details: any } { - const pageSize = Number((db.query("PRAGMA page_size").get() as unknown as { page_size?: number } | null)?.page_size ?? 0); - const pageCount = Number((db.query("PRAGMA page_count").get() as unknown as { page_count?: number } | null)?.page_count ?? 0); - const freelistCount = Number((db.query("PRAGMA freelist_count").get() as unknown as { freelist_count?: number } | null)?.freelist_count ?? 0); - const schemaVersion = Number((db.query("PRAGMA user_version").get() as unknown as { user_version?: number } | null)?.user_version ?? 0); - const searches = schemaVersion === DB_SCHEMA_VERSION - ? Number((db.query("SELECT COUNT(*) AS count FROM searches").get() as unknown as { count?: number } | null)?.count ?? 0) - : 0; - const latestSearch = schemaVersion === DB_SCHEMA_VERSION ? db.query(` - SELECT id,searched_at,status,result_count,error - FROM searches ORDER BY id DESC LIMIT 1 - `).get() : null; - const details = { - database: "exa.sqlite", - schemaVersion, - expectedSchemaVersion: DB_SCHEMA_VERSION, - retentionDays: RETENTION_DAYS, - searches, - allocatedBytes: pageSize * pageCount, - reusableBytes: pageSize * freelistCount, - latestSearch, - }; - const latest = latestSearch as null | { id?: number; status?: string; result_count?: number }; - const latestText = latest - ? ` Latest #${latest.id ?? "?"}: ${latest.status ?? "unknown"}, ${latest.result_count ?? 0} results.` - : " No searches yet."; - return { - text: `Exa storage (schema ${schemaVersion}/${DB_SCHEMA_VERSION}): ${searches} searches; ${RETENTION_DAYS}-day retention; ${details.allocatedBytes} bytes allocated (${details.reusableBytes} reusable).${latestText}`, - details, - }; -} - function Exa() { return ( @@ -168,15 +136,6 @@ mount(() => ); loadView(revision); return ""; }, - invokeTool(name: string) { - try { - const value = name === "research.storage_status" ? storageStatus() - : (() => { throw new Error("Data-writing tools run in the background App Data Action"); })(); - return JSON.stringify({ text: value.text, details: value.details, isError: false }); - } catch (error) { - return JSON.stringify({ text: error instanceof Error ? error.message : String(error), isError: true }); - } - }, tap(x: number, y: number) { if (y < 112 && x < 100) return JSON.stringify({ type: "navigate", app: "pi-agent" }); if (x >= 620 && y >= 294 && y <= 426) scrollHistory(-1); diff --git a/apps/exa/data-action.ts b/apps/exa/data-action.ts index 7e16c2a..4a50518 100644 --- a/apps/exa/data-action.ts +++ b/apps/exa/data-action.ts @@ -9,7 +9,6 @@ if (handle < 0) throw new Error("open exa.sqlite"); const SCHEMA_VERSION = 5; const RETENTION_DAYS = 7; const RETENTION_SECONDS = RETENTION_DAYS * 24 * 60 * 60; -const HTTP_TIMEOUT_MS = 60_000; function dbError(): string { return String(nativeDb.lastError(handle) || "SQLite operation failed"); } function exec(sql: string): void { if (nativeDb.exec(handle, sql) !== 0) throw new Error(dbError()); } @@ -49,7 +48,7 @@ async function post(path: "/search" | "/contents", body: any): Promise { method: "POST", headers: { accept: "application/json", "content-type": "application/json" }, body: JSON.stringify(body), - timeoutMs: HTTP_TIMEOUT_MS, + timeoutMs: (globalThis as any).app.remainingMs(), maxBytes: 96 * 1024, }); const value = await response.json(); diff --git a/apps/exa/dist/app.js b/apps/exa/dist/app.js index d50eb34..ff68885 100644 --- a/apps/exa/dist/app.js +++ b/apps/exa/dist/app.js @@ -1,9 +1,6 @@ -(()=>{var MJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return r0(this.context.count)},getNextContextId(){return r0(this.context.count++)}};function r0(J){let Q=String(J),$=Q.length-1;return MJ.context.id+($?String.fromCharCode(96+$):"")+Q}function o0(J){MJ.context=J}function b4(){return{...MJ.context,id:MJ.getNextContextId(),count:0}}var x4=!1,h4=(J,Q)=>J===Q,B0=Symbol("solid-proxy"),f4=typeof Proxy==="function",g4=Symbol("solid-track"),A2=Symbol("solid-dev-component"),vJ={equals:h4},n0=null,T4=X1,N=1,IJ=2,t0={owned:null,cleanups:null,context:null,owner:null},O=null,B=null,AJ=null,VJ=null,k=null,S=null,f=null,mJ=0;function uJ(J,Q){let $=k,Z=O,X=J.length===0,W=Q===void 0?Z:Q,Y=X?t0:{owned:null,cleanups:null,context:W?W.context:null,owner:W},j=X?J:()=>J(()=>r(()=>o(Y)));O=Y,k=null;try{return i(j,!0)}finally{k=$,O=Z}}function WJ(J,Q){Q=Q?Object.assign({},vJ,Q):vJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return Q1($,X)};return[J1.bind($),Z]}function a(J,Q,$){let Z=Z1(J,Q,!1,N);if(AJ&&B&&B.running)S.push(Z);else lJ(Z)}function PJ(J,Q,$){$=$?Object.assign({},vJ,$):vJ;let Z=Z1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,AJ&&B&&B.running)Z.tState=N,S.push(Z);else lJ(Z);return J1.bind(Z)}function r(J){if(!VJ&&k===null)return J();let Q=k;k=null;try{if(VJ)return VJ.untrack(J);return J()}finally{k=Q}}function H0(J){if(O===null);else if(O.cleanups===null)O.cleanups=[J];else O.cleanups.push(J);return J}function N4(J){if(B&&B.running)return J(),B.done;let Q=k,$=O;return Promise.resolve().then(()=>{k=Q,O=$;let Z;if(AJ||E4)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return i(J,!1),k=O=null,Z?Z.done:void 0})}var[S2,e0]=WJ(!1),E4;function J1(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===N)lJ(this);else{let Q=S;S=null,i(()=>cJ(this),!1),S=Q}if(k){let Q=this.observers;if(!Q||Q[Q.length-1]!==k){let $=Q?Q.length:0;if(!k.sources)k.sources=[this],k.sourceSlots=[$];else k.sources.push(this),k.sourceSlots.push($);if(!Q)this.observers=[k],this.observerSlots=[k.sources.length-1];else Q.push(k),this.observerSlots.push(k.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function Q1(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)i(()=>{for(let X=0;X1e6)throw S=[],Error()},!1)}return Q}function lJ(J){if(!J.fn)return;o(J);let Q=mJ;if($1(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{i(()=>{B&&(B.running=!0),k=O=J,$1(J,J.tValue,Q),k=O=null},!1)})}function $1(J,Q,$){let Z,X=O,W=k;k=O=J;try{Z=J.fn(Q)}catch(Y){if(J.pure)if(B&&B.running)J.tState=N,J.tOwned&&J.tOwned.forEach(o),J.tOwned=void 0;else J.state=N,J.owned&&J.owned.forEach(o),J.owned=null;return J.updatedAt=$+1,U0(Y)}finally{k=W,O=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)Q1(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function Z1(J,Q,$,Z=N,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:O,context:O?O.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(O===null);else if(O!==t0)if(B&&B.running&&O.pure)if(!O.tOwned)O.tOwned=[W];else O.tOwned.push(W);else if(!O.owned)O.owned=[W];else O.owned.push(W);if(VJ&&W.fn){let Y=W.fn,[j,U]=WJ(void 0,{equals:!1}),V=VJ.factory(Y,U);H0(()=>V.dispose());let w,G=()=>N4(U).then(()=>{if(w)w.dispose(),w=void 0});W.fn=(I)=>{if(j(),B&&B.running){if(!w)w=VJ.factory(Y,G);return w.track(I)}return V.track(I)}}return W}function K0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===IJ)return cJ(J);if(J.suspense&&r(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===N)lJ(J);else if((Q?J.tState:J.state)===IJ){let X=S;S=null,i(()=>cJ(J,$[0]),!1),S=X}}}function i(J,Q){if(S)return J();let $=!1;if(!Q)S=[];if(f)$=!0;else f=[];mJ++;try{let Z=J();return v4($),Z}catch(Z){if(!$)f=null;S=null,U0(Z)}}function v4(J){if(S){if(AJ&&B&&B.running)m4(S);else X1(S);S=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;f.push.apply(f,B.effects),Q=B.resolve;for(let W of f)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,i(()=>{for(let W of X)o(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let Y=0,j=W.owned.length;YT4($),!1);if(Q)Q()}function X1(J){for(let Q=0;Q{Z.delete($),i(()=>{B.running=!0,K0($)},!1),B&&(B.running=!1)})}}function cJ(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)o(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)q1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)o(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function q1(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return H0(()=>z1(W)),()=>{let U=J()||[],V=U.length,w,G;return U[g4],r(()=>{let b,h,c,XJ,HJ,H,F,z,M;if(V===0){if(Y!==0)z1(W),W=[],Z=[],X=[],Y=0,j&&(j=[]);if($.fallback)Z=[l4],X[0]=uJ((L)=>{return W[0]=L,$.fallback()}),Y=1}else if(Y===0){X=Array(V);for(G=0;G=H&&z>=H&&Z[F]===U[z];F--,z--)c[z]=X[F],XJ[z]=W[F],j&&(HJ[z]=j[F]);b=new Map,h=Array(z+1);for(G=z;G>=H;G--)M=U[G],w=b.get(M),h[G]=w===void 0?-1:w,b.set(M,G);for(w=H;w<=F;w++)if(M=Z[w],G=b.get(M),G!==void 0&&G!==-1)c[G]=X[w],XJ[G]=W[w],j&&(HJ[G]=j[w]),G=h[G],b.set(M,G);else W[w]();for(G=H;GJ(Q||{}));return o0($),Z}}return r(()=>J(Q||{}))}function pJ(){return!0}var d4={get(J,Q,$){if(Q===B0)return $;return J.get(Q)},has(J,Q){if(Q===B0)return!0;return J.has(Q)},set:pJ,deleteProperty:pJ,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:pJ,deleteProperty:pJ}},ownKeys(J){return J.keys()}};function M0(J){return!(J=typeof J==="function"?J():J)?{}:J}function s4(){for(let J=0,Q=this.length;J=0;j--){let U=M0(J[j])[Y];if(U!==void 0)return U}},has(Y){for(let j=J.length-1;j>=0;j--)if(Y in M0(J[j]))return!0;return!1},keys(){let Y=[];for(let j=0;j=0;Y--){let j=J[Y];if(!j)continue;let U=Object.getOwnPropertyNames(j);for(let V=U.length-1;V>=0;V--){let w=U[V];if(w==="__proto__"||w==="constructor")continue;let G=Object.getOwnPropertyDescriptor(j,w);if(!Z[w])Z[w]=G.get?{enumerable:!0,configurable:!0,get:s4.bind($[w]=[G.get.bind(j)])}:G.value!==void 0?G:void 0;else{let I=$[w];if(I){if(G.get)I.push(G.get.bind(j));else if(G.value!==void 0)I.push(()=>G.value)}}}}let X={},W=Object.keys(Z);for(let Y=W.length-1;Y>=0;Y--){let j=W[Y],U=Z[j];if(U&&U.get)Object.defineProperty(X,j,U);else X[j]=U?U.value:void 0}return X}var a4=(J)=>`Stale read from <${J}>.`;function r4(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return PJ(c4(()=>J.each,J.children,Q||void 0))}function o4(J){let Q=J.keyed,$=PJ(()=>J.when,void 0,void 0),Z=Q?$:PJ($,void 0,{equals:(X,W)=>!X===!W});return PJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?r(()=>W(Q?X:()=>{if(!r(Z))throw a4("Show");return $()})):W}return J.fallback},void 0,void 0)}var n4=(J)=>PJ(()=>J());function t4({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:Y,getParentNode:j,getFirstChild:U,getNextSibling:V}){function w(H,F,z,M){if(z!==void 0&&!M)M=[];if(typeof F!=="function")return G(H,F,M,z);a((L)=>G(H,F(),L,z),M)}function G(H,F,z,M,L){while(typeof z==="function")z=z();if(F===z)return z;let C=typeof F,D=M!==void 0;if(C==="string"||C==="number"){if(C==="number")F=F.toString();if(D){let P=z[0];if(P&&$(P))Z(P,F);else P=Q(F);z=h(H,z,M,P)}else if(z!==""&&typeof z==="string")Z(U(H),z=F);else h(H,z,M,Q(F)),z=F}else if(F==null||C==="boolean")z=h(H,z,M);else if(C==="function")return a(()=>{let P=F();while(typeof P==="function")P=P();z=G(H,P,z,M)}),()=>z;else if(Array.isArray(F)){let P=[];if(I(P,F,L))return a(()=>z=G(H,P,z,M,!0)),()=>z;if(P.length===0){let kJ=h(H,z,M);if(D)return z=kJ}else if(Array.isArray(z))if(z.length===0)c(H,P,M);else b(H,z,P);else if(z==null||z==="")c(H,P);else b(H,D&&z||[U(H)],P);z=P}else{if(Array.isArray(z)){if(D)return z=h(H,z,M,F);h(H,z,null,F)}else if(z==null||z===""||!U(H))X(H,F);else XJ(H,F,U(H));z=F}return z}function I(H,F,z){let M=!1;for(let L=0,C=F.length;Lp-P){let I2=F[D];while(P=0;D--){let P=F[D];if(L!==P){let kJ=j(P)===H;if(!C&&!D)kJ?XJ(H,L,P):X(H,L,z);else kJ&&W(H,P)}else C=!0}}else X(H,L,z);return[L]}function c(H,F,z){for(let M=0,L=F.length;Mz.children=G(H,F.children,z.children));return a(()=>F.ref&&F.ref(H)),a(()=>{for(let L in F){if(L==="children"||L==="ref")continue;let C=F[L];if(C===z[L])continue;Y(H,L,C,z[L]),z[L]=C}}),z}return{render(H,F){let z;return uJ((M)=>{z=M,w(F,H())}),z},insert:w,spread(H,F,z){if(typeof F==="function")a((M)=>HJ(H,F(),M,z));else HJ(H,F,void 0,z)},createElement:J,createTextNode:Q,insertNode:X,setProp(H,F,z,M){return Y(H,F,z,M),z},mergeProps:j1,effect:a,memo:n4,createComponent:i4,use(H,F,z){return r(()=>H(F,z))}}}function e4(J){let Q=t4(J);return Q.mergeProps=j1,Q}var G1=480,F1=272,qJ={view:0,text:1,image:2},J6=1,Q6=-1,$6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},K={f32:0,color:1,int:2},Z6={width:K.f32,height:K.f32,minW:K.f32,minH:K.f32,maxW:K.f32,maxH:K.f32,paddingT:K.f32,paddingR:K.f32,paddingB:K.f32,paddingL:K.f32,marginT:K.f32,marginR:K.f32,marginB:K.f32,marginL:K.f32,gap:K.f32,flexDir:K.int,justify:K.int,align:K.int,grow:K.f32,shrink:K.f32,basis:K.f32,flexWrap:K.int,posType:K.int,insetT:K.f32,insetR:K.f32,insetB:K.f32,insetL:K.f32,display:K.int,overflow:K.int,zIndex:K.int,hitPass:K.int,bgColor:K.color,gradFrom:K.color,gradTo:K.color,gradDir:K.int,radius:K.f32,opacity:K.f32,borderColor:K.color,borderWidth:K.f32,shadow:K.int,bevelOuterLight:K.color,bevelOuterDark:K.color,bevelInnerLight:K.color,bevelInnerDark:K.color,bevelWidth:K.f32,textColor:K.color,fontSlot:K.int,textAlign:K.int,lineHeight:K.f32,tracking:K.f32,translateX:K.f32,translateY:K.f32,scale:K.f32,rotate:K.f32,scaleX:K.f32,scaleY:K.f32,originX:K.f32,originY:K.f32,rotateX:K.f32,rotateY:K.f32,translateZ:K.f32,perspective:K.f32,arcStart:K.f32,arcSweep:K.f32,arcWidth:K.f32},E={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},X6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},W6=1,_2=2,y2=1,b2=2,x2=131072,h2=1,f2=262144,g2=1,T2=1,N2=1,E2=2,v2=4,m2=8,u2=16,l2=1,c2=2;function B1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var p2=1,q6=1263551300,Y6=1,z6=32,j6=24,m={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},YJ=32896,i2=0.016666666666666666;function H1(J){return J.__viewport??null}var V0=null;function G6(){return null}function K1(J,Q=G6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function F6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return K1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return K1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function B6(J){V0=J}function RJ(){if(!V0)throw Error("PocketJS: host not installed — call render() first");return V0}function x(){return RJ().ops}function H6(J){globalThis.frame=J}function K6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function U6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return B1($>>>16&255,$>>>8&255,$&255,255);return B1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function M6(J,Q){let $=Z6[J];if(typeof Q==="string"){if($===K.color)return U6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===K.color||$===K.int)return Q>>>0;return Q}var iJ=60,U1=[1,2,3,4,5,6,10,12,15,20,30,60],P0=iJ,n=-1,V6=0,SJ=[];function P6(J){if(!Number.isFinite(J)||J<=0)return iJ;let Q=U1[0];for(let $ of U1)if(Math.abs($-J)Q.at<=n).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;SJ=SJ.filter((Q)=>Q.at>n);for(let Q of J)Q.cb()}var R0=0.12,dJ=YJ;function L6(J){dJ=J===void 0?YJ:J&65535}function C6(){dJ=YJ}function P1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function k6(){return P1(dJ&255)}var R1=new Set,I6=0;function A6(){R1.clear(),I6=0,C6()}function S6(J){for(let Q of[...R1])Q(J)}var zJ=null,w1=null;function _6(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function D1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function _J(J){w0();let Q=zJ?zJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return w1.slice(Q.off,Q.off+Q.len)}var yJ=null,A=null,jJ=null,sJ=0,GJ=[],L0=[],C0=[];function C1(J){if(yJ=J,A=null,jJ=null,sJ=0,GJ.length=0,L0.length=0,C0.length=0,v){if(v.pressTarget=null,v.target=null,v.spriteDirty=!0,v.fresh=!0,v.vw=0,v.tex>=0){let Q=x();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(v.tex),v.tex=-1}}}function b6(J,Q){J.onPress=Q??void 0}function x6(J,Q){if(J.focusable=Q,S1(),!Q&&A===J)T(null)}function T(J){if(jJ&&jJ!==J)FJ(null);A=J,x().setFocus(J?J.id:0)}function FJ(J){if(jJ===J)return;let Q=x();if(jJ)Q.setActive?.(jJ.id,0);if(jJ=J,J)Q.setActive?.(J.id,1)}function O0(){return GJ.length>0?GJ[GJ.length-1]:yJ}function k0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;T($[X])}function g6(){if(!A)return null;let J=O0();if(J&&!u(A,J))return null;for(let Q=L0.length-1;Q>=0;Q--){let $=L0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function T6(J){let Q=g6();if(!Q)return!1;let $=[];if(k0(Q.node,$),$.length===0){if(A)T(null);return!0}let Z=Q.columns,X=A?$.indexOf(A):-1;if(X<0)return T(O1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)T($[W]);return!0}function N6(){if(!A)return null;let J=O0();if(J&&!u(A,J))return null;for(let Q=C0.length-1;Q>=0;Q--){let $=C0[Q];if(J&&!u($.node,J)&&!u(J,$.node))continue;if(u(A,$.node))return $}return null}function aJ(J){let Q=N6();if(Q&&Q.move(J))return;if(T6(J))return;f6(J)}function k1(){I1(A)}function I1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function rJ(J){FJ(J)}function E6(J){T(J),I1(J)}function u(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function I0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=I0(Q.children[X]);if(W){T(W);return}}let Z=Q;while(Z){if(Z.focusable){T(Z);return}Z=Z.parent}}T(null)}var v=null,A1=0;function S1(){A1++}var m6=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],u6=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function l6(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=m6[Q]>>$&1,X=u6[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,Y=X?255:0;J[W]=Y,J[W+1]=Y,J[W+2]=Y,J[W+3]=255}return J}function c6(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=_J($.image)}catch(Y){if(RJ().strict)throw Y;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):p6(Q,W),X<0&&RJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(l6(),16,16,X6.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function p6(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&W6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function oJ(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=oJ($[Z],Q);if(X)return X}return null}var nJ=null;function _1(J){nJ=J}function y1(J){let Q=GJ.length>0?GJ[GJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||u($,Q)))return $;$=$.parent}return null}function b1(J,Q,$){return y1(x1(J,Q,$))}function x1(J,Q,$){if($!==void 0)return $===0?null:oJ(nJ??yJ,$);let Z=x(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return oJ(nJ??yJ,X(J,Q))}function i6(J,Q,$){let Z=v,X=x();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let G=H1(X);if(Z.vw=G?G.w:G1,Z.vh=G?G.h:F1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)c6(Z,X);let W=O6()*Z.speed,Y=k6()*Z.speed;if(Z.dpadSpeed>0&&W===0&&Y===0){if(J&m.LEFT)W=-Z.dpadSpeed;if(J&m.RIGHT)W=Z.dpadSpeed;if(J&m.UP)Y=-Z.dpadSpeed;if(J&m.DOWN)Y=Z.dpadSpeed}let j=Z.fresh;if(W!==0||Y!==0){let G=R6()/60,I=Math.min(Math.max(Z.x+W*G,0),Z.vw-1),b=Math.min(Math.max(Z.y+Y*G,0),Z.vh-1);if(I!==Z.x||b!==Z.y)Z.x=I,Z.y=b,j=!0}if(j)X.setCursorPos(Z.x,Z.y);let U=(Q|$)&Z.button,V=A1;if(j||U!==0||V!==Z.gen)Z.gen=V,Z.fresh=!1,Z.target=y1(oJ(nJ??yJ,X.hitTest(Z.x,Z.y)));let w=Z.target;if(w!==A)T(w);if(Q&Z.button&&w)Z.pressTarget=w;if(Z.pressTarget){if(FJ(w===Z.pressTarget?Z.pressTarget:null),$&Z.button){let G=w===Z.pressTarget;if(Z.pressTarget=null,FJ(null),G)k1()}}else if($&Z.button)FJ(null);return!0}function d6(J){let Q=J&~sJ,$=sJ&~J;if(sJ=J,v&&i6(J,Q,$))return;if($&m.CIRCLE)FJ(null);if(Q===0)return;if(Q&m.DOWN)aJ("down");if(Q&m.RIGHT)aJ("right");if(Q&m.UP)aJ("up");if(Q&m.LEFT)aJ("left");if(Q&m.CIRCLE)FJ(A),k1()}var A0=null;function h1(J){A0=J}function wJ(){if(S1(),A0)A0()}function s6(J,Q){J.debugName=Q||void 0,wJ()}var t={id:J6,type:qJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},f1=Symbol.for("pocketjs.native-node"),S0=1,bJ=3,d=8,a6=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function tJ(J){return J.domAttrs??={}}function g1(J,Q){let $=J.domNodeType??(xJ(J)?bJ:S0),Z=$===bJ?eJ(J.text??""):$===d?n6(J.domData??""):l1(J.domTag??Q0(J));for(let X of Object.keys(J.domAttrs??{}))_0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)e(Z,g1(X,!0));return Z}function _0(J,Q,$){if(a6.has(Q)){LJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete tJ(J)[Q];else tJ(J)[Q]=$}function y0(J){if(J[f1]===!0)return J;return Object.defineProperty(J,f1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(xJ(J)?bJ:S0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else J0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else J0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===d)return J.domData??"";if(xJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===d)J.domData=Z;else if(xJ(J))J0(J,Z);else if(X8(J),Z)e(J,eJ(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return p1(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??Q0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===bJ)return"#text";if(J.domNodeType===d)return"#comment";return(J.domTag??Q0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){LJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===t)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return e(J,$),$},insertBefore($,Z){return e(J,$,Z??null),$},removeChild($){return hJ(J,$),$},replaceChild($,Z){return e(J,$,Z),hJ(J,Z),Z},cloneNode($=!1){return g1(J,!!$)},remove(){if(J.parent)hJ(J.parent,J)},setAttribute($,Z){_0(J,$,Z)},removeAttribute($){_0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}y0(t);var b0=null;function r6(J){b0=J}var x0={unknownClass:0,unknownTexture:0},T1=new Map;function N1(J,Q){T1.set(J,Q)}var E1=new Map;function v1(J,Q){E1.set(J,Q)}var DJ=new Set,o6=new Set;function m1(J){if(!J)return!1;if(o6.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return y0({id:x().createNode(Q),type:Q,parent:null,children:[],domNodeType:S0,domTag:J})}function eJ(J){let Q=x(),$=Q.createNode(qJ.text);return Q.setText($,J),y0({id:$,type:qJ.text,parent:null,children:[],text:J,domNodeType:bJ,domTag:"#text"})}function n6(J=""){let Q=eJ("");return Q.domNodeType=d,Q.domTag="#comment",Q.domData=J,Q}function J0(J,Q){x().replaceText(J.id,Q),J.text=Q,wJ()}function xJ(J){return J.type===qJ.text}function c1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function e(J,Q,$){let Z=x();if(c1(Q),DJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function hJ(J,Q){if(!Q)return;v6(Q),x().removeChild(J.id,Q.id),c1(Q),DJ.add(Q),wJ()}function t6(J){return J.parent??void 0}function e6(J){return J.children[0]}function p1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function J8(J,Q){let $=x();if(wJ(),Q==null||Q===""){$.setStyle(J.id,Q6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=b0?b0(Q):void 0;if(Z===void 0){if(RJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);x0.unknownClass++;return}$.setStyle(J.id,Z)}function Q8(J,Q){let $=x();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=T1.get(Q);if(Z===void 0){if(RJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);x0.unknownTexture++;return}$.setImage(J.id,Z)}function $8(J,Q){let $=x();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=E1.get(Q);if(Z===void 0){if(RJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);x0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function Z8(J,Q,$){let Z=x(),X=Q??{},W=$??{},Y=!1;for(let j in X){let U=X[j];if(W[j]===U)continue;let V=$6[j];if(V===void 0)throw Error(`PocketJS: unknown style prop '${j}' (see spec PROP)`);Z.setProp(J.id,V,M6(j,U)),Y=!0}if(Y)wJ()}function LJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete tJ(J)[Q];else tJ(J)[Q]=$;switch(Q){case"class":return J8(J,$),$;case"onPress":case"on:press":return b6(J,$),$;case"src":return Q8(J,$),$;case"sprite":return $8(J,$),$;case"style":return Z8(J,$,Z),$;case"focusable":return x6(J,!!$),$;case"debugName":return s6(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${Q0(J)}>`)}function X8(J){for(let Q of[...J.children])hJ(J,Q)}function Q0(J){for(let Q of Object.keys(qJ))if(qJ[Q]===J.type)return Q;return String(J.type)}function W8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}LJ(J,Q,$,Z)}var q8=e4({createElement:l1,createTextNode:eJ,replaceText:J0,isTextNode:xJ,setProperty:W8,insertNode(J,Q,$){e(J,Q,$)},removeNode(J,Q){hJ(J,Q)},getParentNode:t6,getFirstChild:e6,getNextSibling:p1}),{render:Y8,effect:d2,memo:s,createComponent:R,createElement:i1,insert:s2,spread:z8,mergeProps:a2,use:r2}=q8,o2={linear:E.Easing.Linear,in:E.Easing.EaseIn,out:E.Easing.EaseOut,"in-out":E.Easing.EaseInOut,"out-back":E.Easing.OutBack,spring:E.Easing.Spring,"spring-bouncy":E.Easing.SpringBouncy},j8=null;function d1(J){j8=J}function G8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function s1(J,Q){let $=i1(J);return z8($,Q,!1),G8(Q.nodeRef,$),$}function _(J){return s1("view",J)}function y(J){return s1("text",J)}var n2=new WeakMap,t2=new WeakMap,F8={}!==null?Object.freeze({...{}}):Object.freeze({}),e2=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:F8}),JQ=new Map,JJ=36000,h0=30,B8=30,q={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(JJ),tapeAnalog:new Uint16Array(JJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-h0,saidHello:!1,hostCalls:0};function H8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};q.ops=J,q.frame=0,q.tapeStart=0,q.tapeLen=0,q.tapeFirstFrame=0,q.tapeTouch=null,q.replayMasks=null,q.replayAnalog=null,q.replayTouch=null,q.paused=!1,q.stepQueued=0,q.inspectReportId=null,q.inspectAskedAt=0,q.treeDirty=!0,q.treeSentAt=-h0,q.saidHello=!1,q.hostCalls=0,q.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)q.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)q.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else q.transport=null;if(q.transport)h1(()=>{q.treeDirty=!0}),D8();else h1(null);globalThis.__pocketDevtools=C8}function K8(J){return(Q,$,Z,X)=>{if(q.hostCalls++,q.transport)M8(),R8();let W=Q,Y=$===void 0?YJ:$&65535,j=Z,U=X;if(q.replayMasks)if(q.replayAt0?$.slice(0,8):null;if(Z&&!q.tapeTouch)q.tapeTouch=Array(JJ).fill(null);if(q.tapeLen1||Q.length===1&&Q[0][0]!==YJ)J.analog=Q;if(q.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function o1(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,Y]of J)Z.fill(W,X,Math.min(X+Y,$)),X+=Y;return Z}function n1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return o1(J.masks,0,Q)}function t1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return o1(J.analog??[],YJ,Q)}function e1(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&q.hostCalls%Q!==0)return;if(!q.saidHello)q.saidHello=!0,g({t:"hello",app:q.app,host:L8(),frame:q.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` -`))if(X.trim())V8(X)}}function V8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=q.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),q.inspectReportId=Z||null,q.inspectAskedAt=q.hostCalls,!Z)g({t:"inspect",id:0,rect:null});break}case"pause":q.paused=!0,q.stepQueued=0,$?.debugPause?.(!0),f0();break;case"resume":q.paused=!1,$?.debugPause?.(!1),f0();break;case"step":q.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":J4();break;case"eval":{let Z=!0,X;try{X=$0((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}g({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":g({t:"tape",tape:r1()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}g({t:"devStats",frame:q.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())g({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:q.frame});else g({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))q.replayMasks=n1(Z),q.replayAnalog=Z.analog?t1(Z):null,q.replayTouch=Z.touch?e1(Z):null,q.replayAt=0;break}default:break}}function P8(){if(q.treeDirty&&q.frame-q.treeSentAt>=h0)J4();if(q.frame%B8===0)f0()}function R8(){let J=q.inspectReportId;if(J==null)return;let Q=q.ops;if(!Q?.debugRectXY||!Q.debugRectWH){q.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(q.hostCalls-q.inspectAskedAt>60)q.inspectReportId=null,g({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();q.inspectReportId=null,g({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function f0(){g({t:"stats",frame:q.frame,nodes:Z4(t),tapeLen:q.tapeLen,paused:q.paused})}function J4(){q.treeDirty=!1,q.treeSentAt=q.frame,g({t:"tree",frame:q.frame,root:$4(t)})}function w8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function g0(J,Q){if(Array.isArray(J)){for(let $ of J)g0($,Q);return}if(w8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)g0($,Q)}}function Q4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)g0(Z,Q)}function $4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(Q4(J,(X)=>{if(X.domNodeType===8)return;Z.push($4(X))}),Z.length)Q.k=Z;return Q}function Z4(J){let Q=1;return Q4(J,($)=>{Q+=Z4($)}),Q}function D8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{g({t:"log",level:$,args:X.map((W)=>$0(W))}),Z?.apply(Q,X)}}}function $0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?X4(W):JSON.stringify(X4(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((Y)=>$0(Y,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,Y])=>`${W}: ${$0(Y,Q+1)}`).join(", ")}}`}function X4(J){return J.length>200?J.slice(0,199)+"…":J}function L8(){let J=q.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var C8={get frame(){return q.frame},dumpTape:()=>r1(),replay:(J)=>{q.replayMasks=n1(J),q.replayAnalog=J.analog?t1(J):null,q.replayTouch=J.touch?e1(J):null,q.replayAt=0}},W4=new Map,T0=new Map;function q4(J){return J.trim().replace(/\s+/g," ")}function Y4(J){return J.split(" ").sort().join(" ")}var z4=-1;function O8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=q4(Q);W4.set(Z,$);let X=Y4(Z),W=T0.get(X);T0.set(X,W!==void 0&&W!==$?z4:$)}}function k8(J){let Q=q4(J),$=W4.get(Q);if($!==void 0)return $;let Z=T0.get(Y4(Q));return Z===z4?void 0:Z}var N0=9,I8=(1<{let X=($&S8)!==0,W=X?E0:N0,Y=X?_8:I8;return Object.freeze({id:$>>>(X?y8:A8)&255,x:$&Y,y:$>>>W&Y,hit:Q?.[Z]})}))}function x8(){return Z0}function h8(){Z0=v0}var j4=8,QJ=8,f8=3,g8=8,T8=6,N8=0.5,l=1,fJ=2,m0=4,BJ=8,CJ=[],G4=0,X0=0,$J=Array.from({length:j4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(QJ),histY:new Int16Array(QJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function E8(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function v8(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=x1(Q,$,Z.fact);let j=Z.hit;if(j)return E8(j,W)}let Y=X.rect?.();if(!Y)return!1;return Q>=Y.x&&Q=Y.y&&$=0;Y--){let j=CJ[Y];if(j.disposed)continue;if(G4>0&&!j.opts.allowWhenBlocked)continue;if(!v8(j,$,Z,W))continue;j.flags[J.slot]=l,J.owners.push(j)}for(let Y of J.owners)Y.opts.onDown?.(J)}function l8(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%QJ,J.histLenY||Z>Y))X.flags[J.slot]|=fJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&l)||W&(fJ|m0))continue;if(!X.opts.onLongPress)continue;let Y=Math.max(1,Math.round((X.opts.longPressSeconds??N8)*M1()));if(J.frames=0)CJ.splice($,1)},cancel(){if(!Q.disposed)H4(Q)},get panning(){for(let $ of $J)if($.used&&Q.flags[$.slot]&BJ)return!0;return!1}}}function s8(J){let Q=d8(J);return H0(()=>Q.dispose()),Q}function K4(){CJ.length=0,G4=0,X0=0;for(let J of $J)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function a8(){return s8({onDown:(J)=>{let Q=b1(J.x,J.y,J.hit);if(Q)rJ(Q)},onTap:(J)=>{rJ(null);let Q=b1(J.x,J.y,J.hit);if(Q)E6(Q)},onUp:()=>rJ(null),onCancel:()=>rJ(null)})}var r8=1,u0=new Map,W0=[];function o8(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function n8(){r8=1,u0.clear(),W0=[]}function t8(){if(W0.length===0)return;let J=W0;W0=[];for(let{id:Q,result:$}of J){let Z=u0.get(Q);if(!Z)continue;u0.delete(Q),o8()?.({t:"delivery",frame:V1(),id:Q,kind:Z.kind}),Z.onResult($)}}var U4=new Set;function e8(){if(U4.size===0)return;for(let J of U4)J()}var J2={"flex-col w-full h-full bg-slate-50":0,"relative grow px-6 pt-4 flex-col":1,"absolute left-[628] top-[16] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":2,"absolute left-[628] top-[742] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":3,"w-[584] h-[890] flex-col gap-[12]":4,"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":5,"w-[390] flex-col gap-2":6,"text-lg text-slate-900 font-bold":7,"text-base text-slate-500":8,"text-base text-indigo-600 font-bold":9,"absolute left-[24] top-[16] w-[672] h-[890] bg-slate-50":10,"h-[96]":11,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":12,"absolute inset-0 z-50 flex-col items-center justify-center":13,"absolute inset-0 bg-slate-950":14,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":15,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":16,"flex-row flex-wrap":17,grow:18,"text-2xl text-white font-bold":19,"text-2xl text-slate-950 font-bold":20,"text-xl text-slate-900 font-bold":21,"text-base text-slate-600 font-bold":22,"text-lg text-slate-900":23,"text-base text-slate-500 font-bold":24,"px-6":25,"px-6 py-5":26,"gap-4":27,"rounded-xl shadow bg-white border-slate-100":28,"rounded-xl shadow bg-emerald-100 border-emerald-500":29,"bg-white":30,"bg-slate-100":31,"bg-slate-950":32,"px-3 py-2 rounded-lg bg-slate-100":33,"px-3 py-2 rounded-lg bg-indigo-100":34,"text-base text-indigo-700 font-bold":35,"px-3 py-2 rounded-lg bg-emerald-100":36,"text-base text-emerald-700 font-bold":37,"px-3 py-2 rounded-lg bg-amber-100":38,"text-base text-amber-700 font-bold":39,"px-3 py-2 rounded-lg bg-red-100":40,"text-base text-red-500 font-bold":41,"w-[34] h-[34] rounded-lg bg-amber-400":42,"w-[34] h-[34] rounded-lg bg-red-500":43,"w-[34] h-[34] rounded-lg bg-slate-800":44,"w-[34] h-[34] rounded-lg bg-emerald-500":45,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":46,"flex-row items-center gap-4":47,"w-[34] text-2xl text-white font-bold":48,"w-[332] flex-col items-end gap-2":49,"text-base text-slate-300 font-bold":50,"text-base text-slate-400":51,"h-[166] px-6 pt-6 flex-col gap-3":52,"text-base text-orange-600 font-bold":53,"text-lg text-slate-600":54,"h-[44] px-1 flex-row items-center justify-between":55,"w-full h-full items-center justify-center rounded-xl bg-slate-200":56,"w-full h-full items-center justify-center rounded-xl bg-red-100":57,"w-full h-full items-center justify-center rounded-xl bg-slate-100":58,"w-full h-full items-center justify-center rounded-xl bg-orange-600":59,"text-lg text-slate-500 font-bold":60,"text-lg text-red-500 font-bold":61,"text-lg text-white font-bold":62,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":63,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":64,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":65,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":66,"text-2xl text-indigo-700 font-bold":67,"text-2xl text-slate-600 font-bold":68,"pt-7 text-2xl text-slate-900 font-bold":69,"pt-4 text-lg text-slate-500":70,"text-xl text-emerald-600 font-bold":71,"text-xl text-red-500 font-bold":72,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":73,"text-base text-red-300":74,"text-base text-slate-300":75,"text-base text-red-500":76,"w-full h-full px-6 flex-row items-center bg-slate-950":77,"w-full h-full flex-row items-center":78};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var Q2="ui:styles",$2="ui:font.",M4="ui:img.",V4="ui:sprite.";function Z2(){return globalThis.ui}function X2(J){if(J.__textures)return;for(let Q of D0(M4)){let $=_J(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)N1(Q.slice(M4.length),Z)}}function W2(J){if(J.__sprites)return;for(let Q of D0(V4)){let $=_J(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),Y=$[4],j=Z.getUint16(6,!0),U=Z.getUint16(8,!0),V=Z.getUint16(10,!0),w=J.uploadTexture($.subarray(16),X,W,Y);if(w>=0)v1(Q.slice(V4.length),{handle:w,frames:j,cols:U,step:V})}}function P4(J){let Q=i1("view");return LJ(Q,"style",J,void 0),Q}var q0=null,Y0=null;function q2(J,Q){if(!q0||!Y0)return;LJ(q0,"style",{width:J,height:Q,overflow:E.Overflow.Hidden},void 0),LJ(Y0,"style",{width:J,height:Q,posType:E.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=x();$.__viewport={w:J,h:Q}}function Y2(J,Q={}){let $=F6(Q.ops);if(B6($),r6(k8),Q.styles)O8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let I in Z)N1(I,Z[I]);let G=$.ops.__sprites;if(G)for(let I in G)v1(I,G[I])}if($.kind==="injected"||Z===void 0){if(Q.pak)L1(Q.pak);if(y6()){for(let G of D0())if(G===Q2)$.ops.loadStyles?.(_J(G));else if(G.startsWith($2))$.ops.loadFontAtlas?.(_J(G))}}let X=H1($.ops),W=X?.w??G1,Y=X?.h??F1,j=P4({width:W,height:Y,overflow:E.Overflow.Hidden}),U=P4({width:W,height:Y,posType:E.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});e(t,j),e(t,U),d1(U),q0=j,Y0=U,C1(j),_1(t),A6(),K4(),a8(),w6(),n8(),H8($.ops),H6(K8((G,I,b,h)=>{D6(),L6(I),b8(b,h),e8(),t8(),i8(),S6(G),d6(G),u1()}));let V=Y8(J,j),w=K6(q2);return()=>{w(),h8(),K4(),V(),C1(null),_1(null),d1(null),q0=null,Y0=null;for(let G of t.children.splice(0))G.parent=null,$.ops.destroyNode(G.id);u1()}}function z2(J,Q={}){let $=Q.ops??Z2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)L1(Q.pak);return X2($),W2($),Y2(J,{ops:$,styles:Q.styles??J2,pak:Q.pak})}var R4="$b",j2=9007199254740991,G2=":memory:",OJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function F2(J){let Q="";for(let $=0;$>2]+OJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2j2)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function K2(J){if(J!==null&&typeof J==="object")return B2(J[R4]);return J}function U2(J){if(Array.isArray(J))return JSON.stringify(J.map(w4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=w4(Z);return JSON.stringify(Q)}class l0{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,U2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=D4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(K2))}run(...J){let Q=this.execute(D4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function D4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class L4{statements=new Map;txDepth=0;constructor(J=G2){let Q=H2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new l0(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new l0(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let Y=J(...Q);return this.txDepth--,this.exec(X),Y}catch(Y){throw this.txDepth--,this.exec(W),Y}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var C4={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"},z0={neutral:{surface:"px-3 py-2 rounded-lg bg-slate-100",text:"text-base text-slate-600 font-bold"},info:{surface:"px-3 py-2 rounded-lg bg-indigo-100",text:"text-base text-indigo-700 font-bold"},success:{surface:"px-3 py-2 rounded-lg bg-emerald-100",text:"text-base text-emerald-700 font-bold"},warning:{surface:"px-3 py-2 rounded-lg bg-amber-100",text:"text-base text-amber-700 font-bold"},danger:{surface:"px-3 py-2 rounded-lg bg-red-100",text:"text-base text-red-500 font-bold"}};function M2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return R(_,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[R(_,{class:"flex-row items-center gap-4",get children(){return[s(()=>s(()=>!!J.back)()?R(y,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):R(_,{get["class"](){return Q()}})),R(y,{get["class"](){return C4.appTitle},get children(){return J.title}})]}}),R(_,{class:"w-[332] flex-col items-end gap-2",get children(){return[R(y,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),R(y,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function V2(J){return R(_,{class:"h-[166] px-6 pt-6 flex-col gap-3",get children(){return[R(y,{get["class"](){return J.tone==="info"?"text-base text-indigo-700 font-bold":"text-base text-orange-600 font-bold"},get children(){return J.eyebrow}}),R(y,{get["class"](){return C4.pageTitle},get children(){return J.title}}),R(y,{class:"text-lg text-slate-600",get children(){return J.description}})]}})}function P2(J){return R(_,{get["class"](){return J.compact?"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100"},get children(){return[s(()=>s(()=>!!J.icon)()?R(_,{get["class"](){return J.tone==="info"?"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100"},get children(){return R(y,{get["class"](){return J.tone==="info"?"text-2xl text-indigo-700 font-bold":"text-2xl text-slate-600 font-bold"},get children(){return J.icon}})}}):null),R(y,{get["class"](){return J.icon?"pt-7 text-2xl text-slate-900 font-bold":"text-lg text-slate-500 font-bold"},get children(){return J.title}}),s(()=>s(()=>!!J.detail)()?R(y,{class:"pt-4 text-lg text-slate-500",get children(){return J.detail}}):null)]}})}function R2(J){let Q=()=>J.dark?J.tone==="danger"?"text-base text-red-300":"text-base text-slate-300":J.tone==="danger"?"text-base text-red-500":"text-base text-slate-500";return R(_,{get["class"](){return J.dark?"w-full h-full px-6 flex-row items-center bg-slate-950":"w-full h-full flex-row items-center"},get children(){return R(y,{get["class"](){return Q()},get children(){return J.text}})}})}function w2(J){return[R(_,{get["class"](){return J.top},get children(){return R(y,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),R(_,{get["class"](){return J.bottom},get children(){return R(y,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var TJ=5,O4=7,NJ=10,c0=6,ZJ=new L4("exa"),[EJ,j0]=WJ([]),[k4,p0]=WJ(!1),[i0,G0]=WJ(0),[I4,d0]=WJ("SEARCH HISTORY IS LOCAL"),F0=-1,s0=!1;function D2(J){try{return JSON.parse(J)}catch{return null}}function L2(J){let Q=new Date(J*1000).toISOString();return Q.slice(0,10)+" · "+Q.slice(11,16)+" UTC"}function A4(J){return ZJ.query(` +(()=>{var MJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return s0(this.context.count)},getNextContextId(){return s0(this.context.count++)}};function s0(J){let Q=String(J),$=Q.length-1;return MJ.context.id+($?String.fromCharCode(96+$):"")+Q}function a0(J){MJ.context=J}function _4(){return{...MJ.context,id:MJ.getNextContextId(),count:0}}var y4=!1,b4=(J,Q)=>J===Q,G0=Symbol("solid-proxy"),h4=typeof Proxy==="function",x4=Symbol("solid-track"),k2=Symbol("solid-dev-component"),NJ={equals:b4},r0=null,f4=$1,N=1,kJ=2,o0={owned:null,cleanups:null,context:null,owner:null},O=null,B=null,IJ=null,UJ=null,k=null,S=null,f=null,EJ=0;function vJ(J,Q){let $=k,Z=O,X=J.length===0,W=Q===void 0?Z:Q,Y=X?o0:{owned:null,cleanups:null,context:W?W.context:null,owner:W},j=X?J:()=>J(()=>r(()=>o(Y)));O=Y,k=null;try{return i(j,!0)}finally{k=$,O=Z}}function XJ(J,Q){Q=Q?Object.assign({},NJ,Q):NJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return e0($,X)};return[t0.bind($),Z]}function a(J,Q,$){let Z=Q1(J,Q,!1,N);if(IJ&&B&&B.running)S.push(Z);else mJ(Z)}function VJ(J,Q,$){$=$?Object.assign({},NJ,$):NJ;let Z=Q1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,IJ&&B&&B.running)Z.tState=N,S.push(Z);else mJ(Z);return t0.bind(Z)}function r(J){if(!UJ&&k===null)return J();let Q=k;k=null;try{if(UJ)return UJ.untrack(J);return J()}finally{k=Q}}function F0(J){if(O===null);else if(O.cleanups===null)O.cleanups=[J];else O.cleanups.push(J);return J}function g4(J){if(B&&B.running)return J(),B.done;let Q=k,$=O;return Promise.resolve().then(()=>{k=Q,O=$;let Z;if(IJ||T4)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return i(J,!1),k=O=null,Z?Z.done:void 0})}var[I2,n0]=XJ(!1),T4;function t0(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===N)mJ(this);else{let Q=S;S=null,i(()=>lJ(this),!1),S=Q}if(k){let Q=this.observers;if(!Q||Q[Q.length-1]!==k){let $=Q?Q.length:0;if(!k.sources)k.sources=[this],k.sourceSlots=[$];else k.sources.push(this),k.sourceSlots.push($);if(!Q)this.observers=[k],this.observerSlots=[k.sources.length-1];else Q.push(k),this.observerSlots.push(k.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function e0(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)i(()=>{for(let X=0;X1e6)throw S=[],Error()},!1)}return Q}function mJ(J){if(!J.fn)return;o(J);let Q=EJ;if(J1(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{i(()=>{B&&(B.running=!0),k=O=J,J1(J,J.tValue,Q),k=O=null},!1)})}function J1(J,Q,$){let Z,X=O,W=k;k=O=J;try{Z=J.fn(Q)}catch(Y){if(J.pure)if(B&&B.running)J.tState=N,J.tOwned&&J.tOwned.forEach(o),J.tOwned=void 0;else J.state=N,J.owned&&J.owned.forEach(o),J.owned=null;return J.updatedAt=$+1,H0(Y)}finally{k=W,O=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)e0(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function Q1(J,Q,$,Z=N,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:O,context:O?O.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(O===null);else if(O!==o0)if(B&&B.running&&O.pure)if(!O.tOwned)O.tOwned=[W];else O.tOwned.push(W);else if(!O.owned)O.owned=[W];else O.owned.push(W);if(UJ&&W.fn){let Y=W.fn,[j,M]=XJ(void 0,{equals:!1}),V=UJ.factory(Y,M);F0(()=>V.dispose());let D,G=()=>g4(M).then(()=>{if(D)D.dispose(),D=void 0});W.fn=(I)=>{if(j(),B&&B.running){if(!D)D=UJ.factory(Y,G);return D.track(I)}return V.track(I)}}return W}function B0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===kJ)return lJ(J);if(J.suspense&&r(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===N)mJ(J);else if((Q?J.tState:J.state)===kJ){let X=S;S=null,i(()=>lJ(J,$[0]),!1),S=X}}}function i(J,Q){if(S)return J();let $=!1;if(!Q)S=[];if(f)$=!0;else f=[];EJ++;try{let Z=J();return N4($),Z}catch(Z){if(!$)f=null;S=null,H0(Z)}}function N4(J){if(S){if(IJ&&B&&B.running)E4(S);else $1(S);S=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;f.push.apply(f,B.effects),Q=B.resolve;for(let W of f)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,i(()=>{for(let W of X)o(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let Y=0,j=W.owned.length;Yf4($),!1);if(Q)Q()}function $1(J){for(let Q=0;Q{Z.delete($),i(()=>{B.running=!0,B0($)},!1),B&&(B.running=!1)})}}function lJ(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)o(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)X1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)o(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function X1(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return F0(()=>q1(W)),()=>{let M=J()||[],V=M.length,D,G;return M[x4],r(()=>{let b,x,c,ZJ,BJ,H,F,z,U;if(V===0){if(Y!==0)q1(W),W=[],Z=[],X=[],Y=0,j&&(j=[]);if($.fallback)Z=[m4],X[0]=vJ((L)=>{return W[0]=L,$.fallback()}),Y=1}else if(Y===0){X=Array(V);for(G=0;G=H&&z>=H&&Z[F]===M[z];F--,z--)c[z]=X[F],ZJ[z]=W[F],j&&(BJ[z]=j[F]);b=new Map,x=Array(z+1);for(G=z;G>=H;G--)U=M[G],D=b.get(U),x[G]=D===void 0?-1:D,b.set(U,G);for(D=H;D<=F;D++)if(U=Z[D],G=b.get(U),G!==void 0&&G!==-1)c[G]=X[D],ZJ[G]=W[D],j&&(BJ[G]=j[D]),G=x[G],b.set(U,G);else W[D]();for(G=H;GJ(Q||{}));return a0($),Z}}return r(()=>J(Q||{}))}function uJ(){return!0}var p4={get(J,Q,$){if(Q===G0)return $;return J.get(Q)},has(J,Q){if(Q===G0)return!0;return J.has(Q)},set:uJ,deleteProperty:uJ,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:uJ,deleteProperty:uJ}},ownKeys(J){return J.keys()}};function K0(J){return!(J=typeof J==="function"?J():J)?{}:J}function i4(){for(let J=0,Q=this.length;J=0;j--){let M=K0(J[j])[Y];if(M!==void 0)return M}},has(Y){for(let j=J.length-1;j>=0;j--)if(Y in K0(J[j]))return!0;return!1},keys(){let Y=[];for(let j=0;j=0;Y--){let j=J[Y];if(!j)continue;let M=Object.getOwnPropertyNames(j);for(let V=M.length-1;V>=0;V--){let D=M[V];if(D==="__proto__"||D==="constructor")continue;let G=Object.getOwnPropertyDescriptor(j,D);if(!Z[D])Z[D]=G.get?{enumerable:!0,configurable:!0,get:i4.bind($[D]=[G.get.bind(j)])}:G.value!==void 0?G:void 0;else{let I=$[D];if(I){if(G.get)I.push(G.get.bind(j));else if(G.value!==void 0)I.push(()=>G.value)}}}}let X={},W=Object.keys(Z);for(let Y=W.length-1;Y>=0;Y--){let j=W[Y],M=Z[j];if(M&&M.get)Object.defineProperty(X,j,M);else X[j]=M?M.value:void 0}return X}var d4=(J)=>`Stale read from <${J}>.`;function s4(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return VJ(l4(()=>J.each,J.children,Q||void 0))}function a4(J){let Q=J.keyed,$=VJ(()=>J.when,void 0,void 0),Z=Q?$:VJ($,void 0,{equals:(X,W)=>!X===!W});return VJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?r(()=>W(Q?X:()=>{if(!r(Z))throw d4("Show");return $()})):W}return J.fallback},void 0,void 0)}var r4=(J)=>VJ(()=>J());function o4({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:Y,getParentNode:j,getFirstChild:M,getNextSibling:V}){function D(H,F,z,U){if(z!==void 0&&!U)U=[];if(typeof F!=="function")return G(H,F,U,z);a((L)=>G(H,F(),L,z),U)}function G(H,F,z,U,L){while(typeof z==="function")z=z();if(F===z)return z;let C=typeof F,w=U!==void 0;if(C==="string"||C==="number"){if(C==="number")F=F.toString();if(w){let P=z[0];if(P&&$(P))Z(P,F);else P=Q(F);z=x(H,z,U,P)}else if(z!==""&&typeof z==="string")Z(M(H),z=F);else x(H,z,U,Q(F)),z=F}else if(F==null||C==="boolean")z=x(H,z,U);else if(C==="function")return a(()=>{let P=F();while(typeof P==="function")P=P();z=G(H,P,z,U)}),()=>z;else if(Array.isArray(F)){let P=[];if(I(P,F,L))return a(()=>z=G(H,P,z,U,!0)),()=>z;if(P.length===0){let OJ=x(H,z,U);if(w)return z=OJ}else if(Array.isArray(z))if(z.length===0)c(H,P,U);else b(H,z,P);else if(z==null||z==="")c(H,P);else b(H,w&&z||[M(H)],P);z=P}else{if(Array.isArray(z)){if(w)return z=x(H,z,U,F);x(H,z,null,F)}else if(z==null||z===""||!M(H))X(H,F);else ZJ(H,F,M(H));z=F}return z}function I(H,F,z){let U=!1;for(let L=0,C=F.length;Lp-P){let O2=F[w];while(P=0;w--){let P=F[w];if(L!==P){let OJ=j(P)===H;if(!C&&!w)OJ?ZJ(H,L,P):X(H,L,z);else OJ&&W(H,P)}else C=!0}}else X(H,L,z);return[L]}function c(H,F,z){for(let U=0,L=F.length;Uz.children=G(H,F.children,z.children));return a(()=>F.ref&&F.ref(H)),a(()=>{for(let L in F){if(L==="children"||L==="ref")continue;let C=F[L];if(C===z[L])continue;Y(H,L,C,z[L]),z[L]=C}}),z}return{render(H,F){let z;return vJ((U)=>{z=U,D(F,H())}),z},insert:D,spread(H,F,z){if(typeof F==="function")a((U)=>BJ(H,F(),U,z));else BJ(H,F,void 0,z)},createElement:J,createTextNode:Q,insertNode:X,setProp(H,F,z,U){return Y(H,F,z,U),z},mergeProps:Y1,effect:a,memo:r4,createComponent:c4,use(H,F,z){return r(()=>H(F,z))}}}function n4(J){let Q=o4(J);return Q.mergeProps=Y1,Q}var z1=480,j1=272,WJ={view:0,text:1,image:2},t4=1,e4=-1,J6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},K={f32:0,color:1,int:2},Q6={width:K.f32,height:K.f32,minW:K.f32,minH:K.f32,maxW:K.f32,maxH:K.f32,paddingT:K.f32,paddingR:K.f32,paddingB:K.f32,paddingL:K.f32,marginT:K.f32,marginR:K.f32,marginB:K.f32,marginL:K.f32,gap:K.f32,flexDir:K.int,justify:K.int,align:K.int,grow:K.f32,shrink:K.f32,basis:K.f32,flexWrap:K.int,posType:K.int,insetT:K.f32,insetR:K.f32,insetB:K.f32,insetL:K.f32,display:K.int,overflow:K.int,zIndex:K.int,hitPass:K.int,bgColor:K.color,gradFrom:K.color,gradTo:K.color,gradDir:K.int,radius:K.f32,opacity:K.f32,borderColor:K.color,borderWidth:K.f32,shadow:K.int,bevelOuterLight:K.color,bevelOuterDark:K.color,bevelInnerLight:K.color,bevelInnerDark:K.color,bevelWidth:K.f32,textColor:K.color,fontSlot:K.int,textAlign:K.int,lineHeight:K.f32,tracking:K.f32,translateX:K.f32,translateY:K.f32,scale:K.f32,rotate:K.f32,scaleX:K.f32,scaleY:K.f32,originX:K.f32,originY:K.f32,rotateX:K.f32,rotateY:K.f32,translateZ:K.f32,perspective:K.f32,arcStart:K.f32,arcSweep:K.f32,arcWidth:K.f32},E={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},$6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},Z6=1,A2=2,S2=1,_2=2,y2=131072,b2=1,h2=262144,x2=1,f2=1,g2=1,T2=2,N2=4,E2=8,v2=16,m2=1,l2=2;function G1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var u2=1,X6=1263551300,W6=1,q6=32,Y6=24,m={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},qJ=32896,c2=0.016666666666666666;function F1(J){return J.__viewport??null}var M0=null;function z6(){return null}function B1(J,Q=z6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function j6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return B1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return B1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function G6(J){M0=J}function PJ(){if(!M0)throw Error("PocketJS: host not installed — call render() first");return M0}function h(){return PJ().ops}function F6(J){globalThis.frame=J}function B6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function H6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return G1($>>>16&255,$>>>8&255,$&255,255);return G1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function K6(J,Q){let $=Q6[J];if(typeof Q==="string"){if($===K.color)return H6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===K.color||$===K.int)return Q>>>0;return Q}var cJ=60,H1=[1,2,3,4,5,6,10,12,15,20,30,60],U0=cJ,n=-1,M6=0,AJ=[];function U6(J){if(!Number.isFinite(J)||J<=0)return cJ;let Q=H1[0];for(let $ of H1)if(Math.abs($-J)Q.at<=n).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;AJ=AJ.filter((Q)=>Q.at>n);for(let Q of J)Q.cb()}var V0=0.12,pJ=qJ;function D6(J){pJ=J===void 0?qJ:J&65535}function w6(){pJ=qJ}function U1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function C6(){return U1(pJ&255)}var V1=new Set,O6=0;function k6(){V1.clear(),O6=0,w6()}function I6(J){for(let Q of[...V1])Q(J)}var YJ=null,P1=null;function A6(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function R1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function SJ(J){P0();let Q=YJ?YJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return P1.slice(Q.off,Q.off+Q.len)}var _J=null,A=null,zJ=null,iJ=0,jJ=[],D0=[],w0=[];function w1(J){if(_J=J,A=null,zJ=null,iJ=0,jJ.length=0,D0.length=0,w0.length=0,v){if(v.pressTarget=null,v.target=null,v.spriteDirty=!0,v.fresh=!0,v.vw=0,v.tex>=0){let Q=h();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(v.tex),v.tex=-1}}}function _6(J,Q){J.onPress=Q??void 0}function y6(J,Q){if(J.focusable=Q,I1(),!Q&&A===J)T(null)}function T(J){if(zJ&&zJ!==J)GJ(null);A=J,h().setFocus(J?J.id:0)}function GJ(J){if(zJ===J)return;let Q=h();if(zJ)Q.setActive?.(zJ.id,0);if(zJ=J,J)Q.setActive?.(J.id,1)}function L0(){return jJ.length>0?jJ[jJ.length-1]:_J}function C0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;T($[X])}function x6(){if(!A)return null;let J=L0();if(J&&!l(A,J))return null;for(let Q=D0.length-1;Q>=0;Q--){let $=D0[Q];if(J&&!l($.node,J)&&!l(J,$.node))continue;if(l(A,$.node))return $}return null}function f6(J){let Q=x6();if(!Q)return!1;let $=[];if(C0(Q.node,$),$.length===0){if(A)T(null);return!0}let Z=Q.columns,X=A?$.indexOf(A):-1;if(X<0)return T(L1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)T($[W]);return!0}function g6(){if(!A)return null;let J=L0();if(J&&!l(A,J))return null;for(let Q=w0.length-1;Q>=0;Q--){let $=w0[Q];if(J&&!l($.node,J)&&!l(J,$.node))continue;if(l(A,$.node))return $}return null}function dJ(J){let Q=g6();if(Q&&Q.move(J))return;if(f6(J))return;h6(J)}function C1(){O1(A)}function O1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function sJ(J){GJ(J)}function T6(J){T(J),O1(J)}function l(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function O0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=O0(Q.children[X]);if(W){T(W);return}}let Z=Q;while(Z){if(Z.focusable){T(Z);return}Z=Z.parent}}T(null)}var v=null,k1=0;function I1(){k1++}var E6=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],v6=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function m6(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=E6[Q]>>$&1,X=v6[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,Y=X?255:0;J[W]=Y,J[W+1]=Y,J[W+2]=Y,J[W+3]=255}return J}function l6(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=SJ($.image)}catch(Y){if(PJ().strict)throw Y;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):u6(Q,W),X<0&&PJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(m6(),16,16,$6.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function u6(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&Z6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function aJ(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=aJ($[Z],Q);if(X)return X}return null}var rJ=null;function A1(J){rJ=J}function S1(J){let Q=jJ.length>0?jJ[jJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||l($,Q)))return $;$=$.parent}return null}function _1(J,Q,$){return S1(y1(J,Q,$))}function y1(J,Q,$){if($!==void 0)return $===0?null:aJ(rJ??_J,$);let Z=h(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return aJ(rJ??_J,X(J,Q))}function c6(J,Q,$){let Z=v,X=h();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let G=F1(X);if(Z.vw=G?G.w:z1,Z.vh=G?G.h:j1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)l6(Z,X);let W=L6()*Z.speed,Y=C6()*Z.speed;if(Z.dpadSpeed>0&&W===0&&Y===0){if(J&m.LEFT)W=-Z.dpadSpeed;if(J&m.RIGHT)W=Z.dpadSpeed;if(J&m.UP)Y=-Z.dpadSpeed;if(J&m.DOWN)Y=Z.dpadSpeed}let j=Z.fresh;if(W!==0||Y!==0){let G=V6()/60,I=Math.min(Math.max(Z.x+W*G,0),Z.vw-1),b=Math.min(Math.max(Z.y+Y*G,0),Z.vh-1);if(I!==Z.x||b!==Z.y)Z.x=I,Z.y=b,j=!0}if(j)X.setCursorPos(Z.x,Z.y);let M=(Q|$)&Z.button,V=k1;if(j||M!==0||V!==Z.gen)Z.gen=V,Z.fresh=!1,Z.target=S1(aJ(rJ??_J,X.hitTest(Z.x,Z.y)));let D=Z.target;if(D!==A)T(D);if(Q&Z.button&&D)Z.pressTarget=D;if(Z.pressTarget){if(GJ(D===Z.pressTarget?Z.pressTarget:null),$&Z.button){let G=D===Z.pressTarget;if(Z.pressTarget=null,GJ(null),G)C1()}}else if($&Z.button)GJ(null);return!0}function p6(J){let Q=J&~iJ,$=iJ&~J;if(iJ=J,v&&c6(J,Q,$))return;if($&m.CIRCLE)GJ(null);if(Q===0)return;if(Q&m.DOWN)dJ("down");if(Q&m.RIGHT)dJ("right");if(Q&m.UP)dJ("up");if(Q&m.LEFT)dJ("left");if(Q&m.CIRCLE)GJ(A),C1()}var k0=null;function b1(J){k0=J}function RJ(){if(I1(),k0)k0()}function i6(J,Q){J.debugName=Q||void 0,RJ()}var t={id:t4,type:WJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},h1=Symbol.for("pocketjs.native-node"),I0=1,yJ=3,d=8,d6=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function oJ(J){return J.domAttrs??={}}function x1(J,Q){let $=J.domNodeType??(bJ(J)?yJ:I0),Z=$===yJ?nJ(J.text??""):$===d?r6(J.domData??""):m1(J.domTag??eJ(J));for(let X of Object.keys(J.domAttrs??{}))A0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)e(Z,x1(X,!0));return Z}function A0(J,Q,$){if(d6.has(Q)){wJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete oJ(J)[Q];else oJ(J)[Q]=$}function S0(J){if(J[h1]===!0)return J;return Object.defineProperty(J,h1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(bJ(J)?yJ:I0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else tJ(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===d?J.domData??"":J.text??""},set($){if(J.domNodeType===d)J.domData=String($??"");else tJ(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===d)return J.domData??"";if(bJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===d)J.domData=Z;else if(bJ(J))tJ(J,Z);else if($8(J),Z)e(J,nJ(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return u1(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??eJ(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===yJ)return"#text";if(J.domNodeType===d)return"#comment";return(J.domTag??eJ(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){wJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===t)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return e(J,$),$},insertBefore($,Z){return e(J,$,Z??null),$},removeChild($){return hJ(J,$),$},replaceChild($,Z){return e(J,$,Z),hJ(J,Z),Z},cloneNode($=!1){return x1(J,!!$)},remove(){if(J.parent)hJ(J.parent,J)},setAttribute($,Z){A0(J,$,Z)},removeAttribute($){A0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}S0(t);var _0=null;function s6(J){_0=J}var y0={unknownClass:0,unknownTexture:0},f1=new Map;function g1(J,Q){f1.set(J,Q)}var T1=new Map;function N1(J,Q){T1.set(J,Q)}var DJ=new Set,a6=new Set;function E1(J){if(!J)return!1;if(a6.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return S0({id:h().createNode(Q),type:Q,parent:null,children:[],domNodeType:I0,domTag:J})}function nJ(J){let Q=h(),$=Q.createNode(WJ.text);return Q.setText($,J),S0({id:$,type:WJ.text,parent:null,children:[],text:J,domNodeType:yJ,domTag:"#text"})}function r6(J=""){let Q=nJ("");return Q.domNodeType=d,Q.domTag="#comment",Q.domData=J,Q}function tJ(J,Q){h().replaceText(J.id,Q),J.text=Q,RJ()}function bJ(J){return J.type===WJ.text}function l1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function e(J,Q,$){let Z=h();if(l1(Q),DJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,RJ()}function hJ(J,Q){if(!Q)return;N6(Q),h().removeChild(J.id,Q.id),l1(Q),DJ.add(Q),RJ()}function o6(J){return J.parent??void 0}function n6(J){return J.children[0]}function u1(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function t6(J,Q){let $=h();if(RJ(),Q==null||Q===""){$.setStyle(J.id,e4);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=_0?_0(Q):void 0;if(Z===void 0){if(PJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);y0.unknownClass++;return}$.setStyle(J.id,Z)}function e6(J,Q){let $=h();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=f1.get(Q);if(Z===void 0){if(PJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);y0.unknownTexture++;return}$.setImage(J.id,Z)}function J8(J,Q){let $=h();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=T1.get(Q);if(Z===void 0){if(PJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);y0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function Q8(J,Q,$){let Z=h(),X=Q??{},W=$??{},Y=!1;for(let j in X){let M=X[j];if(W[j]===M)continue;let V=J6[j];if(V===void 0)throw Error(`PocketJS: unknown style prop '${j}' (see spec PROP)`);Z.setProp(J.id,V,K6(j,M)),Y=!0}if(Y)RJ()}function wJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete oJ(J)[Q];else oJ(J)[Q]=$;switch(Q){case"class":return t6(J,$),$;case"onPress":case"on:press":return _6(J,$),$;case"src":return e6(J,$),$;case"sprite":return J8(J,$),$;case"style":return Q8(J,$,Z),$;case"focusable":return y6(J,!!$),$;case"debugName":return i6(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${eJ(J)}>`)}function $8(J){for(let Q of[...J.children])hJ(J,Q)}function eJ(J){for(let Q of Object.keys(WJ))if(WJ[Q]===J.type)return Q;return String(J.type)}function Z8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}wJ(J,Q,$,Z)}var X8=n4({createElement:m1,createTextNode:nJ,replaceText:tJ,isTextNode:bJ,setProperty:Z8,insertNode(J,Q,$){e(J,Q,$)},removeNode(J,Q){hJ(J,Q)},getParentNode:o6,getFirstChild:n6,getNextSibling:u1}),{render:W8,effect:p2,memo:s,createComponent:R,createElement:c1,insert:i2,spread:q8,mergeProps:d2,use:s2}=X8,a2={linear:E.Easing.Linear,in:E.Easing.EaseIn,out:E.Easing.EaseOut,"in-out":E.Easing.EaseInOut,"out-back":E.Easing.OutBack,spring:E.Easing.Spring,"spring-bouncy":E.Easing.SpringBouncy},Y8=null;function p1(J){Y8=J}function z8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function i1(J,Q){let $=c1(J);return q8($,Q,!1),z8(Q.nodeRef,$),$}function _(J){return i1("view",J)}function y(J){return i1("text",J)}var r2=new WeakMap,o2=new WeakMap,j8={}!==null?Object.freeze({...{}}):Object.freeze({}),n2=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:j8}),t2=new Map,JJ=36000,b0=30,G8=30,q={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(JJ),tapeAnalog:new Uint16Array(JJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-b0,saidHello:!1,hostCalls:0};function F8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};q.ops=J,q.frame=0,q.tapeStart=0,q.tapeLen=0,q.tapeFirstFrame=0,q.tapeTouch=null,q.replayMasks=null,q.replayAnalog=null,q.replayTouch=null,q.paused=!1,q.stepQueued=0,q.inspectReportId=null,q.inspectAskedAt=0,q.treeDirty=!0,q.treeSentAt=-b0,q.saidHello=!1,q.hostCalls=0,q.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)q.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)q.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else q.transport=null;if(q.transport)b1(()=>{q.treeDirty=!0}),R8();else b1(null);globalThis.__pocketDevtools=w8}function B8(J){return(Q,$,Z,X)=>{if(q.hostCalls++,q.transport)K8(),V8();let W=Q,Y=$===void 0?qJ:$&65535,j=Z,M=X;if(q.replayMasks)if(q.replayAt0?$.slice(0,8):null;if(Z&&!q.tapeTouch)q.tapeTouch=Array(JJ).fill(null);if(q.tapeLen1||Q.length===1&&Q[0][0]!==qJ)J.analog=Q;if(q.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function a1(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,Y]of J)Z.fill(W,X,Math.min(X+Y,$)),X+=Y;return Z}function r1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return a1(J.masks,0,Q)}function o1(J){let Q=0;for(let[,$]of J.masks)Q+=$;return a1(J.analog??[],qJ,Q)}function n1(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&q.hostCalls%Q!==0)return;if(!q.saidHello)q.saidHello=!0,g({t:"hello",app:q.app,host:D8(),frame:q.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` +`))if(X.trim())M8(X)}}function M8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=q.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),q.inspectReportId=Z||null,q.inspectAskedAt=q.hostCalls,!Z)g({t:"inspect",id:0,rect:null});break}case"pause":q.paused=!0,q.stepQueued=0,$?.debugPause?.(!0),h0();break;case"resume":q.paused=!1,$?.debugPause?.(!1),h0();break;case"step":q.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":t1();break;case"eval":{let Z=!0,X;try{X=J0((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}g({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":g({t:"tape",tape:s1()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}g({t:"devStats",frame:q.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())g({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:q.frame});else g({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))q.replayMasks=r1(Z),q.replayAnalog=Z.analog?o1(Z):null,q.replayTouch=Z.touch?n1(Z):null,q.replayAt=0;break}default:break}}function U8(){if(q.treeDirty&&q.frame-q.treeSentAt>=b0)t1();if(q.frame%G8===0)h0()}function V8(){let J=q.inspectReportId;if(J==null)return;let Q=q.ops;if(!Q?.debugRectXY||!Q.debugRectWH){q.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(q.hostCalls-q.inspectAskedAt>60)q.inspectReportId=null,g({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();q.inspectReportId=null,g({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function h0(){g({t:"stats",frame:q.frame,nodes:Q4(t),tapeLen:q.tapeLen,paused:q.paused})}function t1(){q.treeDirty=!1,q.treeSentAt=q.frame,g({t:"tree",frame:q.frame,root:J4(t)})}function P8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function x0(J,Q){if(Array.isArray(J)){for(let $ of J)x0($,Q);return}if(P8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)x0($,Q)}}function e1(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)x0(Z,Q)}function J4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(e1(J,(X)=>{if(X.domNodeType===8)return;Z.push(J4(X))}),Z.length)Q.k=Z;return Q}function Q4(J){let Q=1;return e1(J,($)=>{Q+=Q4($)}),Q}function R8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{g({t:"log",level:$,args:X.map((W)=>J0(W))}),Z?.apply(Q,X)}}}function J0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?$4(W):JSON.stringify($4(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((Y)=>J0(Y,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,Y])=>`${W}: ${J0(Y,Q+1)}`).join(", ")}}`}function $4(J){return J.length>200?J.slice(0,199)+"…":J}function D8(){let J=q.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var w8={get frame(){return q.frame},dumpTape:()=>s1(),replay:(J)=>{q.replayMasks=r1(J),q.replayAnalog=J.analog?o1(J):null,q.replayTouch=J.touch?n1(J):null,q.replayAt=0}},Z4=new Map,f0=new Map;function X4(J){return J.trim().replace(/\s+/g," ")}function W4(J){return J.split(" ").sort().join(" ")}var q4=-1;function L8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=X4(Q);Z4.set(Z,$);let X=W4(Z),W=f0.get(X);f0.set(X,W!==void 0&&W!==$?q4:$)}}function C8(J){let Q=X4(J),$=Z4.get(Q);if($!==void 0)return $;let Z=f0.get(W4(Q));return Z===q4?void 0:Z}var g0=9,O8=(1<{let X=($&I8)!==0,W=X?T0:g0,Y=X?A8:O8;return Object.freeze({id:$>>>(X?S8:k8)&255,x:$&Y,y:$>>>W&Y,hit:Q?.[Z]})}))}function y8(){return Q0}function b8(){Q0=N0}var Y4=8,QJ=8,h8=3,x8=8,f8=6,g8=0.5,u=1,xJ=2,E0=4,FJ=8,LJ=[],z4=0,$0=0,$J=Array.from({length:Y4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(QJ),histY:new Int16Array(QJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function T8(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function N8(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=y1(Q,$,Z.fact);let j=Z.hit;if(j)return T8(j,W)}let Y=X.rect?.();if(!Y)return!1;return Q>=Y.x&&Q=Y.y&&$=0;Y--){let j=LJ[Y];if(j.disposed)continue;if(z4>0&&!j.opts.allowWhenBlocked)continue;if(!N8(j,$,Z,W))continue;j.flags[J.slot]=u,J.owners.push(j)}for(let Y of J.owners)Y.opts.onDown?.(J)}function m8(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%QJ,J.histLenY||Z>Y))X.flags[J.slot]|=xJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&u)||W&(xJ|E0))continue;if(!X.opts.onLongPress)continue;let Y=Math.max(1,Math.round((X.opts.longPressSeconds??g8)*K1()));if(J.frames=0)LJ.splice($,1)},cancel(){if(!Q.disposed)F4(Q)},get panning(){for(let $ of $J)if($.used&&Q.flags[$.slot]&FJ)return!0;return!1}}}function i8(J){let Q=p8(J);return F0(()=>Q.dispose()),Q}function B4(){LJ.length=0,z4=0,$0=0;for(let J of $J)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function d8(){return i8({onDown:(J)=>{let Q=_1(J.x,J.y,J.hit);if(Q)sJ(Q)},onTap:(J)=>{sJ(null);let Q=_1(J.x,J.y,J.hit);if(Q)T6(Q)},onUp:()=>sJ(null),onCancel:()=>sJ(null)})}var s8=1,v0=new Map,Z0=[];function a8(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function r8(){s8=1,v0.clear(),Z0=[]}function o8(){if(Z0.length===0)return;let J=Z0;Z0=[];for(let{id:Q,result:$}of J){let Z=v0.get(Q);if(!Z)continue;v0.delete(Q),a8()?.({t:"delivery",frame:M1(),id:Q,kind:Z.kind}),Z.onResult($)}}var H4=new Set;function n8(){if(H4.size===0)return;for(let J of H4)J()}var t8={"flex-col w-full h-full bg-slate-50":0,"relative grow px-6 pt-4 flex-col":1,"absolute left-[628] top-[16] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":2,"absolute left-[628] top-[742] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":3,"w-[584] h-[890] flex-col gap-[12]":4,"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":5,"w-[390] flex-col gap-2":6,"text-lg text-slate-900 font-bold":7,"text-base text-slate-500":8,"text-base text-indigo-600 font-bold":9,"absolute left-[24] top-[16] w-[672] h-[890] bg-slate-50":10,"h-[96]":11,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":12,"absolute inset-0 z-50 flex-col items-center justify-center":13,"absolute inset-0 bg-slate-950":14,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":15,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":16,"flex-row flex-wrap":17,grow:18,"text-2xl text-white font-bold":19,"text-2xl text-slate-950 font-bold":20,"text-xl text-slate-900 font-bold":21,"text-base text-slate-600 font-bold":22,"text-base text-slate-500 font-bold":23,"px-3 py-2 rounded-lg bg-slate-100":24,"px-3 py-2 rounded-lg bg-indigo-100":25,"text-base text-indigo-700 font-bold":26,"px-3 py-2 rounded-lg bg-emerald-100":27,"text-base text-emerald-700 font-bold":28,"px-3 py-2 rounded-lg bg-amber-100":29,"text-base text-amber-700 font-bold":30,"px-3 py-2 rounded-lg bg-red-100":31,"text-base text-red-500 font-bold":32,"w-[34] h-[34] rounded-lg bg-amber-400":33,"w-[34] h-[34] rounded-lg bg-red-500":34,"w-[34] h-[34] rounded-lg bg-slate-800":35,"w-[34] h-[34] rounded-lg bg-emerald-500":36,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":37,"flex-row items-center gap-4":38,"w-[34] text-2xl text-white font-bold":39,"w-[332] flex-col items-end gap-2":40,"text-base text-slate-300 font-bold":41,"text-base text-slate-400":42,"h-[166] px-6 pt-6 flex-col gap-3":43,"text-base text-orange-600 font-bold":44,"text-lg text-slate-600":45,"h-[44] px-1 flex-row items-center justify-between":46,"w-full h-full items-center justify-center rounded-xl bg-slate-200":47,"w-full h-full items-center justify-center rounded-xl bg-red-100":48,"w-full h-full items-center justify-center rounded-xl bg-slate-100":49,"w-full h-full items-center justify-center rounded-xl bg-orange-600":50,"text-lg text-slate-500 font-bold":51,"text-lg text-red-500 font-bold":52,"text-lg text-white font-bold":53,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":54,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":55,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":56,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":57,"text-2xl text-indigo-700 font-bold":58,"text-2xl text-slate-600 font-bold":59,"pt-7 text-2xl text-slate-900 font-bold":60,"pt-4 text-lg text-slate-500":61,"text-xl text-emerald-600 font-bold":62,"text-xl text-red-500 font-bold":63,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":64,"text-base text-red-300":65,"text-base text-slate-300":66,"text-base text-red-500":67,"w-full h-full px-6 flex-row items-center bg-slate-950":68,"w-full h-full flex-row items-center":69};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var e8="ui:styles",J2="ui:font.",K4="ui:img.",M4="ui:sprite.";function Q2(){return globalThis.ui}function $2(J){if(J.__textures)return;for(let Q of R0(K4)){let $=SJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)g1(Q.slice(K4.length),Z)}}function Z2(J){if(J.__sprites)return;for(let Q of R0(M4)){let $=SJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),Y=$[4],j=Z.getUint16(6,!0),M=Z.getUint16(8,!0),V=Z.getUint16(10,!0),D=J.uploadTexture($.subarray(16),X,W,Y);if(D>=0)N1(Q.slice(M4.length),{handle:D,frames:j,cols:M,step:V})}}function U4(J){let Q=c1("view");return wJ(Q,"style",J,void 0),Q}var X0=null,W0=null;function X2(J,Q){if(!X0||!W0)return;wJ(X0,"style",{width:J,height:Q,overflow:E.Overflow.Hidden},void 0),wJ(W0,"style",{width:J,height:Q,posType:E.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=h();$.__viewport={w:J,h:Q}}function W2(J,Q={}){let $=j6(Q.ops);if(G6($),s6(C8),Q.styles)L8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let I in Z)g1(I,Z[I]);let G=$.ops.__sprites;if(G)for(let I in G)N1(I,G[I])}if($.kind==="injected"||Z===void 0){if(Q.pak)D1(Q.pak);if(S6()){for(let G of R0())if(G===e8)$.ops.loadStyles?.(SJ(G));else if(G.startsWith(J2))$.ops.loadFontAtlas?.(SJ(G))}}let X=F1($.ops),W=X?.w??z1,Y=X?.h??j1,j=U4({width:W,height:Y,overflow:E.Overflow.Hidden}),M=U4({width:W,height:Y,posType:E.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});e(t,j),e(t,M),p1(M),X0=j,W0=M,w1(j),A1(t),k6(),B4(),d8(),P6(),r8(),F8($.ops),F6(B8((G,I,b,x)=>{R6(),D6(I),_8(b,x),n8(),o8(),c8(),I6(G),p6(G),v1()}));let V=W8(J,j),D=B6(X2);return()=>{D(),b8(),B4(),V(),w1(null),A1(null),p1(null),X0=null,W0=null;for(let G of t.children.splice(0))G.parent=null,$.ops.destroyNode(G.id);v1()}}function q2(J,Q={}){let $=Q.ops??Q2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)D1(Q.pak);return $2($),Z2($),W2(J,{ops:$,styles:Q.styles??t8,pak:Q.pak})}var V4="$b",Y2=9007199254740991,z2=":memory:",CJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function j2(J){let Q="";for(let $=0;$>2]+CJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2Y2)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function B2(J){if(J!==null&&typeof J==="object")return G2(J[V4]);return J}function H2(J){if(Array.isArray(J))return JSON.stringify(J.map(P4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=P4(Z);return JSON.stringify(Q)}class m0{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,H2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=R4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(B2))}run(...J){let Q=this.execute(R4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function R4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class D4{statements=new Map;txDepth=0;constructor(J=z2){let Q=F2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new m0(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new m0(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let Y=J(...Q);return this.txDepth--,this.exec(X),Y}catch(Y){throw this.txDepth--,this.exec(W),Y}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var w4={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",captionStrong:"text-base text-slate-500 font-bold"},q0={neutral:{surface:"px-3 py-2 rounded-lg bg-slate-100",text:"text-base text-slate-600 font-bold"},info:{surface:"px-3 py-2 rounded-lg bg-indigo-100",text:"text-base text-indigo-700 font-bold"},success:{surface:"px-3 py-2 rounded-lg bg-emerald-100",text:"text-base text-emerald-700 font-bold"},warning:{surface:"px-3 py-2 rounded-lg bg-amber-100",text:"text-base text-amber-700 font-bold"},danger:{surface:"px-3 py-2 rounded-lg bg-red-100",text:"text-base text-red-500 font-bold"}};function K2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return R(_,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[R(_,{class:"flex-row items-center gap-4",get children(){return[s(()=>s(()=>!!J.back)()?R(y,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):R(_,{get["class"](){return Q()}})),R(y,{get["class"](){return w4.appTitle},get children(){return J.title}})]}}),R(_,{class:"w-[332] flex-col items-end gap-2",get children(){return[R(y,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),R(y,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function M2(J){return R(_,{class:"h-[166] px-6 pt-6 flex-col gap-3",get children(){return[R(y,{get["class"](){return J.tone==="info"?"text-base text-indigo-700 font-bold":"text-base text-orange-600 font-bold"},get children(){return J.eyebrow}}),R(y,{get["class"](){return w4.pageTitle},get children(){return J.title}}),R(y,{class:"text-lg text-slate-600",get children(){return J.description}})]}})}function U2(J){return R(_,{get["class"](){return J.compact?"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100"},get children(){return[s(()=>s(()=>!!J.icon)()?R(_,{get["class"](){return J.tone==="info"?"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100"},get children(){return R(y,{get["class"](){return J.tone==="info"?"text-2xl text-indigo-700 font-bold":"text-2xl text-slate-600 font-bold"},get children(){return J.icon}})}}):null),R(y,{get["class"](){return J.icon?"pt-7 text-2xl text-slate-900 font-bold":"text-lg text-slate-500 font-bold"},get children(){return J.title}}),s(()=>s(()=>!!J.detail)()?R(y,{class:"pt-4 text-lg text-slate-500",get children(){return J.detail}}):null)]}})}function V2(J){let Q=()=>J.dark?J.tone==="danger"?"text-base text-red-300":"text-base text-slate-300":J.tone==="danger"?"text-base text-red-500":"text-base text-slate-500";return R(_,{get["class"](){return J.dark?"w-full h-full px-6 flex-row items-center bg-slate-950":"w-full h-full flex-row items-center"},get children(){return R(y,{get["class"](){return Q()},get children(){return J.text}})}})}function P2(J){return[R(_,{get["class"](){return J.top},get children(){return R(y,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),R(_,{get["class"](){return J.bottom},get children(){return R(y,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var R2=5,gJ=10,l0=6,L4=new D4("exa"),[TJ,Y0]=XJ([]),[C4,u0]=XJ(!1),[c0,z0]=XJ(0),[O4,p0]=XJ("SEARCH HISTORY IS LOCAL"),j0=-1,i0=!1;function D2(J){try{return JSON.parse(J)}catch{return null}}function w2(J){let Q=new Date(J*1000).toISOString();return Q.slice(0,10)+" · "+Q.slice(11,16)+" UTC"}function k4(J){return L4.query(` SELECT id,query,searched_at,status,result_count,top_title,error FROM searches ORDER BY id DESC LIMIT ? OFFSET ? - `).all(NJ+1,J)}function C2(){if(s0||!k4())return;s0=!0;try{let J=A4(EJ().length);j0((Q)=>[...Q,...J.slice(0,NJ)]),p0(J.length>NJ)}finally{s0=!1}}function S4(J){if(J>0&&i0()+c0+4>EJ().length&&k4())C2();G0(($)=>J<0?Math.max(0,$-4):Math.min(Math.max(0,EJ().length-c0),$+4))}function _4(J){if(F0===J)return;try{let Q=ZJ.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==TJ){j0([]),p0(!1),G0(0),d0("SEARCH HISTORY IS LOCAL");return}let $=A4(0),Z=$.slice(0,NJ);j0(Z),p0($.length>NJ),G0(0),d0(Z[0]?.status==="error"?String(Z[0].error||"EXA SEARCH FAILED").slice(0,80):Z.length?"SEARCH HISTORY UPDATED FROM SQLITE":"SEARCH HISTORY IS LOCAL"),F0=J}catch{j0([]),G0(0),d0("SEARCH HISTORY IS LOCAL")}}function O2(){let J=Number(ZJ.query("PRAGMA page_size").get()?.page_size??0),Q=Number(ZJ.query("PRAGMA page_count").get()?.page_count??0),$=Number(ZJ.query("PRAGMA freelist_count").get()?.freelist_count??0),Z=Number(ZJ.query("PRAGMA user_version").get()?.user_version??0),X=Z===TJ?Number(ZJ.query("SELECT COUNT(*) AS count FROM searches").get()?.count??0):0,W=Z===TJ?ZJ.query(` - SELECT id,searched_at,status,result_count,error - FROM searches ORDER BY id DESC LIMIT 1 - `).get():null,Y={database:"exa.sqlite",schemaVersion:Z,expectedSchemaVersion:TJ,retentionDays:O4,searches:X,allocatedBytes:J*Q,reusableBytes:J*$,latestSearch:W},j=W,U=j?` Latest #${j.id??"?"}: ${j.status??"unknown"}, ${j.result_count??0} results.`:" No searches yet.";return{text:`Exa storage (schema ${Z}/${TJ}): ${X} searches; ${O4}-day retention; ${Y.allocatedBytes} bytes allocated (${Y.reusableBytes} reusable).${U}`,details:Y}}function k2(){return R(_,{class:"flex-col w-full h-full bg-slate-50",get children(){return[R(M2,{title:"EXA RESEARCH",back:!0,metaTop:"POCKET APP",metaBottom:"SQLITE HISTORY"}),R(V2,{eyebrow:"AGENT RESEARCH MEMORY",title:"Search history",description:"Every research.search call is saved here automatically.",tone:"info"}),R(_,{class:"relative grow px-6 pt-4 flex-col",get children(){return[R(w2,{top:"absolute left-[628] top-[16] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",bottom:"absolute left-[628] top-[742] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100"}),R(_,{class:"w-[584] h-[890] flex-col gap-[12]",get children(){return R(r4,{get each(){return EJ().slice(i0(),i0()+c0)},children:(J)=>R(_,{class:"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[R(_,{class:"w-[390] flex-col gap-2",get children(){return[R(y,{class:"text-lg text-slate-900 font-bold",get children(){return J.query.slice(0,48)}}),R(y,{class:"text-base text-slate-500",get children(){return(J.top_title||J.error||"No result title").slice(0,58)}}),R(y,{class:"text-base text-indigo-600 font-bold",get children(){return L2(J.searched_at)}})]}}),R(_,{get["class"](){return s(()=>J.status==="ok")()?z0.success.surface:z0.danger.surface},get children(){return R(y,{get["class"](){return s(()=>J.status==="ok")()?z0.success.text:z0.danger.text},get children(){return s(()=>J.status==="ok")()?J.result_count+" RESULTS":"FAILED"}})}})]}})})}}),R(o4,{get when(){return EJ().length===0},get children(){return R(_,{class:"absolute left-[24] top-[16] w-[672] h-[890] bg-slate-50",get children(){return R(P2,{icon:"E",title:"No searches yet",detail:`Ask Pi Agent to research a topic. -The search and its results will appear here.`,tone:"info"})}})}})]}}),R(_,{class:"h-[96]",get children(){return R(R2,{get text(){return I4()},get tone(){return I4().includes("FAILED")?"danger":"neutral"},dark:!0})}})]}})}_4(0),z2(()=>R(k2,{})),globalThis.PocketPiApp={tick(){return""},dataChanged(J){let Q=D2(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),F0):F0;return _4($),""},invokeTool(J){try{let Q=J==="research.storage_status"?O2():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:Q.text,details:Q.details,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(J>=620&&Q>=294&&Q<=426)S4(-1);else if(J>=620&&Q>=1020&&Q<=1152)S4(1);return""}}})(); + `).all(gJ+1,J)}function L2(){if(i0||!C4())return;i0=!0;try{let J=k4(TJ().length);Y0((Q)=>[...Q,...J.slice(0,gJ)]),u0(J.length>gJ)}finally{i0=!1}}function I4(J){if(J>0&&c0()+l0+4>TJ().length&&C4())L2();z0(($)=>J<0?Math.max(0,$-4):Math.min(Math.max(0,TJ().length-l0),$+4))}function A4(J){if(j0===J)return;try{let Q=L4.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==R2){Y0([]),u0(!1),z0(0),p0("SEARCH HISTORY IS LOCAL");return}let $=k4(0),Z=$.slice(0,gJ);Y0(Z),u0($.length>gJ),z0(0),p0(Z[0]?.status==="error"?String(Z[0].error||"EXA SEARCH FAILED").slice(0,80):Z.length?"SEARCH HISTORY UPDATED FROM SQLITE":"SEARCH HISTORY IS LOCAL"),j0=J}catch{Y0([]),z0(0),p0("SEARCH HISTORY IS LOCAL")}}function C2(){return R(_,{class:"flex-col w-full h-full bg-slate-50",get children(){return[R(K2,{title:"EXA RESEARCH",back:!0,metaTop:"POCKET APP",metaBottom:"SQLITE HISTORY"}),R(M2,{eyebrow:"AGENT RESEARCH MEMORY",title:"Search history",description:"Every research.search call is saved here automatically.",tone:"info"}),R(_,{class:"relative grow px-6 pt-4 flex-col",get children(){return[R(P2,{top:"absolute left-[628] top-[16] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",bottom:"absolute left-[628] top-[742] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100"}),R(_,{class:"w-[584] h-[890] flex-col gap-[12]",get children(){return R(s4,{get each(){return TJ().slice(c0(),c0()+l0)},children:(J)=>R(_,{class:"h-[126] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[R(_,{class:"w-[390] flex-col gap-2",get children(){return[R(y,{class:"text-lg text-slate-900 font-bold",get children(){return J.query.slice(0,48)}}),R(y,{class:"text-base text-slate-500",get children(){return(J.top_title||J.error||"No result title").slice(0,58)}}),R(y,{class:"text-base text-indigo-600 font-bold",get children(){return w2(J.searched_at)}})]}}),R(_,{get["class"](){return s(()=>J.status==="ok")()?q0.success.surface:q0.danger.surface},get children(){return R(y,{get["class"](){return s(()=>J.status==="ok")()?q0.success.text:q0.danger.text},get children(){return s(()=>J.status==="ok")()?J.result_count+" RESULTS":"FAILED"}})}})]}})})}}),R(a4,{get when(){return TJ().length===0},get children(){return R(_,{class:"absolute left-[24] top-[16] w-[672] h-[890] bg-slate-50",get children(){return R(U2,{icon:"E",title:"No searches yet",detail:`Ask Pi Agent to research a topic. +The search and its results will appear here.`,tone:"info"})}})}})]}}),R(_,{class:"h-[96]",get children(){return R(V2,{get text(){return O4()},get tone(){return O4().includes("FAILED")?"danger":"neutral"},dark:!0})}})]}})}A4(0),q2(()=>R(C2,{})),globalThis.PocketPiApp={tick(){return""},dataChanged(J){let Q=D2(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),j0):j0;return A4($),""},tap(J,Q){if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(J>=620&&Q>=294&&Q<=426)I4(-1);else if(J>=620&&Q>=1020&&Q<=1152)I4(1);return""}}})(); diff --git a/apps/exa/dist/app.pak b/apps/exa/dist/app.pak index af467c4c0a331e5132bd6f358dd6e091014f74c9..ad08f24f6e9b88fe3f108ebc7722be4818a90424 100644 GIT binary patch delta 61 zcmX@mFSwykaDoJ*!9>aVj4F*gTX!=A(;K&Uo8Cf`h^a4kS7#Elgm0=VB@){f&S*HiMvdEjWIxt-P z_4L0BP|(5AjX_{%<9~OM0(%bzMj*||=)mwF2tf45uRp;w6Px(|=?k1#WVY)$vHW2H E04DM>6#xJL diff --git a/apps/exa/dist/data-action.js b/apps/exa/dist/data-action.js index fe81809..9858d86 100644 --- a/apps/exa/dist/data-action.js +++ b/apps/exa/dist/data-action.js @@ -1,4 +1,4 @@ -(()=>{var Z=["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"];var z=65536,V=131072,K=262144,g=32,j=8192,F=30000,M=120000;var i={unavailable:"unavailable",invalidRequest:"invalid_request",busy:"busy",dns:"dns",connect:"connect",tls:"tls",timeout:"timeout",redirect:"redirect",responseTooLarge:"response_too_large",protocol:"protocol",cancelled:"cancelled",other:"other"};var E={};for(let f=0;f<64;f++)E["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[f]]=f;function J(f){let n=0;for(let h=0;h65535)h++;n+=a<128?1:a<2048?2:a<65536?3:4}let c=new Uint8Array(n),r=0;for(let h=0;h65535)h++;else if(a>=55296&&a<=57343)a=65533;if(a<128)c[r++]=a;else if(a<2048)c[r++]=192|a>>6,c[r++]=128|a&63;else if(a<65536)c[r++]=224|a>>12,c[r++]=128|a>>6&63,c[r++]=128|a&63;else c[r++]=240|a>>18,c[r++]=128|a>>12&63,c[r++]=128|a>>6&63,c[r++]=128|a&63}return c}function S(f){let n="",c=0;while(cf.length)throw Error("invalid UTF-8");for(let L=0;L1114111||h>=55296&&h<=57343||a===1&&h<128||a===2&&h<2048||a===3&&h<65536)throw Error("invalid UTF-8");if(h<65536)n+=String.fromCharCode(h);else h-=65536,n+=String.fromCharCode(55296+(h>>10),56320+(h&1023))}return n}var X=new Set;function Y(f){return X.add(f),()=>X.delete(f)}class w extends Error{constructor(f,n){super(n);this.name="NetError",this.code=f}}class O{constructor(f,n,c,r){this.status=f,this.url=n,this.headers=Object.freeze({...c}),this.ok=f>=200&&f<300,this.data=new Uint8Array(r)}get byteLength(){return this.data.byteLength}async bytes(){return this.data.slice()}async arrayBuffer(){return this.data.slice().buffer}async text(){try{return S(this.data)}catch{throw Error("net: response is not valid UTF-8")}}async json(){return JSON.parse(await this.text())}}var A=new Map,l=null,I=null;function v(){let f=globalThis.net;if(!f||typeof f!=="object")return null;let n=f;return typeof n.start==="function"&&typeof n.take==="function"&&typeof n.cancel==="function"&&typeof n.poll==="function"&&typeof n.lastError==="function"?n:null}function B(f){let n=String(f);for(let c of Object.values(i))if(c===n)return c;return i.other}function p(f){let n=A.get(f.h);if(!n)return;if(A.delete(f.h),f.t==="error")n.reject(new w(B(f.code),String(f.message||f.code)));else if(!Number.isInteger(f.status)||f.status<100||f.status>599||typeof f.url!=="string"||typeof f.headers!=="object"||f.headers===null||!Number.isInteger(f.bytes)||f.bytes<0||f.bytes>K)n.ops.cancel(f.h),n.reject(new w(i.protocol,"net: malformed done event"));else{let c=new ArrayBuffer(f.bytes);if(n.ops.take(f.h,c)!==f.bytes)n.ops.cancel(f.h),n.reject(new w(i.protocol,"net: response body transfer failed"));else n.resolve(new O(f.status,f.url,f.headers,c))}if(A.size===0&&l)l(),l=null,I=null}function U(){if(A.size===0)return;let f=I;if(!f)return;let n=f.poll();if(n!==void 0){let c=null;try{c=JSON.parse(n)}catch{}if(!Array.isArray(c))for(let[r,h]of A)f.cancel(r),A.delete(r),h.reject(new w(i.protocol,"net: malformed event batch"));else for(let r of c){if(!r||typeof r!=="object")continue;let h=r;if(!Number.isInteger(h.h)||h.t!=="done"&&h.t!=="error")continue;p(h)}}if(A.size===0&&l)l(),l=null,I=null}function Q(f,n){return Promise.reject(new w(f,n))}function t(f,n,c,r){if(!Number.isInteger(f)||fc)throw new w(i.invalidRequest,`net: ${r} must be ${n}..${c}`);return f}function e(f){let n=Object.create(null),c=0,r=0;for(let h of Object.keys(f??{})){let a=h.toLowerCase(),L=String(f[h]);if(!/^[!#$%&'*+.^_`|~0-9a-z-]+$/.test(a)||/[\r\n]/.test(L))throw new w(i.invalidRequest,`net: invalid header ${h}`);if(c++,r+=J(a).byteLength+J(L).byteLength+4,c>g||r>j)throw new w(i.invalidRequest,"net: request headers exceed limits");n[a]=L}return n}function o(f){if(f===void 0)return new Uint8Array(0);if(typeof f==="string")return J(f);if(f instanceof Uint8Array)return f.slice();if(f instanceof ArrayBuffer)return new Uint8Array(f.slice(0));throw new w(i.invalidRequest,"net: body must be string or bytes")}function P(f,n={}){let c=v();if(!c)return Q(i.unavailable,"net: host did not mount the net module");try{if(typeof f!=="string"||!/^https?:\/\/[^\s/]+(?:\/|$)/.test(f))throw new w(i.invalidRequest,"net: url must be absolute http:// or https://");let r=n.method??"GET";if(!Z.includes(r))throw new w(i.invalidRequest,`net: unsupported method ${String(r)}`);let h=o(n.body);if((r==="GET"||r==="HEAD")&&h.byteLength>0)throw new w(i.invalidRequest,`net: ${r} cannot have a body`);if(h.byteLength>z)throw new w(i.invalidRequest,"net: request body exceeds 64 KiB");let a=t(n.timeoutMs??F,1,M,"timeoutMs"),L=t(n.maxBytes??V,1,K,"maxBytes"),x=JSON.stringify({url:f,method:r,headers:e(n.headers),timeoutMs:a,maxBytes:L});if(I&&I!==c)throw new w(i.unavailable,"net: mounted host changed while requests are pending");let k=c.start(x,h.buffer);if(!Number.isInteger(k)||k<0){let q=c.lastError()||"unavailable: request refused",D=q.indexOf(":"),R=B(D<0?i.other:q.slice(0,D)),b=D<0?q:q.slice(D+1).trim();return Q(R,b)}return new Promise((q,D)=>{if(A.set(k,{ops:c,resolve:q,reject:D}),I=c,!l)l=Y(U)})}catch(r){return r instanceof w?Promise.reject(r):Q(i.invalidRequest,String(r))}}var H=globalThis.db,$=H.open("exa");if($<0)throw Error("open exa.sqlite");var T=5,ff=7,nf=ff*24*60*60,cf=60000;function rf(){return String(H.lastError($)||"SQLite operation failed")}function G(f){if(H.exec($,f)!==0)throw Error(rf())}function N(f,n=[]){let c=JSON.parse(H.query($,f,JSON.stringify(n)));if(c.error)throw Error(String(c.error));return c}function W(f,n=[]){return N(f,n)}var hf=Number(N("PRAGMA user_version")?.rows?.[0]?.[0]??0);if(hf!==T)G(` +(()=>{var U=["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"];var Z=65536,z=131072,K=262144,V=32,j=8192,F=30000,M=120000;var i={unavailable:"unavailable",invalidRequest:"invalid_request",busy:"busy",dns:"dns",connect:"connect",tls:"tls",timeout:"timeout",redirect:"redirect",responseTooLarge:"response_too_large",protocol:"protocol",cancelled:"cancelled",other:"other"};var E={};for(let f=0;f<64;f++)E["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[f]]=f;function J(f){let n=0;for(let h=0;h65535)h++;n+=a<128?1:a<2048?2:a<65536?3:4}let c=new Uint8Array(n),r=0;for(let h=0;h65535)h++;else if(a>=55296&&a<=57343)a=65533;if(a<128)c[r++]=a;else if(a<2048)c[r++]=192|a>>6,c[r++]=128|a&63;else if(a<65536)c[r++]=224|a>>12,c[r++]=128|a>>6&63,c[r++]=128|a&63;else c[r++]=240|a>>18,c[r++]=128|a>>12&63,c[r++]=128|a>>6&63,c[r++]=128|a&63}return c}function X(f){let n="",c=0;while(cf.length)throw Error("invalid UTF-8");for(let L=0;L1114111||h>=55296&&h<=57343||a===1&&h<128||a===2&&h<2048||a===3&&h<65536)throw Error("invalid UTF-8");if(h<65536)n+=String.fromCharCode(h);else h-=65536,n+=String.fromCharCode(55296+(h>>10),56320+(h&1023))}return n}var S=new Set;function Y(f){return S.add(f),()=>S.delete(f)}class w extends Error{constructor(f,n){super(n);this.name="NetError",this.code=f}}class O{constructor(f,n,c,r){this.status=f,this.url=n,this.headers=Object.freeze({...c}),this.ok=f>=200&&f<300,this.data=new Uint8Array(r)}get byteLength(){return this.data.byteLength}async bytes(){return this.data.slice()}async arrayBuffer(){return this.data.slice().buffer}async text(){try{return X(this.data)}catch{throw Error("net: response is not valid UTF-8")}}async json(){return JSON.parse(await this.text())}}var l=new Map,A=null,u=null;function p(){let f=globalThis.net;if(!f||typeof f!=="object")return null;let n=f;return typeof n.start==="function"&&typeof n.take==="function"&&typeof n.cancel==="function"&&typeof n.poll==="function"&&typeof n.lastError==="function"?n:null}function B(f){let n=String(f);for(let c of Object.values(i))if(c===n)return c;return i.other}function v(f){let n=l.get(f.h);if(!n)return;if(l.delete(f.h),f.t==="error")n.reject(new w(B(f.code),String(f.message||f.code)));else if(!Number.isInteger(f.status)||f.status<100||f.status>599||typeof f.url!=="string"||typeof f.headers!=="object"||f.headers===null||!Number.isInteger(f.bytes)||f.bytes<0||f.bytes>K)n.ops.cancel(f.h),n.reject(new w(i.protocol,"net: malformed done event"));else{let c=new ArrayBuffer(f.bytes);if(n.ops.take(f.h,c)!==f.bytes)n.ops.cancel(f.h),n.reject(new w(i.protocol,"net: response body transfer failed"));else n.resolve(new O(f.status,f.url,f.headers,c))}if(l.size===0&&A)A(),A=null,u=null}function W(){if(l.size===0)return;let f=u;if(!f)return;let n=f.poll();if(n!==void 0){let c=null;try{c=JSON.parse(n)}catch{}if(!Array.isArray(c))for(let[r,h]of l)f.cancel(r),l.delete(r),h.reject(new w(i.protocol,"net: malformed event batch"));else for(let r of c){if(!r||typeof r!=="object")continue;let h=r;if(!Number.isInteger(h.h)||h.t!=="done"&&h.t!=="error")continue;v(h)}}if(l.size===0&&A)A(),A=null,u=null}function Q(f,n){return Promise.reject(new w(f,n))}function t(f,n,c,r){if(!Number.isInteger(f)||fc)throw new w(i.invalidRequest,`net: ${r} must be ${n}..${c}`);return f}function e(f){let n=Object.create(null),c=0,r=0;for(let h of Object.keys(f??{})){let a=h.toLowerCase(),L=String(f[h]);if(!/^[!#$%&'*+.^_`|~0-9a-z-]+$/.test(a)||/[\r\n]/.test(L))throw new w(i.invalidRequest,`net: invalid header ${h}`);if(c++,r+=J(a).byteLength+J(L).byteLength+4,c>V||r>j)throw new w(i.invalidRequest,"net: request headers exceed limits");n[a]=L}return n}function o(f){if(f===void 0)return new Uint8Array(0);if(typeof f==="string")return J(f);if(f instanceof Uint8Array)return f.slice();if(f instanceof ArrayBuffer)return new Uint8Array(f.slice(0));throw new w(i.invalidRequest,"net: body must be string or bytes")}function P(f,n={}){let c=p();if(!c)return Q(i.unavailable,"net: host did not mount the net module");try{if(typeof f!=="string"||!/^https?:\/\/[^\s/]+(?:\/|$)/.test(f))throw new w(i.invalidRequest,"net: url must be absolute http:// or https://");let r=n.method??"GET";if(!U.includes(r))throw new w(i.invalidRequest,`net: unsupported method ${String(r)}`);let h=o(n.body);if((r==="GET"||r==="HEAD")&&h.byteLength>0)throw new w(i.invalidRequest,`net: ${r} cannot have a body`);if(h.byteLength>Z)throw new w(i.invalidRequest,"net: request body exceeds 64 KiB");let a=t(n.timeoutMs??F,1,M,"timeoutMs"),L=t(n.maxBytes??z,1,K,"maxBytes"),x=JSON.stringify({url:f,method:r,headers:e(n.headers),timeoutMs:a,maxBytes:L});if(u&&u!==c)throw new w(i.unavailable,"net: mounted host changed while requests are pending");let k=c.start(x,h.buffer);if(!Number.isInteger(k)||k<0){let q=c.lastError()||"unavailable: request refused",D=q.indexOf(":"),b=B(D<0?i.other:q.slice(0,D)),_=D<0?q:q.slice(D+1).trim();return Q(b,_)}return new Promise((q,D)=>{if(l.set(k,{ops:c,resolve:q,reject:D}),u=c,!A)A=Y(W)})}catch(r){return r instanceof w?Promise.reject(r):Q(i.invalidRequest,String(r))}}var H=globalThis.db,$=H.open("exa");if($<0)throw Error("open exa.sqlite");var s=5,ff=7,nf=ff*24*60*60;function cf(){return String(H.lastError($)||"SQLite operation failed")}function G(f){if(H.exec($,f)!==0)throw Error(cf())}function N(f,n=[]){let c=JSON.parse(H.query($,f,JSON.stringify(n)));if(c.error)throw Error(String(c.error));return c}function g(f,n=[]){return N(f,n)}var rf=Number(N("PRAGMA user_version")?.rows?.[0]?.[0]??0);if(rf!==s)G(` DROP TABLE IF EXISTS searches; CREATE TABLE searches ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -10,5 +10,5 @@ error TEXT ); CREATE INDEX searches_retention ON searches(searched_at); - PRAGMA user_version=${T}; - `);function af(){return Math.floor(Date.now()/1000)}function y(f){let n=f-nf;W("DELETE FROM searches WHERE searched_at < ?",[n])}async function d(f,n){let c=await P(`https://api.exa.ai${f}`,{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify(n),timeoutMs:cf,maxBytes:98304}),r=await c.json();if(!c.ok)throw Error(`Exa HTTP ${c.status}: ${JSON.stringify(r)}`);return r}function s(f){G("BEGIN IMMEDIATE");try{f(),G("COMMIT")}catch(n){try{G("ROLLBACK")}catch{}throw n}globalThis.app.commit()}async function wf(f){let n=String(f.query??"").trim();if(!n)throw Error("query is required");let c=af();try{let r={query:n,type:f.searchType??"auto",numResults:Math.max(1,Math.min(10,Number(f.numResults??10))),contents:{highlights:{maxCharacters:800}}};for(let x of["includeDomains","excludeDomains","startPublishedDate","endPublishedDate","category","userLocation","additionalQueries","moderation"])if(f[x]!==void 0)r[x]=f[x];if(f.maxAgeHours!==void 0)r.contents.maxAgeHours=f.maxAgeHours;let h=await d("/search",r),a=Array.isArray(h?.results)?h.results:[],L=typeof a[0]?.title==="string"?a[0].title:null;return s(()=>{W("INSERT INTO searches(query,searched_at,status,result_count,top_title,error) VALUES(?,?,?,?,?,NULL)",[n,c,"ok",a.length,L]),y(c)}),h}catch(r){let h=r instanceof Error?r.message:String(r);throw s(()=>{W("INSERT INTO searches(query,searched_at,status,result_count,top_title,error) VALUES(?,?,?,0,NULL,?)",[n,c,"error",h]),y(c)}),r}}async function Lf(f){let n=String(f.url??"").trim();if(!n)throw Error("url is required");let c={urls:[n],text:{maxCharacters:Math.max(200,Math.min(12000,Number(f.maxCharacters??6000))),includeHtmlTags:!1}};if(f.maxAgeHours!==void 0)c.maxAgeHours=f.maxAgeHours;return d("/contents",c)}var u,C=!1;function _(f){return JSON.stringify({text:f instanceof Error?f.message:String(f),isError:!0})}function m(f){if(C)throw Error("Exa Data Action is already running");C=!0,u=void 0,f().then((n)=>{u=JSON.stringify({text:JSON.stringify(n),isError:!1}),C=!1},(n)=>{u=_(n),C=!1})}globalThis.PocketPiData={beginInvokeTask(f){m(async()=>{throw Error("Unknown Exa Data Action: "+f)})},beginInvokeTool(f,n){try{let c=JSON.parse(n);m(()=>f==="research.search"?wf(c):f==="research.fetch"?Lf(c):Promise.reject(Error("Unknown Exa tool: "+f)))}catch(c){u=_(c),C=!1}},tick(){U()},pollResult(){let f=u;return u=void 0,f}};})(); + PRAGMA user_version=${s}; + `);function hf(){return Math.floor(Date.now()/1000)}function y(f){let n=f-nf;g("DELETE FROM searches WHERE searched_at < ?",[n])}async function d(f,n){let c=await P(`https://api.exa.ai${f}`,{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify(n),timeoutMs:globalThis.app.remainingMs(),maxBytes:98304}),r=await c.json();if(!c.ok)throw Error(`Exa HTTP ${c.status}: ${JSON.stringify(r)}`);return r}function T(f){G("BEGIN IMMEDIATE");try{f(),G("COMMIT")}catch(n){try{G("ROLLBACK")}catch{}throw n}globalThis.app.commit()}async function af(f){let n=String(f.query??"").trim();if(!n)throw Error("query is required");let c=hf();try{let r={query:n,type:f.searchType??"auto",numResults:Math.max(1,Math.min(10,Number(f.numResults??10))),contents:{highlights:{maxCharacters:800}}};for(let x of["includeDomains","excludeDomains","startPublishedDate","endPublishedDate","category","userLocation","additionalQueries","moderation"])if(f[x]!==void 0)r[x]=f[x];if(f.maxAgeHours!==void 0)r.contents.maxAgeHours=f.maxAgeHours;let h=await d("/search",r),a=Array.isArray(h?.results)?h.results:[],L=typeof a[0]?.title==="string"?a[0].title:null;return T(()=>{g("INSERT INTO searches(query,searched_at,status,result_count,top_title,error) VALUES(?,?,?,?,?,NULL)",[n,c,"ok",a.length,L]),y(c)}),h}catch(r){let h=r instanceof Error?r.message:String(r);throw T(()=>{g("INSERT INTO searches(query,searched_at,status,result_count,top_title,error) VALUES(?,?,?,0,NULL,?)",[n,c,"error",h]),y(c)}),r}}async function wf(f){let n=String(f.url??"").trim();if(!n)throw Error("url is required");let c={urls:[n],text:{maxCharacters:Math.max(200,Math.min(12000,Number(f.maxCharacters??6000))),includeHtmlTags:!1}};if(f.maxAgeHours!==void 0)c.maxAgeHours=f.maxAgeHours;return d("/contents",c)}var C,I=!1;function R(f){return JSON.stringify({text:f instanceof Error?f.message:String(f),isError:!0})}function m(f){if(I)throw Error("Exa Data Action is already running");I=!0,C=void 0,f().then((n)=>{C=JSON.stringify({text:JSON.stringify(n),isError:!1}),I=!1},(n)=>{C=R(n),I=!1})}globalThis.PocketPiData={beginInvokeTask(f){m(async()=>{throw Error("Unknown Exa Data Action: "+f)})},beginInvokeTool(f,n){try{let c=JSON.parse(n);m(()=>f==="research.search"?af(c):f==="research.fetch"?wf(c):Promise.reject(Error("Unknown Exa tool: "+f)))}catch(c){C=R(c),I=!1}},tick(){W()},pollResult(){let f=C;return C=void 0,f}};})(); diff --git a/apps/pi-agent/dist/app.js b/apps/pi-agent/dist/app.js index 5328bc9..4ffff7f 100644 --- a/apps/pi-agent/dist/app.js +++ b/apps/pi-agent/dist/app.js @@ -1,5 +1,5 @@ (()=>{var kJ={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return H1(this.context.count)},getNextContextId(){return H1(this.context.count++)}};function H1(J){let Q=String(J),$=Q.length-1;return kJ.context.id+($?String.fromCharCode(96+$):"")+Q}function j1(J){kJ.context=J}function q6(){return{...kJ.context,id:kJ.getNextContextId(),count:0}}var X6=!1,Y6=(J,Q)=>J===Q,A0=Symbol("solid-proxy"),z6=typeof Proxy==="function",G6=Symbol("solid-track"),DQ=Symbol("solid-dev-component"),oJ={equals:Y6},K1=null,W6=V1,l=1,yJ=2,F1={owned:null,cleanups:null,context:null,owner:null},S=null,K=null,fJ=null,SJ=null,b=null,E=null,T=null,nJ=0;function tJ(J,Q){let $=b,Z=S,q=J.length===0,X=Q===void 0?Z:Q,z=q?F1:{owned:null,cleanups:null,context:X?X.context:null,owner:X},W=q?J:()=>J(()=>QJ(()=>$J(z)));S=z,b=null;try{return c(W,!0)}finally{b=$,S=Z}}function C(J,Q){Q=Q?Object.assign({},oJ,Q):oJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(q)=>{if(typeof q==="function")if(K&&K.running&&K.sources.has($))q=q($.tValue);else q=q($.value);return R1($,q)};return[U1.bind($),Z]}function JJ(J,Q,$){let Z=D1(J,Q,!1,l);if(fJ&&K&&K.running)E.push(Z);else eJ(Z)}function bJ(J,Q,$){$=$?Object.assign({},oJ,$):oJ;let Z=D1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,fJ&&K&&K.running)Z.tState=l,E.push(Z);else eJ(Z);return U1.bind(Z)}function B6(J){return c(J,!1)}function QJ(J){if(!SJ&&b===null)return J();let Q=b;b=null;try{if(SJ)return SJ.untrack(J);return J()}finally{b=Q}}function _0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function H6(J){if(K&&K.running)return J(),K.done;let Q=b,$=S;return Promise.resolve().then(()=>{b=Q,S=$;let Z;if(fJ||j6)Z=K||(K={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((q)=>Z.resolve=q)),Z.running=!0;return c(J,!1),b=S=null,Z?Z.done:void 0})}var[VQ,M1]=C(!1),j6;function U1(){let J=K&&K.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===l)eJ(this);else{let Q=E;E=null,c(()=>J0(this),!1),E=Q}if(b){let Q=this.observers;if(!Q||Q[Q.length-1]!==b){let $=Q?Q.length:0;if(!b.sources)b.sources=[this],b.sourceSlots=[$];else b.sources.push(this),b.sourceSlots.push($);if(!Q)this.observers=[b],this.observerSlots=[b.sources.length-1];else Q.push(b),this.observerSlots.push(b.sources.length-1)}}if(J&&K.sources.has(this))return this.tValue;return this.value}function R1(J,Q,$){let Z=K&&K.running&&K.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(K){let q=K.running;if(q||!$&&K.sources.has(J))K.sources.add(J),J.tValue=Q;if(!q)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)c(()=>{for(let q=0;q1e6)throw E=[],Error()},!1)}return Q}function eJ(J){if(!J.fn)return;$J(J);let Q=nJ;if(P1(J,K&&K.running&&K.sources.has(J)?J.tValue:J.value,Q),K&&!K.running&&K.sources.has(J))queueMicrotask(()=>{c(()=>{K&&(K.running=!0),b=S=J,P1(J,J.tValue,Q),b=S=null},!1)})}function P1(J,Q,$){let Z,q=S,X=b;b=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(K&&K.running)J.tState=l,J.tOwned&&J.tOwned.forEach($J),J.tOwned=void 0;else J.state=l,J.owned&&J.owned.forEach($J),J.owned=null;return J.updatedAt=$+1,S0(z)}finally{b=X,S=q}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)R1(J,Z,!0);else if(K&&K.running&&J.pure){if(!K.sources.has(J))J.value=Z;K.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function D1(J,Q,$,Z=l,q){let X={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(K&&K.running)X.state=0,X.tState=Z;if(S===null);else if(S!==F1)if(K&&K.running&&S.pure)if(!S.tOwned)S.tOwned=[X];else S.tOwned.push(X);else if(!S.owned)S.owned=[X];else S.owned.push(X);if(SJ&&X.fn){let z=X.fn,[W,U]=C(void 0,{equals:!1}),P=SJ.factory(z,U);_0(()=>P.dispose());let D,B=()=>H6(U).then(()=>{if(D)D.dispose(),D=void 0});X.fn=(_)=>{if(W(),K&&K.running){if(!D)D=SJ.factory(z,B);return D.track(_)}return P.track(_)}}return X}function k0(J){let Q=K&&K.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===yJ)return J0(J);if(J.suspense&&QJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let q=J,X=$[Z+1];while((q=q.owner)&&q!==X)if(K.disposed.has(q))return}if((Q?J.tState:J.state)===l)eJ(J);else if((Q?J.tState:J.state)===yJ){let q=E;E=null,c(()=>J0(J,$[0]),!1),E=q}}}function c(J,Q){if(E)return J();let $=!1;if(!Q)E=[];if(T)$=!0;else T=[];nJ++;try{let Z=J();return K6($),Z}catch(Z){if(!$)T=null;E=null,S0(Z)}}function K6(J){if(E){if(fJ&&K&&K.running)F6(E);else V1(E);E=null}if(J)return;let Q;if(K){if(!K.promises.size&&!K.queue.size){let{sources:Z,disposed:q}=K;T.push.apply(T,K.effects),Q=K.resolve;for(let X of T)"tState"in X&&(X.state=X.tState),delete X.tState;K=null,c(()=>{for(let X of q)$J(X);for(let X of Z){if(X.value=X.tValue,X.owned)for(let z=0,W=X.owned.length;zW6($),!1);if(Q)Q()}function V1(J){for(let Q=0;Q{Z.delete($),c(()=>{K.running=!0,k0($)},!1),K&&(K.running=!1)})}}function J0(J,Q){let $=K&&K.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)$J(J.tOwned[Q]);delete J.tOwned}if(K&&K.running&&J.pure)O1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)$J(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(K&&K.running)J.tState=0;else J.state=0}function O1(J,Q){if(!Q)J.tState=0,K.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return _0(()=>A1(X)),()=>{let U=J()||[],P=U.length,D,B;return U[G6],QJ(()=>{let g,w,a,HJ,IJ,F,j,H,L;if(P===0){if(z!==0)A1(X),X=[],Z=[],q=[],z=0,W&&(W=[]);if($.fallback)Z=[U6],q[0]=tJ((A)=>{return X[0]=A,$.fallback()}),z=1}else if(z===0){q=Array(P);for(B=0;B=F&&H>=F&&Z[j]===U[H];j--,H--)a[H]=q[j],HJ[H]=X[j],W&&(IJ[H]=W[j]);g=new Map,w=Array(H+1);for(B=H;B>=F;B--)L=U[B],D=g.get(L),w[B]=D===void 0?-1:D,g.set(L,B);for(D=F;D<=j;D++)if(L=Z[D],B=g.get(L),B!==void 0&&B!==-1)a[B]=q[D],HJ[B]=X[D],W&&(IJ[B]=W[D]),B=w[B],g.set(L,B);else X[D]();for(B=F;BJ(Q||{}));return j1($),Z}}return QJ(()=>J(Q||{}))}function Q0(){return!0}var V6={get(J,Q,$){if(Q===A0)return $;return J.get(Q)},has(J,Q){if(Q===A0)return!0;return J.has(Q)},set:Q0,deleteProperty:Q0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:Q0,deleteProperty:Q0}},ownKeys(J){return J.keys()}};function b0(J){return!(J=typeof J==="function"?J():J)?{}:J}function L6(){for(let J=0,Q=this.length;J=0;W--){let U=b0(J[W])[z];if(U!==void 0)return U}},has(z){for(let W=J.length-1;W>=0;W--)if(z in b0(J[W]))return!0;return!1},keys(){let z=[];for(let W=0;W=0;z--){let W=J[z];if(!W)continue;let U=Object.getOwnPropertyNames(W);for(let P=U.length-1;P>=0;P--){let D=U[P];if(D==="__proto__"||D==="constructor")continue;let B=Object.getOwnPropertyDescriptor(W,D);if(!Z[D])Z[D]=B.get?{enumerable:!0,configurable:!0,get:L6.bind($[D]=[B.get.bind(W)])}:B.value!==void 0?B:void 0;else{let _=$[D];if(_){if(B.get)_.push(B.get.bind(W));else if(B.value!==void 0)_.push(()=>B.value)}}}}let q={},X=Object.keys(Z);for(let z=X.length-1;z>=0;z--){let W=X[z],U=Z[W];if(U&&U.get)Object.defineProperty(q,W,U);else q[W]=U?U.value:void 0}return q}var O6=(J)=>`Stale read from <${J}>.`;function jJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return bJ(R6(()=>J.each,J.children,Q||void 0))}function ZJ(J){let Q=J.keyed,$=bJ(()=>J.when,void 0,void 0),Z=Q?$:bJ($,void 0,{equals:(q,X)=>!q===!X});return bJ(()=>{let q=Z();if(q){let X=J.children;return typeof X==="function"&&X.length>0?QJ(()=>X(Q?q:()=>{if(!QJ(Z))throw O6("Show");return $()})):X}return J.fallback},void 0,void 0)}var I6=(J)=>bJ(()=>J());function A6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:q,removeNode:X,setProperty:z,getParentNode:W,getFirstChild:U,getNextSibling:P}){function D(F,j,H,L){if(H!==void 0&&!L)L=[];if(typeof j!=="function")return B(F,j,L,H);JJ((A)=>B(F,j(),A,H),L)}function B(F,j,H,L,A){while(typeof H==="function")H=H();if(j===H)return H;let k=typeof j,I=L!==void 0;if(k==="string"||k==="number"){if(k==="number")j=j.toString();if(I){let O=H[0];if(O&&$(O))Z(O,j);else O=Q(j);H=w(F,H,L,O)}else if(H!==""&&typeof H==="string")Z(U(F),H=j);else w(F,H,L,Q(j)),H=j}else if(j==null||k==="boolean")H=w(F,H,L);else if(k==="function")return JJ(()=>{let O=j();while(typeof O==="function")O=O();H=B(F,O,H,L)}),()=>H;else if(Array.isArray(j)){let O=[];if(_(O,j,A))return JJ(()=>H=B(F,O,H,L,!0)),()=>H;if(O.length===0){let TJ=w(F,H,L);if(I)return H=TJ}else if(Array.isArray(H))if(H.length===0)a(F,O,L);else g(F,H,O);else if(H==null||H==="")a(F,O);else g(F,I&&H||[U(F)],O);H=O}else{if(Array.isArray(H)){if(I)return H=w(F,H,L,j);w(F,H,null,j)}else if(H==null||H===""||!U(F))q(F,j);else HJ(F,j,U(F));H=j}return H}function _(F,j,H){let L=!1;for(let A=0,k=j.length;Ar-O){let PQ=j[I];while(O=0;I--){let O=j[I];if(A!==O){let TJ=W(O)===F;if(!k&&!I)TJ?HJ(F,A,O):q(F,A,H);else TJ&&X(F,O)}else k=!0}}else q(F,A,H);return[A]}function a(F,j,H){for(let L=0,A=j.length;LH.children=B(F,j.children,H.children));return JJ(()=>j.ref&&j.ref(F)),JJ(()=>{for(let A in j){if(A==="children"||A==="ref")continue;let k=j[A];if(k===H[A])continue;z(F,A,k,H[A]),H[A]=k}}),H}return{render(F,j){let H;return tJ((L)=>{H=L,D(j,F())}),H},insert:D,spread(F,j,H){if(typeof j==="function")JJ((L)=>IJ(F,j(),L,H));else IJ(F,j,void 0,H)},createElement:J,createTextNode:Q,insertNode:q,setProp(F,j,H,L){return z(F,j,H,L),H},mergeProps:_1,effect:JJ,memo:I6,createComponent:D6,use(F,j,H){return QJ(()=>F(j,H))}}}function _6(J){let Q=A6(J);return Q.mergeProps=_1,Q}var k1=480,S1=272,KJ={view:0,text:1,image:2},k6=1,S6=-1,b6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},R={f32:0,color:1,int:2},g6={width:R.f32,height:R.f32,minW:R.f32,minH:R.f32,maxW:R.f32,maxH:R.f32,paddingT:R.f32,paddingR:R.f32,paddingB:R.f32,paddingL:R.f32,marginT:R.f32,marginR:R.f32,marginB:R.f32,marginL:R.f32,gap:R.f32,flexDir:R.int,justify:R.int,align:R.int,grow:R.f32,shrink:R.f32,basis:R.f32,flexWrap:R.int,posType:R.int,insetT:R.f32,insetR:R.f32,insetB:R.f32,insetL:R.f32,display:R.int,overflow:R.int,zIndex:R.int,hitPass:R.int,bgColor:R.color,gradFrom:R.color,gradTo:R.color,gradDir:R.int,radius:R.f32,opacity:R.f32,borderColor:R.color,borderWidth:R.f32,shadow:R.int,bevelOuterLight:R.color,bevelOuterDark:R.color,bevelInnerLight:R.color,bevelInnerDark:R.color,bevelWidth:R.f32,textColor:R.color,fontSlot:R.int,textAlign:R.int,lineHeight:R.f32,tracking:R.f32,translateX:R.f32,translateY:R.f32,scale:R.f32,rotate:R.f32,scaleX:R.f32,scaleY:R.f32,originX:R.f32,originY:R.f32,rotateX:R.f32,rotateY:R.f32,translateZ:R.f32,perspective:R.f32,arcStart:R.f32,arcSweep:R.f32,arcWidth:R.f32},u={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},w6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},C6=1,LQ=2,OQ=1,IQ=2,AQ=131072,_Q=1,kQ=262144,SQ=1,bQ=1,gQ=1,wQ=2,CQ=4,NQ=8,EQ=16,hQ=1,TQ=2;function b1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var yQ=1,N6=1263551300,E6=1,h6=32,T6=24,d={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},FJ=32896,fQ=0.016666666666666666;function g1(J){return J.__viewport??null}var g0=null;function y6(){return null}function w1(J,Q=y6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function f6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return w1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return w1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function x6(J){g0=J}function gJ(){if(!g0)throw Error("PocketJS: host not installed — call render() first");return g0}function h(){return gJ().ops}function v6(J){globalThis.frame=J}function m6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(q,X)=>J(q,X);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function l6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return b1($>>>16&255,$>>>8&255,$&255,255);return b1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function u6(J,Q){let $=g6[J];if(typeof Q==="string"){if($===R.color)return l6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===R.color||$===R.int)return Q>>>0;return Q}var $0=60,C1=[1,2,3,4,5,6,10,12,15,20,30,60],w0=$0,qJ=-1,p6=0,xJ=[];function c6(J){if(!Number.isFinite(J)||J<=0)return $0;let Q=C1[0];for(let $ of C1)if(Math.abs($-J)Q.at<=qJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;xJ=xJ.filter((Q)=>Q.at>qJ);for(let Q of J)Q.cb()}var C0=0.12,Z0=FJ;function a6(J){Z0=J===void 0?FJ:J&65535}function r6(){Z0=FJ}function h1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function n6(){return h1(Z0&255)}var T1=new Set,t6=0;function e6(){T1.clear(),t6=0,r6()}function J8(J){for(let Q of[...T1])Q(J)}var MJ=null,y1=null;function Q8(J,Q,$){let Z="";for(let q=0;q<$;q++)Z+=String.fromCharCode(J[Q+q]);return Z}function f1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){N0();let Q=MJ?MJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return y1.slice(Q.off,Q.off+Q.len)}var mJ=null,N=null,UJ=null,q0=0,RJ=[],h0=[],T0=[];function v1(J){if(mJ=J,N=null,UJ=null,q0=0,RJ.length=0,h0.length=0,T0.length=0,p){if(p.pressTarget=null,p.target=null,p.spriteDirty=!0,p.fresh=!0,p.vw=0,p.tex>=0){let Q=h();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(p.tex),p.tex=-1}}}function Z8(J,Q){J.onPress=Q??void 0}function q8(J,Q){if(J.focusable=Q,c1(),!Q&&N===J)x(null)}function x(J){if(UJ&&UJ!==J)PJ(null);N=J,h().setFocus(J?J.id:0)}function PJ(J){if(UJ===J)return;let Q=h();if(UJ)Q.setActive?.(UJ.id,0);if(UJ=J,J)Q.setActive?.(J.id,1)}function y0(){return RJ.length>0?RJ[RJ.length-1]:mJ}function f0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;x($[q])}function z8(){if(!N)return null;let J=y0();if(J&&!i(N,J))return null;for(let Q=h0.length-1;Q>=0;Q--){let $=h0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(N,$.node))return $}return null}function G8(J){let Q=z8();if(!Q)return!1;let $=[];if(f0(Q.node,$),$.length===0){if(N)x(null);return!0}let Z=Q.columns,q=N?$.indexOf(N):-1;if(q<0)return x(m1(J)===1?$[0]:$[$.length-1]),!0;let X=q;switch(J){case"right":if(q+1<$.length&&q%Z0)X=q-1;else if(Q.wrap)X=Math.min($.length-1,Math.floor(q/Z)*Z+Z-1);break;case"down":if(q+Z<$.length)X=q+Z;else if(Q.wrap)X=q%Z;break;case"up":if(q-Z>=0)X=q-Z;else if(Q.wrap){X=q%Z;while(X+Z<$.length)X+=Z}break}if(X!==q)x($[X]);return!0}function W8(){if(!N)return null;let J=y0();if(J&&!i(N,J))return null;for(let Q=T0.length-1;Q>=0;Q--){let $=T0[Q];if(J&&!i($.node,J)&&!i(J,$.node))continue;if(i(N,$.node))return $}return null}function X0(J){let Q=W8();if(Q&&Q.move(J))return;if(G8(J))return;Y8(J)}function l1(){u1(N)}function u1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){PJ(J)}function B8(J){x(J),u1(J)}function i(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function x0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;q--){let X=x0(Q.children[q]);if(X){x(X);return}}let Z=Q;while(Z){if(Z.focusable){x(Z);return}Z=Z.parent}}x(null)}var p=null,p1=0;function c1(){p1++}var j8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],K8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function F8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=j8[Q]>>$&1,q=K8[Q]>>$&1;if(!Z&&!q)continue;let X=(Q*16+$)*4,z=q?255:0;J[X]=z,J[X+1]=z,J[X+2]=z,J[X+3]=255}return J}function M8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,q=-1,X=null;if(typeof $.image==="string")try{X=vJ($.image)}catch(z){if(gJ().strict)throw z;X=null}else if($.image)X=$.image;if(X){if(q=Q.uploadImgEntry?Q.uploadImgEntry(X):U8(Q,X),q<0&&gJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(q<0)q=Q.uploadTexture(F8(),16,16,w6.PSM_8888);if(J.tex=q,Q.setCursor(q,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==q)Q.freeTexture?.(Z)}function U8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&C6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function z0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let q=z0($[Z],Q);if(q)return q}return null}var G0=null;function d1(J){G0=J}function i1(J){let Q=RJ.length>0?RJ[RJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||i($,Q)))return $;$=$.parent}return null}function s1(J,Q,$){return i1(a1(J,Q,$))}function a1(J,Q,$){if($!==void 0)return $===0?null:z0(G0??mJ,$);let Z=h(),q=Z.hitTestBounds??Z.hitTest;if(!q)return null;return z0(G0??mJ,q(J,Q))}function R8(J,Q,$){let Z=p,q=h();if(!q.hitTest||!q.setCursor||!q.setCursorPos)return!1;if(Z.vw===0){let B=g1(q);if(Z.vw=B?B.w:k1,Z.vh=B?B.h:S1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)M8(Z,q);let X=o6()*Z.speed,z=n6()*Z.speed;if(Z.dpadSpeed>0&&X===0&&z===0){if(J&d.LEFT)X=-Z.dpadSpeed;if(J&d.RIGHT)X=Z.dpadSpeed;if(J&d.UP)z=-Z.dpadSpeed;if(J&d.DOWN)z=Z.dpadSpeed}let W=Z.fresh;if(X!==0||z!==0){let B=d6()/60,_=Math.min(Math.max(Z.x+X*B,0),Z.vw-1),g=Math.min(Math.max(Z.y+z*B,0),Z.vh-1);if(_!==Z.x||g!==Z.y)Z.x=_,Z.y=g,W=!0}if(W)q.setCursorPos(Z.x,Z.y);let U=(Q|$)&Z.button,P=p1;if(W||U!==0||P!==Z.gen)Z.gen=P,Z.fresh=!1,Z.target=i1(z0(G0??mJ,q.hitTest(Z.x,Z.y)));let D=Z.target;if(D!==N)x(D);if(Q&Z.button&&D)Z.pressTarget=D;if(Z.pressTarget){if(PJ(D===Z.pressTarget?Z.pressTarget:null),$&Z.button){let B=D===Z.pressTarget;if(Z.pressTarget=null,PJ(null),B)l1()}}else if($&Z.button)PJ(null);return!0}function P8(J){let Q=J&~q0,$=q0&~J;if(q0=J,p&&R8(J,Q,$))return;if($&d.CIRCLE)PJ(null);if(Q===0)return;if(Q&d.DOWN)X0("down");if(Q&d.RIGHT)X0("right");if(Q&d.UP)X0("up");if(Q&d.LEFT)X0("left");if(Q&d.CIRCLE)PJ(N),l1()}var v0=null;function r1(J){v0=J}function wJ(){if(c1(),v0)v0()}function D8(J,Q){J.debugName=Q||void 0,wJ()}var XJ={id:k6,type:KJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},o1=Symbol.for("pocketjs.native-node"),m0=1,lJ=3,o=8,V8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function W0(J){return J.domAttrs??={}}function n1(J,Q){let $=J.domNodeType??(uJ(J)?lJ:m0),Z=$===lJ?B0(J.text??""):$===o?I8(J.domData??""):q4(J.domTag??j0(J));for(let q of Object.keys(J.domAttrs??{}))l0(Z,q,J.domAttrs[q]);if(Q)for(let q of J.children)YJ(Z,n1(q,!0));return Z}function l0(J,Q,$){if(V8.has(Q)){NJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete W0(J)[Q];else W0(J)[Q]=$}function u0(J){if(J[o1]===!0)return J;return Object.defineProperty(J,o1,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?lJ:m0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else H0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===o?J.domData??"":J.text??""},set($){if(J.domNodeType===o)J.domData=String($??"");else H0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===o)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===o)J.domData=Z;else if(uJ(J))H0(J,Z);else if(w8(J),Z)YJ(J,B0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return Y4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??j0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===lJ)return"#text";if(J.domNodeType===o)return"#comment";return(J.domTag??j0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){NJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===XJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return YJ(J,$),$},insertBefore($,Z){return YJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return YJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return n1(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){l0(J,$,Z)},removeAttribute($){l0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}u0(XJ);var p0=null;function L8(J){p0=J}var c0={unknownClass:0,unknownTexture:0},t1=new Map;function e1(J,Q){t1.set(J,Q)}var J4=new Map;function Q4(J,Q){J4.set(J,Q)}var CJ=new Set,O8=new Set;function $4(J){if(!J)return!1;if(O8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return u0({id:h().createNode(Q),type:Q,parent:null,children:[],domNodeType:m0,domTag:J})}function B0(J){let Q=h(),$=Q.createNode(KJ.text);return Q.setText($,J),u0({id:$,type:KJ.text,parent:null,children:[],text:J,domNodeType:lJ,domTag:"#text"})}function I8(J=""){let Q=B0("");return Q.domNodeType=o,Q.domTag="#comment",Q.domData=J,Q}function H0(J,Q){h().replaceText(J.id,Q),J.text=Q,wJ()}function uJ(J){return J.type===KJ.text}function X4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function YJ(J,Q,$){let Z=h();if(X4(Q),CJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let q=J.children.indexOf($);if(q<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(q,0,Q)}else J.children.push(Q);Q.parent=J,wJ()}function pJ(J,Q){if(!Q)return;H8(Q),h().removeChild(J.id,Q.id),X4(Q),CJ.add(Q),wJ()}function A8(J){return J.parent??void 0}function _8(J){return J.children[0]}function Y4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function k8(J,Q){let $=h();if(wJ(),Q==null||Q===""){$.setStyle(J.id,S6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=p0?p0(Q):void 0;if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);c0.unknownClass++;return}$.setStyle(J.id,Z)}function S8(J,Q){let $=h();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=t1.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);c0.unknownTexture++;return}$.setImage(J.id,Z)}function b8(J,Q){let $=h();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=J4.get(Q);if(Z===void 0){if(gJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);c0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function g8(J,Q,$){let Z=h(),q=Q??{},X=$??{},z=!1;for(let W in q){let U=q[W];if(X[W]===U)continue;let P=b6[W];if(P===void 0)throw Error(`PocketJS: unknown style prop '${W}' (see spec PROP)`);Z.setProp(J.id,P,u6(W,U)),z=!0}if(z)wJ()}function NJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete W0(J)[Q];else W0(J)[Q]=$;switch(Q){case"class":return k8(J,$),$;case"onPress":case"on:press":return Z8(J,$),$;case"src":return S8(J,$),$;case"sprite":return b8(J,$),$;case"style":return g8(J,$,Z),$;case"focusable":return q8(J,!!$),$;case"debugName":return D8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${j0(J)}>`)}function w8(J){for(let Q of[...J.children])pJ(J,Q)}function j0(J){for(let Q of Object.keys(KJ))if(KJ[Q]===J.type)return Q;return String(J.type)}function C8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}NJ(J,Q,$,Z)}var N8=_6({createElement:q4,createTextNode:B0,replaceText:H0,isTextNode:uJ,setProperty:C8,insertNode(J,Q,$){YJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:A8,getFirstChild:_8,getNextSibling:Y4}),{render:E8,effect:xQ,memo:v,createComponent:Y,createElement:z4,insert:vQ,spread:h8,mergeProps:mQ,use:lQ}=N8,uQ={linear:u.Easing.Linear,in:u.Easing.EaseIn,out:u.Easing.EaseOut,"in-out":u.Easing.EaseInOut,"out-back":u.Easing.OutBack,spring:u.Easing.Spring,"spring-bouncy":u.Easing.SpringBouncy},T8=null;function G4(J){T8=J}function y8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function W4(J,Q){let $=z4(J);return h8($,Q,!1),y8(Q.nodeRef,$),$}function M(J){return W4("view",J)}function V(J){return W4("text",J)}var pQ=new WeakMap,cQ=new WeakMap,f8={}!==null?Object.freeze({...{}}):Object.freeze({}),dQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:f8}),iQ=new Map,zJ=36000,d0=30,x8=30,G={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(zJ),tapeAnalog:new Uint16Array(zJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-d0,saidHello:!1,hostCalls:0};function v8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};G.ops=J,G.frame=0,G.tapeStart=0,G.tapeLen=0,G.tapeFirstFrame=0,G.tapeTouch=null,G.replayMasks=null,G.replayAnalog=null,G.replayTouch=null,G.paused=!1,G.stepQueued=0,G.inspectReportId=null,G.inspectAskedAt=0,G.treeDirty=!0,G.treeSentAt=-d0,G.saidHello=!1,G.hostCalls=0,G.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)G.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)G.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else G.transport=null;if(G.transport)r1(()=>{G.treeDirty=!0}),s8();else r1(null);globalThis.__pocketDevtools=r8}function m8(J){return(Q,$,Z,q)=>{if(G.hostCalls++,G.transport)u8(),d8();let X=Q,z=$===void 0?FJ:$&65535,W=Z,U=q;if(G.replayMasks)if(G.replayAt0?$.slice(0,8):null;if(Z&&!G.tapeTouch)G.tapeTouch=Array(zJ).fill(null);if(G.tapeLen1||Q.length===1&&Q[0][0]!==FJ)J.analog=Q;if(G.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function j4(J,Q,$){let Z=new Uint16Array($).fill(Q),q=0;for(let[X,z]of J)Z.fill(X,q,Math.min(q+z,$)),q+=z;return Z}function K4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return j4(J.masks,0,Q)}function F4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return j4(J.analog??[],FJ,Q)}function M4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,q]of J.touch??[])if(Z>=0&&Z1&&G.hostCalls%Q!==0)return;if(!G.saidHello)G.saidHello=!0,y({t:"hello",app:G.app,host:a8(),frame:G.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let q of Z.split(` -`))if(q.trim())p8(q)}}function p8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=G.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),G.inspectReportId=Z||null,G.inspectAskedAt=G.hostCalls,!Z)y({t:"inspect",id:0,rect:null});break}case"pause":G.paused=!0,G.stepQueued=0,$?.debugPause?.(!0),i0();break;case"resume":G.paused=!1,$?.debugPause?.(!1),i0();break;case"step":G.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":U4();break;case"eval":{let Z=!0,q;try{q=K0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}y({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":y({t:"tape",tape:H4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}y({t:"devStats",frame:G.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())y({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:G.frame});else y({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))G.replayMasks=K4(Z),G.replayAnalog=Z.analog?F4(Z):null,G.replayTouch=Z.touch?M4(Z):null,G.replayAt=0;break}default:break}}function c8(){if(G.treeDirty&&G.frame-G.treeSentAt>=d0)U4();if(G.frame%x8===0)i0()}function d8(){let J=G.inspectReportId;if(J==null)return;let Q=G.ops;if(!Q?.debugRectXY||!Q.debugRectWH){G.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(G.hostCalls-G.inspectAskedAt>60)G.inspectReportId=null,y({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();G.inspectReportId=null,y({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function i0(){y({t:"stats",frame:G.frame,nodes:D4(XJ),tapeLen:G.tapeLen,paused:G.paused})}function U4(){G.treeDirty=!1,G.treeSentAt=G.frame,y({t:"tree",frame:G.frame,root:P4(XJ)})}function i8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function s0(J,Q){if(Array.isArray(J)){for(let $ of J)s0($,Q);return}if(i8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)s0($,Q)}}function R4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)s0(Z,Q)}function P4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(R4(J,(q)=>{if(q.domNodeType===8)return;Z.push(P4(q))}),Z.length)Q.k=Z;return Q}function D4(J){let Q=1;return R4(J,($)=>{Q+=D4($)}),Q}function s8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{y({t:"log",level:$,args:q.map((X)=>K0(X))}),Z?.apply(Q,q)}}}function K0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?V4(X):JSON.stringify(V4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>K0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${K0(z,Q+1)}`).join(", ")}}`}function V4(J){return J.length>200?J.slice(0,199)+"…":J}function a8(){let J=G.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var r8={get frame(){return G.frame},dumpTape:()=>H4(),replay:(J)=>{G.replayMasks=K4(J),G.replayAnalog=J.analog?F4(J):null,G.replayTouch=J.touch?M4(J):null,G.replayAt=0}},L4=new Map,a0=new Map;function O4(J){return J.trim().replace(/\s+/g," ")}function I4(J){return J.split(" ").sort().join(" ")}var A4=-1;function o8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=O4(Q);L4.set(Z,$);let q=I4(Z),X=a0.get(q);a0.set(q,X!==void 0&&X!==$?A4:$)}}function n8(J){let Q=O4(J),$=L4.get(Q);if($!==void 0)return $;let Z=a0.get(I4(Q));return Z===A4?void 0:Z}var r0=9,t8=(1<{let q=($&J2)!==0,X=q?o0:r0,z=q?Q2:t8;return Object.freeze({id:$>>>(q?$2:e8)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function q2(){return F0}function X2(){F0=n0}var _4=8,GJ=8,Y2=3,z2=8,G2=6,W2=0.5,s=1,cJ=2,t0=4,DJ=8,EJ=[],k4=0,M0=0,WJ=Array.from({length:_4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(GJ),histY:new Int16Array(GJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function B2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function H2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=a1(Q,$,Z.fact);let W=Z.hit;if(W)return B2(W,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let W=EJ[z];if(W.disposed)continue;if(k4>0&&!W.opts.allowWhenBlocked)continue;if(!H2(W,$,Z,X))continue;W.flags[J.slot]=s,J.owners.push(W)}for(let z of J.owners)z.opts.onDown?.(J)}function F2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%GJ,J.histLenz||Z>z))q.flags[J.slot]|=cJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(cJ|t0))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??W2)*N1()));if(J.frames=0)EJ.splice($,1)},cancel(){if(!Q.disposed)g4(Q)},get panning(){for(let $ of WJ)if($.used&&Q.flags[$.slot]&DJ)return!0;return!1}}}function D2(J){let Q=P2(J);return _0(()=>Q.dispose()),Q}function w4(){EJ.length=0,k4=0,M0=0;for(let J of WJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function V2(){return D2({onDown:(J)=>{let Q=s1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=s1(J.x,J.y,J.hit);if(Q)B8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var L2=1,e0=new Map,U0=[];function O2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function I2(){L2=1,e0.clear(),U0=[]}function A2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=e0.get(Q);if(!Z)continue;e0.delete(Q),O2()?.({t:"delivery",frame:E1(),id:Q,kind:Z.kind}),Z.onResult($)}}var C4=new Set;function _2(){if(C4.size===0)return;for(let J of C4)J()}var k2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[318] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[30] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-lg text-orange-600 font-bold":9,"h-[84] pt-3 text-xl text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-lg text-emerald-700 font-bold":13,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":14,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":15,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":16,"text-base text-slate-600 font-bold":17,"pt-6 text-lg text-slate-500":18,"pt-6 text-lg text-slate-900 font-bold":19,"h-[146] px-6 pt-7 flex-col bg-slate-50":20,"h-[80]":21,"h-[1060] px-6 pt-5 flex-col":22,"h-[48] px-4 justify-center bg-slate-100":23,"text-base text-slate-600":24,"pt-[10] flex-col gap-[12]":25,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":26,"w-[48] h-[48] items-center justify-center bg-blue-100":27,"w-[48] h-[48] items-center justify-center bg-emerald-100":28,"text-lg text-blue-700 font-bold":29,"w-[474] flex-col gap-2":30,"text-lg text-slate-900 font-bold":31,"text-base text-slate-500":32,"pt-20 pl-10 text-lg text-slate-500":33,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":34,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":35,"h-[1060] px-6 pt-7 flex-col gap-4":36,"text-base text-slate-500 font-bold":37,"h-[214] px-7 items-center justify-center bg-slate-100":38,"text-lg text-slate-500 font-bold":39,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":40,"flex-row items-center gap-5":41,"w-[68] h-[68] items-center justify-center bg-orange-100":42,"text-xl text-orange-700 font-bold":43,"w-[500] flex-col gap-2":44,"text-xl text-slate-900 font-bold":45,"text-lg text-slate-600":46,"text-2xl text-orange-600":47,"mt-4 h-[112] px-6 justify-center bg-slate-100":48,"relative h-[154] px-5 pt-5 flex-col bg-white":49,"pt-3 text-lg text-orange-600 font-bold":50,"pt-3 text-base text-slate-500":51,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":52,"text-lg text-white font-bold":53,"h-[40] pt-3 text-base text-slate-500":54,"h-[470] flex-col gap-2":55,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":56,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":57,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":58,"h-[160] px-5 pt-5 flex-col bg-white":59,"pt-3 text-lg text-slate-900 font-bold":60,"pt-3 text-base text-slate-600":61,"h-[108] pt-7 flex-row gap-4":62,"w-[316] h-[80] items-center justify-center bg-slate-100":63,"w-[340] h-[80] items-center justify-center bg-red-100":64,"text-lg text-red-500 font-bold":65,"h-[1052] px-6 pt-5 flex-col":66,"h-[270] px-[22] pt-6 bg-white":67,"text-lg text-slate-900":68,"text-lg text-slate-400":69,"h-[86] px-1 flex-row items-center justify-between":70,"w-[132] h-[58] items-center justify-center bg-slate-300":71,"w-[132] h-[58] items-center justify-center bg-slate-100":72,"text-base text-slate-900 font-bold":73,"h-[140] flex-row gap-2":74,"grow h-[120] items-center justify-center bg-slate-300":75,"grow h-[120] items-center justify-center bg-white":76,"w-[104] h-[120] items-center justify-center bg-slate-300":77,"w-[104] h-[120] items-center justify-center bg-slate-100":78,"h-[176] flex-row gap-2":79,"w-[92] h-[156] items-center justify-center bg-slate-300":80,"w-[92] h-[156] items-center justify-center bg-slate-100":81,"w-[300] h-[156] items-center justify-center bg-slate-300":82,"w-[300] h-[156] items-center justify-center bg-slate-100":83,"w-[144] h-[156] items-center justify-center bg-slate-300":84,"w-[144] h-[156] items-center justify-center bg-slate-100":85,"w-[112] h-[156] items-center justify-center bg-emerald-700":86,"w-[112] h-[156] items-center justify-center bg-emerald-500":87,"text-base text-slate-950 font-bold":88,"h-[108] px-6 py-3 flex-col bg-slate-50":89,"h-[84] items-center justify-center bg-slate-300":90,"h-[84] items-center justify-center bg-slate-100":91,"h-[1168] px-6 pt-5 flex-col":92,"h-[82] px-4 justify-center bg-white":93,"w-[584] h-[900] px-5 pt-5 bg-slate-950":94,"text-base text-slate-200":95,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":96,"w-[584] h-[900] px-5 pt-5 bg-white":97,"text-xl text-slate-900":98,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":99,"absolute inset-0 z-50 flex-col items-center justify-center":100,"absolute inset-0 bg-slate-950":101,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":102,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":103,"flex-row flex-wrap":104,grow:105,"text-2xl text-white font-bold":106,"text-2xl text-slate-950 font-bold":107,"px-6":108,"px-6 py-5":109,"gap-4":110,"rounded-xl shadow bg-white border-slate-100":111,"rounded-xl shadow bg-emerald-100 border-emerald-500":112,"bg-white":113,"bg-slate-100":114,"bg-slate-950":115,"px-3 py-2 rounded-lg bg-slate-100":116,"px-3 py-2 rounded-lg bg-indigo-100":117,"text-base text-indigo-700 font-bold":118,"px-3 py-2 rounded-lg bg-emerald-100":119,"text-base text-emerald-700 font-bold":120,"px-3 py-2 rounded-lg bg-amber-100":121,"text-base text-amber-700 font-bold":122,"px-3 py-2 rounded-lg bg-red-100":123,"text-base text-red-500 font-bold":124,"w-[34] h-[34] rounded-lg bg-amber-400":125,"w-[34] h-[34] rounded-lg bg-red-500":126,"w-[34] h-[34] rounded-lg bg-slate-800":127,"w-[34] h-[34] rounded-lg bg-emerald-500":128,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":129,"flex-row items-center gap-4":130,"w-[34] text-2xl text-white font-bold":131,"w-[332] flex-col items-end gap-2":132,"text-base text-slate-300 font-bold":133,"text-base text-slate-400":134,"h-[166] px-6 pt-6 flex-col gap-3":135,"text-base text-orange-600 font-bold":136,"h-[44] px-1 flex-row items-center justify-between":137,"w-full h-full items-center justify-center rounded-xl bg-slate-200":138,"w-full h-full items-center justify-center rounded-xl bg-red-100":139,"w-full h-full items-center justify-center rounded-xl bg-slate-100":140,"w-full h-full items-center justify-center rounded-xl bg-orange-600":141,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":142,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":143,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":144,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":145,"text-2xl text-indigo-700 font-bold":146,"text-2xl text-slate-600 font-bold":147,"pt-7 text-2xl text-slate-900 font-bold":148,"pt-4 text-lg text-slate-500":149,"text-xl text-emerald-600 font-bold":150,"text-xl text-red-500 font-bold":151,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":152,"text-base text-red-300":153,"text-base text-slate-300":154,"text-base text-red-500":155,"w-full h-full px-6 flex-row items-center bg-slate-950":156,"w-full h-full flex-row items-center":157};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var S2="ui:styles",b2="ui:font.",N4="ui:img.",E4="ui:sprite.";function g2(){return globalThis.ui}function w2(J){if(J.__textures)return;for(let Q of E0(N4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)e1(Q.slice(N4.length),Z)}}function C2(J){if(J.__sprites)return;for(let Q of E0(E4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],W=Z.getUint16(6,!0),U=Z.getUint16(8,!0),P=Z.getUint16(10,!0),D=J.uploadTexture($.subarray(16),q,X,z);if(D>=0)Q4(Q.slice(E4.length),{handle:D,frames:W,cols:U,step:P})}}function h4(J){let Q=z4("view");return NJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function N2(J,Q){if(!R0||!P0)return;NJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),NJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=h();$.__viewport={w:J,h:Q}}function E2(J,Q={}){let $=f6(Q.ops);if(x6($),L8(n8),Q.styles)o8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)e1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)Q4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)x1(Q.pak);if($8()){for(let B of E0())if(B===S2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(b2))$.ops.loadFontAtlas?.(vJ(B))}}let q=g1($.ops),X=q?.w??k1,z=q?.h??S1,W=h4({width:X,height:z,overflow:u.Overflow.Hidden}),U=h4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});YJ(XJ,W),YJ(XJ,U),G4(U),R0=W,P0=U,v1(W),d1(XJ),e6(),w4(),V2(),i6(),I2(),v8($.ops),v6(m8((B,_,g,w)=>{s6(),a6(_),Z2(g,w),_2(),A2(),R2(),J8(B),P8(B),Z4()}));let P=E8(J,W),D=m6(N2);return()=>{D(),X2(),w4(),P(),v1(null),d1(null),G4(null),R0=null,P0=null;for(let B of XJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);Z4()}}function h2(J,Q={}){let $=Q.ops??g2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)x1(Q.pak);return w2($),C2($),E2(J,{ops:$,styles:Q.styles??k2,pak:Q.pak})}var T2="$b",y2=65536,T4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function v2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function y4(){let J=v2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function m2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,y2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let W=f2(z.data[T2]);if($.push(W),Z+=W.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function l2(J,Q){let $=m2(y4(),J);return Q==="utf8"||Q==="utf-8"?x2($):$}function u2(J,Q){let $=y4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var p2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"};function c2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(M,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(M,{class:"flex-row items-center gap-4",get children(){return[v(()=>v(()=>!!J.back)()?Y(V,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(M,{get["class"](){return Q()}})),Y(V,{get["class"](){return p2.appTitle},get children(){return J.title}})]}}),Y(M,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(V,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(V,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function d2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(M,{get["class"](){return Q()},get children(){return Y(V,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(M,{get["class"](){return J.top},get children(){return Y(V,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(M,{get["class"](){return J.bottom},get children(){return Y(V,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var sQ="‘’“”–—…•",i2=512;function s2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let W=Q(z);if(q&&X+W>$)Z.push(q),q="",X=0;q+=z,X+=W}if(q)Z.push(q);return Z}function f4(J,Q,$){let Z=new Map,q=(W)=>{let U=Z.get(W);if(U===void 0)U=h().measureText(W,Q),Z.set(W,U);return U},X=[],z=q(" ");for(let W of J.split(` +`))if(q.trim())p8(q)}}function p8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=G.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),G.inspectReportId=Z||null,G.inspectAskedAt=G.hostCalls,!Z)y({t:"inspect",id:0,rect:null});break}case"pause":G.paused=!0,G.stepQueued=0,$?.debugPause?.(!0),i0();break;case"resume":G.paused=!1,$?.debugPause?.(!1),i0();break;case"step":G.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":U4();break;case"eval":{let Z=!0,q;try{q=K0((0,eval)(String(Q.code)))}catch(X){Z=!1,q=X instanceof Error?`${X.name}: ${X.message}`:String(X)}y({t:"evalResult",id:Q.id,ok:Z,value:q});break}case"dumpTape":y({t:"tape",tape:H4()});break;case"devStats":{let Z=null,q=$?.debugStats?.();if(q)try{Z=JSON.parse(q)}catch{Z=null}y({t:"devStats",frame:G.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())y({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:G.frame});else y({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))G.replayMasks=K4(Z),G.replayAnalog=Z.analog?F4(Z):null,G.replayTouch=Z.touch?M4(Z):null,G.replayAt=0;break}default:break}}function c8(){if(G.treeDirty&&G.frame-G.treeSentAt>=d0)U4();if(G.frame%x8===0)i0()}function d8(){let J=G.inspectReportId;if(J==null)return;let Q=G.ops;if(!Q?.debugRectXY||!Q.debugRectWH){G.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(G.hostCalls-G.inspectAskedAt>60)G.inspectReportId=null,y({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();G.inspectReportId=null,y({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function i0(){y({t:"stats",frame:G.frame,nodes:D4(XJ),tapeLen:G.tapeLen,paused:G.paused})}function U4(){G.treeDirty=!1,G.treeSentAt=G.frame,y({t:"tree",frame:G.frame,root:P4(XJ)})}function i8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function s0(J,Q){if(Array.isArray(J)){for(let $ of J)s0($,Q);return}if(i8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)s0($,Q)}}function R4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)s0(Z,Q)}function P4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(R4(J,(q)=>{if(q.domNodeType===8)return;Z.push(P4(q))}),Z.length)Q.k=Z;return Q}function D4(J){let Q=1;return R4(J,($)=>{Q+=D4($)}),Q}function s8(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...q)=>{y({t:"log",level:$,args:q.map((X)=>K0(X))}),Z?.apply(Q,q)}}}function K0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let X=J;return Q===0?V4(X):JSON.stringify(V4(X))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let X=J.name;return X?`[function ${X}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let X=J.slice(0,20).map((z)=>K0(z,Q+1));if(J.length>20)X.push(`… ${J.length-20} more`);return`[${X.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([X,z])=>`${X}: ${K0(z,Q+1)}`).join(", ")}}`}function V4(J){return J.length>200?J.slice(0,199)+"…":J}function a8(){let J=G.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var r8={get frame(){return G.frame},dumpTape:()=>H4(),replay:(J)=>{G.replayMasks=K4(J),G.replayAnalog=J.analog?F4(J):null,G.replayTouch=J.touch?M4(J):null,G.replayAt=0}},L4=new Map,a0=new Map;function O4(J){return J.trim().replace(/\s+/g," ")}function I4(J){return J.split(" ").sort().join(" ")}var A4=-1;function o8(J){for(let Q of Object.keys(J)){let $=J[Q],Z=O4(Q);L4.set(Z,$);let q=I4(Z),X=a0.get(q);a0.set(q,X!==void 0&&X!==$?A4:$)}}function n8(J){let Q=O4(J),$=L4.get(Q);if($!==void 0)return $;let Z=a0.get(I4(Q));return Z===A4?void 0:Z}var r0=9,t8=(1<{let q=($&J2)!==0,X=q?o0:r0,z=q?Q2:t8;return Object.freeze({id:$>>>(q?$2:e8)&255,x:$&z,y:$>>>X&z,hit:Q?.[Z]})}))}function q2(){return F0}function X2(){F0=n0}var _4=8,GJ=8,Y2=3,z2=8,G2=6,W2=0.5,s=1,cJ=2,t0=4,DJ=8,EJ=[],k4=0,M0=0,WJ=Array.from({length:_4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(GJ),histY:new Int16Array(GJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function B2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function H2(J,Q,$,Z){let q=J.opts.region;if(!q)return!0;let X=q.node?.();if(X){if(Z.hit===void 0)Z.hit=a1(Q,$,Z.fact);let W=Z.hit;if(W)return B2(W,X)}let z=q.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let W=EJ[z];if(W.disposed)continue;if(k4>0&&!W.opts.allowWhenBlocked)continue;if(!H2(W,$,Z,X))continue;W.flags[J.slot]=s,J.owners.push(W)}for(let z of J.owners)z.opts.onDown?.(J)}function F2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%GJ,J.histLenz||Z>z))q.flags[J.slot]|=cJ}if(!J.claimedBy)for(let q of J.owners){let X=q.flags[J.slot];if(!(X&s)||X&(cJ|t0))continue;if(!q.opts.onLongPress)continue;let z=Math.max(1,Math.round((q.opts.longPressSeconds??W2)*N1()));if(J.frames=0)EJ.splice($,1)},cancel(){if(!Q.disposed)g4(Q)},get panning(){for(let $ of WJ)if($.used&&Q.flags[$.slot]&DJ)return!0;return!1}}}function D2(J){let Q=P2(J);return _0(()=>Q.dispose()),Q}function w4(){EJ.length=0,k4=0,M0=0;for(let J of WJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function V2(){return D2({onDown:(J)=>{let Q=s1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=s1(J.x,J.y,J.hit);if(Q)B8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var L2=1,e0=new Map,U0=[];function O2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function I2(){L2=1,e0.clear(),U0=[]}function A2(){if(U0.length===0)return;let J=U0;U0=[];for(let{id:Q,result:$}of J){let Z=e0.get(Q);if(!Z)continue;e0.delete(Q),O2()?.({t:"delivery",frame:E1(),id:Q,kind:Z.kind}),Z.onResult($)}}var C4=new Set;function _2(){if(C4.size===0)return;for(let J of C4)J()}var k2={"h-[108] px-[10] py-4 flex-row gap-[10] bg-slate-950":0,"w-[165] h-[76] items-center justify-center bg-orange-600":1,"w-[165] h-[76] items-center justify-center bg-slate-900":2,"text-base text-white font-bold":3,"flex-col w-full h-full bg-slate-50":4,"h-[686] px-6 pt-7 flex-col gap-[22]":5,"w-[584] h-[318] px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":6,"h-[30] flex-row items-center gap-3":7,"w-[10] h-[10] rounded bg-orange-500":8,"text-lg text-orange-600 font-bold":9,"h-[84] pt-3 text-xl text-slate-900":10,"h-[2] mx-1 my-4 bg-slate-100":11,"w-[10] h-[10] rounded bg-emerald-500":12,"text-lg text-emerald-700 font-bold":13,"absolute left-[628] top-[28] w-[68] h-[132] items-center justify-center bg-orange-100":14,"absolute left-[628] top-[512] w-[68] h-[132] items-center justify-center bg-orange-100":15,"h-[228] mx-6 px-6 py-5 flex-col rounded-xl shadow bg-white border-slate-100":16,"text-base text-slate-600 font-bold":17,"pt-6 text-lg text-slate-500":18,"pt-6 text-lg text-slate-900 font-bold":19,"h-[146] px-6 pt-7 flex-col bg-slate-50":20,"h-[80]":21,"h-[1060] px-6 pt-5 flex-col":22,"h-[48] px-4 justify-center bg-slate-100":23,"text-base text-slate-600":24,"pt-[10] flex-col gap-[12]":25,"w-[584] h-[92] px-[18] flex-row items-center gap-5 bg-white":26,"w-[48] h-[48] items-center justify-center bg-blue-100":27,"w-[48] h-[48] items-center justify-center bg-emerald-100":28,"text-lg text-blue-700 font-bold":29,"w-[474] flex-col gap-2":30,"text-lg text-slate-900 font-bold":31,"text-base text-slate-500":32,"pt-20 pl-10 text-lg text-slate-500":33,"absolute left-[628] top-[78] w-[68] h-[132] items-center justify-center bg-orange-100":34,"absolute left-[628] top-[828] w-[68] h-[132] items-center justify-center bg-orange-100":35,"h-[1060] px-6 pt-7 flex-col gap-4":36,"text-base text-slate-500 font-bold":37,"h-[214] px-7 items-center justify-center bg-slate-100":38,"text-lg text-slate-500 font-bold":39,"w-[672] h-[150] px-6 flex-row items-center justify-between bg-white":40,"flex-row items-center gap-5":41,"w-[68] h-[68] items-center justify-center bg-orange-100":42,"text-xl text-orange-700 font-bold":43,"w-[500] flex-col gap-2":44,"text-xl text-slate-900 font-bold":45,"text-lg text-slate-600":46,"text-2xl text-orange-600":47,"mt-4 h-[112] px-6 justify-center bg-slate-100":48,"relative h-[154] px-5 pt-5 flex-col bg-white":49,"pt-3 text-lg text-orange-600 font-bold":50,"pt-3 text-base text-slate-500":51,"absolute left-[456] top-[14] w-[196] h-[72] items-center justify-center bg-orange-600":52,"text-lg text-white font-bold":53,"h-[40] pt-3 text-base text-slate-500":54,"h-[470] flex-col gap-2":55,"w-[584] h-[84] px-5 flex-row items-center justify-between bg-white":56,"absolute left-[604] top-[0] w-[68] h-[132] items-center justify-center bg-orange-100":57,"absolute left-[604] top-[320] w-[68] h-[132] items-center justify-center bg-orange-100":58,"h-[160] px-5 pt-5 flex-col bg-white":59,"pt-3 text-lg text-slate-900 font-bold":60,"pt-3 text-base text-slate-600":61,"h-[108] pt-7 flex-row gap-4":62,"w-[316] h-[80] items-center justify-center bg-slate-100":63,"w-[340] h-[80] items-center justify-center bg-red-100":64,"text-lg text-red-500 font-bold":65,"h-[1052] px-6 pt-5 flex-col":66,"h-[270] px-[22] pt-6 bg-white":67,"text-lg text-slate-900":68,"text-lg text-slate-400":69,"h-[86] px-1 flex-row items-center justify-between":70,"w-[132] h-[58] items-center justify-center bg-slate-300":71,"w-[132] h-[58] items-center justify-center bg-slate-100":72,"text-base text-slate-900 font-bold":73,"h-[140] flex-row gap-2":74,"grow h-[120] items-center justify-center bg-slate-300":75,"grow h-[120] items-center justify-center bg-white":76,"w-[104] h-[120] items-center justify-center bg-slate-300":77,"w-[104] h-[120] items-center justify-center bg-slate-100":78,"h-[176] flex-row gap-2":79,"w-[92] h-[156] items-center justify-center bg-slate-300":80,"w-[92] h-[156] items-center justify-center bg-slate-100":81,"w-[300] h-[156] items-center justify-center bg-slate-300":82,"w-[300] h-[156] items-center justify-center bg-slate-100":83,"w-[144] h-[156] items-center justify-center bg-slate-300":84,"w-[144] h-[156] items-center justify-center bg-slate-100":85,"w-[112] h-[156] items-center justify-center bg-emerald-700":86,"w-[112] h-[156] items-center justify-center bg-emerald-500":87,"text-base text-slate-950 font-bold":88,"h-[108] px-6 py-3 flex-col bg-slate-50":89,"h-[84] items-center justify-center bg-slate-300":90,"h-[84] items-center justify-center bg-slate-100":91,"h-[1168] px-6 pt-5 flex-col":92,"h-[82] px-4 justify-center bg-white":93,"w-[584] h-[900] px-5 pt-5 bg-slate-950":94,"text-base text-slate-200":95,"absolute left-[628] top-[58] w-[68] h-[132] items-center justify-center bg-orange-100":96,"w-[584] h-[900] px-5 pt-5 bg-white":97,"text-xl text-slate-900":98,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":99,"absolute inset-0 z-50 flex-col items-center justify-center":100,"absolute inset-0 bg-slate-950":101,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":102,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":103,"flex-row flex-wrap":104,grow:105,"text-2xl text-white font-bold":106,"text-2xl text-slate-950 font-bold":107,"px-3 py-2 rounded-lg bg-slate-100":108,"px-3 py-2 rounded-lg bg-indigo-100":109,"text-base text-indigo-700 font-bold":110,"px-3 py-2 rounded-lg bg-emerald-100":111,"text-base text-emerald-700 font-bold":112,"px-3 py-2 rounded-lg bg-amber-100":113,"text-base text-amber-700 font-bold":114,"px-3 py-2 rounded-lg bg-red-100":115,"text-base text-red-500 font-bold":116,"w-[34] h-[34] rounded-lg bg-amber-400":117,"w-[34] h-[34] rounded-lg bg-red-500":118,"w-[34] h-[34] rounded-lg bg-slate-800":119,"w-[34] h-[34] rounded-lg bg-emerald-500":120,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":121,"flex-row items-center gap-4":122,"w-[34] text-2xl text-white font-bold":123,"w-[332] flex-col items-end gap-2":124,"text-base text-slate-300 font-bold":125,"text-base text-slate-400":126,"h-[166] px-6 pt-6 flex-col gap-3":127,"text-base text-orange-600 font-bold":128,"h-[44] px-1 flex-row items-center justify-between":129,"w-full h-full items-center justify-center rounded-xl bg-slate-200":130,"w-full h-full items-center justify-center rounded-xl bg-red-100":131,"w-full h-full items-center justify-center rounded-xl bg-slate-100":132,"w-full h-full items-center justify-center rounded-xl bg-orange-600":133,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":134,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":135,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":136,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":137,"text-2xl text-indigo-700 font-bold":138,"text-2xl text-slate-600 font-bold":139,"pt-7 text-2xl text-slate-900 font-bold":140,"pt-4 text-lg text-slate-500":141,"text-xl text-emerald-600 font-bold":142,"text-xl text-red-500 font-bold":143,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":144,"text-base text-red-300":145,"text-base text-slate-300":146,"text-base text-red-500":147,"w-full h-full px-6 flex-row items-center bg-slate-950":148,"w-full h-full flex-row items-center":149};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var S2="ui:styles",b2="ui:font.",N4="ui:img.",E4="ui:sprite.";function g2(){return globalThis.ui}function w2(J){if(J.__textures)return;for(let Q of E0(N4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let q=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),q.getUint16(0,!0),q.getUint16(2,!0),$[4])}if(Z>=0)e1(Q.slice(N4.length),Z)}}function C2(J){if(J.__sprites)return;for(let Q of E0(E4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),q=Z.getUint16(0,!0),X=Z.getUint16(2,!0),z=$[4],W=Z.getUint16(6,!0),U=Z.getUint16(8,!0),P=Z.getUint16(10,!0),D=J.uploadTexture($.subarray(16),q,X,z);if(D>=0)Q4(Q.slice(E4.length),{handle:D,frames:W,cols:U,step:P})}}function h4(J){let Q=z4("view");return NJ(Q,"style",J,void 0),Q}var R0=null,P0=null;function N2(J,Q){if(!R0||!P0)return;NJ(R0,"style",{width:J,height:Q,overflow:u.Overflow.Hidden},void 0),NJ(P0,"style",{width:J,height:Q,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=h();$.__viewport={w:J,h:Q}}function E2(J,Q={}){let $=f6(Q.ops);if(x6($),L8(n8),Q.styles)o8(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let _ in Z)e1(_,Z[_]);let B=$.ops.__sprites;if(B)for(let _ in B)Q4(_,B[_])}if($.kind==="injected"||Z===void 0){if(Q.pak)x1(Q.pak);if($8()){for(let B of E0())if(B===S2)$.ops.loadStyles?.(vJ(B));else if(B.startsWith(b2))$.ops.loadFontAtlas?.(vJ(B))}}let q=g1($.ops),X=q?.w??k1,z=q?.h??S1,W=h4({width:X,height:z,overflow:u.Overflow.Hidden}),U=h4({width:X,height:z,posType:u.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});YJ(XJ,W),YJ(XJ,U),G4(U),R0=W,P0=U,v1(W),d1(XJ),e6(),w4(),V2(),i6(),I2(),v8($.ops),v6(m8((B,_,g,w)=>{s6(),a6(_),Z2(g,w),_2(),A2(),R2(),J8(B),P8(B),Z4()}));let P=E8(J,W),D=m6(N2);return()=>{D(),X2(),w4(),P(),v1(null),d1(null),G4(null),R0=null,P0=null;for(let B of XJ.children.splice(0))B.parent=null,$.ops.destroyNode(B.id);Z4()}}function h2(J,Q={}){let $=Q.ops??g2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)x1(Q.pak);return w2($),C2($),E2(J,{ops:$,styles:Q.styles??k2,pak:Q.pak})}var T2="$b",y2=65536,T4="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",dJ={};for(let J=0;JJ.length)throw Error("invalid UTF-8");for(let z=0;z1114111||q>=55296&&q<=57343||X===1&&q<128||X===2&&q<2048||X===3&&q<65536)throw Error("invalid UTF-8");if(q<65536)Q+=String.fromCharCode(q);else q-=65536,Q+=String.fromCharCode(55296+(q>>10),56320+(q&1023))}return Q}function v2(){let J=globalThis.fs;if(!J||typeof J!=="object")return null;return typeof J.read==="function"?J:null}function y4(){let J=v2();if(!J)throw Error("fs: globalThis.fs is not mounted — declare `data.fs` in pocket.json requires");return J}function m2(J,Q){let $=[],Z=0;for(;;){let z=JSON.parse(J.read(Q,Z,y2));if(z.error!==void 0)throw Error(`fs: read ${Q}: ${z.error}`);let W=f2(z.data[T2]);if($.push(W),Z+=W.length,z.eof)break}if($.length===1)return $[0];let q=new Uint8Array(Z),X=0;for(let z of $)q.set(z,X),X+=z.length;return q}function l2(J,Q){let $=m2(y4(),J);return Q==="utf8"||Q==="utf-8"?x2($):$}function u2(J,Q){let $=y4(),Z=[],q=0;for(;;){let X=JSON.parse($.list(J,q));if(X.error!==void 0)throw Error(`fs: readdir ${J}: ${X.error}`);for(let z of X.entries)Z.push({...z,isFile:()=>z.kind==="file",isDirectory:()=>z.kind==="dir"});if(q+=X.entries.length,X.eof)break}return Q?.withFileTypes?Z:Z.map((X)=>X.name)}var p2={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",captionStrong:"text-base text-slate-500 font-bold"};function c2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return Y(M,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[Y(M,{class:"flex-row items-center gap-4",get children(){return[v(()=>v(()=>!!J.back)()?Y(V,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):Y(M,{get["class"](){return Q()}})),Y(V,{get["class"](){return p2.appTitle},get children(){return J.title}})]}}),Y(M,{class:"w-[332] flex-col items-end gap-2",get children(){return[Y(V,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),Y(V,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function d2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return Y(M,{get["class"](){return Q()},get children(){return Y(V,{get["class"](){return $()},get children(){return J.label}})}})}function iJ(J){return[Y(M,{get["class"](){return J.top},get children(){return Y(V,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),Y(M,{get["class"](){return J.bottom},get children(){return Y(V,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var sQ="‘’“”–—…•",i2=512;function s2(J,Q,$){let Z=[],q="",X=0;for(let z of J){let W=Q(z);if(q&&X+W>$)Z.push(q),q="",X=0;q+=z,X+=W}if(q)Z.push(q);return Z}function f4(J,Q,$){let Z=new Map,q=(W)=>{let U=Z.get(W);if(U===void 0)U=h().measureText(W,Q),Z.set(W,U);return U},X=[],z=q(" ");for(let W of J.split(` `)){let U=W.split(" ").flatMap((B)=>B&&q(B)>$?s2(B,q,$):[B]),P="",D=0;for(let B of U){let _=q(B);if(!P)P=B,D=_;else if(D+z+_<=$)P+=" "+B,D+=z+_;else X.push(P),P=B,D=_}X.push(P)}return X}function J1(J,Q,$,Z){let q=J.slice(0,i2),X=f4(q,Q,$);if(q.length===J.length&&X.length<=Z)return X.join(` `);let z=X.slice(0,Z),W=z.length-1;return z[W]=z[W].replace(/[\s.]+$/,"")+"…",z.join(` `)}function a2(J,Q,$,Z){let q=$;while(qnoPlSFBrKvB?xNPTS62#CC~i Tx^e@X^!A#1wj(SY3{U_7&&3#2 delta 151 zcmX@mE_I+oYJvolL(4>|b4*r3jjvi?F}A*9YJJ7r`iiCX73Hj*P6+?=`Z?o3lDFT>SO)zY9>%!O@LDU}xih qcaQ>m4+cgc&B*A$@E-_3^vAD1!88+_`2Xqu>eytqf2m_T!U6!)05Q4% diff --git a/apps/robinhood/TOOLS.md b/apps/robinhood/TOOLS.md index b2c8b4b..3c02189 100644 --- a/apps/robinhood/TOOLS.md +++ b/apps/robinhood/TOOLS.md @@ -2,7 +2,7 @@ Pocket Pi snapshots the upstream Robinhood Trading MCP catalog, but does not put all upstream schemas in every model request. The checked-in snapshot currently -contains 54 upstream Tools. The initial Agent catalog contains four small Pocket +contains 54 upstream Tools. The initial Agent catalog contains three small Pocket Pi Tools: - `robinhood.search_tools` returns matching upstream descriptions and exact JSON @@ -10,7 +10,6 @@ Pi Tools: - `robinhood.call` validates one upstream call against that schema and routes it through the native static allowlist. - `robinhood.refresh_portfolio` refreshes the bounded fixed-View projection. -- `robinhood.storage_status` inspects local projection health. This is Pocket Pi's cross-model fallback for deferred Tool loading. It follows the same load-on-demand design as OpenAI client-executed Tool Search, but is not diff --git a/apps/robinhood/agent-app.json b/apps/robinhood/agent-app.json index a184629..1070bf7 100644 --- a/apps/robinhood/agent-app.json +++ b/apps/robinhood/agent-app.json @@ -141,15 +141,6 @@ "properties": {}, "additionalProperties": false } - }, - { - "name": "robinhood.storage_status", - "description": "Inspect bounded Robinhood App SQLite table counts and recent run summaries without contacting Robinhood. Account numbers are returned only as suffixes.", - "parameters": { - "type": "object", - "properties": {}, - "additionalProperties": false - } } ], "tasks": [ diff --git a/apps/robinhood/app.tsx b/apps/robinhood/app.tsx index d0e9e3a..7e0a5ce 100644 --- a/apps/robinhood/app.tsx +++ b/apps/robinhood/app.tsx @@ -320,29 +320,6 @@ function tick(): string { return ""; } -function storageStatus(): any { - const tables = db.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all() as unknown as Array<{ name: string; sql: string }>; - const names = new Set(tables.map((table) => table.name)); - const tableSummary = tables.map((table) => { - const rowCount = (db.query("SELECT COUNT(*) AS count FROM " + table.name).get() as unknown as { count: number }).count; - return { name: table.name, rowCount, schema: table.sql }; - }); - const latestRefreshes = names.has("refresh_runs") - ? db.query("SELECT id,started_at,completed_at,operation_count,success_count,status,error FROM refresh_runs ORDER BY id DESC LIMIT 3").all() : []; - const latestPortfolios = names.has("portfolio_current") - ? db.query("SELECT substr(account_number,-4) AS account_suffix,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current ORDER BY observed_at DESC LIMIT 4").all() : []; - const latestValues = names.has("total_value") - ? db.query("SELECT substr(account_number,-4) AS account_suffix,observed_at,value FROM total_value ORDER BY observed_at DESC LIMIT 8").all() : []; - return { - database: "robinhood.sqlite", - schemaVersion: DB_SCHEMA_VERSION, - tables: tableSummary, - latestRefreshes, - latestPortfolios, - latestValues, - }; -} - function trend(): { change: string; percent: string; positive: boolean } { return chartTrend(); } @@ -505,13 +482,6 @@ mount(() => ); loadView(revision); return ""; }, - invokeTool(name: string) { - try { - const value = name === "robinhood.storage_status" ? storageStatus() - : (() => { throw new Error("Data-writing tools run in the background App Data Action"); })(); - return JSON.stringify({ text: JSON.stringify(value), details: value, isError: false }); - } catch (error) { return JSON.stringify({ text: error instanceof Error ? error.message : String(error), isError: true }); } - }, tap(x: number, y: number) { if (screen() !== "dashboard") { if (y < 112 && x < 220) { setScreen("dashboard"); return ""; } diff --git a/apps/robinhood/dist/app.js b/apps/robinhood/dist/app.js index 5d9cfab..11d2076 100644 --- a/apps/robinhood/dist/app.js +++ b/apps/robinhood/dist/app.js @@ -1,5 +1,5 @@ -(()=>{var _J={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return M1(this.context.count)},getNextContextId(){return M1(this.context.count++)}};function M1(J){let Q=String(J),$=Q.length-1;return _J.context.id+($?String.fromCharCode(96+$):"")+Q}function P1(J){_J.context=J}function B6(){return{..._J.context,id:_J.getNextContextId(),count:0}}var K6=!1,U6=(J,Q)=>J===Q,A0=Symbol("solid-proxy"),M6=typeof Proxy==="function",P6=Symbol("solid-track"),wQ=Symbol("solid-dev-component"),nJ={equals:U6},V1=null,V6=_1,c=1,EJ=2,D1={owned:null,cleanups:null,context:null,owner:null},S=null,B=null,bJ=null,AJ=null,f=null,h=null,N=null,oJ=0;function tJ(J,Q){let $=f,Z=S,X=J.length===0,W=Q===void 0?Z:Q,z=X?D1:{owned:null,cleanups:null,context:W?W.context:null,owner:W},F=X?J:()=>J(()=>qJ(()=>zJ(z)));S=z,f=null;try{return n(F,!0)}finally{f=$,S=Z}}function E(J,Q){Q=Q?Object.assign({},nJ,Q):nJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return L1($,X)};return[O1.bind($),Z]}function WJ(J,Q,$){let Z=k1(J,Q,!1,c);if(bJ&&B&&B.running)h.push(Z);else J0(Z)}function $J(J,Q,$){$=$?Object.assign({},nJ,$):nJ;let Z=k1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,bJ&&B&&B.running)Z.tState=c,h.push(Z);else J0(Z);return O1.bind(Z)}function eJ(J){return n(J,!1)}function qJ(J){if(!AJ&&f===null)return J();let Q=f;f=null;try{if(AJ)return AJ.untrack(J);return J()}finally{f=Q}}function w0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function D6(J){if(B&&B.running)return J(),B.done;let Q=f,$=S;return Promise.resolve().then(()=>{f=Q,S=$;let Z;if(bJ||R6)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return n(J,!1),f=S=null,Z?Z.done:void 0})}var[SQ,R1]=E(!1),R6;function O1(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===c)J0(this);else{let Q=h;h=null,n(()=>Q0(this),!1),h=Q}if(f){let Q=this.observers;if(!Q||Q[Q.length-1]!==f){let $=Q?Q.length:0;if(!f.sources)f.sources=[this],f.sourceSlots=[$];else f.sources.push(this),f.sourceSlots.push($);if(!Q)this.observers=[f],this.observerSlots=[f.sources.length-1];else Q.push(f),this.observerSlots.push(f.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function L1(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)n(()=>{for(let X=0;X1e6)throw h=[],Error()},!1)}return Q}function J0(J){if(!J.fn)return;zJ(J);let Q=oJ;if(I1(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{n(()=>{B&&(B.running=!0),f=S=J,I1(J,J.tValue,Q),f=S=null},!1)})}function I1(J,Q,$){let Z,X=S,W=f;f=S=J;try{Z=J.fn(Q)}catch(z){if(J.pure)if(B&&B.running)J.tState=c,J.tOwned&&J.tOwned.forEach(zJ),J.tOwned=void 0;else J.state=c,J.owned&&J.owned.forEach(zJ),J.owned=null;return J.updatedAt=$+1,y0(z)}finally{f=W,S=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)L1(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function k1(J,Q,$,Z=c,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(S===null);else if(S!==D1)if(B&&B.running&&S.pure)if(!S.tOwned)S.tOwned=[W];else S.tOwned.push(W);else if(!S.owned)S.owned=[W];else S.owned.push(W);if(AJ&&W.fn){let z=W.fn,[F,D]=E(void 0,{equals:!1}),R=AJ.factory(z,D);w0(()=>R.dispose());let U,H=()=>D6(D).then(()=>{if(U)U.dispose(),U=void 0});W.fn=(w)=>{if(F(),B&&B.running){if(!U)U=AJ.factory(z,H);return U.track(w)}return R.track(w)}}return W}function S0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===EJ)return Q0(J);if(J.suspense&&qJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===c)J0(J);else if((Q?J.tState:J.state)===EJ){let X=h;h=null,n(()=>Q0(J,$[0]),!1),h=X}}}function n(J,Q){if(h)return J();let $=!1;if(!Q)h=[];if(N)$=!0;else N=[];oJ++;try{let Z=J();return O6($),Z}catch(Z){if(!$)N=null;h=null,y0(Z)}}function O6(J){if(h){if(bJ&&B&&B.running)L6(h);else _1(h);h=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;N.push.apply(N,B.effects),Q=B.resolve;for(let W of N)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,n(()=>{for(let W of X)zJ(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let z=0,F=W.owned.length;zV6($),!1);if(Q)Q()}function _1(J){for(let Q=0;Q{Z.delete($),n(()=>{B.running=!0,S0($)},!1),B&&(B.running=!1)})}}function Q0(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)zJ(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)w1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)zJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function w1(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return w0(()=>y1(W)),()=>{let D=J()||[],R=D.length,U,H;return D[P6],qJ(()=>{let x,g,A,a,r,K,j,G,P;if(R===0){if(z!==0)y1(W),W=[],Z=[],X=[],z=0,F&&(F=[]);if($.fallback)Z=[k6],X[0]=tJ((k)=>{return W[0]=k,$.fallback()}),z=1}else if(z===0){X=Array(R);for(H=0;H=K&&G>=K&&Z[j]===D[G];j--,G--)A[G]=X[j],a[G]=W[j],F&&(r[G]=F[j]);x=new Map,g=Array(G+1);for(H=G;H>=K;H--)P=D[H],U=x.get(P),g[H]=U===void 0?-1:U,x.set(P,H);for(U=K;U<=j;U++)if(P=Z[U],H=x.get(P),H!==void 0&&H!==-1)A[H]=X[U],a[H]=W[U],F&&(r[H]=F[U]),H=g[H],x.set(P,H);else W[U]();for(H=K;HJ(Q||{}));return P1($),Z}}return qJ(()=>J(Q||{}))}function $0(){return!0}var S6={get(J,Q,$){if(Q===A0)return $;return J.get(Q)},has(J,Q){if(Q===A0)return!0;return J.has(Q)},set:$0,deleteProperty:$0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:$0,deleteProperty:$0}},ownKeys(J){return J.keys()}};function f0(J){return!(J=typeof J==="function"?J():J)?{}:J}function y6(){for(let J=0,Q=this.length;J=0;F--){let D=f0(J[F])[z];if(D!==void 0)return D}},has(z){for(let F=J.length-1;F>=0;F--)if(z in f0(J[F]))return!0;return!1},keys(){let z=[];for(let F=0;F=0;z--){let F=J[z];if(!F)continue;let D=Object.getOwnPropertyNames(F);for(let R=D.length-1;R>=0;R--){let U=D[R];if(U==="__proto__"||U==="constructor")continue;let H=Object.getOwnPropertyDescriptor(F,U);if(!Z[U])Z[U]=H.get?{enumerable:!0,configurable:!0,get:y6.bind($[U]=[H.get.bind(F)])}:H.value!==void 0?H:void 0;else{let w=$[U];if(w){if(H.get)w.push(H.get.bind(F));else if(H.value!==void 0)w.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let z=W.length-1;z>=0;z--){let F=W[z],D=Z[F];if(D&&D.get)Object.defineProperty(X,F,D);else X[F]=D?D.value:void 0}return X}var f6=(J)=>`Stale read from <${J}>.`;function NJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return $J(_6(()=>J.each,J.children,Q||void 0))}function Z0(J){let Q=J.keyed,$=$J(()=>J.when,void 0,void 0),Z=Q?$:$J($,void 0,{equals:(X,W)=>!X===!W});return $J(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?qJ(()=>W(Q?X:()=>{if(!qJ(Z))throw f6("Show");return $()})):W}return J.fallback},void 0,void 0)}var x6=(J)=>$J(()=>J());function C6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:z,getParentNode:F,getFirstChild:D,getNextSibling:R}){function U(K,j,G,P){if(G!==void 0&&!P)P=[];if(typeof j!=="function")return H(K,j,P,G);WJ((k)=>H(K,j(),k,G),P)}function H(K,j,G,P,k){while(typeof G==="function")G=G();if(j===G)return G;let _=typeof j,I=P!==void 0;if(_==="string"||_==="number"){if(_==="number")j=j.toString();if(I){let L=G[0];if(L&&$(L))Z(L,j);else L=Q(j);G=g(K,G,P,L)}else if(G!==""&&typeof G==="string")Z(D(K),G=j);else g(K,G,P,Q(j)),G=j}else if(j==null||_==="boolean")G=g(K,G,P);else if(_==="function")return WJ(()=>{let L=j();while(typeof L==="function")L=L();G=H(K,L,G,P)}),()=>G;else if(Array.isArray(j)){let L=[];if(w(L,j,k))return WJ(()=>G=H(K,L,G,P,!0)),()=>G;if(L.length===0){let hJ=g(K,G,P);if(I)return G=hJ}else if(Array.isArray(G))if(G.length===0)A(K,L,P);else x(K,G,L);else if(G==null||G==="")A(K,L);else x(K,I&&G||[D(K)],L);G=L}else{if(Array.isArray(G)){if(I)return G=g(K,G,P,j);g(K,G,null,j)}else if(G==null||G===""||!D(K))X(K,j);else a(K,j,D(K));G=j}return G}function w(K,j,G){let P=!1;for(let k=0,_=j.length;k<_;k++){let I=j[k],L;if(I==null||I===!0||I===!1);else if(Array.isArray(I))P=w(K,I)||P;else if((L=typeof I)==="string"||L==="number")K.push(Q(I));else if(L==="function")if(G){while(typeof I==="function")I=I();P=w(K,Array.isArray(I)?I:[I])||P}else K.push(I),P=!0;else K.push(I)}return P}function x(K,j,G){let P=G.length,k=j.length,_=P,I=0,L=0,hJ=R(j[k-1]),IJ=null;while(IQJ-L){let AQ=j[I];while(L=0;I--){let L=j[I];if(k!==L){let hJ=F(L)===K;if(!_&&!I)hJ?a(K,k,L):X(K,k,G);else hJ&&W(K,L)}else _=!0}}else X(K,k,G);return[k]}function A(K,j,G){for(let P=0,k=j.length;PG.children=H(K,j.children,G.children));return WJ(()=>j.ref&&j.ref(K)),WJ(()=>{for(let k in j){if(k==="children"||k==="ref")continue;let _=j[k];if(_===G[k])continue;z(K,k,_,G[k]),G[k]=_}}),G}return{render(K,j){let G;return tJ((P)=>{G=P,U(j,K())}),G},insert:U,spread(K,j,G){if(typeof j==="function")WJ((P)=>r(K,j(),P,G));else r(K,j,void 0,G)},createElement:J,createTextNode:Q,insertNode:X,setProp(K,j,G,P){return z(K,j,G,P),G},mergeProps:f1,effect:WJ,memo:x6,createComponent:w6,use(K,j,G){return qJ(()=>K(j,G))}}}function g6(J){let Q=C6(J);return Q.mergeProps=f1,Q}var x1=480,C1=272,KJ={view:0,text:1,image:2},h6=1,E6=-1,b6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},M={f32:0,color:1,int:2},N6={width:M.f32,height:M.f32,minW:M.f32,minH:M.f32,maxW:M.f32,maxH:M.f32,paddingT:M.f32,paddingR:M.f32,paddingB:M.f32,paddingL:M.f32,marginT:M.f32,marginR:M.f32,marginB:M.f32,marginL:M.f32,gap:M.f32,flexDir:M.int,justify:M.int,align:M.int,grow:M.f32,shrink:M.f32,basis:M.f32,flexWrap:M.int,posType:M.int,insetT:M.f32,insetR:M.f32,insetB:M.f32,insetL:M.f32,display:M.int,overflow:M.int,zIndex:M.int,hitPass:M.int,bgColor:M.color,gradFrom:M.color,gradTo:M.color,gradDir:M.int,radius:M.f32,opacity:M.f32,borderColor:M.color,borderWidth:M.f32,shadow:M.int,bevelOuterLight:M.color,bevelOuterDark:M.color,bevelInnerLight:M.color,bevelInnerDark:M.color,bevelWidth:M.f32,textColor:M.color,fontSlot:M.int,textAlign:M.int,lineHeight:M.f32,tracking:M.f32,translateX:M.f32,translateY:M.f32,scale:M.f32,rotate:M.f32,scaleX:M.f32,scaleY:M.f32,originX:M.f32,originY:M.f32,rotateX:M.f32,rotateY:M.f32,translateZ:M.f32,perspective:M.f32,arcStart:M.f32,arcSweep:M.f32,arcWidth:M.f32},d={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},T6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},v6=1,yQ=2,fQ=1,xQ=2,CQ=131072,gQ=1,hQ=262144,EQ=1,bQ=1,NQ=1,TQ=2,vQ=4,mQ=8,lQ=16,uQ=1,pQ=2;function g1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var cQ=1,m6=1263551300,l6=1,u6=32,p6=24,o={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},UJ=32896,dQ=0.016666666666666666;function h1(J){return J.__viewport??null}var x0=null;function c6(){return null}function E1(J,Q=c6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function d6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return E1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return E1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function i6(J){x0=J}function wJ(){if(!x0)throw Error("PocketJS: host not installed — call render() first");return x0}function b(){return wJ().ops}function s6(J){globalThis.frame=J}function a6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function r6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return g1($>>>16&255,$>>>8&255,$&255,255);return g1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function n6(J,Q){let $=N6[J];if(typeof Q==="string"){if($===M.color)return r6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===M.color||$===M.int)return Q>>>0;return Q}var X0=60,b1=[1,2,3,4,5,6,10,12,15,20,30,60],C0=X0,YJ=-1,o6=0,TJ=[];function t6(J){if(!Number.isFinite(J)||J<=0)return X0;let Q=b1[0];for(let $ of b1)if(Math.abs($-J)Q.at<=YJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;TJ=TJ.filter((Q)=>Q.at>YJ);for(let Q of J)Q.cb()}var g0=0.12,W0=UJ;function $8(J){W0=J===void 0?UJ:J&65535}function Z8(){W0=UJ}function v1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function W8(){return v1(W0&255)}var m1=new Set,q8=0;function z8(){m1.clear(),q8=0,Z8()}function Y8(J){for(let Q of[...m1])Q(J)}var MJ=null,l1=null;function G8(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function u1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){h0();let Q=MJ?MJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return l1.slice(Q.off,Q.off+Q.len)}var mJ=null,C=null,PJ=null,q0=0,VJ=[],b0=[],N0=[];function c1(J){if(mJ=J,C=null,PJ=null,q0=0,VJ.length=0,b0.length=0,N0.length=0,i){if(i.pressTarget=null,i.target=null,i.spriteDirty=!0,i.fresh=!0,i.vw=0,i.tex>=0){let Q=b();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(i.tex),i.tex=-1}}}function j8(J,Q){J.onPress=Q??void 0}function F8(J,Q){if(J.focusable=Q,r1(),!Q&&C===J)v(null)}function v(J){if(PJ&&PJ!==J)DJ(null);C=J,b().setFocus(J?J.id:0)}function DJ(J){if(PJ===J)return;let Q=b();if(PJ)Q.setActive?.(PJ.id,0);if(PJ=J,J)Q.setActive?.(J.id,1)}function T0(){return VJ.length>0?VJ[VJ.length-1]:mJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;v($[X])}function U8(){if(!C)return null;let J=T0();if(J&&!t(C,J))return null;for(let Q=b0.length-1;Q>=0;Q--){let $=b0[Q];if(J&&!t($.node,J)&&!t(J,$.node))continue;if(t(C,$.node))return $}return null}function M8(J){let Q=U8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(C)v(null);return!0}let Z=Q.columns,X=C?$.indexOf(C):-1;if(X<0)return v(d1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)v($[W]);return!0}function P8(){if(!C)return null;let J=T0();if(J&&!t(C,J))return null;for(let Q=N0.length-1;Q>=0;Q--){let $=N0[Q];if(J&&!t($.node,J)&&!t(J,$.node))continue;if(t(C,$.node))return $}return null}function z0(J){let Q=P8();if(Q&&Q.move(J))return;if(M8(J))return;K8(J)}function i1(){s1(C)}function s1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){DJ(J)}function V8(J){v(J),s1(J)}function t(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=m0(Q.children[X]);if(W){v(W);return}}let Z=Q;while(Z){if(Z.focusable){v(Z);return}Z=Z.parent}}v(null)}var i=null,a1=0;function r1(){a1++}var R8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],O8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function L8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=R8[Q]>>$&1,X=O8[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,z=X?255:0;J[W]=z,J[W+1]=z,J[W+2]=z,J[W+3]=255}return J}function I8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=vJ($.image)}catch(z){if(wJ().strict)throw z;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):k8(Q,W),X<0&&wJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(L8(),16,16,T6.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function k8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&v6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function G0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=G0($[Z],Q);if(X)return X}return null}var H0=null;function n1(J){H0=J}function o1(J){let Q=VJ.length>0?VJ[VJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||t($,Q)))return $;$=$.parent}return null}function t1(J,Q,$){return o1(e1(J,Q,$))}function e1(J,Q,$){if($!==void 0)return $===0?null:G0(H0??mJ,$);let Z=b(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return G0(H0??mJ,X(J,Q))}function _8(J,Q,$){let Z=i,X=b();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=h1(X);if(Z.vw=H?H.w:x1,Z.vh=H?H.h:C1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)I8(Z,X);let W=X8()*Z.speed,z=W8()*Z.speed;if(Z.dpadSpeed>0&&W===0&&z===0){if(J&o.LEFT)W=-Z.dpadSpeed;if(J&o.RIGHT)W=Z.dpadSpeed;if(J&o.UP)z=-Z.dpadSpeed;if(J&o.DOWN)z=Z.dpadSpeed}let F=Z.fresh;if(W!==0||z!==0){let H=e6()/60,w=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),x=Math.min(Math.max(Z.y+z*H,0),Z.vh-1);if(w!==Z.x||x!==Z.y)Z.x=w,Z.y=x,F=!0}if(F)X.setCursorPos(Z.x,Z.y);let D=(Q|$)&Z.button,R=a1;if(F||D!==0||R!==Z.gen)Z.gen=R,Z.fresh=!1,Z.target=o1(G0(H0??mJ,X.hitTest(Z.x,Z.y)));let U=Z.target;if(U!==C)v(U);if(Q&Z.button&&U)Z.pressTarget=U;if(Z.pressTarget){if(DJ(U===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=U===Z.pressTarget;if(Z.pressTarget=null,DJ(null),H)i1()}}else if($&Z.button)DJ(null);return!0}function A8(J){let Q=J&~q0,$=q0&~J;if(q0=J,i&&_8(J,Q,$))return;if($&o.CIRCLE)DJ(null);if(Q===0)return;if(Q&o.DOWN)z0("down");if(Q&o.RIGHT)z0("right");if(Q&o.UP)z0("up");if(Q&o.LEFT)z0("left");if(Q&o.CIRCLE)DJ(C),i1()}var l0=null;function J4(J){l0=J}function SJ(){if(r1(),l0)l0()}function w8(J,Q){J.debugName=Q||void 0,SJ()}var GJ={id:h6,type:KJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},Q4=Symbol.for("pocketjs.native-node"),u0=1,lJ=3,ZJ=8,S8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function j0(J){return J.domAttrs??={}}function $4(J,Q){let $=J.domNodeType??(uJ(J)?lJ:u0),Z=$===lJ?F0(J.text??""):$===ZJ?x8(J.domData??""):G4(J.domTag??K0(J));for(let X of Object.keys(J.domAttrs??{}))p0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)HJ(Z,$4(X,!0));return Z}function p0(J,Q,$){if(S8.has(Q)){fJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete j0(J)[Q];else j0(J)[Q]=$}function c0(J){if(J[Q4]===!0)return J;return Object.defineProperty(J,Q4,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?lJ:u0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===ZJ?J.domData??"":J.text??""},set($){if(J.domNodeType===ZJ)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===ZJ?J.domData??"":J.text??""},set($){if(J.domNodeType===ZJ)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===ZJ)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===ZJ)J.domData=Z;else if(uJ(J))B0(J,Z);else if(T8(J),Z)HJ(J,F0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return j4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??K0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===lJ)return"#text";if(J.domNodeType===ZJ)return"#comment";return(J.domTag??K0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){fJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===GJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return HJ(J,$),$},insertBefore($,Z){return HJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return HJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return $4(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){p0(J,$,Z)},removeAttribute($){p0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(GJ);var d0=null;function y8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},Z4=new Map;function X4(J,Q){Z4.set(J,Q)}var W4=new Map;function q4(J,Q){W4.set(J,Q)}var yJ=new Set,f8=new Set;function z4(J){if(!J)return!1;if(f8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:b().createNode(Q),type:Q,parent:null,children:[],domNodeType:u0,domTag:J})}function F0(J){let Q=b(),$=Q.createNode(KJ.text);return Q.setText($,J),c0({id:$,type:KJ.text,parent:null,children:[],text:J,domNodeType:lJ,domTag:"#text"})}function x8(J=""){let Q=F0("");return Q.domNodeType=ZJ,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){b().replaceText(J.id,Q),J.text=Q,SJ()}function uJ(J){return J.type===KJ.text}function H4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function HJ(J,Q,$){let Z=b();if(H4(Q),yJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,SJ()}function pJ(J,Q){if(!Q)return;D8(Q),b().removeChild(J.id,Q.id),H4(Q),yJ.add(Q),SJ()}function C8(J){return J.parent??void 0}function g8(J){return J.children[0]}function j4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function h8(J,Q){let $=b();if(SJ(),Q==null||Q===""){$.setStyle(J.id,E6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function E8(J,Q){let $=b();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=Z4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function b8(J,Q){let $=b();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=W4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function N8(J,Q,$){let Z=b(),X=Q??{},W=$??{},z=!1;for(let F in X){let D=X[F];if(W[F]===D)continue;let R=b6[F];if(R===void 0)throw Error(`PocketJS: unknown style prop '${F}' (see spec PROP)`);Z.setProp(J.id,R,n6(F,D)),z=!0}if(z)SJ()}function fJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete j0(J)[Q];else j0(J)[Q]=$;switch(Q){case"class":return h8(J,$),$;case"onPress":case"on:press":return j8(J,$),$;case"src":return E8(J,$),$;case"sprite":return b8(J,$),$;case"style":return N8(J,$,Z),$;case"focusable":return F8(J,!!$),$;case"debugName":return w8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${K0(J)}>`)}function T8(J){for(let Q of[...J.children])pJ(J,Q)}function K0(J){for(let Q of Object.keys(KJ))if(KJ[Q]===J.type)return Q;return String(J.type)}function v8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}fJ(J,Q,$,Z)}var m8=g6({createElement:G4,createTextNode:F0,replaceText:B0,isTextNode:uJ,setProperty:v8,insertNode(J,Q,$){HJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:C8,getFirstChild:g8,getNextSibling:j4}),{render:l8,effect:iQ,memo:l,createComponent:q,createElement:F4,insert:sQ,spread:u8,mergeProps:aQ,use:rQ}=m8,nQ={linear:d.Easing.Linear,in:d.Easing.EaseIn,out:d.Easing.EaseOut,"in-out":d.Easing.EaseInOut,"out-back":d.Easing.OutBack,spring:d.Easing.Spring,"spring-bouncy":d.Easing.SpringBouncy},p8=null;function B4(J){p8=J}function c8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function K4(J,Q){let $=F4(J);return u8($,Q,!1),c8(Q.nodeRef,$),$}function V(J){return K4("view",J)}function O(J){return K4("text",J)}var oQ=new WeakMap,tQ=new WeakMap,d8={}!==null?Object.freeze({...{}}):Object.freeze({}),eQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:d8}),J9=new Map,jJ=36000,s0=30,i8=30,Y={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(jJ),tapeAnalog:new Uint16Array(jJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function s8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};Y.ops=J,Y.frame=0,Y.tapeStart=0,Y.tapeLen=0,Y.tapeFirstFrame=0,Y.tapeTouch=null,Y.replayMasks=null,Y.replayAnalog=null,Y.replayTouch=null,Y.paused=!1,Y.stepQueued=0,Y.inspectReportId=null,Y.inspectAskedAt=0,Y.treeDirty=!0,Y.treeSentAt=-s0,Y.saidHello=!1,Y.hostCalls=0,Y.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)Y.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)Y.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else Y.transport=null;if(Y.transport)J4(()=>{Y.treeDirty=!0}),Q2();else J4(null);globalThis.__pocketDevtools=Z2}function a8(J){return(Q,$,Z,X)=>{if(Y.hostCalls++,Y.transport)n8(),e8();let W=Q,z=$===void 0?UJ:$&65535,F=Z,D=X;if(Y.replayMasks)if(Y.replayAt0?$.slice(0,8):null;if(Z&&!Y.tapeTouch)Y.tapeTouch=Array(jJ).fill(null);if(Y.tapeLen1||Q.length===1&&Q[0][0]!==UJ)J.analog=Q;if(Y.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function P4(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,z]of J)Z.fill(W,X,Math.min(X+z,$)),X+=z;return Z}function V4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return P4(J.masks,0,Q)}function D4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return P4(J.analog??[],UJ,Q)}function R4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&Y.hostCalls%Q!==0)return;if(!Y.saidHello)Y.saidHello=!0,T({t:"hello",app:Y.app,host:$2(),frame:Y.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` -`))if(X.trim())o8(X)}}function o8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=Y.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),Y.inspectReportId=Z||null,Y.inspectAskedAt=Y.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":Y.paused=!0,Y.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":Y.paused=!1,$?.debugPause?.(!1),a0();break;case"step":Y.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":O4();break;case"eval":{let Z=!0,X;try{X=U0((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}T({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":T({t:"tape",tape:M4()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}T({t:"devStats",frame:Y.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:Y.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))Y.replayMasks=V4(Z),Y.replayAnalog=Z.analog?D4(Z):null,Y.replayTouch=Z.touch?R4(Z):null,Y.replayAt=0;break}default:break}}function t8(){if(Y.treeDirty&&Y.frame-Y.treeSentAt>=s0)O4();if(Y.frame%i8===0)a0()}function e8(){let J=Y.inspectReportId;if(J==null)return;let Q=Y.ops;if(!Q?.debugRectXY||!Q.debugRectWH){Y.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(Y.hostCalls-Y.inspectAskedAt>60)Y.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();Y.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){T({t:"stats",frame:Y.frame,nodes:k4(GJ),tapeLen:Y.tapeLen,paused:Y.paused})}function O4(){Y.treeDirty=!1,Y.treeSentAt=Y.frame,T({t:"tree",frame:Y.frame,root:I4(GJ)})}function J2(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(J2(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function L4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function I4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(L4(J,(X)=>{if(X.domNodeType===8)return;Z.push(I4(X))}),Z.length)Q.k=Z;return Q}function k4(J){let Q=1;return L4(J,($)=>{Q+=k4($)}),Q}function Q2(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{T({t:"log",level:$,args:X.map((W)=>U0(W))}),Z?.apply(Q,X)}}}function U0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?_4(W):JSON.stringify(_4(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((z)=>U0(z,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,z])=>`${W}: ${U0(z,Q+1)}`).join(", ")}}`}function _4(J){return J.length>200?J.slice(0,199)+"…":J}function $2(){let J=Y.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var Z2={get frame(){return Y.frame},dumpTape:()=>M4(),replay:(J)=>{Y.replayMasks=V4(J),Y.replayAnalog=J.analog?D4(J):null,Y.replayTouch=J.touch?R4(J):null,Y.replayAt=0}},A4=new Map,n0=new Map;function w4(J){return J.trim().replace(/\s+/g," ")}function S4(J){return J.split(" ").sort().join(" ")}var y4=-1;function X2(J){for(let Q of Object.keys(J)){let $=J[Q],Z=w4(Q);A4.set(Z,$);let X=S4(Z),W=n0.get(X);n0.set(X,W!==void 0&&W!==$?y4:$)}}function W2(J){let Q=w4(J),$=A4.get(Q);if($!==void 0)return $;let Z=n0.get(S4(Q));return Z===y4?void 0:Z}var o0=9,q2=(1<{let X=($&Y2)!==0,W=X?t0:o0,z=X?G2:q2;return Object.freeze({id:$>>>(X?H2:z2)&255,x:$&z,y:$>>>W&z,hit:Q?.[Z]})}))}function F2(){return M0}function B2(){M0=e0}var f4=8,FJ=8,K2=3,U2=8,M2=6,P2=0.5,e=1,cJ=2,J1=4,RJ=8,xJ=[],x4=0,P0=0,BJ=Array.from({length:f4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(FJ),histY:new Int16Array(FJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function V2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function D2(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=e1(Q,$,Z.fact);let F=Z.hit;if(F)return V2(F,W)}let z=X.rect?.();if(!z)return!1;return Q>=z.x&&Q=z.y&&$=0;z--){let F=xJ[z];if(F.disposed)continue;if(x4>0&&!F.opts.allowWhenBlocked)continue;if(!D2(F,$,Z,W))continue;F.flags[J.slot]=e,J.owners.push(F)}for(let z of J.owners)z.opts.onDown?.(J)}function L2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%FJ,J.histLenz||Z>z))X.flags[J.slot]|=cJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&e)||W&(cJ|J1))continue;if(!X.opts.onLongPress)continue;let z=Math.max(1,Math.round((X.opts.longPressSeconds??P2)*N1()));if(J.frames=0)xJ.splice($,1)},cancel(){if(!Q.disposed)h4(Q)},get panning(){for(let $ of BJ)if($.used&&Q.flags[$.slot]&RJ)return!0;return!1}}}function w2(J){let Q=A2(J);return w0(()=>Q.dispose()),Q}function E4(){xJ.length=0,x4=0,P0=0;for(let J of BJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function S2(){return w2({onDown:(J)=>{let Q=t1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=t1(J.x,J.y,J.hit);if(Q)V8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var y2=1,Q1=new Map,V0=[];function f2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function x2(){y2=1,Q1.clear(),V0=[]}function C2(){if(V0.length===0)return;let J=V0;V0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),f2()?.({t:"delivery",frame:T1(),id:Q,kind:Z.kind}),Z.onResult($)}}var b4=new Set;function g2(){if(b4.size===0)return;for(let J of b4)J()}var h2={"w-[210] h-[104]":0,"h-[72] px-5 flex-row items-center justify-between":1,"w-[450] flex-col gap-2":2,"text-lg text-slate-900 font-bold":3,"text-base text-slate-500":4,"text-base text-emerald-600 font-bold":5,"text-base text-slate-900 font-bold":6,"h-[64] px-5 flex-row items-center":7,"w-[240] text-lg text-slate-900 font-bold":8,"w-[156] text-base text-slate-500":9,"relative w-[632] h-[196] flex-col":10,"relative w-[632] h-[160] overflow-hidden":11,"absolute w-[632] h-[2] bg-slate-200":12,"absolute text-base text-slate-500 font-bold":13,"absolute rounded-lg bg-emerald-500":14,"absolute rounded-lg bg-red-500":15,"absolute w-[6] h-[6] rounded-lg bg-emerald-500":16,"absolute w-[6] h-[6] rounded-lg bg-red-500":17,"h-[36] px-1 flex-row items-center justify-between":18,"flex-col w-full h-full bg-slate-50":19,"h-[64] px-6 pt-2":20,"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":21,"text-base text-slate-500 font-bold":22,"h-[304] px-6 pt-3":23,"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100":24,"h-[64] flex-row items-end justify-between":25,"text-2xl text-slate-950 font-bold":26,"text-lg text-emerald-600 font-bold":27,"text-lg text-red-500 font-bold":28,"h-[60] px-6 pt-2 flex-row gap-3":29,"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":30,"w-[100] h-[44] items-center justify-center rounded-lg bg-white":31,"text-base text-white font-bold":32,"pt-3 text-base text-slate-500":33,"h-[126] px-6 pt-3 flex-row items-start gap-[21]":34,"h-[200] px-6 flex-col":35,"h-[150] flex-col rounded-xl shadow bg-white border-slate-100":36,"h-[184] px-6 flex-col":37,"h-[136] flex-col rounded-xl shadow bg-white border-slate-100":38,"h-[126] px-6 pt-2":39,"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":40,"flex-col gap-3":41,"text-xl text-slate-900 font-bold":42,"text-2xl text-emerald-600 font-bold":43,"text-2xl text-red-500 font-bold":44,"h-[104] px-6 flex-row items-center justify-between":45,"w-[460] h-[64]":46,"w-[176] h-[64]":47,"absolute left-[628] top-[156] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":48,"absolute left-[628] top-[972] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":49,"relative flex-col w-full h-full bg-slate-50":50,"px-6 pt-[14] flex-col gap-[12]":51,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":52,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":53,"flex-row items-center justify-between":54,"text-lg text-slate-500 font-bold":55,"px-6 pt-[14] flex-col gap-[14]":56,"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100":57,"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":58,"flex-row items-center":59,"w-[170] text-xl text-slate-900 font-bold":60,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":61,"absolute inset-0 z-50 flex-col items-center justify-center":62,"absolute inset-0 bg-slate-950":63,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":64,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":65,"flex-row flex-wrap":66,grow:67,"text-2xl text-white font-bold":68,"text-base text-slate-600 font-bold":69,"text-lg text-slate-900":70,"px-6":71,"px-6 py-5":72,"gap-4":73,"rounded-xl shadow bg-white border-slate-100":74,"rounded-xl shadow bg-emerald-100 border-emerald-500":75,"bg-white":76,"bg-slate-100":77,"bg-slate-950":78,"px-3 py-2 rounded-lg bg-slate-100":79,"px-3 py-2 rounded-lg bg-indigo-100":80,"text-base text-indigo-700 font-bold":81,"px-3 py-2 rounded-lg bg-emerald-100":82,"text-base text-emerald-700 font-bold":83,"px-3 py-2 rounded-lg bg-amber-100":84,"text-base text-amber-700 font-bold":85,"px-3 py-2 rounded-lg bg-red-100":86,"text-base text-red-500 font-bold":87,"w-[34] h-[34] rounded-lg bg-amber-400":88,"w-[34] h-[34] rounded-lg bg-red-500":89,"w-[34] h-[34] rounded-lg bg-slate-800":90,"w-[34] h-[34] rounded-lg bg-emerald-500":91,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":92,"flex-row items-center gap-4":93,"w-[34] text-2xl text-white font-bold":94,"w-[332] flex-col items-end gap-2":95,"text-base text-slate-300 font-bold":96,"text-base text-slate-400":97,"h-[166] px-6 pt-6 flex-col gap-3":98,"text-base text-orange-600 font-bold":99,"text-lg text-slate-600":100,"h-[44] px-1 flex-row items-center justify-between":101,"w-full h-full items-center justify-center rounded-xl bg-slate-200":102,"w-full h-full items-center justify-center rounded-xl bg-red-100":103,"w-full h-full items-center justify-center rounded-xl bg-slate-100":104,"w-full h-full items-center justify-center rounded-xl bg-orange-600":105,"text-lg text-white font-bold":106,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":107,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":108,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":109,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":110,"text-2xl text-indigo-700 font-bold":111,"text-2xl text-slate-600 font-bold":112,"pt-7 text-2xl text-slate-900 font-bold":113,"pt-4 text-lg text-slate-500":114,"text-xl text-emerald-600 font-bold":115,"text-xl text-red-500 font-bold":116,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":117,"text-base text-red-300":118,"text-base text-slate-300":119,"text-base text-red-500":120,"w-full h-full px-6 flex-row items-center bg-slate-950":121,"w-full h-full flex-row items-center":122};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var E2="ui:styles",b2="ui:font.",N4="ui:img.",T4="ui:sprite.";function N2(){return globalThis.ui}function T2(J){if(J.__textures)return;for(let Q of E0(N4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)X4(Q.slice(N4.length),Z)}}function v2(J){if(J.__sprites)return;for(let Q of E0(T4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),z=$[4],F=Z.getUint16(6,!0),D=Z.getUint16(8,!0),R=Z.getUint16(10,!0),U=J.uploadTexture($.subarray(16),X,W,z);if(U>=0)q4(Q.slice(T4.length),{handle:U,frames:F,cols:D,step:R})}}function v4(J){let Q=F4("view");return fJ(Q,"style",J,void 0),Q}var D0=null,R0=null;function m2(J,Q){if(!D0||!R0)return;fJ(D0,"style",{width:J,height:Q,overflow:d.Overflow.Hidden},void 0),fJ(R0,"style",{width:J,height:Q,posType:d.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=b();$.__viewport={w:J,h:Q}}function l2(J,Q={}){let $=d6(Q.ops);if(i6($),y8(W2),Q.styles)X2(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let w in Z)X4(w,Z[w]);let H=$.ops.__sprites;if(H)for(let w in H)q4(w,H[w])}if($.kind==="injected"||Z===void 0){if(Q.pak)p1(Q.pak);if(H8()){for(let H of E0())if(H===E2)$.ops.loadStyles?.(vJ(H));else if(H.startsWith(b2))$.ops.loadFontAtlas?.(vJ(H))}}let X=h1($.ops),W=X?.w??x1,z=X?.h??C1,F=v4({width:W,height:z,overflow:d.Overflow.Hidden}),D=v4({width:W,height:z,posType:d.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});HJ(GJ,F),HJ(GJ,D),B4(D),D0=F,R0=D,c1(F),n1(GJ),z8(),E4(),S2(),J8(),x2(),s8($.ops),s6(a8((H,w,x,g)=>{Q8(),$8(w),j2(x,g),g2(),C2(),_2(),Y8(H),A8(H),Y4()}));let R=l8(J,F),U=a6(m2);return()=>{U(),B2(),E4(),R(),c1(null),n1(null),B4(null),D0=null,R0=null;for(let H of GJ.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);Y4()}}function u2(J,Q={}){let $=Q.ops??N2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)p1(Q.pak);return T2($),v2($),l2(J,{ops:$,styles:Q.styles??h2,pak:Q.pak})}var m4="$b",p2=9007199254740991,c2=":memory:",CJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function d2(J){let Q="";for(let $=0;$>2]+CJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2p2)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function a2(J){if(J!==null&&typeof J==="object")return i2(J[m4]);return J}function r2(J){if(Array.isArray(J))return JSON.stringify(J.map(l4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=l4(Z);return JSON.stringify(Q)}class $1{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,r2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=u4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(a2))}run(...J){let Q=this.execute(u4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function u4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class p4{statements=new Map;txDepth=0;constructor(J=c2){let Q=s2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new $1(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new $1(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let z=J(...Q);return this.txDepth--,this.exec(X),z}catch(z){throw this.txDepth--,this.exec(W),z}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var O0={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",body:"text-lg text-slate-900",bodyStrong:"text-lg text-slate-900 font-bold",caption:"text-base text-slate-500",captionStrong:"text-base text-slate-500 font-bold"},c4={neutral:{surface:"px-3 py-2 rounded-lg bg-slate-100",text:"text-base text-slate-600 font-bold"},info:{surface:"px-3 py-2 rounded-lg bg-indigo-100",text:"text-base text-indigo-700 font-bold"},success:{surface:"px-3 py-2 rounded-lg bg-emerald-100",text:"text-base text-emerald-700 font-bold"},warning:{surface:"px-3 py-2 rounded-lg bg-amber-100",text:"text-base text-amber-700 font-bold"},danger:{surface:"px-3 py-2 rounded-lg bg-red-100",text:"text-base text-red-500 font-bold"}};function n2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return q(V,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[q(V,{class:"flex-row items-center gap-4",get children(){return[l(()=>l(()=>!!J.back)()?q(O,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):q(V,{get["class"](){return Q()}})),q(O,{get["class"](){return O0.appTitle},get children(){return J.title}})]}}),q(V,{class:"w-[332] flex-col items-end gap-2",get children(){return[q(O,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),q(O,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function o2(J){let Q=()=>J.action?J.detail?J.detail+" · VIEW ALL ›":"VIEW ALL ›":J.detail??"";return q(V,{class:"h-[44] px-1 flex-row items-center justify-between",get children(){return[q(O,{get["class"](){return O0.heading},get children(){return J.title}}),q(O,{get["class"](){return O0.captionStrong},get children(){return Q()}})]}})}function t2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return q(V,{get["class"](){return Q()},get children(){return q(O,{get["class"](){return $()},get children(){return J.label}})}})}function d4(J){return q(V,{get["class"](){return J.compact?"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100"},get children(){return[l(()=>l(()=>!!J.icon)()?q(V,{get["class"](){return J.tone==="info"?"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100"},get children(){return q(O,{get["class"](){return J.tone==="info"?"text-2xl text-indigo-700 font-bold":"text-2xl text-slate-600 font-bold"},get children(){return J.icon}})}}):null),q(O,{get["class"](){return J.icon?"pt-7 text-2xl text-slate-900 font-bold":"text-lg text-slate-500 font-bold"},get children(){return J.title}}),l(()=>l(()=>!!J.detail)()?q(O,{class:"pt-4 text-lg text-slate-500",get children(){return J.detail}}):null)]}})}function e2(J){let Q=()=>J.tone==="success"?"text-xl text-emerald-600 font-bold":J.tone==="danger"?"text-xl text-red-500 font-bold":"text-xl text-slate-900 font-bold";return q(V,{class:"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(O,{get["class"](){return O0.label},get children(){return J.label}}),q(O,{get["class"](){return Q()},get children(){return J.value}})]}})}function JQ(J){let Q=()=>J.dark?J.tone==="danger"?"text-base text-red-300":"text-base text-slate-300":J.tone==="danger"?"text-base text-red-500":"text-base text-slate-500";return q(V,{get["class"](){return J.dark?"w-full h-full px-6 flex-row items-center bg-slate-950":"w-full h-full flex-row items-center"},get children(){return q(O,{get["class"](){return Q()},get children(){return J.text}})}})}function QQ(J){return[q(V,{get["class"](){return J.top},get children(){return q(O,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),q(V,{get["class"](){return J.bottom},get children(){return q(O,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var i4=5,m=new p4("robinhood"),$Q={number:"",label:"ACCOUNT",suffix:"",status:"WAITING FOR ROBINHOOD"},Z1={title:"NO RECENT ACTIVITY",timestamp:"",detail:"",state:"",amount:"",side:""},ZQ={...Z1,title:"ACTIVITY UNAVAILABLE"},XQ={...Z1,title:""},X1={symbol:"NO OPEN POSITIONS",quantity:"",averagePrice:"",marketValue:""},WQ={...X1,symbol:"POSITIONS UNAVAILABLE"},qQ={...X1,symbol:""},iJ={account:$Q,totalValue:null,cash:null,buyingPower:null,pnlDay:null,pnlWeek:null,positions:[],activity:[],positionsAvailable:!0,activityAvailable:!0,observedAt:null},[s,sJ]=E("dashboard"),[u,zQ]=E("day"),[gJ,W1]=E([]),[L0,I0]=E(""),[y,aJ]=E(iJ),[s4,OJ]=E([]),[YQ,LJ]=E([]),[q1,z1]=E([]),[GQ,Y1]=E({change:"$—",percent:"—",positive:!0}),[G1,a4]=E(0),[r4,n4]=E(0),[o4,t4]=E(0),[e4,XJ]=E("WAITING FOR ROBINHOOD"),[rJ,J6]=E(!1),p=0,Q6=-1,$6=-1,Z6=-1,H1=new Map,j1=new Map;function X6(){return Math.floor(Date.now()/1000)}function HQ(J){try{return J?JSON.parse(J):null}catch{return null}}function jQ(){return m.query("SELECT account_number,label,suffix,status FROM accounts ORDER BY label,account_number LIMIT 16").all().map((Q)=>({number:Q.account_number,label:Q.label,suffix:Q.suffix,status:Q.status}))}function FQ(J,Q){if($6===J)return;let $=m.query("SELECT account_number,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current LIMIT 16").all(),Z=m.query(` +(()=>{var _J={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return M1(this.context.count)},getNextContextId(){return M1(this.context.count++)}};function M1(J){let Q=String(J),$=Q.length-1;return _J.context.id+($?String.fromCharCode(96+$):"")+Q}function P1(J){_J.context=J}function F6(){return{..._J.context,id:_J.getNextContextId(),count:0}}var B6=!1,K6=(J,Q)=>J===Q,A0=Symbol("solid-proxy"),U6=typeof Proxy==="function",M6=Symbol("solid-track"),AQ=Symbol("solid-dev-component"),nJ={equals:K6},V1=null,P6=_1,p=1,hJ=2,D1={owned:null,cleanups:null,context:null,owner:null},S=null,B=null,EJ=null,AJ=null,f=null,b=null,N=null,oJ=0;function tJ(J,Q){let $=f,Z=S,X=J.length===0,W=Q===void 0?Z:Q,Y=X?D1:{owned:null,cleanups:null,context:W?W.context:null,owner:W},F=X?J:()=>J(()=>WJ(()=>qJ(Y)));S=Y,f=null;try{return r(F,!0)}finally{f=$,S=Z}}function h(J,Q){Q=Q?Object.assign({},nJ,Q):nJ;let $={value:J,observers:null,observerSlots:null,comparator:Q.equals||void 0},Z=(X)=>{if(typeof X==="function")if(B&&B.running&&B.sources.has($))X=X($.tValue);else X=X($.value);return L1($,X)};return[O1.bind($),Z]}function XJ(J,Q,$){let Z=k1(J,Q,!1,p);if(EJ&&B&&B.running)b.push(Z);else J0(Z)}function QJ(J,Q,$){$=$?Object.assign({},nJ,$):nJ;let Z=k1(J,Q,!0,0);if(Z.observers=null,Z.observerSlots=null,Z.comparator=$.equals||void 0,EJ&&B&&B.running)Z.tState=p,b.push(Z);else J0(Z);return O1.bind(Z)}function eJ(J){return r(J,!1)}function WJ(J){if(!AJ&&f===null)return J();let Q=f;f=null;try{if(AJ)return AJ.untrack(J);return J()}finally{f=Q}}function w0(J){if(S===null);else if(S.cleanups===null)S.cleanups=[J];else S.cleanups.push(J);return J}function V6(J){if(B&&B.running)return J(),B.done;let Q=f,$=S;return Promise.resolve().then(()=>{f=Q,S=$;let Z;if(EJ||D6)Z=B||(B={sources:new Set,effects:[],promises:new Set,disposed:new Set,queue:new Set,running:!0}),Z.done||(Z.done=new Promise((X)=>Z.resolve=X)),Z.running=!0;return r(J,!1),f=S=null,Z?Z.done:void 0})}var[wQ,R1]=h(!1),D6;function O1(){let J=B&&B.running;if(this.sources&&(J?this.tState:this.state))if((J?this.tState:this.state)===p)J0(this);else{let Q=b;b=null,r(()=>Q0(this),!1),b=Q}if(f){let Q=this.observers;if(!Q||Q[Q.length-1]!==f){let $=Q?Q.length:0;if(!f.sources)f.sources=[this],f.sourceSlots=[$];else f.sources.push(this),f.sourceSlots.push($);if(!Q)this.observers=[f],this.observerSlots=[f.sources.length-1];else Q.push(f),this.observerSlots.push(f.sources.length-1)}}if(J&&B.sources.has(this))return this.tValue;return this.value}function L1(J,Q,$){let Z=B&&B.running&&B.sources.has(J)?J.tValue:J.value;if(!J.comparator||!J.comparator(Z,Q)){if(B){let X=B.running;if(X||!$&&B.sources.has(J))B.sources.add(J),J.tValue=Q;if(!X)J.value=Q}else J.value=Q;if(J.observers&&J.observers.length)r(()=>{for(let X=0;X1e6)throw b=[],Error()},!1)}return Q}function J0(J){if(!J.fn)return;qJ(J);let Q=oJ;if(I1(J,B&&B.running&&B.sources.has(J)?J.tValue:J.value,Q),B&&!B.running&&B.sources.has(J))queueMicrotask(()=>{r(()=>{B&&(B.running=!0),f=S=J,I1(J,J.tValue,Q),f=S=null},!1)})}function I1(J,Q,$){let Z,X=S,W=f;f=S=J;try{Z=J.fn(Q)}catch(Y){if(J.pure)if(B&&B.running)J.tState=p,J.tOwned&&J.tOwned.forEach(qJ),J.tOwned=void 0;else J.state=p,J.owned&&J.owned.forEach(qJ),J.owned=null;return J.updatedAt=$+1,y0(Y)}finally{f=W,S=X}if(!J.updatedAt||J.updatedAt<=$){if(J.updatedAt!=null&&"observers"in J)L1(J,Z,!0);else if(B&&B.running&&J.pure){if(!B.sources.has(J))J.value=Z;B.sources.add(J),J.tValue=Z}else J.value=Z;J.updatedAt=$}}function k1(J,Q,$,Z=p,X){let W={fn:J,state:Z,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:Q,owner:S,context:S?S.context:null,pure:$};if(B&&B.running)W.state=0,W.tState=Z;if(S===null);else if(S!==D1)if(B&&B.running&&S.pure)if(!S.tOwned)S.tOwned=[W];else S.tOwned.push(W);else if(!S.owned)S.owned=[W];else S.owned.push(W);if(AJ&&W.fn){let Y=W.fn,[F,D]=h(void 0,{equals:!1}),R=AJ.factory(Y,D);w0(()=>R.dispose());let U,H=()=>V6(D).then(()=>{if(U)U.dispose(),U=void 0});W.fn=(w)=>{if(F(),B&&B.running){if(!U)U=AJ.factory(Y,H);return U.track(w)}return R.track(w)}}return W}function S0(J){let Q=B&&B.running;if((Q?J.tState:J.state)===0)return;if((Q?J.tState:J.state)===hJ)return Q0(J);if(J.suspense&&WJ(J.suspense.inFallback))return J.suspense.effects.push(J);let $=[J];while((J=J.owner)&&(!J.updatedAt||J.updatedAt=0;Z--){if(J=$[Z],Q){let X=J,W=$[Z+1];while((X=X.owner)&&X!==W)if(B.disposed.has(X))return}if((Q?J.tState:J.state)===p)J0(J);else if((Q?J.tState:J.state)===hJ){let X=b;b=null,r(()=>Q0(J,$[0]),!1),b=X}}}function r(J,Q){if(b)return J();let $=!1;if(!Q)b=[];if(N)$=!0;else N=[];oJ++;try{let Z=J();return R6($),Z}catch(Z){if(!$)N=null;b=null,y0(Z)}}function R6(J){if(b){if(EJ&&B&&B.running)O6(b);else _1(b);b=null}if(J)return;let Q;if(B){if(!B.promises.size&&!B.queue.size){let{sources:Z,disposed:X}=B;N.push.apply(N,B.effects),Q=B.resolve;for(let W of N)"tState"in W&&(W.state=W.tState),delete W.tState;B=null,r(()=>{for(let W of X)qJ(W);for(let W of Z){if(W.value=W.tValue,W.owned)for(let Y=0,F=W.owned.length;YP6($),!1);if(Q)Q()}function _1(J){for(let Q=0;Q{Z.delete($),r(()=>{B.running=!0,S0($)},!1),B&&(B.running=!1)})}}function Q0(J,Q){let $=B&&B.running;if($)J.tState=0;else J.state=0;for(let Z=0;Z=0;Q--)qJ(J.tOwned[Q]);delete J.tOwned}if(B&&B.running&&J.pure)w1(J,!0);else if(J.owned){for(Q=J.owned.length-1;Q>=0;Q--)qJ(J.owned[Q]);J.owned=null}if(J.cleanups){for(Q=J.cleanups.length-1;Q>=0;Q--)J.cleanups[Q]();J.cleanups=null}if(B&&B.running)J.tState=0;else J.state=0}function w1(J,Q){if(!Q)J.tState=0,B.disposed.add(J);if(J.owned)for(let $=0;$1?[]:null;return w0(()=>y1(W)),()=>{let D=J()||[],R=D.length,U,H;return D[M6],WJ(()=>{let x,g,A,s,a,K,j,G,P;if(R===0){if(Y!==0)y1(W),W=[],Z=[],X=[],Y=0,F&&(F=[]);if($.fallback)Z=[I6],X[0]=tJ((k)=>{return W[0]=k,$.fallback()}),Y=1}else if(Y===0){X=Array(R);for(H=0;H=K&&G>=K&&Z[j]===D[G];j--,G--)A[G]=X[j],s[G]=W[j],F&&(a[G]=F[j]);x=new Map,g=Array(G+1);for(H=G;H>=K;H--)P=D[H],U=x.get(P),g[H]=U===void 0?-1:U,x.set(P,H);for(U=K;U<=j;U++)if(P=Z[U],H=x.get(P),H!==void 0&&H!==-1)A[H]=X[U],s[H]=W[U],F&&(a[H]=F[U]),H=g[H],x.set(P,H);else W[U]();for(H=K;HJ(Q||{}));return P1($),Z}}return WJ(()=>J(Q||{}))}function $0(){return!0}var w6={get(J,Q,$){if(Q===A0)return $;return J.get(Q)},has(J,Q){if(Q===A0)return!0;return J.has(Q)},set:$0,deleteProperty:$0,getOwnPropertyDescriptor(J,Q){return{configurable:!0,enumerable:!0,get(){return J.get(Q)},set:$0,deleteProperty:$0}},ownKeys(J){return J.keys()}};function f0(J){return!(J=typeof J==="function"?J():J)?{}:J}function S6(){for(let J=0,Q=this.length;J=0;F--){let D=f0(J[F])[Y];if(D!==void 0)return D}},has(Y){for(let F=J.length-1;F>=0;F--)if(Y in f0(J[F]))return!0;return!1},keys(){let Y=[];for(let F=0;F=0;Y--){let F=J[Y];if(!F)continue;let D=Object.getOwnPropertyNames(F);for(let R=D.length-1;R>=0;R--){let U=D[R];if(U==="__proto__"||U==="constructor")continue;let H=Object.getOwnPropertyDescriptor(F,U);if(!Z[U])Z[U]=H.get?{enumerable:!0,configurable:!0,get:S6.bind($[U]=[H.get.bind(F)])}:H.value!==void 0?H:void 0;else{let w=$[U];if(w){if(H.get)w.push(H.get.bind(F));else if(H.value!==void 0)w.push(()=>H.value)}}}}let X={},W=Object.keys(Z);for(let Y=W.length-1;Y>=0;Y--){let F=W[Y],D=Z[F];if(D&&D.get)Object.defineProperty(X,F,D);else X[F]=D?D.value:void 0}return X}var y6=(J)=>`Stale read from <${J}>.`;function NJ(J){let Q="fallback"in J&&{fallback:()=>J.fallback};return QJ(k6(()=>J.each,J.children,Q||void 0))}function Z0(J){let Q=J.keyed,$=QJ(()=>J.when,void 0,void 0),Z=Q?$:QJ($,void 0,{equals:(X,W)=>!X===!W});return QJ(()=>{let X=Z();if(X){let W=J.children;return typeof W==="function"&&W.length>0?WJ(()=>W(Q?X:()=>{if(!WJ(Z))throw y6("Show");return $()})):W}return J.fallback},void 0,void 0)}var f6=(J)=>QJ(()=>J());function x6({createElement:J,createTextNode:Q,isTextNode:$,replaceText:Z,insertNode:X,removeNode:W,setProperty:Y,getParentNode:F,getFirstChild:D,getNextSibling:R}){function U(K,j,G,P){if(G!==void 0&&!P)P=[];if(typeof j!=="function")return H(K,j,P,G);XJ((k)=>H(K,j(),k,G),P)}function H(K,j,G,P,k){while(typeof G==="function")G=G();if(j===G)return G;let _=typeof j,I=P!==void 0;if(_==="string"||_==="number"){if(_==="number")j=j.toString();if(I){let L=G[0];if(L&&$(L))Z(L,j);else L=Q(j);G=g(K,G,P,L)}else if(G!==""&&typeof G==="string")Z(D(K),G=j);else g(K,G,P,Q(j)),G=j}else if(j==null||_==="boolean")G=g(K,G,P);else if(_==="function")return XJ(()=>{let L=j();while(typeof L==="function")L=L();G=H(K,L,G,P)}),()=>G;else if(Array.isArray(j)){let L=[];if(w(L,j,k))return XJ(()=>G=H(K,L,G,P,!0)),()=>G;if(L.length===0){let bJ=g(K,G,P);if(I)return G=bJ}else if(Array.isArray(G))if(G.length===0)A(K,L,P);else x(K,G,L);else if(G==null||G==="")A(K,L);else x(K,I&&G||[D(K)],L);G=L}else{if(Array.isArray(G)){if(I)return G=g(K,G,P,j);g(K,G,null,j)}else if(G==null||G===""||!D(K))X(K,j);else s(K,j,D(K));G=j}return G}function w(K,j,G){let P=!1;for(let k=0,_=j.length;k<_;k++){let I=j[k],L;if(I==null||I===!0||I===!1);else if(Array.isArray(I))P=w(K,I)||P;else if((L=typeof I)==="string"||L==="number")K.push(Q(I));else if(L==="function")if(G){while(typeof I==="function")I=I();P=w(K,Array.isArray(I)?I:[I])||P}else K.push(I),P=!0;else K.push(I)}return P}function x(K,j,G){let P=G.length,k=j.length,_=P,I=0,L=0,bJ=R(j[k-1]),IJ=null;while(IJJ-L){let _Q=j[I];while(L=0;I--){let L=j[I];if(k!==L){let bJ=F(L)===K;if(!_&&!I)bJ?s(K,k,L):X(K,k,G);else bJ&&W(K,L)}else _=!0}}else X(K,k,G);return[k]}function A(K,j,G){for(let P=0,k=j.length;PG.children=H(K,j.children,G.children));return XJ(()=>j.ref&&j.ref(K)),XJ(()=>{for(let k in j){if(k==="children"||k==="ref")continue;let _=j[k];if(_===G[k])continue;Y(K,k,_,G[k]),G[k]=_}}),G}return{render(K,j){let G;return tJ((P)=>{G=P,U(j,K())}),G},insert:U,spread(K,j,G){if(typeof j==="function")XJ((P)=>a(K,j(),P,G));else a(K,j,void 0,G)},createElement:J,createTextNode:Q,insertNode:X,setProp(K,j,G,P){return Y(K,j,G,P),G},mergeProps:f1,effect:XJ,memo:f6,createComponent:A6,use(K,j,G){return WJ(()=>K(j,G))}}}function C6(J){let Q=x6(J);return Q.mergeProps=f1,Q}var x1=480,C1=272,KJ={view:0,text:1,image:2},g6=1,b6=-1,h6={width:1,height:2,minW:3,minH:4,maxW:5,maxH:6,paddingT:8,paddingR:9,paddingB:10,paddingL:11,marginT:12,marginR:13,marginB:14,marginL:15,gap:16,flexDir:17,justify:18,align:19,grow:20,shrink:21,basis:22,flexWrap:23,posType:24,insetT:25,insetR:26,insetB:27,insetL:28,display:29,overflow:30,zIndex:31,hitPass:32,bgColor:64,gradFrom:65,gradTo:66,gradDir:67,radius:68,opacity:69,borderColor:70,borderWidth:71,shadow:72,bevelOuterLight:77,bevelOuterDark:78,bevelInnerLight:79,bevelInnerDark:80,bevelWidth:81,textColor:96,fontSlot:97,textAlign:98,lineHeight:99,tracking:100,translateX:128,translateY:129,scale:130,rotate:131,scaleX:132,scaleY:133,originX:134,originY:135,rotateX:136,rotateY:137,translateZ:138,perspective:139,arcStart:140,arcSweep:141,arcWidth:142},M={f32:0,color:1,int:2},E6={width:M.f32,height:M.f32,minW:M.f32,minH:M.f32,maxW:M.f32,maxH:M.f32,paddingT:M.f32,paddingR:M.f32,paddingB:M.f32,paddingL:M.f32,marginT:M.f32,marginR:M.f32,marginB:M.f32,marginL:M.f32,gap:M.f32,flexDir:M.int,justify:M.int,align:M.int,grow:M.f32,shrink:M.f32,basis:M.f32,flexWrap:M.int,posType:M.int,insetT:M.f32,insetR:M.f32,insetB:M.f32,insetL:M.f32,display:M.int,overflow:M.int,zIndex:M.int,hitPass:M.int,bgColor:M.color,gradFrom:M.color,gradTo:M.color,gradDir:M.int,radius:M.f32,opacity:M.f32,borderColor:M.color,borderWidth:M.f32,shadow:M.int,bevelOuterLight:M.color,bevelOuterDark:M.color,bevelInnerLight:M.color,bevelInnerDark:M.color,bevelWidth:M.f32,textColor:M.color,fontSlot:M.int,textAlign:M.int,lineHeight:M.f32,tracking:M.f32,translateX:M.f32,translateY:M.f32,scale:M.f32,rotate:M.f32,scaleX:M.f32,scaleY:M.f32,originX:M.f32,originY:M.f32,rotateX:M.f32,rotateY:M.f32,translateZ:M.f32,perspective:M.f32,arcStart:M.f32,arcSweep:M.f32,arcWidth:M.f32},c={FlexDir:{Row:0,Col:1},Justify:{Start:0,Center:1,End:2,Between:3,Around:4},Align:{Start:0,Center:1,End:2,Stretch:3},PosType:{Relative:0,Absolute:1},Display:{Flex:0,None:1},Overflow:{Visible:0,Hidden:1},TextAlign:{Left:0,Center:1,Right:2},GradDir:{ToTop:0,ToBottom:1,ToLeft:2,ToRight:3},Easing:{Linear:0,EaseIn:1,EaseOut:2,EaseInOut:3,OutBack:4,Spring:5,SpringBouncy:6,CubicBezier:7}},N6={PSM_5650:0,PSM_4444:2,PSM_8888:3,PSM_T8:5},T6=1,SQ=2,yQ=1,fQ=2,xQ=131072,CQ=1,gQ=262144,bQ=1,hQ=1,EQ=1,NQ=2,TQ=4,vQ=8,mQ=16,lQ=1,uQ=2;function g1(J,Q,$,Z=255){return((Z&255)<<24|($&255)<<16|(Q&255)<<8|J&255)>>>0}var pQ=1,v6=1263551300,m6=1,l6=32,u6=24,n={SELECT:1,START:8,UP:16,RIGHT:32,DOWN:64,LEFT:128,LTRIGGER:256,RTRIGGER:512,TRIANGLE:4096,CIRCLE:8192,CROSS:16384,SQUARE:32768},UJ=32896,cQ=0.016666666666666666;function b1(J){return J.__viewport??null}var x0=null;function p6(){return null}function h1(J,Q=p6()){if(!Q)return;if(typeof J.__host!=="string")throw Error(`PocketJS: this bundle targets "${Q.target}" but the native host predates platform `+"contracts — add __host/__hostAbi to its ui namespace (see framework/src/host.ts HostOps)");if(J.__host!==Q.target)throw Error(`PocketJS: native target mismatch (bundle=${Q.target}, host=${J.__host})`);if(J.__hostAbi!==Q.hostAbi)throw Error(`PocketJS: native host ABI mismatch (bundle=${Q.hostAbi}, host=${J.__hostAbi??"missing"})`)}function c6(J){let Q=globalThis.ui,$=Q!==void 0&&(typeof Q.__host==="string"||Q.__textures!==void 0);if(J){if(Q!==void 0&&J===Q&&$)return h1(Q),{ops:J,kind:"native",target:Q.__host??"unknown",strict:!1};return{ops:J,kind:"injected",target:J.__host??"injected",strict:!0}}if(Q!==void 0&&$)return h1(Q),{ops:Q,kind:"native",target:Q.__host??"unknown",strict:!1};if(Q)return{ops:Q,kind:"injected",target:"injected",strict:!0};throw Error("PocketJS: no host — pass HostOps to render() (web/test) or run under a native runtime (globalThis.ui)")}function d6(J){x0=J}function wJ(){if(!x0)throw Error("PocketJS: host not installed — call render() first");return x0}function E(){return wJ().ops}function i6(J){globalThis.frame=J}function s6(J){let Q=globalThis,$=Q.__pocketResizeViewport,Z=(X,W)=>J(X,W);return Q.__pocketResizeViewport=Z,()=>{if(Q.__pocketResizeViewport!==Z)return;if($)Q.__pocketResizeViewport=$;else delete Q.__pocketResizeViewport}}function a6(J){let Q=J.slice(1);if(Q.length===3)Q=Q[0]+Q[0]+Q[1]+Q[1]+Q[2]+Q[2];if(Q.length!==6&&Q.length!==8)throw Error(`PocketJS: bad color '${J}' (expected #rgb/#rrggbb/#rrggbbaa)`);if(!/^[0-9a-fA-F]+$/.test(Q))throw Error(`PocketJS: bad color '${J}'`);let $=parseInt(Q,16);if(Q.length===6)return g1($>>>16&255,$>>>8&255,$&255,255);return g1($>>>24&255,$>>>16&255,$>>>8&255,$&255)}function r6(J,Q){let $=E6[J];if(typeof Q==="string"){if($===M.color)return a6(Q);let Z=Number(Q);if(Number.isNaN(Z))throw Error(`PocketJS: non-numeric value '${Q}' for prop '${J}'`);Q=Z}if($===M.color||$===M.int)return Q>>>0;return Q}var X0=60,E1=[1,2,3,4,5,6,10,12,15,20,30,60],C0=X0,zJ=-1,n6=0,TJ=[];function o6(J){if(!Number.isFinite(J)||J<=0)return X0;let Q=E1[0];for(let $ of E1)if(Math.abs($-J)Q.at<=zJ).sort((Q,$)=>Q.at-$.at||Q.seq-$.seq);if(J.length===0)return;TJ=TJ.filter((Q)=>Q.at>zJ);for(let Q of J)Q.cb()}var g0=0.12,W0=UJ;function Q8(J){W0=J===void 0?UJ:J&65535}function $8(){W0=UJ}function v1(J){let Q=Math.max(-1,Math.min(1,(J-128)/127)),$=Math.abs(Q);if($>8&255)}function X8(){return v1(W0&255)}var m1=new Set,W8=0;function q8(){m1.clear(),W8=0,$8()}function z8(J){for(let Q of[...m1])Q(J)}var MJ=null,l1=null;function Y8(J,Q,$){let Z="";for(let X=0;X<$;X++)Z+=String.fromCharCode(J[Q+X]);return Z}function u1(J){let Q=new DataView(J);if(J.byteLength=J.length&&$.slice(0,J.length)===J)Q.push($);return Q.sort(),Q}function vJ(J){b0();let Q=MJ?MJ.get(J):void 0;if(!Q)throw Error("pak: missing key "+J+" (no __pak provided, or the pack is incomplete)");return l1.slice(Q.off,Q.off+Q.len)}var mJ=null,C=null,PJ=null,q0=0,VJ=[],E0=[],N0=[];function c1(J){if(mJ=J,C=null,PJ=null,q0=0,VJ.length=0,E0.length=0,N0.length=0,d){if(d.pressTarget=null,d.target=null,d.spriteDirty=!0,d.fresh=!0,d.vw=0,d.tex>=0){let Q=E();Q.setCursor?.(-1,0,0,0,0),Q.freeTexture?.(d.tex),d.tex=-1}}}function H8(J,Q){J.onPress=Q??void 0}function j8(J,Q){if(J.focusable=Q,r1(),!Q&&C===J)v(null)}function v(J){if(PJ&&PJ!==J)DJ(null);C=J,E().setFocus(J?J.id:0)}function DJ(J){if(PJ===J)return;let Q=E();if(PJ)Q.setActive?.(PJ.id,0);if(PJ=J,J)Q.setActive?.(J.id,1)}function T0(){return VJ.length>0?VJ[VJ.length-1]:mJ}function v0(J,Q){if(!J)return;if(J.focusable)Q.push(J);if(!Array.isArray(J.children))return;for(let $=0;$=$.length)return;v($[X])}function K8(){if(!C)return null;let J=T0();if(J&&!o(C,J))return null;for(let Q=E0.length-1;Q>=0;Q--){let $=E0[Q];if(J&&!o($.node,J)&&!o(J,$.node))continue;if(o(C,$.node))return $}return null}function U8(J){let Q=K8();if(!Q)return!1;let $=[];if(v0(Q.node,$),$.length===0){if(C)v(null);return!0}let Z=Q.columns,X=C?$.indexOf(C):-1;if(X<0)return v(d1(J)===1?$[0]:$[$.length-1]),!0;let W=X;switch(J){case"right":if(X+1<$.length&&X%Z0)W=X-1;else if(Q.wrap)W=Math.min($.length-1,Math.floor(X/Z)*Z+Z-1);break;case"down":if(X+Z<$.length)W=X+Z;else if(Q.wrap)W=X%Z;break;case"up":if(X-Z>=0)W=X-Z;else if(Q.wrap){W=X%Z;while(W+Z<$.length)W+=Z}break}if(W!==X)v($[W]);return!0}function M8(){if(!C)return null;let J=T0();if(J&&!o(C,J))return null;for(let Q=N0.length-1;Q>=0;Q--){let $=N0[Q];if(J&&!o($.node,J)&&!o(J,$.node))continue;if(o(C,$.node))return $}return null}function z0(J){let Q=M8();if(Q&&Q.move(J))return;if(U8(J))return;B8(J)}function i1(){s1(C)}function s1(J){let Q=J;while(Q){if(Q.onPress){Q.onPress();return}Q=Q.parent}}function Y0(J){DJ(J)}function P8(J){v(J),s1(J)}function o(J,Q){if(!J||!Q)return!1;let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function m0(J){if(!J)return null;if(J.focusable)return J;if(!Array.isArray(J.children))return null;for(let Q=0;Q=0;X--){let W=m0(Q.children[X]);if(W){v(W);return}}let Z=Q;while(Z){if(Z.focusable){v(Z);return}Z=Z.parent}}v(null)}var d=null,a1=0;function r1(){a1++}var D8=[1,3,5,9,17,33,65,129,257,513,1985,73,149,147,288,480],R8=[0,0,2,6,14,30,62,126,254,510,62,54,98,96,192,0];function O8(){let J=new Uint8Array(1024);for(let Q=0;Q<16;Q++)for(let $=0;$<16;$++){let Z=D8[Q]>>$&1,X=R8[Q]>>$&1;if(!Z&&!X)continue;let W=(Q*16+$)*4,Y=X?255:0;J[W]=Y,J[W+1]=Y,J[W+2]=Y,J[W+3]=255}return J}function L8(J,Q){let $=J.sprite;J.spriteDirty=!1;let Z=J.tex,X=-1,W=null;if(typeof $.image==="string")try{W=vJ($.image)}catch(Y){if(wJ().strict)throw Y;W=null}else if($.image)W=$.image;if(W){if(X=Q.uploadImgEntry?Q.uploadImgEntry(W):I8(Q,W),X<0&&wJ().strict)throw Error("enableCursor: cursor image rejected (malformed or RLE-only IMG entry)")}if(X<0)X=Q.uploadTexture(O8(),16,16,N6.PSM_8888);if(J.tex=X,Q.setCursor(X,$.hotspot[0],$.hotspot[1],$.size[0],$.size[1]),Z>=0&&Z!==X)Q.freeTexture?.(Z)}function I8(J,Q){if(Q.length<8)return-1;let $=new DataView(Q.buffer,Q.byteOffset,Q.byteLength);if(Q[5]&T6)return-1;return J.uploadTexture(Q.subarray(8),$.getUint16(0,!0),$.getUint16(2,!0),Q[4])}function G0(J,Q){if(!J||Q===0)return null;if(J.id===Q)return J;let $=J.children;if(!Array.isArray($))return null;for(let Z=0;Z<$.length;Z++){let X=G0($[Z],Q);if(X)return X}return null}var H0=null;function n1(J){H0=J}function o1(J){let Q=VJ.length>0?VJ[VJ.length-1]:null,$=J;while($){if($.focusable&&(!Q||o($,Q)))return $;$=$.parent}return null}function t1(J,Q,$){return o1(e1(J,Q,$))}function e1(J,Q,$){if($!==void 0)return $===0?null:G0(H0??mJ,$);let Z=E(),X=Z.hitTestBounds??Z.hitTest;if(!X)return null;return G0(H0??mJ,X(J,Q))}function k8(J,Q,$){let Z=d,X=E();if(!X.hitTest||!X.setCursor||!X.setCursorPos)return!1;if(Z.vw===0){let H=b1(X);if(Z.vw=H?H.w:x1,Z.vh=H?H.h:C1,Z.x<0)Z.x=Math.floor(Z.vw/2),Z.y=Math.floor(Z.vh/2)}if(Z.spriteDirty)L8(Z,X);let W=Z8()*Z.speed,Y=X8()*Z.speed;if(Z.dpadSpeed>0&&W===0&&Y===0){if(J&n.LEFT)W=-Z.dpadSpeed;if(J&n.RIGHT)W=Z.dpadSpeed;if(J&n.UP)Y=-Z.dpadSpeed;if(J&n.DOWN)Y=Z.dpadSpeed}let F=Z.fresh;if(W!==0||Y!==0){let H=t6()/60,w=Math.min(Math.max(Z.x+W*H,0),Z.vw-1),x=Math.min(Math.max(Z.y+Y*H,0),Z.vh-1);if(w!==Z.x||x!==Z.y)Z.x=w,Z.y=x,F=!0}if(F)X.setCursorPos(Z.x,Z.y);let D=(Q|$)&Z.button,R=a1;if(F||D!==0||R!==Z.gen)Z.gen=R,Z.fresh=!1,Z.target=o1(G0(H0??mJ,X.hitTest(Z.x,Z.y)));let U=Z.target;if(U!==C)v(U);if(Q&Z.button&&U)Z.pressTarget=U;if(Z.pressTarget){if(DJ(U===Z.pressTarget?Z.pressTarget:null),$&Z.button){let H=U===Z.pressTarget;if(Z.pressTarget=null,DJ(null),H)i1()}}else if($&Z.button)DJ(null);return!0}function _8(J){let Q=J&~q0,$=q0&~J;if(q0=J,d&&k8(J,Q,$))return;if($&n.CIRCLE)DJ(null);if(Q===0)return;if(Q&n.DOWN)z0("down");if(Q&n.RIGHT)z0("right");if(Q&n.UP)z0("up");if(Q&n.LEFT)z0("left");if(Q&n.CIRCLE)DJ(C),i1()}var l0=null;function J4(J){l0=J}function SJ(){if(r1(),l0)l0()}function A8(J,Q){J.debugName=Q||void 0,SJ()}var YJ={id:g6,type:KJ.view,parent:null,children:[],domNodeType:1,domTag:"root"},Q4=Symbol.for("pocketjs.native-node"),u0=1,lJ=3,$J=8,w8=new Set(["class","className","style","src","onPress","on:press","focusable","debugName","ref","nodeRef","key","children"]);function j0(J){return J.domAttrs??={}}function $4(J,Q){let $=J.domNodeType??(uJ(J)?lJ:u0),Z=$===lJ?F0(J.text??""):$===$J?f8(J.domData??""):G4(J.domTag??K0(J));for(let X of Object.keys(J.domAttrs??{}))p0(Z,X,J.domAttrs[X]);if(Q)for(let X of J.children)GJ(Z,$4(X,!0));return Z}function p0(J,Q,$){if(w8.has(Q)){fJ(J,Q,$,J.domAttrs?.[Q]);return}if($==null)delete j0(J)[Q];else j0(J)[Q]=$}function c0(J){if(J[Q4]===!0)return J;return Object.defineProperty(J,Q4,{value:!0}),Object.defineProperties(J,{nodeType:{configurable:!0,get(){return J.domNodeType??(uJ(J)?lJ:u0)}},nodeValue:{configurable:!0,get(){return J.domNodeType===$J?J.domData??"":J.text??""},set($){if(J.domNodeType===$J)J.domData=String($??"");else B0(J,String($??""))}},data:{configurable:!0,get(){return J.domNodeType===$J?J.domData??"":J.text??""},set($){if(J.domNodeType===$J)J.domData=String($??"");else B0(J,String($??""))}},textContent:{configurable:!0,get(){if(J.domNodeType===$J)return J.domData??"";if(uJ(J))return J.text??"";return J.children.map(($)=>$.text??"").join("")},set($){let Z=String($??"");if(J.domNodeType===$J)J.domData=Z;else if(uJ(J))B0(J,Z);else if(N8(J),Z)GJ(J,F0(Z))}},parentNode:{configurable:!0,get(){return J.parent}},parentElement:{configurable:!0,get(){return J.parent}},childNodes:{configurable:!0,get(){return J.children}},firstChild:{configurable:!0,get(){return J.children[0]??null}},lastChild:{configurable:!0,get(){return J.children[J.children.length-1]??null}},nextSibling:{configurable:!0,get(){return j4(J)??null}},previousSibling:{configurable:!0,get(){let $=J.parent;if(!$)return null;let Z=$.children.indexOf(J);return Z>0?$.children[Z-1]:null}},tagName:{configurable:!0,get(){return(J.domTag??K0(J)).toUpperCase()}},nodeName:{configurable:!0,get(){if(J.domNodeType===lJ)return"#text";if(J.domNodeType===$J)return"#comment";return(J.domTag??K0(J)).toUpperCase()}},className:{configurable:!0,get(){return String(J.domAttrs?.class??"")},set($){fJ(J,"class",$,J.domAttrs?.class)}},isConnected:{configurable:!0,get(){let $=J;while($){if($===YJ)return!0;$=$.parent}return!1}}}),Object.assign(J,{appendChild($){return GJ(J,$),$},insertBefore($,Z){return GJ(J,$,Z??null),$},removeChild($){return pJ(J,$),$},replaceChild($,Z){return GJ(J,$,Z),pJ(J,Z),Z},cloneNode($=!1){return $4(J,!!$)},remove(){if(J.parent)pJ(J.parent,J)},setAttribute($,Z){p0(J,$,Z)},removeAttribute($){p0(J,$,void 0)},getAttribute($){let Z=J.domAttrs?.[$];return Z==null?null:String(Z)},hasAttribute($){return J.domAttrs?.[$]!=null},hasChildNodes(){return J.children.length>0},contains($){let Z=$??null;while(Z){if(Z===J)return!0;Z=Z.parent}return!1},addEventListener(){},removeEventListener(){}},{style:{length:0,item:()=>""},classList:{add(){},remove(){}}}),J}c0(YJ);var d0=null;function S8(J){d0=J}var i0={unknownClass:0,unknownTexture:0},Z4=new Map;function X4(J,Q){Z4.set(J,Q)}var W4=new Map;function q4(J,Q){W4.set(J,Q)}var yJ=new Set,y8=new Set;function z4(J){if(!J)return!1;if(y8.has(J))return!0;if(J.children){for(let Q=0;Q - only view/text/image exist`);return c0({id:E().createNode(Q),type:Q,parent:null,children:[],domNodeType:u0,domTag:J})}function F0(J){let Q=E(),$=Q.createNode(KJ.text);return Q.setText($,J),c0({id:$,type:KJ.text,parent:null,children:[],text:J,domNodeType:lJ,domTag:"#text"})}function f8(J=""){let Q=F0("");return Q.domNodeType=$J,Q.domTag="#comment",Q.domData=J,Q}function B0(J,Q){E().replaceText(J.id,Q),J.text=Q,SJ()}function uJ(J){return J.type===KJ.text}function H4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);if($>=0)Q.children.splice($,1);J.parent=null}function GJ(J,Q,$){let Z=E();if(H4(Q),yJ.delete(Q),Z.insertBefore(J.id,Q.id,$?$.id:0),$){let X=J.children.indexOf($);if(X<0)throw Error("PocketJS: insert anchor is not a child of parent");J.children.splice(X,0,Q)}else J.children.push(Q);Q.parent=J,SJ()}function pJ(J,Q){if(!Q)return;V8(Q),E().removeChild(J.id,Q.id),H4(Q),yJ.add(Q),SJ()}function x8(J){return J.parent??void 0}function C8(J){return J.children[0]}function j4(J){let Q=J.parent;if(!Q)return;let $=Q.children.indexOf(J);return $>=0?Q.children[$+1]:void 0}function g8(J,Q){let $=E();if(SJ(),Q==null||Q===""){$.setStyle(J.id,b6);return}if(typeof Q!=="string")throw Error("PocketJS: class must be a string literal of utilities");let Z=d0?d0(Q):void 0;if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown class "${Q}" - not in the compiled style table (dynamic classes must be ternaries of full literals)`);i0.unknownClass++;return}$.setStyle(J.id,Z)}function b8(J,Q){let $=E();if(Q==null||Q===""){$.setImage(J.id,-1);return}if(typeof Q!=="string")throw Error("PocketJS: src must be a string key");let Z=Z4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown image src "${Q}" - no texture registered under that key`);i0.unknownTexture++;return}$.setImage(J.id,Z)}function h8(J,Q){let $=E();if(Q==null||Q===""){$.setSprite(J.id,-1,0,0,0);return}if(typeof Q!=="string")throw Error("PocketJS: sprite must be a string key");let Z=W4.get(Q);if(Z===void 0){if(wJ().strict)throw Error(`PocketJS: unknown sprite "${Q}" - no sprite atlas registered under that key`);i0.unknownTexture++;return}$.setSprite(J.id,Z.handle,Z.frames,Z.cols,Z.step)}function E8(J,Q,$){let Z=E(),X=Q??{},W=$??{},Y=!1;for(let F in X){let D=X[F];if(W[F]===D)continue;let R=h6[F];if(R===void 0)throw Error(`PocketJS: unknown style prop '${F}' (see spec PROP)`);Z.setProp(J.id,R,r6(F,D)),Y=!0}if(Y)SJ()}function fJ(J,Q,$,Z){if($===Z&&Q!=="style")return $;if(Q==="className")Q="class";if(Q!=="children"&&Q!=="key"&&Q!=="ref"&&Q!=="nodeRef")if($==null)delete j0(J)[Q];else j0(J)[Q]=$;switch(Q){case"class":return g8(J,$),$;case"onPress":case"on:press":return H8(J,$),$;case"src":return b8(J,$),$;case"sprite":return h8(J,$),$;case"style":return E8(J,$,Z),$;case"focusable":return j8(J,!!$),$;case"debugName":return A8(J,$==null?void 0:String($)),$;case"ref":case"nodeRef":case"key":case"children":return $;default:break}if(Q==="classList")throw Error("PocketJS: classList is not supported - use ternaries of full class literals");if(Q.startsWith("on:")||Q.startsWith("bool:")||Q.startsWith("prop:"))throw Error(`PocketJS: unsupported namespaced attribute '${Q}'`);throw Error(`PocketJS: unknown property '${Q}' on <${K0(J)}>`)}function N8(J){for(let Q of[...J.children])pJ(J,Q)}function K0(J){for(let Q of Object.keys(KJ))if(KJ[Q]===J.type)return Q;return String(J.type)}function T8(J,Q,$,Z){if(Q==="ref"&&typeof $==="function"){$(J);return}fJ(J,Q,$,Z)}var v8=C6({createElement:G4,createTextNode:F0,replaceText:B0,isTextNode:uJ,setProperty:T8,insertNode(J,Q,$){GJ(J,Q,$)},removeNode(J,Q){pJ(J,Q)},getParentNode:x8,getFirstChild:C8,getNextSibling:j4}),{render:m8,effect:dQ,memo:m,createComponent:q,createElement:F4,insert:iQ,spread:l8,mergeProps:sQ,use:aQ}=v8,rQ={linear:c.Easing.Linear,in:c.Easing.EaseIn,out:c.Easing.EaseOut,"in-out":c.Easing.EaseInOut,"out-back":c.Easing.OutBack,spring:c.Easing.Spring,"spring-bouncy":c.Easing.SpringBouncy},u8=null;function B4(J){u8=J}function p8(J,Q){if(!J)return;if(typeof J==="function")J(Q);else if("current"in J)J.current=Q}function K4(J,Q){let $=F4(J);return l8($,Q,!1),p8(Q.nodeRef,$),$}function V(J){return K4("view",J)}function O(J){return K4("text",J)}var nQ=new WeakMap,oQ=new WeakMap,c8={}!==null?Object.freeze({...{}}):Object.freeze({}),tQ=Object.freeze({target:"",pixelRatio:Number.isInteger(1)?1:1,features:c8}),eQ=new Map,HJ=36000,s0=30,d8=30,z={ops:null,transport:null,app:void 0,frame:0,tape:new Uint16Array(HJ),tapeAnalog:new Uint16Array(HJ),tapeTouch:null,tapeStart:0,tapeLen:0,tapeFirstFrame:0,replayMasks:null,replayAnalog:null,replayTouch:null,replayAt:0,paused:!1,stepQueued:0,inspectReportId:null,inspectAskedAt:0,treeDirty:!0,treeSentAt:-s0,saidHello:!1,hostCalls:0};function i8(J){let Q=globalThis;if(!Q.console)Q.console={log(){},warn(){},error(){}};z.ops=J,z.frame=0,z.tapeStart=0,z.tapeLen=0,z.tapeFirstFrame=0,z.tapeTouch=null,z.replayMasks=null,z.replayAnalog=null,z.replayTouch=null,z.paused=!1,z.stepQueued=0,z.inspectReportId=null,z.inspectAskedAt=0,z.treeDirty=!0,z.treeSentAt=-s0,z.saidHello=!1,z.hostCalls=0,z.app=globalThis.__pocketApp;let $=globalThis.__pocketDevtoolsTransport;if($)z.transport=$;else if(J.__dbgActive?.()&&J.__dbgPoll&&J.__dbgSend)z.transport={send:(Z)=>J.__dbgSend(Z),recv:()=>J.__dbgPoll(),everyFrames:10};else z.transport=null;if(z.transport)J4(()=>{z.treeDirty=!0}),J2();else J4(null);globalThis.__pocketDevtools=$2}function s8(J){return(Q,$,Z,X)=>{if(z.hostCalls++,z.transport)r8(),t8();let W=Q,Y=$===void 0?UJ:$&65535,F=Z,D=X;if(z.replayMasks)if(z.replayAt0?$.slice(0,8):null;if(Z&&!z.tapeTouch)z.tapeTouch=Array(HJ).fill(null);if(z.tapeLen1||Q.length===1&&Q[0][0]!==UJ)J.analog=Q;if(z.tapeTouch){let $=[];for(let Z=0;Z0)J.v=2,J.touch=$}return J}function P4(J,Q,$){let Z=new Uint16Array($).fill(Q),X=0;for(let[W,Y]of J)Z.fill(W,X,Math.min(X+Y,$)),X+=Y;return Z}function V4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return P4(J.masks,0,Q)}function D4(J){let Q=0;for(let[,$]of J.masks)Q+=$;return P4(J.analog??[],UJ,Q)}function R4(J){let Q=0;for(let[,Z]of J.masks)Q+=Z;let $=Array(Q).fill(void 0);for(let[Z,X]of J.touch??[])if(Z>=0&&Z1&&z.hostCalls%Q!==0)return;if(!z.saidHello)z.saidHello=!0,T({t:"hello",app:z.app,host:Q2(),frame:z.frame});for(let $=0;$<64;$++){let Z=J.recv();if(!Z)break;for(let X of Z.split(` +`))if(X.trim())n8(X)}}function n8(J){let Q;try{Q=JSON.parse(J)}catch{return}let $=z.ops;switch(Q.t){case"inspect":{let Z=typeof Q.id==="number"?Q.id:0;if($?.debugInspect?.(Z),z.inspectReportId=Z||null,z.inspectAskedAt=z.hostCalls,!Z)T({t:"inspect",id:0,rect:null});break}case"pause":z.paused=!0,z.stepQueued=0,$?.debugPause?.(!0),a0();break;case"resume":z.paused=!1,$?.debugPause?.(!1),a0();break;case"step":z.stepQueued+=typeof Q.n==="number"&&Q.n>0?Q.n:1;break;case"getTree":O4();break;case"eval":{let Z=!0,X;try{X=U0((0,eval)(String(Q.code)))}catch(W){Z=!1,X=W instanceof Error?`${W.name}: ${W.message}`:String(W)}T({t:"evalResult",id:Q.id,ok:Z,value:X});break}case"dumpTape":T({t:"tape",tape:M4()});break;case"devStats":{let Z=null,X=$?.debugStats?.();if(X)try{Z=JSON.parse(X)}catch{Z=null}T({t:"devStats",frame:z.frame,data:Z});break}case"screenshot":{if($?.__dbgShot?.())T({t:"screenshotRaw",file:"shot.raw",w:480,h:272,stride:512,frame:z.frame});else T({t:"log",level:"warn",args:["screenshot: not supported on this host"]});break}case"replay":{let Z=Q.tape;if(Z&&Array.isArray(Z.masks))z.replayMasks=V4(Z),z.replayAnalog=Z.analog?D4(Z):null,z.replayTouch=Z.touch?R4(Z):null,z.replayAt=0;break}default:break}}function o8(){if(z.treeDirty&&z.frame-z.treeSentAt>=s0)O4();if(z.frame%d8===0)a0()}function t8(){let J=z.inspectReportId;if(J==null)return;let Q=z.ops;if(!Q?.debugRectXY||!Q.debugRectWH){z.inspectReportId=null;return}let $=Q.debugRectXY();if($===-1){if(z.hostCalls-z.inspectAskedAt>60)z.inspectReportId=null,T({t:"inspect",id:J,rect:null});return}let Z=Q.debugRectWH();z.inspectReportId=null,T({t:"inspect",id:J,rect:[$<<16>>16,$>>16,Z&65535,Z>>16&65535]})}function a0(){T({t:"stats",frame:z.frame,nodes:k4(YJ),tapeLen:z.tapeLen,paused:z.paused})}function O4(){z.treeDirty=!1,z.treeSentAt=z.frame,T({t:"tree",frame:z.frame,root:I4(YJ)})}function e8(J){if(J==null||typeof J!=="object")return!1;let Q=J;return typeof Q.id==="number"&&typeof Q.type==="number"}function r0(J,Q){if(Array.isArray(J)){for(let $ of J)r0($,Q);return}if(e8(J)){Q(J);return}if(J!=null&&typeof J==="object"){let $=J.nodes;if($!==void 0)r0($,Q)}}function L4(J,Q){let $=Array.isArray(J.children)?J.children:[];for(let Z of $)r0(Z,Q)}function I4(J){let Q={i:J.id,t:J.domTag??String(J.type)};if(J.debugName)Q.n=J.debugName;let $=J.domAttrs?.class;if(typeof $==="string"&&$)Q.c=$;if(J.text)Q.x=J.text.length>80?J.text.slice(0,79)+"…":J.text;let Z=[];if(L4(J,(X)=>{if(X.domNodeType===8)return;Z.push(I4(X))}),Z.length)Q.k=Z;return Q}function k4(J){let Q=1;return L4(J,($)=>{Q+=k4($)}),Q}function J2(){let J=globalThis;if(!J.console)J.console={};let Q=J.console;if(Q.__pocketBridged)return;Q.__pocketBridged=!0;for(let $ of["log","warn","error"]){let Z=Q[$];Q[$]=(...X)=>{T({t:"log",level:$,args:X.map((W)=>U0(W))}),Z?.apply(Q,X)}}}function U0(J,Q=0){if(J===void 0)return"undefined";if(J===null)return"null";let $=typeof J;if($==="string"){let W=J;return Q===0?_4(W):JSON.stringify(_4(W))}if($==="number"||$==="boolean"||$==="bigint")return String(J);if($==="function"){let W=J.name;return W?`[function ${W}]`:"[function]"}if(Q>=3)return Array.isArray(J)?"[…]":"{…}";if(Array.isArray(J)){let W=J.slice(0,20).map((Y)=>U0(Y,Q+1));if(J.length>20)W.push(`… ${J.length-20} more`);return`[${W.join(", ")}]`}if(J instanceof Error)return`${J.name}: ${J.message}`;return`{${Object.entries(J).slice(0,20).map(([W,Y])=>`${W}: ${U0(Y,Q+1)}`).join(", ")}}`}function _4(J){return J.length>200?J.slice(0,199)+"…":J}function Q2(){let J=z.ops;if(typeof J?.__host==="string")return J.__host;if(J?.__textures!==void 0)return"psp";if(typeof globalThis.document<"u")return"web";return"headless"}var $2={get frame(){return z.frame},dumpTape:()=>M4(),replay:(J)=>{z.replayMasks=V4(J),z.replayAnalog=J.analog?D4(J):null,z.replayTouch=J.touch?R4(J):null,z.replayAt=0}},A4=new Map,n0=new Map;function w4(J){return J.trim().replace(/\s+/g," ")}function S4(J){return J.split(" ").sort().join(" ")}var y4=-1;function Z2(J){for(let Q of Object.keys(J)){let $=J[Q],Z=w4(Q);A4.set(Z,$);let X=S4(Z),W=n0.get(X);n0.set(X,W!==void 0&&W!==$?y4:$)}}function X2(J){let Q=w4(J),$=A4.get(Q);if($!==void 0)return $;let Z=n0.get(S4(Q));return Z===y4?void 0:Z}var o0=9,W2=(1<{let X=($&z2)!==0,W=X?t0:o0,Y=X?Y2:W2;return Object.freeze({id:$>>>(X?G2:q2)&255,x:$&Y,y:$>>>W&Y,hit:Q?.[Z]})}))}function j2(){return M0}function F2(){M0=e0}var f4=8,jJ=8,B2=3,K2=8,U2=6,M2=0.5,t=1,cJ=2,J1=4,RJ=8,xJ=[],x4=0,P0=0,FJ=Array.from({length:f4},(J,Q)=>({slot:Q,used:!1,present:!1,id:0,x:0,y:0,startX:0,startY:0,dx:0,dy:0,fdx:0,fdy:0,vx:0,vy:0,downFrame:0,frames:0,histX:new Int16Array(jJ),histY:new Int16Array(jJ),histHead:0,histLen:0,owners:[],claimedBy:null}));function P2(J,Q){let $=J;while($){if($===Q)return!0;$=$.parent}return!1}function V2(J,Q,$,Z){let X=J.opts.region;if(!X)return!0;let W=X.node?.();if(W){if(Z.hit===void 0)Z.hit=e1(Q,$,Z.fact);let F=Z.hit;if(F)return P2(F,W)}let Y=X.rect?.();if(!Y)return!1;return Q>=Y.x&&Q=Y.y&&$=0;Y--){let F=xJ[Y];if(F.disposed)continue;if(x4>0&&!F.opts.allowWhenBlocked)continue;if(!V2(F,$,Z,W))continue;F.flags[J.slot]=t,J.owners.push(F)}for(let Y of J.owners)Y.opts.onDown?.(J)}function O2(J,Q,$){if(J.present=!0,J.fdx=Q-J.x,J.fdy=$-J.y,J.x=Q,J.y=$,J.dx=Q-J.startX,J.dy=$-J.startY,J.frames++,J.histX[J.histHead]=Q,J.histY[J.histHead]=$,J.histHead=(J.histHead+1)%jJ,J.histLenY||Z>Y))X.flags[J.slot]|=cJ}if(!J.claimedBy)for(let X of J.owners){let W=X.flags[J.slot];if(!(W&t)||W&(cJ|J1))continue;if(!X.opts.onLongPress)continue;let Y=Math.max(1,Math.round((X.opts.longPressSeconds??M2)*N1()));if(J.frames=0)xJ.splice($,1)},cancel(){if(!Q.disposed)b4(Q)},get panning(){for(let $ of FJ)if($.used&&Q.flags[$.slot]&RJ)return!0;return!1}}}function A2(J){let Q=_2(J);return w0(()=>Q.dispose()),Q}function h4(){xJ.length=0,x4=0,P0=0;for(let J of FJ)J.used=!1,J.present=!1,J.owners.length=0,J.claimedBy=null}function w2(){return A2({onDown:(J)=>{let Q=t1(J.x,J.y,J.hit);if(Q)Y0(Q)},onTap:(J)=>{Y0(null);let Q=t1(J.x,J.y,J.hit);if(Q)P8(Q)},onUp:()=>Y0(null),onCancel:()=>Y0(null)})}var S2=1,Q1=new Map,V0=[];function y2(){let J=globalThis.__pocketEffectTrace;return typeof J==="function"?J:null}function f2(){S2=1,Q1.clear(),V0=[]}function x2(){if(V0.length===0)return;let J=V0;V0=[];for(let{id:Q,result:$}of J){let Z=Q1.get(Q);if(!Z)continue;Q1.delete(Q),y2()?.({t:"delivery",frame:T1(),id:Q,kind:Z.kind}),Z.onResult($)}}var E4=new Set;function C2(){if(E4.size===0)return;for(let J of E4)J()}var g2={"w-[210] h-[104]":0,"h-[72] px-5 flex-row items-center justify-between":1,"w-[450] flex-col gap-2":2,"text-lg text-slate-900 font-bold":3,"text-base text-slate-500":4,"text-base text-emerald-600 font-bold":5,"text-base text-slate-900 font-bold":6,"h-[64] px-5 flex-row items-center":7,"w-[240] text-lg text-slate-900 font-bold":8,"w-[156] text-base text-slate-500":9,"relative w-[632] h-[196] flex-col":10,"relative w-[632] h-[160] overflow-hidden":11,"absolute w-[632] h-[2] bg-slate-200":12,"absolute text-base text-slate-500 font-bold":13,"absolute rounded-lg bg-emerald-500":14,"absolute rounded-lg bg-red-500":15,"absolute w-[6] h-[6] rounded-lg bg-emerald-500":16,"absolute w-[6] h-[6] rounded-lg bg-red-500":17,"h-[36] px-1 flex-row items-center justify-between":18,"flex-col w-full h-full bg-slate-50":19,"h-[64] px-6 pt-2":20,"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":21,"text-base text-slate-500 font-bold":22,"h-[304] px-6 pt-3":23,"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100":24,"h-[64] flex-row items-end justify-between":25,"text-2xl text-slate-950 font-bold":26,"text-lg text-emerald-600 font-bold":27,"text-lg text-red-500 font-bold":28,"h-[60] px-6 pt-2 flex-row gap-3":29,"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":30,"w-[100] h-[44] items-center justify-center rounded-lg bg-white":31,"text-base text-white font-bold":32,"pt-3 text-base text-slate-500":33,"h-[126] px-6 pt-3 flex-row items-start gap-[21]":34,"h-[200] px-6 flex-col":35,"h-[150] flex-col rounded-xl shadow bg-white border-slate-100":36,"h-[184] px-6 flex-col":37,"h-[136] flex-col rounded-xl shadow bg-white border-slate-100":38,"h-[126] px-6 pt-2":39,"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100":40,"flex-col gap-3":41,"text-xl text-slate-900 font-bold":42,"text-2xl text-emerald-600 font-bold":43,"text-2xl text-red-500 font-bold":44,"h-[104] px-6 flex-row items-center justify-between":45,"w-[460] h-[64]":46,"w-[176] h-[64]":47,"absolute left-[628] top-[156] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":48,"absolute left-[628] top-[972] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100":49,"relative flex-col w-full h-full bg-slate-50":50,"px-6 pt-[14] flex-col gap-[12]":51,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":52,"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":53,"flex-row items-center justify-between":54,"text-lg text-slate-500 font-bold":55,"px-6 pt-[14] flex-col gap-[14]":56,"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100":57,"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100":58,"flex-row items-center":59,"w-[170] text-xl text-slate-900 font-bold":60,"relative flex-col w-full h-full bg-slate-50 overflow-hidden":61,"absolute inset-0 z-50 flex-col items-center justify-center":62,"absolute inset-0 bg-slate-950":63,"flex-col gap-2 w-[328] p-3 rounded-xl shadow-lg bg-white border-slate-200":64,"absolute left-3 right-3 bottom-3 flex-row items-center justify-between px-2 py-1 rounded-lg shadow-md bg-white border-slate-200":65,"flex-row flex-wrap":66,grow:67,"text-2xl text-white font-bold":68,"text-base text-slate-600 font-bold":69,"px-3 py-2 rounded-lg bg-slate-100":70,"px-3 py-2 rounded-lg bg-indigo-100":71,"text-base text-indigo-700 font-bold":72,"px-3 py-2 rounded-lg bg-emerald-100":73,"text-base text-emerald-700 font-bold":74,"px-3 py-2 rounded-lg bg-amber-100":75,"text-base text-amber-700 font-bold":76,"px-3 py-2 rounded-lg bg-red-100":77,"text-base text-red-500 font-bold":78,"w-[34] h-[34] rounded-lg bg-amber-400":79,"w-[34] h-[34] rounded-lg bg-red-500":80,"w-[34] h-[34] rounded-lg bg-slate-800":81,"w-[34] h-[34] rounded-lg bg-emerald-500":82,"h-[112] px-6 flex-row items-center justify-between bg-slate-950":83,"flex-row items-center gap-4":84,"w-[34] text-2xl text-white font-bold":85,"w-[332] flex-col items-end gap-2":86,"text-base text-slate-300 font-bold":87,"text-base text-slate-400":88,"h-[166] px-6 pt-6 flex-col gap-3":89,"text-base text-orange-600 font-bold":90,"text-lg text-slate-600":91,"h-[44] px-1 flex-row items-center justify-between":92,"w-full h-full items-center justify-center rounded-xl bg-slate-200":93,"w-full h-full items-center justify-center rounded-xl bg-red-100":94,"w-full h-full items-center justify-center rounded-xl bg-slate-100":95,"w-full h-full items-center justify-center rounded-xl bg-orange-600":96,"text-lg text-white font-bold":97,"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":98,"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":99,"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":100,"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100":101,"text-2xl text-indigo-700 font-bold":102,"text-2xl text-slate-600 font-bold":103,"pt-7 text-2xl text-slate-900 font-bold":104,"pt-4 text-lg text-slate-500":105,"text-xl text-emerald-600 font-bold":106,"text-xl text-red-500 font-bold":107,"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100":108,"text-base text-red-300":109,"text-base text-slate-300":110,"text-base text-red-500":111,"w-full h-full px-6 flex-row items-center bg-slate-950":112,"w-full h-full flex-row items-center":113};if(typeof globalThis.queueMicrotask!=="function")globalThis.queueMicrotask=(J)=>{Promise.resolve().then(J)};var b2="ui:styles",h2="ui:font.",N4="ui:img.",T4="ui:sprite.";function E2(){return globalThis.ui}function N2(J){if(J.__textures)return;for(let Q of h0(N4)){let $=vJ(Q),Z;if(J.uploadImgEntry)Z=J.uploadImgEntry($);else{let X=new DataView($.buffer,$.byteOffset,$.byteLength);Z=J.uploadTexture($.subarray(8),X.getUint16(0,!0),X.getUint16(2,!0),$[4])}if(Z>=0)X4(Q.slice(N4.length),Z)}}function T2(J){if(J.__sprites)return;for(let Q of h0(T4)){let $=vJ(Q),Z=new DataView($.buffer,$.byteOffset,$.byteLength),X=Z.getUint16(0,!0),W=Z.getUint16(2,!0),Y=$[4],F=Z.getUint16(6,!0),D=Z.getUint16(8,!0),R=Z.getUint16(10,!0),U=J.uploadTexture($.subarray(16),X,W,Y);if(U>=0)q4(Q.slice(T4.length),{handle:U,frames:F,cols:D,step:R})}}function v4(J){let Q=F4("view");return fJ(Q,"style",J,void 0),Q}var D0=null,R0=null;function v2(J,Q){if(!D0||!R0)return;fJ(D0,"style",{width:J,height:Q,overflow:c.Overflow.Hidden},void 0),fJ(R0,"style",{width:J,height:Q,posType:c.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000},void 0);let $=E();$.__viewport={w:J,h:Q}}function m2(J,Q={}){let $=c6(Q.ops);if(d6($),S8(X2),Q.styles)Z2(Q.styles);let Z=$.kind==="native"?$.ops.__textures:void 0;if($.kind==="native"){if(Z)for(let w in Z)X4(w,Z[w]);let H=$.ops.__sprites;if(H)for(let w in H)q4(w,H[w])}if($.kind==="injected"||Z===void 0){if(Q.pak)p1(Q.pak);if(G8()){for(let H of h0())if(H===b2)$.ops.loadStyles?.(vJ(H));else if(H.startsWith(h2))$.ops.loadFontAtlas?.(vJ(H))}}let X=b1($.ops),W=X?.w??x1,Y=X?.h??C1,F=v4({width:W,height:Y,overflow:c.Overflow.Hidden}),D=v4({width:W,height:Y,posType:c.PosType.Absolute,insetT:0,insetR:0,insetB:0,insetL:0,zIndex:1000,hitPass:1});GJ(YJ,F),GJ(YJ,D),B4(D),D0=F,R0=D,c1(F),n1(YJ),q8(),h4(),w2(),e6(),f2(),i8($.ops),i6(s8((H,w,x,g)=>{J8(),Q8(w),H2(x,g),C2(),x2(),k2(),z8(H),_8(H),Y4()}));let R=m8(J,F),U=s6(v2);return()=>{U(),F2(),h4(),R(),c1(null),n1(null),B4(null),D0=null,R0=null;for(let H of YJ.children.splice(0))H.parent=null,$.ops.destroyNode(H.id);Y4()}}function l2(J,Q={}){let $=Q.ops??E2();if(!$)throw Error("PocketJS: mount() requires globalThis.ui or opts.ops");if(Q.pak)p1(Q.pak);return N2($),T2($),m2(J,{ops:$,styles:Q.styles??g2,pak:Q.pak})}var m4="$b",u2=9007199254740991,p2=":memory:",CJ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function c2(J){let Q="";for(let $=0;$>2]+CJ[(Z&3)<<4|X>>4],Q+=$+1>6]:"=",Q+=$+2u2)throw Error("db: integer exceeds DB_MAX_SAFE_INTEGER");return J}function s2(J){if(J!==null&&typeof J==="object")return d2(J[m4]);return J}function a2(J){if(Array.isArray(J))return JSON.stringify(J.map(l4));let Q={};for(let[$,Z]of Object.entries(J))Q[$]=l4(Z);return JSON.stringify(Q)}class $1{cols=[];constructor(J,Q,$){this.ops=J,this.handle=Q,this.sql=$}get columnNames(){return this.cols}execute(J){let Q=this.ops.query(this.handle,this.sql,a2(J)),$=JSON.parse(Q);if($.error!==void 0)throw Error(`db: ${$.error}`);return this.cols=$.cols??[],$}get(...J){let Q=this.values(...J);if(Q.length===0)return null;let $={};return this.cols.forEach((Z,X)=>$[Z]=Q[0][X]),$}all(...J){return this.values(...J).map(($)=>{let Z={};return this.cols.forEach((X,W)=>Z[X]=$[W]),Z})}values(...J){let Q=u4(J);return(this.execute(Q).rows??[]).map((Z)=>Z.map(s2))}run(...J){let Q=this.execute(u4(J));return{changes:Q.changes??0,lastInsertRowid:Q.lastInsertRowid??0}}}function u4(J){if(J.length===1&&Array.isArray(J[0]))return J[0];if(J.length===1&&J[0]!==null&&typeof J[0]==="object"&&!(J[0]instanceof Uint8Array))return J[0];return J}class p4{statements=new Map;txDepth=0;constructor(J=p2){let Q=i2();if(!Q)throw Error("db: globalThis.db is not mounted — declare `data.sqlite` in pocket.json requires");let $=Q.open(J);if($<0)throw Error(`db: open(${JSON.stringify(J)}) refused`);this.ops=Q,this.handle=$}query(J){let Q=this.statements.get(J);if(!Q)Q=new $1(this.ops,this.handle,J),this.statements.set(J,Q);return Q}prepare(J){return new $1(this.ops,this.handle,J)}run(J,Q=[]){return this.query(J).run(Q)}exec(J){if(this.ops.exec(this.handle,J)!==0)throw Error(`db: ${this.ops.lastError(this.handle)}`)}transaction(J){return(...Q)=>{let $=`pocket_tx_${this.txDepth}`,[Z,X,W]=this.txDepth===0?["BEGIN","COMMIT","ROLLBACK"]:[`SAVEPOINT ${$}`,`RELEASE ${$}`,`ROLLBACK TO ${$}; RELEASE ${$}`];this.exec(Z),this.txDepth++;try{let Y=J(...Q);return this.txDepth--,this.exec(X),Y}catch(Y){throw this.txDepth--,this.exec(W),Y}}}close(){this.statements.clear(),this.ops.close(this.handle)}}var O0={appTitle:"text-2xl text-white font-bold",pageTitle:"text-2xl text-slate-950 font-bold",heading:"text-xl text-slate-900 font-bold",label:"text-base text-slate-600 font-bold",captionStrong:"text-base text-slate-500 font-bold"},c4={neutral:{surface:"px-3 py-2 rounded-lg bg-slate-100",text:"text-base text-slate-600 font-bold"},info:{surface:"px-3 py-2 rounded-lg bg-indigo-100",text:"text-base text-indigo-700 font-bold"},success:{surface:"px-3 py-2 rounded-lg bg-emerald-100",text:"text-base text-emerald-700 font-bold"},warning:{surface:"px-3 py-2 rounded-lg bg-amber-100",text:"text-base text-amber-700 font-bold"},danger:{surface:"px-3 py-2 rounded-lg bg-red-100",text:"text-base text-red-500 font-bold"}};function r2(J){let Q=()=>J.accent==="busy"?"w-[34] h-[34] rounded-lg bg-amber-400":J.accent==="danger"?"w-[34] h-[34] rounded-lg bg-red-500":J.accent==="none"?"w-[34] h-[34] rounded-lg bg-slate-800":"w-[34] h-[34] rounded-lg bg-emerald-500";return q(V,{class:"h-[112] px-6 flex-row items-center justify-between bg-slate-950",get children(){return[q(V,{class:"flex-row items-center gap-4",get children(){return[m(()=>m(()=>!!J.back)()?q(O,{class:"w-[34] text-2xl text-white font-bold",children:"‹"}):q(V,{get["class"](){return Q()}})),q(O,{get["class"](){return O0.appTitle},get children(){return J.title}})]}}),q(V,{class:"w-[332] flex-col items-end gap-2",get children(){return[q(O,{class:"text-base text-slate-300 font-bold",get children(){return J.metaTop??""}}),q(O,{class:"text-base text-slate-400",get children(){return J.metaBottom??""}})]}})]}})}function n2(J){let Q=()=>J.action?J.detail?J.detail+" · VIEW ALL ›":"VIEW ALL ›":J.detail??"";return q(V,{class:"h-[44] px-1 flex-row items-center justify-between",get children(){return[q(O,{get["class"](){return O0.heading},get children(){return J.title}}),q(O,{get["class"](){return O0.captionStrong},get children(){return Q()}})]}})}function o2(J){let Q=()=>J.disabled?"w-full h-full items-center justify-center rounded-xl bg-slate-200":J.tone==="danger"?"w-full h-full items-center justify-center rounded-xl bg-red-100":J.tone==="neutral"?"w-full h-full items-center justify-center rounded-xl bg-slate-100":"w-full h-full items-center justify-center rounded-xl bg-orange-600",$=()=>J.disabled?"text-lg text-slate-500 font-bold":J.tone==="danger"?"text-lg text-red-500 font-bold":J.tone==="neutral"?"text-lg text-slate-900 font-bold":"text-lg text-white font-bold";return q(V,{get["class"](){return Q()},get children(){return q(O,{get["class"](){return $()},get children(){return J.label}})}})}function d4(J){return q(V,{get["class"](){return J.compact?"w-full h-[150] px-5 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100":"w-full h-[430] px-12 flex-col items-center justify-center rounded-xl shadow bg-white border-slate-100"},get children(){return[m(()=>m(()=>!!J.icon)()?q(V,{get["class"](){return J.tone==="info"?"w-[88] h-[88] items-center justify-center rounded-xl bg-indigo-100":"w-[88] h-[88] items-center justify-center rounded-xl bg-slate-100"},get children(){return q(O,{get["class"](){return J.tone==="info"?"text-2xl text-indigo-700 font-bold":"text-2xl text-slate-600 font-bold"},get children(){return J.icon}})}}):null),q(O,{get["class"](){return J.icon?"pt-7 text-2xl text-slate-900 font-bold":"text-lg text-slate-500 font-bold"},get children(){return J.title}}),m(()=>m(()=>!!J.detail)()?q(O,{class:"pt-4 text-lg text-slate-500",get children(){return J.detail}}):null)]}})}function t2(J){let Q=()=>J.tone==="success"?"text-xl text-emerald-600 font-bold":J.tone==="danger"?"text-xl text-red-500 font-bold":"text-xl text-slate-900 font-bold";return q(V,{class:"w-full h-full px-5 py-4 flex-col gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(O,{get["class"](){return O0.label},get children(){return J.label}}),q(O,{get["class"](){return Q()},get children(){return J.value}})]}})}function e2(J){let Q=()=>J.dark?J.tone==="danger"?"text-base text-red-300":"text-base text-slate-300":J.tone==="danger"?"text-base text-red-500":"text-base text-slate-500";return q(V,{get["class"](){return J.dark?"w-full h-full px-6 flex-row items-center bg-slate-950":"w-full h-full flex-row items-center"},get children(){return q(O,{get["class"](){return Q()},get children(){return J.text}})}})}function JQ(J){return[q(V,{get["class"](){return J.top},get children(){return q(O,{class:"text-base text-orange-600 font-bold",children:"UP"})}}),q(V,{get["class"](){return J.bottom},get children(){return q(O,{class:"text-base text-orange-600 font-bold",children:"DN"})}})]}var QQ=5,BJ=new p4("robinhood"),$Q={number:"",label:"ACCOUNT",suffix:"",status:"WAITING FOR ROBINHOOD"},Z1={title:"NO RECENT ACTIVITY",timestamp:"",detail:"",state:"",amount:"",side:""},ZQ={...Z1,title:"ACTIVITY UNAVAILABLE"},XQ={...Z1,title:""},X1={symbol:"NO OPEN POSITIONS",quantity:"",averagePrice:"",marketValue:""},WQ={...X1,symbol:"POSITIONS UNAVAILABLE"},qQ={...X1,symbol:""},iJ={account:$Q,totalValue:null,cash:null,buyingPower:null,pnlDay:null,pnlWeek:null,positions:[],activity:[],positionsAvailable:!0,activityAvailable:!0,observedAt:null},[i,sJ]=h("dashboard"),[l,zQ]=h("day"),[gJ,W1]=h([]),[L0,I0]=h(""),[y,aJ]=h(iJ),[i4,OJ]=h([]),[YQ,LJ]=h([]),[q1,z1]=h([]),[GQ,Y1]=h({change:"$—",percent:"—",positive:!0}),[G1,s4]=h(0),[a4,r4]=h(0),[n4,o4]=h(0),[t4,ZJ]=h("WAITING FOR ROBINHOOD"),[rJ,e4]=h(!1),u=0,J6=-1,Q6=-1,$6=-1,H1=new Map,j1=new Map;function Z6(){return Math.floor(Date.now()/1000)}function HQ(J){try{return J?JSON.parse(J):null}catch{return null}}function jQ(){return BJ.query("SELECT account_number,label,suffix,status FROM accounts ORDER BY label,account_number LIMIT 16").all().map((Q)=>({number:Q.account_number,label:Q.label,suffix:Q.suffix,status:Q.status}))}function FQ(J,Q){if(Q6===J)return;let $=BJ.query("SELECT account_number,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current LIMIT 16").all(),Z=BJ.query(` SELECT value.account_number,value.value,value.observed_at FROM total_value value JOIN ( @@ -7,7 +7,7 @@ FROM total_value GROUP BY account_number ) latest ON latest.account_number=value.account_number AND latest.observed_at=value.observed_at LIMIT 16 - `).all(),X=m.query("SELECT account_number,symbol,quantity,average_price,market_value FROM positions ORDER BY account_number,CAST(market_value AS REAL) DESC,symbol LIMIT 1024").all(),W=m.query("SELECT account_number,activity_id,occurred_at,symbol,side,quantity,price,amount,state,activity_type FROM activities ORDER BY account_number,occurred_at DESC,observed_at DESC LIMIT 1024").all(),z=new Map($.map((U)=>[U.account_number,U])),F=new Map(Z.map((U)=>[U.account_number,U])),D=new Map,R=new Map;for(let U of X){let H=D.get(U.account_number)||[];if(H.length<64)H.push(U);D.set(U.account_number,H)}for(let U of W){let H=R.get(U.account_number)||[];if(H.length<64)H.push(U);R.set(U.account_number,H)}H1.clear();for(let U of Q){let H=z.get(U.number),w=F.get(U.number),x=D.get(U.number)||[],g=R.get(U.number)||[];H1.set(U.number,{loadedRevision:J,value:{account:U,totalValue:w?.value??null,cash:H?.cash??null,buyingPower:H?.buying_power??null,pnlDay:H?.day_pnl??null,pnlWeek:H?.week_pnl??null,positions:x.map((A)=>({symbol:A.symbol,quantity:A.quantity||"—",averagePrice:A.average_price||"—",marketValue:A.market_value||""})),activity:g.map((A)=>({title:(A.side?A.side+" ":"")+(A.symbol||"ORDER"),timestamp:BQ(A.occurred_at),detail:A.quantity?A.quantity+" SH · "+(A.activity_type||"ORDER"):A.activity_type||"ORDER",state:A.state||"RECENT",amount:A.amount||A.price||A.quantity||"",side:A.side||""})),positionsAvailable:H!==void 0,activityAvailable:H!==void 0,observedAt:Math.max(H?.observed_at??0,w?.observed_at??0)||null}})}$6=J}function k0(J){if(J===null)return null;let Q=Number(J.replace(/[$,%]/g,""));return Number.isFinite(Q)?Q:null}function BQ(J){if(!J)return"RECENT";let Q=new Date(J);if(!Number.isFinite(Q.getTime()))return J.slice(0,16).toUpperCase();return String(Q.getMonth()+1).padStart(2,"0")+"/"+String(Q.getDate()).padStart(2,"0")+" "+String(Q.getHours()).padStart(2,"0")+":"+String(Q.getMinutes()).padStart(2,"0")}function W6(J){let Q=Math.max(0,X6()-J);if(Q<60)return"JUST NOW";if(Q<3600)return Math.floor(Q/60)+" MIN AGO";if(Q<86400)return Math.floor(Q/3600)+" HR AGO";return Math.floor(Q/86400)+" DAY AGO"}function JJ(J){if(!J)return"$—";let Q=k0(J);if(Q===null)return J;let Z=Math.abs(Q).toFixed(2).split("."),X="$"+Z[0].replace(/\B(?=(\d{3})+(?!\d))/g,",")+"."+Z[1];return Q<0?"-"+X:X}function q6(J,Q){let $=J+":"+u(),Z=j1.get($);if(Z?.loadedRevision===Q){OJ(Z.value.points),LJ(Z.value.segments),z1(Z.value.labels),Y1(Z.value.trend);return}let X=u()==="day"?86400:604800,z=X6()-X,D=m.query(` + `).all(),X=BJ.query("SELECT account_number,symbol,quantity,average_price,market_value FROM positions ORDER BY account_number,CAST(market_value AS REAL) DESC,symbol LIMIT 1024").all(),W=BJ.query("SELECT account_number,activity_id,occurred_at,symbol,side,quantity,price,amount,state,activity_type FROM activities ORDER BY account_number,occurred_at DESC,observed_at DESC LIMIT 1024").all(),Y=new Map($.map((U)=>[U.account_number,U])),F=new Map(Z.map((U)=>[U.account_number,U])),D=new Map,R=new Map;for(let U of X){let H=D.get(U.account_number)||[];if(H.length<64)H.push(U);D.set(U.account_number,H)}for(let U of W){let H=R.get(U.account_number)||[];if(H.length<64)H.push(U);R.set(U.account_number,H)}H1.clear();for(let U of Q){let H=Y.get(U.number),w=F.get(U.number),x=D.get(U.number)||[],g=R.get(U.number)||[];H1.set(U.number,{loadedRevision:J,value:{account:U,totalValue:w?.value??null,cash:H?.cash??null,buyingPower:H?.buying_power??null,pnlDay:H?.day_pnl??null,pnlWeek:H?.week_pnl??null,positions:x.map((A)=>({symbol:A.symbol,quantity:A.quantity||"—",averagePrice:A.average_price||"—",marketValue:A.market_value||""})),activity:g.map((A)=>({title:(A.side?A.side+" ":"")+(A.symbol||"ORDER"),timestamp:BQ(A.occurred_at),detail:A.quantity?A.quantity+" SH · "+(A.activity_type||"ORDER"):A.activity_type||"ORDER",state:A.state||"RECENT",amount:A.amount||A.price||A.quantity||"",side:A.side||""})),positionsAvailable:H!==void 0,activityAvailable:H!==void 0,observedAt:Math.max(H?.observed_at??0,w?.observed_at??0)||null}})}Q6=J}function k0(J){if(J===null)return null;let Q=Number(J.replace(/[$,%]/g,""));return Number.isFinite(Q)?Q:null}function BQ(J){if(!J)return"RECENT";let Q=new Date(J);if(!Number.isFinite(Q.getTime()))return J.slice(0,16).toUpperCase();return String(Q.getMonth()+1).padStart(2,"0")+"/"+String(Q.getDate()).padStart(2,"0")+" "+String(Q.getHours()).padStart(2,"0")+":"+String(Q.getMinutes()).padStart(2,"0")}function X6(J){let Q=Math.max(0,Z6()-J);if(Q<60)return"JUST NOW";if(Q<3600)return Math.floor(Q/60)+" MIN AGO";if(Q<86400)return Math.floor(Q/3600)+" HR AGO";return Math.floor(Q/86400)+" DAY AGO"}function e(J){if(!J)return"$—";let Q=k0(J);if(Q===null)return J;let Z=Math.abs(Q).toFixed(2).split("."),X="$"+Z[0].replace(/\B(?=(\d{3})+(?!\d))/g,",")+"."+Z[1];return Q<0?"-"+X:X}function W6(J,Q){let $=J+":"+l(),Z=j1.get($);if(Z?.loadedRevision===Q){OJ(Z.value.points),LJ(Z.value.segments),z1(Z.value.labels),Y1(Z.value.trend);return}let X=l()==="day"?86400:604800,Y=Z6()-X,D=BJ.query(` WITH RECURSIVE buckets(bucket_index, bucket_time) AS ( SELECT 0, ?1 UNION ALL @@ -19,4 +19,4 @@ WHERE account_number = ?3 AND observed_at >= ?1 AND observed_at <= bucket_time ORDER BY observed_at DESC LIMIT 1) AS total_value FROM buckets ORDER BY bucket_index - `).all(z,X,J).map((j)=>({time:j.bucket_time,value:k0(j.total_value)})),R=D.map((j)=>j.time),U=D.map((j)=>j.value).filter((j)=>j!==null),H=[R[0],R[9],R[19]].map((j)=>{let G=new Date(j*1000);return u()==="day"?String(G.getHours()).padStart(2,"0")+":"+String(G.getMinutes()).padStart(2,"0"):String(G.getMonth()+1)+"/"+String(G.getDate())});if(U.length===0){let j=u()==="day"?y().pnlDay:y().pnlWeek,G=k0(j),P={points:[],segments:[],labels:H,trend:{change:JJ(j),percent:"—",positive:G===null||G>=0}};j1.set($,{loadedRevision:Q,value:P}),OJ(P.points),LJ(P.segments),z1(P.labels),Y1(P.trend);return}let w=Math.min(...U),x=Math.max(...U),g=Math.max(0.01,x-w),A=D.flatMap((j,G)=>j.value===null?[]:[{x:G*622/19,y:U.length===1?80:10+(x-j.value)*140/g}]),a=A.slice(1).map((j,G)=>{let P=A[G],k=j.x-P.x,_=j.y-P.y;return{x:P.x,y:P.y,width:Math.sqrt(k*k+_*_),angle:Math.atan2(_,k)*180/Math.PI}}),r=U[U.length-1]-U[0],K={change:JJ(String(r)),percent:U[0]===0?"—":(r*100/U[0]).toFixed(2)+"%",positive:r>=0};j1.set($,{loadedRevision:Q,value:{points:A,segments:a,labels:H,trend:K}}),OJ(A),LJ(a),z1(H),Y1(K)}function KQ(J){if(Z6===J)return;let Q=m.query("SELECT status,error,completed_at FROM refresh_runs ORDER BY id DESC LIMIT 1").get();if(J6(!1),Q?.status==="failed")XJ("REFRESH FAILED · "+String(Q.error||"UNKNOWN ERROR").slice(0,52));else if(Q?.status==="partial")XJ("LIVE WITH PARTIAL DATA");else if(y().observedAt)XJ("LIVE · "+W6(y().observedAt));else XJ("WAITING FOR ROBINHOOD");Z6=J}function z6(J,Q){if(!J){if(aJ(iJ),OJ([]),LJ([]),!rJ())XJ("WAITING FOR ROBINHOOD");return}let $=H1.get(J);if($?.loadedRevision===Q){if(aJ($.value),q6(J,Q),$.value.observedAt&&!rJ())XJ("LIVE · "+W6($.value.observedAt));return}aJ(iJ),OJ([]),LJ([])}function Y6(J=p){try{let Q=m.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==i4){W1([]),I0(""),aJ(iJ),OJ([]),LJ([]),XJ("WAITING FOR ROBINHOOD");return}eJ(()=>{p=Math.max(p,J);let $=gJ();if(Q6!==p)$=jQ(),W1($),Q6=p;FQ(p,$);let Z=L0();if(!$.some((X)=>X.number===Z))Z=$[0]?.number||"",I0(Z);z6(Z,p),KQ(p)})}catch{eJ(()=>{W1([]),I0(""),aJ(iJ),OJ([]),LJ([]),XJ("WAITING FOR ROBINHOOD")})}}function UQ(){return""}function MQ(){let J=m.query("SELECT name,sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all(),Q=new Set(J.map((z)=>z.name)),$=J.map((z)=>{let F=m.query("SELECT COUNT(*) AS count FROM "+z.name).get().count;return{name:z.name,rowCount:F,schema:z.sql}}),Z=Q.has("refresh_runs")?m.query("SELECT id,started_at,completed_at,operation_count,success_count,status,error FROM refresh_runs ORDER BY id DESC LIMIT 3").all():[],X=Q.has("portfolio_current")?m.query("SELECT substr(account_number,-4) AS account_suffix,cash,buying_power,day_pnl,week_pnl,observed_at FROM portfolio_current ORDER BY observed_at DESC LIMIT 4").all():[],W=Q.has("total_value")?m.query("SELECT substr(account_number,-4) AS account_suffix,observed_at,value FROM total_value ORDER BY observed_at DESC LIMIT 8").all():[];return{database:"robinhood.sqlite",schemaVersion:i4,tables:$,latestRefreshes:Z,latestPortfolios:X,latestValues:W}}function F1(){return GQ()}function _0(J){return q(n2,{get title(){return J.title},back:!0,metaTop:"AGENTIC",get metaBottom(){return J.metaBottom??"AUTO · 5 MIN"}})}function B1(J){return q(V,{class:"w-[210] h-[104]",get children(){return q(e2,{get label(){return J.label},get value(){return JJ(J.value)}})}})}function G6(J){return q(o2,{get title(){return J.title},get detail(){return J.detail},action:!0})}function PQ(J){if(J===0&&!y().activityAvailable)return ZQ;return y().activity[J]??(J===0?Z1:XQ)}function H6(J){let Q=()=>PQ(J.index);return q(V,{class:"h-[72] px-5 flex-row items-center justify-between",get children(){return[q(V,{class:"w-[450] flex-col gap-2",get children(){return[q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q().title}}),q(O,{class:"text-base text-slate-500",get children(){return l(()=>!!Q().timestamp)()?Q().timestamp+" · "+Q().detail:""}})]}}),q(O,{get["class"](){return Q().side==="SELL"?"text-base text-emerald-600 font-bold":"text-base text-slate-900 font-bold"},get children(){return l(()=>!!Q().amount)()?JJ(Q().amount):""}})]}})}function VQ(J){if(J===0&&!y().positionsAvailable)return WQ;return y().positions[J]??(J===0?X1:qQ)}function j6(J){let Q=()=>VQ(J.index);return q(V,{class:"h-[64] px-5 flex-row items-center",get children(){return[q(O,{class:"w-[240] text-lg text-slate-900 font-bold",get children(){return Q().symbol}}),q(O,{class:"w-[156] text-base text-slate-500",get children(){return l(()=>!!Q().quantity)()?Q().quantity+" SH":""}}),q(O,{class:"text-base text-slate-500",get children(){return l(()=>!!Q().averagePrice)()?"AVG "+JJ(Q().averagePrice):""}})]}})}function DQ(){return q(V,{class:"relative w-[632] h-[196] flex-col",get children(){return[q(V,{class:"relative w-[632] h-[160] overflow-hidden",get children(){return[q(V,{class:"absolute w-[632] h-[2] bg-slate-200",style:{posType:1,insetL:0,insetT:158}}),q(O,{class:"absolute text-base text-slate-500 font-bold",style:{posType:1,insetL:152,insetT:72},get children(){return s4().length<2?"COLLECTING 5M VALUE HISTORY":""}}),q(NJ,{get each(){return YQ()},children:(J)=>q(V,{get["class"](){return F1().positive?"absolute rounded-lg bg-emerald-500":"absolute rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x,insetT:J.y-1,width:J.width,height:2,rotate:J.angle,originX:-0.5,originY:0}}})}),q(NJ,{get each(){return s4()},children:(J)=>q(V,{get["class"](){return F1().positive?"absolute w-[6] h-[6] rounded-lg bg-emerald-500":"absolute w-[6] h-[6] rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x-3,insetT:J.y-3}}})})]}}),q(V,{class:"h-[36] px-1 flex-row items-center justify-between",get children(){return[q(O,{class:"text-base text-slate-500",get children(){return q1()[0]||""}}),q(O,{class:"text-base text-slate-500",get children(){return q1()[1]||""}}),q(O,{class:"text-base text-slate-500",get children(){return q1()[2]||""}})]}})]}})}function RQ(){let J=()=>F1();return q(V,{class:"flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ROBINHOOD"}),q(V,{class:"h-[64] px-6 pt-2",get children(){return q(V,{class:"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(O,{class:"text-base text-slate-500 font-bold",children:"ACCOUNT"}),q(O,{class:"text-base text-slate-900 font-bold",get children(){return y().account.label+(y().account.suffix?" ····"+y().account.suffix+" "+(gJ().findIndex((Q)=>Q.number===L0())+1)+"/"+gJ().length:"")+" ›"}})]}})}}),q(V,{class:"h-[304] px-6 pt-3",get children(){return q(V,{class:"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"h-[64] flex-row items-end justify-between",get children(){return[q(O,{class:"text-2xl text-slate-950 font-bold",get children(){return JJ(y().totalValue)}}),q(O,{get["class"](){return J().positive?"text-lg text-emerald-600 font-bold":"text-lg text-red-500 font-bold"},get children(){return J().change+" ("+J().percent+")"}})]}}),q(DQ,{})]}})}}),q(V,{class:"h-[60] px-6 pt-2 flex-row gap-3",get children(){return[q(V,{get["class"](){return u()==="day"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(O,{get["class"](){return u()==="day"?"text-base text-white font-bold":"text-base text-slate-500 font-bold"},children:"1D"})}}),q(V,{get["class"](){return u()==="week"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(O,{get["class"](){return u()==="week"?"text-base text-white font-bold":"text-base text-slate-500 font-bold"},children:"1W"})}}),q(O,{class:"pt-3 text-base text-slate-500",get children(){return u()==="day"?"TODAY":"PAST WEEK"}})]}}),q(V,{class:"h-[126] px-6 pt-3 flex-row items-start gap-[21]",get children(){return[q(B1,{label:"VALUE",get value(){return y().totalValue}}),q(B1,{label:"CASH",get value(){return y().cash}}),q(B1,{label:"BUY POWER",get value(){return y().buyingPower}})]}}),q(V,{class:"h-[200] px-6 flex-col",get children(){return[q(G6,{title:"ACTIVITY",detail:"LAST 7 DAYS"}),q(V,{class:"h-[150] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(H6,{index:0}),q(H6,{index:1})]}})]}}),q(V,{class:"h-[184] px-6 flex-col",get children(){return[q(G6,{title:"POSITIONS"}),q(V,{class:"h-[136] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(j6,{index:0}),q(j6,{index:1})]}})]}}),q(V,{class:"h-[126] px-6 pt-2",get children(){return q(V,{class:"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-col gap-3",get children(){return[q(O,{class:"text-xl text-slate-900 font-bold",children:"REALIZED P&L"}),q(O,{class:"text-base text-slate-500",get children(){return"EQUITIES / "+(u()==="day"?"TODAY":"WEEK")}})]}}),q(O,{get["class"](){return(k0(u()==="day"?y().pnlDay:y().pnlWeek)??0)>=0?"text-2xl text-emerald-600 font-bold":"text-2xl text-red-500 font-bold"},get children(){return JJ(u()==="day"?y().pnlDay:y().pnlWeek)}})]}})}}),q(V,{class:"h-[104] px-6 flex-row items-center justify-between",get children(){return[q(V,{class:"w-[460] h-[64]",get children(){return q(JQ,{get text(){return e4()},get tone(){return e4().startsWith("REFRESH FAILED")?"danger":"neutral"}})}}),q(V,{class:"w-[176] h-[64]",get children(){return q(t2,{get label(){return rJ()?"REFRESHING":"REFRESH NOW"},get disabled(){return rJ()}})}})]}})]}})}function K1(){return q(QQ,{top:"absolute left-[628] top-[156] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",bottom:"absolute left-[628] top-[972] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100"})}function OQ(){let J=$J(()=>gJ().slice(G1(),G1()+8)),Q=L0();return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ACCOUNTS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(NJ,{get each(){return J()},children:($)=>q(V,{get["class"](){return $.number===Q?"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100"},get children(){return[q(V,{class:"flex-row items-center justify-between",get children(){return[q(O,{class:"text-xl text-slate-900 font-bold",get children(){return $.label}}),q(O,{class:"text-lg text-slate-500 font-bold",get children(){return"····"+$.suffix}})]}}),q(V,{class:"flex-row items-center justify-between",get children(){return[q(V,{get["class"](){return c4.success.surface},get children(){return q(O,{get["class"](){return c4.success.text},get children(){return $.status}})}}),q(Z0,{get when(){return $.number===Q},get children(){return q(O,{class:"text-base text-emerald-600 font-bold",children:"SELECTED"})}})]}})]}})})}}),q(K1,{})]}})}function LQ(){let J=$J(()=>y().activity.slice(r4(),r4()+8));return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ACTIVITY",metaBottom:"LAST 7 DAYS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[14]",get children(){return q(Z0,{get when(){return l(()=>!!y().activityAvailable)()&&J().length>0},get fallback(){return q(d4,{get title(){return y().activityAvailable?"NO ACTIVITY YET":"ACTIVITY UNAVAILABLE"},compact:!0})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(V,{class:"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-row items-center justify-between",get children(){return[q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q.title}}),q(O,{get["class"](){return Q.side==="SELL"?"text-lg text-emerald-600 font-bold":"text-lg text-slate-900 font-bold"},get children(){return JJ(Q.amount)}})]}}),q(O,{class:"text-base text-slate-500",get children(){return Q.timestamp+" · "+Q.detail}}),q(O,{class:"text-base text-emerald-600 font-bold",get children(){return Q.state}})]}})})}})}}),q(K1,{})]}})}function IQ(){let J=$J(()=>y().positions.slice(o4(),o4()+9));return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"POSITIONS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(Z0,{get when(){return l(()=>!!y().positionsAvailable)()&&J().length>0},get fallback(){return q(d4,{get title(){return y().positionsAvailable?"NO OPEN POSITIONS":"POSITIONS UNAVAILABLE"},compact:!0})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(V,{class:"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-row items-center",get children(){return[q(O,{class:"w-[170] text-xl text-slate-900 font-bold",get children(){return Q.symbol}}),q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q.quantity+" SH"}})]}}),q(O,{class:"text-base text-slate-500",get children(){return"AVERAGE COST "+JJ(Q.averagePrice)+(Q.marketValue?" · VALUE "+JJ(Q.marketValue):"")}})]}})})}})}}),q(K1,{})]}})}function kQ(){if(s()==="accounts")return q(OQ,{});if(s()==="activity")return q(LQ,{});return q(IQ,{})}function _Q(){return q(Z0,{get when(){return s()==="dashboard"},get fallback(){return q(kQ,{})},get children(){return q(RQ,{})}})}Y6(),u2(()=>q(_Q,{})),globalThis.PocketPiApp={tick:UQ,dataChanged(J){let Q=HQ(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),p):p;return Y6($),""},invokeTool(J){try{let Q=J==="robinhood.storage_status"?MQ():(()=>{throw Error("Data-writing tools run in the background App Data Action")})();return JSON.stringify({text:JSON.stringify(Q),details:Q,isError:!1})}catch(Q){return JSON.stringify({text:Q instanceof Error?Q.message:String(Q),isError:!0})}},tap(J,Q){if(s()!=="dashboard"){if(Q<112&&J<220)return sJ("dashboard"),"";if(J>=620&&Q>=140&&Q<310){if(s()==="accounts")a4(($)=>Math.max(0,$-1));if(s()==="activity")n4(($)=>Math.max(0,$-1));if(s()==="positions")t4(($)=>Math.max(0,$-1));return""}if(J>=620&&Q>=940&&Q<1130){if(s()==="accounts")a4(($)=>Math.min(Math.max(0,gJ().length-8),$+1));if(s()==="activity")n4(($)=>Math.min(Math.max(0,y().activity.length-8),$+1));if(s()==="positions")t4(($)=>Math.min(Math.max(0,y().positions.length-9),$+1));return""}if(s()==="accounts"&&J<610&&Q>=126){let $=G1()+Math.floor((Q-126)/112),Z=gJ()[$];if(Z)eJ(()=>{I0(Z.number),sJ("dashboard")}),z6(Z.number,p)}return""}if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(Q>=112&&Q<176)return sJ("accounts"),"";if(Q>=480&&Q<540)return eJ(()=>{zQ(J<136?"day":"week"),q6(L0(),p)}),"";if(Q>=666&&Q<866)return sJ("activity"),"";if(Q>=866&&Q<1050)return sJ("positions"),"";if(Q>=1176&&J>=500){if(rJ())return"";return J6(!0),XJ("REFRESHING ROBINHOOD…"),JSON.stringify({type:"invokeTask",task:"refreshPortfolio"})}return""}}})(); + `).all(Y,X,J).map((j)=>({time:j.bucket_time,value:k0(j.total_value)})),R=D.map((j)=>j.time),U=D.map((j)=>j.value).filter((j)=>j!==null),H=[R[0],R[9],R[19]].map((j)=>{let G=new Date(j*1000);return l()==="day"?String(G.getHours()).padStart(2,"0")+":"+String(G.getMinutes()).padStart(2,"0"):String(G.getMonth()+1)+"/"+String(G.getDate())});if(U.length===0){let j=l()==="day"?y().pnlDay:y().pnlWeek,G=k0(j),P={points:[],segments:[],labels:H,trend:{change:e(j),percent:"—",positive:G===null||G>=0}};j1.set($,{loadedRevision:Q,value:P}),OJ(P.points),LJ(P.segments),z1(P.labels),Y1(P.trend);return}let w=Math.min(...U),x=Math.max(...U),g=Math.max(0.01,x-w),A=D.flatMap((j,G)=>j.value===null?[]:[{x:G*622/19,y:U.length===1?80:10+(x-j.value)*140/g}]),s=A.slice(1).map((j,G)=>{let P=A[G],k=j.x-P.x,_=j.y-P.y;return{x:P.x,y:P.y,width:Math.sqrt(k*k+_*_),angle:Math.atan2(_,k)*180/Math.PI}}),a=U[U.length-1]-U[0],K={change:e(String(a)),percent:U[0]===0?"—":(a*100/U[0]).toFixed(2)+"%",positive:a>=0};j1.set($,{loadedRevision:Q,value:{points:A,segments:s,labels:H,trend:K}}),OJ(A),LJ(s),z1(H),Y1(K)}function KQ(J){if($6===J)return;let Q=BJ.query("SELECT status,error,completed_at FROM refresh_runs ORDER BY id DESC LIMIT 1").get();if(e4(!1),Q?.status==="failed")ZJ("REFRESH FAILED · "+String(Q.error||"UNKNOWN ERROR").slice(0,52));else if(Q?.status==="partial")ZJ("LIVE WITH PARTIAL DATA");else if(y().observedAt)ZJ("LIVE · "+X6(y().observedAt));else ZJ("WAITING FOR ROBINHOOD");$6=J}function q6(J,Q){if(!J){if(aJ(iJ),OJ([]),LJ([]),!rJ())ZJ("WAITING FOR ROBINHOOD");return}let $=H1.get(J);if($?.loadedRevision===Q){if(aJ($.value),W6(J,Q),$.value.observedAt&&!rJ())ZJ("LIVE · "+X6($.value.observedAt));return}aJ(iJ),OJ([]),LJ([])}function z6(J=u){try{let Q=BJ.query("PRAGMA user_version").get();if(Number(Q?.user_version??0)!==QQ){W1([]),I0(""),aJ(iJ),OJ([]),LJ([]),ZJ("WAITING FOR ROBINHOOD");return}eJ(()=>{u=Math.max(u,J);let $=gJ();if(J6!==u)$=jQ(),W1($),J6=u;FQ(u,$);let Z=L0();if(!$.some((X)=>X.number===Z))Z=$[0]?.number||"",I0(Z);q6(Z,u),KQ(u)})}catch{eJ(()=>{W1([]),I0(""),aJ(iJ),OJ([]),LJ([]),ZJ("WAITING FOR ROBINHOOD")})}}function UQ(){return""}function F1(){return GQ()}function _0(J){return q(r2,{get title(){return J.title},back:!0,metaTop:"AGENTIC",get metaBottom(){return J.metaBottom??"AUTO · 5 MIN"}})}function B1(J){return q(V,{class:"w-[210] h-[104]",get children(){return q(t2,{get label(){return J.label},get value(){return e(J.value)}})}})}function Y6(J){return q(n2,{get title(){return J.title},get detail(){return J.detail},action:!0})}function MQ(J){if(J===0&&!y().activityAvailable)return ZQ;return y().activity[J]??(J===0?Z1:XQ)}function G6(J){let Q=()=>MQ(J.index);return q(V,{class:"h-[72] px-5 flex-row items-center justify-between",get children(){return[q(V,{class:"w-[450] flex-col gap-2",get children(){return[q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q().title}}),q(O,{class:"text-base text-slate-500",get children(){return m(()=>!!Q().timestamp)()?Q().timestamp+" · "+Q().detail:""}})]}}),q(O,{get["class"](){return Q().side==="SELL"?"text-base text-emerald-600 font-bold":"text-base text-slate-900 font-bold"},get children(){return m(()=>!!Q().amount)()?e(Q().amount):""}})]}})}function PQ(J){if(J===0&&!y().positionsAvailable)return WQ;return y().positions[J]??(J===0?X1:qQ)}function H6(J){let Q=()=>PQ(J.index);return q(V,{class:"h-[64] px-5 flex-row items-center",get children(){return[q(O,{class:"w-[240] text-lg text-slate-900 font-bold",get children(){return Q().symbol}}),q(O,{class:"w-[156] text-base text-slate-500",get children(){return m(()=>!!Q().quantity)()?Q().quantity+" SH":""}}),q(O,{class:"text-base text-slate-500",get children(){return m(()=>!!Q().averagePrice)()?"AVG "+e(Q().averagePrice):""}})]}})}function VQ(){return q(V,{class:"relative w-[632] h-[196] flex-col",get children(){return[q(V,{class:"relative w-[632] h-[160] overflow-hidden",get children(){return[q(V,{class:"absolute w-[632] h-[2] bg-slate-200",style:{posType:1,insetL:0,insetT:158}}),q(O,{class:"absolute text-base text-slate-500 font-bold",style:{posType:1,insetL:152,insetT:72},get children(){return i4().length<2?"COLLECTING 5M VALUE HISTORY":""}}),q(NJ,{get each(){return YQ()},children:(J)=>q(V,{get["class"](){return F1().positive?"absolute rounded-lg bg-emerald-500":"absolute rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x,insetT:J.y-1,width:J.width,height:2,rotate:J.angle,originX:-0.5,originY:0}}})}),q(NJ,{get each(){return i4()},children:(J)=>q(V,{get["class"](){return F1().positive?"absolute w-[6] h-[6] rounded-lg bg-emerald-500":"absolute w-[6] h-[6] rounded-lg bg-red-500"},get style(){return{posType:1,insetL:J.x-3,insetT:J.y-3}}})})]}}),q(V,{class:"h-[36] px-1 flex-row items-center justify-between",get children(){return[q(O,{class:"text-base text-slate-500",get children(){return q1()[0]||""}}),q(O,{class:"text-base text-slate-500",get children(){return q1()[1]||""}}),q(O,{class:"text-base text-slate-500",get children(){return q1()[2]||""}})]}})]}})}function DQ(){let J=()=>F1();return q(V,{class:"flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ROBINHOOD"}),q(V,{class:"h-[64] px-6 pt-2",get children(){return q(V,{class:"w-full h-[56] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(O,{class:"text-base text-slate-500 font-bold",children:"ACCOUNT"}),q(O,{class:"text-base text-slate-900 font-bold",get children(){return y().account.label+(y().account.suffix?" ····"+y().account.suffix+" "+(gJ().findIndex((Q)=>Q.number===L0())+1)+"/"+gJ().length:"")+" ›"}})]}})}}),q(V,{class:"h-[304] px-6 pt-3",get children(){return q(V,{class:"h-[291] px-5 pt-4 flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"h-[64] flex-row items-end justify-between",get children(){return[q(O,{class:"text-2xl text-slate-950 font-bold",get children(){return e(y().totalValue)}}),q(O,{get["class"](){return J().positive?"text-lg text-emerald-600 font-bold":"text-lg text-red-500 font-bold"},get children(){return J().change+" ("+J().percent+")"}})]}}),q(VQ,{})]}})}}),q(V,{class:"h-[60] px-6 pt-2 flex-row gap-3",get children(){return[q(V,{get["class"](){return l()==="day"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(O,{get["class"](){return l()==="day"?"text-base text-white font-bold":"text-base text-slate-500 font-bold"},children:"1D"})}}),q(V,{get["class"](){return l()==="week"?"w-[100] h-[44] items-center justify-center rounded-lg bg-orange-600":"w-[100] h-[44] items-center justify-center rounded-lg bg-white"},get children(){return q(O,{get["class"](){return l()==="week"?"text-base text-white font-bold":"text-base text-slate-500 font-bold"},children:"1W"})}}),q(O,{class:"pt-3 text-base text-slate-500",get children(){return l()==="day"?"TODAY":"PAST WEEK"}})]}}),q(V,{class:"h-[126] px-6 pt-3 flex-row items-start gap-[21]",get children(){return[q(B1,{label:"VALUE",get value(){return y().totalValue}}),q(B1,{label:"CASH",get value(){return y().cash}}),q(B1,{label:"BUY POWER",get value(){return y().buyingPower}})]}}),q(V,{class:"h-[200] px-6 flex-col",get children(){return[q(Y6,{title:"ACTIVITY",detail:"LAST 7 DAYS"}),q(V,{class:"h-[150] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(G6,{index:0}),q(G6,{index:1})]}})]}}),q(V,{class:"h-[184] px-6 flex-col",get children(){return[q(Y6,{title:"POSITIONS"}),q(V,{class:"h-[136] flex-col rounded-xl shadow bg-white border-slate-100",get children(){return[q(H6,{index:0}),q(H6,{index:1})]}})]}}),q(V,{class:"h-[126] px-6 pt-2",get children(){return q(V,{class:"w-full h-[110] px-5 flex-row items-center justify-between rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-col gap-3",get children(){return[q(O,{class:"text-xl text-slate-900 font-bold",children:"REALIZED P&L"}),q(O,{class:"text-base text-slate-500",get children(){return"EQUITIES / "+(l()==="day"?"TODAY":"WEEK")}})]}}),q(O,{get["class"](){return(k0(l()==="day"?y().pnlDay:y().pnlWeek)??0)>=0?"text-2xl text-emerald-600 font-bold":"text-2xl text-red-500 font-bold"},get children(){return e(l()==="day"?y().pnlDay:y().pnlWeek)}})]}})}}),q(V,{class:"h-[104] px-6 flex-row items-center justify-between",get children(){return[q(V,{class:"w-[460] h-[64]",get children(){return q(e2,{get text(){return t4()},get tone(){return t4().startsWith("REFRESH FAILED")?"danger":"neutral"}})}}),q(V,{class:"w-[176] h-[64]",get children(){return q(o2,{get label(){return rJ()?"REFRESHING":"REFRESH NOW"},get disabled(){return rJ()}})}})]}})]}})}function K1(){return q(JQ,{top:"absolute left-[628] top-[156] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100",bottom:"absolute left-[628] top-[972] w-[68] h-[132] items-center justify-center rounded-xl bg-orange-100"})}function RQ(){let J=QJ(()=>gJ().slice(G1(),G1()+8)),Q=L0();return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ACCOUNTS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(NJ,{get each(){return J()},children:($)=>q(V,{get["class"](){return $.number===Q?"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-emerald-100 border-emerald-500":"w-[584] h-[100] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100"},get children(){return[q(V,{class:"flex-row items-center justify-between",get children(){return[q(O,{class:"text-xl text-slate-900 font-bold",get children(){return $.label}}),q(O,{class:"text-lg text-slate-500 font-bold",get children(){return"····"+$.suffix}})]}}),q(V,{class:"flex-row items-center justify-between",get children(){return[q(V,{get["class"](){return c4.success.surface},get children(){return q(O,{get["class"](){return c4.success.text},get children(){return $.status}})}}),q(Z0,{get when(){return $.number===Q},get children(){return q(O,{class:"text-base text-emerald-600 font-bold",children:"SELECTED"})}})]}})]}})})}}),q(K1,{})]}})}function OQ(){let J=QJ(()=>y().activity.slice(a4(),a4()+8));return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"ACTIVITY",metaBottom:"LAST 7 DAYS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[14]",get children(){return q(Z0,{get when(){return m(()=>!!y().activityAvailable)()&&J().length>0},get fallback(){return q(d4,{get title(){return y().activityAvailable?"NO ACTIVITY YET":"ACTIVITY UNAVAILABLE"},compact:!0})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(V,{class:"w-[584] h-[112] px-5 flex-col justify-center gap-2 rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-row items-center justify-between",get children(){return[q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q.title}}),q(O,{get["class"](){return Q.side==="SELL"?"text-lg text-emerald-600 font-bold":"text-lg text-slate-900 font-bold"},get children(){return e(Q.amount)}})]}}),q(O,{class:"text-base text-slate-500",get children(){return Q.timestamp+" · "+Q.detail}}),q(O,{class:"text-base text-emerald-600 font-bold",get children(){return Q.state}})]}})})}})}}),q(K1,{})]}})}function LQ(){let J=QJ(()=>y().positions.slice(n4(),n4()+9));return q(V,{class:"relative flex-col w-full h-full bg-slate-50",get children(){return[q(_0,{title:"POSITIONS"}),q(V,{class:"px-6 pt-[14] flex-col gap-[12]",get children(){return q(Z0,{get when(){return m(()=>!!y().positionsAvailable)()&&J().length>0},get fallback(){return q(d4,{get title(){return y().positionsAvailable?"NO OPEN POSITIONS":"POSITIONS UNAVAILABLE"},compact:!0})},get children(){return q(NJ,{get each(){return J()},children:(Q)=>q(V,{class:"w-[584] h-[98] px-5 flex-col justify-center gap-3 rounded-xl shadow bg-white border-slate-100",get children(){return[q(V,{class:"flex-row items-center",get children(){return[q(O,{class:"w-[170] text-xl text-slate-900 font-bold",get children(){return Q.symbol}}),q(O,{class:"text-lg text-slate-900 font-bold",get children(){return Q.quantity+" SH"}})]}}),q(O,{class:"text-base text-slate-500",get children(){return"AVERAGE COST "+e(Q.averagePrice)+(Q.marketValue?" · VALUE "+e(Q.marketValue):"")}})]}})})}})}}),q(K1,{})]}})}function IQ(){if(i()==="accounts")return q(RQ,{});if(i()==="activity")return q(OQ,{});return q(LQ,{})}function kQ(){return q(Z0,{get when(){return i()==="dashboard"},get fallback(){return q(IQ,{})},get children(){return q(DQ,{})}})}z6(),l2(()=>q(kQ,{})),globalThis.PocketPiApp={tick:UQ,dataChanged(J){let Q=HQ(J),$=Array.isArray(Q)?Q.reduce((Z,X)=>Math.max(Z,Number(X?.revision??0)),u):u;return z6($),""},tap(J,Q){if(i()!=="dashboard"){if(Q<112&&J<220)return sJ("dashboard"),"";if(J>=620&&Q>=140&&Q<310){if(i()==="accounts")s4(($)=>Math.max(0,$-1));if(i()==="activity")r4(($)=>Math.max(0,$-1));if(i()==="positions")o4(($)=>Math.max(0,$-1));return""}if(J>=620&&Q>=940&&Q<1130){if(i()==="accounts")s4(($)=>Math.min(Math.max(0,gJ().length-8),$+1));if(i()==="activity")r4(($)=>Math.min(Math.max(0,y().activity.length-8),$+1));if(i()==="positions")o4(($)=>Math.min(Math.max(0,y().positions.length-9),$+1));return""}if(i()==="accounts"&&J<610&&Q>=126){let $=G1()+Math.floor((Q-126)/112),Z=gJ()[$];if(Z)eJ(()=>{I0(Z.number),sJ("dashboard")}),q6(Z.number,u)}return""}if(Q<112&&J<100)return JSON.stringify({type:"navigate",app:"pi-agent"});if(Q>=112&&Q<176)return sJ("accounts"),"";if(Q>=480&&Q<540)return eJ(()=>{zQ(J<136?"day":"week"),W6(L0(),u)}),"";if(Q>=666&&Q<866)return sJ("activity"),"";if(Q>=866&&Q<1050)return sJ("positions"),"";if(Q>=1176&&J>=500){if(rJ())return"";return e4(!0),ZJ("REFRESHING ROBINHOOD…"),JSON.stringify({type:"invokeTask",task:"refreshPortfolio"})}return""}}})(); diff --git a/apps/robinhood/dist/app.pak b/apps/robinhood/dist/app.pak index 3dc252f68e0fb1b37ad2619a697e41e3c098c531..a715b607b1c64500eb3106c20e96d47b3091d315 100644 GIT binary patch delta 59 zcmX>wOK`(X!3h#f8+;~8&0|`{+qkQB7h~%#rq*4|TX(Ve*fADuXSZir$1(k;2aELf NG!K?rENl#5006GH6Sn{W delta 177 zcmdlmQ}Dnn!3h#f4!#qm<}o?&HSTKN#n`%wsdX3g)?F+ Instant { + Instant::now() + APP_ACTION_TIMEOUT +} + #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct AppDescriptor { @@ -155,6 +159,11 @@ impl AppCatalog { .filter(|title| !title.is_empty()) .ok_or_else(|| anyhow!("App {} pocket.json is missing title", descriptor.id))? .to_owned(); + anyhow::ensure!( + pocket.get("version").and_then(Value::as_str) == Some(descriptor.version.as_str()), + "App {} version differs between agent-app.json and pocket.json", + descriptor.id + ); if descriptor.tool_namespace.is_empty() { descriptor.tool_namespace.clone_from(&descriptor.id); } @@ -211,15 +220,6 @@ impl AppCatalog { { anyhow::bail!("duplicate App tool: {name}"); } - if let Some(operation) = tool.get("providerOperation") { - let operation = operation - .as_str() - .ok_or_else(|| anyhow!("{name} providerOperation must be a string"))?; - anyhow::ensure!( - name == format!("{}.{}", app.descriptor.id, operation), - "{name} providerOperation must match its namespaced Tool name" - ); - } } } Ok(Self { apps, tool_owner }) @@ -244,18 +244,6 @@ impl AppCatalog { self.apps.get(id).map(|app| &app.descriptor) } - /// Provider operations are declared by the App release and consumed by a - /// native credential/transport owner as its exact allowlist. Local-only - /// App Tools omit `providerOperation` and can never cross this boundary. - pub fn provider_operations(&self, app_id: &str) -> BTreeSet { - self.apps - .get(app_id) - .into_iter() - .flat_map(|app| &app.descriptor.provider_operations) - .cloned() - .collect() - } - pub fn provider_operation_allowed(&self, app_id: &str, operation: &str) -> bool { self.descriptor(app_id) .is_some_and(|app| app.provider_operations.iter().any(|item| item == operation)) @@ -306,12 +294,15 @@ impl AppCatalog { /// own TLS, credentials and MCP sessions; Apps own operation selection, /// normalization, SQLite and View behavior. pub trait AppServiceHost: Send + Sync { + /// Execute one policy-checked synchronous service call without outliving + /// the App Data Action's absolute deadline. fn call( &self, app_id: &str, service: &str, operation: &str, args: &Value, + deadline: Instant, ) -> Result; /// Execute one policy-checked PocketJS HTTP request. This is called only @@ -320,6 +311,7 @@ pub trait AppServiceHost: Send + Sync { &self, _app_id: &str, request: HttpRequest, + _deadline: Instant, ) -> std::result::Result { Err(NetFailure::new( "unavailable", @@ -357,6 +349,8 @@ struct DataActionRequest { kind: DataActionKind, name: String, args: Value, + deadline: Instant, + response: Option>, } #[derive(Clone)] @@ -368,15 +362,25 @@ struct DataAppConfig { net: bool, } +struct AppHttpRequest { + request: HttpRequest, + deadline: Instant, +} + struct AppNetTransport { - requests: mpsc::SyncSender, + requests: mpsc::SyncSender, completions: mpsc::Receiver, cancelled: BTreeSet, + action_deadline: Rc>>, } impl AppNetTransport { - fn start(app_id: String, services: Arc) -> Result { - let (request_tx, request_rx) = mpsc::sync_channel::(NET_COMPLETION_QUEUE); + fn start( + app_id: String, + services: Arc, + action_deadline: Rc>>, + ) -> Result { + let (request_tx, request_rx) = mpsc::sync_channel::(NET_COMPLETION_QUEUE); let (completion_tx, completion_rx) = mpsc::sync_channel::(NET_COMPLETION_QUEUE); let worker_name = format!("net-{app_id}"); @@ -384,11 +388,20 @@ impl AppNetTransport { .name(worker_name) .stack_size(NET_WORKER_STACK_BYTES) .spawn(move || { - while let Ok(request) = request_rx.recv() { - let handle = request.handle; - let completion = services - .http(&app_id, request) - .unwrap_or_else(|failure| TransportCompletion::Error { handle, failure }); + while let Ok(mut work) = request_rx.recv() { + let handle = work.request.handle; + let completion = match remaining_timeout_ms(work.deadline) { + Ok(remaining_ms) => { + work.request.timeout_ms = work.request.timeout_ms.min(remaining_ms); + services + .http(&app_id, work.request, work.deadline) + .unwrap_or_else(|failure| TransportCompletion::Error { + handle, + failure, + }) + } + Err(failure) => TransportCompletion::Error { handle, failure }, + }; if completion_tx.send(completion).is_err() { break; } @@ -399,14 +412,20 @@ impl AppNetTransport { requests: request_tx, completions: completion_rx, cancelled: BTreeSet::new(), + action_deadline, }) } } impl HttpTransport for AppNetTransport { - fn start(&mut self, request: HttpRequest) -> std::result::Result<(), NetFailure> { + fn start(&mut self, mut request: HttpRequest) -> std::result::Result<(), NetFailure> { + let deadline = self.action_deadline.get().ok_or_else(|| { + NetFailure::new("unavailable", "HTTP request has no active App Data Action") + })?; + let remaining_ms = remaining_timeout_ms(deadline)?; + request.timeout_ms = request.timeout_ms.min(remaining_ms); self.requests - .try_send(request) + .try_send(AppHttpRequest { request, deadline }) .map_err(|_| NetFailure::new("busy", "native HTTP worker queue is full")) } @@ -427,9 +446,18 @@ impl HttpTransport for AppNetTransport { } } +fn remaining_timeout_ms(deadline: Instant) -> std::result::Result { + let remaining = deadline + .checked_duration_since(Instant::now()) + .filter(|duration| !duration.is_zero()) + .ok_or_else(|| NetFailure::new("timeout", "App Data Action deadline expired"))?; + Ok(remaining.as_millis().clamp(1, u128::from(u32::MAX)) as u32) +} + struct DataActionRuntime { guest: Guest, net: Option>, + action_deadline: Rc>>, _database: SharedDb, _revision: AppRevision, } @@ -438,13 +466,23 @@ impl DataActionRuntime { fn load(config: &DataAppConfig, services: Arc) -> Result { let guest = Guest::new()?; mount_shared_db(&guest, config.database.clone())?; - mount_data_lifecycle(&guest, config.revision.clone())?; + let action_deadline = Rc::new(Cell::new(None)); + mount_data_lifecycle(&guest, config.revision.clone(), action_deadline.clone())?; let net = if config.net { - let surface = NetSurface::new(AppNetTransport::start(config.app_id.clone(), services)?); + let surface = NetSurface::new(AppNetTransport::start( + config.app_id.clone(), + services, + action_deadline.clone(), + )?); surface.mount(&guest)?; Some(surface) } else { - mount_services(&guest, config.app_id.clone(), services)?; + mount_services( + &guest, + config.app_id.clone(), + services, + action_deadline.clone(), + )?; None }; let source = std::fs::read_to_string(&config.source_path) @@ -458,33 +496,43 @@ impl DataActionRuntime { Ok(Self { guest, net, + action_deadline, _database: config.database.clone(), _revision: config.revision.clone(), }) } fn invoke(&self, request: &DataActionRequest) -> Result { - if let Some(net) = &self.net { - return self.invoke_net(request, net); - } - let method = match request.kind { - DataActionKind::Task => "invokeTask", - DataActionKind::Tool => "invokeTool", + anyhow::ensure!( + Instant::now() < request.deadline, + "{} timed out before its Data Action started", + request.name + ); + self.action_deadline.set(Some(request.deadline)); + let result = if let Some(net) = &self.net { + self.invoke_net(request, net) + } else { + let method = match request.kind { + DataActionKind::Task => "invokeTask", + DataActionKind::Tool => "invokeTool", + }; + let line: Result = self.guest.with(|ctx| { + let data: Object = ctx + .globals() + .get("PocketPiData") + .map_err(|error| anyhow!("PocketPiData missing: {error}"))?; + let function: Function = data + .get(method) + .map_err(|error| anyhow!("PocketPiData.{method} missing: {error}"))?; + function + .call::<_, String>((request.name.clone(), request.args.to_string())) + .catch(&ctx) + .map_err(|error| anyhow!("PocketPiData.{method}: {error}")) + }); + line.and_then(|line| parse_data_result(&line)) }; - let line: String = self.guest.with(|ctx| { - let data: Object = ctx - .globals() - .get("PocketPiData") - .map_err(|error| anyhow!("PocketPiData missing: {error}"))?; - let function: Function = data - .get(method) - .map_err(|error| anyhow!("PocketPiData.{method} missing: {error}"))?; - function - .call::<_, String>((request.name.clone(), request.args.to_string())) - .catch(&ctx) - .map_err(|error| anyhow!("PocketPiData.{method}: {error}")) - })?; - parse_data_result(&line) + self.action_deadline.set(None); + result } fn invoke_net( @@ -502,7 +550,6 @@ impl DataActionRuntime { function.call::<_, ()>((request.name.clone(), request.args.to_string()))?; Ok(()) })?; - let deadline = std::time::Instant::now() + TOOL_TIMEOUT; loop { net.begin_tick(); let line = self.guest.with(|ctx| -> Result> { @@ -517,7 +564,7 @@ impl DataActionRuntime { return parse_data_result(&line); } anyhow::ensure!( - std::time::Instant::now() < deadline, + Instant::now() < request.deadline, "PocketPiData.{method} timed out" ); yield_scheduler_tick(); @@ -542,14 +589,8 @@ fn parse_data_result(line: &str) -> Result { }) } -struct DataActionCompletion { - run_id: u64, - result: ToolResult, -} - struct AppDataRunner { tx: mpsc::SyncSender, - completions: Mutex>, next_run_id: AtomicU32, busy: Arc, } @@ -557,7 +598,6 @@ struct AppDataRunner { impl AppDataRunner { fn start(configs: Vec, services: Arc) -> Result { let (tx, rx) = mpsc::sync_channel::(DATA_ACTION_QUEUE); - let (completion_tx, completion_rx) = mpsc::channel::(); let busy = Arc::new(AtomicBool::new(false)); let worker_busy = busy.clone(); std::thread::Builder::new() @@ -586,6 +626,11 @@ impl AppDataRunner { .expect("Data Action runtime inserted") .invoke(&request) })(); + if result.is_err() && Instant::now() >= request.deadline { + // Drop the timed-out Guest and its pending promises. + // The next request gets a clean runtime and NET worker. + runtimes.remove(&request.app_id); + } let result = match result { Ok(result) if result.is_error => { log::warn!( @@ -608,23 +653,29 @@ impl AppDataRunner { tool_error(format!("{}: {error:#}", request.name)) } }; - let _ = completion_tx.send(DataActionCompletion { - run_id: request.run_id, - result, - }); + if let Some(response) = request.response { + let _ = response.send(result); + } worker_busy.store(false, Ordering::Release); } }) .context("start App Data Action runner")?; Ok(Self { tx, - completions: Mutex::new(completion_rx), next_run_id: AtomicU32::new(1), busy, }) } - fn enqueue(&self, app_id: &str, kind: DataActionKind, name: &str, args: Value) -> Result { + fn enqueue( + &self, + app_id: &str, + kind: DataActionKind, + name: &str, + args: Value, + deadline: Instant, + response: Option>, + ) -> Result { let run_id = u64::from(self.next_run_id.fetch_add(1, Ordering::Relaxed)); self.tx .try_send(DataActionRequest { @@ -633,6 +684,8 @@ impl AppDataRunner { kind, name: name.to_owned(), args, + deadline, + response, }) .map_err(|error| anyhow!("queue App Data Action: {error}"))?; Ok(run_id) @@ -641,17 +694,6 @@ impl AppDataRunner { fn busy(&self) -> bool { self.busy.load(Ordering::Acquire) } - - fn poll_completions(&self) -> Vec { - let Ok(completions) = self.completions.lock() else { - return Vec::new(); - }; - let mut ready = Vec::new(); - while let Ok(completion) = completions.try_recv() { - ready.push(completion); - } - ready - } } struct AppRuntime { @@ -682,6 +724,10 @@ impl AppRuntime { descriptor.id == app.descriptor.id, "installed App id mismatch" ); + anyhow::ensure!( + descriptor.version == app.descriptor.version, + "installed App version mismatch" + ); let manifest: Value = serde_json::from_slice( &std::fs::read(release_dir.join("pocket.json")).context("read pocket.json")?, ) @@ -801,33 +847,10 @@ impl AppRuntime { self.call_optional_method("pointerUp", ()) } - fn invoke_tool(&self, name: &str, args_json: &str) -> Result { - let line: String = - self.call_method("invokeTool", (name.to_owned(), args_json.to_owned()))?; - self.tool_result(&line) - } - fn with_ui(&self, f: impl FnOnce(&mut pocketjs_core::Ui) -> R) -> R { self.surface.with_ui(f) } - fn tool_result(&self, line: &str) -> Result { - let value: Value = serde_json::from_str(line).context("parse App result")?; - Ok(ToolResult { - text: value - .get("text") - .and_then(Value::as_str) - .unwrap_or(line) - .to_owned(), - details: value.get("details").cloned().unwrap_or(Value::Null), - is_error: value - .get("isError") - .and_then(Value::as_bool) - .unwrap_or(false), - terminate: false, - }) - } - fn call_method(&self, name: &str, args: A) -> Result where A: for<'js> pocket_mod::qjs::function::IntoArgs<'js>, @@ -935,7 +958,12 @@ fn mount_shared_db(guest: &Guest, db: SharedDb) -> Result<()> { }) } -fn mount_services(guest: &Guest, app_id: String, services: Arc) -> Result<()> { +fn mount_services( + guest: &Guest, + app_id: String, + services: Arc, + action_deadline: Rc>>, +) -> Result<()> { guest.mount("services", |ctx, ns| { ns.set( "call", @@ -943,7 +971,17 @@ fn mount_services(guest: &Guest, app_id: String, services: Arc String { let args = serde_json::from_str(&args_json).unwrap_or(Value::Null); - match services.call(&app_id, &service, &operation, &args) { + let result = action_deadline + .get() + .ok_or_else(|| "App service call has no active Data Action".to_owned()) + .and_then(|deadline| { + if Instant::now() >= deadline { + Err("App Data Action deadline expired".to_owned()) + } else { + services.call(&app_id, &service, &operation, &args, deadline) + } + }); + match result { Ok(value) => json!({"ok":true,"value":value}).to_string(), Err(error) => json!({"ok":false,"error":error}).to_string(), } @@ -959,8 +997,8 @@ fn yield_scheduler_tick() { unsafe extern "C" { fn vTaskDelay(ticks: u32); } - // The firmware runs FreeRTOS at 100 Hz. Sub-tick sleeps remain runnable, - // so block for one actual scheduler tick and let the IDLE task run. + // The firmware runs FreeRTOS at 100 Hz. Block through one scheduler tick + // instead of sub-tick polling so the IDLE task gets a scheduling chance. unsafe { vTaskDelay(1) }; } @@ -977,7 +1015,11 @@ fn yield_after_db_call() { #[cfg(not(target_os = "espidf"))] fn yield_after_db_call() {} -fn mount_data_lifecycle(guest: &Guest, revision: AppRevision) -> Result<()> { +fn mount_data_lifecycle( + guest: &Guest, + revision: AppRevision, + action_deadline: Rc>>, +) -> Result<()> { guest.mount("app", |ctx, ns| { ns.set( "commit", @@ -987,6 +1029,18 @@ fn mount_data_lifecycle(guest: &Guest, revision: AppRevision) -> Result<()> { revision.fetch_add(1, Ordering::Release).saturating_add(1) as f64 })?, )?; + ns.set( + "remainingMs", + Function::new(ctx.clone(), move || -> f64 { + action_deadline.get().map_or(1, |deadline| { + deadline + .checked_duration_since(Instant::now()) + .map_or(1, |remaining| { + remaining.as_millis().clamp(1, u128::from(u32::MAX)) as u32 + }) + }) as f64 + })?, + )?; Ok(()) }) } @@ -996,7 +1050,6 @@ pub struct AppSupervisor { catalog: AppCatalog, services: Arc, data_runner: AppDataRunner, - pending_tool_responses: Mutex>>, /// The Pi Agent System App is booted once and remains resident for the /// entire supervisor lifetime. Foreground navigation never replaces it. system: AppRuntime, @@ -1086,7 +1139,6 @@ impl AppSupervisor { catalog, services, data_runner, - pending_tool_responses: Mutex::new(BTreeMap::new()), system, agent: None, runtimes, @@ -1157,8 +1209,7 @@ impl AppSupervisor { .map_err(|error| anyhow!(error)) } - /// Advance the resident System App and cheap View bookkeeping. Only the - /// selected surface is rendered; Data Actions progress on their own runner. + /// Advance the resident System App and render the selected View. pub fn frame(&self) -> Result> { self.frame_render(true) } @@ -1166,7 +1217,6 @@ impl AppSupervisor { /// Advance the Agent every host tick, but only ask the selected PocketJS /// View to produce a new DrawList when the host knows it is dirty. pub fn frame_render(&self, render_selected: bool) -> Result> { - self.deliver_data_action_completions(); let events = match &self.agent { Some(agent) => agent .tick(&self.system.guest) @@ -1182,18 +1232,6 @@ impl AppSupervisor { Ok(events) } - fn deliver_data_action_completions(&self) { - let completions = self.data_runner.poll_completions(); - let Ok(mut pending) = self.pending_tool_responses.lock() else { - return; - }; - for completion in completions { - if let Some(response) = pending.remove(&completion.run_id) { - let _ = response.send(completion.result); - } - } - } - pub fn update_root(&self, projection: &Value) -> Result<()> { self.system.update(projection) } @@ -1220,60 +1258,27 @@ impl AppSupervisor { self.active().projection_is_stale() } - pub fn invoke_tool(&mut self, name: &str, args_json: &str) -> ToolResult { - let Some(app_id) = self.catalog.app_for_tool(name).map(str::to_owned) else { - return tool_error(format!("unknown App tool: {name}")); - }; - if name.ends_with(".storage_status") { - return self - .with_runtime(&app_id, |runtime| runtime.invoke_tool(name, args_json)) - .unwrap_or_else(|error| tool_error(format!("{name}: {error:#}"))); - } - let args = serde_json::from_str(args_json).unwrap_or(Value::Null); - match self - .data_runner - .enqueue(&app_id, DataActionKind::Tool, name, args) - { - Ok(run_id) => ToolResult { - text: format!("Queued {name} as App Data Action {run_id}"), - details: json!({"status":"queued","runId":run_id,"app":app_id}), - is_error: false, - terminate: false, - }, - Err(error) => tool_error(format!("{name}: {error:#}")), - } - } - fn begin_agent_tool( - &mut self, + &self, name: &str, args_json: &str, + deadline: Instant, response: mpsc::Sender, ) { let Some(app_id) = self.catalog.app_for_tool(name).map(str::to_owned) else { let _ = response.send(tool_error(format!("unknown App tool: {name}"))); return; }; - if name.ends_with(".storage_status") { - let _ = response.send( - self.with_runtime(&app_id, |runtime| runtime.invoke_tool(name, args_json)) - .unwrap_or_else(|error| tool_error(format!("{name}: {error:#}"))), - ); - return; - } let args = serde_json::from_str(args_json).unwrap_or(Value::Null); - match self - .data_runner - .enqueue(&app_id, DataActionKind::Tool, name, args) - { - Ok(run_id) => { - if let Ok(mut pending) = self.pending_tool_responses.lock() { - pending.insert(run_id, response); - } else { - let _ = - response.send(tool_error("App Tool completion registry is unavailable")); - } - } + match self.data_runner.enqueue( + &app_id, + DataActionKind::Tool, + name, + args, + deadline, + Some(response.clone()), + ) { + Ok(_) => {} Err(error) => { let _ = response.send(tool_error(format!("{name}: {error:#}"))); } @@ -1285,10 +1290,14 @@ impl AppSupervisor { /// native services never hide touch feedback. pub fn invoke_active_task(&mut self, name: &str, args: &Value) -> ToolResult { let app_id = self.active_id().to_owned(); - match self - .data_runner - .enqueue(&app_id, DataActionKind::Task, name, args.clone()) - { + match self.data_runner.enqueue( + &app_id, + DataActionKind::Task, + name, + args.clone(), + new_action_deadline(), + None, + ) { Ok(run_id) => ToolResult { text: format!("Queued {app_id}.{name} as App Data Action {run_id}"), details: json!({"status":"queued","runId":run_id,"app":app_id}), @@ -1308,6 +1317,8 @@ impl AppSupervisor { DataActionKind::Task, &due.task, due.args.clone(), + new_action_deadline(), + None, ) { Ok(run_id) => ToolResult { text: format!("Queued {label} as App Data Action {run_id}"), @@ -1323,25 +1334,6 @@ impl AppSupervisor { results } - fn with_runtime( - &mut self, - app_id: &str, - f: impl FnOnce(&AppRuntime) -> Result, - ) -> Result { - if app_id == ROOT_APP_ID { - let result = f(&self.system)?; - self.system.advance(self.active_app.is_none())?; - return Ok(result); - } - let runtime = self - .runtimes - .get(app_id) - .ok_or_else(|| anyhow!("unknown App: {app_id}"))?; - let result = f(runtime)?; - runtime.advance(self.active_app.as_deref() == Some(app_id))?; - Ok(result) - } - fn active(&self) -> &AppRuntime { self.active_app .as_deref() @@ -1499,8 +1491,9 @@ fn atomic_write(path: &Path, bytes: &[u8]) -> Result<()> { } pub struct AppToolRequest { - pub name: String, - pub args_json: String, + name: String, + args_json: String, + deadline: Instant, response: mpsc::Sender, } @@ -1539,26 +1532,37 @@ impl ToolHost for RoutedToolHost { return self.native.execute(call_id, name, args_json); } let (response, response_rx) = mpsc::channel(); + let deadline = new_action_deadline(); if self .app_tx .send(AppToolRequest { name: name.to_owned(), args_json: args_json.to_owned(), + deadline, response, }) .is_err() { return tool_error("App Supervisor is unavailable"); } - response_rx - .recv_timeout(TOOL_TIMEOUT) - .unwrap_or_else(|_| tool_error(format!("App Tool timed out after {TOOL_TIMEOUT:?}"))) + loop { + if Instant::now() >= deadline { + return tool_error(format!("App Tool timed out after {APP_ACTION_TIMEOUT:?}")); + } + match response_rx.try_recv() { + Ok(result) => return result, + Err(mpsc::TryRecvError::Disconnected) => { + return tool_error("App Data Action response channel closed"); + } + Err(mpsc::TryRecvError::Empty) => yield_scheduler_tick(), + } + } } } impl AppToolRequest { - pub fn handle(self, supervisor: &mut AppSupervisor) { - supervisor.begin_agent_tool(&self.name, &self.args_json, self.response); + pub fn handle(self, supervisor: &AppSupervisor) { + supervisor.begin_agent_tool(&self.name, &self.args_json, self.deadline, self.response); } } @@ -1659,9 +1663,7 @@ impl AppScheduleStore { .filter(|item| item.next_run_at <= now) .min_by_key(|item| item.next_run_at)?; let scheduled_at = item.next_run_at; - while item.next_run_at <= now { - item.next_run_at = item.next_run_at.saturating_add(item.every_seconds); - } + item.next_run_at = next_schedule_run(item.next_run_at, item.every_seconds, now); let due = DueTask { app_id: item.app_id.clone(), schedule_id: item.schedule_id.clone(), @@ -1710,10 +1712,42 @@ fn unix_seconds() -> u64 { .unwrap_or(0) } +fn next_schedule_run(current: u64, interval: u64, now: u64) -> u64 { + let elapsed_intervals = now.saturating_sub(current) / interval; + current.saturating_add(interval.saturating_mul(elapsed_intervals.saturating_add(1))) +} + #[cfg(test)] mod tests { use super::*; + struct NoServices; + + impl AppServiceHost for NoServices { + fn call( + &self, + _app_id: &str, + _service: &str, + _operation: &str, + _args: &Value, + _deadline: Instant, + ) -> std::result::Result { + Err("unexpected App service call".into()) + } + } + + struct NoTools; + + impl ToolHost for NoTools { + fn definitions(&self) -> Vec { + Vec::new() + } + + fn execute(&self, _call_id: &str, name: &str, _args_json: &str) -> ToolResult { + tool_error(format!("unexpected native Tool: {name}")) + } + } + #[test] fn catalog_uses_each_apps_declared_tool_namespace() { let catalog = AppCatalog::new([ @@ -1776,6 +1810,45 @@ mod tests { ); } + #[test] + fn app_tool_request_carries_the_single_80_second_deadline() { + assert_eq!(APP_ACTION_TIMEOUT, Duration::from_secs(80)); + let catalog = AppCatalog::new([ + fixture( + r#"{"id":"pi-agent","description":"System","version":"1","tools":[],"tasks":[],"schedules":[]}"#, + Some("agent"), + ), + fixture( + r#"{"id":"search","description":"Research","version":"1","toolNamespace":"research","tools":[{"name":"research.query","parameters":{"type":"object"}}],"tasks":[],"schedules":[]}"#, + None, + ), + ]) + .unwrap(); + let (tools, requests) = RoutedToolHost::new(Arc::new(NoTools), catalog); + let call = std::thread::spawn(move || tools.execute("call", "research.query", "{}")); + let request = requests.recv().unwrap(); + let remaining = request.deadline.saturating_duration_since(Instant::now()); + assert!(!remaining.is_zero()); + assert!(remaining <= APP_ACTION_TIMEOUT); + request + .response + .send(ToolResult { + text: "done".into(), + ..ToolResult::default() + }) + .unwrap(); + assert_eq!(call.join().unwrap().text, "done"); + } + + #[test] + fn missed_schedules_advance_in_constant_time() { + let hour = 60 * 60; + let ten_years = 10 * 365 * 24 * hour; + let next = next_schedule_run(hour, hour, ten_years); + assert!(next > ten_years); + assert_eq!(next % hour, 0); + } + #[test] fn data_version_resets_only_that_apps_database_once() { let temp = tempfile::tempdir().unwrap(); @@ -1811,14 +1884,78 @@ mod tests { assert!(!database.exists()); } + #[test] + fn app_revisions_coalesce_at_the_foreground_frame_boundary() { + let temp = tempfile::tempdir().unwrap(); + let catalog = AppCatalog::new([pi_agent_bundle(), exa_bundle()]).unwrap(); + let mut supervisor = + AppSupervisor::new(temp.path(), catalog, Arc::new(NoServices)).unwrap(); + supervisor.open("exa").unwrap(); + + let revision = supervisor.runtimes["exa"].revision.clone(); + revision.fetch_add(1, Ordering::Release); + revision.fetch_add(1, Ordering::Release); + revision.fetch_add(1, Ordering::Release); + assert!(supervisor.active_projection_is_stale()); + + supervisor.frame_render(false).unwrap(); + assert_eq!(supervisor.runtimes["exa"].projection_refreshes.get(), 0); + assert_eq!(supervisor.runtimes["exa"].last_seen_revision.get(), 0); + + supervisor.frame_render(true).unwrap(); + assert_eq!(supervisor.runtimes["exa"].projection_refreshes.get(), 1); + assert_eq!(supervisor.runtimes["exa"].last_seen_revision.get(), 3); + assert!(!supervisor.active_projection_is_stale()); + + for _ in 0..5 { + supervisor.frame_render(true).unwrap(); + } + assert_eq!(supervisor.runtimes["exa"].projection_refreshes.get(), 1); + + supervisor.open(ROOT_APP_ID).unwrap(); + revision.fetch_add(1, Ordering::Release); + revision.fetch_add(1, Ordering::Release); + for _ in 0..3 { + supervisor.frame_render(true).unwrap(); + } + assert_eq!(supervisor.runtimes["exa"].projection_refreshes.get(), 1); + + supervisor.open("exa").unwrap(); + supervisor.frame_render(true).unwrap(); + assert_eq!(supervisor.runtimes["exa"].projection_refreshes.get(), 2); + assert_eq!(supervisor.runtimes["exa"].last_seen_revision.get(), 5); + } + fn fixture(descriptor_json: &'static str, agent_js: Option<&'static str>) -> EmbeddedApp { EmbeddedApp::new( descriptor_json, - r#"{"pocket":2,"name":"fixture","title":"Fixture","engine":{"capabilities":{"requires":[]}}}"#, + r#"{"pocket":2,"name":"fixture","title":"Fixture","version":"1","engine":{"capabilities":{"requires":[]}}}"#, "", None, agent_js, &[], ) } + + fn pi_agent_bundle() -> EmbeddedApp { + EmbeddedApp::new( + include_str!("../../../apps/pi-agent/agent-app.json"), + include_str!("../../../apps/pi-agent/pocket.json"), + include_str!("../../../apps/pi-agent/dist/app.js"), + None, + Some(include_str!("../../../apps/pi-agent/dist/agent.js")), + include_bytes!("../../../apps/pi-agent/dist/app.pak"), + ) + } + + fn exa_bundle() -> EmbeddedApp { + EmbeddedApp::new( + include_str!("../../../apps/exa/agent-app.json"), + include_str!("../../../apps/exa/pocket.json"), + include_str!("../../../apps/exa/dist/app.js"), + Some(include_str!("../../../apps/exa/dist/data-action.js")), + None, + include_bytes!("../../../apps/exa/dist/app.pak"), + ) + } } diff --git a/crates/pocket-pi-app-pack/Cargo.toml b/crates/pocket-pi-app-pack/Cargo.toml index 2dd46f1..ab9b0df 100644 --- a/crates/pocket-pi-app-pack/Cargo.toml +++ b/crates/pocket-pi-app-pack/Cargo.toml @@ -10,8 +10,9 @@ build = "build.rs" [dependencies] anyhow.workspace = true pocket-pi-agentos = { path = "../pocket-pi-agentos" } -serde_json.workspace = true [dev-dependencies] +pocket-db.workspace = true pocket-pi-embedded = { path = "../pocket-pi-embedded" } +serde_json.workspace = true tempfile = "3" diff --git a/crates/pocket-pi-app-pack/build.rs b/crates/pocket-pi-app-pack/build.rs index 84a7ac1..b21557b 100644 --- a/crates/pocket-pi-app-pack/build.rs +++ b/crates/pocket-pi-app-pack/build.rs @@ -57,9 +57,7 @@ fn bundle(root: &Path, app: &str, system: bool) -> String { } let data = app.join("dist/data-action.js"); let agent = app.join("dist/agent.js"); - if data.is_file() { - println!("cargo:rerun-if-changed={}", data.display()); - } + println!("cargo:rerun-if-changed={}", data.display()); if system { println!("cargo:rerun-if-changed={}", agent.display()); } diff --git a/crates/pocket-pi-app-pack/src/lib.rs b/crates/pocket-pi-app-pack/src/lib.rs index 18aa876..90dc712 100644 --- a/crates/pocket-pi-app-pack/src/lib.rs +++ b/crates/pocket-pi-app-pack/src/lib.rs @@ -22,8 +22,8 @@ mod tests { actual.sort_unstable(); let mut expected = vec!["pi-agent"]; let selected = option_env!("POCKET_PI_APPS").unwrap_or("robinhood,exa"); - if selected != "none" { - expected.extend(selected.split(',')); + if selected != "none" && !selected.is_empty() { + expected.extend(selected.split(',').map(str::trim)); } expected.sort_unstable(); assert_eq!(actual, expected); @@ -44,30 +44,13 @@ mod tests { .iter() .map(|tool| tool["name"].as_str().unwrap().to_owned()) .collect::>(); - assert_eq!(catalog.provider_operations("robinhood"), upstream); - assert_eq!(upstream.len(), 54); - assert_eq!(descriptor.tools.len(), 4); - } - - #[test] - fn exa_search_exposes_category_dates_and_depth() { - let catalog = catalog().unwrap(); - let Some(descriptor) = catalog.descriptor("exa") else { - return; - }; - let search = descriptor - .tools + let allowed = descriptor + .provider_operations .iter() - .find(|tool| tool["name"] == "research.search") - .unwrap(); - let properties = search["parameters"]["properties"].as_object().unwrap(); - for name in [ - "category", - "startPublishedDate", - "endPublishedDate", - "searchType", - ] { - assert!(properties.contains_key(name), "missing search field {name}"); - } + .cloned() + .collect::>(); + assert_eq!(allowed, upstream); + assert_eq!(upstream.len(), 54); + assert_eq!(descriptor.tools.len(), 3); } } diff --git a/crates/pocket-pi-app-pack/tests/runtime.rs b/crates/pocket-pi-app-pack/tests/runtime.rs index df986c5..aa552c1 100644 --- a/crates/pocket-pi-app-pack/tests/runtime.rs +++ b/crates/pocket-pi-app-pack/tests/runtime.rs @@ -5,7 +5,7 @@ use std::time::{Duration, Instant}; use pocket_pi_agentos::{ AppServiceHost, AppSupervisor, HttpRequest, NetFailure, RoutedToolHost, TransportCompletion, - ROOT_APP_ID, + APP_ACTION_TIMEOUT, ROOT_APP_ID, }; use pocket_pi_app_pack::catalog; use pocket_pi_embedded::{AgentEvent, ModelBackend, ToolHost, ToolResult}; @@ -20,14 +20,23 @@ impl AppServiceHost for Services { _service: &str, _operation: &str, _args: &Value, + _deadline: Instant, ) -> Result { Err("unexpected App service call".into()) } - fn http(&self, app_id: &str, request: HttpRequest) -> Result { + fn http( + &self, + app_id: &str, + request: HttpRequest, + deadline: Instant, + ) -> Result { assert_eq!(app_id, "exa"); assert_eq!(request.url, "https://api.exa.ai/search"); assert_eq!(request.method, "POST"); + let total_ms = APP_ACTION_TIMEOUT.as_millis() as u32; + assert!((1..=total_ms).contains(&request.timeout_ms)); + assert!(deadline.saturating_duration_since(Instant::now()) <= APP_ACTION_TIMEOUT); let body: Value = serde_json::from_slice(&request.body).unwrap(); assert_eq!(body["query"], "Pocket Pi architecture"); let response = serde_json::json!({ @@ -122,9 +131,9 @@ fn agent_routes_a_background_app_tool_through_http_and_sqlite() { let mut finished = false; while Instant::now() < deadline && !finished { while let Ok(request) = requests.try_recv() { - request.handle(&mut supervisor); + request.handle(&supervisor); } - for event in supervisor.frame().unwrap() { + for event in supervisor.frame_render(true).unwrap() { match event { AgentEvent::ResponseText(delta) => response.push_str(&delta), AgentEvent::Done => finished = true, @@ -138,9 +147,21 @@ fn agent_routes_a_background_app_tool_through_http_and_sqlite() { assert!(finished); assert_eq!(response, "research complete"); assert_eq!(supervisor.active_id(), "robinhood"); - let storage = supervisor.invoke_tool("research.storage_status", "{}"); - assert!(!storage.is_error, "{}", storage.text); - assert_eq!(storage.details["searches"], 1); + let mut database = + pocket_db::DbModule::new(pocket_db::Storage::Dir(temp.path().join("apps/exa/data"))); + let handle = database.open("exa"); + assert!(handle >= 0); + let query: Value = serde_json::from_str(&database.query( + handle, + "SELECT query,status,result_count FROM searches", + "[]", + )) + .unwrap(); + database.close(handle); + assert_eq!( + query["rows"], + serde_json::json!([["Pocket Pi architecture", "ok", 1]]) + ); supervisor.open(ROOT_APP_ID).unwrap(); assert_eq!(supervisor.active_id(), ROOT_APP_ID); } diff --git a/docs/agentos-architecture.md b/docs/agentos-architecture.md index c1b9387..7d1a14e 100644 --- a/docs/agentos-architecture.md +++ b/docs/agentos-architecture.md @@ -2,7 +2,7 @@ 状态:架构基线 + v1 实现记录(以“常驻 Pi Agent System App”为当前实现)。 -截至 2026-08-11,当前工作树已经实现可运行的第一版:Pi Agent Root App、App +截至 2026-08-12,当前工作树已经实现可运行的第一版:Pi Agent Root App、App Supervisor、App Tool Catalog/Router、`AppTask` Schedule、`data.fs`、 `data.sqlite`、后台 Data Action、revision-coalesced projection cache,以及 Robinhood 和 Exa 两个可选 App,以及 build-time App selection。 @@ -357,7 +357,6 @@ export default defineApp({ search_tools: { parameters: searchSchema, action: "searchTools" }, call: { parameters: deferredCallSchema, action: "validatedProviderCall" }, refresh_portfolio: { parameters: {}, action: "refreshPortfolio" }, - storage_status: { parameters: {}, action: "storageStatus" }, }, providerOperations: checkedInRobinhoodAllowlist, actions: { searchTools, validatedProviderCall, refreshPortfolio }, @@ -548,8 +547,7 @@ App Tools robinhood.search_tools robinhood.call robinhood.refresh_portfolio - robinhood.storage_status - research.search · research.fetch · research.storage_status + research.search · research.fetch ``` Workspace 动态自定义 Tools 不属于 v1。 @@ -573,7 +571,7 @@ Model 产生 Tool call App name -> App Supervisor.enqueue_data_action(app, tool, args) -> data-action.js -> native transport -> 仅在 Fixed View 消费结果时写 SQLite + app.commit() - -> completion registry 返回真实 ToolResult + -> Data Action worker 直接返回真实 ToolResult -> normalized ToolResult -> Model ``` @@ -581,10 +579,11 @@ Model 产生 Tool call Public Tool 参数先由 Agent Tool layer 按 `agent-app.json` schema 校验;Robinhood `robinhood.call` 的 deferred upstream schema 再由 Data Action 使用 `tool-catalog.json` 校验。Tool Router 只负责 ownership、namespaced routing 和 bounded -completion wait,不声称实现通用结果截断。会改变数据或调用 provider 的 App Tool -不在 View Guest 执行;纯只读的诊断 Tool(例如 `storage_status`)可以直接读取 -bounded SQLite projection。Agent 发起的 App Tool 等待 Data Action 的真实 completion; -UI Task 和 Schedule 只需要快速 enqueue receipt。 +completion wait,不声称实现通用结果截断。所有 App Tool 都进入 headless Data Action, +不在 View Guest 执行。Agent 发起的 App Tool 等待 Data Action 的真实 completion; +UI Task 和 Schedule 只需要快速 enqueue receipt。一次 Agent App Tool 从进入 Router +起只有一个 80 秒绝对 deadline;排队、Data Action、PocketJS `fetch()` 和 native MCP +共同消费剩余时间,不能各自维护另一套业务 timeout。 ## 12. Robinhood MCP 如何接入 @@ -607,8 +606,7 @@ Firmware 负责: App 负责: - checked in 54 个 upstream operation snapshot 与 allowlist; -- 只向 Agent 常驻暴露 `search_tools`、`call`、`refresh_portfolio`、`storage_status` - 四个小 Tool; +- 只向 Agent 常驻暴露 `search_tools`、`call`、`refresh_portfolio` 三个小 Tool; - 按需返回某个 upstream Tool 的描述与完整 JSON Schema,并在调用前本地校验; - 把本地 Tool/Task 映射到 MCP call; - normalize provider response; @@ -742,9 +740,9 @@ bounded projection,不能重读整个数据库。 - Robinhood 1D/1W chart 固定为 20 个 time buckets;一次 indexed SQLite query 恰好返回 20 行,View 只绘制这些 bucket 的 point projection; - migrations 必须创建必要索引; -- provider 的模型 stream 只在 transport/decoder 内部消费;Pi Agent 等完整结果 - 后只向 Root View 发一次文本更新,不能让每个 token 触发 JS event、layout 或 - flash write; +- provider 的模型 progress 在一次 host poll 内合并为至多一次 Guest delta,不能让 + 每个 token 触发 JS event、layout 或 flash write;当前 UART bridge 则进一步把 + provider chunks 合并为一个 final result; - schema version 和 migrations 由 App 管理。 ### 13.4 App 数据库保存业务事实,不保存原始 Tool payload @@ -792,6 +790,10 @@ Pi Agent 是拥有更宽 filesystem mount 的特殊 System App,负责: - Files、Runs/Schedules、Device Settings View; - `agent.sqlite` 中的 conversation、message、run、Tool call。 +这是 Root Runtime 的目标职责。当前 v1 已实现 Chat、Files、Apps、Settings 与 +Chat 内的 next AgentWake 摘要;独立 Runs/Schedules View 和 `agent.sqlite` 持久化仍 +以 22.2 的未实现状态为准。 + Agent Loop 由 System App release 中的 JavaScript `agent.js`(`pi-agent-core`) 提供,并与 `app.js` Root View eval 到同一个 PocketJS Guest。Rust 只提供 模型 transport、Native/App Tool 路由、调度和生命周期;它不拥有第二套 Agent @@ -854,7 +856,7 @@ Context Assembler 把选定 workspace files 组装成有严格上限的 Agent co | `data.fs` | confinement、quota、atomic replace | App files 和 config | | `net.http` | TLS、credential、policy allowlist、limits、non-blocking transport | `fetch()`、endpoint 选择和 domain decoding | | `mcp.client` | auth、session、framing、limits | safe operation mapping 和 domain semantics | -| `model.stream` | provider transport、内部 stream decode 和完整 result | Agent policy;thinking/text delta 在每次 host poll 合并后进入 Guest,Root View 只渲染正文 delta | +| `model.stream` | provider transport、可选的内部 stream decode 和完整 result | Agent policy;wireless progress 可在 host poll 合并后进入 Guest,当前 UART bridge 则把 provider chunks 合并为一个 final result | | `schedule.wake` | clock、persistence、claiming | AgentWake 或 AppTask declaration | | `shell.bounded` | allowlisted device/workspace operations | Agent 决定何时调用 | | `device.settings` | Wi-Fi、NVS、restart | Settings View | @@ -869,7 +871,8 @@ Native 层拥有稀缺资源、硬件和 secrets;Bundle 拥有产品行为。 ### 17.1 Root/Home -Pi Agent Root View 提供 Chat、Apps、Files、Runs/Schedules 和 Settings。它会 +Pi Agent Root View 当前提供 Chat、Apps、Files、Settings,以及 Chat 内的 next +AgentWake 摘要。独立 Runs/Schedules View 尚未实现。Root View 会 替代当前产品 UI 的 Rust `ScreenState`。产品 UI 不保留 legacy Rust 实现或 双轨 fallback;固件只负责渲染 PocketJS DrawList 和必要的底层硬件错误日志。 @@ -1029,8 +1032,8 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 合并成一次 `dataChanged`。普通 frame 与后台 App 不读 SQLite。 9. Robinhood Data Action 拥有 54 个 operation 的 checked-in deferred catalog、schema validation、MCP operation mapping、完整 response decode 和单次 refresh transaction; - Pi Agent 常驻只看到 `search_tools`、`call`、`refresh_portfolio`、`storage_status` - 四个 Tool。每个 provider 结果都返回 Agent,但只有 Fixed View 消费的数据才更新 + Pi Agent 常驻只看到 `search_tools`、`call`、`refresh_portfolio` 三个 Tool。每个 + provider 结果都返回 Agent,但只有 Fixed View 消费的数据才更新 domain table,不保存原始 Tool payload。View 只拥有 accounts/portfolio/positions/ activity/chart 的 bounded projection 和 cache。chart 的 1D/1W 窗口固定为 20 个 time buckets,SQLite query 最多返回 20 行,render 不读取 DB。 @@ -1039,11 +1042,11 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 `/contents` 并注入 API key。View 从 `searches` 先读取最新 10 条搜索历史,滚动 到边界后再按 10 条增量读取;每次 provider search 使用 Exa 标准的最多 10 条 结果,fetch 不落库。 -11. Root View 已提供 Chat、App 入口、Files、Runs/Schedules、Settings 摘要和 +11. Root View 已提供 Chat、App 入口、Files、Settings 与 next AgentWake 摘要和 屏幕键盘;Agent policy/loop 在 JS,workspace/App Tools 的受限底层实现和 AgentWake 由 Rust host 提供。Pocket Pi 的小型 shared Design System inventory 单独记录在 `docs/pocket-pi-design-system.md`;它只包含 PocketJS 上的基础 - typography/tokens/components,不包含 App-specific View 或 native UI logic。 + typography/recipes/components,不包含 App-specific View 或 native UI logic。 12. ESP32-P4 使用 4 KiB PSRAM launcher,待 ESP-IDF entry task 退出后创建 64 KiB internal AgentOS runtime stack;App bundle 构建后会 minify 以降低固件 footprint,但不会把 minify 当作 stack isolation。App Data pthread 使用 128 @@ -1051,8 +1054,8 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 worker;常驻 model worker 使用 64 KiB PSRAM stack。System App 的其他线程仍 使用恢复后的 platform default。 13. AgentOS 核心 contract tests 已证明:Agent turn 进行中打开 Robinhood,仍能收到完整回复 - 和 `agent_end`;前后台切换前后 System App Guest identity 不变;Exa 在前台 - 时 Agent 仍能路由 Robinhood App Tool、写 SQLite 并完成 turn。revision contract + 和 `agent_end`;普通 App 在前台时 Agent 仍能路由另一 App 的 Tool、写 SQLite + 并完成 turn。revision contract test 证明 3 次 commit 在下一前台 frame 只 reload 一次,5 个普通 frame 不 reload,后台 2 次 commit 在重新打开时只 reload 一次。 14. Simulator 的核心 Data Action tests 已证明:Exa search 用一次 transaction 写入 @@ -1064,9 +1067,10 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 16. 删除全部 legacy Rust UI 后的基线固件已刷入 ESP32-P4;实机从 System App release 的 `agent.js` 在 Root Guest 中启动 Agent,并经 UART Codex backend 完成 prompt 和 `agent_end`。当前 embedded presentation contract 已进一步改为: - provider 可以在 host/transport 内部 stream,但一次 model request 只给 Root View - 一个完整文本更新。实机长回复测试在 bridge 内部合并 409 个 provider chunks、 - 615 个字符后只发送一个 UART result;完成后继续观察 30 秒没有 task watchdog。 + provider 可以在 host/transport 内部 stream。wireless host 会在每次 poll 内合并 + progress;当前实机 UART presentation 则在 bridge 内部合并 409 个 provider + chunks、615 个字符后只发送一个 final result;完成后继续观察 30 秒没有 task + watchdog。 17. ESP32-P4 的 PocketJS View 已接入真实 PPA backend,矩形填充、A8 字形混合和 SRM 图像转换不再走全屏 CPU software fallback;每个 triple-buffer framebuffer 保留独立 incremental render state。实机启动日志已确认 @@ -1079,7 +1083,13 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 dirty 时才执行 UI `frame()`、更新 retained DrawList 和提交 panel render。 ESP32 owner 是原生 FreeRTOS task,主循环必须用 `vTaskDelay` 明确让出 CPU,不能用 pthread 语义的 `std::thread::sleep` 代替; - 否则即使总 CPU/内存数字不高,CPU0 idle task 仍可能无法喂 watchdog。 + 否则即使总 CPU/内存数字不高,CPU0 idle task 仍可能无法喂 watchdog。固件把 + FreeRTOS 固定为 100 Hz,因此 scheduler tick 周期是 10 ms;所有等待至少用 + `vTaskDelay(1)` 跨过一个调度点。App deadline 使用 monotonic `Instant` 计时, + 不改变 scheduler tick,也不创建亚 tick 轮询。MCP + `EAGAIN` 重试必须先让出一个 tick,并限制重复日志。ESP32 Router 不使用受 + wall-clock 校准影响的 pthread timed condition wait;它每 tick 检查一次 result + channel 和 monotonic deadline。 20. 当前自动化只保留 Tool catalog、安全边界、App state ownership、Data Action transaction、resident Agent lifecycle、Tool routing 和 revision coalescing 等核心 contract;不保留 UI 坐标、按压视觉状态或重复 smoke tests。对应实现已通过 @@ -1093,8 +1103,7 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 22. Exa schema v5 只保存固定 View 消费的 bounded search-history row:query、时间、 terminal status、result count、top title 和 error;provider 原始 JSON、其余结果 和 fetched document 都只返回 Agent,不进入 SQLite。每次 search transaction - 删除 7 天前的 searches;不自动执行 `VACUUM`。`research.storage_status` 只返回 - search count、allocated/reusable bytes、retention policy 和最近一次运行状态。 + 删除 7 天前的 searches;不自动执行 `VACUUM`。 23. 正式 `pocket-net` 路径曾在 schema v4 镜像的实体 ESP32-P4 上完成 Exa provider success、SQLite 持久化、重启恢复和 30 秒稳定性观察。schema v5 只收窄 App-owned projection,不改变已验证的 `/search`、`/contents` transport contract。 @@ -1103,10 +1112,12 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 saved authorization 时交互补录。未传该 flag 的实机 `get_accounts` 已完成 MCP initialize 与 provider HTTP 200,收到 7222-byte body,不再出现 `OAuth token not provided`。 -25. Agent 发起 App Tool 时,`RoutedToolHost` 通过 completion registry 等待真实 - Data Action 结果,不再把 queued receipt 当作模型结果。Exa 和 Robinhood 的 - provider payload 都只放进 ToolResult `text`;不再同时复制到 `details`。View 内 - 的小型 `storage_status` 诊断仍可使用结构化 `details`。 +25. Agent 发起 App Tool 时,`RoutedToolHost` 与 Data Action 共用从 Router 创建的 + 80 秒绝对 deadline;worker 直接把真实结果返回等待方,不再经过 Supervisor frame + 转发,也不把 queued receipt 当作模型结果。PocketJS HTTP 和 native + MCP 都只能使用剩余 budget,超时的 Data Action Guest 会被丢弃,避免 pending + Promise 在后续调用中恢复。Exa 和 Robinhood 的 provider payload 都只放进 + ToolResult `text`,不再同时复制到 `details`。 26. 最新实机链路已完成 Exa search → fetch → DeepSeek 最终总结;模型 worker 内复用 HTTPS client 后,该轮没有 TLS `-0x3000`、pthread 创建失败或重启。大 Tool Result 同步进入 QuickJS context 时仍出现 task-watchdog warning,所以持续无人值守稳定性 @@ -1136,9 +1147,6 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 - 通用 Data Action runner 已在当前实机验证 FreeRTOS pthread stack、断网 failure transaction、SQLite dump、network fail-fast 与 provider success;持续 触摸切换和成功/失败交替 retry 仍待验证。 -- Agent Tool completion 已实现,但当前 Router 的 bounded wait 为 45 秒;Exa transport - 自身允许 60 秒。两层 timeout 需要在后续统一,避免深度搜索仍在进行时 Agent 先收到 - Router timeout。 - v1 是一个 App-level revision。Robinhood 已将 DB read 限制在 initial/ `dataChanged` 和 account/span 的 bounded cache miss,但所有 projection cache 的 `loadedRevision` 仍需继续显式化,随后再用板上 query 计数确认交互路径为零重读。 diff --git a/docs/esp32-p4-port.md b/docs/esp32-p4-port.md index cf66cfd..02c62f4 100644 --- a/docs/esp32-p4-port.md +++ b/docs/esp32-p4-port.md @@ -68,7 +68,8 @@ physical-board test. The thin bridge CLI provisions the boot-time model choice and routes framed model decisions. Its `uart_bridge` adapters reuse a logged-in Codex Coding Plan through the persistent Codex app-server, or Claude Code through `stream-json`. -Both paths forward real text deltas instead of waiting for the whole reply. +Both paths consume provider deltas internally, then coalesce them into one +final `PPI-RPC-STREAM` result for the current device-side `UartBackend`. Wi-Fi can be selected later from the on-device Settings page. ```sh diff --git a/docs/pocket-pi-design-system.md b/docs/pocket-pi-design-system.md index 3f300af..0003c1b 100644 --- a/docs/pocket-pi-design-system.md +++ b/docs/pocket-pi-design-system.md @@ -11,10 +11,10 @@ PocketJS framework primitives,不能调用 ESP-IDF、Pocket Pi Rust 私有接 | Foundation | 包含 | 当前规则 | | --- | --- | --- | -| `type` | app title、page title、heading、label、body、caption | ESP 主阅读文本由 14/16px 提升到 16/18px;24px title 保持不变 | -| `space` | 24px screen gutter、card padding、stack gap | 720x1280 screen density | -| `surface` | card、selected card、row、muted、shell recipes | arbitrary children 的容器保持 literal View,不增加不稳定 wrapper | -| `Tone` | neutral、info、success、warning、danger | 统一背景色、文字色和状态语义 | +| type hierarchy | app title、page title、heading、label、body、caption | 只保留 shared components 实际消费的 class recipe;ESP 主阅读文本由 14/16px 提升到 16/18px,24px title 保持不变 | +| spacing | 24px screen gutter、card padding、stack gap | 直接写在当前 concrete component recipe 中,不导出无人消费的 token map | +| surfaces | card、selected card、row、muted、shell recipes | arbitrary children 的容器保持 literal View;当前没有单独的 unused surface registry | +| `statusBadge` | neutral、info、success、warning、danger | 统一背景色、文字色和状态语义;保留为当前 shared component recipe | | dynamic glyphs | curly quotes、en/em dash、ellipsis、bullet | 进入现有 Inter subset atlas | PocketJS 当前只提供 12 / 14 / 16 / 18 / 20 / 24 / 36px 的 baked font diff --git a/firmware/esp32-p4/Cargo.lock b/firmware/esp32-p4/Cargo.lock index 1792fb7..1dc5eee 100644 --- a/firmware/esp32-p4/Cargo.lock +++ b/firmware/esp32-p4/Cargo.lock @@ -1192,7 +1192,6 @@ version = "0.1.0" dependencies = [ "anyhow", "pocket-pi-agentos", - "serde_json", ] [[package]] diff --git a/firmware/esp32-p4/sdkconfig.defaults b/firmware/esp32-p4/sdkconfig.defaults index ab991d9..c578875 100644 --- a/firmware/esp32-p4/sdkconfig.defaults +++ b/firmware/esp32-p4/sdkconfig.defaults @@ -34,6 +34,15 @@ CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096 CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=4096 CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=4096 +# AgentOS deliberately yields one scheduler tick in its native loops. Pin the +# 10 ms tick period so vTaskDelay(1) keeps yielding across builds. +CONFIG_FREERTOS_HZ=100 +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=y +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y + # Expose per-task runtime counters so the status bar can report real average # CPU utilization across both ESP32-P4 cores. diff --git a/firmware/esp32-p4/src/agentos_main.rs b/firmware/esp32-p4/src/agentos_main.rs index 3e7bba2..6044f88 100644 --- a/firmware/esp32-p4/src/agentos_main.rs +++ b/firmware/esp32-p4/src/agentos_main.rs @@ -21,6 +21,9 @@ use super::{ BOARD_NAME, PANEL_HEIGHT, PANEL_WIDTH, }; +const AGENTOS_FREERTOS_HZ: u32 = 100; +const _: () = assert!(esp_idf_svc::sys::configTICK_RATE_HZ == AGENTOS_FREERTOS_HZ); + #[derive(Clone)] struct Message { role: &'static str, @@ -504,9 +507,9 @@ pub fn run() -> anyhow::Result<()> { ); last_heartbeat = Instant::now(); } - // AgentOS is a native FreeRTOS task, not a pthread. The firmware uses - // a 100 Hz tick, so one tick polls touch every 10 ms while still - // giving CPU0's idle task a watchdog-feeding scheduling window. + // AgentOS is a native FreeRTOS task, not a pthread. With a 100 Hz tick, + // delaying one tick keeps the loop at scheduler granularity and gives + // CPU0's idle task a watchdog-feeding scheduling opportunity. unsafe { esp_idf_svc::sys::vTaskDelay(1) }; } } diff --git a/firmware/esp32-p4/src/app_services.rs b/firmware/esp32-p4/src/app_services.rs index 85c0e58..88d6d37 100644 --- a/firmware/esp32-p4/src/app_services.rs +++ b/firmware/esp32-p4/src/app_services.rs @@ -17,8 +17,11 @@ use pocket_pi_agentos::{ }; use serde_json::{json, Value}; +use super::delay_current_task; + const MCP_PROTOCOL_VERSION: &str = "2025-06-18"; const MAX_MCP_RESPONSE: usize = 160 * 1024; +const MCP_RETRY_DELAY: Duration = Duration::from_millis(250); pub struct EspAppServices { inner: Arc, @@ -60,6 +63,7 @@ impl EspAppServicesInner { &self, app_id: &str, request: HttpRequest, + deadline: Instant, ) -> std::result::Result { let policy = self .catalog @@ -76,10 +80,15 @@ impl EspAppServicesInner { "App supplied a forbidden HTTP header", )); } - execute_http(request, policy.credential.as_ref(), &self.credentials) + execute_http( + request, + policy.credential.as_ref(), + &self.credentials, + deadline, + ) } - fn mcp_call(&self, app_id: &str, args: &Value) -> Result { + fn mcp_call(&self, app_id: &str, args: &Value, deadline: Instant) -> Result { let connection = args .get("connection") .and_then(Value::as_str) @@ -116,18 +125,25 @@ impl EspAppServicesInner { next_id: 1, }); for attempt in 0..2 { - let result = - self.mcp_once(&policy, &credential, state, operation, arguments, retryable); + let result = self.mcp_once( + &policy, + &credential, + state, + operation, + arguments, + retryable, + deadline, + ); match result { Ok(value) => return Ok(value), Err(error) if attempt == 0 && stale_mcp_session(&error) => { log::warn!("MCP reconnecting after: {error}"); state.session_id = None; - std::thread::sleep(Duration::from_millis(250)); + wait_to_retry(deadline)?; } Err(error) if attempt == 0 && retryable && transient_mcp_connect(&error) => { log::warn!("MCP transport retry after: {error}"); - std::thread::sleep(Duration::from_millis(250)); + wait_to_retry(deadline)?; } Err(error) => return Err(error), } @@ -135,7 +151,7 @@ impl EspAppServicesInner { unreachable!() } - fn mcp_calls(&self, app_id: &str, args: &Value) -> Result { + fn mcp_calls(&self, app_id: &str, args: &Value, deadline: Instant) -> Result { let connection = args .get("connection") .and_then(Value::as_str) @@ -175,17 +191,18 @@ impl EspAppServicesInner { next_id: 1, }); for attempt in 0..2 { - let result = self.mcp_batch_once(&policy, &credential, state, calls, retryable); + let result = + self.mcp_batch_once(&policy, &credential, state, calls, retryable, deadline); match result { Ok(value) => return Ok(value), Err(error) if attempt == 0 && stale_mcp_session(&error) => { log::warn!("MCP batch reconnecting after: {error}"); state.session_id = None; - std::thread::sleep(Duration::from_millis(250)); + wait_to_retry(deadline)?; } Err(error) if attempt == 0 && retryable && transient_mcp_connect(&error) => { log::warn!("MCP batch transport retry after: {error}"); - std::thread::sleep(Duration::from_millis(250)); + wait_to_retry(deadline)?; } Err(error) => return Err(error), } @@ -207,8 +224,9 @@ impl EspAppServicesInner { state: &mut McpState, calls: &[Value], retryable: bool, + deadline: Instant, ) -> Result { - self.ensure_mcp_session(policy, credential, state)?; + self.ensure_mcp_session(policy, credential, state, deadline)?; let mut requests = Vec::with_capacity(calls.len()); let mut request_ids = Vec::with_capacity(calls.len()); for call in calls { @@ -233,6 +251,7 @@ impl EspAppServicesInner { &requests, request_ids.len(), retryable, + deadline, )?; if returned_session.is_some() { state.session_id = returned_session; @@ -267,6 +286,7 @@ impl EspAppServicesInner { policy: &McpServicePolicy, credential: &str, state: &mut McpState, + deadline: Instant, ) -> Result<(), String> { if state.session_id.is_some() { return Ok(()); @@ -278,13 +298,20 @@ impl EspAppServicesInner { "params":{"protocolVersion":MCP_PROTOCOL_VERSION,"capabilities":{},"clientInfo":{"name":"pocket-pi-agentos","version":"0.1.0"}} }); state.next_id = state.next_id.saturating_add(1); - let (body, session) = post_mcp(policy, credential, None, &request, true)?; + let (body, session) = post_mcp(policy, credential, None, &request, true, deadline)?; if let Some(error) = body.get("error") { return Err(format!("MCP initialize failed: {error}")); } let session = session.ok_or_else(|| "MCP omitted session id".to_owned())?; let notification = json!({"jsonrpc":"2.0","method":"notifications/initialized"}); - let _ = post_mcp(policy, credential, Some(&session), ¬ification, true)?; + let _ = post_mcp( + policy, + credential, + Some(&session), + ¬ification, + true, + deadline, + )?; state.session_id = Some(session); log::info!("MCP session initialized"); Ok(()) @@ -298,10 +325,11 @@ impl EspAppServicesInner { operation: &str, args: &Value, retryable: bool, + deadline: Instant, ) -> Result { let operation_started = Instant::now(); log::info!("MCP {operation} started"); - self.ensure_mcp_session(policy, credential, state)?; + self.ensure_mcp_session(policy, credential, state, deadline)?; let request = json!({ "jsonrpc":"2.0", "id":state.next_id, @@ -315,6 +343,7 @@ impl EspAppServicesInner { state.session_id.as_deref(), &request, retryable, + deadline, )?; if returned_session.is_some() { state.session_id = returned_session; @@ -335,13 +364,14 @@ impl AppServiceHost for EspAppServices { service: &str, operation: &str, args: &Value, + deadline: Instant, ) -> Result { if !self.inner.network_ready.load(Ordering::Acquire) { return Err("Network is not connected; App data was not changed".to_owned()); } match (service, operation) { - ("mcp.client", "callTool") => self.inner.mcp_call(app_id, args), - ("mcp.client", "callTools") => self.inner.mcp_calls(app_id, args), + ("mcp.client", "callTool") => self.inner.mcp_call(app_id, args, deadline), + ("mcp.client", "callTools") => self.inner.mcp_calls(app_id, args, deadline), _ => Err(format!("App {app_id} cannot access service {service}")), } } @@ -350,11 +380,12 @@ impl AppServiceHost for EspAppServices { &self, app_id: &str, request: HttpRequest, + deadline: Instant, ) -> std::result::Result { if !self.inner.network_ready.load(Ordering::Acquire) { return Err(NetFailure::new("unavailable", "network is not connected")); } - self.inner.http(app_id, request) + self.inner.http(app_id, request, deadline) } } @@ -382,10 +413,28 @@ fn transient_mcp_connect(error: &str) -> bool { error.contains("ESP_ERR_HTTP_CONNECT") } +fn remaining(deadline: Instant) -> Result { + deadline + .checked_duration_since(Instant::now()) + .filter(|duration| !duration.is_zero()) + .ok_or_else(|| "App Data Action deadline expired".to_owned()) +} + +fn yield_current_task() { + unsafe { esp_idf_svc::sys::vTaskDelay(1) }; +} + +fn wait_to_retry(deadline: Instant) -> Result<(), String> { + let delay = remaining(deadline)?.min(MCP_RETRY_DELAY); + delay_current_task(delay); + remaining(deadline).map(|_| ()) +} + fn execute_http( meta: HttpRequest, credential: Option<&CredentialBinding>, credentials: &BTreeMap, + deadline: Instant, ) -> std::result::Result { let length = meta.body.len().to_string(); let mut values = meta.headers; @@ -408,8 +457,7 @@ fn execute_http( .iter() .map(|(name, value)| (name.as_str(), value.as_str())) .collect::>(); - let mut client = - client(Duration::from_millis(u64::from(meta.timeout_ms))).map_err(net_failure)?; + let mut client = client(remaining(deadline).map_err(net_failure)?).map_err(net_failure)?; let mut request = client .request(http_method(&meta.method)?, &meta.url, &headers) .map_err(|error| net_failure(format!("create HTTPS request: {error}")))?; @@ -427,7 +475,8 @@ fn execute_http( let expected_length = response .header("content-length") .and_then(|value| value.parse::().ok()); - let body = read_bounded(&mut response, meta.max_bytes, expected_length).map_err(net_failure)?; + let body = read_bounded(&mut response, meta.max_bytes, expected_length, deadline) + .map_err(net_failure)?; let mut response_headers = BTreeMap::new(); if let Some(content_type) = content_type { response_headers.insert("content-type".to_owned(), content_type); @@ -478,6 +527,7 @@ fn submit_mcp( payload: &str, request_label: &str, retryable: bool, + deadline: Instant, ) -> Result, String> { let length = payload.len().to_string(); for attempt in 0..2 { @@ -491,7 +541,7 @@ fn submit_mcp( if let Some(session) = session { headers.push(("mcp-session-id", session)); } - let mut connection = connection(Duration::from_secs(12))?; + let mut connection = connection(remaining(deadline)?)?; connection .initiate_request(Method::Post, &policy.url, &headers) .map_err(|error| format!("create MCP request: {error:?}"))?; @@ -521,6 +571,7 @@ fn submit_mcp( "MCP {request_label} received no response headers in {}ms; reconnecting once", started.elapsed().as_millis() ); + wait_to_retry(deadline)?; } Err(error) => { return Err(format!("send MCP request: {error:?}")); @@ -536,6 +587,7 @@ fn post_mcp( session: Option<&str>, body: &Value, retryable: bool, + deadline: Instant, ) -> Result<(Value, Option), String> { let request_label = body .get("params") @@ -551,6 +603,7 @@ fn post_mcp( &payload, request_label, retryable, + deadline, )?; let status = response.status(); let returned_session = response.header("Mcp-Session-Id").map(str::to_owned); @@ -564,12 +617,12 @@ fn post_mcp( } let body_started = Instant::now(); let bytes = if is_event_stream { - read_sse_event(&mut response, MAX_MCP_RESPONSE)? + read_sse_event(&mut response, MAX_MCP_RESPONSE, deadline)? } else { let expected_length = response .header("content-length") .and_then(|value| value.parse::().ok()); - read_bounded(&mut response, MAX_MCP_RESPONSE, expected_length)? + read_bounded(&mut response, MAX_MCP_RESPONSE, expected_length, deadline)? }; log::info!( "MCP HTTP {request_label} body bytes={} in {}ms", @@ -593,21 +646,35 @@ fn post_mcp_batch( bodies: &[Value], expected_responses: usize, retryable: bool, + deadline: Instant, ) -> Result<(Vec, Option), String> { let payload = serde_json::to_string(bodies).map_err(|error| format!("encode MCP batch: {error}"))?; - let mut response = submit_mcp(policy, credential, session, &payload, "batch", retryable)?; + let mut response = submit_mcp( + policy, + credential, + session, + &payload, + "batch", + retryable, + deadline, + )?; let status = response.status(); let returned_session = response.header("Mcp-Session-Id").map(str::to_owned); if !(200..300).contains(&status) { - let bytes = read_bounded(&mut response, MAX_MCP_RESPONSE, None)?; + let bytes = read_bounded(&mut response, MAX_MCP_RESPONSE, None, deadline)?; return Err(format!( "MCP batch HTTP {status}: {}", String::from_utf8_lossy(&bytes) )); } let body_started = Instant::now(); - let responses = read_sse_values(&mut response, MAX_MCP_RESPONSE, expected_responses)?; + let responses = read_sse_values( + &mut response, + MAX_MCP_RESPONSE, + expected_responses, + deadline, + )?; log::info!( "MCP HTTP batch responses={} in {}ms", responses.len(), @@ -620,6 +687,7 @@ fn read_bounded( reader: &mut impl embedded_svc::io::Read, limit: usize, expected_length: Option, + deadline: Instant, ) -> Result, String> { if expected_length.is_some_and(|length| length > limit) { return Err(format!("HTTPS response exceeded {limit} bytes")); @@ -627,6 +695,7 @@ fn read_bounded( let mut out = Vec::with_capacity(8 * 1024); let mut chunk = [0u8; 2048]; loop { + remaining(deadline)?; let count = reader .read(&mut chunk) .map_err(|error| format!("read HTTPS response: {error:?}"))?; @@ -655,6 +724,7 @@ fn read_bounded( fn read_sse_event( reader: &mut impl embedded_svc::io::Read, limit: usize, + deadline: Instant, ) -> Result, String> { let mut out = Vec::with_capacity(8 * 1024); // Stop after the first complete SSE event because the server keeps this @@ -663,6 +733,7 @@ fn read_sse_event( // already available from esp_http_client in bounded chunks instead. let mut chunk = [0u8; 512]; loop { + remaining(deadline)?; let count = reader .read(&mut chunk) .map_err(|error| format!("read MCP SSE response: {error:?}"))?; @@ -681,7 +752,12 @@ fn read_sse_event( Ok(out) } -fn read_sse_values(reader: &mut R, limit: usize, expected: usize) -> Result, String> +fn read_sse_values( + reader: &mut R, + limit: usize, + expected: usize, + deadline: Instant, +) -> Result, String> where R: embedded_svc::io::Read, { @@ -689,18 +765,23 @@ where let mut consumed = 0; let mut values = Vec::with_capacity(expected); let mut chunk = [0u8; 2048]; - let deadline = Instant::now() + Duration::from_secs(120); + let mut waiting_logged = false; while values.len() < expected { + remaining(deadline)?; let count = match reader.read(&mut chunk) { Ok(count) => count, Err(error) if error.0.code() == -esp_idf_svc::sys::ESP_ERR_HTTP_EAGAIN && Instant::now() < deadline => { - log::info!( - "MCP batch waiting for SSE responses ({}/{expected})", - values.len() - ); + if !waiting_logged { + log::info!( + "MCP batch waiting for SSE responses ({}/{expected})", + values.len() + ); + waiting_logged = true; + } + yield_current_task(); continue; } Err(error) if error.0.code() == -esp_idf_svc::sys::ESP_ERR_HTTP_EAGAIN => { diff --git a/firmware/esp32-p4/src/main.rs b/firmware/esp32-p4/src/main.rs index 64ab1e1..19bf735 100644 --- a/firmware/esp32-p4/src/main.rs +++ b/firmware/esp32-p4/src/main.rs @@ -28,6 +28,13 @@ const WIFI_NVS_PASSWORD_KEY: &str = "wifi_pass"; const AGENTOS_LAUNCHER_STACK_BYTES: u32 = 4 * 1024; const AGENTOS_TASK_STACK_BYTES: u32 = 64 * 1024; +fn delay_current_task(delay: Duration) { + let ticks = esp_idf_svc::hal::delay::TickType::from(delay) + .ticks() + .max(1); + unsafe { esp_idf_svc::sys::vTaskDelay(ticks) }; +} + fn main() -> anyhow::Result<()> { esp_idf_svc::sys::link_patches(); esp_idf_svc::log::EspLogger::initialize_default(); @@ -56,7 +63,7 @@ unsafe extern "C" fn agentos_launcher_task(_argument: *mut core::ffi::c_void) { // Let ESP-IDF delete its entry task first. That releases enough contiguous // internal RAM for the large runtime stack required by QuickJS. The tiny // launcher itself lives in PSRAM and never performs flash I/O. - esp_idf_svc::sys::vTaskDelay(10); + delay_current_task(Duration::from_millis(100)); let mut task = core::ptr::null_mut(); let result = esp_idf_svc::sys::xTaskCreatePinnedToCoreWithCaps( Some(agentos_task), @@ -77,7 +84,7 @@ unsafe extern "C" fn agentos_launcher_task(_argument: *mut core::ffi::c_void) { log::error!("could not create AgentOS runtime task (result={result})"); } loop { - esp_idf_svc::sys::vTaskDelay(1000); + delay_current_task(Duration::from_secs(10)); } } @@ -86,7 +93,7 @@ unsafe extern "C" fn agentos_task(_argument: *mut core::ffi::c_void) { log::error!("AgentOS runtime stopped: {error:#}"); } loop { - esp_idf_svc::sys::vTaskDelay(1000); + delay_current_task(Duration::from_secs(10)); } } @@ -128,7 +135,7 @@ impl PlatformTools for EspPlatform { .name("delayed-reboot".to_owned()) .stack_size(4 * 1024) .spawn(|| { - std::thread::sleep(Duration::from_millis(750)); + delay_current_task(Duration::from_millis(750)); unsafe { esp_idf_svc::sys::esp_restart() } }) .map_err(|error| format!("schedule reboot: {error}"))?; @@ -152,7 +159,7 @@ fn init_wifi( if Instant::now() >= deadline { anyhow::bail!("C6 Wi-Fi driver did not stop before lwIP attach") } - std::thread::sleep(Duration::from_millis(25)); + delay_current_task(Duration::from_millis(25)); } let sta_netif = EspNetif::new(NetifStack::Sta)?; esp_result("esp_netif_attach_wifi_station", unsafe { @@ -228,7 +235,7 @@ impl WifiConnection { // driver's connecting state even though is_connected() is false. // Clear that state before every explicit attempt or retry. let _ = self.driver.disconnect(); - std::thread::sleep(Duration::from_millis(50)); + delay_current_task(Duration::from_millis(50)); } self.driver .set_configuration(&Configuration::Client(ClientConfiguration { diff --git a/firmware/esp32-p4/src/transport/uart.rs b/firmware/esp32-p4/src/transport/uart.rs index 1b380fa..f98d6d6 100644 --- a/firmware/esp32-p4/src/transport/uart.rs +++ b/firmware/esp32-p4/src/transport/uart.rs @@ -70,8 +70,6 @@ impl LineTransport for UartLineTransport { } else { frame.clear(); } - } else { - std::thread::sleep(Duration::from_millis(1)); } } Err(format!("timed out waiting for {prefix}")) diff --git a/hosts/esp32-p4-sim/src/main.rs b/hosts/esp32-p4-sim/src/main.rs index 9188d50..ad47380 100644 --- a/hosts/esp32-p4-sim/src/main.rs +++ b/hosts/esp32-p4-sim/src/main.rs @@ -175,7 +175,11 @@ impl AppServiceHost for SimAppServices { service: &str, operation: &str, args: &Value, + deadline: Instant, ) -> Result { + if Instant::now() >= deadline { + return Err("App Data Action deadline expired".into()); + } let tool_name = args.get("name").and_then(Value::as_str).unwrap_or(""); let tool_args = args.get("arguments").unwrap_or(&Value::Null); if app_id == "robinhood" @@ -196,7 +200,7 @@ impl AppServiceHost for SimAppServices { "name":name, "arguments":call.get("arguments").unwrap_or(&Value::Null) }); - match self.call(app_id, service, "callTool", &single) { + match self.call(app_id, service, "callTool", &single, deadline) { Ok(value) => json!({"name":name,"ok":true,"value":value}), Err(error) => json!({"name":name,"ok":false,"error":error}), } @@ -267,7 +271,14 @@ impl AppServiceHost for SimAppServices { &self, app_id: &str, request: HttpRequest, + deadline: Instant, ) -> std::result::Result { + if Instant::now() >= deadline { + return Err(NetFailure::new( + "timeout", + "App Data Action deadline expired", + )); + } if app_id != "exa" || request.method != "POST" { return Err(NetFailure::new( "invalid_request", @@ -474,7 +485,7 @@ impl Product { fn poll(&mut self) -> Result<()> { while let Ok(request) = self.app_rx.try_recv() { - request.handle(&mut self.supervisor); + request.handle(&self.supervisor); self.projection_dirty = true; } if self.last_schedule_poll.elapsed() >= Duration::from_secs(1) { @@ -819,6 +830,7 @@ impl ApplicationHandler for WindowApp { #[cfg(test)] mod tests { use super::*; + use pocket_pi_embedded::ToolResult; fn init_logs() { let _ = env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")) @@ -835,12 +847,47 @@ mod tests { service: &str, operation: &str, _args: &Value, + _deadline: Instant, ) -> Result { let _ = (service, operation); Err("simulated Robinhood outage".into()) } } + struct NoTools; + + impl ToolHost for NoTools { + fn definitions(&self) -> Vec { + Vec::new() + } + + fn execute(&self, _call_id: &str, name: &str, _args_json: &str) -> ToolResult { + ToolResult { + text: format!("unexpected Tool {name}"), + is_error: true, + ..ToolResult::default() + } + } + } + + fn route_tool(supervisor: &mut AppSupervisor, name: &str, args_json: &str) -> ToolResult { + let (tools, requests) = + RoutedToolHost::new(Arc::new(NoTools), supervisor.catalog().clone()); + let name = name.to_owned(); + let args_json = args_json.to_owned(); + let call = std::thread::spawn(move || tools.execute("test", &name, &args_json)); + let deadline = Instant::now() + Duration::from_secs(5); + while !call.is_finished() { + while let Ok(request) = requests.try_recv() { + request.handle(supervisor); + } + supervisor.frame_render(true).unwrap(); + assert!(Instant::now() < deadline, "timed out routing App Tool"); + std::thread::sleep(Duration::from_millis(2)); + } + call.join().unwrap() + } + fn wait_for(mut ready: impl FnMut() -> bool) { for _ in 0..100 { if ready() { @@ -851,33 +898,57 @@ mod tests { panic!("timed out waiting for background App Data Action"); } + fn try_query_app_database( + workspace: &Path, + app_id: &str, + database_name: &str, + sql: &str, + ) -> Option> { + let mut database = pocket_db::DbModule::new(pocket_db::Storage::Dir( + workspace.join("apps").join(app_id).join("data"), + )); + let handle = database.open(database_name); + if handle < 0 { + return None; + } + let value: Value = serde_json::from_str(&database.query(handle, sql, "[]")).ok()?; + database.close(handle); + if value.get("error").is_some() { + return None; + } + value["rows"].as_array().cloned() + } + + fn query_app_database( + workspace: &Path, + app_id: &str, + database_name: &str, + sql: &str, + ) -> Vec { + try_query_app_database(workspace, app_id, database_name, sql) + .unwrap_or_else(|| panic!("query {app_id}/{database_name}: {sql}")) + } + #[test] fn exa_tool_writes_app_owned_sqlite() { init_logs(); let temp = tempfile::tempdir().unwrap(); let mut supervisor = AppSupervisor::new(temp.path(), catalog().unwrap(), Arc::new(SimAppServices)).unwrap(); - let result = supervisor.invoke_tool( + let result = route_tool( + &mut supervisor, "research.search", r#"{"query":"NVIDIA FY2026 annual report 10-K revenue data center guidance","numResults":5,"includeDomains":["investor.nvidia.com","sec.gov"]}"#, ); assert!(!result.is_error, "{}", result.text); - assert_eq!(result.details["status"], "queued"); - wait_for(|| { - let storage = supervisor.invoke_tool("research.storage_status", "{}"); - storage.details["searches"] == 1 - }); assert!(temp.path().join("apps/exa/data/exa.sqlite").exists()); - let storage = supervisor.invoke_tool("research.storage_status", "{}"); - assert!(!storage.is_error, "{}", storage.text); - assert_eq!(storage.details["searches"], 1); - assert_eq!(storage.details["retentionDays"], 7); - assert_eq!(storage.details["schemaVersion"], 5); - assert_eq!(storage.details["expectedSchemaVersion"], 5); - assert_eq!(storage.details["latestSearch"]["status"], "ok"); - assert!(storage.text.len() < 240, "{}", storage.text); - assert!(storage.details.get("tables").is_none()); - assert!(storage.details.get("latestSearches").is_none()); + let rows = query_app_database( + temp.path(), + "exa", + "exa", + "SELECT status,result_count FROM searches ORDER BY id DESC LIMIT 1", + ); + assert_eq!(rows, vec![json!(["ok", 2])]); } #[test] @@ -886,14 +957,12 @@ mod tests { let temp = tempfile::tempdir().unwrap(); let mut supervisor = AppSupervisor::new(temp.path(), catalog().unwrap(), Arc::new(SimAppServices)).unwrap(); - let first = supervisor.invoke_tool("research.search", r#"{"query":"expired search"}"#); + let first = route_tool( + &mut supervisor, + "research.search", + r#"{"query":"expired search"}"#, + ); assert!(!first.is_error, "{}", first.text); - wait_for(|| { - supervisor - .invoke_tool("research.storage_status", "{}") - .details["searches"] - == 1 - }); let mut database = pocket_db::DbModule::new(pocket_db::Storage::Dir(temp.path().join("apps/exa/data"))); @@ -907,16 +976,19 @@ mod tests { ); database.close(handle); - let second = supervisor.invoke_tool("research.search", r#"{"query":"new search"}"#); + let second = route_tool( + &mut supervisor, + "research.search", + r#"{"query":"new search"}"#, + ); assert!(!second.is_error, "{}", second.text); - wait_for(|| { - supervisor - .invoke_tool("research.storage_status", "{}") - .details["latestSearch"]["id"] - == 2 - }); - let storage = supervisor.invoke_tool("research.storage_status", "{}"); - assert_eq!(storage.details["searches"], 1); + let rows = query_app_database( + temp.path(), + "exa", + "exa", + "SELECT id,query FROM searches ORDER BY id", + ); + assert_eq!(rows, vec![json!([2, "new search"])]); } #[test] @@ -931,24 +1003,23 @@ mod tests { let failed = supervisor.invoke_active_task("refreshPortfolio", &Value::Null); assert!(!failed.is_error); wait_for(|| { - let storage = supervisor.invoke_tool("robinhood.storage_status", "{}"); - storage.details["latestRefreshes"] - .as_array() - .and_then(|rows| rows.first()) - .is_some_and(|row| row["status"] == "failed") + try_query_app_database( + temp.path(), + "robinhood", + "robinhood", + "SELECT status FROM refresh_runs ORDER BY id DESC LIMIT 1", + ) + .is_some_and(|rows| rows.first() == Some(&json!(["failed"]))) }); - supervisor.frame().unwrap(); + supervisor.frame_render(true).unwrap(); - let storage = supervisor.invoke_tool("robinhood.storage_status", "{}"); - assert!(!storage.is_error, "{}", storage.text); - assert_eq!(storage.details["latestRefreshes"][0]["status"], "failed"); - let values = storage.details["tables"] - .as_array() - .unwrap() - .iter() - .find(|table| table["name"] == "total_value") - .unwrap(); - assert_eq!(values["rowCount"], 0); + let rows = query_app_database( + temp.path(), + "robinhood", + "robinhood", + "SELECT COUNT(*) FROM total_value", + ); + assert_eq!(rows, vec![json!([0])]); } #[test] @@ -958,48 +1029,23 @@ mod tests { let mut supervisor = AppSupervisor::new(temp.path(), catalog().unwrap(), Arc::new(SimAppServices)).unwrap(); supervisor.open("robinhood").unwrap(); - let refreshed = supervisor.invoke_tool("robinhood.refresh_portfolio", "{}"); + let refreshed = route_tool(&mut supervisor, "robinhood.refresh_portfolio", "{}"); assert!(!refreshed.is_error, "{}", refreshed.text); - wait_for(|| { - let storage = supervisor.invoke_tool("robinhood.storage_status", "{}"); - storage.details["latestRefreshes"] - .as_array() - .and_then(|rows| rows.first()) - .is_some_and(|row| row["status"] == "succeeded") - }); - supervisor.frame().unwrap(); + supervisor.frame_render(true).unwrap(); - let storage = supervisor.invoke_tool("robinhood.storage_status", "{}"); - assert!(!storage.is_error, "{}", storage.text); - assert_eq!( - storage.details["latestRefreshes"].as_array().unwrap().len(), - 1 - ); - assert_eq!(storage.details["latestRefreshes"][0]["status"], "succeeded"); - assert_eq!(storage.details["latestRefreshes"][0]["operation_count"], 16); - assert_eq!(storage.details["latestRefreshes"][0]["success_count"], 16); - let tables = storage.details["tables"].as_array().unwrap(); - assert!(tables.iter().all(|table| table["name"] != "tool_events")); - assert_eq!( - tables - .iter() - .find(|table| table["name"] == "accounts") - .unwrap()["rowCount"], - 3 - ); - assert_eq!( - tables - .iter() - .find(|table| table["name"] == "portfolio_current") - .unwrap()["rowCount"], - 3 + let rows = query_app_database( + temp.path(), + "robinhood", + "robinhood", + "SELECT status,operation_count,success_count FROM refresh_runs ORDER BY id DESC LIMIT 1", ); - assert_eq!( - tables - .iter() - .find(|table| table["name"] == "total_value") - .unwrap()["rowCount"], - 3 + assert_eq!(rows, vec![json!(["succeeded", 16, 16])]); + let rows = query_app_database( + temp.path(), + "robinhood", + "robinhood", + "SELECT (SELECT COUNT(*) FROM accounts),(SELECT COUNT(*) FROM portfolio_current),(SELECT COUNT(*) FROM total_value)", ); + assert_eq!(rows, vec![json!([3, 3, 3])]); } } From 64f951ea426d5d89a7077e24439072c3e4f43a8d Mon Sep 17 00:00:00 2001 From: Jerry Yuan Date: Wed, 12 Aug 2026 22:31:26 +0800 Subject: [PATCH 24/24] docs: define Pocket Pi as a device runtime --- ARCHITECTURE.md | 30 +++++-- README.md | 155 +++++++++++++++++++---------------- docs/agentos-architecture.md | 46 +++++++---- docs/esp32-p4-port.md | 24 ++++-- 4 files changed, 150 insertions(+), 105 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 7b49251..ce5fffc 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -1,11 +1,21 @@ # Pocket Pi architecture -Pocket Pi is one embedded AgentOS runtime with two hosts: +Pocket Pi is a complete Agent-native runtime for embedded and dedicated +devices. The Agent is a resident system actor with a persistent workspace, +native capabilities, schedules and Agent-native Apps—not a desktop application +or a generic Agent SDK. -| Run mode | Host | Agent profile | +The current implementation has one supported hardware target and one companion +development tool: + +| Role | Composition | Status | | --- | --- | --- | -| ESP32 simulator | `hosts/esp32-p4-sim` | embedded `pi-agent-core` System App | -| ESP32-P4 | `firmware/esp32-p4` | embedded `pi-agent-core` System App | +| Reference hardware | `firmware/esp32-p4` | ESP32-P4 is the first fully supported Pocket Pi target | +| Development simulator | `hosts/esp32-p4-sim` | Runs the ESP32-P4 product contracts on macOS; not a desktop product or hardware target | + +Both compositions use the same resident `pi-agent-core` System App and PocketJS +App bundles. The simulator substitutes development adapters; only the physical +composition proves hardware behavior. The authoritative detailed design is [`docs/agentos-architecture.md`](docs/agentos-architecture.md). @@ -27,7 +37,8 @@ The authoritative detailed design is - `crates/pocket-pi-protocols` owns model/provider transport protocols. - Hosts own hardware, transport, credentials, and rendering adapters. -There is no legacy Rust product UI. Simulator and ESP32 render the same +There is no legacy Rust product UI or general-purpose desktop runtime. The +simulator and ESP32-P4 render the same PocketJS App bundles at a 720x1280 logical viewport. Rust firmware supplies the display/touch driver and renders the selected App's DrawList. @@ -51,8 +62,8 @@ crates/pocket-pi-app-pack/ build-selected embedded App composition crates/pocket-pi-embedded/ embedded pi-agent-core bridge and host traits crates/pocket-pi-tools/ native workspace/shell/time/schedule Tools crates/pocket-pi-protocols/ provider codecs -hosts/esp32-p4-sim/ embedded AgentOS simulator -firmware/esp32-p4/ ESP-IDF hardware composition root +hosts/esp32-p4-sim/ macOS development simulator for ESP32-P4 contracts +firmware/esp32-p4/ first supported target and reference implementation tools/uart_bridge/ Mac Codex/Claude streaming adapters tools/uart-model-bridge.py UART framing and provisioning CLI ``` @@ -68,4 +79,7 @@ cargo xtask snapshot esp32-p4-sim ``` Simulator proof, firmware compilation, and physical-board proof are separate -evidence tiers. Physical ESP32-P4 remains the final hardware acceptance target. +evidence tiers. ESP32-P4 is the current reference hardware and physical-board +proof remains its final acceptance tier. Future device targets must provide +their own native composition and physical validation without moving product +logic into firmware. diff --git a/README.md b/README.md index 6f02536..801e39a 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,63 @@ # Pocket Pi -Pocket Pi runs the [Pi coding agent](https://github.com/badlogic/pi-mono) in -QuickJS. Its touch UI is built with -[PocketJS](https://github.com/pocket-stack/pocketjs) for the ESP32-P4 product. - -This repository contains one embedded Agent profile with two supported run modes: - -| Run mode | Agent profile | What it is for | -|---|---|---| -| ESP32 simulator on macOS | Embedded `pi-agent-core` | Fast development of the ESP32 product UI, tools and Agent flows | -| Physical ESP32-P4 | Embedded `pi-agent-core` | The real standalone [PocketJS](https://github.com/pocket-stack/pocketjs)/QuickJS device | - -The simulator and firmware compile the same embedded Agent, device UI, tool -contracts and interaction state. Only their platform adapters differ. - -> **Project status:** the ESP32 simulator and physical Waveshare ESP32-P4 target -> have working end-to-end paths. The embedded port is still board-specific and -> under active development; see +Pocket Pi is a complete Agent-native runtime for embedded and dedicated +devices. It makes the Agent a resident system actor instead of a user-launched +application on a general-purpose desktop or mobile OS. One device runtime +combines a persistent Pi Agent, local `/workspace`, native tools, schedules, +Agent-native Apps, local SQLite state and a PocketJS UI. + +Pocket Pi builds on: + +- [`pi-agent-core`](https://github.com/badlogic/pi-mono) for the Agent Loop and + Tool Call harness; +- [PocketJS](https://github.com/pocket-stack/pocketjs) and QuickJS for embedded + Apps and device UI; +- native target hosts for storage, credentials, networking, rendering, device + capabilities and lifecycle. + +**ESP32-P4 is the first fully supported hardware target and the current +reference implementation.** The macOS ESP32-P4 simulator is a development and +product-contract testing tool; it is not a desktop Pocket Pi product or a +second hardware target. + +> **Project status:** the Waveshare ESP32-P4 target has working end-to-end +> Agent, workspace, schedule, App, display/touch and provider paths. The first +> target remains board-specific and under active development; see > [Current validation](#current-validation) for the exact evidence and limits. -## One product profile, two hosts - -The embedded profile runs upstream `pi-agent-core` in QuickJS and implements Pi -tools as small native Rust capabilities. The simulator is a product-contract -host for fast development; the physical ESP32-P4 is the final product host. +## One complete device runtime -The architecture keeps the Pi Harness design in both hosts: +The current runtime runs upstream `pi-agent-core` in QuickJS and implements Pi +tools as bounded native capabilities. Its architecture preserves the Pi Harness +contracts while adding the device-level responsibilities Pocket Pi owns: - the model decides when to call a tool; - tools have explicit schemas and return structured results; - the Agent loop is separate from model transports and platform APIs; -- workspaces and schedules are capabilities, not UI or prompt special cases. +- workspace and schedules are durable device capabilities; +- Apps combine Agent-facing Tools, local state, autonomous Tasks and a fixed + human-facing View; +- the native host owns credentials, transport, hardware and lifecycle. -The macOS simulator is a product-contract simulator, not an ESP32 CPU or -peripheral emulator. It gives the embedded Agent the same UI, tool registry and -workspace rules while replacing LCD, touch, storage and networking with macOS -adapters. Physical hardware remains the final acceptance target. +The companion simulator runs the same AgentOS, PocketJS App bundles, UI, Tool +registry and workspace contracts while replacing hardware adapters with macOS +implementations. It is not an ESP32 CPU/peripheral emulator, and simulator +success never replaces physical-device acceptance. ## Quick start ### Prerequisites -- Rust stable for the simulator; +- Rust stable for the development simulator; - Bun for rebuilding the embedded JavaScript guest; - a logged-in `codex` CLI for the simulator's local Codex backend; - the esp-rs/ESP-IDF toolchain, `nightly-2026-05-01`, and `espflash` for the - physical ESP32-P4 target. + supported ESP32-P4 target. The current firmware target is the **Waveshare ESP32-P4-WIFI6-Touch-LCD-5**. -### Build both modes +### Build the device and development simulator ```sh cargo xtask build agentos-apps @@ -68,43 +75,11 @@ cargo xtask build esp32-p4 --apps exa cargo xtask build esp32-p4 --apps none ``` -### 1. ESP32 Pocket Pi simulator on macOS - -The simulator defaults to the Mac's existing Codex Coding Plan login: - -```sh -cargo xtask run esp32-p4-sim \ - --backend codex \ - --workspace target/esp32-workspace -``` - -Direct API-key backends are also available: - -```sh -OPENAI_API_KEY=... \ - cargo xtask run esp32-p4-sim --backend openai --model gpt-5.6 - -OPENROUTER_API_KEY=... \ - cargo xtask run esp32-p4-sim \ - --backend openrouter --model openai/gpt-5.6 - -ANTHROPIC_API_KEY=... \ - cargo xtask run esp32-p4-sim \ - --backend anthropic --model claude-sonnet-4-6 - -DEEPSEEK_API_KEY=... DEEPSEEK_THINKING_LEVEL=xhigh \ - cargo xtask run esp32-p4-sim --backend deepseek -``` - -The window uses the ESP32's 720x1280 coordinate system. Mouse input is mapped -through the same hit-testing code as physical touch input. Generate a -deterministic UI snapshot with: - -```sh -cargo xtask snapshot esp32-p4-sim -``` +`--apps none` builds the smallest Pocket Pi device image: the resident Pi Agent, +workspace, native tools, schedules and Root View without ordinary Apps. It is +not a generic `pi-agent-core` SDK or desktop harness. -### 2. Physical Pocket Pi on ESP32-P4 +### 1. Pocket Pi on ESP32-P4 Build and flash the release firmware: @@ -156,6 +131,42 @@ from Keychain and injects its access token into the board's RAM-only boot configuration. `--provision-robinhood` is only the interactive fallback when no saved authorization exists. +### 2. Develop with the ESP32-P4 simulator on macOS + +The simulator defaults to the Mac's existing Codex Coding Plan login: + +```sh +cargo xtask run esp32-p4-sim \ + --backend codex \ + --workspace target/esp32-workspace +``` + +Direct API-key backends are also available: + +```sh +OPENAI_API_KEY=... \ + cargo xtask run esp32-p4-sim --backend openai --model gpt-5.6 + +OPENROUTER_API_KEY=... \ + cargo xtask run esp32-p4-sim \ + --backend openrouter --model openai/gpt-5.6 + +ANTHROPIC_API_KEY=... \ + cargo xtask run esp32-p4-sim \ + --backend anthropic --model claude-sonnet-4-6 + +DEEPSEEK_API_KEY=... DEEPSEEK_THINKING_LEVEL=xhigh \ + cargo xtask run esp32-p4-sim --backend deepseek +``` + +The window uses the ESP32-P4 product's 720x1280 coordinate system. Mouse input +is mapped through the same hit-testing code as physical touch input. Generate a +deterministic UI snapshot with: + +```sh +cargo xtask snapshot esp32-p4-sim +``` + ## Model backends Backends belong to their host composition, not to the Agent core: @@ -213,13 +224,13 @@ credentials, transport and hardware adapters. ## Repository map ```text -crates/pocket-pi-embedded/ embedded pi-agent-core guest and host traits +crates/pocket-pi-embedded/ bounded Agent Loop bridge used by device runtimes crates/pocket-pi-tools/ portable workspace, shell, time and schedule tools crates/pocket-pi-protocols/ model request, response and streaming codecs crates/pocket-pi-agentos/ App Supervisor, System App lifecycle and App contracts crates/pocket-pi-app-pack/ build-selected embedded App composition -hosts/esp32-p4-sim/ macOS adapters for the embedded product -firmware/esp32-p4/ ESP-IDF hardware composition root and adapters +hosts/esp32-p4-sim/ macOS development simulator for ESP32-P4 contracts +firmware/esp32-p4/ first supported device and reference implementation tools/uart_bridge/ Mac Codex and Claude Code streaming adapters tools/uart-model-bridge.py UART framing and provisioning CLI ``` @@ -257,10 +268,12 @@ require physical-board acceptance. ## Non-goals +- providing a macOS/Windows/Linux desktop Pocket Pi product; +- providing a generic `pi-agent-core` SDK or standalone harness; - Emulating the ESP32 CPU or peripherals on macOS; - exposing arbitrary desktop shell or Node APIs on the microcontroller; - coupling model providers, UI, trading services or research services into Pi - Harness core; + Agent Loop core; - claiming that an API codec compile proves a live provider connection. ## License diff --git a/docs/agentos-architecture.md b/docs/agentos-architecture.md index 7d1a14e..fde9324 100644 --- a/docs/agentos-architecture.md +++ b/docs/agentos-architecture.md @@ -1,5 +1,15 @@ # Pocket Pi AgentOS 架构设计 +Pocket Pi 是面向嵌入式设备和专用设备的完整 Agent-native runtime。Agent 是设备 +上的常驻 system actor,而不是运行在通用桌面或移动操作系统上的用户应用;设备的 +workspace、native tools、schedules、Agent-native Apps、本地状态、UI 和生命周期共同 +构成 Pocket Pi。 + +ESP32-P4 是第一台完整支持的硬件和当前 reference implementation。macOS 上的 +`esp32-p4-sim` 只用于开发和 product-contract 验证,不是 Pocket Pi 桌面产品、通用 +`pi-agent-core` SDK 或第二个硬件 target。本文件定义的是完整设备 runtime 的 +AgentOS/App 语义,不定义 standalone Agent harness。 + 状态:架构基线 + v1 实现记录(以“常驻 Pi Agent System App”为当前实现)。 截至 2026-08-12,当前工作树已经实现可运行的第一版:Pi Agent Root App、App @@ -16,10 +26,10 @@ Registry 启动和一次完整 UART model turn。运行中切换普通 App 的 ## 1. 一句话结论 -Pocket Pi 是一套面向 Agent 的本地 App Runtime:Rust 固件提供稳定的硬件和 -能力层;Pi Agent 拥有顶层 `/workspace`;每个 App 是一个预编译 PocketJS -Bundle,里面包含暴露给 Agent 的 Tools、内部 Tasks、Schedules、SQLite -数据和绑定这些数据的固定 View。 +Pocket Pi 是一套设备级 Agent-native Runtime:Rust/native host 提供稳定的硬件、 +安全和生命周期机制;Pi Agent 作为常驻 System App 拥有顶层 `/workspace`;每个 App +是一个预编译 PocketJS Bundle,里面包含暴露给 Agent 的 Tools、内部 Tasks、 +Schedules、SQLite 数据和绑定这些数据的固定 View。 最短的理解方式是: @@ -64,8 +74,8 @@ catalog、Agent Tool ownership 或后台任务生命周期。如果其中某个 ## 2. 设计目标 -1. 完整保留当前 Pocket Pi 的 Agent、模型、workspace、schedule、设备和 - Settings 能力。 +1. 在嵌入式和专用设备上提供完整常驻 Agent runtime,而不是构建通用桌面 Agent、 + Node compatibility layer 或 standalone `pi-agent-core` SDK。 2. Robinhood、Exa 等产品逻辑和 UI 不再进入通用 Rust 固件。 3. App 可以给 Pi Agent 暴露 Tools,但不需要暴露内部表结构、凭据、网络协议 和 UI 实现。 @@ -909,14 +919,14 @@ Guest 中运行,但 Root View 暂不产生前台 DrawList。用户仍可操作 新增而不是现有的能力包括:App Supervisor、App Catalog、App Tools、AppTask Schedules、revision-coalesced projection cache 和 Bundle-based Views。 -## 19. Host profiles 与跨硬件 +## 19. 设备 Target、开发 Simulator 与跨硬件 -Pocket Pi 保留一个 embedded Agent profile,由两个 Host 实现: +Pocket Pi 当前有一个完整支持的硬件 composition,以及一个配套开发 simulator: -| Host | Agent profile | 额外能力 | +| 角色 | Composition | 说明 | | --- | --- | --- | -| ESP32 simulator | embedded `pi-agent-core` | 用 macOS adapter 实现相同 embedded contracts | -| ESP32-P4 | embedded `pi-agent-core` | LittleFS、touch/LCD、Wi-Fi/NVS 和嵌入式 limits | +| Reference hardware | ESP32-P4 firmware | 第一台完整支持的设备;实现 LittleFS、touch/LCD、Wi-Fi/NVS 和嵌入式 limits | +| Development tool | ESP32-P4 simulator | 用 macOS adapter 验证相同 product contracts;不是桌面产品或硬件 target | ### 19.1 “一次适配,不同硬件跑”的准确含义 @@ -956,7 +966,8 @@ filesystem、network 和 credential 实现。 3. App 原生暴露语义化 Tools 给 Agent。 4. App 同时提供人类可见的 View。 5. 本地 Schedule 让系统能自主工作,不需要模型参与每个循环。 -6. Host 统一管理 capabilities、credentials、lifecycle 和 hardware。 +6. Native target composition 统一管理 capabilities、credentials、lifecycle 和 + hardware。 7. Tools、Tasks、State 和 View 可以作为 App 单元演进,不改 firmware。 8. Agent 的执行生命周期独立于当前前台 View,用户和 Agent 可以并行操作同一 套 App platform。 @@ -964,9 +975,10 @@ filesystem、network 和 credential 实现。 但它不是传统通用 OS:它不提供任意进程、多用户安全、POSIX 兼容或通用 desktop。准确说法应当是: -> Pocket Pi 是一套 embedded AgentOS runtime:Agent 拥有 workspace;本地 -> App 通过 Agent Tools、durable state、autonomous Tasks 和 human View 同时 -> 服务 Agent 与用户。 +> Pocket Pi 是一套面向嵌入式和专用设备的完整 Agent-native runtime:Agent 作为 +> 常驻 system actor 拥有 workspace;本地 App 通过 Agent Tools、durable state、 +> autonomous Tasks 和 human View 同时服务 Agent 与用户。ESP32-P4 是它的第一台 +> 完整支持硬件。 这比“Agent UI”更准确,也比“替代传统操作系统”更克制。 @@ -1130,8 +1142,8 @@ isolation 和 lifecycle。App Bundle 拥有名称、schema、provider mapping、 - release 已有 descriptor/`pocket.json` 校验和 atomic `current` 写入,但由 PocketJS resolver 生成并校验真实 `plan.json`、完整 artifact hash、migration transaction、上一版本回退和独立 recovery UI 还没有完成。 -- 当前跨硬件实证是 ESP32 simulator + physical ESP32-P4;simulator 证明共享 - product contract,最终硬件验收仍以实体设备为准。 +- 当前唯一完整支持的硬件 target 是 physical ESP32-P4;配套 simulator 只证明共享 + product contract,不能计作第二个硬件实现,最终验收仍以实体设备为准。 - build-selected catalog 的普通 App View 现在全部在 Supervisor 启动时 preload;真实 ESP32-P4 启动时长已量测,但持续切换仍需人工验收。后续如果 catalog 扩大,再依据实测在 PocketJS runtime 层设计加载策略,不能先引入 Marketplace、 diff --git a/docs/esp32-p4-port.md b/docs/esp32-p4-port.md index 02c62f4..cd89887 100644 --- a/docs/esp32-p4-port.md +++ b/docs/esp32-p4-port.md @@ -1,17 +1,23 @@ -# ESP32-P4 host +# ESP32-P4 reference target -Pocket Pi has one embedded agent profile and two hosts: +ESP32-P4 is Pocket Pi's first fully supported hardware target and current +reference implementation. It demonstrates the complete device runtime: +resident Pi Agent, `/workspace`, native tools, schedules, Agent-native Apps, +local state, PocketJS UI and native device lifecycle. -| Target | Agent profile | Runs on | +The repository also provides one companion development composition: + +| Role | Implementation | Runs on | |---|---|---| -| `esp32-p4` | bounded `pi-agent-core` | ESP32-P4 | -| `esp32-p4-sim` | bounded `pi-agent-core` | macOS | +| Supported hardware target | `firmware/esp32-p4` | ESP32-P4 | +| Product-contract simulator | `hosts/esp32-p4-sim` | macOS development host | The physical host and simulator use the same PocketJS App bundles and `pocket-pi-agentos` supervisor at a 720x1280 logical viewport. Simulator mouse clicks and physical touch coordinates are both dispatched to the selected App View. The Pi Agent Root View displays Chat, Apps, Files and Settings; there is -no parallel Rust product UI. +no parallel Rust product UI. The simulator is not a desktop Pocket Pi product, +a generic Agent harness or a second supported target. The physical host selects `UartBackend` for a Mac Codex/Claude Code bridge or `WirelessBackend` for direct OpenAI/OpenRouter/Anthropic/DeepSeek HTTPS. These remain @@ -51,15 +57,15 @@ cargo xtask run esp32-p4-sim --backend codex \ --workspace target/esp32-workspace ``` -The Mac simulator and physical firmware register the same core tool contracts: +The development simulator and physical firmware register the same core tool contracts: `read/write/edit/find/grep/ls`, bounded `bash`, `device.status`, `time.now`, `workspace.context`, and the four `schedule.*` operations. The Pi runtime obtains these definitions directly from the executable tool registry, so advertised and executable tools cannot drift. -The simulator is a contract-level product simulator, not a CPU or peripheral +The simulator is a contract-level development tool, not a CPU or peripheral emulator. It must exercise the embedded Agent, tools, workspace, schedules and -plugin contracts, but may use simpler macOS adapters. ESP-IDF, PSRAM, PPA, +App contracts, but may use simpler macOS adapters. ESP-IDF, PSRAM, PPA, LittleFS capacity, MIPI-DSI, touch-controller and Wi-Fi/NVS behavior require a physical-board test.