@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,90 @@
1
+ import {
2
+ getUserEncryptionKeypair,
3
+ initSodium,
4
+ sealedBoxDecrypt,
5
+ sealedBoxEncrypt
6
+ } from "@arbidocs/client";
7
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
8
+ import { useDocumentTools } from "./environment.js";
9
+ import { arbiQueryKeys } from "../query-keys.js";
10
+ const INFORMAL_SIGNATURE_NOTE = "Your saved signature or initials are placed as an image on the document.";
11
+ async function keypair(source = getUserEncryptionKeypair) {
12
+ await initSodium();
13
+ const pair = await source();
14
+ if (!pair) throw new Error("Sign in again to use your saved signature.");
15
+ return pair;
16
+ }
17
+ function detail(error, fallback) {
18
+ const d = error?.detail;
19
+ return typeof d === "string" ? d : fallback;
20
+ }
21
+ async function fetchSavedSignature(client, source) {
22
+ const { data, error } = await client.GET("/v1/user/signature");
23
+ if (!data) throw new Error(detail(error, "Your saved signature could not be read"));
24
+ if (!data.sealed) return null;
25
+ const pair = await keypair(source);
26
+ const json = new TextDecoder().decode(sealedBoxDecrypt(data.sealed, pair.secretKey));
27
+ return JSON.parse(json);
28
+ }
29
+ async function storeSavedSignature(client, signature, source) {
30
+ const pair = await keypair(source);
31
+ const sealed = sealedBoxEncrypt(
32
+ Uint8Array.from(new TextEncoder().encode(JSON.stringify(signature))),
33
+ pair.publicKey
34
+ );
35
+ const { error, response } = await client.PUT("/v1/user/signature", { body: { sealed } });
36
+ if (!response.ok) throw new Error(detail(error, "Your signature could not be saved"));
37
+ }
38
+ async function deleteSavedSignature(client) {
39
+ const { error, response } = await client.DELETE("/v1/user/signature");
40
+ if (!response.ok) throw new Error(detail(error, "Your saved signature could not be deleted"));
41
+ }
42
+ function useSavedSignature(enabled = true) {
43
+ const { client } = useDocumentTools();
44
+ return useQuery({
45
+ queryKey: arbiQueryKeys.savedSignature(),
46
+ queryFn: () => fetchSavedSignature(client),
47
+ enabled,
48
+ staleTime: 6e4,
49
+ retry: false
50
+ });
51
+ }
52
+ function useStoreSavedSignature() {
53
+ const { client } = useDocumentTools();
54
+ const queryClient = useQueryClient();
55
+ return useMutation({
56
+ mutationFn: (signature) => storeSavedSignature(client, signature),
57
+ onSuccess: (_, signature) => queryClient.setQueryData(arbiQueryKeys.savedSignature(), signature)
58
+ });
59
+ }
60
+ function useDeleteSavedSignature() {
61
+ const { client } = useDocumentTools();
62
+ const queryClient = useQueryClient();
63
+ return useMutation({
64
+ mutationFn: () => deleteSavedSignature(client),
65
+ onSuccess: () => queryClient.setQueryData(arbiQueryKeys.savedSignature(), null)
66
+ });
67
+ }
68
+ function pngBytes(base64) {
69
+ const raw = atob(base64);
70
+ const out = new Uint8Array(raw.length);
71
+ for (let i = 0; i < raw.length; i++) out[i] = raw.charCodeAt(i);
72
+ return out;
73
+ }
74
+ function pngSize(base64) {
75
+ const bytes = pngBytes(base64.slice(0, 64));
76
+ const view = new DataView(bytes.buffer);
77
+ return { width: view.getUint32(16), height: view.getUint32(20) };
78
+ }
79
+ export {
80
+ INFORMAL_SIGNATURE_NOTE,
81
+ deleteSavedSignature,
82
+ fetchSavedSignature,
83
+ pngBytes,
84
+ pngSize,
85
+ storeSavedSignature,
86
+ useDeleteSavedSignature,
87
+ useSavedSignature,
88
+ useStoreSavedSignature
89
+ };
90
+ //# sourceMappingURL=saved-signature.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/document-tools/saved-signature.ts"],
4
+ "sourcesContent": ["/**\n * A signature saved to one's account, for informal use: inserted into a Word document as a picture,\n * or placed on a PDF as a stamp, and offered again the next time one adopts a signature to sign.\n *\n * It is sealed HERE, in the browser, to the user's own X25519 key (a SealedBox to the public half of\n * the keypair their signing key derives): the server keeps the sealed bytes (`/v1/user/signature`)\n * and can never read them. Only with the user's explicit consent (\"Save to my account for future\n * use\"); Delete removes it from the account completely. A typed mark is saved as its picture too,\n * so every use has an image to place.\n */\n\nimport {\n getUserEncryptionKeypair,\n initSodium,\n sealedBoxDecrypt,\n sealedBoxEncrypt,\n type KeyPair,\n} from '@arbidocs/client'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useDocumentTools, type DocumentToolsClient } from './environment'\nimport { arbiQueryKeys } from '../query-keys'\n\nexport interface SavedSignature {\n name: string\n initials: string\n /** How the signature was adopted (a typed one is saved as its picture as well). */\n style: 'typed' | 'drawn' | 'uploaded'\n initials_style: 'typed' | 'drawn'\n /** Base64 PNGs, transparent around the ink. */\n signature_png: string\n initials_png: string\n}\n\n/** The one line shown wherever a saved signature is placed by hand. */\nexport const INFORMAL_SIGNATURE_NOTE =\n 'Your saved signature or initials are placed as an image on the document.'\n\n/** The user's own keypair (the session's); a host or a test may pass another. */\nexport type KeypairSource = () => Promise<KeyPair | null>\n\nasync function keypair(source: KeypairSource = getUserEncryptionKeypair): Promise<KeyPair> {\n await initSodium()\n const pair = await source()\n if (!pair) throw new Error('Sign in again to use your saved signature.')\n return pair\n}\n\nfunction detail(error: unknown, fallback: string): string {\n const d = (error as { detail?: unknown } | undefined)?.detail\n return typeof d === 'string' ? d : fallback\n}\n\n/** The saved signature, opened with the user's own key; null when none is saved. */\nexport async function fetchSavedSignature(\n client: DocumentToolsClient,\n source?: KeypairSource\n): Promise<SavedSignature | null> {\n const { data, error } = await client.GET('/v1/user/signature')\n if (!data) throw new Error(detail(error, 'Your saved signature could not be read'))\n if (!data.sealed) return null\n const pair = await keypair(source)\n const json = new TextDecoder().decode(sealedBoxDecrypt(data.sealed, pair.secretKey))\n return JSON.parse(json) as SavedSignature\n}\n\n/** Seal it to the user's own key and save it (replacing any saved before). */\nexport async function storeSavedSignature(\n client: DocumentToolsClient,\n signature: SavedSignature,\n source?: KeypairSource\n): Promise<void> {\n const pair = await keypair(source)\n const sealed = sealedBoxEncrypt(\n Uint8Array.from(new TextEncoder().encode(JSON.stringify(signature))),\n pair.publicKey\n )\n const { error, response } = await client.PUT('/v1/user/signature', { body: { sealed } })\n if (!response.ok) throw new Error(detail(error, 'Your signature could not be saved'))\n}\n\n/** Remove it from the account completely. */\nexport async function deleteSavedSignature(client: DocumentToolsClient): Promise<void> {\n const { error, response } = await client.DELETE('/v1/user/signature')\n if (!response.ok) throw new Error(detail(error, 'Your saved signature could not be deleted'))\n}\n\nexport function useSavedSignature(enabled = true) {\n const { client } = useDocumentTools()\n return useQuery({\n queryKey: arbiQueryKeys.savedSignature(),\n queryFn: () => fetchSavedSignature(client),\n enabled,\n staleTime: 60_000,\n retry: false,\n })\n}\n\nexport function useStoreSavedSignature() {\n const { client } = useDocumentTools()\n const queryClient = useQueryClient()\n return useMutation({\n mutationFn: (signature: SavedSignature) => storeSavedSignature(client, signature),\n onSuccess: (_, signature) =>\n queryClient.setQueryData(arbiQueryKeys.savedSignature(), signature),\n })\n}\n\nexport function useDeleteSavedSignature() {\n const { client } = useDocumentTools()\n const queryClient = useQueryClient()\n return useMutation({\n mutationFn: () => deleteSavedSignature(client),\n onSuccess: () => queryClient.setQueryData(arbiQueryKeys.savedSignature(), null),\n })\n}\n\n/** Base64 PNG bytes, decoded (for an inline picture or an upload). */\nexport function pngBytes(base64: string): Uint8Array {\n const raw = atob(base64)\n const out = new Uint8Array(raw.length)\n for (let i = 0; i < raw.length; i++) out[i] = raw.charCodeAt(i)\n return out\n}\n\n/** A PNG's pixel size, read from its header (IHDR). */\nexport function pngSize(base64: string): { width: number; height: number } {\n const bytes = pngBytes(base64.slice(0, 64))\n const view = new DataView(bytes.buffer)\n return { width: view.getUint32(16), height: view.getUint32(20) }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,310 @@
1
+ import { signMessage, unlockIdentityWithPassword } from "@arbidocs/client";
2
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
3
+ import { workspaces } from "@arbidocs/sdk/browser";
4
+ import { useDocumentTools } from "./environment.js";
5
+ import { intentText, sha256Hex, SigningError } from "./signing.js";
6
+ import { arbiQueryKeys } from "../query-keys.js";
7
+ import { useArbiHost } from "../host/config.js";
8
+ function useOpenWorkspaceRead() {
9
+ const arbi = useArbiHost().arbi;
10
+ const workspaceId = arbi?.hasWorkspace ? arbi.getWorkspaceId() : void 0;
11
+ const read = (run) => arbi && workspaceId ? arbi.readInWorkspace(workspaceId, run) : run();
12
+ return { workspaceId, read };
13
+ }
14
+ const SIGNATURE_FIELD_TYPES = [
15
+ "signature",
16
+ "initials",
17
+ "date",
18
+ "name"
19
+ ];
20
+ const FIELD_TYPE_LABELS = {
21
+ signature: "Signature",
22
+ initials: "Initials",
23
+ date: "Date signed",
24
+ name: "Name"
25
+ };
26
+ const DEFAULT_FIELD_SIZE = {
27
+ signature: { width: 0.28, height: 0.05 },
28
+ initials: { width: 0.1, height: 0.04 },
29
+ date: { width: 0.22, height: 0.028 },
30
+ name: { width: 0.28, height: 0.028 }
31
+ };
32
+ const SIGNER_PROGRESS_LABELS = {
33
+ invited: "Invited",
34
+ registered: "Not opened yet",
35
+ viewed: "Viewed",
36
+ signed: "Signed",
37
+ declined: "Declined"
38
+ };
39
+ const EMAIL = /^[^@\s<>,;]{1,64}@[^@\s<>,;]{1,255}\.[^@\s<>,;]{1,63}$/;
40
+ const isEmailSigner = (signer) => EMAIL.test(signer.trim());
41
+ const MARK_FIELD_TYPES = ["signature", "initials"];
42
+ function detail(error, fallback) {
43
+ const d = error?.detail;
44
+ if (typeof d === "string") return d;
45
+ if (Array.isArray(d) && d[0] && typeof d[0] === "object" && "msg" in d[0]) {
46
+ return String(d[0].msg);
47
+ }
48
+ return fallback;
49
+ }
50
+ function newFieldId() {
51
+ return `f${Math.random().toString(36).slice(2, 10)}`;
52
+ }
53
+ function initialsOf(name) {
54
+ return name.split(/\s+/).filter(Boolean).map((part) => part[0].toUpperCase()).join("").slice(0, 4);
55
+ }
56
+ function fieldsInSigningOrder(fields, signer) {
57
+ return fields.filter((f) => f.signer === signer).sort((a, b) => a.page - b.page || a.y - b.y || a.x - b.x);
58
+ }
59
+ function sendBlocker(fields) {
60
+ if (fields.length === 0) return "Place at least one field.";
61
+ const signers = [...new Set(fields.map((f) => f.signer))];
62
+ for (const signer of signers) {
63
+ if (!fields.some((f) => f.signer === signer && MARK_FIELD_TYPES.includes(f.type))) {
64
+ return "Every signer needs a signature or initials field.";
65
+ }
66
+ }
67
+ return null;
68
+ }
69
+ function fieldsFromSuggestions(suggestions, assign, members = /* @__PURE__ */ new Map()) {
70
+ return suggestions.flatMap((s) => {
71
+ const email = s.signer_email?.toLowerCase();
72
+ const signer = email ? members.get(email) ?? email : assign[s.group];
73
+ if (!signer) return [];
74
+ return [
75
+ {
76
+ id: newFieldId(),
77
+ type: s.type,
78
+ page: s.page,
79
+ x: s.x,
80
+ y: s.y,
81
+ width: s.width,
82
+ height: s.height,
83
+ signer,
84
+ required: s.required ?? true
85
+ }
86
+ ];
87
+ });
88
+ }
89
+ function splitSuggestions(suggestions) {
90
+ return {
91
+ placed: suggestions.filter((s) => s.source === "anchor"),
92
+ extras: suggestions.filter((s) => s.source !== "anchor")
93
+ };
94
+ }
95
+ async function fetchDocumentSignatureRequests(client, documentId) {
96
+ const { data, error } = await client.GET("/v1/document/{document_ext_id}/signature-requests", {
97
+ params: { path: { document_ext_id: documentId } }
98
+ });
99
+ if (!data) throw new Error(detail(error, "The signature requests could not be read"));
100
+ return data;
101
+ }
102
+ function useDocumentSignatureRequests(documentId, enabled = true) {
103
+ const { client } = useDocumentTools();
104
+ return useQuery({
105
+ queryKey: arbiQueryKeys.signatureRequestsForDocument(documentId ?? ""),
106
+ queryFn: () => fetchDocumentSignatureRequests(client, documentId),
107
+ enabled: enabled && !!documentId,
108
+ staleTime: 15e3
109
+ });
110
+ }
111
+ async function signatureFieldSuggestions(client, documentId, version) {
112
+ const { data, error } = await client.GET(
113
+ "/v1/document/{document_ext_id}/signature-fields/suggest",
114
+ {
115
+ params: { path: { document_ext_id: documentId }, ...version ? { query: { version } } : {} }
116
+ }
117
+ );
118
+ if (!data) throw new Error(detail(error, "Signature blocks could not be read"));
119
+ return { fields: data.fields, signers: data.signers ?? [] };
120
+ }
121
+ async function suggestSignatureFields(client, documentId, version) {
122
+ return (await signatureFieldSuggestions(client, documentId, version)).fields;
123
+ }
124
+ async function saveSignatureRequest(client, { documentId, version, fields, message, requestId, send }) {
125
+ if (!requestId) {
126
+ const { data, error } = await client.POST("/v1/document/{document_ext_id}/signature-requests", {
127
+ params: { path: { document_ext_id: documentId } },
128
+ body: { fields, message: message || null, send, ...version ? { version } : {} }
129
+ });
130
+ if (!data) throw new Error(detail(error, "The signature request could not be saved"));
131
+ return data;
132
+ }
133
+ const path = { request_ext_id: requestId };
134
+ const updated = await client.PATCH("/v1/signature-requests/{request_ext_id}", {
135
+ params: { path },
136
+ body: { fields, message: message ?? null }
137
+ });
138
+ if (!updated.data) throw new Error(detail(updated.error, "The draft could not be saved"));
139
+ if (!send) return updated.data;
140
+ const sent = await client.POST("/v1/signature-requests/{request_ext_id}/send", {
141
+ params: { path }
142
+ });
143
+ if (!sent.data) throw new Error(detail(sent.error, "The request could not be sent"));
144
+ return sent.data;
145
+ }
146
+ function useInvalidateRequests() {
147
+ const queryClient = useQueryClient();
148
+ return () => queryClient.invalidateQueries({ queryKey: arbiQueryKeys.signatureRequests() });
149
+ }
150
+ function useSaveSignatureRequest() {
151
+ const { client } = useDocumentTools();
152
+ const invalidate = useInvalidateRequests();
153
+ return useMutation({
154
+ mutationFn: (vars) => saveSignatureRequest(client, vars),
155
+ onSuccess: invalidate
156
+ });
157
+ }
158
+ function useVoidSignatureRequest() {
159
+ const { client } = useDocumentTools();
160
+ const invalidate = useInvalidateRequests();
161
+ return useMutation({
162
+ mutationFn: async (requestId) => {
163
+ const { data, error } = await client.POST("/v1/signature-requests/{request_ext_id}/void", {
164
+ params: { path: { request_ext_id: requestId } }
165
+ });
166
+ if (!data) throw new Error(detail(error, "The request could not be voided"));
167
+ return data;
168
+ },
169
+ onSuccess: invalidate
170
+ });
171
+ }
172
+ function useDeclineSignatureRequest() {
173
+ const { client } = useDocumentTools();
174
+ const invalidate = useInvalidateRequests();
175
+ return useMutation({
176
+ mutationFn: async ({ requestId, reason }) => {
177
+ const { data, error } = await client.POST("/v1/signature-requests/{request_ext_id}/decline", {
178
+ params: { path: { request_ext_id: requestId } },
179
+ body: { reason: reason || null }
180
+ });
181
+ if (!data) throw new Error(detail(error, "Could not decline"));
182
+ return data;
183
+ },
184
+ onSuccess: invalidate
185
+ });
186
+ }
187
+ async function signSignatureRequest(client, deploymentDomain, { request, pdfBlob, email, password, adopted, fields }) {
188
+ const path = { request_ext_id: request.external_id };
189
+ const body = { adopted, fields };
190
+ const prepared = await client.POST("/v1/signature-requests/{request_ext_id}/sign/prepare", {
191
+ params: { path },
192
+ body
193
+ });
194
+ if (!prepared.data) {
195
+ throw new SigningError(detail(prepared.error, "Could not prepare signing"), "failed");
196
+ }
197
+ const { statement, intent, source_sha256, timestamp } = prepared.data;
198
+ if (source_sha256 !== request.source_sha256 || await sha256Hex(pdfBlob) !== source_sha256) {
199
+ throw new SigningError("The document changed since it was sent. Ask for it again.", "stale");
200
+ }
201
+ if (intent !== intentText({ name: adopted.name })) {
202
+ throw new Error("Signing statement mismatch; not signed.");
203
+ }
204
+ const identity = await unlockIdentityWithPassword(email, password, deploymentDomain);
205
+ const signed = await client.POST("/v1/signature-requests/{request_ext_id}/sign", {
206
+ params: { path },
207
+ body: { ...body, timestamp, signature: signMessage(statement, identity) }
208
+ });
209
+ if (!signed.data) throw new SigningError(detail(signed.error, "Signing failed"), "failed");
210
+ return signed.data;
211
+ }
212
+ function useSignSignatureRequest() {
213
+ const env = useDocumentTools();
214
+ const invalidate = useInvalidateRequests();
215
+ const queryClient = useQueryClient();
216
+ return useMutation({
217
+ mutationFn: (vars) => {
218
+ if (!env.deploymentDomain) throw new Error("Signing is not set up: no deployment domain");
219
+ return signSignatureRequest(env.client, env.deploymentDomain, vars);
220
+ },
221
+ onSuccess: async (result) => {
222
+ await invalidate();
223
+ if (result.completed && result.request.doc_ext_id) {
224
+ await env.onDocumentsChanged?.([result.request.doc_ext_id], "signed");
225
+ await queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documentSignatures() });
226
+ }
227
+ }
228
+ });
229
+ }
230
+ function useSignerCandidates(enabled = true) {
231
+ const { client, user } = useDocumentTools();
232
+ const { workspaceId, read } = useOpenWorkspaceRead();
233
+ return useQuery({
234
+ queryKey: arbiQueryKeys.signatureCandidates(workspaceId ?? ""),
235
+ queryFn: async () => {
236
+ const { data, error } = await read(() => client.GET("/v1/workspace/users"));
237
+ if (!data) throw new Error(detail(error, "The workspace members could not be read"));
238
+ const people = data.filter((m) => m.user.external_id.startsWith("usr-")).map((m) => ({
239
+ externalId: m.user.external_id,
240
+ name: [m.user.given_name, m.user.family_name].filter(Boolean).join(" ") || m.user.email,
241
+ email: m.user.email,
242
+ role: String(m.role)
243
+ }));
244
+ const me = user?.email?.toLowerCase();
245
+ return [...people].sort(
246
+ (a, b) => Number(b.email.toLowerCase() === me) - Number(a.email.toLowerCase() === me)
247
+ );
248
+ },
249
+ enabled,
250
+ staleTime: 6e4
251
+ });
252
+ }
253
+ async function inviteSigners(client, documentId, emails) {
254
+ if (!emails.length) return;
255
+ const { error, response } = await client.POST("/v1/workspace/users", {
256
+ body: workspaces.addWorkspaceMembersBody({
257
+ emails,
258
+ role: "guest",
259
+ confirm_invite: true,
260
+ resource_type: "document",
261
+ resource_ext_id: documentId
262
+ })
263
+ });
264
+ if (response.status === 409) {
265
+ throw new Error("Share the document with the workspace before asking others to sign it.");
266
+ }
267
+ if (error && response.status !== 404) {
268
+ throw new Error(detail(error, "The signers could not be invited"));
269
+ }
270
+ }
271
+ function useInviteSigners() {
272
+ const { client } = useDocumentTools();
273
+ const invalidate = useInvalidateRequests();
274
+ const queryClient = useQueryClient();
275
+ return useMutation({
276
+ mutationFn: ({ documentId, emails }) => inviteSigners(client, documentId, emails),
277
+ onSuccess: async () => {
278
+ await invalidate();
279
+ await queryClient.invalidateQueries({ queryKey: arbiQueryKeys.signatureCandidates() });
280
+ }
281
+ });
282
+ }
283
+ export {
284
+ DEFAULT_FIELD_SIZE,
285
+ FIELD_TYPE_LABELS,
286
+ MARK_FIELD_TYPES,
287
+ SIGNATURE_FIELD_TYPES,
288
+ SIGNER_PROGRESS_LABELS,
289
+ fetchDocumentSignatureRequests,
290
+ fieldsFromSuggestions,
291
+ fieldsInSigningOrder,
292
+ initialsOf,
293
+ inviteSigners,
294
+ isEmailSigner,
295
+ newFieldId,
296
+ saveSignatureRequest,
297
+ sendBlocker,
298
+ signSignatureRequest,
299
+ signatureFieldSuggestions,
300
+ splitSuggestions,
301
+ suggestSignatureFields,
302
+ useDeclineSignatureRequest,
303
+ useDocumentSignatureRequests,
304
+ useInviteSigners,
305
+ useSaveSignatureRequest,
306
+ useSignSignatureRequest,
307
+ useSignerCandidates,
308
+ useVoidSignatureRequest
309
+ };
310
+ //# sourceMappingURL=signature-requests.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/document-tools/signature-requests.ts"],
4
+ "sourcesContent": ["/**\n * Signature requests: an author places fields (signature, initials, date, name) on the PDF of one\n * exact document version and assigns each to a signer: a workspace member (a guest too), or anyone\n * by email, who is invited to the workspace and signs once they join. A Word document's own\n * signature fields (Insert \u203A Signature field) come back from `suggest` placed exactly, with their\n * signer (`source: 'anchor'`). Each signer is then walked\n * through their fields, adopts a signature once and applies it at each. They sign ONCE for all of\n * their fields: the server's statement binds the PDF they were shown, every field they applied and\n * what they adopted. The last signature draws every field and seals the signed copy as the\n * document's next version (see `src/core/signature_requests.py` in ARBI).\n */\n\nimport { signMessage, unlockIdentityWithPassword, type components } from '@arbidocs/client'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { workspaces } from '@arbidocs/sdk/browser'\nimport { useDocumentTools, type DocumentToolsClient } from './environment'\nimport { intentText, sha256Hex, SigningError } from './signing'\nimport { arbiQueryKeys } from '../query-keys'\nimport { useArbiHost } from '../host/config'\n\n/**\n * The open workspace, when the host has an `Arbi` with one, and a guard that keeps a read made for\n * it only if that workspace stayed open on the server meanwhile (these lists are the open\n * workspace's there): a read that crosses a switch is dropped, never cached as another's.\n */\nfunction useOpenWorkspaceRead() {\n const arbi = useArbiHost().arbi\n const workspaceId = arbi?.hasWorkspace ? arbi.getWorkspaceId() : undefined\n const read = <T>(run: () => Promise<T>): Promise<T> =>\n arbi && workspaceId ? arbi.readInWorkspace(workspaceId, run) : run()\n return { workspaceId, read }\n}\n\nexport type SignatureField = components['schemas']['SignatureField']\nexport type SignatureFieldType = SignatureField['type']\nexport type SignatureRequest = components['schemas']['SignatureRequestResponse']\nexport type SignatureRequestSigner = components['schemas']['SignatureRequestSigner']\nexport type SignerProgress = components['schemas']['SignerProgress']\nexport type SuggestedSignatureField = components['schemas']['SuggestedSignatureField']\nexport type AdoptedSignature = components['schemas']['AdoptedSignature']\nexport type SignRequestSignResponse = components['schemas']['SignRequestSignResponse']\n\n/** Field types in the order the editor offers them. */\nexport const SIGNATURE_FIELD_TYPES: readonly SignatureFieldType[] = [\n 'signature',\n 'initials',\n 'date',\n 'name',\n]\n\nexport const FIELD_TYPE_LABELS: Record<SignatureFieldType, string> = {\n signature: 'Signature',\n initials: 'Initials',\n date: 'Date signed',\n name: 'Name',\n}\n\n/**\n * Default size of a new field, as fractions of the page (the backend draws to fit the box). The\n * same sizes the server's suggester places fields in (`esign_suggest._SIZE`).\n */\nexport const DEFAULT_FIELD_SIZE: Record<SignatureFieldType, { width: number; height: number }> = {\n signature: { width: 0.28, height: 0.05 },\n initials: { width: 0.1, height: 0.04 },\n date: { width: 0.22, height: 0.028 },\n name: { width: 0.28, height: 0.028 },\n}\n\n/** How far each signer has got, as the request's sender sees it. */\nexport const SIGNER_PROGRESS_LABELS: Record<SignerProgress, string> = {\n invited: 'Invited',\n registered: 'Not opened yet',\n viewed: 'Viewed',\n signed: 'Signed',\n declined: 'Declined',\n}\n\nconst EMAIL = /^[^@\\s<>,;]{1,64}@[^@\\s<>,;]{1,255}\\.[^@\\s<>,;]{1,63}$/\n\n/** Whether a field's signer is an email (someone to invite) rather than a member or request signer. */\nexport const isEmailSigner = (signer: string) => EMAIL.test(signer.trim())\n\n/** The fields carrying a signer's mark: every signer needs at least one to be sent the request. */\nexport const MARK_FIELD_TYPES: readonly SignatureFieldType[] = ['signature', 'initials']\n\nfunction detail(error: unknown, fallback: string): string {\n const d = (error as { detail?: unknown } | undefined)?.detail\n if (typeof d === 'string') return d\n if (Array.isArray(d) && d[0] && typeof d[0] === 'object' && 'msg' in d[0]) {\n return String((d[0] as { msg: unknown }).msg)\n }\n return fallback\n}\n\n/** A short unique id for a new field (the server only needs it unique within the request). */\nexport function newFieldId(): string {\n return `f${Math.random().toString(36).slice(2, 10)}`\n}\n\n/** Initials from a name: \"Olive M. Owner\" -> \"OMO\". */\nexport function initialsOf(name: string): string {\n return name\n .split(/\\s+/)\n .filter(Boolean)\n .map((part) => part[0]!.toUpperCase())\n .join('')\n .slice(0, 4)\n}\n\n/** The fields a signer completes, in the order they are walked through: page, then top to bottom. */\nexport function fieldsInSigningOrder(fields: SignatureField[], signer: string): SignatureField[] {\n return fields\n .filter((f) => f.signer === signer)\n .sort((a, b) => a.page - b.page || a.y - b.y || a.x - b.x)\n}\n\n/** Why a draft cannot be sent yet, or null when it can. Mirrors the server's checks. */\nexport function sendBlocker(fields: SignatureField[]): string | null {\n if (fields.length === 0) return 'Place at least one field.'\n const signers = [...new Set(fields.map((f) => f.signer))]\n for (const signer of signers) {\n if (!fields.some((f) => f.signer === signer && MARK_FIELD_TYPES.includes(f.type))) {\n return 'Every signer needs a signature or initials field.'\n }\n }\n return null\n}\n\n/**\n * Suggested fields grouped by signature block; `assign` maps a block (`group`) to the signer its\n * fields go to. A field placed in the Word document that names its signer goes to them: the\n * member with that email (`members`, by lowercased email), else the email itself (an invitee).\n * Unassigned blocks are left out.\n */\nexport function fieldsFromSuggestions(\n suggestions: SuggestedSignatureField[],\n assign: Record<number, string | undefined>,\n members: ReadonlyMap<string, string> = new Map()\n): SignatureField[] {\n return suggestions.flatMap((s) => {\n const email = s.signer_email?.toLowerCase()\n const signer = email ? (members.get(email) ?? email) : assign[s.group]\n if (!signer) return []\n return [\n {\n id: newFieldId(),\n type: s.type,\n page: s.page,\n x: s.x,\n y: s.y,\n width: s.width,\n height: s.height,\n signer,\n required: s.required ?? true,\n },\n ]\n })\n}\n\n/** The Word document's own fields (found by their anchors) and the optional layout suggestions. */\nexport function splitSuggestions(suggestions: SuggestedSignatureField[]) {\n return {\n placed: suggestions.filter((s) => s.source === 'anchor'),\n extras: suggestions.filter((s) => s.source !== 'anchor'),\n }\n}\n\n// \u2500\u2500 Reads \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function fetchDocumentSignatureRequests(\n client: DocumentToolsClient,\n documentId: string\n): Promise<SignatureRequest[]> {\n const { data, error } = await client.GET('/v1/document/{document_ext_id}/signature-requests', {\n params: { path: { document_ext_id: documentId } },\n })\n if (!data) throw new Error(detail(error, 'The signature requests could not be read'))\n return data\n}\n\n/** A document's signature requests, newest first. */\nexport function useDocumentSignatureRequests(\n documentId: string | null | undefined,\n enabled = true\n) {\n const { client } = useDocumentTools()\n return useQuery({\n queryKey: arbiQueryKeys.signatureRequestsForDocument(documentId ?? ''),\n queryFn: () => fetchDocumentSignatureRequests(client, documentId!),\n enabled: enabled && !!documentId,\n staleTime: 15_000,\n })\n}\n\n/** A signer the Word document's placed fields name, with the name they give. */\nexport interface NamedSigner {\n email: string\n name: string\n}\n\n/** What a document asks to be signed: the fields found, and the signers its Word fields name. */\nexport interface SignatureFieldSuggestions {\n fields: SuggestedSignatureField[]\n /**\n * Named even when the PDF shows none of the Word fields' anchors (the fields are then placed by\n * hand): who each email belongs to. Empty from a server that does not report them.\n */\n signers: NamedSigner[]\n}\n\nexport async function signatureFieldSuggestions(\n client: DocumentToolsClient,\n documentId: string,\n version?: number\n): Promise<SignatureFieldSuggestions> {\n const { data, error } = await client.GET(\n '/v1/document/{document_ext_id}/signature-fields/suggest',\n {\n params: { path: { document_ext_id: documentId }, ...(version ? { query: { version } } : {}) },\n }\n )\n if (!data) throw new Error(detail(error, 'Signature blocks could not be read'))\n return { fields: data.fields, signers: (data as { signers?: NamedSigner[] }).signers ?? [] }\n}\n\nexport async function suggestSignatureFields(\n client: DocumentToolsClient,\n documentId: string,\n version?: number\n): Promise<SuggestedSignatureField[]> {\n return (await signatureFieldSuggestions(client, documentId, version)).fields\n}\n\n// \u2500\u2500 Prepare \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface SaveSignatureRequestVars {\n documentId: string\n /** The version the fields were placed on (the PDF shown). Omitted = current. */\n version?: number\n fields: SignatureField[]\n message?: string\n /** Existing draft to update instead of creating a new request. */\n requestId?: string\n /** Send it to the signers (else it is saved as a draft). */\n send: boolean\n}\n\nexport async function saveSignatureRequest(\n client: DocumentToolsClient,\n { documentId, version, fields, message, requestId, send }: SaveSignatureRequestVars\n): Promise<SignatureRequest> {\n if (!requestId) {\n const { data, error } = await client.POST('/v1/document/{document_ext_id}/signature-requests', {\n params: { path: { document_ext_id: documentId } },\n body: { fields, message: message || null, send, ...(version ? { version } : {}) },\n })\n if (!data) throw new Error(detail(error, 'The signature request could not be saved'))\n return data\n }\n const path = { request_ext_id: requestId }\n const updated = await client.PATCH('/v1/signature-requests/{request_ext_id}', {\n params: { path },\n body: { fields, message: message ?? null },\n })\n if (!updated.data) throw new Error(detail(updated.error, 'The draft could not be saved'))\n if (!send) return updated.data\n const sent = await client.POST('/v1/signature-requests/{request_ext_id}/send', {\n params: { path },\n })\n if (!sent.data) throw new Error(detail(sent.error, 'The request could not be sent'))\n return sent.data\n}\n\nfunction useInvalidateRequests() {\n const queryClient = useQueryClient()\n return () => queryClient.invalidateQueries({ queryKey: arbiQueryKeys.signatureRequests() })\n}\n\nexport function useSaveSignatureRequest() {\n const { client } = useDocumentTools()\n const invalidate = useInvalidateRequests()\n return useMutation({\n mutationFn: (vars: SaveSignatureRequestVars) => saveSignatureRequest(client, vars),\n onSuccess: invalidate,\n })\n}\n\nexport function useVoidSignatureRequest() {\n const { client } = useDocumentTools()\n const invalidate = useInvalidateRequests()\n return useMutation({\n mutationFn: async (requestId: string) => {\n const { data, error } = await client.POST('/v1/signature-requests/{request_ext_id}/void', {\n params: { path: { request_ext_id: requestId } },\n })\n if (!data) throw new Error(detail(error, 'The request could not be voided'))\n return data\n },\n onSuccess: invalidate,\n })\n}\n\nexport function useDeclineSignatureRequest() {\n const { client } = useDocumentTools()\n const invalidate = useInvalidateRequests()\n return useMutation({\n mutationFn: async ({ requestId, reason }: { requestId: string; reason?: string }) => {\n const { data, error } = await client.POST('/v1/signature-requests/{request_ext_id}/decline', {\n params: { path: { request_ext_id: requestId } },\n body: { reason: reason || null },\n })\n if (!data) throw new Error(detail(error, 'Could not decline'))\n return data\n },\n onSuccess: invalidate,\n })\n}\n\n// \u2500\u2500 Sign \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface SignRequestVars {\n request: SignatureRequest\n /** The PDF the signer was walked through (`GET /view?version=` of the request's version). */\n pdfBlob: Blob\n email: string\n password: string\n adopted: AdoptedSignature\n /** The ids of the fields the signer applied: every required one of theirs. */\n fields: string[]\n}\n\n/**\n * Sign all of the signer's fields at once: the server prepares the statement, the browser checks\n * it covers the PDF on screen under the wording the signer read, re-derives the Ed25519 key from\n * the password and signs. Resolves with `completed` when this was the last signature.\n */\nexport async function signSignatureRequest(\n client: DocumentToolsClient,\n deploymentDomain: string,\n { request, pdfBlob, email, password, adopted, fields }: SignRequestVars\n): Promise<SignRequestSignResponse> {\n const path = { request_ext_id: request.external_id }\n const body = { adopted, fields }\n const prepared = await client.POST('/v1/signature-requests/{request_ext_id}/sign/prepare', {\n params: { path },\n body,\n })\n if (!prepared.data) {\n throw new SigningError(detail(prepared.error, 'Could not prepare signing'), 'failed')\n }\n const { statement, intent, source_sha256, timestamp } = prepared.data\n if (source_sha256 !== request.source_sha256 || (await sha256Hex(pdfBlob)) !== source_sha256) {\n throw new SigningError('The document changed since it was sent. Ask for it again.', 'stale')\n }\n if (intent !== intentText({ name: adopted.name })) {\n throw new Error('Signing statement mismatch; not signed.')\n }\n const identity = await unlockIdentityWithPassword(email, password, deploymentDomain)\n const signed = await client.POST('/v1/signature-requests/{request_ext_id}/sign', {\n params: { path },\n body: { ...body, timestamp, signature: signMessage(statement, identity) },\n })\n if (!signed.data) throw new SigningError(detail(signed.error, 'Signing failed'), 'failed')\n return signed.data\n}\n\nexport function useSignSignatureRequest() {\n const env = useDocumentTools()\n const invalidate = useInvalidateRequests()\n const queryClient = useQueryClient()\n return useMutation({\n mutationFn: (vars: SignRequestVars) => {\n if (!env.deploymentDomain) throw new Error('Signing is not set up: no deployment domain')\n return signSignatureRequest(env.client, env.deploymentDomain, vars)\n },\n onSuccess: async (result) => {\n await invalidate()\n if (result.completed && result.request.doc_ext_id) {\n await env.onDocumentsChanged?.([result.request.doc_ext_id], 'signed')\n await queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documentSignatures() })\n }\n },\n })\n}\n\n// \u2500\u2500 Who can sign \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface SignerCandidate {\n externalId: string\n name: string\n email: string\n role: string\n}\n\n/**\n * The people in the active workspace who may sign: owners, collaborators and guests (an agent never\n * does). The first one listed is the current user when they are a member.\n */\nexport function useSignerCandidates(enabled = true) {\n const { client, user } = useDocumentTools()\n const { workspaceId, read } = useOpenWorkspaceRead()\n return useQuery({\n queryKey: arbiQueryKeys.signatureCandidates(workspaceId ?? ''),\n queryFn: async (): Promise<SignerCandidate[]> => {\n const { data, error } = await read(() => client.GET('/v1/workspace/users'))\n if (!data) throw new Error(detail(error, 'The workspace members could not be read'))\n const people = data\n .filter((m) => m.user.external_id.startsWith('usr-'))\n .map((m) => ({\n externalId: m.user.external_id,\n name: [m.user.given_name, m.user.family_name].filter(Boolean).join(' ') || m.user.email,\n email: m.user.email,\n role: String(m.role),\n }))\n const me = user?.email?.toLowerCase()\n return [...people].sort(\n (a, b) => Number(b.email.toLowerCase() === me) - Number(a.email.toLowerCase() === me)\n )\n },\n enabled,\n staleTime: 60_000,\n })\n}\n\n// \u2500\u2500 Invite \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Invite signers who are not in the workspace yet, as guests, through the workspace's own invite\n * (`POST /v1/workspace/users` with `confirm_invite`): a registered person is added at once, anyone\n * else is emailed an invitation that lands on the document. Each is asked to sign when they join.\n * Only a workspace owner can invite.\n */\nexport async function inviteSigners(\n client: DocumentToolsClient,\n documentId: string,\n emails: string[]\n): Promise<void> {\n if (!emails.length) return\n const { error, response } = await client.POST('/v1/workspace/users', {\n body: workspaces.addWorkspaceMembersBody({\n emails,\n role: 'guest',\n confirm_invite: true,\n resource_type: 'document',\n resource_ext_id: documentId,\n }),\n })\n if (response.status === 409) {\n throw new Error('Share the document with the workspace before asking others to sign it.')\n }\n // 404 \"No users found to add\": everyone is a member already (nothing to do).\n if (error && response.status !== 404) {\n throw new Error(detail(error, 'The signers could not be invited'))\n }\n}\n\nexport function useInviteSigners() {\n const { client } = useDocumentTools()\n const invalidate = useInvalidateRequests()\n const queryClient = useQueryClient()\n return useMutation({\n mutationFn: ({ documentId, emails }: { documentId: string; emails: string[] }) =>\n inviteSigners(client, documentId, emails),\n onSuccess: async () => {\n await invalidate()\n await queryClient.invalidateQueries({ queryKey: arbiQueryKeys.signatureCandidates() })\n },\n })\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,127 @@
1
+ import { signMessage, unlockIdentityWithPassword } from "@arbidocs/client";
2
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
3
+ import { parseVersionRef } from "../artifacts/versions.js";
4
+ import { useDocumentTools } from "./environment.js";
5
+ import { arbiQueryKeys } from "../query-keys.js";
6
+ function intentText(signer) {
7
+ return `I, ${signer.name.trim()}, sign this document electronically. I intend this electronic signature to have the same effect as my handwritten signature.`;
8
+ }
9
+ async function sha256Hex(blob) {
10
+ const digest = await crypto.subtle.digest("SHA-256", new Uint8Array(await blob.arrayBuffer()));
11
+ return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, "0")).join("");
12
+ }
13
+ function toAppearance(box) {
14
+ return { page: box.page - 1, x: box.rect.x, y: box.rect.y, width: box.rect.w, height: box.rect.h };
15
+ }
16
+ const MIN_SIGNATURE_BOX = { width: 0.3, height: 0.07 };
17
+ function isLegibleSignatureBox(rect) {
18
+ return rect.w >= MIN_SIGNATURE_BOX.width && rect.h >= MIN_SIGNATURE_BOX.height;
19
+ }
20
+ const SIGNATURES_PATH = "/v1/document/{document_ext_id}/signatures";
21
+ function errorDetail(error, fallback) {
22
+ const detail = error?.detail;
23
+ return typeof detail === "string" ? detail : fallback;
24
+ }
25
+ async function fetchDocumentSignatures(client, documentRef) {
26
+ const { docId, version } = parseVersionRef(documentRef);
27
+ const { data, error } = await client.GET(SIGNATURES_PATH, {
28
+ params: { path: { document_ext_id: docId }, ...version ? { query: { version } } : {} }
29
+ });
30
+ if (!data) throw new Error(errorDetail(error, "The signatures could not be read"));
31
+ return data;
32
+ }
33
+ function useDocumentSignatures(documentId, enabled = true) {
34
+ const { client } = useDocumentTools();
35
+ const { docId, version } = parseVersionRef(documentId);
36
+ return useQuery({
37
+ queryKey: arbiQueryKeys.documentSignatures(docId ?? "", version),
38
+ queryFn: () => fetchDocumentSignatures(client, documentId),
39
+ enabled: enabled && !!docId,
40
+ staleTime: 6e4
41
+ });
42
+ }
43
+ class SigningError extends Error {
44
+ reason;
45
+ constructor(message, reason) {
46
+ super(message);
47
+ this.name = "SigningError";
48
+ this.reason = reason;
49
+ }
50
+ }
51
+ function signingErrorReason(detail) {
52
+ if (/still being prepared/i.test(detail)) return "preparing";
53
+ if (/no longer the current version/i.test(detail)) return "stale";
54
+ return "failed";
55
+ }
56
+ function signingError(error, fallback) {
57
+ const detail = errorDetail(error, fallback);
58
+ return new SigningError(detail, signingErrorReason(detail));
59
+ }
60
+ const PREPARE_RETRIES = 3;
61
+ const PREPARE_RETRY_DELAY_MS = 1500;
62
+ const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
63
+ async function signDocument(client, deploymentDomain, {
64
+ documentId,
65
+ pdfBlob,
66
+ email,
67
+ password,
68
+ signer,
69
+ appearance,
70
+ includeDate = false,
71
+ version
72
+ }) {
73
+ const path = { document_ext_id: documentId };
74
+ const body = {
75
+ signer: { name: signer.name },
76
+ ...appearance ? { appearance } : {},
77
+ include_date: includeDate,
78
+ ...version ? { version } : {}
79
+ };
80
+ const prepare = () => client.POST("/v1/document/{document_ext_id}/sign/prepare", { params: { path }, body });
81
+ let prepared = await prepare();
82
+ for (let attempt = 0; !prepared.data && attempt < PREPARE_RETRIES; attempt++) {
83
+ if (signingError(prepared.error, "").reason !== "preparing") break;
84
+ await wait(PREPARE_RETRY_DELAY_MS);
85
+ prepared = await prepare();
86
+ }
87
+ if (!prepared.data) throw signingError(prepared.error, "Could not prepare signing");
88
+ const { statement, intent, source_sha256, timestamp } = prepared.data;
89
+ if (await sha256Hex(pdfBlob) !== source_sha256) {
90
+ throw new Error("The document changed since it was opened. Reopen it and sign again.");
91
+ }
92
+ if (intent !== intentText(signer)) throw new Error("Signing statement mismatch; not signed.");
93
+ const identity = await unlockIdentityWithPassword(email, password, deploymentDomain);
94
+ const signed = await client.POST("/v1/document/{document_ext_id}/sign", {
95
+ params: { path },
96
+ body: { ...body, timestamp, signature: signMessage(statement, identity) }
97
+ });
98
+ if (!signed.data) throw signingError(signed.error, "Signing failed");
99
+ return signed.data;
100
+ }
101
+ function useSignDocument() {
102
+ const env = useDocumentTools();
103
+ const queryClient = useQueryClient();
104
+ return useMutation({
105
+ mutationFn: (vars) => {
106
+ if (!env.deploymentDomain) throw new Error("Signing is not set up: no deployment domain");
107
+ return signDocument(env.client, env.deploymentDomain, vars);
108
+ },
109
+ onSuccess: async (result) => {
110
+ await env.onDocumentsChanged?.([result.doc_ext_id], "signed");
111
+ await queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documentSignatures() });
112
+ }
113
+ });
114
+ }
115
+ export {
116
+ PREPARE_RETRIES,
117
+ SigningError,
118
+ fetchDocumentSignatures,
119
+ intentText,
120
+ isLegibleSignatureBox,
121
+ sha256Hex,
122
+ signDocument,
123
+ toAppearance,
124
+ useDocumentSignatures,
125
+ useSignDocument
126
+ };
127
+ //# sourceMappingURL=signing.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/document-tools/signing.ts"],
4
+ "sourcesContent": ["/**\n * Electronic signing. The backend (`src/core/esign.py` in ARBI) defines what a signature binds;\n * the helpers mirror the two pieces the browser must reproduce exactly: the statement of intent\n * shown to the signer, and the SHA-256 of the PDF the viewer displayed.\n */\n\nimport { signMessage, unlockIdentityWithPassword, type components } from '@arbidocs/client'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { parseVersionRef } from '../artifacts/versions'\nimport { useDocumentTools, type DocumentToolsClient } from './environment'\nimport { arbiQueryKeys } from '../query-keys'\n\n/**\n * Who signs: the name only. A role, a firm or a place go on the page as ordinary annotation text,\n * which is not part of the signature.\n */\nexport type SignerDetails = components['schemas']['SignerDetails']\n\n/** Same sentence as `esign.intent_text`; the dialog refuses to sign if the server's differs. */\nexport function intentText(signer: SignerDetails): string {\n return `I, ${signer.name.trim()}, sign this document electronically. I intend this electronic signature to have the same effect as my handwritten signature.`\n}\n\nexport async function sha256Hex(blob: Blob): Promise<string> {\n const digest = await crypto.subtle.digest('SHA-256', new Uint8Array(await blob.arrayBuffer()))\n return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, '0')).join('')\n}\n\n/** A signature box drawn on the annotation overlay, as the signing API's placement. */\nexport function toAppearance(box: {\n page: number\n rect: { x: number; y: number; w: number; h: number }\n}): { page: number; x: number; y: number; width: number; height: number } {\n // The layer counts pages from 1, the signing API from 0. Both use fractions of the page as\n // displayed, origin top-left.\n return { page: box.page - 1, x: box.rect.x, y: box.rect.y, width: box.rect.w, height: box.rect.h }\n}\n\n/**\n * The smallest box the backend can draw a legible signature in: the signer's name and the\n * details line shrink to fit, so a box under these fractions of the page is shrunk to near\n * unreadable size. The backend's own default box is 0.40 x 0.10.\n */\nconst MIN_SIGNATURE_BOX = { width: 0.3, height: 0.07 }\n\nexport function isLegibleSignatureBox(rect: { w: number; h: number }): boolean {\n return rect.w >= MIN_SIGNATURE_BOX.width && rect.h >= MIN_SIGNATURE_BOX.height\n}\n\n// \u2500\u2500 Signing through the API \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 type SignatureAppearance = components['schemas']['SignatureAppearance']\nexport type SignatureStatusResponse = components['schemas']['SignatureStatusResponse']\nexport type SignatureRecord = components['schemas']['SignatureRecord']\nexport type SignDocumentResponse = components['schemas']['SignDocumentResponse']\n\nconst SIGNATURES_PATH = '/v1/document/{document_ext_id}/signatures'\n/**\n * The same key openapi-react-query gives this request (`['get', path, init]`), so a host that\n * reads or persists the API cache by path treats it like its own queries.\n */\n\nfunction errorDetail(error: unknown, fallback: string): string {\n const detail = (error as { detail?: unknown } | undefined)?.detail\n return typeof detail === 'string' ? detail : fallback\n}\n\n/** Whether a document version is a signed copy, and its signatures. */\nexport async function fetchDocumentSignatures(\n client: DocumentToolsClient,\n documentRef: string\n): Promise<SignatureStatusResponse> {\n const { docId, version } = parseVersionRef(documentRef)\n const { data, error } = await client.GET(SIGNATURES_PATH, {\n params: { path: { document_ext_id: docId }, ...(version ? { query: { version } } : {}) },\n })\n if (!data) throw new Error(errorDetail(error, 'The signatures could not be read'))\n return data\n}\n\n/**\n * Is a document version a signed copy? `documentId` is a document id (its current version) or a\n * version reference `doc-\u2026@v{n}`. Needs a React Query `QueryClientProvider`.\n */\nexport function useDocumentSignatures(documentId: string | null | undefined, enabled = true) {\n const { client } = useDocumentTools()\n const { docId, version } = parseVersionRef(documentId)\n return useQuery({\n queryKey: arbiQueryKeys.documentSignatures(docId ?? '', version),\n queryFn: () => fetchDocumentSignatures(client, documentId!),\n enabled: enabled && !!docId,\n staleTime: 60_000,\n })\n}\n\n/**\n * Why the server would not sign: the PDF of a Word or text document is still being rendered\n * (`preparing`, worth another try in a moment), or the version on screen is no longer the current\n * one (`stale`: only the current version can be signed, so the signer reopens it).\n */\nexport type SigningErrorReason = 'preparing' | 'stale' | 'failed'\n\nexport class SigningError extends Error {\n readonly reason: SigningErrorReason\n constructor(message: string, reason: SigningErrorReason) {\n super(message)\n this.name = 'SigningError'\n this.reason = reason\n }\n}\n\n/** The 409s the backend's signing router raises, told apart by their wording. */\nfunction signingErrorReason(detail: string): SigningErrorReason {\n if (/still being prepared/i.test(detail)) return 'preparing'\n if (/no longer the current version/i.test(detail)) return 'stale'\n return 'failed'\n}\n\nfunction signingError(error: unknown, fallback: string): SigningError {\n const detail = errorDetail(error, fallback)\n return new SigningError(detail, signingErrorReason(detail))\n}\n\n/** How often, and how long apart, a prepare is retried while the PDF is still being rendered. */\nexport const PREPARE_RETRIES = 3\nconst PREPARE_RETRY_DELAY_MS = 1500\n\nconst wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))\n\nexport interface SignDocumentVars {\n documentId: string\n /**\n * The PDF bytes the viewer is showing (`GET /view?version=`, never the original's download): the\n * signer signs exactly these.\n */\n pdfBlob: Blob\n /**\n * The version `pdfBlob` is of. The server signs only the current version and refuses\n * (`SigningError` `stale`) when this one has been superseded. Omitted = the current version.\n */\n version?: number\n email: string\n password: string\n signer: SignerDetails\n /** Where the signature goes; omitted = the backend default (bottom of the last page). */\n appearance?: SignatureAppearance\n /** Draw the signing date under the signature. Default off: only the signature is drawn. */\n includeDate?: boolean\n}\n\n/**\n * Sign a document: the server prepares the statement, the browser checks that it covers the PDF\n * on screen under the wording the signer read, re-derives the user's Ed25519 key from their\n * password and signs it, and the server seals the signed copy as a new version.\n *\n * What is drawn on the page is only the signature (the signer's name as the signature mark) and,\n * with `includeDate`, the date; anyone can click it to open its certificate. A role, a firm or a\n * place go on the page as ordinary annotation text, which is not part of the signature.\n */\nexport async function signDocument(\n client: DocumentToolsClient,\n deploymentDomain: string,\n {\n documentId,\n pdfBlob,\n email,\n password,\n signer,\n appearance,\n includeDate = false,\n version,\n }: SignDocumentVars\n): Promise<SignDocumentResponse> {\n const path = { document_ext_id: documentId }\n // One body for both calls: the server refuses a /sign whose include_date (or placement) differs\n // from what was prepared, since what the signature shows is part of what is signed.\n const body = {\n signer: { name: signer.name },\n ...(appearance ? { appearance } : {}),\n include_date: includeDate,\n ...(version ? { version } : {}),\n }\n\n // A Word or text document's PDF is rendered after upload: while it is, prepare says so, and a\n // short wait usually sees it ready.\n const prepare = () =>\n client.POST('/v1/document/{document_ext_id}/sign/prepare', { params: { path }, body })\n let prepared = await prepare()\n for (let attempt = 0; !prepared.data && attempt < PREPARE_RETRIES; attempt++) {\n if (signingError(prepared.error, '').reason !== 'preparing') break\n await wait(PREPARE_RETRY_DELAY_MS)\n prepared = await prepare()\n }\n if (!prepared.data) throw signingError(prepared.error, 'Could not prepare signing')\n const { statement, intent, source_sha256, timestamp } = prepared.data\n // Sign only what was on screen, under the wording the signer read.\n if ((await sha256Hex(pdfBlob)) !== source_sha256) {\n throw new Error('The document changed since it was opened. Reopen it and sign again.')\n }\n if (intent !== intentText(signer)) throw new Error('Signing statement mismatch; not signed.')\n\n // The re-typed password must open the session's identity, which is the key the server verifies.\n const identity = await unlockIdentityWithPassword(email, password, deploymentDomain)\n const signed = await client.POST('/v1/document/{document_ext_id}/sign', {\n params: { path },\n body: { ...body, timestamp, signature: signMessage(statement, identity) },\n })\n if (!signed.data) throw signingError(signed.error, 'Signing failed')\n return signed.data\n}\n\n/** The signing mutation. On success the host hears the document changed (`'signed'`). */\nexport function useSignDocument() {\n const env = useDocumentTools()\n const queryClient = useQueryClient()\n return useMutation({\n mutationFn: (vars: SignDocumentVars) => {\n if (!env.deploymentDomain) throw new Error('Signing is not set up: no deployment domain')\n return signDocument(env.client, env.deploymentDomain, vars)\n },\n onSuccess: async (result) => {\n // The signed copy is the document's new current version: the host refreshes its row,\n // versions and rendered PDF, and the signature badge reads again.\n await env.onDocumentsChanged?.([result.doc_ext_id], 'signed')\n await queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documentSignatures() })\n },\n })\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }