@printwithsynergy/artwork-pdf-editor 0.2.0 → 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 (236) hide show
  1. package/LICENSE +62 -0
  2. package/dist/components/AccessibilityHintsPanel.d.ts +142 -0
  3. package/dist/components/AccessibilityHintsPanel.d.ts.map +1 -0
  4. package/dist/components/AccessibilityHintsPanel.js +158 -0
  5. package/dist/components/AccessibilityHintsPanel.js.map +1 -0
  6. package/dist/components/AnnotationOverlay.d.ts +142 -0
  7. package/dist/components/AnnotationOverlay.d.ts.map +1 -0
  8. package/dist/components/AnnotationOverlay.js +141 -0
  9. package/dist/components/AnnotationOverlay.js.map +1 -0
  10. package/dist/components/AnnotationsSidebar.d.ts +98 -0
  11. package/dist/components/AnnotationsSidebar.d.ts.map +1 -0
  12. package/dist/components/AnnotationsSidebar.js +100 -0
  13. package/dist/components/AnnotationsSidebar.js.map +1 -0
  14. package/dist/components/BarcodeGeneratorPanel.d.ts +58 -0
  15. package/dist/components/BarcodeGeneratorPanel.d.ts.map +1 -0
  16. package/dist/components/BarcodeGeneratorPanel.js +91 -0
  17. package/dist/components/BarcodeGeneratorPanel.js.map +1 -0
  18. package/dist/components/BraillePanel.d.ts +99 -0
  19. package/dist/components/BraillePanel.d.ts.map +1 -0
  20. package/dist/components/BraillePanel.js +221 -0
  21. package/dist/components/BraillePanel.js.map +1 -0
  22. package/dist/components/BrandAssetsPanel.d.ts +130 -0
  23. package/dist/components/BrandAssetsPanel.d.ts.map +1 -0
  24. package/dist/components/BrandAssetsPanel.js +125 -0
  25. package/dist/components/BrandAssetsPanel.js.map +1 -0
  26. package/dist/components/BrandConsistencyPanel.d.ts +140 -0
  27. package/dist/components/BrandConsistencyPanel.d.ts.map +1 -0
  28. package/dist/components/BrandConsistencyPanel.js +158 -0
  29. package/dist/components/BrandConsistencyPanel.js.map +1 -0
  30. package/dist/components/ComplianceFindingsPanel.d.ts +62 -0
  31. package/dist/components/ComplianceFindingsPanel.d.ts.map +1 -0
  32. package/dist/components/ComplianceFindingsPanel.js +118 -0
  33. package/dist/components/ComplianceFindingsPanel.js.map +1 -0
  34. package/dist/components/DesignSuggestionsPanel.d.ts +148 -0
  35. package/dist/components/DesignSuggestionsPanel.d.ts.map +1 -0
  36. package/dist/components/DesignSuggestionsPanel.js +154 -0
  37. package/dist/components/DesignSuggestionsPanel.js.map +1 -0
  38. package/dist/components/DielineParametersPanel.d.ts +62 -0
  39. package/dist/components/DielineParametersPanel.d.ts.map +1 -0
  40. package/dist/components/DielineParametersPanel.js +170 -0
  41. package/dist/components/DielineParametersPanel.js.map +1 -0
  42. package/dist/components/DielinePreview.d.ts +150 -0
  43. package/dist/components/DielinePreview.d.ts.map +1 -0
  44. package/dist/components/DielinePreview.js +146 -0
  45. package/dist/components/DielinePreview.js.map +1 -0
  46. package/dist/components/EditorApp.d.ts +18 -3
  47. package/dist/components/EditorApp.d.ts.map +1 -1
  48. package/dist/components/EditorApp.js +42 -7
  49. package/dist/components/EditorApp.js.map +1 -1
  50. package/dist/components/EditorCanvas.d.ts +31 -2
  51. package/dist/components/EditorCanvas.d.ts.map +1 -1
  52. package/dist/components/EditorCanvas.js +97 -16
  53. package/dist/components/EditorCanvas.js.map +1 -1
  54. package/dist/components/EmailNotifyPanel.d.ts +165 -0
  55. package/dist/components/EmailNotifyPanel.d.ts.map +1 -0
  56. package/dist/components/EmailNotifyPanel.js +211 -0
  57. package/dist/components/EmailNotifyPanel.js.map +1 -0
  58. package/dist/components/FileDropZone.d.ts +9 -1
  59. package/dist/components/FileDropZone.d.ts.map +1 -1
  60. package/dist/components/FileDropZone.js +53 -5
  61. package/dist/components/FileDropZone.js.map +1 -1
  62. package/dist/components/FoldEditorPanel.d.ts +68 -0
  63. package/dist/components/FoldEditorPanel.d.ts.map +1 -0
  64. package/dist/components/FoldEditorPanel.js +65 -0
  65. package/dist/components/FoldEditorPanel.js.map +1 -0
  66. package/dist/components/FoldPreviewOverlay.d.ts +48 -0
  67. package/dist/components/FoldPreviewOverlay.d.ts.map +1 -0
  68. package/dist/components/FoldPreviewOverlay.js +182 -0
  69. package/dist/components/FoldPreviewOverlay.js.map +1 -0
  70. package/dist/components/Gs1DigitalLinkPanel.d.ts +103 -0
  71. package/dist/components/Gs1DigitalLinkPanel.d.ts.map +1 -0
  72. package/dist/components/Gs1DigitalLinkPanel.js +199 -0
  73. package/dist/components/Gs1DigitalLinkPanel.js.map +1 -0
  74. package/dist/components/HistoryPanel.d.ts +39 -0
  75. package/dist/components/HistoryPanel.d.ts.map +1 -0
  76. package/dist/components/HistoryPanel.js +72 -0
  77. package/dist/components/HistoryPanel.js.map +1 -0
  78. package/dist/components/IccSoftProofOverlay.d.ts +67 -0
  79. package/dist/components/IccSoftProofOverlay.d.ts.map +1 -0
  80. package/dist/components/IccSoftProofOverlay.js +119 -0
  81. package/dist/components/IccSoftProofOverlay.js.map +1 -0
  82. package/dist/components/ImposePanel.d.ts +71 -0
  83. package/dist/components/ImposePanel.d.ts.map +1 -0
  84. package/dist/components/ImposePanel.js +127 -0
  85. package/dist/components/ImposePanel.js.map +1 -0
  86. package/dist/components/InksPanel.d.ts +61 -0
  87. package/dist/components/InksPanel.d.ts.map +1 -0
  88. package/dist/components/InksPanel.js +84 -0
  89. package/dist/components/InksPanel.js.map +1 -0
  90. package/dist/components/JobSetupPanel.d.ts +118 -0
  91. package/dist/components/JobSetupPanel.d.ts.map +1 -0
  92. package/dist/components/JobSetupPanel.js +169 -0
  93. package/dist/components/JobSetupPanel.js.map +1 -0
  94. package/dist/components/LayersPanel.d.ts.map +1 -1
  95. package/dist/components/LayersPanel.js +1 -0
  96. package/dist/components/LayersPanel.js.map +1 -1
  97. package/dist/components/MarkLibraryPanel.d.ts +131 -0
  98. package/dist/components/MarkLibraryPanel.d.ts.map +1 -0
  99. package/dist/components/MarkLibraryPanel.js +184 -0
  100. package/dist/components/MarkLibraryPanel.js.map +1 -0
  101. package/dist/components/MisEstimateButton.d.ts +73 -0
  102. package/dist/components/MisEstimateButton.d.ts.map +1 -0
  103. package/dist/components/MisEstimateButton.js +57 -0
  104. package/dist/components/MisEstimateButton.js.map +1 -0
  105. package/dist/components/NutritionPanel.d.ts +118 -0
  106. package/dist/components/NutritionPanel.d.ts.map +1 -0
  107. package/dist/components/NutritionPanel.js +169 -0
  108. package/dist/components/NutritionPanel.js.map +1 -0
  109. package/dist/components/PageNavigator.d.ts.map +1 -1
  110. package/dist/components/PageNavigator.js +6 -1
  111. package/dist/components/PageNavigator.js.map +1 -1
  112. package/dist/components/PaletteManager.d.ts +32 -0
  113. package/dist/components/PaletteManager.d.ts.map +1 -0
  114. package/dist/components/PaletteManager.js +89 -0
  115. package/dist/components/PaletteManager.js.map +1 -0
  116. package/dist/components/PaletteToSpotPanel.d.ts +122 -0
  117. package/dist/components/PaletteToSpotPanel.d.ts.map +1 -0
  118. package/dist/components/PaletteToSpotPanel.js +160 -0
  119. package/dist/components/PaletteToSpotPanel.js.map +1 -0
  120. package/dist/components/PreflightAutoFixPanel.d.ts +110 -0
  121. package/dist/components/PreflightAutoFixPanel.d.ts.map +1 -0
  122. package/dist/components/PreflightAutoFixPanel.js +119 -0
  123. package/dist/components/PreflightAutoFixPanel.js.map +1 -0
  124. package/dist/components/PreflightDiffPanel.d.ts +127 -0
  125. package/dist/components/PreflightDiffPanel.d.ts.map +1 -0
  126. package/dist/components/PreflightDiffPanel.js +0 -0
  127. package/dist/components/PreflightDiffPanel.js.map +1 -0
  128. package/dist/components/ProcessRulesPanel.d.ts +81 -0
  129. package/dist/components/ProcessRulesPanel.d.ts.map +1 -0
  130. package/dist/components/ProcessRulesPanel.js +143 -0
  131. package/dist/components/ProcessRulesPanel.js.map +1 -0
  132. package/dist/components/SlackNotifyPanel.d.ts +139 -0
  133. package/dist/components/SlackNotifyPanel.d.ts.map +1 -0
  134. package/dist/components/SlackNotifyPanel.js +133 -0
  135. package/dist/components/SlackNotifyPanel.js.map +1 -0
  136. package/dist/components/SmartSpotMatchPanel.d.ts +143 -0
  137. package/dist/components/SmartSpotMatchPanel.d.ts.map +1 -0
  138. package/dist/components/SmartSpotMatchPanel.js +159 -0
  139. package/dist/components/SmartSpotMatchPanel.js.map +1 -0
  140. package/dist/components/SwatchesPicker.d.ts +83 -0
  141. package/dist/components/SwatchesPicker.d.ts.map +1 -0
  142. package/dist/components/SwatchesPicker.js +151 -0
  143. package/dist/components/SwatchesPicker.js.map +1 -0
  144. package/dist/components/TacOverlay.d.ts +47 -0
  145. package/dist/components/TacOverlay.d.ts.map +1 -0
  146. package/dist/components/TacOverlay.js +116 -0
  147. package/dist/components/TacOverlay.js.map +1 -0
  148. package/dist/components/TrapEditorPanel.d.ts +52 -0
  149. package/dist/components/TrapEditorPanel.d.ts.map +1 -0
  150. package/dist/components/TrapEditorPanel.js +64 -0
  151. package/dist/components/TrapEditorPanel.js.map +1 -0
  152. package/dist/components/TrapPreviewOverlay.d.ts +64 -0
  153. package/dist/components/TrapPreviewOverlay.d.ts.map +1 -0
  154. package/dist/components/TrapPreviewOverlay.js +120 -0
  155. package/dist/components/TrapPreviewOverlay.js.map +1 -0
  156. package/dist/components/VariantMatrixPanel.d.ts +61 -0
  157. package/dist/components/VariantMatrixPanel.d.ts.map +1 -0
  158. package/dist/components/VariantMatrixPanel.js +97 -0
  159. package/dist/components/VariantMatrixPanel.js.map +1 -0
  160. package/dist/components/VariantMatrixVersionPanel.d.ts +122 -0
  161. package/dist/components/VariantMatrixVersionPanel.d.ts.map +1 -0
  162. package/dist/components/VariantMatrixVersionPanel.js +162 -0
  163. package/dist/components/VariantMatrixVersionPanel.js.map +1 -0
  164. package/dist/components/WebhookNotifyPanel.d.ts +160 -0
  165. package/dist/components/WebhookNotifyPanel.d.ts.map +1 -0
  166. package/dist/components/WebhookNotifyPanel.js +100 -0
  167. package/dist/components/WebhookNotifyPanel.js.map +1 -0
  168. package/dist/components/WhiteUnderbasePanel.d.ts +107 -0
  169. package/dist/components/WhiteUnderbasePanel.d.ts.map +1 -0
  170. package/dist/components/WhiteUnderbasePanel.js +104 -0
  171. package/dist/components/WhiteUnderbasePanel.js.map +1 -0
  172. package/dist/hooks/useEditorMode.d.ts +25 -5
  173. package/dist/hooks/useEditorMode.d.ts.map +1 -1
  174. package/dist/hooks/useEditorMode.js +18 -5
  175. package/dist/hooks/useEditorMode.js.map +1 -1
  176. package/dist/index.d.ts +49 -2
  177. package/dist/index.d.ts.map +1 -1
  178. package/dist/index.js +49 -2
  179. package/dist/index.js.map +1 -1
  180. package/dist/lens/preflight-findings.d.ts.map +1 -1
  181. package/dist/lens/preflight-findings.js.map +1 -1
  182. package/dist/lib/barcode-scan.d.ts +154 -0
  183. package/dist/lib/barcode-scan.d.ts.map +1 -0
  184. package/dist/lib/barcode-scan.js +152 -0
  185. package/dist/lib/barcode-scan.js.map +1 -0
  186. package/dist/lib/color-math.d.ts +76 -0
  187. package/dist/lib/color-math.d.ts.map +1 -0
  188. package/dist/lib/color-math.js +96 -0
  189. package/dist/lib/color-math.js.map +1 -0
  190. package/dist/lib/dieline-template.d.ts +87 -0
  191. package/dist/lib/dieline-template.d.ts.map +1 -1
  192. package/dist/lib/dieline-template.js +163 -0
  193. package/dist/lib/dieline-template.js.map +1 -1
  194. package/dist/lib/editor-config.d.ts +384 -0
  195. package/dist/lib/editor-config.d.ts.map +1 -1
  196. package/dist/lib/editor-config.js +89 -0
  197. package/dist/lib/editor-config.js.map +1 -1
  198. package/dist/lib/fold-geometry.d.ts +144 -0
  199. package/dist/lib/fold-geometry.d.ts.map +1 -0
  200. package/dist/lib/fold-geometry.js +138 -0
  201. package/dist/lib/fold-geometry.js.map +1 -0
  202. package/dist/lib/merge-tokens.d.ts +81 -0
  203. package/dist/lib/merge-tokens.d.ts.map +1 -0
  204. package/dist/lib/merge-tokens.js +88 -0
  205. package/dist/lib/merge-tokens.js.map +1 -0
  206. package/dist/lib/palette-registry.d.ts +40 -0
  207. package/dist/lib/palette-registry.d.ts.map +1 -0
  208. package/dist/lib/palette-registry.js +49 -0
  209. package/dist/lib/palette-registry.js.map +1 -0
  210. package/dist/lib/panel-anchor.d.ts +101 -0
  211. package/dist/lib/panel-anchor.d.ts.map +1 -0
  212. package/dist/lib/panel-anchor.js +68 -0
  213. package/dist/lib/panel-anchor.js.map +1 -0
  214. package/dist/lib/preflight/checks.d.ts.map +1 -1
  215. package/dist/lib/preflight/checks.js +71 -0
  216. package/dist/lib/preflight/checks.js.map +1 -1
  217. package/dist/lib/preflight/types.d.ts.map +1 -1
  218. package/dist/lib/preflight/types.js +11 -0
  219. package/dist/lib/preflight/types.js.map +1 -1
  220. package/dist/lib/rasterize.d.ts +93 -0
  221. package/dist/lib/rasterize.d.ts.map +1 -0
  222. package/dist/lib/rasterize.js +117 -0
  223. package/dist/lib/rasterize.js.map +1 -0
  224. package/dist/lib/separations-registry.d.ts +99 -0
  225. package/dist/lib/separations-registry.d.ts.map +1 -0
  226. package/dist/lib/separations-registry.js +59 -0
  227. package/dist/lib/separations-registry.js.map +1 -0
  228. package/dist/lib/unwired.d.ts +29 -0
  229. package/dist/lib/unwired.d.ts.map +1 -0
  230. package/dist/lib/unwired.js +58 -0
  231. package/dist/lib/unwired.js.map +1 -0
  232. package/package.json +20 -11
  233. package/dist/components/SeparationsPanel.d.ts +0 -9
  234. package/dist/components/SeparationsPanel.d.ts.map +0 -1
  235. package/dist/components/SeparationsPanel.js +0 -168
  236. package/dist/components/SeparationsPanel.js.map +0 -1
@@ -0,0 +1,199 @@
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
+ /**
5
+ * Wave 3 G3 — GS1 Digital Link composer panel.
6
+ *
7
+ * GS1 Digital Link (ISO/IEC 15459 + GS1 Digital Link Standard v1.3) is
8
+ * a structured URL form for product identifiers that can be encoded
9
+ * into a single QR code and resolved on-device. Shape:
10
+ *
11
+ * `https://<domain>/01/<gtin>[/22/<cpv>][/10/<lot>][/21/<serial>][?...]`
12
+ *
13
+ * Path AIs (Application Identifiers) carry the "primary key" segments
14
+ * — `01` (GTIN) is mandatory, then `22`/`10`/`21` in canonical order.
15
+ * Query-string AIs carry the long tail (expiration date, batch, etc.)
16
+ * via `<ai>=<value>` pairs.
17
+ *
18
+ * The panel handles URL composition only — emitting the URL via
19
+ * `onLink`. Hosts that also want a rendered QR bitmap wire the Wave 3
20
+ * G2g {@link import("./BarcodeGeneratorPanel").BarcodeRenderFn} shape
21
+ * via the optional `renderer` prop and receive the bitmap via
22
+ * `onRendered`. This keeps the composer free of any rendering library
23
+ * dep and lets G2g + G3 share one adapter.
24
+ *
25
+ * @public
26
+ */
27
+ import { useState } from "react";
28
+ /**
29
+ * The GS1 community-default resolver domain. Re-exported for hosts
30
+ * that want to display it as a hint or seed a settings UI.
31
+ *
32
+ * @public
33
+ */
34
+ export const DEFAULT_GS1_DOMAIN = "id.gs1.org";
35
+ const PATH_AIS_IN_ORDER = ["22", "10", "21"];
36
+ /**
37
+ * Validate a GS1 AI 17 (expiration date) value: must be exactly six
38
+ * digits in `YYMMDD` order with month 1-12 and a real calendar day.
39
+ * Year is two digits per the GS1 spec so the validator checks the
40
+ * day against an arbitrary 21st-century year — the year value itself
41
+ * does not constrain the calendar.
42
+ *
43
+ * Exported alongside {@link composeGs1DigitalLink} so server-side
44
+ * callers can reject invalid expiries before composing.
45
+ *
46
+ * @public
47
+ */
48
+ export function isValidGs1Ai17(value) {
49
+ if (!/^\d{6}$/.test(value))
50
+ return false;
51
+ const yy = Number(value.slice(0, 2));
52
+ const mm = Number(value.slice(2, 4));
53
+ const dd = Number(value.slice(4, 6));
54
+ if (mm < 1 || mm > 12)
55
+ return false;
56
+ if (dd < 1 || dd > 31)
57
+ return false;
58
+ const fullYear = 2000 + yy;
59
+ const date = new Date(fullYear, mm - 1, dd);
60
+ return date.getFullYear() === fullYear && date.getMonth() === mm - 1 && date.getDate() === dd;
61
+ }
62
+ /**
63
+ * Compose a canonical GS1 Digital Link URL from a GTIN + optional
64
+ * path-AIs + optional query-AIs. Pure function — exported so server
65
+ * components (Next.js RSC, Astro frontmatter) can pre-compute URLs
66
+ * without bundling the panel.
67
+ *
68
+ * Path-AI order is `22 → 10 → 21` per the GS1 Digital Link Standard;
69
+ * any other AIs flow into the query string in the order supplied.
70
+ *
71
+ * @public
72
+ */
73
+ export function composeGs1DigitalLink(input) {
74
+ // Normalize the host: trim whitespace, strip any explicit
75
+ // `http(s)://` scheme the user pasted (the composer always emits
76
+ // `https://`), then drop trailing slashes. Empty / whitespace-only
77
+ // input falls back to the GS1 community default rather than
78
+ // producing the malformed `https:///01/...`.
79
+ const trimmed = input.domain.trim().replace(/^https?:\/\//i, "");
80
+ const stripped = trimmed.replace(/\/+$/, "");
81
+ const domain = stripped === "" ? DEFAULT_GS1_DOMAIN : stripped;
82
+ const pathAisByCode = new Map();
83
+ for (const entry of input.pathAis ?? []) {
84
+ pathAisByCode.set(entry.ai, entry.value);
85
+ }
86
+ let pathSegment = `/01/${encodeURIComponent(input.gtin)}`;
87
+ for (const code of PATH_AIS_IN_ORDER) {
88
+ const value = pathAisByCode.get(code);
89
+ if (value !== undefined && value !== "") {
90
+ pathSegment += `/${code}/${encodeURIComponent(value)}`;
91
+ }
92
+ }
93
+ const querySegments = (input.queryAis ?? [])
94
+ .filter((entry) => entry.value !== "")
95
+ .map((entry) => `${encodeURIComponent(entry.ai)}=${encodeURIComponent(entry.value)}`);
96
+ const querySegment = querySegments.length > 0 ? `?${querySegments.join("&")}` : "";
97
+ return {
98
+ url: `https://${domain}${pathSegment}${querySegment}`,
99
+ pathSegment,
100
+ querySegment,
101
+ };
102
+ }
103
+ /**
104
+ * GS1 Digital Link composer panel. The user picks a domain, types a
105
+ * GTIN, optionally adds CPV / lot / serial path-AIs and free-form
106
+ * query-AIs; the panel emits the composed URL via `onLink`. When the
107
+ * host wires a `renderer`, a "Generate QR" button hands the URL to
108
+ * the adapter with `format: "QR"` and forwards the bitmap to
109
+ * `onRendered`.
110
+ *
111
+ * @public
112
+ */
113
+ export function Gs1DigitalLinkPanel({ renderer, onLink, onRendered, defaultDomain = DEFAULT_GS1_DOMAIN, }) {
114
+ const [domain, setDomain] = useState(defaultDomain);
115
+ const [gtin, setGtin] = useState("");
116
+ const [cpv, setCpv] = useState("");
117
+ const [lot, setLot] = useState("");
118
+ const [serial, setSerial] = useState("");
119
+ const [expiration, setExpiration] = useState("");
120
+ const [busy, setBusy] = useState(false);
121
+ const [error, setError] = useState(null);
122
+ /**
123
+ * Validate the form. Returns the composed result on success or an
124
+ * error message; null `result` means the caller must not proceed.
125
+ * Centralised here so `handlePreview` and `handleGenerate` share
126
+ * the same checks.
127
+ */
128
+ function validateAndCompose() {
129
+ const trimmedGtin = gtin.trim();
130
+ if (!trimmedGtin) {
131
+ return { result: null, error: "GTIN is required." };
132
+ }
133
+ // GS1 GTINs are 8 / 12 / 13 / 14 digits (GTIN-8, UPC-A, EAN-13,
134
+ // GTIN-14). The check digit isn't validated here — leave that to
135
+ // the host renderer / server, which can also surface check-digit
136
+ // errors with a specific message.
137
+ if (!/^\d{8}$|^\d{12}$|^\d{13}$|^\d{14}$/.test(trimmedGtin)) {
138
+ return {
139
+ result: null,
140
+ error: "GTIN must be 8, 12, 13, or 14 digits.",
141
+ };
142
+ }
143
+ const trimmedExpiration = expiration.trim();
144
+ if (trimmedExpiration !== "" && !isValidGs1Ai17(trimmedExpiration)) {
145
+ return {
146
+ result: null,
147
+ error: "Expiration date (AI 17) must be a valid YYMMDD value.",
148
+ };
149
+ }
150
+ return {
151
+ error: null,
152
+ result: composeGs1DigitalLink({
153
+ domain,
154
+ gtin: trimmedGtin,
155
+ pathAis: [
156
+ ...(cpv.trim() ? [{ ai: "22", value: cpv.trim() }] : []),
157
+ ...(lot.trim() ? [{ ai: "10", value: lot.trim() }] : []),
158
+ ...(serial.trim() ? [{ ai: "21", value: serial.trim() }] : []),
159
+ ],
160
+ queryAis: trimmedExpiration ? [{ ai: "17", value: trimmedExpiration }] : [],
161
+ }),
162
+ };
163
+ }
164
+ function handlePreview() {
165
+ const { result, error: validationError } = validateAndCompose();
166
+ if (!result) {
167
+ setError(validationError);
168
+ return;
169
+ }
170
+ setError(null);
171
+ onLink?.(result);
172
+ }
173
+ async function handleGenerate() {
174
+ const { result, error: validationError } = validateAndCompose();
175
+ if (!result) {
176
+ setError(validationError);
177
+ return;
178
+ }
179
+ if (!renderer) {
180
+ setError("No QR renderer wired.");
181
+ return;
182
+ }
183
+ setBusy(true);
184
+ setError(null);
185
+ try {
186
+ onLink?.(result);
187
+ const bitmap = await renderer({ format: "QR", payload: result.url });
188
+ onRendered?.(bitmap);
189
+ }
190
+ catch (err) {
191
+ setError(err instanceof Error ? err.message : String(err));
192
+ }
193
+ finally {
194
+ setBusy(false);
195
+ }
196
+ }
197
+ return (_jsxs("div", { "data-testid": "gs1-digital-link-panel", style: { padding: "0.5rem" }, children: [_jsx("h3", { style: { margin: "0 0 0.5rem 0" }, children: "GS1 Digital Link" }), _jsxs("label", { style: { display: "block", marginBottom: "0.5rem" }, children: ["Resolver domain", _jsx("input", { type: "text", value: domain, onChange: (e) => setDomain(e.target.value), "aria-label": "GS1 resolver domain", style: { marginLeft: "0.5rem", width: "16em" } })] }), _jsxs("label", { style: { display: "block", marginBottom: "0.5rem" }, children: ["GTIN (AI 01)", _jsx("input", { type: "text", value: gtin, onChange: (e) => setGtin(e.target.value), "aria-label": "GTIN", style: { marginLeft: "0.5rem", width: "16em" } })] }), _jsxs("label", { style: { display: "block", marginBottom: "0.5rem" }, children: ["CPV (AI 22, optional)", _jsx("input", { type: "text", value: cpv, onChange: (e) => setCpv(e.target.value), "aria-label": "Consumer product variant", style: { marginLeft: "0.5rem", width: "12em" } })] }), _jsxs("label", { style: { display: "block", marginBottom: "0.5rem" }, children: ["Lot (AI 10, optional)", _jsx("input", { type: "text", value: lot, onChange: (e) => setLot(e.target.value), "aria-label": "Lot or batch", style: { marginLeft: "0.5rem", width: "12em" } })] }), _jsxs("label", { style: { display: "block", marginBottom: "0.5rem" }, children: ["Serial (AI 21, optional)", _jsx("input", { type: "text", value: serial, onChange: (e) => setSerial(e.target.value), "aria-label": "Serial number", style: { marginLeft: "0.5rem", width: "12em" } })] }), _jsxs("label", { style: { display: "block", marginBottom: "0.5rem" }, children: ["Expiration date (AI 17, YYMMDD, optional)", _jsx("input", { type: "text", value: expiration, onChange: (e) => setExpiration(e.target.value), "aria-label": "Expiration date", style: { marginLeft: "0.5rem", width: "8em" } })] }), _jsx("button", { type: "button", onClick: handlePreview, style: { padding: "0.4rem 0.8rem", marginRight: "0.5rem" }, children: "Preview URL" }), renderer && (_jsx("button", { type: "button", onClick: handleGenerate, disabled: busy, style: { padding: "0.4rem 0.8rem" }, children: busy ? "Generating…" : "Generate QR" })), error && (_jsx("div", { role: "alert", style: { marginTop: "0.5rem", color: "#a00" }, children: error }))] }));
198
+ }
199
+ //# sourceMappingURL=Gs1DigitalLinkPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Gs1DigitalLinkPanel.js","sourceRoot":"","sources":["../../src/components/Gs1DigitalLinkPanel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Props for the X2 history-scrubber panel.
3
+ *
4
+ * The panel is purely presentational — EditorCanvas owns the
5
+ * snapshot stack + the active cursor and threads them in via these
6
+ * props. `onSelect(idx)` seeks the canvas to the chosen snapshot;
7
+ * stack depth is derived from `objectCounts.length` (single source
8
+ * of truth — no separate `entries` prop to keep in sync).
9
+ *
10
+ * `cursor` is 0-indexed; row 0 is the initial canvas state, row N
11
+ * is the most recent commit.
12
+ *
13
+ * @public
14
+ */
15
+ export type HistoryPanelProps = {
16
+ /** 0-indexed position of the active snapshot. */
17
+ cursor: number;
18
+ /** Per-snapshot object count, in stack order. Length defines the
19
+ * number of rows; the array itself drives the per-row count chip. */
20
+ objectCounts: number[];
21
+ /** Click handler — seek the canvas to the given snapshot index. */
22
+ onSelect: (idx: number) => void;
23
+ };
24
+ /**
25
+ * Vertical list of history snapshots. The newest entry sits at the
26
+ * top; the active cursor is highlighted with the brand color.
27
+ *
28
+ * Stack-size cap is enforced upstream in `EditorCanvas` (see the
29
+ * 100-snapshot ceiling in `commit()`); rendering the entire list
30
+ * here is cheap because the cap keeps the row count bounded.
31
+ *
32
+ * @returns An `<aside>` element containing the history header and
33
+ * one `<button>` per snapshot. Each button is keyed by its
34
+ * snapshot index and reports `aria-current="step"` when it is the
35
+ * active cursor.
36
+ * @public
37
+ */
38
+ export declare function HistoryPanel({ cursor, objectCounts, onSelect }: HistoryPanelProps): import("react/jsx-runtime").JSX.Element;
39
+ //# sourceMappingURL=HistoryPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HistoryPanel.d.ts","sourceRoot":"","sources":["../../src/components/HistoryPanel.tsx"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf;0EACsE;IACtE,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mEAAmE;IACnE,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,CAAC;AAgCF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,iBAAiB,2CA6CjF"}
@@ -0,0 +1,72 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ "use client";
3
+ import { jsxs as _jsxs } from "react/jsx-runtime";
4
+ const PANEL_BG = "#1a0f08";
5
+ const BORDER = "#3d1a00";
6
+ const BRAND = "#fc5102";
7
+ const TEXT = "#f4ece6";
8
+ const MUTED = "#888";
9
+ const headerStyle = {
10
+ fontSize: "0.7rem",
11
+ letterSpacing: "0.08em",
12
+ textTransform: "uppercase",
13
+ color: MUTED,
14
+ padding: "0.55rem 0.85rem",
15
+ borderBottom: `1px solid ${BORDER}`,
16
+ fontFamily: "inherit",
17
+ };
18
+ const rowBaseStyle = {
19
+ display: "flex",
20
+ alignItems: "center",
21
+ justifyContent: "space-between",
22
+ width: "100%",
23
+ padding: "0.4rem 0.85rem",
24
+ background: "transparent",
25
+ border: "none",
26
+ cursor: "pointer",
27
+ fontFamily: "inherit",
28
+ fontSize: "0.78rem",
29
+ textAlign: "left",
30
+ };
31
+ /**
32
+ * Vertical list of history snapshots. The newest entry sits at the
33
+ * top; the active cursor is highlighted with the brand color.
34
+ *
35
+ * Stack-size cap is enforced upstream in `EditorCanvas` (see the
36
+ * 100-snapshot ceiling in `commit()`); rendering the entire list
37
+ * here is cheap because the cap keeps the row count bounded.
38
+ *
39
+ * @returns An `<aside>` element containing the history header and
40
+ * one `<button>` per snapshot. Each button is keyed by its
41
+ * snapshot index and reports `aria-current="step"` when it is the
42
+ * active cursor.
43
+ * @public
44
+ */
45
+ export function HistoryPanel({ cursor, objectCounts, onSelect }) {
46
+ // Render newest → oldest so the most-recent action is at the top
47
+ // (mirrors the canvas's "future-of-undo is at the top of the
48
+ // stack" mental model). Stack depth comes from objectCounts.length
49
+ // — single source of truth.
50
+ const entries = objectCounts.length;
51
+ const indices = Array.from({ length: entries }, (_, i) => entries - 1 - i);
52
+ return (_jsxs("aside", { style: {
53
+ width: 200,
54
+ background: PANEL_BG,
55
+ borderLeft: `1px solid ${BORDER}`,
56
+ color: TEXT,
57
+ display: "flex",
58
+ flexDirection: "column",
59
+ overflow: "auto",
60
+ flexShrink: 0,
61
+ }, children: [_jsxs("div", { style: headerStyle, children: ["History \u00B7 ", entries, " steps"] }), indices.map((idx) => {
62
+ const active = idx === cursor;
63
+ const count = objectCounts[idx] ?? 0;
64
+ return (_jsxs("button", { type: "button", onClick: () => onSelect(idx), "aria-current": active ? "step" : undefined, style: {
65
+ ...rowBaseStyle,
66
+ background: active ? "#241308" : "transparent",
67
+ color: active ? BRAND : TEXT,
68
+ borderLeft: active ? `2px solid ${BRAND}` : "2px solid transparent",
69
+ }, children: [_jsxs("span", { children: ["Step ", idx] }), _jsxs("span", { style: { color: MUTED, fontSize: "0.72rem" }, children: [count, " obj"] })] }, idx));
70
+ })] }));
71
+ }
72
+ //# sourceMappingURL=HistoryPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HistoryPanel.js","sourceRoot":"","sources":["../../src/components/HistoryPanel.tsx"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,YAAY,CAAC;;AA4Bb,MAAM,QAAQ,GAAG,SAAS,CAAC;AAC3B,MAAM,MAAM,GAAG,SAAS,CAAC;AACzB,MAAM,KAAK,GAAG,SAAS,CAAC;AACxB,MAAM,IAAI,GAAG,SAAS,CAAC;AACvB,MAAM,KAAK,GAAG,MAAM,CAAC;AAErB,MAAM,WAAW,GAAkB;IACjC,QAAQ,EAAE,QAAQ;IAClB,aAAa,EAAE,QAAQ;IACvB,aAAa,EAAE,WAAW;IAC1B,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,iBAAiB;IAC1B,YAAY,EAAE,aAAa,MAAM,EAAE;IACnC,UAAU,EAAE,SAAS;CACtB,CAAC;AAEF,MAAM,YAAY,GAAkB;IAClC,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,QAAQ;IACpB,cAAc,EAAE,eAAe;IAC/B,KAAK,EAAE,MAAM;IACb,OAAO,EAAE,gBAAgB;IACzB,UAAU,EAAE,aAAa;IACzB,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,SAAS;IACjB,UAAU,EAAE,SAAS;IACrB,QAAQ,EAAE,SAAS;IACnB,SAAS,EAAE,MAAM;CAClB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAqB;IAChF,iEAAiE;IACjE,6DAA6D;IAC7D,mEAAmE;IACnE,4BAA4B;IAC5B,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC;IACpC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAE3E,OAAO,CACL,iBACE,KAAK,EAAE;YACL,KAAK,EAAE,GAAG;YACV,UAAU,EAAE,QAAQ;YACpB,UAAU,EAAE,aAAa,MAAM,EAAE;YACjC,KAAK,EAAE,IAAI;YACX,OAAO,EAAE,MAAM;YACf,aAAa,EAAE,QAAQ;YACvB,QAAQ,EAAE,MAAM;YAChB,UAAU,EAAE,CAAC;SACd,aAED,eAAK,KAAK,EAAE,WAAW,gCAAa,OAAO,cAAa,EACvD,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBACnB,MAAM,MAAM,GAAG,GAAG,KAAK,MAAM,CAAC;gBAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACrC,OAAO,CACL,kBAEE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,kBACd,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EACzC,KAAK,EAAE;wBACL,GAAG,YAAY;wBACf,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa;wBAC9C,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;wBAC5B,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,KAAK,EAAE,CAAC,CAAC,CAAC,uBAAuB;qBACpE,aAED,oCAAY,GAAG,IAAQ,EACvB,gBAAM,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAG,KAAK,YAAY,KAZjE,GAAG,CAaD,CACV,CAAC;YACJ,CAAC,CAAC,IACI,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * ICC rendering intent — mirrors the four ICC v4 intents that
3
+ * compile-pdf's soft-proof producer accepts.
4
+ *
5
+ * @public
6
+ */
7
+ export type SoftProofIntent = "perceptual" | "relative-colorimetric" | "saturation" | "absolute-colorimetric";
8
+ /**
9
+ * Result shape returned by an {@link IccSoftProofLoaderFn}. `deltaE`
10
+ * is a per-pixel ImageData (R = clamped deltaE * 4, G/B = 0, A = 255)
11
+ * the overlay paints over the canvas; `max` / `avg` drive the footer
12
+ * chip. Keeping max/avg outside the ImageData lets the host compute
13
+ * them server-side without re-walking the buffer on the client.
14
+ *
15
+ * @public
16
+ */
17
+ export type IccSoftProofResult = {
18
+ deltaE: ImageData;
19
+ max: number;
20
+ avg: number;
21
+ };
22
+ /**
23
+ * Host-supplied adapter. Receives the rasterized document + source /
24
+ * destination ICC profiles + rendering intent; returns the delta-E
25
+ * heatmap. Rejects on transport errors; the overlay surfaces the
26
+ * message inline.
27
+ *
28
+ * **Identity matters.** The overlay re-fetches whenever the `loader`
29
+ * reference changes; hosts that build the adapter inline should
30
+ * memoize it with `useCallback` so an unrelated parent re-render
31
+ * doesn't trigger a spurious `POST /v1/soft-proof/apply` round-trip.
32
+ *
33
+ * @public
34
+ */
35
+ export type IccSoftProofLoaderFn = (input: {
36
+ documentB64: string;
37
+ sourceProfile: string;
38
+ destinationProfile: string;
39
+ intent: SoftProofIntent;
40
+ }) => Promise<IccSoftProofResult>;
41
+ /**
42
+ * @public
43
+ */
44
+ export type IccSoftProofOverlayProps = {
45
+ /** Latest rendered document (base64 PDF) or `undefined` while
46
+ * the host has nothing to soft-proof. */
47
+ documentB64: string | undefined;
48
+ /** Source ICC profile name (e.g. `"ISOcoated_v2_eci"`). */
49
+ sourceProfile: string | undefined;
50
+ /** Destination ICC profile name (e.g. `"USWebUncoated"`). */
51
+ destinationProfile: string | undefined;
52
+ /** Rendering intent. Defaults to `"relative-colorimetric"` when
53
+ * the host doesn't supply one. */
54
+ intent?: SoftProofIntent;
55
+ /** Adapter that resolves to the delta-E result. */
56
+ loader: IccSoftProofLoaderFn;
57
+ /** Pixel width of the overlay (= the rasterized canvas width).
58
+ * The overlay draws the deltaE ImageData 1:1. */
59
+ width: number;
60
+ /** Pixel height of the overlay. */
61
+ height: number;
62
+ };
63
+ /**
64
+ * @public
65
+ */
66
+ export declare function IccSoftProofOverlay({ documentB64, sourceProfile, destinationProfile, intent, loader, width, height, }: IccSoftProofOverlayProps): import("react/jsx-runtime").JSX.Element | null;
67
+ //# sourceMappingURL=IccSoftProofOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IccSoftProofOverlay.d.ts","sourceRoot":"","sources":["../../src/components/IccSoftProofOverlay.tsx"],"names":[],"mappings":"AA0BA;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GACvB,YAAY,GACZ,uBAAuB,GACvB,YAAY,GACZ,uBAAuB,CAAC;AAE5B;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,SAAS,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,eAAe,CAAC;CACzB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAElC;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;8CAC0C;IAC1C,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,2DAA2D;IAC3D,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,6DAA6D;IAC7D,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC;uCACmC;IACnC,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,mDAAmD;IACnD,MAAM,EAAE,oBAAoB,CAAC;IAC7B;sDACkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAKF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,MAAgC,EAChC,MAAM,EACN,KAAK,EACL,MAAM,GACP,EAAE,wBAAwB,kDAmG1B"}
@@ -0,0 +1,119 @@
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
+ /**
5
+ * Wave 2 PR-6 (C5) — ICC soft-proof overlay.
6
+ *
7
+ * Surfaces compile-pdf's per-pixel delta-E map (source ICC →
8
+ * destination ICC, simulated through the selected rendering intent)
9
+ * as a heat overlay on top of the canvas, plus a footer chip showing
10
+ * `max / avg deltaE`. Workflow:
11
+ *
12
+ * 1. Host rasterizes the active page + collects the source +
13
+ * destination ICC profiles + intent.
14
+ * 2. Host hands the `loader` adapter to the overlay; the adapter
15
+ * POSTs to compile-pdf's `/v1/soft-proof/apply` (Wave 2 PR-G).
16
+ * 3. The overlay paints the returned delta-E ImageData on a
17
+ * positioned canvas, recomputing every time the inputs change.
18
+ *
19
+ * Adapter pattern (matches {@link ComplianceFindingsPanel}): hosts
20
+ * wire the HTTP client themselves so this package stays free of a
21
+ * compile-pdf runtime dep.
22
+ *
23
+ * @public
24
+ */
25
+ import { useEffect, useRef, useState } from "react";
26
+ const FOOTER_BG = "rgba(0,0,0,0.65)";
27
+ const FOOTER_TEXT = "#f4ece6";
28
+ /**
29
+ * @public
30
+ */
31
+ export function IccSoftProofOverlay({ documentB64, sourceProfile, destinationProfile, intent = "relative-colorimetric", loader, width, height, }) {
32
+ const canvasRef = useRef(null);
33
+ const [error, setError] = useState(null);
34
+ const [loading, setLoading] = useState(false);
35
+ const [stats, setStats] = useState(null);
36
+ useEffect(() => {
37
+ if (!documentB64 || !sourceProfile || !destinationProfile) {
38
+ setStats(null);
39
+ setError(null);
40
+ // Also clear the in-flight loading state — a request started
41
+ // before the inputs were cleared would otherwise leave the
42
+ // footer chip stuck on "soft-proofing…".
43
+ setLoading(false);
44
+ return;
45
+ }
46
+ let disposed = false;
47
+ // Reset stats + the canvas up front so a slow fetch doesn't
48
+ // leave the previous run's heatmap visible under the
49
+ // "soft-proofing…" footer.
50
+ setStats(null);
51
+ const ctx = canvasRef.current?.getContext("2d");
52
+ if (ctx)
53
+ ctx.clearRect(0, 0, canvasRef.current?.width ?? 0, canvasRef.current?.height ?? 0);
54
+ setLoading(true);
55
+ setError(null);
56
+ // Wrap the loader call in an async IIFE so synchronous throws
57
+ // from the adapter (e.g. host-side input validation) flow into
58
+ // the same `setError` path as a rejected Promise — otherwise
59
+ // the throw would escape the effect and leave the overlay stuck.
60
+ void (async () => {
61
+ try {
62
+ const result = await loader({
63
+ documentB64,
64
+ sourceProfile,
65
+ destinationProfile,
66
+ intent,
67
+ });
68
+ if (disposed)
69
+ return;
70
+ const ctx = canvasRef.current?.getContext("2d");
71
+ if (ctx)
72
+ ctx.putImageData(result.deltaE, 0, 0);
73
+ setStats({ max: result.max, avg: result.avg });
74
+ }
75
+ catch (err) {
76
+ if (disposed)
77
+ return;
78
+ setError(err instanceof Error ? err.message : String(err));
79
+ }
80
+ finally {
81
+ if (!disposed)
82
+ setLoading(false);
83
+ }
84
+ })();
85
+ return () => {
86
+ disposed = true;
87
+ };
88
+ }, [documentB64, sourceProfile, destinationProfile, intent, loader]);
89
+ if (!documentB64 || !sourceProfile || !destinationProfile)
90
+ return null;
91
+ return (_jsxs("div", { "data-testid": "icc-soft-proof-overlay", style: { position: "relative", width, height, pointerEvents: "none" }, children: [_jsx("canvas", { ref: canvasRef, width: width, height: height, style: {
92
+ position: "absolute",
93
+ inset: 0,
94
+ width: "100%",
95
+ height: "100%",
96
+ // Multiply blend so the heatmap reads as a tint over the
97
+ // canvas rather than replacing it — matches how the C4 TAC
98
+ // overlay composites.
99
+ mixBlendMode: "multiply",
100
+ opacity: 0.7,
101
+ } }), _jsx("output", { style: {
102
+ position: "absolute",
103
+ right: 8,
104
+ bottom: 8,
105
+ padding: "2px 8px",
106
+ background: FOOTER_BG,
107
+ color: FOOTER_TEXT,
108
+ borderRadius: 4,
109
+ fontSize: "0.7rem",
110
+ fontFamily: "monospace",
111
+ }, children: loading
112
+ ? "soft-proofing…"
113
+ : error
114
+ ? `soft-proof failed: ${error}`
115
+ : stats
116
+ ? `ΔE max ${stats.max.toFixed(1)} · avg ${stats.avg.toFixed(1)}`
117
+ : null })] }));
118
+ }
119
+ //# sourceMappingURL=IccSoftProofOverlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IccSoftProofOverlay.js","sourceRoot":"","sources":["../../src/components/IccSoftProofOverlay.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Wire-shape mirror of `apps/service`'s `ImposeTemplate`. Kept inline
3
+ * here so the published editor package has no runtime dep on
4
+ * `apps/service`; the structural duplication is intentional — a
5
+ * future refactor may centralize this in `@artworkpdf/document-model`.
6
+ *
7
+ * Sheet size is in PDF points (1 pt = 1/72 in) to match the wire
8
+ * boundary; the panel renders human-friendly mm read-outs but stores
9
+ * points so the value can be POSTed to compile-pdf unchanged.
10
+ *
11
+ * @public
12
+ */
13
+ export type ImposePanelValue = {
14
+ sheetWidthPt: number;
15
+ sheetHeightPt: number;
16
+ rows: number;
17
+ cols: number;
18
+ pageMapping?: "sequential" | "repeat";
19
+ gutterMm?: number;
20
+ marginMm?: number;
21
+ registrationMarks?: boolean;
22
+ cropMarks?: boolean;
23
+ };
24
+ /**
25
+ * Pre-populated sheet presets. PDF-points dimensions match standard
26
+ * commercial press sheet sizes used by the dieline library and
27
+ * impose policies. Hosts can add custom presets via the `presets`
28
+ * prop without losing the defaults.
29
+ *
30
+ * @public
31
+ */
32
+ export type ImposePanelPreset = {
33
+ /** Stable id, used as the `<option>` value. */
34
+ id: string;
35
+ /** Human label rendered in the dropdown. */
36
+ label: string;
37
+ widthPt: number;
38
+ heightPt: number;
39
+ };
40
+ /**
41
+ * @public
42
+ */
43
+ export type ImposePanelProps = {
44
+ /** Current template. `undefined` means "no impose configured" —
45
+ * the panel renders preset defaults the user can fill in. */
46
+ value: ImposePanelValue | undefined;
47
+ /** Fires on every change to any field (sheet picker, spinner,
48
+ * toggle, radio). Hosts wire this to the job's `imposeTemplate`
49
+ * field on submission. */
50
+ onChange: (next: ImposePanelValue) => void;
51
+ /** Override the default sheet-size dropdown. The first preset is
52
+ * used as the initial value when `value` is `undefined`. */
53
+ presets?: readonly ImposePanelPreset[];
54
+ };
55
+ /**
56
+ * O1 sheet-imposition builder.
57
+ *
58
+ * Controlled component: surfaces sheet size, rows × cols, gutter /
59
+ * margin in mm, and registration / crop-mark toggles. Renders no
60
+ * chrome of its own — hosts wrap it in a modal, drawer, or
61
+ * right-rail container (matches the `JobSetupPanel` / `TrapEditorPanel`
62
+ * convention).
63
+ *
64
+ * Wire shape uses PDF points everywhere; the panel converts to mm
65
+ * for display so values can be POSTed to compile-pdf's
66
+ * `/v1/impose/apply` endpoint without rescaling.
67
+ *
68
+ * @public
69
+ */
70
+ export declare function ImposePanel({ value, onChange, presets }: ImposePanelProps): import("react/jsx-runtime").JSX.Element;
71
+ //# sourceMappingURL=ImposePanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImposePanel.d.ts","sourceRoot":"","sources":["../../src/components/ImposePanel.tsx"],"names":[],"mappings":"AAKA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,YAAY,GAAG,QAAQ,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,+CAA+C;IAC/C,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAaF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B;kEAC8D;IAC9D,KAAK,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACpC;;+BAE2B;IAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC3C;iEAC6D;IAC7D,OAAO,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACxC,CAAC;AA0CF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAyB,EAAE,EAAE,gBAAgB,2CA8M3F"}