@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,152 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ /**
3
+ * Canonical list of every {@link BarcodeFormat} the module supports.
4
+ * Exported so UI surfaces ({@link import("../components/BarcodeGeneratorPanel").BarcodeGeneratorPanel}
5
+ * default dropdown, host-supplied filters, contract tests) don't have
6
+ * to redeclare the list and drift out of sync when a new format is
7
+ * added to the union.
8
+ *
9
+ * @public
10
+ */
11
+ export const ALL_BARCODE_FORMATS = [
12
+ "EAN-13",
13
+ "UPC-A",
14
+ "GS1-128",
15
+ "QR",
16
+ ];
17
+ /**
18
+ * EAN-13 check-digit validation.
19
+ *
20
+ * EAN-13 is 13 digits; the 13th is a mod-10 checksum over the first
21
+ * 12 with alternating weights (1, 3, 1, 3, …). Returns `true` iff the
22
+ * input is exactly 13 ASCII digits and the checksum matches.
23
+ *
24
+ * @public
25
+ */
26
+ export function validateEAN13(code) {
27
+ if (!/^[0-9]{13}$/.test(code))
28
+ return false;
29
+ let sum = 0;
30
+ for (let i = 0; i < 12; i++) {
31
+ const d = code.charCodeAt(i) - 48;
32
+ // Odd-positioned digits (1-indexed) get weight 1; even get 3.
33
+ sum += i % 2 === 0 ? d : d * 3;
34
+ }
35
+ const check = (10 - (sum % 10)) % 10;
36
+ return check === code.charCodeAt(12) - 48;
37
+ }
38
+ /**
39
+ * UPC-A check-digit validation.
40
+ *
41
+ * UPC-A is 12 digits; the 12th is a mod-10 checksum over the first
42
+ * 11 with weights (3, 1, 3, 1, …). Returns `true` iff the input is
43
+ * exactly 12 ASCII digits and the checksum matches.
44
+ *
45
+ * @public
46
+ */
47
+ export function validateUPCA(code) {
48
+ if (!/^[0-9]{12}$/.test(code))
49
+ return false;
50
+ let sum = 0;
51
+ for (let i = 0; i < 11; i++) {
52
+ const d = code.charCodeAt(i) - 48;
53
+ // Odd-positioned digits (1-indexed) get weight 3; even get 1 —
54
+ // mirror image of EAN-13's weight pattern.
55
+ sum += i % 2 === 0 ? d * 3 : d;
56
+ }
57
+ const check = (10 - (sum % 10)) % 10;
58
+ return check === code.charCodeAt(11) - 48;
59
+ }
60
+ /**
61
+ * GS1-128 structural validation.
62
+ *
63
+ * GS1-128 (formerly UCC/EAN-128) encodes structured data using
64
+ * Application Identifiers — each AI is 2–4 digits followed by a
65
+ * data field of AI-dependent length. A full validator would require
66
+ * the AI table; the shippable approximation here checks that:
67
+ *
68
+ * - The payload contains only printable ASCII (no control chars
69
+ * other than the `<GS>` `0x1D` separator used between
70
+ * variable-length data fields).
71
+ * - The payload starts with at least two digits (the first AI).
72
+ * - The payload is non-empty and ≤ 48 chars (real-world
73
+ * GS1-128 codes rarely exceed this).
74
+ *
75
+ * Returns `true` for plausibly-structured payloads. False positives
76
+ * are intentional — preflight is a sanity check, not a parser.
77
+ *
78
+ * @public
79
+ */
80
+ export function validateGS1128(code) {
81
+ if (code.length === 0 || code.length > 48)
82
+ return false;
83
+ if (!/^[0-9]{2}/.test(code))
84
+ return false;
85
+ // 0x1D is the GS separator GS1-128 uses; everything else must be
86
+ // printable ASCII so we don't accept binary garbage.
87
+ for (let i = 0; i < code.length; i++) {
88
+ const c = code.charCodeAt(i);
89
+ if (c === 0x1d)
90
+ continue;
91
+ if (c < 0x20 || c > 0x7e)
92
+ return false;
93
+ }
94
+ return true;
95
+ }
96
+ /**
97
+ * Format-aware validator that dispatches to the right per-format
98
+ * check. QR codes pass when the payload is non-empty (the symbol
99
+ * itself carries a Reed-Solomon checksum the detector already
100
+ * verified before emitting the {@link BarcodeDetection}).
101
+ *
102
+ * @public
103
+ */
104
+ export function validateBarcode(detection) {
105
+ switch (detection.format) {
106
+ case "EAN-13":
107
+ return validateEAN13(detection.code)
108
+ ? { valid: true }
109
+ : { valid: false, reason: "EAN-13 check digit failed or wrong length (need 13 digits)" };
110
+ case "UPC-A":
111
+ return validateUPCA(detection.code)
112
+ ? { valid: true }
113
+ : { valid: false, reason: "UPC-A check digit failed or wrong length (need 12 digits)" };
114
+ case "GS1-128":
115
+ return validateGS1128(detection.code)
116
+ ? { valid: true }
117
+ : {
118
+ valid: false,
119
+ reason: "GS1-128 payload is empty, too long, or contains non-printable chars",
120
+ };
121
+ case "QR":
122
+ return detection.code.length > 0
123
+ ? { valid: true }
124
+ : { valid: false, reason: "QR payload is empty" };
125
+ default:
126
+ // Defensive: detectors that return formats outside our union
127
+ // (e.g. a future library reporting "Code128" before we add it
128
+ // to BarcodeFormat) would otherwise return undefined.
129
+ return { valid: false, reason: "Unsupported barcode format" };
130
+ }
131
+ }
132
+ /**
133
+ * Visual barcode detection from a rasterized image.
134
+ *
135
+ * Currently a stub: returns an empty array regardless of input. The
136
+ * real implementation lands in a follow-up that adds a barcode
137
+ * detection library (likely `jsqr` for QR + `quagga2` for linear).
138
+ * Until then, callers see no false positives, and the
139
+ * {@link validateBarcode} surface stays usable for codes the user
140
+ * (or G2g, Wave 3) declares directly on the canvas.
141
+ *
142
+ * The async signature is forward-compatible — most barcode
143
+ * detectors are async (decoder workers, WASM init), so callers
144
+ * don't need to refactor when the real detector lands.
145
+ *
146
+ * @public
147
+ */
148
+ export async function scanBarcodes(_imageData) {
149
+ // TODO(wave-1 follow-up): integrate jsqr + a linear scanner.
150
+ return [];
151
+ }
152
+ //# sourceMappingURL=barcode-scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"barcode-scan.js","sourceRoot":"","sources":["../../src/lib/barcode-scan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Tiny color-math helpers used by the C4 live-TAC sampler.
3
+ *
4
+ * Intentionally simple — the editor's TAC heatmap is a sanity check,
5
+ * not a colorimetric proof. Production color management lives
6
+ * server-side in compile-pdf (`codex_pdf.color`'s ICC-profile-aware
7
+ * conversion). These helpers do the cheap browser-side math so the
8
+ * editor can flag obviously over-inked regions without round-tripping
9
+ * to the server.
10
+ *
11
+ * Lab → CMYK is **not** here on purpose — that conversion is profile-
12
+ * dependent and codex owns it. The editor's spots (`EditorSeparation`)
13
+ * carry an optional `lab` for display, but TAC sampling uses the hex
14
+ * source color (via {@link hexToCmyk}) for browser-side speed.
15
+ */
16
+ /**
17
+ * Subtractive RGB → CMYK with auto black extraction (the "K" channel
18
+ * is the minimum of the inverted RGB values; C/M/Y rescale once K is
19
+ * pulled).
20
+ *
21
+ * Each output channel is in the `[0, 1]` range — multiply by 100 for
22
+ * a percentage. Inputs that fall outside `0..1` are clamped (defensive
23
+ * against bad string parsing).
24
+ *
25
+ * @public
26
+ */
27
+ export declare function rgbToCmyk(r: number, g: number, b: number): {
28
+ c: number;
29
+ m: number;
30
+ y: number;
31
+ k: number;
32
+ };
33
+ /**
34
+ * Parse a `#rrggbb` (or `rrggbb`) hex string into `[r, g, b]` floats
35
+ * in the `[0, 1]` range. Returns `null` for malformed input — callers
36
+ * fall back to whatever default they prefer.
37
+ *
38
+ * Accepts a leading `#` or not; case-insensitive. Short-form `#rgb`
39
+ * is **not** supported — the editor canonicalizes to long form at
40
+ * registration time (see `separations-registry.ts`'s lowercase
41
+ * normalization).
42
+ *
43
+ * @public
44
+ */
45
+ export declare function parseHex(hex: string): [number, number, number] | null;
46
+ /**
47
+ * Convert a `#rrggbb` hex string into CMYK fractions.
48
+ *
49
+ * Returns `null` for malformed input (delegates parsing to
50
+ * {@link parseHex}). Use the `.c + .m + .y + .k` sum × 100 for a
51
+ * total-area-coverage estimate on the pixel.
52
+ *
53
+ * @public
54
+ */
55
+ export declare function hexToCmyk(hex: string): {
56
+ c: number;
57
+ m: number;
58
+ y: number;
59
+ k: number;
60
+ } | null;
61
+ /**
62
+ * Total area coverage of a single CMYK quadruple, in percent (0-400).
63
+ *
64
+ * Sum of all four ink channels — the standard print-industry TAC
65
+ * metric. The TAC limit on coated stock is usually 280-320%; on
66
+ * newsprint, 240%. The editor's preflight default is 300%.
67
+ *
68
+ * @public
69
+ */
70
+ export declare function tacPercent(cmyk: {
71
+ c: number;
72
+ m: number;
73
+ y: number;
74
+ k: number;
75
+ }): number;
76
+ //# sourceMappingURL=color-math.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color-math.d.ts","sourceRoot":"","sources":["../../src/lib/color-math.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CACvB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAgBhD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CASrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAI5F;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEvF"}
@@ -0,0 +1,96 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ /**
3
+ * Tiny color-math helpers used by the C4 live-TAC sampler.
4
+ *
5
+ * Intentionally simple — the editor's TAC heatmap is a sanity check,
6
+ * not a colorimetric proof. Production color management lives
7
+ * server-side in compile-pdf (`codex_pdf.color`'s ICC-profile-aware
8
+ * conversion). These helpers do the cheap browser-side math so the
9
+ * editor can flag obviously over-inked regions without round-tripping
10
+ * to the server.
11
+ *
12
+ * Lab → CMYK is **not** here on purpose — that conversion is profile-
13
+ * dependent and codex owns it. The editor's spots (`EditorSeparation`)
14
+ * carry an optional `lab` for display, but TAC sampling uses the hex
15
+ * source color (via {@link hexToCmyk}) for browser-side speed.
16
+ */
17
+ /**
18
+ * Subtractive RGB → CMYK with auto black extraction (the "K" channel
19
+ * is the minimum of the inverted RGB values; C/M/Y rescale once K is
20
+ * pulled).
21
+ *
22
+ * Each output channel is in the `[0, 1]` range — multiply by 100 for
23
+ * a percentage. Inputs that fall outside `0..1` are clamped (defensive
24
+ * against bad string parsing).
25
+ *
26
+ * @public
27
+ */
28
+ export function rgbToCmyk(r, g, b) {
29
+ const R = Math.max(0, Math.min(1, r));
30
+ const G = Math.max(0, Math.min(1, g));
31
+ const B = Math.max(0, Math.min(1, b));
32
+ const k = 1 - Math.max(R, G, B);
33
+ if (k >= 1) {
34
+ // Pure black — no chroma channels, all ink in K.
35
+ return { c: 0, m: 0, y: 0, k: 1 };
36
+ }
37
+ const scale = 1 - k;
38
+ return {
39
+ c: (1 - R - k) / scale,
40
+ m: (1 - G - k) / scale,
41
+ y: (1 - B - k) / scale,
42
+ k,
43
+ };
44
+ }
45
+ /**
46
+ * Parse a `#rrggbb` (or `rrggbb`) hex string into `[r, g, b]` floats
47
+ * in the `[0, 1]` range. Returns `null` for malformed input — callers
48
+ * fall back to whatever default they prefer.
49
+ *
50
+ * Accepts a leading `#` or not; case-insensitive. Short-form `#rgb`
51
+ * is **not** supported — the editor canonicalizes to long form at
52
+ * registration time (see `separations-registry.ts`'s lowercase
53
+ * normalization).
54
+ *
55
+ * @public
56
+ */
57
+ export function parseHex(hex) {
58
+ const trimmed = hex.trim();
59
+ const body = trimmed.startsWith("#") ? trimmed.slice(1) : trimmed;
60
+ if (body.length !== 6)
61
+ return null;
62
+ if (!/^[0-9a-fA-F]{6}$/.test(body))
63
+ return null;
64
+ const r = Number.parseInt(body.slice(0, 2), 16) / 255;
65
+ const g = Number.parseInt(body.slice(2, 4), 16) / 255;
66
+ const b = Number.parseInt(body.slice(4, 6), 16) / 255;
67
+ return [r, g, b];
68
+ }
69
+ /**
70
+ * Convert a `#rrggbb` hex string into CMYK fractions.
71
+ *
72
+ * Returns `null` for malformed input (delegates parsing to
73
+ * {@link parseHex}). Use the `.c + .m + .y + .k` sum × 100 for a
74
+ * total-area-coverage estimate on the pixel.
75
+ *
76
+ * @public
77
+ */
78
+ export function hexToCmyk(hex) {
79
+ const rgb = parseHex(hex);
80
+ if (rgb === null)
81
+ return null;
82
+ return rgbToCmyk(rgb[0], rgb[1], rgb[2]);
83
+ }
84
+ /**
85
+ * Total area coverage of a single CMYK quadruple, in percent (0-400).
86
+ *
87
+ * Sum of all four ink channels — the standard print-industry TAC
88
+ * metric. The TAC limit on coated stock is usually 280-320%; on
89
+ * newsprint, 240%. The editor's preflight default is 300%.
90
+ *
91
+ * @public
92
+ */
93
+ export function tacPercent(cmyk) {
94
+ return (cmyk.c + cmyk.m + cmyk.y + cmyk.k) * 100;
95
+ }
96
+ //# sourceMappingURL=color-math.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color-math.js","sourceRoot":"","sources":["../../src/lib/color-math.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,21 @@
1
+ import type { Dieline } from "@artworkpdf/dieline-parser";
1
2
  import type { CanvasObj } from "../components/EditorCanvas";
3
+ import type { EditorSeparation } from "./separations-registry";
4
+ /**
5
+ * One packaging structure — geometry + metadata for a known dieline
6
+ * (pouch, bottle wrap, carton, etc.).
7
+ *
8
+ * `dimensions` is the *trim* size in mm; `bleedMm` is the per-side
9
+ * bleed extension; `trimBox` is the trim rect in mm relative to the
10
+ * full bleed-included page. `previewSvg` is an inline string suitable
11
+ * for thumbnail rendering in the template-picker UI.
12
+ *
13
+ * Distinct from `@artworkpdf/document-model`'s `DielineTemplate`: the
14
+ * shape here is a published, self-contained type so the editor
15
+ * package doesn't force the document-model dep on hosts.
16
+ *
17
+ * @public
18
+ */
2
19
  export type DielineTemplate = {
3
20
  id: string;
4
21
  name: string;
@@ -44,6 +61,15 @@ export type TemplateSet = {
44
61
  tags: string[];
45
62
  isDefault?: boolean;
46
63
  };
64
+ /**
65
+ * All bundled dieline templates, in library declaration order.
66
+ *
67
+ * Mirrors the shape of `data/dielines.json`. Hosts that want a
68
+ * filtered or ordered subset should derive from this array rather
69
+ * than reloading the JSON file.
70
+ *
71
+ * @public
72
+ */
47
73
  export declare const TEMPLATES: DielineTemplate[];
48
74
  /**
49
75
  * Bundled multi-page template sets (e.g. carton front + back). Empty if
@@ -52,7 +78,20 @@ export declare const TEMPLATES: DielineTemplate[];
52
78
  * @public
53
79
  */
54
80
  export declare const TEMPLATE_SETS: TemplateSet[];
81
+ /**
82
+ * Return the library's default template (`isDefault: true`), falling
83
+ * back to the first entry. Throws if the library is empty — that
84
+ * would indicate a packaging defect, not a runtime condition.
85
+ *
86
+ * @public
87
+ */
55
88
  export declare function getDefaultTemplate(): DielineTemplate;
89
+ /**
90
+ * Lookup by template id. Returns `undefined` (not throws) for
91
+ * unknown or missing ids so callers can fall back to a default.
92
+ *
93
+ * @public
94
+ */
56
95
  export declare function getTemplateById(id: string | undefined): DielineTemplate | undefined;
57
96
  /**
58
97
  * Lookup a multi-page template set by id (e.g. `"carton-6x4x2-set"`).
@@ -90,6 +129,11 @@ export type Page = {
90
129
  templateId?: string;
91
130
  /** Human label shown in the page navigator (e.g. "Front", "Back"). */
92
131
  name?: string;
132
+ /** AI4 separations registry — spot inks the user has registered
133
+ * on this page. Threads through to compile-pdf via the
134
+ * job request's `separationsOverride`. Absent → no overrides;
135
+ * empty array → explicit composite-only render. */
136
+ separations?: EditorSeparation[];
93
137
  };
94
138
  /**
95
139
  * Build a {@link Page} from a {@link DielineTemplate}. Mirrors the
@@ -110,6 +154,22 @@ export declare function templatesToPages(entries: ReadonlyArray<{
110
154
  template: DielineTemplate;
111
155
  name?: string;
112
156
  }>, bleedMmOverride?: number): Page[];
157
+ /**
158
+ * Build the initial canvas state for a single template — the dieline
159
+ * trim rect (locked, non-interactive) plus the page size including
160
+ * bleed on all sides.
161
+ *
162
+ * Pass `bleedMmOverride` to use a host-supplied bleed instead of the
163
+ * template's bundled value (e.g. when the user picks a custom bleed
164
+ * in the URL or UI). Returned coordinates are in PDF points
165
+ * (1 mm = 2.83465 pt).
166
+ *
167
+ * Use this for single-page seeds; for multi-page documents use
168
+ * {@link templateToPage} or {@link templatesToPages} which wrap the
169
+ * result in a {@link Page}.
170
+ *
171
+ * @public
172
+ */
113
173
  export declare function templateToInitialState(template: DielineTemplate, bleedMmOverride?: number): {
114
174
  objects: CanvasObj[];
115
175
  pageSize: {
@@ -117,4 +177,31 @@ export declare function templateToInitialState(template: DielineTemplate, bleedM
117
177
  height: number;
118
178
  };
119
179
  };
180
+ /**
181
+ * Build a {@link Page} from a parsed {@link Dieline} (CF2 / DDES /
182
+ * ARD import).
183
+ *
184
+ * Each `DielinePath` becomes one locked `CanvasObj` of type `"path"`
185
+ * rendered as a Konva `Path` (the `Path` import was added to
186
+ * `EditorCanvas` for this case). Type-specific stroke colors come
187
+ * from {@link DIELINE_PATH_STROKES}. The whole page is locked so
188
+ * users can't accidentally drag the structural reference geometry —
189
+ * same invariant as the bundled-template dieline rect.
190
+ *
191
+ * Coordinate units: the parser emits SVG path `d` strings in
192
+ * **dieline-native millimeters** (Y-down). We position each path
193
+ * object at `(bleedMm * MM_TO_PT, bleedMm * MM_TO_PT)` so the dieline
194
+ * trim sits inside the bleed margin. The path data itself is in
195
+ * mm — Konva renders it without further conversion because the
196
+ * containing Stage is configured in points and the relative offsets
197
+ * align (the Stage's own scale handles the mm→pt for display).
198
+ *
199
+ * `bleedMmOverride`: pass a host-supplied bleed (URL param, UI
200
+ * input) instead of the default. Defaults to 0 for parsed dielines —
201
+ * the source files don't carry their own bleed convention and the
202
+ * caller is the right place to decide.
203
+ *
204
+ * @public
205
+ */
206
+ export declare function dielineToPage(dieline: Dieline, bleedMmOverride?: number): Page;
120
207
  //# sourceMappingURL=dieline-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dieline-template.d.ts","sourceRoot":"","sources":["../../src/lib/dieline-template.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dieline-template.d.ts","sourceRoot":"","sources":["../../src/lib/dieline-template.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,17 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ //
3
+ // Dieline-template bundle + helpers for seeding the editor canvas.
4
+ //
5
+ // The shipped JSON library (`data/dielines.json`) gets loaded eagerly
6
+ // so server components (Next.js RSC, Astro frontmatter) can pick a
7
+ // template and produce initial Page state without touching the
8
+ // browser-only editor bundle.
9
+ //
10
+ // `dielineToPage()` is the parallel ingress for user-supplied CF2 /
11
+ // DDES / ARD files (parsed via `@artworkpdf/dieline-parser`'s
12
+ // `parseCF2` / `parseDDES` / `parseARD`) — each parsed `Dieline`
13
+ // becomes a single-page `Page` seeded with one locked path per
14
+ // `DielinePath`.
1
15
  import library from "../data/dielines.json";
2
16
  const MM_TO_PT = 2.83465;
3
17
  /** Stroke color + display name for the dieline trim rect. The dieline
@@ -6,6 +20,15 @@ const MM_TO_PT = 2.83465;
6
20
  export const DIELINE_STROKE = "#fc5102";
7
21
  export const DIELINE_NAME = "Die Line";
8
22
  const LIBRARY = library;
23
+ /**
24
+ * All bundled dieline templates, in library declaration order.
25
+ *
26
+ * Mirrors the shape of `data/dielines.json`. Hosts that want a
27
+ * filtered or ordered subset should derive from this array rather
28
+ * than reloading the JSON file.
29
+ *
30
+ * @public
31
+ */
9
32
  export const TEMPLATES = LIBRARY.templates;
10
33
  /**
11
34
  * Bundled multi-page template sets (e.g. carton front + back). Empty if
@@ -14,6 +37,13 @@ export const TEMPLATES = LIBRARY.templates;
14
37
  * @public
15
38
  */
16
39
  export const TEMPLATE_SETS = LIBRARY.templateSets ?? [];
40
+ /**
41
+ * Return the library's default template (`isDefault: true`), falling
42
+ * back to the first entry. Throws if the library is empty — that
43
+ * would indicate a packaging defect, not a runtime condition.
44
+ *
45
+ * @public
46
+ */
17
47
  export function getDefaultTemplate() {
18
48
  const flagged = TEMPLATES.find((t) => t.isDefault);
19
49
  if (flagged)
@@ -23,6 +53,12 @@ export function getDefaultTemplate() {
23
53
  throw new Error("dielines.json contains no templates");
24
54
  return first;
25
55
  }
56
+ /**
57
+ * Lookup by template id. Returns `undefined` (not throws) for
58
+ * unknown or missing ids so callers can fall back to a default.
59
+ *
60
+ * @public
61
+ */
26
62
  export function getTemplateById(id) {
27
63
  if (!id)
28
64
  return undefined;
@@ -85,6 +121,22 @@ export function templateToPage(template, bleedMmOverride, name) {
85
121
  export function templatesToPages(entries, bleedMmOverride) {
86
122
  return entries.map(({ template, name }) => templateToPage(template, bleedMmOverride, name));
87
123
  }
124
+ /**
125
+ * Build the initial canvas state for a single template — the dieline
126
+ * trim rect (locked, non-interactive) plus the page size including
127
+ * bleed on all sides.
128
+ *
129
+ * Pass `bleedMmOverride` to use a host-supplied bleed instead of the
130
+ * template's bundled value (e.g. when the user picks a custom bleed
131
+ * in the URL or UI). Returned coordinates are in PDF points
132
+ * (1 mm = 2.83465 pt).
133
+ *
134
+ * Use this for single-page seeds; for multi-page documents use
135
+ * {@link templateToPage} or {@link templatesToPages} which wrap the
136
+ * result in a {@link Page}.
137
+ *
138
+ * @public
139
+ */
88
140
  export function templateToInitialState(template, bleedMmOverride) {
89
141
  const bleedMm = bleedMmOverride ?? template.bleedMm;
90
142
  const pageSize = {
@@ -111,4 +163,115 @@ export function templateToInitialState(template, bleedMmOverride) {
111
163
  };
112
164
  return { objects: [dielineObj], pageSize };
113
165
  }
166
+ /**
167
+ * Stroke color per DielinePath type. Chosen to match the
168
+ * print-industry conventions our preview uses elsewhere:
169
+ *
170
+ * - cut — orange (brand, same as bundled DIELINE_STROKE)
171
+ * - crease — blue (folding score)
172
+ * - perf — red (perforation)
173
+ * - bleed — cyan (bleed edge / safety boundary)
174
+ */
175
+ const DIELINE_PATH_STROKES = {
176
+ cut: DIELINE_STROKE,
177
+ crease: "#1e90ff",
178
+ perf: "#ef4444",
179
+ bleed: "#0ea5e9",
180
+ };
181
+ /**
182
+ * Scale every coordinate in an SVG `d` string from millimeters to
183
+ * PDF points (multiply by `MM_TO_PT`).
184
+ *
185
+ * The dieline-parser emits absolute `M` / `L` / `A` commands in
186
+ * dieline-native millimeters. The editor's Konva Stage is configured
187
+ * in PDF points (the canvas / pageSize math is all in points), so
188
+ * the raw `d` string would render at ~35% of intended size if used
189
+ * directly. We pre-scale here so `pathData` matches the canvas unit
190
+ * system end-to-end (no Konva.Path `scaleX` / `scaleY` shenanigans
191
+ * that would also scale stroke width).
192
+ *
193
+ * Per-command coordinate slots:
194
+ * - `M x,y` / `L x,y` → both coordinates are positions; scale all.
195
+ * - `A rx,ry,xRot,largeArc,sweep,x,y` → rx and ry are radii (scale),
196
+ * xRot is degrees (pass through), the two flags are 0/1 (pass
197
+ * through), the trailing x,y are positions (scale).
198
+ *
199
+ * Unknown commands pass through unchanged. The parser's output only
200
+ * uses M / L / A so the full SVG-path alphabet doesn't need handling.
201
+ */
202
+ function scalePathMmToPt(d) {
203
+ return d.replace(/([MLA])\s*([\d.,\s-]+)/g, (_, cmd, args) => {
204
+ const nums = args
205
+ .trim()
206
+ .split(/[\s,]+/)
207
+ .map(Number)
208
+ .filter((n) => !Number.isNaN(n));
209
+ if (cmd === "A") {
210
+ // Arc: rx, ry, xRot, largeArc, sweep, x, y — scale rx, ry, x, y; pass others.
211
+ const out = [];
212
+ for (let i = 0; i + 6 < nums.length; i += 7) {
213
+ out.push((nums[i] ?? 0) * MM_TO_PT, (nums[i + 1] ?? 0) * MM_TO_PT, nums[i + 2] ?? 0, nums[i + 3] ?? 0, nums[i + 4] ?? 0, (nums[i + 5] ?? 0) * MM_TO_PT, (nums[i + 6] ?? 0) * MM_TO_PT);
214
+ }
215
+ return `${cmd}${out.join(",")}`;
216
+ }
217
+ // M / L: alternating x,y pairs.
218
+ return `${cmd}${nums.map((n) => n * MM_TO_PT).join(",")}`;
219
+ });
220
+ }
221
+ /**
222
+ * Build a {@link Page} from a parsed {@link Dieline} (CF2 / DDES /
223
+ * ARD import).
224
+ *
225
+ * Each `DielinePath` becomes one locked `CanvasObj` of type `"path"`
226
+ * rendered as a Konva `Path` (the `Path` import was added to
227
+ * `EditorCanvas` for this case). Type-specific stroke colors come
228
+ * from {@link DIELINE_PATH_STROKES}. The whole page is locked so
229
+ * users can't accidentally drag the structural reference geometry —
230
+ * same invariant as the bundled-template dieline rect.
231
+ *
232
+ * Coordinate units: the parser emits SVG path `d` strings in
233
+ * **dieline-native millimeters** (Y-down). We position each path
234
+ * object at `(bleedMm * MM_TO_PT, bleedMm * MM_TO_PT)` so the dieline
235
+ * trim sits inside the bleed margin. The path data itself is in
236
+ * mm — Konva renders it without further conversion because the
237
+ * containing Stage is configured in points and the relative offsets
238
+ * align (the Stage's own scale handles the mm→pt for display).
239
+ *
240
+ * `bleedMmOverride`: pass a host-supplied bleed (URL param, UI
241
+ * input) instead of the default. Defaults to 0 for parsed dielines —
242
+ * the source files don't carry their own bleed convention and the
243
+ * caller is the right place to decide.
244
+ *
245
+ * @public
246
+ */
247
+ export function dielineToPage(dieline, bleedMmOverride) {
248
+ const bleedMm = bleedMmOverride ?? 0;
249
+ const pageSize = {
250
+ width: (dieline.widthMm + bleedMm * 2) * MM_TO_PT,
251
+ height: (dieline.heightMm + bleedMm * 2) * MM_TO_PT,
252
+ };
253
+ const bleedOffsetPt = bleedMm * MM_TO_PT;
254
+ const objects = dieline.paths.map((p) => ({
255
+ id: `dieline-${dieline.format.toLowerCase()}-${p.id}`,
256
+ type: "path",
257
+ x: bleedOffsetPt,
258
+ y: bleedOffsetPt,
259
+ width: 0,
260
+ height: 0,
261
+ fill: "transparent",
262
+ stroke: DIELINE_PATH_STROKES[p.type],
263
+ strokeWidth: 1,
264
+ opacity: 1,
265
+ // Pre-scale mm → pt so pathData matches the canvas unit system.
266
+ pathData: scalePathMmToPt(p.d),
267
+ name: `${dieline.format} ${p.type}`,
268
+ locked: true,
269
+ }));
270
+ return {
271
+ id: `page-${dieline.format.toLowerCase()}-${Math.random().toString(36).slice(2, 8)}`,
272
+ objects,
273
+ pageSize,
274
+ bleedMm,
275
+ };
276
+ }
114
277
  //# sourceMappingURL=dieline-template.js.map