pi-straw-boss 0.61.0 → 0.62.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/NOTICE.md +10 -0
  2. package/README.md +3 -1
  3. package/README.zh-TW.md +2 -0
  4. package/dist/gui/assets/allyasks-CpVBhFoD.js +2 -0
  5. package/dist/gui/assets/{allyunits-Bh_tEPaq.js → allyunits-DD2qpiHU.js} +2 -2
  6. package/dist/gui/assets/{answer-BqAjR42Q.js → answer-CNS536Ni.js} +1 -1
  7. package/dist/gui/assets/{ask-DZ8GOgV1.js → ask-PWjAd6ec.js} +1 -1
  8. package/dist/gui/assets/{asks-ZIM0AEBV.js → asks-iqMQ860g.js} +1 -1
  9. package/dist/gui/assets/boot-BCyyZKXB.js +53 -0
  10. package/dist/gui/assets/chat-DTBz2CQi.js +2 -0
  11. package/dist/gui/assets/drawer-DG5paePE.js +1 -0
  12. package/dist/gui/assets/index-BVjKruBA.css +1 -0
  13. package/dist/gui/assets/index-D4RgSZfB.js +4 -0
  14. package/dist/gui/assets/layer-DVPGsH7V.js +1 -0
  15. package/dist/gui/assets/{lightbox-CCKT7aoR.js → lightbox-VOqxxDbY.js} +1 -1
  16. package/dist/gui/assets/link-DGdcOgpH.js +1 -0
  17. package/dist/gui/assets/linkdialogs-por8my_6.js +1 -0
  18. package/dist/gui/assets/markdown-Dz6BWlns.js +6 -0
  19. package/dist/gui/assets/{pair-DFrMdpe9.js → pair-DPvATSSP.js} +3 -3
  20. package/dist/gui/assets/{picker-CmwHymCS.js → picker-D3vYdb8l.js} +1 -1
  21. package/dist/gui/assets/{server-D4UMq7Jn.js → server-DyNZCrwO.js} +2 -2
  22. package/dist/gui/assets/sessionfacts-D89ym3Po.js +1 -0
  23. package/dist/gui/assets/{settings-D7aX5zbf.js → settings-VBvE_h2i.js} +2 -2
  24. package/dist/gui/assets/spawn-859EnLDj.js +1 -0
  25. package/dist/gui/assets/termcard-BBfFRJdj.js +6 -0
  26. package/dist/gui/assets/{towermodel-DJLQh2fz.js → towermodel-CAbNR8ZT.js} +1 -1
  27. package/dist/gui/assets/{towerturns-CYO3ciQ8.js → towerturns-BsduFBNn.js} +1 -1
  28. package/dist/gui/assets/{trust-DikBv6hp.js → trust-SYAGOsew.js} +1 -1
  29. package/dist/gui/assets/unit_count-BE8Ap1BH.js +1 -0
  30. package/dist/gui/assets/views-C99M0mjj.js +2 -0
  31. package/dist/gui/assets/waitcard-xzYkyiRK.js +1 -0
  32. package/dist/gui/index.html +10 -5
  33. package/dist/gui/themes/geek/favicon-geek-NbvktVwy.svg +1 -0
  34. package/dist/gui/themes/geek/geek-0-3t8eQn.js +1 -0
  35. package/dist/gui/themes/geek/geek-BrKDj_sO.css +1 -0
  36. package/dist/gui/themes/raven/ask-CKjyJvC0.mp3 +0 -0
  37. package/dist/gui/themes/raven/backdrop-DxjCTy-q.webp +0 -0
  38. package/dist/gui/themes/raven/done-DhgK-iW_.mp3 +0 -0
  39. package/dist/gui/themes/raven/error-BaITyHHK.mp3 +0 -0
  40. package/dist/gui/themes/raven/favicon-raven-OQEWezoq.svg +1 -0
  41. package/dist/gui/themes/raven/perch-BrZYsIjo.webp +0 -0
  42. package/dist/gui/themes/raven/raven-BMjXXgdA.js +12 -0
  43. package/dist/gui/themes/raven/raven-UuXWXN6q.css +1 -0
  44. package/dist/gui/themes/zen/favicon-zen-Drb9eAC0.svg +1 -0
  45. package/dist/gui/themes/zen/zen-Bteg9WFH.css +1 -0
  46. package/dist/gui/themes/zen/zen-pqCdNAph.js +2 -0
  47. package/dist/gui/themes.json +17 -0
  48. package/dist/server/{chunk-DST2WCCT.mjs → chunk-MJTINL47.mjs} +911 -175
  49. package/dist/server/cli.mjs +1125 -58
  50. package/dist/server/main.mjs +8257 -4627
  51. package/package.json +1 -1
  52. package/prompts/head-run.md +2 -2
  53. package/prompts/main.md +1 -0
  54. package/prompts/tower-run.md +2 -2
  55. package/prompts/tower.md +1 -1
  56. package/src/agent/sidecar.ts +2 -1
  57. package/src/ask.ts +1 -1
  58. package/src/bindings.ts +65 -0
  59. package/src/board.ts +4 -3
  60. package/src/boardauto.ts +2 -2
  61. package/src/boardfill.ts +4 -3
  62. package/src/boardread.ts +3 -3
  63. package/src/boss.ts +3 -3
  64. package/src/bosslink.ts +44 -5
  65. package/src/bossviews.ts +11 -0
  66. package/src/bridge.ts +7 -6
  67. package/src/briefing.ts +2 -1
  68. package/src/closemain.ts +2 -1
  69. package/src/closer.ts +4 -0
  70. package/src/control.ts +99 -34
  71. package/src/dashboard.ts +2 -2
  72. package/src/dialogs.ts +2 -2
  73. package/src/election.ts +3 -0
  74. package/src/foreground.ts +10 -0
  75. package/src/guard.ts +4 -2
  76. package/src/gui.ts +65 -28
  77. package/src/guithemes.ts +28 -0
  78. package/src/handover.ts +2 -1
  79. package/src/headcmd.ts +4 -4
  80. package/src/header.ts +10 -6
  81. package/src/herdr.ts +1 -1
  82. package/src/host.ts +2 -2
  83. package/src/hygiene.ts +30 -5
  84. package/src/keys.ts +44 -11
  85. package/src/link/crypto.ts +46 -0
  86. package/src/link/holder.ts +340 -38
  87. package/src/link/kinds.ts +90 -15
  88. package/src/link/operate.ts +407 -0
  89. package/src/link/policy.ts +130 -5
  90. package/src/link/relay.ts +14 -0
  91. package/src/link/service.ts +40 -3
  92. package/src/link/sse.ts +28 -1
  93. package/src/membership.ts +5 -0
  94. package/src/memorycmd.ts +45 -6
  95. package/src/memorytool.ts +12 -2
  96. package/src/net.ts +39 -8
  97. package/src/nethead.ts +10 -8
  98. package/src/opener.ts +72 -17
  99. package/src/operateroutes.ts +129 -0
  100. package/src/operateseam.ts +209 -0
  101. package/src/operateslice.ts +32 -0
  102. package/src/order.ts +2 -2
  103. package/src/presence.ts +9 -4
  104. package/src/probe.ts +65 -7
  105. package/src/reach.ts +7 -6
  106. package/src/roles.ts +15 -6
  107. package/src/runhead.ts +5 -1
  108. package/src/runmode.ts +2 -2
  109. package/src/server/cli.ts +20 -2
  110. package/src/server/guihost.ts +12 -4
  111. package/src/server/guiprefs.ts +3 -3
  112. package/src/server/headasks.ts +83 -6
  113. package/src/server/headbrief.ts +9 -3
  114. package/src/server/headnet.ts +51 -19
  115. package/src/server/headside.ts +5 -2
  116. package/src/server/headtools.ts +9 -3
  117. package/src/server/main.ts +48 -12
  118. package/src/server/opentower.ts +35 -7
  119. package/src/server/operatebox.ts +513 -0
  120. package/src/server/operateguard.ts +110 -0
  121. package/src/server/operatehost.ts +646 -0
  122. package/src/server/operateledger.ts +204 -0
  123. package/src/server/operateoff.ts +59 -0
  124. package/src/server/operateroles.ts +3 -0
  125. package/src/server/operatesanitize.ts +289 -0
  126. package/src/server/operatescope.ts +167 -0
  127. package/src/server/operatewire.ts +138 -0
  128. package/src/server/procs.ts +5 -5
  129. package/src/server/procsops.ts +1 -1
  130. package/src/server/runs.ts +23 -4
  131. package/src/server/runtools.ts +7 -1
  132. package/src/server/towerbrief.ts +35 -12
  133. package/src/server/towermemory.ts +90 -10
  134. package/src/server/towers.ts +36 -11
  135. package/src/server/towerstore.ts +2 -0
  136. package/src/server/traincmds.ts +199 -0
  137. package/src/server/traingate.ts +473 -0
  138. package/src/server/trainlock.ts +226 -0
  139. package/src/server/waitcard.ts +223 -0
  140. package/src/server/waitpress.ts +173 -0
  141. package/src/session.ts +38 -4
  142. package/src/spawn.ts +4 -1
  143. package/src/stash.ts +7 -1
  144. package/src/state.ts +7 -3
  145. package/src/tools.ts +12 -6
  146. package/src/train/accept.ts +277 -0
  147. package/src/train/board.ts +404 -0
  148. package/src/train/cars.ts +179 -0
  149. package/src/train/spec.ts +367 -0
  150. package/src/train/waits.ts +102 -0
  151. package/src/trainrole.ts +75 -0
  152. package/src/upload.ts +15 -7
  153. package/src/views.ts +14 -0
  154. package/src/waitbudget.ts +29 -0
  155. package/src/watch.ts +9 -5
  156. package/dist/gui/assets/allyasks-BN7ncpWb.js +0 -2
  157. package/dist/gui/assets/chat-BSorjsse.js +0 -2
  158. package/dist/gui/assets/drawer-DFn5FHxd.js +0 -1
  159. package/dist/gui/assets/index-DjdUAEow.css +0 -1
  160. package/dist/gui/assets/index-Pr0dJgxC.js +0 -3
  161. package/dist/gui/assets/layer-C8Ns_rzf.js +0 -1
  162. package/dist/gui/assets/link-ncQm2fkP.js +0 -1
  163. package/dist/gui/assets/linkdialogs-ZGa6BuDm.js +0 -1
  164. package/dist/gui/assets/markdown-Bk5NWfKQ.js +0 -6
  165. package/dist/gui/assets/sessionfacts-CMRQ4qU6.js +0 -1
  166. package/dist/gui/assets/spawn-B5QVXpp1.js +0 -1
  167. package/dist/gui/assets/termcard-CRZebaAl.js +0 -6
  168. package/dist/gui/assets/unit_count-CJMBHDBg.js +0 -1
  169. package/dist/gui/assets/views-5AetTmVk.js +0 -2
  170. package/dist/gui/assets/waitpanel-BPE99fTH.js +0 -1
  171. package/dist/gui/assets/zenchunk-CLalxZKN.js +0 -2
  172. package/dist/gui/assets/zenchunk-EDuPI-9_.css +0 -1
  173. /package/dist/gui/{assets → themes/zen}/audiobus-D2ARHGet.js +0 -0
  174. /package/dist/gui/{assets → themes/zen}/zenmusic-5XvJwQvP.js +0 -0
package/NOTICE.md CHANGED
@@ -64,3 +64,13 @@ Straw Link's safety words are drawn from the BIP-39 English word list (2048 word
64
64
  ## Zen view lines
65
65
 
66
66
  The short lines under the Zen view's idle circle (`gui/zenlines.ts`) are one sentence or less each, shown with their source. Their sources, with the book, page, or chapter of each, are named in the comment above every entry: Thich Nhat Hanh, *Peace Is Every Step* (Bantam, 1991; 橡實文化 for the Chinese); Tara Brach and Mindful.org (mindful.org); Sharon Salzberg (sharonsalzberg.com); 華人正念減壓中心 (mindfulness.com.tw); 陳德中 and 台灣正念工坊 (Firstory); Zen Mind, Beginner's Mind by Shunryu Suzuki (Weatherhill, 1970); and the Japanese works whose originals are shown in small type under a line: Matsuo Bashō (おくのほそ道, haiku), Yosa Buson and Kobayashi Issa (haiku), Kamo no Chōmei (方丈記), Yoshida Kenkō (徒然草), Sei Shōnagon (枕草子), the waka of Fujiwara no Teika (新古今和歌集), Ki no Tomonori (古今和歌集), Yamabe no Akahito (万葉集), and Dōgen (傘松道詠), 利休百首 (Urasenke's text), Ii Naosuke (茶湯一会集), Tanizaki Jun'ichirō (陰翳礼讃), Masaoka Shiki and Natsume Sōseki (haiku), and Taneda Santōka (草木塔); the texts of Aozora Bunko, Wikisource, the Nara Manyo Culture Museum database, and Urasenke are named in the comments. A Chinese line marked `zh: our translation`, and an English line marked `en: our translation`, are ours.
67
+
68
+ ## Raven Keep view (`gui/themes/raven/`)
69
+
70
+ The Raven Keep (鴉閣) view's art is original to this project. Its ten role icons and its crest favicon were drawn as an ink-engraving sheet with an image generator (Codex image generation) and traced to single-colour SVG with [potrace](https://potrace.sourceforge.net/) (`sprite.svg`, `favicon.svg`); the backdrop illustration (`backdrop.webp`) was made with the same generator and resized; so was the perched raven (`perch.webp`, one strip of two frames, profile and head turned: the head of the second frame is blended onto the body of the first). The Zen ensō and Geek `>_` tab icons (`gui/themes/zen/favicon.svg`, `gui/themes/geek/favicon.svg`) are drawn for this project. Nothing in them is copied from a published setting.
71
+
72
+ Its three sounds are released under Creative Commons Zero (CC0 1.0), trimmed and converted to mono MP3 (`sounds/`):
73
+
74
+ - `ask.mp3`, a crow's caw: "crow caw" by zeroisnotnull, https://opengameart.org/content/crow-caw
75
+ - `done.mp3`, one church-bell strike, trimmed to 1.5 s with a fade: "Church bell" by kgeshev, https://freesound.org/people/kgeshev/sounds/378799/
76
+ - `error.mp3`, an old wooden door creaking: "An old wooden door creaking" by soundofsong, https://freesound.org/people/soundofsong/sounds/647646/
package/README.md CHANGED
@@ -28,6 +28,8 @@ English | [繁體中文](https://github.com/wayne930242/pi-straw-boss/blob/main/
28
28
 
29
29
  <p align="center"><img src="docs/gui-zen-wait.png" width="49%" alt="The Zen view with a tower's wait for you: the tower and its base as the title, the question, an answer box with a reply typed under a thin line, and Send, Dismiss, and Maybe later"> <img src="docs/gui-wait-answer.png" width="49%" alt="The Standard view's dialog for a tower's wait: the question, the answer box with a reply typed, Send, the link to the tower's comms, Later, and Dismiss"></p>
30
30
 
31
+ A tower's wait for you is a card, not a line of text: what happened, what you do, where (a link to open, or a command to copy; sb never runs one), what happens after, and which session raised it, with the buttons that fit (I'm done, a choice's options, or the steps of a secret entered in the terminal), a **Skip** that takes two taps and tells the tower and the session, and a reply box. The demo's `?waits=cards` shows each kind.
32
+
31
33
  <p align="center"><img src="docs/gui-zen-history.png" width="49%" alt="The Zen view with an item's Context open: the unit's session log inside the card, above the question's choices, which stay answerable"> <img src="docs/gui-zen-palette.png" width="49%" alt="The Zen view's command palette (⌘K) open over the companion session, with the quiet strip of working and idle units above"></p>
32
34
 
33
35
  <p align="center"><img src="docs/gui-zen-music.png" width="49%" alt="The Zen view with a music folder: the ♪ switch and the open track list in the corner"></p>
@@ -152,7 +154,7 @@ The tower only routes and coordinates, so it can run a lighter model: set `tower
152
154
  | `/boss gui`, `/boss gui stop`, `/boss gui rotate` | Open the net in the browser (any session, joins nothing); stop its GUI, from any session. The GUI is served by the sb server, one per machine, so it does not depend on which pi session runs: `/boss gui` starts the server when none runs and prints the URL, and a server that went down comes back when any pi session starts or looks (or from `cli.mjs up`). The URL carries a random token that is kept across a restart, an upgrade, a crash, a reboot, and a `/boss gui stop` followed by `/boss gui` (on the same port, in `gui-secrets.json`), so a page left open reconnects by itself and a phone stays paired. A new token comes only from `/boss gui rotate` (after a confirm; it unpairs every phone and opens the new address), a missing or corrupt `gui-secrets.json`, or a port that was taken at the next start: the old address then answers 403 and a phone scans the QR code again. Keeping the token has a cost you chose: another account on this machine that binds the port during a crash or restart gap sees what an open page sends; rotate after a gap you do not trust. With `STRAW_BOSS_DESK=1` (a desk shell shows the page itself) it opens no browser and the page leaves out Phone & devices and Stash. Only `/boss gui stop` keeps the GUI stopped, until the next `/boss gui` or `cli.mjs up`; `/boss stash` and `/boss close all` do not start a stopped GUI. The settings page's Server section (this computer's page only) shows the server's state, restarts it, and shows its log. Type into a session from its comms view, or work its terminal with the key pad under the terminal tile, or on a desktop by clicking into it and typing; answer a waiting `robot_hand` selector, `ask_user_question` questionnaire, or pi-code hook confirmation there or in its alert (so can any extension's `select` and `confirm`, also from a paired device; other dialogs show read-only, to answer in the terminal; `secret_drop` always takes its secret in the terminal, never on a page, local or over the tailnet, because pi-intercom identities are self-reported). Documents a session shows with [pi-herdr-doc-review](https://www.npmjs.com/package/pi-herdr-doc-review) 0.4.0 or newer open beside its comms: HTML in a sandboxed frame whose form answers the agent, text read-only. |
153
155
  | `/boss gui devices`, `/boss gui unpair <id\|all>` | List the paired phones (id, label, Tailscale or Wi-Fi, when paired and last seen) and unpair one (an id or the start of one) or all of them (after a confirm). The address does not change; `/boss gui rotate` is the one that gives a new address. |
154
156
  | `/boss gui lan`, `/boss gui lan off`, `/boss gui lan reset` | Reach the GUI from a phone on the same Wi-Fi, without Tailscale. It is off until you turn it on. This computer makes its own certificate, after showing you the risk: anyone who copies its key from this computer could pose to your phones as private-network sites (your router's page, a NAS) until you remove it from each phone. So use it on your phone's hotspot, or on a Wi-Fi that connects the phone directly to this computer. Each phone installs the certificate once (AirDrop or Quick Share it from the computer, and check it as the screen says), then pairs by QR code or typed code, and you allow each new phone on the computer by typing the number it shows. [How it works](docs/how-it-works.md#browser-view). |
155
- | `/boss gui view`, `/boss gui view auto\|standard\|geek\|zen` | Show or set the GUI's default view. A device on Auto (the page's default) shows it; a device that chose Standard or Geek in its settings keeps its choice, and with the default on `auto` a device follows its screen's contrast setting. Open pages switch at once, and a new page paints it on its first frame (the Geek view, the Zen view, and the settings page are pictured at the top). Only this command sets it: no page, paired phone included, can. Showing it (no value) only reads: it starts no server, so one stopped on purpose stays down. |
157
+ | `/boss gui view`, `/boss gui view auto\|standard\|geek\|zen\|raven` | Show or set the GUI's default view. A device on Auto (the page's default) shows it; a device that chose Standard or Geek in its settings keeps its choice, and with the default on `auto` a device follows its screen's contrast setting. Open pages switch at once, and a new page paints it on its first frame (the Geek view, the Zen view, and the settings page are pictured at the top). Only this command sets it: no page, paired phone included, can. Showing it (no value) only reads: it starts no server, so one stopped on purpose stays down. |
156
158
  | `/boss gui remote`, `/boss gui remote off` | Reach the GUI from your phone over your tailnet (`tailscale serve`, never Funnel): pair by QR code (or, in an installed app, by the short code shown beside it), and a phone stays paired (90 days from its last use, `remote off` included) until you unpair it in the settings page's Phone & devices section or the GUI gets a new token (a pairing belongs to the token, which a restart keeps; `/boss gui rotate`, a lost `gui-secrets.json`, or a taken port makes a new one and the old pairings are cleared); remote access stays on across a restart or a new server until `remote off`, and a paired phone keeps working after a restart; after a new token a phone pairs again: in the browser by scanning the QR code, in an installed app by typing the pairing code (see below); off removes only its own serve entry. The serve entry points at a second loopback listener of the sb server's GUI, so a request is remote because of the listener it arrived on, whatever headers it carries. The page installs as an app (Add to Home Screen, or Chrome's Install) with a fixed entry, `https://<this machine>.<tailnet>.ts.net:8443/sb-app/`, as its start URL (a token-free address on the tailnet listener only): open with a pairing, it leads to the current page; open without one (after a new token, or on iOS, where the app keeps cookies of its own and scanning the QR in Safari never reaches it), it shows eight boxes for the **pairing code** that `/boss gui remote` prints under the QR (and the Phone & devices section shows beside it), one character per box (a paste fills them all). The code is 8 characters, shown as two groups of four (`ABCD EFGH`; no hyphen to type), works once within ten minutes, and is void after five wrong tries until you ask this computer for a new one. An app installed before this entry existed opens its old address, which now leads to the entry as well. |
157
159
  | `node dist/server/cli.mjs up --dir <folder> --label <name>` (a shell, not a pi command) | The desk steps of `up`, for a shell that shows the page itself (straw-boss-desk): with `STRAW_BOSS_DESK=1` set in the environment of `herdr server` and of this command, it installs Herdr's pi integration when it is not current, makes the shell's home base (a workspace in the folder, recorded in `desk.json` and found again by its workspace id), has the sb server stand in for its tower, waits for the GUI, and prints one JSON line with `url`, `workspace`, `pane`, `tower`, `created`, and `integration`. Idempotent: a second run opens nothing. Without the switch it exits 2. See [Desk mode](docs/how-it-works.md#desk-mode-up---dir). |
158
160
 
package/README.zh-TW.md CHANGED
@@ -28,6 +28,8 @@
28
28
 
29
29
  <p align="center"><img src="docs/gui-zen-wait.png" width="49%" alt="禪檢視裡塔台的一則等待:塔台和基地名當標題、問題、細線下打了一句回覆的輸入框,以及送出、略過和晚點再說"> <img src="docs/gui-wait-answer.png" width="49%" alt="標準檢視裡塔台等待事項的對話框:問題、打了一句回覆的輸入框、送出、前往塔台通訊的連結、稍後和略過"></p>
30
30
 
31
+ 塔台對你的等待是一張卡片,不是一行文字:發生什麼事、你要做的事、在哪裡做(可開啟的連結,或可複製的指令;sb 不會執行指令)、做完之後會怎樣,以及是哪個 session 提出的;按鈕依類型而定(我做完了、選項,或在終端機輸入密鑰的步驟),**略過**要點兩下,並會告訴塔台和那個 session,也有回覆的輸入框。示範頁的 `?waits=cards` 每一類都看得到。
32
+
31
33
  <p align="center"><img src="docs/gui-zen-history.png" width="49%" alt="打開「前情」的禪檢視:卡片裡是這個 unit 的 session 紀錄,問題的選項仍然可以回答"> <img src="docs/gui-zen-palette.png" width="49%" alt="在陪伴的 session 上打開指令面板(⌘K)的禪檢視,頂端有工作中與閒著的 unit 數的淡淡一行"></p>
32
34
 
33
35
  <p align="center"><img src="docs/gui-zen-music.png" width="49%" alt="有音樂資料夾時的禪檢視:右上角的 ♪ 開關與打開的曲目清單"></p>
@@ -0,0 +1,2 @@
1
+ import{w as e}from"./towermodel-CAbNR8ZT.js";import{t}from"./runtime-ZX6HkxDa.js";import{at as n,rt as r,tt as i}from"./index-D4RgSZfB.js";import{mountDialogCards as a}from"./linkdialogs-por8my_6.js";var o=t=>{let n=e(`en`,t?.count,{},!0);return n===`one`?`${t?.count} question waits for you: answer it here`:n===`other`?`${t?.count} questions wait for you: answer them here`:`ally_asks_button`},s=e=>`${e?.count} 個問題等你回答,在這裡回答`,c=((e,n={})=>(n.locale??t())===`zh-TW`?s(e):o(e)),l=e=>e.tower===`blocked`||e.tabs.some(e=>e.state===`blocked`);function u(e){let t=new Map,n=r(e?.allies??[]);for(let r of e?.alerts??[]){let e=r.kind===`dialog`?i(r):void 0;if(e!==`open`&&e!==`sent`)continue;let a=n.filter(e=>e.device===r.data.device),o=a.filter(e=>e.teams.some(e=>e.team===r.team)),s=o.length?o:a,c=s.find(l)??s[0];c&&t.set(c.id,[...t.get(c.id)??[],r])}return t}var d=`.ally-unit[data-state="blocked"], .ally-tab[data-state="blocked"]`;function f(){let e=new WeakMap,t=t=>{let i=e.get(t);if(i)return i;let o=n(`button`,{type:`button`,class:`ally-asks-btn`,"aria-expanded":`false`}),s=n(`ul`,{class:`ally-asks-list`}),c=n(`div`,{class:`ally-asks`},o,s);return i={box:c,btn:o,list:s,cards:a(),ids:``},e.set(t,i),o.onclick=()=>r(t),t.addEventListener(`click`,e=>{let n=e.target?.closest?.(d);n&&t.contains(n)&&t.dataset.asks&&!e.target.closest(`details`)&&r(t)}),t.append(c),i};function r(t){let n=e.get(t);if(!n||!t.dataset.asks)return;let r=t.dataset.asking===void 0;r?t.dataset.asking=``:delete t.dataset.asking,n.list.hidden=!r,n.btn.setAttribute(`aria-expanded`,String(r))}function i(n,r){if(!r.length&&!e.has(n))return;let i=t(n);if(i.box.hidden=!r.length,!r.length){delete n.dataset.asks,delete n.dataset.asking,i.btn.setAttribute(`aria-expanded`,`false`),i.cards.keep(new Set),i.list.replaceChildren(),i.ids=``;return}n.dataset.asks=String(r.length),i.btn.textContent=c({count:r.length}),i.list.hidden=n.dataset.asking===void 0,i.cards.keep(new Set(r.map(e=>e.id)));let a=r.map(e=>i.cards.row(e)),o=r.map(e=>e.id).join(`
2
+ `);o!==i.ids&&(i.list.replaceChildren(...a),i.ids=o)}return{toggle:r,fill:i,show:(e,t,n)=>i(e,u(n).get(t.id)??[])}}export{f as mountAllyAsks};
@@ -1,2 +1,2 @@
1
- import{w as e}from"./towermodel-DJLQh2fz.js";import{t}from"./runtime-ZX6HkxDa.js";import{n}from"./post-DDdE-PdN.js";import{Ct as r,Et as i,Ft as a,O as o,P as s,R as c,S as l,et as u,h as d,k as f}from"./index-Pr0dJgxC.js";var p=e=>`by ${e?.who}`,m=e=>`派工者 ${e?.who}`,h=((e,n={})=>(n.locale??t())===`zh-TW`?m(e):p(e)),g=((e={},n={})=>(n.locale??t())===`zh-TW`?`中斷並停止`:`Interrupt and stop`),_=e=>`${e?.box} was not asked: ${e?.reason}`,v=e=>`沒有請 ${e?.box} 停止:${e?.reason}`,y=((e,n={})=>(n.locale??t())===`zh-TW`?v(e):_(e)),b=((e={},n={})=>(n.locale??t())===`zh-TW`?`停止`:`Stop`),x=e=>`Stop the main ${e?.name}`,S=e=>`停止主智慧體 ${e?.name}`,C=((e,n={})=>(n.locale??t())===`zh-TW`?S(e):x(e)),w=e=>`Ask ${e?.box} to stop the main ${e?.name}? Stop lets it quit when it is idle; Interrupt and stop aborts the turn it is in first. The box decides and tells you what happened.`,T=e=>`要請 ${e?.box} 停止主智慧體 ${e?.name} 嗎?「停止」等它閒下來才結束;「中斷並停止」會先中止它進行中的回合。由那台機器決定,結果會通知你。`,E=((e,n={})=>(n.locale??t())===`zh-TW`?T(e):w(e)),D=e=>`Mains (${e?.count})`,O=e=>`主智慧體(${e?.count})`,k=((e,n={})=>(n.locale??t())===`zh-TW`?O(e):D(e)),A=((e={},n={})=>(n.locale??t())===`zh-TW`?`前`:` ago`),j=((e={},n={})=>(n.locale??t())===`zh-TW`?`發生了什麼事`:`What happened`),M=((e={},n={})=>(n.locale??t())===`zh-TW`?`這個單位最後一次回報的時間`:`When this unit last reported`),N=t=>{let n=e(`en`,t?.count,{},!0);return n===`one`?`${t?.count} monitor`:n===`other`?`${t?.count} monitors`:`link_unit_monitors`},P=e=>`${e?.count} 個監看程序`,F=((e,n={})=>(n.locale??t())===`zh-TW`?P(e):N(e)),ee=((e={},n={})=>(n.locale??t())===`zh-TW`?`最後回報`:`Last report`),I=((e={},n={})=>(n.locale??t())===`zh-TW`?`最近沒有狀態`:`no status lately`),L=((e={},n={})=>(n.locale??t())===`zh-TW`?`盒子已超過 3 分鐘沒送狀態,這是它最後一次的內容`:`The box has sent no status for 3 minutes; this is its last one`),R=((e={},n={})=>(n.locale??t())===`zh-TW`?`請在盒子的 trust.json 加入這個專案`:`Add the project to the box's trust.json`),z=((e={},n={})=>(n.locale??t())===`zh-TW`?`為什麼停了`:`Why it stopped`),B=((e={},n={})=>(n.locale??t())===`zh-TW`?`前更新`:` ago`),V=((e={},n={})=>(n.locale??t())===`zh-TW`?``:`updated `),H={choose:s,post:(e,t)=>n(e,t)},U=12e4,W=new Map,G=(e,t)=>`${e.device}/${t.handle}`,K=(e,t,n=Date.now())=>n-(W.get(G(e,t))??-1/0)<U;async function q(e,t,n){let a=await H.choose(E({box:n,name:t.name}),[{label:b(),value:`quit`},{label:g(),value:`interrupt`,tone:`danger`}]);if(!a)return!1;let o=await H.post(`link/unit-stop`,{team:e.team,device:e.device,handle:t.handle,mode:a,reason:``}).catch(()=>({ok:!1,status:0,body:{}}));return o.ok?(W.set(G(e,t),Date.now()),!0):(await H.choose(y({box:n,reason:o.body.reason??(o.status?r({status:o.status}):i())}),[]),!1)}var J=()=>l(`<li class="ally-unit"><div class="au-head"><i class="au-dot"></i><b class="au-word"></b><span class="au-name"></span><span class="au-time" hidden><span class="au-pre"></span><span class="age"></span><span class="au-ago"></span></span><em class="au-stale" hidden></em></div><p class="au-mons" hidden><b></b><span></span></p><details class="au-mains" hidden><summary><b class="au-mains-label"></b></summary><ul class="au-main-list"></ul></details><details class="au-crash" hidden><summary><b></b><span class="au-time"><span class="age"></span><span class="au-ago"></span></span></summary><pre></pre><p class="au-hint" hidden></p></details><details class="au-report" hidden><summary><b class="au-label"></b><span class="au-peek"></span></summary><div class="md au-md"></div></details></li>`),Y,X=new WeakMap;function Z(e){let t=e.querySelector(`.au-md`),n=X.get(e)??``;e.open&&t.dataset.report!==n&&(Y?Promise.resolve(Y):c(()=>import(`./markdown-Bk5NWfKQ.js`).then(e=>e.t).then(e=>Y=e),[],import.meta.url)).then(({mount:r,parse:i})=>{e.open&&X.get(e)===n&&(t.dataset.report=n,t.replaceChildren(r(i(n))))})}function Q(e,t,n=``,r=A()){let i=e.querySelector(`.age`);i.dataset.since=String(t),i.textContent=d(t),e.querySelector(`.au-pre`)?.replaceChildren(n),e.querySelector(`.au-ago`).textContent=r}var $=()=>l(`<li class="au-main"><span class="au-mdot"></span><b class="au-mname"></b><span class="au-mstate"></span><span class="au-mby" hidden></span><button type="button" class="au-stop" hidden></button></li>`);function te(e,t,n){let r=e.querySelector(`.au-mains`);r.hidden=!t.mains.length,t.mains.length&&(f(r,`.au-mains-label`,k({count:t.mains.length})),o(r.querySelector(`.au-main-list`),t.mains.map(e=>({...e,id:e.handle})),$,(e,r)=>{let i=r.stopping||K(t,r),o=i?a():r.word;e.dataset.tone=i?`other`:r.tone,f(e,`.au-mname`,r.name),f(e,`.au-mstate`,o);let s=e.querySelector(`.au-mby`);s.hidden=r.byLabel===void 0,s.textContent=r.byLabel===void 0?``:h({who:r.byLabel});let c=e.querySelector(`.au-stop`);c.hidden=!r.canStop||i,c.textContent=b(),c.setAttribute(`aria-label`,C({name:r.name})),c.onclick=()=>{c.disabled=!0,q(t,r,n).then(t=>{c.disabled=!1,t&&(e.dataset.tone=`other`,f(e,`.au-mstate`,a()),c.hidden=!0)})}}))}function ne(e,t,n,r=``){o(e,t.map(e=>({...e,id:e.unit,named:n})),J,(e,t)=>{e.dataset.state=t.state,e.dataset.tone=t.tone,e.classList.toggle(`stale`,t.stale),f(e,`.au-word`,t.word),f(e,`.au-name`,t.named?t.unit:``);let n=e.querySelector(`.au-head > .au-time`);n.hidden=!1,n.title=M(),Q(n,t.at,V(),B());let i=e.querySelector(`.au-stale`);i.hidden=!t.stale,i.textContent=t.stale?I():``,i.title=t.stale?L():``;let a=e.querySelector(`.au-mons`);a.hidden=!t.monitors.length,t.monitors.length&&(f(a,`b`,F({count:t.monitors.length})),f(a,`span`,t.monitors.join(` · `)),a.title=t.monitors.join(`
2
- `)),te(e,t,r);let o=e.querySelector(`.au-crash`);if(o.hidden=!t.crash,o.toggleAttribute(`data-trust`,t.crash?.trust===!0),t.crash){f(o,`summary > b`,t.crash.trust?z():j()),Q(o.querySelector(`summary > .au-time`),t.crash.at),f(o,`pre`,t.crash.text);let e=o.querySelector(`.au-hint`);e.hidden=!t.crash.trust,e.textContent=t.crash.trust?R():``}let s=e.querySelector(`.au-report`);s.hidden=!t.report,t.report&&(f(s,`.au-label`,ee()),f(s,`.au-peek`,u(t.report)),X.set(s,t.report),s.ontoggle=()=>Z(s),Z(s))})}export{ne as fillAllyUnits};
1
+ import{w as e}from"./towermodel-CAbNR8ZT.js";import{t}from"./runtime-ZX6HkxDa.js";import{n}from"./post-DDdE-PdN.js";import{At as r,B as i,C as a,_ as o,it as s,k as c,u as l,w as u,xt as d,yt as f}from"./index-D4RgSZfB.js";var p=e=>`by ${e?.who}`,m=e=>`派工者 ${e?.who}`,h=((e,n={})=>(n.locale??t())===`zh-TW`?m(e):p(e)),g=((e={},n={})=>(n.locale??t())===`zh-TW`?`中斷並停止`:`Interrupt and stop`),_=e=>`${e?.box} was not asked: ${e?.reason}`,v=e=>`沒有請 ${e?.box} 停止:${e?.reason}`,y=((e,n={})=>(n.locale??t())===`zh-TW`?v(e):_(e)),b=((e={},n={})=>(n.locale??t())===`zh-TW`?`停止`:`Stop`),x=e=>`Stop the main ${e?.name}`,S=e=>`停止主智慧體 ${e?.name}`,C=((e,n={})=>(n.locale??t())===`zh-TW`?S(e):x(e)),w=e=>`Ask ${e?.box} to stop the main ${e?.name}? Stop lets it quit when it is idle; Interrupt and stop aborts the turn it is in first. The box decides and tells you what happened.`,T=e=>`要請 ${e?.box} 停止主智慧體 ${e?.name} 嗎?「停止」等它閒下來才結束;「中斷並停止」會先中止它進行中的回合。由那台機器決定,結果會通知你。`,E=((e,n={})=>(n.locale??t())===`zh-TW`?T(e):w(e)),D=e=>`Mains (${e?.count})`,O=e=>`主智慧體(${e?.count})`,k=((e,n={})=>(n.locale??t())===`zh-TW`?O(e):D(e)),A=((e={},n={})=>(n.locale??t())===`zh-TW`?`前`:` ago`),j=((e={},n={})=>(n.locale??t())===`zh-TW`?`發生了什麼事`:`What happened`),M=((e={},n={})=>(n.locale??t())===`zh-TW`?`這個單位最後一次回報的時間`:`When this unit last reported`),N=t=>{let n=e(`en`,t?.count,{},!0);return n===`one`?`${t?.count} monitor`:n===`other`?`${t?.count} monitors`:`link_unit_monitors`},P=e=>`${e?.count} 個監看程序`,ee=((e,n={})=>(n.locale??t())===`zh-TW`?P(e):N(e)),F=((e={},n={})=>(n.locale??t())===`zh-TW`?`最後回報`:`Last report`),I=((e={},n={})=>(n.locale??t())===`zh-TW`?`最近沒有狀態`:`no status lately`),L=((e={},n={})=>(n.locale??t())===`zh-TW`?`盒子已超過 3 分鐘沒送狀態,這是它最後一次的內容`:`The box has sent no status for 3 minutes; this is its last one`),R=((e={},n={})=>(n.locale??t())===`zh-TW`?`請在盒子的 trust.json 加入這個專案`:`Add the project to the box's trust.json`),z=((e={},n={})=>(n.locale??t())===`zh-TW`?`為什麼停了`:`Why it stopped`),B=((e={},n={})=>(n.locale??t())===`zh-TW`?`前更新`:` ago`),V=((e={},n={})=>(n.locale??t())===`zh-TW`?``:`updated `),H={choose:c,post:(e,t)=>n(e,t)},U=12e4,W=new Map,G=(e,t)=>`${e.device}/${t.handle}`,K=(e,t,n=Date.now())=>n-(W.get(G(e,t))??-1/0)<U;async function q(e,t,n){let r=await H.choose(E({box:n,name:t.name}),[{label:b(),value:`quit`},{label:g(),value:`interrupt`,tone:`danger`}]);if(!r)return!1;let i=await H.post(`link/unit-stop`,{team:e.team,device:e.device,handle:t.handle,mode:r,reason:``}).catch(()=>({ok:!1,status:0,body:{}}));return i.ok?(W.set(G(e,t),Date.now()),!0):(await H.choose(y({box:n,reason:i.body.reason??(i.status?f({status:i.status}):d())}),[]),!1)}var J=()=>o(`<li class="ally-unit"><div class="au-head"><i class="au-dot"></i><b class="au-word"></b><span class="au-name"></span><span class="au-time" hidden><span class="au-pre"></span><span class="age"></span><span class="au-ago"></span></span><em class="au-stale" hidden></em></div><p class="au-mons" hidden><b></b><span></span></p><details class="au-mains" hidden><summary><b class="au-mains-label"></b></summary><ul class="au-main-list"></ul></details><details class="au-crash" hidden><summary><b></b><span class="au-time"><span class="age"></span><span class="au-ago"></span></span></summary><pre></pre><p class="au-hint" hidden></p></details><details class="au-report" hidden><summary><b class="au-label"></b><span class="au-peek"></span></summary><div class="md au-md"></div></details></li>`),Y,X=new WeakMap;function Z(e){let t=e.querySelector(`.au-md`),n=X.get(e)??``;e.open&&t.dataset.report!==n&&(Y?Promise.resolve(Y):i(()=>import(`./markdown-Dz6BWlns.js`).then(e=>e.t).then(e=>Y=e),[],import.meta.url)).then(({mount:r,parse:i})=>{e.open&&X.get(e)===n&&(t.dataset.report=n,t.replaceChildren(r(i(n))))})}function Q(e,t,n=``,r=A()){let i=e.querySelector(`.age`);i.dataset.since=String(t),i.textContent=l(t),e.querySelector(`.au-pre`)?.replaceChildren(n),e.querySelector(`.au-ago`).textContent=r}var $=()=>o(`<li class="au-main"><span class="au-mdot"></span><b class="au-mname"></b><span class="au-mstate"></span><span class="au-mby" hidden></span><button type="button" class="au-stop" hidden></button></li>`);function te(e,t,n){let i=e.querySelector(`.au-mains`);i.hidden=!t.mains.length,t.mains.length&&(u(i,`.au-mains-label`,k({count:t.mains.length})),a(i.querySelector(`.au-main-list`),t.mains.map(e=>({...e,id:e.handle})),$,(e,i)=>{let a=i.stopping||K(t,i),o=a?r():i.word;e.dataset.tone=a?`other`:i.tone,u(e,`.au-mname`,i.name),u(e,`.au-mstate`,o);let s=e.querySelector(`.au-mby`);s.hidden=i.byLabel===void 0,s.textContent=i.byLabel===void 0?``:h({who:i.byLabel});let c=e.querySelector(`.au-stop`);c.hidden=!i.canStop||a,c.textContent=b(),c.setAttribute(`aria-label`,C({name:i.name})),c.onclick=()=>{c.disabled=!0,q(t,i,n).then(t=>{c.disabled=!1,t&&(e.dataset.tone=`other`,u(e,`.au-mstate`,r()),c.hidden=!0)})}}))}function ne(e,t,n,r=``){a(e,t.map(e=>({...e,id:e.unit,named:n})),J,(e,t)=>{e.dataset.state=t.state,e.dataset.tone=t.tone,e.classList.toggle(`stale`,t.stale),u(e,`.au-word`,t.word),u(e,`.au-name`,t.named?t.unit:``);let n=e.querySelector(`.au-head > .au-time`);n.hidden=!1,n.title=M(),Q(n,t.at,V(),B());let i=e.querySelector(`.au-stale`);i.hidden=!t.stale,i.textContent=t.stale?I():``,i.title=t.stale?L():``;let a=e.querySelector(`.au-mons`);a.hidden=!t.monitors.length,t.monitors.length&&(u(a,`b`,ee({count:t.monitors.length})),u(a,`span`,t.monitors.join(` · `)),a.title=t.monitors.join(`
2
+ `)),te(e,t,r);let o=e.querySelector(`.au-crash`);if(o.hidden=!t.crash,o.toggleAttribute(`data-trust`,t.crash?.trust===!0),t.crash){u(o,`summary > b`,t.crash.trust?z():j()),Q(o.querySelector(`summary > .au-time`),t.crash.at),u(o,`pre`,t.crash.text);let e=o.querySelector(`.au-hint`);e.hidden=!t.crash.trust,e.textContent=t.crash.trust?R():``}let c=e.querySelector(`.au-report`);c.hidden=!t.report,t.report&&(u(c,`.au-label`,F()),u(c,`.au-peek`,s(t.report)),X.set(c,t.report),c.ontoggle=()=>Z(c),Z(c))})}export{ne as fillAllyUnits};
@@ -1 +1 @@
1
- import{t as e}from"./rolldown-runtime-DK3Fl9T5.js";import{t}from"./ask-DZ8GOgV1.js";import{n}from"./post-DDdE-PdN.js";var r=e({answerPost:()=>i,canAnswer:()=>o,mountAnswer:()=>s,trustPost:()=>a}),i=(e,t)=>t?.(e)??((t,r)=>n(e.startsWith(`grant:`)?`panes/${encodeURIComponent(e.slice(6))}/${t}`:`sessions/${encodeURIComponent(e)}/${t}`,r)),a=e=>e??(e=>n(`trust/answer`,e)),o=(e,...t)=>e===`waiting`&&t.every(Boolean),s=(e,{key:n,show:r,post:i,remote:a,accepted:o,label:s})=>t(e,i,a,{key:n,show:r},o,s);export{a,s as i,r as n,o as r,i as t};
1
+ import{t as e}from"./rolldown-runtime-DK3Fl9T5.js";import{t}from"./ask-PWjAd6ec.js";import{n}from"./post-DDdE-PdN.js";var r=e({answerPost:()=>i,canAnswer:()=>o,mountAnswer:()=>s,trustPost:()=>a}),i=(e,t)=>t?.(e)??((t,r)=>n(e.startsWith(`grant:`)?`panes/${encodeURIComponent(e.slice(6))}/${t}`:`sessions/${encodeURIComponent(e)}/${t}`,r)),a=e=>e??(e=>n(`trust/answer`,e)),o=(e,...t)=>e===`waiting`&&t.every(Boolean),s=(e,{key:n,show:r,post:i,remote:a,accepted:o,label:s})=>t(e,i,a,{key:n,show:r},o,s);export{a,s as i,r as n,o as r,i as t};
@@ -1 +1 @@
1
- import{t as e}from"./runtime-ZX6HkxDa.js";import{a as t,i as n,n as r,r as i,t as a}from"./sending-aEpvzoz2.js";import{Ct as o,Yt as s,t as c,tt as l}from"./index-Pr0dJgxC.js";var u=((t={},n={})=>(n.locale??e())===`zh-TW`?`請在終端機中回答。`:`Answer it in the terminal.`),d=((t={},n={})=>(n.locale??e())===`zh-TW`?`請在終端機中回答。`:`Answer them in the terminal.`),f=((t={},n={})=>(n.locale??e())===`zh-TW`?`下方還有 ▾`:`More below ▾`),p=((t={},n={})=>(n.locale??e())===`zh-TW`?`也可以自己輸入答案。`:`It also takes your own words.`),m=((t={},n={})=>(n.locale??e())===`zh-TW`?`可以複選。`:`It takes several choices.`),h=((t={},n={})=>(n.locale??e())===`zh-TW`?`已取消。`:`Cancelled.`),g=((t={},n={})=>(n.locale??e())===`zh-TW`?`選擇`:`Choices`),_=((t={},n={})=>(n.locale??e())===`zh-TW`?`瀏覽器拒絕存取剪貼簿。`:`The browser refused the clipboard.`),v=((t={},n={})=>(n.locale??e())===`zh-TW`?`已複製到這台裝置的剪貼簿。`:`Copied to this device's clipboard.`),y=((t={},n={})=>(n.locale??e())===`zh-TW`?`複製指令`:`Copy command`),ee=((t={},n={})=>(n.locale??e())===`zh-TW`?`這個選項有預覽;請在終端機中查看。`:`It has a preview; see it in the terminal.`),b=((t={},n={})=>(n.locale??e())===`zh-TW`?`備註`:`Note`),x=((t={},n={})=>(n.locale??e())===`zh-TW`?`備註(選填)`:`Note (optional)`),S=e=>`Opened while ${e?.tool} was running; it may not be about that call.`,C=e=>`在 ${e?.tool} 執行時開啟,不一定與該呼叫有關。`,te=((t,n={})=>(n.locale??e())===`zh-TW`?C(t):S(t)),w=((t={},n={})=>(n.locale??e())===`zh-TW`?`選項`:`Options`),T=((t={},n={})=>(n.locale??e())===`zh-TW`?`另一個答案沒有被採用;這個可以送出。`:`The other answer was not taken; this one can go.`),E=((t={},n={})=>(n.locale??e())===`zh-TW`?`你的答案`:`Your own answer`),D=((t={},n={})=>(n.locale??e())===`zh-TW`?`或自己輸入答案`:`Or type your own answer`),O=((t={},n={})=>(n.locale??e())===`zh-TW`?`問題已變更,請重新閱讀。`:`The question changed; read it again.`),k=((t={},n={})=>(n.locale??e())===`zh-TW`?`session 讀不懂這個答案。`:`The session could not read that answer.`),A=((t={},n={})=>(n.locale??e())===`zh-TW`?`這個答案不符合問題。`:`That answer does not fit the question.`),j=((t={},n={})=>(n.locale??e())===`zh-TW`?`session 拒絕了這個答案。`:`The session refused that answer.`),M=((t={},n={})=>(n.locale??e())===`zh-TW`?`安全考量,遠端不支援輸入機密。請到執行 GUI 的那台電腦的終端機中回答。`:`For security, entering a secret is not supported remotely. Answer it in the terminal on the computer the GUI runs on.`),N=((t={},n={})=>(n.locale??e())===`zh-TW`?`機密內容只能在終端機輸入,這裡不接受。請到執行 GUI 的那台電腦的終端機中回答。`:`A secret is entered in the terminal only, not here. Answer it in the terminal on the computer the GUI runs on.`),P=((t={},n={})=>(n.locale??e())===`zh-TW`?`送出答案`:`Send answer`),F=((t={},n={})=>(n.locale??e())===`zh-TW`?`顯示終端機`:`Show terminal`),I=((t={},n={})=>(n.locale??e())===`zh-TW`?`已在終端機中關閉。`:`It was dismissed in the terminal.`),L=((t={},n={})=>(n.locale??e())===`zh-TW`?`它已不再開啟。`:`It is no longer open.`),R=((t={},n={})=>(n.locale??e())===`zh-TW`?`已在終端機中回答。`:`It was already answered in the terminal.`),z=((t={},n={})=>(n.locale??e())===`zh-TW`?`它在等待對話框。`:`It waits on a dialog.`),B={ArrowDown:1,ArrowRight:1,ArrowUp:-1,ArrowLeft:-1};function V(e,t,n,r,i){let{q:a}=n,o=r[a],s=B[e]??0,c=e===`ArrowUp`,l=c||e===`ArrowDown`,u=()=>({to:r.map((e,t)=>({q:(a+1+t)%r.length,part:`opt`})).find(e=>e.q!==a&&!i[e.q])??`send`});if(e===`Tab`){let e=r[a-1],i=n.part===`opt`?o.own||o.note:n.part===`own`&&o.note;return t?n.part===`opt`&&e?{to:{q:a-1,part:e.note?`note`:e.own?`own`:`opt`}}:void 0:i||a===r.length-1?void 0:{to:{q:a+1,part:`opt`}}}if(!t){if(n.part===`opt`){let t=n.o+s;if(s)return t>=0&&t<o.options?{to:{q:a,part:`opt`,o:t},...o.multiple?{}:{pick:t}}:{to:s>0&&o.own?{q:a,part:`own`}:n};if(e===`Enter`||e===` `&&!o.multiple)return{...u(),...o.multiple?{}:{pick:n.o}}}else if(n.part===`own`){if(e===`Enter`)return u();if(l)return{to:c?{q:a,part:`opt`,o:o.options-1}:{q:a,part:`note`}}}else if(c)return{to:{q:a,part:`own`}}}}function H(e,t,n){let r=e=>Math.max(0,e.opts.findIndex(e=>e.getAttribute(`aria-checked`)===`true`)),i=(e,t)=>e.opts.forEach((e,n)=>e.setAttribute(`tabindex`,n===t?`0`:`-1`)),a=e=>{for(let[n,r]of t.entries()){let t=r.opts.indexOf(e);if(t>=0)return{q:n,part:`opt`,o:t};if(e===r.own||e===r.note)return{q:n,part:e===r.own?`own`:`note`}}};t.forEach(e=>i(e,r(e)));let o=e=>{let n=a(e.target);n?.part===`opt`&&i(t[n.q],n.o)};e.addEventListener(`focusin`,o),e.addEventListener(`click`,o);let s=!1,c=!1;return e.addEventListener(`keydown`,i=>{i.key===` `&&(c=!0);let o=a(i.target);if(!o||i.ctrlKey||i.altKey||i.metaKey||i.isComposing)return;let l=i.target;if(o.part!==`opt`&&(i.key===`ArrowUp`?l.selectionStart!==0:i.key===`ArrowDown`&&l.selectionEnd!==l.value.length))return;let u=V(i.key,i.shiftKey,o,t.map(e=>({options:e.opts.length,multiple:e.multiple,own:!!e.own,note:!!e.note})),t.map(e=>e.answered()));if(!u||(i.preventDefault(),i.repeat&&[`Enter`,` `].includes(i.key)))return;if(s=i.key===` `,u.pick!==void 0){let e=t[o.q].opts[u.pick];e.getAttribute(`aria-checked`)!==`true`&&e.click()}let d=u.to===`send`?void 0:t[u.to.q],f=u.to===`send`?n():u.to.part===`opt`?d.opts[u.to.o??r(d)]:u.to.part===`own`?d.own:d.note;f&&!f.disabled&&(e.dispatchEvent(new CustomEvent(`ask-reveal`,{detail:f})),f.focus())}),e.addEventListener(`keyup`,e=>{e.key===` `&&((s||!c)&&e.preventDefault(),s=c=!1)}),()=>t[0]?.opts[r(t[0])]}var U=e=>e.multiple?m():e.freeform&&e.options.length?p():``,W=90,G=(e,t)=>l(`div`,{class:`ask-one`},e.header&&l(`b`,{class:`ask-head`},e.header),l(`p`,{class:`ask-q`,...e.question.length>W?{"data-long":``}:{}},e.question),e.context&&l(`div`,{class:`ask-ctx`},e.context),e.options.length>0&&l(`ol`,{class:`ask-opts`,"aria-label":w()},...e.options.map(e=>l(`li`,{class:`ask-opt`},l(`b`,null,e.title),e.description&&l(`small`,null,e.description)))),t&&U(e)&&l(`small`,{class:`ask-how`},U(e))),K=e=>e.replace(/[\u0000-\u0008\u000b-\u001f\u007f-\u009f\p{Cf}]/gu,`�`),q=e=>(e.select?.choices??[]).map((e,t)=>({...e,i:t})),J=(e,t,n)=>({...e.size?{choices:[...e].sort((e,t)=>e-t)}:{},...t.trim()?{text:t}:{},...n.trim()?{note:n}:{}}),Y=(e,t,n)=>({dialog:e.dialog,digest:e.digest,answerId:n,...t}),X=(e,t)=>({dialog:e.dialog,digest:e.digest,answerId:t,cancel:!0}),Z=(e,t)=>e.cancel===!0&&!(t&&e.select?.choices.every(e=>e.hereOnly)),Q={digest:O,"not-allowed":A,malformed:k};function ne(e,i=!1){let{outcome:a,reason:s,by:c}=e.body;return a===`accepted`?[`ok`,i?h():n()]:a===`stale`?[`error`,c===`local`?R():c===`cancel`?I():L()]:a===`rejected`?[`error`,(Object.hasOwn(Q,String(s))?Q[String(s)]:j)()]:a===`busy`?[`error`,t()]:a===`unknown`||e.status===504?[`error`,r(),!0]:[`error`,s??o({status:e.status})]}var re=e=>[`accepted`,`stale`,`busy`,`unknown`].includes(String(e.body.outcome))||e.status===504,$=e=>e.answer?`d\n${e.answer.dialog}\n${e.answer.digest}`:`c\n${e.callId}\n${e.why??``}`;function ie(e){if(e.dataset.cued)return;e.dataset.cued=`1`;let t=()=>{e.toggleAttribute(`data-more`,e.scrollHeight-e.scrollTop-e.clientHeight>4);for(let t of e.querySelectorAll(`.ask-acts`))t.dataset.cue=f()};for(let n of[`scroll`,`input`])e.addEventListener(n,t,{passive:!0});typeof ResizeObserver<`u`&&new ResizeObserver(t).observe(e),typeof MutationObserver<`u`&&new MutationObserver(t).observe(e,{childList:!0,subtree:!0,characterData:!0}),typeof requestAnimationFrame<`u`&&requestAnimationFrame(t)}function ae(e,t,n=location.hostname!==`127.0.0.1`,o,f,p=F){let m,h,S,C=!1,O=!1,k;for(let e of[`focusin`,`pointerdown`])document.addEventListener(e,e=>h&&!h.el.contains(e.target)&&(h.lost=void 0));let A=(e,t,n,...r)=>(e.dataset.tone=t,e.replaceChildren(n,...r)),j=()=>{if(!h)return;let e=document.activeElement;e&&e!==document.body&&e!==h.lost&&(h.lost=void 0),h.controls.forEach(e=>e.disabled=!C||O||h.done),h.send&&(h.send.disabled=!C||O||h.done||!h.pick()),e&&h.el.contains(e)&&e.disabled&&(h.lost=e);let t=h.lost;t&&!t.disabled&&h.el.contains(t)&&(!document.activeElement||document.activeElement===document.body)&&(t.focus(),h.lost=void 0)};async function I(e,n){[e.sending,O,e.spell]=[!0,!0,!1],j(),A(e.note,``,a());let s=await t(`answer`,n).catch(()=>void 0),u=l(`button`,{type:`button`,class:`cmp-link`},i());u.onclick=()=>void I(e,n);let[d,p,m]=s?ne(s,n.cancel===!0):[`error`,r(),!0];[e.done,e.sending,O,e.busy]=[!s||re(s),!1,!1,s?.body.outcome===`busy`],A(e.note,d,p,...m?[u]:[]);let h=s?.body.outcome===`accepted`?s.body.then:void 0,g=h&&c(h,{key:o?.key??``,command:e.copy,answerId:String(n.answerId??``)});g&&A(e.note,d,`${p} ${g}`),j(),e.note.scrollIntoView?.({block:`nearest`}),f&&s?.body.outcome===`accepted`&&setTimeout(()=>f(!!h&&!g),h&&!g?0:1200)}let L=(e,t,n,r,i)=>{let a=l(`button`,{type:`button`,class:`ask-opt`,role:e,"aria-checked":`false`},l(`b`,i?{"data-n":String(i)}:null,t),...n.filter(Boolean).map(e=>l(`small`,null,e)));return a.onclick=r,a};function R(e,t){let r,i=q(t).map(e=>L(`radio`,K(e.label),[e.note&&K(e.note)],()=>(r=e.i,i.forEach((n,r)=>n.setAttribute(`aria-checked`,String(q(t)[r].i===e.i))),j()),e.i+1)),a=t.select?.copy!==void 0&&l(`button`,{type:`button`,class:`cmp-link`},y());a&&(a.disabled=!navigator.clipboard,a.onclick=()=>void navigator.clipboard.writeText(t.select.copy).then(()=>A(e.note,`ok`,v()),()=>A(e.note,`error`,_())));let o=i.filter((e,r)=>!(n&&q(t)[r].hereOnly));return i.forEach(e=>!o.includes(e)&&(e.disabled=!0)),e.pick=()=>r===void 0?void 0:{choice:r},e.first=H(e.el,[{opts:i,multiple:!1,answered:()=>r!==void 0}],()=>e.send),e.controls=o,[l(`pre`,{class:`ask-title`},K(t.select.title)),l(`div`,{class:`ask-opts`,role:`radiogroup`,"aria-label":g()},...i),l(`div`,{class:`ask-acts`},e.send,e.cancel,a)]}function B(e,t){let n=t.questions.map(()=>({picks:new Set,text:l(`textarea`,{rows:`1`,maxlength:`8192`,class:`ask-own`,placeholder:D(),"aria-label":E()}),note:l(`input`,{type:`text`,maxlength:`2048`,class:`ask-own ask-memo`,placeholder:x(),"aria-label":b()})})),r=[],i=t.questions.map((t,i)=>{let a=n[i],o=t.multiple?`checkbox`:`radio`,s=t.options.map((e,n)=>L(o,e.title,[e.description,e.preview&&ee()],()=>{t.multiple||(a.picks.clear(),a.text.value=``),a.picks.has(n)?a.picks.delete(n):a.picks.add(n),s.forEach((e,t)=>e.setAttribute(`aria-checked`,String(a.picks.has(t)))),j()}));return a.text.oninput=()=>(t.multiple||(a.picks.clear(),s.forEach(e=>e.setAttribute(`aria-checked`,`false`))),j()),e.controls.push(...s,a.text,a.note),r.push({opts:s,multiple:!!t.multiple,own:a.text,note:a.note,answered:()=>a.picks.size>0||a.text.value.trim()!==``}),l(`div`,{class:`ask-one`},t.header&&l(`b`,{class:`ask-head`},t.header),l(`p`,{class:`ask-q`,...t.question.length>W?{"data-long":``}:{}},t.question),l(`div`,{class:`ask-opts`,role:t.multiple?`group`:`radiogroup`,"aria-label":w()},...s),a.text,a.note)});return e.pick=()=>n.every(e=>e.picks.size||e.text.value.trim())?{answers:n.map(e=>J(e.picks,e.text.value,e.note.value))}:void 0,e.first=H(e.el,r,()=>e.send),[...i,l(`div`,{class:`ask-acts`},e.send,e.cancel)]}function V(e){let t=e.asks??(e.ask?[e.ask]:[]),r=t.length>1,i=e.answer,a={copy:i?.select?.copy,key:$(e),el:l(`section`,{class:`ask`}),note:l(`p`,{class:`ask-note`,role:`status`,"aria-live":`polite`}),controls:[],pick:()=>void 0,done:!1,sending:!1};i&&((a.send=l(`button`,{type:`button`,class:`ask-send`},P())).onclick=()=>void(a.pick()&&I(a,Y(i,a.pick(),crypto.randomUUID()))));let c=e.tool===`secret_drop`;i&&!c&&Z(i,n)&&((a.cancel=l(`button`,{type:`button`,class:`ask-cancel`},s())).onclick=()=>void I(a,X(i,crypto.randomUUID())));let f=l(`p`,{class:`ask-term`},e.why&&t.length?e.why:`${r?d():u()} ${r||!t[0]?``:U(t[0])}`.trim()),m=o&&e.tool!==`secret_drop`&&l(`button`,{type:`button`,class:`cmp-link`},p());m&&(m.onclick=o.show);let h=e.answer?.twin&&e.tool&&e.tool!==`dialog`?[l(`p`,{class:`ask-why`},te({tool:e.tool}))]:[];return a.el.append(...h,...i&&!c?i.select?R(a,i):B(a,i):[...t.length?t.map(e=>G(e,r)):[l(`p`,{class:`ask-why`},c?n?M():N():e.why??z())],l(`div`,{class:`ask-acts`},c?l(`p`,{class:`ask-term`},u()):f,m)],a.note),a.cancel&&a.controls.push(a.cancel),a}let Q=(t,n)=>{let r=document.activeElement;h&&h!==n&&(h.focus=h.el.contains(r)?r:void 0),[m,h,S]=[t,n,n?.send?n:S],e.replaceChildren(...n?[n.el]:[]),n&&ie(n.el),j(),n?.focus&&(!document.activeElement||document.activeElement===document.body)&&n.focus.focus()};return{enter(){let e=h&&!h.done?h.first?.():void 0;return!!(e&&!e.disabled&&(e.focus(),1))},cancel(){let e=h&&!h.done?h.cancel:void 0;return!!(e&&!e.disabled&&(e.click(),1))},sending:()=>O,update(e,t){C=t,e&&(k=void clearTimeout(k)),!e&&(h?.done||h?.sending)?k??=setTimeout(()=>(k=void 0,Q()),6e3):e?h&&($(e)===h.key||!e.answer&&(h.done||h.sending)&&e.callId===m?.callId)?((h.busy||h.sending)&&!e.answer?h.spell=!0:h.busy&&h.spell&&e.answer&&([h.done,h.busy]=[!1,!1],A(h.note,``,T())),m=e):Q(e,S?.key===$(e)&&!S.done?S:V(e)):Q(),j()}}}export{ae as t};
1
+ import{t as e}from"./runtime-ZX6HkxDa.js";import{a as t,i as n,n as r,r as i,t as a}from"./sending-aEpvzoz2.js";import{Ht as o,at as s,t as c,yt as l}from"./index-D4RgSZfB.js";var u=((t={},n={})=>(n.locale??e())===`zh-TW`?`請在終端機中回答。`:`Answer it in the terminal.`),d=((t={},n={})=>(n.locale??e())===`zh-TW`?`請在終端機中回答。`:`Answer them in the terminal.`),f=((t={},n={})=>(n.locale??e())===`zh-TW`?`下方還有 ▾`:`More below ▾`),p=((t={},n={})=>(n.locale??e())===`zh-TW`?`也可以自己輸入答案。`:`It also takes your own words.`),m=((t={},n={})=>(n.locale??e())===`zh-TW`?`可以複選。`:`It takes several choices.`),h=((t={},n={})=>(n.locale??e())===`zh-TW`?`已取消。`:`Cancelled.`),g=((t={},n={})=>(n.locale??e())===`zh-TW`?`選擇`:`Choices`),_=((t={},n={})=>(n.locale??e())===`zh-TW`?`瀏覽器拒絕存取剪貼簿。`:`The browser refused the clipboard.`),v=((t={},n={})=>(n.locale??e())===`zh-TW`?`已複製到這台裝置的剪貼簿。`:`Copied to this device's clipboard.`),y=((t={},n={})=>(n.locale??e())===`zh-TW`?`複製指令`:`Copy command`),ee=((t={},n={})=>(n.locale??e())===`zh-TW`?`這個選項有預覽;請在終端機中查看。`:`It has a preview; see it in the terminal.`),b=((t={},n={})=>(n.locale??e())===`zh-TW`?`備註`:`Note`),x=((t={},n={})=>(n.locale??e())===`zh-TW`?`備註(選填)`:`Note (optional)`),S=e=>`Opened while ${e?.tool} was running; it may not be about that call.`,C=e=>`在 ${e?.tool} 執行時開啟,不一定與該呼叫有關。`,te=((t,n={})=>(n.locale??e())===`zh-TW`?C(t):S(t)),w=((t={},n={})=>(n.locale??e())===`zh-TW`?`選項`:`Options`),T=((t={},n={})=>(n.locale??e())===`zh-TW`?`另一個答案沒有被採用;這個可以送出。`:`The other answer was not taken; this one can go.`),E=((t={},n={})=>(n.locale??e())===`zh-TW`?`你的答案`:`Your own answer`),D=((t={},n={})=>(n.locale??e())===`zh-TW`?`或自己輸入答案`:`Or type your own answer`),O=((t={},n={})=>(n.locale??e())===`zh-TW`?`問題已變更,請重新閱讀。`:`The question changed; read it again.`),k=((t={},n={})=>(n.locale??e())===`zh-TW`?`session 讀不懂這個答案。`:`The session could not read that answer.`),A=((t={},n={})=>(n.locale??e())===`zh-TW`?`這個答案不符合問題。`:`That answer does not fit the question.`),j=((t={},n={})=>(n.locale??e())===`zh-TW`?`session 拒絕了這個答案。`:`The session refused that answer.`),M=((t={},n={})=>(n.locale??e())===`zh-TW`?`安全考量,遠端不支援輸入機密。請到執行 GUI 的那台電腦的終端機中回答。`:`For security, entering a secret is not supported remotely. Answer it in the terminal on the computer the GUI runs on.`),N=((t={},n={})=>(n.locale??e())===`zh-TW`?`機密內容只能在終端機輸入,這裡不接受。請到執行 GUI 的那台電腦的終端機中回答。`:`A secret is entered in the terminal only, not here. Answer it in the terminal on the computer the GUI runs on.`),P=((t={},n={})=>(n.locale??e())===`zh-TW`?`送出答案`:`Send answer`),F=((t={},n={})=>(n.locale??e())===`zh-TW`?`顯示終端機`:`Show terminal`),I=((t={},n={})=>(n.locale??e())===`zh-TW`?`已在終端機中關閉。`:`It was dismissed in the terminal.`),L=((t={},n={})=>(n.locale??e())===`zh-TW`?`它已不再開啟。`:`It is no longer open.`),R=((t={},n={})=>(n.locale??e())===`zh-TW`?`已在終端機中回答。`:`It was already answered in the terminal.`),z=((t={},n={})=>(n.locale??e())===`zh-TW`?`它在等待對話框。`:`It waits on a dialog.`),B={ArrowDown:1,ArrowRight:1,ArrowUp:-1,ArrowLeft:-1};function V(e,t,n,r,i){let{q:a}=n,o=r[a],s=B[e]??0,c=e===`ArrowUp`,l=c||e===`ArrowDown`,u=()=>({to:r.map((e,t)=>({q:(a+1+t)%r.length,part:`opt`})).find(e=>e.q!==a&&!i[e.q])??`send`});if(e===`Tab`){let e=r[a-1],i=n.part===`opt`?o.own||o.note:n.part===`own`&&o.note;return t?n.part===`opt`&&e?{to:{q:a-1,part:e.note?`note`:e.own?`own`:`opt`}}:void 0:i||a===r.length-1?void 0:{to:{q:a+1,part:`opt`}}}if(!t){if(n.part===`opt`){let t=n.o+s;if(s)return t>=0&&t<o.options?{to:{q:a,part:`opt`,o:t},...o.multiple?{}:{pick:t}}:{to:s>0&&o.own?{q:a,part:`own`}:n};if(e===`Enter`||e===` `&&!o.multiple)return{...u(),...o.multiple?{}:{pick:n.o}}}else if(n.part===`own`){if(e===`Enter`)return u();if(l)return{to:c?{q:a,part:`opt`,o:o.options-1}:{q:a,part:`note`}}}else if(c)return{to:{q:a,part:`own`}}}}function H(e,t,n){let r=e=>Math.max(0,e.opts.findIndex(e=>e.getAttribute(`aria-checked`)===`true`)),i=(e,t)=>e.opts.forEach((e,n)=>e.setAttribute(`tabindex`,n===t?`0`:`-1`)),a=e=>{for(let[n,r]of t.entries()){let t=r.opts.indexOf(e);if(t>=0)return{q:n,part:`opt`,o:t};if(e===r.own||e===r.note)return{q:n,part:e===r.own?`own`:`note`}}};t.forEach(e=>i(e,r(e)));let o=e=>{let n=a(e.target);n?.part===`opt`&&i(t[n.q],n.o)};e.addEventListener(`focusin`,o),e.addEventListener(`click`,o);let s=!1,c=!1;return e.addEventListener(`keydown`,i=>{i.key===` `&&(c=!0);let o=a(i.target);if(!o||i.ctrlKey||i.altKey||i.metaKey||i.isComposing)return;let l=i.target;if(o.part!==`opt`&&(i.key===`ArrowUp`?l.selectionStart!==0:i.key===`ArrowDown`&&l.selectionEnd!==l.value.length))return;let u=V(i.key,i.shiftKey,o,t.map(e=>({options:e.opts.length,multiple:e.multiple,own:!!e.own,note:!!e.note})),t.map(e=>e.answered()));if(!u||(i.preventDefault(),i.repeat&&[`Enter`,` `].includes(i.key)))return;if(s=i.key===` `,u.pick!==void 0){let e=t[o.q].opts[u.pick];e.getAttribute(`aria-checked`)!==`true`&&e.click()}let d=u.to===`send`?void 0:t[u.to.q],f=u.to===`send`?n():u.to.part===`opt`?d.opts[u.to.o??r(d)]:u.to.part===`own`?d.own:d.note;f&&!f.disabled&&(e.dispatchEvent(new CustomEvent(`ask-reveal`,{detail:f})),f.focus())}),e.addEventListener(`keyup`,e=>{e.key===` `&&((s||!c)&&e.preventDefault(),s=c=!1)}),()=>t[0]?.opts[r(t[0])]}var U=e=>e.multiple?m():e.freeform&&e.options.length?p():``,W=90,G=(e,t)=>s(`div`,{class:`ask-one`},e.header&&s(`b`,{class:`ask-head`},e.header),s(`p`,{class:`ask-q`,...e.question.length>W?{"data-long":``}:{}},e.question),e.context&&s(`div`,{class:`ask-ctx`},e.context),e.options.length>0&&s(`ol`,{class:`ask-opts`,"aria-label":w()},...e.options.map(e=>s(`li`,{class:`ask-opt`},s(`b`,null,e.title),e.description&&s(`small`,null,e.description)))),t&&U(e)&&s(`small`,{class:`ask-how`},U(e))),K=e=>e.replace(/[\u0000-\u0008\u000b-\u001f\u007f-\u009f\p{Cf}]/gu,`�`),q=e=>(e.select?.choices??[]).map((e,t)=>({...e,i:t})),J=(e,t,n)=>({...e.size?{choices:[...e].sort((e,t)=>e-t)}:{},...t.trim()?{text:t}:{},...n.trim()?{note:n}:{}}),Y=(e,t,n)=>({dialog:e.dialog,digest:e.digest,answerId:n,...t}),X=(e,t)=>({dialog:e.dialog,digest:e.digest,answerId:t,cancel:!0}),Z=(e,t)=>e.cancel===!0&&!(t&&e.select?.choices.every(e=>e.hereOnly)),Q={digest:O,"not-allowed":A,malformed:k};function ne(e,i=!1){let{outcome:a,reason:o,by:s}=e.body;return a===`accepted`?[`ok`,i?h():n()]:a===`stale`?[`error`,s===`local`?R():s===`cancel`?I():L()]:a===`rejected`?[`error`,(Object.hasOwn(Q,String(o))?Q[String(o)]:j)()]:a===`busy`?[`error`,t()]:a===`unknown`||e.status===504?[`error`,r(),!0]:[`error`,o??l({status:e.status})]}var re=e=>[`accepted`,`stale`,`busy`,`unknown`].includes(String(e.body.outcome))||e.status===504,$=e=>e.answer?`d\n${e.answer.dialog}\n${e.answer.digest}`:`c\n${e.callId}\n${e.why??``}`;function ie(e){if(e.dataset.cued)return;e.dataset.cued=`1`;let t=()=>{e.toggleAttribute(`data-more`,e.scrollHeight-e.scrollTop-e.clientHeight>4);for(let t of e.querySelectorAll(`.ask-acts`))t.dataset.cue=f()};for(let n of[`scroll`,`input`])e.addEventListener(n,t,{passive:!0});typeof ResizeObserver<`u`&&new ResizeObserver(t).observe(e),typeof MutationObserver<`u`&&new MutationObserver(t).observe(e,{childList:!0,subtree:!0,characterData:!0}),typeof requestAnimationFrame<`u`&&requestAnimationFrame(t)}function ae(e,t,n=location.hostname!==`127.0.0.1`,l,f,p=F){let m,h,S,C=!1,O=!1,k;for(let e of[`focusin`,`pointerdown`])document.addEventListener(e,e=>h&&!h.el.contains(e.target)&&(h.lost=void 0));let A=(e,t,n,...r)=>(e.dataset.tone=t,e.replaceChildren(n,...r)),j=()=>{if(!h)return;let e=document.activeElement;e&&e!==document.body&&e!==h.lost&&(h.lost=void 0),h.controls.forEach(e=>e.disabled=!C||O||h.done),h.send&&(h.send.disabled=!C||O||h.done||!h.pick()),e&&h.el.contains(e)&&e.disabled&&(h.lost=e);let t=h.lost;t&&!t.disabled&&h.el.contains(t)&&(!document.activeElement||document.activeElement===document.body)&&(t.focus(),h.lost=void 0)};async function I(e,n){[e.sending,O,e.spell]=[!0,!0,!1],j(),A(e.note,``,a());let o=await t(`answer`,n).catch(()=>void 0),u=s(`button`,{type:`button`,class:`cmp-link`},i());u.onclick=()=>void I(e,n);let[d,p,m]=o?ne(o,n.cancel===!0):[`error`,r(),!0];[e.done,e.sending,O,e.busy]=[!o||re(o),!1,!1,o?.body.outcome===`busy`],A(e.note,d,p,...m?[u]:[]);let h=o?.body.outcome===`accepted`?o.body.then:void 0,g=h&&c(h,{key:l?.key??``,command:e.copy,answerId:String(n.answerId??``)});g&&A(e.note,d,`${p} ${g}`),j(),e.note.scrollIntoView?.({block:`nearest`}),f&&o?.body.outcome===`accepted`&&setTimeout(()=>f(!!h&&!g),h&&!g?0:1200)}let L=(e,t,n,r,i)=>{let a=s(`button`,{type:`button`,class:`ask-opt`,role:e,"aria-checked":`false`},s(`b`,i?{"data-n":String(i)}:null,t),...n.filter(Boolean).map(e=>s(`small`,null,e)));return a.onclick=r,a};function R(e,t){let r,i=q(t).map(e=>L(`radio`,K(e.label),[e.note&&K(e.note)],()=>(r=e.i,i.forEach((n,r)=>n.setAttribute(`aria-checked`,String(q(t)[r].i===e.i))),j()),e.i+1)),a=t.select?.copy!==void 0&&s(`button`,{type:`button`,class:`cmp-link`},y());a&&(a.disabled=!navigator.clipboard,a.onclick=()=>void navigator.clipboard.writeText(t.select.copy).then(()=>A(e.note,`ok`,v()),()=>A(e.note,`error`,_())));let o=i.filter((e,r)=>!(n&&q(t)[r].hereOnly));return i.forEach(e=>!o.includes(e)&&(e.disabled=!0)),e.pick=()=>r===void 0?void 0:{choice:r},e.first=H(e.el,[{opts:i,multiple:!1,answered:()=>r!==void 0}],()=>e.send),e.controls=o,[s(`pre`,{class:`ask-title`},K(t.select.title)),s(`div`,{class:`ask-opts`,role:`radiogroup`,"aria-label":g()},...i),s(`div`,{class:`ask-acts`},e.send,e.cancel,a)]}function B(e,t){let n=t.questions.map(()=>({picks:new Set,text:s(`textarea`,{rows:`1`,maxlength:`8192`,class:`ask-own`,placeholder:D(),"aria-label":E()}),note:s(`input`,{type:`text`,maxlength:`2048`,class:`ask-own ask-memo`,placeholder:x(),"aria-label":b()})})),r=[],i=t.questions.map((t,i)=>{let a=n[i],o=t.multiple?`checkbox`:`radio`,c=t.options.map((e,n)=>L(o,e.title,[e.description,e.preview&&ee()],()=>{t.multiple||(a.picks.clear(),a.text.value=``),a.picks.has(n)?a.picks.delete(n):a.picks.add(n),c.forEach((e,t)=>e.setAttribute(`aria-checked`,String(a.picks.has(t)))),j()}));return a.text.oninput=()=>(t.multiple||(a.picks.clear(),c.forEach(e=>e.setAttribute(`aria-checked`,`false`))),j()),e.controls.push(...c,a.text,a.note),r.push({opts:c,multiple:!!t.multiple,own:a.text,note:a.note,answered:()=>a.picks.size>0||a.text.value.trim()!==``}),s(`div`,{class:`ask-one`},t.header&&s(`b`,{class:`ask-head`},t.header),s(`p`,{class:`ask-q`,...t.question.length>W?{"data-long":``}:{}},t.question),s(`div`,{class:`ask-opts`,role:t.multiple?`group`:`radiogroup`,"aria-label":w()},...c),a.text,a.note)});return e.pick=()=>n.every(e=>e.picks.size||e.text.value.trim())?{answers:n.map(e=>J(e.picks,e.text.value,e.note.value))}:void 0,e.first=H(e.el,r,()=>e.send),[...i,s(`div`,{class:`ask-acts`},e.send,e.cancel)]}function V(e){let t=e.asks??(e.ask?[e.ask]:[]),r=t.length>1,i=e.answer,a={copy:i?.select?.copy,key:$(e),el:s(`section`,{class:`ask`}),note:s(`p`,{class:`ask-note`,role:`status`,"aria-live":`polite`}),controls:[],pick:()=>void 0,done:!1,sending:!1};i&&((a.send=s(`button`,{type:`button`,class:`ask-send`},P())).onclick=()=>void(a.pick()&&I(a,Y(i,a.pick(),crypto.randomUUID()))));let c=e.tool===`secret_drop`;i&&!c&&Z(i,n)&&((a.cancel=s(`button`,{type:`button`,class:`ask-cancel`},o())).onclick=()=>void I(a,X(i,crypto.randomUUID())));let f=s(`p`,{class:`ask-term`},e.why&&t.length?e.why:`${r?d():u()} ${r||!t[0]?``:U(t[0])}`.trim()),m=l&&e.tool!==`secret_drop`&&s(`button`,{type:`button`,class:`cmp-link`},p());m&&(m.onclick=l.show);let h=e.answer?.twin&&e.tool&&e.tool!==`dialog`?[s(`p`,{class:`ask-why`},te({tool:e.tool}))]:[];return a.el.append(...h,...i&&!c?i.select?R(a,i):B(a,i):[...t.length?t.map(e=>G(e,r)):[s(`p`,{class:`ask-why`},c?n?M():N():e.why??z())],s(`div`,{class:`ask-acts`},c?s(`p`,{class:`ask-term`},u()):f,m)],a.note),a.cancel&&a.controls.push(a.cancel),a}let Q=(t,n)=>{let r=document.activeElement;h&&h!==n&&(h.focus=h.el.contains(r)?r:void 0),[m,h,S]=[t,n,n?.send?n:S],e.replaceChildren(...n?[n.el]:[]),n&&ie(n.el),j(),n?.focus&&(!document.activeElement||document.activeElement===document.body)&&n.focus.focus()};return{enter(){let e=h&&!h.done?h.first?.():void 0;return!!(e&&!e.disabled&&(e.focus(),1))},cancel(){let e=h&&!h.done?h.cancel:void 0;return!!(e&&!e.disabled&&(e.click(),1))},sending:()=>O,update(e,t){C=t,e&&(k=void clearTimeout(k)),!e&&(h?.done||h?.sending)?k??=setTimeout(()=>(k=void 0,Q()),6e3):e?h&&($(e)===h.key||!e.answer&&(h.done||h.sending)&&e.callId===m?.callId)?((h.busy||h.sending)&&!e.answer?h.spell=!0:h.busy&&h.spell&&e.answer&&([h.done,h.busy]=[!1,!1],A(h.note,``,T())),m=e):Q(e,S?.key===$(e)&&!S.done?S:V(e)):Q(),j()}}}export{ae as t};
@@ -1 +1 @@
1
- import{t as e}from"./rolldown-runtime-DK3Fl9T5.js";import{m as t}from"./towermodel-DJLQh2fz.js";import{t as n}from"./runtime-ZX6HkxDa.js";import{n as r}from"./post-DDdE-PdN.js";import{Ct as i}from"./index-Pr0dJgxC.js";var a=((e={},t={})=>(t.locale??n())===`zh-TW`?`沒有符合這個號碼的請求。`:`No request has that number.`),o=((e={},t={})=>(t.locale??n())===`zh-TW`?`這個請求已經不在了。`:`That request is gone.`),s=((e={},t={})=>(t.locale??n())===`zh-TW`?`連續輸入三次錯誤號碼,所以所有等待中的請求都已拒絕。請按「新的配對碼」重新配對。`:`Three wrong numbers in a row, so every waiting request was denied. Press New code and pair again.`),c=((e={},t={})=>(t.locale??n())===`zh-TW`?`這個請求已經變了,請重新看過。`:`That request changed. Look at it again.`),l=((e={},t={})=>(t.locale??n())===`zh-TW`?`這個請求已經不在了,或已逾時。`:`That request is gone or has timed out.`),u=((e={},t={})=>(t.locale??n())===`zh-TW`?`這個團隊沒有在這台裝置上執行。`:`That team is not running on this device.`),d=((e={},t={})=>(t.locale??n())===`zh-TW`?`已在該裝置上取消。`:`It was cancelled at the device.`),f=((e={},t={})=>(t.locale??n())===`zh-TW`?`你已從這裡回答。`:`You answered it from here.`),p=((e={},t={})=>(t.locale??n())===`zh-TW`?`已在該裝置上回答。`:`Answered at the device itself.`),m=((e={},t={})=>(t.locale??n())===`zh-TW`?`已由團隊的另一個控制端回答。`:`Answered by another controller of this team.`),h=e=>`The answer was not sent: ${e?.reason}`,g=e=>`答案沒有送出:${e?.reason}`,_=((e,t={})=>(t.locale??n())===`zh-TW`?g(e):h(e)),v=((e={},t={})=>(t.locale??n())===`zh-TW`?`問題在有人回答前就結束了。`:`It ended before anyone answered it.`),y=((e={},t={})=>(t.locale??n())===`zh-TW`?`已送出你的答案;對方裝置還沒關閉這個問題。`:`Your answer was sent; the device has not closed the question yet.`),b=((e={},t={})=>(t.locale??n())===`zh-TW`?`你已不再負責回答這台裝置的問題;問題在那邊仍未結束。`:`You no longer answer this device's questions; it is still open there.`);function x(e){switch(e){case`sent`:return y();case`done-here`:return f();case`done-other`:return m();case`done-local`:return p();case`cancelled`:return d();case`expired`:return v();case`withdrawn`:return b()}}var S=e=>typeof e==`object`&&!!e&&!Array.isArray(e),C=e=>typeof e==`string`,w=e=>Array.isArray(e)&&e.every(e=>S(e)&&C(e.title));function T(e){let{dialog:t,dialogId:n,digest:r}=e.data;if(!C(t)||!C(n)||!C(r))return;let i;try{i=JSON.parse(t)}catch{return}if(!S(i))return;let{select:a,questions:o,cancel:s}=i,c={dialog:n,digest:r,...s===!0?{cancel:!0}:{}};if(S(a)&&C(a.title)&&Array.isArray(a.choices)&&a.choices.every(e=>S(e)&&C(e.label)))return{callId:n,tool:`dialog`,answer:{...c,select:a}};if(Array.isArray(o)&&o.length>0&&o.every(e=>S(e)&&C(e.question)&&w(e.options)))return{callId:n,tool:`dialog`,answer:{...c,questions:o}}}var E=e=>e.cancel===!0?{cancel:!0}:e.choice===void 0?{answers:e.answers}:{choice:e.choice},D=e({confirmActions:()=>M,confirmWhy:()=>N,forwardedAnswer:()=>P,joined:()=>k,lanActions:()=>I,lanReading:()=>L,outcome:()=>O,proposalActions:()=>F,taken:()=>j,waitActions:()=>A}),O=e=>{let t=e.body.outcome;return t===void 0?e.status===504?`unknown`:e.ok&&(e.body.accepted===!0||Array.isArray(e.body.entries))?`accepted`:`refused`:t===`accepted`?`accepted`:t===`unknown`?`unknown`:`refused`},k=e=>e.replace(/^([A-Z])(?=[a-z])/,e=>e.toLowerCase()),A=(e,n)=>({tell:t=>n(`input`,{text:t,as:`send`,answers:e.id}),dismiss:()=>r(`${t(e.ws)}/memory`,{op:`drop`,id:e.id}),goto:{view:`session`,ws:e.ws,key:e.tower}}),j=e=>e.ok&&e.body.outcome===void 0?{...e,body:{...e.body,outcome:`accepted`}}:e,M=e=>{let t=t=>r(`link/confirm-answer`,{dialogId:e.dialogId,digest:e.digest,allow:t}).then(j);return{allow:()=>t(!0),deny:()=>t(!1)}},N=e=>{let t=String(e.body.reason??e.body.error??``);return[[/^That request is gone/,l],[/^That team is not running/,u],[/^That request changed/,c]].find(([e])=>e.test(t))?.[1]()??(t||i({status:e.status}))},P=e=>async(t,n)=>{let a=await r(`link/dialog-answer`,{device:e.device,dialogId:e.dialogId,digest:e.digest,answer:E(n)});return a.ok?j(a):{ok:!1,status:a.status,body:{reason:_({reason:a.body.reason??i({status:a.status})})}}},F=e=>({confirm:()=>r(`${t(e.ws)}/memory`,{op:`confirm`,proposal:e.id,rev:e.rev()}),reject:()=>r(`${t(e.ws)}/memory`,{op:`reject`,proposal:e.id})}),I=e=>({approve:t=>e(`lan/approve`,{number:t}).then(j),deny:t=>e(`lan/approve`,{deny:t}).then(e=>e.ok&&e.body.denied===0?{...e,ok:!1,body:{error:`gone`,reason:o()}}:j(e)),denyAll:()=>e(`lan/approve`,{deny:`all`}).then(j)});function L(e){let t=!e.ok&&e.body.error===`no_match`&&Number(e.body.denied)>0;return{answer:e.ok||t?``:e.body.error===`no_match`?a():String(e.body.reason??i({status:e.status})),verdict:t?s():``}}export{k as a,O as c,x as d,T as f,P as i,F as l,M as n,I as o,N as r,L as s,D as t,A as u};
1
+ import{t as e}from"./rolldown-runtime-DK3Fl9T5.js";import{m as t}from"./towermodel-CAbNR8ZT.js";import{t as n}from"./runtime-ZX6HkxDa.js";import{n as r}from"./post-DDdE-PdN.js";import{yt as i}from"./index-D4RgSZfB.js";var a=((e={},t={})=>(t.locale??n())===`zh-TW`?`沒有符合這個號碼的請求。`:`No request has that number.`),o=((e={},t={})=>(t.locale??n())===`zh-TW`?`這個請求已經不在了。`:`That request is gone.`),s=((e={},t={})=>(t.locale??n())===`zh-TW`?`連續輸入三次錯誤號碼,所以所有等待中的請求都已拒絕。請按「新的配對碼」重新配對。`:`Three wrong numbers in a row, so every waiting request was denied. Press New code and pair again.`),c=((e={},t={})=>(t.locale??n())===`zh-TW`?`這個請求已經變了,請重新看過。`:`That request changed. Look at it again.`),l=((e={},t={})=>(t.locale??n())===`zh-TW`?`這個請求已經不在了,或已逾時。`:`That request is gone or has timed out.`),u=((e={},t={})=>(t.locale??n())===`zh-TW`?`這個團隊沒有在這台裝置上執行。`:`That team is not running on this device.`),d=((e={},t={})=>(t.locale??n())===`zh-TW`?`已在該裝置上取消。`:`It was cancelled at the device.`),f=((e={},t={})=>(t.locale??n())===`zh-TW`?`你已從這裡回答。`:`You answered it from here.`),p=((e={},t={})=>(t.locale??n())===`zh-TW`?`已在該裝置上回答。`:`Answered at the device itself.`),m=((e={},t={})=>(t.locale??n())===`zh-TW`?`已由團隊的另一個控制端回答。`:`Answered by another controller of this team.`),h=e=>`The answer was not sent: ${e?.reason}`,g=e=>`答案沒有送出:${e?.reason}`,_=((e,t={})=>(t.locale??n())===`zh-TW`?g(e):h(e)),v=((e={},t={})=>(t.locale??n())===`zh-TW`?`問題在有人回答前就結束了。`:`It ended before anyone answered it.`),y=((e={},t={})=>(t.locale??n())===`zh-TW`?`已送出你的答案;對方裝置還沒關閉這個問題。`:`Your answer was sent; the device has not closed the question yet.`),b=((e={},t={})=>(t.locale??n())===`zh-TW`?`你已不再負責回答這台裝置的問題;問題在那邊仍未結束。`:`You no longer answer this device's questions; it is still open there.`);function x(e){switch(e){case`sent`:return y();case`done-here`:return f();case`done-other`:return m();case`done-local`:return p();case`cancelled`:return d();case`expired`:return v();case`withdrawn`:return b()}}var S=e=>typeof e==`object`&&!!e&&!Array.isArray(e),C=e=>typeof e==`string`,w=e=>Array.isArray(e)&&e.every(e=>S(e)&&C(e.title));function T(e){let{dialog:t,dialogId:n,digest:r}=e.data;if(!C(t)||!C(n)||!C(r))return;let i;try{i=JSON.parse(t)}catch{return}if(!S(i))return;let{select:a,questions:o,cancel:s}=i,c={dialog:n,digest:r,...s===!0?{cancel:!0}:{}};if(S(a)&&C(a.title)&&Array.isArray(a.choices)&&a.choices.every(e=>S(e)&&C(e.label)))return{callId:n,tool:`dialog`,answer:{...c,select:a}};if(Array.isArray(o)&&o.length>0&&o.every(e=>S(e)&&C(e.question)&&w(e.options)))return{callId:n,tool:`dialog`,answer:{...c,questions:o}}}var E=e=>e.cancel===!0?{cancel:!0}:e.choice===void 0?{answers:e.answers}:{choice:e.choice},D=e({confirmActions:()=>M,confirmWhy:()=>N,forwardedAnswer:()=>P,joined:()=>k,lanActions:()=>I,lanReading:()=>L,outcome:()=>O,proposalActions:()=>F,taken:()=>j,waitActions:()=>A}),O=e=>{let t=e.body.outcome;return t===void 0?e.status===504?`unknown`:e.ok&&(e.body.accepted===!0||Array.isArray(e.body.entries))?`accepted`:`refused`:t===`accepted`?`accepted`:t===`unknown`?`unknown`:`refused`},k=e=>e.replace(/^([A-Z])(?=[a-z])/,e=>e.toLowerCase()),A=(e,n)=>({tell:t=>n(`input`,{text:t,as:`send`,answers:e.id}),press:(n,i)=>r(`${t(e.ws)}/memory`,{op:`press`,id:e.id,act:n,...i}),read:()=>r(`${t(e.ws)}/memory`,{op:`read`}),goto:{view:`session`,ws:e.ws,key:e.tower}}),j=e=>e.ok&&e.body.outcome===void 0?{...e,body:{...e.body,outcome:`accepted`}}:e,M=e=>{let t=t=>r(`link/confirm-answer`,{dialogId:e.dialogId,digest:e.digest,allow:t}).then(j);return{allow:()=>t(!0),deny:()=>t(!1)}},N=e=>{let t=String(e.body.reason??e.body.error??``);return[[/^That request is gone/,l],[/^That team is not running/,u],[/^That request changed/,c]].find(([e])=>e.test(t))?.[1]()??(t||i({status:e.status}))},P=e=>async(t,n)=>{let a=await r(`link/dialog-answer`,{device:e.device,dialogId:e.dialogId,digest:e.digest,answer:E(n)});return a.ok?j(a):{ok:!1,status:a.status,body:{reason:_({reason:a.body.reason??i({status:a.status})})}}},F=e=>({confirm:()=>r(`${t(e.ws)}/memory`,{op:`confirm`,proposal:e.id,rev:e.rev()}),reject:()=>r(`${t(e.ws)}/memory`,{op:`reject`,proposal:e.id})}),I=e=>({approve:t=>e(`lan/approve`,{number:t}).then(j),deny:t=>e(`lan/approve`,{deny:t}).then(e=>e.ok&&e.body.denied===0?{...e,ok:!1,body:{error:`gone`,reason:o()}}:j(e)),denyAll:()=>e(`lan/approve`,{deny:`all`}).then(j)});function L(e){let t=!e.ok&&e.body.error===`no_match`&&Number(e.body.denied)>0;return{answer:e.ok||t?``:e.body.error===`no_match`?a():String(e.body.reason??i({status:e.status})),verdict:t?s():``}}export{k as a,O as c,x as d,T as f,P as i,F as l,M as n,I as o,N as r,L as s,D as t,A as u};
@@ -0,0 +1,53 @@
1
+ // The first frame's view, before the body exists (docs/specs/2026-11-07-raven-view/spec.md §1.2). A classic script with no imports, so it blocks nothing but the parser: the page entry's module has not run yet.
2
+ // It resolves the device's view as gui/view.ts does on a fresh load (the stored choice, then the server's default in <meta name="sb-view">, then prefers-contrast; `held` and `zen-away` cannot exist yet), puts it on <html> as data-view, sets the
3
+ // theme-color and the tab icon, and, when the view is a theme whose stylesheet the server did not already link, writes that link (parser-inserted, so it blocks the first paint). tests/view.test.ts runs this file against view.ts's `resolve`.
4
+ // The theme map is <meta name="sb-themes"> (the build writes it into index.html). Anything wrong here (no storage, no map) leaves the page as the server wrote it: main.ts corrects the view and loads the theme as today.
5
+ (function () {
6
+ var d = document, root = d.documentElement;
7
+ function meta(name) {
8
+ var m = d.querySelector('meta[name="' + name + '"]');
9
+ return m ? m.getAttribute("content") : null;
10
+ }
11
+ var themes = {};
12
+ try {
13
+ themes = JSON.parse(meta("sb-themes") || "{}") || {};
14
+ } catch (e) {}
15
+ var names = ["standard"];
16
+ for (var k in themes) if (Object.prototype.hasOwnProperty.call(themes, k)) names.push(k);
17
+ /** A name of a view, anything else is Auto. */
18
+ function choice(value) {
19
+ return typeof value === "string" && names.indexOf(value) >= 0 ? value : "auto";
20
+ }
21
+ /** gui/view.ts `resolve(choiceOf(stored), contrast, choiceOf(server))`. */
22
+ function resolve(stored, contrast, server) {
23
+ var own = choice(stored), shared = choice(server);
24
+ if (own !== "auto") return own;
25
+ if (shared !== "auto") return shared;
26
+ return contrast && names.indexOf("geek") >= 0 ? "geek" : "standard";
27
+ }
28
+ // The theme-color of each view that has one of its own (gui/view.ts THEME); Standard keeps the color the page came with.
29
+ var colors = { geek: "#000000", zen: "#14110e", raven: "#0d0a10" };
30
+ globalThis.sbBoot = { resolve: resolve, colors: colors };
31
+ try {
32
+ var stored = null;
33
+ try {
34
+ stored = localStorage.getItem("sb.view");
35
+ } catch (e) {} // storage refused: the screen and the server decide
36
+ var view = resolve(stored, matchMedia("(prefers-contrast: more)").matches, meta("sb-view"));
37
+ root.dataset.view = view;
38
+ var theme = themes[view];
39
+ if (colors[view]) {
40
+ var bar = d.querySelector('meta[name="theme-color"]');
41
+ if (bar) bar.setAttribute("content", colors[view]);
42
+ }
43
+ var icon = d.querySelector('link[rel="icon"]');
44
+ if (icon && !(theme && theme.icon) && icon.hasAttribute("data-standard")) icon.setAttribute("href", icon.getAttribute("data-standard")); // the server wrote its default's icon; this device's view has none
45
+ if (theme && theme.icon) {
46
+ if (icon) {
47
+ if (!icon.hasAttribute("data-standard")) icon.setAttribute("data-standard", icon.getAttribute("href") || ""); // main.ts draws Standard's icon from it
48
+ icon.setAttribute("href", theme.icon);
49
+ }
50
+ }
51
+ if (theme && theme.css && !d.querySelector('link[data-theme="' + view + '"]')) d.write('<link rel="stylesheet" data-theme="' + view + '" href="' + theme.css + '">');
52
+ } catch (e) {}
53
+ })();
@@ -0,0 +1,2 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./index-BVjKruBA.css"])))=>i.map(i=>d[i]);
2
+ import{r as e}from"./towermodel-CAbNR8ZT.js";import{t}from"./runtime-ZX6HkxDa.js";import{n,r}from"./markdown-Dz6BWlns.js";import{i,n as a,r as o,t as s}from"./towerturns-BsduFBNn.js";import{B as c,X as l,Y as u,_ as d,at as f,s as p,st as ee,x as m}from"./index-D4RgSZfB.js";var te=((e={},n={})=>(n.locale??t())===`zh-TW`?`可能已被當機的 run 處理過:動手前先確認。`:`A run that crashed may already have handled this: check before acting.`),ne=((e={},n={})=>(n.locale??t())===`zh-TW`?`分支摘要`:`branch summary`),re=((e={},n={})=>(n.locale??t())===`zh-TW`?`通訊紀錄`:`Comms log`),h=e=>`context compacted · ${e?.tokens} tokens summarized`,ie=e=>`上下文已壓縮 · 摘要了 ${e?.tokens} tokens`,ae=((e,n={})=>(n.locale??t())===`zh-TW`?ie(e):h(e)),oe=((e={},n={})=>(n.locale??t())===`zh-TW`?`…(於 1 MB 截斷)`:`… (cut at 1 MB)`),g=e=>`exit ${e?.code}`,_=e=>`結束碼 ${e?.code}`,se=((e,n={})=>(n.locale??t())===`zh-TW`?_(e):g(e)),v=e=>`New chapter · ${e?.date} · ${e?.why}`,y=e=>`新的一章・${e?.date}・${e?.why}`,ce=((e,n={})=>(n.locale??t())===`zh-TW`?y(e):v(e)),b=((e={},n={})=>(n.locale??t())===`zh-TW`?`第一次對話`:`the first conversation`),x=((e={},n={})=>(n.locale??t())===`zh-TW`?`你要求開新對話`:`you asked for a new conversation`),S=((e={},n={})=>(n.locale??t())===`zh-TW`?`上一章太長了`:`the last one grew too large`),C=((e={},n={})=>(n.locale??t())===`zh-TW`?`上一章無法接續`:`the last one could not be resumed`),w=e=>`Image ${e?.n}`,T=e=>`圖片 ${e?.n}`,le=((e,n={})=>(n.locale??t())===`zh-TW`?T(e):w(e)),ue=((e={},n={})=>(n.locale??t())===`zh-TW`?`圖片無法讀取`:`Image unavailable`),E=e=>`${e?.count} image(s)`,D=e=>`${e?.count} 張圖片`,de=((e,n={})=>(n.locale??t())===`zh-TW`?D(e):E(e)),fe=((e={},n={})=>(n.locale??t())===`zh-TW`?`收到`:`incoming`),O=((e={},n={})=>(n.locale??t())===`zh-TW`?`跳到最新`:`jump to latest`),k=e=>`${e?.count} new`,A=e=>`${e?.count} 則新訊息`,j=((e,n={})=>(n.locale??t())===`zh-TW`?A(e):k(e)),pe=((e={},n={})=>(n.locale??t())===`zh-TW`?`還沒有通訊。`:`No transmissions yet.`),me=((e={},n={})=>(n.locale??t())===`zh-TW`?`通知`:`notice`),he=((e={},n={})=>(n.locale??t())===`zh-TW`?`細節`:`details`),M=((e={},n={})=>(n.locale??t())===`zh-TW`?`表單回覆`:`form answers`),ge=((e={},n={})=>(n.locale??t())===`zh-TW`?`訊息,來自`:`message from`),N=e=>`answer from ${e?.from}`,P=e=>`${e?.from} 的回答`,_e=((e,n={})=>(n.locale??t())===`zh-TW`?P(e):N(e)),F=e=>`request from ${e?.from}`,I=e=>`${e?.from} 的請求`,ve=((e,n={})=>(n.locale??t())===`zh-TW`?I(e):F(e)),L=e=>`message from ${e?.from}`,R=e=>`${e?.from} 的訊息`,ye=((e,n={})=>(n.locale??t())===`zh-TW`?R(e):L(e)),be=e=>`reply to your ask from ${e?.from}`,z=e=>`${e?.from} 回覆了你的詢問`,xe=((e,n={})=>(n.locale??t())===`zh-TW`?z(e):be(e)),B=((e={},n={})=>(n.locale??t())===`zh-TW`?`記憶`:`memory`),V=((e={},n={})=>(n.locale??t())===`zh-TW`?`監看`:`monitor`),Se=((e={},n={})=>(n.locale??t())===`zh-TW`?`本機`:`this computer`),Ce=((e={},n={})=>(n.locale??t())===`zh-TW`?`隊友`:`teammate`),we=((e={},n={})=>(n.locale??t())===`zh-TW`?`提問,來自`:`question from`),H=((e={},n={})=>(n.locale??t())===`zh-TW`?`回報,來自`:`report from`),Te=((e={},n={})=>(n.locale??t())===`zh-TW`?`sb server 的通知`:`notice from the sb server`),Ee=((e={},n={})=>(n.locale??t())===`zh-TW`?`狀態:`:`status of`),U=((e={},n={})=>(n.locale??t())===`zh-TW`?`Straw Link 訊息`:`Straw Link message`),De=((e={},n={})=>(n.locale??t())===`zh-TW`?`喚醒鬧鐘`:`wake-up call`),W=((e={},n={})=>(n.locale??t())===`zh-TW`?`塔台事件`:`tower event`),Oe=((e={},n={})=>(n.locale??t())===`zh-TW`?`在旁開啟`:`open beside`),ke=e=>`Open image ${e?.n}`,G=e=>`打開圖片 ${e?.n}`,Ae=((e,n={})=>(n.locale??t())===`zh-TW`?G(e):ke(e)),K=e=>`show all (${e?.size})`,q=e=>`顯示全部(${e?.size})`,je=((e,n={})=>(n.locale??t())===`zh-TW`?q(e):K(e)),Me=((e={},n={})=>(n.locale??t())===`zh-TW`?`顯示全部參數`:`show all arguments`),J=e=>`◇ thought · ${e?.count} chars`,Y=e=>`◇ 思考 · ${e?.count} 字元`,Ne=((e,n={})=>(n.locale??t())===`zh-TW`?Y(e):J(e)),Pe=((e={},n={})=>(n.locale??t())===`zh-TW`?`◇ 思考 · 已遮蔽`:`◇ thought · redacted`),Fe=((e={},n={})=>(n.locale??t())===`zh-TW`?`這座塔台正在待命。有訊息進來時,sb server 會喚醒它跑一個 run;你在這裡送出的第一則訊息就會啟動它。`:`This tower stands by. The sb server wakes it for a run when a message arrives; your first message here starts that run.`),Ie=((e={},n={})=>(n.locale??t())===`zh-TW`?`無法取得`:`unavailable`);function Le(){let e=!0,t=0,n=!0,r=0;return{get pinned(){return e},scrolled(r){r!==n&&(n=e=r,r&&(t=0))},parked:e=>void(r=e),moved(i,a){let o=i-r;return r=i,o<-.5&&e&&a()-i>1?!(e=!1):o!==0&&!e&&n&&a()-i<=1&&(e=!0,t=0,!0)},hold:()=>void(n=e=!1),arrived(n){return e||(t+=n),e},jump:()=>void(n=e=!0,t=0),button:n=>e&&!n?void 0:t&&!n?j({count:t}):O()}}async function Re(e,t,n,r){let i=()=>e.items.some(e=>e.id===n);for(;!i()&&e.before;)r(e.prepend(await t.older(e.before)));return i()?!0:(r(e.reset(await t.latest())),!1)}function ze(e=600){let t=[],n,r=!1,i=new Set,a=new Map,o=new Map,s=e=>e.forEach(e=>(i.delete(e.id),e.tools?.forEach(e=>(o.delete(e.id),a.delete(e.id)))));function c(e,t){let n=[];for(let r of e)i.has(r.id)||(i.add(r.id),r.kind===`result`&&r.callId?(a.set(r.callId,r),o.has(r.callId)&&t.add(o.get(r.callId))):(r.tools?.forEach(e=>o.set(e.id,r.id)),n.push(r)));return n}let l=e=>({rebuild:!1,added:[],touched:[],dropped:[],front:!1,...e});return{get items(){return t},get before(){return n},get detached(){return r},result:e=>a.get(e),reset(e){return[t,n,r]=[[],e.before,!1],i.clear(),a.clear(),o.clear(),t=c(e.items,new Set),l({rebuild:!0,added:t})},append(i){if(r)return l({});let a=new Set,o=c(i,a);t.push(...o);let u=t.length>e?t.splice(0,t.length-e):[];return s(u),u.length&&(n=t[0].id),l({added:o,touched:[...a],dropped:u.map(e=>e.id)})},prepend(i){let a=new Set,o=c(i.items,a);t.unshift(...o),n=i.before;let u=t.length>e?t.splice(e):[];return s(u),u.length&&(r=!0),l({added:o,touched:[...a],dropped:u.map(e=>e.id),front:!0})}}}var Be=(e,t)=>({first:b,new:x,size:S,unreadable:C})[e??``]?.()??t??``,Ve=e=>e.head?u(`head_tower`):m(e.role),He=e=>e?new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`,hour12:!1}):``,Ue=e=>e>=1024?`${(e/1024).toFixed(e>=10240?0:1)} KB`:`${e} B`,We={intercom_message:ge,subagent_result:H,subagent_ping:we,subagent_status:Ee,"pi-loop-monitor":V,"memory-context":B,"doc-review":M,"straw-tower":W,"straw-link":U},X=e=>{let t=d(`<span class="ava"><svg><use/></svg></span>`),n=t.querySelector(`use`),r=p[e]??e;return n.dataset.icon=r,n.setAttribute(`href`,l(r)),t};function Ge(e){let t=[],n=0;for(let r of e.matchAll(/https?:\/\/[^\s<>)\]]+/g))t.push(e.slice(n,r.index),f(`a`,{href:r[0],rel:`noopener noreferrer`,target:`_blank`},r[0])),n=r.index+r[0].length;return[...t,e.slice(n)]}function Z(l,d,{who:p,link:m,docFor:h,page:ie}){let g=ze(),_=new Map,v=new Set,y=()=>v.forEach(e=>e.button.isConnected?(e.shown=!0,e.button.hidden=!e.paths.some(e=>h?.(e))):e.shown&&v.delete(e)),b=f(`div`,{class:`chat-list`}),x=f(`div`,{class:`chat-top`}),S=f(`div`,{class:`chat-end`}),C=f(`button`,{class:`chat-pill`,type:`button`,hidden:``}),w=f(`p`,{class:`chat-empty`},pe()),T=f(`div`,{class:`chat-scroll`,tabindex:`-1`,"aria-label":re()},x,b,S);l.replaceChildren(T,C);let E=Le(),D=!1,O=!1,k,A,j=0,M=!1,N,P=()=>M||N!==void 0,F=()=>(clearTimeout(N),N=setTimeout(()=>(N=void 0,E.pinned&&!g.detached&&R()),250)),I=(e=E.button(g.detached))=>(C.hidden=!e,C.textContent=e??``),L=()=>(T.scrollTop=T.scrollHeight,E.parked(T.scrollTop)),R=()=>(E.jump(),A=void 0,L(),I());async function be(e){D=!0;let t=await Re(g,d,e,e=>(J(e),Q(e))).finally(()=>D=!1),n=_.get(e);if(k===e){if(!t||!n)return R();E.hold(),A=n,n.scrollIntoView({block:`center`}),ee(n,`lit`),clearTimeout(j),j=window.setTimeout(()=>(A=void 0,n.classList.remove(`lit`)),2e3),I()}}let z=()=>k?void be(k):R(),B=(e,t,n,r)=>{e.disabled=!0,d.entry(n).then(n=>{let i=n&&r(n);if(i===void 0)return void(e.textContent=Ie());t.textContent=i,e.remove()},()=>e.textContent=Ie())};function V(e,t=0){if(!t||!d.pic)return null;let n=Array.from({length:t},(t,n)=>d.pic(e,n));return f(`div`,{class:`pics`},...n.map((e,t)=>{let r=f(`img`,{src:e,alt:le({n:t+1}),loading:`lazy`,decoding:`async`}),i=f(`button`,{type:`button`,class:`pic`,"aria-label":Ae({n:t+1})},r);return r.addEventListener(`error`,()=>i.replaceWith(f(`em`,{class:`pic-gone`},ue()))),i.addEventListener(`click`,()=>void c(async()=>{let{lightbox:e}=await import(`./lightbox-VOqxxDbY.js`);return{lightbox:e}},__vite__mapDeps([0]),import.meta.url).then(({lightbox:e})=>e(n,t))),i}))}function we(e,t){let n=g.result(e.id),r=f(`pre`,{class:`out`},n?.text??``),i=f(`pre`,{class:`args`},e.args??``),a=e.cut?f(`button`,{class:`more`,type:`button`},Me()):null;a?.addEventListener(`click`,()=>B(a,i,t,t=>(e=>e&&`${e.args??``}${e.cut?`\n${oe()}`:``}`)(t.tools?.find(t=>t.id===e.id))));let o=n?.more?f(`button`,{class:`more`,type:`button`},je({size:Ue(n.bytes??0)})):null;o?.addEventListener(`click`,()=>B(o,r,n.id,e=>e.text));let s=e.name===`show_doc`&&h?f(`button`,{class:`more open`,type:`button`,hidden:``},Oe()):null;s?.addEventListener(`click`,t=>(t.preventDefault(),e.summary.split(`, `).forEach(e=>h?.(e)?.()))),s&&v.add({paths:e.summary.split(`, `),button:s}),s&&queueMicrotask(y);let c=f(`details`,{class:`act`},f(`summary`,{"data-mark":n?n.isError?`error`:`done`:`working`},f(`b`,{class:`badge`}),f(`code`,null,e.name),f(`span`,{class:`sum`},e.summary),s),i,a,n&&f(`div`,{class:`result`},n.images?f(`em`,null,de({count:n.images})):null,r,o)),l=n&&V(n.id,n.images);return l?[c,l]:[c]}let H=e=>f(`time`,null,He(e.at)),Ee=(e,t,n,r)=>f(`article`,{class:`tx you`},f(`header`,null,H(e),f(`b`,null,u(`you`)),X(`user`)),f(`div`,{class:`bubble`,title:r},n?f(`small`,{class:`boss-flag`},te()):null,...Ge(t),V(e.id,e.images))),U=(e,t,n,r={})=>f(`article`,{class:`tx sys`},f(`details`,{class:`notice`},f(`summary`,null,X(`comms`),f(`em`,null,fe()),...t,H(e)),r.crashed?f(`small`,{class:`boss-flag`},te()):null,f(`pre`,null,n),r.raw?f(`details`,{class:`notice-raw`},f(`summary`,null,he()),f(`pre`,{class:`raw`},r.raw)):null)),W=e=>{let t=i(e);return[ge(),` `,t.name&&m(t.name)||t.name,t.id?` (${t.id})`:``,` · `,Se()]},ke=e=>e.kind===`link`?[{ask:ve,reply:xe,answer:_e,message:ye}[e.what]({from:e.from}),` · `,Ce()]:e.kind===`intercom`?W(e.from):[e.kind===`server`?Te():De()],G=()=>ie===!0&&p().head===!0,K=()=>f(`article`,{class:`tx skip`,hidden:``});function q(e){switch(e.kind){case`user`:{let t=p().service?o(e.text):void 0;if(t)return U(e,t.kind===`intercom`?W(t.from):[t.kind===`server`?Te():De()],e.text??``);let n=p().service?s(e.text):void 0;return Ee(e,n?n.body:e.text??``,n?.crashed,n?e.text??``:``)}case`assistant`:{let t=p();if(G()&&!e.text&&!e.thought&&!e.error&&!e.stop)return K();let i=f(`pre`,{class:`thought-text`}),a=e.thought?f(`button`,{class:`thought`,type:`button`},e.thought<0?Pe():Ne({count:e.thought.toLocaleString()})):null;return e.thought&&e.thought>0&&a?.addEventListener(`click`,()=>B(a,i,e.id,e=>e.thoughtText)),f(`article`,{class:t.head?`tx in head`:`tx in`},X(t.head?`crown`:t.role),f(`div`,{class:`tx-body`},f(`header`,null,f(`b`,null,Ve(t)),e.model?f(`span`,null,e.model):null,H(e),e.stop?f(`span`,{class:`stop`,"data-mark":`error`},e.stop):null),a,i,e.text?f(`div`,{class:`md`},n(r(e.text))):null,e.error?f(`p`,{class:`fault`},e.error):null,...(G()?[]:e.tools??[]).flatMap(t=>we(t,e.id))))}case`bash`:return G()?K():f(`article`,{class:`tx sys`},f(`details`,{class:`act`},f(`summary`,{"data-mark":e.exit?`error`:`done`},f(`b`,{class:`badge`}),f(`code`,null,`shell`),f(`span`,{class:`sum`},`! ${e.command}`),e.exit?f(`span`,{class:`stop`,"data-mark":`error`},se({code:e.exit})):null),e.text?f(`pre`,{class:`out`},e.text):null));case`notice`:{let t=a(e);return t?.kind===`boss`&&p().service?Ee(e,t.body,t.crashed,e.text??``):G()&&(t?.kind===`server`||t?.kind===`timer`)?K():t&&t.kind!==`boss`?U(e,ke(t),t.body,t.kind===`link`?{raw:t.raw}:{crashed:t.crashed}):U(e,[We[e.type??``]?.()??e.type??me(),` `,e.from&&m(e.from)||(e.from??``)],e.text??``)}case`divider`:return e.type===`chapter`?f(`article`,{class:`tx rule chapter`},f(`p`,null,ce({date:e.at?new Date(e.at).toLocaleDateString(t(),{year:`numeric`,month:`short`,day:`numeric`}):``,why:Be(e.code,e.text)}))):f(`article`,{class:`tx rule`},f(`details`,null,f(`summary`,null,e.type===`compaction`?ae({tokens:(e.tokens??0).toLocaleString()}):ne()),f(`pre`,null,e.text??``)));default:return f(`article`,{class:`tx note`},e.text??``,` `,H(e))}}function J(e){e.rebuild&&(_.clear(),b.replaceChildren());for(let t of e.dropped)_.get(t)?.remove(),_.delete(t);let t=e.added.map(e=>(_.set(e.id,q(e)),_.get(e.id)));e.front?b.prepend(...t):b.append(...t),O&&!e.front&&!e.rebuild&&t.forEach(e=>(e.classList.add(`fresh`),e.dataset.born=String(Date.now()))),w.remove();let n=p().service;w.textContent=n?.state===`standing`&&!n.run?Fe():pe(),g.items.length||b.append(w),x.hidden=!g.before,Ke()}let Y=[],Z=new Map;function Ke(){let t=new Set;for(let n of Y){let r=Date.parse(n.startedAt),i=g.items.findIndex(e=>e.at!==void 0&&Date.parse(e.at)>=r);if(i===0&&g.before)continue;let a=i<0?``:g.items[i].id,o=JSON.stringify([a,e(n)]),s=Z.get(n.id);if(t.add(n.id),s&&s.sig===o&&s.el.isConnected)continue;s?.el.remove();let c=e(n),l=f(`article`,{class:`tx rule conv-rule`},f(`div`,null,f(`b`,null,c.title),c.ended?f(`small`,null,c.ended):null));Z.set(n.id,{el:l,sig:o});let u=a?_.get(a):void 0;u?u.before(l):b.append(l)}for(let[e,n]of Z)t.has(e)||(n.el.remove(),Z.delete(e))}let Q=e=>e.touched.forEach(e=>{let t=_.get(e),n=g.items.find(t=>t.id===e);if(t&&n){let r=q(n);t.classList.contains(`fresh`)&&Date.now()-Number(t.dataset.born??0)<400&&r.classList.add(`fresh`),t.replaceWith(r),_.set(e,r)}}),qe=async()=>{if(!D&&g.before&&O){D=!0;try{let e=T.scrollHeight,t=g.prepend(await d.older(g.before));J(t),Q(t),T.scrollTop+=T.scrollHeight-e}finally{D=!1}g.before&&T.clientHeight&&x.getBoundingClientRect().bottom>=T.getBoundingClientRect().top&&qe()}};C.addEventListener(`click`,()=>{k=void 0,g.detached?d.latest().then(e=>(J(g.reset(e)),R())):R()});let Je=[new IntersectionObserver(e=>e.some(e=>e.isIntersecting)&&void qe(),{root:T}),new IntersectionObserver(e=>T.clientHeight&&(E.scrolled(e.at(-1).isIntersecting),I()),{root:T,rootMargin:`0px 0px 67px`})],$,Ye=()=>($??(Je[0].observe(x),Je[1].observe(S)),clearTimeout($),$=setTimeout(()=>($=void 0,Je.forEach(e=>e.disconnect())),600));T.addEventListener(`scroll`,()=>(Ye(),E.moved(T.scrollTop,()=>T.scrollHeight-T.clientHeight)&&I(),!M&&N!==void 0&&F()),{passive:!0}),T.addEventListener(`wheel`,e=>e.deltaY<0&&F(),{passive:!0}),T.addEventListener(`keydown`,e=>([`ArrowUp`,`PageUp`,`Home`].includes(e.key)||e.key===` `&&e.shiftKey)&&F(),{passive:!0}),T.addEventListener(`touchstart`,()=>(M=!0,clearTimeout(N),N=void 0),{passive:!0});for(let e of[`touchend`,`touchcancel`])T.addEventListener(e,()=>(M=!1,F()),{passive:!0});for(let e of[`wheel`,`touchstart`,`pointerdown`,`keydown`])T.addEventListener(e,()=>A=k=void 0,{passive:!0});let Xe=new ResizeObserver(()=>P()?E.parked(T.scrollTop):E.pinned&&!g.detached?L():A?.scrollIntoView({block:`center`}));return Xe.observe(b),Xe.observe(T),{log:T,docs:y,runs(e){JSON.stringify(e)!==JSON.stringify(Y)&&(Y=e,Ke())},apply(e){if(e.reset)J(g.reset({items:e.items??[],before:e.before})),O=!0,z();else if(e.items?.length){let t=g.append(e.items);J(t),Q(t),E.arrived(t.added.length)&&!g.detached&&!P()?R():I()}},reveal(e){k=e,O&&z()}}}export{Z as mountChat,le as t};
@@ -0,0 +1 @@
1
+ import"./towermodel-CAbNR8ZT.js";import{t as e}from"./runtime-ZX6HkxDa.js";import{t}from"./open_main_title-Ccbha5pD.js";import{t as n}from"./unit_count-BE8Ap1BH.js";import{A as r,C as i,F as a,O as o,R as s,Rt as c,S as l,Y as u,_ as d,at as f,b as p,d as m,f as ee,ft as h,h as g,j as _,l as v,w as y,x as b}from"./index-D4RgSZfB.js";var te=((t={},n={})=>(n.locale??e())===`zh-TW`?`關閉清單`:`Close the list`),ne=((t={},n={})=>(n.locale??e())===`zh-TW`?`切換到其他單位`:`Switch to a unit`),x=((t={},n={})=>(n.locale??e())===`zh-TW`?`回到主地圖`:`Back to the map`),S=((t={},n={})=>(n.locale??e())===`zh-TW`?`所有單位`:`All units`),C=((t={},n={})=>(n.locale??e())===`zh-TW`?`指揮中`:`commanding`),w=((t={},n={})=>(n.locale??e())===`zh-TW`?`已結束`:`ended`),T=((t={},n={})=>(n.locale??e())===`zh-TW`?`錯誤`:`error`),E=((t={},n={})=>(n.locale??e())===`zh-TW`?`閒置`:`idle`),D=((t={},n={})=>(n.locale??e())===`zh-TW`?`無狀態`:`unknown`),O=((t={},n={})=>(n.locale??e())===`zh-TW`?`等待`:`waiting`),k=((t={},n={})=>(n.locale??e())===`zh-TW`?`工作中`:`working`),A=.4;function j(e,t,n){let[r,i]=[Math.abs(e),Math.abs(t)];return Math.max(r,i)<10?`wait`:r>=1.7*i&&(n?e<0:e>0)?`drag`:`pass`}var M=(e,t,n)=>Math.abs(n)>=.45?n>0:e>=t*A,N=(e,t)=>t||e.some(e=>e.editable||e.sink||e.scrollsX||[`input`,`textarea`,`select`].includes(e.tag));function P(e){let t=e,n=getComputedStyle(e).overflowX;return{tag:e.tagName.toLowerCase(),editable:t.isContentEditable,sink:e.matches(`.composer, .term-sink`),scrollsX:(n===`auto`||n===`scroll`)&&e.scrollWidth>e.clientWidth+1}}var F=e=>{let t=[];for(let n=e;n;n=n.parentElement)t.push(P(n));return t},I={working:k,waiting:O,idle:E,done:w,error:T,unknown:D,commanding:C},L=(e,t,n)=>(t?w:I[e])({},n&&{locale:n}),R=(e,t)=>t.flatMap(t=>[t,...t.subs.map(e=>({...e,sub:!0}))].map(t=>({id:t.key,key:t.key,ws:e,name:t.name,role:t.role,mark:t.mark,note:t.note,ended:!!t.ended,sub:`sub`in t,control:!!t.control})));function z(e){return e.bases.flatMap(e=>{let t=[{id:`tower`,rows:e.tower?R(e.id,[{...e.tower,role:`tower`}]):[]},...e.tabs.map(t=>({id:t.id,label:h({label:t.label}),rows:R(e.id,t.units)})),{id:`outside`,label:u(`outside_net`),rows:R(e.id,e.outside)}].filter(e=>e.rows.length);return t.length?[{id:e.id,label:e.label,mark:e.mark,groups:t}]:[]})}var B=(e,t)=>e?.head?{mark:e.head.mark,word:e.head.state===`absent`?c({},t&&{locale:t}):L(e.head.mark,!1,t)}:void 0,V=e=>e.role===`main`&&e.mark===`idle`,H=e=>e.reduce((e,t)=>(t.sub?e.at(-1)?.subs.push(t):e.push({...t,subs:[]}),e),[]),U=()=>d(`<div class="unit"><div class="card"><a class="hit"></a>${v}<div class="meta"><span class="name"></span><span class="line"><em class="role"></em><b class="dstate"></b><span class="note"></span></span></div><button type="button" class="quit-btn" data-close="unit" hidden></button></div><div class="subs"></div></div>`),W=()=>d(`<div class="unit tower-row"><div class="trow"><a class="tower-go">${v}<span class="meta"><span class="name"></span><span class="line"><em class="role"></em><b class="dstate"></b></span></span></a><button type="button" class="pair-btn tower-add"></button></div><div class="subs"></div></div>`),G=()=>d(`<section class="dbase"><h3><a></a><small></small></h3><div class="dgroups"></div></section>`),K=()=>d(`<div class="dgroup"><h4></h4><div class="drows"></div></div>`),q=()=>matchMedia(`(max-width: 640px)`).matches;function J(e=()=>!1){let c=f(`div`,{class:`drawer-body`}),h=f(`button`,{type:`button`,class:`x`,"aria-label":te()},`×`),v=f(`a`,{class:`drawer-map`},x()),C=f(`button`,{type:`button`,class:`pair-btn`,"data-close":`dismiss-all`,hidden:``}),w=f(`div`,{class:`drawer-sweep`,hidden:``},C);m(v,{view:`map`});let T=d(`<a class="drawer-head"><svg viewBox="0 0 512 512" aria-hidden="true"><use data-icon="crown"/></svg><span class="name"></span><b class="dstate"></b></a>`);T.hidden=!0,m(T,{view:`head`});let E=f(`aside`,{class:`drawer`,"aria-label":ne()},f(`header`,null,f(`b`,null,S()),h),T,c,f(`footer`,{class:`drawer-foot`},w,v)),D=f(`div`,{class:`drawer-veil`});document.body.append(D,E);let O,k,A=!1,P=!1,I=0,R=0,J,Y=()=>{let e=B(O);T.hidden=!e,e&&(p(T,e.mark),y(T,`.name`,u(`head_tower`)),y(T,`.dstate`,e.word),T.classList.toggle(`current`,A),T.toggleAttribute(`data-news`,a(O?.head,s())&&!A)),_(C,O??{bases:[]}),w.hidden=C.hidden;let r=(e,t)=>{m(e.querySelector(`.hit`),{view:`session`,ws:t.ws,key:t.key}),e.querySelector(`.hit`).setAttribute(`aria-label`,`${t.name}: ${L(t.mark,t.ended)}`),e.classList.toggle(`current`,t.key===k),e.toggleAttribute(`data-dismiss`,t.role===`subagent`&&t.ended),e.dataset.key=t.key,p(e,t.mark),g(e.querySelector(`.plate`),t.role,t.mark),y(e,`.name`,t.name),y(e,`.role`,b(t.role)),y(e,`.dstate`,L(t.mark,t.ended)),l(e,`.note`,t.note,t.mark,t.note?void 0:``);let n=e.querySelector(`:scope > .card > .quit-btn`);V(t)?o(n,t):n.hidden=!0,i(e.querySelector(`.subs`),t.subs??[],U,r)},d=(e,n)=>{let a=e.querySelector(`.tower-go`),o=e.querySelector(`.tower-add`),s=O?.bases.find(e=>e.id===n.ws);m(a,{view:`session`,ws:n.ws,key:n.key}),a.setAttribute(`aria-label`,`${n.name}: ${L(n.mark,n.ended)}`),e.classList.toggle(`current`,n.key===k),e.dataset.key=n.key,p(e,n.mark),g(a.querySelector(`.plate`),`tower`,n.mark),y(a,`.name`,n.name),y(a,`.role`,b(`tower`)),y(a,`.dstate`,L(n.mark,n.ended)),o.hidden=!s,s&&(ee(o,s),o.setAttribute(`aria-label`,t({base:s.label}))),i(e.querySelector(`.subs`),n.subs,U,r)};i(c,z(O??{bases:[]}),G,(e,t)=>{p(e,t.mark),y(e,`h3 a`,t.label),m(e.querySelector(`h3 a`),{view:`workspace`,ws:t.id}),y(e,`small`,n({count:t.groups.reduce((e,t)=>e+t.rows.length,0)})),i(e.querySelector(`.dgroups`),t.groups,K,(e,t)=>{y(e,`h4`,t.label??``),e.querySelector(`h4`).toggleAttribute(`hidden`,!t.label),t.id===`tower`?i(e.querySelector(`.drows`),H(t.rows),W,d):i(e.querySelector(`.drows`),H(t.rows),U,r)})})},X=e=>{I=Math.max(0,Math.min(R,e)),E.style.setProperty(`--dx`,`${I}px`),D.style.opacity=String(R?I/R:0),D.style.pointerEvents=I>0?`auto`:`none`},Z=e=>{P=e,E.classList.toggle(`on`,e),E.inert=!e,document.documentElement.classList.remove(`drawer-drag`),X(e?R:0)},Q=()=>{R=E.offsetWidth,Y(),E.classList.add(`on`),document.documentElement.classList.add(`drawer-drag`)};E.inert=!0,document.addEventListener(`touchstart`,t=>{let n=t.target,r=E.contains(n)||n===D;if(J=void 0,!q()||e()||t.touches.length!==1||document.querySelector(`dialog.sheet[open], dialog.lightbox[open], [popover]:popover-open`)||(P?!r:N(F(n),!!getSelection()?.toString())))return;let i=t.touches[0],a=P?n.closest(`.unit[data-dismiss] > .card`)??void 0:void 0;J={x0:i.clientX,y0:i.clientY,mode:`wait`,was:P,base:I,last:i.clientX,at:performance.now(),v:0,card:a}},{passive:!0}),document.addEventListener(`touchmove`,e=>{if(!J||J.mode===`pass`)return;let t=e.touches[0],n=t.clientX-J.x0,r=t.clientY-J.y0;if(J.mode===`wait`){let e=j(n,r,J.was);if(e===`wait`)return;if(e===`pass`&&J.card&&j(n,r,!1)===`drag`)J.mode=`card`,J.card.classList.add(`swiping`);else if(e===`pass`)return void(J.mode=`pass`);else J.mode=`drag`,Q()}e.preventDefault();let i=performance.now();if(J.v=(t.clientX-J.last)/Math.max(1,i-J.at),[J.last,J.at]=[t.clientX,i],J.mode!==`card`)return X(J.base+n);let a=Math.max(0,n);J.card.style.setProperty(`--sx`,`${a}px`),J.card.style.setProperty(`--so`,String(1-a/J.card.offsetWidth))},{passive:!1});let re=(e,t)=>{e.classList.remove(`swiping`),e.style.removeProperty(`--sx`),e.style.removeProperty(`--so`),t&&(e.classList.add(`gone`),r({key:e.parentElement.dataset.key}).then(t=>t||e.classList.remove(`gone`)))},$=e=>{let t=J;J=void 0,t?.mode===`drag`&&Z(M(I,R,t.v)),t?.mode===`card`&&re(t.card,e.type===`touchend`&&M(Math.max(0,t.last-t.x0),t.card.offsetWidth,t.v))};return document.addEventListener(`touchend`,$),document.addEventListener(`touchcancel`,$),D.addEventListener(`click`,()=>Z(!1)),E.addEventListener(`click`,e=>e.target.closest(`a[data-route], button[data-open], .x`)&&Z(!1)),document.addEventListener(`keydown`,e=>P&&e.key===`Escape`&&(e.preventDefault(),Z(!1)),!0),document.addEventListener(`sb-drawer`,()=>(P||Q(),Z(!P))),{net(e){O=e,P&&Y()},route(e){k=e.view===`session`?e.key:void 0,A=e.view===`head`||e.view===`session`&&e.ws===`@head`,v.toggleAttribute(`aria-current`,e.view===`map`),P&&Y()}}}export{J as mountDrawer};