@arbidocs/react 0.5.111 → 0.5.113

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 (972) hide show
  1. package/dist/account/client.js +96 -0
  2. package/dist/account/client.js.map +7 -0
  3. package/dist/account/delete.js +70 -0
  4. package/dist/account/delete.js.map +7 -0
  5. package/dist/account/didit.js +34 -0
  6. package/dist/account/didit.js.map +7 -0
  7. package/dist/account/dismissed-tips.js +33 -0
  8. package/dist/account/dismissed-tips.js.map +7 -0
  9. package/dist/account/email.js +84 -0
  10. package/dist/account/email.js.map +7 -0
  11. package/dist/account/entitlements.js +47 -0
  12. package/dist/account/entitlements.js.map +7 -0
  13. package/dist/account/identity.js +270 -0
  14. package/dist/account/identity.js.map +7 -0
  15. package/dist/account/index.js +93 -0
  16. package/dist/account/index.js.map +7 -0
  17. package/dist/account/notifications.js +59 -0
  18. package/dist/account/notifications.js.map +7 -0
  19. package/dist/account/password.js +103 -0
  20. package/dist/account/password.js.map +7 -0
  21. package/dist/account/profile.js +116 -0
  22. package/dist/account/profile.js.map +7 -0
  23. package/dist/account/recovery.js +13 -0
  24. package/dist/account/recovery.js.map +7 -0
  25. package/dist/account/relevance.js +82 -0
  26. package/dist/account/relevance.js.map +7 -0
  27. package/dist/account/sessions.js +37 -0
  28. package/dist/account/sessions.js.map +7 -0
  29. package/dist/account/settings.js +39 -0
  30. package/dist/account/settings.js.map +7 -0
  31. package/dist/account/table-views.js +16 -0
  32. package/dist/account/table-views.js.map +7 -0
  33. package/dist/ai/AiAnswer.js +83 -0
  34. package/dist/ai/AiAnswer.js.map +7 -0
  35. package/dist/ai/AiMarkdown.js +40 -0
  36. package/dist/ai/AiMarkdown.js.map +7 -0
  37. package/dist/ai/ArtifactCanvas.js +193 -0
  38. package/dist/ai/ArtifactCanvas.js.map +7 -0
  39. package/dist/ai/CitationRenderer.js +413 -0
  40. package/dist/ai/CitationRenderer.js.map +7 -0
  41. package/dist/{chunk-WL2Y2T47.js → ai/MarkdownRenderer.js} +35 -101
  42. package/dist/ai/MarkdownRenderer.js.map +7 -0
  43. package/dist/ai/MessageArtifactCard.js +75 -0
  44. package/dist/ai/MessageArtifactCard.js.map +7 -0
  45. package/dist/ai/PassageCard.js +79 -0
  46. package/dist/ai/PassageCard.js.map +7 -0
  47. package/dist/ai/engine.js +110 -0
  48. package/dist/ai/engine.js.map +7 -0
  49. package/dist/ai/index.js +63 -0
  50. package/dist/ai/index.js.map +7 -0
  51. package/dist/ai/markdown-base-components.js +37 -0
  52. package/dist/ai/markdown-base-components.js.map +7 -0
  53. package/dist/ai/markdown-streaming-context.js +6 -0
  54. package/dist/ai/markdown-streaming-context.js.map +7 -0
  55. package/dist/{chunk-VSCU7K4V.js → ai/normalize-citations.js} +12 -19
  56. package/dist/ai/normalize-citations.js.map +7 -0
  57. package/dist/ai/redline.js +41 -0
  58. package/dist/ai/redline.js.map +7 -0
  59. package/dist/ai/split-markdown-blocks.js +40 -0
  60. package/dist/ai/split-markdown-blocks.js.map +7 -0
  61. package/dist/{chunk-UW2SGTI5.js → ai/stored-markdown.js} +41 -93
  62. package/dist/ai/stored-markdown.js.map +7 -0
  63. package/dist/annotations/AnnotationPageOverlay.js +807 -0
  64. package/dist/annotations/AnnotationPageOverlay.js.map +7 -0
  65. package/dist/annotations/AnnotationToolbar.js +398 -0
  66. package/dist/annotations/AnnotationToolbar.js.map +7 -0
  67. package/dist/annotations/FreezeDialog.js +170 -0
  68. package/dist/annotations/FreezeDialog.js.map +7 -0
  69. package/dist/annotations/ProductionDialog.js +354 -0
  70. package/dist/annotations/ProductionDialog.js.map +7 -0
  71. package/dist/annotations/controller.js +49 -0
  72. package/dist/annotations/controller.js.map +7 -0
  73. package/dist/annotations/freeze/browser.js +21 -0
  74. package/dist/annotations/freeze/browser.js.map +7 -0
  75. package/dist/annotations/freeze/bundle.js +201 -0
  76. package/dist/annotations/freeze/bundle.js.map +7 -0
  77. package/dist/annotations/freeze/coords.js +37 -0
  78. package/dist/annotations/freeze/coords.js.map +7 -0
  79. package/dist/annotations/freeze/freeze.js +261 -0
  80. package/dist/annotations/freeze/freeze.js.map +7 -0
  81. package/dist/annotations/freeze/hash.js +28 -0
  82. package/dist/annotations/freeze/hash.js.map +7 -0
  83. package/dist/annotations/freeze/index-page.js +78 -0
  84. package/dist/annotations/freeze/index-page.js.map +7 -0
  85. package/dist/annotations/freeze/index.js +28 -22
  86. package/dist/annotations/freeze/index.js.map +7 -1
  87. package/dist/annotations/freeze/raster.js +208 -0
  88. package/dist/annotations/freeze/raster.js.map +7 -0
  89. package/dist/annotations/freeze/stamp.js +117 -0
  90. package/dist/annotations/freeze/stamp.js.map +7 -0
  91. package/dist/annotations/freeze/types.js +14 -0
  92. package/dist/annotations/freeze/types.js.map +7 -0
  93. package/dist/annotations/freeze/vector.js +283 -0
  94. package/dist/annotations/freeze/vector.js.map +7 -0
  95. package/dist/annotations/geometry.js +81 -0
  96. package/dist/annotations/geometry.js.map +7 -0
  97. package/dist/annotations/index.js +125 -6
  98. package/dist/annotations/index.js.map +7 -1
  99. package/dist/annotations/merge.js +53 -0
  100. package/dist/annotations/merge.js.map +7 -0
  101. package/dist/{chunk-T3USOSVN.js → annotations/model.js} +23 -16
  102. package/dist/annotations/model.js.map +7 -0
  103. package/dist/annotations/overlay-geometry.js +41 -0
  104. package/dist/annotations/overlay-geometry.js.map +7 -0
  105. package/dist/annotations/redaction-log.js +33 -0
  106. package/dist/annotations/redaction-log.js.map +7 -0
  107. package/dist/annotations/selection-marks.js +122 -0
  108. package/dist/annotations/selection-marks.js.map +7 -0
  109. package/dist/annotations/state.js +140 -0
  110. package/dist/annotations/state.js.map +7 -0
  111. package/dist/annotations/store.js +49 -0
  112. package/dist/annotations/store.js.map +7 -0
  113. package/dist/annotations/useAnnotationLayer.js +306 -0
  114. package/dist/annotations/useAnnotationLayer.js.map +7 -0
  115. package/dist/annotations/useAnnotationShortcuts.js +31 -0
  116. package/dist/annotations/useAnnotationShortcuts.js.map +7 -0
  117. package/dist/annotations/useTextSelectionMarks.js +100 -0
  118. package/dist/annotations/useTextSelectionMarks.js.map +7 -0
  119. package/dist/artifacts/artifact-kind.js +19 -0
  120. package/dist/artifacts/artifact-kind.js.map +7 -0
  121. package/dist/artifacts/index.js +89 -571
  122. package/dist/artifacts/index.js.map +7 -1
  123. package/dist/{chunk-WUTL62MC.js → artifacts/normalize-markdown.js} +12 -14
  124. package/dist/artifacts/normalize-markdown.js.map +7 -0
  125. package/dist/artifacts/redline-core.js +12 -3
  126. package/dist/artifacts/redline-core.js.map +7 -1
  127. package/dist/{chunk-74N436VK.js → artifacts/redline-diff.js} +10 -9
  128. package/dist/artifacts/redline-diff.js.map +7 -0
  129. package/dist/artifacts/redline-engine.js +14 -0
  130. package/dist/artifacts/redline-engine.js.map +7 -0
  131. package/dist/artifacts/renderArtifactMarkdown.js +9 -0
  132. package/dist/artifacts/renderArtifactMarkdown.js.map +7 -0
  133. package/dist/artifacts/useArtifactEditSession.js +183 -0
  134. package/dist/artifacts/useArtifactEditSession.js.map +7 -0
  135. package/dist/artifacts/useArtifactSession.js +173 -0
  136. package/dist/artifacts/useArtifactSession.js.map +7 -0
  137. package/dist/artifacts/useArtifactSource.js +16 -0
  138. package/dist/artifacts/useArtifactSource.js.map +7 -0
  139. package/dist/artifacts/useArtifactText.js +78 -0
  140. package/dist/artifacts/useArtifactText.js.map +7 -0
  141. package/dist/artifacts/useRedline.js +65 -0
  142. package/dist/artifacts/useRedline.js.map +7 -0
  143. package/dist/artifacts/useStreamedArtifact.js +74 -0
  144. package/dist/artifacts/useStreamedArtifact.js.map +7 -0
  145. package/dist/artifacts/versions.js +68 -0
  146. package/dist/artifacts/versions.js.map +7 -0
  147. package/dist/billing.js +200 -0
  148. package/dist/billing.js.map +7 -0
  149. package/dist/boot-timeout.js +19 -0
  150. package/dist/boot-timeout.js.map +7 -0
  151. package/dist/calendar/accounts.js +213 -0
  152. package/dist/calendar/accounts.js.map +7 -0
  153. package/dist/calendar/hooks.js +409 -0
  154. package/dist/calendar/hooks.js.map +7 -0
  155. package/dist/calendar/index.js +31 -0
  156. package/dist/calendar/index.js.map +7 -0
  157. package/dist/calendar/keys.js +5 -0
  158. package/dist/calendar/keys.js.map +7 -0
  159. package/dist/calendar/offline/outbox.js +231 -0
  160. package/dist/calendar/offline/outbox.js.map +7 -0
  161. package/dist/calendar/offline/runtime.js +109 -0
  162. package/dist/calendar/offline/runtime.js.map +7 -0
  163. package/dist/calendar/offline/support.js +41 -0
  164. package/dist/calendar/offline/support.js.map +7 -0
  165. package/dist/calendar/support.js +34 -0
  166. package/dist/calendar/support.js.map +7 -0
  167. package/dist/calls/actions.js +226 -0
  168. package/dist/calls/actions.js.map +7 -0
  169. package/dist/calls/events.js +138 -0
  170. package/dist/calls/events.js.map +7 -0
  171. package/dist/calls/gate.js +19 -0
  172. package/dist/calls/gate.js.map +7 -0
  173. package/dist/calls/hooks.js +115 -0
  174. package/dist/calls/hooks.js.map +7 -0
  175. package/dist/calls/in-call-chat.js +132 -0
  176. package/dist/calls/in-call-chat.js.map +7 -0
  177. package/dist/calls/index.js +24 -0
  178. package/dist/calls/index.js.map +7 -0
  179. package/dist/calls/keys.js +17 -0
  180. package/dist/calls/keys.js.map +7 -0
  181. package/dist/calls/livekit/index.js +6 -958
  182. package/dist/calls/livekit/index.js.map +7 -1
  183. package/dist/calls/livekit/room.js +98 -0
  184. package/dist/calls/livekit/room.js.map +7 -0
  185. package/dist/calls/livekit/useCallRecorder.js +219 -0
  186. package/dist/calls/livekit/useCallRecorder.js.map +7 -0
  187. package/dist/calls/livekit/useCallTranscriber.js +309 -0
  188. package/dist/calls/livekit/useCallTranscriber.js.map +7 -0
  189. package/dist/calls/livekit/useHostMuteNotice.js +29 -0
  190. package/dist/calls/livekit/useHostMuteNotice.js.map +7 -0
  191. package/dist/calls/livekit/useInCallChat.js +161 -0
  192. package/dist/calls/livekit/useInCallChat.js.map +7 -0
  193. package/dist/calls/livekit/useWebinar.js +239 -0
  194. package/dist/calls/livekit/useWebinar.js.map +7 -0
  195. package/dist/calls/meeting-chat.js +149 -0
  196. package/dist/calls/meeting-chat.js.map +7 -0
  197. package/dist/calls/moderation.js +50 -0
  198. package/dist/calls/moderation.js.map +7 -0
  199. package/dist/calls/open-meeting-chat.js +29 -0
  200. package/dist/calls/open-meeting-chat.js.map +7 -0
  201. package/dist/calls/read-only.js +24 -0
  202. package/dist/calls/read-only.js.map +7 -0
  203. package/dist/calls/recording-media.js +218 -0
  204. package/dist/calls/recording-media.js.map +7 -0
  205. package/dist/calls/recording-playback.js +260 -0
  206. package/dist/calls/recording-playback.js.map +7 -0
  207. package/dist/calls/recording.js +268 -0
  208. package/dist/calls/recording.js.map +7 -0
  209. package/dist/calls/save-to-thread.js +80 -0
  210. package/dist/calls/save-to-thread.js.map +7 -0
  211. package/dist/calls/session.js +134 -0
  212. package/dist/calls/session.js.map +7 -0
  213. package/dist/calls/transcript-format.js +147 -0
  214. package/dist/calls/transcript-format.js.map +7 -0
  215. package/dist/calls/transcription.js +101 -0
  216. package/dist/calls/transcription.js.map +7 -0
  217. package/dist/calls/webinar.js +71 -0
  218. package/dist/calls/webinar.js.map +7 -0
  219. package/dist/charge-watch.js +71 -0
  220. package/dist/charge-watch.js.map +7 -0
  221. package/dist/chat/ChatBubble.js +146 -0
  222. package/dist/chat/ChatBubble.js.map +7 -0
  223. package/dist/chat/ConversationScope.js +30 -0
  224. package/dist/chat/ConversationScope.js.map +7 -0
  225. package/dist/chat/active-config.js +20 -0
  226. package/dist/chat/active-config.js.map +7 -0
  227. package/dist/chat/agent-chat-owner.js +25 -0
  228. package/dist/chat/agent-chat-owner.js.map +7 -0
  229. package/dist/chat/chat-artifacts.js +64 -0
  230. package/dist/chat/chat-artifacts.js.map +7 -0
  231. package/dist/chat/citations.js +32 -0
  232. package/dist/chat/citations.js.map +7 -0
  233. package/dist/chat/config-model.js +10 -0
  234. package/dist/chat/config-model.js.map +7 -0
  235. package/dist/chat/conversation-cache.js +676 -0
  236. package/dist/chat/conversation-cache.js.map +7 -0
  237. package/dist/chat/conversation-events.js +57 -0
  238. package/dist/chat/conversation-events.js.map +7 -0
  239. package/dist/chat/conversation-mentions.js +58 -0
  240. package/dist/chat/conversation-mentions.js.map +7 -0
  241. package/dist/chat/conversation-workspace.js +58 -0
  242. package/dist/chat/conversation-workspace.js.map +7 -0
  243. package/dist/chat/mentions.js +116 -0
  244. package/dist/chat/mentions.js.map +7 -0
  245. package/dist/chat/open-document.js +106 -0
  246. package/dist/chat/open-document.js.map +7 -0
  247. package/dist/chat/orphaned.js +44 -0
  248. package/dist/chat/orphaned.js.map +7 -0
  249. package/dist/chat/pendingFirstTurn.js +30 -0
  250. package/dist/chat/pendingFirstTurn.js.map +7 -0
  251. package/dist/chat/reply-target.js +12 -0
  252. package/dist/chat/reply-target.js.map +7 -0
  253. package/dist/chat/run-finished.js +28 -0
  254. package/dist/chat/run-finished.js.map +7 -0
  255. package/dist/chat/run-state.js +91 -0
  256. package/dist/chat/run-state.js.map +7 -0
  257. package/dist/chat/stream-handlers.js +419 -0
  258. package/dist/chat/stream-handlers.js.map +7 -0
  259. package/dist/chat/thread-binding.js +76 -0
  260. package/dist/chat/thread-binding.js.map +7 -0
  261. package/dist/chat/thread-document.js +53 -0
  262. package/dist/chat/thread-document.js.map +7 -0
  263. package/dist/chat/turn-control.js +79 -0
  264. package/dist/chat/turn-control.js.map +7 -0
  265. package/dist/chat/useAgentRunControl.js +36 -0
  266. package/dist/chat/useAgentRunControl.js.map +7 -0
  267. package/dist/chat/useAnswerAgentQuestion.js +19 -0
  268. package/dist/chat/useAnswerAgentQuestion.js.map +7 -0
  269. package/dist/chat/useAskAgain.js +32 -0
  270. package/dist/chat/useAskAgain.js.map +7 -0
  271. package/dist/chat/useAutoSendDraft.js +17 -0
  272. package/dist/chat/useAutoSendDraft.js.map +7 -0
  273. package/dist/chat/useBranchNavigation.js +97 -0
  274. package/dist/chat/useBranchNavigation.js.map +7 -0
  275. package/dist/chat/useConnectRunStream.js +169 -0
  276. package/dist/chat/useConnectRunStream.js.map +7 -0
  277. package/dist/chat/useConversation.js +431 -0
  278. package/dist/chat/useConversation.js.map +7 -0
  279. package/dist/chat/useConversationActions.js +662 -0
  280. package/dist/chat/useConversationActions.js.map +7 -0
  281. package/dist/chat/useConversationData.js +143 -0
  282. package/dist/chat/useConversationData.js.map +7 -0
  283. package/dist/chat/useConversationDocuments.js +41 -0
  284. package/dist/chat/useConversationDocuments.js.map +7 -0
  285. package/dist/chat/useConversationSettings.js +78 -0
  286. package/dist/chat/useConversationSettings.js.map +7 -0
  287. package/dist/chat/useConversationTurn.js +31 -0
  288. package/dist/chat/useConversationTurn.js.map +7 -0
  289. package/dist/chat/useConversationWorkspace.js +12 -0
  290. package/dist/chat/useConversationWorkspace.js.map +7 -0
  291. package/dist/chat/useDeleteMessage.js +15 -0
  292. package/dist/chat/useDeleteMessage.js.map +7 -0
  293. package/dist/chat/useDocumentAutoAdd.js +73 -0
  294. package/dist/chat/useDocumentAutoAdd.js.map +7 -0
  295. package/dist/chat/useMessageTimer.js +39 -0
  296. package/dist/chat/useMessageTimer.js.map +7 -0
  297. package/dist/chat/useThinkingContent.js +67 -0
  298. package/dist/chat/useThinkingContent.js.map +7 -0
  299. package/dist/chat/useThreadDocument.js +61 -0
  300. package/dist/chat/useThreadDocument.js.map +7 -0
  301. package/dist/chat/workflow-run-titles.js +50 -0
  302. package/dist/chat/workflow-run-titles.js.map +7 -0
  303. package/dist/config/config-hooks.js +209 -0
  304. package/dist/config/config-hooks.js.map +7 -0
  305. package/dist/connectivity.js +72 -0
  306. package/dist/connectivity.js.map +7 -0
  307. package/dist/connectors/hooks.js +263 -0
  308. package/dist/connectors/hooks.js.map +7 -0
  309. package/dist/connectors/index.js +28 -0
  310. package/dist/connectors/index.js.map +7 -0
  311. package/dist/contacts.js +100 -0
  312. package/dist/contacts.js.map +7 -0
  313. package/dist/conversation-list.js +65 -0
  314. package/dist/conversation-list.js.map +7 -0
  315. package/dist/databases.js +195 -0
  316. package/dist/databases.js.map +7 -0
  317. package/dist/datasets/aggregate.js +281 -0
  318. package/dist/datasets/aggregate.js.map +7 -0
  319. package/dist/datasets/index.js +122 -0
  320. package/dist/datasets/index.js.map +7 -0
  321. package/dist/datasets/members.js +27 -0
  322. package/dist/datasets/members.js.map +7 -0
  323. package/dist/datasets/panel.js +44 -0
  324. package/dist/datasets/panel.js.map +7 -0
  325. package/dist/datasets/registry.js +47 -0
  326. package/dist/datasets/registry.js.map +7 -0
  327. package/dist/datasets/rows-source.js +44 -0
  328. package/dist/datasets/rows-source.js.map +7 -0
  329. package/dist/datasets/sources/activity.js +83 -0
  330. package/dist/datasets/sources/activity.js.map +7 -0
  331. package/dist/datasets/sources/conversations.js +74 -0
  332. package/dist/datasets/sources/conversations.js.map +7 -0
  333. package/dist/datasets/sources/database.js +209 -0
  334. package/dist/datasets/sources/database.js.map +7 -0
  335. package/dist/datasets/sources/documents.js +93 -0
  336. package/dist/datasets/sources/documents.js.map +7 -0
  337. package/dist/datasets/sources/facts.js +56 -0
  338. package/dist/datasets/sources/facts.js.map +7 -0
  339. package/dist/datasets/sources/projects.js +117 -0
  340. package/dist/datasets/sources/projects.js.map +7 -0
  341. package/dist/datasets/sources/tags.js +67 -0
  342. package/dist/datasets/sources/tags.js.map +7 -0
  343. package/dist/datasets/sources/usage.js +268 -0
  344. package/dist/datasets/sources/usage.js.map +7 -0
  345. package/dist/datasets/sources/workflows.js +91 -0
  346. package/dist/datasets/sources/workflows.js.map +7 -0
  347. package/dist/datasets/sources/workspaces.js +67 -0
  348. package/dist/datasets/sources/workspaces.js.map +7 -0
  349. package/dist/datasets/store.js +194 -0
  350. package/dist/datasets/store.js.map +7 -0
  351. package/dist/datasets/types.js +14 -0
  352. package/dist/datasets/types.js.map +7 -0
  353. package/dist/directmessages/ConversationList.js +148 -0
  354. package/dist/directmessages/ConversationList.js.map +7 -0
  355. package/dist/directmessages/DateSeparator.js +8 -0
  356. package/dist/directmessages/DateSeparator.js.map +7 -0
  357. package/dist/directmessages/DmAvatar.js +29 -0
  358. package/dist/directmessages/DmAvatar.js.map +7 -0
  359. package/dist/directmessages/DmComposer.js +201 -0
  360. package/dist/directmessages/DmComposer.js.map +7 -0
  361. package/dist/directmessages/arrivals.js +29 -0
  362. package/dist/directmessages/arrivals.js.map +7 -0
  363. package/dist/directmessages/chat-cache.js +192 -0
  364. package/dist/directmessages/chat-cache.js.map +7 -0
  365. package/dist/directmessages/grouping.js +26 -0
  366. package/dist/directmessages/grouping.js.map +7 -0
  367. package/dist/directmessages/index.js +81 -0
  368. package/dist/directmessages/index.js.map +7 -0
  369. package/dist/directmessages/useChats.js +266 -0
  370. package/dist/directmessages/useChats.js.map +7 -0
  371. package/dist/directmessages/utils.js +23 -0
  372. package/dist/directmessages/utils.js.map +7 -0
  373. package/dist/document-tools/can-annotate.js +7 -0
  374. package/dist/document-tools/can-annotate.js.map +7 -0
  375. package/dist/document-tools/core.js +218 -12
  376. package/dist/document-tools/core.js.map +7 -1
  377. package/dist/document-tools/document-pdf.js +76 -0
  378. package/dist/document-tools/document-pdf.js.map +7 -0
  379. package/dist/document-tools/environment.js +136 -0
  380. package/dist/document-tools/environment.js.map +7 -0
  381. package/dist/document-tools/file-shares.js +112 -0
  382. package/dist/document-tools/file-shares.js.map +7 -0
  383. package/dist/document-tools/frozen-copy.js +27 -0
  384. package/dist/document-tools/frozen-copy.js.map +7 -0
  385. package/dist/document-tools/index.js +26 -148
  386. package/dist/document-tools/index.js.map +7 -1
  387. package/dist/document-tools/markup-download.js +51 -0
  388. package/dist/document-tools/markup-download.js.map +7 -0
  389. package/dist/document-tools/markup-store.js +138 -0
  390. package/dist/document-tools/markup-store.js.map +7 -0
  391. package/dist/document-tools/markup-transfer.js +88 -0
  392. package/dist/document-tools/markup-transfer.js.map +7 -0
  393. package/dist/document-tools/production.js +147 -0
  394. package/dist/document-tools/production.js.map +7 -0
  395. package/dist/document-tools/saved-signature.js +90 -0
  396. package/dist/document-tools/saved-signature.js.map +7 -0
  397. package/dist/document-tools/signature-requests.js +310 -0
  398. package/dist/document-tools/signature-requests.js.map +7 -0
  399. package/dist/document-tools/signing.js +127 -0
  400. package/dist/document-tools/signing.js.map +7 -0
  401. package/dist/document-tools/useDocumentBytes.js +38 -0
  402. package/dist/document-tools/useDocumentBytes.js.map +7 -0
  403. package/dist/document-tools/useDocumentMarkup.js +154 -0
  404. package/dist/document-tools/useDocumentMarkup.js.map +7 -0
  405. package/dist/document-tools/useIsOnline.js +13 -0
  406. package/dist/document-tools/useIsOnline.js.map +7 -0
  407. package/dist/document-tools/verification.js +60 -0
  408. package/dist/document-tools/verification.js.map +7 -0
  409. package/dist/documents/DocumentReview.js +220 -0
  410. package/dist/documents/DocumentReview.js.map +7 -0
  411. package/dist/documents/DraftTitleControls.js +41 -0
  412. package/dist/documents/DraftTitleControls.js.map +7 -0
  413. package/dist/documents/InlineMicButton.js +90 -0
  414. package/dist/documents/InlineMicButton.js.map +7 -0
  415. package/dist/documents/MicRecordingOverlay.js +29 -0
  416. package/dist/documents/MicRecordingOverlay.js.map +7 -0
  417. package/dist/documents/MicWaveformIndicator.js +68 -0
  418. package/dist/documents/MicWaveformIndicator.js.map +7 -0
  419. package/dist/documents/PhotoCapture.js +120 -0
  420. package/dist/documents/PhotoCapture.js.map +7 -0
  421. package/dist/documents/VideoCapture.js +129 -0
  422. package/dist/documents/VideoCapture.js.map +7 -0
  423. package/dist/documents/VoiceNoteRecorder.js +166 -0
  424. package/dist/documents/VoiceNoteRecorder.js.map +7 -0
  425. package/dist/documents/audio-segmenter.js +63 -0
  426. package/dist/documents/audio-segmenter.js.map +7 -0
  427. package/dist/documents/capture-frame.js +21 -0
  428. package/dist/documents/capture-frame.js.map +7 -0
  429. package/dist/documents/chunked-recorder.js +190 -0
  430. package/dist/documents/chunked-recorder.js.map +7 -0
  431. package/dist/documents/document-download.js +53 -0
  432. package/dist/documents/document-download.js.map +7 -0
  433. package/dist/documents/document-fields.js +109 -0
  434. package/dist/documents/document-fields.js.map +7 -0
  435. package/dist/documents/documents-cache.js +110 -0
  436. package/dist/documents/documents-cache.js.map +7 -0
  437. package/dist/documents/documents-data.js +128 -0
  438. package/dist/documents/documents-data.js.map +7 -0
  439. package/dist/documents/documents-loader.js +113 -0
  440. package/dist/documents/documents-loader.js.map +7 -0
  441. package/dist/documents/documents-writes.js +448 -0
  442. package/dist/documents/documents-writes.js.map +7 -0
  443. package/dist/documents/format-elapsed.js +10 -0
  444. package/dist/documents/format-elapsed.js.map +7 -0
  445. package/dist/documents/has-video-track.js +26 -0
  446. package/dist/documents/has-video-track.js.map +7 -0
  447. package/dist/documents/index.js +266 -0
  448. package/dist/documents/index.js.map +7 -0
  449. package/dist/documents/media-error.js +18 -0
  450. package/dist/documents/media-error.js.map +7 -0
  451. package/dist/documents/offline-documents.js +160 -0
  452. package/dist/documents/offline-documents.js.map +7 -0
  453. package/dist/documents/pending-sync.js +210 -0
  454. package/dist/documents/pending-sync.js.map +7 -0
  455. package/dist/documents/processing-live.js +122 -0
  456. package/dist/documents/processing-live.js.map +7 -0
  457. package/dist/documents/processing-order.js +59 -0
  458. package/dist/documents/processing-order.js.map +7 -0
  459. package/dist/documents/processing-settle.js +21 -0
  460. package/dist/documents/processing-settle.js.map +7 -0
  461. package/dist/documents/related-documents.js +133 -0
  462. package/dist/documents/related-documents.js.map +7 -0
  463. package/dist/documents/support.js +29 -0
  464. package/dist/documents/support.js.map +7 -0
  465. package/dist/documents/upload-files.js +169 -0
  466. package/dist/documents/upload-files.js.map +7 -0
  467. package/dist/documents/useAudioRecorder.js +315 -0
  468. package/dist/documents/useAudioRecorder.js.map +7 -0
  469. package/dist/documents/useCameraStream.js +35 -0
  470. package/dist/documents/useCameraStream.js.map +7 -0
  471. package/dist/documents/useDocumentThumbnails.js +71 -0
  472. package/dist/documents/useDocumentThumbnails.js.map +7 -0
  473. package/dist/documents/useDownloadDocuments.js +90 -0
  474. package/dist/documents/useDownloadDocuments.js.map +7 -0
  475. package/dist/documents/usePassageQuotes.js +37 -0
  476. package/dist/documents/usePassageQuotes.js.map +7 -0
  477. package/dist/documents/useUploadFiles.js +165 -0
  478. package/dist/documents/useUploadFiles.js.map +7 -0
  479. package/dist/documents/useUploadFromUrls.js +63 -0
  480. package/dist/documents/useUploadFromUrls.js.map +7 -0
  481. package/dist/documents/useVideoRecorder.js +62 -0
  482. package/dist/documents/useVideoRecorder.js.map +7 -0
  483. package/dist/entities/AgentMarkers.js +61 -0
  484. package/dist/entities/AgentMarkers.js.map +7 -0
  485. package/dist/entities/DocumentEntity.js +125 -0
  486. package/dist/entities/DocumentEntity.js.map +7 -0
  487. package/dist/entities/EntityPill.js +250 -0
  488. package/dist/entities/EntityPill.js.map +7 -0
  489. package/dist/entities/ProjectEntity.js +61 -0
  490. package/dist/entities/ProjectEntity.js.map +7 -0
  491. package/dist/entities/ShieldIcon.js +49 -0
  492. package/dist/entities/ShieldIcon.js.map +7 -0
  493. package/dist/entities/TagEntity.js +79 -0
  494. package/dist/entities/TagEntity.js.map +7 -0
  495. package/dist/entities/ThreadVisibilityIcon.js +15 -0
  496. package/dist/entities/ThreadVisibilityIcon.js.map +7 -0
  497. package/dist/entities/UserEntity.js +211 -0
  498. package/dist/entities/UserEntity.js.map +7 -0
  499. package/dist/entities/VerifiedBadge.js +19 -0
  500. package/dist/entities/VerifiedBadge.js.map +7 -0
  501. package/dist/entities/agent-avatar-colors.js +26 -0
  502. package/dist/entities/agent-avatar-colors.js.map +7 -0
  503. package/dist/entities/colors.js +64 -0
  504. package/dist/entities/colors.js.map +7 -0
  505. package/dist/entities/file-type.js +151 -0
  506. package/dist/entities/file-type.js.map +7 -0
  507. package/dist/entities/index.js +100 -0
  508. package/dist/entities/index.js.map +7 -0
  509. package/dist/entities/media-type.js +61 -0
  510. package/dist/entities/media-type.js.map +7 -0
  511. package/dist/entities/registry.js +385 -0
  512. package/dist/entities/registry.js.map +7 -0
  513. package/dist/entities/status.js +43 -0
  514. package/dist/entities/status.js.map +7 -0
  515. package/dist/entities/tag-kinds.js +23 -0
  516. package/dist/entities/tag-kinds.js.map +7 -0
  517. package/dist/entities/tag-types.js +44 -0
  518. package/dist/entities/tag-types.js.map +7 -0
  519. package/dist/entities/vocabulary.js +12 -0
  520. package/dist/entities/vocabulary.js.map +7 -0
  521. package/dist/entity-extraction.js +25 -0
  522. package/dist/entity-extraction.js.map +7 -0
  523. package/dist/facts-search.js +57 -0
  524. package/dist/facts-search.js.map +7 -0
  525. package/dist/facts.js +69 -0
  526. package/dist/facts.js.map +7 -0
  527. package/dist/hooks.js +320 -0
  528. package/dist/hooks.js.map +7 -0
  529. package/dist/host/ArbiHost.js +24 -0
  530. package/dist/host/ArbiHost.js.map +7 -0
  531. package/dist/host/assistant-copy.js +54 -0
  532. package/dist/host/assistant-copy.js.map +7 -0
  533. package/dist/host/config.js +9 -0
  534. package/dist/host/config.js.map +7 -0
  535. package/dist/host/context.js +10 -0
  536. package/dist/host/context.js.map +7 -0
  537. package/dist/host/features.js +144 -0
  538. package/dist/host/features.js.map +7 -0
  539. package/dist/host/index.js +12 -0
  540. package/dist/host/index.js.map +7 -0
  541. package/dist/{chunk-DPYBZDJB.js → host/merge.js} +7 -7
  542. package/dist/host/merge.js.map +7 -0
  543. package/dist/house-template.js +40 -0
  544. package/dist/house-template.js.map +7 -0
  545. package/dist/icons/AppleIcon.js +25 -0
  546. package/dist/icons/AppleIcon.js.map +7 -0
  547. package/dist/icons/ArbiBotHeadIcon.js +46 -0
  548. package/dist/icons/ArbiBotHeadIcon.js.map +7 -0
  549. package/dist/icons/ArbiIcon.js +24 -0
  550. package/dist/icons/ArbiIcon.js.map +7 -0
  551. package/dist/icons/AudIcon.js +56 -0
  552. package/dist/icons/AudIcon.js.map +7 -0
  553. package/dist/icons/ClaudeIcon.js +28 -0
  554. package/dist/icons/ClaudeIcon.js.map +7 -0
  555. package/dist/icons/DocIcon.js +56 -0
  556. package/dist/icons/DocIcon.js.map +7 -0
  557. package/dist/icons/EmlIcon.js +57 -0
  558. package/dist/icons/EmlIcon.js.map +7 -0
  559. package/dist/icons/FireworksIcon.js +47 -0
  560. package/dist/icons/FireworksIcon.js.map +7 -0
  561. package/dist/icons/GeminiIcon.js +37 -0
  562. package/dist/icons/GeminiIcon.js.map +7 -0
  563. package/dist/icons/GitHubIcon.js +32 -0
  564. package/dist/icons/GitHubIcon.js.map +7 -0
  565. package/dist/icons/GoogleIcon.js +53 -0
  566. package/dist/icons/GoogleIcon.js.map +7 -0
  567. package/dist/icons/HtmlIcon.js +56 -0
  568. package/dist/icons/HtmlIcon.js.map +7 -0
  569. package/dist/icons/ImgIcon.js +56 -0
  570. package/dist/icons/ImgIcon.js.map +7 -0
  571. package/dist/icons/LinkedInIcon.js +25 -0
  572. package/dist/icons/LinkedInIcon.js.map +7 -0
  573. package/dist/icons/OpenAIIcon.js +28 -0
  574. package/dist/icons/OpenAIIcon.js.map +7 -0
  575. package/dist/icons/PdfIcon.js +56 -0
  576. package/dist/icons/PdfIcon.js.map +7 -0
  577. package/dist/icons/ProviderIcon.js +42 -0
  578. package/dist/icons/ProviderIcon.js.map +7 -0
  579. package/dist/icons/TxtIcon.js +56 -0
  580. package/dist/icons/TxtIcon.js.map +7 -0
  581. package/dist/icons/VidIcon.js +56 -0
  582. package/dist/icons/VidIcon.js.map +7 -0
  583. package/dist/icons/XlsIcon.js +56 -0
  584. package/dist/icons/XlsIcon.js.map +7 -0
  585. package/dist/icons/arbi-mark.js +5 -0
  586. package/dist/icons/arbi-mark.js.map +7 -0
  587. package/dist/icons/colors.js +31 -0
  588. package/dist/icons/colors.js.map +7 -0
  589. package/dist/icons/file-type.js +105 -0
  590. package/dist/icons/file-type.js.map +7 -0
  591. package/dist/icons/index.js +55 -0
  592. package/dist/icons/index.js.map +7 -0
  593. package/dist/imagecrop/ImageCropModal.js +56 -0
  594. package/dist/imagecrop/ImageCropModal.js.map +7 -0
  595. package/dist/imagecrop/ImageCropper.js +100 -0
  596. package/dist/imagecrop/ImageCropper.js.map +7 -0
  597. package/dist/imagecrop/cropImage.js +43 -0
  598. package/dist/imagecrop/cropImage.js.map +7 -0
  599. package/dist/imagecrop/index.js +13 -0
  600. package/dist/imagecrop/index.js.map +7 -0
  601. package/dist/index.js +702 -17116
  602. package/dist/index.js.map +7 -1
  603. package/dist/{chunk-SSXFVWCT.js → lazy-chunk.js} +8 -8
  604. package/dist/lazy-chunk.js.map +7 -0
  605. package/dist/lib/collision-padding.js +13 -0
  606. package/dist/lib/collision-padding.js.map +7 -0
  607. package/dist/lib/format-friendly-date.js +55 -0
  608. package/dist/lib/format-friendly-date.js.map +7 -0
  609. package/dist/lib/format-relative-time.js +52 -0
  610. package/dist/lib/format-relative-time.js.map +7 -0
  611. package/dist/lib/markdown-to-text.js +35 -0
  612. package/dist/lib/markdown-to-text.js.map +7 -0
  613. package/dist/lib/toast-interaction.js +9 -0
  614. package/dist/lib/toast-interaction.js.map +7 -0
  615. package/dist/lib/utils.js +9 -0
  616. package/dist/lib/utils.js.map +7 -0
  617. package/dist/mail/client.js +103 -0
  618. package/dist/mail/client.js.map +7 -0
  619. package/dist/mail/document-attachment.js +38 -0
  620. package/dist/mail/document-attachment.js.map +7 -0
  621. package/dist/mail/filing.js +132 -0
  622. package/dist/mail/filing.js.map +7 -0
  623. package/dist/mail/hooks.js +393 -0
  624. package/dist/mail/hooks.js.map +7 -0
  625. package/dist/mail/index.js +120 -0
  626. package/dist/mail/index.js.map +7 -0
  627. package/dist/mail/offline/changes.js +258 -0
  628. package/dist/mail/offline/changes.js.map +7 -0
  629. package/dist/mail/offline/confirm-sign-out.js +37 -0
  630. package/dist/mail/offline/confirm-sign-out.js.map +7 -0
  631. package/dist/mail/offline/crypto.js +26 -0
  632. package/dist/mail/offline/crypto.js.map +7 -0
  633. package/dist/mail/offline/drafts.js +69 -0
  634. package/dist/mail/offline/drafts.js.map +7 -0
  635. package/dist/mail/offline/hooks.js +104 -0
  636. package/dist/mail/offline/hooks.js.map +7 -0
  637. package/dist/mail/offline/index.js +48 -0
  638. package/dist/mail/offline/index.js.map +7 -0
  639. package/dist/mail/offline/live.js +233 -0
  640. package/dist/mail/offline/live.js.map +7 -0
  641. package/dist/mail/offline/mailbox.js +191 -0
  642. package/dist/mail/offline/mailbox.js.map +7 -0
  643. package/dist/mail/offline/outbox.js +167 -0
  644. package/dist/mail/offline/outbox.js.map +7 -0
  645. package/dist/mail/offline/reads.js +159 -0
  646. package/dist/mail/offline/reads.js.map +7 -0
  647. package/dist/mail/offline/runtime.js +100 -0
  648. package/dist/mail/offline/runtime.js.map +7 -0
  649. package/dist/mail/offline/settings.js +84 -0
  650. package/dist/mail/offline/settings.js.map +7 -0
  651. package/dist/mail/offline/store.js +29 -0
  652. package/dist/mail/offline/store.js.map +7 -0
  653. package/dist/mail/offline/sync.js +251 -0
  654. package/dist/mail/offline/sync.js.map +7 -0
  655. package/dist/mail/offline/wipe.js +19 -0
  656. package/dist/mail/offline/wipe.js.map +7 -0
  657. package/dist/mail/thread-keys.js +53 -0
  658. package/dist/mail/thread-keys.js.map +7 -0
  659. package/dist/mail/threads.js +71 -0
  660. package/dist/mail/threads.js.map +7 -0
  661. package/dist/mail/useMailClient.js +42 -0
  662. package/dist/mail/useMailClient.js.map +7 -0
  663. package/dist/model-connections.js +58 -0
  664. package/dist/model-connections.js.map +7 -0
  665. package/dist/notifications/ActivityFeed.js +70 -0
  666. package/dist/notifications/ActivityFeed.js.map +7 -0
  667. package/dist/notifications/NotificationBell.js +200 -0
  668. package/dist/notifications/NotificationBell.js.map +7 -0
  669. package/dist/notifications/Toaster.js +24 -0
  670. package/dist/notifications/Toaster.js.map +7 -0
  671. package/dist/notifications/activity-types.js +65 -0
  672. package/dist/notifications/activity-types.js.map +7 -0
  673. package/dist/notifications/bell.js +24 -0
  674. package/dist/notifications/bell.js.map +7 -0
  675. package/dist/notifications/calendar-notifications.js +79 -0
  676. package/dist/notifications/calendar-notifications.js.map +7 -0
  677. package/dist/notifications/index.js +108 -0
  678. package/dist/notifications/index.js.map +7 -0
  679. package/dist/notifications/live.js +28 -0
  680. package/dist/notifications/live.js.map +7 -0
  681. package/dist/notifications/notification-types.js +127 -0
  682. package/dist/notifications/notification-types.js.map +7 -0
  683. package/dist/{chunk-BF5KW5ZI.js → notifications/notify-store.js} +24 -74
  684. package/dist/notifications/notify-store.js.map +7 -0
  685. package/dist/notifications/server-notifications.js +452 -0
  686. package/dist/notifications/server-notifications.js.map +7 -0
  687. package/dist/notifications/useNotifications.js +34 -0
  688. package/dist/notifications/useNotifications.js.map +7 -0
  689. package/dist/offline-store/network.js +11 -0
  690. package/dist/offline-store/network.js.map +7 -0
  691. package/dist/offline-store/store.js +136 -0
  692. package/dist/offline-store/store.js.map +7 -0
  693. package/dist/offline-store/wipe.js +8 -0
  694. package/dist/offline-store/wipe.js.map +7 -0
  695. package/dist/offline.js +58 -0
  696. package/dist/offline.js.map +7 -0
  697. package/dist/people.js +122 -0
  698. package/dist/people.js.map +7 -0
  699. package/dist/projects.js +30 -0
  700. package/dist/projects.js.map +7 -0
  701. package/dist/query-client.js +63 -0
  702. package/dist/query-client.js.map +7 -0
  703. package/dist/{chunk-ZM6N7YZH.js → query-keys.js} +18 -31
  704. package/dist/query-keys.js.map +7 -0
  705. package/dist/query-persist.js +66 -0
  706. package/dist/query-persist.js.map +7 -0
  707. package/dist/queued-writes.js +59 -0
  708. package/dist/queued-writes.js.map +7 -0
  709. package/dist/remote-control.js +67 -0
  710. package/dist/remote-control.js.map +7 -0
  711. package/dist/search/index.js +23 -0
  712. package/dist/search/index.js.map +7 -0
  713. package/dist/search/session.js +58 -0
  714. package/dist/search/session.js.map +7 -0
  715. package/dist/search/useSemanticSearch.js +82 -0
  716. package/dist/search/useSemanticSearch.js.map +7 -0
  717. package/dist/session/chat.js +512 -0
  718. package/dist/session/chat.js.map +7 -0
  719. package/dist/session/documents.js +196 -0
  720. package/dist/session/documents.js.map +7 -0
  721. package/dist/session/drafts.js +103 -0
  722. package/dist/session/drafts.js.map +7 -0
  723. package/dist/session/index.js +123 -0
  724. package/dist/session/index.js.map +7 -0
  725. package/dist/session/layout.js +339 -0
  726. package/dist/session/layout.js.map +7 -0
  727. package/dist/session/persist.js +106 -0
  728. package/dist/session/persist.js.map +7 -0
  729. package/dist/session/session-hooks.js +53 -0
  730. package/dist/session/session-hooks.js.map +7 -0
  731. package/dist/session/signed-in.js +36 -0
  732. package/dist/session/signed-in.js.map +7 -0
  733. package/dist/session/store.js +166 -0
  734. package/dist/session/store.js.map +7 -0
  735. package/dist/session/thread-tabs.js +121 -0
  736. package/dist/session/thread-tabs.js.map +7 -0
  737. package/dist/session/ui-state-storage.js +76 -0
  738. package/dist/session/ui-state-storage.js.map +7 -0
  739. package/dist/session/workspace.js +77 -0
  740. package/dist/session/workspace.js.map +7 -0
  741. package/dist/shell/index.js +43 -10
  742. package/dist/shell/index.js.map +7 -1
  743. package/dist/skill-pack.js +111 -0
  744. package/dist/skill-pack.js.map +7 -0
  745. package/dist/storage.js +186 -0
  746. package/dist/storage.js.map +7 -0
  747. package/dist/support/index.js +35 -0
  748. package/dist/support/index.js.map +7 -0
  749. package/dist/tags.js +204 -0
  750. package/dist/tags.js.map +7 -0
  751. package/dist/ui/DebouncedInput.js +109 -0
  752. package/dist/ui/DebouncedInput.js.map +7 -0
  753. package/dist/ui/DictateContext.js +8 -0
  754. package/dist/ui/DictateContext.js.map +7 -0
  755. package/dist/ui/IconToggle.js +79 -0
  756. package/dist/ui/IconToggle.js.map +7 -0
  757. package/dist/ui/VerifiedToggle.js +38 -0
  758. package/dist/ui/VerifiedToggle.js.map +7 -0
  759. package/dist/ui/VisibilityToggle.js +103 -0
  760. package/dist/ui/VisibilityToggle.js.map +7 -0
  761. package/dist/ui/avatar.js +40 -0
  762. package/dist/ui/avatar.js.map +7 -0
  763. package/dist/ui/badge.js +28 -0
  764. package/dist/ui/badge.js.map +7 -0
  765. package/dist/ui/button.js +48 -0
  766. package/dist/ui/button.js.map +7 -0
  767. package/dist/ui/card.js +90 -0
  768. package/dist/ui/card.js.map +7 -0
  769. package/dist/ui/checkbox.js +22 -0
  770. package/dist/ui/checkbox.js.map +7 -0
  771. package/dist/ui/collapsible.js +10 -0
  772. package/dist/ui/collapsible.js.map +7 -0
  773. package/dist/ui/command.js +103 -0
  774. package/dist/ui/command.js.map +7 -0
  775. package/dist/{chunk-YNNAJJ5Z.js → ui/dialog.js} +30 -68
  776. package/dist/ui/dialog.js.map +7 -0
  777. package/dist/{chunk-47CCGUWR.js → ui/dropdown-menu.js} +40 -45
  778. package/dist/ui/dropdown-menu.js.map +7 -0
  779. package/dist/ui/hover-card.js +36 -0
  780. package/dist/ui/hover-card.js.map +7 -0
  781. package/dist/ui/index.js +290 -10
  782. package/dist/ui/index.js.map +7 -1
  783. package/dist/ui/input.js +65 -0
  784. package/dist/ui/input.js.map +7 -0
  785. package/dist/ui/label.js +16 -0
  786. package/dist/ui/label.js.map +7 -0
  787. package/dist/ui/mark-menu.js +300 -0
  788. package/dist/ui/mark-menu.js.map +7 -0
  789. package/dist/ui/popover.js +40 -0
  790. package/dist/ui/popover.js.map +7 -0
  791. package/dist/ui/portal-container.js +17 -0
  792. package/dist/ui/portal-container.js.map +7 -0
  793. package/dist/ui/progress.js +24 -0
  794. package/dist/ui/progress.js.map +7 -0
  795. package/dist/ui/radio-group.js +29 -0
  796. package/dist/ui/radio-group.js.map +7 -0
  797. package/dist/ui/scroll-area.js +39 -0
  798. package/dist/ui/scroll-area.js.map +7 -0
  799. package/dist/ui/select.js +130 -0
  800. package/dist/ui/select.js.map +7 -0
  801. package/dist/ui/separator.js +23 -0
  802. package/dist/ui/separator.js.map +7 -0
  803. package/dist/ui/slider.js +23 -0
  804. package/dist/ui/slider.js.map +7 -0
  805. package/dist/ui/switch.js +28 -0
  806. package/dist/ui/switch.js.map +7 -0
  807. package/dist/ui/table.js +75 -0
  808. package/dist/ui/table.js.map +7 -0
  809. package/dist/ui/tabs.js +48 -0
  810. package/dist/ui/tabs.js.map +7 -0
  811. package/dist/ui/textarea.js +63 -0
  812. package/dist/ui/textarea.js.map +7 -0
  813. package/dist/ui/toggle-group.js +43 -0
  814. package/dist/ui/toggle-group.js.map +7 -0
  815. package/dist/ui/toggle.js +40 -0
  816. package/dist/ui/toggle.js.map +7 -0
  817. package/dist/ui/tooltip.js +215 -0
  818. package/dist/ui/tooltip.js.map +7 -0
  819. package/dist/usage-metered.js +8 -0
  820. package/dist/usage-metered.js.map +7 -0
  821. package/dist/useArbi.js +16 -0
  822. package/dist/useArbi.js.map +7 -0
  823. package/dist/useInstallSkillPack.js +81 -0
  824. package/dist/useInstallSkillPack.js.map +7 -0
  825. package/dist/usermenu/UserMenu.js +188 -0
  826. package/dist/usermenu/UserMenu.js.map +7 -0
  827. package/dist/usermenu/index.js +5 -0
  828. package/dist/usermenu/index.js.map +7 -0
  829. package/dist/users/index.js +15 -0
  830. package/dist/users/index.js.map +7 -0
  831. package/dist/users/user-display.js +60 -0
  832. package/dist/users/user-display.js.map +7 -0
  833. package/dist/viewers/AudioViewer.js +23 -0
  834. package/dist/viewers/AudioViewer.js.map +7 -0
  835. package/dist/viewers/DocxViewer.js +81 -0
  836. package/dist/viewers/DocxViewer.js.map +7 -0
  837. package/dist/viewers/ImageViewer.js +31 -0
  838. package/dist/viewers/ImageViewer.js.map +7 -0
  839. package/dist/viewers/PdfViewer.js +19 -3
  840. package/dist/viewers/PdfViewer.js.map +7 -1
  841. package/dist/{PdfViewerImpl-TEBYF2QI.js → viewers/PdfViewerImpl.js} +25 -19
  842. package/dist/viewers/PdfViewerImpl.js.map +7 -0
  843. package/dist/viewers/VideoViewer.js +31 -0
  844. package/dist/viewers/VideoViewer.js.map +7 -0
  845. package/dist/viewers/XlsxViewer.js +102 -0
  846. package/dist/viewers/XlsxViewer.js.map +7 -0
  847. package/dist/viewers/index.js +61 -271
  848. package/dist/viewers/index.js.map +7 -1
  849. package/dist/viewers/page-scroll.js +59 -0
  850. package/dist/viewers/page-scroll.js.map +7 -0
  851. package/dist/viewers/pdf-viewer-constants.js +9 -0
  852. package/dist/viewers/pdf-viewer-constants.js.map +7 -0
  853. package/dist/{chunk-PTOP7OHG.js → viewers/pdfjs-polyfills.js} +5 -6
  854. package/dist/viewers/pdfjs-polyfills.js.map +7 -0
  855. package/dist/viewers/selection-runs.js +38 -0
  856. package/dist/viewers/selection-runs.js.map +7 -0
  857. package/dist/viewers/usePageIntersectionObserver.js +68 -0
  858. package/dist/viewers/usePageIntersectionObserver.js.map +7 -0
  859. package/dist/viewers/useProcessedChunks.js +58 -0
  860. package/dist/viewers/useProcessedChunks.js.map +7 -0
  861. package/dist/viewers/viewer-zoom.js +163 -0
  862. package/dist/viewers/viewer-zoom.js.map +7 -0
  863. package/dist/websocket/ArbiWebSocketProvider.js +207 -0
  864. package/dist/websocket/ArbiWebSocketProvider.js.map +7 -0
  865. package/dist/websocket/context.js +14 -0
  866. package/dist/websocket/context.js.map +7 -0
  867. package/dist/websocket/hooks.js +30 -0
  868. package/dist/websocket/hooks.js.map +7 -0
  869. package/dist/websocket/index.js +22 -0
  870. package/dist/websocket/index.js.map +7 -0
  871. package/dist/websocket/live-updates.js +38 -0
  872. package/dist/websocket/live-updates.js.map +7 -0
  873. package/dist/websocket/reconnect.js +13 -0
  874. package/dist/websocket/reconnect.js.map +7 -0
  875. package/dist/websocket/store.js +58 -0
  876. package/dist/websocket/store.js.map +7 -0
  877. package/dist/workforce.js +607 -0
  878. package/dist/workforce.js.map +7 -0
  879. package/dist/workspaces/access-request.js +35 -0
  880. package/dist/workspaces/access-request.js.map +7 -0
  881. package/dist/workspaces/archive.js +59 -0
  882. package/dist/workspaces/archive.js.map +7 -0
  883. package/dist/workspaces/current.js +20 -0
  884. package/dist/workspaces/current.js.map +7 -0
  885. package/dist/workspaces/delete-workspaces.js +15 -0
  886. package/dist/workspaces/delete-workspaces.js.map +7 -0
  887. package/dist/workspaces/export-archive.js +40 -0
  888. package/dist/workspaces/export-archive.js.map +7 -0
  889. package/dist/workspaces/index.js +99 -0
  890. package/dist/workspaces/index.js.map +7 -0
  891. package/dist/workspaces/settings.js +45 -0
  892. package/dist/workspaces/settings.js.map +7 -0
  893. package/dist/workspaces/shell-workspaces.js +49 -0
  894. package/dist/workspaces/shell-workspaces.js.map +7 -0
  895. package/dist/workspaces/switch.js +234 -0
  896. package/dist/workspaces/switch.js.map +7 -0
  897. package/dist/workspaces/transfer.js +170 -0
  898. package/dist/workspaces/transfer.js.map +7 -0
  899. package/dist/workspaces/useShellWorkspaces.js +86 -0
  900. package/dist/workspaces/useShellWorkspaces.js.map +7 -0
  901. package/dist/workspaces/workspace-users.js +65 -0
  902. package/dist/workspaces/workspace-users.js.map +7 -0
  903. package/package.json +4 -4
  904. package/dist/PdfViewerImpl-TEBYF2QI.js.map +0 -1
  905. package/dist/PdfViewerImpl.d-B28hLEuj.d.cts +0 -62
  906. package/dist/ProductionDialog.d-CpzslFn0.d.cts +0 -51
  907. package/dist/annotations/freeze/index.d.cts +0 -205
  908. package/dist/annotations/index.d.cts +0 -360
  909. package/dist/artifacts/index.d.cts +0 -476
  910. package/dist/artifacts/redline-core.d.cts +0 -39
  911. package/dist/bundle-YNOX7VIL.js +0 -5
  912. package/dist/bundle-YNOX7VIL.js.map +0 -1
  913. package/dist/bundle.d-BnCSbHy2.d.cts +0 -85
  914. package/dist/calls/livekit/index.d.cts +0 -280
  915. package/dist/chunk-47CCGUWR.js.map +0 -1
  916. package/dist/chunk-4FL3X3LA.js +0 -2057
  917. package/dist/chunk-4FL3X3LA.js.map +0 -1
  918. package/dist/chunk-6QNBSXCE.js +0 -271
  919. package/dist/chunk-6QNBSXCE.js.map +0 -1
  920. package/dist/chunk-74N436VK.js.map +0 -1
  921. package/dist/chunk-APZZQZ6P.js +0 -147
  922. package/dist/chunk-APZZQZ6P.js.map +0 -1
  923. package/dist/chunk-BF5KW5ZI.js.map +0 -1
  924. package/dist/chunk-DPYBZDJB.js.map +0 -1
  925. package/dist/chunk-DZKRL5H3.js +0 -2766
  926. package/dist/chunk-DZKRL5H3.js.map +0 -1
  927. package/dist/chunk-HDCRPPBW.js +0 -75
  928. package/dist/chunk-HDCRPPBW.js.map +0 -1
  929. package/dist/chunk-L2IPPTVC.js +0 -20
  930. package/dist/chunk-L2IPPTVC.js.map +0 -1
  931. package/dist/chunk-LSU4UPS5.js +0 -1011
  932. package/dist/chunk-LSU4UPS5.js.map +0 -1
  933. package/dist/chunk-NIKPG4PW.js +0 -1128
  934. package/dist/chunk-NIKPG4PW.js.map +0 -1
  935. package/dist/chunk-NNAJLY6B.js +0 -4974
  936. package/dist/chunk-NNAJLY6B.js.map +0 -1
  937. package/dist/chunk-OYPKKHXY.js +0 -559
  938. package/dist/chunk-OYPKKHXY.js.map +0 -1
  939. package/dist/chunk-PTOP7OHG.js.map +0 -1
  940. package/dist/chunk-QMY2JKBI.js +0 -246
  941. package/dist/chunk-QMY2JKBI.js.map +0 -1
  942. package/dist/chunk-SN5YV6FF.js +0 -11
  943. package/dist/chunk-SN5YV6FF.js.map +0 -1
  944. package/dist/chunk-SSXFVWCT.js.map +0 -1
  945. package/dist/chunk-T3USOSVN.js.map +0 -1
  946. package/dist/chunk-T4CLW3DN.js +0 -2560
  947. package/dist/chunk-T4CLW3DN.js.map +0 -1
  948. package/dist/chunk-UW2SGTI5.js.map +0 -1
  949. package/dist/chunk-VSCU7K4V.js.map +0 -1
  950. package/dist/chunk-WL2Y2T47.js.map +0 -1
  951. package/dist/chunk-WUTL62MC.js.map +0 -1
  952. package/dist/chunk-XWPLOFDN.js +0 -644
  953. package/dist/chunk-XWPLOFDN.js.map +0 -1
  954. package/dist/chunk-Y3MTRA7D.js +0 -97
  955. package/dist/chunk-Y3MTRA7D.js.map +0 -1
  956. package/dist/chunk-YNNAJJ5Z.js.map +0 -1
  957. package/dist/chunk-ZM6N7YZH.js.map +0 -1
  958. package/dist/document-tools/core.d.cts +0 -883
  959. package/dist/document-tools/index.d.cts +0 -90
  960. package/dist/index.d-LArLnpI8.d.cts +0 -2036
  961. package/dist/index.d-oR5FKZpJ.d.cts +0 -579
  962. package/dist/index.d.cts +0 -15923
  963. package/dist/lazy-chunk.d-B6YDLMKI.d.cts +0 -31
  964. package/dist/model.d-CNtRWKVK.d.cts +0 -110
  965. package/dist/query-keys.d-B1Am9tIF.d.cts +0 -337
  966. package/dist/shell/index.d.cts +0 -6
  967. package/dist/store.d-GADDvC7w.d.cts +0 -35
  968. package/dist/stored-markdown.d-Bp18vrbr.d.cts +0 -125
  969. package/dist/ui/index.d.cts +0 -26
  970. package/dist/useAudioRecorder.d-B9rlMI_E.d.cts +0 -778
  971. package/dist/viewers/PdfViewer.d.cts +0 -9
  972. package/dist/viewers/index.d.cts +0 -262
@@ -0,0 +1,218 @@
1
+ import { continuityPrompt } from "@arbidocs/sdk/browser";
2
+ import { conversationKeyForCall, decryptPart, unwrapTrackKey } from "./recording.js";
3
+ import {
4
+ EXPORT_SAMPLE_RATE,
5
+ RECORDING_SEGMENTER,
6
+ createTrackCutter,
7
+ encodeWav,
8
+ floatToWav,
9
+ extensionFor,
10
+ fileSafe,
11
+ splitIntoFiles,
12
+ standalone,
13
+ timelineDurationMs,
14
+ timelineOf,
15
+ writeSamples
16
+ } from "./recording-playback.js";
17
+ import { storeTranscriptSegment } from "./transcription.js";
18
+ async function openRecording(arbi, queryClient, call, recordingExtId, loaded) {
19
+ const recording = loaded ?? await arbi.calls.recording.get(call.external_id, recordingExtId);
20
+ const convKeys = /* @__PURE__ */ new Map();
21
+ const keys = /* @__PURE__ */ new Map();
22
+ for (const track of recording.tracks ?? []) {
23
+ const version = track.key_version ?? null;
24
+ const id = String(version);
25
+ if (!convKeys.has(id)) {
26
+ convKeys.set(
27
+ id,
28
+ conversationKeyForCall(arbi, queryClient, call, { keyVersion: version }).then((c) => c.key)
29
+ );
30
+ }
31
+ try {
32
+ keys.set(track.external_id, await unwrapTrackKey(track.wrapped_key, await convKeys.get(id)));
33
+ } catch (err) {
34
+ console.warn("[calls] a recording track key does not open", err);
35
+ }
36
+ }
37
+ return { recording, keys };
38
+ }
39
+ function speakerTracks(recording) {
40
+ return (recording.tracks ?? []).filter((t) => t.kind === "speaker");
41
+ }
42
+ function compositeTrack(recording) {
43
+ return (recording.tracks ?? []).find((t) => t.kind === "composite") ?? null;
44
+ }
45
+ function sortedParts(track) {
46
+ return [...track.parts ?? []].sort((a, b) => a.seq - b.seq);
47
+ }
48
+ async function fetchPart(arbi, part, fileKey) {
49
+ if (!part.download_url) throw new Error("This recording\u2019s media was deleted");
50
+ return decryptPart(await arbi.calls.recording.downloadPart(part.download_url), fileKey);
51
+ }
52
+ async function compositeFiles(arbi, track, fileKey) {
53
+ const parts = [];
54
+ for (const part of sortedParts(track)) parts.push(await fetchPart(arbi, part, fileKey));
55
+ const type = track.mime_type.split(";")[0] || "video/webm";
56
+ return splitIntoFiles(parts).map((file) => new Blob(file.map(standalone), { type }));
57
+ }
58
+ async function decodeMono16k(bytes) {
59
+ const ctx = new OfflineAudioContext(1, 1, EXPORT_SAMPLE_RATE);
60
+ const buffer = await ctx.decodeAudioData(standalone(bytes).buffer);
61
+ return buffer.getChannelData(0);
62
+ }
63
+ async function speakerWav(arbi, track, fileKey, onPart) {
64
+ const parts = sortedParts(track);
65
+ const totalMs = timelineDurationMs(timelineOf([track]));
66
+ const samples = new Int16Array(Math.ceil(totalMs / 1e3 * EXPORT_SAMPLE_RATE) + 1);
67
+ for (const part of parts) {
68
+ const bytes = await fetchPart(arbi, part, fileKey);
69
+ try {
70
+ writeSamples(
71
+ samples,
72
+ await decodeMono16k(bytes),
73
+ part.offset_ms / 1e3 * EXPORT_SAMPLE_RATE
74
+ );
75
+ } catch (err) {
76
+ console.warn("[calls] a recording part does not decode", err);
77
+ }
78
+ onPart?.();
79
+ }
80
+ return new Blob([encodeWav(samples, EXPORT_SAMPLE_RATE)], { type: "audio/wav" });
81
+ }
82
+ async function recordingFiles(arbi, opened, title, onProgress) {
83
+ const { recording, keys } = opened;
84
+ const base = fileSafe(title || "Meeting");
85
+ const date = recording.started_at.slice(0, 10);
86
+ const total = (recording.tracks ?? []).reduce((n, t) => n + (t.parts?.length ?? 0), 0);
87
+ let done = 0;
88
+ const tick = () => onProgress?.(++done, total);
89
+ const files = [];
90
+ for (const track of speakerTracks(recording)) {
91
+ const key = keys.get(track.external_id);
92
+ if (!key || !track.parts?.length) continue;
93
+ const wav = await speakerWav(arbi, track, key, tick);
94
+ const who = fileSafe(track.speaker_name || track.speaker_ext_id || "speaker");
95
+ files.push(new File([wav], `${base}-${date}-${who}.wav`, { type: "audio/wav" }));
96
+ }
97
+ const composite = compositeTrack(recording);
98
+ const compositeKey = composite && keys.get(composite.external_id);
99
+ if (composite && compositeKey && composite.parts?.length) {
100
+ const videos = await compositeFiles(arbi, composite, compositeKey);
101
+ done += composite.parts.length;
102
+ onProgress?.(done, total);
103
+ const ext = extensionFor(composite.mime_type);
104
+ videos.forEach(
105
+ (blob, i) => files.push(
106
+ new File([blob], `${base}-${date}-video${videos.length > 1 ? `-${i + 1}` : ""}.${ext}`, {
107
+ type: blob.type
108
+ })
109
+ )
110
+ );
111
+ }
112
+ return files;
113
+ }
114
+ const PROMPT_HISTORY_CHARS = 400;
115
+ async function transcribeRecording(params) {
116
+ const {
117
+ arbi,
118
+ queryClient,
119
+ callExtId,
120
+ opened,
121
+ ref,
122
+ onProgress,
123
+ decode = decodeMono16k,
124
+ language
125
+ } = params;
126
+ const { recording, keys } = opened;
127
+ const tracks = speakerTracks(recording).filter((t) => keys.has(t.external_id));
128
+ const total = tracks.reduce((n, t) => n + (t.parts?.length ?? 0), 0);
129
+ const start = Date.parse(recording.started_at);
130
+ let done = 0;
131
+ let stored = 0;
132
+ let failed = 0;
133
+ for (const track of tracks) {
134
+ const key = keys.get(track.external_id);
135
+ const cutter = createTrackCutter(EXPORT_SAMPLE_RATE, RECORDING_SEGMENTER, { mergeShort: true });
136
+ let previous = "";
137
+ let nextSegment = 0;
138
+ const send = async (request) => {
139
+ try {
140
+ const result = await arbi.calls.recording.transcribe(callExtId, recording.external_id, {
141
+ audio: request.audio,
142
+ trackExtId: track.external_id,
143
+ seq: request.seq ?? null,
144
+ segment: request.segment ?? null,
145
+ segmentOffsetMs: request.seq == null ? request.offsetMs : 0,
146
+ language,
147
+ prompt: continuityPrompt(previous)
148
+ });
149
+ const text = result.text.trim();
150
+ if (!text) return;
151
+ previous = `${previous} ${text}`.slice(-PROMPT_HISTORY_CHARS);
152
+ const segment = {
153
+ segmentId: result.segment_id || (request.seq != null ? `rec-${track.external_id}-${request.seq}` : `rec-${track.external_id}-s${request.segment}`),
154
+ text,
155
+ speakerIdentity: result.speaker_ext_id ?? track.speaker_ext_id ?? "",
156
+ speakerName: result.speaker_name ?? track.speaker_name ?? "Speaker",
157
+ startedAt: Number.isFinite(start) ? new Date(start + (result.offset_ms ?? Math.round(request.offsetMs))).toISOString() : null
158
+ };
159
+ await storeTranscriptSegment(arbi, queryClient, ref, segment);
160
+ stored += 1;
161
+ } catch (err) {
162
+ failed += 1;
163
+ console.warn("[calls] a recording piece could not be transcribed", err);
164
+ }
165
+ };
166
+ const sendPieces = async (pieces) => {
167
+ for (const piece of pieces) {
168
+ await send({
169
+ audio: new Blob([floatToWav(piece.samples, EXPORT_SAMPLE_RATE)], { type: "audio/wav" }),
170
+ segment: nextSegment++,
171
+ offsetMs: piece.start / EXPORT_SAMPLE_RATE * 1e3
172
+ });
173
+ }
174
+ };
175
+ for (const part of sortedParts(track)) {
176
+ let bytes;
177
+ try {
178
+ bytes = await fetchPart(arbi, part, key);
179
+ } catch (err) {
180
+ failed += 1;
181
+ console.warn("[calls] a recording part could not be read", err);
182
+ onProgress?.(++done, total);
183
+ continue;
184
+ }
185
+ let pcm = null;
186
+ try {
187
+ pcm = await decode(bytes);
188
+ } catch (err) {
189
+ console.warn("[calls] a recording part does not decode; sending it whole", err);
190
+ }
191
+ if (pcm) {
192
+ await sendPieces(cutter.push(part.offset_ms, pcm));
193
+ } else {
194
+ await send({
195
+ audio: new Blob([standalone(bytes)], { type: track.mime_type }),
196
+ seq: part.seq,
197
+ offsetMs: part.offset_ms
198
+ });
199
+ }
200
+ onProgress?.(++done, total);
201
+ }
202
+ await sendPieces(cutter.finish());
203
+ }
204
+ return { stored, failed };
205
+ }
206
+ export {
207
+ compositeFiles,
208
+ compositeTrack,
209
+ decodeMono16k,
210
+ fetchPart,
211
+ openRecording,
212
+ recordingFiles,
213
+ sortedParts,
214
+ speakerTracks,
215
+ speakerWav,
216
+ transcribeRecording
217
+ };
218
+ //# sourceMappingURL=recording-media.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/calls/recording-media.ts"],
4
+ "sourcesContent": ["/**\n * A stored call recording, opened in the browser: keys unwrapped, parts downloaded and decrypted\n * on demand, exported as files, and transcribed (ARBI `docs/meeting-chats-plan.md` \u00A76).\n * See `recording-playback.ts` for the playback and export formats.\n */\n\nimport type { QueryClient } from '@tanstack/react-query'\nimport { continuityPrompt, type Arbi, type calls } from '@arbidocs/sdk/browser'\nimport { conversationKeyForCall, decryptPart, unwrapTrackKey } from './recording'\nimport {\n EXPORT_SAMPLE_RATE,\n RECORDING_SEGMENTER,\n createTrackCutter,\n encodeWav,\n floatToWav,\n extensionFor,\n fileSafe,\n splitIntoFiles,\n standalone,\n timelineDurationMs,\n timelineOf,\n writeSamples,\n type TrackPiece,\n} from './recording-playback'\nimport { storeTranscriptSegment, type TranscriptSegment } from './transcription'\nimport type { MeetingChatRef } from './meeting-chat'\n\nexport interface OpenedRecording {\n recording: calls.CallRecording\n /** File key per track ext id (a track whose key does not open is absent). */\n keys: Map<string, Uint8Array>\n}\n\n/** Read a recording and unwrap its tracks' file keys under the call's conversation key. */\nexport async function openRecording(\n arbi: Arbi,\n queryClient: QueryClient,\n call: calls.CallResponse,\n recordingExtId: string,\n loaded?: calls.CallRecording\n): Promise<OpenedRecording> {\n const recording = loaded ?? (await arbi.calls.recording.get(call.external_id, recordingExtId))\n const convKeys = new Map<string, Promise<Uint8Array>>()\n const keys = new Map<string, Uint8Array>()\n for (const track of recording.tracks ?? []) {\n const version = track.key_version ?? null\n const id = String(version)\n if (!convKeys.has(id)) {\n convKeys.set(\n id,\n conversationKeyForCall(arbi, queryClient, call, { keyVersion: version }).then((c) => c.key)\n )\n }\n try {\n keys.set(track.external_id, await unwrapTrackKey(track.wrapped_key, await convKeys.get(id)!))\n } catch (err) {\n console.warn('[calls] a recording track key does not open', err)\n }\n }\n return { recording, keys }\n}\n\nexport function speakerTracks(recording: calls.CallRecording): calls.RecordingTrack[] {\n return (recording.tracks ?? []).filter((t) => t.kind === 'speaker')\n}\n\nexport function compositeTrack(recording: calls.CallRecording): calls.RecordingTrack | null {\n return (recording.tracks ?? []).find((t) => t.kind === 'composite') ?? null\n}\n\nexport function sortedParts(track: calls.RecordingTrack): calls.RecordingPart[] {\n return [...(track.parts ?? [])].sort((a, b) => a.seq - b.seq)\n}\n\n/** One part's plaintext. */\nexport async function fetchPart(\n arbi: Arbi,\n part: calls.RecordingPart,\n fileKey: Uint8Array\n): Promise<Uint8Array> {\n if (!part.download_url) throw new Error('This recording\u2019s media was deleted')\n return decryptPart(await arbi.calls.recording.downloadPart(part.download_url), fileKey)\n}\n\n/** The composite as playable files (normally one). */\nexport async function compositeFiles(\n arbi: Arbi,\n track: calls.RecordingTrack,\n fileKey: Uint8Array\n): Promise<Blob[]> {\n const parts: Uint8Array[] = []\n for (const part of sortedParts(track)) parts.push(await fetchPart(arbi, part, fileKey))\n const type = track.mime_type.split(';')[0] || 'video/webm'\n return splitIntoFiles(parts).map((file) => new Blob(file.map(standalone), { type }))\n}\n\n/** Decode a standalone audio part to mono samples at 16 kHz (decodeAudioData resamples). */\nexport async function decodeMono16k(bytes: Uint8Array): Promise<Float32Array> {\n const ctx = new OfflineAudioContext(1, 1, EXPORT_SAMPLE_RATE)\n const buffer = await ctx.decodeAudioData(standalone(bytes).buffer)\n return buffer.getChannelData(0)\n}\n\n/** A speaker track as ONE WAV (16 kHz mono), its parts at their offsets from the recording start. */\nexport async function speakerWav(\n arbi: Arbi,\n track: calls.RecordingTrack,\n fileKey: Uint8Array,\n onPart?: () => void\n): Promise<Blob> {\n const parts = sortedParts(track)\n const totalMs = timelineDurationMs(timelineOf([track]))\n const samples = new Int16Array(Math.ceil((totalMs / 1000) * EXPORT_SAMPLE_RATE) + 1)\n // decodeAudioData resamples to the context's rate.\n for (const part of parts) {\n const bytes = await fetchPart(arbi, part, fileKey)\n try {\n writeSamples(\n samples,\n await decodeMono16k(bytes),\n (part.offset_ms / 1000) * EXPORT_SAMPLE_RATE\n )\n } catch (err) {\n console.warn('[calls] a recording part does not decode', err)\n }\n onPart?.()\n }\n return new Blob([encodeWav(samples, EXPORT_SAMPLE_RATE)], { type: 'audio/wav' })\n}\n\n/** Every decrypted file of a recording: one WAV per speaker, the composite as one video. */\nexport async function recordingFiles(\n arbi: Arbi,\n opened: OpenedRecording,\n title: string | null | undefined,\n onProgress?: (done: number, total: number) => void\n): Promise<File[]> {\n const { recording, keys } = opened\n const base = fileSafe(title || 'Meeting')\n const date = recording.started_at.slice(0, 10)\n const total = (recording.tracks ?? []).reduce((n, t) => n + (t.parts?.length ?? 0), 0)\n let done = 0\n const tick = () => onProgress?.(++done, total)\n const files: File[] = []\n for (const track of speakerTracks(recording)) {\n const key = keys.get(track.external_id)\n if (!key || !track.parts?.length) continue\n const wav = await speakerWav(arbi, track, key, tick)\n const who = fileSafe(track.speaker_name || track.speaker_ext_id || 'speaker')\n files.push(new File([wav], `${base}-${date}-${who}.wav`, { type: 'audio/wav' }))\n }\n const composite = compositeTrack(recording)\n const compositeKey = composite && keys.get(composite.external_id)\n if (composite && compositeKey && composite.parts?.length) {\n const videos = await compositeFiles(arbi, composite, compositeKey)\n done += composite.parts.length\n onProgress?.(done, total)\n const ext = extensionFor(composite.mime_type)\n videos.forEach((blob, i) =>\n files.push(\n new File([blob], `${base}-${date}-video${videos.length > 1 ? `-${i + 1}` : ''}.${ext}`, {\n type: blob.type,\n })\n )\n )\n }\n return files\n}\n\n/** A track's previous text, kept for the continuity prompt (a little more than it sends). */\nconst PROMPT_HISTORY_CHARS = 400\n\n/**\n * The host's \"Transcribe\": each speaker track is decrypted and decoded here part by part, its parts\n * placed on ONE continuous timeline by their offsets (gaps are silence) and cut at the track's\n * pauses ({@link createTrackCutter} with {@link RECORDING_SEGMENTER}: the live 700 ms pause rule,\n * pieces up to 25 s), so no sentence is split at a part boundary. Each piece (a 16 kHz mono WAV) is\n * sent through the shared transcription helper WITHOUT a part `seq`: its index across the track\n * (`segment`) and its start from the recording start (`segment_offset_ms`) \u2192 segment id\n * `rec-<track>-s<n>`. The user's language and the speaker's previous text (continuity prompt) go\n * with every piece.\n *\n * Each line is stored as an attributed transcript entry exactly like a live one (P5) \u2014 an E2E chat\n * message of kind `transcript` with `dedupe_key` = the segment id, or a thread comment with the\n * transcript marker \u2014 so running it twice stores each line once; the recording's lines then\n * supersede the live ones of the same window. A part this browser cannot decode is sent whole\n * (`rec-<track>-<seq>`) and is silence on the timeline.\n */\nexport async function transcribeRecording(params: {\n arbi: Arbi\n queryClient: QueryClient\n callExtId: string\n opened: OpenedRecording\n ref: MeetingChatRef\n onProgress?(done: number, total: number): void\n /** Decoder (tests); default WebAudio at 16 kHz. */\n decode?(bytes: Uint8Array): Promise<Float32Array>\n /** ISO-639-1 spoken language, when known; otherwise the transcriber detects it. */\n language?: string\n}): Promise<{ stored: number; failed: number }> {\n const {\n arbi,\n queryClient,\n callExtId,\n opened,\n ref,\n onProgress,\n decode = decodeMono16k,\n language,\n } = params\n const { recording, keys } = opened\n const tracks = speakerTracks(recording).filter((t) => keys.has(t.external_id))\n const total = tracks.reduce((n, t) => n + (t.parts?.length ?? 0), 0)\n const start = Date.parse(recording.started_at)\n let done = 0\n let stored = 0\n let failed = 0\n\n for (const track of tracks) {\n const key = keys.get(track.external_id)!\n const cutter = createTrackCutter(EXPORT_SAMPLE_RATE, RECORDING_SEGMENTER, { mergeShort: true })\n let previous = ''\n let nextSegment = 0\n\n const send = async (request: {\n audio: Blob\n seq?: number\n segment?: number\n /** From the recording start (a piece), or from the part start (a whole part: 0). */\n offsetMs: number\n }) => {\n try {\n const result = await arbi.calls.recording.transcribe(callExtId, recording.external_id, {\n audio: request.audio,\n trackExtId: track.external_id,\n seq: request.seq ?? null,\n segment: request.segment ?? null,\n segmentOffsetMs: request.seq == null ? request.offsetMs : 0,\n language,\n prompt: continuityPrompt(previous),\n })\n const text = result.text.trim()\n if (!text) return\n previous = `${previous} ${text}`.slice(-PROMPT_HISTORY_CHARS)\n const segment: TranscriptSegment = {\n segmentId:\n result.segment_id ||\n (request.seq != null\n ? `rec-${track.external_id}-${request.seq}`\n : `rec-${track.external_id}-s${request.segment}`),\n text,\n speakerIdentity: result.speaker_ext_id ?? track.speaker_ext_id ?? '',\n speakerName: result.speaker_name ?? track.speaker_name ?? 'Speaker',\n startedAt: Number.isFinite(start)\n ? new Date(start + (result.offset_ms ?? Math.round(request.offsetMs))).toISOString()\n : null,\n }\n await storeTranscriptSegment(arbi, queryClient, ref, segment)\n stored += 1\n } catch (err) {\n failed += 1\n console.warn('[calls] a recording piece could not be transcribed', err)\n }\n }\n const sendPieces = async (pieces: TrackPiece[]) => {\n for (const piece of pieces) {\n await send({\n audio: new Blob([floatToWav(piece.samples, EXPORT_SAMPLE_RATE)], { type: 'audio/wav' }),\n segment: nextSegment++,\n offsetMs: (piece.start / EXPORT_SAMPLE_RATE) * 1000,\n })\n }\n }\n\n for (const part of sortedParts(track)) {\n let bytes: Uint8Array\n try {\n bytes = await fetchPart(arbi, part, key)\n } catch (err) {\n failed += 1\n console.warn('[calls] a recording part could not be read', err)\n onProgress?.(++done, total)\n continue\n }\n let pcm: Float32Array | null = null\n try {\n pcm = await decode(bytes)\n } catch (err) {\n console.warn('[calls] a recording part does not decode; sending it whole', err)\n }\n if (pcm) {\n await sendPieces(cutter.push(part.offset_ms, pcm))\n } else {\n await send({\n audio: new Blob([standalone(bytes)], { type: track.mime_type }),\n seq: part.seq,\n offsetMs: part.offset_ms,\n })\n }\n onProgress?.(++done, total)\n }\n // The end of the track: the last piece (a closing line) is sent too.\n await sendPieces(cutter.finish())\n }\n return { stored, failed }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,260 @@
1
+ import {
2
+ DEFAULT_SEGMENTER_CONFIG,
3
+ INITIAL_SEGMENTER_STATE,
4
+ flushSegmenter,
5
+ levelFromRms,
6
+ stepSegmenter
7
+ } from "../documents/audio-segmenter.js";
8
+ const partKey = (p) => `${p.trackExtId}:${p.seq}`;
9
+ function timelineOf(tracks) {
10
+ return tracks.flatMap(
11
+ (t) => (t.parts ?? []).map((p) => ({
12
+ trackExtId: t.external_id,
13
+ seq: p.seq,
14
+ offsetMs: p.offset_ms,
15
+ durationMs: p.duration_ms
16
+ }))
17
+ ).sort((a, b) => a.offsetMs - b.offsetMs || a.seq - b.seq);
18
+ }
19
+ function timelineDurationMs(parts) {
20
+ return parts.reduce((max, p) => Math.max(max, p.offsetMs + p.durationMs), 0);
21
+ }
22
+ const PLAYBACK_LOOKAHEAD_MS = 2e4;
23
+ function partsDue(parts, playheadMs, lookaheadMs, scheduled) {
24
+ return parts.filter(
25
+ (p) => !scheduled.has(partKey(p)) && p.offsetMs < playheadMs + lookaheadMs && p.offsetMs + p.durationMs > playheadMs
26
+ );
27
+ }
28
+ function schedulePart(params) {
29
+ const { partOffsetMs, bufferDurationS, ctxStart, seekMs, ctxNow } = params;
30
+ let when = ctxStart + (partOffsetMs - seekMs) / 1e3;
31
+ let offset = 0;
32
+ if (when < ctxNow) {
33
+ offset = ctxNow - when;
34
+ when = ctxNow;
35
+ }
36
+ if (offset >= bufferDurationS) return null;
37
+ return { when, offset };
38
+ }
39
+ function playheadAt(ctxNow, ctxStart, seekMs) {
40
+ return seekMs + Math.max(0, ctxNow - ctxStart) * 1e3;
41
+ }
42
+ const EBML_MAGIC = [26, 69, 223, 163];
43
+ const FTYP = [102, 116, 121, 112];
44
+ function startsMediaFile(bytes) {
45
+ if (EBML_MAGIC.every((b, i) => bytes[i] === b)) return true;
46
+ return FTYP.every((b, i) => bytes[4 + i] === b);
47
+ }
48
+ function splitIntoFiles(parts) {
49
+ const files = [];
50
+ for (const part of parts) {
51
+ if (!files.length || startsMediaFile(part)) files.push([part]);
52
+ else files[files.length - 1].push(part);
53
+ }
54
+ return files;
55
+ }
56
+ function extensionFor(mimeType) {
57
+ if (mimeType.includes("mp4")) return mimeType.startsWith("video") ? "mp4" : "m4a";
58
+ if (mimeType.includes("ogg")) return "ogg";
59
+ return "webm";
60
+ }
61
+ function fileSafe(name) {
62
+ return name.replace(/[^\p{L}\p{N} ._-]+/gu, "").trim().replace(/\s+/g, "-").slice(0, 60) || "recording";
63
+ }
64
+ const EXPORT_SAMPLE_RATE = 16e3;
65
+ function writeSamples(target, samples, offsetSamples) {
66
+ const start = Math.max(0, Math.round(offsetSamples));
67
+ const n = Math.min(samples.length, target.length - start);
68
+ for (let i = 0; i < n; i++) {
69
+ const s = Math.max(-1, Math.min(1, samples[i]));
70
+ target[start + i] = s < 0 ? s * 32768 : s * 32767;
71
+ }
72
+ }
73
+ function encodeWav(samples, sampleRate) {
74
+ const dataBytes = samples.length * 2;
75
+ const out = new Uint8Array(44 + dataBytes);
76
+ const view = new DataView(out.buffer);
77
+ const ascii = (offset, text) => {
78
+ for (let i = 0; i < text.length; i++) out[offset + i] = text.charCodeAt(i);
79
+ };
80
+ ascii(0, "RIFF");
81
+ view.setUint32(4, 36 + dataBytes, true);
82
+ ascii(8, "WAVE");
83
+ ascii(12, "fmt ");
84
+ view.setUint32(16, 16, true);
85
+ view.setUint16(20, 1, true);
86
+ view.setUint16(22, 1, true);
87
+ view.setUint32(24, sampleRate, true);
88
+ view.setUint32(28, sampleRate * 2, true);
89
+ view.setUint16(32, 2, true);
90
+ view.setUint16(34, 16, true);
91
+ ascii(36, "data");
92
+ view.setUint32(40, dataBytes, true);
93
+ for (let i = 0; i < samples.length; i++) view.setInt16(44 + i * 2, samples[i], true);
94
+ return out;
95
+ }
96
+ function standalone(bytes) {
97
+ return new Uint8Array(bytes);
98
+ }
99
+ function floatToWav(samples, sampleRate) {
100
+ const pcm = new Int16Array(samples.length);
101
+ writeSamples(pcm, samples, 0);
102
+ return encodeWav(pcm, sampleRate);
103
+ }
104
+ const SEGMENT_FRAME_MS = 50;
105
+ const SEGMENT_PRE_ROLL_MS = 200;
106
+ const RECORDING_SEGMENTER = {
107
+ maxMs: 25e3,
108
+ minVoiceMs: 300,
109
+ silenceMs: 1500
110
+ };
111
+ const SHORT_PIECE_MERGE_GAP_MS = 1e3;
112
+ function createTrackCutter(sampleRate, config = {}, options = {}) {
113
+ const cfg = { ...DEFAULT_SEGMENTER_CONFIG, ...config };
114
+ const frame = Math.max(1, Math.round(sampleRate * SEGMENT_FRAME_MS / 1e3));
115
+ const preRoll = Math.round(SEGMENT_PRE_ROLL_MS / 1e3 * sampleRate);
116
+ const toSample = (ms) => Math.round(ms / 1e3 * sampleRate);
117
+ const toMs = (sample) => sample / sampleRate * 1e3;
118
+ let buf = new Float32Array(sampleRate * 4);
119
+ let bufStart = 0;
120
+ let len = 0;
121
+ let origin = null;
122
+ let cursor = 0;
123
+ let nextFrame = 0;
124
+ let state = INITIAL_SEGMENTER_STATE;
125
+ let pending = null;
126
+ let out = [];
127
+ const append = (samples) => {
128
+ if (len + samples.length > buf.length) {
129
+ const grown = new Float32Array(Math.max(buf.length * 2, len + samples.length));
130
+ grown.set(buf.subarray(0, len));
131
+ buf = grown;
132
+ }
133
+ buf.set(samples, len);
134
+ len += samples.length;
135
+ cursor += samples.length;
136
+ };
137
+ const emit = (piece) => {
138
+ const from = Math.max(piece.start, bufStart);
139
+ if (piece.end <= from) return;
140
+ out.push({
141
+ start: from,
142
+ end: piece.end,
143
+ voiceMs: piece.voiceMs,
144
+ samples: buf.slice(from - bufStart, piece.end - bufStart)
145
+ });
146
+ };
147
+ const onEvents = (events) => {
148
+ for (const e of events) {
149
+ if (e.type === "start") {
150
+ if (pending && e.at - pending.at > SHORT_PIECE_MERGE_GAP_MS) pending = null;
151
+ continue;
152
+ }
153
+ let piece = {
154
+ start: Math.max(origin ?? 0, toSample(e.startedAt) - preRoll),
155
+ end: Math.min(cursor, toSample(e.at)),
156
+ voiceMs: e.voiceMs,
157
+ at: e.at
158
+ };
159
+ if (pending) {
160
+ if (piece.end - pending.start <= toSample(cfg.maxMs) + preRoll) {
161
+ piece = { ...piece, start: pending.start, voiceMs: piece.voiceMs + pending.voiceMs };
162
+ }
163
+ pending = null;
164
+ }
165
+ if (piece.voiceMs >= cfg.minVoiceMs) emit(piece);
166
+ else if (options.mergeShort && piece.end > piece.start) pending = piece;
167
+ }
168
+ };
169
+ const step = (from, n) => {
170
+ let sum = 0;
171
+ const base = from - bufStart;
172
+ for (let j = 0; j < n; j++) sum += buf[base + j] * buf[base + j];
173
+ const result = stepSegmenter(state, levelFromRms(Math.sqrt(sum / n)), toMs(from), cfg);
174
+ state = result.state;
175
+ onEvents(result.events);
176
+ };
177
+ const run = () => {
178
+ while (nextFrame + frame <= cursor) {
179
+ step(nextFrame, frame);
180
+ nextFrame += frame;
181
+ }
182
+ let keepFrom = cursor - preRoll;
183
+ if (state.phase === "voice") keepFrom = Math.min(keepFrom, toSample(state.startedAt) - preRoll);
184
+ if (pending) keepFrom = Math.min(keepFrom, pending.start);
185
+ keepFrom = Math.min(Math.max(keepFrom, bufStart), nextFrame);
186
+ if (keepFrom > bufStart) {
187
+ buf.copyWithin(0, keepFrom - bufStart, len);
188
+ len -= keepFrom - bufStart;
189
+ bufStart = keepFrom;
190
+ }
191
+ };
192
+ const take = () => {
193
+ const done = out;
194
+ out = [];
195
+ return done;
196
+ };
197
+ return {
198
+ push(offsetMs, samples) {
199
+ const at = toSample(Math.max(0, offsetMs));
200
+ if (origin === null) {
201
+ origin = at;
202
+ bufStart = cursor = nextFrame = at;
203
+ }
204
+ if (at > cursor) {
205
+ const second = new Float32Array(sampleRate);
206
+ while (cursor < at) {
207
+ append(second.subarray(0, Math.min(sampleRate, at - cursor)));
208
+ run();
209
+ }
210
+ }
211
+ const fresh = at < cursor ? samples.subarray(Math.min(samples.length, cursor - at)) : samples;
212
+ if (fresh.length) {
213
+ append(fresh);
214
+ run();
215
+ }
216
+ return take();
217
+ },
218
+ finish() {
219
+ if (origin !== null) {
220
+ if (nextFrame < cursor) {
221
+ step(nextFrame, cursor - nextFrame);
222
+ nextFrame = cursor;
223
+ }
224
+ onEvents(flushSegmenter(state, toMs(cursor), cfg).events);
225
+ state = INITIAL_SEGMENTER_STATE;
226
+ }
227
+ pending = null;
228
+ return take();
229
+ }
230
+ };
231
+ }
232
+ function cutAtPauses(samples, sampleRate, config = {}) {
233
+ const cutter = createTrackCutter(sampleRate, config);
234
+ return [...cutter.push(0, samples), ...cutter.finish()].map(({ start, end }) => ({ start, end }));
235
+ }
236
+ export {
237
+ EXPORT_SAMPLE_RATE,
238
+ PLAYBACK_LOOKAHEAD_MS,
239
+ RECORDING_SEGMENTER,
240
+ SEGMENT_FRAME_MS,
241
+ SEGMENT_PRE_ROLL_MS,
242
+ SHORT_PIECE_MERGE_GAP_MS,
243
+ createTrackCutter,
244
+ cutAtPauses,
245
+ encodeWav,
246
+ extensionFor,
247
+ fileSafe,
248
+ floatToWav,
249
+ partKey,
250
+ partsDue,
251
+ playheadAt,
252
+ schedulePart,
253
+ splitIntoFiles,
254
+ standalone,
255
+ startsMediaFile,
256
+ timelineDurationMs,
257
+ timelineOf,
258
+ writeSamples
259
+ };
260
+ //# sourceMappingURL=recording-playback.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/calls/recording-playback.ts"],
4
+ "sourcesContent": ["/**\n * Playing and exporting a call recording in the browser (ARBI `docs/meeting-chats-plan.md` \u00A76).\n * Everything here works on DECRYPTED part bytes; nothing leaves the browser.\n *\n * Speaker audio \u2014 mixed in sync with WebAudio: each speaker part is a standalone file placed at its\n * `offset_ms` on one AudioContext timeline. Parts are fetched, decrypted and decoded only a little\n * ahead of the playhead ({@link partsDue}) and dropped once played, so an hour-long recording never\n * sits decoded in memory.\n *\n * Composite video \u2014 the host's composite is recorded as ONE continuous WebM (MediaRecorder\n * timeslice: only the first part carries the header), so its decrypted parts concatenated in order\n * ARE the file: it plays in a plain <video> and downloads as one file. This was chosen over\n * MediaSource (codec strings and append juggling per browser) and over part-by-part playback\n * (a visible gap every 30 s) as the simplest robust option. A reconnect of the host starts a new\n * file mid-recording; {@link splitIntoFiles} cuts at each new header, so each run plays on its own.\n *\n * Download \u2014 each speaker track becomes one WAV (16 kHz mono) with its parts at their offsets, so\n * every speaker's file starts at the recording's start and they line up in any editor.\n */\n\nimport type { calls } from '@arbidocs/sdk/browser'\nimport {\n DEFAULT_SEGMENTER_CONFIG,\n INITIAL_SEGMENTER_STATE,\n flushSegmenter,\n levelFromRms,\n stepSegmenter,\n type SegmenterConfig,\n type SegmenterEvent,\n type SegmenterState,\n} from '../documents/audio-segmenter'\n\n// \u2500\u2500 Timeline \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface TimelinePart {\n trackExtId: string\n seq: number\n offsetMs: number\n durationMs: number\n}\n\nexport const partKey = (p: Pick<TimelinePart, 'trackExtId' | 'seq'>) => `${p.trackExtId}:${p.seq}`\n\n/** Every part of the given tracks, in time order. */\nexport function timelineOf(\n tracks: Pick<calls.RecordingTrack, 'external_id' | 'parts'>[]\n): TimelinePart[] {\n return tracks\n .flatMap((t) =>\n (t.parts ?? []).map((p: calls.RecordingPart) => ({\n trackExtId: t.external_id,\n seq: p.seq,\n offsetMs: p.offset_ms,\n durationMs: p.duration_ms,\n }))\n )\n .sort((a, b) => a.offsetMs - b.offsetMs || a.seq - b.seq)\n}\n\n/** The recording's length: the end of its last part. */\nexport function timelineDurationMs(parts: TimelinePart[]): number {\n return parts.reduce((max, p) => Math.max(max, p.offsetMs + p.durationMs), 0)\n}\n\n/** How far ahead of the playhead parts are fetched and decoded. */\nexport const PLAYBACK_LOOKAHEAD_MS = 20_000\n\n/** Parts not yet scheduled that play within the window `[playhead, playhead + lookahead)`. */\nexport function partsDue(\n parts: TimelinePart[],\n playheadMs: number,\n lookaheadMs: number,\n scheduled: ReadonlySet<string>\n): TimelinePart[] {\n return parts.filter(\n (p) =>\n !scheduled.has(partKey(p)) &&\n p.offsetMs < playheadMs + lookaheadMs &&\n p.offsetMs + p.durationMs > playheadMs\n )\n}\n\n/**\n * When to start a decoded part on the AudioContext clock. Playback began at context time\n * `ctxStart` from recording position `seekMs`, so position `t` plays at\n * `ctxStart + (t \u2212 seekMs)/1000`. A part whose start already passed (a seek into it, or it decoded\n * late) starts now, `offset` seconds into its buffer. Null: nothing of it is left to play.\n */\nexport function schedulePart(params: {\n partOffsetMs: number\n bufferDurationS: number\n ctxStart: number\n seekMs: number\n ctxNow: number\n}): { when: number; offset: number } | null {\n const { partOffsetMs, bufferDurationS, ctxStart, seekMs, ctxNow } = params\n let when = ctxStart + (partOffsetMs - seekMs) / 1000\n let offset = 0\n if (when < ctxNow) {\n offset = ctxNow - when\n when = ctxNow\n }\n if (offset >= bufferDurationS) return null\n return { when, offset }\n}\n\n/** The recording position (ms) the AudioContext clock is at. */\nexport function playheadAt(ctxNow: number, ctxStart: number, seekMs: number): number {\n return seekMs + Math.max(0, ctxNow - ctxStart) * 1000\n}\n\n// \u2500\u2500 Files \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst EBML_MAGIC = [0x1a, 0x45, 0xdf, 0xa3]\nconst FTYP = [0x66, 0x74, 0x79, 0x70]\n\n/** Whether these bytes start a media file (a WebM/Matroska EBML header or an MP4 `ftyp` box). */\nexport function startsMediaFile(bytes: Uint8Array): boolean {\n if (EBML_MAGIC.every((b, i) => bytes[i] === b)) return true\n return FTYP.every((b, i) => bytes[4 + i] === b)\n}\n\n/** Consecutive parts grouped into files: a new file at each part that starts with a header. */\nexport function splitIntoFiles(parts: Uint8Array[]): Uint8Array[][] {\n const files: Uint8Array[][] = []\n for (const part of parts) {\n if (!files.length || startsMediaFile(part)) files.push([part])\n else files[files.length - 1].push(part)\n }\n return files\n}\n\n/** File extension for a recorded MIME type. */\nexport function extensionFor(mimeType: string): string {\n if (mimeType.includes('mp4')) return mimeType.startsWith('video') ? 'mp4' : 'm4a'\n if (mimeType.includes('ogg')) return 'ogg'\n return 'webm'\n}\n\n/** A safe file name piece. */\nexport function fileSafe(name: string): string {\n return (\n name\n .replace(/[^\\p{L}\\p{N} ._-]+/gu, '')\n .trim()\n .replace(/\\s+/g, '-')\n .slice(0, 60) || 'recording'\n )\n}\n\n// \u2500\u2500 WAV \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const EXPORT_SAMPLE_RATE = 16_000\n\n/** Copy decoded samples (\u22121\u20261) into a 16-bit timeline at `offsetSamples`, clipped. */\nexport function writeSamples(\n target: Int16Array,\n samples: Float32Array,\n offsetSamples: number\n): void {\n const start = Math.max(0, Math.round(offsetSamples))\n const n = Math.min(samples.length, target.length - start)\n for (let i = 0; i < n; i++) {\n const s = Math.max(-1, Math.min(1, samples[i]))\n target[start + i] = s < 0 ? s * 0x8000 : s * 0x7fff\n }\n}\n\n/** A mono 16-bit PCM WAV file. */\nexport function encodeWav(samples: Int16Array, sampleRate: number): Uint8Array<ArrayBuffer> {\n const dataBytes = samples.length * 2\n const out = new Uint8Array(44 + dataBytes)\n const view = new DataView(out.buffer)\n const ascii = (offset: number, text: string) => {\n for (let i = 0; i < text.length; i++) out[offset + i] = text.charCodeAt(i)\n }\n ascii(0, 'RIFF')\n view.setUint32(4, 36 + dataBytes, true)\n ascii(8, 'WAVE')\n ascii(12, 'fmt ')\n view.setUint32(16, 16, true)\n view.setUint16(20, 1, true) // PCM\n view.setUint16(22, 1, true) // mono\n view.setUint32(24, sampleRate, true)\n view.setUint32(28, sampleRate * 2, true)\n view.setUint16(32, 2, true)\n view.setUint16(34, 16, true)\n ascii(36, 'data')\n view.setUint32(40, dataBytes, true)\n for (let i = 0; i < samples.length; i++) view.setInt16(44 + i * 2, samples[i], true)\n return out\n}\n\n/** Bytes as a standalone ArrayBuffer-backed view (Blob/decodeAudioData want one). */\nexport function standalone(bytes: Uint8Array): Uint8Array<ArrayBuffer> {\n return new Uint8Array(bytes) as Uint8Array<ArrayBuffer>\n}\n\n/** Decoded mono samples as a 16-bit WAV. */\nexport function floatToWav(samples: Float32Array, sampleRate: number): Uint8Array<ArrayBuffer> {\n const pcm = new Int16Array(samples.length)\n writeSamples(pcm, samples, 0)\n return encodeWav(pcm, sampleRate)\n}\n\n// \u2500\u2500 Cutting at pauses (transcription) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** One piece of a part, in samples. */\nexport interface AudioPiece {\n start: number\n end: number\n}\n\n/** A piece of a whole track: absolute sample positions on the track's timeline, and its audio. */\nexport interface TrackPiece extends AudioPiece {\n samples: Float32Array\n /** Voiced time in the piece. */\n voiceMs: number\n}\n\n/** Meter frame for the segmenter (the live recorder's meter ticks every 50 ms). */\nexport const SEGMENT_FRAME_MS = 50\n/** Kept before a piece's first voiced frame, so a word's onset is not clipped. */\nexport const SEGMENT_PRE_ROLL_MS = 200\n\n/**\n * The segmenter for a RECORDED track (transcribed after the call). Nothing waits on it, so it cuts\n * only at a real turn: 1.5 s without voice (live uses 700 ms for latency). A speaker's own track is\n * silent for seconds while others talk, but a quiet syllable mid-sentence can read as a short\n * \"pause\" \u2014 the 3-person demo split \"\u2026two hundred and fifty / thousand pounds\u2026\" at 700 ms and the\n * cut half came back as \"$250,000\". A piece runs to 25 s before it is cut (a 25 s 16 kHz WAV is\n * ~0.8 MB, well under the 2 MB cap), and a piece needs only 300 ms of voice: a short closing line\n * (\"Perfect. Thank you both.\") is speech, not a click.\n */\nexport const RECORDING_SEGMENTER: Partial<SegmenterConfig> = {\n maxMs: 25_000,\n minVoiceMs: 300,\n silenceMs: 1_500,\n}\n/**\n * A recorded piece with too little voice is held, and joined to the next piece when that starts\n * within this gap (\"Perfect.\" \u2026 \"Thank you both.\"); otherwise it is dropped.\n */\nexport const SHORT_PIECE_MERGE_GAP_MS = 1000\n\nexport interface TrackCutter {\n /**\n * Feed the next decoded part, placed at `offsetMs` on the track's timeline (a gap before it is\n * silence; an overlap with what came before is skipped). Returns the pieces it completed.\n */\n push(offsetMs: number, samples: Float32Array): TrackPiece[]\n /** The end of the track: closes the open piece. Returns the pieces it completed. */\n finish(): TrackPiece[]\n}\n\n/**\n * Cut a whole track at its pauses, part after part, with the SAME voice-activity segmenter as live\n * transcription (P5): RMS per 50 ms frame \u2192 meter level \u2192 `stepSegmenter`. The parts are placed on\n * ONE continuous timeline by their offsets, so a sentence spoken across a part boundary stays one\n * piece. Only the open piece (\u2264 `maxMs`) is kept in memory, never the whole track.\n *\n * `mergeShort`: a piece with less voice than `minVoiceMs` is held and joined to the next one if it\n * starts within {@link SHORT_PIECE_MERGE_GAP_MS}, instead of being dropped at once.\n */\nexport function createTrackCutter(\n sampleRate: number,\n config: Partial<SegmenterConfig> = {},\n options: { mergeShort?: boolean } = {}\n): TrackCutter {\n const cfg = { ...DEFAULT_SEGMENTER_CONFIG, ...config }\n const frame = Math.max(1, Math.round((sampleRate * SEGMENT_FRAME_MS) / 1000))\n const preRoll = Math.round((SEGMENT_PRE_ROLL_MS / 1000) * sampleRate)\n const toSample = (ms: number) => Math.round((ms / 1000) * sampleRate)\n const toMs = (sample: number) => (sample / sampleRate) * 1000\n\n // Retained audio: `buf[0..len)` holds the absolute samples `[bufStart, bufStart + len)`.\n let buf = new Float32Array(sampleRate * 4)\n let bufStart = 0\n let len = 0\n /** Absolute index of the first sample of the timeline (null before the first part). */\n let origin: number | null = null\n /** Absolute index just past the last sample fed. */\n let cursor = 0\n /** Absolute index of the next meter frame. */\n let nextFrame = 0\n let state: SegmenterState = INITIAL_SEGMENTER_STATE\n /** A short piece waiting for the next one (mergeShort). */\n let pending: { start: number; end: number; voiceMs: number; at: number } | null = null\n let out: TrackPiece[] = []\n\n const append = (samples: Float32Array) => {\n if (len + samples.length > buf.length) {\n const grown = new Float32Array(Math.max(buf.length * 2, len + samples.length))\n grown.set(buf.subarray(0, len))\n buf = grown\n }\n buf.set(samples, len)\n len += samples.length\n cursor += samples.length\n }\n\n const emit = (piece: { start: number; end: number; voiceMs: number }) => {\n const from = Math.max(piece.start, bufStart)\n if (piece.end <= from) return\n out.push({\n start: from,\n end: piece.end,\n voiceMs: piece.voiceMs,\n samples: buf.slice(from - bufStart, piece.end - bufStart),\n })\n }\n\n const onEvents = (events: SegmenterEvent[]) => {\n for (const e of events) {\n if (e.type === 'start') {\n // Too long a pause after a held short piece: it stands alone, too short to keep.\n if (pending && e.at - pending.at > SHORT_PIECE_MERGE_GAP_MS) pending = null\n continue\n }\n let piece = {\n start: Math.max(origin ?? 0, toSample(e.startedAt) - preRoll),\n end: Math.min(cursor, toSample(e.at)),\n voiceMs: e.voiceMs,\n at: e.at,\n }\n if (pending) {\n if (piece.end - pending.start <= toSample(cfg.maxMs) + preRoll) {\n piece = { ...piece, start: pending.start, voiceMs: piece.voiceMs + pending.voiceMs }\n }\n pending = null\n }\n if (piece.voiceMs >= cfg.minVoiceMs) emit(piece)\n else if (options.mergeShort && piece.end > piece.start) pending = piece\n }\n }\n\n const step = (from: number, n: number) => {\n let sum = 0\n const base = from - bufStart\n for (let j = 0; j < n; j++) sum += buf[base + j] * buf[base + j]\n const result = stepSegmenter(state, levelFromRms(Math.sqrt(sum / n)), toMs(from), cfg)\n state = result.state\n onEvents(result.events)\n }\n\n /** Run the meter over every whole frame fed so far, then drop audio no piece can reach. */\n const run = () => {\n while (nextFrame + frame <= cursor) {\n step(nextFrame, frame)\n nextFrame += frame\n }\n let keepFrom = cursor - preRoll\n if (state.phase === 'voice') keepFrom = Math.min(keepFrom, toSample(state.startedAt) - preRoll)\n if (pending) keepFrom = Math.min(keepFrom, pending.start)\n keepFrom = Math.min(Math.max(keepFrom, bufStart), nextFrame)\n if (keepFrom > bufStart) {\n buf.copyWithin(0, keepFrom - bufStart, len)\n len -= keepFrom - bufStart\n bufStart = keepFrom\n }\n }\n\n const take = () => {\n const done = out\n out = []\n return done\n }\n\n return {\n push(offsetMs, samples) {\n const at = toSample(Math.max(0, offsetMs))\n if (origin === null) {\n origin = at\n bufStart = cursor = nextFrame = at\n }\n if (at > cursor) {\n // A gap between parts (a reconnect): silence, a second at a time.\n const second = new Float32Array(sampleRate)\n while (cursor < at) {\n append(second.subarray(0, Math.min(sampleRate, at - cursor)))\n run()\n }\n }\n // Overlapping the previous part: skip what is already on the timeline.\n const fresh = at < cursor ? samples.subarray(Math.min(samples.length, cursor - at)) : samples\n if (fresh.length) {\n append(fresh)\n run()\n }\n return take()\n },\n finish() {\n if (origin !== null) {\n if (nextFrame < cursor) {\n step(nextFrame, cursor - nextFrame)\n nextFrame = cursor\n }\n onEvents(flushSegmenter(state, toMs(cursor), cfg).events)\n state = INITIAL_SEGMENTER_STATE\n }\n pending = null\n return take()\n },\n }\n}\n\n/**\n * Cut decoded speech at its pauses with the SAME voice-activity segmenter as live transcription\n * (P5): RMS per 50 ms frame \u2192 meter level \u2192 `stepSegmenter` (a piece ends after ~700 ms of\n * silence, is cut at `maxMs`, and is dropped with too little voice). A whole 30 s part sent at\n * once made the transcriber drop repeated sentences; short pieces do not.\n */\nexport function cutAtPauses(\n samples: Float32Array,\n sampleRate: number,\n config: Partial<SegmenterConfig> = {}\n): AudioPiece[] {\n const cutter = createTrackCutter(sampleRate, config)\n return [...cutter.push(0, samples), ...cutter.finish()].map(({ start, end }) => ({ start, end }))\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }