@printwithsynergy/lens-pdf 0.3.0-beta.81

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 (213) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +344 -0
  3. package/dist/browser/codexOverlay.d.ts +109 -0
  4. package/dist/browser/codexOverlay.d.ts.map +1 -0
  5. package/dist/browser/codexOverlay.js +256 -0
  6. package/dist/browser/codexOverlay.js.map +1 -0
  7. package/dist/browser/constants.d.ts +13 -0
  8. package/dist/browser/constants.d.ts.map +1 -0
  9. package/dist/browser/constants.js +13 -0
  10. package/dist/browser/constants.js.map +1 -0
  11. package/dist/browser/index.d.ts +211 -0
  12. package/dist/browser/index.d.ts.map +1 -0
  13. package/dist/browser/index.js +1190 -0
  14. package/dist/browser/index.js.map +1 -0
  15. package/dist/browser/pantone-gold.d.ts +59 -0
  16. package/dist/browser/pantone-gold.d.ts.map +1 -0
  17. package/dist/browser/pantone-gold.js +237 -0
  18. package/dist/browser/pantone-gold.js.map +1 -0
  19. package/dist/components/AnnotationCanvas.d.ts +27 -0
  20. package/dist/components/AnnotationCanvas.d.ts.map +1 -0
  21. package/dist/components/AnnotationCanvas.js +401 -0
  22. package/dist/components/AnnotationCanvas.js.map +1 -0
  23. package/dist/components/AnnotationNotesPanel.d.ts +15 -0
  24. package/dist/components/AnnotationNotesPanel.d.ts.map +1 -0
  25. package/dist/components/AnnotationNotesPanel.js +235 -0
  26. package/dist/components/AnnotationNotesPanel.js.map +1 -0
  27. package/dist/components/AnnotationThread.d.ts +18 -0
  28. package/dist/components/AnnotationThread.d.ts.map +1 -0
  29. package/dist/components/AnnotationThread.js +163 -0
  30. package/dist/components/AnnotationThread.js.map +1 -0
  31. package/dist/components/AnnotationToolbar.d.ts +39 -0
  32. package/dist/components/AnnotationToolbar.d.ts.map +1 -0
  33. package/dist/components/AnnotationToolbar.js +258 -0
  34. package/dist/components/AnnotationToolbar.js.map +1 -0
  35. package/dist/components/BoxOverlay.d.ts +20 -0
  36. package/dist/components/BoxOverlay.d.ts.map +1 -0
  37. package/dist/components/BoxOverlay.js +107 -0
  38. package/dist/components/BoxOverlay.js.map +1 -0
  39. package/dist/components/ColorPickerTool.d.ts +11 -0
  40. package/dist/components/ColorPickerTool.d.ts.map +1 -0
  41. package/dist/components/ColorPickerTool.js +220 -0
  42. package/dist/components/ColorPickerTool.js.map +1 -0
  43. package/dist/components/DensitometerTool.d.ts +25 -0
  44. package/dist/components/DensitometerTool.d.ts.map +1 -0
  45. package/dist/components/DensitometerTool.js +246 -0
  46. package/dist/components/DensitometerTool.js.map +1 -0
  47. package/dist/components/DielineInfoPanel.d.ts +27 -0
  48. package/dist/components/DielineInfoPanel.d.ts.map +1 -0
  49. package/dist/components/DielineInfoPanel.js +23 -0
  50. package/dist/components/DielineInfoPanel.js.map +1 -0
  51. package/dist/components/DielineOverlay.d.ts +10 -0
  52. package/dist/components/DielineOverlay.d.ts.map +1 -0
  53. package/dist/components/DielineOverlay.js +57 -0
  54. package/dist/components/DielineOverlay.js.map +1 -0
  55. package/dist/components/FindingsSidebar.d.ts +50 -0
  56. package/dist/components/FindingsSidebar.d.ts.map +1 -0
  57. package/dist/components/FindingsSidebar.js +78 -0
  58. package/dist/components/FindingsSidebar.js.map +1 -0
  59. package/dist/components/LayerCanvas.d.ts +30 -0
  60. package/dist/components/LayerCanvas.d.ts.map +1 -0
  61. package/dist/components/LayerCanvas.js +84 -0
  62. package/dist/components/LayerCanvas.js.map +1 -0
  63. package/dist/components/LayerPanel.d.ts +9 -0
  64. package/dist/components/LayerPanel.d.ts.map +1 -0
  65. package/dist/components/LayerPanel.js +144 -0
  66. package/dist/components/LayerPanel.js.map +1 -0
  67. package/dist/components/LensPDF.d.ts +61 -0
  68. package/dist/components/LensPDF.d.ts.map +1 -0
  69. package/dist/components/LensPDF.js +49 -0
  70. package/dist/components/LensPDF.js.map +1 -0
  71. package/dist/components/LensPDFDemo.d.ts +160 -0
  72. package/dist/components/LensPDFDemo.d.ts.map +1 -0
  73. package/dist/components/LensPDFDemo.js +1060 -0
  74. package/dist/components/LensPDFDemo.js.map +1 -0
  75. package/dist/components/LensPDFDemo.styles.d.ts +38 -0
  76. package/dist/components/LensPDFDemo.styles.d.ts.map +1 -0
  77. package/dist/components/LensPDFDemo.styles.js +282 -0
  78. package/dist/components/LensPDFDemo.styles.js.map +1 -0
  79. package/dist/components/LensPDFViewer.d.ts +79 -0
  80. package/dist/components/LensPDFViewer.d.ts.map +1 -0
  81. package/dist/components/LensPDFViewer.js +254 -0
  82. package/dist/components/LensPDFViewer.js.map +1 -0
  83. package/dist/components/MeasureTool.d.ts +16 -0
  84. package/dist/components/MeasureTool.d.ts.map +1 -0
  85. package/dist/components/MeasureTool.js +137 -0
  86. package/dist/components/MeasureTool.js.map +1 -0
  87. package/dist/components/MobileBottomSheet.d.ts +12 -0
  88. package/dist/components/MobileBottomSheet.d.ts.map +1 -0
  89. package/dist/components/MobileBottomSheet.js +113 -0
  90. package/dist/components/MobileBottomSheet.js.map +1 -0
  91. package/dist/components/MobileDrawer.d.ts +31 -0
  92. package/dist/components/MobileDrawer.d.ts.map +1 -0
  93. package/dist/components/MobileDrawer.js +67 -0
  94. package/dist/components/MobileDrawer.js.map +1 -0
  95. package/dist/components/PageCanvas.d.ts +33 -0
  96. package/dist/components/PageCanvas.d.ts.map +1 -0
  97. package/dist/components/PageCanvas.js +385 -0
  98. package/dist/components/PageCanvas.js.map +1 -0
  99. package/dist/components/PageNavigator.d.ts +18 -0
  100. package/dist/components/PageNavigator.d.ts.map +1 -0
  101. package/dist/components/PageNavigator.js +44 -0
  102. package/dist/components/PageNavigator.js.map +1 -0
  103. package/dist/components/SeparationCanvas.d.ts +12 -0
  104. package/dist/components/SeparationCanvas.d.ts.map +1 -0
  105. package/dist/components/SeparationCanvas.js +174 -0
  106. package/dist/components/SeparationCanvas.js.map +1 -0
  107. package/dist/components/TACHeatmapOverlay.d.ts +17 -0
  108. package/dist/components/TACHeatmapOverlay.d.ts.map +1 -0
  109. package/dist/components/TACHeatmapOverlay.js +119 -0
  110. package/dist/components/TACHeatmapOverlay.js.map +1 -0
  111. package/dist/components/ZoomControls.d.ts +11 -0
  112. package/dist/components/ZoomControls.d.ts.map +1 -0
  113. package/dist/components/ZoomControls.js +26 -0
  114. package/dist/components/ZoomControls.js.map +1 -0
  115. package/dist/components/defaultShellPlugins.d.ts +3 -0
  116. package/dist/components/defaultShellPlugins.d.ts.map +1 -0
  117. package/dist/components/defaultShellPlugins.js +273 -0
  118. package/dist/components/defaultShellPlugins.js.map +1 -0
  119. package/dist/components/index.d.ts +32 -0
  120. package/dist/components/index.d.ts.map +1 -0
  121. package/dist/components/index.js +32 -0
  122. package/dist/components/index.js.map +1 -0
  123. package/dist/components/presets.d.ts +8 -0
  124. package/dist/components/presets.d.ts.map +1 -0
  125. package/dist/components/presets.js +14 -0
  126. package/dist/components/presets.js.map +1 -0
  127. package/dist/components/shellPlugins.d.ts +105 -0
  128. package/dist/components/shellPlugins.d.ts.map +1 -0
  129. package/dist/components/shellPlugins.js +52 -0
  130. package/dist/components/shellPlugins.js.map +1 -0
  131. package/dist/components/useIsMobile.d.ts +16 -0
  132. package/dist/components/useIsMobile.d.ts.map +1 -0
  133. package/dist/components/useIsMobile.js +30 -0
  134. package/dist/components/useIsMobile.js.map +1 -0
  135. package/dist/fallback-pdfjs/index.d.ts +60 -0
  136. package/dist/fallback-pdfjs/index.d.ts.map +1 -0
  137. package/dist/fallback-pdfjs/index.js +163 -0
  138. package/dist/fallback-pdfjs/index.js.map +1 -0
  139. package/dist/host/LensPDFProvider.d.ts +36 -0
  140. package/dist/host/LensPDFProvider.d.ts.map +1 -0
  141. package/dist/host/LensPDFProvider.js +12 -0
  142. package/dist/host/LensPDFProvider.js.map +1 -0
  143. package/dist/host/index.d.ts +167 -0
  144. package/dist/host/index.d.ts.map +1 -0
  145. package/dist/host/index.js +173 -0
  146. package/dist/host/index.js.map +1 -0
  147. package/dist/host/pdfFallback.d.ts +50 -0
  148. package/dist/host/pdfFallback.d.ts.map +1 -0
  149. package/dist/host/pdfFallback.js +171 -0
  150. package/dist/host/pdfFallback.js.map +1 -0
  151. package/dist/host/pdfValidation.d.ts +45 -0
  152. package/dist/host/pdfValidation.d.ts.map +1 -0
  153. package/dist/host/pdfValidation.js +78 -0
  154. package/dist/host/pdfValidation.js.map +1 -0
  155. package/dist/host/shareLink.d.ts +80 -0
  156. package/dist/host/shareLink.d.ts.map +1 -0
  157. package/dist/host/shareLink.js +114 -0
  158. package/dist/host/shareLink.js.map +1 -0
  159. package/dist/host/useLensPDF.d.ts +73 -0
  160. package/dist/host/useLensPDF.d.ts.map +1 -0
  161. package/dist/host/useLensPDF.js +213 -0
  162. package/dist/host/useLensPDF.js.map +1 -0
  163. package/dist/index.d.ts +68 -0
  164. package/dist/index.d.ts.map +1 -0
  165. package/dist/index.js +62 -0
  166. package/dist/index.js.map +1 -0
  167. package/dist/plugin/context.d.ts +70 -0
  168. package/dist/plugin/context.d.ts.map +1 -0
  169. package/dist/plugin/context.js +16 -0
  170. package/dist/plugin/context.js.map +1 -0
  171. package/dist/plugin/findings-location.d.ts +53 -0
  172. package/dist/plugin/findings-location.d.ts.map +1 -0
  173. package/dist/plugin/findings-location.js +72 -0
  174. package/dist/plugin/findings-location.js.map +1 -0
  175. package/dist/plugin/index.d.ts +19 -0
  176. package/dist/plugin/index.d.ts.map +1 -0
  177. package/dist/plugin/index.js +16 -0
  178. package/dist/plugin/index.js.map +1 -0
  179. package/dist/plugin/registry.d.ts +61 -0
  180. package/dist/plugin/registry.d.ts.map +1 -0
  181. package/dist/plugin/registry.js +102 -0
  182. package/dist/plugin/registry.js.map +1 -0
  183. package/dist/plugin/services.d.ts +380 -0
  184. package/dist/plugin/services.d.ts.map +1 -0
  185. package/dist/plugin/services.js +104 -0
  186. package/dist/plugin/services.js.map +1 -0
  187. package/dist/plugin/types.d.ts +198 -0
  188. package/dist/plugin/types.d.ts.map +1 -0
  189. package/dist/plugin/types.js +24 -0
  190. package/dist/plugin/types.js.map +1 -0
  191. package/dist/types/index.d.ts +191 -0
  192. package/dist/types/index.d.ts.map +1 -0
  193. package/dist/types/index.js +95 -0
  194. package/dist/types/index.js.map +1 -0
  195. package/dist/units/index.d.ts +64 -0
  196. package/dist/units/index.d.ts.map +1 -0
  197. package/dist/units/index.js +98 -0
  198. package/dist/units/index.js.map +1 -0
  199. package/docs/architecture.md +90 -0
  200. package/docs/components.md +569 -0
  201. package/docs/contributing.md +78 -0
  202. package/docs/fallback.md +174 -0
  203. package/docs/lens-pdf-viewer.md +128 -0
  204. package/docs/licensing.md +78 -0
  205. package/docs/measurement-units.md +87 -0
  206. package/docs/plugins.md +256 -0
  207. package/docs/security.md +69 -0
  208. package/docs/server.md +212 -0
  209. package/docs/services.md +210 -0
  210. package/docs/share-links.md +111 -0
  211. package/docs/theming.md +164 -0
  212. package/docs/validation.md +83 -0
  213. package/package.json +139 -0
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useEffect, useRef } from "react";
4
+ import { THUMBNAIL_DPI } from "../types/index.js";
5
+ import { useViewerServices } from "../host/index.js";
6
+ export function PageNavigator({ pages, currentPage, items, onPageChange, horizontal, }) {
7
+ const { pageImages } = useViewerServices();
8
+ const activeRef = useRef(null);
9
+ useEffect(() => {
10
+ activeRef.current?.scrollIntoView({
11
+ block: horizontal ? "nearest" : "nearest",
12
+ inline: horizontal ? "center" : undefined,
13
+ behavior: "smooth",
14
+ });
15
+ }, [currentPage, horizontal]);
16
+ const itemsPerPage = new Map();
17
+ for (const item of items) {
18
+ if (!item.page)
19
+ continue;
20
+ const curr = itemsPerPage.get(item.page) ?? { errors: 0, warnings: 0 };
21
+ if (item.tier === "error")
22
+ curr.errors++;
23
+ else if (item.tier === "warning")
24
+ curr.warnings++;
25
+ itemsPerPage.set(item.page, curr);
26
+ }
27
+ if (horizontal) {
28
+ return (_jsx(_Fragment, { children: pages.map((page) => {
29
+ const isActive = page.page_num === currentPage;
30
+ const counts = itemsPerPage.get(page.page_num);
31
+ return (_jsxs("button", { ref: isActive ? activeRef : undefined, onClick: () => onPageChange(page.page_num), className: `relative shrink-0 rounded border p-0.5 transition-colors ${isActive
32
+ ? "border-blue-500 ring-2 ring-blue-500/30"
33
+ : "border-white/[0.06] hover:border-slate-500"}`, style: { width: 56 }, children: [_jsx("img", { src: pageImages.getPageImageUrl({ pageNum: page.page_num, dpi: THUMBNAIL_DPI }), alt: `Page ${page.page_num}`, className: "w-full rounded", loading: "lazy" }), _jsx("span", { className: "absolute bottom-0.5 left-0.5 rounded bg-black/60 px-1 text-[9px] text-white", children: page.page_num }), counts && (_jsxs("div", { className: "absolute right-0.5 top-0.5 flex gap-0.5", children: [counts.errors > 0 && (_jsx("span", { className: "rounded-full bg-red-500 px-1 text-[8px] text-white", children: counts.errors })), counts.warnings > 0 && (_jsx("span", { className: "rounded-full bg-amber-500 px-1 text-[8px] text-white", children: counts.warnings }))] }))] }, page.page_num));
34
+ }) }));
35
+ }
36
+ return (_jsxs("div", { className: "flex flex-col gap-1 overflow-y-auto p-2", children: [_jsxs("div", { className: "mb-1 text-xs font-medium text-muted-foreground", children: ["Pages (", pages.length, ")"] }), pages.map((page) => {
37
+ const isActive = page.page_num === currentPage;
38
+ const counts = itemsPerPage.get(page.page_num);
39
+ return (_jsxs("button", { ref: isActive ? activeRef : undefined, onClick: () => onPageChange(page.page_num), className: `relative rounded border p-0.5 transition-colors ${isActive
40
+ ? "border-primary ring-2 ring-primary/30"
41
+ : "border-border hover:border-primary/50"}`, children: [_jsx("img", { src: pageImages.getPageImageUrl({ pageNum: page.page_num, dpi: THUMBNAIL_DPI }), alt: `Page ${page.page_num}`, className: "w-full rounded", loading: "lazy" }), _jsx("span", { className: "absolute bottom-0.5 left-0.5 rounded bg-black/60 px-1 text-[10px] text-white", children: page.page_num }), counts && (_jsxs("div", { className: "absolute right-0.5 top-0.5 flex gap-0.5", children: [counts.errors > 0 && (_jsx("span", { className: "rounded-full bg-destructive px-1 text-[9px] text-white", children: counts.errors })), counts.warnings > 0 && (_jsx("span", { className: "rounded-full bg-warning px-1 text-[9px] text-white", children: counts.warnings }))] }))] }, page.page_num));
42
+ })] }));
43
+ }
44
+ //# sourceMappingURL=PageNavigator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageNavigator.js","sourceRoot":"","sources":["../../components/PageNavigator.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ interface SeparationCanvasProps {
2
+ jobId: string;
3
+ pageNum: number;
4
+ enabledChannels: Set<string>;
5
+ allChannels: string[];
6
+ width: number;
7
+ height: number;
8
+ dpi?: number;
9
+ }
10
+ export declare function SeparationCanvas({ jobId: _jobId, pageNum, enabledChannels, allChannels, width, height, dpi, }: SeparationCanvasProps): import("react/jsx-runtime").JSX.Element | null;
11
+ export {};
12
+ //# sourceMappingURL=SeparationCanvas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeparationCanvas.d.ts","sourceRoot":"","sources":["../../components/SeparationCanvas.tsx"],"names":[],"mappings":"AA4CA,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EAAE,MAAM,EACb,OAAO,EACP,eAAe,EACf,WAAW,EACX,KAAK,EACL,MAAM,EACN,GAAiB,GAClB,EAAE,qBAAqB,kDA6IvB"}
@@ -0,0 +1,174 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useCallback, useEffect, useRef, useState } from "react";
4
+ import { DEFAULT_DPI } from "../types/index.js";
5
+ import { isUnwired, logUnwiredHide, useViewerHost, useViewerServices } from "../host/index.js";
6
+ /**
7
+ * RGB tint colors for compositing each channel onto a white background
8
+ * using multiply blending. For CMYK channels, we use their subtractive
9
+ * color representation. Spot colors get a generated hue.
10
+ */
11
+ const CHANNEL_RGB = {
12
+ Cyan: [0, 183, 235],
13
+ Magenta: [236, 0, 140],
14
+ Yellow: [255, 242, 0],
15
+ Black: [35, 31, 32],
16
+ };
17
+ function spotColorRgb(name) {
18
+ let hash = 0;
19
+ for (let i = 0; i < name.length; i++) {
20
+ hash = name.charCodeAt(i) + ((hash << 5) - hash);
21
+ }
22
+ const hue = Math.abs(hash) % 360;
23
+ // Convert HSL(hue, 70%, 45%) to RGB
24
+ const s = 0.7;
25
+ const l = 0.45;
26
+ const c = (1 - Math.abs(2 * l - 1)) * s;
27
+ const x = c * (1 - Math.abs(((hue / 60) % 2) - 1));
28
+ const m = l - c / 2;
29
+ let r = 0, g = 0, b = 0;
30
+ if (hue < 60) {
31
+ r = c;
32
+ g = x;
33
+ }
34
+ else if (hue < 120) {
35
+ r = x;
36
+ g = c;
37
+ }
38
+ else if (hue < 180) {
39
+ g = c;
40
+ b = x;
41
+ }
42
+ else if (hue < 240) {
43
+ g = x;
44
+ b = c;
45
+ }
46
+ else if (hue < 300) {
47
+ r = x;
48
+ b = c;
49
+ }
50
+ else {
51
+ r = c;
52
+ b = x;
53
+ }
54
+ return [
55
+ Math.round((r + m) * 255),
56
+ Math.round((g + m) * 255),
57
+ Math.round((b + m) * 255),
58
+ ];
59
+ }
60
+ export function SeparationCanvas({ jobId: _jobId, pageNum, enabledChannels, allChannels, width, height, dpi = DEFAULT_DPI, }) {
61
+ const { separations } = useViewerServices();
62
+ const { debug } = useViewerHost();
63
+ const hidden = isUnwired(separations);
64
+ const canvasRef = useRef(null);
65
+ const [channelImages, setChannelImages] = useState(new Map());
66
+ const [loadingChannels, setLoadingChannels] = useState(new Set());
67
+ // Clear cached channel images when page changes
68
+ useEffect(() => {
69
+ setChannelImages(new Map());
70
+ setLoadingChannels(new Set());
71
+ }, [pageNum]);
72
+ useEffect(() => {
73
+ if (hidden && debug)
74
+ logUnwiredHide("SeparationCanvas", "separations");
75
+ }, [hidden, debug]);
76
+ // Load channel images lazily
77
+ const loadChannel = useCallback(async (channelName) => {
78
+ if (channelImages.has(channelName) || loadingChannels.has(channelName)) {
79
+ return;
80
+ }
81
+ setLoadingChannels((prev) => new Set(prev).add(channelName));
82
+ const img = new Image();
83
+ const url = separations.getChannelImageUrl({ pageNum, channelName, dpi });
84
+ await new Promise((resolve) => {
85
+ img.onload = () => {
86
+ setChannelImages((prev) => {
87
+ const next = new Map(prev);
88
+ next.set(channelName, img);
89
+ return next;
90
+ });
91
+ setLoadingChannels((prev) => {
92
+ const next = new Set(prev);
93
+ next.delete(channelName);
94
+ return next;
95
+ });
96
+ resolve();
97
+ };
98
+ img.onerror = () => {
99
+ setLoadingChannels((prev) => {
100
+ const next = new Set(prev);
101
+ next.delete(channelName);
102
+ return next;
103
+ });
104
+ resolve();
105
+ };
106
+ img.src = url;
107
+ });
108
+ }, [separations, pageNum, dpi, channelImages, loadingChannels]);
109
+ // Load enabled channels
110
+ useEffect(() => {
111
+ for (const ch of enabledChannels) {
112
+ if (!channelImages.has(ch)) {
113
+ loadChannel(ch);
114
+ }
115
+ }
116
+ }, [enabledChannels, channelImages, loadChannel]);
117
+ // Composite enabled channels onto canvas
118
+ useEffect(() => {
119
+ const canvas = canvasRef.current;
120
+ if (!canvas)
121
+ return;
122
+ const ctx = canvas.getContext("2d");
123
+ if (!ctx)
124
+ return;
125
+ // Start with white paper
126
+ ctx.fillStyle = "#ffffff";
127
+ ctx.fillRect(0, 0, width, height);
128
+ // Composite each enabled channel using multiply blend
129
+ for (const channelName of allChannels) {
130
+ if (!enabledChannels.has(channelName))
131
+ continue;
132
+ const img = channelImages.get(channelName);
133
+ if (!img)
134
+ continue;
135
+ // channelName comes from the allChannels list we own — typed Record lookup.
136
+ // eslint-disable-next-line security/detect-object-injection
137
+ const rgb = CHANNEL_RGB[channelName] ?? spotColorRgb(channelName);
138
+ // Create offscreen canvas for tinting
139
+ const offscreen = document.createElement("canvas");
140
+ offscreen.width = width;
141
+ offscreen.height = height;
142
+ const offCtx = offscreen.getContext("2d");
143
+ // Draw grayscale channel image
144
+ offCtx.drawImage(img, 0, 0, width, height);
145
+ // Get pixel data and tint with channel color
146
+ const imageData = offCtx.getImageData(0, 0, width, height);
147
+ const data = imageData.data;
148
+ for (let i = 0; i < data.length; i += 4) {
149
+ // Grayscale value: 0 = full ink, 255 = no ink (inverted)
150
+ // Convert to ink density: 0 = no ink, 255 = full ink
151
+ // data is a Uint8ClampedArray and i is a bounded loop index.
152
+ // eslint-disable-next-line security/detect-object-injection
153
+ const inkDensity = 255 - (data[i] ?? 0);
154
+ // Tinted color = white * (1 - density/255) + channelColor * (density/255)
155
+ const t = inkDensity / 255;
156
+ // eslint-disable-next-line security/detect-object-injection
157
+ data[i] = Math.round(255 * (1 - t) + (rgb[0] ?? 0) * t);
158
+ data[i + 1] = Math.round(255 * (1 - t) + (rgb[1] ?? 0) * t);
159
+ data[i + 2] = Math.round(255 * (1 - t) + (rgb[2] ?? 0) * t);
160
+ data[i + 3] = 255;
161
+ }
162
+ offCtx.putImageData(imageData, 0, 0);
163
+ // Multiply blend onto main canvas
164
+ ctx.globalCompositeOperation = "multiply";
165
+ ctx.drawImage(offscreen, 0, 0);
166
+ }
167
+ // Reset blend mode
168
+ ctx.globalCompositeOperation = "source-over";
169
+ }, [width, height, enabledChannels, channelImages, allChannels]);
170
+ if (hidden)
171
+ return null;
172
+ return (_jsx("canvas", { ref: canvasRef, width: width, height: height, style: { position: "absolute", left: 0, top: 0, width, height } }));
173
+ }
174
+ //# sourceMappingURL=SeparationCanvas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeparationCanvas.js","sourceRoot":"","sources":["../../components/SeparationCanvas.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ interface TACHeatmapOverlayProps {
2
+ jobId: string;
3
+ pageNum: number;
4
+ width: number;
5
+ height: number;
6
+ /** Page width in PDF points — needed to place SVG hit-targets from
7
+ * the top-left-origin bbox coordinates. */
8
+ pageWidthPts?: number;
9
+ /** Page height in PDF points. */
10
+ pageHeightPts?: number;
11
+ opacity?: number;
12
+ dpi?: number;
13
+ tacLimit?: number;
14
+ }
15
+ export declare function TACHeatmapOverlay({ jobId: _jobId, pageNum, width, height, pageWidthPts, pageHeightPts, opacity, dpi, tacLimit, }: TACHeatmapOverlayProps): import("react/jsx-runtime").JSX.Element | null;
16
+ export {};
17
+ //# sourceMappingURL=TACHeatmapOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TACHeatmapOverlay.d.ts","sourceRoot":"","sources":["../../components/TACHeatmapOverlay.tsx"],"names":[],"mappings":"AAyBA,UAAU,sBAAsB;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;gDAC4C;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,EACP,KAAK,EACL,MAAM,EACN,YAAY,EACZ,aAAa,EACb,OAAa,EACb,GAAiB,EACjB,QAAc,GACf,EAAE,sBAAsB,kDAsMxB"}
@@ -0,0 +1,119 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { DEFAULT_DPI } from "../types/index.js";
5
+ import { isUnwired, logUnwiredHide, useViewerHost, useViewerServices } from "../host/index.js";
6
+ export function TACHeatmapOverlay({ jobId: _jobId, pageNum, width, height, pageWidthPts, pageHeightPts, opacity = 0.5, dpi = DEFAULT_DPI, tacLimit = 300, }) {
7
+ const { tacHeatmap } = useViewerServices();
8
+ const { debug } = useViewerHost();
9
+ const hidden = isUnwired(tacHeatmap);
10
+ const canvasRef = useRef(null);
11
+ const [heatmapImg, setHeatmapImg] = useState(null);
12
+ const [loading, setLoading] = useState(true);
13
+ const [error, setError] = useState("");
14
+ const [runs, setRuns] = useState([]);
15
+ const [hoveredRun, setHoveredRun] = useState(null);
16
+ useEffect(() => {
17
+ if (hidden) {
18
+ if (debug)
19
+ logUnwiredHide("TACHeatmapOverlay", "tacHeatmap");
20
+ return;
21
+ }
22
+ setLoading(true);
23
+ setError("");
24
+ const img = new Image();
25
+ img.onload = () => {
26
+ setHeatmapImg(img);
27
+ setLoading(false);
28
+ };
29
+ img.onerror = () => {
30
+ setError("Failed to load TAC heatmap");
31
+ setLoading(false);
32
+ };
33
+ img.src = tacHeatmap.getHeatmapImageUrl({ pageNum, dpi, tacLimit });
34
+ }, [tacHeatmap, pageNum, dpi, tacLimit, hidden, debug]);
35
+ // Fetch run metadata in parallel with the PNG so the tooltip layer
36
+ // and the pixel gradient appear together. The service's listRuns()
37
+ // already swallows non-fatal failures and returns [] — keep the
38
+ // local cancellation flag so a fast page-flip doesn't write stale
39
+ // runs onto the new page.
40
+ useEffect(() => {
41
+ let cancelled = false;
42
+ setRuns([]);
43
+ void tacHeatmap
44
+ .listRuns({ pageNum, dpi, tacLimit })
45
+ .then((items) => {
46
+ if (!cancelled)
47
+ setRuns([...items]);
48
+ });
49
+ return () => {
50
+ cancelled = true;
51
+ };
52
+ }, [tacHeatmap, pageNum, dpi, tacLimit]);
53
+ useEffect(() => {
54
+ const canvas = canvasRef.current;
55
+ if (!canvas || !heatmapImg)
56
+ return;
57
+ const ctx = canvas.getContext("2d");
58
+ if (!ctx)
59
+ return;
60
+ ctx.clearRect(0, 0, width, height);
61
+ ctx.globalAlpha = opacity;
62
+ ctx.drawImage(heatmapImg, 0, 0, width, height);
63
+ ctx.globalAlpha = 1.0;
64
+ }, [heatmapImg, width, height, opacity]);
65
+ if (hidden)
66
+ return null;
67
+ if (loading) {
68
+ return (_jsx("div", { className: "flex items-center justify-center", style: {
69
+ position: "absolute",
70
+ left: 0,
71
+ top: 0,
72
+ width,
73
+ height,
74
+ }, children: _jsxs("div", { className: "flex flex-col items-center gap-2 rounded-lg bg-black/60 px-4 py-3", children: [_jsxs("svg", { className: "h-6 w-6 animate-spin text-white", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })] }), _jsx("span", { className: "text-xs text-white/70", children: "Generating heatmap" })] }) }));
75
+ }
76
+ if (error) {
77
+ return null;
78
+ }
79
+ // pt → CSS-pixel scale. Falls back to identity when the caller didn't
80
+ // pass dimensions (in that case the SVG layer is skipped entirely so
81
+ // we don't render rectangles at nonsense coordinates).
82
+ const sx = pageWidthPts && pageWidthPts > 0 ? width / pageWidthPts : 0;
83
+ const sy = pageHeightPts && pageHeightPts > 0 ? height / pageHeightPts : 0;
84
+ const showTooltipLayer = sx > 0 && sy > 0 && runs.length > 0;
85
+ return (_jsxs(_Fragment, { children: [_jsx("canvas", { ref: canvasRef, width: width, height: height, style: {
86
+ position: "absolute",
87
+ left: 0,
88
+ top: 0,
89
+ width,
90
+ height,
91
+ pointerEvents: "none",
92
+ } }), showTooltipLayer && (_jsx("svg", { style: {
93
+ position: "absolute",
94
+ left: 0,
95
+ top: 0,
96
+ width,
97
+ height,
98
+ pointerEvents: "none",
99
+ }, width: width, height: height, children: runs.map((run, idx) => {
100
+ const x = run.x0 * sx;
101
+ const y = run.y0 * sy;
102
+ const w = Math.max(1, (run.x1 - run.x0) * sx);
103
+ const h = Math.max(1, (run.y1 - run.y0) * sy);
104
+ return (_jsx("rect", { x: x, y: y, width: w, height: h, fill: "transparent", stroke: "transparent", style: { pointerEvents: "all", cursor: "help" }, onMouseEnter: () => setHoveredRun({
105
+ run,
106
+ x: x + w / 2,
107
+ y,
108
+ }), onMouseLeave: () => setHoveredRun(null) }, idx));
109
+ }) })), hoveredRun && (_jsxs("div", { className: "pointer-events-none absolute z-20 -translate-x-1/2 -translate-y-full rounded-md px-2 py-1 text-xs font-medium text-white shadow-lg", style: {
110
+ left: hoveredRun.x,
111
+ top: Math.max(0, hoveredRun.y - 4),
112
+ backgroundColor: hoveredRun.run.exceeds
113
+ ? "rgba(220, 38, 38, 0.95)"
114
+ : "rgba(37, 99, 235, 0.92)",
115
+ }, children: ["Mean TAC ", Math.round(hoveredRun.run.mean_tac), "%", hoveredRun.run.exceeds
116
+ ? ` — exceeds ${Math.round(hoveredRun.run.limit)}% limit`
117
+ : ` (limit ${Math.round(hoveredRun.run.limit)}%)`] })), _jsxs("div", { className: "absolute bottom-20 right-2 rounded bg-black/80 p-2 text-xs text-white shadow-lg sm:bottom-2", children: [_jsx("p", { className: "mb-1 font-semibold", children: "TAC Coverage" }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "inline-block h-2 w-4 rounded", style: { backgroundColor: "rgb(0, 180, 0)" } }), _jsx("span", { children: "< 250%" })] }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "inline-block h-2 w-4 rounded", style: { backgroundColor: "rgb(255, 200, 0)" } }), _jsxs("span", { children: ["250\u2013", tacLimit, "%"] })] }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "inline-block h-2 w-4 rounded", style: { backgroundColor: "rgb(255, 0, 0)" } }), _jsxs("span", { children: ["\u2265 ", tacLimit, "%"] })] })] })] }));
118
+ }
119
+ //# sourceMappingURL=TACHeatmapOverlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TACHeatmapOverlay.js","sourceRoot":"","sources":["../../components/TACHeatmapOverlay.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ interface ZoomControlsProps {
2
+ zoom: number;
3
+ onZoomChange: (zoom: number) => void;
4
+ /** Compact mode: smaller buttons, no border. */
5
+ compact?: boolean;
6
+ /** Dark theme: light text on dark background. */
7
+ dark?: boolean;
8
+ }
9
+ export declare function ZoomControls({ zoom, onZoomChange, compact, dark }: ZoomControlsProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
11
+ //# sourceMappingURL=ZoomControls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ZoomControls.d.ts","sourceRoot":"","sources":["../../components/ZoomControls.tsx"],"names":[],"mappings":"AAEA,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,gDAAgD;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iDAAiD;IACjD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAID,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,iBAAiB,2CAqEpF"}
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ const ZOOM_STEPS = [25, 50, 75, 100, 125, 150, 200, 300, 400];
4
+ export function ZoomControls({ zoom, onZoomChange, compact, dark }) {
5
+ const zoomIn = () => {
6
+ const next = ZOOM_STEPS.find((z) => z > zoom);
7
+ if (next)
8
+ onZoomChange(next);
9
+ };
10
+ const zoomOut = () => {
11
+ const prev = [...ZOOM_STEPS].reverse().find((z) => z < zoom);
12
+ if (prev)
13
+ onZoomChange(prev);
14
+ };
15
+ if (compact) {
16
+ const btnClass = dark
17
+ ? "rounded p-1 text-xs text-slate-300 hover:bg-white/10 hover:text-white disabled:opacity-40"
18
+ : "rounded p-1 text-xs hover:bg-muted disabled:opacity-40";
19
+ const selectClass = dark
20
+ ? "rounded border border-white/10 bg-white/[0.04] px-1 py-0.5 text-xs text-white outline-none"
21
+ : "rounded border px-1 py-0.5 text-xs";
22
+ return (_jsxs("div", { className: "flex items-center gap-0.5", children: [_jsx("button", { onClick: zoomOut, disabled: zoom <= ZOOM_STEPS[0], className: btnClass, title: "Zoom out", children: "\u2212" }), _jsx("select", { value: zoom, onChange: (e) => onZoomChange(Number(e.target.value)), className: selectClass, children: ZOOM_STEPS.map((z) => (_jsxs("option", { value: z, children: [z, "%"] }, z))) }), _jsx("button", { onClick: zoomIn, disabled: zoom >= ZOOM_STEPS[ZOOM_STEPS.length - 1], className: btnClass, title: "Zoom in", children: "+" })] }));
23
+ }
24
+ return (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { onClick: zoomOut, disabled: zoom <= ZOOM_STEPS[0], className: "rounded border px-2 py-1 text-sm hover:bg-muted disabled:opacity-40", title: "Zoom out", children: "\u2212" }), _jsx("select", { value: zoom, onChange: (e) => onZoomChange(Number(e.target.value)), className: "rounded border px-1 py-1 text-sm", children: ZOOM_STEPS.map((z) => (_jsxs("option", { value: z, children: [z, "%"] }, z))) }), _jsx("button", { onClick: zoomIn, disabled: zoom >= ZOOM_STEPS[ZOOM_STEPS.length - 1], className: "rounded border px-2 py-1 text-sm hover:bg-muted disabled:opacity-40", title: "Zoom in", children: "+" })] }));
25
+ }
26
+ //# sourceMappingURL=ZoomControls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ZoomControls.js","sourceRoot":"","sources":["../../components/ZoomControls.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAWb,MAAM,UAAU,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAE9D,MAAM,UAAU,YAAY,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAqB;IACnF,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC9C,IAAI,IAAI;YAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,MAAM,IAAI,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC7D,IAAI,IAAI;YAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,QAAQ,GAAG,IAAI;YACnB,CAAC,CAAC,2FAA2F;YAC7F,CAAC,CAAC,wDAAwD,CAAC;QAC7D,MAAM,WAAW,GAAG,IAAI;YACtB,CAAC,CAAC,4FAA4F;YAC9F,CAAC,CAAC,oCAAoC,CAAC;QAEzC,OAAO,CACL,eAAK,SAAS,EAAC,2BAA2B,aACxC,iBAAQ,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,IAAI,UAAU,CAAC,CAAC,CAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAC,UAAU,uBAExF,EACT,iBAAQ,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,WAAW,YAC/F,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACrB,kBAAgB,KAAK,EAAE,CAAC,aACrB,CAAC,UADS,CAAC,CAEL,CACV,CAAC,GACK,EACT,iBAAQ,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAC,SAAS,kBAE1G,IACL,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAC,yBAAyB,aACtC,iBACE,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,IAAI,IAAI,UAAU,CAAC,CAAC,CAAE,EAChC,SAAS,EAAC,qEAAqE,EAC/E,KAAK,EAAC,UAAU,uBAGT,EACT,iBACE,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EACrD,SAAS,EAAC,kCAAkC,YAE3C,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACrB,kBAAgB,KAAK,EAAE,CAAC,aACrB,CAAC,UADS,CAAC,CAEL,CACV,CAAC,GACK,EACT,iBACE,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,IAAI,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAE,EACpD,SAAS,EAAC,qEAAqE,EAC/E,KAAK,EAAC,SAAS,kBAGR,IACL,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { LensPDFShellPlugin } from "./shellPlugins";
2
+ export declare function createDefaultShellPlugins(): LensPDFShellPlugin[];
3
+ //# sourceMappingURL=defaultShellPlugins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaultShellPlugins.d.ts","sourceRoot":"","sources":["../../components/defaultShellPlugins.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,kBAAkB,EAA6B,MAAM,gBAAgB,CAAC;AA6jBpF,wBAAgB,yBAAyB,IAAI,kBAAkB,EAAE,CAShE"}