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