@printwithsynergy/artwork-pdf-editor 0.1.6 → 0.3.0

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 (249) hide show
  1. package/LICENSE +62 -0
  2. package/README.md +63 -2
  3. package/dist/components/AccessibilityHintsPanel.d.ts +142 -0
  4. package/dist/components/AccessibilityHintsPanel.d.ts.map +1 -0
  5. package/dist/components/AccessibilityHintsPanel.js +158 -0
  6. package/dist/components/AccessibilityHintsPanel.js.map +1 -0
  7. package/dist/components/AnnotationOverlay.d.ts +142 -0
  8. package/dist/components/AnnotationOverlay.d.ts.map +1 -0
  9. package/dist/components/AnnotationOverlay.js +141 -0
  10. package/dist/components/AnnotationOverlay.js.map +1 -0
  11. package/dist/components/AnnotationsSidebar.d.ts +98 -0
  12. package/dist/components/AnnotationsSidebar.d.ts.map +1 -0
  13. package/dist/components/AnnotationsSidebar.js +100 -0
  14. package/dist/components/AnnotationsSidebar.js.map +1 -0
  15. package/dist/components/BarcodeGeneratorPanel.d.ts +58 -0
  16. package/dist/components/BarcodeGeneratorPanel.d.ts.map +1 -0
  17. package/dist/components/BarcodeGeneratorPanel.js +91 -0
  18. package/dist/components/BarcodeGeneratorPanel.js.map +1 -0
  19. package/dist/components/BraillePanel.d.ts +99 -0
  20. package/dist/components/BraillePanel.d.ts.map +1 -0
  21. package/dist/components/BraillePanel.js +221 -0
  22. package/dist/components/BraillePanel.js.map +1 -0
  23. package/dist/components/BrandAssetsPanel.d.ts +130 -0
  24. package/dist/components/BrandAssetsPanel.d.ts.map +1 -0
  25. package/dist/components/BrandAssetsPanel.js +125 -0
  26. package/dist/components/BrandAssetsPanel.js.map +1 -0
  27. package/dist/components/BrandConsistencyPanel.d.ts +140 -0
  28. package/dist/components/BrandConsistencyPanel.d.ts.map +1 -0
  29. package/dist/components/BrandConsistencyPanel.js +158 -0
  30. package/dist/components/BrandConsistencyPanel.js.map +1 -0
  31. package/dist/components/ComplianceFindingsPanel.d.ts +62 -0
  32. package/dist/components/ComplianceFindingsPanel.d.ts.map +1 -0
  33. package/dist/components/ComplianceFindingsPanel.js +118 -0
  34. package/dist/components/ComplianceFindingsPanel.js.map +1 -0
  35. package/dist/components/DesignSuggestionsPanel.d.ts +148 -0
  36. package/dist/components/DesignSuggestionsPanel.d.ts.map +1 -0
  37. package/dist/components/DesignSuggestionsPanel.js +154 -0
  38. package/dist/components/DesignSuggestionsPanel.js.map +1 -0
  39. package/dist/components/DielineParametersPanel.d.ts +62 -0
  40. package/dist/components/DielineParametersPanel.d.ts.map +1 -0
  41. package/dist/components/DielineParametersPanel.js +170 -0
  42. package/dist/components/DielineParametersPanel.js.map +1 -0
  43. package/dist/components/DielinePreview.d.ts +150 -0
  44. package/dist/components/DielinePreview.d.ts.map +1 -0
  45. package/dist/components/DielinePreview.js +146 -0
  46. package/dist/components/DielinePreview.js.map +1 -0
  47. package/dist/components/EditorApp.d.ts +39 -5
  48. package/dist/components/EditorApp.d.ts.map +1 -1
  49. package/dist/components/EditorApp.js +110 -5
  50. package/dist/components/EditorApp.js.map +1 -1
  51. package/dist/components/EditorCanvas.d.ts +51 -2
  52. package/dist/components/EditorCanvas.d.ts.map +1 -1
  53. package/dist/components/EditorCanvas.js +117 -48
  54. package/dist/components/EditorCanvas.js.map +1 -1
  55. package/dist/components/EmailNotifyPanel.d.ts +165 -0
  56. package/dist/components/EmailNotifyPanel.d.ts.map +1 -0
  57. package/dist/components/EmailNotifyPanel.js +211 -0
  58. package/dist/components/EmailNotifyPanel.js.map +1 -0
  59. package/dist/components/FileDropZone.d.ts +9 -1
  60. package/dist/components/FileDropZone.d.ts.map +1 -1
  61. package/dist/components/FileDropZone.js +53 -5
  62. package/dist/components/FileDropZone.js.map +1 -1
  63. package/dist/components/FoldEditorPanel.d.ts +68 -0
  64. package/dist/components/FoldEditorPanel.d.ts.map +1 -0
  65. package/dist/components/FoldEditorPanel.js +65 -0
  66. package/dist/components/FoldEditorPanel.js.map +1 -0
  67. package/dist/components/FoldPreviewOverlay.d.ts +48 -0
  68. package/dist/components/FoldPreviewOverlay.d.ts.map +1 -0
  69. package/dist/components/FoldPreviewOverlay.js +182 -0
  70. package/dist/components/FoldPreviewOverlay.js.map +1 -0
  71. package/dist/components/Gs1DigitalLinkPanel.d.ts +103 -0
  72. package/dist/components/Gs1DigitalLinkPanel.d.ts.map +1 -0
  73. package/dist/components/Gs1DigitalLinkPanel.js +199 -0
  74. package/dist/components/Gs1DigitalLinkPanel.js.map +1 -0
  75. package/dist/components/HistoryPanel.d.ts +39 -0
  76. package/dist/components/HistoryPanel.d.ts.map +1 -0
  77. package/dist/components/HistoryPanel.js +72 -0
  78. package/dist/components/HistoryPanel.js.map +1 -0
  79. package/dist/components/IccSoftProofOverlay.d.ts +67 -0
  80. package/dist/components/IccSoftProofOverlay.d.ts.map +1 -0
  81. package/dist/components/IccSoftProofOverlay.js +119 -0
  82. package/dist/components/IccSoftProofOverlay.js.map +1 -0
  83. package/dist/components/ImposePanel.d.ts +71 -0
  84. package/dist/components/ImposePanel.d.ts.map +1 -0
  85. package/dist/components/ImposePanel.js +127 -0
  86. package/dist/components/ImposePanel.js.map +1 -0
  87. package/dist/components/InksPanel.d.ts +61 -0
  88. package/dist/components/InksPanel.d.ts.map +1 -0
  89. package/dist/components/InksPanel.js +84 -0
  90. package/dist/components/InksPanel.js.map +1 -0
  91. package/dist/components/JobSetupPanel.d.ts +118 -0
  92. package/dist/components/JobSetupPanel.d.ts.map +1 -0
  93. package/dist/components/JobSetupPanel.js +169 -0
  94. package/dist/components/JobSetupPanel.js.map +1 -0
  95. package/dist/components/LayersPanel.d.ts.map +1 -1
  96. package/dist/components/LayersPanel.js +1 -0
  97. package/dist/components/LayersPanel.js.map +1 -1
  98. package/dist/components/MarkLibraryPanel.d.ts +131 -0
  99. package/dist/components/MarkLibraryPanel.d.ts.map +1 -0
  100. package/dist/components/MarkLibraryPanel.js +184 -0
  101. package/dist/components/MarkLibraryPanel.js.map +1 -0
  102. package/dist/components/MisEstimateButton.d.ts +73 -0
  103. package/dist/components/MisEstimateButton.d.ts.map +1 -0
  104. package/dist/components/MisEstimateButton.js +57 -0
  105. package/dist/components/MisEstimateButton.js.map +1 -0
  106. package/dist/components/NutritionPanel.d.ts +118 -0
  107. package/dist/components/NutritionPanel.d.ts.map +1 -0
  108. package/dist/components/NutritionPanel.js +169 -0
  109. package/dist/components/NutritionPanel.js.map +1 -0
  110. package/dist/components/PageNavigator.d.ts +26 -0
  111. package/dist/components/PageNavigator.d.ts.map +1 -0
  112. package/dist/components/PageNavigator.js +96 -0
  113. package/dist/components/PageNavigator.js.map +1 -0
  114. package/dist/components/PaletteManager.d.ts +32 -0
  115. package/dist/components/PaletteManager.d.ts.map +1 -0
  116. package/dist/components/PaletteManager.js +89 -0
  117. package/dist/components/PaletteManager.js.map +1 -0
  118. package/dist/components/PaletteToSpotPanel.d.ts +122 -0
  119. package/dist/components/PaletteToSpotPanel.d.ts.map +1 -0
  120. package/dist/components/PaletteToSpotPanel.js +160 -0
  121. package/dist/components/PaletteToSpotPanel.js.map +1 -0
  122. package/dist/components/PreflightAutoFixPanel.d.ts +110 -0
  123. package/dist/components/PreflightAutoFixPanel.d.ts.map +1 -0
  124. package/dist/components/PreflightAutoFixPanel.js +119 -0
  125. package/dist/components/PreflightAutoFixPanel.js.map +1 -0
  126. package/dist/components/PreflightDiffPanel.d.ts +127 -0
  127. package/dist/components/PreflightDiffPanel.d.ts.map +1 -0
  128. package/dist/components/PreflightDiffPanel.js +0 -0
  129. package/dist/components/PreflightDiffPanel.js.map +1 -0
  130. package/dist/components/ProcessRulesPanel.d.ts +81 -0
  131. package/dist/components/ProcessRulesPanel.d.ts.map +1 -0
  132. package/dist/components/ProcessRulesPanel.js +143 -0
  133. package/dist/components/ProcessRulesPanel.js.map +1 -0
  134. package/dist/components/SlackNotifyPanel.d.ts +139 -0
  135. package/dist/components/SlackNotifyPanel.d.ts.map +1 -0
  136. package/dist/components/SlackNotifyPanel.js +133 -0
  137. package/dist/components/SlackNotifyPanel.js.map +1 -0
  138. package/dist/components/SmartSpotMatchPanel.d.ts +143 -0
  139. package/dist/components/SmartSpotMatchPanel.d.ts.map +1 -0
  140. package/dist/components/SmartSpotMatchPanel.js +159 -0
  141. package/dist/components/SmartSpotMatchPanel.js.map +1 -0
  142. package/dist/components/SwatchesPicker.d.ts +83 -0
  143. package/dist/components/SwatchesPicker.d.ts.map +1 -0
  144. package/dist/components/SwatchesPicker.js +151 -0
  145. package/dist/components/SwatchesPicker.js.map +1 -0
  146. package/dist/components/TacOverlay.d.ts +47 -0
  147. package/dist/components/TacOverlay.d.ts.map +1 -0
  148. package/dist/components/TacOverlay.js +116 -0
  149. package/dist/components/TacOverlay.js.map +1 -0
  150. package/dist/components/TrapEditorPanel.d.ts +52 -0
  151. package/dist/components/TrapEditorPanel.d.ts.map +1 -0
  152. package/dist/components/TrapEditorPanel.js +64 -0
  153. package/dist/components/TrapEditorPanel.js.map +1 -0
  154. package/dist/components/TrapPreviewOverlay.d.ts +64 -0
  155. package/dist/components/TrapPreviewOverlay.d.ts.map +1 -0
  156. package/dist/components/TrapPreviewOverlay.js +120 -0
  157. package/dist/components/TrapPreviewOverlay.js.map +1 -0
  158. package/dist/components/VariantMatrixPanel.d.ts +61 -0
  159. package/dist/components/VariantMatrixPanel.d.ts.map +1 -0
  160. package/dist/components/VariantMatrixPanel.js +97 -0
  161. package/dist/components/VariantMatrixPanel.js.map +1 -0
  162. package/dist/components/VariantMatrixVersionPanel.d.ts +122 -0
  163. package/dist/components/VariantMatrixVersionPanel.d.ts.map +1 -0
  164. package/dist/components/VariantMatrixVersionPanel.js +162 -0
  165. package/dist/components/VariantMatrixVersionPanel.js.map +1 -0
  166. package/dist/components/WebhookNotifyPanel.d.ts +160 -0
  167. package/dist/components/WebhookNotifyPanel.d.ts.map +1 -0
  168. package/dist/components/WebhookNotifyPanel.js +100 -0
  169. package/dist/components/WebhookNotifyPanel.js.map +1 -0
  170. package/dist/components/WhiteUnderbasePanel.d.ts +107 -0
  171. package/dist/components/WhiteUnderbasePanel.d.ts.map +1 -0
  172. package/dist/components/WhiteUnderbasePanel.js +104 -0
  173. package/dist/components/WhiteUnderbasePanel.js.map +1 -0
  174. package/dist/data/dielines.json +35 -0
  175. package/dist/hooks/useEditorMode.d.ts +25 -5
  176. package/dist/hooks/useEditorMode.d.ts.map +1 -1
  177. package/dist/hooks/useEditorMode.js +18 -5
  178. package/dist/hooks/useEditorMode.js.map +1 -1
  179. package/dist/index.d.ts +49 -2
  180. package/dist/index.d.ts.map +1 -1
  181. package/dist/index.js +49 -2
  182. package/dist/index.js.map +1 -1
  183. package/dist/lens/dieline-overlay.d.ts +25 -0
  184. package/dist/lens/dieline-overlay.d.ts.map +1 -0
  185. package/dist/lens/dieline-overlay.js +50 -0
  186. package/dist/lens/dieline-overlay.js.map +1 -0
  187. package/dist/lens/index.d.ts +27 -0
  188. package/dist/lens/index.d.ts.map +1 -0
  189. package/dist/lens/index.js +28 -0
  190. package/dist/lens/index.js.map +1 -0
  191. package/dist/lens/preflight-findings.d.ts +21 -0
  192. package/dist/lens/preflight-findings.d.ts.map +1 -0
  193. package/dist/lens/preflight-findings.js +82 -0
  194. package/dist/lens/preflight-findings.js.map +1 -0
  195. package/dist/lib/barcode-scan.d.ts +154 -0
  196. package/dist/lib/barcode-scan.d.ts.map +1 -0
  197. package/dist/lib/barcode-scan.js +152 -0
  198. package/dist/lib/barcode-scan.js.map +1 -0
  199. package/dist/lib/color-math.d.ts +76 -0
  200. package/dist/lib/color-math.d.ts.map +1 -0
  201. package/dist/lib/color-math.js +96 -0
  202. package/dist/lib/color-math.js.map +1 -0
  203. package/dist/lib/dieline-template.d.ts +169 -0
  204. package/dist/lib/dieline-template.d.ts.map +1 -1
  205. package/dist/lib/dieline-template.js +229 -1
  206. package/dist/lib/dieline-template.js.map +1 -1
  207. package/dist/lib/editor-config.d.ts +384 -1
  208. package/dist/lib/editor-config.d.ts.map +1 -1
  209. package/dist/lib/editor-config.js +89 -2
  210. package/dist/lib/editor-config.js.map +1 -1
  211. package/dist/lib/fold-geometry.d.ts +144 -0
  212. package/dist/lib/fold-geometry.d.ts.map +1 -0
  213. package/dist/lib/fold-geometry.js +138 -0
  214. package/dist/lib/fold-geometry.js.map +1 -0
  215. package/dist/lib/merge-tokens.d.ts +81 -0
  216. package/dist/lib/merge-tokens.d.ts.map +1 -0
  217. package/dist/lib/merge-tokens.js +88 -0
  218. package/dist/lib/merge-tokens.js.map +1 -0
  219. package/dist/lib/palette-registry.d.ts +40 -0
  220. package/dist/lib/palette-registry.d.ts.map +1 -0
  221. package/dist/lib/palette-registry.js +49 -0
  222. package/dist/lib/palette-registry.js.map +1 -0
  223. package/dist/lib/panel-anchor.d.ts +101 -0
  224. package/dist/lib/panel-anchor.d.ts.map +1 -0
  225. package/dist/lib/panel-anchor.js +68 -0
  226. package/dist/lib/panel-anchor.js.map +1 -0
  227. package/dist/lib/preflight/checks.d.ts.map +1 -1
  228. package/dist/lib/preflight/checks.js +71 -0
  229. package/dist/lib/preflight/checks.js.map +1 -1
  230. package/dist/lib/preflight/types.d.ts.map +1 -1
  231. package/dist/lib/preflight/types.js +11 -0
  232. package/dist/lib/preflight/types.js.map +1 -1
  233. package/dist/lib/rasterize.d.ts +93 -0
  234. package/dist/lib/rasterize.d.ts.map +1 -0
  235. package/dist/lib/rasterize.js +117 -0
  236. package/dist/lib/rasterize.js.map +1 -0
  237. package/dist/lib/separations-registry.d.ts +99 -0
  238. package/dist/lib/separations-registry.d.ts.map +1 -0
  239. package/dist/lib/separations-registry.js +59 -0
  240. package/dist/lib/separations-registry.js.map +1 -0
  241. package/dist/lib/unwired.d.ts +29 -0
  242. package/dist/lib/unwired.d.ts.map +1 -0
  243. package/dist/lib/unwired.js +58 -0
  244. package/dist/lib/unwired.js.map +1 -0
  245. package/package.json +29 -11
  246. package/dist/components/SeparationsPanel.d.ts +0 -9
  247. package/dist/components/SeparationsPanel.d.ts.map +0 -1
  248. package/dist/components/SeparationsPanel.js +0 -168
  249. package/dist/components/SeparationsPanel.js.map +0 -1
@@ -0,0 +1,83 @@
1
+ /**
2
+ * One PANTONE catalogue entry from compile-pdf's `/v1/spots/*`
3
+ * endpoints. Mirrors `SpotEntry` on the apps/service
4
+ * `CompilePdfClient`, kept structural here so editor-app stays
5
+ * apps/service-dep-free.
6
+ *
7
+ * @public
8
+ */
9
+ export type Spot = {
10
+ name: string;
11
+ library?: string | null;
12
+ lab?: [number, number, number] | null;
13
+ cmyk_bridge?: [number, number, number, number] | null;
14
+ };
15
+ /**
16
+ * Search adapter — the editor passes in a function that fronts
17
+ * `CompilePdfClient.spotSearch()`. Threading the search via a prop
18
+ * (rather than calling fetch directly) keeps SwatchesPicker
19
+ * decoupled from the network — tests pass a stub, the demo can
20
+ * preload an in-memory fixture, etc.
21
+ *
22
+ * @public
23
+ */
24
+ export type SpotSearchFn = (opts: {
25
+ q?: string;
26
+ library?: string;
27
+ limit?: number;
28
+ }) => Promise<{
29
+ results: Spot[];
30
+ total: number;
31
+ limit: number;
32
+ }>;
33
+ /**
34
+ * Library descriptor — matches the wire shape of one entry in
35
+ * `/v1/spots/libraries`.
36
+ *
37
+ * @public
38
+ */
39
+ export type SpotLibrary = {
40
+ id: string;
41
+ count: number;
42
+ };
43
+ /**
44
+ * Props for the C3 SwatchesPicker palette.
45
+ *
46
+ * `search` is the only required prop; library filter + initial
47
+ * query are optional. `onSelect` fires when the user clicks a
48
+ * swatch — typically wired to AI4's `registerSpot` in the host.
49
+ *
50
+ * `enable_palettes: false` collapses the entire palette system off;
51
+ * hosts mount this component only when `isPanelVisible(config,
52
+ * "swatches")` returns true.
53
+ *
54
+ * @public
55
+ */
56
+ export type SwatchesPickerProps = {
57
+ search: SpotSearchFn;
58
+ /** Initial libraries-filter dropdown values. Hosts that already
59
+ * fetched `spotLibraries()` thread the result here. */
60
+ libraries?: SpotLibrary[];
61
+ /** Optional initial query. */
62
+ initialQuery?: string;
63
+ /** Click callback. Receives the full Spot row. */
64
+ onSelect: (spot: Spot) => void;
65
+ };
66
+ /**
67
+ * Right-rail palette for browsing compile-pdf's PANTONE catalogue
68
+ * (codex-pdf's public-domain reference set).
69
+ *
70
+ * UX:
71
+ * - Search input → debounced (250 ms) call to `search()`.
72
+ * - Optional library dropdown (when `libraries` is supplied).
73
+ * - Result list as colored chips with the canonical name; click
74
+ * fires `onSelect`.
75
+ * - Footer disclaimer ("public-domain reference, not licensed
76
+ * PANTONE data") — present per the trademark stance.
77
+ *
78
+ * @returns An `<aside>` element with search input, library filter,
79
+ * results list, and the trademark disclaimer footer.
80
+ * @public
81
+ */
82
+ export declare function SwatchesPicker({ search, libraries, initialQuery, onSelect, }: SwatchesPickerProps): import("react/jsx-runtime").JSX.Element;
83
+ //# sourceMappingURL=SwatchesPicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwatchesPicker.d.ts","sourceRoot":"","sources":["../../src/components/SwatchesPicker.tsx"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,MAAM,MAAM,IAAI,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACtC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CACvD,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE;IAChC,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,KAAK,OAAO,CAAC;IAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,YAAY,CAAC;IACrB;4DACwD;IACxD,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;IAC1B,8BAA8B;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CAChC,CAAC;AAoBF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,SAAS,EACT,YAAiB,EACjB,QAAQ,GACT,EAAE,mBAAmB,2CAuKrB"}
@@ -0,0 +1,151 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ "use client";
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ import { useEffect, useRef, useState } from "react";
5
+ const PANEL_BG = "#1a0f08";
6
+ const BORDER = "#3d1a00";
7
+ const BRAND = "#fc5102";
8
+ const TEXT = "#f4ece6";
9
+ const MUTED = "#888";
10
+ const DEBOUNCE_MS = 250;
11
+ const inputStyle = {
12
+ flex: 1,
13
+ padding: "0.4rem 0.6rem",
14
+ background: "#0f0a05",
15
+ border: `1px solid ${BORDER}`,
16
+ borderRadius: 4,
17
+ color: TEXT,
18
+ fontSize: "0.8rem",
19
+ fontFamily: "inherit",
20
+ };
21
+ /**
22
+ * Right-rail palette for browsing compile-pdf's PANTONE catalogue
23
+ * (codex-pdf's public-domain reference set).
24
+ *
25
+ * UX:
26
+ * - Search input → debounced (250 ms) call to `search()`.
27
+ * - Optional library dropdown (when `libraries` is supplied).
28
+ * - Result list as colored chips with the canonical name; click
29
+ * fires `onSelect`.
30
+ * - Footer disclaimer ("public-domain reference, not licensed
31
+ * PANTONE data") — present per the trademark stance.
32
+ *
33
+ * @returns An `<aside>` element with search input, library filter,
34
+ * results list, and the trademark disclaimer footer.
35
+ * @public
36
+ */
37
+ export function SwatchesPicker({ search, libraries, initialQuery = "", onSelect, }) {
38
+ const [query, setQuery] = useState(initialQuery);
39
+ const [library, setLibrary] = useState("");
40
+ const [results, setResults] = useState([]);
41
+ const [loading, setLoading] = useState(false);
42
+ const [error, setError] = useState(null);
43
+ const reqIdRef = useRef(0);
44
+ useEffect(() => {
45
+ // Debounce — bump the request id and only commit results from
46
+ // the latest call. Prevents stale results overriding fresh ones
47
+ // when the user types quickly.
48
+ const id = ++reqIdRef.current;
49
+ const handle = setTimeout(() => {
50
+ setLoading(true);
51
+ setError(null);
52
+ const opts = { limit: 50 };
53
+ if (query)
54
+ opts.q = query;
55
+ if (library)
56
+ opts.library = library;
57
+ search(opts)
58
+ .then((res) => {
59
+ if (id !== reqIdRef.current)
60
+ return; // stale
61
+ setResults(res.results);
62
+ setLoading(false);
63
+ })
64
+ .catch((err) => {
65
+ if (id !== reqIdRef.current)
66
+ return;
67
+ const msg = err instanceof Error ? err.message : "spots search failed";
68
+ setError(msg);
69
+ setLoading(false);
70
+ });
71
+ }, DEBOUNCE_MS);
72
+ return () => clearTimeout(handle);
73
+ }, [query, library, search]);
74
+ return (_jsxs("aside", { style: {
75
+ width: 240,
76
+ background: PANEL_BG,
77
+ borderLeft: `1px solid ${BORDER}`,
78
+ color: TEXT,
79
+ display: "flex",
80
+ flexDirection: "column",
81
+ overflow: "hidden",
82
+ flexShrink: 0,
83
+ }, children: [_jsx("div", { style: {
84
+ fontSize: "0.7rem",
85
+ letterSpacing: "0.08em",
86
+ textTransform: "uppercase",
87
+ color: MUTED,
88
+ padding: "0.55rem 0.85rem",
89
+ borderBottom: `1px solid ${BORDER}`,
90
+ }, children: "Swatches" }), _jsx("div", { style: { padding: "0.55rem 0.65rem", display: "flex", gap: "0.4rem" }, children: _jsx("input", { value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Search PANTONE\u2026", "aria-label": "Search PANTONE catalogue", style: inputStyle }) }), libraries && libraries.length > 0 && (_jsx("div", { style: { padding: "0 0.65rem 0.55rem" }, children: _jsxs("select", { value: library, onChange: (e) => setLibrary(e.target.value), "aria-label": "Filter by library", style: { ...inputStyle, width: "100%" }, children: [_jsx("option", { value: "", children: "All libraries" }), libraries.map((lib) => (_jsxs("option", { value: lib.id, children: [lib.id, " (", lib.count, ")"] }, lib.id)))] }) })), _jsxs("div", { style: { flex: 1, overflow: "auto" }, children: [loading && (_jsx("div", { style: { padding: "0.55rem 0.85rem", color: MUTED, fontSize: "0.78rem" }, children: "Loading\u2026" })), error && !loading && (_jsx("div", { role: "alert", style: { padding: "0.55rem 0.85rem", color: "#ef4444", fontSize: "0.78rem" }, children: error })), !loading && !error && results.length === 0 && (_jsx("div", { style: { padding: "0.55rem 0.85rem", color: MUTED, fontSize: "0.78rem" }, children: "No matches." })), !loading &&
91
+ !error &&
92
+ results.map((spot) => {
93
+ const swatchColor = labToCssApprox(spot.lab) ?? "#666";
94
+ return (_jsxs("button", { type: "button", onClick: () => onSelect(spot), style: {
95
+ display: "flex",
96
+ alignItems: "center",
97
+ gap: "0.55rem",
98
+ width: "100%",
99
+ padding: "0.35rem 0.85rem",
100
+ background: "transparent",
101
+ border: "none",
102
+ borderLeft: "2px solid transparent",
103
+ cursor: "pointer",
104
+ color: TEXT,
105
+ fontSize: "0.78rem",
106
+ fontFamily: "inherit",
107
+ textAlign: "left",
108
+ }, onMouseEnter: (e) => {
109
+ e.currentTarget.style.borderLeftColor = BRAND;
110
+ }, onMouseLeave: (e) => {
111
+ e.currentTarget.style.borderLeftColor = "transparent";
112
+ }, children: [_jsx("span", { style: {
113
+ display: "inline-block",
114
+ width: 16,
115
+ height: 16,
116
+ borderRadius: 3,
117
+ background: swatchColor,
118
+ border: `1px solid ${BORDER}`,
119
+ flexShrink: 0,
120
+ } }), _jsx("span", { style: { overflow: "hidden", textOverflow: "ellipsis" }, children: spot.name })] }, spot.name));
121
+ })] }), _jsx("div", { style: {
122
+ padding: "0.45rem 0.85rem",
123
+ borderTop: `1px solid ${BORDER}`,
124
+ color: MUTED,
125
+ fontSize: "0.65rem",
126
+ lineHeight: 1.35,
127
+ }, children: "Public-domain colour-science reference. Not licensed PANTONE data." })] }));
128
+ }
129
+ /**
130
+ * Crude Lab → CSS-color approximation for the swatch chips. Not a
131
+ * colorimetric conversion — just enough to give each row a
132
+ * recognizable tint in the picker. Returns `undefined` for entries
133
+ * without a Lab triplet (the chip falls back to a neutral grey).
134
+ *
135
+ * Lab L is 0-100 (perceptual lightness); we map directly to sRGB
136
+ * grey then shift slightly toward a/b axes. Future: replace with a
137
+ * proper Lab→sRGB conversion via culori or chroma-js if perceptual
138
+ * accuracy matters for the picker.
139
+ */
140
+ function labToCssApprox(lab) {
141
+ if (!lab)
142
+ return undefined;
143
+ const [L, a, b] = lab;
144
+ // Very rough — clamps to a tinted grey based on a/b sign.
145
+ const lum = Math.max(0, Math.min(255, Math.round((L / 100) * 255)));
146
+ const r = Math.max(0, Math.min(255, lum + Math.round(a * 1.5)));
147
+ const g = Math.max(0, Math.min(255, lum - Math.round(Math.abs(a) * 0.5)));
148
+ const bl = Math.max(0, Math.min(255, lum - Math.round(b * 1.5)));
149
+ return `rgb(${r}, ${g}, ${bl})`;
150
+ }
151
+ //# sourceMappingURL=SwatchesPicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwatchesPicker.js","sourceRoot":"","sources":["../../src/components/SwatchesPicker.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type Konva from "konva";
2
+ /**
3
+ * C4 live total-area-coverage overlay.
4
+ *
5
+ * Sits as an absolutely-positioned `<canvas>` on top of the Konva
6
+ * Stage, debouncing a rasterize-and-sample pass on every change to
7
+ * the watched objects array. Paints pixels whose TAC exceeds the
8
+ * configured threshold (default 300%) in translucent red — a "where
9
+ * the ink is going to pool" hint — and shows a `max / avg` chip in
10
+ * the bottom-left.
11
+ *
12
+ * Browser-side sanity check, not a colorimetric proof: the same
13
+ * caveats as {@link import("../lib/rasterize").sampleTACFromImageData}
14
+ * apply (subtractive sRGB → CMYK with K-extraction, alpha composited
15
+ * onto an opaque white background). Production TAC enforcement lives
16
+ * server-side in compile-pdf's `total_ink_coverage` preflight rule.
17
+ *
18
+ * @public
19
+ */
20
+ export type TacOverlayProps = {
21
+ /** Live Konva Stage. The overlay no-ops while this is `null` (the
22
+ * ref starts null on first render). */
23
+ stage: Konva.Stage | null;
24
+ /** Container width/height in CSS pixels — the overlay canvas
25
+ * matches these so it lines up with the Stage. */
26
+ width: number;
27
+ height: number;
28
+ /** Re-sample trigger. Any change to this value (by reference for
29
+ * arrays, by equality for primitives) debounces a new rasterize
30
+ * pass. The value itself isn't read — it just lets React's effect
31
+ * diffing detect editor changes. Pass `objects` (the canvas
32
+ * contents array) so every commit re-samples. */
33
+ trigger: unknown;
34
+ /** TAC threshold in percent (0-400). Pixels at or above the
35
+ * threshold are painted; pixels below are transparent. Defaults to
36
+ * 300% — the standard coated-stock preflight ceiling. */
37
+ thresholdPct?: number;
38
+ /** Debounce window in milliseconds before a new sample fires.
39
+ * Defaults to 250 ms — fast enough to feel live, slow enough that
40
+ * click-drag operations don't thrash the rasterizer. */
41
+ debounceMs?: number;
42
+ };
43
+ /**
44
+ * @public
45
+ */
46
+ export declare function TacOverlay({ stage, width, height, trigger, thresholdPct, debounceMs, }: TacOverlayProps): import("react/jsx-runtime").JSX.Element;
47
+ //# sourceMappingURL=TacOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TacOverlay.d.ts","sourceRoot":"","sources":["../../src/components/TacOverlay.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;4CACwC;IACxC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;IAC1B;uDACmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;;;;sDAIkD;IAClD,OAAO,EAAE,OAAO,CAAC;IACjB;;8DAE0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;6DAEyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;GAEG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,MAAM,EACN,OAAO,EACP,YAAkB,EAClB,UAAgB,GACjB,EAAE,eAAe,2CA0HjB"}
@@ -0,0 +1,116 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ "use client";
3
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
4
+ import { useEffect, useRef, useState } from "react";
5
+ import { rasterizeStage } from "../lib/rasterize";
6
+ /**
7
+ * @public
8
+ */
9
+ export function TacOverlay({ stage, width, height, trigger, thresholdPct = 300, debounceMs = 250, }) {
10
+ const canvasRef = useRef(null);
11
+ const [readout, setReadout] = useState(null);
12
+ useEffect(() => {
13
+ // `trigger` is intentionally read here (no-op `void` cast) so the
14
+ // exhaustive-deps lint sees it as used; the actual value is never
15
+ // consumed — only its identity change is meaningful.
16
+ void trigger;
17
+ if (!stage || width <= 0 || height <= 0) {
18
+ setReadout(null);
19
+ return;
20
+ }
21
+ const handle = setTimeout(() => {
22
+ let image;
23
+ try {
24
+ image = rasterizeStage(stage);
25
+ }
26
+ catch {
27
+ // Stage's 2d context occasionally fails to acquire during
28
+ // teardown (unmount race); silently skip — next change will
29
+ // try again.
30
+ return;
31
+ }
32
+ const canvas = canvasRef.current;
33
+ if (!canvas)
34
+ return;
35
+ // Match the source image so writes are 1:1 — the canvas CSS
36
+ // size is what scales it back to the displayed Stage area.
37
+ canvas.width = image.width;
38
+ canvas.height = image.height;
39
+ const ctx = canvas.getContext("2d");
40
+ if (!ctx)
41
+ return;
42
+ // One fused pass: sample TAC per pixel inline AND paint the
43
+ // overlay where TAC crosses the threshold. We can't reuse the
44
+ // shared sampler's `perPixelPct` for the threshold check
45
+ // because that array clamps the 0-400 % range to a byte
46
+ // (255 = ≥255 %), which collapses every pixel above the
47
+ // default 300 % threshold to a single bucket; honest threshold
48
+ // checks need the un-truncated percentage here.
49
+ const src = image.data;
50
+ const overlay = ctx.createImageData(image.width, image.height);
51
+ const dst = overlay.data;
52
+ const pixelCount = image.width * image.height;
53
+ let maxPct = 0;
54
+ let sumPct = 0;
55
+ for (let p = 0, i = 0; p < src.length; p += 4, i++) {
56
+ // Pre-multiply with opaque white background so semi-
57
+ // transparent pixels reflect printable ink. Mirrors the
58
+ // canonical sampler's composite step.
59
+ const a = (src[p + 3] ?? 255) / 255;
60
+ const inv = 1 - a;
61
+ const r = ((src[p] ?? 0) * a + 255 * inv) / 255;
62
+ const g = ((src[p + 1] ?? 0) * a + 255 * inv) / 255;
63
+ const b = ((src[p + 2] ?? 0) * a + 255 * inv) / 255;
64
+ const k = 1 - Math.max(r, g, b);
65
+ let c = 0;
66
+ let m = 0;
67
+ let y = 0;
68
+ if (k < 1) {
69
+ const scale = 1 - k;
70
+ c = (1 - r - k) / scale;
71
+ m = (1 - g - k) / scale;
72
+ y = (1 - b - k) / scale;
73
+ }
74
+ const tac = (c + m + y + k) * 100;
75
+ if (tac > maxPct)
76
+ maxPct = tac;
77
+ sumPct += tac;
78
+ if (tac >= thresholdPct) {
79
+ const j = i * 4;
80
+ dst[j] = 220; // R
81
+ dst[j + 1] = 38; // G
82
+ dst[j + 2] = 38; // B
83
+ // Alpha scales linearly from 64 at threshold to 192 at
84
+ // (threshold + 100 %), so a 305 % pixel barely glows but
85
+ // a 400 % pixel screams. Clamped to keep the red readable
86
+ // over busy artwork.
87
+ const intensity = Math.min(192, 64 + (tac - thresholdPct) * 1.28);
88
+ dst[j + 3] = intensity;
89
+ }
90
+ }
91
+ ctx.putImageData(overlay, 0, 0);
92
+ setReadout({ maxPct, avgPct: pixelCount > 0 ? sumPct / pixelCount : 0 });
93
+ }, debounceMs);
94
+ return () => clearTimeout(handle);
95
+ }, [stage, width, height, trigger, thresholdPct, debounceMs]);
96
+ return (_jsxs(_Fragment, { children: [_jsx("canvas", { ref: canvasRef, style: {
97
+ position: "absolute",
98
+ inset: 0,
99
+ width: `${width}px`,
100
+ height: `${height}px`,
101
+ pointerEvents: "none",
102
+ } }), readout !== null && (_jsxs("output", { "aria-label": "Total area coverage", style: {
103
+ position: "absolute",
104
+ bottom: 8,
105
+ left: 8,
106
+ padding: "0.25rem 0.5rem",
107
+ background: "rgba(15, 23, 42, 0.78)",
108
+ color: "#f8fafc",
109
+ fontSize: "0.7rem",
110
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
111
+ borderRadius: 4,
112
+ pointerEvents: "none",
113
+ lineHeight: 1.3,
114
+ }, children: [_jsxs("div", { children: ["TAC max ", readout.maxPct.toFixed(0), "%"] }), _jsxs("div", { style: { opacity: 0.75 }, children: ["avg ", readout.avgPct.toFixed(0), "%"] })] }))] }));
115
+ }
116
+ //# sourceMappingURL=TacOverlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TacOverlay.js","sourceRoot":"","sources":["../../src/components/TacOverlay.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Controlled trap-policy shape consumed by the editor. Mirrors
3
+ * `@artworkpdf/document-model`'s `TrapPolicy` minus the runtime dep
4
+ * (the published editor package can't pull in document-model). Keep
5
+ * these in sync; the future structural-dedup follow-up will move both
6
+ * into a shared types module.
7
+ *
8
+ * @public
9
+ */
10
+ export type TrapEditorValue = {
11
+ widthMm: number;
12
+ mode?: "auto" | "spread" | "choke";
13
+ };
14
+ /**
15
+ * @public
16
+ */
17
+ export type TrapEditorPanelProps = {
18
+ /** Current policy. `undefined` means "no trap policy set" — the
19
+ * panel renders empty defaults the user can fill in. */
20
+ value: TrapEditorValue | undefined;
21
+ /** Fires on every committed change (slider release, select change).
22
+ * Hosts wire this to `document.pages[activeIdx].trapConfig` so the
23
+ * D1 preview overlay (PR-12) updates live as the user adjusts. */
24
+ onChange: (next: TrapEditorValue) => void;
25
+ /** Min width in mm. Defaults to 0 (no trap). */
26
+ minMm?: number;
27
+ /** Max width in mm. Defaults to 1.0 — typical maximum for press
28
+ * trapping. Hosts can raise for specialty work. */
29
+ maxMm?: number;
30
+ /** Step in mm. Defaults to 0.01 mm (one hundredth-millimeter) so
31
+ * fine-grain edits feel natural. */
32
+ stepMm?: number;
33
+ };
34
+ /**
35
+ * D2 interactive trap-policy editor.
36
+ *
37
+ * Controlled component: takes the current `TrapEditorValue` and emits
38
+ * the next one on every committed change. Surfaces the two fields the
39
+ * Wave 1 `TrapPolicy` shape supports today — `widthMm` (0–1 mm) and
40
+ * `mode` (`auto` / `spread` / `choke`). Per-edge (top/right/bottom/
41
+ * left) and per-color-pair tables are wired in a follow-up once the
42
+ * compile-pdf trap producer exposes them; the panel layout reserves
43
+ * space for those without committing to their final shape.
44
+ *
45
+ * Renders no chrome of its own — hosts wrap it in whatever modal /
46
+ * drawer / right-rail container fits their layout (matches
47
+ * `JobSetupPanel`'s embedding convention).
48
+ *
49
+ * @public
50
+ */
51
+ export declare function TrapEditorPanel({ value, onChange, minMm, maxMm, stepMm, }: TrapEditorPanelProps): import("react/jsx-runtime").JSX.Element;
52
+ //# sourceMappingURL=TrapEditorPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TrapEditorPanel.d.ts","sourceRoot":"","sources":["../../src/components/TrapEditorPanel.tsx"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;6DACyD;IACzD,KAAK,EAAE,eAAe,GAAG,SAAS,CAAC;IACnC;;uEAEmE;IACnE,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IAC1C,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;wDACoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;yCACqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,KAAS,EACT,KAAS,EACT,MAAa,GACd,EAAE,oBAAoB,2CA0FtB"}
@@ -0,0 +1,64 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ "use client";
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ import { useId } from "react";
5
+ /**
6
+ * D2 interactive trap-policy editor.
7
+ *
8
+ * Controlled component: takes the current `TrapEditorValue` and emits
9
+ * the next one on every committed change. Surfaces the two fields the
10
+ * Wave 1 `TrapPolicy` shape supports today — `widthMm` (0–1 mm) and
11
+ * `mode` (`auto` / `spread` / `choke`). Per-edge (top/right/bottom/
12
+ * left) and per-color-pair tables are wired in a follow-up once the
13
+ * compile-pdf trap producer exposes them; the panel layout reserves
14
+ * space for those without committing to their final shape.
15
+ *
16
+ * Renders no chrome of its own — hosts wrap it in whatever modal /
17
+ * drawer / right-rail container fits their layout (matches
18
+ * `JobSetupPanel`'s embedding convention).
19
+ *
20
+ * @public
21
+ */
22
+ export function TrapEditorPanel({ value, onChange, minMm = 0, maxMm = 1, stepMm = 0.01, }) {
23
+ const widthId = useId();
24
+ const modeId = useId();
25
+ const current = value ?? { widthMm: 0.144, mode: "auto" };
26
+ const updateWidth = (next) => {
27
+ // Clamp to the configured range so a stray pointer-up at the
28
+ // slider edges doesn't propagate an out-of-range value.
29
+ const clamped = Math.max(minMm, Math.min(maxMm, next));
30
+ onChange({ ...current, widthMm: clamped });
31
+ };
32
+ const updateMode = (next) => {
33
+ onChange({ ...current, mode: next });
34
+ };
35
+ return (_jsxs("div", { style: {
36
+ display: "flex",
37
+ flexDirection: "column",
38
+ gap: "0.75rem",
39
+ padding: "0.75rem",
40
+ fontSize: "0.85rem",
41
+ color: "#1f2937",
42
+ background: "#ffffff",
43
+ border: "1px solid #e5e7eb",
44
+ borderRadius: 6,
45
+ minWidth: 240,
46
+ }, children: [_jsxs("label", { htmlFor: widthId, style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [_jsx("span", { style: { fontWeight: 600 }, children: "Trap width" }), _jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [_jsx("input", { id: widthId, type: "range", min: minMm, max: maxMm, step: stepMm, value: current.widthMm, onChange: (e) => updateWidth(Number.parseFloat(e.target.value)), style: { flex: 1 } }), _jsxs("span", { style: {
47
+ minWidth: "3.5rem",
48
+ textAlign: "right",
49
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
50
+ fontSize: "0.75rem",
51
+ }, children: [current.widthMm.toFixed(3), " mm"] })] })] }), _jsxs("label", { htmlFor: modeId, style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [_jsx("span", { style: { fontWeight: 600 }, children: "Mode" }), _jsxs("select", { id: modeId, value: current.mode ?? "auto", onChange: (e) => updateMode(e.target.value), style: {
52
+ padding: "0.25rem 0.5rem",
53
+ fontSize: "0.8rem",
54
+ border: "1px solid #d1d5db",
55
+ borderRadius: 4,
56
+ background: "#ffffff",
57
+ }, children: [_jsx("option", { value: "auto", children: "Auto (density-based)" }), _jsx("option", { value: "spread", children: "Spread (lighter into darker)" }), _jsx("option", { value: "choke", children: "Choke (darker into lighter)" })] })] }), _jsx("p", { style: {
58
+ margin: 0,
59
+ fontSize: "0.7rem",
60
+ color: "#6b7280",
61
+ lineHeight: 1.4,
62
+ }, children: "Per-edge and per-color-pair overrides land in a future revision once the compile-pdf trap producer exposes them." })] }));
63
+ }
64
+ //# sourceMappingURL=TrapEditorPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TrapEditorPanel.js","sourceRoot":"","sources":["../../src/components/TrapEditorPanel.tsx"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,YAAY,CAAC;;AAEb,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAqC9B;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,KAAK,GAAG,CAAC,EACT,KAAK,GAAG,CAAC,EACT,MAAM,GAAG,IAAI,GACQ;IACrB,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,KAAK,EAAE,CAAC;IACvB,MAAM,OAAO,GAAoB,KAAK,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAE3E,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,EAAE;QACnC,6DAA6D;QAC7D,wDAAwD;QACxD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QACvD,QAAQ,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7C,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,IAA0C,EAAE,EAAE;QAChE,QAAQ,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC;IAEF,OAAO,CACL,eACE,KAAK,EAAE;YACL,OAAO,EAAE,MAAM;YACf,aAAa,EAAE,QAAQ;YACvB,GAAG,EAAE,SAAS;YACd,OAAO,EAAE,SAAS;YAClB,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE,SAAS;YACrB,MAAM,EAAE,mBAAmB;YAC3B,YAAY,EAAE,CAAC;YACf,QAAQ,EAAE,GAAG;SACd,aAED,iBAAO,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,aAC1F,eAAM,KAAK,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,2BAAmB,EACnD,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,aAClE,gBACE,EAAE,EAAE,OAAO,EACX,IAAI,EAAC,OAAO,EACZ,GAAG,EAAE,KAAK,EACV,GAAG,EAAE,KAAK,EACV,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,CAAC,OAAO,EACtB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAC/D,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,GAClB,EACF,gBACE,KAAK,EAAE;oCACL,QAAQ,EAAE,QAAQ;oCAClB,SAAS,EAAE,OAAO;oCAClB,UAAU,EAAE,gDAAgD;oCAC5D,QAAQ,EAAE,SAAS;iCACpB,aAEA,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,WACtB,IACH,IACA,EAER,iBAAO,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,aACzF,eAAM,KAAK,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,qBAAa,EAC7C,kBACE,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,OAAO,CAAC,IAAI,IAAI,MAAM,EAC7B,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAA6C,CAAC,EACnF,KAAK,EAAE;4BACL,OAAO,EAAE,gBAAgB;4BACzB,QAAQ,EAAE,QAAQ;4BAClB,MAAM,EAAE,mBAAmB;4BAC3B,YAAY,EAAE,CAAC;4BACf,UAAU,EAAE,SAAS;yBACtB,aAED,iBAAQ,KAAK,EAAC,MAAM,qCAA8B,EAClD,iBAAQ,KAAK,EAAC,QAAQ,6CAAsC,EAC5D,iBAAQ,KAAK,EAAC,OAAO,4CAAqC,IACnD,IACH,EAER,YACE,KAAK,EAAE;oBACL,MAAM,EAAE,CAAC;oBACT,QAAQ,EAAE,QAAQ;oBAClB,KAAK,EAAE,SAAS;oBAChB,UAAU,EAAE,GAAG;iBAChB,iIAIC,IACA,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * One trap operation as predicted by the D1 preview pass. Pixel-space
3
+ * rectangle in PDF points (1 pt = 1/72 in) plus the source/destination
4
+ * ink names.
5
+ *
6
+ * Mirrors compile-pdf's `trap_diff.operations[i]` shape (see
7
+ * `apps/service/src/compile-pdf-client.ts`'s `TrapOperation`). Kept
8
+ * inline here so the published editor package has no runtime dep on
9
+ * apps/service — a future refactor may centralize this shape in
10
+ * `@artworkpdf/document-model` to remove the structural duplication.
11
+ *
12
+ * @public
13
+ */
14
+ export type TrapPreviewOperation = {
15
+ /** Server-side page index — **0-indexed**, matching compile-pdf's
16
+ * `TrapZone.page_index: NonNegativeInt`. Note the distinct
17
+ * convention from the overlay's prop, which uses **1-indexed**
18
+ * `pageIndex` to match PDF user-facing page numbers; the overlay
19
+ * converts internally. */
20
+ page_index: number;
21
+ rect_pt: [number, number, number, number];
22
+ from_ink: string;
23
+ to_ink: string;
24
+ width_pt?: number;
25
+ };
26
+ /**
27
+ * Pluggable preview fetcher. Hosts inject this so the editor never
28
+ * imports `CompilePdfClient` directly — matches the
29
+ * {@link import("./SwatchesPicker").SpotSearchFn} adapter pattern.
30
+ *
31
+ * @public
32
+ */
33
+ export type TrapPreviewFn = () => Promise<{
34
+ operations: TrapPreviewOperation[];
35
+ }>;
36
+ /**
37
+ * @public
38
+ */
39
+ export type TrapPreviewOverlayProps = {
40
+ /** Container width / height in CSS pixels — the overlay canvas
41
+ * matches these so it aligns with the Konva Stage underneath. */
42
+ width: number;
43
+ height: number;
44
+ /** 1-indexed page number to render. The trap-diff payload may carry
45
+ * operations for many pages; the overlay only draws this page. */
46
+ pageIndex: number;
47
+ /** Stage scale × DPR-equivalent factor: how many CSS pixels one PDF
48
+ * point occupies. The component multiplies `rect_pt` by this to
49
+ * position each trap rectangle on the overlay. */
50
+ pointsToPx: number;
51
+ /** Re-fetch trigger — change this value to debounce a new preview
52
+ * pass. The value itself isn't read. Pass the editor's `objects`
53
+ * array or a policy-version counter. */
54
+ trigger: unknown;
55
+ /** Async fetcher returning the trap operations for the current
56
+ * document + policy. Hosts wire this to
57
+ * `CompilePdfClient.trapPreview()` and a serialized canvas PDF. */
58
+ previewFn: TrapPreviewFn | null;
59
+ /** Debounce window in milliseconds. Defaults to 500 — slower than
60
+ * C4's 250 ms because the trap preview is a server round trip. */
61
+ debounceMs?: number;
62
+ };
63
+ export declare function TrapPreviewOverlay({ width, height, pageIndex, pointsToPx, trigger, previewFn, debounceMs, }: TrapPreviewOverlayProps): import("react/jsx-runtime").JSX.Element;
64
+ //# sourceMappingURL=TrapPreviewOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TrapPreviewOverlay.d.ts","sourceRoot":"","sources":["../../src/components/TrapPreviewOverlay.tsx"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;;+BAI2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC;IACxC,UAAU,EAAE,oBAAoB,EAAE,CAAC;CACpC,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC;sEACkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;uEACmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB;;uDAEmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB;;6CAEyC;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB;;wEAEoE;IACpE,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC;uEACmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AA8BF,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,MAAM,EACN,SAAS,EACT,UAAU,EACV,OAAO,EACP,SAAS,EACT,UAAgB,GACjB,EAAE,uBAAuB,2CAoGzB"}