@opengeni/react 6.5.2-canary.41607687019001 → 6.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1154) hide show
  1. package/dist/app/app-state.d.ts +4 -0
  2. package/dist/app/app-state.js +19 -14
  3. package/dist/app/components/Composer.js +25 -23
  4. package/dist/app/components/agent/agent-capability-picker.js +10 -8
  5. package/dist/app/components/artifacts/artifact-browse-controls.js +4 -4
  6. package/dist/app/components/artifacts/artifact-library.js +21 -19
  7. package/dist/app/components/artifacts/artifact-page-chrome.js +3 -3
  8. package/dist/app/components/artifacts/artifact-viewer.js +23 -22
  9. package/dist/app/components/artifacts/artifact-viewer.js.map +1 -1
  10. package/dist/app/components/artifacts/chat-interactive-block.js +12 -12
  11. package/dist/app/components/artifacts/copy-artifact-link.js +7 -5
  12. package/dist/app/components/artifacts/file-reach-dialog.js +11 -9
  13. package/dist/app/components/artifacts/inline-chat-image.js +18 -18
  14. package/dist/app/components/artifacts/retained-file-preview.js +24 -23
  15. package/dist/app/components/artifacts/retained-text-preview.js +3 -3
  16. package/dist/app/components/artifacts/site-audience.js +6 -5
  17. package/dist/app/components/artifacts/site-conversations.js +16 -14
  18. package/dist/app/components/artifacts/site-data.js +18 -16
  19. package/dist/app/components/artifacts/site-public-link.js +3 -2
  20. package/dist/app/components/artifacts/site-publishing-page.js +39 -37
  21. package/dist/app/components/artifacts/site-publishing.js +34 -32
  22. package/dist/app/components/artifacts/site-settings.js +38 -36
  23. package/dist/app/components/artifacts/site-version-menu.js +8 -7
  24. package/dist/app/components/billing-class-mark.js +3 -3
  25. package/dist/app/components/bots/bot-launch-strip.js +17 -17
  26. package/dist/app/components/bots/bot-template-dialog.js +30 -28
  27. package/dist/app/components/bots/bot-template-shortcuts.js +19 -19
  28. package/dist/app/components/bots/bot-templates-page.js +38 -36
  29. package/dist/app/components/bots/bot-templates-page.js.map +1 -1
  30. package/dist/app/components/capabilities/capability-detail-sheet.js +13 -11
  31. package/dist/app/components/capabilities/capability-logo-source.js +13 -13
  32. package/dist/app/components/capabilities/capability-logo.js +4 -3
  33. package/dist/app/components/capabilities/connector-tool-permissions.js +8 -6
  34. package/dist/app/components/capabilities/native-connect-setup.js +14 -14
  35. package/dist/app/components/capabilities/own-logins-shared-heads-up.js +7 -6
  36. package/dist/app/components/capabilities/perform-capability-action.js +7 -6
  37. package/dist/app/components/capabilities/prepared-mcp-setup-card.js +17 -17
  38. package/dist/app/components/capabilities/session-capability-card.js +72 -70
  39. package/dist/app/components/capabilities/session-capability-card.js.map +1 -1
  40. package/dist/app/components/capabilities/session-chrome-card.js +28 -26
  41. package/dist/app/components/capabilities/session-connection-accounts.js +4 -3
  42. package/dist/app/components/capabilities/session-custom-mcp-card.js +20 -19
  43. package/dist/app/components/capabilities/session-github-card.js +22 -20
  44. package/dist/app/components/capabilities/session-machine-card.js +27 -25
  45. package/dist/app/components/capabilities/session-personal-github-card.js +16 -16
  46. package/dist/app/components/capabilities/session-plugin-card.js +10 -9
  47. package/dist/app/components/capabilities/use-capabilities-catalog.js +4 -3
  48. package/dist/app/components/capabilities/use-connection-accounts.js +5 -4
  49. package/dist/app/components/command-menu/chat-status.js +15 -13
  50. package/dist/app/components/command-menu/chat-switcher.js +35 -33
  51. package/dist/app/components/command-menu/chat-switcher.js.map +1 -1
  52. package/dist/app/components/command-menu/command-menu.js +53 -50
  53. package/dist/app/components/command-menu/command-menu.js.map +1 -1
  54. package/dist/app/components/command-menu/shortcut-sheet.js +18 -16
  55. package/dist/app/components/command-menu/shortcut-sheet.js.map +1 -1
  56. package/dist/app/components/common.js +4 -3
  57. package/dist/app/components/composer-capabilities-menu-body.js +4 -4
  58. package/dist/app/components/composer-mobile-plus-panel.js +8 -8
  59. package/dist/app/components/composer-mobile-plus.js +1 -1
  60. package/dist/app/components/credit-required-gate.js +3 -3
  61. package/dist/app/components/credit-required-prompt.js +10 -8
  62. package/dist/app/components/credit-required-prompt.js.map +1 -1
  63. package/dist/app/components/credits/checkout-credits-celebration.js +3 -2
  64. package/dist/app/components/credits/checkout-return.js +3 -2
  65. package/dist/app/components/credits/checkout-return.js.map +1 -1
  66. package/dist/app/components/credits/coupon-redeem.js +5 -4
  67. package/dist/app/components/credits/credit-refusal-notice.js +7 -5
  68. package/dist/app/components/cross-slot-deep-link-recovery.js +5 -4
  69. package/dist/app/components/desktop/app-shots.js +13 -11
  70. package/dist/app/components/desktop/computer-use.js +6 -4
  71. package/dist/app/components/desktop/this-computer.js +9 -7
  72. package/dist/app/components/feedback.js +5 -4
  73. package/dist/app/components/follow-up-repository-menu-body.js +8 -6
  74. package/dist/app/components/follow-up-repository-menu-body.js.map +1 -1
  75. package/dist/app/components/follow-up-repository-picker.js +1 -1
  76. package/dist/app/components/github-app-connect-launcher.js +5 -4
  77. package/dist/app/components/in-app-help-link.js +3 -3
  78. package/dist/app/components/knowledge/agent-learning-settings.js +3 -2
  79. package/dist/app/components/knowledge/agent-learning-settings.js.map +1 -1
  80. package/dist/app/components/machines/connect-machine-dialog.js +18 -16
  81. package/dist/app/components/manual-repository-editor.js +3 -2
  82. package/dist/app/components/markdown.js +6 -6
  83. package/dist/app/components/models/models-ui.js +12 -10
  84. package/dist/app/components/my-things.js +12 -10
  85. package/dist/app/components/my-things.js.map +1 -1
  86. package/dist/app/components/new-session-starters.js +3 -3
  87. package/dist/app/components/own-where-it-works.js +9 -7
  88. package/dist/app/components/personal-resource-attachment-surface.js +4 -4
  89. package/dist/app/components/pickers.js +5 -5
  90. package/dist/app/components/rail/channel-create-dialog.js +7 -5
  91. package/dist/app/components/rail/project-glyph.js +17 -17
  92. package/dist/app/components/rail/project-profile.js +31 -29
  93. package/dist/app/components/rail/rail-context.js +3 -3
  94. package/dist/app/components/rail/rail-sections.js +68 -66
  95. package/dist/app/components/rail/session-header.js +59 -57
  96. package/dist/app/components/rail/session-list.js +66 -64
  97. package/dist/app/components/rail/session-row-content.js +4 -4
  98. package/dist/app/components/rail/session-row-hover-details.js +14 -12
  99. package/dist/app/components/rail/session-shell.js +90 -88
  100. package/dist/app/components/rail/site-session-group-heading.js +8 -8
  101. package/dist/app/components/repository-picker.js +8 -6
  102. package/dist/app/components/secrets/session-secrets-panel.js +4 -3
  103. package/dist/app/components/secrets/vault-model.js +3 -2
  104. package/dist/app/components/session/agent-configuration-panel.js +25 -23
  105. package/dist/app/components/session/agent-configuration-panel.js.map +1 -1
  106. package/dist/app/components/session/artifact-link-boundary.js +3 -3
  107. package/dist/app/components/session/artifact-session-page.js +11 -9
  108. package/dist/app/components/session/banners.js +8 -8
  109. package/dist/app/components/session/codex-usage-notice.js +5 -3
  110. package/dist/app/components/session/console-new-conversation.js +42 -40
  111. package/dist/app/components/session/context-text-reader.js +3 -2
  112. package/dist/app/components/session/descendant-requests.js +39 -37
  113. package/dist/app/components/session/descendant-requests.js.map +1 -1
  114. package/dist/app/components/session/editable-artifacts-workspace.js +36 -34
  115. package/dist/app/components/session/editable-artifacts-workspace.js.map +1 -1
  116. package/dist/app/components/session/failed-session-banner.js +13 -11
  117. package/dist/app/components/session/failed-session-banner.js.map +1 -1
  118. package/dist/app/components/session/failure-recovery-boundary.js +3 -3
  119. package/dist/app/components/session/human-input-delegation-record.js +2 -2
  120. package/dist/app/components/session/human-input.js +33 -31
  121. package/dist/app/components/session/inspector.js +57 -55
  122. package/dist/app/components/session/inspector.js.map +1 -1
  123. package/dist/app/components/session/message-actions.js +5 -4
  124. package/dist/app/components/session/message-actions.js.map +1 -1
  125. package/dist/app/components/session/message-resource-attachments.js +12 -11
  126. package/dist/app/components/session/message-resource-attachments.js.map +1 -1
  127. package/dist/app/components/session/model-context-inspector.js +6 -4
  128. package/dist/app/components/session/model-recovery-notice.js +3 -3
  129. package/dist/app/components/session/new-session-settings-menu.js +11 -9
  130. package/dist/app/components/session/new-session-setup-strip.js +18 -18
  131. package/dist/app/components/session/sandbox-recovery-actions.js +3 -3
  132. package/dist/app/components/session/sandbox-switcher.js +10 -9
  133. package/dist/app/components/session/sandbox-workspace.js +47 -46
  134. package/dist/app/components/session/search-markdown-highlight.js +7 -7
  135. package/dist/app/components/session/search-results-view.js +8 -8
  136. package/dist/app/components/session/session-admin-access.js +13 -11
  137. package/dist/app/components/session/session-admission-notice.js +7 -5
  138. package/dist/app/components/session/session-avatar-picker.js +22 -20
  139. package/dist/app/components/session/session-avatar.js +16 -16
  140. package/dist/app/components/session/session-machine-access-notice.js +7 -5
  141. package/dist/app/components/session/session-profile-dialog.js +29 -27
  142. package/dist/app/components/session/session-profile-editor.js +30 -28
  143. package/dist/app/components/session/session-retention.js +10 -8
  144. package/dist/app/components/session/session-search-dialog.js +10 -10
  145. package/dist/app/components/session/session-skill-reviews.js +2 -1
  146. package/dist/app/components/session/session-skill-reviews.js.map +1 -1
  147. package/dist/app/components/session/session-tenancy-control.js +13 -11
  148. package/dist/app/components/session/session-tenancy-control.js.map +1 -1
  149. package/dist/app/components/session/session-unattended-setting.js +7 -5
  150. package/dist/app/components/session/session-usage-limit-section.js +11 -9
  151. package/dist/app/components/session/share-chat-dialog.js +9 -7
  152. package/dist/app/components/session/site-origin-link.js +3 -3
  153. package/dist/app/components/session/subagents.js +8 -8
  154. package/dist/app/components/session/subscription-account-indicator.js +6 -6
  155. package/dist/app/components/session-connectors-menu-body.js +4 -3
  156. package/dist/app/components/session-connectors-menu-body.js.map +1 -1
  157. package/dist/app/components/settings/row-select.js +7 -5
  158. package/dist/app/components/toaster.js +3 -2
  159. package/dist/app/components/transcription-settings.js +11 -9
  160. package/dist/app/components/ui/destructive-confirm.js +11 -9
  161. package/dist/app/components/usage/usage-entry.js +5 -5
  162. package/dist/app/components/window-bar.js +16 -14
  163. package/dist/app/components/workspace-composer-plus.js +22 -21
  164. package/dist/app/components/workspace-reach.js +6 -4
  165. package/dist/app/components/workspace-tenant-boundary.js +5 -4
  166. package/dist/app/embed/memory-navigation.js +3 -3
  167. package/dist/app/embed/session-app.js +211 -209
  168. package/dist/app/lib/actions/actions-provider.js +15 -13
  169. package/dist/app/lib/agent-capabilities.js +3 -3
  170. package/dist/app/lib/app-surfaces.js +7 -6
  171. package/dist/app/lib/archive-session.d.ts +9 -4
  172. package/dist/app/lib/archive-session.js +4 -2
  173. package/dist/app/lib/bot-templates.js +3 -2
  174. package/dist/app/lib/capabilities.js +3 -2
  175. package/dist/app/lib/codex-usage-query.js +2 -2
  176. package/dist/app/lib/composer-connectors.js +17 -16
  177. package/dist/app/lib/console-site.js +2 -2
  178. package/dist/app/lib/console-text.js +2 -2
  179. package/dist/app/lib/events.js +9 -9
  180. package/dist/app/lib/failed-session-copy.js +3 -3
  181. package/dist/app/lib/inbox.js +4 -2
  182. package/dist/app/lib/model-access-onboarding.js +3 -3
  183. package/dist/app/lib/move-chat-to-machine.js +3 -3
  184. package/dist/app/lib/navigation.js +2 -2
  185. package/dist/app/lib/session-branch-cache.js +6 -6
  186. package/dist/app/lib/session-create.js +4 -4
  187. package/dist/app/lib/session-group-pagination.js +6 -6
  188. package/dist/app/lib/session-hover-facts.js +13 -11
  189. package/dist/app/lib/session-model.js +2 -2
  190. package/dist/app/lib/session-rail.js +3 -3
  191. package/dist/app/lib/session-rename.js +3 -3
  192. package/dist/app/lib/session-restart-operation-controller.js +4 -3
  193. package/dist/app/lib/session-tenancy.js +3 -2
  194. package/dist/app/lib/session-usage-limit.js +3 -2
  195. package/dist/app/lib/sessions-group.js +5 -5
  196. package/dist/app/lib/site-publishing.js +3 -2
  197. package/dist/app/lib/site-tool-consent-dialog.js +9 -7
  198. package/dist/app/lib/site-tool-consent-dialog.js.map +1 -1
  199. package/dist/app/lib/site-tool-consent.js +1 -1
  200. package/dist/app/lib/subscription-plans.js +3 -2
  201. package/dist/app/lib/toast.js +2 -1
  202. package/dist/app/lib/turn-failure-analytics.js +4 -4
  203. package/dist/app/lib/use-duplicate-site.js +6 -5
  204. package/dist/app/lib/use-follow-up-repositories.js +6 -5
  205. package/dist/app/lib/use-workspace-integrations.js +4 -3
  206. package/dist/app/lib/use-workspace-machines.js +4 -4
  207. package/dist/app/lib/use-workspace-model-catalog.js +5 -4
  208. package/dist/app/lib/use-workspace-rigs.js +2 -2
  209. package/dist/app/lib/workspace-navigation-preference.js +4 -4
  210. package/dist/app/lib/workspace-scope-context.js +3 -3
  211. package/dist/app/routes/artifacts.js +67 -66
  212. package/dist/app/routes/artifacts.js.map +1 -1
  213. package/dist/app/routes/retained-artifact.js +42 -40
  214. package/dist/app/routes/retained-artifact.js.map +1 -1
  215. package/dist/app/routes/session-unavailable.js +8 -7
  216. package/dist/app/routes/session.js +119 -117
  217. package/dist/app/routes/sessions-index-hydration.js +5 -5
  218. package/dist/app/routes/sessions-index.js +104 -102
  219. package/dist/app/routes/site-view.js +67 -65
  220. package/dist/app/routes/site-view.js.map +1 -1
  221. package/dist/artifacts-document.js +4 -4
  222. package/dist/artifacts-presentation.js +4 -4
  223. package/dist/artifacts-spreadsheet.js +4 -4
  224. package/dist/artifacts.js +10 -10
  225. package/dist/automations.js +17 -15
  226. package/dist/automations.js.map +1 -1
  227. package/dist/browser-viewer-TC27OCIP.js +23 -0
  228. package/dist/chat-interactive-block-RWPQBHVS.js +18 -0
  229. package/dist/chunk-2BDT3UZQ.js +229 -0
  230. package/dist/chunk-2CLNIEK4.js +373 -0
  231. package/dist/chunk-2FSBSCZJ.js +451 -0
  232. package/dist/chunk-2I7HDP53.js +199 -0
  233. package/dist/chunk-2INLDVK3.js +15 -0
  234. package/dist/chunk-2KALVELR.js +126 -0
  235. package/dist/chunk-2M3J7ZWQ.js +418 -0
  236. package/dist/chunk-2OP6WLGV.js +708 -0
  237. package/dist/chunk-2RG7NIAS.js +2936 -0
  238. package/dist/chunk-2STUPWEL.js +135 -0
  239. package/dist/chunk-2YUOVM3G.js +271 -0
  240. package/dist/chunk-2Z3NQNTM.js +3670 -0
  241. package/dist/chunk-3CPWWGNK.js +920 -0
  242. package/dist/chunk-3ED2U6XE.js +37 -0
  243. package/dist/chunk-3GZA4BUW.js +216 -0
  244. package/dist/chunk-3IK6UYO6.js +1022 -0
  245. package/dist/chunk-3PZ7JZI2.js +431 -0
  246. package/dist/chunk-4DVJ6ONS.js +50 -0
  247. package/dist/chunk-4DVNUCRR.js +2386 -0
  248. package/dist/chunk-4DVNUCRR.js.map +1 -0
  249. package/dist/chunk-4E3ZJRTZ.js +41 -0
  250. package/dist/chunk-4SAWSRAA.js +141 -0
  251. package/dist/chunk-53AGXXZM.js +307 -0
  252. package/dist/chunk-54YW6SZZ.js +818 -0
  253. package/dist/chunk-57AZS3IE.js +2317 -0
  254. package/dist/chunk-5CPEEAFD.js +143 -0
  255. package/dist/chunk-5EWSRZ2Y.js +340 -0
  256. package/dist/chunk-5IE76VCY.js +387 -0
  257. package/dist/chunk-5NWEKLDZ.js +170 -0
  258. package/dist/chunk-5O2FCCHZ.js +198 -0
  259. package/dist/chunk-5QAY6K77.js +399 -0
  260. package/dist/chunk-5YKW2K6I.js +625 -0
  261. package/dist/chunk-5YKW2K6I.js.map +1 -0
  262. package/dist/chunk-6BCXNDEI.js +4116 -0
  263. package/dist/chunk-6BCXNDEI.js.map +1 -0
  264. package/dist/chunk-6DK6Z4UN.js +2599 -0
  265. package/dist/chunk-6DVCC7QS.js +702 -0
  266. package/dist/chunk-6JHU2UBS.js +2058 -0
  267. package/dist/chunk-6PZ7OBYU.js +490 -0
  268. package/dist/chunk-6WD2INST.js +539 -0
  269. package/dist/chunk-6WD2INST.js.map +1 -0
  270. package/dist/chunk-6WGRDRMA.js +163 -0
  271. package/dist/chunk-77WAKEAH.js +186 -0
  272. package/dist/chunk-7T2ZE3VT.js +5558 -0
  273. package/dist/chunk-7T2ZE3VT.js.map +1 -0
  274. package/dist/chunk-7TDO3CUM.js +393 -0
  275. package/dist/chunk-7TIX2UAR.js +247 -0
  276. package/dist/chunk-7V5REBCP.js +148 -0
  277. package/dist/chunk-7VMZGLYI.js +339 -0
  278. package/dist/chunk-7W37NS3I.js +236 -0
  279. package/dist/chunk-7X6SDK2C.js +111 -0
  280. package/dist/chunk-7ZNUHRP5.js +95 -0
  281. package/dist/chunk-A36PZALD.js +84 -0
  282. package/dist/chunk-AUI6VA63.js +107 -0
  283. package/dist/chunk-AW2MQB37.js +24 -0
  284. package/dist/chunk-AWKES45Y.js +198 -0
  285. package/dist/chunk-AXHZYXUV.js +132 -0
  286. package/dist/chunk-BHNSJVBC.js +129 -0
  287. package/dist/chunk-BJEJFISW.js +50 -0
  288. package/dist/chunk-BJFH6JI5.js +422 -0
  289. package/dist/chunk-BMICEQZQ.js +960 -0
  290. package/dist/chunk-BTLBYBLU.js +29 -0
  291. package/dist/chunk-BXBDYNRP.js +89 -0
  292. package/dist/chunk-C372BFOV.js +357 -0
  293. package/dist/chunk-C43KRXGA.js +234 -0
  294. package/dist/chunk-C43KRXGA.js.map +1 -0
  295. package/dist/chunk-CMKGILJK.js +4824 -0
  296. package/dist/chunk-CRAOSVHC.js +50 -0
  297. package/dist/chunk-CRU35QQH.js +281 -0
  298. package/dist/chunk-CUIWCGMA.js +172 -0
  299. package/dist/chunk-D5TWNFFE.js +38 -0
  300. package/dist/chunk-DF5EAHDN.js +4461 -0
  301. package/dist/chunk-DJAXC5OK.js +56 -0
  302. package/dist/chunk-DXBYWSL5.js +3550 -0
  303. package/dist/chunk-DXR5PDFP.js +84 -0
  304. package/dist/chunk-DZWARC4M.js +267 -0
  305. package/dist/chunk-DZXEDSQI.js +106 -0
  306. package/dist/chunk-E7XERZWC.js +48 -0
  307. package/dist/chunk-ECJBYNLJ.js +79 -0
  308. package/dist/chunk-EDI6SJ2N.js +43 -0
  309. package/dist/chunk-EWSOC6WF.js +114 -0
  310. package/dist/chunk-F2OPHAUN.js +103 -0
  311. package/dist/chunk-F4ISQGGM.js +81 -0
  312. package/dist/chunk-FO4LYKJL.js +197 -0
  313. package/dist/chunk-FPXASDG5.js +73 -0
  314. package/dist/chunk-FSOQDUCG.js +117 -0
  315. package/dist/chunk-FSOQDUCG.js.map +1 -0
  316. package/dist/chunk-FVXBNBHO.js +157 -0
  317. package/dist/chunk-FYWT2O76.js +34 -0
  318. package/dist/chunk-FYWT2O76.js.map +1 -0
  319. package/dist/chunk-FZC5N55X.js +981 -0
  320. package/dist/chunk-GAVYGBFI.js +99 -0
  321. package/dist/chunk-GFIMOUDT.js +846 -0
  322. package/dist/chunk-GFIMOUDT.js.map +1 -0
  323. package/dist/chunk-GKVJIDHF.js +33 -0
  324. package/dist/chunk-GVN5SZLX.js +212 -0
  325. package/dist/chunk-H3T7IWNA.js +134 -0
  326. package/dist/chunk-HAX4LCR5.js +261 -0
  327. package/dist/chunk-HC4JFZVU.js +121 -0
  328. package/dist/chunk-HEFPPMBQ.js +581 -0
  329. package/dist/chunk-HGKTHF2U.js +1356 -0
  330. package/dist/chunk-HGKTHF2U.js.map +1 -0
  331. package/dist/chunk-HNLR7Q4Z.js +83 -0
  332. package/dist/chunk-HSOXMJOT.js +12 -0
  333. package/dist/chunk-I4MRDSUF.js +281 -0
  334. package/dist/chunk-I4QEJ62Y.js +202 -0
  335. package/dist/chunk-I5B5L6Q4.js +56 -0
  336. package/dist/chunk-I5QZJODL.js +264 -0
  337. package/dist/chunk-I7ITSXSJ.js +603 -0
  338. package/dist/chunk-I7XIZRFD.js +390 -0
  339. package/dist/chunk-IDANQPRH.js +82 -0
  340. package/dist/chunk-IFB3WJ36.js +212 -0
  341. package/dist/chunk-IHTAKKTK.js +264 -0
  342. package/dist/chunk-IKXNLWAL.js +205 -0
  343. package/dist/chunk-IKXNLWAL.js.map +1 -0
  344. package/dist/chunk-ILDXWY37.js +173 -0
  345. package/dist/chunk-IMDQUHBJ.js +570 -0
  346. package/dist/chunk-IMZCQBOT.js +119 -0
  347. package/dist/chunk-IXPTECSC.js +403 -0
  348. package/dist/chunk-J255A3N5.js +71 -0
  349. package/dist/chunk-J5F5HPPW.js +141 -0
  350. package/dist/chunk-JDTGRRNU.js +5045 -0
  351. package/dist/chunk-JDTGRRNU.js.map +1 -0
  352. package/dist/chunk-JEA3QDX7.js +2469 -0
  353. package/dist/chunk-JEUPAVYY.js +156 -0
  354. package/dist/chunk-JKHKLL5W.js +194 -0
  355. package/dist/chunk-JQL7ZH6C.js +650 -0
  356. package/dist/chunk-JWB44UGJ.js +57 -0
  357. package/dist/chunk-JZ4NLCAP.js +333 -0
  358. package/dist/chunk-K2A5PXQ5.js +412 -0
  359. package/dist/chunk-K56XV3C3.js +623 -0
  360. package/dist/chunk-K6GAXXVA.js +23 -0
  361. package/dist/chunk-KCBMFSMS.js +199 -0
  362. package/dist/chunk-KF2FV3ZJ.js +268 -0
  363. package/dist/chunk-KJD65EJP.js +278 -0
  364. package/dist/chunk-KLEUWIMZ.js +386 -0
  365. package/dist/chunk-KODELWYT.js +309 -0
  366. package/dist/chunk-KRDR5RJD.js +83 -0
  367. package/dist/chunk-KUDGXAF7.js +914 -0
  368. package/dist/chunk-KY2R73CG.js +171 -0
  369. package/dist/chunk-KY2R73CG.js.map +1 -0
  370. package/dist/chunk-KYS77RPN.js +85 -0
  371. package/dist/chunk-L7YTNTIK.js +368 -0
  372. package/dist/chunk-LHPNABDH.js +686 -0
  373. package/dist/chunk-MFROMEKA.js +401 -0
  374. package/dist/chunk-MIHN76LX.js +2656 -0
  375. package/dist/chunk-MIYFS2XN.js +42 -0
  376. package/dist/chunk-MJUCFQMS.js +65 -0
  377. package/dist/chunk-MM4FNWI4.js +3064 -0
  378. package/dist/chunk-MNZG4OHU.js +790 -0
  379. package/dist/chunk-MVW6HNPI.js +250 -0
  380. package/dist/chunk-MVW6HNPI.js.map +1 -0
  381. package/dist/chunk-N6AACDUW.js +200 -0
  382. package/dist/chunk-NC55IFN3.js +781 -0
  383. package/dist/chunk-NC7PVOEK.js +98 -0
  384. package/dist/chunk-NCYMNCJO.js +70 -0
  385. package/dist/chunk-ND2BXV3P.js +259 -0
  386. package/dist/chunk-NDBTFUO6.js +272 -0
  387. package/dist/chunk-NDQJZ7HF.js +206 -0
  388. package/dist/chunk-NGJJJPZZ.js +162 -0
  389. package/dist/chunk-NJTSNNE7.js +251 -0
  390. package/dist/chunk-NPGISCU6.js +4159 -0
  391. package/dist/chunk-NPGISCU6.js.map +1 -0
  392. package/dist/chunk-NRTE7DNV.js +1270 -0
  393. package/dist/chunk-NULUNM7H.js +290 -0
  394. package/dist/chunk-NUNZS36W.js +227 -0
  395. package/dist/chunk-NW53H5RW.js +2424 -0
  396. package/dist/chunk-NXCMHIKI.js +263 -0
  397. package/dist/chunk-O3LKCBP5.js +159 -0
  398. package/dist/chunk-O4EA4F3W.js +103 -0
  399. package/dist/chunk-O4EA4F3W.js.map +1 -0
  400. package/dist/chunk-O4OOG3D6.js +116 -0
  401. package/dist/chunk-O4OOG3D6.js.map +1 -0
  402. package/dist/chunk-O6N4ABCA.js +376 -0
  403. package/dist/chunk-O732GAFC.js +112 -0
  404. package/dist/chunk-OF4TIKYC.js +690 -0
  405. package/dist/chunk-OMPVOMPP.js +70 -0
  406. package/dist/chunk-OPJJSKUK.js +118 -0
  407. package/dist/chunk-OPWCMA4D.js +196 -0
  408. package/dist/chunk-ORJPS5VN.js +1193 -0
  409. package/dist/chunk-OSY5K7L7.js +187 -0
  410. package/dist/chunk-OV6QJRT4.js +45 -0
  411. package/dist/chunk-OVKYVZMW.js +108 -0
  412. package/dist/chunk-OZCBM3UC.js +171 -0
  413. package/dist/chunk-P3A2EINJ.js +61 -0
  414. package/dist/chunk-PTAG4PDC.js +27 -0
  415. package/dist/chunk-PTF5B7TJ.js +298 -0
  416. package/dist/chunk-Q3DPEYX4.js +848 -0
  417. package/dist/chunk-Q6CGOPJD.js +215 -0
  418. package/dist/chunk-Q6CGOPJD.js.map +1 -0
  419. package/dist/chunk-QB2KMIDP.js +100 -0
  420. package/dist/chunk-QCSJ4CWE.js +1067 -0
  421. package/dist/chunk-QIOQ2NPQ.js +414 -0
  422. package/dist/chunk-QK5EFEUT.js +353 -0
  423. package/dist/chunk-QPQBLYQJ.js +41 -0
  424. package/dist/chunk-QPSGCC5D.js +184 -0
  425. package/dist/chunk-QZAAUQRN.js +474 -0
  426. package/dist/chunk-QZM6YDJW.js +489 -0
  427. package/dist/chunk-QZM6YDJW.js.map +1 -0
  428. package/dist/chunk-RGBI63KJ.js +188 -0
  429. package/dist/chunk-RLBKLAEY.js +138 -0
  430. package/dist/chunk-RMFKVOM7.js +304 -0
  431. package/dist/chunk-ROKQU7WG.js +258 -0
  432. package/dist/chunk-RPVREAU7.js +251 -0
  433. package/dist/chunk-RQKLF42C.js +723 -0
  434. package/dist/chunk-SC6RRD2D.js +38 -0
  435. package/dist/chunk-SC6RRD2D.js.map +1 -0
  436. package/dist/chunk-SEO7TICN.js +94 -0
  437. package/dist/chunk-SHHJCL7X.js +432 -0
  438. package/dist/chunk-SIRLACNZ.js +114 -0
  439. package/dist/chunk-SKPHMYAA.js +237 -0
  440. package/dist/chunk-SODC7T6L.js +1583 -0
  441. package/dist/chunk-SQJIKMN3.js +366 -0
  442. package/dist/chunk-SVINDKVW.js +26 -0
  443. package/dist/chunk-SYCDHPZF.js +335 -0
  444. package/dist/chunk-T2QX3FDP.js +133 -0
  445. package/dist/chunk-T3OWFVMS.js +1187 -0
  446. package/dist/chunk-T6XI5FLY.js +61 -0
  447. package/dist/chunk-T7OXJZCX.js +62 -0
  448. package/dist/chunk-TAT5USZN.js +353 -0
  449. package/dist/chunk-TPQTRNER.js +172 -0
  450. package/dist/chunk-TUIN4MB7.js +266 -0
  451. package/dist/chunk-TX3VECZU.js +71 -0
  452. package/dist/chunk-TXLIEOJX.js +9624 -0
  453. package/dist/chunk-U3DN4HEY.js +27 -0
  454. package/dist/chunk-U7XM7CB4.js +191 -0
  455. package/dist/chunk-UJK53QFL.js +140 -0
  456. package/dist/chunk-UMTXA2TH.js +319 -0
  457. package/dist/chunk-UPDSXFK5.js +199 -0
  458. package/dist/chunk-UTIAXH52.js +269 -0
  459. package/dist/chunk-UVN5TMHU.js +1184 -0
  460. package/dist/chunk-V4Z4B2E3.js +52 -0
  461. package/dist/chunk-V4Z4B2E3.js.map +1 -0
  462. package/dist/chunk-VGYXW3VG.js +246 -0
  463. package/dist/chunk-VS7AHPCZ.js +255 -0
  464. package/dist/chunk-VTTAJOQ7.js +121 -0
  465. package/dist/chunk-VWPOLUAO.js +99 -0
  466. package/dist/chunk-X3MWB2QU.js +3851 -0
  467. package/dist/chunk-X6KAJI3V.js +211 -0
  468. package/dist/chunk-XBLRHV5R.js +50 -0
  469. package/dist/chunk-XDFP2LMW.js +605 -0
  470. package/dist/chunk-XEQMZB3C.js +525 -0
  471. package/dist/chunk-XEYLT5VA.js +223 -0
  472. package/dist/chunk-XHIQ5I6N.js +918 -0
  473. package/dist/chunk-XLH7QY2R.js +378 -0
  474. package/dist/chunk-XWFAMUZQ.js +113 -0
  475. package/dist/chunk-Y4BB2KS2.js +294 -0
  476. package/dist/chunk-Y4BB2KS2.js.map +1 -0
  477. package/dist/chunk-Y4OBB2VN.js +84 -0
  478. package/dist/chunk-YCVD6CI3.js +234 -0
  479. package/dist/chunk-YENLNISG.js +270 -0
  480. package/dist/chunk-YIRVLKAX.js +351 -0
  481. package/dist/chunk-YL73CVNK.js +390 -0
  482. package/dist/chunk-YLS6QE5G.js +288 -0
  483. package/dist/chunk-YNF2OC54.js +366 -0
  484. package/dist/chunk-YNF2OC54.js.map +1 -0
  485. package/dist/chunk-YPWU5KPE.js +147 -0
  486. package/dist/chunk-YQXTDZSU.js +2984 -0
  487. package/dist/chunk-YSJEAAOL.js +178 -0
  488. package/dist/chunk-YWIFM7D7.js +499 -0
  489. package/dist/chunk-YWVI6ZMK.js +103 -0
  490. package/dist/chunk-Z4FMAFNH.js +847 -0
  491. package/dist/chunk-Z654FWNU.js +136 -0
  492. package/dist/chunk-Z7Y523PS.js +130 -0
  493. package/dist/chunk-ZD67RM6G.js +60 -0
  494. package/dist/chunk-ZEG4VPBL.js +187 -0
  495. package/dist/chunk-ZHDFQITM.js +283 -0
  496. package/dist/chunk-ZHDFQITM.js.map +1 -0
  497. package/dist/chunk-ZLYCOBHW.js +75 -0
  498. package/dist/chunk-ZNJ5MTXV.js +89 -0
  499. package/dist/chunk-ZSGY3H53.js +155 -0
  500. package/dist/chunk-ZTPXACWB.js +1788 -0
  501. package/dist/chunk-ZUA3JMI6.js +107 -0
  502. package/dist/chunk-ZYAZUPPV.js +559 -0
  503. package/dist/composer.js +8 -8
  504. package/dist/computer-viewer-TDDO25AV.js +21 -0
  505. package/dist/connect.js +12 -12
  506. package/dist/desktop-dictation.js +12 -10
  507. package/dist/desktop-dictation.js.map +1 -1
  508. package/dist/desktop.js +2 -2
  509. package/dist/editor.js +2 -2
  510. package/dist/embedded-new-voice-2G3VLPVQ.js +24 -0
  511. package/dist/embedded-voice-T5IWOWGD.js +24 -0
  512. package/dist/fleet-decision-row-WM64KXP3.js +361 -0
  513. package/dist/in-chat-connect-model.js +5 -5
  514. package/dist/index.js +51 -51
  515. package/dist/interaction.js +5 -5
  516. package/dist/machines.js +3 -3
  517. package/dist/meetings-recorder.js +1 -1
  518. package/dist/meetings.js +40 -32
  519. package/dist/meetings.js.map +1 -1
  520. package/dist/messages/en.d.ts +3 -0
  521. package/dist/messages.js +1 -1
  522. package/dist/model-policy-picker-menu-SMC6J6QN.js +22 -0
  523. package/dist/payment-page-card-G4U63KUV.js +223 -0
  524. package/dist/platform-activity-row-BUZGZAKZ.js +128 -0
  525. package/dist/queue-surface-implementation-4KUZ4PJV.js +908 -0
  526. package/dist/realtime.js +4 -4
  527. package/dist/recorder-host-WF2RRR56.js +69 -0
  528. package/dist/recorder-host-WF2RRR56.js.map +1 -0
  529. package/dist/recordings.js +3 -3
  530. package/dist/sandbox-files-ESDMOFSD.js +27 -0
  531. package/dist/session-app.js +211 -209
  532. package/dist/session-connect-cards-Q53KMMYY.js +25 -0
  533. package/dist/session-list-model.js +2 -2
  534. package/dist/session-realtime-CF3I35WJ.js +30 -0
  535. package/dist/session-realtime.js +2 -2
  536. package/dist/session-ui.js +33 -31
  537. package/dist/session.js +5 -5
  538. package/dist/sites.js +2 -2
  539. package/dist/terminal.js +2 -2
  540. package/dist/this-computer.js +3 -3
  541. package/dist/timeline-annotation-markers-CJK4RYZ4.js +157 -0
  542. package/dist/timeline-annotation-selection-67GF5H26.js +208 -0
  543. package/dist/timeline-annotations-dialog-ONJPQDJQ.js +283 -0
  544. package/dist/ui/access-list.js +11 -9
  545. package/dist/ui/access-list.js.map +1 -1
  546. package/dist/ui/api-error.d.ts +6 -3
  547. package/dist/ui/api-error.js +2 -1
  548. package/dist/ui/cadence-picker.js +6 -4
  549. package/dist/ui/choice-cards.js +5 -3
  550. package/dist/ui/confirm-dialog.js +2 -2
  551. package/dist/ui/copy-field.js +5 -3
  552. package/dist/ui/detail-page.js +2 -2
  553. package/dist/ui/detail-sheet.js +2 -2
  554. package/dist/ui/diff-view.js +4 -3
  555. package/dist/ui/disclosure.js +3 -3
  556. package/dist/ui/email-chips-input.js +5 -3
  557. package/dist/ui/error-message.js +2 -1
  558. package/dist/ui/error-reference.d.ts +15 -0
  559. package/dist/ui/error-text.d.ts +10 -0
  560. package/dist/ui/error-text.js +9 -0
  561. package/dist/ui/error-text.js.map +1 -0
  562. package/dist/ui/field.js +4 -2
  563. package/dist/ui/flush-form-page.js +8 -6
  564. package/dist/ui/form-dialog.js +7 -5
  565. package/dist/ui/list-row.js +3 -3
  566. package/dist/ui/load-failure.js +3 -2
  567. package/dist/ui/load-failure.js.map +1 -1
  568. package/dist/ui/notice.js +3 -1
  569. package/dist/ui/relative-time.js +2 -2
  570. package/dist/ui/revision-history.js +9 -7
  571. package/dist/ui/revision-history.js.map +1 -1
  572. package/dist/ui/role-select.js +10 -8
  573. package/dist/ui/segmented-control.js +4 -2
  574. package/dist/ui/select-menu.js +5 -3
  575. package/dist/ui/setting-row.js +3 -1
  576. package/dist/ui/switch.js +4 -2
  577. package/dist/ui/usage-meter.js +3 -3
  578. package/dist/ui/word-list-row.js +4 -2
  579. package/dist/usage.js +2 -2
  580. package/dist/workbench.js +4 -4
  581. package/package.json +5 -6
  582. package/src/app/app-state.tsx +126 -14
  583. package/src/app/components/artifacts/site-data.tsx +2 -2
  584. package/src/app/components/artifacts/site-settings.tsx +2 -2
  585. package/src/app/components/rail/session-list.tsx +7 -8
  586. package/src/app/components/rail/session-shell.tsx +3 -3
  587. package/src/app/components/repository-picker.tsx +8 -1
  588. package/src/app/components/session/model-context-inspector.tsx +2 -1
  589. package/src/app/components/session/session-admin-access.tsx +2 -2
  590. package/src/app/lib/actions/chat-operations.ts +4 -4
  591. package/src/app/lib/archive-session.test.tsx +265 -2
  592. package/src/app/lib/archive-session.tsx +175 -9
  593. package/src/app/lib/copy-link.ts +2 -2
  594. package/src/app/lib/inbox.tsx +2 -2
  595. package/src/app/lib/session-failure-toasts.ts +3 -2
  596. package/src/app/lib/toast.test.tsx +215 -0
  597. package/src/app/lib/toast.tsx +67 -2
  598. package/src/app/personal-github-reconnect.test.tsx +356 -0
  599. package/src/app/routes/artifacts.tsx +1 -2
  600. package/src/components/tool-action-review.tsx +14 -1
  601. package/src/meetings/delete-meeting-dialog.tsx +2 -1
  602. package/src/meetings/meeting-ask.tsx +2 -1
  603. package/src/meetings/meeting-detail-page.tsx +2 -1
  604. package/src/meetings/meeting-notes.tsx +2 -1
  605. package/src/meetings/meeting-settings.tsx +4 -1
  606. package/src/meetings/meeting-transcript.tsx +4 -1
  607. package/src/meetings/recorder-context.tsx +10 -0
  608. package/src/meetings/recorder-host.test.tsx +60 -2
  609. package/src/meetings/recorder-host.tsx +16 -3
  610. package/src/meetings/recorder-panel.tsx +2 -1
  611. package/src/meetings/recorder-workspace.test.tsx +26 -1
  612. package/src/messages/en.ts +6 -0
  613. package/src/ui/api-error.test.ts +29 -5
  614. package/src/ui/api-error.tsx +10 -4
  615. package/src/ui/error-message.tsx +8 -0
  616. package/src/ui/error-reference.test.ts +54 -0
  617. package/src/ui/error-reference.ts +51 -0
  618. package/src/ui/error-text.test.tsx +66 -0
  619. package/src/ui/error-text.tsx +49 -0
  620. package/src/ui/field.tsx +4 -1
  621. package/src/ui/notice.tsx +7 -2
  622. package/src/ui/setting-row.tsx +4 -1
  623. package/styles/app.css +12 -0
  624. package/styles/compiled.css +9 -0
  625. package/dist/browser-viewer-NOP5EAUO.js +0 -23
  626. package/dist/chat-interactive-block-G7O44JHR.js +0 -18
  627. package/dist/chunk-26RWVLRD.js +0 -135
  628. package/dist/chunk-2AHTY7OT.js +0 -247
  629. package/dist/chunk-2GDNWKSC.js +0 -3670
  630. package/dist/chunk-2JENKGCE.js +0 -339
  631. package/dist/chunk-2KYQC4T5.js +0 -155
  632. package/dist/chunk-2RREGDQH.js +0 -708
  633. package/dist/chunk-2T7DX6KR.js +0 -353
  634. package/dist/chunk-2VB2O4FQ.js +0 -920
  635. package/dist/chunk-2VTTKH23.js +0 -94
  636. package/dist/chunk-2XNG2KNT.js +0 -172
  637. package/dist/chunk-2YC6JQRO.js +0 -399
  638. package/dist/chunk-2ZVRJRXC.js +0 -27
  639. package/dist/chunk-35737UT4.js +0 -162
  640. package/dist/chunk-366XZ4PM.js +0 -41
  641. package/dist/chunk-36MIDGAH.js +0 -199
  642. package/dist/chunk-3FD76LXM.js +0 -212
  643. package/dist/chunk-3OVIXY4O.js +0 -213
  644. package/dist/chunk-3OVIXY4O.js.map +0 -1
  645. package/dist/chunk-3QNRBEYH.js +0 -432
  646. package/dist/chunk-3QX55WLC.js +0 -15
  647. package/dist/chunk-3USJPT2S.js +0 -1022
  648. package/dist/chunk-42CMQ5VR.js +0 -251
  649. package/dist/chunk-4LPOWQJY.js +0 -42
  650. package/dist/chunk-4NBTZRKT.js +0 -79
  651. package/dist/chunk-4OXI6HCV.js +0 -118
  652. package/dist/chunk-4SZZAFYQ.js +0 -2317
  653. package/dist/chunk-4TQL3WP2.js +0 -140
  654. package/dist/chunk-4Y6BK7IU.js +0 -196
  655. package/dist/chunk-4YD7YZC5.js +0 -373
  656. package/dist/chunk-5DTST3TP.js +0 -81
  657. package/dist/chunk-5FH5LQVS.js +0 -130
  658. package/dist/chunk-5KWMYPJV.js +0 -847
  659. package/dist/chunk-5MUJDC6C.js +0 -84
  660. package/dist/chunk-5QM2WPKV.js +0 -41
  661. package/dist/chunk-5WUN7XPD.js +0 -1184
  662. package/dist/chunk-64PO2WXU.js +0 -1067
  663. package/dist/chunk-6AHATAAY.js +0 -431
  664. package/dist/chunk-6ED2YWBT.js +0 -56
  665. package/dist/chunk-6GXVYAGR.js +0 -170
  666. package/dist/chunk-6H4SJBPE.js +0 -85
  667. package/dist/chunk-6MT3HHUB.js +0 -84
  668. package/dist/chunk-6UHCBH4G.js +0 -198
  669. package/dist/chunk-6WLX3NR3.js +0 -198
  670. package/dist/chunk-73NXYYWE.js +0 -112
  671. package/dist/chunk-76ERNKIZ.js +0 -603
  672. package/dist/chunk-776QZ573.js +0 -57
  673. package/dist/chunk-7BYWOFVH.js +0 -171
  674. package/dist/chunk-7O5CGGIQ.js +0 -108
  675. package/dist/chunk-7QOHRZ67.js +0 -251
  676. package/dist/chunk-7WIDB4PL.js +0 -2058
  677. package/dist/chunk-7WKP3DYJ.js +0 -37
  678. package/dist/chunk-7XOVTPDI.js +0 -227
  679. package/dist/chunk-AB5MBIXY.js +0 -281
  680. package/dist/chunk-ADNMXBCX.js +0 -1193
  681. package/dist/chunk-AFBJTUFK.js +0 -202
  682. package/dist/chunk-ALVRWCXE.js +0 -61
  683. package/dist/chunk-AOHU6O3M.js +0 -247
  684. package/dist/chunk-AOHU6O3M.js.map +0 -1
  685. package/dist/chunk-APW4T4SW.js +0 -270
  686. package/dist/chunk-AXBSYWKX.js +0 -2656
  687. package/dist/chunk-B2I5ZW35.js +0 -422
  688. package/dist/chunk-B3LMRTRF.js +0 -223
  689. package/dist/chunk-BE2XENG2.js +0 -292
  690. package/dist/chunk-BE2XENG2.js.map +0 -1
  691. package/dist/chunk-BF4SADKX.js +0 -29
  692. package/dist/chunk-BKP43KK4.js +0 -1788
  693. package/dist/chunk-BM3NEZ6X.js +0 -781
  694. package/dist/chunk-BT3BAGB5.js +0 -216
  695. package/dist/chunk-BTSYDIVJ.js +0 -357
  696. package/dist/chunk-BUBNGKWG.js +0 -70
  697. package/dist/chunk-BVUJV5WR.js +0 -126
  698. package/dist/chunk-BZO5ZMUP.js +0 -27
  699. package/dist/chunk-C3HUF3M2.js +0 -157
  700. package/dist/chunk-C5QCAOES.js +0 -264
  701. package/dist/chunk-CGK6ALQU.js +0 -159
  702. package/dist/chunk-CPYGO76Q.js +0 -335
  703. package/dist/chunk-CQH4FWYA.js +0 -490
  704. package/dist/chunk-CZP5QXNB.js +0 -234
  705. package/dist/chunk-D2TOWEYH.js +0 -266
  706. package/dist/chunk-D6L4GHRH.js +0 -340
  707. package/dist/chunk-DKT3N37I.js +0 -50
  708. package/dist/chunk-DMMJIFKA.js +0 -84
  709. package/dist/chunk-DO74DQC7.js +0 -26
  710. package/dist/chunk-DOFJZ2JU.js +0 -83
  711. package/dist/chunk-DSXVY5WZ.js +0 -119
  712. package/dist/chunk-E337C2VK.js +0 -82
  713. package/dist/chunk-E6NRSRBE.js +0 -114
  714. package/dist/chunk-E6SQKHAU.js +0 -114
  715. package/dist/chunk-E7UIVD7F.js +0 -236
  716. package/dist/chunk-EGBII4CP.js +0 -229
  717. package/dist/chunk-EILSAQVJ.js +0 -200
  718. package/dist/chunk-ELL6HSYR.js +0 -307
  719. package/dist/chunk-EUBGLFFR.js +0 -73
  720. package/dist/chunk-EW6RNWSH.js +0 -212
  721. package/dist/chunk-EYUT5Y6V.js +0 -2599
  722. package/dist/chunk-F7U3QPZ3.js +0 -304
  723. package/dist/chunk-FBTJKSTM.js +0 -1270
  724. package/dist/chunk-FC2FTSK3.js +0 -2424
  725. package/dist/chunk-FOGNA3BU.js +0 -148
  726. package/dist/chunk-FQFKHNC7.js +0 -650
  727. package/dist/chunk-FTCHM755.js +0 -50
  728. package/dist/chunk-FXSHP4JZ.js +0 -3550
  729. package/dist/chunk-G6ZZC543.js +0 -818
  730. package/dist/chunk-G7FU6PUA.js +0 -100
  731. package/dist/chunk-GA4YEAMX.js +0 -3851
  732. package/dist/chunk-GE33BGB7.js +0 -12
  733. package/dist/chunk-GQ67HSJY.js +0 -570
  734. package/dist/chunk-GXXZ3WAK.js +0 -106
  735. package/dist/chunk-H2TCRX3H.js +0 -237
  736. package/dist/chunk-HLL4PBO7.js +0 -60
  737. package/dist/chunk-HLOEPV5C.js +0 -259
  738. package/dist/chunk-HUAGBS4O.js +0 -56
  739. package/dist/chunk-I36GSRUJ.js +0 -211
  740. package/dist/chunk-I6VBHT7S.js +0 -261
  741. package/dist/chunk-ICNNNOXE.js +0 -333
  742. package/dist/chunk-ICX64J4U.js +0 -172
  743. package/dist/chunk-ID36Y46W.js +0 -5046
  744. package/dist/chunk-ID36Y46W.js.map +0 -1
  745. package/dist/chunk-IGVVXLKJ.js +0 -559
  746. package/dist/chunk-IKJLSBUI.js +0 -2984
  747. package/dist/chunk-IKMUFDVS.js +0 -50
  748. package/dist/chunk-IKUNOX7F.js +0 -255
  749. package/dist/chunk-ILKDYBON.js +0 -288
  750. package/dist/chunk-IVYJX3OY.js +0 -187
  751. package/dist/chunk-JCY4CMDH.js +0 -107
  752. package/dist/chunk-JJZPLGIP.js +0 -474
  753. package/dist/chunk-JW33RV4V.js +0 -143
  754. package/dist/chunk-JWPA6ZPZ.js +0 -351
  755. package/dist/chunk-JZ4QXS6D.js +0 -50
  756. package/dist/chunk-K42OUZQ3.js +0 -386
  757. package/dist/chunk-K5TOVX5A.js +0 -206
  758. package/dist/chunk-K63HGHZX.js +0 -99
  759. package/dist/chunk-K6R5T44I.js +0 -75
  760. package/dist/chunk-KHJ5PXFM.js +0 -914
  761. package/dist/chunk-KJZRQ55O.js +0 -2319
  762. package/dist/chunk-KJZRQ55O.js.map +0 -1
  763. package/dist/chunk-KKI55ZMW.js +0 -65
  764. package/dist/chunk-KRPLAAFP.js +0 -199
  765. package/dist/chunk-KVFEZDBO.js +0 -134
  766. package/dist/chunk-L4I665WK.js +0 -45
  767. package/dist/chunk-L4OF77LE.js +0 -110
  768. package/dist/chunk-L4OF77LE.js.map +0 -1
  769. package/dist/chunk-LA5T52RM.js +0 -70
  770. package/dist/chunk-LM2W5YAT.js +0 -401
  771. package/dist/chunk-LQ62ECE6.js +0 -390
  772. package/dist/chunk-LQDUHU3Y.js +0 -71
  773. package/dist/chunk-LRJIYTZW.js +0 -4157
  774. package/dist/chunk-LRJIYTZW.js.map +0 -1
  775. package/dist/chunk-LRN6GYAZ.js +0 -138
  776. package/dist/chunk-M4SDVTKJ.js +0 -790
  777. package/dist/chunk-MA6O7CM6.js +0 -99
  778. package/dist/chunk-MBIBB6GI.js +0 -197
  779. package/dist/chunk-MF3ZFB4H.js +0 -199
  780. package/dist/chunk-MJJGJMYJ.js +0 -98
  781. package/dist/chunk-MLJADQFI.js +0 -4824
  782. package/dist/chunk-MQG7RV3B.js +0 -62
  783. package/dist/chunk-MTTGSQA5.js +0 -186
  784. package/dist/chunk-MW7Y3T55.js +0 -525
  785. package/dist/chunk-MYUFMVCH.js +0 -121
  786. package/dist/chunk-N3OARGH2.js +0 -61
  787. package/dist/chunk-NB2HMRT2.js +0 -353
  788. package/dist/chunk-NFDFYWMV.js +0 -141
  789. package/dist/chunk-NWGNFN3N.js +0 -1187
  790. package/dist/chunk-NWJRPDIO.js +0 -840
  791. package/dist/chunk-NWJRPDIO.js.map +0 -1
  792. package/dist/chunk-NXWBBZJV.js +0 -267
  793. package/dist/chunk-NY2QWROL.js +0 -71
  794. package/dist/chunk-O2IOPP3R.js +0 -848
  795. package/dist/chunk-O2UWH5RG.js +0 -141
  796. package/dist/chunk-O5YWDLYF.js +0 -393
  797. package/dist/chunk-OBMCZO7E.js +0 -121
  798. package/dist/chunk-OD3DCCCB.js +0 -132
  799. package/dist/chunk-OMH7R6I3.js +0 -390
  800. package/dist/chunk-OSA5EQG5.js +0 -113
  801. package/dist/chunk-OSJ3MUTZ.js +0 -2936
  802. package/dist/chunk-OWAYJ2OV.js +0 -368
  803. package/dist/chunk-OYXBFSGK.js +0 -269
  804. package/dist/chunk-PC2EBA5G.js +0 -4116
  805. package/dist/chunk-PC2EBA5G.js.map +0 -1
  806. package/dist/chunk-PC2MVXIP.js +0 -363
  807. package/dist/chunk-PC2MVXIP.js.map +0 -1
  808. package/dist/chunk-PENGLDR5.js +0 -309
  809. package/dist/chunk-PSMAWRPL.js +0 -191
  810. package/dist/chunk-PW4IMTYR.js +0 -702
  811. package/dist/chunk-PW54V7T5.js +0 -387
  812. package/dist/chunk-Q2EXYSMO.js +0 -24
  813. package/dist/chunk-Q2XJK5I4.js +0 -51
  814. package/dist/chunk-Q2XJK5I4.js.map +0 -1
  815. package/dist/chunk-Q4EFRI6X.js +0 -258
  816. package/dist/chunk-Q52CXW6C.js +0 -48
  817. package/dist/chunk-Q6XQ2R37.js +0 -184
  818. package/dist/chunk-QAJ53XBW.js +0 -23
  819. package/dist/chunk-QDTKECT4.js +0 -129
  820. package/dist/chunk-QE3ZFGI3.js +0 -43
  821. package/dist/chunk-QHHSUR2Y.js +0 -298
  822. package/dist/chunk-QHNVNR7B.js +0 -173
  823. package/dist/chunk-QIK2Q6N5.js +0 -376
  824. package/dist/chunk-QWL4L366.js +0 -38
  825. package/dist/chunk-R3J2PTVQ.js +0 -690
  826. package/dist/chunk-RBRX5ZS3.js +0 -319
  827. package/dist/chunk-REX6JIC7.js +0 -33
  828. package/dist/chunk-RGZ7EEC3.js +0 -537
  829. package/dist/chunk-RGZ7EEC3.js.map +0 -1
  830. package/dist/chunk-RIPS7GFR.js +0 -960
  831. package/dist/chunk-RTBZNFNV.js +0 -1354
  832. package/dist/chunk-RTBZNFNV.js.map +0 -1
  833. package/dist/chunk-SKMNW4SW.js +0 -187
  834. package/dist/chunk-SRFARKXC.js +0 -623
  835. package/dist/chunk-SWIHWCTW.js +0 -4461
  836. package/dist/chunk-TA5CFTO4.js +0 -103
  837. package/dist/chunk-TF4ZVJLI.js +0 -156
  838. package/dist/chunk-TG7DADJR.js +0 -9624
  839. package/dist/chunk-TI4R2ZD5.js +0 -623
  840. package/dist/chunk-TI4R2ZD5.js.map +0 -1
  841. package/dist/chunk-TNKWOUWP.js +0 -412
  842. package/dist/chunk-TNUSPXPW.js +0 -5555
  843. package/dist/chunk-TNUSPXPW.js.map +0 -1
  844. package/dist/chunk-TNYFHKVV.js +0 -366
  845. package/dist/chunk-TPMZBOFH.js +0 -178
  846. package/dist/chunk-TW3LKRJF.js +0 -263
  847. package/dist/chunk-TZAO65I4.js +0 -83
  848. package/dist/chunk-U5EFEMYU.js +0 -89
  849. package/dist/chunk-U6M4LS3M.js +0 -378
  850. package/dist/chunk-UI4HI5QK.js +0 -918
  851. package/dist/chunk-UJDOWCQ3.js +0 -272
  852. package/dist/chunk-UJUQ2QOX.js +0 -581
  853. package/dist/chunk-UQ3IM6FY.js +0 -133
  854. package/dist/chunk-UYE47LO6.js +0 -246
  855. package/dist/chunk-VADHIT26.js +0 -89
  856. package/dist/chunk-VFQ3H6CO.js +0 -163
  857. package/dist/chunk-VGUN6VB2.js +0 -188
  858. package/dist/chunk-VGWWEVSD.js +0 -723
  859. package/dist/chunk-VIEFJ2DM.js +0 -2469
  860. package/dist/chunk-VLXM36VS.js +0 -268
  861. package/dist/chunk-W3BFRR2G.js +0 -499
  862. package/dist/chunk-W5MPXR3A.js +0 -981
  863. package/dist/chunk-W5OWKVZG.js +0 -136
  864. package/dist/chunk-W6FRORMX.js +0 -486
  865. package/dist/chunk-W6FRORMX.js.map +0 -1
  866. package/dist/chunk-W7XROSZO.js +0 -232
  867. package/dist/chunk-W7XROSZO.js.map +0 -1
  868. package/dist/chunk-WEZ5PXZP.js +0 -403
  869. package/dist/chunk-WHWUWN2X.js +0 -197
  870. package/dist/chunk-WHWUWN2X.js.map +0 -1
  871. package/dist/chunk-WLEDGIVS.js +0 -114
  872. package/dist/chunk-WLEDGIVS.js.map +0 -1
  873. package/dist/chunk-WNDAKLHG.js +0 -281
  874. package/dist/chunk-WTJ4PLMU.js +0 -103
  875. package/dist/chunk-WV2KPJUW.js +0 -107
  876. package/dist/chunk-X3VY5EGY.js +0 -277
  877. package/dist/chunk-X3VY5EGY.js.map +0 -1
  878. package/dist/chunk-XDBYWVCW.js +0 -418
  879. package/dist/chunk-XF7MA4U5.js +0 -36
  880. package/dist/chunk-XF7MA4U5.js.map +0 -1
  881. package/dist/chunk-XOSQP3YA.js +0 -605
  882. package/dist/chunk-XYBV4ZJQ.js +0 -271
  883. package/dist/chunk-YBKVGLQR.js +0 -147
  884. package/dist/chunk-YDCUBUWH.js +0 -1583
  885. package/dist/chunk-YG6NARQY.js +0 -51
  886. package/dist/chunk-YG6NARQY.js.map +0 -1
  887. package/dist/chunk-YSVD5HI4.js +0 -278
  888. package/dist/chunk-YT3WGNG6.js +0 -290
  889. package/dist/chunk-YYICQDK4.js +0 -414
  890. package/dist/chunk-YYLMZLI6.js +0 -686
  891. package/dist/chunk-ZAMTKG5U.js +0 -95
  892. package/dist/chunk-ZDLYSXKN.js +0 -111
  893. package/dist/chunk-ZG447FSS.js +0 -194
  894. package/dist/chunk-ZIT5KD4Q.js +0 -264
  895. package/dist/chunk-ZUDOVDKR.js +0 -3064
  896. package/dist/chunk-ZW2ECJ3A.js +0 -451
  897. package/dist/computer-viewer-LPZ763KF.js +0 -21
  898. package/dist/embedded-new-voice-YVMKSLKJ.js +0 -24
  899. package/dist/embedded-voice-BJPQFXSU.js +0 -24
  900. package/dist/fleet-decision-row-AA4H5CDT.js +0 -361
  901. package/dist/model-policy-picker-menu-HSMWVO4P.js +0 -22
  902. package/dist/payment-page-card-3LTSFJGN.js +0 -223
  903. package/dist/platform-activity-row-5VYV6TX4.js +0 -128
  904. package/dist/queue-surface-implementation-NXHZUKD2.js +0 -908
  905. package/dist/recorder-host-ZKRWTDBM.js +0 -57
  906. package/dist/recorder-host-ZKRWTDBM.js.map +0 -1
  907. package/dist/sandbox-files-YCMLQUFU.js +0 -27
  908. package/dist/session-connect-cards-KSQLMRM5.js +0 -25
  909. package/dist/session-realtime-ZR6JLG3Y.js +0 -30
  910. package/dist/timeline-annotation-markers-YAHDPWVG.js +0 -157
  911. package/dist/timeline-annotation-selection-KHXNCEJP.js +0 -208
  912. package/dist/timeline-annotations-dialog-Y4XD3N7B.js +0 -283
  913. /package/dist/{browser-viewer-NOP5EAUO.js.map → browser-viewer-TC27OCIP.js.map} +0 -0
  914. /package/dist/{chat-interactive-block-G7O44JHR.js.map → chat-interactive-block-RWPQBHVS.js.map} +0 -0
  915. /package/dist/{chunk-EGBII4CP.js.map → chunk-2BDT3UZQ.js.map} +0 -0
  916. /package/dist/{chunk-4YD7YZC5.js.map → chunk-2CLNIEK4.js.map} +0 -0
  917. /package/dist/{chunk-ZW2ECJ3A.js.map → chunk-2FSBSCZJ.js.map} +0 -0
  918. /package/dist/{chunk-KRPLAAFP.js.map → chunk-2I7HDP53.js.map} +0 -0
  919. /package/dist/{chunk-3QX55WLC.js.map → chunk-2INLDVK3.js.map} +0 -0
  920. /package/dist/{chunk-BVUJV5WR.js.map → chunk-2KALVELR.js.map} +0 -0
  921. /package/dist/{chunk-XDBYWVCW.js.map → chunk-2M3J7ZWQ.js.map} +0 -0
  922. /package/dist/{chunk-2RREGDQH.js.map → chunk-2OP6WLGV.js.map} +0 -0
  923. /package/dist/{chunk-OSJ3MUTZ.js.map → chunk-2RG7NIAS.js.map} +0 -0
  924. /package/dist/{chunk-26RWVLRD.js.map → chunk-2STUPWEL.js.map} +0 -0
  925. /package/dist/{chunk-XYBV4ZJQ.js.map → chunk-2YUOVM3G.js.map} +0 -0
  926. /package/dist/{chunk-2GDNWKSC.js.map → chunk-2Z3NQNTM.js.map} +0 -0
  927. /package/dist/{chunk-2VB2O4FQ.js.map → chunk-3CPWWGNK.js.map} +0 -0
  928. /package/dist/{chunk-7WKP3DYJ.js.map → chunk-3ED2U6XE.js.map} +0 -0
  929. /package/dist/{chunk-BT3BAGB5.js.map → chunk-3GZA4BUW.js.map} +0 -0
  930. /package/dist/{chunk-3USJPT2S.js.map → chunk-3IK6UYO6.js.map} +0 -0
  931. /package/dist/{chunk-6AHATAAY.js.map → chunk-3PZ7JZI2.js.map} +0 -0
  932. /package/dist/{chunk-JZ4QXS6D.js.map → chunk-4DVJ6ONS.js.map} +0 -0
  933. /package/dist/{chunk-5QM2WPKV.js.map → chunk-4E3ZJRTZ.js.map} +0 -0
  934. /package/dist/{chunk-NFDFYWMV.js.map → chunk-4SAWSRAA.js.map} +0 -0
  935. /package/dist/{chunk-ELL6HSYR.js.map → chunk-53AGXXZM.js.map} +0 -0
  936. /package/dist/{chunk-G6ZZC543.js.map → chunk-54YW6SZZ.js.map} +0 -0
  937. /package/dist/{chunk-4SZZAFYQ.js.map → chunk-57AZS3IE.js.map} +0 -0
  938. /package/dist/{chunk-JW33RV4V.js.map → chunk-5CPEEAFD.js.map} +0 -0
  939. /package/dist/{chunk-D6L4GHRH.js.map → chunk-5EWSRZ2Y.js.map} +0 -0
  940. /package/dist/{chunk-PW54V7T5.js.map → chunk-5IE76VCY.js.map} +0 -0
  941. /package/dist/{chunk-6GXVYAGR.js.map → chunk-5NWEKLDZ.js.map} +0 -0
  942. /package/dist/{chunk-6UHCBH4G.js.map → chunk-5O2FCCHZ.js.map} +0 -0
  943. /package/dist/{chunk-2YC6JQRO.js.map → chunk-5QAY6K77.js.map} +0 -0
  944. /package/dist/{chunk-EYUT5Y6V.js.map → chunk-6DK6Z4UN.js.map} +0 -0
  945. /package/dist/{chunk-PW4IMTYR.js.map → chunk-6DVCC7QS.js.map} +0 -0
  946. /package/dist/{chunk-7WIDB4PL.js.map → chunk-6JHU2UBS.js.map} +0 -0
  947. /package/dist/{chunk-CQH4FWYA.js.map → chunk-6PZ7OBYU.js.map} +0 -0
  948. /package/dist/{chunk-VFQ3H6CO.js.map → chunk-6WGRDRMA.js.map} +0 -0
  949. /package/dist/{chunk-MTTGSQA5.js.map → chunk-77WAKEAH.js.map} +0 -0
  950. /package/dist/{chunk-O5YWDLYF.js.map → chunk-7TDO3CUM.js.map} +0 -0
  951. /package/dist/{chunk-2AHTY7OT.js.map → chunk-7TIX2UAR.js.map} +0 -0
  952. /package/dist/{chunk-FOGNA3BU.js.map → chunk-7V5REBCP.js.map} +0 -0
  953. /package/dist/{chunk-2JENKGCE.js.map → chunk-7VMZGLYI.js.map} +0 -0
  954. /package/dist/{chunk-E7UIVD7F.js.map → chunk-7W37NS3I.js.map} +0 -0
  955. /package/dist/{chunk-ZDLYSXKN.js.map → chunk-7X6SDK2C.js.map} +0 -0
  956. /package/dist/{chunk-ZAMTKG5U.js.map → chunk-7ZNUHRP5.js.map} +0 -0
  957. /package/dist/{chunk-DMMJIFKA.js.map → chunk-A36PZALD.js.map} +0 -0
  958. /package/dist/{chunk-WV2KPJUW.js.map → chunk-AUI6VA63.js.map} +0 -0
  959. /package/dist/{chunk-Q2EXYSMO.js.map → chunk-AW2MQB37.js.map} +0 -0
  960. /package/dist/{chunk-6WLX3NR3.js.map → chunk-AWKES45Y.js.map} +0 -0
  961. /package/dist/{chunk-OD3DCCCB.js.map → chunk-AXHZYXUV.js.map} +0 -0
  962. /package/dist/{chunk-QDTKECT4.js.map → chunk-BHNSJVBC.js.map} +0 -0
  963. /package/dist/{chunk-FTCHM755.js.map → chunk-BJEJFISW.js.map} +0 -0
  964. /package/dist/{chunk-B2I5ZW35.js.map → chunk-BJFH6JI5.js.map} +0 -0
  965. /package/dist/{chunk-RIPS7GFR.js.map → chunk-BMICEQZQ.js.map} +0 -0
  966. /package/dist/{chunk-BF4SADKX.js.map → chunk-BTLBYBLU.js.map} +0 -0
  967. /package/dist/{chunk-U5EFEMYU.js.map → chunk-BXBDYNRP.js.map} +0 -0
  968. /package/dist/{chunk-BTSYDIVJ.js.map → chunk-C372BFOV.js.map} +0 -0
  969. /package/dist/{chunk-MLJADQFI.js.map → chunk-CMKGILJK.js.map} +0 -0
  970. /package/dist/{chunk-DKT3N37I.js.map → chunk-CRAOSVHC.js.map} +0 -0
  971. /package/dist/{chunk-WNDAKLHG.js.map → chunk-CRU35QQH.js.map} +0 -0
  972. /package/dist/{chunk-2XNG2KNT.js.map → chunk-CUIWCGMA.js.map} +0 -0
  973. /package/dist/{chunk-QWL4L366.js.map → chunk-D5TWNFFE.js.map} +0 -0
  974. /package/dist/{chunk-SWIHWCTW.js.map → chunk-DF5EAHDN.js.map} +0 -0
  975. /package/dist/{chunk-HUAGBS4O.js.map → chunk-DJAXC5OK.js.map} +0 -0
  976. /package/dist/{chunk-FXSHP4JZ.js.map → chunk-DXBYWSL5.js.map} +0 -0
  977. /package/dist/{chunk-5MUJDC6C.js.map → chunk-DXR5PDFP.js.map} +0 -0
  978. /package/dist/{chunk-NXWBBZJV.js.map → chunk-DZWARC4M.js.map} +0 -0
  979. /package/dist/{chunk-GXXZ3WAK.js.map → chunk-DZXEDSQI.js.map} +0 -0
  980. /package/dist/{chunk-Q52CXW6C.js.map → chunk-E7XERZWC.js.map} +0 -0
  981. /package/dist/{chunk-4NBTZRKT.js.map → chunk-ECJBYNLJ.js.map} +0 -0
  982. /package/dist/{chunk-QE3ZFGI3.js.map → chunk-EDI6SJ2N.js.map} +0 -0
  983. /package/dist/{chunk-E6NRSRBE.js.map → chunk-EWSOC6WF.js.map} +0 -0
  984. /package/dist/{chunk-TA5CFTO4.js.map → chunk-F2OPHAUN.js.map} +0 -0
  985. /package/dist/{chunk-5DTST3TP.js.map → chunk-F4ISQGGM.js.map} +0 -0
  986. /package/dist/{chunk-MBIBB6GI.js.map → chunk-FO4LYKJL.js.map} +0 -0
  987. /package/dist/{chunk-EUBGLFFR.js.map → chunk-FPXASDG5.js.map} +0 -0
  988. /package/dist/{chunk-C3HUF3M2.js.map → chunk-FVXBNBHO.js.map} +0 -0
  989. /package/dist/{chunk-W5MPXR3A.js.map → chunk-FZC5N55X.js.map} +0 -0
  990. /package/dist/{chunk-MA6O7CM6.js.map → chunk-GAVYGBFI.js.map} +0 -0
  991. /package/dist/{chunk-REX6JIC7.js.map → chunk-GKVJIDHF.js.map} +0 -0
  992. /package/dist/{chunk-EW6RNWSH.js.map → chunk-GVN5SZLX.js.map} +0 -0
  993. /package/dist/{chunk-KVFEZDBO.js.map → chunk-H3T7IWNA.js.map} +0 -0
  994. /package/dist/{chunk-I6VBHT7S.js.map → chunk-HAX4LCR5.js.map} +0 -0
  995. /package/dist/{chunk-OBMCZO7E.js.map → chunk-HC4JFZVU.js.map} +0 -0
  996. /package/dist/{chunk-UJUQ2QOX.js.map → chunk-HEFPPMBQ.js.map} +0 -0
  997. /package/dist/{chunk-DOFJZ2JU.js.map → chunk-HNLR7Q4Z.js.map} +0 -0
  998. /package/dist/{chunk-GE33BGB7.js.map → chunk-HSOXMJOT.js.map} +0 -0
  999. /package/dist/{chunk-AB5MBIXY.js.map → chunk-I4MRDSUF.js.map} +0 -0
  1000. /package/dist/{chunk-AFBJTUFK.js.map → chunk-I4QEJ62Y.js.map} +0 -0
  1001. /package/dist/{chunk-6ED2YWBT.js.map → chunk-I5B5L6Q4.js.map} +0 -0
  1002. /package/dist/{chunk-C5QCAOES.js.map → chunk-I5QZJODL.js.map} +0 -0
  1003. /package/dist/{chunk-76ERNKIZ.js.map → chunk-I7ITSXSJ.js.map} +0 -0
  1004. /package/dist/{chunk-OMH7R6I3.js.map → chunk-I7XIZRFD.js.map} +0 -0
  1005. /package/dist/{chunk-E337C2VK.js.map → chunk-IDANQPRH.js.map} +0 -0
  1006. /package/dist/{chunk-3FD76LXM.js.map → chunk-IFB3WJ36.js.map} +0 -0
  1007. /package/dist/{chunk-ZIT5KD4Q.js.map → chunk-IHTAKKTK.js.map} +0 -0
  1008. /package/dist/{chunk-QHNVNR7B.js.map → chunk-ILDXWY37.js.map} +0 -0
  1009. /package/dist/{chunk-GQ67HSJY.js.map → chunk-IMDQUHBJ.js.map} +0 -0
  1010. /package/dist/{chunk-DSXVY5WZ.js.map → chunk-IMZCQBOT.js.map} +0 -0
  1011. /package/dist/{chunk-WEZ5PXZP.js.map → chunk-IXPTECSC.js.map} +0 -0
  1012. /package/dist/{chunk-NY2QWROL.js.map → chunk-J255A3N5.js.map} +0 -0
  1013. /package/dist/{chunk-O2UWH5RG.js.map → chunk-J5F5HPPW.js.map} +0 -0
  1014. /package/dist/{chunk-VIEFJ2DM.js.map → chunk-JEA3QDX7.js.map} +0 -0
  1015. /package/dist/{chunk-TF4ZVJLI.js.map → chunk-JEUPAVYY.js.map} +0 -0
  1016. /package/dist/{chunk-ZG447FSS.js.map → chunk-JKHKLL5W.js.map} +0 -0
  1017. /package/dist/{chunk-FQFKHNC7.js.map → chunk-JQL7ZH6C.js.map} +0 -0
  1018. /package/dist/{chunk-776QZ573.js.map → chunk-JWB44UGJ.js.map} +0 -0
  1019. /package/dist/{chunk-ICNNNOXE.js.map → chunk-JZ4NLCAP.js.map} +0 -0
  1020. /package/dist/{chunk-TNKWOUWP.js.map → chunk-K2A5PXQ5.js.map} +0 -0
  1021. /package/dist/{chunk-SRFARKXC.js.map → chunk-K56XV3C3.js.map} +0 -0
  1022. /package/dist/{chunk-QAJ53XBW.js.map → chunk-K6GAXXVA.js.map} +0 -0
  1023. /package/dist/{chunk-MF3ZFB4H.js.map → chunk-KCBMFSMS.js.map} +0 -0
  1024. /package/dist/{chunk-VLXM36VS.js.map → chunk-KF2FV3ZJ.js.map} +0 -0
  1025. /package/dist/{chunk-YSVD5HI4.js.map → chunk-KJD65EJP.js.map} +0 -0
  1026. /package/dist/{chunk-K42OUZQ3.js.map → chunk-KLEUWIMZ.js.map} +0 -0
  1027. /package/dist/{chunk-PENGLDR5.js.map → chunk-KODELWYT.js.map} +0 -0
  1028. /package/dist/{chunk-TZAO65I4.js.map → chunk-KRDR5RJD.js.map} +0 -0
  1029. /package/dist/{chunk-KHJ5PXFM.js.map → chunk-KUDGXAF7.js.map} +0 -0
  1030. /package/dist/{chunk-6H4SJBPE.js.map → chunk-KYS77RPN.js.map} +0 -0
  1031. /package/dist/{chunk-OWAYJ2OV.js.map → chunk-L7YTNTIK.js.map} +0 -0
  1032. /package/dist/{chunk-YYLMZLI6.js.map → chunk-LHPNABDH.js.map} +0 -0
  1033. /package/dist/{chunk-LM2W5YAT.js.map → chunk-MFROMEKA.js.map} +0 -0
  1034. /package/dist/{chunk-AXBSYWKX.js.map → chunk-MIHN76LX.js.map} +0 -0
  1035. /package/dist/{chunk-4LPOWQJY.js.map → chunk-MIYFS2XN.js.map} +0 -0
  1036. /package/dist/{chunk-KKI55ZMW.js.map → chunk-MJUCFQMS.js.map} +0 -0
  1037. /package/dist/{chunk-ZUDOVDKR.js.map → chunk-MM4FNWI4.js.map} +0 -0
  1038. /package/dist/{chunk-M4SDVTKJ.js.map → chunk-MNZG4OHU.js.map} +0 -0
  1039. /package/dist/{chunk-EILSAQVJ.js.map → chunk-N6AACDUW.js.map} +0 -0
  1040. /package/dist/{chunk-BM3NEZ6X.js.map → chunk-NC55IFN3.js.map} +0 -0
  1041. /package/dist/{chunk-MJJGJMYJ.js.map → chunk-NC7PVOEK.js.map} +0 -0
  1042. /package/dist/{chunk-LA5T52RM.js.map → chunk-NCYMNCJO.js.map} +0 -0
  1043. /package/dist/{chunk-HLOEPV5C.js.map → chunk-ND2BXV3P.js.map} +0 -0
  1044. /package/dist/{chunk-UJDOWCQ3.js.map → chunk-NDBTFUO6.js.map} +0 -0
  1045. /package/dist/{chunk-K5TOVX5A.js.map → chunk-NDQJZ7HF.js.map} +0 -0
  1046. /package/dist/{chunk-35737UT4.js.map → chunk-NGJJJPZZ.js.map} +0 -0
  1047. /package/dist/{chunk-42CMQ5VR.js.map → chunk-NJTSNNE7.js.map} +0 -0
  1048. /package/dist/{chunk-FBTJKSTM.js.map → chunk-NRTE7DNV.js.map} +0 -0
  1049. /package/dist/{chunk-YT3WGNG6.js.map → chunk-NULUNM7H.js.map} +0 -0
  1050. /package/dist/{chunk-7XOVTPDI.js.map → chunk-NUNZS36W.js.map} +0 -0
  1051. /package/dist/{chunk-FC2FTSK3.js.map → chunk-NW53H5RW.js.map} +0 -0
  1052. /package/dist/{chunk-TW3LKRJF.js.map → chunk-NXCMHIKI.js.map} +0 -0
  1053. /package/dist/{chunk-CGK6ALQU.js.map → chunk-O3LKCBP5.js.map} +0 -0
  1054. /package/dist/{chunk-QIK2Q6N5.js.map → chunk-O6N4ABCA.js.map} +0 -0
  1055. /package/dist/{chunk-73NXYYWE.js.map → chunk-O732GAFC.js.map} +0 -0
  1056. /package/dist/{chunk-R3J2PTVQ.js.map → chunk-OF4TIKYC.js.map} +0 -0
  1057. /package/dist/{chunk-BUBNGKWG.js.map → chunk-OMPVOMPP.js.map} +0 -0
  1058. /package/dist/{chunk-4OXI6HCV.js.map → chunk-OPJJSKUK.js.map} +0 -0
  1059. /package/dist/{chunk-4Y6BK7IU.js.map → chunk-OPWCMA4D.js.map} +0 -0
  1060. /package/dist/{chunk-ADNMXBCX.js.map → chunk-ORJPS5VN.js.map} +0 -0
  1061. /package/dist/{chunk-SKMNW4SW.js.map → chunk-OSY5K7L7.js.map} +0 -0
  1062. /package/dist/{chunk-L4I665WK.js.map → chunk-OV6QJRT4.js.map} +0 -0
  1063. /package/dist/{chunk-7O5CGGIQ.js.map → chunk-OVKYVZMW.js.map} +0 -0
  1064. /package/dist/{chunk-7BYWOFVH.js.map → chunk-OZCBM3UC.js.map} +0 -0
  1065. /package/dist/{chunk-ALVRWCXE.js.map → chunk-P3A2EINJ.js.map} +0 -0
  1066. /package/dist/{chunk-BZO5ZMUP.js.map → chunk-PTAG4PDC.js.map} +0 -0
  1067. /package/dist/{chunk-QHHSUR2Y.js.map → chunk-PTF5B7TJ.js.map} +0 -0
  1068. /package/dist/{chunk-O2IOPP3R.js.map → chunk-Q3DPEYX4.js.map} +0 -0
  1069. /package/dist/{chunk-G7FU6PUA.js.map → chunk-QB2KMIDP.js.map} +0 -0
  1070. /package/dist/{chunk-64PO2WXU.js.map → chunk-QCSJ4CWE.js.map} +0 -0
  1071. /package/dist/{chunk-YYICQDK4.js.map → chunk-QIOQ2NPQ.js.map} +0 -0
  1072. /package/dist/{chunk-NB2HMRT2.js.map → chunk-QK5EFEUT.js.map} +0 -0
  1073. /package/dist/{chunk-366XZ4PM.js.map → chunk-QPQBLYQJ.js.map} +0 -0
  1074. /package/dist/{chunk-Q6XQ2R37.js.map → chunk-QPSGCC5D.js.map} +0 -0
  1075. /package/dist/{chunk-JJZPLGIP.js.map → chunk-QZAAUQRN.js.map} +0 -0
  1076. /package/dist/{chunk-VGUN6VB2.js.map → chunk-RGBI63KJ.js.map} +0 -0
  1077. /package/dist/{chunk-LRN6GYAZ.js.map → chunk-RLBKLAEY.js.map} +0 -0
  1078. /package/dist/{chunk-F7U3QPZ3.js.map → chunk-RMFKVOM7.js.map} +0 -0
  1079. /package/dist/{chunk-Q4EFRI6X.js.map → chunk-ROKQU7WG.js.map} +0 -0
  1080. /package/dist/{chunk-7QOHRZ67.js.map → chunk-RPVREAU7.js.map} +0 -0
  1081. /package/dist/{chunk-VGWWEVSD.js.map → chunk-RQKLF42C.js.map} +0 -0
  1082. /package/dist/{chunk-2VTTKH23.js.map → chunk-SEO7TICN.js.map} +0 -0
  1083. /package/dist/{chunk-3QNRBEYH.js.map → chunk-SHHJCL7X.js.map} +0 -0
  1084. /package/dist/{chunk-E6SQKHAU.js.map → chunk-SIRLACNZ.js.map} +0 -0
  1085. /package/dist/{chunk-H2TCRX3H.js.map → chunk-SKPHMYAA.js.map} +0 -0
  1086. /package/dist/{chunk-YDCUBUWH.js.map → chunk-SODC7T6L.js.map} +0 -0
  1087. /package/dist/{chunk-TNYFHKVV.js.map → chunk-SQJIKMN3.js.map} +0 -0
  1088. /package/dist/{chunk-DO74DQC7.js.map → chunk-SVINDKVW.js.map} +0 -0
  1089. /package/dist/{chunk-CPYGO76Q.js.map → chunk-SYCDHPZF.js.map} +0 -0
  1090. /package/dist/{chunk-UQ3IM6FY.js.map → chunk-T2QX3FDP.js.map} +0 -0
  1091. /package/dist/{chunk-NWGNFN3N.js.map → chunk-T3OWFVMS.js.map} +0 -0
  1092. /package/dist/{chunk-N3OARGH2.js.map → chunk-T6XI5FLY.js.map} +0 -0
  1093. /package/dist/{chunk-MQG7RV3B.js.map → chunk-T7OXJZCX.js.map} +0 -0
  1094. /package/dist/{chunk-2T7DX6KR.js.map → chunk-TAT5USZN.js.map} +0 -0
  1095. /package/dist/{chunk-ICX64J4U.js.map → chunk-TPQTRNER.js.map} +0 -0
  1096. /package/dist/{chunk-D2TOWEYH.js.map → chunk-TUIN4MB7.js.map} +0 -0
  1097. /package/dist/{chunk-LQDUHU3Y.js.map → chunk-TX3VECZU.js.map} +0 -0
  1098. /package/dist/{chunk-TG7DADJR.js.map → chunk-TXLIEOJX.js.map} +0 -0
  1099. /package/dist/{chunk-2ZVRJRXC.js.map → chunk-U3DN4HEY.js.map} +0 -0
  1100. /package/dist/{chunk-PSMAWRPL.js.map → chunk-U7XM7CB4.js.map} +0 -0
  1101. /package/dist/{chunk-4TQL3WP2.js.map → chunk-UJK53QFL.js.map} +0 -0
  1102. /package/dist/{chunk-RBRX5ZS3.js.map → chunk-UMTXA2TH.js.map} +0 -0
  1103. /package/dist/{chunk-36MIDGAH.js.map → chunk-UPDSXFK5.js.map} +0 -0
  1104. /package/dist/{chunk-OYXBFSGK.js.map → chunk-UTIAXH52.js.map} +0 -0
  1105. /package/dist/{chunk-5WUN7XPD.js.map → chunk-UVN5TMHU.js.map} +0 -0
  1106. /package/dist/{chunk-UYE47LO6.js.map → chunk-VGYXW3VG.js.map} +0 -0
  1107. /package/dist/{chunk-IKUNOX7F.js.map → chunk-VS7AHPCZ.js.map} +0 -0
  1108. /package/dist/{chunk-MYUFMVCH.js.map → chunk-VTTAJOQ7.js.map} +0 -0
  1109. /package/dist/{chunk-K63HGHZX.js.map → chunk-VWPOLUAO.js.map} +0 -0
  1110. /package/dist/{chunk-GA4YEAMX.js.map → chunk-X3MWB2QU.js.map} +0 -0
  1111. /package/dist/{chunk-I36GSRUJ.js.map → chunk-X6KAJI3V.js.map} +0 -0
  1112. /package/dist/{chunk-IKMUFDVS.js.map → chunk-XBLRHV5R.js.map} +0 -0
  1113. /package/dist/{chunk-XOSQP3YA.js.map → chunk-XDFP2LMW.js.map} +0 -0
  1114. /package/dist/{chunk-MW7Y3T55.js.map → chunk-XEQMZB3C.js.map} +0 -0
  1115. /package/dist/{chunk-B3LMRTRF.js.map → chunk-XEYLT5VA.js.map} +0 -0
  1116. /package/dist/{chunk-UI4HI5QK.js.map → chunk-XHIQ5I6N.js.map} +0 -0
  1117. /package/dist/{chunk-U6M4LS3M.js.map → chunk-XLH7QY2R.js.map} +0 -0
  1118. /package/dist/{chunk-OSA5EQG5.js.map → chunk-XWFAMUZQ.js.map} +0 -0
  1119. /package/dist/{chunk-6MT3HHUB.js.map → chunk-Y4OBB2VN.js.map} +0 -0
  1120. /package/dist/{chunk-CZP5QXNB.js.map → chunk-YCVD6CI3.js.map} +0 -0
  1121. /package/dist/{chunk-APW4T4SW.js.map → chunk-YENLNISG.js.map} +0 -0
  1122. /package/dist/{chunk-JWPA6ZPZ.js.map → chunk-YIRVLKAX.js.map} +0 -0
  1123. /package/dist/{chunk-LQ62ECE6.js.map → chunk-YL73CVNK.js.map} +0 -0
  1124. /package/dist/{chunk-ILKDYBON.js.map → chunk-YLS6QE5G.js.map} +0 -0
  1125. /package/dist/{chunk-YBKVGLQR.js.map → chunk-YPWU5KPE.js.map} +0 -0
  1126. /package/dist/{chunk-IKJLSBUI.js.map → chunk-YQXTDZSU.js.map} +0 -0
  1127. /package/dist/{chunk-TPMZBOFH.js.map → chunk-YSJEAAOL.js.map} +0 -0
  1128. /package/dist/{chunk-W3BFRR2G.js.map → chunk-YWIFM7D7.js.map} +0 -0
  1129. /package/dist/{chunk-WTJ4PLMU.js.map → chunk-YWVI6ZMK.js.map} +0 -0
  1130. /package/dist/{chunk-5KWMYPJV.js.map → chunk-Z4FMAFNH.js.map} +0 -0
  1131. /package/dist/{chunk-W5OWKVZG.js.map → chunk-Z654FWNU.js.map} +0 -0
  1132. /package/dist/{chunk-5FH5LQVS.js.map → chunk-Z7Y523PS.js.map} +0 -0
  1133. /package/dist/{chunk-HLL4PBO7.js.map → chunk-ZD67RM6G.js.map} +0 -0
  1134. /package/dist/{chunk-IVYJX3OY.js.map → chunk-ZEG4VPBL.js.map} +0 -0
  1135. /package/dist/{chunk-K6R5T44I.js.map → chunk-ZLYCOBHW.js.map} +0 -0
  1136. /package/dist/{chunk-VADHIT26.js.map → chunk-ZNJ5MTXV.js.map} +0 -0
  1137. /package/dist/{chunk-2KYQC4T5.js.map → chunk-ZSGY3H53.js.map} +0 -0
  1138. /package/dist/{chunk-BKP43KK4.js.map → chunk-ZTPXACWB.js.map} +0 -0
  1139. /package/dist/{chunk-JCY4CMDH.js.map → chunk-ZUA3JMI6.js.map} +0 -0
  1140. /package/dist/{chunk-IGVVXLKJ.js.map → chunk-ZYAZUPPV.js.map} +0 -0
  1141. /package/dist/{computer-viewer-LPZ763KF.js.map → computer-viewer-TDDO25AV.js.map} +0 -0
  1142. /package/dist/{embedded-new-voice-YVMKSLKJ.js.map → embedded-new-voice-2G3VLPVQ.js.map} +0 -0
  1143. /package/dist/{embedded-voice-BJPQFXSU.js.map → embedded-voice-T5IWOWGD.js.map} +0 -0
  1144. /package/dist/{fleet-decision-row-AA4H5CDT.js.map → fleet-decision-row-WM64KXP3.js.map} +0 -0
  1145. /package/dist/{model-policy-picker-menu-HSMWVO4P.js.map → model-policy-picker-menu-SMC6J6QN.js.map} +0 -0
  1146. /package/dist/{payment-page-card-3LTSFJGN.js.map → payment-page-card-G4U63KUV.js.map} +0 -0
  1147. /package/dist/{platform-activity-row-5VYV6TX4.js.map → platform-activity-row-BUZGZAKZ.js.map} +0 -0
  1148. /package/dist/{queue-surface-implementation-NXHZUKD2.js.map → queue-surface-implementation-4KUZ4PJV.js.map} +0 -0
  1149. /package/dist/{sandbox-files-YCMLQUFU.js.map → sandbox-files-ESDMOFSD.js.map} +0 -0
  1150. /package/dist/{session-connect-cards-KSQLMRM5.js.map → session-connect-cards-Q53KMMYY.js.map} +0 -0
  1151. /package/dist/{session-realtime-ZR6JLG3Y.js.map → session-realtime-CF3I35WJ.js.map} +0 -0
  1152. /package/dist/{timeline-annotation-markers-YAHDPWVG.js.map → timeline-annotation-markers-CJK4RYZ4.js.map} +0 -0
  1153. /package/dist/{timeline-annotation-selection-KHXNCEJP.js.map → timeline-annotation-selection-67GF5H26.js.map} +0 -0
  1154. /package/dist/{timeline-annotations-dialog-Y4XD3N7B.js.map → timeline-annotations-dialog-ONJPQDJQ.js.map} +0 -0
@@ -1,3851 +0,0 @@
1
- "use client";
2
- import {
3
- ArtifactSubmissionProvider,
4
- ArtifactSurface,
5
- EditableArtifactDownloadButton,
6
- EditableArtifactMessage,
7
- editableArtifactAccessRevoked,
8
- editableArtifactStatusLabel,
9
- useArtifactSubmissions,
10
- useEditableArtifactView
11
- } from "./chunk-2JENKGCE.js";
12
- import {
13
- cn
14
- } from "./chunk-TXS65BB2.js";
15
- import {
16
- useOpenGeniText
17
- } from "./chunk-TNUSPXPW.js";
18
-
19
- // src/components/artifacts/spreadsheet-grid.tsx
20
- import { PlusIcon } from "lucide-react";
21
- import {
22
- useCallback as useCallback3,
23
- useEffect as useEffect3,
24
- useId,
25
- useLayoutEffect,
26
- useMemo as useMemo2,
27
- useRef as useRef3,
28
- useState as useState3
29
- } from "react";
30
-
31
- // src/components/artifacts/spreadsheet-command-queue.ts
32
- import { useCallback, useEffect, useRef, useState } from "react";
33
- function overlaps(a, b) {
34
- return a.top <= b.bottom && a.bottom >= b.top && a.left <= b.right && a.right >= b.left;
35
- }
36
- function contains(a, b) {
37
- return a.top <= b.top && a.bottom >= b.bottom && a.left <= b.left && a.right >= b.right;
38
- }
39
- function useSpreadsheetCommandQueue({
40
- scopeKey,
41
- enabled,
42
- onCommandError
43
- }) {
44
- const t = useOpenGeniText();
45
- const [pendingCount, setPendingCount] = useState(0);
46
- const [failures, setFailures] = useState([]);
47
- const commandsRef = useRef(/* @__PURE__ */ new Map());
48
- const nextIdRef = useRef(0);
49
- const mountedRef = useRef(true);
50
- const optionsRef = useRef({ scopeKey, enabled, onCommandError });
51
- optionsRef.current = { scopeKey, enabled, onCommandError };
52
- const scopeRef = useRef({ key: scopeKey, epoch: 0 });
53
- if (scopeRef.current.key !== scopeKey) {
54
- scopeRef.current = { key: scopeKey, epoch: scopeRef.current.epoch + 1 };
55
- }
56
- useEffect(() => {
57
- mountedRef.current = true;
58
- return () => {
59
- mountedRef.current = false;
60
- };
61
- }, []);
62
- useEffect(() => {
63
- commandsRef.current.clear();
64
- setPendingCount(0);
65
- setFailures([]);
66
- }, [scopeKey]);
67
- const refreshFailures = useCallback(() => {
68
- setFailures(
69
- [...commandsRef.current.values()].filter(
70
- (command) => command.message !== void 0 && !command.covered
71
- )
72
- );
73
- }, []);
74
- const clearPreflightFailure = useCallback(() => {
75
- let changed = false;
76
- for (const previous of commandsRef.current.values()) {
77
- if (previous.target === null && previous.message !== void 0) {
78
- commandsRef.current.delete(previous.id);
79
- changed = true;
80
- }
81
- }
82
- if (changed) refreshFailures();
83
- }, [refreshFailures]);
84
- const run = useCallback(
85
- (invoke, retry, rollback, target, accepted) => {
86
- if (!optionsRef.current.enabled) return;
87
- const scope = optionsRef.current.scopeKey;
88
- const epoch = scopeRef.current.epoch;
89
- const id = ++nextIdRef.current;
90
- clearPreflightFailure();
91
- const command = { id, target: null, overlapped: false, covered: false };
92
- commandsRef.current.set(id, command);
93
- const current = () => mountedRef.current && optionsRef.current.scopeKey === scope && scopeRef.current.epoch === epoch;
94
- const fail = (cause) => {
95
- if (!current()) return;
96
- rollback(id);
97
- if (command.covered) {
98
- commandsRef.current.delete(id);
99
- return;
100
- }
101
- const error = cause instanceof Error ? cause : new Error(String(cause));
102
- command.message = error.message || t("artifacts.spreadsheetCommandQueue.spreadsheetChangeFailed");
103
- command.retry = () => {
104
- if (!current() || !optionsRef.current.enabled || command.overlapped) return;
105
- commandsRef.current.delete(id);
106
- refreshFailures();
107
- retry();
108
- };
109
- refreshFailures();
110
- optionsRef.current.onCommandError?.(error);
111
- };
112
- let result;
113
- try {
114
- command.target = typeof target === "function" ? target() : target ?? null;
115
- if (command.target) {
116
- for (const previous of commandsRef.current.values()) {
117
- if (previous.id === id || !previous.target || !overlaps(command.target, previous.target))
118
- continue;
119
- previous.overlapped = true;
120
- previous.covered ||= contains(command.target, previous.target);
121
- if (previous.covered && previous.message !== void 0)
122
- commandsRef.current.delete(previous.id);
123
- }
124
- refreshFailures();
125
- }
126
- result = invoke(id);
127
- } catch (cause) {
128
- fail(cause);
129
- return;
130
- }
131
- const succeed = () => {
132
- if (!current()) return;
133
- commandsRef.current.delete(id);
134
- accepted?.(id);
135
- };
136
- if (!result || typeof result.then !== "function") {
137
- succeed();
138
- return;
139
- }
140
- setPendingCount((count) => count + 1);
141
- void Promise.resolve(result).then(
142
- () => {
143
- if (!current()) return;
144
- setPendingCount((count) => Math.max(0, count - 1));
145
- succeed();
146
- },
147
- (cause) => {
148
- if (!current()) return;
149
- setPendingCount((count) => Math.max(0, count - 1));
150
- fail(cause);
151
- }
152
- );
153
- },
154
- [clearPreflightFailure, refreshFailures, t]
155
- );
156
- const first = failures[0];
157
- return {
158
- run,
159
- clearPreflightFailure,
160
- pendingCount,
161
- error: first ? {
162
- message: failures.length > 1 ? t("artifacts.spreadsheetCommandQueue.messageLengthChangesNotSaved", {
163
- message: first.message,
164
- length: failures.length
165
- }) : first.message,
166
- retry: enabled && !first.overlapped ? first.retry : void 0
167
- } : null
168
- };
169
- }
170
-
171
- // src/components/artifacts/spreadsheet-general-display.ts
172
- function formatSpreadsheetGeneralDisplay(value) {
173
- if (value === null || value === void 0) return "";
174
- if (value instanceof Date) return Number.isNaN(value.getTime()) ? "" : value.toLocaleDateString();
175
- if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
176
- if (typeof value === "number") {
177
- if (Object.is(value, -0) || value === 0) return "0";
178
- if (!Number.isFinite(value)) return String(value);
179
- const rounded = Number(value.toPrecision(15));
180
- return String(Number.isFinite(rounded) ? rounded : value);
181
- }
182
- return String(value);
183
- }
184
- function spreadsheetCellEditSource(value) {
185
- if (value === null || value === void 0) return "";
186
- if (value instanceof Date) return Number.isNaN(value.getTime()) ? "" : value.toLocaleDateString();
187
- if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
188
- return String(value);
189
- }
190
-
191
- // src/components/artifacts/spreadsheet-canvas.ts
192
- var TILE_SIZE = 256;
193
- var MAX_CACHE_PHYSICAL_PIXELS = 32e6;
194
- var MAX_CACHE_TILES = 96;
195
- var MAX_DEVICE_PIXEL_RATIO = 4;
196
- var MAX_AXIS_MARKS_PER_PAINT = 8192;
197
- var MAX_CANVAS_EDGE = 8192;
198
- var MAX_CANVAS_PIXELS = 16e6;
199
- var MAX_TILES_PER_PAINT = 512;
200
- var SparseSpreadsheetCellIndex = class {
201
- size;
202
- rows;
203
- constructor(entries) {
204
- const sorted = [...entries].sort((left, right) => left.row - right.row || left.col - right.col);
205
- this.size = sorted.length;
206
- this.rows = [];
207
- for (const entry of sorted) {
208
- const previous = this.rows.at(-1);
209
- if (previous?.row === entry.row) previous.cells.push(entry);
210
- else this.rows.push({ row: entry.row, cells: [entry] });
211
- }
212
- }
213
- forEachInRange(rowStart, rowEnd, columnStart, columnEnd, visit) {
214
- let rowIndex = lowerBound(this.rows, rowStart, (row) => row.row);
215
- while (rowIndex < this.rows.length) {
216
- const row = this.rows[rowIndex];
217
- if (row.row >= rowEnd) break;
218
- let cellIndex = lowerBound(row.cells, columnStart, (cell) => cell.col);
219
- while (cellIndex < row.cells.length) {
220
- const cell = row.cells[cellIndex];
221
- if (cell.col >= columnEnd) break;
222
- visit(cell);
223
- cellIndex += 1;
224
- }
225
- rowIndex += 1;
226
- }
227
- }
228
- };
229
- function lowerBound(values, target, valueAt) {
230
- let low = 0;
231
- let high = values.length;
232
- while (low < high) {
233
- const middle = low + high >>> 1;
234
- if (valueAt(values[middle]) < target) low = middle + 1;
235
- else high = middle;
236
- }
237
- return low;
238
- }
239
- function coverageContains(coverage, query) {
240
- return coverage === void 0 || coverage.rowStart <= query.rowStart && coverage.rowEnd >= query.rowEnd && coverage.columnStart <= query.columnStart && coverage.columnEnd >= query.columnEnd;
241
- }
242
- function intersectCoverage(query, coverage) {
243
- if (coverage === void 0) return query;
244
- const intersection = {
245
- rowStart: Math.max(query.rowStart, coverage.rowStart),
246
- rowEnd: Math.min(query.rowEnd, coverage.rowEnd),
247
- columnStart: Math.max(query.columnStart, coverage.columnStart),
248
- columnEnd: Math.min(query.columnEnd, coverage.columnEnd)
249
- };
250
- return intersection.rowStart < intersection.rowEnd && intersection.columnStart < intersection.columnEnd ? intersection : null;
251
- }
252
- function spreadsheetCanvasDevicePixelRatio(value) {
253
- if (!Number.isFinite(value) || value <= 0) return 1;
254
- return Math.max(1, Math.min(MAX_DEVICE_PIXEL_RATIO, value));
255
- }
256
- function spreadsheetCanvasBackingScale(width, height, devicePixelRatio) {
257
- const safeWidth = finiteExtent(width);
258
- const safeHeight = finiteExtent(height);
259
- const requested = spreadsheetCanvasDevicePixelRatio(devicePixelRatio);
260
- return Math.max(
261
- Number.EPSILON,
262
- Math.min(
263
- requested,
264
- MAX_CANVAS_EDGE / safeWidth,
265
- MAX_CANVAS_EDGE / safeHeight,
266
- Math.sqrt(MAX_CANVAS_PIXELS / (safeWidth * safeHeight))
267
- )
268
- );
269
- }
270
- var SpreadsheetCanvasRenderer = class {
271
- tiles = /* @__PURE__ */ new Map();
272
- generation = "";
273
- clock = 0;
274
- dispose() {
275
- this.tiles.clear();
276
- this.generation = "";
277
- }
278
- paint(input) {
279
- const context = safeCanvasContext(input.canvas);
280
- if (!context) return null;
281
- const width = finiteExtent(input.viewportWidth);
282
- const height = finiteExtent(input.viewportHeight);
283
- const dpr = spreadsheetCanvasBackingScale(width, height, input.devicePixelRatio);
284
- const pixelWidth = Math.max(1, Math.min(MAX_CANVAS_EDGE, Math.round(width * dpr)));
285
- const pixelHeight = Math.max(1, Math.min(MAX_CANVAS_EDGE, Math.round(height * dpr)));
286
- if (input.canvas.width !== pixelWidth) input.canvas.width = pixelWidth;
287
- if (input.canvas.height !== pixelHeight) input.canvas.height = pixelHeight;
288
- input.canvas.style.width = `${width}px`;
289
- input.canvas.style.height = `${height}px`;
290
- context.setTransform(dpr, 0, 0, dpr, 0, 0);
291
- context.clearRect(0, 0, width, height);
292
- const generation = [
293
- input.projection.sheetId,
294
- input.projection.generationId ?? "<none>",
295
- input.projection.revision,
296
- input.dimensionRevision,
297
- dpr,
298
- input.theme.signature
299
- ].join("/");
300
- if (generation !== this.generation) {
301
- this.tiles.clear();
302
- this.generation = generation;
303
- }
304
- setFill(context, input.theme.background, "#ffffff");
305
- context.fillRect(0, 0, width, height);
306
- const bodyLeft = input.rowHeaderWidth;
307
- const bodyTop = input.columnHeaderHeight;
308
- const visibleLeft = clamp(input.logicalScrollLeft, 0, input.columns.total);
309
- const visibleTop = clamp(input.logicalScrollTop, 0, input.rows.total);
310
- const visibleRight = clamp(
311
- input.logicalScrollLeft + width - bodyLeft,
312
- visibleLeft,
313
- input.columns.total
314
- );
315
- const visibleBottom = clamp(
316
- input.logicalScrollTop + height - bodyTop,
317
- visibleTop,
318
- input.rows.total
319
- );
320
- let paintedTiles = 0;
321
- let reusedTiles = 0;
322
- let uncachedTiles = 0;
323
- context.save();
324
- context.beginPath();
325
- context.rect(bodyLeft, bodyTop, Math.max(0, width - bodyLeft), Math.max(0, height - bodyTop));
326
- context.clip();
327
- const firstTileColumn = Math.floor(visibleLeft / TILE_SIZE);
328
- const lastTileColumn = Math.floor(
329
- Math.max(visibleLeft, visibleRight - Number.EPSILON) / TILE_SIZE
330
- );
331
- const firstTileRow = Math.floor(visibleTop / TILE_SIZE);
332
- const lastTileRow = Math.floor(
333
- Math.max(visibleTop, visibleBottom - Number.EPSILON) / TILE_SIZE
334
- );
335
- let visitedTiles = 0;
336
- tileLoop: for (let tileRow = firstTileRow; tileRow <= lastTileRow; tileRow += 1) {
337
- for (let tileColumn = firstTileColumn; tileColumn <= lastTileColumn; tileColumn += 1) {
338
- if (visitedTiles >= MAX_TILES_PER_PAINT) break tileLoop;
339
- visitedTiles += 1;
340
- const key = `${tileColumn}:${tileRow}`;
341
- let tile = this.tiles.get(key);
342
- if (!tile) {
343
- const painted = this.paintTile(input, tileColumn, tileRow, dpr);
344
- tile = {
345
- canvas: painted.canvas,
346
- lastUsed: ++this.clock
347
- };
348
- if (painted.cacheable) this.tiles.set(key, tile);
349
- else uncachedTiles += 1;
350
- paintedTiles += 1;
351
- } else {
352
- tile.lastUsed = ++this.clock;
353
- reusedTiles += 1;
354
- }
355
- const logicalX = tileColumn * TILE_SIZE;
356
- const logicalY = tileRow * TILE_SIZE;
357
- context.drawImage(
358
- tile.canvas,
359
- bodyLeft + logicalX - input.logicalScrollLeft,
360
- bodyTop + logicalY - input.logicalScrollTop,
361
- TILE_SIZE,
362
- TILE_SIZE
363
- );
364
- }
365
- }
366
- paintSelection(context, input);
367
- paintVisibleGrid(context, input, visibleLeft, visibleTop, visibleRight, visibleBottom);
368
- context.restore();
369
- paintHeaders(
370
- context,
371
- input,
372
- width,
373
- height,
374
- visibleLeft,
375
- visibleTop,
376
- visibleRight,
377
- visibleBottom
378
- );
379
- this.evictTiles(dpr);
380
- return {
381
- cacheSize: this.tiles.size,
382
- paintedTiles,
383
- reusedTiles,
384
- uncachedTiles,
385
- devicePixelRatio: dpr
386
- };
387
- }
388
- paintTile(input, tileColumn, tileRow, dpr) {
389
- const tile = input.canvas.ownerDocument.createElement("canvas");
390
- tile.width = Math.max(1, Math.round(TILE_SIZE * dpr));
391
- tile.height = Math.max(1, Math.round(TILE_SIZE * dpr));
392
- const context = safeCanvasContext(tile);
393
- if (!context) return { canvas: tile, cacheable: false };
394
- context.setTransform(dpr, 0, 0, dpr, 0, 0);
395
- setFill(context, input.theme.background, "#ffffff");
396
- context.fillRect(0, 0, TILE_SIZE, TILE_SIZE);
397
- const tileLeft = tileColumn * TILE_SIZE;
398
- const tileTop = tileRow * TILE_SIZE;
399
- const tileRight = Math.min(input.columns.total, tileLeft + TILE_SIZE);
400
- const tileBottom = Math.min(input.rows.total, tileTop + TILE_SIZE);
401
- const firstColumn = input.columns.indexAtOffset(tileLeft);
402
- const lastColumn = input.columns.indexAtOffset(Math.max(tileLeft, tileRight - Number.EPSILON));
403
- const firstRow = input.rows.indexAtOffset(tileTop);
404
- const lastRow = input.rows.indexAtOffset(Math.max(tileTop, tileBottom - Number.EPSILON));
405
- const query = {
406
- rowStart: firstRow,
407
- rowEnd: Math.min(input.rows.count, lastRow + 1),
408
- columnStart: firstColumn,
409
- columnEnd: Math.min(input.columns.count, lastColumn + 1)
410
- };
411
- const coveredQuery = intersectCoverage(query, input.projection.coverage);
412
- const cacheable = coverageContains(input.projection.coverage, query);
413
- const cells = [];
414
- if (coveredQuery) {
415
- input.projection.cells.forEachInRange(
416
- coveredQuery.rowStart,
417
- coveredQuery.rowEnd,
418
- coveredQuery.columnStart,
419
- coveredQuery.columnEnd,
420
- (cell) => cells.push(cell)
421
- );
422
- }
423
- for (const cell of cells) {
424
- const fill = cell.format.fill;
425
- if (!fill) continue;
426
- const x = input.columns.offsetAt(cell.col) - tileLeft;
427
- const y = input.rows.offsetAt(cell.row) - tileTop;
428
- const width = input.columns.sizeAt(cell.col);
429
- const height = input.rows.sizeAt(cell.row);
430
- setFill(context, fill, input.theme.background);
431
- context.fillRect(x, y, width, height);
432
- }
433
- paintTileGrid(context, input, tileLeft, tileTop, tileRight, tileBottom);
434
- for (const cell of cells) {
435
- const value = input.projection.valueAt(cell);
436
- const text = formatSpreadsheetGeneralDisplay(value);
437
- if (!text) continue;
438
- paintCellText(context, input, cell, text, tileLeft, tileTop);
439
- }
440
- return { canvas: tile, cacheable };
441
- }
442
- evictTiles(dpr) {
443
- const pixelsPerTile = Math.max(1, Math.round(TILE_SIZE * dpr)) ** 2;
444
- const maximum = Math.max(
445
- 4,
446
- Math.min(MAX_CACHE_TILES, Math.floor(MAX_CACHE_PHYSICAL_PIXELS / pixelsPerTile))
447
- );
448
- if (this.tiles.size <= maximum) return;
449
- const oldest = [...this.tiles.entries()].sort(
450
- (left, right) => left[1].lastUsed - right[1].lastUsed
451
- );
452
- for (let index = 0; index < oldest.length - maximum; index += 1) {
453
- this.tiles.delete(oldest[index][0]);
454
- }
455
- }
456
- };
457
- function finiteExtent(value) {
458
- if (!Number.isFinite(value) || value <= 0) return 1;
459
- return Math.max(1, Math.floor(value));
460
- }
461
- function safeCanvasContext(canvas) {
462
- try {
463
- return canvas.getContext("2d", { alpha: false });
464
- } catch {
465
- return null;
466
- }
467
- }
468
- function setFill(context, value, fallback) {
469
- context.fillStyle = fallback;
470
- try {
471
- context.fillStyle = value;
472
- } catch {
473
- }
474
- }
475
- function setStroke(context, value, fallback) {
476
- context.strokeStyle = fallback;
477
- try {
478
- context.strokeStyle = value;
479
- } catch {
480
- }
481
- }
482
- function paintTileGrid(context, input, tileLeft, tileTop, tileRight, tileBottom) {
483
- setFill(context, input.theme.border, "#d1d5db");
484
- visitAxisBoundaries(input.columns, tileLeft, tileRight, (offset) => {
485
- context.fillRect(offset - tileLeft - 1, 0, 1, TILE_SIZE);
486
- });
487
- visitAxisBoundaries(input.rows, tileTop, tileBottom, (offset) => {
488
- context.fillRect(0, offset - tileTop - 1, TILE_SIZE, 1);
489
- });
490
- }
491
- function paintVisibleGrid(context, input, visibleLeft, visibleTop, visibleRight, visibleBottom) {
492
- setFill(context, input.theme.border, "#d1d5db");
493
- visitAxisBoundaries(input.columns, visibleLeft, visibleRight, (offset) => {
494
- const x = input.rowHeaderWidth + offset - input.logicalScrollLeft;
495
- context.fillRect(x - 1, input.columnHeaderHeight, 1, input.viewportHeight);
496
- });
497
- visitAxisBoundaries(input.rows, visibleTop, visibleBottom, (offset) => {
498
- const y = input.columnHeaderHeight + offset - input.logicalScrollTop;
499
- context.fillRect(input.rowHeaderWidth, y - 1, input.viewportWidth, 1);
500
- });
501
- }
502
- function visitAxisBoundaries(axis, start, end, visit) {
503
- if (axis.count <= 0 || end < start) return;
504
- let index = axis.indexAtOffset(start);
505
- let visits = 0;
506
- while (index < axis.count && visits < MAX_AXIS_MARKS_PER_PAINT) {
507
- const boundary = axis.offsetAt(index + 1);
508
- if (boundary > end + 1) break;
509
- if (boundary >= start) visit(boundary);
510
- index += 1;
511
- visits += 1;
512
- }
513
- }
514
- function paintSelection(context, input) {
515
- const { selection } = input;
516
- const left = input.rowHeaderWidth + input.columns.offsetAt(selection.left) - input.logicalScrollLeft;
517
- const right = input.rowHeaderWidth + input.columns.offsetAt(selection.right + 1) - input.logicalScrollLeft;
518
- const top = input.columnHeaderHeight + input.rows.offsetAt(selection.top) - input.logicalScrollTop;
519
- const bottom = input.columnHeaderHeight + input.rows.offsetAt(selection.bottom + 1) - input.logicalScrollTop;
520
- context.save();
521
- setFill(context, input.theme.accent, "#545454");
522
- context.globalAlpha = 0.1;
523
- context.fillRect(left, top, right - left, bottom - top);
524
- context.restore();
525
- const activeLeft = input.rowHeaderWidth + input.columns.offsetAt(selection.focusColumn) - input.logicalScrollLeft;
526
- const activeTop = input.columnHeaderHeight + input.rows.offsetAt(selection.focusRow) - input.logicalScrollTop;
527
- const activeWidth = input.columns.sizeAt(selection.focusColumn);
528
- const activeHeight = input.rows.sizeAt(selection.focusRow);
529
- context.save();
530
- setStroke(context, input.theme.accent, "#545454");
531
- context.lineWidth = 2;
532
- context.strokeRect(
533
- activeLeft + 1,
534
- activeTop + 1,
535
- Math.max(0, activeWidth - 2),
536
- Math.max(0, activeHeight - 2)
537
- );
538
- context.restore();
539
- }
540
- function paintHeaders(context, input, width, height, visibleLeft, visibleTop, visibleRight, visibleBottom) {
541
- setFill(context, input.theme.headerBackground, "#f3f4f6");
542
- context.fillRect(0, 0, width, input.columnHeaderHeight);
543
- context.fillRect(0, input.columnHeaderHeight, input.rowHeaderWidth, height);
544
- setFill(context, input.theme.border, "#d1d5db");
545
- context.fillRect(0, input.columnHeaderHeight - 1, width, 1);
546
- context.fillRect(input.rowHeaderWidth - 1, 0, 1, height);
547
- context.save();
548
- context.beginPath();
549
- context.rect(
550
- input.rowHeaderWidth,
551
- 0,
552
- Math.max(0, width - input.rowHeaderWidth),
553
- input.columnHeaderHeight
554
- );
555
- context.clip();
556
- setFill(context, input.theme.mutedForeground, "#6b7280");
557
- context.font = `600 ${input.theme.headerFontSize}px ${input.theme.fontFamily}`;
558
- context.textAlign = "center";
559
- context.textBaseline = "middle";
560
- visitAxisItems(input.columns, visibleLeft, visibleRight, (column, offset, size) => {
561
- const x = input.rowHeaderWidth + offset - input.logicalScrollLeft;
562
- setFill(context, input.theme.border, "#d1d5db");
563
- context.fillRect(x + size - 1, 0, 1, input.columnHeaderHeight);
564
- if (size >= 8) {
565
- setFill(context, input.theme.mutedForeground, "#6b7280");
566
- context.fillText(columnName(column), x + size / 2, input.columnHeaderHeight / 2);
567
- }
568
- });
569
- context.restore();
570
- context.save();
571
- context.beginPath();
572
- context.rect(
573
- 0,
574
- input.columnHeaderHeight,
575
- input.rowHeaderWidth,
576
- Math.max(0, height - input.columnHeaderHeight)
577
- );
578
- context.clip();
579
- setFill(context, input.theme.mutedForeground, "#6b7280");
580
- context.font = `400 ${input.theme.headerFontSize}px ${input.theme.fontFamily}`;
581
- context.textAlign = "center";
582
- context.textBaseline = "middle";
583
- visitAxisItems(input.rows, visibleTop, visibleBottom, (row, offset, size) => {
584
- const y = input.columnHeaderHeight + offset - input.logicalScrollTop;
585
- setFill(context, input.theme.border, "#d1d5db");
586
- context.fillRect(0, y + size - 1, input.rowHeaderWidth, 1);
587
- if (size >= 8) {
588
- setFill(context, input.theme.mutedForeground, "#6b7280");
589
- context.fillText(String(row + 1), input.rowHeaderWidth / 2, y + size / 2);
590
- }
591
- });
592
- context.restore();
593
- }
594
- function visitAxisItems(axis, start, end, visit) {
595
- if (axis.count <= 0 || end < start) return;
596
- let index = axis.indexAtOffset(start);
597
- let visits = 0;
598
- while (index < axis.count && visits < MAX_AXIS_MARKS_PER_PAINT) {
599
- const offset = axis.offsetAt(index);
600
- if (offset > end) break;
601
- visit(index, offset, axis.sizeAt(index));
602
- index += 1;
603
- visits += 1;
604
- }
605
- }
606
- function paintCellText(context, input, cell, text, tileLeft, tileTop) {
607
- const format = cell.format;
608
- const x = input.columns.offsetAt(cell.col) - tileLeft;
609
- const y = input.rows.offsetAt(cell.row) - tileTop;
610
- const width = input.columns.sizeAt(cell.col);
611
- const height = input.rows.sizeAt(cell.row);
612
- if (width <= 2 || height <= 2) return;
613
- const fontSize = finitePositive(format.font?.size, input.theme.fontSize);
614
- const fontFamily = format.font?.name || input.theme.fontFamily;
615
- const weight = format.font?.bold ? 600 : 400;
616
- const italic = format.font?.italic ? "italic " : "";
617
- context.save();
618
- context.beginPath();
619
- context.rect(x + 1, y + 1, Math.max(0, width - 2), Math.max(0, height - 2));
620
- context.clip();
621
- context.font = `${italic}${weight} ${fontSize}px ${fontFamily}`;
622
- setFill(
623
- context,
624
- format.font?.color ?? (text.startsWith("#") ? input.theme.error : input.theme.foreground),
625
- input.theme.foreground
626
- );
627
- const alignment = format.horizontalAlignment;
628
- context.textAlign = alignment === "center" ? "center" : alignment === "right" ? "right" : "left";
629
- context.textBaseline = "alphabetic";
630
- const padding = 6;
631
- const textX = alignment === "center" ? x + width / 2 : alignment === "right" ? x + width - padding : x + padding;
632
- const lineHeight = fontSize * 1.5;
633
- const availableWidth = Math.max(0, width - padding * 2);
634
- const lines = format.wrapText ? wrapText(context, text, availableWidth, Math.max(1, Math.floor(height / lineHeight))) : [ellipsize(context, text.replaceAll(/\r?\n/g, " "), availableWidth)];
635
- const blockHeight = lines.length * lineHeight;
636
- const vertical = format.verticalAlignment;
637
- const firstBaseline = vertical === "top" ? y + Math.min(height, padding + fontSize) : vertical === "bottom" ? y + height - padding - blockHeight + fontSize : y + (height - blockHeight) / 2 + fontSize;
638
- for (let index = 0; index < lines.length; index += 1) {
639
- const line = lines[index];
640
- const baseline = firstBaseline + index * lineHeight;
641
- context.fillText(line, textX, baseline);
642
- if (format.font?.underline && line) {
643
- const metrics = context.measureText(line);
644
- const textWidth = metrics.width;
645
- const startX = alignment === "center" ? textX - textWidth / 2 : alignment === "right" ? textX - textWidth : textX;
646
- setFill(context, format.font.color ?? input.theme.foreground, input.theme.foreground);
647
- context.fillRect(startX, baseline + 1, textWidth, Math.max(1, fontSize / 14));
648
- }
649
- }
650
- context.restore();
651
- }
652
- function wrapText(context, input, maximumWidth, maximumLines) {
653
- if (maximumWidth <= 0) return [""];
654
- const output = [];
655
- for (const paragraph of input.split(/\r?\n/)) {
656
- const words = paragraph.split(/\s+/).filter(Boolean);
657
- if (words.length === 0) output.push("");
658
- let line = "";
659
- for (const word of words) {
660
- const next = line ? `${line} ${word}` : word;
661
- if (!line || context.measureText(next).width <= maximumWidth) line = next;
662
- else {
663
- output.push(ellipsize(context, line, maximumWidth));
664
- line = word;
665
- }
666
- if (output.length >= maximumLines) break;
667
- }
668
- if (output.length < maximumLines && line) output.push(ellipsize(context, line, maximumWidth));
669
- if (output.length >= maximumLines) break;
670
- }
671
- return output.slice(0, maximumLines);
672
- }
673
- function ellipsize(context, input, maximumWidth) {
674
- if (!input || maximumWidth <= 0) return "";
675
- if (context.measureText(input).width <= maximumWidth) return input;
676
- const suffix = "\u2026";
677
- const suffixWidth = context.measureText(suffix).width;
678
- if (suffixWidth > maximumWidth) return "";
679
- let low = 0;
680
- let high = input.length;
681
- while (low < high) {
682
- const middle = Math.ceil((low + high) / 2);
683
- if (context.measureText(`${input.slice(0, middle)}${suffix}`).width <= maximumWidth)
684
- low = middle;
685
- else high = middle - 1;
686
- }
687
- return `${input.slice(0, low)}${suffix}`;
688
- }
689
- function finitePositive(value, fallback) {
690
- return value !== void 0 && Number.isFinite(value) && value > 0 ? value : fallback;
691
- }
692
- function columnName(index) {
693
- let value = index + 1;
694
- let result = "";
695
- while (value > 0) {
696
- const remainder = (value - 1) % 26;
697
- result = String.fromCharCode(65 + remainder) + result;
698
- value = Math.floor((value - 1) / 26);
699
- }
700
- return result;
701
- }
702
- function clamp(value, minimum, maximum) {
703
- return Math.max(minimum, Math.min(maximum, value));
704
- }
705
-
706
- // src/components/artifacts/spreadsheet-resize.tsx
707
- import {
708
- useCallback as useCallback2,
709
- useEffect as useEffect2,
710
- useMemo,
711
- useRef as useRef2,
712
- useState as useState2
713
- } from "react";
714
- import { jsx } from "react/jsx-runtime";
715
- var MIN_SIZE = 8;
716
- var MAX_SIZE = 4096;
717
- function keyOf(change) {
718
- return `${change.axis}:${change.index}`;
719
- }
720
- function boundedSize(size) {
721
- return Math.max(MIN_SIZE, Math.min(MAX_SIZE, Math.round(size)));
722
- }
723
- function useSpreadsheetResizing(options) {
724
- const t = useOpenGeniText();
725
- const optionsRef = useRef2(options);
726
- optionsRef.current = options;
727
- const [gesture, setGesture] = useState2(null);
728
- const [pending, setPending] = useState2([]);
729
- const [inFlightCount, setInFlightCount] = useState2(0);
730
- const [errors, setErrors] = useState2([]);
731
- const errorsRef = useRef2(/* @__PURE__ */ new Map());
732
- const activeRef = useRef2(null);
733
- const pendingRef = useRef2(/* @__PURE__ */ new Map());
734
- const frameRef = useRef2(null);
735
- const nextIdRef = useRef2(0);
736
- const scopeRef = useRef2(0);
737
- const mountedRef = useRef2(true);
738
- const clearError = useCallback2(() => {
739
- errorsRef.current.clear();
740
- setErrors([]);
741
- }, []);
742
- const cancelFrame = useCallback2(() => {
743
- if (frameRef.current !== null) globalThis.cancelAnimationFrame?.(frameRef.current);
744
- frameRef.current = null;
745
- }, []);
746
- const cancel = useCallback2(() => {
747
- cancelFrame();
748
- activeRef.current = null;
749
- setGesture(null);
750
- }, [cancelFrame]);
751
- useEffect2(() => {
752
- mountedRef.current = true;
753
- return () => {
754
- mountedRef.current = false;
755
- scopeRef.current += 1;
756
- cancelFrame();
757
- };
758
- }, [cancelFrame]);
759
- useEffect2(() => {
760
- scopeRef.current += 1;
761
- cancel();
762
- pendingRef.current.clear();
763
- setPending([]);
764
- setInFlightCount(0);
765
- clearError();
766
- }, [cancel, clearError, options.enabled, options.generationId, options.sheetId]);
767
- const authoritativeSize = useCallback2((axis, index) => {
768
- const current = optionsRef.current;
769
- const entries = axis === "row" ? current.rowHeights : current.columnWidths;
770
- return entries.find(([at]) => at === index)?.[1] ?? (axis === "row" ? current.defaultRowHeight : current.defaultColumnWidth);
771
- }, []);
772
- useEffect2(() => {
773
- let changed = false;
774
- for (const [key, entry] of pendingRef.current) {
775
- if (entry.settled && (authoritativeSize(entry.axis, entry.index) === entry.size || options.revision !== entry.baseRevision)) {
776
- pendingRef.current.delete(key);
777
- changed = true;
778
- }
779
- }
780
- if (changed) setPending([...pendingRef.current.values()]);
781
- }, [authoritativeSize, options.columnWidths, options.revision, options.rowHeights, pending]);
782
- const submit = useCallback2(
783
- (change) => {
784
- const current = optionsRef.current;
785
- if (!current.enabled || !current.commit || change.sheetId !== current.sheetId) return;
786
- const scope = scopeRef.current;
787
- const id = ++nextIdRef.current;
788
- const key = keyOf(change);
789
- const entry = {
790
- ...change,
791
- id,
792
- baseRevision: current.revision,
793
- settled: false
794
- };
795
- pendingRef.current.set(key, entry);
796
- setPending([...pendingRef.current.values()]);
797
- errorsRef.current.delete(key);
798
- setErrors([...errorsRef.current.values()]);
799
- current.onStart?.();
800
- let asynchronous = false;
801
- const settle = (failed, cause) => {
802
- if (!mountedRef.current || scopeRef.current !== scope) return;
803
- if (asynchronous) setInFlightCount((count) => Math.max(0, count - 1));
804
- const latest = pendingRef.current.get(key);
805
- if (latest?.id !== id) return;
806
- if (failed) {
807
- pendingRef.current.delete(key);
808
- const failure = cause instanceof Error ? cause : new Error(String(cause));
809
- errorsRef.current.set(key, {
810
- key,
811
- message: failure.message || t("artifacts.spreadsheetResize.spreadsheetResizeFailed"),
812
- retry: () => {
813
- if (!mountedRef.current || scopeRef.current !== scope) return;
814
- submit(change);
815
- }
816
- });
817
- setErrors([...errorsRef.current.values()]);
818
- optionsRef.current.onCommandError?.(failure);
819
- } else {
820
- pendingRef.current.set(key, {
821
- ...entry,
822
- baseRevision: optionsRef.current.revision,
823
- settled: true
824
- });
825
- }
826
- setPending([...pendingRef.current.values()]);
827
- };
828
- try {
829
- const result = current.commit(change);
830
- if (result && typeof result.then === "function") {
831
- asynchronous = true;
832
- setInFlightCount((count) => count + 1);
833
- void Promise.resolve(result).then(
834
- () => settle(false),
835
- (cause) => settle(true, cause)
836
- );
837
- } else {
838
- settle(false);
839
- }
840
- } catch (cause) {
841
- settle(true, cause);
842
- }
843
- },
844
- [t]
845
- );
846
- const update = useCallback2((next) => {
847
- activeRef.current = next;
848
- if (frameRef.current !== null) return;
849
- if (typeof globalThis.requestAnimationFrame !== "function") {
850
- setGesture(next);
851
- return;
852
- }
853
- frameRef.current = globalThis.requestAnimationFrame(() => {
854
- frameRef.current = null;
855
- if (mountedRef.current) setGesture(activeRef.current);
856
- });
857
- }, []);
858
- const finish = useCallback2(() => {
859
- const active = activeRef.current;
860
- cancel();
861
- if (!active || active.size === active.startSize) return;
862
- submit({ sheetId: active.sheetId, axis: active.axis, index: active.index, size: active.size });
863
- }, [cancel, submit]);
864
- const begin = useCallback2(
865
- (axis, index, pointerId, position) => {
866
- const current = optionsRef.current;
867
- if (!current.enabled || !current.commit) return;
868
- const existing = pendingRef.current.get(keyOf({ axis, index }));
869
- const size = existing?.size ?? authoritativeSize(axis, index);
870
- cancel();
871
- const next = {
872
- sheetId: current.sheetId,
873
- axis,
874
- index,
875
- size,
876
- startSize: size,
877
- startPosition: position,
878
- pointerId
879
- };
880
- activeRef.current = next;
881
- setGesture(next);
882
- current.onStart?.();
883
- },
884
- [authoritativeSize, cancel]
885
- );
886
- const handleProps = useCallback2(
887
- (axis, index) => ({
888
- onPointerDown(event) {
889
- if (event.button !== 0 || event.isPrimary === false) return;
890
- event.preventDefault();
891
- event.stopPropagation();
892
- event.currentTarget.focus({ preventScroll: true });
893
- begin(axis, index, event.pointerId, axis === "column" ? event.clientX : event.clientY);
894
- event.currentTarget.setPointerCapture?.(event.pointerId);
895
- },
896
- onPointerMove(event) {
897
- const active = activeRef.current;
898
- if (!active || active.pointerId !== event.pointerId || active.axis !== axis || active.index !== index)
899
- return;
900
- event.preventDefault();
901
- event.stopPropagation();
902
- const position = axis === "column" ? event.clientX : event.clientY;
903
- update({
904
- ...active,
905
- size: boundedSize(active.startSize + position - active.startPosition)
906
- });
907
- },
908
- onPointerUp(event) {
909
- const active = activeRef.current;
910
- if (!active || active.pointerId !== event.pointerId || active.axis !== axis || active.index !== index)
911
- return;
912
- event.preventDefault();
913
- event.stopPropagation();
914
- const position = axis === "column" ? event.clientX : event.clientY;
915
- activeRef.current = {
916
- ...active,
917
- size: boundedSize(active.startSize + position - active.startPosition)
918
- };
919
- finish();
920
- if (event.currentTarget.hasPointerCapture?.(event.pointerId)) {
921
- event.currentTarget.releasePointerCapture?.(event.pointerId);
922
- }
923
- },
924
- onPointerCancel(event) {
925
- const active = activeRef.current;
926
- if (active?.pointerId === event.pointerId && active.axis === axis && active.index === index)
927
- cancel();
928
- event.stopPropagation();
929
- },
930
- onLostPointerCapture(event) {
931
- const active = activeRef.current;
932
- if (active?.pointerId === event.pointerId && active.axis === axis && active.index === index)
933
- cancel();
934
- },
935
- onKeyDown(event) {
936
- event.stopPropagation();
937
- if (event.key === "Escape") {
938
- event.preventDefault();
939
- cancel();
940
- return;
941
- }
942
- if (event.key === "Enter") {
943
- event.preventDefault();
944
- finish();
945
- return;
946
- }
947
- const negative = axis === "column" ? "ArrowLeft" : "ArrowUp";
948
- const positive = axis === "column" ? "ArrowRight" : "ArrowDown";
949
- if (event.key !== negative && event.key !== positive && event.key !== "Home") return;
950
- event.preventDefault();
951
- if (activeRef.current?.pointerId !== null || activeRef.current.axis !== axis || activeRef.current.index !== index) {
952
- begin(axis, index, null, 0);
953
- }
954
- const active = activeRef.current;
955
- if (!active) return;
956
- const current = optionsRef.current;
957
- const size = event.key === "Home" ? axis === "row" ? current.defaultRowHeight : current.defaultColumnWidth : active.size + (event.key === negative ? -1 : 1) * (event.shiftKey ? 1 : 8);
958
- update({ ...active, size: boundedSize(size) });
959
- },
960
- onKeyUp(event) {
961
- event.stopPropagation();
962
- const active = activeRef.current;
963
- if (active?.axis === axis && active.index === index && (event.key === "Home" || event.key.startsWith("Arrow")))
964
- finish();
965
- },
966
- onBlur() {
967
- const active = activeRef.current;
968
- if (active?.pointerId === null && active.axis === axis && active.index === index) finish();
969
- }
970
- }),
971
- [begin, cancel, finish, update]
972
- );
973
- const pendingRows = useMemo(() => pending.filter((entry) => entry.axis === "row"), [pending]);
974
- const pendingColumns = useMemo(
975
- () => pending.filter((entry) => entry.axis === "column"),
976
- [pending]
977
- );
978
- const rowGesture = gesture?.axis === "row" ? gesture : null;
979
- const columnGesture = gesture?.axis === "column" ? gesture : null;
980
- const rowHeights = useMemo(
981
- () => previewDimensions(options.rowHeights, pendingRows, rowGesture),
982
- [options.rowHeights, pendingRows, rowGesture]
983
- );
984
- const columnWidths = useMemo(
985
- () => previewDimensions(options.columnWidths, pendingColumns, columnGesture),
986
- [options.columnWidths, pendingColumns, columnGesture]
987
- );
988
- const previewKey = [
989
- ...pending.map((entry) => `${entry.axis}:${entry.index}:${entry.size}`),
990
- ...gesture ? [`${gesture.axis}:${gesture.index}:${gesture.size}`] : []
991
- ].join(";");
992
- return {
993
- rowHeights,
994
- columnWidths,
995
- previewKey,
996
- handleProps,
997
- pendingCount: inFlightCount,
998
- error: errors[0] ? { message: errors[0].message, retry: options.enabled ? errors[0].retry : void 0 } : null,
999
- clearError
1000
- };
1001
- }
1002
- function previewDimensions(entries, pending, gesture) {
1003
- if (!pending.length && !gesture) return entries;
1004
- const projected = new Map(entries);
1005
- for (const entry of pending) projected.set(entry.index, entry.size);
1006
- if (gesture) projected.set(gesture.index, gesture.size);
1007
- return [...projected.entries()];
1008
- }
1009
- function SpreadsheetResizeHandle({
1010
- axis,
1011
- label,
1012
- size,
1013
- ...handlers
1014
- }) {
1015
- const t = useOpenGeniText();
1016
- return /* @__PURE__ */ jsx(
1017
- "div",
1018
- {
1019
- ...handlers,
1020
- role: "separator",
1021
- tabIndex: 0,
1022
- "aria-label": label,
1023
- "aria-orientation": axis === "column" ? "vertical" : "horizontal",
1024
- "aria-valuemin": MIN_SIZE,
1025
- "aria-valuemax": MAX_SIZE,
1026
- "aria-valuenow": size,
1027
- "aria-valuetext": t("artifacts.spreadsheetResize.sizePixels", { size }),
1028
- "data-og-resize-axis": axis,
1029
- style: { [axis === "column" ? "right" : "bottom"]: "calc(var(--spacing) * -1)" },
1030
- className: cn(
1031
- "pointer-events-auto absolute z-40 touch-none outline-hidden hover:bg-og-accent/20 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent",
1032
- axis === "column" ? "top-0 h-full w-2 cursor-col-resize" : "left-0 h-2 w-full cursor-row-resize"
1033
- )
1034
- }
1035
- );
1036
- }
1037
-
1038
- // src/components/artifacts/spreadsheet-grid.tsx
1039
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
1040
- var MAX_ROWS = 1048576;
1041
- var MAX_COLUMNS = 16384;
1042
- var ROW_HEADER_WIDTH = 48;
1043
- var COLUMN_HEADER_HEIGHT = 28;
1044
- var FALLBACK_VIEWPORT_WIDTH = 880;
1045
- var FALLBACK_VIEWPORT_HEIGHT = 480;
1046
- var MAX_PHYSICAL_SCROLL_SPAN = 8e6;
1047
- var MIN_PHYSICAL_ITEM_SPAN = 4;
1048
- var MAX_MOUNTED_AXIS_ITEMS = 512;
1049
- var MAX_MOUNTED_GRID_CELLS = 2048;
1050
- var MAX_CLIPBOARD_INPUT_BYTES = 4 * 1024 * 1024;
1051
- var MAX_CLIPBOARD_CELLS = 65536;
1052
- var EMPTY_DIMENSIONS = [];
1053
- var useClientLayoutEffect = typeof window === "undefined" ? useEffect3 : useLayoutEffect;
1054
- function boundedInteger(value, fallback, max) {
1055
- if (value === void 0) return fallback;
1056
- if (!Number.isFinite(value)) return fallback;
1057
- return Math.min(max, Math.max(1, Math.floor(value)));
1058
- }
1059
- function buildAxis(count, defaultSize, entries) {
1060
- const normalizedDefault = Number.isFinite(defaultSize) && defaultSize > 0 ? defaultSize : 1;
1061
- const sorted = [...entries].filter(
1062
- ([index, size]) => Number.isInteger(index) && index >= 0 && index < count && Number.isFinite(size) && size > 0
1063
- ).sort(([left], [right]) => left - right);
1064
- const overrides = [];
1065
- let cumulativeDelta = 0;
1066
- for (const [index, size] of sorted) {
1067
- const previous = overrides.at(-1);
1068
- if (previous?.index === index) {
1069
- cumulativeDelta -= previous.size - normalizedDefault;
1070
- overrides.pop();
1071
- }
1072
- if (size === normalizedDefault) continue;
1073
- const start = index * normalizedDefault + cumulativeDelta;
1074
- cumulativeDelta += size - normalizedDefault;
1075
- overrides.push({
1076
- index,
1077
- size,
1078
- start,
1079
- end: start + size,
1080
- cumulativeDelta
1081
- });
1082
- }
1083
- return {
1084
- count,
1085
- defaultSize: normalizedDefault,
1086
- overrides,
1087
- total: count * normalizedDefault + cumulativeDelta
1088
- };
1089
- }
1090
- function lowerBoundOverrideIndex(axis, index) {
1091
- let low = 0;
1092
- let high = axis.overrides.length;
1093
- while (low < high) {
1094
- const middle = low + high >>> 1;
1095
- if (axis.overrides[middle].index < index) low = middle + 1;
1096
- else high = middle;
1097
- }
1098
- return low;
1099
- }
1100
- function axisOffsetAt(axis, index) {
1101
- if (index <= 0) return 0;
1102
- if (index >= axis.count) return axis.total;
1103
- const insertion = lowerBoundOverrideIndex(axis, index);
1104
- const delta = insertion > 0 ? axis.overrides[insertion - 1].cumulativeDelta : 0;
1105
- return index * axis.defaultSize + delta;
1106
- }
1107
- function axisSizeAt(axis, index) {
1108
- const candidate = axis.overrides[lowerBoundOverrideIndex(axis, index)];
1109
- return candidate?.index === index ? candidate.size : axis.defaultSize;
1110
- }
1111
- function upperBoundOverrideStart(axis, offset) {
1112
- let low = 0;
1113
- let high = axis.overrides.length;
1114
- while (low < high) {
1115
- const middle = low + high >>> 1;
1116
- if (axis.overrides[middle].start <= offset) low = middle + 1;
1117
- else high = middle;
1118
- }
1119
- return low;
1120
- }
1121
- function indexAtOffset(axis, offset) {
1122
- if (axis.count <= 1) return 0;
1123
- const target = Math.max(0, Math.min(axis.total - 1, offset));
1124
- const previousIndex = upperBoundOverrideStart(axis, target) - 1;
1125
- if (previousIndex < 0) {
1126
- return Math.min(
1127
- (axis.overrides[0]?.index ?? axis.count) - 1,
1128
- Math.floor(target / axis.defaultSize)
1129
- );
1130
- }
1131
- const previous = axis.overrides[previousIndex];
1132
- if (target < previous.end) return previous.index;
1133
- const nextOverrideIndex = axis.overrides[previousIndex + 1]?.index ?? axis.count;
1134
- return Math.min(
1135
- axis.count - 1,
1136
- nextOverrideIndex - 1,
1137
- previous.index + 1 + Math.floor((target - previous.end) / axis.defaultSize)
1138
- );
1139
- }
1140
- function visibleInterval(axis, startOffset, viewportSize, overscan) {
1141
- const start = Math.max(0, indexAtOffset(axis, startOffset) - overscan);
1142
- const end = Math.min(
1143
- axis.count,
1144
- indexAtOffset(axis, startOffset + Math.max(1, viewportSize)) + overscan + 1
1145
- );
1146
- return { start, end };
1147
- }
1148
- function boundVisibleWindows(rows, columns, focus) {
1149
- let rowCount = Math.min(MAX_MOUNTED_AXIS_ITEMS, rows.end - rows.start);
1150
- let columnCount = Math.min(MAX_MOUNTED_AXIS_ITEMS, columns.end - columns.start);
1151
- if (rowCount * columnCount > MAX_MOUNTED_GRID_CELLS) {
1152
- const balancedLimit = Math.floor(Math.sqrt(MAX_MOUNTED_GRID_CELLS));
1153
- if (rowCount > balancedLimit && columnCount > balancedLimit) {
1154
- rowCount = balancedLimit;
1155
- columnCount = balancedLimit;
1156
- } else if (rowCount >= columnCount) {
1157
- rowCount = Math.max(1, Math.floor(MAX_MOUNTED_GRID_CELLS / columnCount));
1158
- } else {
1159
- columnCount = Math.max(1, Math.floor(MAX_MOUNTED_GRID_CELLS / rowCount));
1160
- }
1161
- }
1162
- return {
1163
- rows: centeredInterval(rows, rowCount, focus.row),
1164
- columns: centeredInterval(columns, columnCount, focus.col)
1165
- };
1166
- }
1167
- function centeredInterval(interval, count, focus) {
1168
- if (count >= interval.end - interval.start) return interval;
1169
- if (focus < interval.start || focus >= interval.end) {
1170
- return { start: interval.start, end: interval.start + count };
1171
- }
1172
- const start = Math.max(
1173
- interval.start,
1174
- Math.min(interval.end - count, focus - Math.floor(count / 2))
1175
- );
1176
- return { start, end: start + count };
1177
- }
1178
- function indexesBetween(start, end) {
1179
- return Array.from({ length: end - start }, (_, index) => start + index);
1180
- }
1181
- function rawBoundaryAt(projection, index) {
1182
- if (index <= 0) return 0;
1183
- if (index >= projection.axis.count) {
1184
- return projection.axis.count * projection.baseItemSpan + projection.proportionalSpan;
1185
- }
1186
- return index * projection.baseItemSpan + axisOffsetAt(projection.axis, index) / projection.axis.total * projection.proportionalSpan;
1187
- }
1188
- function rawOffsetAtLogical(projection, offset) {
1189
- if (offset <= 0) return 0;
1190
- if (offset >= projection.axis.total) {
1191
- return rawBoundaryAt(projection, projection.axis.count);
1192
- }
1193
- const index = indexAtOffset(projection.axis, offset);
1194
- const logicalStart = axisOffsetAt(projection.axis, index);
1195
- const logicalSize = axisSizeAt(projection.axis, index);
1196
- const fraction = Math.max(0, Math.min(1, (offset - logicalStart) / logicalSize));
1197
- const rawStart = rawBoundaryAt(projection, index);
1198
- const rawEnd = rawBoundaryAt(projection, index + 1);
1199
- return rawStart + fraction * (rawEnd - rawStart);
1200
- }
1201
- function logicalOffsetAtRaw(projection, rawOffset) {
1202
- const target = Math.max(0, Math.min(projection.rawMax, rawOffset));
1203
- let low = 0;
1204
- let high = projection.axis.count;
1205
- while (low < high) {
1206
- const middle = Math.ceil((low + high) / 2);
1207
- if (rawBoundaryAt(projection, middle) <= target) low = middle;
1208
- else high = middle - 1;
1209
- }
1210
- const index = Math.min(projection.axis.count - 1, low);
1211
- const rawStart = rawBoundaryAt(projection, index);
1212
- const rawEnd = rawBoundaryAt(projection, index + 1);
1213
- const fraction = rawEnd === rawStart ? 0 : (target - rawStart) / (rawEnd - rawStart);
1214
- return Math.min(
1215
- projection.logicalMax,
1216
- axisOffsetAt(projection.axis, index) + fraction * axisSizeAt(projection.axis, index)
1217
- );
1218
- }
1219
- function buildScrollProjection(axis, headerSize, viewportSize) {
1220
- const logicalTotal = headerSize + axis.total;
1221
- const physicalTotal = Math.min(logicalTotal, MAX_PHYSICAL_SCROLL_SPAN);
1222
- const logicalMax = Math.max(0, logicalTotal - viewportSize);
1223
- const physicalMax = Math.max(0, physicalTotal - viewportSize);
1224
- const mode = physicalTotal === logicalTotal ? "identity" : "indexed";
1225
- const physicalAxisCapacity = Math.max(0, physicalTotal - headerSize);
1226
- const baseItemSpan = mode === "indexed" ? Math.min(MIN_PHYSICAL_ITEM_SPAN, physicalAxisCapacity / axis.count) : 0;
1227
- const projection = {
1228
- axis,
1229
- mode,
1230
- physicalTotal,
1231
- logicalMax,
1232
- physicalMax,
1233
- baseItemSpan,
1234
- proportionalSpan: Math.max(0, physicalAxisCapacity - baseItemSpan * axis.count),
1235
- rawMax: 0
1236
- };
1237
- projection.rawMax = rawOffsetAtLogical(projection, logicalMax);
1238
- return projection;
1239
- }
1240
- function clampPhysicalScroll(offset, projection) {
1241
- return Math.max(0, Math.min(projection.physicalMax, offset));
1242
- }
1243
- function physicalToLogicalScroll(offset, projection) {
1244
- if (projection.logicalMax === 0 || projection.physicalMax === 0) return 0;
1245
- if (projection.mode === "indexed") {
1246
- return logicalOffsetAtRaw(
1247
- projection,
1248
- clampPhysicalScroll(offset, projection) / projection.physicalMax * projection.rawMax
1249
- );
1250
- }
1251
- return clampPhysicalScroll(offset, projection) / projection.physicalMax * projection.logicalMax;
1252
- }
1253
- function logicalToPhysicalScroll(offset, projection) {
1254
- if (projection.logicalMax === 0 || projection.physicalMax === 0) return 0;
1255
- const logical = Math.max(0, Math.min(projection.logicalMax, offset));
1256
- if (projection.mode === "indexed") {
1257
- return rawOffsetAtLogical(projection, logical) / projection.rawMax * projection.physicalMax;
1258
- }
1259
- return logical / projection.logicalMax * projection.physicalMax;
1260
- }
1261
- function columnName2(index) {
1262
- let value = index + 1;
1263
- let result = "";
1264
- while (value > 0) {
1265
- const remainder = (value - 1) % 26;
1266
- result = String.fromCharCode(65 + remainder) + result;
1267
- value = Math.floor((value - 1) / 26);
1268
- }
1269
- return result;
1270
- }
1271
- function cellName(cell) {
1272
- return `${columnName2(cell.col)}${cell.row + 1}`;
1273
- }
1274
- function normalizeSelection(selection) {
1275
- return {
1276
- top: Math.min(selection.anchor.row, selection.focus.row),
1277
- bottom: Math.max(selection.anchor.row, selection.focus.row),
1278
- left: Math.min(selection.anchor.col, selection.focus.col),
1279
- right: Math.max(selection.anchor.col, selection.focus.col)
1280
- };
1281
- }
1282
- function selectionName(selection) {
1283
- const normalized = normalizeSelection(selection);
1284
- const first = cellName({ row: normalized.top, col: normalized.left });
1285
- const last = cellName({ row: normalized.bottom, col: normalized.right });
1286
- return first === last ? first : `${first}:${last}`;
1287
- }
1288
- function isCellSelected(selection, row, col) {
1289
- const normalized = normalizeSelection(selection);
1290
- return row >= normalized.top && row <= normalized.bottom && col >= normalized.left && col <= normalized.right;
1291
- }
1292
- function parseCellInput(input) {
1293
- if (input === "") return null;
1294
- const normalized = input.trim();
1295
- if (/^(?:true|false)$/i.test(normalized)) return normalized.toLowerCase() === "true";
1296
- if (/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i.test(normalized)) {
1297
- const number = Number(normalized);
1298
- if (Number.isFinite(number)) return number;
1299
- }
1300
- return input;
1301
- }
1302
- function parseSpreadsheetClipboard(t, input) {
1303
- if (new TextEncoder().encode(input).byteLength > MAX_CLIPBOARD_INPUT_BYTES) {
1304
- throw new Error(t("artifacts.spreadsheetGrid.clipboardDataIsTooLarge"));
1305
- }
1306
- const records = [[]];
1307
- let field = "";
1308
- let quoted = false;
1309
- let endedWithRecordSeparator = false;
1310
- for (let index = 0; index < input.length; index += 1) {
1311
- const character = input[index];
1312
- if (quoted) {
1313
- if (character === '"') {
1314
- if (input[index + 1] === '"') {
1315
- field += '"';
1316
- index += 1;
1317
- } else {
1318
- quoted = false;
1319
- }
1320
- } else {
1321
- field += character;
1322
- }
1323
- endedWithRecordSeparator = false;
1324
- continue;
1325
- }
1326
- if (character === '"' && field.length === 0) {
1327
- quoted = true;
1328
- endedWithRecordSeparator = false;
1329
- } else if (character === " ") {
1330
- records.at(-1).push(field);
1331
- field = "";
1332
- endedWithRecordSeparator = false;
1333
- } else if (character === "\r" || character === "\n") {
1334
- records.at(-1).push(field);
1335
- field = "";
1336
- records.push([]);
1337
- if (character === "\r" && input[index + 1] === "\n") index += 1;
1338
- endedWithRecordSeparator = true;
1339
- } else {
1340
- field += character;
1341
- endedWithRecordSeparator = false;
1342
- }
1343
- }
1344
- if (quoted) throw new Error(t("artifacts.spreadsheetGrid.clipboardDataContainsAnUnterminated"));
1345
- if (endedWithRecordSeparator) records.pop();
1346
- else records.at(-1).push(field);
1347
- if (records.length === 0) records.push([""]);
1348
- const columns = Math.max(1, ...records.map((record) => record.length));
1349
- const cellCount = records.length * columns;
1350
- if (cellCount > MAX_CLIPBOARD_CELLS) {
1351
- throw new Error(t("artifacts.spreadsheetGrid.clipboardRangeIsTooLarge"));
1352
- }
1353
- const inputs = records.flatMap((record) => [
1354
- ...record,
1355
- ...Array.from({ length: columns - record.length }, () => "")
1356
- ]);
1357
- return Object.freeze({ rows: records.length, columns, inputs: Object.freeze(inputs) });
1358
- }
1359
- function escapeSpreadsheetClipboardField(input) {
1360
- return /["\t\r\n]/u.test(input) ? `"${input.replaceAll('"', '""')}"` : input;
1361
- }
1362
- function cellStyle(format) {
1363
- return {
1364
- background: format.fill,
1365
- color: format.font?.color,
1366
- fontFamily: format.font?.name,
1367
- fontSize: format.font?.size,
1368
- fontWeight: format.font?.bold ? 600 : void 0,
1369
- fontStyle: format.font?.italic ? "italic" : void 0,
1370
- textDecoration: format.font?.underline ? "underline" : void 0,
1371
- textAlign: format.horizontalAlignment,
1372
- justifyContent: format.horizontalAlignment === "center" ? "center" : format.horizontalAlignment === "right" ? "flex-end" : "flex-start",
1373
- alignItems: format.verticalAlignment === "top" ? "flex-start" : format.verticalAlignment === "bottom" ? "flex-end" : "center",
1374
- whiteSpace: format.wrapText ? "normal" : "nowrap"
1375
- };
1376
- }
1377
- function canvasAxis(axis) {
1378
- return {
1379
- count: axis.count,
1380
- total: axis.total,
1381
- offsetAt: (index) => axisOffsetAt(axis, index),
1382
- sizeAt: (index) => axisSizeAt(axis, index),
1383
- indexAtOffset: (offset) => indexAtOffset(axis, offset)
1384
- };
1385
- }
1386
- function computedToken(style, name, fallback) {
1387
- return style.getPropertyValue(name).trim() || fallback;
1388
- }
1389
- function computedPixels(style, name, fallback) {
1390
- const value = Number.parseFloat(style.getPropertyValue(name));
1391
- return Number.isFinite(value) && value > 0 ? value : fallback;
1392
- }
1393
- function spreadsheetCanvasTheme(element) {
1394
- const style = getComputedStyle(element);
1395
- const background = style.backgroundColor || computedToken(style, "--og-color-surface-1", "#ffffff");
1396
- const headerBackground = computedToken(style, "--og-color-surface-2", "#f3f4f6");
1397
- const border = computedToken(style, "--og-color-border", "#d1d5db");
1398
- const foreground = style.color || computedToken(style, "--og-color-fg", "#111827");
1399
- const mutedForeground = computedToken(style, "--og-color-fg-muted", "#6b7280");
1400
- const accent = computedToken(style, "--og-color-accent", "#545454");
1401
- const error = computedToken(style, "--og-color-status-failed", "#dc2626");
1402
- const fontFamily = style.fontFamily || computedToken(
1403
- style,
1404
- "--og-font-sans",
1405
- 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'
1406
- );
1407
- const fontSize = Number.parseFloat(style.fontSize) || computedPixels(style, "--og-font-size-sm", 12);
1408
- const headerFontSize = computedPixels(style, "--og-font-size-xs", 11);
1409
- return {
1410
- background,
1411
- headerBackground,
1412
- border,
1413
- foreground,
1414
- mutedForeground,
1415
- accent,
1416
- error,
1417
- fontFamily,
1418
- fontSize,
1419
- headerFontSize,
1420
- signature: [
1421
- background,
1422
- headerBackground,
1423
- border,
1424
- foreground,
1425
- mutedForeground,
1426
- accent,
1427
- error,
1428
- fontFamily,
1429
- fontSize,
1430
- headerFontSize
1431
- ].join("")
1432
- };
1433
- }
1434
- function useWorkbookViewState(workbook) {
1435
- const [view, setView] = useState3(() => ({
1436
- revision: workbook.revision,
1437
- dimensionRevision: 0
1438
- }));
1439
- useEffect3(() => {
1440
- setView(
1441
- (current) => current.revision === workbook.revision ? current : { revision: workbook.revision, dimensionRevision: current.dimensionRevision + 1 }
1442
- );
1443
- return workbook.onChange((change) => {
1444
- setView((current) => ({
1445
- revision: change.revision,
1446
- dimensionRevision: change.reason === "dimension" || change.reason === "structure" ? current.dimensionRevision + 1 : current.dimensionRevision
1447
- }));
1448
- });
1449
- }, [workbook]);
1450
- return view;
1451
- }
1452
- function nextAvailableSheetName(t, workbook) {
1453
- let index = workbook.worksheets.items.length + 1;
1454
- while (workbook.worksheets.items.some((sheet) => sheet.name === `Sheet${index}`)) index += 1;
1455
- return t("artifacts.spreadsheetGrid.sheetIndex", { index });
1456
- }
1457
- function SpreadsheetArtifactSurface({
1458
- workbook,
1459
- title: titleProp,
1460
- subtitle,
1461
- actions,
1462
- initialSheetId,
1463
- allowAddSheet = true,
1464
- readOnly = false,
1465
- ...gridProps
1466
- }) {
1467
- const t = useOpenGeniText();
1468
- const title = titleProp === void 0 ? t("artifacts.spreadsheetGrid.workbook") : titleProp;
1469
- const { revision } = useWorkbookViewState(workbook);
1470
- const availableSheets = workbook.worksheets.items;
1471
- const initial = (initialSheetId ? availableSheets.find((sheet) => sheet.id === initialSheetId) : void 0) ?? (() => {
1472
- try {
1473
- return workbook.worksheets.getActiveWorksheet();
1474
- } catch {
1475
- return availableSheets[0];
1476
- }
1477
- })();
1478
- const [activeSheetId, setActiveSheetId] = useState3(initial?.id ?? null);
1479
- const activeSheet = availableSheets.find((sheet) => sheet.id === activeSheetId) ?? availableSheets[0] ?? null;
1480
- useEffect3(() => {
1481
- if (!activeSheet && activeSheetId !== null) setActiveSheetId(null);
1482
- else if (activeSheet && activeSheet.id !== activeSheetId) setActiveSheetId(activeSheet.id);
1483
- }, [activeSheet, activeSheetId, revision]);
1484
- const selectSheet = useCallback3(
1485
- (sheet) => {
1486
- workbook.worksheets.setActiveWorksheet(sheet);
1487
- setActiveSheetId(sheet.id);
1488
- },
1489
- [workbook]
1490
- );
1491
- const addSheet = useCallback3(() => {
1492
- const sheet = workbook.worksheets.add(nextAvailableSheetName(t, workbook));
1493
- selectSheet(sheet);
1494
- }, [selectSheet, workbook, t]);
1495
- const footer = /* @__PURE__ */ jsxs(
1496
- "div",
1497
- {
1498
- className: "flex min-h-9 items-center gap-1 overflow-x-auto px-2",
1499
- role: "tablist",
1500
- "aria-label": t("artifacts.spreadsheetGrid.worksheets"),
1501
- children: [
1502
- availableSheets.map((sheet) => /* @__PURE__ */ jsx2(
1503
- "button",
1504
- {
1505
- type: "button",
1506
- role: "tab",
1507
- "aria-selected": sheet.id === activeSheet?.id,
1508
- onClick: () => selectSheet(sheet),
1509
- className: cn(
1510
- "h-7 shrink-0 rounded-og-sm px-2.5 text-og-sm transition-colors",
1511
- sheet.id === activeSheet?.id ? "bg-og-surface-3 font-medium text-og-fg" : "text-og-fg-muted hover:bg-og-surface-3 hover:text-og-fg"
1512
- ),
1513
- children: sheet.name
1514
- },
1515
- sheet.id
1516
- )),
1517
- !readOnly && allowAddSheet ? /* @__PURE__ */ jsx2(
1518
- "button",
1519
- {
1520
- type: "button",
1521
- onClick: addSheet,
1522
- "aria-label": t("artifacts.spreadsheetGrid.addWorksheet"),
1523
- className: "grid size-7 shrink-0 place-items-center rounded-og-sm text-og-fg-muted hover:bg-og-surface-3 hover:text-og-fg [&>svg]:size-3.5",
1524
- children: /* @__PURE__ */ jsx2(PlusIcon, {})
1525
- }
1526
- ) : null
1527
- ]
1528
- }
1529
- );
1530
- return /* @__PURE__ */ jsx2(
1531
- ArtifactSurface,
1532
- {
1533
- modality: "spreadsheet",
1534
- title,
1535
- subtitle: subtitle ?? (activeSheet ? t("counts.sheets", { count: availableSheets.length }) : t("artifacts.spreadsheetGrid.emptyWorkbook")),
1536
- actions,
1537
- footer,
1538
- children: activeSheet ? /* @__PURE__ */ jsx2(
1539
- SpreadsheetGrid,
1540
- {
1541
- ...gridProps,
1542
- workbook,
1543
- worksheet: activeSheet,
1544
- readOnly
1545
- },
1546
- activeSheet.id
1547
- ) : /* @__PURE__ */ jsx2(
1548
- "div",
1549
- {
1550
- className: "grid h-full place-items-center bg-og-bg p-6 text-center",
1551
- style: { minHeight: 224 },
1552
- children: /* @__PURE__ */ jsxs("div", { children: [
1553
- /* @__PURE__ */ jsx2("p", { className: "text-og-base font-medium text-og-fg", children: t("artifacts.spreadsheetGrid.thisWorkbookHasNoWorksheets") }),
1554
- !readOnly && allowAddSheet ? /* @__PURE__ */ jsx2(
1555
- "button",
1556
- {
1557
- type: "button",
1558
- onClick: addSheet,
1559
- className: "mt-3 rounded-og-sm border border-og-primary-border bg-og-primary text-og-primary-fg px-3 py-1.5 text-og-sm font-medium hover:bg-og-primary-hover",
1560
- children: t("artifacts.spreadsheetGrid.addWorksheet")
1561
- }
1562
- ) : null
1563
- ] })
1564
- }
1565
- )
1566
- }
1567
- );
1568
- }
1569
- function SpreadsheetGrid({
1570
- workbook,
1571
- worksheet,
1572
- readOnly = false,
1573
- rowCount: requestedRowCount,
1574
- columnCount: requestedColumnCount,
1575
- overscanRows = 3,
1576
- overscanColumns = 2,
1577
- onSelectionChange,
1578
- onCommit,
1579
- onResize,
1580
- onViewportChange,
1581
- className
1582
- }) {
1583
- const { revision, dimensionRevision } = useWorkbookViewState(workbook);
1584
- const boundedProjection = requestedRowCount !== void 0 || requestedColumnCount !== void 0;
1585
- const usedRange = useMemo2(() => {
1586
- void revision;
1587
- return boundedProjection ? worksheet.usedRangeAddress() : null;
1588
- }, [boundedProjection, revision, worksheet]);
1589
- const rowCount = boundedInteger(
1590
- Math.max(
1591
- requestedRowCount ?? MAX_ROWS,
1592
- (usedRange?.row ?? 0) + (usedRange?.rowCount ?? 0) + 32
1593
- ),
1594
- MAX_ROWS,
1595
- MAX_ROWS
1596
- );
1597
- const columnCount = boundedInteger(
1598
- Math.max(
1599
- requestedColumnCount ?? MAX_COLUMNS,
1600
- (usedRange?.col ?? 0) + (usedRange?.colCount ?? 0) + 8
1601
- ),
1602
- MAX_COLUMNS,
1603
- MAX_COLUMNS
1604
- );
1605
- const rowHeights = useMemo2(() => {
1606
- void dimensionRevision;
1607
- return [...worksheet.rowHeightEntries()];
1608
- }, [dimensionRevision, worksheet]);
1609
- const columnWidths = useMemo2(() => {
1610
- void dimensionRevision;
1611
- return [...worksheet.columnWidthEntries()];
1612
- }, [dimensionRevision, worksheet]);
1613
- const projection = useMemo2(() => {
1614
- void dimensionRevision;
1615
- const cells = new SparseSpreadsheetCellIndex(
1616
- function* projectedCells() {
1617
- for (const { row, col, data } of worksheet.cellEntries()) {
1618
- yield {
1619
- row,
1620
- col,
1621
- value: data.value,
1622
- formula: data.formula,
1623
- format: data.format
1624
- };
1625
- }
1626
- }()
1627
- );
1628
- return {
1629
- sheetId: worksheet.id,
1630
- sheetName: worksheet.name,
1631
- generationId: worksheet.id,
1632
- revision,
1633
- dimensionRevision,
1634
- rowCount,
1635
- columnCount,
1636
- defaultRowHeight: worksheet.defaultRowHeight,
1637
- defaultColumnWidth: worksheet.defaultColumnWidth,
1638
- rowHeights,
1639
- columnWidths,
1640
- usedRange,
1641
- cells,
1642
- valueAt: (cell) => cell.formula ? workbook.valueAt(worksheet, { row: cell.row, col: cell.col }) : cell.value,
1643
- readCell: (row, col) => {
1644
- const data = worksheet.cellData(row, col);
1645
- return {
1646
- value: data.formula ? workbook.valueAt(worksheet, { row, col }) : data.value,
1647
- input: data.formula ?? spreadsheetCellEditSource(data.value),
1648
- format: data.format
1649
- };
1650
- }
1651
- };
1652
- }, [
1653
- columnCount,
1654
- columnWidths,
1655
- dimensionRevision,
1656
- revision,
1657
- rowCount,
1658
- rowHeights,
1659
- usedRange,
1660
- workbook,
1661
- worksheet
1662
- ]);
1663
- const commit = useCallback3(
1664
- (next) => {
1665
- const target = worksheet.getCell(next.cell.row, next.cell.col);
1666
- if (next.kind === "formula") target.formulas = [[next.input]];
1667
- else target.values = [[parseCellInput(next.input)]];
1668
- onCommit?.(next);
1669
- },
1670
- [onCommit, worksheet]
1671
- );
1672
- const commitRange = useCallback3(
1673
- (next) => {
1674
- if (next.rows * next.columns !== next.inputs.length) {
1675
- throw new Error("Spreadsheet paste shape is invalid");
1676
- }
1677
- workbook.transact(() => {
1678
- for (let index = 0; index < next.inputs.length; index += 1) {
1679
- const input = next.inputs[index];
1680
- const row = next.anchor.row + Math.floor(index / next.columns);
1681
- const col = next.anchor.col + index % next.columns;
1682
- worksheet.setCell(
1683
- row,
1684
- col,
1685
- input.startsWith("=") ? { formula: input, value: null } : { formula: null, value: parseCellInput(input) },
1686
- "content"
1687
- );
1688
- }
1689
- });
1690
- },
1691
- [workbook, worksheet]
1692
- );
1693
- const clear = useCallback3(
1694
- (next) => {
1695
- const normalized = normalizeSelection(next);
1696
- worksheet.getRangeByIndexes(
1697
- normalized.top,
1698
- normalized.left,
1699
- normalized.bottom - normalized.top + 1,
1700
- normalized.right - normalized.left + 1
1701
- ).clear({ applyTo: "contents" });
1702
- },
1703
- [worksheet]
1704
- );
1705
- const resize = useCallback3(
1706
- (change) => {
1707
- if (change.axis === "column") worksheet.setColumnWidth(change.index, change.size);
1708
- else worksheet.setRowHeight(change.index, change.size);
1709
- onResize?.(change);
1710
- },
1711
- [onResize, worksheet]
1712
- );
1713
- return /* @__PURE__ */ jsx2(
1714
- SpreadsheetProjectionGrid,
1715
- {
1716
- projection,
1717
- readOnly,
1718
- overscanRows,
1719
- overscanColumns,
1720
- onSelectionChange,
1721
- commit,
1722
- commitRange,
1723
- clear,
1724
- resize,
1725
- onViewportChange,
1726
- className
1727
- }
1728
- );
1729
- }
1730
- function SpreadsheetProjectionGrid({
1731
- projection,
1732
- readOnly = false,
1733
- overscanRows = 3,
1734
- overscanColumns = 2,
1735
- onSelectionChange,
1736
- commit,
1737
- commitRange,
1738
- clear,
1739
- resize,
1740
- pendingTransactions = 0,
1741
- syncStatus,
1742
- syncError,
1743
- onCommandError,
1744
- onViewportChange,
1745
- className
1746
- }) {
1747
- const t = useOpenGeniText();
1748
- const { revision, rowCount, columnCount } = projection;
1749
- const editable = !readOnly && commit !== void 0;
1750
- const commandQueue = useSpreadsheetCommandQueue({
1751
- scopeKey: `${projection.sheetId}:${projection.generationId ?? "none"}`,
1752
- enabled: editable,
1753
- onCommandError
1754
- });
1755
- const [commandFailure, setCommandFailure] = useState3(null);
1756
- const clearPreflightFailure = commandQueue.clearPreflightFailure;
1757
- const clearCommandFailure = useCallback3(() => {
1758
- setCommandFailure(null);
1759
- clearPreflightFailure();
1760
- }, [clearPreflightFailure]);
1761
- const resizing = useSpreadsheetResizing({
1762
- sheetId: projection.sheetId,
1763
- generationId: projection.generationId,
1764
- revision: projection.dimensionRevision ?? revision,
1765
- rowHeights: projection.rowHeights ?? EMPTY_DIMENSIONS,
1766
- columnWidths: projection.columnWidths ?? EMPTY_DIMENSIONS,
1767
- defaultRowHeight: projection.defaultRowHeight ?? 24,
1768
- defaultColumnWidth: projection.defaultColumnWidth ?? 96,
1769
- enabled: !readOnly && resize !== void 0,
1770
- commit: resize,
1771
- onCommandError,
1772
- onStart: clearCommandFailure
1773
- });
1774
- const dimensionRevision = `${projection.dimensionRevision ?? 0}:${resizing.previewKey}`;
1775
- const rows = useMemo2(() => {
1776
- return buildAxis(rowCount, projection.defaultRowHeight ?? 24, resizing.rowHeights);
1777
- }, [projection.defaultRowHeight, resizing.rowHeights, rowCount]);
1778
- const columns = useMemo2(() => {
1779
- return buildAxis(columnCount, projection.defaultColumnWidth ?? 96, resizing.columnWidths);
1780
- }, [columnCount, resizing.columnWidths, projection.defaultColumnWidth]);
1781
- const canvasRows = useMemo2(() => canvasAxis(rows), [rows]);
1782
- const canvasColumns = useMemo2(() => canvasAxis(columns), [columns]);
1783
- const [selection, setSelection] = useState3(() => ({
1784
- sheetId: projection.sheetId,
1785
- anchor: { row: 0, col: 0 },
1786
- focus: { row: 0, col: 0 }
1787
- }));
1788
- const [editMode, setEditMode] = useState3(null);
1789
- const [draft, setDraft] = useState3(
1790
- () => projection.readCell(selection.focus.row, selection.focus.col)?.input ?? ""
1791
- );
1792
- const visibleCommandFailure = resizing.error ?? commandQueue.error ?? commandFailure ?? (syncError ? { message: syncError, retry: void 0 } : null);
1793
- const pendingCommandCount = commandQueue.pendingCount + resizing.pendingCount + pendingTransactions;
1794
- const visibleSyncStatus = pendingCommandCount > 0 && (!syncStatus || syncStatus === t("artifacts.editableSpreadsheet.saved") || syncStatus === t("artifacts.editableSpreadsheet.readOnly")) ? t("artifacts.spreadsheetGrid.saving") : syncStatus;
1795
- const runQueuedCommand = commandQueue.run;
1796
- const [viewport, setViewport] = useState3({
1797
- width: FALLBACK_VIEWPORT_WIDTH,
1798
- height: FALLBACK_VIEWPORT_HEIGHT,
1799
- scrollLeft: 0,
1800
- scrollTop: 0,
1801
- devicePixelRatio: 1
1802
- });
1803
- const [canvasReady, setCanvasReady] = useState3(false);
1804
- const [canvasEpoch, setCanvasEpoch] = useState3(0);
1805
- const viewportRef = useRef3(null);
1806
- const canvasRef = useRef3(null);
1807
- const editorRef = useRef3(null);
1808
- const selectionRef = useRef3(selection);
1809
- const selectingRef = useRef3(null);
1810
- const committingRef = useRef3(false);
1811
- const composingRef = useRef3(false);
1812
- const commitAfterCompositionRef = useRef3(false);
1813
- const selectDraftOnFocusRef = useRef3(true);
1814
- const initialDraftRef = useRef3(draft);
1815
- const optimisticInputsRef = useRef3(
1816
- /* @__PURE__ */ new Map()
1817
- );
1818
- const [optimisticEpoch, setOptimisticEpoch] = useState3(0);
1819
- const refreshOptimisticInputs = useCallback3(() => setOptimisticEpoch((value) => value + 1), []);
1820
- const optimisticScope = `${projection.sheetId}:${projection.generationId ?? "none"}`;
1821
- const optimisticScopeRef = useRef3(optimisticScope);
1822
- if (optimisticScopeRef.current !== optimisticScope) {
1823
- optimisticScopeRef.current = optimisticScope;
1824
- optimisticInputsRef.current.clear();
1825
- }
1826
- const projectionRef = useRef3(projection);
1827
- projectionRef.current = projection;
1828
- const editModeRef = useRef3(editMode);
1829
- editModeRef.current = editMode;
1830
- const canvasRendererRef = useRef3(null);
1831
- if (!canvasRendererRef.current) canvasRendererRef.current = new SpreadsheetCanvasRenderer();
1832
- const reactId = useId().replaceAll(":", "");
1833
- const readEditInput = useCallback3(
1834
- (cell) => optimisticInputsRef.current.get(`${cell.row}:${cell.col}`)?.input ?? projectionRef.current.readCell(cell.row, cell.col)?.input ?? "",
1835
- []
1836
- );
1837
- const forgetOptimisticInputs = useCallback3(
1838
- (target) => {
1839
- let changed = false;
1840
- for (const [key, entry] of optimisticInputsRef.current) {
1841
- if (entry.row >= target.top && entry.row <= target.bottom && entry.col >= target.left && entry.col <= target.right) {
1842
- optimisticInputsRef.current.delete(key);
1843
- changed = true;
1844
- }
1845
- }
1846
- if (changed) refreshOptimisticInputs();
1847
- },
1848
- [refreshOptimisticInputs]
1849
- );
1850
- const updateSelection = useCallback3(
1851
- (next) => {
1852
- selectionRef.current = next;
1853
- setSelection(next);
1854
- onSelectionChange?.(next);
1855
- },
1856
- [onSelectionChange]
1857
- );
1858
- useEffect3(() => {
1859
- if (selection.sheetId === projection.sheetId) return;
1860
- const next = {
1861
- sheetId: projection.sheetId,
1862
- anchor: { row: 0, col: 0 },
1863
- focus: { row: 0, col: 0 }
1864
- };
1865
- optimisticInputsRef.current.clear();
1866
- setCommandFailure(null);
1867
- setEditMode(null);
1868
- updateSelection(next);
1869
- }, [projection.sheetId, selection.sheetId, updateSelection]);
1870
- useEffect3(() => {
1871
- optimisticInputsRef.current.clear();
1872
- refreshOptimisticInputs();
1873
- }, [projection.generationId, projection.sheetId, refreshOptimisticInputs]);
1874
- useClientLayoutEffect(() => {
1875
- let changed = false;
1876
- for (const [key, optimistic] of optimisticInputsRef.current) {
1877
- const coverage = projection.coverage;
1878
- const covered = !coverage || optimistic.row >= coverage.rowStart && optimistic.row < coverage.rowEnd && optimistic.col >= coverage.columnStart && optimistic.col < coverage.columnEnd;
1879
- if (!optimistic.pending && covered && (projection.readCell(optimistic.row, optimistic.col)?.input === optimistic.input || revision !== optimistic.baseRevision)) {
1880
- optimisticInputsRef.current.delete(key);
1881
- changed = true;
1882
- }
1883
- }
1884
- if (changed) refreshOptimisticInputs();
1885
- if (editMode === null) setDraft(readEditInput(selection.focus));
1886
- }, [
1887
- commandQueue.pendingCount,
1888
- editMode,
1889
- projection,
1890
- readEditInput,
1891
- revision,
1892
- selection.focus,
1893
- refreshOptimisticInputs,
1894
- optimisticEpoch
1895
- ]);
1896
- useClientLayoutEffect(() => {
1897
- const element = viewportRef.current;
1898
- if (!element) return;
1899
- const measure = () => {
1900
- setViewport((current) => ({
1901
- ...current,
1902
- width: element.clientWidth || FALLBACK_VIEWPORT_WIDTH,
1903
- height: element.clientHeight || FALLBACK_VIEWPORT_HEIGHT,
1904
- devicePixelRatio: spreadsheetCanvasDevicePixelRatio(globalThis.devicePixelRatio || 1)
1905
- }));
1906
- };
1907
- measure();
1908
- const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(measure);
1909
- observer?.observe(element);
1910
- globalThis.addEventListener?.("resize", measure);
1911
- return () => {
1912
- observer?.disconnect();
1913
- globalThis.removeEventListener?.("resize", measure);
1914
- };
1915
- }, []);
1916
- useEffect3(() => {
1917
- return () => canvasRendererRef.current?.dispose();
1918
- }, []);
1919
- useEffect3(() => {
1920
- if (typeof document === "undefined") return;
1921
- let active = true;
1922
- void document.fonts?.ready.then(() => {
1923
- if (active) {
1924
- canvasRendererRef.current?.dispose();
1925
- setCanvasEpoch((value) => value + 1);
1926
- }
1927
- });
1928
- if (typeof MutationObserver === "undefined") {
1929
- return () => {
1930
- active = false;
1931
- };
1932
- }
1933
- const observer = new MutationObserver(() => setCanvasEpoch((value) => value + 1));
1934
- let ancestor = viewportRef.current;
1935
- while (ancestor) {
1936
- observer.observe(ancestor, {
1937
- attributes: true,
1938
- attributeFilter: ["class", "style", "data-og-theme", "data-og-density"]
1939
- });
1940
- ancestor = ancestor.parentElement;
1941
- }
1942
- return () => {
1943
- active = false;
1944
- observer.disconnect();
1945
- };
1946
- }, []);
1947
- useEffect3(() => {
1948
- if (editMode !== "cell") return;
1949
- const editor = editorRef.current;
1950
- editor?.focus();
1951
- if (!editor) return;
1952
- if (selectDraftOnFocusRef.current) editor.select();
1953
- else editor.setSelectionRange(editor.value.length, editor.value.length);
1954
- }, [editMode]);
1955
- const ensureVisible = useCallback3(
1956
- (cell) => {
1957
- const element = viewportRef.current;
1958
- if (!element) return;
1959
- const viewportWidth = element.clientWidth || FALLBACK_VIEWPORT_WIDTH;
1960
- const viewportHeight = element.clientHeight || FALLBACK_VIEWPORT_HEIGHT;
1961
- const horizontalProjection2 = buildScrollProjection(columns, ROW_HEADER_WIDTH, viewportWidth);
1962
- const verticalProjection2 = buildScrollProjection(rows, COLUMN_HEADER_HEIGHT, viewportHeight);
1963
- const left = ROW_HEADER_WIDTH + axisOffsetAt(columns, cell.col);
1964
- const right = left + axisSizeAt(columns, cell.col);
1965
- const top = COLUMN_HEADER_HEIGHT + axisOffsetAt(rows, cell.row);
1966
- const bottom = top + axisSizeAt(rows, cell.row);
1967
- const logicalScrollLeft2 = physicalToLogicalScroll(element.scrollLeft, horizontalProjection2);
1968
- const logicalScrollTop2 = physicalToLogicalScroll(element.scrollTop, verticalProjection2);
1969
- const viewportLeft = logicalScrollLeft2 + ROW_HEADER_WIDTH;
1970
- const viewportRight = logicalScrollLeft2 + viewportWidth;
1971
- const viewportTop = logicalScrollTop2 + COLUMN_HEADER_HEIGHT;
1972
- const viewportBottom = logicalScrollTop2 + viewportHeight;
1973
- if (left < viewportLeft) {
1974
- element.scrollLeft = logicalToPhysicalScroll(
1975
- Math.max(0, left - ROW_HEADER_WIDTH),
1976
- horizontalProjection2
1977
- );
1978
- } else if (right > viewportRight) {
1979
- element.scrollLeft = logicalToPhysicalScroll(right - viewportWidth, horizontalProjection2);
1980
- }
1981
- if (top < viewportTop) {
1982
- element.scrollTop = logicalToPhysicalScroll(
1983
- Math.max(0, top - COLUMN_HEADER_HEIGHT),
1984
- verticalProjection2
1985
- );
1986
- } else if (bottom > viewportBottom) {
1987
- element.scrollTop = logicalToPhysicalScroll(bottom - viewportHeight, verticalProjection2);
1988
- }
1989
- },
1990
- [columns, rows]
1991
- );
1992
- const moveSelection = useCallback3(
1993
- (rowDelta, colDelta, extend) => {
1994
- const focus = {
1995
- row: Math.max(0, Math.min(rowCount - 1, selection.focus.row + rowDelta)),
1996
- col: Math.max(0, Math.min(columnCount - 1, selection.focus.col + colDelta))
1997
- };
1998
- const next = {
1999
- sheetId: projection.sheetId,
2000
- anchor: extend ? selection.anchor : focus,
2001
- focus
2002
- };
2003
- updateSelection(next);
2004
- ensureVisible(focus);
2005
- },
2006
- [columnCount, ensureVisible, projection.sheetId, rowCount, selection, updateSelection]
2007
- );
2008
- const runCommand = useCallback3(
2009
- (invoke, retry, rollback, target, accepted) => {
2010
- setCommandFailure(null);
2011
- runQueuedCommand(invoke, retry, rollback, target, accepted);
2012
- },
2013
- [runQueuedCommand]
2014
- );
2015
- const reportCommandFailure = useCallback3(
2016
- (cause) => {
2017
- const error = cause instanceof Error ? cause : new Error(String(cause));
2018
- setCommandFailure({
2019
- message: error.message || t("artifacts.spreadsheetGrid.spreadsheetActionFailed")
2020
- });
2021
- onCommandError?.(error);
2022
- },
2023
- [onCommandError, t]
2024
- );
2025
- const commitDraft = useCallback3(
2026
- (input = draft) => {
2027
- if (committingRef.current) return;
2028
- committingRef.current = true;
2029
- if (!editable || !commit) {
2030
- setEditMode(null);
2031
- queueMicrotask(() => {
2032
- committingRef.current = false;
2033
- });
2034
- return;
2035
- }
2036
- if (input === initialDraftRef.current) {
2037
- setEditMode(null);
2038
- viewportRef.current?.focus();
2039
- queueMicrotask(() => {
2040
- committingRef.current = false;
2041
- });
2042
- return;
2043
- }
2044
- const next = {
2045
- sheetId: projection.sheetId,
2046
- cell: { ...selection.focus },
2047
- input,
2048
- kind: input.startsWith("=") ? "formula" : "value"
2049
- };
2050
- const execute = () => {
2051
- const retryFocus = selectionRef.current.focus;
2052
- if (editModeRef.current === null && retryFocus.row === next.cell.row && retryFocus.col === next.cell.col) {
2053
- setDraft(input);
2054
- }
2055
- const key = `${next.cell.row}:${next.cell.col}`;
2056
- runCommand(
2057
- (commandId) => {
2058
- optimisticInputsRef.current.set(key, {
2059
- ...next.cell,
2060
- input,
2061
- baseRevision: revision,
2062
- commandId,
2063
- pending: true
2064
- });
2065
- refreshOptimisticInputs();
2066
- return commit(next);
2067
- },
2068
- execute,
2069
- (commandId) => {
2070
- if (optimisticInputsRef.current.get(key)?.commandId !== commandId) return;
2071
- optimisticInputsRef.current.delete(key);
2072
- refreshOptimisticInputs();
2073
- const current = selectionRef.current.focus;
2074
- if (editModeRef.current === null && current.row === next.cell.row && current.col === next.cell.col) {
2075
- setDraft(readEditInput(current));
2076
- }
2077
- },
2078
- { top: next.cell.row, bottom: next.cell.row, left: next.cell.col, right: next.cell.col },
2079
- (commandId) => {
2080
- const optimistic = optimisticInputsRef.current.get(key);
2081
- if (optimistic?.commandId === commandId) {
2082
- optimistic.pending = false;
2083
- optimistic.baseRevision = projectionRef.current.revision;
2084
- refreshOptimisticInputs();
2085
- }
2086
- }
2087
- );
2088
- };
2089
- execute();
2090
- initialDraftRef.current = input;
2091
- setEditMode(null);
2092
- viewportRef.current?.focus();
2093
- queueMicrotask(() => {
2094
- committingRef.current = false;
2095
- });
2096
- },
2097
- [
2098
- commit,
2099
- draft,
2100
- editable,
2101
- projection,
2102
- readEditInput,
2103
- revision,
2104
- runCommand,
2105
- selection.focus,
2106
- refreshOptimisticInputs
2107
- ]
2108
- );
2109
- const clearSelection = useCallback3(() => {
2110
- if (!editable || !clear) return;
2111
- const current = selection;
2112
- const target = normalizeSelection(current);
2113
- const execute = () => runCommand(
2114
- () => {
2115
- forgetOptimisticInputs(target);
2116
- return clear(current);
2117
- },
2118
- execute,
2119
- () => {
2120
- },
2121
- target
2122
- );
2123
- execute();
2124
- }, [clear, editable, forgetOptimisticInputs, runCommand, selection]);
2125
- const pasteClipboard = useCallback3(
2126
- (event) => {
2127
- if (!editable || editMode !== null) return;
2128
- const clipboardText = event.clipboardData.getData("text/plain");
2129
- if (!clipboardText && !event.clipboardData.types.includes("text/plain")) return;
2130
- event.preventDefault();
2131
- const previousSelection = selectionRef.current;
2132
- const anchor = previousSelection.focus;
2133
- const execute = () => {
2134
- let prepared;
2135
- let target;
2136
- const prepare = () => {
2137
- prepared = parseSpreadsheetClipboard(t, clipboardText);
2138
- if (anchor.row + prepared.rows > rowCount || anchor.col + prepared.columns > columnCount) {
2139
- throw new Error(t("artifacts.spreadsheetGrid.clipboardRangeDoesNotFit"));
2140
- }
2141
- if (!commitRange && prepared.inputs.length !== 1) {
2142
- throw new Error(t("artifacts.spreadsheetGrid.thisSpreadsheetAdapterDoesNot"));
2143
- }
2144
- target = {
2145
- top: anchor.row,
2146
- left: anchor.col,
2147
- bottom: anchor.row + prepared.rows - 1,
2148
- right: anchor.col + prepared.columns - 1
2149
- };
2150
- return target;
2151
- };
2152
- const invoke = () => {
2153
- const parsed = prepared;
2154
- forgetOptimisticInputs(target);
2155
- const bottomRight = {
2156
- row: anchor.row + parsed.rows - 1,
2157
- col: anchor.col + parsed.columns - 1
2158
- };
2159
- updateSelection({
2160
- sheetId: projection.sheetId,
2161
- anchor: { ...anchor },
2162
- focus: bottomRight
2163
- });
2164
- ensureVisible(bottomRight);
2165
- if (commitRange) {
2166
- return commitRange({
2167
- sheetId: projection.sheetId,
2168
- anchor: { ...anchor },
2169
- rows: parsed.rows,
2170
- columns: parsed.columns,
2171
- inputs: parsed.inputs
2172
- });
2173
- }
2174
- const input = parsed.inputs[0];
2175
- return commit({
2176
- sheetId: projection.sheetId,
2177
- cell: { ...anchor },
2178
- input,
2179
- kind: input.startsWith("=") ? "formula" : "value"
2180
- });
2181
- };
2182
- runCommand(
2183
- invoke,
2184
- execute,
2185
- () => {
2186
- const current = selectionRef.current;
2187
- if (target && current.anchor.row === anchor.row && current.anchor.col === anchor.col && current.focus.row === target.bottom && current.focus.col === target.right) {
2188
- updateSelection(previousSelection);
2189
- }
2190
- },
2191
- prepare
2192
- );
2193
- };
2194
- execute();
2195
- },
2196
- [
2197
- columnCount,
2198
- commit,
2199
- commitRange,
2200
- editMode,
2201
- editable,
2202
- ensureVisible,
2203
- forgetOptimisticInputs,
2204
- projection.sheetId,
2205
- rowCount,
2206
- runCommand,
2207
- updateSelection,
2208
- t
2209
- ]
2210
- );
2211
- const copySelection = useCallback3(
2212
- (event) => {
2213
- if (editMode !== null) return;
2214
- const selected = normalizeSelection(selectionRef.current);
2215
- const rowsToCopy = selected.bottom - selected.top + 1;
2216
- const columnsToCopy = selected.right - selected.left + 1;
2217
- if (rowsToCopy * columnsToCopy > MAX_CLIPBOARD_CELLS) {
2218
- event.preventDefault();
2219
- reportCommandFailure(new Error(t("artifacts.spreadsheetGrid.selectedRangeIsTooLarge")));
2220
- return;
2221
- }
2222
- const coverage = projection.coverage;
2223
- if (coverage && (selected.top < coverage.rowStart || selected.bottom >= coverage.rowEnd || selected.left < coverage.columnStart || selected.right >= coverage.columnEnd)) {
2224
- event.preventDefault();
2225
- reportCommandFailure(
2226
- new Error(t("artifacts.spreadsheetGrid.selectedCellsAreStillLoading"))
2227
- );
2228
- return;
2229
- }
2230
- const output = [];
2231
- for (let row = selected.top; row <= selected.bottom; row += 1) {
2232
- const fields = [];
2233
- for (let col = selected.left; col <= selected.right; col += 1) {
2234
- fields.push(escapeSpreadsheetClipboardField(projection.readCell(row, col)?.input ?? ""));
2235
- }
2236
- output.push(fields.join(" "));
2237
- }
2238
- event.clipboardData.setData("text/plain", output.join("\r\n"));
2239
- event.preventDefault();
2240
- setCommandFailure(null);
2241
- },
2242
- [editMode, projection, reportCommandFailure, t]
2243
- );
2244
- const beginEditing = useCallback3(
2245
- (initial, cell = selectionRef.current.focus) => {
2246
- if (!editable) return;
2247
- ensureVisible(cell);
2248
- const current = readEditInput(cell);
2249
- initialDraftRef.current = current;
2250
- selectDraftOnFocusRef.current = initial === void 0;
2251
- setDraft(initial ?? current);
2252
- setEditMode("cell");
2253
- },
2254
- [editable, ensureVisible, readEditInput]
2255
- );
2256
- const onGridKeyDown = useCallback3(
2257
- (event) => {
2258
- if (editMode !== null) return;
2259
- if (event.nativeEvent.isComposing || event.nativeEvent.keyCode === 229) return;
2260
- switch (event.key) {
2261
- case "ArrowUp":
2262
- event.preventDefault();
2263
- moveSelection(-1, 0, event.shiftKey);
2264
- return;
2265
- case "ArrowDown":
2266
- event.preventDefault();
2267
- moveSelection(1, 0, event.shiftKey);
2268
- return;
2269
- case "ArrowLeft":
2270
- event.preventDefault();
2271
- moveSelection(0, -1, event.shiftKey);
2272
- return;
2273
- case "ArrowRight":
2274
- event.preventDefault();
2275
- moveSelection(0, 1, event.shiftKey);
2276
- return;
2277
- case "Tab":
2278
- event.preventDefault();
2279
- moveSelection(0, event.shiftKey ? -1 : 1, false);
2280
- return;
2281
- case "Enter":
2282
- case "F2":
2283
- event.preventDefault();
2284
- beginEditing();
2285
- return;
2286
- case "Backspace":
2287
- case "Delete":
2288
- event.preventDefault();
2289
- clearSelection();
2290
- return;
2291
- case "Home": {
2292
- event.preventDefault();
2293
- const target = event.metaKey || event.ctrlKey ? { row: 0, col: 0 } : { row: selection.focus.row, col: 0 };
2294
- updateSelection({ sheetId: projection.sheetId, anchor: target, focus: target });
2295
- ensureVisible(target);
2296
- return;
2297
- }
2298
- case "End": {
2299
- event.preventDefault();
2300
- const used = projection.usedRange;
2301
- const target = event.metaKey || event.ctrlKey ? {
2302
- row: Math.min(rowCount - 1, (used?.row ?? 0) + (used?.rowCount ?? 1) - 1),
2303
- col: Math.min(columnCount - 1, (used?.col ?? 0) + (used?.colCount ?? 1) - 1)
2304
- } : { row: selection.focus.row, col: columnCount - 1 };
2305
- updateSelection({ sheetId: projection.sheetId, anchor: target, focus: target });
2306
- ensureVisible(target);
2307
- return;
2308
- }
2309
- }
2310
- if (editable && !event.metaKey && !event.ctrlKey && !event.altKey && event.key.length === 1) {
2311
- event.preventDefault();
2312
- beginEditing(event.key);
2313
- }
2314
- },
2315
- [
2316
- beginEditing,
2317
- clearSelection,
2318
- columnCount,
2319
- editMode,
2320
- ensureVisible,
2321
- moveSelection,
2322
- editable,
2323
- rowCount,
2324
- selection.focus.row,
2325
- updateSelection,
2326
- projection.sheetId,
2327
- projection.usedRange
2328
- ]
2329
- );
2330
- const onEditorKeyDown = useCallback3(
2331
- (event) => {
2332
- if (composingRef.current || event.nativeEvent.isComposing) return;
2333
- if (event.key === "Enter") {
2334
- event.preventDefault();
2335
- commitDraft();
2336
- } else if (event.key === "Escape") {
2337
- event.preventDefault();
2338
- committingRef.current = true;
2339
- setDraft(readEditInput(selection.focus));
2340
- setEditMode(null);
2341
- viewportRef.current?.focus();
2342
- queueMicrotask(() => {
2343
- committingRef.current = false;
2344
- });
2345
- }
2346
- },
2347
- [commitDraft, readEditInput, selection.focus]
2348
- );
2349
- const onEditorCompositionStart = useCallback3(() => {
2350
- composingRef.current = true;
2351
- }, []);
2352
- const onEditorCompositionEnd = useCallback3(
2353
- (input) => {
2354
- composingRef.current = false;
2355
- if (!commitAfterCompositionRef.current) return;
2356
- commitAfterCompositionRef.current = false;
2357
- commitDraft(input);
2358
- },
2359
- [commitDraft]
2360
- );
2361
- const commitEditorOnBlur = useCallback3(
2362
- (mode, input) => {
2363
- if (editMode !== mode) return;
2364
- if (composingRef.current) {
2365
- commitAfterCompositionRef.current = true;
2366
- return;
2367
- }
2368
- commitDraft(input);
2369
- },
2370
- [commitDraft, editMode]
2371
- );
2372
- const selectCell = useCallback3(
2373
- (cell, extend) => {
2374
- const current = selectionRef.current;
2375
- const next = {
2376
- sheetId: projection.sheetId,
2377
- anchor: extend ? current.anchor : cell,
2378
- focus: cell
2379
- };
2380
- updateSelection(next);
2381
- setEditMode(null);
2382
- viewportRef.current?.focus();
2383
- },
2384
- [projection.sheetId, updateSelection]
2385
- );
2386
- const hitTestCell = useCallback3(
2387
- (clientX, clientY) => {
2388
- const element = viewportRef.current;
2389
- if (!element) return null;
2390
- const bounds = element.getBoundingClientRect();
2391
- const viewportX = clientX - bounds.left;
2392
- const viewportY = clientY - bounds.top;
2393
- const viewportWidth = element.clientWidth || FALLBACK_VIEWPORT_WIDTH;
2394
- const viewportHeight = element.clientHeight || FALLBACK_VIEWPORT_HEIGHT;
2395
- if (viewportX < ROW_HEADER_WIDTH || viewportY < COLUMN_HEADER_HEIGHT || viewportX >= viewportWidth || viewportY >= viewportHeight) {
2396
- return null;
2397
- }
2398
- const horizontalProjection2 = buildScrollProjection(columns, ROW_HEADER_WIDTH, viewportWidth);
2399
- const verticalProjection2 = buildScrollProjection(rows, COLUMN_HEADER_HEIGHT, viewportHeight);
2400
- const logicalX = physicalToLogicalScroll(element.scrollLeft, horizontalProjection2) + viewportX - ROW_HEADER_WIDTH;
2401
- const logicalY = physicalToLogicalScroll(element.scrollTop, verticalProjection2) + viewportY - COLUMN_HEADER_HEIGHT;
2402
- if (logicalX < 0 || logicalY < 0 || logicalX >= columns.total || logicalY >= rows.total) {
2403
- return null;
2404
- }
2405
- return {
2406
- row: Math.min(rowCount - 1, indexAtOffset(rows, logicalY)),
2407
- col: Math.min(columnCount - 1, indexAtOffset(columns, logicalX))
2408
- };
2409
- },
2410
- [columnCount, columns, rowCount, rows]
2411
- );
2412
- const onGridPointerDown = useCallback3(
2413
- (event) => {
2414
- if (event.button !== 0) return;
2415
- const cell = hitTestCell(event.clientX, event.clientY);
2416
- if (!cell) return;
2417
- event.preventDefault();
2418
- const current = selectionRef.current;
2419
- const anchor = event.shiftKey ? current.anchor : cell;
2420
- selectingRef.current = { pointerId: event.pointerId, anchor };
2421
- try {
2422
- event.currentTarget.setPointerCapture(event.pointerId);
2423
- } catch {
2424
- }
2425
- updateSelection({ sheetId: projection.sheetId, anchor, focus: cell });
2426
- setEditMode(null);
2427
- event.currentTarget.focus();
2428
- },
2429
- [hitTestCell, projection.sheetId, updateSelection]
2430
- );
2431
- const onGridPointerMove = useCallback3(
2432
- (event) => {
2433
- const selecting = selectingRef.current;
2434
- if (!selecting || selecting.pointerId !== event.pointerId) return;
2435
- const cell = hitTestCell(event.clientX, event.clientY);
2436
- if (!cell) return;
2437
- const current = selectionRef.current;
2438
- if (current.focus.row === cell.row && current.focus.col === cell.col) return;
2439
- updateSelection({ sheetId: projection.sheetId, anchor: selecting.anchor, focus: cell });
2440
- },
2441
- [hitTestCell, projection.sheetId, updateSelection]
2442
- );
2443
- const stopPointerSelection = useCallback3((pointerId) => {
2444
- if (pointerId !== void 0 && selectingRef.current?.pointerId !== pointerId) return;
2445
- selectingRef.current = null;
2446
- }, []);
2447
- useEffect3(() => {
2448
- if (typeof window === "undefined") return;
2449
- const stopSelecting = () => stopPointerSelection();
2450
- window.addEventListener("pointerup", stopSelecting);
2451
- return () => window.removeEventListener("pointerup", stopSelecting);
2452
- }, [stopPointerSelection]);
2453
- const horizontalProjection = buildScrollProjection(columns, ROW_HEADER_WIDTH, viewport.width);
2454
- const verticalProjection = buildScrollProjection(rows, COLUMN_HEADER_HEIGHT, viewport.height);
2455
- const physicalScrollLeft = clampPhysicalScroll(viewport.scrollLeft, horizontalProjection);
2456
- const physicalScrollTop = clampPhysicalScroll(viewport.scrollTop, verticalProjection);
2457
- const logicalScrollLeft = physicalToLogicalScroll(viewport.scrollLeft, horizontalProjection);
2458
- const logicalScrollTop = physicalToLogicalScroll(viewport.scrollTop, verticalProjection);
2459
- const visibleRowWindow = visibleInterval(
2460
- rows,
2461
- logicalScrollTop,
2462
- Math.max(1, viewport.height - COLUMN_HEADER_HEIGHT),
2463
- 0
2464
- );
2465
- const visibleColumnWindow = visibleInterval(
2466
- columns,
2467
- logicalScrollLeft,
2468
- Math.max(1, viewport.width - ROW_HEADER_WIDTH),
2469
- 0
2470
- );
2471
- const projectedRowWindow = visibleInterval(
2472
- rows,
2473
- logicalScrollTop,
2474
- Math.max(1, viewport.height - COLUMN_HEADER_HEIGHT),
2475
- Math.max(0, overscanRows)
2476
- );
2477
- const projectedColumnWindow = visibleInterval(
2478
- columns,
2479
- logicalScrollLeft,
2480
- Math.max(1, viewport.width - ROW_HEADER_WIDTH),
2481
- Math.max(0, overscanColumns)
2482
- );
2483
- const { rows: rowWindow, columns: columnWindow } = boundVisibleWindows(
2484
- projectedRowWindow,
2485
- projectedColumnWindow,
2486
- selection.focus
2487
- );
2488
- const visibleRows = indexesBetween(rowWindow.start, rowWindow.end);
2489
- const visibleColumns = indexesBetween(columnWindow.start, columnWindow.end);
2490
- const rowLayout = visibleRows.map((row) => ({
2491
- row,
2492
- top: physicalScrollTop + COLUMN_HEADER_HEIGHT + axisOffsetAt(rows, row) - logicalScrollTop,
2493
- height: axisSizeAt(rows, row)
2494
- }));
2495
- const columnLayout = visibleColumns.map((col) => ({
2496
- col,
2497
- left: physicalScrollLeft + ROW_HEADER_WIDTH + axisOffsetAt(columns, col) - logicalScrollLeft,
2498
- width: axisSizeAt(columns, col)
2499
- }));
2500
- const activeCellVisible = selection.focus.row >= rowWindow.start && selection.focus.row < rowWindow.end && selection.focus.col >= columnWindow.start && selection.focus.col < columnWindow.end;
2501
- const activeCellId = `${reactId}-cell-${selection.focus.row}-${selection.focus.col}`;
2502
- const hiddenActiveValue = activeCellVisible ? null : projection.readCell(selection.focus.row, selection.focus.col)?.value;
2503
- useEffect3(() => {
2504
- if (!onViewportChange) return;
2505
- const next = {
2506
- sheetId: projection.sheetId,
2507
- rowStart: visibleRowWindow.start,
2508
- rowEnd: visibleRowWindow.end,
2509
- columnStart: visibleColumnWindow.start,
2510
- columnEnd: visibleColumnWindow.end,
2511
- overscanRowStart: projectedRowWindow.start,
2512
- overscanRowEnd: projectedRowWindow.end,
2513
- overscanColumnStart: projectedColumnWindow.start,
2514
- overscanColumnEnd: projectedColumnWindow.end,
2515
- logicalScrollLeft,
2516
- logicalScrollTop,
2517
- viewportWidth: viewport.width,
2518
- viewportHeight: viewport.height
2519
- };
2520
- let active = true;
2521
- const notify = () => {
2522
- if (active) onViewportChange(next);
2523
- };
2524
- if (typeof globalThis.requestAnimationFrame === "function") {
2525
- const frame = globalThis.requestAnimationFrame(notify);
2526
- return () => {
2527
- active = false;
2528
- globalThis.cancelAnimationFrame?.(frame);
2529
- };
2530
- }
2531
- queueMicrotask(notify);
2532
- return () => {
2533
- active = false;
2534
- };
2535
- }, [
2536
- logicalScrollLeft,
2537
- logicalScrollTop,
2538
- onViewportChange,
2539
- projectedColumnWindow.end,
2540
- projectedColumnWindow.start,
2541
- projectedRowWindow.end,
2542
- projectedRowWindow.start,
2543
- viewport.height,
2544
- viewport.width,
2545
- visibleColumnWindow.end,
2546
- visibleColumnWindow.start,
2547
- visibleRowWindow.end,
2548
- visibleRowWindow.start,
2549
- projection.sheetId
2550
- ]);
2551
- useClientLayoutEffect(() => {
2552
- void canvasEpoch;
2553
- const canvas = canvasRef.current;
2554
- const viewportElement = viewportRef.current;
2555
- const renderer = canvasRendererRef.current;
2556
- if (!canvas || !viewportElement || !renderer) return;
2557
- const normalized = normalizeSelection(selection);
2558
- const theme = spreadsheetCanvasTheme(viewportElement);
2559
- const paintStartedAt = performance.now();
2560
- const stats = renderer.paint({
2561
- canvas,
2562
- projection,
2563
- rows: canvasRows,
2564
- columns: canvasColumns,
2565
- selection: {
2566
- ...normalized,
2567
- focusRow: selection.focus.row,
2568
- focusColumn: selection.focus.col
2569
- },
2570
- logicalScrollLeft,
2571
- logicalScrollTop,
2572
- viewportWidth: viewport.width,
2573
- viewportHeight: viewport.height,
2574
- rowHeaderWidth: ROW_HEADER_WIDTH,
2575
- columnHeaderHeight: COLUMN_HEADER_HEIGHT,
2576
- dimensionRevision,
2577
- devicePixelRatio: viewport.devicePixelRatio,
2578
- theme
2579
- });
2580
- const paintDurationMs = performance.now() - paintStartedAt;
2581
- if (!stats) {
2582
- if (canvasReady) setCanvasReady(false);
2583
- return;
2584
- }
2585
- canvas.dataset.ogTileCacheSize = String(stats.cacheSize);
2586
- canvas.dataset.ogPaintedTiles = String(stats.paintedTiles);
2587
- canvas.dataset.ogReusedTiles = String(stats.reusedTiles);
2588
- canvas.dataset.ogUncachedTiles = String(stats.uncachedTiles);
2589
- canvas.dataset.ogDevicePixelRatio = String(stats.devicePixelRatio);
2590
- canvas.dataset.ogLogicalScrollLeft = String(logicalScrollLeft);
2591
- canvas.dataset.ogLogicalScrollTop = String(logicalScrollTop);
2592
- canvas.dataset.ogPaintDurationMs = String(paintDurationMs);
2593
- if (!canvasReady) setCanvasReady(true);
2594
- }, [
2595
- canvasColumns,
2596
- canvasEpoch,
2597
- canvasReady,
2598
- canvasRows,
2599
- dimensionRevision,
2600
- logicalScrollLeft,
2601
- logicalScrollTop,
2602
- projection,
2603
- revision,
2604
- selection,
2605
- viewport.devicePixelRatio,
2606
- viewport.height,
2607
- viewport.width
2608
- ]);
2609
- return /* @__PURE__ */ jsxs(
2610
- "div",
2611
- {
2612
- className: cn("relative flex h-full min-w-0 flex-col bg-og-bg", className),
2613
- "data-og-command-state": visibleCommandFailure ? "error" : pendingCommandCount > 0 ? "pending" : "idle",
2614
- style: { minHeight: 256 },
2615
- children: [
2616
- /* @__PURE__ */ jsxs("div", { className: "flex min-h-9 shrink-0 items-center border-b border-og-border bg-og-surface-1", children: [
2617
- /* @__PURE__ */ jsx2(
2618
- "output",
2619
- {
2620
- "aria-label": t("artifacts.spreadsheetGrid.selectedRange"),
2621
- className: "shrink-0 border-r border-og-border px-2 font-mono text-og-xs text-og-fg-muted",
2622
- style: { width: 96 },
2623
- children: selectionName(selection)
2624
- }
2625
- ),
2626
- /* @__PURE__ */ jsx2("span", { "aria-hidden": true, className: "px-2 font-og-mono text-og-sm italic text-og-fg-subtle", children: t("artifacts.spreadsheetGrid.fx") }),
2627
- /* @__PURE__ */ jsx2(
2628
- "input",
2629
- {
2630
- "aria-label": t("artifacts.spreadsheetGrid.formulaOrValue"),
2631
- readOnly: !editable,
2632
- "aria-invalid": visibleCommandFailure ? "true" : void 0,
2633
- value: draft,
2634
- onFocus: () => {
2635
- if (editable) {
2636
- const current = readEditInput(selection.focus);
2637
- initialDraftRef.current = current;
2638
- setDraft(current);
2639
- setEditMode("formula");
2640
- }
2641
- },
2642
- onInput: (event) => setDraft(event.currentTarget.value),
2643
- onKeyDown: onEditorKeyDown,
2644
- onCompositionStart: onEditorCompositionStart,
2645
- onCompositionEnd: (event) => onEditorCompositionEnd(event.currentTarget.value),
2646
- onBlur: (event) => commitEditorOnBlur("formula", event.currentTarget.value),
2647
- className: "h-8 min-w-0 flex-1 bg-transparent px-1 font-mono text-og-sm text-og-fg outline-hidden placeholder:text-og-fg-subtle"
2648
- }
2649
- ),
2650
- visibleSyncStatus ? /* @__PURE__ */ jsx2(
2651
- "output",
2652
- {
2653
- "aria-label": t("artifacts.spreadsheetGrid.spreadsheetSyncStatus"),
2654
- className: "shrink-0 px-2 text-og-xs text-og-fg-muted",
2655
- children: visibleCommandFailure ? t("artifacts.spreadsheetGrid.notSaved") : visibleSyncStatus
2656
- }
2657
- ) : null
2658
- ] }),
2659
- /* @__PURE__ */ jsx2("div", { role: "status", "aria-live": "polite", className: "sr-only", children: visibleCommandFailure?.message ?? (pendingCommandCount > 0 ? t("artifacts.spreadsheetGrid.savingSpreadsheetChanges") : "") }),
2660
- visibleCommandFailure ? /* @__PURE__ */ jsxs(
2661
- "div",
2662
- {
2663
- role: "alert",
2664
- className: "absolute bottom-2 left-2 z-50 flex items-center gap-2 rounded-og-sm border border-og-status-failed/30 bg-og-surface-1/95 px-2 py-1 text-og-xs text-og-status-failed shadow-og-sm",
2665
- style: { maxWidth: "calc(100% - 1rem)" },
2666
- children: [
2667
- /* @__PURE__ */ jsx2("span", { className: "truncate", children: visibleCommandFailure.message }),
2668
- visibleCommandFailure.retry ? /* @__PURE__ */ jsx2(
2669
- "button",
2670
- {
2671
- type: "button",
2672
- onClick: visibleCommandFailure.retry,
2673
- className: "shrink-0 rounded-og-xs px-1.5 py-0.5 font-medium outline-hidden hover:bg-og-surface-3 focus-visible:ring-2 focus-visible:ring-og-accent",
2674
- children: t("artifacts.spreadsheetGrid.retry")
2675
- }
2676
- ) : null
2677
- ]
2678
- }
2679
- ) : null,
2680
- /* @__PURE__ */ jsx2(
2681
- "div",
2682
- {
2683
- ref: viewportRef,
2684
- role: "grid",
2685
- tabIndex: 0,
2686
- "aria-label": t("artifacts.spreadsheetGrid.sheetnameSpreadsheet", {
2687
- sheetName: projection.sheetName
2688
- }),
2689
- "aria-rowcount": rowCount,
2690
- "aria-colcount": columnCount,
2691
- "aria-multiselectable": "true",
2692
- "aria-readonly": !editable,
2693
- "aria-busy": pendingCommandCount > 0 ? "true" : void 0,
2694
- "aria-activedescendant": activeCellId,
2695
- onKeyDown: onGridKeyDown,
2696
- onCopy: copySelection,
2697
- onPaste: pasteClipboard,
2698
- onCompositionEnd: (event) => {
2699
- if (editMode === null && editable && event.data) beginEditing(event.data);
2700
- },
2701
- onPointerDown: onGridPointerDown,
2702
- onPointerMove: onGridPointerMove,
2703
- onPointerUp: (event) => stopPointerSelection(event.pointerId),
2704
- onPointerCancel: (event) => stopPointerSelection(event.pointerId),
2705
- onDoubleClick: (event) => {
2706
- const cell = hitTestCell(event.clientX, event.clientY);
2707
- if (!cell) return;
2708
- selectCell(cell, event.shiftKey);
2709
- beginEditing(void 0, cell);
2710
- },
2711
- onScroll: (event) => {
2712
- const element = event.currentTarget;
2713
- setViewport((current) => ({
2714
- ...current,
2715
- scrollLeft: element.scrollLeft,
2716
- scrollTop: element.scrollTop
2717
- }));
2718
- },
2719
- className: "relative min-h-0 min-w-0 flex-1 overflow-auto overscroll-contain bg-og-surface-1 text-og-sm outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent",
2720
- children: /* @__PURE__ */ jsxs(
2721
- "div",
2722
- {
2723
- role: "rowgroup",
2724
- className: "relative",
2725
- style: {
2726
- width: horizontalProjection.physicalTotal,
2727
- height: verticalProjection.physicalTotal,
2728
- // Centered boundary handles must not enlarge the bounded scroll
2729
- // extent at the final row/column. Unlike hidden, clip does not
2730
- // create another scroll container for the sticky headers.
2731
- overflow: "clip"
2732
- },
2733
- children: [
2734
- /* @__PURE__ */ jsx2(
2735
- "canvas",
2736
- {
2737
- ref: canvasRef,
2738
- "aria-hidden": "true",
2739
- "data-og-spreadsheet-canvas": "retained-tiles",
2740
- className: "pointer-events-none absolute z-0 block",
2741
- style: {
2742
- left: physicalScrollLeft,
2743
- top: physicalScrollTop,
2744
- width: viewport.width,
2745
- height: viewport.height
2746
- }
2747
- }
2748
- ),
2749
- /* @__PURE__ */ jsx2(
2750
- "div",
2751
- {
2752
- "aria-hidden": true,
2753
- className: "sticky left-0 top-0 z-40 border-b border-r border-og-border bg-og-surface-2",
2754
- style: {
2755
- width: ROW_HEADER_WIDTH,
2756
- height: COLUMN_HEADER_HEIGHT,
2757
- ...canvasReady ? { background: "transparent", borderColor: "transparent" } : void 0
2758
- }
2759
- }
2760
- ),
2761
- /* @__PURE__ */ jsx2("div", { role: "row", className: "contents", children: columnLayout.map(({ col, left, width }) => /* @__PURE__ */ jsxs(
2762
- "div",
2763
- {
2764
- role: "columnheader",
2765
- "aria-colindex": col + 1,
2766
- className: "pointer-events-none sticky top-0 z-30 grid select-none place-items-center border-b border-r border-og-border bg-og-surface-2 text-og-xs font-medium text-og-fg-muted",
2767
- style: {
2768
- position: "absolute",
2769
- left,
2770
- top: physicalScrollTop,
2771
- width,
2772
- height: COLUMN_HEADER_HEIGHT,
2773
- ...canvasReady ? {
2774
- background: "transparent",
2775
- borderColor: "transparent",
2776
- color: "transparent"
2777
- } : void 0
2778
- },
2779
- children: [
2780
- /* @__PURE__ */ jsx2("span", { className: "max-w-full overflow-hidden", children: columnName2(col) }),
2781
- !readOnly && resize ? /* @__PURE__ */ jsx2(
2782
- SpreadsheetResizeHandle,
2783
- {
2784
- axis: "column",
2785
- label: t("artifacts.spreadsheetGrid.resizeColumnColumnname", {
2786
- columnName: columnName2(col)
2787
- }),
2788
- size: width,
2789
- ...resizing.handleProps("column", col)
2790
- }
2791
- ) : null
2792
- ]
2793
- },
2794
- `header-${col}`
2795
- )) }),
2796
- rowLayout.map(({ row, top, height }) => {
2797
- return /* @__PURE__ */ jsxs(
2798
- "div",
2799
- {
2800
- role: "row",
2801
- "aria-rowindex": row + 1,
2802
- className: "absolute left-0",
2803
- style: {
2804
- top,
2805
- width: horizontalProjection.physicalTotal,
2806
- height
2807
- },
2808
- children: [
2809
- /* @__PURE__ */ jsxs(
2810
- "div",
2811
- {
2812
- role: "rowheader",
2813
- className: "pointer-events-none sticky left-0 z-20 grid h-full select-none place-items-center border-b border-r border-og-border bg-og-surface-2 text-og-xs text-og-fg-muted",
2814
- style: {
2815
- width: ROW_HEADER_WIDTH,
2816
- ...canvasReady ? {
2817
- background: "transparent",
2818
- borderColor: "transparent",
2819
- color: "transparent"
2820
- } : void 0
2821
- },
2822
- children: [
2823
- row + 1,
2824
- !readOnly && resize ? /* @__PURE__ */ jsx2(
2825
- SpreadsheetResizeHandle,
2826
- {
2827
- axis: "row",
2828
- label: t("artifacts.spreadsheetGrid.resizeRowRow", { row: row + 1 }),
2829
- size: height,
2830
- ...resizing.handleProps("row", row)
2831
- }
2832
- ) : null
2833
- ]
2834
- }
2835
- ),
2836
- columnLayout.map(({ col, left, width }) => {
2837
- const active = selection.focus.row === row && selection.focus.col === col;
2838
- const selected = isCellSelected(selection, row, col);
2839
- const data = projection.readCell(row, col) ?? {
2840
- value: null,
2841
- input: "",
2842
- format: {}
2843
- };
2844
- const value = data.value;
2845
- const optimistic = editable ? optimisticInputsRef.current.get(`${row}:${col}`) : void 0;
2846
- const display = optimistic ? optimistic.input : formatSpreadsheetGeneralDisplay(value);
2847
- const address = cellName({ row, col });
2848
- const error = typeof value === "string" && value.startsWith("#");
2849
- return /* @__PURE__ */ jsx2(
2850
- "div",
2851
- {
2852
- id: `${reactId}-cell-${row}-${col}`,
2853
- role: "gridcell",
2854
- "aria-colindex": col + 1,
2855
- "aria-selected": selected,
2856
- "aria-label": `${address}${display ? `, ${display}` : ""}${optimistic ? optimistic.input.startsWith("=") ? ", pending formula, awaiting calculation" : ", pending edit" : ""}`,
2857
- "data-og-pending-input": optimistic ? "true" : void 0,
2858
- "data-og-cell": address,
2859
- className: cn(
2860
- "pointer-events-none absolute top-0 flex h-full min-w-0 overflow-hidden border-b border-r border-og-border px-1.5 text-og-fg",
2861
- (!canvasReady || optimistic) && selected && !active && "bg-og-accent/10",
2862
- (!canvasReady || optimistic) && active && "z-10 bg-og-accent/10 ring-2 ring-inset ring-og-accent",
2863
- !canvasReady && error && "text-og-status-failed"
2864
- ),
2865
- style: {
2866
- left,
2867
- width,
2868
- ...cellStyle(data.format),
2869
- ...canvasReady && !optimistic ? {
2870
- background: "transparent",
2871
- borderColor: "transparent",
2872
- color: "transparent"
2873
- } : void 0,
2874
- ...optimistic ? {
2875
- background: data.format.fill ?? "var(--og-color-surface-1)",
2876
- zIndex: 10
2877
- } : void 0
2878
- },
2879
- children: active && editMode === "cell" ? /* @__PURE__ */ jsx2(
2880
- "input",
2881
- {
2882
- ref: editorRef,
2883
- "aria-label": t("artifacts.spreadsheetGrid.editAddress", { address }),
2884
- value: draft,
2885
- onInput: (event) => setDraft(event.currentTarget.value),
2886
- onKeyDown: onEditorKeyDown,
2887
- onCompositionStart: onEditorCompositionStart,
2888
- onCompositionEnd: (event) => onEditorCompositionEnd(event.currentTarget.value),
2889
- onBlur: (event) => commitEditorOnBlur("cell", event.currentTarget.value),
2890
- onPointerDown: (event) => event.stopPropagation(),
2891
- className: "pointer-events-auto absolute inset-0 size-full bg-og-surface-1 px-1.5 font-mono text-og-sm text-og-fg outline-hidden ring-2 ring-inset ring-og-accent"
2892
- }
2893
- ) : /* @__PURE__ */ jsx2("span", { className: "block min-w-0 overflow-hidden text-ellipsis", children: display })
2894
- },
2895
- col
2896
- );
2897
- })
2898
- ]
2899
- },
2900
- `row-${row}`
2901
- );
2902
- }),
2903
- !activeCellVisible ? /* @__PURE__ */ jsx2("div", { role: "row", "aria-rowindex": selection.focus.row + 1, className: "sr-only", children: /* @__PURE__ */ jsx2(
2904
- "div",
2905
- {
2906
- id: activeCellId,
2907
- role: "gridcell",
2908
- "aria-colindex": selection.focus.col + 1,
2909
- "aria-selected": "true",
2910
- "aria-label": `${cellName(selection.focus)}${hiddenActiveValue == null ? "" : `, ${formatSpreadsheetGeneralDisplay(hiddenActiveValue)}`}`
2911
- }
2912
- ) }) : null
2913
- ]
2914
- }
2915
- )
2916
- }
2917
- )
2918
- ]
2919
- }
2920
- );
2921
- }
2922
-
2923
- // src/components/artifacts/editable-spreadsheet.tsx
2924
- import {
2925
- SPREADSHEET_ARTIFACT_COMMAND_VERSION,
2926
- editableArtifactStableId,
2927
- spreadsheetSheetId
2928
- } from "@opengeni/sdk/editable-artifacts";
2929
- import { PlusIcon as PlusIcon2 } from "lucide-react";
2930
- import {
2931
- useCallback as useCallback4,
2932
- useEffect as useEffect4,
2933
- useId as useId2,
2934
- useLayoutEffect as useLayoutEffect2,
2935
- useMemo as useMemo3,
2936
- useRef as useRef4,
2937
- useState as useState4
2938
- } from "react";
2939
-
2940
- // src/components/artifacts/spreadsheet-download.tsx
2941
- import { jsx as jsx3 } from "react/jsx-runtime";
2942
- function SpreadsheetDownloadButton(props) {
2943
- return /* @__PURE__ */ jsx3(EditableArtifactDownloadButton, { ...props, format: "xlsx" });
2944
- }
2945
-
2946
- // src/components/artifacts/editable-spreadsheet.tsx
2947
- import { Fragment, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
2948
- var EXCEL_MAX_ROWS = 1048576;
2949
- var EXCEL_MAX_COLUMNS = 16384;
2950
- var INITIAL_VIEWPORT_ROWS = 64;
2951
- var INITIAL_VIEWPORT_COLUMNS = 32;
2952
- var MAX_INTERACTIVE_QUERY_CELLS = 65536;
2953
- var MAX_INTERACTIVE_QUERY_BYTES = 8 * 1024 * 1024;
2954
- var EMPTY_FORMAT = Object.freeze({});
2955
- var EMPTY_SHEETS = [];
2956
- var useClientLayoutEffect2 = typeof window === "undefined" ? useEffect4 : useLayoutEffect2;
2957
- var SESSION_KEYS = /* @__PURE__ */ new WeakMap();
2958
- var nextSessionKey = 0;
2959
- function EditableSpreadsheetGrid(props) {
2960
- return /* @__PURE__ */ jsx4(
2961
- EditableSpreadsheetGridSession,
2962
- {
2963
- ...props
2964
- },
2965
- `${spreadsheetSessionKey(props.session)}:${props.sheet.sheetId}:${props.sheet.generationId ?? "pending"}`
2966
- );
2967
- }
2968
- function EditableSpreadsheetGridSession({
2969
- session,
2970
- sheet,
2971
- metadataRevision,
2972
- readOnly = false,
2973
- rowCount: requestedRowCount,
2974
- columnCount: requestedColumnCount,
2975
- overscanRows = 3,
2976
- overscanColumns = 2,
2977
- onSelectionChange,
2978
- onCommit,
2979
- onResize,
2980
- onCommandError,
2981
- onViewportChange,
2982
- className
2983
- }) {
2984
- const t = useOpenGeniText();
2985
- const authoringLifetime = useSpreadsheetAuthoringLifetime();
2986
- const submissions = useArtifactSubmissions();
2987
- const view = useEditableArtifactView(session);
2988
- const rowCount = boundedSheetCount(requestedRowCount, EXCEL_MAX_ROWS, sheet.usedBounds?.endRow);
2989
- const columnCount = boundedSheetCount(
2990
- requestedColumnCount,
2991
- EXCEL_MAX_COLUMNS,
2992
- sheet.usedBounds?.endColumn
2993
- );
2994
- const [state, setState] = useState4(() => ({
2995
- session,
2996
- generationId: sheet.generationId,
2997
- query: initialViewportQuery(sheet.sheetId, rowCount, columnCount),
2998
- projection: null,
2999
- error: null
3000
- }));
3001
- const activeCellRef = useRef4({ row: 0, column: 0 });
3002
- useEffect4(() => {
3003
- setState(
3004
- (current) => current.session === session && current.generationId === sheet.generationId && current.query.sheetId === sheet.sheetId ? current : {
3005
- session,
3006
- generationId: sheet.generationId,
3007
- query: initialViewportQuery(sheet.sheetId, rowCount, columnCount),
3008
- projection: null,
3009
- error: null
3010
- }
3011
- );
3012
- activeCellRef.current = { row: 0, column: 0 };
3013
- }, [columnCount, rowCount, session, sheet.generationId, sheet.sheetId]);
3014
- useEffect4(() => {
3015
- const query = state.query;
3016
- const matchesScope = (current) => current.session === session && current.generationId === sheet.generationId && sameViewportQuery(current.query, query);
3017
- let active = true;
3018
- const unsubscribe = session.subscribeSpreadsheetViewport(
3019
- query,
3020
- (projection2) => {
3021
- if (!active || !sameViewport(projection2, query)) return;
3022
- if (sheet.generationId !== null && projection2.generationId !== sheet.generationId) {
3023
- setState(
3024
- (current) => matchesScope(current) ? {
3025
- ...current,
3026
- projection: null,
3027
- error: new Error("Spreadsheet generation changed; refreshing metadata")
3028
- } : current
3029
- );
3030
- return;
3031
- }
3032
- setState(
3033
- (current) => matchesScope(current) ? { ...current, projection: projection2, error: null } : current
3034
- );
3035
- },
3036
- {
3037
- onError(error) {
3038
- if (!active) return;
3039
- setState((current) => matchesScope(current) ? { ...current, error } : current);
3040
- }
3041
- }
3042
- );
3043
- return () => {
3044
- active = false;
3045
- unsubscribe();
3046
- };
3047
- }, [session, sheet.generationId, state.query]);
3048
- const projection = useMemo3(
3049
- () => projectSdkViewport(
3050
- sheet,
3051
- metadataRevision,
3052
- state.query,
3053
- state.session === session && state.generationId === sheet.generationId ? state.projection : null,
3054
- rowCount,
3055
- columnCount
3056
- ),
3057
- [columnCount, metadataRevision, rowCount, session, sheet, state]
3058
- );
3059
- const generation = useMemo3(() => sheetGeneration(sheet), [sheet]);
3060
- const editable = !readOnly && view.writable && !view.authoringBlockedReason && generation !== null;
3061
- const syncStatus = view.authoringBlockedReason ? t("artifacts.editableSpreadsheet.waitingForEarlierEdits") : view.state === "live" ? editable ? t("artifacts.editableSpreadsheet.saved") : t("artifacts.editableSpreadsheet.readOnly") : editableArtifactStatusLabel(t, view);
3062
- const syncError = view.blockedPending.length > 0 ? t("artifacts.editableSpreadsheet.someEarlierChangesCouldNot") : view.lastError?.message;
3063
- const resizable = editable && sheet.defaultRowHeight !== void 0 && sheet.defaultColumnWidth !== void 0;
3064
- const handleCommit = useCallback4(
3065
- async (commit) => {
3066
- const lifetime = requireSpreadsheetAuthoringLifetime(authoringLifetime);
3067
- if (!generation) throw new Error(t("artifacts.editableSpreadsheet.thisSheetGenerationIsNot"));
3068
- const input = spreadsheetCellInput(commit.input, commit.kind);
3069
- await submissions.run(
3070
- () => session.applySpreadsheetCommands({
3071
- version: SPREADSHEET_ARTIFACT_COMMAND_VERSION,
3072
- commands: [
3073
- {
3074
- kind: "cells.set",
3075
- sheet: generation,
3076
- anchor: { row: commit.cell.row, column: commit.cell.col },
3077
- rows: 1,
3078
- columns: 1,
3079
- cells: [input]
3080
- }
3081
- ]
3082
- })
3083
- );
3084
- if (authoringLifetime.current === lifetime) onCommit?.(commit);
3085
- },
3086
- [authoringLifetime, generation, onCommit, session, submissions, t]
3087
- );
3088
- const handleClear = useCallback4(
3089
- async (selection) => {
3090
- requireSpreadsheetAuthoringLifetime(authoringLifetime);
3091
- if (!generation) throw new Error(t("artifacts.editableSpreadsheet.thisSheetGenerationIsNot"));
3092
- const top = Math.min(selection.anchor.row, selection.focus.row);
3093
- const bottom = Math.max(selection.anchor.row, selection.focus.row);
3094
- const left = Math.min(selection.anchor.col, selection.focus.col);
3095
- const right = Math.max(selection.anchor.col, selection.focus.col);
3096
- await submissions.run(
3097
- () => session.applySpreadsheetCommands({
3098
- version: SPREADSHEET_ARTIFACT_COMMAND_VERSION,
3099
- commands: [
3100
- {
3101
- kind: "range.clear",
3102
- sheet: generation,
3103
- range: {
3104
- start: { row: top, column: left },
3105
- end: { row: bottom, column: right }
3106
- }
3107
- }
3108
- ]
3109
- })
3110
- );
3111
- },
3112
- [authoringLifetime, generation, session, submissions, t]
3113
- );
3114
- const handleCommitRange = useCallback4(
3115
- async (commit) => {
3116
- requireSpreadsheetAuthoringLifetime(authoringLifetime);
3117
- if (!generation) throw new Error(t("artifacts.editableSpreadsheet.thisSheetGenerationIsNot"));
3118
- await submissions.run(
3119
- () => session.applySpreadsheetCommands({
3120
- version: SPREADSHEET_ARTIFACT_COMMAND_VERSION,
3121
- commands: [
3122
- {
3123
- kind: "cells.set",
3124
- sheet: generation,
3125
- anchor: { row: commit.anchor.row, column: commit.anchor.col },
3126
- rows: commit.rows,
3127
- columns: commit.columns,
3128
- cells: commit.inputs.map(
3129
- (input) => spreadsheetCellInput(input, input.startsWith("=") ? "formula" : "value")
3130
- )
3131
- }
3132
- ]
3133
- })
3134
- );
3135
- },
3136
- [authoringLifetime, generation, session, submissions, t]
3137
- );
3138
- const handleResize = useCallback4(
3139
- async (change) => {
3140
- const lifetime = requireSpreadsheetAuthoringLifetime(authoringLifetime);
3141
- if (!generation) throw new Error(t("artifacts.editableSpreadsheet.thisSheetGenerationIsNot"));
3142
- await submissions.run(
3143
- () => session.applySpreadsheetCommands({
3144
- version: SPREADSHEET_ARTIFACT_COMMAND_VERSION,
3145
- commands: [
3146
- change.axis === "column" ? {
3147
- kind: "column.width.set",
3148
- sheet: generation,
3149
- column: change.index,
3150
- width: change.size === sheet.defaultColumnWidth ? null : change.size
3151
- } : {
3152
- kind: "row.height.set",
3153
- sheet: generation,
3154
- row: change.index,
3155
- height: change.size === sheet.defaultRowHeight ? null : change.size
3156
- }
3157
- ]
3158
- })
3159
- );
3160
- if (authoringLifetime.current === lifetime) onResize?.(change);
3161
- },
3162
- [
3163
- authoringLifetime,
3164
- generation,
3165
- onResize,
3166
- session,
3167
- sheet.defaultColumnWidth,
3168
- sheet.defaultRowHeight,
3169
- submissions,
3170
- t
3171
- ]
3172
- );
3173
- const handleSelection = useCallback4(
3174
- (selection) => {
3175
- activeCellRef.current = {
3176
- row: selection.focus.row,
3177
- column: selection.focus.col
3178
- };
3179
- setState((current) => {
3180
- if (queryContains(current.query, selection.focus.row, selection.focus.col)) return current;
3181
- return {
3182
- ...current,
3183
- query: boundedViewportQuery(
3184
- sheet.sheetId,
3185
- selection.focus.row,
3186
- selection.focus.row + 1,
3187
- selection.focus.col,
3188
- selection.focus.col + 1,
3189
- rowCount,
3190
- columnCount,
3191
- activeCellRef.current
3192
- ),
3193
- projection: current.projection,
3194
- error: null
3195
- };
3196
- });
3197
- onSelectionChange?.(selection);
3198
- },
3199
- [columnCount, onSelectionChange, rowCount, sheet.sheetId]
3200
- );
3201
- const handleViewport = useCallback4(
3202
- (viewport) => {
3203
- const next = boundedViewportQuery(
3204
- sheet.sheetId,
3205
- viewport.overscanRowStart,
3206
- viewport.overscanRowEnd,
3207
- viewport.overscanColumnStart,
3208
- viewport.overscanColumnEnd,
3209
- rowCount,
3210
- columnCount,
3211
- activeCellRef.current
3212
- );
3213
- setState(
3214
- (current) => sameViewportQuery(current.query, next) ? current : { ...current, query: next, error: null }
3215
- );
3216
- onViewportChange?.(viewport);
3217
- },
3218
- [columnCount, onViewportChange, rowCount, sheet.sheetId]
3219
- );
3220
- if (editableArtifactAccessRevoked(view)) {
3221
- return /* @__PURE__ */ jsx4(
3222
- EditableArtifactMessage,
3223
- {
3224
- title: t("artifacts.editableSpreadsheet.spreadsheetUnavailable"),
3225
- detail: t("artifacts.editableSpreadsheet.youNoLongerHaveAccess")
3226
- }
3227
- );
3228
- }
3229
- return /* @__PURE__ */ jsxs2("div", { className: cn("relative h-full min-h-0", className), children: [
3230
- /* @__PURE__ */ jsx4(
3231
- SpreadsheetProjectionGrid,
3232
- {
3233
- projection,
3234
- readOnly: !editable,
3235
- overscanRows,
3236
- overscanColumns,
3237
- onSelectionChange: handleSelection,
3238
- commit: editable ? handleCommit : void 0,
3239
- commitRange: editable ? handleCommitRange : void 0,
3240
- clear: editable ? handleClear : void 0,
3241
- resize: resizable ? handleResize : void 0,
3242
- pendingTransactions: view.pendingTransactions,
3243
- syncStatus,
3244
- syncError,
3245
- onCommandError,
3246
- onViewportChange: handleViewport
3247
- }
3248
- ),
3249
- state.error && state.session === session && state.generationId === sheet.generationId ? /* @__PURE__ */ jsx4(
3250
- "output",
3251
- {
3252
- role: "status",
3253
- className: "pointer-events-none absolute bottom-2 left-2 z-50 rounded-og-sm border border-og-status-failed/30 bg-og-surface-1/95 px-2 py-1 text-og-xs text-og-status-failed shadow-og-sm",
3254
- style: { maxWidth: "min(28rem, calc(100% - 1rem))" },
3255
- children: state.error.message
3256
- }
3257
- ) : null
3258
- ] });
3259
- }
3260
- function EditableSpreadsheetArtifactSurface(props) {
3261
- return /* @__PURE__ */ jsx4(ArtifactSubmissionProvider, { children: /* @__PURE__ */ jsx4(EditableSpreadsheetArtifactSurfaceSession, { ...props }) }, spreadsheetSessionKey(props.session));
3262
- }
3263
- function EditableSpreadsheetArtifactSurfaceSession({
3264
- session,
3265
- title: titleProp,
3266
- showHeader,
3267
- subtitle,
3268
- actions,
3269
- download,
3270
- initialSheetId,
3271
- allowAddSheet = true,
3272
- readOnly = false,
3273
- ...gridProps
3274
- }) {
3275
- const t = useOpenGeniText();
3276
- const title = titleProp === void 0 ? t("artifacts.editableSpreadsheet.workbook") : titleProp;
3277
- const authoringLifetime = useSpreadsheetAuthoringLifetime();
3278
- const submissions = useArtifactSubmissions();
3279
- const { metadata, error: metadataError } = useSpreadsheetMetadata(session);
3280
- const view = useEditableArtifactView(session);
3281
- const [activeSheetId, setActiveSheetId] = useState4(initialSheetId ?? null);
3282
- const [creatingSheet, setCreatingSheet] = useState4(false);
3283
- const [surfaceError, setSurfaceError] = useState4(null);
3284
- const sheets = metadata?.sheets ?? EMPTY_SHEETS;
3285
- const activeSheet = sheets.find((sheet) => sheet.sheetId === activeSheetId) ?? (initialSheetId ? sheets.find((sheet) => sheet.sheetId === initialSheetId) : void 0) ?? sheets[0] ?? null;
3286
- const writable = !readOnly && view.writable && !view.authoringBlockedReason;
3287
- const accessRevoked = editableArtifactAccessRevoked(view);
3288
- const addSheet = useCallback4(async () => {
3289
- if (!writable || creatingSheet) return;
3290
- const lifetime = requireSpreadsheetAuthoringLifetime(authoringLifetime);
3291
- setCreatingSheet(true);
3292
- setSurfaceError(null);
3293
- try {
3294
- const after = activeSheet ? sheetGeneration(activeSheet) : null;
3295
- const created = await submissions.run(
3296
- () => session.createSpreadsheetSheet({
3297
- name: nextAvailableSheetName2(t, sheets),
3298
- after
3299
- })
3300
- );
3301
- if (authoringLifetime.current === lifetime) setActiveSheetId(created.sheetId);
3302
- } catch (cause) {
3303
- if (authoringLifetime.current === lifetime) setSurfaceError(asError(cause));
3304
- } finally {
3305
- if (authoringLifetime.current === lifetime) setCreatingSheet(false);
3306
- }
3307
- }, [activeSheet, authoringLifetime, creatingSheet, session, sheets, submissions, writable, t]);
3308
- const footer = /* @__PURE__ */ jsxs2(
3309
- "div",
3310
- {
3311
- className: "flex min-h-9 items-center gap-1 overflow-x-auto px-2",
3312
- role: "tablist",
3313
- "aria-label": t("artifacts.editableSpreadsheet.worksheets"),
3314
- children: [
3315
- sheets.map((sheet) => /* @__PURE__ */ jsx4(
3316
- EditableWorksheetTab,
3317
- {
3318
- session,
3319
- sheet,
3320
- sheets,
3321
- selected: sheet.sheetId === activeSheet?.sheetId,
3322
- writable,
3323
- onSelect: () => setActiveSheetId(sheet.sheetId),
3324
- onCommandError: gridProps.onCommandError
3325
- },
3326
- `${sheet.sheetId}:${sheet.generationId ?? "pending"}`
3327
- )),
3328
- writable && allowAddSheet ? /* @__PURE__ */ jsx4(
3329
- "button",
3330
- {
3331
- type: "button",
3332
- onClick: () => void addSheet(),
3333
- disabled: creatingSheet,
3334
- "aria-label": creatingSheet ? t("artifacts.editableSpreadsheet.addingWorksheet") : t("artifacts.editableSpreadsheet.addWorksheet"),
3335
- className: "grid size-7 shrink-0 place-items-center rounded-og-sm text-og-fg-muted outline-hidden hover:bg-og-surface-3 hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent disabled:opacity-50 [&>svg]:size-3.5",
3336
- children: /* @__PURE__ */ jsx4(PlusIcon2, {})
3337
- }
3338
- ) : null
3339
- ]
3340
- }
3341
- );
3342
- const error = surfaceError ?? metadataError;
3343
- return /* @__PURE__ */ jsx4(
3344
- ArtifactSurface,
3345
- {
3346
- modality: "spreadsheet",
3347
- title,
3348
- showHeader,
3349
- subtitle: subtitle ?? (accessRevoked ? editableArtifactStatusLabel(t, view) : metadata ? t("counts.sheets", { count: sheets.length }) : editableArtifactStatusLabel(t, view)),
3350
- actions: download ? /* @__PURE__ */ jsxs2(Fragment, { children: [
3351
- actions,
3352
- /* @__PURE__ */ jsx4(SpreadsheetDownloadButton, { session, title, download })
3353
- ] }) : actions,
3354
- footer: accessRevoked ? void 0 : footer,
3355
- busy: !accessRevoked && !metadata && !error,
3356
- children: accessRevoked ? /* @__PURE__ */ jsx4(
3357
- EditableArtifactMessage,
3358
- {
3359
- title: t("artifacts.editableSpreadsheet.accessChanged"),
3360
- detail: editableArtifactStatusLabel(t, view)
3361
- }
3362
- ) : activeSheet && metadata ? /* @__PURE__ */ jsx4(
3363
- EditableSpreadsheetGrid,
3364
- {
3365
- ...gridProps,
3366
- session,
3367
- sheet: activeSheet,
3368
- metadataRevision: metadata.revision,
3369
- readOnly: !writable
3370
- },
3371
- `${activeSheet.sheetId}:${activeSheet.generationId ?? "pending"}`
3372
- ) : error ? /* @__PURE__ */ jsx4(
3373
- EditableArtifactMessage,
3374
- {
3375
- title: t("artifacts.editableSpreadsheet.couldNotOpenThisWorkbook"),
3376
- detail: error.message
3377
- }
3378
- ) : metadata ? /* @__PURE__ */ jsx4("div", { className: "grid h-full place-items-center bg-og-bg p-6 text-center", children: /* @__PURE__ */ jsxs2("div", { children: [
3379
- /* @__PURE__ */ jsx4("p", { className: "text-og-base font-medium text-og-fg", children: t("artifacts.editableSpreadsheet.thisWorkbookHasNoWorksheets") }),
3380
- writable && allowAddSheet ? /* @__PURE__ */ jsx4(
3381
- "button",
3382
- {
3383
- type: "button",
3384
- onClick: () => void addSheet(),
3385
- disabled: creatingSheet,
3386
- className: "mt-3 rounded-og-sm border border-og-primary-border bg-og-primary text-og-primary-fg px-3 py-1.5 text-og-sm font-medium hover:bg-og-primary-hover outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent disabled:opacity-50",
3387
- children: creatingSheet ? t("artifacts.editableSpreadsheet.adding") : t("artifacts.editableSpreadsheet.addWorksheet")
3388
- }
3389
- ) : null
3390
- ] }) }) : /* @__PURE__ */ jsx4(
3391
- EditableArtifactMessage,
3392
- {
3393
- title: t("artifacts.editableSpreadsheet.openingWorkbook"),
3394
- detail: editableArtifactStatusLabel(t, view)
3395
- }
3396
- )
3397
- }
3398
- );
3399
- }
3400
- function EditableWorksheetTab({
3401
- session,
3402
- sheet,
3403
- sheets,
3404
- selected,
3405
- writable,
3406
- onSelect,
3407
- onCommandError
3408
- }) {
3409
- const t = useOpenGeniText();
3410
- const submissions = useArtifactSubmissions();
3411
- const [editing, setEditing] = useState4(false);
3412
- const [name, setName] = useState4(sheet.name);
3413
- const [saving, setSaving] = useState4(false);
3414
- const [accepted, setAccepted] = useState4(false);
3415
- const [error, setError] = useState4(null);
3416
- const inputRef = useRef4(null);
3417
- const tabRef = useRef4(null);
3418
- const busyRef = useRef4(false);
3419
- const mountedRef = useRef4(true);
3420
- const latestRef = useRef4({ session, sheet, writable });
3421
- latestRef.current = { session, sheet, writable };
3422
- const errorId = useId2();
3423
- const canRename = writable && sheet.generationId !== null;
3424
- const scopeRef = useRef4({
3425
- session,
3426
- sheetId: sheet.sheetId,
3427
- generationId: sheet.generationId,
3428
- canRename
3429
- });
3430
- if (scopeRef.current.session !== session || scopeRef.current.sheetId !== sheet.sheetId || scopeRef.current.generationId !== sheet.generationId || scopeRef.current.canRename !== canRename) {
3431
- scopeRef.current = {
3432
- session,
3433
- sheetId: sheet.sheetId,
3434
- generationId: sheet.generationId,
3435
- canRename
3436
- };
3437
- }
3438
- useEffect4(() => {
3439
- mountedRef.current = true;
3440
- return () => {
3441
- mountedRef.current = false;
3442
- };
3443
- }, []);
3444
- useEffect4(() => {
3445
- setEditing(false);
3446
- setSaving(false);
3447
- setAccepted(false);
3448
- setError(null);
3449
- busyRef.current = false;
3450
- }, [session, sheet.generationId, sheet.sheetId, canRename]);
3451
- useEffect4(() => {
3452
- if (!editing) return;
3453
- inputRef.current?.focus();
3454
- inputRef.current?.select();
3455
- }, [editing]);
3456
- useEffect4(() => {
3457
- if (!accepted || !editing || sheet.name !== name) return;
3458
- const restoreFocus = document.activeElement === document.body || document.activeElement === inputRef.current;
3459
- setEditing(false);
3460
- setSaving(false);
3461
- setAccepted(false);
3462
- busyRef.current = false;
3463
- if (restoreFocus) queueMicrotask(() => tabRef.current?.focus({ preventScroll: true }));
3464
- }, [accepted, editing, name, sheet.name]);
3465
- const start = () => {
3466
- if (!canRename || busyRef.current) return;
3467
- onSelect();
3468
- setName(sheet.name);
3469
- setError(null);
3470
- setAccepted(false);
3471
- setEditing(true);
3472
- };
3473
- const cancel = () => {
3474
- if (busyRef.current) return;
3475
- setEditing(false);
3476
- setError(null);
3477
- queueMicrotask(() => tabRef.current?.focus({ preventScroll: true }));
3478
- };
3479
- const rename = async () => {
3480
- if (!canRename || busyRef.current) return;
3481
- const generation = sheetGeneration(sheet);
3482
- if (!generation) return;
3483
- const next = name.trim();
3484
- if (!next || next.length > 31 || /[\\/?*[\]:\0]/u.test(next)) {
3485
- setError(t("artifacts.editableSpreadsheet.use131CharactersWithout"));
3486
- return;
3487
- }
3488
- if (sheets.some((other) => other.sheetId !== sheet.sheetId && other.name === next)) {
3489
- setError(t("artifacts.editableSpreadsheet.aWorksheetAlreadyHasThis"));
3490
- return;
3491
- }
3492
- if (next === sheet.name) {
3493
- cancel();
3494
- return;
3495
- }
3496
- setName(next);
3497
- setError(null);
3498
- setSaving(true);
3499
- busyRef.current = true;
3500
- const scope = scopeRef.current;
3501
- const current = () => mountedRef.current && scopeRef.current === scope && latestRef.current.writable;
3502
- try {
3503
- await submissions.run(
3504
- () => session.applySpreadsheetCommands({
3505
- version: SPREADSHEET_ARTIFACT_COMMAND_VERSION,
3506
- commands: [{ kind: "sheet.rename", sheet: generation, name: next }]
3507
- })
3508
- );
3509
- if (current()) setAccepted(true);
3510
- } catch (cause) {
3511
- if (!current()) return;
3512
- const failure = asError(cause);
3513
- busyRef.current = false;
3514
- setSaving(false);
3515
- setError(failure.message || t("artifacts.editableSpreadsheet.couldNotRenameWorksheetTry"));
3516
- onCommandError?.(failure);
3517
- queueMicrotask(() => inputRef.current?.focus());
3518
- }
3519
- };
3520
- const tab = /* @__PURE__ */ jsx4(
3521
- "button",
3522
- {
3523
- ref: tabRef,
3524
- type: "button",
3525
- role: "tab",
3526
- tabIndex: editing && canRename ? -1 : void 0,
3527
- "aria-selected": selected,
3528
- "aria-keyshortcuts": canRename ? "F2" : void 0,
3529
- title: canRename ? t("artifacts.editableSpreadsheet.doubleClickOrPressF2") : void 0,
3530
- onClick: onSelect,
3531
- onDoubleClick: start,
3532
- onKeyDown: (event) => {
3533
- if (event.key === "F2") {
3534
- event.preventDefault();
3535
- start();
3536
- }
3537
- },
3538
- className: cn(
3539
- "h-7 shrink-0 rounded-og-sm px-2.5 text-og-sm outline-hidden transition-colors focus-visible:ring-2 focus-visible:ring-og-accent",
3540
- selected ? "bg-og-surface-3 font-medium text-og-fg" : "text-og-fg-muted hover:bg-og-surface-3 hover:text-og-fg"
3541
- ),
3542
- children: sheet.name
3543
- }
3544
- );
3545
- return editing && canRename ? /* @__PURE__ */ jsxs2(Fragment, { children: [
3546
- /* @__PURE__ */ jsx4("span", { className: "sr-only", children: tab }),
3547
- /* @__PURE__ */ jsxs2(
3548
- "form",
3549
- {
3550
- className: "flex min-w-0 flex-wrap items-center gap-1 py-1",
3551
- style: { width: "min(18rem, 100%)" },
3552
- onSubmit: (event) => {
3553
- event.preventDefault();
3554
- void rename();
3555
- },
3556
- children: [
3557
- /* @__PURE__ */ jsx4(
3558
- "input",
3559
- {
3560
- ref: inputRef,
3561
- "aria-label": t("artifacts.editableSpreadsheet.worksheetName"),
3562
- "aria-invalid": error ? "true" : void 0,
3563
- "aria-describedby": error ? errorId : void 0,
3564
- disabled: saving,
3565
- value: name,
3566
- onInput: (event) => {
3567
- setName(event.currentTarget.value);
3568
- setError(null);
3569
- },
3570
- onKeyDown: (event) => {
3571
- if (event.nativeEvent.isComposing || event.keyCode === 229) return;
3572
- if (event.key === "Escape") {
3573
- event.preventDefault();
3574
- cancel();
3575
- }
3576
- if (event.key === "Enter") {
3577
- event.preventDefault();
3578
- void rename();
3579
- }
3580
- },
3581
- className: "h-7 w-40 rounded-og-sm border border-og-border bg-og-surface-1 px-2 text-og-sm text-og-fg outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent disabled:opacity-50"
3582
- }
3583
- ),
3584
- saving ? /* @__PURE__ */ jsx4("span", { role: "status", className: "text-og-xs text-og-fg-muted", children: t("artifacts.editableSpreadsheet.renaming") }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
3585
- /* @__PURE__ */ jsx4(
3586
- "button",
3587
- {
3588
- type: "submit",
3589
- className: "rounded-og-sm px-2 py-1 text-og-xs text-og-fg outline-hidden hover:bg-og-surface-3 focus-visible:ring-2 focus-visible:ring-og-accent",
3590
- children: t("artifacts.editableSpreadsheet.save")
3591
- }
3592
- ),
3593
- /* @__PURE__ */ jsx4(
3594
- "button",
3595
- {
3596
- type: "button",
3597
- onClick: cancel,
3598
- className: "rounded-og-sm px-2 py-1 text-og-xs text-og-fg-muted outline-hidden hover:bg-og-surface-3 focus-visible:ring-2 focus-visible:ring-og-accent",
3599
- children: t("artifacts.editableSpreadsheet.cancel")
3600
- }
3601
- )
3602
- ] }),
3603
- error ? /* @__PURE__ */ jsx4(
3604
- "span",
3605
- {
3606
- id: errorId,
3607
- role: "alert",
3608
- className: "text-og-xs text-og-status-failed",
3609
- style: { flexBasis: "100%", overflowWrap: "anywhere" },
3610
- children: error
3611
- }
3612
- ) : null
3613
- ]
3614
- }
3615
- )
3616
- ] }) : tab;
3617
- }
3618
- function spreadsheetSessionKey(session) {
3619
- let key = SESSION_KEYS.get(session);
3620
- if (key === void 0) {
3621
- key = ++nextSessionKey;
3622
- SESSION_KEYS.set(session, key);
3623
- }
3624
- return key;
3625
- }
3626
- function useSpreadsheetAuthoringLifetime() {
3627
- const lifetime = useRef4({});
3628
- useClientLayoutEffect2(() => {
3629
- lifetime.current = {};
3630
- return () => {
3631
- lifetime.current = null;
3632
- };
3633
- }, []);
3634
- return lifetime;
3635
- }
3636
- function requireSpreadsheetAuthoringLifetime(lifetime) {
3637
- if (!lifetime.current) throw new Error("Spreadsheet authoring session changed");
3638
- return lifetime.current;
3639
- }
3640
- function useSpreadsheetMetadata(session) {
3641
- const [state, setState] = useState4({ session, metadata: null, error: null });
3642
- useEffect4(() => {
3643
- let active = true;
3644
- const unsubscribe = session.subscribeSpreadsheetMetadata(
3645
- {},
3646
- (metadata) => {
3647
- if (active) setState({ session, metadata, error: null });
3648
- },
3649
- {
3650
- onError: (error) => {
3651
- if (active)
3652
- setState(
3653
- (current) => current.session === session ? { ...current, error } : { session, metadata: null, error }
3654
- );
3655
- }
3656
- }
3657
- );
3658
- return () => {
3659
- active = false;
3660
- unsubscribe();
3661
- };
3662
- }, [session]);
3663
- return state.session === session ? state : { metadata: null, error: null };
3664
- }
3665
- function projectSdkViewport(sheet, metadataRevision, query, viewport, rowCount, columnCount) {
3666
- const current = viewport && viewport.sheetId === sheet.sheetId && viewport.generationId === sheet.generationId ? viewport : null;
3667
- const projectedCells = (current?.cells ?? []).map((cell) => ({
3668
- row: cell.row,
3669
- col: cell.column,
3670
- value: projectedCellValue(cell.value),
3671
- formula: cell.formula,
3672
- format: EMPTY_FORMAT
3673
- }));
3674
- const cells = new SparseSpreadsheetCellIndex(projectedCells);
3675
- const byCoordinate = new Map(
3676
- projectedCells.map((cell) => [`${cell.row}:${cell.col}`, cell])
3677
- );
3678
- const used = sheet.usedBounds;
3679
- return {
3680
- sheetId: sheet.sheetId,
3681
- sheetName: sheet.name,
3682
- generationId: current?.generationId ?? sheet.generationId,
3683
- revision: current?.revision.toString() ?? "loading",
3684
- dimensionRevision: metadataRevision.toString(),
3685
- defaultRowHeight: sheet.defaultRowHeight,
3686
- defaultColumnWidth: sheet.defaultColumnWidth,
3687
- rowHeights: sheet.rowHeights,
3688
- columnWidths: sheet.columnWidths,
3689
- rowCount,
3690
- columnCount,
3691
- usedRange: used ? {
3692
- row: used.startRow,
3693
- col: used.startColumn,
3694
- rowCount: used.endRow - used.startRow + 1,
3695
- colCount: used.endColumn - used.startColumn + 1
3696
- } : null,
3697
- coverage: current ? {
3698
- rowStart: current.startRow,
3699
- rowEnd: current.startRow + current.rowCount,
3700
- columnStart: current.startColumn,
3701
- columnEnd: current.startColumn + current.columnCount
3702
- } : {
3703
- rowStart: query.startRow,
3704
- rowEnd: query.startRow,
3705
- columnStart: query.startColumn,
3706
- columnEnd: query.startColumn
3707
- },
3708
- cells,
3709
- valueAt: (cell) => cell.value,
3710
- readCell: (row, column) => {
3711
- const cell = byCoordinate.get(`${row}:${column}`);
3712
- return cell ? {
3713
- value: cell.value,
3714
- input: cell.formula ?? displayValue(cell.value),
3715
- format: cell.format
3716
- } : null;
3717
- }
3718
- };
3719
- }
3720
- function initialViewportQuery(sheetId, rowCount, columnCount) {
3721
- return {
3722
- sheetId,
3723
- startRow: 0,
3724
- startColumn: 0,
3725
- rowCount: Math.min(rowCount, INITIAL_VIEWPORT_ROWS),
3726
- columnCount: Math.min(columnCount, INITIAL_VIEWPORT_COLUMNS),
3727
- maxCells: MAX_INTERACTIVE_QUERY_CELLS,
3728
- maxBytes: MAX_INTERACTIVE_QUERY_BYTES
3729
- };
3730
- }
3731
- function boundedViewportQuery(sheetId, desiredRowStart, desiredRowEnd, desiredColumnStart, desiredColumnEnd, totalRows, totalColumns, focus) {
3732
- let rowStart = clampInteger(desiredRowStart, 0, totalRows - 1);
3733
- let rowEnd = clampInteger(desiredRowEnd, rowStart + 1, totalRows);
3734
- let columnStart = clampInteger(desiredColumnStart, 0, totalColumns - 1);
3735
- let columnEnd = clampInteger(desiredColumnEnd, columnStart + 1, totalColumns);
3736
- const desiredRows = rowEnd - rowStart;
3737
- const desiredColumns = columnEnd - columnStart;
3738
- if (desiredRows * desiredColumns > MAX_INTERACTIVE_QUERY_CELLS) {
3739
- const columns = Math.min(
3740
- desiredColumns,
3741
- Math.max(1, Math.floor(Math.sqrt(MAX_INTERACTIVE_QUERY_CELLS * 2)))
3742
- );
3743
- const rows = Math.max(1, Math.floor(MAX_INTERACTIVE_QUERY_CELLS / columns));
3744
- columnStart = clampWindowStart(columnStart, columnEnd, focus.column, columns, totalColumns);
3745
- columnEnd = Math.min(totalColumns, columnStart + columns);
3746
- rowStart = clampWindowStart(rowStart, rowEnd, focus.row, rows, totalRows);
3747
- rowEnd = Math.min(totalRows, rowStart + rows);
3748
- }
3749
- return {
3750
- sheetId,
3751
- startRow: rowStart,
3752
- startColumn: columnStart,
3753
- rowCount: rowEnd - rowStart,
3754
- columnCount: columnEnd - columnStart,
3755
- maxCells: MAX_INTERACTIVE_QUERY_CELLS,
3756
- maxBytes: MAX_INTERACTIVE_QUERY_BYTES
3757
- };
3758
- }
3759
- function clampWindowStart(desiredStart, desiredEnd, focus, size, total) {
3760
- if (desiredEnd - desiredStart <= size) return Math.min(desiredStart, Math.max(0, total - size));
3761
- const centered = focus - Math.floor(size / 2);
3762
- return Math.max(desiredStart, Math.min(desiredEnd - size, centered));
3763
- }
3764
- function queryContains(query, row, column) {
3765
- return row >= query.startRow && row < query.startRow + query.rowCount && column >= query.startColumn && column < query.startColumn + query.columnCount;
3766
- }
3767
- function sameViewport(projection, query) {
3768
- return projection.sheetId === query.sheetId && projection.startRow === query.startRow && projection.startColumn === query.startColumn && projection.rowCount === query.rowCount && projection.columnCount === query.columnCount;
3769
- }
3770
- function sameViewportQuery(left, right) {
3771
- return left.sheetId === right.sheetId && left.startRow === right.startRow && left.startColumn === right.startColumn && left.rowCount === right.rowCount && left.columnCount === right.columnCount && left.maxCells === right.maxCells && left.maxBytes === right.maxBytes;
3772
- }
3773
- function sheetGeneration(sheet) {
3774
- if (sheet.generationId === null) return null;
3775
- return {
3776
- kind: "generation",
3777
- sheetId: spreadsheetSheetId(sheet.sheetId),
3778
- creationOperationId: editableArtifactStableId(sheet.generationId)
3779
- };
3780
- }
3781
- function spreadsheetCellInput(input, kind) {
3782
- if (kind === "formula") return { formula: input };
3783
- if (input === "") return null;
3784
- const normalized = input.trim();
3785
- if (/^(?:true|false)$/i.test(normalized)) return normalized.toLowerCase() === "true";
3786
- if (/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i.test(normalized)) {
3787
- const value = Number(normalized);
3788
- if (Number.isFinite(value)) return value;
3789
- }
3790
- return input;
3791
- }
3792
- function projectedCellValue(value) {
3793
- switch (value.kind) {
3794
- case "empty":
3795
- return null;
3796
- case "boolean":
3797
- case "number":
3798
- case "text":
3799
- return value.value;
3800
- case "date":
3801
- return new Date(value.value);
3802
- case "error":
3803
- return spreadsheetErrorText(value.value);
3804
- }
3805
- }
3806
- function spreadsheetErrorText(value) {
3807
- if (typeof value === "object") return value.custom;
3808
- return {
3809
- null: "#NULL!",
3810
- divide_by_zero: "#DIV/0!",
3811
- value: "#VALUE!",
3812
- reference: "#REF!",
3813
- name: "#NAME?",
3814
- number: "#NUM!",
3815
- not_available: "#N/A",
3816
- spill: "#SPILL!",
3817
- calculation: "#CALC!"
3818
- }[value];
3819
- }
3820
- function boundedSheetCount(requested, maximum, usedEnd) {
3821
- const requestedCount = requested === void 0 || !Number.isFinite(requested) ? maximum : Math.max(1, Math.min(maximum, Math.floor(requested)));
3822
- const usedCount = usedEnd === void 0 || !Number.isSafeInteger(usedEnd) ? 1 : Math.max(1, Math.min(maximum, usedEnd + 1));
3823
- return Math.max(requestedCount, usedCount);
3824
- }
3825
- function displayValue(value) {
3826
- if (value === null || value === void 0) return "";
3827
- if (value instanceof Date) return Number.isNaN(value.getTime()) ? "" : value.toISOString();
3828
- if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
3829
- return String(value);
3830
- }
3831
- function nextAvailableSheetName2(t, sheets) {
3832
- let index = sheets.length + 1;
3833
- while (sheets.some((sheet) => sheet.name === `Sheet${index}`)) index += 1;
3834
- return t("artifacts.editableSpreadsheet.sheetIndex", { index });
3835
- }
3836
- function clampInteger(value, minimum, maximum) {
3837
- if (!Number.isFinite(value)) return minimum;
3838
- return Math.min(maximum, Math.max(minimum, Math.floor(value)));
3839
- }
3840
- function asError(cause) {
3841
- return cause instanceof Error ? cause : new Error("Spreadsheet change failed");
3842
- }
3843
-
3844
- export {
3845
- SpreadsheetArtifactSurface,
3846
- SpreadsheetGrid,
3847
- SpreadsheetProjectionGrid,
3848
- EditableSpreadsheetGrid,
3849
- EditableSpreadsheetArtifactSurface
3850
- };
3851
- //# sourceMappingURL=chunk-GA4YEAMX.js.map