@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,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/annotations/freeze/freeze.ts"],
4
+ "sourcesContent": ["/**\n * Freeze: derive a NEW document from an immutable original plus its annotation layer.\n *\n * - `vector`: marks are drawn into the original pages; text stays searchable.\n * - `image`: every page is rasterised with the marks burned in and the PDF is rebuilt from the\n * images alone. Required whenever a redaction applies, because only a rebuild leaves nothing\n * behind the box: no text, no metadata, no annotations, no attachments, no old revisions.\n *\n * The layer itself is never embedded. The output carries a provenance record (counts and reasons,\n * never the redacted text).\n */\n\nimport { EncryptedPDFError, PDFDocument, PDFHexString, PDFName, StandardFonts, rgb } from 'pdf-lib'\nimport {\n isEffectiveRedaction,\n parseLayer,\n type Annotation,\n type AnnotationKind,\n type AnnotationLayer,\n type CommentAnnotation,\n} from '../model'\nimport { displayedSize } from './coords'\nimport { hashLayer, sha256Hex } from './hash'\nimport { burnMarks } from './raster'\nimport {\n ENCRYPTED_MESSAGE,\n FreezeError,\n type FreezeMode,\n type FreezeOptions,\n type FreezeProvenance,\n type FreezeResult,\n type OcrWord,\n} from './types'\nimport {\n TextSanitiser,\n appendCommentAppendix,\n createVectorContext,\n drawVectorMark,\n numberComments,\n pageGeometry,\n} from './vector'\n\nexport const DEFAULT_DPI = 200\nconst DEFAULT_JPEG_QUALITY = 0.92\nconst DEFAULT_REDACTION_PADDING_PT = 1.5\nconst MIN_DPI = 72\nconst MAX_DPI = 600\nconst FALLBACK_PAGE: [number, number] = [595.28, 841.89]\nconst PROVENANCE_KEY = 'ArbiProvenance'\n\nconst KINDS: AnnotationKind[] = ['highlight', 'box', 'comment', 'stamp', 'redaction']\n\nexport async function freezePdf(\n original: Uint8Array,\n rawLayer: AnnotationLayer,\n options: FreezeOptions\n): Promise<FreezeResult> {\n // The layer may have come from storage or an agent: validate before anything is drawn.\n const layer = parseLayer(rawLayer)\n const now = options.now ?? new Date().toISOString()\n const comments = options.comments ?? 'omit'\n const dpi = options.dpi ?? DEFAULT_DPI\n if (!(dpi >= MIN_DPI && dpi <= MAX_DPI)) {\n throw new FreezeError('invalid-option', `dpi must be between ${MIN_DPI} and ${MAX_DPI}`)\n }\n\n const redactions = layer.annotations.filter(isEffectiveRedaction)\n const pending = redactions.filter((r) => r.status === 'pending')\n if (pending.length > 0 && (options.pendingRedactions ?? 'error') === 'error') {\n throw new FreezeError(\n 'pending-redactions',\n `${pending.length} redaction mark(s) have not been approved or rejected`\n )\n }\n\n // Rejected redactions are dropped; every other mark is applied.\n const marks = layer.annotations.filter((a) => a.kind !== 'redaction' || isEffectiveRedaction(a))\n const modeApplied: FreezeMode = redactions.length > 0 ? 'image' : options.mode\n\n const [originalSha256, layerSha256] = await Promise.all([sha256Hex(original), hashLayer(layer)])\n const warnings: string[] = []\n if (redactions.length > 0 && comments !== 'omit' && marks.some((a) => a.kind === 'comment')) {\n warnings.push(\n 'Comments are included in a document with redactions and may repeat redacted text'\n )\n }\n\n let built: { doc: PDFDocument; pages: number; dpi?: number }\n if (modeApplied === 'image') {\n built = await freezeAsImage(marks, options, comments, dpi, now, warnings)\n } else {\n built = await freezeAsVector(original, marks, comments, now, warnings)\n }\n\n const provenance: FreezeProvenance = {\n schema: 1,\n derivedFrom: layer.documentId,\n originalSha256,\n layerSha256,\n modeRequested: options.mode,\n modeApplied,\n ...(modeApplied !== options.mode ? { modeChangedBecause: 'redactions-present' as const } : {}),\n frozenAt: now,\n frozenBy: options.author,\n pages: built.pages,\n ...(built.dpi === undefined ? {} : { dpi: built.dpi }),\n counts: countKinds(marks),\n redactions: summariseRedactions(redactions),\n }\n\n setProvenance(built.doc, provenance)\n return { bytes: await built.doc.save(), provenance, warnings }\n}\n\nfunction countKinds(marks: Annotation[]): Record<AnnotationKind, number> {\n const counts = Object.fromEntries(KINDS.map((k) => [k, 0])) as Record<AnnotationKind, number>\n for (const a of marks) counts[a.kind]++\n return counts\n}\n\nfunction summariseRedactions(redactions: Annotation[]): FreezeProvenance['redactions'] {\n const reasons: Record<string, number> = {}\n const pages = new Set<number>()\n for (const r of redactions) {\n if (r.kind !== 'redaction') continue\n pages.add(r.page)\n reasons[r.reason] = (reasons[r.reason] ?? 0) + 1\n }\n return { count: redactions.length, pages: [...pages].sort((a, b) => a - b), reasons }\n}\n\nfunction checkPages(marks: Annotation[], pages: number) {\n for (const a of marks) {\n if (a.page > pages) {\n throw new FreezeError(\n 'page-out-of-range',\n `mark ${a.id} is on page ${a.page}; the document has ${pages}`\n )\n }\n }\n}\n\nfunction checkAborted(signal?: AbortSignal) {\n if (signal?.aborted) throw new DOMException('Freeze aborted', 'AbortError')\n}\n\n/** Load a PDF for editing, turning pdf-lib's failures into the one FreezeError the UI shows. */\nexport async function loadPdfDocument(bytes: Uint8Array): Promise<PDFDocument> {\n try {\n return await PDFDocument.load(bytes)\n } catch (error) {\n // pdf-lib is compiled to ES5, where a subclass of Error loses its prototype, so `instanceof`\n // can be false for its own EncryptedPDFError; its message is the dependable signal.\n if (\n error instanceof EncryptedPDFError ||\n /is encrypted/i.test((error as Error)?.message ?? '')\n ) {\n throw new FreezeError('encrypted', ENCRYPTED_MESSAGE)\n }\n throw new FreezeError('invalid-pdf', `The PDF could not be read: ${(error as Error).message}`)\n }\n}\n\nasync function freezeAsVector(\n original: Uint8Array,\n marks: Annotation[],\n comments: NonNullable<FreezeOptions['comments']>,\n now: string,\n warnings: string[]\n) {\n const doc = await loadPdfDocument(original)\n const pages = doc.getPages()\n checkPages(marks, pages.length)\n\n const ctx = await createVectorContext(doc, marks, comments)\n for (const a of marks) drawVectorMark(pages[a.page - 1], a, ctx)\n\n if (comments === 'appendix') {\n const first = pages[0] ? displayedSize(pageGeometry(pages[0])) : undefined\n const size: [number, number] = first ? [first.width, first.height] : FALLBACK_PAGE\n appendCommentAppendix(\n ctx,\n marks.filter((a): a is CommentAnnotation => a.kind === 'comment'),\n size\n )\n }\n reportReplaced(ctx.sanitiser, warnings)\n doc.setProducer('ARBI')\n doc.setModificationDate(new Date(now))\n return { doc, pages: pages.length }\n}\n\nasync function freezeAsImage(\n marks: Annotation[],\n options: FreezeOptions,\n comments: NonNullable<FreezeOptions['comments']>,\n dpi: number,\n now: string,\n warnings: string[]\n) {\n const rasterizer = options.rasterizer\n if (!rasterizer) {\n throw new FreezeError('rasterizer-required', 'Image freeze needs a page rasterizer')\n }\n try {\n checkPages(marks, rasterizer.numPages)\n const out = await PDFDocument.create()\n // A fresh document: nothing from the original (title, author, XMP, attachments) is carried over.\n out.setProducer('ARBI')\n out.setCreator('ARBI')\n out.setCreationDate(new Date(now))\n out.setModificationDate(new Date(now))\n\n const numbers = numberComments(marks)\n const format = options.imageFormat ?? 'jpeg'\n const quality = options.jpegQuality ?? DEFAULT_JPEG_QUALITY\n const burn = {\n paddingPt: options.redactionPaddingPt ?? DEFAULT_REDACTION_PADDING_PT,\n labels: options.redactionLabels ?? true,\n comments,\n numbers,\n images: await stampImages(marks),\n }\n const ocrFont = options.ocr ? await out.embedFont(StandardFonts.Helvetica) : undefined\n const ocrSanitiser = ocrFont ? new TextSanitiser(ocrFont) : undefined\n\n let lowestDpi = dpi\n let firstSize: [number, number] | undefined\n for (let n = 1; n <= rasterizer.numPages; n++) {\n checkAborted(options.signal)\n const page = await rasterizer.renderPage(n, dpi)\n try {\n burnMarks(\n page,\n marks.filter((a) => a.page === n),\n burn\n )\n const bytes = await page.encode(format, quality)\n const image = format === 'png' ? await out.embedPng(bytes) : await out.embedJpg(bytes)\n const outPage = out.addPage([page.widthPt, page.heightPt])\n outPage.drawImage(image, { x: 0, y: 0, width: page.widthPt, height: page.heightPt })\n lowestDpi = Math.min(lowestDpi, page.dpi)\n firstSize ??= [page.widthPt, page.heightPt]\n\n if (options.ocr && ocrFont && ocrSanitiser) {\n const words = await options.ocr({\n pageNumber: n,\n bytes,\n format,\n widthPx: page.widthPx,\n heightPx: page.heightPx,\n })\n drawInvisibleText(outPage, words, page.widthPt, page.heightPt, ocrFont, ocrSanitiser)\n }\n } finally {\n page.release()\n }\n options.onProgress?.(n, rasterizer.numPages)\n }\n\n if (comments === 'appendix') {\n const ctx = await createVectorContext(out, marks, comments)\n appendCommentAppendix(\n ctx,\n marks.filter((a): a is CommentAnnotation => a.kind === 'comment'),\n firstSize ?? FALLBACK_PAGE\n )\n reportReplaced(ctx.sanitiser, warnings)\n }\n return { doc: out, pages: rasterizer.numPages, dpi: Math.round(lowestDpi) }\n } finally {\n await rasterizer.destroy()\n }\n}\n\n/** Invisible words over the burned image, so the page is searchable without the redacted text. */\nfunction drawInvisibleText(\n page: ReturnType<PDFDocument['addPage']>,\n words: OcrWord[],\n widthPt: number,\n heightPt: number,\n font: Awaited<ReturnType<PDFDocument['embedFont']>>,\n sanitiser: TextSanitiser\n) {\n for (const w of words) {\n if (!w.text || !sanitiser.supports(w.text)) continue\n const size = Math.max(1, w.h * heightPt * 0.8)\n page.drawText(w.text, {\n x: w.x * widthPt,\n y: heightPt - (w.y + w.h) * heightPt,\n size,\n font,\n color: rgb(0, 0, 0),\n opacity: 0,\n })\n }\n}\n\nfunction reportReplaced(sanitiser: TextSanitiser, warnings: string[]) {\n if (sanitiser.replaced.size > 0) {\n warnings.push(\n `${sanitiser.replaced.size} character(s) in comments cannot be drawn by the built-in font and were replaced with \"?\"`\n )\n }\n}\n\nfunction setProvenance(doc: PDFDocument, provenance: FreezeProvenance) {\n // The info dictionary exists once any metadata setter has run (both builders call one).\n const info = doc.context.lookup(doc.context.trailerInfo.Info)\n if (!info || !('set' in info)) throw new Error('document has no info dictionary')\n ;(info as unknown as { set(k: PDFName, v: PDFHexString): void }).set(\n PDFName.of(PROVENANCE_KEY),\n PDFHexString.fromText(JSON.stringify(provenance))\n )\n}\n\n/** Read the provenance record back out of a frozen PDF, or null if it has none. */\nexport async function readProvenance(bytes: Uint8Array): Promise<FreezeProvenance | null> {\n const doc = await PDFDocument.load(bytes)\n const info = doc.context.lookup(doc.context.trailerInfo.Info)\n if (!info || !('get' in info)) return null\n const value = (info as unknown as { get(k: PDFName): unknown }).get(PDFName.of(PROVENANCE_KEY))\n if (!(value instanceof PDFHexString)) return null\n return JSON.parse(value.decodeText()) as FreezeProvenance\n}\n\n/** The picture stamps' images, decoded for drawing onto rendered pages (none where unsupported). */\nasync function stampImages(marks: Annotation[]) {\n const out = new Map<string, ImageBitmap>()\n if (typeof createImageBitmap !== 'function') return out\n for (const a of marks) {\n if (a.kind !== 'stamp' || !a.image) continue\n const raw = atob(a.image)\n const bytes = new Uint8Array(raw.length)\n for (let i = 0; i < raw.length; i++) bytes[i] = raw.charCodeAt(i)\n out.set(a.id, await createImageBitmap(new Blob([bytes], { type: 'image/png' })))\n }\n return out\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,28 @@
1
+ async function sha256Hex(bytes) {
2
+ const copy = new Uint8Array(bytes.byteLength);
3
+ copy.set(bytes);
4
+ const digest = await globalThis.crypto.subtle.digest("SHA-256", copy.buffer);
5
+ return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, "0")).join("");
6
+ }
7
+ function canonicalJson(value) {
8
+ if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
9
+ if (value && typeof value === "object") {
10
+ const entries = Object.entries(value).filter(([, v]) => v !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
11
+ return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`).join(",")}}`;
12
+ }
13
+ return JSON.stringify(value);
14
+ }
15
+ function layerFingerprint(layer) {
16
+ return {
17
+ ...layer,
18
+ annotations: layer.annotations.map((a) => {
19
+ return a.kind === "redaction" ? { ...a, text: void 0 } : a;
20
+ })
21
+ };
22
+ }
23
+ const hashLayer = (layer) => sha256Hex(new TextEncoder().encode(canonicalJson(layerFingerprint(layer))));
24
+ export {
25
+ hashLayer,
26
+ sha256Hex
27
+ };
28
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/annotations/freeze/hash.ts"],
4
+ "sourcesContent": ["import type { AnnotationLayer } from '../model'\n\nexport async function sha256Hex(bytes: Uint8Array): Promise<string> {\n // Copy into a plain ArrayBuffer: `bytes` may be a view over a larger or shared buffer.\n const copy = new Uint8Array(bytes.byteLength)\n copy.set(bytes)\n const digest = await globalThis.crypto.subtle.digest('SHA-256', copy.buffer)\n return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, '0')).join('')\n}\n\n/** JSON with object keys sorted, so equal data always hashes equally. */\nfunction canonicalJson(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`\n if (value && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`).join(',')}}`\n }\n return JSON.stringify(value)\n}\n\n/** The layer as hashed for provenance: the text under redactions is dropped first. */\nfunction layerFingerprint(layer: AnnotationLayer): unknown {\n return {\n ...layer,\n annotations: layer.annotations.map((a) => {\n // `text: undefined` is dropped by canonicalJson, so the text never reaches the hash.\n return a.kind === 'redaction' ? { ...a, text: undefined } : a\n }),\n }\n}\n\nexport const hashLayer = (layer: AnnotationLayer) =>\n sha256Hex(new TextEncoder().encode(canonicalJson(layerFingerprint(layer))))\n"],
5
+ "mappings": "AAEA,eAAsB,UAAU,OAAoC;AAElE,QAAM,OAAO,IAAI,WAAW,MAAM,UAAU;AAC5C,OAAK,IAAI,KAAK;AACd,QAAM,SAAS,MAAM,WAAW,OAAO,OAAO,OAAO,WAAW,KAAK,MAAM;AAC3E,SAAO,MAAM,KAAK,IAAI,WAAW,MAAM,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AAC3F;AAGA,SAAS,cAAc,OAAwB;AAC7C,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,IAAI,MAAM,IAAI,aAAa,EAAE,KAAK,GAAG,CAAC;AACvE,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,UAAU,OAAO,QAAQ,KAAgC,EAC5D,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS,EACjC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE;AAClD,WAAO,IAAI,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,UAAU,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC;AAAA,EAC1F;AACA,SAAO,KAAK,UAAU,KAAK;AAC7B;AAGA,SAAS,iBAAiB,OAAiC;AACzD,SAAO;AAAA,IACL,GAAG;AAAA,IACH,aAAa,MAAM,YAAY,IAAI,CAAC,MAAM;AAExC,aAAO,EAAE,SAAS,cAAc,EAAE,GAAG,GAAG,MAAM,OAAU,IAAI;AAAA,IAC9D,CAAC;AAAA,EACH;AACF;AAEO,MAAM,YAAY,CAAC,UACxB,UAAU,IAAI,YAAY,EAAE,OAAO,cAAc,iBAAiB,KAAK,CAAC,CAAC,CAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,78 @@
1
+ import { StandardFonts, rgb } from "pdf-lib";
2
+ import { TextSanitiser, wrap } from "./vector.js";
3
+ const A4 = [595.28, 841.89];
4
+ const MARGIN = 54;
5
+ const LINE = 13;
6
+ const TEXT = rgb(0.1, 0.1, 0.1);
7
+ const MUTED = rgb(0.4, 0.4, 0.4);
8
+ async function insertIndexPages(doc, entries, options) {
9
+ const regular = await doc.embedFont(StandardFonts.Helvetica);
10
+ const bold = await doc.embedFont(StandardFonts.HelveticaBold);
11
+ const sanitiser = new TextSanitiser(regular);
12
+ const [width, height] = options.size ?? A4;
13
+ const columns = {
14
+ number: MARGIN,
15
+ name: MARGIN + 28,
16
+ range: width - MARGIN - 190,
17
+ pages: width - MARGIN - 30
18
+ };
19
+ const nameWidth = columns.range - columns.name - 12;
20
+ let inserted = 0;
21
+ let page;
22
+ let y = 0;
23
+ const newPage = () => {
24
+ page = doc.insertPage(inserted++, [width, height]);
25
+ y = height - MARGIN;
26
+ };
27
+ const text = (value, x, font, size, color = TEXT) => page.drawText(sanitiser.clean(value), { x, y: y - size, size, font, color });
28
+ const header = () => {
29
+ text("#", columns.number, bold, 9, MUTED);
30
+ text("Document", columns.name, bold, 9, MUTED);
31
+ text("Bates range", columns.range, bold, 9, MUTED);
32
+ text("Pages", columns.pages, bold, 9, MUTED);
33
+ y -= LINE + 4;
34
+ };
35
+ newPage();
36
+ text("Production index", MARGIN, bold, 16);
37
+ y -= 24;
38
+ const first = entries[0]?.firstLabel;
39
+ const last = entries[entries.length - 1]?.lastLabel;
40
+ const total = entries.reduce((n, e) => n + e.pages, 0);
41
+ const summary = [
42
+ `${entries.length} document${entries.length === 1 ? "" : "s"}, ${total} page${total === 1 ? "" : "s"}`,
43
+ first && last ? `${first} to ${last}` : "",
44
+ `produced ${options.producedAt.slice(0, 10)}`,
45
+ options.producedBy ? `by ${options.producedBy}` : ""
46
+ ].filter(Boolean).join(", ");
47
+ text(summary, MARGIN, regular, 10, MUTED);
48
+ y -= LINE + 10;
49
+ header();
50
+ const rangeWidth = columns.pages - columns.range - 8;
51
+ entries.forEach((entry, i) => {
52
+ const lines = wrap(regular, sanitiser.clean(entry.name), 10, nameWidth);
53
+ const single = entry.firstLabel === entry.lastLabel ? entry.firstLabel : `${entry.firstLabel} - ${entry.lastLabel}`;
54
+ const range = regular.widthOfTextAtSize(sanitiser.clean(single), 10) <= rangeWidth ? [single] : [`${entry.firstLabel} -`, entry.lastLabel];
55
+ const rows = Math.max(lines.length, range.length);
56
+ if (y - rows * LINE < MARGIN) {
57
+ newPage();
58
+ header();
59
+ }
60
+ const top = y;
61
+ text(String(i + 1), columns.number, regular, 10);
62
+ text(String(entry.pages), columns.pages, regular, 10);
63
+ range.forEach((line, n) => {
64
+ y = top - n * LINE;
65
+ text(line, columns.range, regular, 10);
66
+ });
67
+ lines.forEach((line, n) => {
68
+ y = top - n * LINE;
69
+ text(line, columns.name, regular, 10);
70
+ });
71
+ y = top - rows * LINE - 4;
72
+ });
73
+ return inserted;
74
+ }
75
+ export {
76
+ insertIndexPages
77
+ };
78
+ //# sourceMappingURL=index-page.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/annotations/freeze/index-page.ts"],
4
+ "sourcesContent": ["/**\n * The index (cover) page of a production: every document in numbering order with its Bates range\n * and page count. Plain vector text, so it is searchable; it carries no Bates label of its own.\n */\n\nimport { PDFDocument, StandardFonts, rgb, type PDFFont, type PDFPage } from 'pdf-lib'\nimport { TextSanitiser, wrap } from './vector'\n\nexport interface IndexEntry {\n name: string\n pages: number\n firstLabel: string\n lastLabel: string\n}\n\nexport interface IndexPageOptions {\n /** Page size in points; defaults to A4. */\n size?: [number, number]\n /** ISO timestamp printed as the production date. */\n producedAt: string\n producedBy?: string\n}\n\nconst A4: [number, number] = [595.28, 841.89]\nconst MARGIN = 54\nconst LINE = 13\nconst TEXT = rgb(0.1, 0.1, 0.1)\nconst MUTED = rgb(0.4, 0.4, 0.4)\n\n/**\n * Insert the index as the first page(s) of `doc` (more than one when the list is long). Returns the\n * number of pages inserted.\n */\nexport async function insertIndexPages(\n doc: PDFDocument,\n entries: IndexEntry[],\n options: IndexPageOptions\n): Promise<number> {\n const regular = await doc.embedFont(StandardFonts.Helvetica)\n const bold = await doc.embedFont(StandardFonts.HelveticaBold)\n const sanitiser = new TextSanitiser(regular)\n const [width, height] = options.size ?? A4\n const columns = {\n number: MARGIN,\n name: MARGIN + 28,\n range: width - MARGIN - 190,\n pages: width - MARGIN - 30,\n }\n const nameWidth = columns.range - columns.name - 12\n\n let inserted = 0\n let page: PDFPage\n let y = 0\n const newPage = () => {\n page = doc.insertPage(inserted++, [width, height])\n y = height - MARGIN\n }\n const text = (value: string, x: number, font: PDFFont, size: number, color = TEXT) =>\n page.drawText(sanitiser.clean(value), { x, y: y - size, size, font, color })\n const header = () => {\n text('#', columns.number, bold, 9, MUTED)\n text('Document', columns.name, bold, 9, MUTED)\n text('Bates range', columns.range, bold, 9, MUTED)\n text('Pages', columns.pages, bold, 9, MUTED)\n y -= LINE + 4\n }\n\n newPage()\n text('Production index', MARGIN, bold, 16)\n y -= 24\n const first = entries[0]?.firstLabel\n const last = entries[entries.length - 1]?.lastLabel\n const total = entries.reduce((n, e) => n + e.pages, 0)\n const summary = [\n `${entries.length} document${entries.length === 1 ? '' : 's'}, ${total} page${total === 1 ? '' : 's'}`,\n first && last ? `${first} to ${last}` : '',\n `produced ${options.producedAt.slice(0, 10)}`,\n options.producedBy ? `by ${options.producedBy}` : '',\n ]\n .filter(Boolean)\n .join(', ')\n text(summary, MARGIN, regular, 10, MUTED)\n y -= LINE + 10\n header()\n\n const rangeWidth = columns.pages - columns.range - 8\n entries.forEach((entry, i) => {\n const lines = wrap(regular, sanitiser.clean(entry.name), 10, nameWidth)\n const single =\n entry.firstLabel === entry.lastLabel\n ? entry.firstLabel\n : `${entry.firstLabel} - ${entry.lastLabel}`\n // A long prefix does not fit on one line: first label, then the last below it.\n const range =\n regular.widthOfTextAtSize(sanitiser.clean(single), 10) <= rangeWidth\n ? [single]\n : [`${entry.firstLabel} -`, entry.lastLabel]\n const rows = Math.max(lines.length, range.length)\n if (y - rows * LINE < MARGIN) {\n newPage()\n header()\n }\n const top = y\n text(String(i + 1), columns.number, regular, 10)\n text(String(entry.pages), columns.pages, regular, 10)\n range.forEach((line, n) => {\n y = top - n * LINE\n text(line, columns.range, regular, 10)\n })\n lines.forEach((line, n) => {\n y = top - n * LINE\n text(line, columns.name, regular, 10)\n })\n y = top - rows * LINE - 4\n })\n return inserted\n}\n"],
5
+ "mappings": "AAKA,SAAsB,eAAe,WAAuC;AAC5E,SAAS,eAAe,YAAY;AAiBpC,MAAM,KAAuB,CAAC,QAAQ,MAAM;AAC5C,MAAM,SAAS;AACf,MAAM,OAAO;AACb,MAAM,OAAO,IAAI,KAAK,KAAK,GAAG;AAC9B,MAAM,QAAQ,IAAI,KAAK,KAAK,GAAG;AAM/B,eAAsB,iBACpB,KACA,SACA,SACiB;AACjB,QAAM,UAAU,MAAM,IAAI,UAAU,cAAc,SAAS;AAC3D,QAAM,OAAO,MAAM,IAAI,UAAU,cAAc,aAAa;AAC5D,QAAM,YAAY,IAAI,cAAc,OAAO;AAC3C,QAAM,CAAC,OAAO,MAAM,IAAI,QAAQ,QAAQ;AACxC,QAAM,UAAU;AAAA,IACd,QAAQ;AAAA,IACR,MAAM,SAAS;AAAA,IACf,OAAO,QAAQ,SAAS;AAAA,IACxB,OAAO,QAAQ,SAAS;AAAA,EAC1B;AACA,QAAM,YAAY,QAAQ,QAAQ,QAAQ,OAAO;AAEjD,MAAI,WAAW;AACf,MAAI;AACJ,MAAI,IAAI;AACR,QAAM,UAAU,MAAM;AACpB,WAAO,IAAI,WAAW,YAAY,CAAC,OAAO,MAAM,CAAC;AACjD,QAAI,SAAS;AAAA,EACf;AACA,QAAM,OAAO,CAAC,OAAe,GAAW,MAAe,MAAc,QAAQ,SAC3E,KAAK,SAAS,UAAU,MAAM,KAAK,GAAG,EAAE,GAAG,GAAG,IAAI,MAAM,MAAM,MAAM,MAAM,CAAC;AAC7E,QAAM,SAAS,MAAM;AACnB,SAAK,KAAK,QAAQ,QAAQ,MAAM,GAAG,KAAK;AACxC,SAAK,YAAY,QAAQ,MAAM,MAAM,GAAG,KAAK;AAC7C,SAAK,eAAe,QAAQ,OAAO,MAAM,GAAG,KAAK;AACjD,SAAK,SAAS,QAAQ,OAAO,MAAM,GAAG,KAAK;AAC3C,SAAK,OAAO;AAAA,EACd;AAEA,UAAQ;AACR,OAAK,oBAAoB,QAAQ,MAAM,EAAE;AACzC,OAAK;AACL,QAAM,QAAQ,QAAQ,CAAC,GAAG;AAC1B,QAAM,OAAO,QAAQ,QAAQ,SAAS,CAAC,GAAG;AAC1C,QAAM,QAAQ,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC;AACrD,QAAM,UAAU;AAAA,IACd,GAAG,QAAQ,MAAM,YAAY,QAAQ,WAAW,IAAI,KAAK,GAAG,KAAK,KAAK,QAAQ,UAAU,IAAI,KAAK,GAAG;AAAA,IACpG,SAAS,OAAO,GAAG,KAAK,OAAO,IAAI,KAAK;AAAA,IACxC,YAAY,QAAQ,WAAW,MAAM,GAAG,EAAE,CAAC;AAAA,IAC3C,QAAQ,aAAa,MAAM,QAAQ,UAAU,KAAK;AAAA,EACpD,EACG,OAAO,OAAO,EACd,KAAK,IAAI;AACZ,OAAK,SAAS,QAAQ,SAAS,IAAI,KAAK;AACxC,OAAK,OAAO;AACZ,SAAO;AAEP,QAAM,aAAa,QAAQ,QAAQ,QAAQ,QAAQ;AACnD,UAAQ,QAAQ,CAAC,OAAO,MAAM;AAC5B,UAAM,QAAQ,KAAK,SAAS,UAAU,MAAM,MAAM,IAAI,GAAG,IAAI,SAAS;AACtE,UAAM,SACJ,MAAM,eAAe,MAAM,YACvB,MAAM,aACN,GAAG,MAAM,UAAU,MAAM,MAAM,SAAS;AAE9C,UAAM,QACJ,QAAQ,kBAAkB,UAAU,MAAM,MAAM,GAAG,EAAE,KAAK,aACtD,CAAC,MAAM,IACP,CAAC,GAAG,MAAM,UAAU,MAAM,MAAM,SAAS;AAC/C,UAAM,OAAO,KAAK,IAAI,MAAM,QAAQ,MAAM,MAAM;AAChD,QAAI,IAAI,OAAO,OAAO,QAAQ;AAC5B,cAAQ;AACR,aAAO;AAAA,IACT;AACA,UAAM,MAAM;AACZ,SAAK,OAAO,IAAI,CAAC,GAAG,QAAQ,QAAQ,SAAS,EAAE;AAC/C,SAAK,OAAO,MAAM,KAAK,GAAG,QAAQ,OAAO,SAAS,EAAE;AACpD,UAAM,QAAQ,CAAC,MAAM,MAAM;AACzB,UAAI,MAAM,IAAI;AACd,WAAK,MAAM,QAAQ,OAAO,SAAS,EAAE;AAAA,IACvC,CAAC;AACD,UAAM,QAAQ,CAAC,MAAM,MAAM;AACzB,UAAI,MAAM,IAAI;AACd,WAAK,MAAM,QAAQ,MAAM,SAAS,EAAE;AAAA,IACtC,CAAC;AACD,QAAI,MAAM,OAAO,OAAO;AAAA,EAC1B,CAAC;AACD,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -1,23 +1,29 @@
1
- import { createPdfJsRasterizer, browserCanvasFactory, freezePdf } from '../../chunk-NIKPG4PW.js';
2
- export { DEFAULT_DPI, FreezeError, MAX_PAGE_PIXELS, batesLabel, browserCanvasFactory, buildBundle, burnMarks, createPdfJsRasterizer, freezePdf, readProvenance } from '../../chunk-NIKPG4PW.js';
3
- import '../../chunk-PTOP7OHG.js';
4
- import { isEffectiveRedaction } from '../../chunk-T3USOSVN.js';
5
- import { pdfjs } from 'react-pdf';
6
-
7
- async function freezePdfInBrowser(bytes, layer, { assets, password, ...options }) {
8
- const needsRaster = options.mode === "image" || layer.annotations.some(isEffectiveRedaction);
9
- const rasterizer = needsRaster ? await createPdfJsRasterizer(pdfjs, bytes, browserCanvasFactory(), {
10
- password,
11
- documentOptions: {
12
- cMapUrl: assets?.cMapUrl ?? "/cmaps/",
13
- cMapPacked: true,
14
- standardFontDataUrl: assets?.standardFontDataUrl ?? "/standard_fonts/",
15
- wasmUrl: assets?.wasmUrl ?? "/wasm/"
16
- }
17
- }) : void 0;
18
- return freezePdf(bytes, layer, { ...options, rasterizer });
19
- }
20
-
21
- export { freezePdfInBrowser };
1
+ import { freezePdf, readProvenance, DEFAULT_DPI } from "./freeze.js";
2
+ import { freezePdfInBrowser } from "./browser.js";
3
+ import {
4
+ buildBundle
5
+ } from "./bundle.js";
6
+ import { batesLabel } from "./stamp.js";
7
+ import {
8
+ browserCanvasFactory,
9
+ burnMarks,
10
+ createPdfJsRasterizer,
11
+ MAX_PAGE_PIXELS
12
+ } from "./raster.js";
13
+ import {
14
+ FreezeError
15
+ } from "./types.js";
16
+ export {
17
+ DEFAULT_DPI,
18
+ FreezeError,
19
+ MAX_PAGE_PIXELS,
20
+ batesLabel,
21
+ browserCanvasFactory,
22
+ buildBundle,
23
+ burnMarks,
24
+ createPdfJsRasterizer,
25
+ freezePdf,
26
+ freezePdfInBrowser,
27
+ readProvenance
28
+ };
22
29
  //# sourceMappingURL=index.js.map
23
- //# sourceMappingURL=index.js.map
@@ -1 +1,7 @@
1
- {"version":3,"sources":["../../../src/annotations/freeze/browser.ts"],"names":[],"mappings":";;;;;;AAkBA,eAAsB,kBAAA,CACpB,OACA,KAAA,EACA,EAAE,QAAQ,QAAA,EAAU,GAAG,SAAQ,EACR;AAEvB,EAAA,MAAM,cAAc,OAAA,CAAQ,IAAA,KAAS,WAAW,KAAA,CAAM,WAAA,CAAY,KAAK,oBAAoB,CAAA;AAC3F,EAAA,MAAM,aAAa,WAAA,GACf,MAAM,sBAAsB,KAAA,EAAiC,KAAA,EAAO,sBAAqB,EAAG;AAAA,IAC1F,QAAA;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,QAAQ,OAAA,IAAW,SAAA;AAAA,MAC5B,UAAA,EAAY,IAAA;AAAA,MACZ,mBAAA,EAAqB,QAAQ,mBAAA,IAAuB,kBAAA;AAAA,MACpD,OAAA,EAAS,QAAQ,OAAA,IAAW;AAAA;AAC9B,GACD,CAAA,GACD,MAAA;AACJ,EAAA,OAAO,UAAU,KAAA,EAAO,KAAA,EAAO,EAAE,GAAG,OAAA,EAAS,YAAY,CAAA;AAC3D","file":"index.js","sourcesContent":["/**\n * Freeze in the browser: wires the pdf.js already loaded for viewing (via react-pdf) into the\n * rasteriser, so a frozen copy is produced client-side and the document never leaves the device.\n */\n\nimport { pdfjs } from 'react-pdf'\nimport type { PdfViewerAssets } from '../../viewers/PdfViewer'\nimport { isEffectiveRedaction, type AnnotationLayer } from '../model'\nimport { freezePdf } from './freeze'\nimport { browserCanvasFactory, createPdfJsRasterizer, type PdfJsModule } from './raster'\nimport type { FreezeOptions, FreezeResult } from './types'\n\nexport type BrowserFreezeOptions = Omit<FreezeOptions, 'rasterizer'> & {\n /** Where the app serves pdf.js cmaps, fonts and wasm from; same shape the viewer takes. */\n assets?: PdfViewerAssets\n password?: string\n}\n\nexport async function freezePdfInBrowser(\n bytes: Uint8Array,\n layer: AnnotationLayer,\n { assets, password, ...options }: BrowserFreezeOptions\n): Promise<FreezeResult> {\n // Redactions always produce an image copy, so a rasteriser is needed whenever they apply.\n const needsRaster = options.mode === 'image' || layer.annotations.some(isEffectiveRedaction)\n const rasterizer = needsRaster\n ? await createPdfJsRasterizer(pdfjs as unknown as PdfJsModule, bytes, browserCanvasFactory(), {\n password,\n documentOptions: {\n cMapUrl: assets?.cMapUrl ?? '/cmaps/',\n cMapPacked: true,\n standardFontDataUrl: assets?.standardFontDataUrl ?? '/standard_fonts/',\n wasmUrl: assets?.wasmUrl ?? '/wasm/',\n },\n })\n : undefined\n return freezePdf(bytes, layer, { ...options, rasterizer })\n}\n"]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/annotations/freeze/index.ts"],
4
+ "sourcesContent": ["/**\n * `@arbidocs/react/annotations/freeze` \u2014 derive a new document from an immutable original and its\n * annotation layer: flattened with text kept (`vector`), or rebuilt from page images (`image`,\n * always used when redactions apply).\n *\n * `buildBundle` then turns frozen PDFs into a production set: one merged file or one file per\n * document, numbered consecutively with a Bates label, optionally with a QR code on every page that\n * links back to the document in ARBI. Splitting documents is not part of it.\n *\n * A SEPARATE ENTRY on purpose: it needs `pdf-lib` and `react-pdf`, both optional peer dependencies,\n * so an app that only draws annotations installs and bundles neither.\n */\n\nexport { freezePdf, readProvenance, DEFAULT_DPI } from './freeze'\nexport { freezePdfInBrowser, type BrowserFreezeOptions } from './browser'\nexport {\n buildBundle,\n type BundleFile,\n type BundleIndexEntry,\n type BundleItem,\n type BundleLayout,\n type BundleOptions,\n type BundleResult,\n} from './bundle'\nexport { batesLabel, type BatesOptions, type StampCorner } from './stamp'\nexport {\n browserCanvasFactory,\n burnMarks,\n createPdfJsRasterizer,\n MAX_PAGE_PIXELS,\n type BurnOptions,\n type CanvasFactory,\n type CanvasHandle,\n type PdfJsModule,\n type PdfJsRasterizerOptions,\n} from './raster'\nexport {\n FreezeError,\n type CommentOutput,\n type FreezeErrorCode,\n type FreezeMode,\n type FreezeOptions,\n type FreezeProvenance,\n type FreezeResult,\n type OcrInput,\n type OcrWord,\n type PageRasterizer,\n type RenderedPage,\n} from './types'\n"],
5
+ "mappings": "AAaA,SAAS,WAAW,gBAAgB,mBAAmB;AACvD,SAAS,0BAAqD;AAC9D;AAAA,EACE;AAAA,OAOK;AACP,SAAS,kBAAuD;AAChE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAMK;AACP;AAAA,EACE;AAAA,OAWK;",
6
+ "names": []
7
+ }
@@ -0,0 +1,208 @@
1
+ import { isEffectiveRedaction } from "../model.js";
2
+ import { installPdfjsPolyfills } from "../../viewers/pdfjs-polyfills.js";
3
+ import { HIGHLIGHT_OPACITY, MARKER_SIZE_PT } from "./vector.js";
4
+ import {
5
+ ENCRYPTED_MESSAGE,
6
+ FreezeError
7
+ } from "./types.js";
8
+ const MAX_PAGE_PIXELS = 36e6;
9
+ const MARKER_FILL = "#ffd43b";
10
+ const MARKER_INK = "#7a5c00";
11
+ function browserCanvasFactory() {
12
+ return (width, height) => {
13
+ if (typeof OffscreenCanvas !== "undefined") {
14
+ const canvas2 = new OffscreenCanvas(width, height);
15
+ const ctx2 = canvas2.getContext("2d");
16
+ return {
17
+ canvas: canvas2,
18
+ ctx: ctx2,
19
+ async encode(format, quality) {
20
+ const blob = await canvas2.convertToBlob({ type: `image/${format}`, quality });
21
+ return new Uint8Array(await blob.arrayBuffer());
22
+ },
23
+ release() {
24
+ canvas2.width = 0;
25
+ canvas2.height = 0;
26
+ }
27
+ };
28
+ }
29
+ const canvas = document.createElement("canvas");
30
+ canvas.width = width;
31
+ canvas.height = height;
32
+ const ctx = canvas.getContext("2d");
33
+ return {
34
+ canvas,
35
+ ctx,
36
+ encode(format, quality) {
37
+ return new Promise((resolve, reject) => {
38
+ canvas.toBlob(
39
+ (blob) => {
40
+ if (!blob) return reject(new Error("canvas could not be encoded"));
41
+ void blob.arrayBuffer().then((buf) => resolve(new Uint8Array(buf)), reject);
42
+ },
43
+ `image/${format}`,
44
+ quality
45
+ );
46
+ });
47
+ },
48
+ release() {
49
+ canvas.width = 0;
50
+ canvas.height = 0;
51
+ }
52
+ };
53
+ };
54
+ }
55
+ async function createPdfJsRasterizer(pdfjs, data, canvases, options = {}) {
56
+ installPdfjsPolyfills();
57
+ const task = pdfjs.getDocument({
58
+ data: data.slice(),
59
+ password: options.password,
60
+ ...options.documentOptions
61
+ });
62
+ let doc;
63
+ try {
64
+ doc = await task.promise;
65
+ } catch (error) {
66
+ await task.destroy().catch(() => {
67
+ });
68
+ if (error?.name === "PasswordException") {
69
+ throw new FreezeError("encrypted", ENCRYPTED_MESSAGE);
70
+ }
71
+ throw error;
72
+ }
73
+ return {
74
+ numPages: doc.numPages,
75
+ async renderPage(pageNumber, dpi) {
76
+ const page = await doc.getPage(pageNumber);
77
+ try {
78
+ const base = page.getViewport({ scale: 1 });
79
+ let scale = dpi / 72;
80
+ const pixels = base.width * scale * (base.height * scale);
81
+ if (pixels > MAX_PAGE_PIXELS) scale *= Math.sqrt(MAX_PAGE_PIXELS / pixels);
82
+ const viewport = page.getViewport({ scale });
83
+ const widthPx = Math.max(1, Math.ceil(viewport.width));
84
+ const heightPx = Math.max(1, Math.ceil(viewport.height));
85
+ const handle = canvases(widthPx, heightPx);
86
+ handle.ctx.fillStyle = "#ffffff";
87
+ handle.ctx.fillRect(0, 0, widthPx, heightPx);
88
+ await page.render({ canvasContext: handle.ctx, canvas: handle.canvas, viewport }).promise;
89
+ return {
90
+ widthPt: base.width,
91
+ heightPt: base.height,
92
+ widthPx,
93
+ heightPx,
94
+ dpi: scale * 72,
95
+ ctx: handle.ctx,
96
+ encode: handle.encode,
97
+ release: handle.release
98
+ };
99
+ } finally {
100
+ page.cleanup();
101
+ }
102
+ },
103
+ destroy: () => task.destroy()
104
+ };
105
+ }
106
+ function burnMarks(page, marks, options) {
107
+ const { ctx } = page;
108
+ const w = page.widthPx;
109
+ const h = page.heightPx;
110
+ const pxPerPt = page.widthPx / page.widthPt;
111
+ ctx.save();
112
+ for (const a of marks) {
113
+ if (a.kind === "highlight") {
114
+ ctx.globalCompositeOperation = "multiply";
115
+ ctx.globalAlpha = HIGHLIGHT_OPACITY;
116
+ ctx.fillStyle = a.color;
117
+ for (const r of a.rects) ctx.fillRect(r.x * w, r.y * h, r.w * w, r.h * h);
118
+ ctx.globalCompositeOperation = "source-over";
119
+ ctx.globalAlpha = 1;
120
+ }
121
+ }
122
+ for (const a of marks) {
123
+ if (a.kind === "box") {
124
+ ctx.strokeStyle = a.color;
125
+ ctx.lineWidth = a.strokeWidth * pxPerPt;
126
+ ctx.strokeRect(a.rect.x * w, a.rect.y * h, a.rect.w * w, a.rect.h * h);
127
+ } else if (a.kind === "stamp" && options.images?.get(a.id)) {
128
+ const picture = options.images.get(a.id);
129
+ const box = { x: a.rect.x * w, y: a.rect.y * h, w: a.rect.w * w, h: a.rect.h * h };
130
+ const scale = Math.min(box.w / picture.width, box.h / picture.height);
131
+ const dw = picture.width * scale;
132
+ const dh = picture.height * scale;
133
+ ctx.drawImage(picture, box.x + (box.w - dw) / 2, box.y + (box.h - dh) / 2, dw, dh);
134
+ } else if (a.kind === "stamp") {
135
+ drawStampOnCanvas(
136
+ ctx,
137
+ a.label,
138
+ a.color,
139
+ { x: a.rect.x * w, y: a.rect.y * h, w: a.rect.w * w, h: a.rect.h * h },
140
+ pxPerPt
141
+ );
142
+ } else if (a.kind === "comment" && options.comments !== "omit") {
143
+ drawMarkerOnCanvas(ctx, a, options.numbers.get(a.id), w, h, pxPerPt);
144
+ }
145
+ }
146
+ for (const a of marks) {
147
+ if (!isEffectiveRedaction(a)) continue;
148
+ const pad = options.paddingPt * pxPerPt;
149
+ a.rects.forEach((r, i) => {
150
+ const x0 = Math.max(0, Math.floor(r.x * w - pad));
151
+ const y0 = Math.max(0, Math.floor(r.y * h - pad));
152
+ const x1 = Math.min(w, Math.ceil((r.x + r.w) * w + pad));
153
+ const y1 = Math.min(h, Math.ceil((r.y + r.h) * h + pad));
154
+ ctx.fillStyle = "#000000";
155
+ ctx.fillRect(x0, y0, x1 - x0, y1 - y0);
156
+ if (options.labels && i === 0)
157
+ drawLabel(ctx, "[REDACTED]", { x: x0, y: y0, w: x1 - x0, h: y1 - y0 });
158
+ });
159
+ }
160
+ ctx.restore();
161
+ }
162
+ function drawStampOnCanvas(ctx, label, color, box, pxPerPt) {
163
+ ctx.strokeStyle = color;
164
+ ctx.lineWidth = 2 * pxPerPt;
165
+ ctx.strokeRect(box.x, box.y, box.w, box.h);
166
+ ctx.fillStyle = color;
167
+ ctx.textAlign = "center";
168
+ ctx.textBaseline = "middle";
169
+ ctx.font = "bold 100px Helvetica, Arial, sans-serif";
170
+ const probe = ctx.measureText(label).width;
171
+ const size = Math.max(1, Math.min(box.h * 0.6, probe > 0 ? box.w * 0.9 * 100 / probe : box.h));
172
+ ctx.font = `bold ${size}px Helvetica, Arial, sans-serif`;
173
+ ctx.fillText(label, box.x + box.w / 2, box.y + box.h / 2);
174
+ }
175
+ function drawMarkerOnCanvas(ctx, a, n, w, h, pxPerPt) {
176
+ if (n === void 0) return;
177
+ const size = MARKER_SIZE_PT * pxPerPt;
178
+ const x = Math.min(a.rect.x * w, w - size);
179
+ const y = Math.min(a.rect.y * h, h - size);
180
+ ctx.fillStyle = MARKER_FILL;
181
+ ctx.fillRect(x, y, size, size);
182
+ ctx.strokeStyle = MARKER_INK;
183
+ ctx.lineWidth = 0.75 * pxPerPt;
184
+ ctx.strokeRect(x, y, size, size);
185
+ ctx.fillStyle = MARKER_INK;
186
+ ctx.textAlign = "center";
187
+ ctx.textBaseline = "middle";
188
+ ctx.font = `bold ${7 * pxPerPt}px Helvetica, Arial, sans-serif`;
189
+ ctx.fillText(String(n), x + size / 2, y + size / 2);
190
+ }
191
+ function drawLabel(ctx, text, box) {
192
+ const size = Math.min(box.h * 0.7, 14);
193
+ if (size < 6) return;
194
+ ctx.font = `${size}px Helvetica, Arial, sans-serif`;
195
+ const width = ctx.measureText(text).width;
196
+ if (width > box.w - 4) return;
197
+ ctx.fillStyle = "#ffffff";
198
+ ctx.textAlign = "center";
199
+ ctx.textBaseline = "middle";
200
+ ctx.fillText(text, box.x + box.w / 2, box.y + box.h / 2);
201
+ }
202
+ export {
203
+ MAX_PAGE_PIXELS,
204
+ browserCanvasFactory,
205
+ burnMarks,
206
+ createPdfJsRasterizer
207
+ };
208
+ //# sourceMappingURL=raster.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/annotations/freeze/raster.ts"],
4
+ "sourcesContent": ["/**\n * Image-only freeze: render each page onto a canvas, burn the marks into the pixels, and encode.\n * Once a redaction rectangle is painted black the original pixels are gone, and the rebuilt PDF\n * has no text layer, so nothing sits behind the box.\n */\n\nimport type { Annotation, CommentAnnotation } from '../model'\nimport { isEffectiveRedaction } from '../model'\nimport { installPdfjsPolyfills } from '../../viewers/pdfjs-polyfills'\nimport { HIGHLIGHT_OPACITY, MARKER_SIZE_PT } from './vector'\nimport {\n ENCRYPTED_MESSAGE,\n FreezeError,\n type CommentOutput,\n type PageRasterizer,\n type RenderedPage,\n} from './types'\n\n/** A canvas the freeze code can draw on, produced by the host's environment. */\nexport interface CanvasHandle {\n canvas: unknown\n ctx: CanvasRenderingContext2D\n encode(format: 'jpeg' | 'png', quality: number): Promise<Uint8Array>\n release(): void\n}\nexport type CanvasFactory = (width: number, height: number) => CanvasHandle\n\n/** Pages beyond this many pixels are rendered at a lower DPI (mobile Safari fails near 16.7M). */\nexport const MAX_PAGE_PIXELS = 36_000_000\nconst MARKER_FILL = '#ffd43b'\nconst MARKER_INK = '#7a5c00'\n\nexport function browserCanvasFactory(): CanvasFactory {\n return (width, height) => {\n if (typeof OffscreenCanvas !== 'undefined') {\n const canvas = new OffscreenCanvas(width, height)\n const ctx = canvas.getContext('2d') as unknown as CanvasRenderingContext2D\n return {\n canvas,\n ctx,\n async encode(format, quality) {\n const blob = await canvas.convertToBlob({ type: `image/${format}`, quality })\n return new Uint8Array(await blob.arrayBuffer())\n },\n release() {\n canvas.width = 0\n canvas.height = 0\n },\n }\n }\n const canvas = document.createElement('canvas')\n canvas.width = width\n canvas.height = height\n const ctx = canvas.getContext('2d') as CanvasRenderingContext2D\n return {\n canvas,\n ctx,\n encode(format, quality) {\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (!blob) return reject(new Error('canvas could not be encoded'))\n void blob.arrayBuffer().then((buf) => resolve(new Uint8Array(buf)), reject)\n },\n `image/${format}`,\n quality\n )\n })\n },\n release() {\n canvas.width = 0\n canvas.height = 0\n },\n }\n }\n}\n\ninterface PdfJsViewport {\n width: number\n height: number\n}\ninterface PdfJsPage {\n getViewport(options: { scale: number }): PdfJsViewport\n render(params: {\n canvasContext: CanvasRenderingContext2D\n canvas: unknown\n viewport: PdfJsViewport\n }): { promise: Promise<void> }\n cleanup(): void\n}\ninterface PdfJsDocument {\n numPages: number\n getPage(n: number): Promise<PdfJsPage>\n}\ninterface PdfJsLoadingTask {\n promise: Promise<PdfJsDocument>\n /** pdf.js 6 removed `PDFDocumentProxy.destroy()`; the loading task owns teardown. */\n destroy(): Promise<void>\n}\n/** The slice of `pdfjs-dist` the rasteriser needs, so the host decides which build to pass. */\nexport interface PdfJsModule {\n getDocument(source: Record<string, unknown>): PdfJsLoadingTask\n}\n\nexport interface PdfJsRasterizerOptions {\n password?: string\n /** Extra `getDocument` options: cMapUrl, standardFontDataUrl, wasmUrl... */\n documentOptions?: Record<string, unknown>\n}\n\nexport async function createPdfJsRasterizer(\n pdfjs: PdfJsModule,\n data: Uint8Array,\n canvases: CanvasFactory,\n options: PdfJsRasterizerOptions = {}\n): Promise<PageRasterizer> {\n installPdfjsPolyfills()\n // pdf.js takes ownership of the buffer, so hand it a copy and keep the caller's bytes intact.\n const task = pdfjs.getDocument({\n data: data.slice(),\n password: options.password,\n ...options.documentOptions,\n })\n let doc: PdfJsDocument\n try {\n doc = await task.promise\n } catch (error) {\n await task.destroy().catch(() => {})\n if ((error as { name?: string })?.name === 'PasswordException') {\n throw new FreezeError('encrypted', ENCRYPTED_MESSAGE)\n }\n throw error\n }\n\n return {\n numPages: doc.numPages,\n async renderPage(pageNumber, dpi): Promise<RenderedPage> {\n const page = await doc.getPage(pageNumber)\n try {\n const base = page.getViewport({ scale: 1 })\n let scale = dpi / 72\n const pixels = base.width * scale * (base.height * scale)\n if (pixels > MAX_PAGE_PIXELS) scale *= Math.sqrt(MAX_PAGE_PIXELS / pixels)\n const viewport = page.getViewport({ scale })\n const widthPx = Math.max(1, Math.ceil(viewport.width))\n const heightPx = Math.max(1, Math.ceil(viewport.height))\n const handle = canvases(widthPx, heightPx)\n handle.ctx.fillStyle = '#ffffff'\n handle.ctx.fillRect(0, 0, widthPx, heightPx)\n await page.render({ canvasContext: handle.ctx, canvas: handle.canvas, viewport }).promise\n return {\n widthPt: base.width,\n heightPt: base.height,\n widthPx,\n heightPx,\n dpi: scale * 72,\n ctx: handle.ctx,\n encode: handle.encode,\n release: handle.release,\n }\n } finally {\n page.cleanup()\n }\n },\n destroy: () => task.destroy(),\n }\n}\n\nexport interface BurnOptions {\n /** Margin added around each redaction rectangle, in points. */\n paddingPt: number\n labels: boolean\n comments: CommentOutput\n numbers: Map<string, number>\n /** Picture stamps' images, decoded, by mark id (a stamp without one draws its label). */\n images?: Map<string, CanvasImageSource & { width: number; height: number }>\n}\n\n/** Paint every mark for one page onto its rendered pixels. Redactions go last, on top. */\nexport function burnMarks(page: RenderedPage, marks: Annotation[], options: BurnOptions) {\n const { ctx } = page\n const w = page.widthPx\n const h = page.heightPx\n const pxPerPt = page.widthPx / page.widthPt\n\n ctx.save()\n for (const a of marks) {\n if (a.kind === 'highlight') {\n ctx.globalCompositeOperation = 'multiply'\n ctx.globalAlpha = HIGHLIGHT_OPACITY\n ctx.fillStyle = a.color\n for (const r of a.rects) ctx.fillRect(r.x * w, r.y * h, r.w * w, r.h * h)\n ctx.globalCompositeOperation = 'source-over'\n ctx.globalAlpha = 1\n }\n }\n for (const a of marks) {\n if (a.kind === 'box') {\n ctx.strokeStyle = a.color\n ctx.lineWidth = a.strokeWidth * pxPerPt\n ctx.strokeRect(a.rect.x * w, a.rect.y * h, a.rect.w * w, a.rect.h * h)\n } else if (a.kind === 'stamp' && options.images?.get(a.id)) {\n const picture = options.images.get(a.id)!\n const box = { x: a.rect.x * w, y: a.rect.y * h, w: a.rect.w * w, h: a.rect.h * h }\n const scale = Math.min(box.w / picture.width, box.h / picture.height)\n const dw = picture.width * scale\n const dh = picture.height * scale\n ctx.drawImage(picture, box.x + (box.w - dw) / 2, box.y + (box.h - dh) / 2, dw, dh)\n } else if (a.kind === 'stamp') {\n drawStampOnCanvas(\n ctx,\n a.label,\n a.color,\n { x: a.rect.x * w, y: a.rect.y * h, w: a.rect.w * w, h: a.rect.h * h },\n pxPerPt\n )\n } else if (a.kind === 'comment' && options.comments !== 'omit') {\n drawMarkerOnCanvas(ctx, a, options.numbers.get(a.id), w, h, pxPerPt)\n }\n }\n for (const a of marks) {\n if (!isEffectiveRedaction(a)) continue\n const pad = options.paddingPt * pxPerPt\n a.rects.forEach((r, i) => {\n // Floor/ceil so anti-aliased edge pixels are covered rather than left half-grey.\n const x0 = Math.max(0, Math.floor(r.x * w - pad))\n const y0 = Math.max(0, Math.floor(r.y * h - pad))\n const x1 = Math.min(w, Math.ceil((r.x + r.w) * w + pad))\n const y1 = Math.min(h, Math.ceil((r.y + r.h) * h + pad))\n ctx.fillStyle = '#000000'\n ctx.fillRect(x0, y0, x1 - x0, y1 - y0)\n if (options.labels && i === 0)\n drawLabel(ctx, '[REDACTED]', { x: x0, y: y0, w: x1 - x0, h: y1 - y0 })\n })\n }\n ctx.restore()\n}\n\nfunction drawStampOnCanvas(\n ctx: CanvasRenderingContext2D,\n label: string,\n color: string,\n box: { x: number; y: number; w: number; h: number },\n pxPerPt: number\n) {\n ctx.strokeStyle = color\n ctx.lineWidth = 2 * pxPerPt\n ctx.strokeRect(box.x, box.y, box.w, box.h)\n ctx.fillStyle = color\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.font = 'bold 100px Helvetica, Arial, sans-serif'\n const probe = ctx.measureText(label).width\n const size = Math.max(1, Math.min(box.h * 0.6, probe > 0 ? (box.w * 0.9 * 100) / probe : box.h))\n ctx.font = `bold ${size}px Helvetica, Arial, sans-serif`\n ctx.fillText(label, box.x + box.w / 2, box.y + box.h / 2)\n}\n\nfunction drawMarkerOnCanvas(\n ctx: CanvasRenderingContext2D,\n a: CommentAnnotation,\n n: number | undefined,\n w: number,\n h: number,\n pxPerPt: number\n) {\n if (n === undefined) return\n const size = MARKER_SIZE_PT * pxPerPt\n const x = Math.min(a.rect.x * w, w - size)\n const y = Math.min(a.rect.y * h, h - size)\n ctx.fillStyle = MARKER_FILL\n ctx.fillRect(x, y, size, size)\n ctx.strokeStyle = MARKER_INK\n ctx.lineWidth = 0.75 * pxPerPt\n ctx.strokeRect(x, y, size, size)\n ctx.fillStyle = MARKER_INK\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.font = `bold ${7 * pxPerPt}px Helvetica, Arial, sans-serif`\n ctx.fillText(String(n), x + size / 2, y + size / 2)\n}\n\n/** Print the redaction reason in white on the black box, only when it fits legibly. */\nfunction drawLabel(\n ctx: CanvasRenderingContext2D,\n text: string,\n box: { x: number; y: number; w: number; h: number }\n) {\n const size = Math.min(box.h * 0.7, 14)\n if (size < 6) return\n ctx.font = `${size}px Helvetica, Arial, sans-serif`\n const width = ctx.measureText(text).width\n if (width > box.w - 4) return\n ctx.fillStyle = '#ffffff'\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillText(text, box.x + box.w / 2, box.y + box.h / 2)\n}\n"],
5
+ "mappings": "AAOA,SAAS,4BAA4B;AACrC,SAAS,6BAA6B;AACtC,SAAS,mBAAmB,sBAAsB;AAClD;AAAA,EACE;AAAA,EACA;AAAA,OAIK;AAYA,MAAM,kBAAkB;AAC/B,MAAM,cAAc;AACpB,MAAM,aAAa;AAEZ,SAAS,uBAAsC;AACpD,SAAO,CAAC,OAAO,WAAW;AACxB,QAAI,OAAO,oBAAoB,aAAa;AAC1C,YAAMA,UAAS,IAAI,gBAAgB,OAAO,MAAM;AAChD,YAAMC,OAAMD,QAAO,WAAW,IAAI;AAClC,aAAO;AAAA,QACL,QAAAA;AAAA,QACA,KAAAC;AAAA,QACA,MAAM,OAAO,QAAQ,SAAS;AAC5B,gBAAM,OAAO,MAAMD,QAAO,cAAc,EAAE,MAAM,SAAS,MAAM,IAAI,QAAQ,CAAC;AAC5E,iBAAO,IAAI,WAAW,MAAM,KAAK,YAAY,CAAC;AAAA,QAChD;AAAA,QACA,UAAU;AACR,UAAAA,QAAO,QAAQ;AACf,UAAAA,QAAO,SAAS;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AACA,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,QAAQ;AACf,WAAO,SAAS;AAChB,UAAM,MAAM,OAAO,WAAW,IAAI;AAClC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,OAAO,QAAQ,SAAS;AACtB,eAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,iBAAO;AAAA,YACL,CAAC,SAAS;AACR,kBAAI,CAAC,KAAM,QAAO,OAAO,IAAI,MAAM,6BAA6B,CAAC;AACjE,mBAAK,KAAK,YAAY,EAAE,KAAK,CAAC,QAAQ,QAAQ,IAAI,WAAW,GAAG,CAAC,GAAG,MAAM;AAAA,YAC5E;AAAA,YACA,SAAS,MAAM;AAAA,YACf;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MACA,UAAU;AACR,eAAO,QAAQ;AACf,eAAO,SAAS;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACF;AAmCA,eAAsB,sBACpB,OACA,MACA,UACA,UAAkC,CAAC,GACV;AACzB,wBAAsB;AAEtB,QAAM,OAAO,MAAM,YAAY;AAAA,IAC7B,MAAM,KAAK,MAAM;AAAA,IACjB,UAAU,QAAQ;AAAA,IAClB,GAAG,QAAQ;AAAA,EACb,CAAC;AACD,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,KAAK;AAAA,EACnB,SAAS,OAAO;AACd,UAAM,KAAK,QAAQ,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AACnC,QAAK,OAA6B,SAAS,qBAAqB;AAC9D,YAAM,IAAI,YAAY,aAAa,iBAAiB;AAAA,IACtD;AACA,UAAM;AAAA,EACR;AAEA,SAAO;AAAA,IACL,UAAU,IAAI;AAAA,IACd,MAAM,WAAW,YAAY,KAA4B;AACvD,YAAM,OAAO,MAAM,IAAI,QAAQ,UAAU;AACzC,UAAI;AACF,cAAM,OAAO,KAAK,YAAY,EAAE,OAAO,EAAE,CAAC;AAC1C,YAAI,QAAQ,MAAM;AAClB,cAAM,SAAS,KAAK,QAAQ,SAAS,KAAK,SAAS;AACnD,YAAI,SAAS,gBAAiB,UAAS,KAAK,KAAK,kBAAkB,MAAM;AACzE,cAAM,WAAW,KAAK,YAAY,EAAE,MAAM,CAAC;AAC3C,cAAM,UAAU,KAAK,IAAI,GAAG,KAAK,KAAK,SAAS,KAAK,CAAC;AACrD,cAAM,WAAW,KAAK,IAAI,GAAG,KAAK,KAAK,SAAS,MAAM,CAAC;AACvD,cAAM,SAAS,SAAS,SAAS,QAAQ;AACzC,eAAO,IAAI,YAAY;AACvB,eAAO,IAAI,SAAS,GAAG,GAAG,SAAS,QAAQ;AAC3C,cAAM,KAAK,OAAO,EAAE,eAAe,OAAO,KAAK,QAAQ,OAAO,QAAQ,SAAS,CAAC,EAAE;AAClF,eAAO;AAAA,UACL,SAAS,KAAK;AAAA,UACd,UAAU,KAAK;AAAA,UACf;AAAA,UACA;AAAA,UACA,KAAK,QAAQ;AAAA,UACb,KAAK,OAAO;AAAA,UACZ,QAAQ,OAAO;AAAA,UACf,SAAS,OAAO;AAAA,QAClB;AAAA,MACF,UAAE;AACA,aAAK,QAAQ;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS,MAAM,KAAK,QAAQ;AAAA,EAC9B;AACF;AAaO,SAAS,UAAU,MAAoB,OAAqB,SAAsB;AACvF,QAAM,EAAE,IAAI,IAAI;AAChB,QAAM,IAAI,KAAK;AACf,QAAM,IAAI,KAAK;AACf,QAAM,UAAU,KAAK,UAAU,KAAK;AAEpC,MAAI,KAAK;AACT,aAAW,KAAK,OAAO;AACrB,QAAI,EAAE,SAAS,aAAa;AAC1B,UAAI,2BAA2B;AAC/B,UAAI,cAAc;AAClB,UAAI,YAAY,EAAE;AAClB,iBAAW,KAAK,EAAE,MAAO,KAAI,SAAS,EAAE,IAAI,GAAG,EAAE,IAAI,GAAG,EAAE,IAAI,GAAG,EAAE,IAAI,CAAC;AACxE,UAAI,2BAA2B;AAC/B,UAAI,cAAc;AAAA,IACpB;AAAA,EACF;AACA,aAAW,KAAK,OAAO;AACrB,QAAI,EAAE,SAAS,OAAO;AACpB,UAAI,cAAc,EAAE;AACpB,UAAI,YAAY,EAAE,cAAc;AAChC,UAAI,WAAW,EAAE,KAAK,IAAI,GAAG,EAAE,KAAK,IAAI,GAAG,EAAE,KAAK,IAAI,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,IACvE,WAAW,EAAE,SAAS,WAAW,QAAQ,QAAQ,IAAI,EAAE,EAAE,GAAG;AAC1D,YAAM,UAAU,QAAQ,OAAO,IAAI,EAAE,EAAE;AACvC,YAAM,MAAM,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,GAAG,EAAE,KAAK,IAAI,GAAG,GAAG,EAAE,KAAK,IAAI,GAAG,GAAG,EAAE,KAAK,IAAI,EAAE;AACjF,YAAM,QAAQ,KAAK,IAAI,IAAI,IAAI,QAAQ,OAAO,IAAI,IAAI,QAAQ,MAAM;AACpE,YAAM,KAAK,QAAQ,QAAQ;AAC3B,YAAM,KAAK,QAAQ,SAAS;AAC5B,UAAI,UAAU,SAAS,IAAI,KAAK,IAAI,IAAI,MAAM,GAAG,IAAI,KAAK,IAAI,IAAI,MAAM,GAAG,IAAI,EAAE;AAAA,IACnF,WAAW,EAAE,SAAS,SAAS;AAC7B;AAAA,QACE;AAAA,QACA,EAAE;AAAA,QACF,EAAE;AAAA,QACF,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,GAAG,EAAE,KAAK,IAAI,GAAG,GAAG,EAAE,KAAK,IAAI,GAAG,GAAG,EAAE,KAAK,IAAI,EAAE;AAAA,QACrE;AAAA,MACF;AAAA,IACF,WAAW,EAAE,SAAS,aAAa,QAAQ,aAAa,QAAQ;AAC9D,yBAAmB,KAAK,GAAG,QAAQ,QAAQ,IAAI,EAAE,EAAE,GAAG,GAAG,GAAG,OAAO;AAAA,IACrE;AAAA,EACF;AACA,aAAW,KAAK,OAAO;AACrB,QAAI,CAAC,qBAAqB,CAAC,EAAG;AAC9B,UAAM,MAAM,QAAQ,YAAY;AAChC,MAAE,MAAM,QAAQ,CAAC,GAAG,MAAM;AAExB,YAAM,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,IAAI,IAAI,GAAG,CAAC;AAChD,YAAM,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,IAAI,IAAI,GAAG,CAAC;AAChD,YAAM,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,GAAG,CAAC;AACvD,YAAM,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,GAAG,CAAC;AACvD,UAAI,YAAY;AAChB,UAAI,SAAS,IAAI,IAAI,KAAK,IAAI,KAAK,EAAE;AACrC,UAAI,QAAQ,UAAU,MAAM;AAC1B,kBAAU,KAAK,cAAc,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,GAAG,CAAC;AAAA,IACzE,CAAC;AAAA,EACH;AACA,MAAI,QAAQ;AACd;AAEA,SAAS,kBACP,KACA,OACA,OACA,KACA,SACA;AACA,MAAI,cAAc;AAClB,MAAI,YAAY,IAAI;AACpB,MAAI,WAAW,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACzC,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,MAAI,OAAO;AACX,QAAM,QAAQ,IAAI,YAAY,KAAK,EAAE;AACrC,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,IAAI,KAAK,QAAQ,IAAK,IAAI,IAAI,MAAM,MAAO,QAAQ,IAAI,CAAC,CAAC;AAC/F,MAAI,OAAO,QAAQ,IAAI;AACvB,MAAI,SAAS,OAAO,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,CAAC;AAC1D;AAEA,SAAS,mBACP,KACA,GACA,GACA,GACA,GACA,SACA;AACA,MAAI,MAAM,OAAW;AACrB,QAAM,OAAO,iBAAiB;AAC9B,QAAM,IAAI,KAAK,IAAI,EAAE,KAAK,IAAI,GAAG,IAAI,IAAI;AACzC,QAAM,IAAI,KAAK,IAAI,EAAE,KAAK,IAAI,GAAG,IAAI,IAAI;AACzC,MAAI,YAAY;AAChB,MAAI,SAAS,GAAG,GAAG,MAAM,IAAI;AAC7B,MAAI,cAAc;AAClB,MAAI,YAAY,OAAO;AACvB,MAAI,WAAW,GAAG,GAAG,MAAM,IAAI;AAC/B,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,MAAI,OAAO,QAAQ,IAAI,OAAO;AAC9B,MAAI,SAAS,OAAO,CAAC,GAAG,IAAI,OAAO,GAAG,IAAI,OAAO,CAAC;AACpD;AAGA,SAAS,UACP,KACA,MACA,KACA;AACA,QAAM,OAAO,KAAK,IAAI,IAAI,IAAI,KAAK,EAAE;AACrC,MAAI,OAAO,EAAG;AACd,MAAI,OAAO,GAAG,IAAI;AAClB,QAAM,QAAQ,IAAI,YAAY,IAAI,EAAE;AACpC,MAAI,QAAQ,IAAI,IAAI,EAAG;AACvB,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,MAAI,SAAS,MAAM,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,CAAC;AACzD;",
6
+ "names": ["canvas", "ctx"]
7
+ }
@@ -0,0 +1,117 @@
1
+ import qrcode from "qrcode-generator";
2
+ import { degrees, rgb } from "pdf-lib";
3
+ import { displayedSize, displayedToUser, normToUserRect } from "./coords.js";
4
+ import { pageGeometry } from "./vector.js";
5
+ import { FreezeError } from "./types.js";
6
+ const EDGE_MARGIN_PT = 18;
7
+ const BATES_FONT_SIZE_PT = 9;
8
+ const QR_SIZE_PT = 56;
9
+ const QR_QUIET_MODULES = 2;
10
+ const PLATE_PADDING_PT = 2;
11
+ function batesLabel(options, index) {
12
+ const digits = options.digits ?? 6;
13
+ const number = String(Math.floor((options.start ?? 1) + index)).padStart(digits, "0");
14
+ return `${options.prefix ?? ""}${number}`;
15
+ }
16
+ function validateBates(options) {
17
+ const { start = 1, digits = 6 } = options;
18
+ if (!Number.isInteger(start) || start < 0) {
19
+ throw new FreezeError("invalid-option", "Bates start must be a whole number, 0 or more");
20
+ }
21
+ if (!Number.isInteger(digits) || digits < 1 || digits > 12) {
22
+ throw new FreezeError("invalid-option", "Bates digits must be a whole number from 1 to 12");
23
+ }
24
+ }
25
+ function plateOrigin(g, corner, w, h) {
26
+ const size = displayedSize(g);
27
+ return {
28
+ x: corner.endsWith("left") ? EDGE_MARGIN_PT : size.width - EDGE_MARGIN_PT - w,
29
+ y: corner.startsWith("top") ? EDGE_MARGIN_PT : size.height - EDGE_MARGIN_PT - h
30
+ };
31
+ }
32
+ function drawPlate(page, g, box) {
33
+ const size = displayedSize(g);
34
+ const u = normToUserRect(g, {
35
+ x: box.x / size.width,
36
+ y: box.y / size.height,
37
+ w: box.w / size.width,
38
+ h: box.h / size.height
39
+ });
40
+ page.drawRectangle({ x: u.x, y: u.y, width: u.width, height: u.height, color: rgb(1, 1, 1) });
41
+ }
42
+ function drawBatesLabel(page, label, font, corner) {
43
+ const g = pageGeometry(page);
44
+ const textWidth = font.widthOfTextAtSize(label, BATES_FONT_SIZE_PT);
45
+ const w = textWidth + PLATE_PADDING_PT * 2;
46
+ const h = BATES_FONT_SIZE_PT + PLATE_PADDING_PT * 2;
47
+ const { x, y } = plateOrigin(g, corner, w, h);
48
+ drawPlate(page, g, { x, y, w, h });
49
+ const origin = displayedToUser(
50
+ g,
51
+ x + PLATE_PADDING_PT,
52
+ y + PLATE_PADDING_PT + BATES_FONT_SIZE_PT * 0.8
53
+ );
54
+ page.drawText(label, {
55
+ x: origin.x,
56
+ y: origin.y,
57
+ size: BATES_FONT_SIZE_PT,
58
+ font,
59
+ color: rgb(0, 0, 0),
60
+ rotate: degrees(g.rotation)
61
+ });
62
+ }
63
+ function buildQr(text) {
64
+ try {
65
+ const qr = qrcode(0, "M");
66
+ qr.addData(text, "Byte");
67
+ qr.make();
68
+ return { modules: qr.getModuleCount(), isDark: (r, c) => qr.isDark(r, c) };
69
+ } catch (error) {
70
+ throw new FreezeError(
71
+ "invalid-option",
72
+ `The QR link could not be encoded: ${error.message}`
73
+ );
74
+ }
75
+ }
76
+ function drawQr(page, qr, corner) {
77
+ const g = pageGeometry(page);
78
+ const total = qr.modules + QR_QUIET_MODULES * 2;
79
+ const module = QR_SIZE_PT / total;
80
+ const { x, y } = plateOrigin(g, corner, QR_SIZE_PT, QR_SIZE_PT);
81
+ drawPlate(page, g, { x, y, w: QR_SIZE_PT, h: QR_SIZE_PT });
82
+ const size = displayedSize(g);
83
+ for (let row = 0; row < qr.modules; row++) {
84
+ let col = 0;
85
+ while (col < qr.modules) {
86
+ if (!qr.isDark(row, col)) {
87
+ col++;
88
+ continue;
89
+ }
90
+ const startCol = col;
91
+ while (col < qr.modules && qr.isDark(row, col)) col++;
92
+ const u = normToUserRect(g, {
93
+ x: (x + (QR_QUIET_MODULES + startCol) * module) / size.width,
94
+ y: (y + (QR_QUIET_MODULES + row) * module) / size.height,
95
+ w: (col - startCol) * module / size.width,
96
+ h: module / size.height
97
+ });
98
+ page.drawRectangle({
99
+ x: u.x,
100
+ y: u.y,
101
+ width: u.width,
102
+ height: u.height,
103
+ color: rgb(0, 0, 0)
104
+ });
105
+ }
106
+ }
107
+ }
108
+ export {
109
+ EDGE_MARGIN_PT,
110
+ QR_SIZE_PT,
111
+ batesLabel,
112
+ buildQr,
113
+ drawBatesLabel,
114
+ drawQr,
115
+ validateBates
116
+ };
117
+ //# sourceMappingURL=stamp.js.map