@buoy-gg/ask-buoy 7.0.34 → 7.0.36

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 (352) hide show
  1. package/README.md +35 -8
  2. package/lib/commonjs/blocks/AskBlocks.js +338 -1
  3. package/lib/commonjs/blocks/AskBlocks.js.map +1 -0
  4. package/lib/commonjs/blocks/BlockRenderer.js +262 -1
  5. package/lib/commonjs/blocks/BlockRenderer.js.map +1 -0
  6. package/lib/commonjs/blocks/ChromePrototypes.js +514 -1
  7. package/lib/commonjs/blocks/ChromePrototypes.js.map +1 -0
  8. package/lib/commonjs/blocks/DataBlocks.js +781 -1
  9. package/lib/commonjs/blocks/DataBlocks.js.map +1 -0
  10. package/lib/commonjs/blocks/ExtraBlocks.js +1860 -1
  11. package/lib/commonjs/blocks/ExtraBlocks.js.map +1 -0
  12. package/lib/commonjs/blocks/MediaBlocks.js +156 -1
  13. package/lib/commonjs/blocks/MediaBlocks.js.map +1 -0
  14. package/lib/commonjs/blocks/ReceiptBlocks.js +586 -1
  15. package/lib/commonjs/blocks/ReceiptBlocks.js.map +1 -0
  16. package/lib/commonjs/blocks/blockText.js +60 -0
  17. package/lib/commonjs/blocks/blockText.js.map +1 -0
  18. package/lib/commonjs/blocks/blockText.test.js +53 -0
  19. package/lib/commonjs/blocks/blockText.test.js.map +1 -0
  20. package/lib/commonjs/blocks/context.js +42 -1
  21. package/lib/commonjs/blocks/context.js.map +1 -0
  22. package/lib/commonjs/blocks/icons.js +96 -1
  23. package/lib/commonjs/blocks/icons.js.map +1 -0
  24. package/lib/commonjs/blocks/index.js +95 -1
  25. package/lib/commonjs/blocks/index.js.map +1 -0
  26. package/lib/commonjs/blocks/listRow.test.js +55 -0
  27. package/lib/commonjs/blocks/listRow.test.js.map +1 -0
  28. package/lib/commonjs/blocks/pageState.js +34 -0
  29. package/lib/commonjs/blocks/pageState.js.map +1 -0
  30. package/lib/commonjs/blocks/pageState.test.js +57 -0
  31. package/lib/commonjs/blocks/pageState.test.js.map +1 -0
  32. package/lib/commonjs/blocks/primitives.js +457 -1
  33. package/lib/commonjs/blocks/primitives.js.map +1 -0
  34. package/lib/commonjs/blocks/primitivesIndex.js +62 -1
  35. package/lib/commonjs/blocks/primitivesIndex.js.map +1 -0
  36. package/lib/commonjs/components/ApprovalCard.js +244 -1
  37. package/lib/commonjs/components/ApprovalCard.js.map +1 -0
  38. package/lib/commonjs/components/AskBuoyHeader.js +196 -1
  39. package/lib/commonjs/components/AskBuoyHeader.js.map +1 -0
  40. package/lib/commonjs/components/AskBuoyIcon.js +19 -1
  41. package/lib/commonjs/components/AskBuoyIcon.js.map +1 -0
  42. package/lib/commonjs/components/AskBuoyModal.js +479 -1
  43. package/lib/commonjs/components/AskBuoyModal.js.map +1 -0
  44. package/lib/commonjs/components/AskBuoySettings.js +119 -0
  45. package/lib/commonjs/components/AskBuoySettings.js.map +1 -0
  46. package/lib/commonjs/components/ChangesBar.js +211 -1
  47. package/lib/commonjs/components/ChangesBar.js.map +1 -0
  48. package/lib/commonjs/components/Composer.js +255 -1
  49. package/lib/commonjs/components/Composer.js.map +1 -0
  50. package/lib/commonjs/components/EmptyState.js +161 -1
  51. package/lib/commonjs/components/EmptyState.js.map +1 -0
  52. package/lib/commonjs/components/KeyboardPad.js +80 -0
  53. package/lib/commonjs/components/KeyboardPad.js.map +1 -0
  54. package/lib/commonjs/components/Markdown.js +310 -1
  55. package/lib/commonjs/components/Markdown.js.map +1 -0
  56. package/lib/commonjs/components/MessageList.js +930 -1
  57. package/lib/commonjs/components/MessageList.js.map +1 -0
  58. package/lib/commonjs/components/QueuedMessages.js +145 -0
  59. package/lib/commonjs/components/QueuedMessages.js.map +1 -0
  60. package/lib/commonjs/components/ThinkingStrip.js +223 -0
  61. package/lib/commonjs/components/ThinkingStrip.js.map +1 -0
  62. package/lib/commonjs/components/TypingDots.js +63 -1
  63. package/lib/commonjs/components/TypingDots.js.map +1 -0
  64. package/lib/commonjs/components/markdownParse.js +131 -0
  65. package/lib/commonjs/components/markdownParse.js.map +1 -0
  66. package/lib/commonjs/components/markdownParse.test.js +99 -0
  67. package/lib/commonjs/components/markdownParse.test.js.map +1 -0
  68. package/lib/commonjs/components/useCopyAction.js +50 -0
  69. package/lib/commonjs/components/useCopyAction.js.map +1 -0
  70. package/lib/commonjs/index.js +252 -1
  71. package/lib/commonjs/index.js.map +1 -0
  72. package/lib/commonjs/preset.js +90 -1
  73. package/lib/commonjs/preset.js.map +1 -0
  74. package/lib/commonjs/store/activityGroups.js +110 -0
  75. package/lib/commonjs/store/activityGroups.js.map +1 -0
  76. package/lib/commonjs/store/activityGroups.test.js +78 -0
  77. package/lib/commonjs/store/activityGroups.test.js.map +1 -0
  78. package/lib/commonjs/store/askBuoySettings.js +72 -0
  79. package/lib/commonjs/store/askBuoySettings.js.map +1 -0
  80. package/lib/commonjs/store/askBuoyStore.js +547 -1
  81. package/lib/commonjs/store/askBuoyStore.js.map +1 -0
  82. package/lib/commonjs/store/blockPlacement.js +64 -0
  83. package/lib/commonjs/store/blockPlacement.js.map +1 -0
  84. package/lib/commonjs/store/blockPlacement.test.js +123 -0
  85. package/lib/commonjs/store/blockPlacement.test.js.map +1 -0
  86. package/lib/commonjs/store/queue.test.js +150 -0
  87. package/lib/commonjs/store/queue.test.js.map +1 -0
  88. package/lib/commonjs/store/resetConversation.js +77 -0
  89. package/lib/commonjs/store/resetConversation.js.map +1 -0
  90. package/lib/commonjs/store/restorePending.test.js +63 -0
  91. package/lib/commonjs/store/restorePending.test.js.map +1 -0
  92. package/lib/commonjs/store/restoredIds.test.js +47 -0
  93. package/lib/commonjs/store/restoredIds.test.js.map +1 -0
  94. package/lib/commonjs/store/suggestions.js +54 -0
  95. package/lib/commonjs/store/suggestions.js.map +1 -0
  96. package/lib/commonjs/store/suggestions.test.js +58 -0
  97. package/lib/commonjs/store/suggestions.test.js.map +1 -0
  98. package/lib/commonjs/store/systemLine.test.js +77 -0
  99. package/lib/commonjs/store/systemLine.test.js.map +1 -0
  100. package/lib/commonjs/store/ticketPrompt.js +17 -0
  101. package/lib/commonjs/store/ticketPrompt.js.map +1 -0
  102. package/lib/commonjs/store/traceText.js +81 -0
  103. package/lib/commonjs/store/traceText.js.map +1 -0
  104. package/lib/commonjs/store/traceText.test.js +112 -0
  105. package/lib/commonjs/store/traceText.test.js.map +1 -0
  106. package/lib/commonjs/store/transcriptPersistence.js +297 -0
  107. package/lib/commonjs/store/transcriptPersistence.js.map +1 -0
  108. package/lib/commonjs/store/transcriptPersistence.test.js +333 -0
  109. package/lib/commonjs/store/transcriptPersistence.test.js.map +1 -0
  110. package/lib/commonjs/store/turnRendering.test.js +151 -0
  111. package/lib/commonjs/store/turnRendering.test.js.map +1 -0
  112. package/lib/commonjs/store/useAskBuoy.js +622 -1
  113. package/lib/commonjs/store/useAskBuoy.js.map +1 -0
  114. package/lib/commonjs/store/useAskBuoySettings.js +14 -0
  115. package/lib/commonjs/store/useAskBuoySettings.js.map +1 -0
  116. package/lib/commonjs/sync/askBuoySyncAdapter.js +140 -1
  117. package/lib/commonjs/sync/askBuoySyncAdapter.js.map +1 -0
  118. package/lib/commonjs/sync/askBuoySyncAdapter.test.js +141 -1
  119. package/lib/commonjs/sync/askBuoySyncAdapter.test.js.map +1 -0
  120. package/lib/commonjs/sync/wire.js +58 -1
  121. package/lib/commonjs/sync/wire.js.map +1 -0
  122. package/lib/commonjs/types.js +6 -1
  123. package/lib/commonjs/types.js.map +1 -0
  124. package/lib/module/blocks/AskBlocks.js +331 -1
  125. package/lib/module/blocks/AskBlocks.js.map +1 -0
  126. package/lib/module/blocks/BlockRenderer.js +257 -1
  127. package/lib/module/blocks/BlockRenderer.js.map +1 -0
  128. package/lib/module/blocks/ChromePrototypes.js +503 -1
  129. package/lib/module/blocks/ChromePrototypes.js.map +1 -0
  130. package/lib/module/blocks/DataBlocks.js +767 -1
  131. package/lib/module/blocks/DataBlocks.js.map +1 -0
  132. package/lib/module/blocks/ExtraBlocks.js +1833 -1
  133. package/lib/module/blocks/ExtraBlocks.js.map +1 -0
  134. package/lib/module/blocks/MediaBlocks.js +151 -1
  135. package/lib/module/blocks/MediaBlocks.js.map +1 -0
  136. package/lib/module/blocks/ReceiptBlocks.js +574 -1
  137. package/lib/module/blocks/ReceiptBlocks.js.map +1 -0
  138. package/lib/module/blocks/blockText.js +55 -0
  139. package/lib/module/blocks/blockText.js.map +1 -0
  140. package/lib/module/blocks/blockText.test.js +53 -0
  141. package/lib/module/blocks/blockText.test.js.map +1 -0
  142. package/lib/module/blocks/context.js +35 -1
  143. package/lib/module/blocks/context.js.map +1 -0
  144. package/lib/module/blocks/icons.js +91 -1
  145. package/lib/module/blocks/icons.js.map +1 -0
  146. package/lib/module/blocks/index.js +8 -1
  147. package/lib/module/blocks/index.js.map +1 -0
  148. package/lib/module/blocks/listRow.test.js +56 -0
  149. package/lib/module/blocks/listRow.test.js.map +1 -0
  150. package/lib/module/blocks/pageState.js +30 -0
  151. package/lib/module/blocks/pageState.js.map +1 -0
  152. package/lib/module/blocks/pageState.test.js +56 -0
  153. package/lib/module/blocks/pageState.test.js.map +1 -0
  154. package/lib/module/blocks/primitives.js +445 -1
  155. package/lib/module/blocks/primitives.js.map +1 -0
  156. package/lib/module/blocks/primitivesIndex.js +5 -1
  157. package/lib/module/blocks/primitivesIndex.js.map +1 -0
  158. package/lib/module/components/ApprovalCard.js +239 -1
  159. package/lib/module/components/ApprovalCard.js.map +1 -0
  160. package/lib/module/components/AskBuoyHeader.js +193 -1
  161. package/lib/module/components/AskBuoyHeader.js.map +1 -0
  162. package/lib/module/components/AskBuoyIcon.js +8 -1
  163. package/lib/module/components/AskBuoyIcon.js.map +1 -0
  164. package/lib/module/components/AskBuoyModal.js +474 -1
  165. package/lib/module/components/AskBuoyModal.js.map +1 -0
  166. package/lib/module/components/AskBuoySettings.js +114 -0
  167. package/lib/module/components/AskBuoySettings.js.map +1 -0
  168. package/lib/module/components/ChangesBar.js +206 -1
  169. package/lib/module/components/ChangesBar.js.map +1 -0
  170. package/lib/module/components/Composer.js +250 -1
  171. package/lib/module/components/Composer.js.map +1 -0
  172. package/lib/module/components/EmptyState.js +156 -1
  173. package/lib/module/components/EmptyState.js.map +1 -0
  174. package/lib/module/components/KeyboardPad.js +75 -0
  175. package/lib/module/components/KeyboardPad.js.map +1 -0
  176. package/lib/module/components/Markdown.js +305 -1
  177. package/lib/module/components/Markdown.js.map +1 -0
  178. package/lib/module/components/MessageList.js +924 -1
  179. package/lib/module/components/MessageList.js.map +1 -0
  180. package/lib/module/components/QueuedMessages.js +140 -0
  181. package/lib/module/components/QueuedMessages.js.map +1 -0
  182. package/lib/module/components/ThinkingStrip.js +218 -0
  183. package/lib/module/components/ThinkingStrip.js.map +1 -0
  184. package/lib/module/components/TypingDots.js +58 -1
  185. package/lib/module/components/TypingDots.js.map +1 -0
  186. package/lib/module/components/markdownParse.js +125 -0
  187. package/lib/module/components/markdownParse.js.map +1 -0
  188. package/lib/module/components/markdownParse.test.js +98 -0
  189. package/lib/module/components/markdownParse.test.js.map +1 -0
  190. package/lib/module/components/useCopyAction.js +46 -0
  191. package/lib/module/components/useCopyAction.js.map +1 -0
  192. package/lib/module/index.js +34 -1
  193. package/lib/module/index.js.map +1 -0
  194. package/lib/module/preset.js +73 -1
  195. package/lib/module/preset.js.map +1 -0
  196. package/lib/module/store/activityGroups.js +103 -0
  197. package/lib/module/store/activityGroups.js.map +1 -0
  198. package/lib/module/store/activityGroups.test.js +77 -0
  199. package/lib/module/store/activityGroups.test.js.map +1 -0
  200. package/lib/module/store/askBuoySettings.js +67 -0
  201. package/lib/module/store/askBuoySettings.js.map +1 -0
  202. package/lib/module/store/askBuoyStore.js +541 -1
  203. package/lib/module/store/askBuoyStore.js.map +1 -0
  204. package/lib/module/store/blockPlacement.js +59 -0
  205. package/lib/module/store/blockPlacement.js.map +1 -0
  206. package/lib/module/store/blockPlacement.test.js +122 -0
  207. package/lib/module/store/blockPlacement.test.js.map +1 -0
  208. package/lib/module/store/queue.test.js +149 -0
  209. package/lib/module/store/queue.test.js.map +1 -0
  210. package/lib/module/store/resetConversation.js +72 -0
  211. package/lib/module/store/resetConversation.js.map +1 -0
  212. package/lib/module/store/restorePending.test.js +62 -0
  213. package/lib/module/store/restorePending.test.js.map +1 -0
  214. package/lib/module/store/restoredIds.test.js +46 -0
  215. package/lib/module/store/restoredIds.test.js.map +1 -0
  216. package/lib/module/store/suggestions.js +49 -0
  217. package/lib/module/store/suggestions.js.map +1 -0
  218. package/lib/module/store/suggestions.test.js +57 -0
  219. package/lib/module/store/suggestions.test.js.map +1 -0
  220. package/lib/module/store/systemLine.test.js +76 -0
  221. package/lib/module/store/systemLine.test.js.map +1 -0
  222. package/lib/module/store/ticketPrompt.js +13 -0
  223. package/lib/module/store/ticketPrompt.js.map +1 -0
  224. package/lib/module/store/traceText.js +75 -0
  225. package/lib/module/store/traceText.js.map +1 -0
  226. package/lib/module/store/traceText.test.js +111 -0
  227. package/lib/module/store/traceText.test.js.map +1 -0
  228. package/lib/module/store/transcriptPersistence.js +287 -0
  229. package/lib/module/store/transcriptPersistence.js.map +1 -0
  230. package/lib/module/store/transcriptPersistence.test.js +332 -0
  231. package/lib/module/store/transcriptPersistence.test.js.map +1 -0
  232. package/lib/module/store/turnRendering.test.js +150 -0
  233. package/lib/module/store/turnRendering.test.js.map +1 -0
  234. package/lib/module/store/useAskBuoy.js +616 -1
  235. package/lib/module/store/useAskBuoy.js.map +1 -0
  236. package/lib/module/store/useAskBuoySettings.js +9 -0
  237. package/lib/module/store/useAskBuoySettings.js.map +1 -0
  238. package/lib/module/sync/askBuoySyncAdapter.js +135 -1
  239. package/lib/module/sync/askBuoySyncAdapter.js.map +1 -0
  240. package/lib/module/sync/askBuoySyncAdapter.test.js +140 -1
  241. package/lib/module/sync/askBuoySyncAdapter.test.js.map +1 -0
  242. package/lib/module/sync/wire.js +47 -1
  243. package/lib/module/sync/wire.js.map +1 -0
  244. package/lib/module/types.js +4 -1
  245. package/lib/module/types.js.map +1 -0
  246. package/lib/typescript/blocks/AskBlocks.d.ts.map +1 -0
  247. package/lib/typescript/blocks/BlockRenderer.d.ts.map +1 -0
  248. package/lib/typescript/blocks/ChromePrototypes.d.ts.map +1 -0
  249. package/lib/typescript/blocks/DataBlocks.d.ts +42 -0
  250. package/lib/typescript/blocks/DataBlocks.d.ts.map +1 -0
  251. package/lib/typescript/blocks/ExtraBlocks.d.ts +29 -2
  252. package/lib/typescript/blocks/ExtraBlocks.d.ts.map +1 -0
  253. package/lib/typescript/blocks/MediaBlocks.d.ts.map +1 -0
  254. package/lib/typescript/blocks/ReceiptBlocks.d.ts.map +1 -0
  255. package/lib/typescript/blocks/blockText.d.ts +14 -0
  256. package/lib/typescript/blocks/blockText.d.ts.map +1 -0
  257. package/lib/typescript/blocks/blockText.test.d.ts +2 -0
  258. package/lib/typescript/blocks/blockText.test.d.ts.map +1 -0
  259. package/lib/typescript/blocks/context.d.ts.map +1 -0
  260. package/lib/typescript/blocks/icons.d.ts.map +1 -0
  261. package/lib/typescript/blocks/index.d.ts.map +1 -0
  262. package/lib/typescript/blocks/listRow.test.d.ts +2 -0
  263. package/lib/typescript/blocks/listRow.test.d.ts.map +1 -0
  264. package/lib/typescript/blocks/pageState.d.ts +23 -0
  265. package/lib/typescript/blocks/pageState.d.ts.map +1 -0
  266. package/lib/typescript/blocks/pageState.test.d.ts +2 -0
  267. package/lib/typescript/blocks/pageState.test.d.ts.map +1 -0
  268. package/lib/typescript/blocks/primitives.d.ts +55 -10
  269. package/lib/typescript/blocks/primitives.d.ts.map +1 -0
  270. package/lib/typescript/blocks/primitivesIndex.d.ts +2 -1
  271. package/lib/typescript/blocks/primitivesIndex.d.ts.map +1 -0
  272. package/lib/typescript/components/ApprovalCard.d.ts.map +1 -0
  273. package/lib/typescript/components/AskBuoyHeader.d.ts +41 -1
  274. package/lib/typescript/components/AskBuoyHeader.d.ts.map +1 -0
  275. package/lib/typescript/components/AskBuoyIcon.d.ts.map +1 -0
  276. package/lib/typescript/components/AskBuoyModal.d.ts.map +1 -0
  277. package/lib/typescript/components/AskBuoySettings.d.ts +2 -0
  278. package/lib/typescript/components/AskBuoySettings.d.ts.map +1 -0
  279. package/lib/typescript/components/ChangesBar.d.ts.map +1 -0
  280. package/lib/typescript/components/Composer.d.ts +16 -1
  281. package/lib/typescript/components/Composer.d.ts.map +1 -0
  282. package/lib/typescript/components/EmptyState.d.ts +5 -1
  283. package/lib/typescript/components/EmptyState.d.ts.map +1 -0
  284. package/lib/typescript/components/KeyboardPad.d.ts +33 -0
  285. package/lib/typescript/components/KeyboardPad.d.ts.map +1 -0
  286. package/lib/typescript/components/Markdown.d.ts +0 -10
  287. package/lib/typescript/components/Markdown.d.ts.map +1 -0
  288. package/lib/typescript/components/MessageList.d.ts +19 -7
  289. package/lib/typescript/components/MessageList.d.ts.map +1 -0
  290. package/lib/typescript/components/QueuedMessages.d.ts +10 -0
  291. package/lib/typescript/components/QueuedMessages.d.ts.map +1 -0
  292. package/lib/typescript/components/ThinkingStrip.d.ts +5 -0
  293. package/lib/typescript/components/ThinkingStrip.d.ts.map +1 -0
  294. package/lib/typescript/components/TypingDots.d.ts.map +1 -0
  295. package/lib/typescript/components/markdownParse.d.ts +49 -0
  296. package/lib/typescript/components/markdownParse.d.ts.map +1 -0
  297. package/lib/typescript/components/markdownParse.test.d.ts +2 -0
  298. package/lib/typescript/components/markdownParse.test.d.ts.map +1 -0
  299. package/lib/typescript/components/useCopyAction.d.ts +5 -0
  300. package/lib/typescript/components/useCopyAction.d.ts.map +1 -0
  301. package/lib/typescript/index.d.ts +5 -0
  302. package/lib/typescript/index.d.ts.map +1 -0
  303. package/lib/typescript/preset.d.ts.map +1 -0
  304. package/lib/typescript/store/activityGroups.d.ts +29 -0
  305. package/lib/typescript/store/activityGroups.d.ts.map +1 -0
  306. package/lib/typescript/store/activityGroups.test.d.ts +2 -0
  307. package/lib/typescript/store/activityGroups.test.d.ts.map +1 -0
  308. package/lib/typescript/store/askBuoySettings.d.ts +44 -0
  309. package/lib/typescript/store/askBuoySettings.d.ts.map +1 -0
  310. package/lib/typescript/store/askBuoyStore.d.ts +216 -18
  311. package/lib/typescript/store/askBuoyStore.d.ts.map +1 -0
  312. package/lib/typescript/store/blockPlacement.d.ts +30 -0
  313. package/lib/typescript/store/blockPlacement.d.ts.map +1 -0
  314. package/lib/typescript/store/blockPlacement.test.d.ts +2 -0
  315. package/lib/typescript/store/blockPlacement.test.d.ts.map +1 -0
  316. package/lib/typescript/store/queue.test.d.ts +2 -0
  317. package/lib/typescript/store/queue.test.d.ts.map +1 -0
  318. package/lib/typescript/store/resetConversation.d.ts +38 -0
  319. package/lib/typescript/store/resetConversation.d.ts.map +1 -0
  320. package/lib/typescript/store/restorePending.test.d.ts +2 -0
  321. package/lib/typescript/store/restorePending.test.d.ts.map +1 -0
  322. package/lib/typescript/store/restoredIds.test.d.ts +2 -0
  323. package/lib/typescript/store/restoredIds.test.d.ts.map +1 -0
  324. package/lib/typescript/store/suggestions.d.ts +32 -0
  325. package/lib/typescript/store/suggestions.d.ts.map +1 -0
  326. package/lib/typescript/store/suggestions.test.d.ts +2 -0
  327. package/lib/typescript/store/suggestions.test.d.ts.map +1 -0
  328. package/lib/typescript/store/systemLine.test.d.ts +2 -0
  329. package/lib/typescript/store/systemLine.test.d.ts.map +1 -0
  330. package/lib/typescript/store/ticketPrompt.d.ts +11 -0
  331. package/lib/typescript/store/ticketPrompt.d.ts.map +1 -0
  332. package/lib/typescript/store/traceText.d.ts +33 -0
  333. package/lib/typescript/store/traceText.d.ts.map +1 -0
  334. package/lib/typescript/store/traceText.test.d.ts +2 -0
  335. package/lib/typescript/store/traceText.test.d.ts.map +1 -0
  336. package/lib/typescript/store/transcriptPersistence.d.ts +79 -0
  337. package/lib/typescript/store/transcriptPersistence.d.ts.map +1 -0
  338. package/lib/typescript/store/transcriptPersistence.test.d.ts +2 -0
  339. package/lib/typescript/store/transcriptPersistence.test.d.ts.map +1 -0
  340. package/lib/typescript/store/turnRendering.test.d.ts +2 -0
  341. package/lib/typescript/store/turnRendering.test.d.ts.map +1 -0
  342. package/lib/typescript/store/useAskBuoy.d.ts +23 -1
  343. package/lib/typescript/store/useAskBuoy.d.ts.map +1 -0
  344. package/lib/typescript/store/useAskBuoySettings.d.ts +3 -0
  345. package/lib/typescript/store/useAskBuoySettings.d.ts.map +1 -0
  346. package/lib/typescript/sync/askBuoySyncAdapter.d.ts +26 -6
  347. package/lib/typescript/sync/askBuoySyncAdapter.d.ts.map +1 -0
  348. package/lib/typescript/sync/askBuoySyncAdapter.test.d.ts.map +1 -0
  349. package/lib/typescript/sync/wire.d.ts.map +1 -0
  350. package/lib/typescript/types.d.ts +24 -1
  351. package/lib/typescript/types.d.ts.map +1 -0
  352. package/package.json +9 -9
@@ -1 +1,1833 @@
1
- "use strict";import{useEffect,useRef,useState}from"react";import{Animated,Image,Pressable,ScrollView,StyleSheet,Switch,Text,TextInput,View}from"react-native";import{AlertTriangle,Check,ChevronDown,ChevronRight,night,RefreshCw,Search,X}from"@buoy-gg/shared-ui";import{BlockRenderer}from"./BlockRenderer";import{useBlockHandlers}from"./context";import{ActionRow,blockStyles as b,Card,toneColor}from"./primitives";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const fmt=e=>"string"==typeof e?e:void 0===e?"—":JSON.stringify(e);export function Suggestions({block:e}){const t=useBlockHandlers();return _jsx(View,{style:styles.chips,testID:`buoy-block-suggestions-${e.id}`,children:e.chips.slice(0,4).map(l=>_jsx(Pressable,{disabled:!!t.busy,onPress:()=>{t.runAction({label:l.label,send:l.send??l.label},e.id)},style:({pressed:e})=>[styles.chip,e&&styles.pressed],accessibilityRole:"button",children:_jsx(Text,{style:styles.chipText,children:l.label})},l.label))})}export function MultiSelect({block:e}){const t=useBlockHandlers(),l=t.answered[e.id],o=!!l,[i,s]=useState([]),n="multi"===l?.kind?l.optionIds:i,r=i.length>=(e.min??1)&&(!e.max||i.length<=e.max);return _jsxs(Card,{testID:`buoy-block-multi-${e.id}`,tone:o?void 0:"info",children:[_jsx(Text,{style:styles.question,children:e.question}),_jsx(View,{style:styles.optionsBox,children:e.options.map((e,t)=>{const l=n.includes(e.id);return _jsxs(Pressable,{disabled:o,onPress:()=>{return t=e.id,s(e=>e.includes(t)?e.filter(e=>e!==t):[...e,t]);var t},style:[styles.option,t>0&&b.rowDivider,o&&!l&&styles.dim],accessibilityRole:"checkbox",accessibilityState:{checked:l},children:[_jsx(View,{style:[styles.checkbox,l&&styles.checkboxOn],children:l?_jsx(Check,{size:11,color:night.color.onAccent}):null}),_jsxs(View,{style:styles.flex,children:[_jsx(Text,{style:styles.optionLabel,children:e.label}),e.detail?_jsx(Text,{style:styles.optionDetail,children:e.detail}):null]})]},e.id)})}),o?null:_jsx(View,{style:styles.rowEnd,children:_jsx(Pressable,{testID:"buoy-block-multi-submit",disabled:!r,onPress:()=>t.answer({blockId:e.id,kind:"multi",optionIds:i,labels:e.options.filter(e=>i.includes(e.id)).map(e=>e.label)}),style:[styles.button,styles.buttonPrimary,!r&&styles.disabled],children:_jsx(Text,{style:styles.buttonTextPrimary,children:e.submitLabel??`Use ${i.length||""}`.trim()})})})]})}export function Select({block:e}){const t=useBlockHandlers(),l=t.answered[e.id],[o,i]=useState(""),[s,n]=useState(!1),r="select"===l?.kind?l.label:null,a=e.options.filter(e=>!o||e.label.toLowerCase().includes(o.toLowerCase())).slice(0,8);return _jsxs(Card,{testID:`buoy-block-select-${e.id}`,tone:l?void 0:"info",children:[_jsx(Text,{style:styles.question,children:e.label}),r?_jsx(Text,{style:styles.decided,children:r}):_jsxs(View,{style:styles.selectBox,children:[_jsxs(Pressable,{onPress:()=>n(e=>!e),style:styles.selectField,accessibilityRole:"button",children:[_jsx(Text,{style:styles.selectPlaceholder,children:s?"Choose…":`${e.options.length} options`}),_jsx(ChevronDown,{size:14,color:night.color.textSecondary})]}),s&&_jsxs(_Fragment,{children:[!1!==e.searchable&&_jsxs(View,{style:styles.search,children:[_jsx(Search,{size:12,color:night.color.textSecondary}),_jsx(TextInput,{style:styles.searchInput,value:o,onChangeText:i,placeholder:"Search",placeholderTextColor:night.color.placeholder,autoCapitalize:"none",autoCorrect:!1})]}),a.map((l,o)=>_jsxs(Pressable,{onPress:()=>t.answer({blockId:e.id,kind:"select",optionId:l.id,label:l.label}),style:[styles.option,o>0&&b.rowDivider],accessibilityRole:"button",children:[_jsxs(View,{style:styles.flex,children:[_jsx(Text,{style:styles.optionLabel,children:l.label}),l.detail?_jsx(Text,{style:styles.optionDetail,children:l.detail}):null]}),_jsx(ChevronRight,{size:12,color:night.color.textTertiary})]},l.id)),e.options.length>a.length?_jsxs(Text,{style:styles.hint,children:[e.options.length-a.length," more — keep typing"]}):null]})]})]})}function SliderControl({min:e,max:t,step:l=1,value:o,unit:i,onChange:s,disabled:n}){const r=useRef(0),a=t>e?(o-e)/(t-e)*100:0,c=o=>Math.min(t,Math.max(e,+(Math.round((o-e)/l)*l+e).toFixed(6))),d=e=>!n&&s(c(o+e*l));return _jsxs(View,{style:styles.sliderRow,children:[_jsx(Pressable,{disabled:n,onPress:()=>d(-1),style:styles.stepBtn,accessibilityRole:"button",accessibilityLabel:"Decrease",children:_jsx(Text,{style:styles.stepText,children:"−"})}),_jsx(Pressable,{style:styles.trackHit,onLayout:e=>{r.current=e.nativeEvent.layout.width},onPress:l=>{if(n||r.current<=0)return;const o=Math.min(1,Math.max(0,l.nativeEvent.locationX/r.current));s(c(e+o*(t-e)))},disabled:n,accessibilityRole:"adjustable",accessibilityValue:{min:e,max:t,now:o},accessibilityActions:[{name:"increment"},{name:"decrement"}],onAccessibilityAction:e=>d("increment"===e.nativeEvent.actionName?1:-1),children:_jsxs(View,{style:styles.track,pointerEvents:"none",children:[_jsx(View,{style:[styles.fill,{width:`${a}%`}]}),_jsx(View,{style:[styles.thumb,{left:`${a}%`}]})]})}),_jsx(Pressable,{disabled:n,onPress:()=>d(1),style:styles.stepBtn,accessibilityRole:"button",accessibilityLabel:"Increase",children:_jsx(Text,{style:styles.stepText,children:"+"})}),_jsxs(Text,{style:styles.sliderValue,children:[o,i?` ${i}`:""]})]})}export function Slider({block:e}){const t=useBlockHandlers(),l=t.answered[e.id],[o,i]=useState(e.value??e.min);return _jsxs(Card,{testID:`buoy-block-slider-${e.id}`,tone:l?void 0:"info",children:[_jsx(Text,{style:styles.question,children:e.label}),_jsx(View,{style:styles.pad,children:_jsx(SliderControl,{min:e.min,max:e.max,step:e.step,value:"slider"===l?.kind?l.value:o,unit:e.unit,onChange:i,disabled:!!l})}),l?null:_jsx(View,{style:styles.rowEnd,children:_jsx(Pressable,{onPress:()=>t.answer({blockId:e.id,kind:"slider",value:o,unit:e.unit}),style:[styles.button,styles.buttonPrimary],children:_jsxs(Text,{style:styles.buttonTextPrimary,children:["Use ",o,e.unit?` ${e.unit}`:""]})})})]})}export function DateTime({block:e}){const t=useBlockHandlers(),l=t.answered[e.id],[o,i]=useState(""),s=e.presets??[{label:"Now",value:(new Date).toISOString()},{label:"Tomorrow",value:new Date(Date.now()+864e5).toISOString()},{label:"+7 days",value:new Date(Date.now()+6048e5).toISOString()},{label:"+30 days",value:new Date(Date.now()+2592e6).toISOString()}];return _jsxs(Card,{testID:`buoy-block-datetime-${e.id}`,tone:l?void 0:"info",children:[_jsx(Text,{style:styles.question,children:e.label}),l?_jsx(Text,{style:styles.decided,children:"dateTime"===l.kind?l.label??l.value:"(skipped)"}):_jsxs(_Fragment,{children:[_jsx(View,{style:[styles.chips,styles.pad],children:s.map(l=>_jsx(Pressable,{onPress:()=>t.answer({blockId:e.id,kind:"dateTime",value:l.value,label:l.label}),style:styles.chip,children:_jsx(Text,{style:styles.chipText,children:l.label})},l.label))}),_jsxs(View,{style:[styles.inputRow,styles.pad],children:[_jsx(TextInput,{style:styles.input,value:o,onChangeText:i,placeholder:"time"===e.mode?"14:30":"2026-09-15",placeholderTextColor:night.color.placeholder,keyboardType:"numbers-and-punctuation"}),_jsx(Pressable,{disabled:!o.trim(),onPress:()=>t.answer({blockId:e.id,kind:"dateTime",value:o.trim()}),style:[styles.button,styles.buttonPrimary,!o.trim()&&styles.disabled],children:_jsx(Text,{style:styles.buttonTextPrimary,children:"Use"})})]})]})]})}function FieldRow({f:e,value:t,onChange:l,disabled:o}){return"toggle"===e.type?_jsxs(View,{style:styles.fieldRow,children:[_jsx(Text,{style:styles.fieldLabel,children:e.label}),_jsx(Switch,{value:!!t,onValueChange:l,disabled:o,trackColor:{true:night.color.accent,false:night.color.fillTertiary},thumbColor:night.color.knob})]}):"select"===e.type?_jsxs(View,{style:styles.fieldCol,children:[_jsx(Text,{style:styles.fieldLabel,children:e.label}),_jsx(View,{style:styles.chips,children:e.options.map(e=>_jsx(Pressable,{disabled:o,onPress:()=>l(e.id),style:[styles.chip,t===e.id&&styles.chipOn],children:_jsx(Text,{style:[styles.chipText,t===e.id&&styles.chipTextOn],children:e.label})},e.id))})]}):"slider"===e.type?_jsxs(View,{style:styles.fieldCol,children:[_jsx(Text,{style:styles.fieldLabel,children:e.label}),_jsx(SliderControl,{min:e.min,max:e.max,step:e.step,unit:e.unit,value:"number"==typeof t?t:e.min,onChange:l,disabled:o})]}):_jsxs(View,{style:styles.fieldRow,children:[_jsx(Text,{style:styles.fieldLabel,children:e.label}),_jsx(TextInput,{style:styles.fieldInput,value:null==t?"":String(t),onChangeText:l,editable:!o,placeholder:e.placeholder??"",placeholderTextColor:night.color.placeholder,keyboardType:"number"===e.type?"numeric":"ascii-capable",secureTextEntry:"secret"===e.type,autoCapitalize:"none",autoCorrect:!1})]})}function useFormValues(e){const[t,l]=useState(()=>Object.fromEntries(e.map(e=>[e.key,e.value])));return{values:t,set:(e,t)=>l(l=>({...l,[e]:t}))}}export function Form({block:e}){const t=useBlockHandlers(),l=t.answered[e.id],{values:o,set:i}=useFormValues(e.fields);return _jsxs(Card,{title:e.title,testID:`buoy-block-form-${e.id}`,tone:l?void 0:"info",children:[_jsx(View,{style:styles.pad,children:e.fields.map(e=>_jsx(FieldRow,{f:e,value:o[e.key],onChange:t=>i(e.key,t),disabled:!!l},e.key))}),l?_jsx(Text,{style:styles.decided,children:"Sent"}):_jsx(View,{style:styles.rowEnd,children:_jsx(Pressable,{onPress:()=>t.answer({blockId:e.id,kind:"form",values:o}),style:[styles.button,styles.buttonPrimary],children:_jsx(Text,{style:styles.buttonTextPrimary,children:e.submitLabel??"Send"})})})]})}export function Proposal({block:e}){const t=useBlockHandlers(),l=t.answered[e.id],{values:o,set:i}=useFormValues(e.fields),s="proposal"===l?.kind?l.approved:null;return _jsxs(Card,{testID:`buoy-block-proposal-${e.id}`,tone:l?void 0:"warning",children:[_jsx(Text,{style:styles.confirmTitle,children:e.title}),_jsx(Text,{style:styles.confirmChange,children:e.change}),_jsx(View,{style:styles.pad,children:e.fields.map(e=>_jsx(FieldRow,{f:e,value:o[e.key],onChange:t=>i(e.key,t),disabled:!!l},e.key))}),e.consequence?_jsx(Text,{style:styles.consequence,children:e.consequence}):null,_jsx(View,{style:styles.actionsRow,children:l?_jsx(Text,{style:styles.decided,children:s?"✓ Applied with these values":"✕ Not applied"}):_jsxs(_Fragment,{children:[_jsx(Pressable,{onPress:()=>t.answer({blockId:e.id,kind:"proposal",approved:!0,values:o}),style:[styles.button,styles.buttonPrimary],children:_jsx(Text,{style:styles.buttonTextPrimary,children:e.approveLabel??"Apply"})}),_jsx(Pressable,{onPress:()=>t.answer({blockId:e.id,kind:"proposal",approved:!1}),style:[styles.button,styles.buttonPlate],children:_jsx(Text,{style:styles.buttonTextPlate,children:"Not now"})})]})})]})}export function Claim({block:e}){const t=useBlockHandlers(),[l,o]=useState(null),i=t.actionState?.[`${e.id}:${e.verify?.label??"Verify"}`],s=e.verified||"done"===i;return _jsxs(View,{style:styles.claim,testID:`buoy-block-claim-${e.id}`,children:[_jsxs(Text,{style:styles.claimText,children:[e.text,e.sources.map((e,t)=>_jsxs(Text,{onPress:()=>o(l===t?null:t),style:styles.cite,children:[" [",t+1,"]"]},t)),s?_jsx(Text,{style:styles.verified,children:" ✓ verified"}):null]}),null!==l&&e.sources[l]?_jsxs(View,{style:styles.citeBox,children:[_jsxs(Text,{style:styles.citeLabel,children:["[",l+1,"] ",e.sources[l].label]}),e.sources[l].detail?_jsx(Text,{style:styles.citeDetail,children:e.sources[l].detail}):null]}):null,e.verify&&!s?_jsxs(Pressable,{onPress:()=>{t.runAction(e.verify,e.id)},style:styles.verifyBtn,accessibilityRole:"button",children:[_jsx(RefreshCw,{size:11,color:night.color.accent}),_jsx(Text,{style:styles.verifyText,children:"running"===i?"Checking…":e.verify.label})]}):null]})}export function Details({block:e}){const[t,l]=useState(!!e.open);return _jsxs(Card,{testID:`buoy-block-details-${e.id}`,children:[_jsxs(Pressable,{onPress:()=>l(e=>!e),style:b.row,accessibilityRole:"button",accessibilityState:{expanded:t},children:[_jsx(Text,{style:b.rowTitle,children:e.summary}),_jsx(t?ChevronDown:ChevronRight,{size:12,color:night.color.textTertiary})]}),t?_jsx(Text,{style:styles.detailsBody,selectable:!0,children:e.body}):null]})}export function Tabs({block:e}){const[t,l]=useState(0);return _jsxs(View,{style:styles.tabsWrap,testID:`buoy-block-tabs-${e.id}`,children:[_jsx(View,{style:styles.tabBar,children:e.tabs.map((e,o)=>_jsx(Pressable,{onPress:()=>l(o),style:[styles.tab,t===o&&styles.tabOn],accessibilityRole:"tab",children:_jsx(Text,{style:[styles.tabText,t===o&&styles.tabTextOn],children:e.label})},e.label))}),e.tabs[t]?_jsx(BlockRenderer,{block:e.tabs[t].block}):null]})}export function Timeline({block:e}){return _jsxs(Card,{title:e.title??"What happened",source:e.source,testID:`buoy-block-timeline-${e.id}`,children:[e.events.slice(0,10).map((t,l)=>_jsxs(View,{style:styles.tlRow,children:[_jsx(Text,{style:styles.tlAt,children:t.at}),_jsxs(View,{style:styles.tlLine,children:[_jsx(View,{style:[styles.tlDot,{backgroundColor:toneColor(t.tone??"muted")}]}),l<e.events.length-1?_jsx(View,{style:styles.tlStem}):null]}),_jsxs(View,{style:styles.flex,children:[_jsx(Text,{style:styles.tlSource,children:t.source.toUpperCase()}),_jsx(Text,{style:b.rowTitle,numberOfLines:2,children:t.label})]})]},l)),e.total&&e.total>e.events.length?_jsxs(Text,{style:styles.hint,children:["+",e.total-e.events.length," more"]}):null]})}export function Sparkline({block:e}){const t=e.series.slice(-60),l=Math.max(1,...t),o=Math.min(...t,0);return _jsxs(Card,{title:e.title,source:e.source,testID:`buoy-block-sparkline-${e.id}`,children:[_jsxs(View,{style:styles.sparkHead,children:[_jsxs(Text,{style:styles.sparkCurrent,children:[e.current??t[t.length-1],e.unit?_jsxs(Text,{style:styles.sparkUnit,children:[" ",e.unit]}):null]}),e.live?_jsx(LivePill,{}):null]}),_jsx(View,{style:[styles.spark,{height:44}],children:t.map((e,i)=>_jsx(View,{style:[styles.sparkBar,{height:Math.max(2,(e-o)/(l-o||1)*44),backgroundColor:i===t.length-1?night.color.accent:night.color.accentBorderStrong}]},i))}),e.label?_jsx(Text,{style:styles.hint,children:e.label}):null]})}export function LivePill(){const e=useRef(new Animated.Value(1)).current;return useEffect(()=>{const t=Animated.loop(Animated.sequence([Animated.timing(e,{toValue:.3,duration:700,useNativeDriver:!0}),Animated.timing(e,{toValue:1,duration:700,useNativeDriver:!0})]));return t.start(),()=>t.stop()},[e]),_jsxs(View,{style:styles.live,children:[_jsx(Animated.View,{style:[styles.liveDot,{opacity:e}]}),_jsx(Text,{style:styles.liveText,children:"LIVE"})]})}export function Compare({block:e}){const t=[...new Set([...e.left.pairs.map(e=>e.key),...e.right.pairs.map(e=>e.key)])],l=Object.fromEntries(e.left.pairs.map(e=>[e.key,e.value])),o=Object.fromEntries(e.right.pairs.map(e=>[e.key,e.value]));return _jsxs(Card,{title:e.title,source:e.source,testID:`buoy-block-compare-${e.id}`,children:[_jsxs(View,{style:styles.cmpHead,children:[_jsx(Text,{style:styles.cmpKey}),_jsx(Text,{style:styles.cmpCol,children:e.left.title}),_jsx(Text,{style:styles.cmpCol,children:e.right.title})]}),t.map((e,t)=>{const i=JSON.stringify(l[e])!==JSON.stringify(o[e]);return _jsxs(View,{style:[styles.cmpRow,t>0&&b.rowDivider,i&&styles.cmpDiff],children:[_jsx(Text,{style:styles.cmpKey,numberOfLines:1,children:e}),_jsx(Text,{style:[styles.cmpVal,i&&{color:night.color.danger}],numberOfLines:2,children:fmt(l[e])}),_jsx(Text,{style:[styles.cmpVal,i&&{color:night.color.accent}],numberOfLines:2,children:fmt(o[e])})]},e)})]})}function CardBody({c:e,id:t}){return _jsxs(_Fragment,{children:[e.image?_jsx(Image,{source:{uri:e.image},style:styles.cardImage,resizeMode:"cover",accessibilityLabel:e.title}):null,_jsxs(View,{style:styles.cardText,children:[_jsx(Text,{style:styles.cardTitle,numberOfLines:2,children:e.title}),e.subtitle?_jsx(Text,{style:b.rowSub,numberOfLines:2,children:e.subtitle}):null,e.facts?.slice(0,4).map(e=>_jsxs(View,{style:styles.fact,children:[_jsx(Text,{style:styles.factLabel,children:e.label}),_jsx(Text,{style:[styles.factValue,e.tone&&{color:toneColor(e.tone)}],children:e.value})]},e.label))]}),_jsx(ActionRow,{actions:e.actions,blockId:t})]})}export function CardView({block:e}){return _jsx(Card,{source:e.source,testID:`buoy-block-card-${e.id}`,children:_jsx(CardBody,{c:e,id:e.id})})}export function CardCarousel({block:e}){return _jsxs(View,{testID:`buoy-block-cardcarousel-${e.id}`,children:[e.title?_jsx(Text,{style:styles.carouselTitle,children:e.title}):null,_jsx(ScrollView,{horizontal:!0,showsHorizontalScrollIndicator:!1,snapToInterval:232,decelerationRate:"fast",contentContainerStyle:styles.carousel,children:e.cards.slice(0,8).map((t,l)=>_jsx(View,{style:styles.carouselCard,children:_jsx(CardBody,{c:t,id:`${e.id}-${l}`})},`${t.title}-${l}`))})]})}export function Screenshot({block:e}){const[t,l]=useState(!1);return _jsxs(Card,{title:e.route?`Screen · ${e.route}`:"Screen",source:e.source,testID:`buoy-block-screenshot-${e.id}`,children:[_jsx(Pressable,{onPress:()=>l(e=>!e),accessibilityRole:"imagebutton",accessibilityLabel:e.caption??"Screenshot",children:_jsx(Image,{source:{uri:e.url},style:[styles.shot,t&&styles.shotBig],resizeMode:"contain"})}),e.caption?_jsx(Text,{style:styles.hint,children:e.caption}):null]})}export function Plan({block:e}){const t=e.steps.filter(e=>"done"===e.state).length;return _jsxs(Card,{title:e.title,testID:`buoy-block-plan-${e.id}`,tone:e.pending?"info":void 0,children:[_jsx(View,{style:styles.progress,children:_jsx(View,{style:[styles.progressFill,{width:t/Math.max(1,e.steps.length)*100+"%"}]})}),e.steps.map((e,t)=>_jsxs(View,{style:[styles.step,t>0&&b.rowDivider],children:[_jsx(View,{style:[styles.stepMark,"done"===e.state&&styles.stepDone,"failed"===e.state&&styles.stepFailed,"running"===e.state&&styles.stepRunning],children:"done"===e.state?_jsx(Check,{size:10,color:night.color.onAccent}):"failed"===e.state?_jsx(X,{size:10,color:night.color.text}):_jsx(Text,{style:styles.stepNum,children:t+1})}),_jsxs(Text,{style:[b.rowTitle,"done"===e.state&&styles.muted],children:[e.text,"running"===e.state?"…":""]})]},t)),_jsx(ActionRow,{actions:e.actions??(e.pending?[{label:"Go",primary:!0,send:"Go ahead with the plan."},{label:"Change it",send:"Let me change the plan first."}]:void 0),blockId:e.id})]})}export function Checkpoint({block:e}){const t=useBlockHandlers();return _jsxs(Pressable,{testID:`buoy-block-checkpoint-${e.id}`,disabled:!e.restore,onPress:()=>e.restore&&void t.runAction(e.restore,e.id),style:styles.checkpoint,accessibilityRole:"button",children:[_jsx(View,{style:styles.cpFlag}),_jsxs(Text,{style:styles.cpText,children:[e.label,e.at?` · ${e.at}`:""]}),e.restore?_jsx(Text,{style:styles.cpRestore,children:e.restore.label}):null]})}export function Task({block:e}){const t="failed"===e.status?night.color.danger:"done"===e.status?night.color.accent:night.color.info;return _jsxs(Card,{testID:`buoy-block-task-${e.id}`,children:[_jsxs(View,{style:styles.taskHead,children:[_jsx(Text,{style:styles.cardTitle,children:e.title}),_jsx(View,{style:[b.pill,{backgroundColor:`${t}22`}],children:_jsx(Text,{style:[b.pillText,{color:t}],children:e.status.toUpperCase()})})]}),void 0!==e.progress?_jsx(View,{style:[styles.progress,styles.pad],children:_jsx(View,{style:[styles.progressFill,{width:`${Math.round(100*e.progress)}%`,backgroundColor:t}]})}):null,e.detail?_jsx(Text,{style:styles.hint,children:e.detail}):null,_jsx(ActionRow,{actions:e.actions,blockId:e.id})]})}export function Banner({block:e}){const t="danger"===e.tone?night.color.danger:"warning"===e.tone?night.color.warning:night.color.info;return _jsxs(View,{style:[styles.banner,{borderColor:t,backgroundColor:`${t}1A`}],testID:`buoy-block-banner-${e.id}`,children:[_jsx(AlertTriangle,{size:13,color:t}),_jsx(Text,{style:[styles.bannerText,{color:t}],numberOfLines:2,children:e.text}),e.actions?.[0]?_jsx(ActionRow,{actions:e.actions.slice(0,1),blockId:e.id,align:"right"}):null]})}export function File({block:e}){return _jsxs(Card,{testID:`buoy-block-file-${e.id}`,children:[_jsxs(View,{style:b.row,children:[_jsx(View,{style:styles.fileIcon,children:_jsx(Text,{style:styles.fileExt,children:(e.type??e.name.split(".").pop()??"file").toUpperCase().slice(0,4)})}),_jsxs(View,{style:styles.flex,children:[_jsx(Text,{style:b.rowTitle,numberOfLines:1,children:e.name}),e.size?_jsx(Text,{style:b.rowSub,children:e.size}):null]})]}),_jsx(ActionRow,{actions:e.actions,blockId:e.id})]})}export function Upload({block:e}){const t=useBlockHandlers(),l=t.answered[e.id];return _jsxs(Card,{testID:`buoy-block-upload-${e.id}`,tone:l?void 0:"info",children:[_jsx(Text,{style:styles.question,children:e.label}),l?_jsx(Text,{style:styles.decided,children:"upload"===l.kind?`Attached ${l.name}`:"(skipped)"}):_jsx(View,{style:[styles.rowEnd,{justifyContent:"flex-start"}],children:_jsx(Pressable,{onPress:()=>t.answer({blockId:e.id,kind:"upload",name:"screenshot.png"}),style:[styles.button,styles.buttonPlate],children:_jsx(Text,{style:styles.buttonTextPlate,children:"image"===e.accept?"Choose a screenshot":"Choose a file"})})})]})}const styles=StyleSheet.create({flex:{flex:1},pad:{paddingHorizontal:12,paddingBottom:8},muted:{color:night.color.textSecondary},dim:{opacity:.45},disabled:{opacity:.5},pressed:{opacity:.7},question:{color:night.color.text,fontSize:night.font.row,fontWeight:"600",lineHeight:20,paddingHorizontal:12,paddingTop:12,paddingBottom:8},hint:{color:night.color.textTertiary,fontSize:night.font.micro,paddingHorizontal:12,paddingBottom:10},decided:{color:night.color.textSecondary,fontSize:night.font.caption,fontWeight:"600",paddingHorizontal:12,paddingVertical:10},rowEnd:{flexDirection:"row",justifyContent:"flex-end",paddingHorizontal:12,paddingBottom:12,gap:8},actionsRow:{flexDirection:"row",gap:8,paddingHorizontal:12,paddingVertical:12,alignItems:"center"},button:{paddingHorizontal:14,paddingVertical:9,borderRadius:night.radius.row},buttonPrimary:{backgroundColor:night.color.accent},buttonPlate:{backgroundColor:night.color.button},buttonTextPrimary:{color:night.color.onAccent,fontSize:night.font.caption,fontWeight:"600"},buttonTextPlate:{color:night.color.text,fontSize:night.font.caption,fontWeight:"600"},chips:{flexDirection:"row",flexWrap:"wrap",gap:6},chip:{paddingHorizontal:12,paddingVertical:7,borderRadius:night.radius.chip,backgroundColor:night.color.fill,borderWidth:StyleSheet.hairlineWidth,borderColor:night.color.border},chipOn:{backgroundColor:night.color.accentSoft,borderColor:night.color.accentBorderStrong},chipText:{color:night.color.text,fontSize:night.font.caption},chipTextOn:{color:night.color.accent,fontWeight:"600"},optionsBox:{marginHorizontal:8,marginBottom:8,borderRadius:night.radius.row,backgroundColor:night.color.surfaceElevated,overflow:"hidden"},option:{flexDirection:"row",alignItems:"center",gap:10,paddingHorizontal:12,paddingVertical:10},optionLabel:{color:night.color.text,fontSize:night.font.body,fontWeight:"500"},optionDetail:{color:night.color.textSecondary,fontSize:night.font.caption},checkbox:{width:20,height:20,borderRadius:6,borderWidth:1.5,borderColor:night.color.textTertiary,alignItems:"center",justifyContent:"center"},checkboxOn:{backgroundColor:night.color.accent,borderColor:night.color.accent},selectBox:{marginHorizontal:12,marginBottom:12,borderRadius:night.radius.row,backgroundColor:night.color.surfaceElevated,overflow:"hidden"},selectField:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:12,paddingVertical:11},selectPlaceholder:{color:night.color.textSecondary,fontSize:night.font.body},search:{flexDirection:"row",alignItems:"center",gap:6,paddingHorizontal:12,paddingVertical:6,borderTopWidth:StyleSheet.hairlineWidth,borderTopColor:night.color.separator},searchInput:{flex:1,color:night.color.text,fontSize:night.font.caption,paddingVertical:4},sliderRow:{flexDirection:"row",alignItems:"center",gap:8},stepBtn:{width:28,height:28,borderRadius:14,backgroundColor:night.color.fill,alignItems:"center",justifyContent:"center"},stepText:{color:night.color.text,fontSize:16,fontWeight:"600"},trackHit:{flex:1,height:36,justifyContent:"center"},track:{height:6,borderRadius:3,backgroundColor:night.color.fillTertiary,justifyContent:"center"},fill:{height:6,borderRadius:3,backgroundColor:night.color.accent},thumb:{position:"absolute",width:20,height:20,borderRadius:10,backgroundColor:night.color.knob,marginLeft:-10,shadowColor:"#000",shadowOpacity:.35,shadowRadius:3,shadowOffset:{width:0,height:1}},sliderValue:{width:64,textAlign:"right",color:night.color.text,fontSize:night.font.caption,fontWeight:"600"},inputRow:{flexDirection:"row",alignItems:"center",gap:8,paddingBottom:12},input:{flex:1,height:38,paddingHorizontal:12,borderRadius:night.radius.row,backgroundColor:night.color.surfaceElevated,color:night.color.text,fontSize:night.font.body},fieldRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:10,paddingVertical:6},fieldCol:{paddingVertical:6,gap:6},fieldLabel:{color:night.color.textSecondary,fontSize:night.font.caption,width:110},fieldInput:{flex:1,height:34,paddingHorizontal:10,borderRadius:night.radius.segment,backgroundColor:night.color.surfaceElevated,color:night.color.text,fontSize:night.font.caption},confirmTitle:{color:night.color.text,fontSize:night.font.row,fontWeight:"600",paddingHorizontal:12,paddingTop:12},confirmChange:{color:night.color.text,fontSize:night.font.body,lineHeight:19,paddingHorizontal:12,paddingTop:6,paddingBottom:6},consequence:{color:night.color.warning,fontSize:night.font.caption,paddingHorizontal:12},claim:{gap:6,paddingHorizontal:2},claimText:{color:night.color.text,fontSize:night.font.row,lineHeight:22},cite:{color:night.color.accent,fontSize:night.font.caption,fontWeight:"700"},verified:{color:night.color.accent,fontSize:night.font.caption,fontWeight:"600"},citeBox:{padding:10,borderRadius:night.radius.row,backgroundColor:night.color.surface,borderWidth:StyleSheet.hairlineWidth,borderColor:night.color.border,gap:2},citeLabel:{color:night.color.text,fontSize:night.font.caption,fontWeight:"600"},citeDetail:{color:night.color.textSecondary,fontSize:night.font.caption,fontFamily:"Menlo"},verifyBtn:{alignSelf:"flex-start",flexDirection:"row",alignItems:"center",gap:5,paddingHorizontal:10,paddingVertical:5,borderRadius:night.radius.chip,backgroundColor:night.color.accentSoft},verifyText:{color:night.color.accent,fontSize:night.font.micro,fontWeight:"700"},detailsBody:{color:night.color.textSecondary,fontSize:night.font.caption,lineHeight:18,paddingHorizontal:12,paddingBottom:12},tabsWrap:{gap:8},tabBar:{flexDirection:"row",gap:6},tab:{paddingHorizontal:12,paddingVertical:6,borderRadius:night.radius.badge,backgroundColor:night.color.fill},tabOn:{backgroundColor:night.color.accentSoft},tabText:{color:night.color.textSecondary,fontSize:night.font.caption,fontWeight:"600"},tabTextOn:{color:night.color.accent},tlRow:{flexDirection:"row",gap:10,paddingHorizontal:12,paddingVertical:4,alignItems:"flex-start"},tlAt:{width:46,color:night.color.textTertiary,fontSize:night.font.micro,fontFamily:"Menlo",paddingTop:3},tlLine:{width:12,alignItems:"center"},tlDot:{width:8,height:8,borderRadius:4,marginTop:5},tlStem:{width:1,flex:1,minHeight:18,backgroundColor:night.color.separator,marginTop:2},tlSource:{color:night.color.textTertiary,fontSize:9,fontWeight:"700",letterSpacing:.6},sparkHead:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:12,paddingTop:8},sparkCurrent:{color:night.color.text,fontSize:22,fontWeight:"700"},sparkUnit:{color:night.color.textSecondary,fontSize:night.font.caption,fontWeight:"500"},spark:{flexDirection:"row",alignItems:"flex-end",gap:2,paddingHorizontal:12,paddingTop:6,paddingBottom:6},sparkBar:{flex:1,borderRadius:1},live:{flexDirection:"row",alignItems:"center",gap:5,paddingHorizontal:8,paddingVertical:3,borderRadius:night.radius.badge,backgroundColor:night.color.dangerSoft},liveDot:{width:6,height:6,borderRadius:3,backgroundColor:night.color.danger},liveText:{color:night.color.danger,fontSize:9,fontWeight:"800",letterSpacing:.8},cmpHead:{flexDirection:"row",paddingHorizontal:12,paddingVertical:6,backgroundColor:night.color.fill,gap:8},cmpCol:{flex:1,color:night.color.textTertiary,fontSize:night.font.micro,fontWeight:"700",letterSpacing:.6,textTransform:"uppercase"},cmpRow:{flexDirection:"row",paddingHorizontal:12,paddingVertical:8,gap:8,alignItems:"flex-start"},cmpDiff:{backgroundColor:night.color.fill},cmpKey:{width:90,color:night.color.textSecondary,fontSize:night.font.caption},cmpVal:{flex:1,color:night.color.text,fontSize:night.font.caption,fontFamily:"Menlo"},cardImage:{width:"100%",height:140,backgroundColor:night.color.fill},cardText:{paddingHorizontal:12,paddingTop:10,paddingBottom:4,gap:4},cardTitle:{color:night.color.text,fontSize:night.font.row,fontWeight:"600"},fact:{flexDirection:"row",justifyContent:"space-between",gap:8},factLabel:{color:night.color.textSecondary,fontSize:night.font.caption},factValue:{color:night.color.text,fontSize:night.font.caption,fontWeight:"500"},carouselTitle:{color:night.color.text,fontSize:night.font.caption,fontWeight:"600",paddingBottom:8},carousel:{gap:8,paddingRight:8},carouselCard:{width:224,borderRadius:night.radius.card,borderWidth:StyleSheet.hairlineWidth,borderColor:night.color.border,backgroundColor:night.color.surface,overflow:"hidden"},shot:{width:"100%",height:220,backgroundColor:night.color.fill},shotBig:{height:520},progress:{height:4,backgroundColor:night.color.fill,marginHorizontal:12,marginTop:6,marginBottom:8,borderRadius:2,overflow:"hidden"},progressFill:{height:4,backgroundColor:night.color.accent},step:{flexDirection:"row",alignItems:"center",gap:10,paddingHorizontal:12,paddingVertical:9},stepMark:{width:20,height:20,borderRadius:10,backgroundColor:night.color.fillTertiary,alignItems:"center",justifyContent:"center"},stepDone:{backgroundColor:night.color.accent},stepFailed:{backgroundColor:night.color.danger},stepRunning:{backgroundColor:night.color.info},stepNum:{color:night.color.text,fontSize:night.font.micro,fontWeight:"700"},checkpoint:{alignSelf:"flex-start",flexDirection:"row",alignItems:"center",gap:8,paddingHorizontal:12,paddingVertical:7,borderRadius:night.radius.chip,backgroundColor:night.color.fill},cpFlag:{width:8,height:8,borderRadius:2,backgroundColor:night.color.info},cpText:{color:night.color.textSecondary,fontSize:night.font.caption},cpRestore:{color:night.color.accent,fontSize:night.font.caption,fontWeight:"600"},taskHead:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:8,paddingHorizontal:12,paddingTop:12},banner:{flexDirection:"row",alignItems:"center",gap:8,paddingLeft:12,paddingRight:4,paddingVertical:4,borderRadius:night.radius.row,borderWidth:StyleSheet.hairlineWidth},bannerText:{flex:1,fontSize:night.font.caption,fontWeight:"600"},fileIcon:{width:40,height:40,borderRadius:8,backgroundColor:night.color.fill,alignItems:"center",justifyContent:"center"},fileExt:{color:night.color.textSecondary,fontSize:10,fontWeight:"800"}});
1
+ "use strict";
2
+
3
+ /**
4
+ * Second-wave blocks from the survey (plan §11). Prototype-quality on purpose:
5
+ * each one exists so it can be judged on the review page, and the ones that
6
+ * survive get the same care as the first wave.
7
+ */
8
+ import { useEffect, useRef, useState } from "react";
9
+ import { Animated, Image, Pressable, ScrollView, StyleSheet, Switch, Text, TextInput, View } from "react-native";
10
+ import { AlertTriangle, Check, ChevronDown, ChevronRight, night, NightSegmented, RefreshCw, Search, X } from "@buoy-gg/shared-ui";
11
+ import { useBlockHandlers } from "./context";
12
+ import { ActionRow, blockStyles as b, Card, More, toneColor, usePaged } from "./primitives";
13
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
14
+ const fmt = v => typeof v === "string" ? v : v === undefined ? "—" : JSON.stringify(v);
15
+
16
+ // ---------------------------------------------------------------- Suggestions
17
+ export function Suggestions({
18
+ block
19
+ }) {
20
+ const h = useBlockHandlers();
21
+ return /*#__PURE__*/_jsx(View, {
22
+ style: styles.chips,
23
+ testID: `buoy-block-suggestions-${block.id}`,
24
+ children: block.chips.slice(0, 4).map(c => /*#__PURE__*/_jsx(Pressable, {
25
+ disabled: !!h.busy,
26
+ onPress: () => void h.runAction({
27
+ label: c.label,
28
+ send: c.send ?? c.label
29
+ }, block.id),
30
+ style: ({
31
+ pressed
32
+ }) => [styles.chip, pressed && styles.pressed],
33
+ accessibilityRole: "button",
34
+ children: /*#__PURE__*/_jsx(Text, {
35
+ style: styles.chipText,
36
+ children: c.label
37
+ })
38
+ }, c.label))
39
+ });
40
+ }
41
+
42
+ // ---------------------------------------------------------------- MultiSelect
43
+ export function MultiSelect({
44
+ block
45
+ }) {
46
+ const h = useBlockHandlers();
47
+ const answer = h.answered[block.id];
48
+ const locked = !!answer;
49
+ const [picked, setPicked] = useState([]);
50
+ const chosen = answer?.kind === "multi" ? answer.optionIds : picked;
51
+ const toggle = id => setPicked(p => p.includes(id) ? p.filter(x => x !== id) : [...p, id]);
52
+ const ok = picked.length >= (block.min ?? 1) && (!block.max || picked.length <= block.max);
53
+ return /*#__PURE__*/_jsxs(Card, {
54
+ testID: `buoy-block-multi-${block.id}`,
55
+ tone: locked ? undefined : "info",
56
+ children: [/*#__PURE__*/_jsx(Text, {
57
+ style: styles.question,
58
+ children: block.question
59
+ }), /*#__PURE__*/_jsx(View, {
60
+ style: styles.optionsBox,
61
+ children: block.options.map((o, i) => {
62
+ const on = chosen.includes(o.id);
63
+ return /*#__PURE__*/_jsxs(Pressable, {
64
+ disabled: locked,
65
+ onPress: () => toggle(o.id),
66
+ style: [styles.option, i > 0 && b.rowDivider, locked && !on && styles.dim],
67
+ accessibilityRole: "checkbox",
68
+ accessibilityState: {
69
+ checked: on
70
+ },
71
+ children: [/*#__PURE__*/_jsx(View, {
72
+ style: [styles.checkbox, on && styles.checkboxOn],
73
+ children: on ? /*#__PURE__*/_jsx(Check, {
74
+ size: 11,
75
+ color: night.color.onAccent
76
+ }) : null
77
+ }), /*#__PURE__*/_jsxs(View, {
78
+ style: styles.flex,
79
+ children: [/*#__PURE__*/_jsx(Text, {
80
+ style: styles.optionLabel,
81
+ children: o.label
82
+ }), o.detail ? /*#__PURE__*/_jsx(Text, {
83
+ style: styles.optionDetail,
84
+ children: o.detail
85
+ }) : null]
86
+ })]
87
+ }, o.id);
88
+ })
89
+ }), locked ? null : /*#__PURE__*/_jsx(View, {
90
+ style: styles.rowEnd,
91
+ children: /*#__PURE__*/_jsx(Pressable, {
92
+ testID: "buoy-block-multi-submit",
93
+ disabled: !ok,
94
+ onPress: () => h.answer({
95
+ blockId: block.id,
96
+ kind: "multi",
97
+ optionIds: picked,
98
+ labels: block.options.filter(o => picked.includes(o.id)).map(o => o.label)
99
+ }),
100
+ style: [styles.button, styles.buttonPrimary, !ok && styles.disabled],
101
+ children: /*#__PURE__*/_jsx(Text, {
102
+ style: styles.buttonTextPrimary,
103
+ children: block.submitLabel ?? `Use ${picked.length || ""}`.trim()
104
+ })
105
+ })
106
+ })]
107
+ });
108
+ }
109
+
110
+ // ---------------------------------------------------------------- Select (long list)
111
+ /** Options needed before a search field earns its space. */
112
+ const SEARCH_FROM = 8;
113
+ export function Select({
114
+ block
115
+ }) {
116
+ const h = useBlockHandlers();
117
+ const answer = h.answered[block.id];
118
+ const [q, setQ] = useState("");
119
+ const [open, setOpen] = useState(false);
120
+ const chosen = answer?.kind === "select" ? answer.label : null;
121
+ const items = block.options.filter(o => !q || o.label.toLowerCase().includes(q.toLowerCase())).slice(0, 8);
122
+ /**
123
+ * A search field over four options is furniture. `searchable` stays the
124
+ * author's opt-OUT (false always hides it); it is no longer an opt-IN for a
125
+ * list short enough to read at a glance.
126
+ */
127
+ const showSearch = block.searchable !== false && block.options.length >= SEARCH_FROM;
128
+ return /*#__PURE__*/_jsxs(Card, {
129
+ testID: `buoy-block-select-${block.id}`,
130
+ tone: answer ? undefined : "info",
131
+ children: [/*#__PURE__*/_jsx(Text, {
132
+ style: styles.question,
133
+ children: block.label
134
+ }), chosen ? /*#__PURE__*/_jsx(Text, {
135
+ style: styles.decided,
136
+ children: chosen
137
+ }) : /*#__PURE__*/_jsxs(View, {
138
+ style: styles.selectBox,
139
+ children: [/*#__PURE__*/_jsxs(Pressable, {
140
+ onPress: () => setOpen(v => !v),
141
+ style: styles.selectField,
142
+ accessibilityRole: "button",
143
+ children: [/*#__PURE__*/_jsx(Text, {
144
+ style: styles.selectPlaceholder,
145
+ children: open ? "Choose…" : `${block.options.length} options`
146
+ }), /*#__PURE__*/_jsx(ChevronDown, {
147
+ size: 14,
148
+ color: night.color.textSecondary
149
+ })]
150
+ }), open && /*#__PURE__*/_jsxs(_Fragment, {
151
+ children: [showSearch && /*#__PURE__*/_jsxs(View, {
152
+ style: styles.search,
153
+ children: [/*#__PURE__*/_jsx(Search, {
154
+ size: 12,
155
+ color: night.color.textSecondary
156
+ }), /*#__PURE__*/_jsx(TextInput, {
157
+ style: styles.searchInput,
158
+ value: q,
159
+ onChangeText: setQ,
160
+ placeholder: "Search",
161
+ placeholderTextColor: night.color.placeholder,
162
+ autoCapitalize: "none",
163
+ autoCorrect: false
164
+ })]
165
+ }), items.map((o, i) => /*#__PURE__*/_jsxs(Pressable, {
166
+ onPress: () => h.answer({
167
+ blockId: block.id,
168
+ kind: "select",
169
+ optionId: o.id,
170
+ label: o.label
171
+ }),
172
+ style: [styles.option, i > 0 && b.rowDivider],
173
+ accessibilityRole: "button",
174
+ children: [/*#__PURE__*/_jsxs(View, {
175
+ style: styles.flex,
176
+ children: [/*#__PURE__*/_jsx(Text, {
177
+ style: styles.optionLabel,
178
+ children: o.label
179
+ }), o.detail ? /*#__PURE__*/_jsx(Text, {
180
+ style: styles.optionDetail,
181
+ children: o.detail
182
+ }) : null]
183
+ }), /*#__PURE__*/_jsx(ChevronRight, {
184
+ size: 12,
185
+ color: night.color.textTertiary
186
+ })]
187
+ }, o.id)), block.options.length > items.length ? /*#__PURE__*/_jsxs(Text, {
188
+ style: styles.hint,
189
+ children: [block.options.length - items.length, " more \u2014 keep typing"]
190
+ }) : null]
191
+ })]
192
+ })]
193
+ });
194
+ }
195
+
196
+ // ---------------------------------------------------------------- Slider
197
+ /**
198
+ * Tap anywhere on the track to jump there, or use the − / + steppers. No drag
199
+ * on purpose: a drag inside a scrolling transcript fights the list for the
200
+ * gesture, and a tap-to-place slider does the job with none of that.
201
+ */
202
+ function SliderControl({
203
+ min,
204
+ max,
205
+ step = 1,
206
+ value,
207
+ unit,
208
+ onChange,
209
+ disabled
210
+ }) {
211
+ const width = useRef(0);
212
+ const pct = max > min ? (value - min) / (max - min) * 100 : 0;
213
+ const quantise = raw => Math.min(max, Math.max(min, +(Math.round((raw - min) / step) * step + min).toFixed(6)));
214
+ const bump = d => !disabled && onChange(quantise(value + d * step));
215
+ const onTrackPress = e => {
216
+ if (disabled || width.current <= 0) return;
217
+ const ratio = Math.min(1, Math.max(0, e.nativeEvent.locationX / width.current));
218
+ onChange(quantise(min + ratio * (max - min)));
219
+ };
220
+ const onLayout = e => {
221
+ width.current = e.nativeEvent.layout.width;
222
+ };
223
+ return /*#__PURE__*/_jsxs(View, {
224
+ style: styles.sliderRow,
225
+ children: [/*#__PURE__*/_jsx(Pressable, {
226
+ disabled: disabled,
227
+ onPress: () => bump(-1),
228
+ style: styles.stepBtn,
229
+ accessibilityRole: "button",
230
+ accessibilityLabel: "Decrease",
231
+ children: /*#__PURE__*/_jsx(Text, {
232
+ style: styles.stepText,
233
+ children: "\u2212"
234
+ })
235
+ }), /*#__PURE__*/_jsx(Pressable, {
236
+ style: styles.trackHit,
237
+ onLayout: onLayout,
238
+ onPress: onTrackPress,
239
+ disabled: disabled,
240
+ accessibilityRole: "adjustable",
241
+ accessibilityValue: {
242
+ min,
243
+ max,
244
+ now: value
245
+ },
246
+ accessibilityActions: [{
247
+ name: "increment"
248
+ }, {
249
+ name: "decrement"
250
+ }],
251
+ onAccessibilityAction: e => bump(e.nativeEvent.actionName === "increment" ? 1 : -1),
252
+ children: /*#__PURE__*/_jsxs(View, {
253
+ style: styles.track,
254
+ pointerEvents: "none",
255
+ children: [/*#__PURE__*/_jsx(View, {
256
+ style: [styles.fill, {
257
+ width: `${pct}%`
258
+ }]
259
+ }), /*#__PURE__*/_jsx(View, {
260
+ style: [styles.thumb, {
261
+ left: `${pct}%`
262
+ }]
263
+ })]
264
+ })
265
+ }), /*#__PURE__*/_jsx(Pressable, {
266
+ disabled: disabled,
267
+ onPress: () => bump(1),
268
+ style: styles.stepBtn,
269
+ accessibilityRole: "button",
270
+ accessibilityLabel: "Increase",
271
+ children: /*#__PURE__*/_jsx(Text, {
272
+ style: styles.stepText,
273
+ children: "+"
274
+ })
275
+ }), /*#__PURE__*/_jsxs(Text, {
276
+ style: styles.sliderValue,
277
+ children: [value, unit ? ` ${unit}` : ""]
278
+ })]
279
+ });
280
+ }
281
+ export function Slider({
282
+ block
283
+ }) {
284
+ const h = useBlockHandlers();
285
+ const answer = h.answered[block.id];
286
+ const [v, setV] = useState(block.value ?? block.min);
287
+ return /*#__PURE__*/_jsxs(Card, {
288
+ testID: `buoy-block-slider-${block.id}`,
289
+ tone: answer ? undefined : "info",
290
+ children: [/*#__PURE__*/_jsx(Text, {
291
+ style: styles.question,
292
+ children: block.label
293
+ }), /*#__PURE__*/_jsx(View, {
294
+ style: styles.pad,
295
+ children: /*#__PURE__*/_jsx(SliderControl, {
296
+ min: block.min,
297
+ max: block.max,
298
+ step: block.step,
299
+ value: answer?.kind === "slider" ? answer.value : v,
300
+ unit: block.unit,
301
+ onChange: setV,
302
+ disabled: !!answer
303
+ })
304
+ }), answer ? null : /*#__PURE__*/_jsx(View, {
305
+ style: styles.rowEnd,
306
+ children: /*#__PURE__*/_jsx(Pressable, {
307
+ onPress: () => h.answer({
308
+ blockId: block.id,
309
+ kind: "slider",
310
+ value: v,
311
+ unit: block.unit
312
+ }),
313
+ style: [styles.button, styles.buttonPrimary],
314
+ children: /*#__PURE__*/_jsxs(Text, {
315
+ style: styles.buttonTextPrimary,
316
+ children: ["Use ", v, block.unit ? ` ${block.unit}` : ""]
317
+ })
318
+ })
319
+ })]
320
+ });
321
+ }
322
+
323
+ // ---------------------------------------------------------------- DateTime
324
+ export function DateTime({
325
+ block
326
+ }) {
327
+ const h = useBlockHandlers();
328
+ const answer = h.answered[block.id];
329
+ const [text, setText] = useState("");
330
+ const presets = block.presets ?? [{
331
+ label: "Now",
332
+ value: new Date().toISOString()
333
+ }, {
334
+ label: "Tomorrow",
335
+ value: new Date(Date.now() + 864e5).toISOString()
336
+ }, {
337
+ label: "+7 days",
338
+ value: new Date(Date.now() + 7 * 864e5).toISOString()
339
+ }, {
340
+ label: "+30 days",
341
+ value: new Date(Date.now() + 30 * 864e5).toISOString()
342
+ }];
343
+ return /*#__PURE__*/_jsxs(Card, {
344
+ testID: `buoy-block-datetime-${block.id}`,
345
+ tone: answer ? undefined : "info",
346
+ children: [/*#__PURE__*/_jsx(Text, {
347
+ style: styles.question,
348
+ children: block.label
349
+ }), answer ? /*#__PURE__*/_jsx(Text, {
350
+ style: styles.decided,
351
+ children: answer.kind === "dateTime" ? answer.label ?? answer.value : "(skipped)"
352
+ }) : /*#__PURE__*/_jsxs(_Fragment, {
353
+ children: [/*#__PURE__*/_jsx(View, {
354
+ style: [styles.chips, styles.pad],
355
+ children: presets.map(p => /*#__PURE__*/_jsx(Pressable, {
356
+ onPress: () => h.answer({
357
+ blockId: block.id,
358
+ kind: "dateTime",
359
+ value: p.value,
360
+ label: p.label
361
+ }),
362
+ style: styles.chip,
363
+ children: /*#__PURE__*/_jsx(Text, {
364
+ style: styles.chipText,
365
+ children: p.label
366
+ })
367
+ }, p.label))
368
+ }), /*#__PURE__*/_jsxs(View, {
369
+ style: [styles.inputRow, styles.pad],
370
+ children: [/*#__PURE__*/_jsx(TextInput, {
371
+ style: styles.input,
372
+ value: text,
373
+ onChangeText: setText,
374
+ placeholder: block.mode === "time" ? "14:30" : "2026-09-15",
375
+ placeholderTextColor: night.color.placeholder,
376
+ keyboardType: "numbers-and-punctuation"
377
+ }), /*#__PURE__*/_jsx(Pressable, {
378
+ disabled: !text.trim(),
379
+ onPress: () => h.answer({
380
+ blockId: block.id,
381
+ kind: "dateTime",
382
+ value: text.trim()
383
+ }),
384
+ style: [styles.button, styles.buttonPrimary, !text.trim() && styles.disabled],
385
+ children: /*#__PURE__*/_jsx(Text, {
386
+ style: styles.buttonTextPrimary,
387
+ children: "Use"
388
+ })
389
+ })]
390
+ })]
391
+ })]
392
+ });
393
+ }
394
+
395
+ // ---------------------------------------------------------------- Form / Proposal
396
+ function FieldRow({
397
+ f,
398
+ value,
399
+ onChange,
400
+ disabled
401
+ }) {
402
+ if (f.type === "toggle") {
403
+ return /*#__PURE__*/_jsxs(View, {
404
+ style: styles.fieldRow,
405
+ children: [/*#__PURE__*/_jsx(Text, {
406
+ style: styles.fieldLabel,
407
+ children: f.label
408
+ }), /*#__PURE__*/_jsx(Switch, {
409
+ value: !!value,
410
+ onValueChange: onChange,
411
+ disabled: disabled,
412
+ trackColor: {
413
+ true: night.color.accent,
414
+ false: night.color.fillTertiary
415
+ },
416
+ thumbColor: night.color.knob
417
+ })]
418
+ });
419
+ }
420
+ if (f.type === "select") {
421
+ return /*#__PURE__*/_jsxs(View, {
422
+ style: styles.fieldCol,
423
+ children: [/*#__PURE__*/_jsx(Text, {
424
+ style: styles.fieldLabel,
425
+ children: f.label
426
+ }), /*#__PURE__*/_jsx(View, {
427
+ style: styles.chips,
428
+ children: f.options.map(o => /*#__PURE__*/_jsx(Pressable, {
429
+ disabled: disabled,
430
+ onPress: () => onChange(o.id),
431
+ style: [styles.chip, value === o.id && styles.chipOn],
432
+ children: /*#__PURE__*/_jsx(Text, {
433
+ style: [styles.chipText, value === o.id && styles.chipTextOn],
434
+ children: o.label
435
+ })
436
+ }, o.id))
437
+ })]
438
+ });
439
+ }
440
+ if (f.type === "slider") {
441
+ return /*#__PURE__*/_jsxs(View, {
442
+ style: styles.fieldCol,
443
+ children: [/*#__PURE__*/_jsx(Text, {
444
+ style: styles.fieldLabel,
445
+ children: f.label
446
+ }), /*#__PURE__*/_jsx(SliderControl, {
447
+ min: f.min,
448
+ max: f.max,
449
+ step: f.step,
450
+ unit: f.unit,
451
+ value: typeof value === "number" ? value : f.min,
452
+ onChange: onChange,
453
+ disabled: disabled
454
+ })]
455
+ });
456
+ }
457
+ return /*#__PURE__*/_jsxs(View, {
458
+ style: styles.fieldRow,
459
+ children: [/*#__PURE__*/_jsx(Text, {
460
+ style: styles.fieldLabel,
461
+ children: f.label
462
+ }), /*#__PURE__*/_jsx(TextInput, {
463
+ style: styles.fieldInput,
464
+ value: value === undefined || value === null ? "" : String(value),
465
+ onChangeText: onChange,
466
+ editable: !disabled,
467
+ placeholder: f.placeholder ?? "",
468
+ placeholderTextColor: night.color.placeholder,
469
+ keyboardType: f.type === "number" ? "numeric" : "ascii-capable",
470
+ secureTextEntry: f.type === "secret",
471
+ autoCapitalize: "none",
472
+ autoCorrect: false
473
+ })]
474
+ });
475
+ }
476
+ function useFormValues(fields) {
477
+ const [values, setValues] = useState(() => Object.fromEntries(fields.map(f => [f.key, f.value])));
478
+ return {
479
+ values,
480
+ set: (k, v) => setValues(m => ({
481
+ ...m,
482
+ [k]: v
483
+ }))
484
+ };
485
+ }
486
+ export function Form({
487
+ block
488
+ }) {
489
+ const h = useBlockHandlers();
490
+ const answer = h.answered[block.id];
491
+ const {
492
+ values,
493
+ set
494
+ } = useFormValues(block.fields);
495
+ return /*#__PURE__*/_jsxs(Card, {
496
+ title: block.title,
497
+ testID: `buoy-block-form-${block.id}`,
498
+ tone: answer ? undefined : "info",
499
+ children: [/*#__PURE__*/_jsx(View, {
500
+ style: styles.pad,
501
+ children: block.fields.map(f => /*#__PURE__*/_jsx(FieldRow, {
502
+ f: f,
503
+ value: values[f.key],
504
+ onChange: v => set(f.key, v),
505
+ disabled: !!answer
506
+ }, f.key))
507
+ }), answer ? /*#__PURE__*/_jsx(Text, {
508
+ style: styles.decided,
509
+ children: "Sent"
510
+ }) : /*#__PURE__*/_jsx(View, {
511
+ style: styles.rowEnd,
512
+ children: /*#__PURE__*/_jsx(Pressable, {
513
+ onPress: () => h.answer({
514
+ blockId: block.id,
515
+ kind: "form",
516
+ values
517
+ }),
518
+ style: [styles.button, styles.buttonPrimary],
519
+ children: /*#__PURE__*/_jsx(Text, {
520
+ style: styles.buttonTextPrimary,
521
+ children: block.submitLabel ?? "Send"
522
+ })
523
+ })
524
+ })]
525
+ });
526
+ }
527
+ export function Proposal({
528
+ block
529
+ }) {
530
+ const h = useBlockHandlers();
531
+ const answer = h.answered[block.id];
532
+ const {
533
+ values,
534
+ set
535
+ } = useFormValues(block.fields);
536
+ const approved = answer?.kind === "proposal" ? answer.approved : null;
537
+ return /*#__PURE__*/_jsxs(Card, {
538
+ testID: `buoy-block-proposal-${block.id}`,
539
+ tone: answer ? undefined : "warning",
540
+ children: [/*#__PURE__*/_jsx(Text, {
541
+ style: styles.confirmTitle,
542
+ children: block.title
543
+ }), /*#__PURE__*/_jsx(Text, {
544
+ style: styles.confirmChange,
545
+ children: block.change
546
+ }), /*#__PURE__*/_jsx(View, {
547
+ style: styles.pad,
548
+ children: block.fields.map(f => /*#__PURE__*/_jsx(FieldRow, {
549
+ f: f,
550
+ value: values[f.key],
551
+ onChange: v => set(f.key, v),
552
+ disabled: !!answer
553
+ }, f.key))
554
+ }), block.consequence ? /*#__PURE__*/_jsx(Text, {
555
+ style: styles.consequence,
556
+ children: block.consequence
557
+ }) : null, /*#__PURE__*/_jsx(View, {
558
+ style: styles.actionsRow,
559
+ children: answer ? /*#__PURE__*/_jsx(Text, {
560
+ style: styles.decided,
561
+ children: approved ? "✓ Applied with these values" : "✕ Not applied"
562
+ }) : /*#__PURE__*/_jsxs(_Fragment, {
563
+ children: [/*#__PURE__*/_jsx(Pressable, {
564
+ onPress: () => h.answer({
565
+ blockId: block.id,
566
+ kind: "proposal",
567
+ approved: true,
568
+ values
569
+ }),
570
+ style: [styles.button, styles.buttonPrimary],
571
+ children: /*#__PURE__*/_jsx(Text, {
572
+ style: styles.buttonTextPrimary,
573
+ children: block.approveLabel ?? "Apply"
574
+ })
575
+ }), /*#__PURE__*/_jsx(Pressable, {
576
+ onPress: () => h.answer({
577
+ blockId: block.id,
578
+ kind: "proposal",
579
+ approved: false
580
+ }),
581
+ style: [styles.button, styles.buttonPlate],
582
+ children: /*#__PURE__*/_jsx(Text, {
583
+ style: styles.buttonTextPlate,
584
+ children: "Not now"
585
+ })
586
+ })]
587
+ })
588
+ })]
589
+ });
590
+ }
591
+
592
+ // ---------------------------------------------------------------- Claim (citations + verify)
593
+ export function Claim({
594
+ block
595
+ }) {
596
+ const h = useBlockHandlers();
597
+ const [open, setOpen] = useState(null);
598
+ const state = h.actionState?.[`${block.id}:${block.verify?.label ?? "Verify"}`];
599
+ const verified = block.verified || state === "done";
600
+ return /*#__PURE__*/_jsxs(View, {
601
+ style: styles.claim,
602
+ testID: `buoy-block-claim-${block.id}`,
603
+ children: [/*#__PURE__*/_jsxs(Text, {
604
+ style: styles.claimText,
605
+ children: [block.text, block.sources.map((s, i) => /*#__PURE__*/_jsxs(Text, {
606
+ onPress: () => setOpen(open === i ? null : i),
607
+ style: styles.cite,
608
+ children: [" [", i + 1, "]"]
609
+ }, i)), verified ? /*#__PURE__*/_jsx(Text, {
610
+ style: styles.verified,
611
+ children: " \u2713 verified"
612
+ }) : null]
613
+ }), open !== null && block.sources[open] ? /*#__PURE__*/_jsxs(View, {
614
+ style: styles.citeBox,
615
+ children: [/*#__PURE__*/_jsxs(Text, {
616
+ style: styles.citeLabel,
617
+ children: ["[", open + 1, "] ", block.sources[open].label]
618
+ }), block.sources[open].detail ? /*#__PURE__*/_jsx(Text, {
619
+ style: styles.citeDetail,
620
+ children: block.sources[open].detail
621
+ }) : null]
622
+ }) : null, block.verify && !verified ? /*#__PURE__*/_jsxs(Pressable, {
623
+ onPress: () => void h.runAction(block.verify, block.id),
624
+ style: styles.verifyBtn,
625
+ accessibilityRole: "button",
626
+ children: [/*#__PURE__*/_jsx(RefreshCw, {
627
+ size: 11,
628
+ color: night.color.accent
629
+ }), /*#__PURE__*/_jsx(Text, {
630
+ style: styles.verifyText,
631
+ children: state === "running" ? "Checking…" : block.verify.label
632
+ })]
633
+ }) : null]
634
+ });
635
+ }
636
+
637
+ // ---------------------------------------------------------------- Details / Tabs
638
+ export function Details({
639
+ block
640
+ }) {
641
+ const [open, setOpen] = useState(!!block.open);
642
+ return /*#__PURE__*/_jsxs(Card, {
643
+ testID: `buoy-block-details-${block.id}`,
644
+ children: [/*#__PURE__*/_jsxs(Pressable, {
645
+ onPress: () => setOpen(v => !v),
646
+ style: b.row,
647
+ accessibilityRole: "button",
648
+ accessibilityState: {
649
+ expanded: open
650
+ },
651
+ children: [/*#__PURE__*/_jsx(Text, {
652
+ style: b.rowTitle,
653
+ children: block.summary
654
+ }), open ? /*#__PURE__*/_jsx(ChevronDown, {
655
+ size: 12,
656
+ color: night.color.textTertiary
657
+ }) : /*#__PURE__*/_jsx(ChevronRight, {
658
+ size: 12,
659
+ color: night.color.textTertiary
660
+ })]
661
+ }), open ? /*#__PURE__*/_jsx(Text, {
662
+ style: styles.detailsBody,
663
+ selectable: true,
664
+ children: block.body
665
+ }) : null]
666
+ });
667
+ }
668
+
669
+ /**
670
+ * The tool-header segmented control, not a strip of this block's own.
671
+ *
672
+ * `NightSegmented` is what the dial settings and the network tool mount, so a
673
+ * tabbed block now reads as part of the same product rather than as a
674
+ * lookalike drawn next to it. `sm` is its compact variant, which is what a
675
+ * control inside a chat bubble wants.
676
+ *
677
+ * Keyed by INDEX, not label: two tabs may legitimately share a label, and a
678
+ * duplicate key would collapse them into one.
679
+ */
680
+ export function Tabs({
681
+ block,
682
+ renderNested
683
+ }) {
684
+ const [i, setI] = useState(0);
685
+ const tabs = block.tabs.map((t, k) => ({
686
+ key: String(k),
687
+ label: t.label
688
+ }));
689
+ const active = block.tabs[i];
690
+ return /*#__PURE__*/_jsxs(View, {
691
+ style: styles.tabsWrap,
692
+ testID: `buoy-block-tabs-${block.id}`,
693
+ children: [/*#__PURE__*/_jsx(NightSegmented, {
694
+ tabs: tabs,
695
+ activeKey: String(i),
696
+ onChange: key => setI(Number(key)),
697
+ size: "sm"
698
+ }), active && renderNested ? renderNested(active.block) : null]
699
+ });
700
+ }
701
+
702
+ // ---------------------------------------------------------------- Timeline
703
+ /** Ten fits a phone without the answer above it scrolling away. */
704
+ const TIMELINE_CAP = 10;
705
+ export function Timeline({
706
+ block
707
+ }) {
708
+ /**
709
+ * The cap used to be a bare `.slice(0, 10)` while the "+N more" line below
710
+ * compared `total` against the FULL event array — so eleven events with a
711
+ * matching total rendered ten and said nothing about the eleventh, and a
712
+ * total larger than the array rendered a "+N more" that was only ever a
713
+ * label. Both counts come from the pager now.
714
+ */
715
+ const paged = usePaged(block.events, TIMELINE_CAP);
716
+ return /*#__PURE__*/_jsxs(Card, {
717
+ title: block.title ?? "What happened",
718
+ source: block.source,
719
+ testID: `buoy-block-timeline-${block.id}`,
720
+ children: [paged.visible.map((e, i) => /*#__PURE__*/_jsxs(View, {
721
+ style: styles.tlRow,
722
+ children: [/*#__PURE__*/_jsx(Text, {
723
+ style: styles.tlAt,
724
+ children: e.at
725
+ }), /*#__PURE__*/_jsxs(View, {
726
+ style: styles.tlLine,
727
+ children: [/*#__PURE__*/_jsx(View, {
728
+ style: [styles.tlDot, {
729
+ backgroundColor: toneColor(e.tone ?? "muted")
730
+ }]
731
+ }), i < paged.visible.length - 1 ? /*#__PURE__*/_jsx(View, {
732
+ style: styles.tlStem
733
+ }) : null]
734
+ }), /*#__PURE__*/_jsxs(View, {
735
+ style: styles.flex,
736
+ children: [/*#__PURE__*/_jsx(Text, {
737
+ style: styles.tlSource,
738
+ children: e.source.toUpperCase()
739
+ }), /*#__PURE__*/_jsx(Text, {
740
+ style: b.rowTitle,
741
+ numberOfLines: 2,
742
+ children: e.label
743
+ })]
744
+ })]
745
+ }, i)), /*#__PURE__*/_jsx(More, {
746
+ paged: paged
747
+ })]
748
+ });
749
+ }
750
+
751
+ // ---------------------------------------------------------------- Sparkline
752
+ export function Sparkline({
753
+ block
754
+ }) {
755
+ const s = block.series.slice(-60);
756
+ const max = Math.max(1, ...s);
757
+ const min = Math.min(...s, 0);
758
+ const H = 44;
759
+ return /*#__PURE__*/_jsxs(Card, {
760
+ title: block.title,
761
+ source: block.source,
762
+ testID: `buoy-block-sparkline-${block.id}`,
763
+ children: [/*#__PURE__*/_jsxs(View, {
764
+ style: styles.sparkHead,
765
+ children: [/*#__PURE__*/_jsxs(Text, {
766
+ style: styles.sparkCurrent,
767
+ children: [block.current ?? s[s.length - 1], block.unit ? /*#__PURE__*/_jsxs(Text, {
768
+ style: styles.sparkUnit,
769
+ children: [" ", block.unit]
770
+ }) : null]
771
+ }), block.live ? /*#__PURE__*/_jsx(LivePill, {}) : null]
772
+ }), /*#__PURE__*/_jsx(View, {
773
+ style: [styles.spark, {
774
+ height: H
775
+ }],
776
+ children: s.map((v, i) => /*#__PURE__*/_jsx(View, {
777
+ style: [styles.sparkBar, {
778
+ height: Math.max(2, (v - min) / (max - min || 1) * H),
779
+ backgroundColor: i === s.length - 1 ? night.color.accent : night.color.accentBorderStrong
780
+ }]
781
+ }, i))
782
+ }), block.label ? /*#__PURE__*/_jsx(Text, {
783
+ style: styles.hint,
784
+ children: block.label
785
+ }) : null]
786
+ });
787
+ }
788
+ export function LivePill() {
789
+ const o = useRef(new Animated.Value(1)).current;
790
+ useEffect(() => {
791
+ const loop = Animated.loop(Animated.sequence([Animated.timing(o, {
792
+ toValue: 0.3,
793
+ duration: 700,
794
+ useNativeDriver: true
795
+ }), Animated.timing(o, {
796
+ toValue: 1,
797
+ duration: 700,
798
+ useNativeDriver: true
799
+ })]));
800
+ loop.start();
801
+ return () => loop.stop();
802
+ }, [o]);
803
+ return /*#__PURE__*/_jsxs(View, {
804
+ style: styles.live,
805
+ children: [/*#__PURE__*/_jsx(Animated.View, {
806
+ style: [styles.liveDot, {
807
+ opacity: o
808
+ }]
809
+ }), /*#__PURE__*/_jsx(Text, {
810
+ style: styles.liveText,
811
+ children: "LIVE"
812
+ })]
813
+ });
814
+ }
815
+
816
+ // ---------------------------------------------------------------- Compare
817
+ export function Compare({
818
+ block
819
+ }) {
820
+ const keys = [...new Set([...block.left.pairs.map(p => p.key), ...block.right.pairs.map(p => p.key)])];
821
+ const l = Object.fromEntries(block.left.pairs.map(p => [p.key, p.value]));
822
+ const r = Object.fromEntries(block.right.pairs.map(p => [p.key, p.value]));
823
+ return /*#__PURE__*/_jsxs(Card, {
824
+ title: block.title,
825
+ source: block.source,
826
+ testID: `buoy-block-compare-${block.id}`,
827
+ children: [/*#__PURE__*/_jsxs(View, {
828
+ style: styles.cmpHead,
829
+ children: [/*#__PURE__*/_jsx(Text, {
830
+ style: styles.cmpKey
831
+ }), /*#__PURE__*/_jsx(Text, {
832
+ style: styles.cmpCol,
833
+ children: block.left.title
834
+ }), /*#__PURE__*/_jsx(Text, {
835
+ style: styles.cmpCol,
836
+ children: block.right.title
837
+ })]
838
+ }), keys.map((k, i) => {
839
+ const diff = JSON.stringify(l[k]) !== JSON.stringify(r[k]);
840
+ return /*#__PURE__*/_jsxs(View, {
841
+ style: [styles.cmpRow, i > 0 && b.rowDivider, diff && styles.cmpDiff],
842
+ children: [/*#__PURE__*/_jsx(Text, {
843
+ style: styles.cmpKey,
844
+ numberOfLines: 1,
845
+ children: k
846
+ }), /*#__PURE__*/_jsx(Text, {
847
+ style: [styles.cmpVal, diff && {
848
+ color: night.color.danger
849
+ }],
850
+ numberOfLines: 2,
851
+ children: fmt(l[k])
852
+ }), /*#__PURE__*/_jsx(Text, {
853
+ style: [styles.cmpVal, diff && {
854
+ color: night.color.accent
855
+ }],
856
+ numberOfLines: 2,
857
+ children: fmt(r[k])
858
+ })]
859
+ }, k);
860
+ })]
861
+ });
862
+ }
863
+
864
+ // ---------------------------------------------------------------- Card / carousel
865
+ function CardBody({
866
+ c,
867
+ id
868
+ }) {
869
+ return /*#__PURE__*/_jsxs(_Fragment, {
870
+ children: [c.image ? /*#__PURE__*/_jsx(Image, {
871
+ source: {
872
+ uri: c.image
873
+ },
874
+ style: styles.cardImage,
875
+ resizeMode: "contain",
876
+ accessibilityLabel: c.title
877
+ }) : null, /*#__PURE__*/_jsxs(View, {
878
+ style: styles.cardText,
879
+ children: [/*#__PURE__*/_jsx(Text, {
880
+ style: styles.cardTitle,
881
+ numberOfLines: 2,
882
+ children: c.title
883
+ }), c.subtitle ? /*#__PURE__*/_jsx(Text, {
884
+ style: b.rowSub,
885
+ numberOfLines: 2,
886
+ children: c.subtitle
887
+ }) : null, c.facts?.slice(0, 4).map(f => /*#__PURE__*/_jsxs(View, {
888
+ style: styles.fact,
889
+ children: [/*#__PURE__*/_jsx(Text, {
890
+ style: styles.factLabel,
891
+ children: f.label
892
+ }), /*#__PURE__*/_jsx(Text, {
893
+ style: [styles.factValue, f.tone && {
894
+ color: toneColor(f.tone)
895
+ }],
896
+ children: f.value
897
+ })]
898
+ }, f.label))]
899
+ }), /*#__PURE__*/_jsx(ActionRow, {
900
+ actions: c.actions,
901
+ blockId: id
902
+ })]
903
+ });
904
+ }
905
+ export function CardView({
906
+ block
907
+ }) {
908
+ return /*#__PURE__*/_jsx(Card, {
909
+ source: block.source,
910
+ testID: `buoy-block-card-${block.id}`,
911
+ children: /*#__PURE__*/_jsx(CardBody, {
912
+ c: block,
913
+ id: block.id
914
+ })
915
+ });
916
+ }
917
+ export function CardCarousel({
918
+ block
919
+ }) {
920
+ return /*#__PURE__*/_jsxs(View, {
921
+ testID: `buoy-block-cardcarousel-${block.id}`,
922
+ children: [block.title ? /*#__PURE__*/_jsx(Text, {
923
+ style: styles.carouselTitle,
924
+ children: block.title
925
+ }) : null, /*#__PURE__*/_jsx(ScrollView, {
926
+ horizontal: true,
927
+ showsHorizontalScrollIndicator: false,
928
+ snapToInterval: 232,
929
+ decelerationRate: "fast",
930
+ contentContainerStyle: styles.carousel,
931
+ children: block.cards.slice(0, 8).map((c, i) => /*#__PURE__*/_jsx(View, {
932
+ style: styles.carouselCard,
933
+ children: /*#__PURE__*/_jsx(CardBody, {
934
+ c: c,
935
+ id: `${block.id}-${i}`
936
+ })
937
+ }, `${c.title}-${i}`))
938
+ })]
939
+ });
940
+ }
941
+
942
+ // ---------------------------------------------------------------- Screenshot
943
+ export function Screenshot({
944
+ block
945
+ }) {
946
+ const [big, setBig] = useState(false);
947
+ return /*#__PURE__*/_jsxs(Card, {
948
+ title: block.route ? `Screen · ${block.route}` : "Screen",
949
+ source: block.source,
950
+ testID: `buoy-block-screenshot-${block.id}`,
951
+ children: [/*#__PURE__*/_jsx(Pressable, {
952
+ onPress: () => setBig(v => !v),
953
+ accessibilityRole: "imagebutton",
954
+ accessibilityLabel: block.caption ?? "Screenshot",
955
+ children: /*#__PURE__*/_jsx(Image, {
956
+ source: {
957
+ uri: block.url
958
+ },
959
+ style: [styles.shot, big && styles.shotBig],
960
+ resizeMode: "contain"
961
+ })
962
+ }), block.caption ? /*#__PURE__*/_jsx(Text, {
963
+ style: styles.hint,
964
+ children: block.caption
965
+ }) : null]
966
+ });
967
+ }
968
+
969
+ // ---------------------------------------------------------------- Plan / Checkpoint / Task
970
+ export function Plan({
971
+ block
972
+ }) {
973
+ const done = block.steps.filter(s => s.state === "done").length;
974
+ return /*#__PURE__*/_jsxs(Card, {
975
+ title: block.title,
976
+ testID: `buoy-block-plan-${block.id}`,
977
+ tone: block.pending ? "info" : undefined,
978
+ children: [/*#__PURE__*/_jsx(View, {
979
+ style: styles.progress,
980
+ children: /*#__PURE__*/_jsx(View, {
981
+ style: [styles.progressFill, {
982
+ width: `${done / Math.max(1, block.steps.length) * 100}%`
983
+ }]
984
+ })
985
+ }), block.steps.map((s, i) => /*#__PURE__*/_jsxs(View, {
986
+ style: [styles.step, i > 0 && b.rowDivider],
987
+ children: [/*#__PURE__*/_jsx(View, {
988
+ style: [styles.stepMark, s.state === "done" && styles.stepDone, s.state === "failed" && styles.stepFailed, s.state === "running" && styles.stepRunning],
989
+ children: s.state === "done" ? /*#__PURE__*/_jsx(Check, {
990
+ size: 10,
991
+ color: night.color.onAccent
992
+ }) : s.state === "failed" ? /*#__PURE__*/_jsx(X, {
993
+ size: 10,
994
+ color: night.color.text
995
+ }) : /*#__PURE__*/_jsx(Text, {
996
+ style: styles.stepNum,
997
+ children: i + 1
998
+ })
999
+ }), /*#__PURE__*/_jsxs(Text, {
1000
+ style: [b.rowTitle, s.state === "done" && styles.muted],
1001
+ children: [s.text, s.state === "running" ? "…" : ""]
1002
+ })]
1003
+ }, i)), /*#__PURE__*/_jsx(ActionRow, {
1004
+ actions: block.actions ?? (block.pending ? [{
1005
+ label: "Go",
1006
+ primary: true,
1007
+ send: "Go ahead with the plan."
1008
+ }, {
1009
+ label: "Change it",
1010
+ send: "Let me change the plan first."
1011
+ }] : undefined),
1012
+ blockId: block.id
1013
+ })]
1014
+ });
1015
+ }
1016
+ export function Checkpoint({
1017
+ block
1018
+ }) {
1019
+ const h = useBlockHandlers();
1020
+ return /*#__PURE__*/_jsxs(Pressable, {
1021
+ testID: `buoy-block-checkpoint-${block.id}`,
1022
+ disabled: !block.restore,
1023
+ onPress: () => block.restore && void h.runAction(block.restore, block.id),
1024
+ style: styles.checkpoint,
1025
+ accessibilityRole: "button",
1026
+ children: [/*#__PURE__*/_jsx(View, {
1027
+ style: styles.cpFlag
1028
+ }), /*#__PURE__*/_jsxs(Text, {
1029
+ style: styles.cpText,
1030
+ children: [block.label, block.at ? ` · ${block.at}` : ""]
1031
+ }), block.restore ? /*#__PURE__*/_jsx(Text, {
1032
+ style: styles.cpRestore,
1033
+ children: block.restore.label
1034
+ }) : null]
1035
+ });
1036
+ }
1037
+ export function Task({
1038
+ block
1039
+ }) {
1040
+ const color = block.status === "failed" ? night.color.danger : block.status === "done" ? night.color.accent : night.color.info;
1041
+ return /*#__PURE__*/_jsxs(Card, {
1042
+ testID: `buoy-block-task-${block.id}`,
1043
+ children: [/*#__PURE__*/_jsxs(View, {
1044
+ style: styles.taskHead,
1045
+ children: [/*#__PURE__*/_jsx(Text, {
1046
+ style: styles.cardTitle,
1047
+ children: block.title
1048
+ }), /*#__PURE__*/_jsx(View, {
1049
+ style: [b.pill, {
1050
+ backgroundColor: `${color}22`
1051
+ }],
1052
+ children: /*#__PURE__*/_jsx(Text, {
1053
+ style: [b.pillText, {
1054
+ color
1055
+ }],
1056
+ children: block.status.toUpperCase()
1057
+ })
1058
+ })]
1059
+ }), block.progress !== undefined ? /*#__PURE__*/_jsx(View, {
1060
+ style: [styles.progress, styles.pad],
1061
+ children: /*#__PURE__*/_jsx(View, {
1062
+ style: [styles.progressFill, {
1063
+ width: `${Math.round(block.progress * 100)}%`,
1064
+ backgroundColor: color
1065
+ }]
1066
+ })
1067
+ }) : null, block.detail ? /*#__PURE__*/_jsx(Text, {
1068
+ style: styles.hint,
1069
+ children: block.detail
1070
+ }) : null, /*#__PURE__*/_jsx(ActionRow, {
1071
+ actions: block.actions,
1072
+ blockId: block.id
1073
+ })]
1074
+ });
1075
+ }
1076
+
1077
+ // ---------------------------------------------------------------- Banner / File / Upload / NotBuilt
1078
+ export function Banner({
1079
+ block
1080
+ }) {
1081
+ const color = block.tone === "danger" ? night.color.danger : block.tone === "warning" ? night.color.warning : night.color.info;
1082
+ return /*#__PURE__*/_jsxs(View, {
1083
+ style: [styles.banner, {
1084
+ borderColor: color,
1085
+ backgroundColor: `${color}1A`
1086
+ }],
1087
+ testID: `buoy-block-banner-${block.id}`,
1088
+ children: [/*#__PURE__*/_jsx(AlertTriangle, {
1089
+ size: 13,
1090
+ color: color
1091
+ }), /*#__PURE__*/_jsx(Text, {
1092
+ style: [styles.bannerText, {
1093
+ color
1094
+ }],
1095
+ numberOfLines: 2,
1096
+ children: block.text
1097
+ }), block.actions?.[0] ? /*#__PURE__*/_jsx(ActionRow, {
1098
+ actions: block.actions.slice(0, 1),
1099
+ blockId: block.id,
1100
+ align: "right"
1101
+ }) : null]
1102
+ });
1103
+ }
1104
+ export function File({
1105
+ block
1106
+ }) {
1107
+ return /*#__PURE__*/_jsxs(Card, {
1108
+ testID: `buoy-block-file-${block.id}`,
1109
+ children: [/*#__PURE__*/_jsxs(View, {
1110
+ style: b.row,
1111
+ children: [/*#__PURE__*/_jsx(View, {
1112
+ style: styles.fileIcon,
1113
+ children: /*#__PURE__*/_jsx(Text, {
1114
+ style: styles.fileExt,
1115
+ children: (block.type ?? block.name.split(".").pop() ?? "file").toUpperCase().slice(0, 4)
1116
+ })
1117
+ }), /*#__PURE__*/_jsxs(View, {
1118
+ style: styles.flex,
1119
+ children: [/*#__PURE__*/_jsx(Text, {
1120
+ style: b.rowTitle,
1121
+ numberOfLines: 1,
1122
+ children: block.name
1123
+ }), block.size ? /*#__PURE__*/_jsx(Text, {
1124
+ style: b.rowSub,
1125
+ children: block.size
1126
+ }) : null]
1127
+ })]
1128
+ }), /*#__PURE__*/_jsx(ActionRow, {
1129
+ actions: block.actions,
1130
+ blockId: block.id
1131
+ })]
1132
+ });
1133
+ }
1134
+ export function Upload({
1135
+ block
1136
+ }) {
1137
+ const h = useBlockHandlers();
1138
+ const answer = h.answered[block.id];
1139
+ return /*#__PURE__*/_jsxs(Card, {
1140
+ testID: `buoy-block-upload-${block.id}`,
1141
+ tone: answer ? undefined : "info",
1142
+ children: [/*#__PURE__*/_jsx(Text, {
1143
+ style: styles.question,
1144
+ children: block.label
1145
+ }), answer ? /*#__PURE__*/_jsx(Text, {
1146
+ style: styles.decided,
1147
+ children: answer.kind === "upload" ? `Attached ${answer.name}` : "(skipped)"
1148
+ }) : /*#__PURE__*/_jsx(View, {
1149
+ style: [styles.rowEnd, {
1150
+ justifyContent: "flex-start"
1151
+ }],
1152
+ children: /*#__PURE__*/_jsx(Pressable, {
1153
+ onPress: () => h.answer({
1154
+ blockId: block.id,
1155
+ kind: "upload",
1156
+ name: "screenshot.png"
1157
+ }),
1158
+ style: [styles.button, styles.buttonPlate],
1159
+ children: /*#__PURE__*/_jsx(Text, {
1160
+ style: styles.buttonTextPlate,
1161
+ children: block.accept === "image" ? "Choose a screenshot" : "Choose a file"
1162
+ })
1163
+ })
1164
+ })]
1165
+ });
1166
+ }
1167
+ const styles = StyleSheet.create({
1168
+ flex: {
1169
+ flex: 1
1170
+ },
1171
+ pad: {
1172
+ paddingHorizontal: 12,
1173
+ paddingBottom: 8
1174
+ },
1175
+ muted: {
1176
+ color: night.color.textSecondary
1177
+ },
1178
+ dim: {
1179
+ opacity: 0.45
1180
+ },
1181
+ disabled: {
1182
+ opacity: 0.5
1183
+ },
1184
+ pressed: {
1185
+ opacity: 0.7
1186
+ },
1187
+ question: {
1188
+ color: night.color.text,
1189
+ fontSize: night.font.row,
1190
+ fontWeight: "600",
1191
+ lineHeight: 20,
1192
+ paddingHorizontal: 12,
1193
+ paddingTop: 12,
1194
+ paddingBottom: 8
1195
+ },
1196
+ hint: {
1197
+ color: night.color.textTertiary,
1198
+ fontSize: night.font.micro,
1199
+ paddingHorizontal: 12,
1200
+ paddingBottom: 10
1201
+ },
1202
+ decided: {
1203
+ color: night.color.textSecondary,
1204
+ fontSize: night.font.caption,
1205
+ fontWeight: "600",
1206
+ paddingHorizontal: 12,
1207
+ paddingVertical: 10
1208
+ },
1209
+ rowEnd: {
1210
+ flexDirection: "row",
1211
+ justifyContent: "flex-end",
1212
+ paddingHorizontal: 12,
1213
+ paddingBottom: 12,
1214
+ gap: 8
1215
+ },
1216
+ actionsRow: {
1217
+ flexDirection: "row",
1218
+ gap: 8,
1219
+ paddingHorizontal: 12,
1220
+ paddingVertical: 12,
1221
+ alignItems: "center"
1222
+ },
1223
+ button: {
1224
+ paddingHorizontal: 14,
1225
+ paddingVertical: 9,
1226
+ borderRadius: night.radius.row
1227
+ },
1228
+ buttonPrimary: {
1229
+ backgroundColor: night.color.accent
1230
+ },
1231
+ buttonPlate: {
1232
+ backgroundColor: night.color.button
1233
+ },
1234
+ buttonTextPrimary: {
1235
+ color: night.color.onAccent,
1236
+ fontSize: night.font.caption,
1237
+ fontWeight: "600"
1238
+ },
1239
+ buttonTextPlate: {
1240
+ color: night.color.text,
1241
+ fontSize: night.font.caption,
1242
+ fontWeight: "600"
1243
+ },
1244
+ chips: {
1245
+ flexDirection: "row",
1246
+ flexWrap: "wrap",
1247
+ gap: 6
1248
+ },
1249
+ chip: {
1250
+ paddingHorizontal: 12,
1251
+ paddingVertical: 7,
1252
+ borderRadius: night.radius.chip,
1253
+ backgroundColor: night.color.fill,
1254
+ borderWidth: StyleSheet.hairlineWidth,
1255
+ borderColor: night.color.border
1256
+ },
1257
+ chipOn: {
1258
+ backgroundColor: night.color.accentSoft,
1259
+ borderColor: night.color.accentBorderStrong
1260
+ },
1261
+ chipText: {
1262
+ color: night.color.text,
1263
+ fontSize: night.font.caption
1264
+ },
1265
+ chipTextOn: {
1266
+ color: night.color.accent,
1267
+ fontWeight: "600"
1268
+ },
1269
+ optionsBox: {
1270
+ marginHorizontal: 8,
1271
+ marginBottom: 8,
1272
+ borderRadius: night.radius.row,
1273
+ backgroundColor: night.color.surfaceElevated,
1274
+ overflow: "hidden"
1275
+ },
1276
+ option: {
1277
+ flexDirection: "row",
1278
+ alignItems: "center",
1279
+ gap: 10,
1280
+ paddingHorizontal: 12,
1281
+ paddingVertical: 10
1282
+ },
1283
+ optionLabel: {
1284
+ color: night.color.text,
1285
+ fontSize: night.font.body,
1286
+ fontWeight: "500"
1287
+ },
1288
+ optionDetail: {
1289
+ color: night.color.textSecondary,
1290
+ fontSize: night.font.caption
1291
+ },
1292
+ checkbox: {
1293
+ width: 20,
1294
+ height: 20,
1295
+ borderRadius: 6,
1296
+ borderWidth: 1.5,
1297
+ borderColor: night.color.textTertiary,
1298
+ alignItems: "center",
1299
+ justifyContent: "center"
1300
+ },
1301
+ checkboxOn: {
1302
+ backgroundColor: night.color.accent,
1303
+ borderColor: night.color.accent
1304
+ },
1305
+ selectBox: {
1306
+ marginHorizontal: 12,
1307
+ marginBottom: 12,
1308
+ borderRadius: night.radius.row,
1309
+ backgroundColor: night.color.surfaceElevated,
1310
+ overflow: "hidden"
1311
+ },
1312
+ selectField: {
1313
+ flexDirection: "row",
1314
+ alignItems: "center",
1315
+ justifyContent: "space-between",
1316
+ paddingHorizontal: 12,
1317
+ paddingVertical: 11
1318
+ },
1319
+ selectPlaceholder: {
1320
+ color: night.color.textSecondary,
1321
+ fontSize: night.font.body
1322
+ },
1323
+ search: {
1324
+ flexDirection: "row",
1325
+ alignItems: "center",
1326
+ gap: 6,
1327
+ paddingHorizontal: 12,
1328
+ paddingVertical: 6,
1329
+ borderTopWidth: StyleSheet.hairlineWidth,
1330
+ borderTopColor: night.color.separator
1331
+ },
1332
+ searchInput: {
1333
+ flex: 1,
1334
+ color: night.color.text,
1335
+ fontSize: night.font.caption,
1336
+ paddingVertical: 4
1337
+ },
1338
+ sliderRow: {
1339
+ flexDirection: "row",
1340
+ alignItems: "center",
1341
+ gap: 8
1342
+ },
1343
+ stepBtn: {
1344
+ width: 28,
1345
+ height: 28,
1346
+ borderRadius: 14,
1347
+ backgroundColor: night.color.fill,
1348
+ alignItems: "center",
1349
+ justifyContent: "center"
1350
+ },
1351
+ stepText: {
1352
+ color: night.color.text,
1353
+ fontSize: 16,
1354
+ fontWeight: "600"
1355
+ },
1356
+ trackHit: {
1357
+ flex: 1,
1358
+ height: 36,
1359
+ justifyContent: "center"
1360
+ },
1361
+ track: {
1362
+ height: 6,
1363
+ borderRadius: 3,
1364
+ backgroundColor: night.color.fillTertiary,
1365
+ justifyContent: "center"
1366
+ },
1367
+ fill: {
1368
+ height: 6,
1369
+ borderRadius: 3,
1370
+ backgroundColor: night.color.accent
1371
+ },
1372
+ thumb: {
1373
+ position: "absolute",
1374
+ width: 20,
1375
+ height: 20,
1376
+ borderRadius: 10,
1377
+ backgroundColor: night.color.knob,
1378
+ marginLeft: -10,
1379
+ shadowColor: "#000",
1380
+ shadowOpacity: 0.35,
1381
+ shadowRadius: 3,
1382
+ shadowOffset: {
1383
+ width: 0,
1384
+ height: 1
1385
+ }
1386
+ },
1387
+ sliderValue: {
1388
+ width: 64,
1389
+ textAlign: "right",
1390
+ color: night.color.text,
1391
+ fontSize: night.font.caption,
1392
+ fontWeight: "600"
1393
+ },
1394
+ inputRow: {
1395
+ flexDirection: "row",
1396
+ alignItems: "center",
1397
+ gap: 8,
1398
+ paddingBottom: 12
1399
+ },
1400
+ input: {
1401
+ flex: 1,
1402
+ height: 38,
1403
+ paddingHorizontal: 12,
1404
+ borderRadius: night.radius.row,
1405
+ backgroundColor: night.color.surfaceElevated,
1406
+ color: night.color.text,
1407
+ fontSize: night.font.body
1408
+ },
1409
+ fieldRow: {
1410
+ flexDirection: "row",
1411
+ alignItems: "center",
1412
+ justifyContent: "space-between",
1413
+ gap: 10,
1414
+ paddingVertical: 6
1415
+ },
1416
+ fieldCol: {
1417
+ paddingVertical: 6,
1418
+ gap: 6
1419
+ },
1420
+ fieldLabel: {
1421
+ color: night.color.textSecondary,
1422
+ fontSize: night.font.caption,
1423
+ width: 110
1424
+ },
1425
+ fieldInput: {
1426
+ flex: 1,
1427
+ height: 34,
1428
+ paddingHorizontal: 10,
1429
+ borderRadius: night.radius.segment,
1430
+ backgroundColor: night.color.surfaceElevated,
1431
+ color: night.color.text,
1432
+ fontSize: night.font.caption
1433
+ },
1434
+ confirmTitle: {
1435
+ color: night.color.text,
1436
+ fontSize: night.font.row,
1437
+ fontWeight: "600",
1438
+ paddingHorizontal: 12,
1439
+ paddingTop: 12
1440
+ },
1441
+ confirmChange: {
1442
+ color: night.color.text,
1443
+ fontSize: night.font.body,
1444
+ lineHeight: 19,
1445
+ paddingHorizontal: 12,
1446
+ paddingTop: 6,
1447
+ paddingBottom: 6
1448
+ },
1449
+ consequence: {
1450
+ color: night.color.warning,
1451
+ fontSize: night.font.caption,
1452
+ paddingHorizontal: 12
1453
+ },
1454
+ claim: {
1455
+ gap: 6,
1456
+ paddingHorizontal: 2
1457
+ },
1458
+ claimText: {
1459
+ color: night.color.text,
1460
+ fontSize: night.font.row,
1461
+ lineHeight: 22
1462
+ },
1463
+ cite: {
1464
+ color: night.color.accent,
1465
+ fontSize: night.font.caption,
1466
+ fontWeight: "700"
1467
+ },
1468
+ verified: {
1469
+ color: night.color.accent,
1470
+ fontSize: night.font.caption,
1471
+ fontWeight: "600"
1472
+ },
1473
+ citeBox: {
1474
+ padding: 10,
1475
+ borderRadius: night.radius.row,
1476
+ backgroundColor: night.color.surface,
1477
+ borderWidth: StyleSheet.hairlineWidth,
1478
+ borderColor: night.color.border,
1479
+ gap: 2
1480
+ },
1481
+ citeLabel: {
1482
+ color: night.color.text,
1483
+ fontSize: night.font.caption,
1484
+ fontWeight: "600"
1485
+ },
1486
+ citeDetail: {
1487
+ color: night.color.textSecondary,
1488
+ fontSize: night.font.caption,
1489
+ fontFamily: "Menlo"
1490
+ },
1491
+ verifyBtn: {
1492
+ alignSelf: "flex-start",
1493
+ flexDirection: "row",
1494
+ alignItems: "center",
1495
+ gap: 5,
1496
+ paddingHorizontal: 10,
1497
+ paddingVertical: 5,
1498
+ borderRadius: night.radius.chip,
1499
+ backgroundColor: night.color.accentSoft
1500
+ },
1501
+ verifyText: {
1502
+ color: night.color.accent,
1503
+ fontSize: night.font.micro,
1504
+ fontWeight: "700"
1505
+ },
1506
+ detailsBody: {
1507
+ color: night.color.textSecondary,
1508
+ fontSize: night.font.caption,
1509
+ lineHeight: 18,
1510
+ paddingHorizontal: 12,
1511
+ paddingBottom: 12
1512
+ },
1513
+ tabsWrap: {
1514
+ gap: 8
1515
+ },
1516
+ tabBar: {
1517
+ flexDirection: "row",
1518
+ gap: 6
1519
+ },
1520
+ tab: {
1521
+ paddingHorizontal: 12,
1522
+ paddingVertical: 6,
1523
+ borderRadius: night.radius.badge,
1524
+ backgroundColor: night.color.fill
1525
+ },
1526
+ tabOn: {
1527
+ backgroundColor: night.color.accentSoft
1528
+ },
1529
+ tabText: {
1530
+ color: night.color.textSecondary,
1531
+ fontSize: night.font.caption,
1532
+ fontWeight: "600"
1533
+ },
1534
+ tabTextOn: {
1535
+ color: night.color.accent
1536
+ },
1537
+ tlRow: {
1538
+ flexDirection: "row",
1539
+ gap: 10,
1540
+ paddingHorizontal: 12,
1541
+ paddingVertical: 4,
1542
+ alignItems: "flex-start"
1543
+ },
1544
+ tlAt: {
1545
+ width: 46,
1546
+ color: night.color.textTertiary,
1547
+ fontSize: night.font.micro,
1548
+ fontFamily: "Menlo",
1549
+ paddingTop: 3
1550
+ },
1551
+ tlLine: {
1552
+ width: 12,
1553
+ alignItems: "center"
1554
+ },
1555
+ tlDot: {
1556
+ width: 8,
1557
+ height: 8,
1558
+ borderRadius: 4,
1559
+ marginTop: 5
1560
+ },
1561
+ tlStem: {
1562
+ width: 1,
1563
+ flex: 1,
1564
+ minHeight: 18,
1565
+ backgroundColor: night.color.separator,
1566
+ marginTop: 2
1567
+ },
1568
+ tlSource: {
1569
+ color: night.color.textTertiary,
1570
+ fontSize: 9,
1571
+ fontWeight: "700",
1572
+ letterSpacing: 0.6
1573
+ },
1574
+ sparkHead: {
1575
+ flexDirection: "row",
1576
+ alignItems: "center",
1577
+ justifyContent: "space-between",
1578
+ paddingHorizontal: 12,
1579
+ paddingTop: 8
1580
+ },
1581
+ sparkCurrent: {
1582
+ color: night.color.text,
1583
+ fontSize: 22,
1584
+ fontWeight: "700"
1585
+ },
1586
+ sparkUnit: {
1587
+ color: night.color.textSecondary,
1588
+ fontSize: night.font.caption,
1589
+ fontWeight: "500"
1590
+ },
1591
+ spark: {
1592
+ flexDirection: "row",
1593
+ alignItems: "flex-end",
1594
+ gap: 2,
1595
+ paddingHorizontal: 12,
1596
+ paddingTop: 6,
1597
+ paddingBottom: 6
1598
+ },
1599
+ sparkBar: {
1600
+ flex: 1,
1601
+ borderRadius: 1
1602
+ },
1603
+ live: {
1604
+ flexDirection: "row",
1605
+ alignItems: "center",
1606
+ gap: 5,
1607
+ paddingHorizontal: 8,
1608
+ paddingVertical: 3,
1609
+ borderRadius: night.radius.badge,
1610
+ backgroundColor: night.color.dangerSoft
1611
+ },
1612
+ liveDot: {
1613
+ width: 6,
1614
+ height: 6,
1615
+ borderRadius: 3,
1616
+ backgroundColor: night.color.danger
1617
+ },
1618
+ liveText: {
1619
+ color: night.color.danger,
1620
+ fontSize: 9,
1621
+ fontWeight: "800",
1622
+ letterSpacing: 0.8
1623
+ },
1624
+ cmpHead: {
1625
+ flexDirection: "row",
1626
+ paddingHorizontal: 12,
1627
+ paddingVertical: 6,
1628
+ backgroundColor: night.color.fill,
1629
+ gap: 8
1630
+ },
1631
+ cmpCol: {
1632
+ flex: 1,
1633
+ color: night.color.textTertiary,
1634
+ fontSize: night.font.micro,
1635
+ fontWeight: "700",
1636
+ letterSpacing: 0.6,
1637
+ textTransform: "uppercase"
1638
+ },
1639
+ cmpRow: {
1640
+ flexDirection: "row",
1641
+ paddingHorizontal: 12,
1642
+ paddingVertical: 8,
1643
+ gap: 8,
1644
+ alignItems: "flex-start"
1645
+ },
1646
+ cmpDiff: {
1647
+ backgroundColor: night.color.fill
1648
+ },
1649
+ cmpKey: {
1650
+ width: 90,
1651
+ color: night.color.textSecondary,
1652
+ fontSize: night.font.caption
1653
+ },
1654
+ cmpVal: {
1655
+ flex: 1,
1656
+ color: night.color.text,
1657
+ fontSize: night.font.caption,
1658
+ fontFamily: "Menlo"
1659
+ },
1660
+ /**
1661
+ * A fixed box the image is fitted INTO, never cropped to.
1662
+ *
1663
+ * This was `cover`, which is right for a decorative banner and wrong for
1664
+ * everything the agent actually passes: product art, avatars and sprites are
1665
+ * square, and a square scaled to fill a 2.4:1 box loses its top and bottom —
1666
+ * a Charizard reduced to a band of its own middle. These pictures are the
1667
+ * app's DATA, being looked at in a devtool; cropping hides the thing you
1668
+ * opened the card to see. `contain` letterboxes a wide image instead, which
1669
+ * costs a little space and no information. The fill behind it is the
1670
+ * letterbox. Same reasoning as the screenshot block, which was already
1671
+ * `contain`.
1672
+ */
1673
+ cardImage: {
1674
+ width: "100%",
1675
+ height: 140,
1676
+ backgroundColor: night.color.fill
1677
+ },
1678
+ cardText: {
1679
+ paddingHorizontal: 12,
1680
+ paddingTop: 10,
1681
+ paddingBottom: 4,
1682
+ gap: 4
1683
+ },
1684
+ cardTitle: {
1685
+ color: night.color.text,
1686
+ fontSize: night.font.row,
1687
+ fontWeight: "600"
1688
+ },
1689
+ fact: {
1690
+ flexDirection: "row",
1691
+ justifyContent: "space-between",
1692
+ gap: 8
1693
+ },
1694
+ factLabel: {
1695
+ color: night.color.textSecondary,
1696
+ fontSize: night.font.caption
1697
+ },
1698
+ factValue: {
1699
+ color: night.color.text,
1700
+ fontSize: night.font.caption,
1701
+ fontWeight: "500"
1702
+ },
1703
+ carouselTitle: {
1704
+ color: night.color.text,
1705
+ fontSize: night.font.caption,
1706
+ fontWeight: "600",
1707
+ paddingBottom: 8
1708
+ },
1709
+ carousel: {
1710
+ gap: 8,
1711
+ paddingRight: 8
1712
+ },
1713
+ carouselCard: {
1714
+ width: 224,
1715
+ borderRadius: night.radius.card,
1716
+ borderWidth: StyleSheet.hairlineWidth,
1717
+ borderColor: night.color.border,
1718
+ backgroundColor: night.color.surface,
1719
+ overflow: "hidden"
1720
+ },
1721
+ shot: {
1722
+ width: "100%",
1723
+ height: 220,
1724
+ backgroundColor: night.color.fill
1725
+ },
1726
+ shotBig: {
1727
+ height: 520
1728
+ },
1729
+ progress: {
1730
+ height: 4,
1731
+ backgroundColor: night.color.fill,
1732
+ marginHorizontal: 12,
1733
+ marginTop: 6,
1734
+ marginBottom: 8,
1735
+ borderRadius: 2,
1736
+ overflow: "hidden"
1737
+ },
1738
+ progressFill: {
1739
+ height: 4,
1740
+ backgroundColor: night.color.accent
1741
+ },
1742
+ step: {
1743
+ flexDirection: "row",
1744
+ alignItems: "center",
1745
+ gap: 10,
1746
+ paddingHorizontal: 12,
1747
+ paddingVertical: 9
1748
+ },
1749
+ stepMark: {
1750
+ width: 20,
1751
+ height: 20,
1752
+ borderRadius: 10,
1753
+ backgroundColor: night.color.fillTertiary,
1754
+ alignItems: "center",
1755
+ justifyContent: "center"
1756
+ },
1757
+ stepDone: {
1758
+ backgroundColor: night.color.accent
1759
+ },
1760
+ stepFailed: {
1761
+ backgroundColor: night.color.danger
1762
+ },
1763
+ stepRunning: {
1764
+ backgroundColor: night.color.info
1765
+ },
1766
+ stepNum: {
1767
+ color: night.color.text,
1768
+ fontSize: night.font.micro,
1769
+ fontWeight: "700"
1770
+ },
1771
+ checkpoint: {
1772
+ alignSelf: "flex-start",
1773
+ flexDirection: "row",
1774
+ alignItems: "center",
1775
+ gap: 8,
1776
+ paddingHorizontal: 12,
1777
+ paddingVertical: 7,
1778
+ borderRadius: night.radius.chip,
1779
+ backgroundColor: night.color.fill
1780
+ },
1781
+ cpFlag: {
1782
+ width: 8,
1783
+ height: 8,
1784
+ borderRadius: 2,
1785
+ backgroundColor: night.color.info
1786
+ },
1787
+ cpText: {
1788
+ color: night.color.textSecondary,
1789
+ fontSize: night.font.caption
1790
+ },
1791
+ cpRestore: {
1792
+ color: night.color.accent,
1793
+ fontSize: night.font.caption,
1794
+ fontWeight: "600"
1795
+ },
1796
+ taskHead: {
1797
+ flexDirection: "row",
1798
+ alignItems: "center",
1799
+ justifyContent: "space-between",
1800
+ gap: 8,
1801
+ paddingHorizontal: 12,
1802
+ paddingTop: 12
1803
+ },
1804
+ banner: {
1805
+ flexDirection: "row",
1806
+ alignItems: "center",
1807
+ gap: 8,
1808
+ paddingLeft: 12,
1809
+ paddingRight: 4,
1810
+ paddingVertical: 4,
1811
+ borderRadius: night.radius.row,
1812
+ borderWidth: StyleSheet.hairlineWidth
1813
+ },
1814
+ bannerText: {
1815
+ flex: 1,
1816
+ fontSize: night.font.caption,
1817
+ fontWeight: "600"
1818
+ },
1819
+ fileIcon: {
1820
+ width: 40,
1821
+ height: 40,
1822
+ borderRadius: 8,
1823
+ backgroundColor: night.color.fill,
1824
+ alignItems: "center",
1825
+ justifyContent: "center"
1826
+ },
1827
+ fileExt: {
1828
+ color: night.color.textSecondary,
1829
+ fontSize: 10,
1830
+ fontWeight: "800"
1831
+ }
1832
+ });
1833
+ //# sourceMappingURL=ExtraBlocks.js.map