@buoy-gg/ask-buoy 7.0.40 → 7.0.42

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