@arbidocs/react 0.5.109 → 0.5.111

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 (85) hide show
  1. package/dist/PdfViewerImpl-QUSDLNNM.cjs +380 -0
  2. package/dist/PdfViewerImpl-QUSDLNNM.cjs.map +1 -0
  3. package/dist/PdfViewerImpl-TEBYF2QI.js +378 -0
  4. package/dist/PdfViewerImpl-TEBYF2QI.js.map +1 -0
  5. package/dist/{PdfViewer.d-bQH9yxFg.d.cts → PdfViewerImpl.d-B28hLEuj.d.cts} +8 -1
  6. package/dist/{PdfViewer.d-bQH9yxFg.d.ts → PdfViewerImpl.d-B28hLEuj.d.ts} +8 -1
  7. package/dist/annotations/freeze/index.d.cts +1 -1
  8. package/dist/annotations/freeze/index.d.ts +1 -1
  9. package/dist/artifacts/index.cjs +13 -13
  10. package/dist/artifacts/index.js +3 -3
  11. package/dist/calls/livekit/index.cjs +48 -48
  12. package/dist/calls/livekit/index.js +3 -3
  13. package/dist/{chunk-W2FATOTX.cjs → chunk-3JAEX57E.cjs} +4 -4
  14. package/dist/{chunk-W2FATOTX.cjs.map → chunk-3JAEX57E.cjs.map} +1 -1
  15. package/dist/{chunk-H5M7FXLB.js → chunk-4FL3X3LA.js} +3 -3
  16. package/dist/{chunk-H5M7FXLB.js.map → chunk-4FL3X3LA.js.map} +1 -1
  17. package/dist/{chunk-HD5H2PPP.cjs → chunk-5TRUFWKT.cjs} +66 -66
  18. package/dist/{chunk-HD5H2PPP.cjs.map → chunk-5TRUFWKT.cjs.map} +1 -1
  19. package/dist/chunk-6QNBSXCE.js +271 -0
  20. package/dist/chunk-6QNBSXCE.js.map +1 -0
  21. package/dist/{chunk-QF2BW6HZ.cjs → chunk-DI5KSVKY.cjs} +38 -38
  22. package/dist/{chunk-QF2BW6HZ.cjs.map → chunk-DI5KSVKY.cjs.map} +1 -1
  23. package/dist/{chunk-DQALOQPI.js → chunk-DZKRL5H3.js} +4 -4
  24. package/dist/{chunk-DQALOQPI.js.map → chunk-DZKRL5H3.js.map} +1 -1
  25. package/dist/{chunk-RVUGSM65.cjs → chunk-GKGAPU6T.cjs} +44 -44
  26. package/dist/{chunk-RVUGSM65.cjs.map → chunk-GKGAPU6T.cjs.map} +1 -1
  27. package/dist/chunk-L2IPPTVC.js +20 -0
  28. package/dist/chunk-L2IPPTVC.js.map +1 -0
  29. package/dist/{chunk-FZJMA32S.js → chunk-LSU4UPS5.js} +4 -4
  30. package/dist/{chunk-FZJMA32S.js.map → chunk-LSU4UPS5.js.map} +1 -1
  31. package/dist/{chunk-7LIMHY56.cjs → chunk-O32T7XRD.cjs} +3 -3
  32. package/dist/{chunk-7LIMHY56.cjs.map → chunk-O32T7XRD.cjs.map} +1 -1
  33. package/dist/chunk-PWGSIM3F.cjs +291 -0
  34. package/dist/chunk-PWGSIM3F.cjs.map +1 -0
  35. package/dist/{chunk-CPQ3CU4B.js → chunk-QMY2JKBI.js} +3 -3
  36. package/dist/{chunk-CPQ3CU4B.js.map → chunk-QMY2JKBI.js.map} +1 -1
  37. package/dist/chunk-QP3WQSAA.cjs +23 -0
  38. package/dist/chunk-QP3WQSAA.cjs.map +1 -0
  39. package/dist/chunk-SSXFVWCT.js +46 -0
  40. package/dist/chunk-SSXFVWCT.js.map +1 -0
  41. package/dist/chunk-T5FZICXN.cjs +50 -0
  42. package/dist/chunk-T5FZICXN.cjs.map +1 -0
  43. package/dist/{chunk-P6WLV5UY.js → chunk-XWPLOFDN.js} +3 -3
  44. package/dist/{chunk-P6WLV5UY.js.map → chunk-XWPLOFDN.js.map} +1 -1
  45. package/dist/{chunk-5HDKL6XB.cjs → chunk-YMB6XUR2.cjs} +57 -57
  46. package/dist/{chunk-5HDKL6XB.cjs.map → chunk-YMB6XUR2.cjs.map} +1 -1
  47. package/dist/{chunk-6H3O63TQ.js → chunk-ZM6N7YZH.js} +3 -3
  48. package/dist/{chunk-6H3O63TQ.js.map → chunk-ZM6N7YZH.js.map} +1 -1
  49. package/dist/document-tools/core.cjs +98 -98
  50. package/dist/document-tools/core.d.cts +2 -2
  51. package/dist/document-tools/core.d.ts +2 -2
  52. package/dist/document-tools/core.js +3 -3
  53. package/dist/document-tools/index.cjs +100 -100
  54. package/dist/document-tools/index.d.cts +1 -1
  55. package/dist/document-tools/index.d.ts +1 -1
  56. package/dist/document-tools/index.js +4 -4
  57. package/dist/index.cjs +1426 -1341
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/{index.d-BMhTH98a.d.ts → index.d-CYXcTKYt.d.ts} +1 -0
  60. package/dist/{index.d-BMhTH98a.d.cts → index.d-LArLnpI8.d.cts} +1 -0
  61. package/dist/index.d.cts +39 -8
  62. package/dist/index.d.ts +39 -8
  63. package/dist/index.js +104 -33
  64. package/dist/index.js.map +1 -1
  65. package/dist/lazy-chunk.d-B6YDLMKI.d.cts +31 -0
  66. package/dist/lazy-chunk.d-B6YDLMKI.d.ts +31 -0
  67. package/dist/{query-keys.d-ChgpJLPF.d.cts → query-keys.d-B1Am9tIF.d.cts} +1 -1
  68. package/dist/{query-keys.d-ChgpJLPF.d.ts → query-keys.d-B1Am9tIF.d.ts} +1 -1
  69. package/dist/ui/index.cjs +13 -0
  70. package/dist/ui/index.d.cts +2 -1
  71. package/dist/ui/index.d.ts +2 -1
  72. package/dist/ui/index.js +1 -0
  73. package/dist/viewers/PdfViewer.cjs +17 -0
  74. package/dist/viewers/PdfViewer.cjs.map +1 -0
  75. package/dist/viewers/PdfViewer.d.cts +9 -0
  76. package/dist/viewers/PdfViewer.d.ts +9 -0
  77. package/dist/viewers/PdfViewer.js +4 -0
  78. package/dist/viewers/PdfViewer.js.map +1 -0
  79. package/dist/viewers/index.cjs +79 -653
  80. package/dist/viewers/index.cjs.map +1 -1
  81. package/dist/viewers/index.d.cts +3 -1
  82. package/dist/viewers/index.d.ts +3 -1
  83. package/dist/viewers/index.js +6 -639
  84. package/dist/viewers/index.js.map +1 -1
  85. package/package.json +11 -3
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/viewers/page-scroll.ts","../src/viewers/usePageIntersectionObserver.ts","../src/viewers/viewer-zoom.ts","../src/viewers/pdf-viewer-constants.ts"],"names":["useEffect","useRef","distance","useCallback","useLayoutEffect"],"mappings":"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","file":"chunk-PWGSIM3F.cjs","sourcesContent":["/**\n * Scroll stability for page-stacked viewers (PDF + parsed/HTML).\n *\n * Pages are lazy: their height can change after the user is already looking at something further\n * down (a placeholder replaced by the real page, a late canvas). Browsers that implement scroll\n * anchoring (Chromium) hide that; Safari/WebKit does not, so the content visibly jumps under the\n * finger and momentum scrolling is cut short. The viewers therefore do their own anchoring, the\n * same way on every engine: native anchoring is switched off and a page that changes height\n * entirely ABOVE the viewport shifts `scrollTop` by exactly that change.\n */\n\nimport { useEffect } from 'react'\nimport type { RefObject } from 'react'\n\n/** One page of a stacked viewer (both viewers mark pages like this). */\nexport const PAGE_SELECTOR = '[role=\"article\"][data-page-number]'\n\n/**\n * How far to move `scrollTop` after a page changed height from `previousHeight` to `nextHeight`.\n * Only a page that lay completely above the visible top edge (`containerTop`) pushes the content\n * the user is reading; anything at or below it just grows or shrinks away from the viewport.\n *\n * @param pageTop viewport-relative top of the page (unchanged by its own resize)\n */\nexport function anchorDelta(\n previousHeight: number,\n nextHeight: number,\n pageTop: number,\n containerTop: number\n): number {\n const delta = nextHeight - previousHeight\n if (delta === 0) return 0\n return pageTop + previousHeight <= containerTop + 1 ? delta : 0\n}\n\nexport interface PageBox {\n n: number\n top: number\n bottom: number\n}\n\n/**\n * Which page is being read: the one showing the most pixels inside [viewTop, viewBottom] (the\n * first on a tie). `score` is those pixels relative to the smaller of the page and the viewport,\n * so a page much taller than the screen can still count as \"mostly visible\". `visibility` maps\n * every page that shows any pixel to its visible fraction (for lazy loading).\n */\nexport function measureVisiblePages(\n pages: readonly PageBox[],\n viewTop: number,\n viewBottom: number\n): { page: number | null; score: number; visibility: Map<number, number> } {\n const visibility = new Map<number, number>()\n let page: number | null = null\n let bestPx = 0\n let score = 0\n const viewHeight = viewBottom - viewTop\n for (const p of pages) {\n const height = p.bottom - p.top\n const px = Math.min(p.bottom, viewBottom) - Math.max(p.top, viewTop)\n if (px <= 0 || height <= 0) continue\n visibility.set(p.n, px / height)\n if (px > bestPx) {\n bestPx = px\n page = p.n\n score = px / Math.min(height, viewHeight)\n }\n }\n return { page, score, visibility }\n}\n\n/**\n * Keep the reading position when pages above it change height. `key` re-scans for pages when the\n * page set changes (page count, first layout).\n */\nexport function useScrollAnchor(containerRef: RefObject<HTMLElement | null>, key: unknown): void {\n useEffect(() => {\n const container = containerRef.current\n if (!container || typeof ResizeObserver === 'undefined') return\n container.style.overflowAnchor = 'none'\n\n const heights = new Map<Element, number>()\n const observer = new ResizeObserver((entries) => {\n let shift = 0\n const containerTop = container.getBoundingClientRect().top\n for (const entry of entries) {\n const el = entry.target\n const height = el.getBoundingClientRect().height\n const previous = heights.get(el)\n heights.set(el, height)\n if (previous === undefined) continue\n shift += anchorDelta(previous, height, el.getBoundingClientRect().top, containerTop)\n }\n // A zoom change re-anchors the scroll position itself (see usePinchZoom).\n if (shift !== 0 && !container.dataset.zooming) container.scrollTop += shift\n })\n container.querySelectorAll(PAGE_SELECTOR).forEach((el) => {\n heights.set(el, el.getBoundingClientRect().height)\n observer.observe(el)\n })\n return () => observer.disconnect()\n }, [containerRef, key])\n}\n","import { useEffect, useRef, RefObject } from 'react'\nimport { measureVisiblePages, type PageBox } from './page-scroll'\n\n// Page synchronization constants\nconst PAGE_UPDATE_DEBOUNCE_MS = 10 // Delay before updating page number after scroll (10ms)\nconst MIN_VISIBILITY_THRESHOLD = 0.15 // Minimum visibility (15%) to consider page \"visible\"\nconst INTERSECTION_THRESHOLDS = [0, 0.25, 0.5, 0.75, 1.0] // IntersectionObserver thresholds\n\ninterface UsePageIntersectionObserverOptions {\n /** Container element that scrolls */\n containerRef: RefObject<HTMLElement | null>\n /** Ref tracking whether initial scroll has completed */\n scrollCompleteRef: RefObject<boolean>\n /** Whether the observer should be active */\n isEnabled: boolean\n /** Function to get page elements to observe */\n getPageElements: () => Element[]\n /** Function to extract page number from element */\n getPageNumber: (element: Element) => number\n /** Callback when page number changes */\n onPageChange: (pageNumber: number) => void\n /** Optional callback with visibility data for custom logic (e.g., lazy loading) */\n onVisibilityUpdate?: (visibilityMap: Map<number, number>) => void\n /**\n * Re-subscribe when this changes (the set of page elements: page count, first layout). Callers\n * may pass fresh inline callbacks every render: they are read through refs and never cause a\n * re-subscribe (a re-subscribe re-delivers every page and, with a state-setting callback, loops).\n */\n observeKey?: unknown\n}\n\n/**\n * Custom hook to track the visible page of a page-stacked viewer.\n * Used for bidirectional page synchronization in document viewers.\n *\n * IntersectionObserver wakes it when pages enter or leave the viewport; a passive scroll listener\n * (at most one measurement per frame) keeps it current in between. The page itself is chosen from\n * live geometry (see `measureVisiblePages`).\n */\nexport function usePageIntersectionObserver({\n containerRef,\n scrollCompleteRef,\n isEnabled,\n getPageElements,\n getPageNumber,\n onPageChange,\n onVisibilityUpdate,\n observeKey,\n}: UsePageIntersectionObserverOptions) {\n const latest = useRef({ getPageElements, getPageNumber, onPageChange, onVisibilityUpdate })\n latest.current = { getPageElements, getPageNumber, onPageChange, onVisibilityUpdate }\n\n useEffect(() => {\n if (!isEnabled || !containerRef.current) return\n\n const container = containerRef.current\n let lastReportedPage: number | null = null\n let updateTimeout: ReturnType<typeof setTimeout> | null = null\n let frame = 0\n\n // Read the live geometry rather than IntersectionObserver ratios: a ratio is relative to the\n // page's own height, so a zoomed page much taller than the screen never reaches the threshold\n // (and ratios only update on a few crossings, which is too coarse for tall pages).\n const evaluate = () => {\n const root = container.getBoundingClientRect()\n const pages: PageBox[] = []\n for (const el of latest.current.getPageElements()) {\n const n = latest.current.getPageNumber(el)\n if (n <= 0) continue\n const r = el.getBoundingClientRect()\n pages.push({ n, top: r.top, bottom: r.bottom })\n }\n const { page, score, visibility } = measureVisiblePages(pages, root.top, root.bottom)\n\n // Only report when the scroll is complete and the page changed\n if (\n scrollCompleteRef.current &&\n page !== null &&\n page !== lastReportedPage &&\n score > MIN_VISIBILITY_THRESHOLD\n ) {\n lastReportedPage = page\n latest.current.onPageChange(page)\n }\n\n // Call optional visibility update callback (e.g., for lazy loading)\n latest.current.onVisibilityUpdate?.(visibility)\n }\n\n const observer = new IntersectionObserver(\n () => {\n // Debounce updates\n if (updateTimeout) clearTimeout(updateTimeout)\n updateTimeout = setTimeout(evaluate, PAGE_UPDATE_DEBOUNCE_MS)\n },\n { root: container, threshold: INTERSECTION_THRESHOLDS }\n )\n // At most one measurement per frame while scrolling; nothing is stored in React state here.\n const onScroll = () => {\n if (!frame) {\n frame = requestAnimationFrame(() => {\n frame = 0\n evaluate()\n })\n }\n }\n container.addEventListener('scroll', onScroll, { passive: true })\n\n // Observe all page elements\n latest.current.getPageElements().forEach((element) => observer.observe(element))\n\n return () => {\n observer.disconnect()\n container.removeEventListener('scroll', onScroll)\n if (updateTimeout) clearTimeout(updateTimeout)\n if (frame) cancelAnimationFrame(frame)\n }\n }, [containerRef, scrollCompleteRef, isEnabled, observeKey])\n}\n","/**\n * Zoom for page-stacked viewers (PDF + parsed/HTML).\n *\n * Browser pinch-zoom only magnifies the bitmap the page already painted: a PDF canvas rendered at\n * fit-width stays blurry however far you pinch. The viewers therefore own the zoom: `zoom` is a\n * multiplier of the fit-width size (1 = fit width, 2 = twice as wide). The PDF viewer re-renders\n * its canvases at the new scale; the parsed viewer reflows its text. This module holds the pure\n * math and the touch gesture hook (pinch, double-tap) both use.\n */\n\nimport { useCallback, useEffect, useLayoutEffect, useRef } from 'react'\nimport type { RefObject } from 'react'\n\nexport const MIN_ZOOM = 0.5\nexport const MAX_ZOOM = 4\nconst DOUBLE_TAP_ZOOM = 2\n/** Canvas pixel budget per page: iOS Safari fails above ~16.7M pixels in total, so stay well under. */\nexport const MAX_CANVAS_PIXELS = 8_000_000\n/** Device pixel ratio is capped: beyond 2x the extra sharpness is invisible and costs 2-3x memory. */\nconst MAX_RENDER_DPR = 2\n\nexport function clampZoom(zoom: number): number {\n if (!Number.isFinite(zoom)) return 1\n return Math.round(Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, zoom)) * 100) / 100\n}\n\n/** The zoom levels the single zoom button steps through before it returns to fit width. */\nconst ZOOM_PRESETS = [1.5, 2, 3]\n\n/** The zoom button: the next preset above the current zoom, or back to fit width after the last. */\nexport function cycleZoom(zoom: number): number {\n return ZOOM_PRESETS.find((preset) => preset > zoom + 0.05) ?? 1\n}\n\n/** Double-tap toggles between fit width and a comfortable reading zoom. */\nexport function doubleTapZoom(zoom: number): number {\n return zoom > 1.05 ? 1 : DOUBLE_TAP_ZOOM\n}\n\nexport function zoomLabel(zoom: number): string {\n return `${Math.round(zoom * 100)}%`\n}\n\n/** The zoom a pinch has reached: the start zoom scaled by how far the fingers moved apart. */\nexport function pinchZoom(startZoom: number, startDistance: number, distance: number): number {\n if (startDistance <= 0) return startZoom\n return clampZoom((startZoom * distance) / startDistance)\n}\n\n/**\n * New scroll offset that keeps the content point under `focal` (a viewport coordinate) still while\n * the zoom changes from `oldZoom` to `newZoom`.\n */\nexport function anchoredScroll(\n scroll: number,\n focal: number,\n oldZoom: number,\n newZoom: number\n): number {\n if (oldZoom <= 0) return scroll\n return ((scroll + focal) * newZoom) / oldZoom - focal\n}\n\n/**\n * Device pixel ratio to rasterise a page of `cssWidth` x `cssHeight` at: the device's own, capped,\n * and lowered further when the page would otherwise exceed the canvas pixel budget.\n */\nexport function renderDpr(\n cssWidth: number,\n cssHeight: number,\n devicePixelRatio: number,\n maxPixels: number = MAX_CANVAS_PIXELS\n): number {\n const wanted = Math.min(Math.max(devicePixelRatio || 1, 1), MAX_RENDER_DPR)\n const area = cssWidth * cssHeight\n if (area <= 0) return wanted\n const fits = Math.sqrt(maxPixels / area)\n return Math.max(1, Math.min(wanted, fits))\n}\n\n/**\n * Width a fit-width page's content gets in a scroller whose content box is `contentWidth` wide:\n * that box less the page's own border, floored so sub-pixel layout never rounds the page up past\n * the box into a sideways overflow.\n */\nexport function fitPageWidth(contentWidth: number, pageBorder: number): number {\n if (!Number.isFinite(contentWidth)) return 0\n return Math.max(0, Math.floor(contentWidth) - pageBorder)\n}\n\n/**\n * An element's content-box width: `clientWidth` (which, unlike `offsetWidth`, leaves out the\n * vertical scrollbar and the borders) less the horizontal padding.\n */\nexport function contentBoxWidth(el: HTMLElement): number {\n const style = getComputedStyle(el)\n const padding = (parseFloat(style.paddingLeft) || 0) + (parseFloat(style.paddingRight) || 0)\n return Math.max(0, el.clientWidth - padding)\n}\n\nconst distance = (a: Touch, b: Touch) => Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY)\nconst INTERACTIVE = 'button, a, input, textarea, select, [role=\"button\"]'\nconst DOUBLE_TAP_MS = 300\nconst DOUBLE_TAP_SLOP_PX = 30\n\ninterface PinchZoomOptions {\n containerRef: RefObject<HTMLElement | null>\n zoom: number\n onZoomChange?: (zoom: number) => void\n}\n\n/**\n * Pinch and double-tap zoom on a scroller, plus focal-point preservation for EVERY zoom change\n * (gesture, buttons, props): after the new zoom has laid out, the scroll offset is moved so the\n * content under the pinch centre (or the viewport centre) stays where it was.\n *\n * The scroller must carry `touch-action: pan-x pan-y` so the browser leaves two-finger gestures\n * to this hook instead of zooming the whole app.\n */\nexport function usePinchZoom({ containerRef, zoom, onZoomChange }: PinchZoomOptions): void {\n const zoomRef = useRef(zoom)\n const onChangeRef = useRef(onZoomChange)\n onChangeRef.current = onZoomChange\n const focalRef = useRef<{ x: number; y: number } | null>(null)\n const appliedZoomRef = useRef(zoom)\n\n const request = useCallback((next: number, focal: { x: number; y: number } | null) => {\n const clamped = clampZoom(next)\n if (clamped === zoomRef.current) return\n focalRef.current = focal\n zoomRef.current = clamped\n onChangeRef.current?.(clamped)\n }, [])\n\n // Zoom changed (from here or from outside): keep the focal point still once it has laid out.\n useLayoutEffect(() => {\n zoomRef.current = zoom\n const container = containerRef.current\n const previous = appliedZoomRef.current\n appliedZoomRef.current = zoom\n if (!container || previous === zoom) return\n const rect = container.getBoundingClientRect()\n const focal = focalRef.current ?? { x: rect.width / 2, y: rect.height / 2 }\n focalRef.current = null\n // The page-anchoring observer must not also react to this resize.\n container.dataset.zooming = 'true'\n container.scrollLeft = anchoredScroll(container.scrollLeft, focal.x, previous, zoom)\n container.scrollTop = anchoredScroll(container.scrollTop, focal.y, previous, zoom)\n requestAnimationFrame(() =>\n requestAnimationFrame(() => {\n delete container.dataset.zooming\n })\n )\n }, [zoom, containerRef])\n\n useEffect(() => {\n const el = containerRef.current\n if (!el) return\n let pinch: { startDistance: number; startZoom: number } | null = null\n let lastTap: { time: number; x: number; y: number } | null = null\n let frame = 0\n let pending: { zoom: number; focal: { x: number; y: number } } | null = null\n\n const focalOf = (a: Touch, b: Touch) => {\n const rect = el.getBoundingClientRect()\n return {\n x: (a.clientX + b.clientX) / 2 - rect.left,\n y: (a.clientY + b.clientY) / 2 - rect.top,\n }\n }\n const flush = () => {\n frame = 0\n if (pending) request(pending.zoom, pending.focal)\n pending = null\n }\n\n const onStart = (e: TouchEvent) => {\n if (e.touches.length === 2) {\n pinch = { startDistance: distance(e.touches[0], e.touches[1]), startZoom: zoomRef.current }\n lastTap = null\n }\n }\n const onMove = (e: TouchEvent) => {\n if (!pinch || e.touches.length !== 2) return\n e.preventDefault()\n pending = {\n zoom: pinchZoom(pinch.startZoom, pinch.startDistance, distance(e.touches[0], e.touches[1])),\n focal: focalOf(e.touches[0], e.touches[1]),\n }\n if (!frame) frame = requestAnimationFrame(flush)\n }\n const onEnd = (e: TouchEvent) => {\n if (pinch && e.touches.length < 2) {\n pinch = null\n return\n }\n if (e.touches.length !== 0 || e.changedTouches.length !== 1) return\n const t = e.changedTouches[0]\n if ((e.target as Element | null)?.closest?.(INTERACTIVE)) return\n const now = e.timeStamp\n if (\n lastTap &&\n now - lastTap.time < DOUBLE_TAP_MS &&\n Math.hypot(t.clientX - lastTap.x, t.clientY - lastTap.y) < DOUBLE_TAP_SLOP_PX\n ) {\n e.preventDefault()\n const rect = el.getBoundingClientRect()\n request(doubleTapZoom(zoomRef.current), {\n x: t.clientX - rect.left,\n y: t.clientY - rect.top,\n })\n lastTap = null\n } else {\n lastTap = { time: now, x: t.clientX, y: t.clientY }\n }\n }\n\n el.addEventListener('touchstart', onStart, { passive: true })\n el.addEventListener('touchmove', onMove, { passive: false })\n el.addEventListener('touchend', onEnd, { passive: false })\n el.addEventListener('touchcancel', onEnd, { passive: false })\n return () => {\n el.removeEventListener('touchstart', onStart)\n el.removeEventListener('touchmove', onMove)\n el.removeEventListener('touchend', onEnd)\n el.removeEventListener('touchcancel', onEnd)\n if (frame) cancelAnimationFrame(frame)\n }\n }, [containerRef, request])\n}\n","/** Pages to render before the visible area (canvas pre-load buffer) */\nexport const LAZY_LOAD_BUFFER_BEFORE = 2\n\n/** Pages to render after the visible area (canvas pre-load buffer) */\nexport const LAZY_LOAD_BUFFER_AFTER = 5\n\n/**\n * Smaller render window used on the very first paint so time-to-first-visible-page is\n * fast. Expanded to LAZY_LOAD_BUFFER_BEFORE / LAZY_LOAD_BUFFER_AFTER once the browser\n * is idle (via requestIdleCallback / setTimeout fallback).\n */\nexport const INITIAL_LAZY_LOAD_BUFFER = { before: 0, after: 1 }\n"]}
@@ -1,4 +1,4 @@
1
- import { useDeploymentDomain } from './chunk-6H3O63TQ.js';
1
+ import { useDeploymentDomain } from './chunk-ZM6N7YZH.js';
2
2
  import { parseVersionRef } from './chunk-UW2SGTI5.js';
3
3
  import { createContext, useRef, useCallback, useMemo, useContext } from 'react';
4
4
  import { jsx } from 'react/jsx-runtime';
@@ -242,5 +242,5 @@ async function fetchMarkupPdf(client, documentId, version, workspaceExtId) {
242
242
  }
243
243
 
244
244
  export { DocumentFetchError, DocumentToolsProvider, MarkupDownloadError, SIGNED_LOCKED_REASON, certificateLink, clientUpload, contentDispositionFileName, currentHasMarkup, defaultCertificateUrl, downloadBlob, fetchDocumentFile, fetchDocumentPdf, fetchMarkupPdf, isSignedVersion, uploadQueryString, useDocumentTools, useOptionalDocumentTools };
245
- //# sourceMappingURL=chunk-CPQ3CU4B.js.map
246
- //# sourceMappingURL=chunk-CPQ3CU4B.js.map
245
+ //# sourceMappingURL=chunk-QMY2JKBI.js.map
246
+ //# sourceMappingURL=chunk-QMY2JKBI.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/document-tools/environment.tsx","../src/document-tools/document-pdf.ts","../src/document-tools/markup-download.ts"],"names":[],"mappings":";;;;;AAmEO,SAAS,kBAAkB,KAAA,EAAoC;AACpE,EAAA,MAAM,MAAA,GAAS,IAAI,eAAA,EAAgB;AACnC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAChD,IAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW;AAC3C,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,OAAA,CAAQ,KAAK,IAAI,KAAA,GAAQ,CAAC,KAAK,CAAA,EAAG,MAAA,CAAO,MAAA,CAAO,GAAA,EAAK,MAAA,CAAO,IAAI,CAAC,CAAA;AAAA,EAC5F;AACA,EAAA,OAAO,OAAO,QAAA,EAAS;AACzB;AAqDO,SAAS,YAAA,CAAa,MAAY,QAAA,EAAwB;AAC/D,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AACpC,EAAA,MAAM,CAAA,GAAI,QAAA,CAAS,aAAA,CAAc,GAAG,CAAA;AACpC,EAAA,CAAA,CAAE,IAAA,GAAO,GAAA;AACT,EAAA,CAAA,CAAE,QAAA,GAAW,QAAA;AACb,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,CAAC,CAAA;AAC3B,EAAA,CAAA,CAAE,KAAA,EAAM;AACR,EAAA,CAAA,CAAE,MAAA,EAAO;AACT,EAAA,UAAA,CAAW,MAAM,GAAA,CAAI,eAAA,CAAgB,GAAG,GAAG,GAAM,CAAA;AACnD;AAGO,SAAS,aAAa,MAAA,EAA6B;AACxD,EAAA,OAAO,OAAO,EAAE,IAAA,EAAM,KAAA,EAAM,KAA6B;AACvD,IAAA,MAAM,QAAA,GAAW,IAAI,QAAA,EAAS;AAC9B,IAAA,QAAA,CAAS,MAAA,CAAO,SAAS,IAAI,CAAA;AAC7B,IAAA,MAAM,EAAE,IAAA,EAAM,QAAA,KAAa,MAAM,MAAA,CAAO,KAAK,qBAAA,EAAuB;AAAA,MAClE,MAAA,EAAQ,EAAE,KAAA,EAAM;AAAA;AAAA,MAEhB,IAAA,EAAM,QAAA;AAAA,MACN,gBAAgB,MAAM;AAAA,KACvB,CAAA;AACD,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAChF,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AACF;AAEO,SAAS,sBAAsB,SAAA,EAA2B;AAC/D,EAAA,MAAM,MAAA,GAAS,OAAO,QAAA,KAAa,WAAA,GAAc,KAAK,QAAA,CAAS,MAAA;AAC/D,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,QAAA,EAAW,kBAAA,CAAmB,SAAS,CAAC,CAAA,CAAA;AAC1D;AAMO,SAAS,eAAA,CACd,WACA,cAAA,EACQ;AACR,EAAA,IAAI,cAAA,EAAgB,OAAO,cAAA,CAAe,SAAA,CAAU,SAAS,CAAA;AAC7D,EAAA,OAAO,SAAA,CAAU,eAAA,IAAmB,qBAAA,CAAsB,SAAA,CAAU,SAAS,CAAA;AAC/E;AAEA,IAAM,oBAAA,GAAuB,cAAuD,IAAI,CAAA;AAMjF,SAAS,qBAAA,CAAsB,EAAE,QAAA,EAAU,GAAG,KAAI,EAA+B;AACtF,EAAA,MAAM,uBAAuB,mBAAA,EAAoB;AACjD,EAAA,MAAM,MAAA,GAAS,MAAA,iBAAO,IAAI,GAAA,EAAkC,CAAA;AAC5D,EAAA,MAAM,cAAA,GAAiB,MAAA,iBAAO,IAAI,GAAA,EAA4B,CAAA;AAC9D,EAAA,MAAM,uBAAA,GAA0B,WAAA,CAAY,CAAC,EAAA,EAAY,KAAA,KAA+B;AACtF,IAAA,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,EAAA,EAAI,KAAK,CAAA;AAC5B,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,EAAE,MAAM,KAAA,EAAO;AACtC,MAAA,MAAA,CAAO,OAAA,CAAQ,OAAO,EAAE,CAAA;AACxB,MAAA,MAAM,UAAU,KAAA,EAAM;AACtB,MAAA,cAAA,CAAe,OAAA,CAAQ,GAAA,CAAI,EAAA,EAAI,OAAO,CAAA;AACtC,MAAA,KAAK,OAAA,CAAQ,IAAA;AAAA,QACX,MAAM;AACJ,UAAA,IAAI,cAAA,CAAe,QAAQ,GAAA,CAAI,EAAE,MAAM,OAAA,EAAS,cAAA,CAAe,OAAA,CAAQ,MAAA,CAAO,EAAE,CAAA;AAAA,QAClF,CAAA;AAAA,QACA,MAAM;AAAA,QAAC;AAAA,OACT;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AACL,EAAA,MAAM,gBAAA,GAAmB,WAAA,CAAY,OAAO,EAAA,KAAe;AACzD,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA;AACnC,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,MAAM,KAAA,EAAM;AACZ,MAAA,cAAA,CAAe,OAAA,CAAQ,OAAO,EAAE,CAAA;AAAA,IAClC,CAAA,MAAO,MAAM,cAAA,CAAe,OAAA,CAAQ,IAAI,EAAE,CAAA;AAAA,EAC5C,CAAA,EAAG,EAAE,CAAA;AACL,EAAA,MAAM;AAAA,IACJ,MAAA;AAAA,IACA,gBAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAA;AAAA,IACA,YAAA;AAAA,IACA,kBAAA;AAAA,IACA,cAAA;AAAA,IACA,QAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF,GAAI,GAAA;AACJ,EAAA,MAAM,KAAA,GAAQ,OAAA;AAAA,IACZ,OAAO;AAAA,MACL,MAAA;AAAA,MACA,gBAAA;AAAA,MACA,uBAAA;AAAA,MACA,kBAAkB,gBAAA,IAAoB,oBAAA;AAAA,MACtC,IAAA;AAAA,MACA,YAAA;AAAA,MACA,kBAAA;AAAA,MACA,aAAA;AAAA,MACA,MAAA,EAAQ,WAAW,MAAM;AAAA,MAAC,CAAA,CAAA;AAAA,MAC1B,UAAU,QAAA,IAAY,YAAA;AAAA,MACtB,cAAA,EAAgB,cAAA,IAAkB,YAAA,CAAa,MAAM,CAAA;AAAA,MACrD;AAAA,KACF,CAAA;AAAA,IACA;AAAA,MACE,MAAA;AAAA,MACA,gBAAA;AAAA,MACA,uBAAA;AAAA,MACA,gBAAA;AAAA,MACA,oBAAA;AAAA,MACA,IAAA;AAAA,MACA,MAAA;AAAA,MACA,YAAA;AAAA,MACA,kBAAA;AAAA,MACA,cAAA;AAAA,MACA,QAAA;AAAA,MACA,aAAA;AAAA,MACA;AAAA;AACF,GACF;AACA,EAAA,uBAAO,GAAA,CAAC,oBAAA,CAAqB,QAAA,EAArB,EAA8B,OAAe,QAAA,EAAS,CAAA;AAChE;AAGO,SAAS,wBAAA,GAAoE;AAClF,EAAA,OAAO,WAAW,oBAAoB,CAAA;AACxC;AAGO,SAAS,gBAAA,GAAqD;AACnE,EAAA,MAAM,GAAA,GAAM,WAAW,oBAAoB,CAAA;AAC3C,EAAA,IAAI,CAAC,GAAA,EAAK,MAAM,IAAI,MAAM,kEAAkE,CAAA;AAC5F,EAAA,OAAO,GAAA;AACT;;;AClPO,IAAM,kBAAA,GAAN,cAAiC,KAAA,CAAM;AAAA,EACnC,MAAA;AAAA,EACT,WAAA,CAAY,SAAiB,MAAA,EAAgB;AAC3C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AACF;AAEA,eAAe,mBACb,MAAA,EACA,QAAA,EACA,WAAA,EACA,OAAA,EACA,SACA,IAAA,EAC6C;AAC7C,EAAA,MAAM,GAAA,GAAM,gBAAgB,WAAW,CAAA;AACvC,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,IAAW,GAAA,CAAI,OAAA;AACvC,EAAA,MAAM,EAAE,IAAA,EAAM,QAAA,KAAa,MAAM,MAAA,CAAO,IAAI,QAAA,EAAU;AAAA,IACpD,MAAA,EAAQ;AAAA,MACN,IAAA,EAAM,EAAE,eAAA,EAAiB,GAAA,CAAI,KAAA,EAAM;AAAA,MACnC,KAAA,EAAO;AAAA,QACL,GAAI,OAAA,GAAU,EAAE,OAAA,KAAY,EAAC;AAAA,QAC7B,GAAI,QAAQ,cAAA,GAAiB,EAAE,kBAAkB,OAAA,CAAQ,cAAA,KAAmB;AAAC;AAC/E,KACF;AAAA,IACA,OAAA;AAAA,IACA,OAAA,EAAS,MAAA;AAAA,IACT,QAAQ,OAAA,CAAQ;AAAA,GACjB,CAAA;AACD,EAAA,IAAI,CAAC,QAAA,CAAS,EAAA,IAAM,EAAE,gBAAgB,IAAA,CAAA,EAAO;AAC3C,IAAA,MAAM,IAAI,kBAAA;AAAA,MACR,CAAA,EAAG,IAAI,CAAA,sBAAA,EAAyB,QAAA,CAAS,MAAM,CAAA,CAAA,CAAA;AAAA,MAC/C,QAAA,CAAS;AAAA,KACX;AAAA,EACF;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,QAAA,EAAS;AAChC;AAMO,SAAS,2BAA2B,MAAA,EAAuD;AAChG,EAAA,IAAI,CAAC,QAAQ,OAAO,MAAA;AACpB,EAAA,MAAM,QAAA,GAAW,6CAAA,CAA8C,IAAA,CAAK,MAAM,CAAA;AAC1E,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,IAAI;AACF,MAAA,OAAO,kBAAA,CAAmB,QAAA,CAAS,CAAC,CAAA,CAAE,IAAA,GAAO,OAAA,CAAQ,QAAA,EAAU,EAAE,CAAC,CAAA,IAAK,KAAA,CAAA;AAAA,IACzE,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACA,EAAA,MAAM,KAAA,GAAQ,6CAAA,CAA8C,IAAA,CAAK,MAAM,CAAA;AACvE,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,CAAC,CAAA,KAAM,SAAY,KAAA,CAAM,CAAC,CAAA,CAAE,OAAA,CAAQ,UAAU,IAAI,CAAA,GAAI,KAAA,CAAM,CAAC,EAAE,IAAA,EAAK;AACvF,EAAA,OAAO,IAAA,IAAQ,MAAA;AACjB;AAMA,eAAsB,gBAAA,CACpB,MAAA,EACA,WAAA,EACA,OAAA,GAAgC,EAAC,EAClB;AACf,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,kBAAA;AAAA,IACrB,MAAA;AAAA,IACA,qCAAA;AAAA,IACA,WAAA;AAAA,IACA,OAAA;AAAA,IACA,EAAE,QAAQ,iBAAA,EAAkB;AAAA,IAC5B;AAAA,GACF;AACA,EAAA,OAAO,IAAA;AACT;AAMA,eAAsB,iBAAA,CACpB,MAAA,EACA,WAAA,EACA,OAAA,GAAgC,EAAC,EACX;AACtB,EAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAS,GAAI,MAAM,kBAAA;AAAA,IAC/B,MAAA;AAAA,IACA,yCAAA;AAAA,IACA,WAAA;AAAA,IACA,OAAA;AAAA,IACA,EAAC;AAAA,IACD;AAAA,GACF;AACA,EAAA,MAAM,OAAO,0BAAA,CAA2B,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,qBAAqB,CAAC,CAAA;AACnF,EAAA,OAAO,IAAA,GAAO,IAAI,IAAA,CAAK,CAAC,IAAI,CAAA,EAAG,IAAA,EAAM,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,CAAA,GAAI,IAAA;AAC9D;;;ACjGO,IAAM,oBAAA,GACX;AAGK,SAAS,eAAA,CAAgB,KAAuB,OAAA,EAA2B;AAChF,EAAA,MAAM,CAAA,GAAI,OAAA,IAAW,GAAA,CAAI,eAAA,IAAmB,CAAA;AAC5C,EAAA,OAAA,CAAQ,GAAA,CAAI,QAAA,IAAY,EAAC,EAAG,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,CAAA,KAAM,CAAA,IAAK,CAAA,CAAE,MAAA,KAAW,QAAQ,CAAA;AAC5E;AAEO,IAAM,mBAAA,GAAN,cAAkC,KAAA,CAAM;AAAA,EAC7C,WAAA,CACE,SACS,MAAA,EACT;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAFJ,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAGT,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AAAA,EACd;AAAA,EAJW,MAAA;AAKb;AAGO,SAAS,iBAAiB,GAAA,EAAgC;AAC/D,EAAA,MAAM,CAAA,GAAI,IAAI,eAAA,IAAmB,CAAA;AACjC,EAAA,OAAA,CAAQ,GAAA,CAAI,QAAA,IAAY,EAAC,EAAG,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,CAAA,KAAM,CAAA,IAAA,CAAM,CAAA,CAAE,YAAA,IAAgB,KAAK,CAAC,CAAA;AAChF;AAGA,eAAsB,cAAA,CACpB,MAAA,EACA,UAAA,EACA,OAAA,EACA,cAAA,EAC2C;AAC3C,EAAA,MAAM,EAAE,IAAA,EAAM,QAAA,KAAa,MAAM,MAAA,CAAO,IAAI,2CAAA,EAA6C;AAAA,IACvF,MAAA,EAAQ;AAAA,MACN,IAAA,EAAM,EAAE,eAAA,EAAiB,UAAA,EAAW;AAAA,MACpC,KAAA,EAAO;AAAA,QACL,GAAI,OAAA,GAAU,EAAE,OAAA,KAAY,EAAC;AAAA,QAC7B,GAAI,cAAA,GAAiB,EAAE,gBAAA,EAAkB,cAAA,KAAmB;AAAC;AAC/D,KACF;AAAA,IACA,OAAA,EAAS;AAAA,GACV,CAAA;AACD,EAAA,IAAI,CAAC,QAAA,CAAS,EAAA,IAAM,CAAC,IAAA,EAAM;AACzB,IAAA,MAAM,IAAI,mBAAA;AAAA,MACR,QAAA,CAAS,WAAW,GAAA,GAChB,iCAAA;AAAA;AAAA,QAEA,QAAA,CAAS,MAAA,KAAW,GAAA,GAClB,oBAAA,GACA;AAAA,OAAA;AAAA,MACN,QAAA,CAAS;AAAA,KACX;AAAA,EACF;AACA,EAAA,MAAM,WAAA,GAAc,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,qBAAqB,CAAA,IAAK,EAAA;AACnE,EAAA,MAAM,IAAA,GAAO,4BAAA,CAA6B,IAAA,CAAK,WAAW,IAAI,CAAC,CAAA;AAC/D,EAAA,MAAM,KAAA,GAAQ,qBAAA,CAAsB,IAAA,CAAK,WAAW,IAAI,CAAC,CAAA;AACzD,EAAA,MAAM,QAAA,GAAW,IAAA,GAAO,kBAAA,CAAmB,IAAI,IAAK,KAAA,IAAS,YAAA;AAC7D,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAc,QAAA,EAAS;AACxC","file":"chunk-CPQ3CU4B.js","sourcesContent":["/**\n * The host app's side of the document tools (markup, freeze, e-signing, versions): the one place\n * the tools reach the app. They never import a store, a router, a toast library or app API code;\n * the host passes what it has to `<DocumentToolsProvider>` and every optional field has a default.\n *\n * `client` is an openapi-fetch client for the ARBI API (`ArbiClient['fetch']` from\n * `@arbidocs/client`, or `arbi.getClient().fetch` from an `@arbidocs/sdk` `Arbi`), signed in with the\n * user's session; it carries the auth.\n */\n\nimport { createContext, useCallback, useContext, useMemo, useRef, type ReactNode } from 'react'\nimport type { ArbiClient, operations } from '@arbidocs/client'\nimport { useDeploymentDomain } from '../useArbi'\n\nexport type DocumentToolsClient = ArbiClient['fetch']\n\nexport type DocumentToolsNoticeKind = 'success' | 'error' | 'info' | 'warning'\n\nexport interface DocumentToolsNoticeOptions {\n /** A second line under the message. */\n description?: string\n /** One action button on the notice (\"Email it\"). */\n action?: { label: string; onClick: () => void }\n}\n\nexport type DocumentToolsNotify = (\n message: string,\n kind: DocumentToolsNoticeKind,\n options?: DocumentToolsNoticeOptions\n) => void\n\nexport interface DocumentToolsUser {\n /** The name marks are authored as and the signer's name is prefilled with. */\n name: string\n /** The sign-in email: signing re-derives the user's key from it and the password. */\n email?: string | null\n /** The user's id (usr-*): which fields of a signature request are theirs. */\n externalId?: string | null\n}\n\n/** What changed about a document, so the host can refresh its own lists and caches. */\nexport type DocumentChange =\n /** A version's markup got its first mark or lost its last one. */\n | 'markup'\n /** A signature was added: the document has a new current version. */\n | 'signed'\n /** A new document was made from it (a frozen copy). The ids are the NEW documents. */\n | 'copy'\n /** A new version was saved (the Word editor's Save version): the document's current version. */\n | 'version'\n\n/**\n * The `/v1/document/upload` query, typed from the API schema: `derived_from` is a list (a\n * production set is derived from every document in it), `shared` a boolean.\n */\nexport type DocumentUploadQuery = NonNullable<operations['upload_documents']['parameters']['query']>\n\nexport interface DocumentUploadRequest {\n file: File\n /** `/v1/document/upload` query: `derived_from`, `derived_role`, `shared`, `folder`. */\n query: DocumentUploadQuery\n}\n\n/**\n * The upload query as a URL query string, for a host that posts the upload itself (an XHR with\n * progress): a list repeats its key (`derived_from=a&derived_from=b`), empty values are left out.\n */\nexport function uploadQueryString(query: DocumentUploadQuery): string {\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(query)) {\n if (value === null || value === undefined) continue\n for (const item of Array.isArray(value) ? value : [value]) params.append(key, String(item))\n }\n return params.toString()\n}\n\nexport interface DocumentToolsEnvironment {\n client: DocumentToolsClient\n /**\n * The deployment domain the user's keys are derived for. Needed for signing. Default: the one\n * the host's `Arbi` computes (`arbi.getDeploymentDomain()`), if any.\n */\n deploymentDomain?: string\n /** The signed-in user; marks are authored as \"You\" without one, and signing is unavailable. */\n user?: DocumentToolsUser | null\n /** Surface a transient message. Default: none (errors still show inline where they can). */\n notify?: DocumentToolsNotify\n /** Open a document or a version reference (`doc-…@v2`): the copy just made, the signed copy. */\n openDocument?: (documentRef: string) => void\n /**\n * Documents changed on the server (see {@link DocumentChange}); refresh the host's lists. The\n * tools wait for it before opening the document, so a copy is listed when it opens.\n */\n onDocumentsChanged?: (documentIds: string[], change: DocumentChange) => void | Promise<void>\n /** Upload a derived copy. Default: `POST /v1/document/upload` through `client`. */\n uploadDocument?: (\n request: DocumentUploadRequest\n ) => Promise<{ doc_ext_ids?: string[] } | undefined>\n /** Save a file to the user's computer. Default: a temporary download link. */\n saveFile?: (blob: Blob, fileName: string) => void\n /** Email a document (offered once it is signed). Omitted: no \"Email it\". */\n emailDocument?: (documentRef: string) => void\n /**\n * The public page that checks a signature (the certificate) in this app. When given, \"View\n * certificate\" opens it in preference to the backend's `certificate_url` (which is on the\n * deployment domain, like the link embedded in the signed PDF). Without it: the backend's\n * `certificate_url`, else `/verify/{reference}` on this origin.\n */\n certificateUrl?: (reference: string) => string\n}\n\n/** The environment with every default filled in. */\nexport interface ResolvedDocumentToolsEnvironment extends DocumentToolsEnvironment {\n prepareFileShare: (documentId: string) => Promise<void>\n registerBeforeFileShare: (documentId: string, flush: () => Promise<void>) => () => void\n notify: DocumentToolsNotify\n saveFile: (blob: Blob, fileName: string) => void\n uploadDocument: (\n request: DocumentUploadRequest\n ) => Promise<{ doc_ext_ids?: string[] } | undefined>\n}\n\n/**\n * Save a blob through a temporary `<a download>`. The object URL is revoked a minute later, not at\n * once: revoking straight after `click()` can cancel the download (Safari, and large files\n * elsewhere) before the browser has read the blob.\n */\nexport function downloadBlob(blob: Blob, fileName: string): void {\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = fileName\n document.body.appendChild(a)\n a.click()\n a.remove()\n setTimeout(() => URL.revokeObjectURL(url), 60_000)\n}\n\n/** The default upload: multipart `files` to `/v1/document/upload` through the API client. */\nexport function clientUpload(client: DocumentToolsClient) {\n return async ({ file, query }: DocumentUploadRequest) => {\n const formData = new FormData()\n formData.append('files', file)\n const { data, response } = await client.POST('/v1/document/upload', {\n params: { query },\n // The schema types the multipart body as `{ files: string[] }`; the FormData is sent as is.\n body: formData as unknown as { files: string[] },\n bodySerializer: () => formData,\n })\n if (!response.ok) throw new Error(`Upload failed with status ${response.status}`)\n return data\n }\n}\n\nexport function defaultCertificateUrl(reference: string): string {\n const origin = typeof location === 'undefined' ? '' : location.origin\n return `${origin}/verify/${encodeURIComponent(reference)}`\n}\n\n/**\n * Where \"View certificate\" goes for a signature: the host's `certificateUrl(reference)` when it\n * gives one, else the `certificate_url` the backend returned, else `/verify/{reference}` here.\n */\nexport function certificateLink(\n signature: { reference: string; certificate_url?: string | null },\n certificateUrl?: (reference: string) => string\n): string {\n if (certificateUrl) return certificateUrl(signature.reference)\n return signature.certificate_url || defaultCertificateUrl(signature.reference)\n}\n\nconst DocumentToolsContext = createContext<ResolvedDocumentToolsEnvironment | null>(null)\n\nexport interface DocumentToolsProviderProps extends DocumentToolsEnvironment {\n children: ReactNode\n}\n\nexport function DocumentToolsProvider({ children, ...env }: DocumentToolsProviderProps) {\n const arbiDeploymentDomain = useDeploymentDomain()\n const guards = useRef(new Map<string, () => Promise<void>>())\n const pendingFlushes = useRef(new Map<string, Promise<void>>())\n const registerBeforeFileShare = useCallback((id: string, flush: () => Promise<void>) => {\n guards.current.set(id, flush)\n return () => {\n if (guards.current.get(id) !== flush) return\n guards.current.delete(id)\n const pending = flush()\n pendingFlushes.current.set(id, pending)\n void pending.then(\n () => {\n if (pendingFlushes.current.get(id) === pending) pendingFlushes.current.delete(id)\n },\n () => {}\n )\n }\n }, [])\n const prepareFileShare = useCallback(async (id: string) => {\n const guard = guards.current.get(id)\n if (guard) {\n await guard()\n pendingFlushes.current.delete(id)\n } else await pendingFlushes.current.get(id)\n }, [])\n const {\n client,\n deploymentDomain,\n user,\n notify,\n openDocument,\n onDocumentsChanged,\n uploadDocument,\n saveFile,\n emailDocument,\n certificateUrl,\n } = env\n const value = useMemo<ResolvedDocumentToolsEnvironment>(\n () => ({\n client,\n prepareFileShare,\n registerBeforeFileShare,\n deploymentDomain: deploymentDomain ?? arbiDeploymentDomain,\n user,\n openDocument,\n onDocumentsChanged,\n emailDocument,\n notify: notify ?? (() => {}),\n saveFile: saveFile ?? downloadBlob,\n uploadDocument: uploadDocument ?? clientUpload(client),\n certificateUrl,\n }),\n [\n client,\n prepareFileShare,\n registerBeforeFileShare,\n deploymentDomain,\n arbiDeploymentDomain,\n user,\n notify,\n openDocument,\n onDocumentsChanged,\n uploadDocument,\n saveFile,\n emailDocument,\n certificateUrl,\n ]\n )\n return <DocumentToolsContext.Provider value={value}>{children}</DocumentToolsContext.Provider>\n}\n\n/** The host's environment, or `null` outside a `<DocumentToolsProvider>`. */\nexport function useOptionalDocumentTools(): ResolvedDocumentToolsEnvironment | null {\n return useContext(DocumentToolsContext)\n}\n\n/** The host's environment; throws outside a `<DocumentToolsProvider>`. */\nexport function useDocumentTools(): ResolvedDocumentToolsEnvironment {\n const env = useContext(DocumentToolsContext)\n if (!env) throw new Error('The document tools must be used within a <DocumentToolsProvider>')\n return env\n}\n","/**\n * A document's bytes, through the host's API client: the PDF the viewer and the tools draw on\n * (`/view`: the file itself for a PDF, its PDF rendering for a Word or text file) and the stored\n * file (`/download`). Either takes a document id or a version reference `doc-…@v{n}`.\n */\n\nimport { parseVersionRef } from '../artifacts/versions'\nimport type { DocumentToolsClient } from './environment'\n\nexport interface DocumentFetchOptions {\n /** The version to fetch. Default: the one `documentRef` names, else the current version. */\n version?: number | null\n workspaceExtId?: string\n signal?: AbortSignal\n}\n\n/** A document's bytes could not be fetched; `status` is the HTTP status. */\nexport class DocumentFetchError extends Error {\n readonly status: number\n constructor(message: string, status: number) {\n super(message)\n this.name = 'DocumentFetchError'\n this.status = status\n }\n}\n\nasync function fetchDocumentBytes(\n client: DocumentToolsClient,\n endpoint: '/v1/document/{document_ext_id}/view' | '/v1/document/{document_ext_id}/download',\n documentRef: string,\n options: DocumentFetchOptions,\n headers: Record<string, string>,\n what: string\n): Promise<{ blob: Blob; response: Response }> {\n const ref = parseVersionRef(documentRef)\n const version = options.version ?? ref.version\n const { data, response } = await client.GET(endpoint, {\n params: {\n path: { document_ext_id: ref.docId },\n query: {\n ...(version ? { version } : {}),\n ...(options.workspaceExtId ? { workspace_ext_id: options.workspaceExtId } : {}),\n },\n },\n headers,\n parseAs: 'blob',\n signal: options.signal,\n })\n if (!response.ok || !(data instanceof Blob)) {\n throw new DocumentFetchError(\n `${what} could not be loaded (${response.status})`,\n response.status\n )\n }\n return { blob: data, response }\n}\n\n/**\n * The file name a `Content-Disposition` header gives, or `undefined`. Prefers the RFC 5987\n * `filename*=UTF-8''…` form (percent-encoded, any script) over the plain `filename=`.\n */\nexport function contentDispositionFileName(header: string | null | undefined): string | undefined {\n if (!header) return undefined\n const extended = /filename\\*\\s*=\\s*(?:[\\w-]+)?'[^']*'([^;]+)/i.exec(header)\n if (extended) {\n try {\n return decodeURIComponent(extended[1].trim().replace(/^\"|\"$/g, '')) || undefined\n } catch {\n // A malformed escape: fall back to the plain parameter.\n }\n }\n const plain = /filename\\s*=\\s*(\"((?:[^\"\\\\]|\\\\.)*)\"|[^;]+)/i.exec(header)\n if (!plain) return undefined\n const name = plain[2] !== undefined ? plain[2].replace(/\\\\(.)/g, '$1') : plain[1].trim()\n return name || undefined\n}\n\n/**\n * The PDF of a document version: `GET /v1/document/{id}/view?version=` with\n * `Accept: application/pdf`. Throws a {@link DocumentFetchError} when there is none (yet).\n */\nexport async function fetchDocumentPdf(\n client: DocumentToolsClient,\n documentRef: string,\n options: DocumentFetchOptions = {}\n): Promise<Blob> {\n const { blob } = await fetchDocumentBytes(\n client,\n '/v1/document/{document_ext_id}/view',\n documentRef,\n options,\n { Accept: 'application/pdf' },\n 'The PDF'\n )\n return blob\n}\n\n/**\n * The stored file of a document version, as uploaded: `GET /v1/document/{id}/download`. When the\n * server names the file (`Content-Disposition`), the result is a `File` carrying that name.\n */\nexport async function fetchDocumentFile(\n client: DocumentToolsClient,\n documentRef: string,\n options: DocumentFetchOptions = {}\n): Promise<Blob | File> {\n const { blob, response } = await fetchDocumentBytes(\n client,\n '/v1/document/{document_ext_id}/download',\n documentRef,\n options,\n {},\n 'The file'\n )\n const name = contentDispositionFileName(response.headers.get('Content-Disposition'))\n return name ? new File([blob], name, { type: blob.type }) : blob\n}\n","/**\n * \"Download with markup\": a document version's markup PDF, the PDF with its annotations as native\n * PDF annotations (comments, highlights, stamps, unapplied redactions), which Acrobat and Preview\n * show. The plain Download serves the original. Kept apart from the annotation layer code so a\n * documents list can offer it without loading the annotation tools.\n *\n * A SIGNED version is locked: nothing but a further signature changes it. Its markup stays in the\n * separate markup layer (a title beside the signature, say) and is never written into its PDF, so\n * it has no \"Download with markup\"; the plain Download is the signed file as it is.\n */\n\nimport type { DocumentToolsClient } from './environment'\n\ninterface DocumentVersions {\n current_version?: number | null\n versions?: Array<{ n: number; markup_count?: number | null; reason?: string | null }> | null\n}\n\n/** Why \"Download with markup\" is off for a signed version. */\nexport const SIGNED_LOCKED_REASON =\n \"Signed documents can't be changed — download the signed file instead\"\n\n/** Whether a version (default: the current one) is a signed copy, per its version entry. */\nexport function isSignedVersion(doc: DocumentVersions, version?: number): boolean {\n const n = version ?? doc.current_version ?? 1\n return (doc.versions ?? []).some((v) => v.n === n && v.reason === 'signed')\n}\n\nexport class MarkupDownloadError extends Error {\n constructor(\n message: string,\n readonly status?: number\n ) {\n super(message)\n this.name = 'MarkupDownloadError'\n }\n}\n\n/** Whether a document's current version has markup (per its version entries). */\nexport function currentHasMarkup(doc: DocumentVersions): boolean {\n const n = doc.current_version ?? 1\n return (doc.versions ?? []).some((v) => v.n === n && (v.markup_count ?? 0) > 0)\n}\n\n/** Fetch a version's markup PDF (default: the current version's). */\nexport async function fetchMarkupPdf(\n client: DocumentToolsClient,\n documentId: string,\n version?: number,\n workspaceExtId?: string\n): Promise<{ blob: Blob; fileName: string }> {\n const { data, response } = await client.GET('/v1/document/{document_ext_id}/markup/pdf', {\n params: {\n path: { document_ext_id: documentId },\n query: {\n ...(version ? { version } : {}),\n ...(workspaceExtId ? { workspace_ext_id: workspaceExtId } : {}),\n },\n },\n parseAs: 'blob',\n })\n if (!response.ok || !data) {\n throw new MarkupDownloadError(\n response.status === 404\n ? 'This document has no markup yet'\n : // The server refuses a signed version: its PDF takes no more changes.\n response.status === 409\n ? SIGNED_LOCKED_REASON\n : 'The markup could not be downloaded',\n response.status\n )\n }\n const disposition = response.headers.get('content-disposition') ?? ''\n const utf8 = /filename\\*=UTF-8''([^;]+)/i.exec(disposition)?.[1]\n const plain = /filename=\"([^\"]+)\"/i.exec(disposition)?.[1]\n const fileName = utf8 ? decodeURIComponent(utf8) : (plain ?? 'markup.pdf')\n return { blob: data as Blob, fileName }\n}\n"]}
1
+ {"version":3,"sources":["../src/document-tools/environment.tsx","../src/document-tools/document-pdf.ts","../src/document-tools/markup-download.ts"],"names":[],"mappings":"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","file":"chunk-QMY2JKBI.js","sourcesContent":["/**\n * The host app's side of the document tools (markup, freeze, e-signing, versions): the one place\n * the tools reach the app. They never import a store, a router, a toast library or app API code;\n * the host passes what it has to `<DocumentToolsProvider>` and every optional field has a default.\n *\n * `client` is an openapi-fetch client for the ARBI API (`ArbiClient['fetch']` from\n * `@arbidocs/client`, or `arbi.getClient().fetch` from an `@arbidocs/sdk` `Arbi`), signed in with the\n * user's session; it carries the auth.\n */\n\nimport { createContext, useCallback, useContext, useMemo, useRef, type ReactNode } from 'react'\nimport type { ArbiClient, operations } from '@arbidocs/client'\nimport { useDeploymentDomain } from '../useArbi'\n\nexport type DocumentToolsClient = ArbiClient['fetch']\n\nexport type DocumentToolsNoticeKind = 'success' | 'error' | 'info' | 'warning'\n\nexport interface DocumentToolsNoticeOptions {\n /** A second line under the message. */\n description?: string\n /** One action button on the notice (\"Email it\"). */\n action?: { label: string; onClick: () => void }\n}\n\nexport type DocumentToolsNotify = (\n message: string,\n kind: DocumentToolsNoticeKind,\n options?: DocumentToolsNoticeOptions\n) => void\n\nexport interface DocumentToolsUser {\n /** The name marks are authored as and the signer's name is prefilled with. */\n name: string\n /** The sign-in email: signing re-derives the user's key from it and the password. */\n email?: string | null\n /** The user's id (usr-*): which fields of a signature request are theirs. */\n externalId?: string | null\n}\n\n/** What changed about a document, so the host can refresh its own lists and caches. */\nexport type DocumentChange =\n /** A version's markup got its first mark or lost its last one. */\n | 'markup'\n /** A signature was added: the document has a new current version. */\n | 'signed'\n /** A new document was made from it (a frozen copy). The ids are the NEW documents. */\n | 'copy'\n /** A new version was saved (the Word editor's Save version): the document's current version. */\n | 'version'\n\n/**\n * The `/v1/document/upload` query, typed from the API schema: `derived_from` is a list (a\n * production set is derived from every document in it), `shared` a boolean.\n */\nexport type DocumentUploadQuery = NonNullable<operations['upload_documents']['parameters']['query']>\n\nexport interface DocumentUploadRequest {\n file: File\n /** `/v1/document/upload` query: `derived_from`, `derived_role`, `shared`, `folder`. */\n query: DocumentUploadQuery\n}\n\n/**\n * The upload query as a URL query string, for a host that posts the upload itself (an XHR with\n * progress): a list repeats its key (`derived_from=a&derived_from=b`), empty values are left out.\n */\nexport function uploadQueryString(query: DocumentUploadQuery): string {\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(query)) {\n if (value === null || value === undefined) continue\n for (const item of Array.isArray(value) ? value : [value]) params.append(key, String(item))\n }\n return params.toString()\n}\n\nexport interface DocumentToolsEnvironment {\n client: DocumentToolsClient\n /**\n * The deployment domain the user's keys are derived for. Needed for signing. Default: the one\n * the host's `Arbi` computes (`arbi.getDeploymentDomain()`), if any.\n */\n deploymentDomain?: string\n /** The signed-in user; marks are authored as \"You\" without one, and signing is unavailable. */\n user?: DocumentToolsUser | null\n /** Surface a transient message. Default: none (errors still show inline where they can). */\n notify?: DocumentToolsNotify\n /** Open a document or a version reference (`doc-…@v2`): the copy just made, the signed copy. */\n openDocument?: (documentRef: string) => void\n /**\n * Documents changed on the server (see {@link DocumentChange}); refresh the host's lists. The\n * tools wait for it before opening the document, so a copy is listed when it opens.\n */\n onDocumentsChanged?: (documentIds: string[], change: DocumentChange) => void | Promise<void>\n /** Upload a derived copy. Default: `POST /v1/document/upload` through `client`. */\n uploadDocument?: (\n request: DocumentUploadRequest\n ) => Promise<{ doc_ext_ids?: string[] } | undefined>\n /** Save a file to the user's computer. Default: a temporary download link. */\n saveFile?: (blob: Blob, fileName: string) => void\n /** Email a document (offered once it is signed). Omitted: no \"Email it\". */\n emailDocument?: (documentRef: string) => void\n /**\n * The public page that checks a signature (the certificate) in this app. When given, \"View\n * certificate\" opens it in preference to the backend's `certificate_url` (which is on the\n * deployment domain, like the link embedded in the signed PDF). Without it: the backend's\n * `certificate_url`, else `/verify/{reference}` on this origin.\n */\n certificateUrl?: (reference: string) => string\n}\n\n/** The environment with every default filled in. */\nexport interface ResolvedDocumentToolsEnvironment extends DocumentToolsEnvironment {\n prepareFileShare: (documentId: string) => Promise<void>\n registerBeforeFileShare: (documentId: string, flush: () => Promise<void>) => () => void\n notify: DocumentToolsNotify\n saveFile: (blob: Blob, fileName: string) => void\n uploadDocument: (\n request: DocumentUploadRequest\n ) => Promise<{ doc_ext_ids?: string[] } | undefined>\n}\n\n/**\n * Save a blob through a temporary `<a download>`. The object URL is revoked a minute later, not at\n * once: revoking straight after `click()` can cancel the download (Safari, and large files\n * elsewhere) before the browser has read the blob.\n */\nexport function downloadBlob(blob: Blob, fileName: string): void {\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = fileName\n document.body.appendChild(a)\n a.click()\n a.remove()\n setTimeout(() => URL.revokeObjectURL(url), 60_000)\n}\n\n/** The default upload: multipart `files` to `/v1/document/upload` through the API client. */\nexport function clientUpload(client: DocumentToolsClient) {\n return async ({ file, query }: DocumentUploadRequest) => {\n const formData = new FormData()\n formData.append('files', file)\n const { data, response } = await client.POST('/v1/document/upload', {\n params: { query },\n // The schema types the multipart body as `{ files: string[] }`; the FormData is sent as is.\n body: formData as unknown as { files: string[] },\n bodySerializer: () => formData,\n })\n if (!response.ok) throw new Error(`Upload failed with status ${response.status}`)\n return data\n }\n}\n\nexport function defaultCertificateUrl(reference: string): string {\n const origin = typeof location === 'undefined' ? '' : location.origin\n return `${origin}/verify/${encodeURIComponent(reference)}`\n}\n\n/**\n * Where \"View certificate\" goes for a signature: the host's `certificateUrl(reference)` when it\n * gives one, else the `certificate_url` the backend returned, else `/verify/{reference}` here.\n */\nexport function certificateLink(\n signature: { reference: string; certificate_url?: string | null },\n certificateUrl?: (reference: string) => string\n): string {\n if (certificateUrl) return certificateUrl(signature.reference)\n return signature.certificate_url || defaultCertificateUrl(signature.reference)\n}\n\nconst DocumentToolsContext = createContext<ResolvedDocumentToolsEnvironment | null>(null)\n\nexport interface DocumentToolsProviderProps extends DocumentToolsEnvironment {\n children: ReactNode\n}\n\nexport function DocumentToolsProvider({ children, ...env }: DocumentToolsProviderProps) {\n const arbiDeploymentDomain = useDeploymentDomain()\n const guards = useRef(new Map<string, () => Promise<void>>())\n const pendingFlushes = useRef(new Map<string, Promise<void>>())\n const registerBeforeFileShare = useCallback((id: string, flush: () => Promise<void>) => {\n guards.current.set(id, flush)\n return () => {\n if (guards.current.get(id) !== flush) return\n guards.current.delete(id)\n const pending = flush()\n pendingFlushes.current.set(id, pending)\n void pending.then(\n () => {\n if (pendingFlushes.current.get(id) === pending) pendingFlushes.current.delete(id)\n },\n () => {}\n )\n }\n }, [])\n const prepareFileShare = useCallback(async (id: string) => {\n const guard = guards.current.get(id)\n if (guard) {\n await guard()\n pendingFlushes.current.delete(id)\n } else await pendingFlushes.current.get(id)\n }, [])\n const {\n client,\n deploymentDomain,\n user,\n notify,\n openDocument,\n onDocumentsChanged,\n uploadDocument,\n saveFile,\n emailDocument,\n certificateUrl,\n } = env\n const value = useMemo<ResolvedDocumentToolsEnvironment>(\n () => ({\n client,\n prepareFileShare,\n registerBeforeFileShare,\n deploymentDomain: deploymentDomain ?? arbiDeploymentDomain,\n user,\n openDocument,\n onDocumentsChanged,\n emailDocument,\n notify: notify ?? (() => {}),\n saveFile: saveFile ?? downloadBlob,\n uploadDocument: uploadDocument ?? clientUpload(client),\n certificateUrl,\n }),\n [\n client,\n prepareFileShare,\n registerBeforeFileShare,\n deploymentDomain,\n arbiDeploymentDomain,\n user,\n notify,\n openDocument,\n onDocumentsChanged,\n uploadDocument,\n saveFile,\n emailDocument,\n certificateUrl,\n ]\n )\n return <DocumentToolsContext.Provider value={value}>{children}</DocumentToolsContext.Provider>\n}\n\n/** The host's environment, or `null` outside a `<DocumentToolsProvider>`. */\nexport function useOptionalDocumentTools(): ResolvedDocumentToolsEnvironment | null {\n return useContext(DocumentToolsContext)\n}\n\n/** The host's environment; throws outside a `<DocumentToolsProvider>`. */\nexport function useDocumentTools(): ResolvedDocumentToolsEnvironment {\n const env = useContext(DocumentToolsContext)\n if (!env) throw new Error('The document tools must be used within a <DocumentToolsProvider>')\n return env\n}\n","/**\n * A document's bytes, through the host's API client: the PDF the viewer and the tools draw on\n * (`/view`: the file itself for a PDF, its PDF rendering for a Word or text file) and the stored\n * file (`/download`). Either takes a document id or a version reference `doc-…@v{n}`.\n */\n\nimport { parseVersionRef } from '../artifacts/versions'\nimport type { DocumentToolsClient } from './environment'\n\nexport interface DocumentFetchOptions {\n /** The version to fetch. Default: the one `documentRef` names, else the current version. */\n version?: number | null\n workspaceExtId?: string\n signal?: AbortSignal\n}\n\n/** A document's bytes could not be fetched; `status` is the HTTP status. */\nexport class DocumentFetchError extends Error {\n readonly status: number\n constructor(message: string, status: number) {\n super(message)\n this.name = 'DocumentFetchError'\n this.status = status\n }\n}\n\nasync function fetchDocumentBytes(\n client: DocumentToolsClient,\n endpoint: '/v1/document/{document_ext_id}/view' | '/v1/document/{document_ext_id}/download',\n documentRef: string,\n options: DocumentFetchOptions,\n headers: Record<string, string>,\n what: string\n): Promise<{ blob: Blob; response: Response }> {\n const ref = parseVersionRef(documentRef)\n const version = options.version ?? ref.version\n const { data, response } = await client.GET(endpoint, {\n params: {\n path: { document_ext_id: ref.docId },\n query: {\n ...(version ? { version } : {}),\n ...(options.workspaceExtId ? { workspace_ext_id: options.workspaceExtId } : {}),\n },\n },\n headers,\n parseAs: 'blob',\n signal: options.signal,\n })\n if (!response.ok || !(data instanceof Blob)) {\n throw new DocumentFetchError(\n `${what} could not be loaded (${response.status})`,\n response.status\n )\n }\n return { blob: data, response }\n}\n\n/**\n * The file name a `Content-Disposition` header gives, or `undefined`. Prefers the RFC 5987\n * `filename*=UTF-8''…` form (percent-encoded, any script) over the plain `filename=`.\n */\nexport function contentDispositionFileName(header: string | null | undefined): string | undefined {\n if (!header) return undefined\n const extended = /filename\\*\\s*=\\s*(?:[\\w-]+)?'[^']*'([^;]+)/i.exec(header)\n if (extended) {\n try {\n return decodeURIComponent(extended[1].trim().replace(/^\"|\"$/g, '')) || undefined\n } catch {\n // A malformed escape: fall back to the plain parameter.\n }\n }\n const plain = /filename\\s*=\\s*(\"((?:[^\"\\\\]|\\\\.)*)\"|[^;]+)/i.exec(header)\n if (!plain) return undefined\n const name = plain[2] !== undefined ? plain[2].replace(/\\\\(.)/g, '$1') : plain[1].trim()\n return name || undefined\n}\n\n/**\n * The PDF of a document version: `GET /v1/document/{id}/view?version=` with\n * `Accept: application/pdf`. Throws a {@link DocumentFetchError} when there is none (yet).\n */\nexport async function fetchDocumentPdf(\n client: DocumentToolsClient,\n documentRef: string,\n options: DocumentFetchOptions = {}\n): Promise<Blob> {\n const { blob } = await fetchDocumentBytes(\n client,\n '/v1/document/{document_ext_id}/view',\n documentRef,\n options,\n { Accept: 'application/pdf' },\n 'The PDF'\n )\n return blob\n}\n\n/**\n * The stored file of a document version, as uploaded: `GET /v1/document/{id}/download`. When the\n * server names the file (`Content-Disposition`), the result is a `File` carrying that name.\n */\nexport async function fetchDocumentFile(\n client: DocumentToolsClient,\n documentRef: string,\n options: DocumentFetchOptions = {}\n): Promise<Blob | File> {\n const { blob, response } = await fetchDocumentBytes(\n client,\n '/v1/document/{document_ext_id}/download',\n documentRef,\n options,\n {},\n 'The file'\n )\n const name = contentDispositionFileName(response.headers.get('Content-Disposition'))\n return name ? new File([blob], name, { type: blob.type }) : blob\n}\n","/**\n * \"Download with markup\": a document version's markup PDF, the PDF with its annotations as native\n * PDF annotations (comments, highlights, stamps, unapplied redactions), which Acrobat and Preview\n * show. The plain Download serves the original. Kept apart from the annotation layer code so a\n * documents list can offer it without loading the annotation tools.\n *\n * A SIGNED version is locked: nothing but a further signature changes it. Its markup stays in the\n * separate markup layer (a title beside the signature, say) and is never written into its PDF, so\n * it has no \"Download with markup\"; the plain Download is the signed file as it is.\n */\n\nimport type { DocumentToolsClient } from './environment'\n\ninterface DocumentVersions {\n current_version?: number | null\n versions?: Array<{ n: number; markup_count?: number | null; reason?: string | null }> | null\n}\n\n/** Why \"Download with markup\" is off for a signed version. */\nexport const SIGNED_LOCKED_REASON =\n \"Signed documents can't be changed — download the signed file instead\"\n\n/** Whether a version (default: the current one) is a signed copy, per its version entry. */\nexport function isSignedVersion(doc: DocumentVersions, version?: number): boolean {\n const n = version ?? doc.current_version ?? 1\n return (doc.versions ?? []).some((v) => v.n === n && v.reason === 'signed')\n}\n\nexport class MarkupDownloadError extends Error {\n constructor(\n message: string,\n readonly status?: number\n ) {\n super(message)\n this.name = 'MarkupDownloadError'\n }\n}\n\n/** Whether a document's current version has markup (per its version entries). */\nexport function currentHasMarkup(doc: DocumentVersions): boolean {\n const n = doc.current_version ?? 1\n return (doc.versions ?? []).some((v) => v.n === n && (v.markup_count ?? 0) > 0)\n}\n\n/** Fetch a version's markup PDF (default: the current version's). */\nexport async function fetchMarkupPdf(\n client: DocumentToolsClient,\n documentId: string,\n version?: number,\n workspaceExtId?: string\n): Promise<{ blob: Blob; fileName: string }> {\n const { data, response } = await client.GET('/v1/document/{document_ext_id}/markup/pdf', {\n params: {\n path: { document_ext_id: documentId },\n query: {\n ...(version ? { version } : {}),\n ...(workspaceExtId ? { workspace_ext_id: workspaceExtId } : {}),\n },\n },\n parseAs: 'blob',\n })\n if (!response.ok || !data) {\n throw new MarkupDownloadError(\n response.status === 404\n ? 'This document has no markup yet'\n : // The server refuses a signed version: its PDF takes no more changes.\n response.status === 409\n ? SIGNED_LOCKED_REASON\n : 'The markup could not be downloaded',\n response.status\n )\n }\n const disposition = response.headers.get('content-disposition') ?? ''\n const utf8 = /filename\\*=UTF-8''([^;]+)/i.exec(disposition)?.[1]\n const plain = /filename=\"([^\"]+)\"/i.exec(disposition)?.[1]\n const fileName = utf8 ? decodeURIComponent(utf8) : (plain ?? 'markup.pdf')\n return { blob: data as Blob, fileName }\n}\n"]}
@@ -0,0 +1,23 @@
1
+ 'use strict';
2
+
3
+ var chunkT5FZICXN_cjs = require('./chunk-T5FZICXN.cjs');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+
6
+ var pdfViewerChunk = chunkT5FZICXN_cjs.lazyChunk(() => import('./PdfViewerImpl-QUSDLNNM.cjs'));
7
+ var PdfViewer = chunkT5FZICXN_cjs.lazyComponent(
8
+ pdfViewerChunk,
9
+ (m) => m.PdfViewer,
10
+ () => /* @__PURE__ */ jsxRuntime.jsx(
11
+ "div",
12
+ {
13
+ className: "h-full w-full animate-pulse bg-muted/40",
14
+ "data-slot": "pdf-loading",
15
+ "aria-busy": "true"
16
+ }
17
+ )
18
+ );
19
+
20
+ exports.PdfViewer = PdfViewer;
21
+ exports.pdfViewerChunk = pdfViewerChunk;
22
+ //# sourceMappingURL=chunk-QP3WQSAA.cjs.map
23
+ //# sourceMappingURL=chunk-QP3WQSAA.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/viewers/PdfViewer.tsx"],"names":["lazyChunk","lazyComponent","jsx"],"mappings":";;;;;AAUO,IAAM,cAAA,GAAiBA,2BAAA,CAAU,MAAM,OAAO,8BAAiB,CAAC;AAEhE,IAAM,SAAA,GAA2CC,+BAAA;AAAA,EACtD,cAAA;AAAA,EACA,CAAC,MAAM,CAAA,CAAE,SAAA;AAAA,EACT,sBACEC,cAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,yCAAA;AAAA,MACV,WAAA,EAAU,aAAA;AAAA,MACV,WAAA,EAAU;AAAA;AAAA;AAGhB","file":"chunk-QP3WQSAA.cjs","sourcesContent":["/**\n * `PdfViewer`: a PDF rendered with pdf.js. The PDF engine is large, so it lives in its own chunk,\n * loaded the first time a PDF renders (`pdfViewerChunk`); meanwhile a blank page area.\n */\nimport type { ComponentType } from 'react'\nimport { lazyChunk, lazyComponent } from '../lazy-chunk'\nimport type { PdfViewerProps } from './PdfViewerImpl'\n\nexport type { PdfViewerAssets, PdfViewerProps } from './PdfViewerImpl'\n\nexport const pdfViewerChunk = lazyChunk(() => import('./PdfViewerImpl'))\n\nexport const PdfViewer: ComponentType<PdfViewerProps> = lazyComponent(\n pdfViewerChunk,\n (m) => m.PdfViewer,\n () => (\n <div\n className=\"h-full w-full animate-pulse bg-muted/40\"\n data-slot=\"pdf-loading\"\n aria-busy=\"true\"\n />\n )\n)\n"]}
@@ -0,0 +1,46 @@
1
+ import { lazy, Suspense } from 'react';
2
+ import { jsx } from 'react/jsx-runtime';
3
+
4
+ // src/lazy-chunk.tsx
5
+ function lazyChunk(load) {
6
+ let module;
7
+ let pending;
8
+ return {
9
+ load: () => pending ??= load().then(
10
+ (m) => module = m,
11
+ (error) => {
12
+ pending = void 0;
13
+ throw error;
14
+ }
15
+ ),
16
+ loaded: () => module
17
+ };
18
+ }
19
+ function preloadChunks(chunks) {
20
+ return Promise.all(chunks.map((c) => c.load()));
21
+ }
22
+ function lazyComponent(c, pick, fallback = () => null) {
23
+ const make = () => lazy(() => {
24
+ const m = c.loaded();
25
+ if (m)
26
+ return {
27
+ then: (resolve) => resolve({ default: pick(m) })
28
+ };
29
+ return c.load().then(
30
+ (loaded) => ({ default: pick(loaded) }),
31
+ (error) => {
32
+ Lazy = make();
33
+ throw error;
34
+ }
35
+ );
36
+ });
37
+ let Lazy = make();
38
+ function LazyComponent(props) {
39
+ return /* @__PURE__ */ jsx(Suspense, { fallback: fallback(props), children: /* @__PURE__ */ jsx(Lazy, { ...props }) });
40
+ }
41
+ return LazyComponent;
42
+ }
43
+
44
+ export { lazyChunk, lazyComponent, preloadChunks };
45
+ //# sourceMappingURL=chunk-SSXFVWCT.js.map
46
+ //# sourceMappingURL=chunk-SSXFVWCT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lazy-chunk.tsx"],"names":[],"mappings":";;;;AAiBO,SAAS,UAAa,IAAA,EAAsC;AACjE,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI,OAAA;AACJ,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MACH,OAAA,KAAY,IAAA,EAAK,CAAE,IAAA;AAAA,MAClB,CAAC,MAAO,MAAA,GAAS,CAAA;AAAA,MACjB,CAAC,KAAA,KAAmB;AAElB,QAAA,OAAA,GAAU,MAAA;AACV,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,KACF;AAAA,IACF,QAAQ,MAAM;AAAA,GAChB;AACF;AAGO,SAAS,cAAc,MAAA,EAA2D;AACvF,EAAA,OAAO,OAAA,CAAQ,IAAI,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAC,CAAA;AAChD;AAUO,SAAS,aAAA,CACd,CAAA,EACA,IAAA,EACA,QAAA,GAAoC,MAAM,IAAA,EACxB;AAClB,EAAA,MAAM,IAAA,GAAO,MACX,IAAA,CAAK,MAAM;AACT,IAAA,MAAM,CAAA,GAAI,EAAE,MAAA,EAAO;AAEnB,IAAA,IAAI,CAAA;AACF,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,CAAC,OAAA,KACL,OAAA,CAAQ,EAAE,OAAA,EAAS,IAAA,CAAK,CAAC,CAAA,EAAG;AAAA,OAChC;AACF,IAAA,OAAO,CAAA,CAAE,MAAK,CAAE,IAAA;AAAA,MACd,CAAC,MAAA,MAAY,EAAE,OAAA,EAAS,IAAA,CAAK,MAAM,CAAA,EAAE,CAAA;AAAA,MACrC,CAAC,KAAA,KAAmB;AAClB,QAAA,IAAA,GAAO,IAAA,EAAK;AACZ,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AACH,EAAA,IAAI,OAAO,IAAA,EAAK;AAChB,EAAA,SAAS,cAAc,KAAA,EAAU;AAC/B,IAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAS,QAAA,EAAU,QAAA,CAAS,KAAK,GAChC,QAAA,kBAAA,GAAA,CAAC,IAAA,EAAA,EAAM,GAAG,KAAA,EAAO,CAAA,EACnB,CAAA;AAAA,EAEJ;AACA,EAAA,OAAO,aAAA;AACT","file":"chunk-SSXFVWCT.js","sourcesContent":["/**\n * Heavy components (the PDF engine, the Word editor, the data grid) live in their own chunk, loaded\n * the first time one renders, so a page that never shows one (a sign-in page) never downloads it.\n *\n * `lazyChunk(load)` names a lazily loaded module; `lazyComponent(chunk, pick, fallback)` renders a\n * component from it with the same props, showing `fallback` until the chunk is in. A chunk loaded\n * beforehand (`preloadChunks`, as test setups do) renders at once, without suspending.\n */\nimport { lazy, Suspense, type ComponentType, type ReactNode } from 'react'\n\nexport interface LazyChunk<M> {\n /** Load the module (once); resolves with it. */\n load: () => Promise<M>\n /** The module, once loaded. */\n loaded: () => M | undefined\n}\n\nexport function lazyChunk<M>(load: () => Promise<M>): LazyChunk<M> {\n let module: M | undefined\n let pending: Promise<M> | undefined\n return {\n load: () =>\n (pending ??= load().then(\n (m) => (module = m),\n (error: unknown) => {\n // A failed download (offline, a stale deploy) is not cached: a later `load()` retries.\n pending = undefined\n throw error\n }\n )),\n loaded: () => module,\n }\n}\n\n/** Load every chunk now (test setups, or warming up after sign-in). */\nexport function preloadChunks(chunks: readonly LazyChunk<unknown>[]): Promise<unknown[]> {\n return Promise.all(chunks.map((c) => c.load()))\n}\n\n/**\n * A component rendered from `c` once it has loaded, with `fallback` (given the props) meanwhile.\n * Generic components keep their type: `lazyComponent(...) as typeof Impl`.\n *\n * A failed download (offline, a stale deploy) throws to the nearest error boundary; its retry\n * renders again and loads again, with no page reload: `React.lazy` keeps a failure for good, so a\n * failed one is replaced.\n */\nexport function lazyComponent<M, P extends object>(\n c: LazyChunk<M>,\n pick: (module: M) => ComponentType<P>,\n fallback: (props: P) => ReactNode = () => null\n): ComponentType<P> {\n const make = () =>\n lazy(() => {\n const m = c.loaded()\n // Already loaded: a thenable that resolves synchronously, so React renders without suspending.\n if (m)\n return {\n then: (resolve: (v: { default: ComponentType<P> }) => void) =>\n resolve({ default: pick(m) }),\n } as never\n return c.load().then(\n (loaded) => ({ default: pick(loaded) }),\n (error: unknown) => {\n Lazy = make()\n throw error\n }\n )\n })\n let Lazy = make()\n function LazyComponent(props: P) {\n return (\n <Suspense fallback={fallback(props)}>\n <Lazy {...props} />\n </Suspense>\n )\n }\n return LazyComponent\n}\n"]}
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+
6
+ // src/lazy-chunk.tsx
7
+ function lazyChunk(load) {
8
+ let module;
9
+ let pending;
10
+ return {
11
+ load: () => pending ??= load().then(
12
+ (m) => module = m,
13
+ (error) => {
14
+ pending = void 0;
15
+ throw error;
16
+ }
17
+ ),
18
+ loaded: () => module
19
+ };
20
+ }
21
+ function preloadChunks(chunks) {
22
+ return Promise.all(chunks.map((c) => c.load()));
23
+ }
24
+ function lazyComponent(c, pick, fallback = () => null) {
25
+ const make = () => react.lazy(() => {
26
+ const m = c.loaded();
27
+ if (m)
28
+ return {
29
+ then: (resolve) => resolve({ default: pick(m) })
30
+ };
31
+ return c.load().then(
32
+ (loaded) => ({ default: pick(loaded) }),
33
+ (error) => {
34
+ Lazy = make();
35
+ throw error;
36
+ }
37
+ );
38
+ });
39
+ let Lazy = make();
40
+ function LazyComponent(props) {
41
+ return /* @__PURE__ */ jsxRuntime.jsx(react.Suspense, { fallback: fallback(props), children: /* @__PURE__ */ jsxRuntime.jsx(Lazy, { ...props }) });
42
+ }
43
+ return LazyComponent;
44
+ }
45
+
46
+ exports.lazyChunk = lazyChunk;
47
+ exports.lazyComponent = lazyComponent;
48
+ exports.preloadChunks = preloadChunks;
49
+ //# sourceMappingURL=chunk-T5FZICXN.cjs.map
50
+ //# sourceMappingURL=chunk-T5FZICXN.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lazy-chunk.tsx"],"names":["lazy","jsx","Suspense"],"mappings":";;;;;;AAiBO,SAAS,UAAa,IAAA,EAAsC;AACjE,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI,OAAA;AACJ,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MACH,OAAA,KAAY,IAAA,EAAK,CAAE,IAAA;AAAA,MAClB,CAAC,MAAO,MAAA,GAAS,CAAA;AAAA,MACjB,CAAC,KAAA,KAAmB;AAElB,QAAA,OAAA,GAAU,MAAA;AACV,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,KACF;AAAA,IACF,QAAQ,MAAM;AAAA,GAChB;AACF;AAGO,SAAS,cAAc,MAAA,EAA2D;AACvF,EAAA,OAAO,OAAA,CAAQ,IAAI,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAC,CAAA;AAChD;AAUO,SAAS,aAAA,CACd,CAAA,EACA,IAAA,EACA,QAAA,GAAoC,MAAM,IAAA,EACxB;AAClB,EAAA,MAAM,IAAA,GAAO,MACXA,UAAA,CAAK,MAAM;AACT,IAAA,MAAM,CAAA,GAAI,EAAE,MAAA,EAAO;AAEnB,IAAA,IAAI,CAAA;AACF,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,CAAC,OAAA,KACL,OAAA,CAAQ,EAAE,OAAA,EAAS,IAAA,CAAK,CAAC,CAAA,EAAG;AAAA,OAChC;AACF,IAAA,OAAO,CAAA,CAAE,MAAK,CAAE,IAAA;AAAA,MACd,CAAC,MAAA,MAAY,EAAE,OAAA,EAAS,IAAA,CAAK,MAAM,CAAA,EAAE,CAAA;AAAA,MACrC,CAAC,KAAA,KAAmB;AAClB,QAAA,IAAA,GAAO,IAAA,EAAK;AACZ,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AACH,EAAA,IAAI,OAAO,IAAA,EAAK;AAChB,EAAA,SAAS,cAAc,KAAA,EAAU;AAC/B,IAAA,uBACEC,cAAA,CAACC,cAAA,EAAA,EAAS,QAAA,EAAU,QAAA,CAAS,KAAK,GAChC,QAAA,kBAAAD,cAAA,CAAC,IAAA,EAAA,EAAM,GAAG,KAAA,EAAO,CAAA,EACnB,CAAA;AAAA,EAEJ;AACA,EAAA,OAAO,aAAA;AACT","file":"chunk-T5FZICXN.cjs","sourcesContent":["/**\n * Heavy components (the PDF engine, the Word editor, the data grid) live in their own chunk, loaded\n * the first time one renders, so a page that never shows one (a sign-in page) never downloads it.\n *\n * `lazyChunk(load)` names a lazily loaded module; `lazyComponent(chunk, pick, fallback)` renders a\n * component from it with the same props, showing `fallback` until the chunk is in. A chunk loaded\n * beforehand (`preloadChunks`, as test setups do) renders at once, without suspending.\n */\nimport { lazy, Suspense, type ComponentType, type ReactNode } from 'react'\n\nexport interface LazyChunk<M> {\n /** Load the module (once); resolves with it. */\n load: () => Promise<M>\n /** The module, once loaded. */\n loaded: () => M | undefined\n}\n\nexport function lazyChunk<M>(load: () => Promise<M>): LazyChunk<M> {\n let module: M | undefined\n let pending: Promise<M> | undefined\n return {\n load: () =>\n (pending ??= load().then(\n (m) => (module = m),\n (error: unknown) => {\n // A failed download (offline, a stale deploy) is not cached: a later `load()` retries.\n pending = undefined\n throw error\n }\n )),\n loaded: () => module,\n }\n}\n\n/** Load every chunk now (test setups, or warming up after sign-in). */\nexport function preloadChunks(chunks: readonly LazyChunk<unknown>[]): Promise<unknown[]> {\n return Promise.all(chunks.map((c) => c.load()))\n}\n\n/**\n * A component rendered from `c` once it has loaded, with `fallback` (given the props) meanwhile.\n * Generic components keep their type: `lazyComponent(...) as typeof Impl`.\n *\n * A failed download (offline, a stale deploy) throws to the nearest error boundary; its retry\n * renders again and loads again, with no page reload: `React.lazy` keeps a failure for good, so a\n * failed one is replaced.\n */\nexport function lazyComponent<M, P extends object>(\n c: LazyChunk<M>,\n pick: (module: M) => ComponentType<P>,\n fallback: (props: P) => ReactNode = () => null\n): ComponentType<P> {\n const make = () =>\n lazy(() => {\n const m = c.loaded()\n // Already loaded: a thenable that resolves synchronously, so React renders without suspending.\n if (m)\n return {\n then: (resolve: (v: { default: ComponentType<P> }) => void) =>\n resolve({ default: pick(m) }),\n } as never\n return c.load().then(\n (loaded) => ({ default: pick(loaded) }),\n (error: unknown) => {\n Lazy = make()\n throw error\n }\n )\n })\n let Lazy = make()\n function LazyComponent(props: P) {\n return (\n <Suspense fallback={fallback(props)}>\n <Lazy {...props} />\n </Suspense>\n )\n }\n return LazyComponent\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { arbiMutationKeys, arbiQueryKeys, useArbi } from './chunk-6H3O63TQ.js';
1
+ import { arbiMutationKeys, arbiQueryKeys, useArbi } from './chunk-ZM6N7YZH.js';
2
2
  import { create } from 'zustand';
3
3
  import { useRef, useCallback, useSyncExternalStore } from 'react';
4
4
  import { useQueryClient, useMutation, useQuery } from '@tanstack/react-query';
@@ -640,5 +640,5 @@ function adjustTagCounts(qc, workspaceId, delta) {
640
640
  }
641
641
 
642
642
  export { DISMISSED_TASK_TTL_MS, DOCUMENTS_FIRST_PAGE_MEASURE, DOCUMENTS_FIRST_PAGE_SIZE, DOCUMENTS_PAGE_SIZE, FINISHED_DOCUMENT_STATUSES, IN_FLIGHT_DOCUMENT_STATUSES, QUEUED_WRITE_BLOCKED_MESSAGE, QUEUED_WRITE_RETRY, SIMILARITY_THRESHOLD, adjustTagCounts, dropTagFromCachedDocuments, finishEntityExtraction, forgetDocuments, getCachedDocuments, inWorkspace, invalidateTagData, invalidateTagTables, isBlockedOnWorkspace, isDocumentsLoading, isRowNewer, isStaleTaskUpdate, isWorkspaceUnavailable, patchCachedDocument, patchDocuments, patchWorkspaceTags, primeOnArbi, primeOnClient, refreshDocuments, replayableTagMutations, resolveDocumentStatus, setCachedDocument, settledByRows, startEntityExtraction, stopDocumentsLoading, subscribeDocumentRows, upsertDocuments, useArbiWsStore, useCapturingWorkspace, useCreateTag, useDeleteTag, useDocument, useDocuments, useDocumentsLoading, useEntityExtractionDocIds, useExtractEntities, useInvalidateTagData, useIsCreatingTag, useRefreshDocuments, useSetTagValues, useSimilarDocuments, useTagKindSchema, useUpdateTag, useUpdateTagKindSchema };
643
- //# sourceMappingURL=chunk-P6WLV5UY.js.map
644
- //# sourceMappingURL=chunk-P6WLV5UY.js.map
643
+ //# sourceMappingURL=chunk-XWPLOFDN.js.map
644
+ //# sourceMappingURL=chunk-XWPLOFDN.js.map