@tangle-network/agent-app 0.11.1 → 0.13.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 (61) hide show
  1. package/dist/DesignCanvas-3JEEIT6Y.js +10 -0
  2. package/dist/DesignCanvas-3JEEIT6Y.js.map +1 -0
  3. package/dist/DesignCanvasEditor-37LPJIIR.js +9 -0
  4. package/dist/DesignCanvasEditor-37LPJIIR.js.map +1 -0
  5. package/dist/TimelineEditor-OXPJZDP2.js +12 -0
  6. package/dist/TimelineEditor-OXPJZDP2.js.map +1 -0
  7. package/dist/apply-Cp8c3K9D.d.ts +249 -0
  8. package/dist/chunk-2Q73HGDI.js +1743 -0
  9. package/dist/chunk-2Q73HGDI.js.map +1 -0
  10. package/dist/chunk-6UOE5CTA.js +1647 -0
  11. package/dist/chunk-6UOE5CTA.js.map +1 -0
  12. package/dist/chunk-7QCIYDGC.js +1119 -0
  13. package/dist/chunk-7QCIYDGC.js.map +1 -0
  14. package/dist/chunk-A76ZHWNF.js +194 -0
  15. package/dist/chunk-A76ZHWNF.js.map +1 -0
  16. package/dist/chunk-ABGSFUJQ.js +111 -0
  17. package/dist/chunk-ABGSFUJQ.js.map +1 -0
  18. package/dist/{chunk-4YTWB5MG.js → chunk-ETX4O4BB.js} +98 -1
  19. package/dist/chunk-ETX4O4BB.js.map +1 -0
  20. package/dist/chunk-F5KTWRO7.js +2276 -0
  21. package/dist/chunk-F5KTWRO7.js.map +1 -0
  22. package/dist/chunk-IHR6K3GF.js +2367 -0
  23. package/dist/chunk-IHR6K3GF.js.map +1 -0
  24. package/dist/chunk-JZAJE3JL.js +990 -0
  25. package/dist/chunk-JZAJE3JL.js.map +1 -0
  26. package/dist/chunk-ZYBWGSAZ.js +130 -0
  27. package/dist/chunk-ZYBWGSAZ.js.map +1 -0
  28. package/dist/design-canvas/drizzle.d.ts +569 -0
  29. package/dist/design-canvas/drizzle.js +183 -0
  30. package/dist/design-canvas/drizzle.js.map +1 -0
  31. package/dist/design-canvas/index.d.ts +261 -0
  32. package/dist/design-canvas/index.js +96 -0
  33. package/dist/design-canvas/index.js.map +1 -0
  34. package/dist/design-canvas-react/index.d.ts +916 -0
  35. package/dist/design-canvas-react/index.js +423 -0
  36. package/dist/design-canvas-react/index.js.map +1 -0
  37. package/dist/export-presets-Dl5Aa5xj.d.ts +284 -0
  38. package/dist/index.d.ts +11 -2
  39. package/dist/index.js +224 -6
  40. package/dist/mcp-CIupfjxV.d.ts +112 -0
  41. package/dist/mcp-rpc-DLw_r9PQ.d.ts +55 -0
  42. package/dist/model-BHLN208Z.d.ts +183 -0
  43. package/dist/runtime/index.d.ts +108 -1
  44. package/dist/runtime/index.js +7 -1
  45. package/dist/sequences/drizzle.d.ts +1244 -0
  46. package/dist/sequences/drizzle.js +368 -0
  47. package/dist/sequences/drizzle.js.map +1 -0
  48. package/dist/sequences/index.d.ts +331 -0
  49. package/dist/sequences/index.js +114 -0
  50. package/dist/sequences/index.js.map +1 -0
  51. package/dist/sequences-react/index.d.ts +752 -0
  52. package/dist/sequences-react/index.js +241 -0
  53. package/dist/sequences-react/index.js.map +1 -0
  54. package/dist/store-CUStmtdH.d.ts +64 -0
  55. package/dist/store-gckrNq-g.d.ts +242 -0
  56. package/dist/tools/index.d.ts +25 -108
  57. package/dist/tools/index.js +16 -6
  58. package/package.json +62 -2
  59. package/dist/chunk-4YTWB5MG.js.map +0 -1
  60. package/dist/chunk-OLCVUGGI.js +0 -137
  61. package/dist/chunk-OLCVUGGI.js.map +0 -1
@@ -0,0 +1,423 @@
1
+ import {
2
+ DUPLICATE_OFFSET,
3
+ DesignCanvasEditor,
4
+ ElementNode,
5
+ GridLayer,
6
+ SelectionLayer,
7
+ Workspace,
8
+ WorkspaceView,
9
+ bakeLineTransform,
10
+ bakeRectTransform,
11
+ bakeTextTransform,
12
+ collectGridTargets,
13
+ createSnapEngine,
14
+ createZoomPanMath,
15
+ marqueeSelect,
16
+ nudgeDelta
17
+ } from "../chunk-2Q73HGDI.js";
18
+ import {
19
+ DesignCanvas,
20
+ EllipseGlyph,
21
+ EyeGlyph,
22
+ EyeOffGlyph,
23
+ GroupGlyph,
24
+ ImageGlyph,
25
+ LineGlyph,
26
+ LockGlyph,
27
+ PagesStrip,
28
+ RectGlyph,
29
+ Rulers,
30
+ SCENE_COMMAND_HISTORY_LIMIT,
31
+ SlotGlyph,
32
+ TextGlyph,
33
+ Toolbar,
34
+ UnlockGlyph,
35
+ VideoGlyph,
36
+ ZoomControls,
37
+ addElementCommand,
38
+ addPageCommand,
39
+ bindSlotCommand,
40
+ buildRulerTicks,
41
+ createSceneCommandStack,
42
+ deleteElementCommand,
43
+ deletePageCommand,
44
+ duplicatePageCommand,
45
+ formatRulerLabel,
46
+ groupElementsCommand,
47
+ multiSetAttrsCommand,
48
+ reorderElementCommand,
49
+ reorderPageCommand,
50
+ selectTickStep,
51
+ setAttrsCommand,
52
+ setDocumentTitleCommand,
53
+ setPageGuidesCommand,
54
+ setPagePropsCommand,
55
+ ungroupElementCommand
56
+ } from "../chunk-F5KTWRO7.js";
57
+ import {
58
+ SCENE_SCHEMA_VERSION,
59
+ bleedAwareExportBounds,
60
+ scaleForPreset
61
+ } from "../chunk-JZAJE3JL.js";
62
+
63
+ // src/design-canvas-react/export-math.ts
64
+ function isExportHiddenNodeName(name) {
65
+ return name.startsWith("overlay:") || name === "Transformer";
66
+ }
67
+ function resolveExportParams(page, opts) {
68
+ const includeBleed = opts.preset !== void 0 ? opts.preset.includeBleed : opts.includeBleed ?? false;
69
+ const cropRect = bleedAwareExportBounds(page, includeBleed);
70
+ const pixelRatio = opts.preset !== void 0 ? scaleForPreset(opts.preset, cropRect) : opts.pixelRatio ?? 1;
71
+ const format = opts.preset !== void 0 ? opts.preset.format : opts.format;
72
+ const mimeType = format === "jpeg" ? "image/jpeg" : "image/png";
73
+ return {
74
+ cropRect,
75
+ pixelRatio,
76
+ mimeType,
77
+ quality: format === "jpeg" ? 0.92 : void 0
78
+ };
79
+ }
80
+ function identifyTaintedSrc(imageSrcs) {
81
+ for (const { src } of imageSrcs) {
82
+ if (isCrossOriginSrc(src)) return src;
83
+ }
84
+ return null;
85
+ }
86
+ function isCrossOriginSrc(src) {
87
+ return /^https?:\/\//i.test(src);
88
+ }
89
+ function documentCropToStageCoords(cropRect, stageScale, stageX, stageY) {
90
+ return {
91
+ x: stageX + cropRect.x * stageScale,
92
+ y: stageY + cropRect.y * stageScale,
93
+ width: cropRect.width * stageScale,
94
+ height: cropRect.height * stageScale
95
+ };
96
+ }
97
+
98
+ // src/design-canvas-react/export.ts
99
+ async function exportPageDataUrl(stage, page, opts) {
100
+ const { cropRect, pixelRatio, mimeType, quality } = resolveExportParams(page, opts);
101
+ const imageSrcs = collectImageSrcs(stage);
102
+ const hiddenNodes = [];
103
+ for (const layer of stage.getLayers()) {
104
+ for (const node of layer.getChildren()) {
105
+ const name = node.name();
106
+ if (isExportHiddenNodeName(name) && node.visible()) {
107
+ node.visible(false);
108
+ hiddenNodes.push(node);
109
+ }
110
+ }
111
+ }
112
+ const stageScale = stage.scaleX();
113
+ const stageCrop = documentCropToStageCoords(cropRect, stageScale, stage.x(), stage.y());
114
+ let dataUrl;
115
+ try {
116
+ dataUrl = stage.toDataURL({
117
+ mimeType,
118
+ ...quality !== void 0 ? { quality } : {},
119
+ pixelRatio,
120
+ x: stageCrop.x,
121
+ y: stageCrop.y,
122
+ width: stageCrop.width,
123
+ height: stageCrop.height
124
+ });
125
+ } catch (err) {
126
+ for (const node of hiddenNodes) {
127
+ node.visible(true);
128
+ }
129
+ if (err instanceof Error && err.name === "SecurityError") {
130
+ const taintedSrc = identifyTaintedSrc(imageSrcs);
131
+ if (taintedSrc !== null) {
132
+ throw new Error(
133
+ `Export failed: image source is CORS-tainted and cannot be read by the canvas. Offending src: "${taintedSrc}". Ensure the image is served with Access-Control-Allow-Origin or use a proxied /api/ path.`
134
+ );
135
+ }
136
+ throw new Error(
137
+ `Export failed: a canvas SecurityError occurred but no cross-origin image src could be identified. The stage may contain a tainted video or image loaded without CORS headers.`
138
+ );
139
+ }
140
+ throw err;
141
+ }
142
+ for (const node of hiddenNodes) {
143
+ node.visible(true);
144
+ }
145
+ return dataUrl;
146
+ }
147
+ function collectImageSrcs(stage) {
148
+ const result = [];
149
+ for (const layer of stage.getLayers()) {
150
+ for (const node of layer.getChildren()) {
151
+ const src = node.getAttr("src");
152
+ if (typeof src === "string" && src.length > 0) {
153
+ result.push({ name: node.name(), src });
154
+ }
155
+ }
156
+ }
157
+ return result;
158
+ }
159
+ function exportDocumentJson(document) {
160
+ if (document.schemaVersion !== SCENE_SCHEMA_VERSION) {
161
+ throw new Error(
162
+ `exportDocumentJson: document schemaVersion is ${document.schemaVersion}, expected ${SCENE_SCHEMA_VERSION} \u2014 upgrade the document before exporting`
163
+ );
164
+ }
165
+ return JSON.stringify(document, null, 2);
166
+ }
167
+ function downloadDataUrl(dataUrl, filename) {
168
+ if (typeof globalThis.document === "undefined") return;
169
+ const a = globalThis.document.createElement("a");
170
+ a.href = dataUrl;
171
+ a.download = filename;
172
+ a.style.display = "none";
173
+ globalThis.document.body.appendChild(a);
174
+ a.click();
175
+ globalThis.document.body.removeChild(a);
176
+ }
177
+
178
+ // src/design-canvas-react/components/LayersPanel.tsx
179
+ import { useMemo, useRef, useState } from "react";
180
+
181
+ // src/design-canvas-react/components/layer-tree.ts
182
+ function flattenLayerTree(page) {
183
+ const rows = [];
184
+ function visit(elements, depth, parentGroupId) {
185
+ for (let i = elements.length - 1; i >= 0; i -= 1) {
186
+ const element = elements[i];
187
+ rows.push({
188
+ element,
189
+ depth,
190
+ isGroup: element.kind === "group",
191
+ ownerIndex: i,
192
+ ownerLength: elements.length,
193
+ parentGroupId
194
+ });
195
+ if (element.kind === "group") {
196
+ visit(element.children, depth + 1, element.id);
197
+ }
198
+ }
199
+ }
200
+ visit(page.elements, 0, null);
201
+ return rows;
202
+ }
203
+ var LAYERS_PANEL_ROW_LIMIT = 500;
204
+
205
+ // src/design-canvas-react/components/LayersPanel.tsx
206
+ import { jsx, jsxs } from "react/jsx-runtime";
207
+ function KindIcon({ kind, className }) {
208
+ switch (kind) {
209
+ case "rect":
210
+ return /* @__PURE__ */ jsx(RectGlyph, { className });
211
+ case "ellipse":
212
+ return /* @__PURE__ */ jsx(EllipseGlyph, { className });
213
+ case "line":
214
+ return /* @__PURE__ */ jsx(LineGlyph, { className });
215
+ case "text":
216
+ return /* @__PURE__ */ jsx(TextGlyph, { className });
217
+ case "image":
218
+ return /* @__PURE__ */ jsx(ImageGlyph, { className });
219
+ case "video":
220
+ return /* @__PURE__ */ jsx(VideoGlyph, { className });
221
+ case "group":
222
+ return /* @__PURE__ */ jsx(GroupGlyph, { className });
223
+ }
224
+ }
225
+ var INDENT_PX = 16;
226
+ function LayersPanel({ page, selectedElementIds, canWrite, onSetAttrs, onReorder, onSelect }) {
227
+ const rows = useMemo(() => flattenLayerTree(page), [page]);
228
+ const [renamingId, setRenamingId] = useState(null);
229
+ const [renameValue, setRenameValue] = useState("");
230
+ const dragRowRef = useRef(null);
231
+ const [dragOverIndex, setDragOverIndex] = useState(null);
232
+ function startRename(element) {
233
+ setRenamingId(element.id);
234
+ setRenameValue(element.name);
235
+ }
236
+ function commitRename(elementId) {
237
+ const name = renameValue.trim();
238
+ if (name.length > 0) onSetAttrs(elementId, { name });
239
+ setRenamingId(null);
240
+ }
241
+ const visible = rows.length > LAYERS_PANEL_ROW_LIMIT ? rows.slice(0, LAYERS_PANEL_ROW_LIMIT) : rows;
242
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden text-[var(--text-primary)]", children: [
243
+ /* @__PURE__ */ jsx("div", { className: "shrink-0 border-b border-[var(--border-default)] px-3 py-1.5 text-[11px] font-medium uppercase tracking-wide text-[var(--text-muted)]", children: "Layers" }),
244
+ /* @__PURE__ */ jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto", children: [
245
+ visible.map((row) => {
246
+ const { element } = row;
247
+ const isSelected = selectedElementIds.includes(element.id);
248
+ const isRenaming = renamingId === element.id;
249
+ return /* @__PURE__ */ jsxs(
250
+ "div",
251
+ {
252
+ "data-layer-row": element.id,
253
+ draggable: canWrite,
254
+ onDragStart: () => {
255
+ dragRowRef.current = {
256
+ elementId: element.id,
257
+ ownerIndex: row.ownerIndex,
258
+ ownerLength: row.ownerLength
259
+ };
260
+ },
261
+ onDragOver: (event) => {
262
+ if (!dragRowRef.current) return;
263
+ event.preventDefault();
264
+ setDragOverIndex(row.ownerIndex);
265
+ },
266
+ onDragLeave: () => setDragOverIndex(null),
267
+ onDrop: () => {
268
+ const drag = dragRowRef.current;
269
+ if (!drag) return;
270
+ if (drag.elementId !== element.id) {
271
+ onReorder(drag.elementId, row.ownerIndex);
272
+ }
273
+ dragRowRef.current = null;
274
+ setDragOverIndex(null);
275
+ },
276
+ onDragEnd: () => {
277
+ dragRowRef.current = null;
278
+ setDragOverIndex(null);
279
+ },
280
+ onClick: (event) => onSelect(element.id, event.metaKey || event.ctrlKey),
281
+ className: [
282
+ "flex cursor-pointer items-center gap-1.5 py-1 pr-2 text-[13px] transition-colors",
283
+ isSelected ? "bg-[var(--brand-primary)]/15 text-[var(--text-primary)]" : "hover:bg-[var(--border-default)]/40 text-[var(--text-secondary)]",
284
+ dragOverIndex === row.ownerIndex ? "border-t border-[var(--brand-primary)]" : ""
285
+ ].join(" "),
286
+ style: { paddingLeft: 8 + row.depth * INDENT_PX },
287
+ children: [
288
+ /* @__PURE__ */ jsx(KindIcon, { kind: element.kind, className: "h-3.5 w-3.5 shrink-0 opacity-60" }),
289
+ element.slot ? /* @__PURE__ */ jsx(SlotGlyph, { className: "h-3 w-3 shrink-0 text-[var(--brand-primary)]" }) : null,
290
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: isRenaming ? /* @__PURE__ */ jsx(
291
+ "input",
292
+ {
293
+ autoFocus: true,
294
+ value: renameValue,
295
+ onChange: (event) => setRenameValue(event.target.value),
296
+ onBlur: () => commitRename(element.id),
297
+ onKeyDown: (event) => {
298
+ if (event.key === "Enter") commitRename(element.id);
299
+ if (event.key === "Escape") setRenamingId(null);
300
+ event.stopPropagation();
301
+ },
302
+ onClick: (event) => event.stopPropagation(),
303
+ className: "w-full rounded border border-[var(--border-default)] bg-[var(--bg-input)] px-1 py-0 text-[13px] text-[var(--text-primary)] outline-none focus:border-[var(--brand-primary)]"
304
+ }
305
+ ) : /* @__PURE__ */ jsx(
306
+ "span",
307
+ {
308
+ onDoubleClick: (event) => {
309
+ event.stopPropagation();
310
+ if (canWrite) startRename(element);
311
+ },
312
+ title: element.name,
313
+ children: element.name
314
+ }
315
+ ) }),
316
+ /* @__PURE__ */ jsx(
317
+ "button",
318
+ {
319
+ type: "button",
320
+ "aria-label": element.visible ? "Hide element" : "Show element",
321
+ onClick: (event) => {
322
+ event.stopPropagation();
323
+ if (canWrite) onSetAttrs(element.id, { visible: !element.visible });
324
+ },
325
+ disabled: !canWrite,
326
+ className: "shrink-0 rounded p-0.5 opacity-0 transition-opacity hover:opacity-100 focus:opacity-100 group-hover:opacity-100 [.flex:hover_&]:opacity-60",
327
+ children: element.visible ? /* @__PURE__ */ jsx(EyeGlyph, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(EyeOffGlyph, { className: "h-3.5 w-3.5 text-[var(--text-muted)]" })
328
+ }
329
+ ),
330
+ /* @__PURE__ */ jsx(
331
+ "button",
332
+ {
333
+ type: "button",
334
+ "aria-label": element.locked ? "Unlock element" : "Lock element",
335
+ onClick: (event) => {
336
+ event.stopPropagation();
337
+ if (canWrite) onSetAttrs(element.id, { locked: !element.locked });
338
+ },
339
+ disabled: !canWrite,
340
+ className: "shrink-0 rounded p-0.5 opacity-0 transition-opacity hover:opacity-100 focus:opacity-100 [.flex:hover_&]:opacity-60",
341
+ children: element.locked ? /* @__PURE__ */ jsx(LockGlyph, { className: "h-3.5 w-3.5 text-amber-400" }) : /* @__PURE__ */ jsx(UnlockGlyph, { className: "h-3.5 w-3.5" })
342
+ }
343
+ )
344
+ ]
345
+ },
346
+ element.id
347
+ );
348
+ }),
349
+ rows.length > LAYERS_PANEL_ROW_LIMIT ? /* @__PURE__ */ jsxs("div", { className: "px-3 py-2 text-[11px] text-[var(--text-muted)]", children: [
350
+ "+",
351
+ rows.length - LAYERS_PANEL_ROW_LIMIT,
352
+ " more elements \u2014 select a group to scope the list"
353
+ ] }) : null
354
+ ] })
355
+ ] });
356
+ }
357
+
358
+ // src/design-canvas-react/lazy.tsx
359
+ import { lazy } from "react";
360
+ var DesignCanvasLazy = lazy(
361
+ () => import("../DesignCanvasEditor-37LPJIIR.js").then((m) => ({ default: m.DesignCanvasEditor }))
362
+ );
363
+ var DesignCanvasChromeLazy = lazy(
364
+ () => import("../DesignCanvas-3JEEIT6Y.js").then((m) => ({ default: m.DesignCanvas }))
365
+ );
366
+ export {
367
+ DUPLICATE_OFFSET,
368
+ DesignCanvas,
369
+ DesignCanvasChromeLazy,
370
+ DesignCanvasEditor,
371
+ DesignCanvasLazy,
372
+ ElementNode,
373
+ GridLayer,
374
+ LAYERS_PANEL_ROW_LIMIT,
375
+ LayersPanel,
376
+ PagesStrip,
377
+ Rulers,
378
+ SCENE_COMMAND_HISTORY_LIMIT,
379
+ SelectionLayer,
380
+ Toolbar,
381
+ Workspace,
382
+ WorkspaceView,
383
+ ZoomControls,
384
+ addElementCommand,
385
+ addPageCommand,
386
+ bakeLineTransform,
387
+ bakeRectTransform,
388
+ bakeTextTransform,
389
+ bindSlotCommand,
390
+ bleedAwareExportBounds,
391
+ buildRulerTicks,
392
+ collectGridTargets,
393
+ createSceneCommandStack,
394
+ createSnapEngine,
395
+ createZoomPanMath,
396
+ deleteElementCommand,
397
+ deletePageCommand,
398
+ documentCropToStageCoords,
399
+ downloadDataUrl,
400
+ duplicatePageCommand,
401
+ exportDocumentJson,
402
+ exportPageDataUrl,
403
+ flattenLayerTree,
404
+ formatRulerLabel,
405
+ groupElementsCommand,
406
+ identifyTaintedSrc,
407
+ isCrossOriginSrc,
408
+ isExportHiddenNodeName,
409
+ marqueeSelect,
410
+ multiSetAttrsCommand,
411
+ nudgeDelta,
412
+ reorderElementCommand,
413
+ reorderPageCommand,
414
+ resolveExportParams,
415
+ scaleForPreset,
416
+ selectTickStep,
417
+ setAttrsCommand,
418
+ setDocumentTitleCommand,
419
+ setPageGuidesCommand,
420
+ setPagePropsCommand,
421
+ ungroupElementCommand
422
+ };
423
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/design-canvas-react/export-math.ts","../../src/design-canvas-react/export.ts","../../src/design-canvas-react/components/LayersPanel.tsx","../../src/design-canvas-react/components/layer-tree.ts","../../src/design-canvas-react/lazy.tsx"],"sourcesContent":["/**\n * Pure export math for the design-canvas surface — no Konva, no DOM, no React.\n *\n * All stage-interaction code (save/restore, node visibility, toDataURL) lives\n * in export.ts and delegates the decision math here so it can be tested\n * without a canvas environment.\n */\n\nimport type { ScenePage } from '../design-canvas/model'\nimport {\n bleedAwareExportBounds,\n scaleForPreset,\n type ExportCropRect,\n type ExportPreset,\n} from '../design-canvas/export-presets'\n\n// ---------------------------------------------------------------------------\n// Re-exports so callers only import from one place\n// ---------------------------------------------------------------------------\n\nexport type { ExportCropRect, ExportPreset }\nexport { bleedAwareExportBounds, scaleForPreset }\n\n// ---------------------------------------------------------------------------\n// Overlay / transformer node name predicates\n// ---------------------------------------------------------------------------\n\n/** Returns true for any Konva node that must be hidden during export. Nodes\n * whose names start with 'overlay:' are editor-only chrome (snap lines,\n * selection indicators, rulers, bleed guides). The transformer node is\n * identified by its canonical name 'Transformer'. */\nexport function isExportHiddenNodeName(name: string): boolean {\n return name.startsWith('overlay:') || name === 'Transformer'\n}\n\n// ---------------------------------------------------------------------------\n// Crop rect + pixel ratio resolution\n// ---------------------------------------------------------------------------\n\nexport interface ResolvedExportParams {\n cropRect: ExportCropRect\n pixelRatio: number\n mimeType: 'image/png' | 'image/jpeg'\n quality: number | undefined\n}\n\n/**\n * Resolve the full set of toDataURL params from a page, format, pixel ratio,\n * bleed flag, and optional preset. When a preset is supplied it overrides\n * `pixelRatio` and `includeBleed` — the explicit args are ignored for those\n * two values so the preset is the single source of truth.\n *\n * `quality` is set to 0.92 for jpeg, undefined for png (Konva ignores it).\n */\nexport function resolveExportParams(\n page: ScenePage,\n opts: {\n format: 'png' | 'jpeg'\n pixelRatio?: number\n includeBleed?: boolean\n preset?: ExportPreset\n },\n): ResolvedExportParams {\n const includeBleed = opts.preset !== undefined\n ? opts.preset.includeBleed\n : (opts.includeBleed ?? false)\n\n const cropRect = bleedAwareExportBounds(page, includeBleed)\n\n const pixelRatio = opts.preset !== undefined\n ? scaleForPreset(opts.preset, cropRect)\n : (opts.pixelRatio ?? 1)\n\n const format = opts.preset !== undefined ? opts.preset.format : opts.format\n const mimeType: 'image/png' | 'image/jpeg' = format === 'jpeg' ? 'image/jpeg' : 'image/png'\n\n return {\n cropRect,\n pixelRatio,\n mimeType,\n quality: format === 'jpeg' ? 0.92 : undefined,\n }\n}\n\n// ---------------------------------------------------------------------------\n// CORS taint detection\n// ---------------------------------------------------------------------------\n\n/**\n * Walk image nodes to find the src of any that may have caused a SecurityError\n * when the stage called toDataURL. Returns the first offending src found, or\n * null if none can be identified.\n *\n * `imageSrcs` is a flat list of { name, src } records collected from all image\n * nodes on the stage before calling toDataURL — export.ts builds it before\n * attempting the export so that if the SecurityError fires we have the data.\n */\nexport function identifyTaintedSrc(imageSrcs: ReadonlyArray<{ name: string; src: string }>): string | null {\n // We cannot re-probe CORS from a caught SecurityError — the browser does not\n // tell us which src triggered it. Return the first src that looks like a\n // cross-origin resource the browser would taint: anything that is not a\n // same-origin relative path or a data: URL.\n for (const { src } of imageSrcs) {\n if (isCrossOriginSrc(src)) return src\n }\n return null\n}\n\n/**\n * Heuristic: a src is potentially cross-origin when it is an absolute http(s)\n * URL. Same-origin relative paths (/api/...) and data: blobs are safe.\n * This is intentionally conservative — the taint check runs only after a\n * SecurityError fires, so a false positive is \"blamed\" without being silently\n * ignored. NOTE: same-origin https:// assets will also match; if a\n * SecurityError fires, the cross-origin culprit may be a different image than\n * the one this function flags first.\n */\nexport function isCrossOriginSrc(src: string): boolean {\n return /^https?:\\/\\//i.test(src)\n}\n\n// ---------------------------------------------------------------------------\n// View state snapshot (used by save/restore helpers)\n// ---------------------------------------------------------------------------\n\n/** Minimal snapshot of stage view state that export.ts saves before mutating\n * zoom/pan/visibility and restores afterward. */\nexport interface ExportViewSnapshot {\n /** Stage scale factor before export. */\n scaleX: number\n scaleY: number\n /** Stage translation before export. */\n x: number\n y: number\n /** node name → prior visibility, for the nodes that were hidden. */\n hiddenNodeNames: string[]\n}\n\n/**\n * Build the toDataURL crop rect translated to stage output coordinates.\n * Konva's `stage.toDataURL({ x, y, width, height })` takes STAGE OUTPUT\n * coordinates, not document coordinates. When the stage has been scaled to fit\n * (zoom × stageScale), the crop rect in document px must be multiplied by the\n * combined scale to land on the right pixels.\n *\n * `stageScale` is the stage's current uniform scale (scaleX == scaleY);\n * `pixelRatio` is separate and handed directly to toDataURL — Konva multiplies\n * it internally when rendering to the backing canvas, so we must NOT include\n * it in the stage-coordinate rect.\n */\nexport function documentCropToStageCoords(\n cropRect: ExportCropRect,\n stageScale: number,\n stageX: number,\n stageY: number,\n): { x: number; y: number; width: number; height: number } {\n return {\n x: stageX + cropRect.x * stageScale,\n y: stageY + cropRect.y * stageScale,\n width: cropRect.width * stageScale,\n height: cropRect.height * stageScale,\n }\n}\n","/**\n * Client-side export for design-canvas pages: raster (PNG/JPEG via Konva\n * stage.toDataURL) and JSON (document serialisation).\n *\n * The heavy lifting — crop math, pixel ratio resolution, CORS taint detection\n * — lives in export-math.ts where it can be unit-tested without a canvas\n * context. This file is the thin Konva-wiring layer: hide overlays, call\n * toDataURL, restore, handle the SecurityError.\n *\n * Konva is an OPTIONAL peer. Import this file only from browser-context code\n * that has konva wired in. The types are written against a minimal structural\n * interface so the file compiles even when konva's types are absent.\n */\n\nimport type { SceneDocument, ScenePage } from '../design-canvas/model'\nimport { SCENE_SCHEMA_VERSION } from '../design-canvas/model'\nimport type { ExportPreset } from '../design-canvas/export-presets'\nimport {\n documentCropToStageCoords,\n identifyTaintedSrc,\n isExportHiddenNodeName,\n resolveExportParams,\n} from './export-math'\n\n// ---------------------------------------------------------------------------\n// Minimal structural interfaces for Konva stage / node\n// (avoids a hard konva import; the real Konva types satisfy these)\n// ---------------------------------------------------------------------------\n\ninterface KonvaNodeLike {\n name(): string\n visible(): boolean\n visible(v: boolean): void\n getAttr(key: string): unknown\n}\n\ninterface KonvaLayerLike {\n getChildren(): KonvaNodeLike[]\n}\n\ninterface KonvaStageLike {\n scaleX(): number\n scaleY(): number\n x(): number\n y(): number\n getLayers(): KonvaLayerLike[]\n toDataURL(params: {\n mimeType: string\n quality?: number\n pixelRatio: number\n x: number\n y: number\n width: number\n height: number\n }): string\n}\n\n// ---------------------------------------------------------------------------\n// Raster export\n// ---------------------------------------------------------------------------\n\nexport interface ExportPageDataUrlOptions {\n format: 'png' | 'jpeg'\n pixelRatio?: number\n includeBleed?: boolean\n preset?: ExportPreset\n}\n\n/**\n * Render a single page to a data URL.\n *\n * The function temporarily hides every node whose name starts with 'overlay:'\n * plus any Transformer node, computes the crop rect and pixel ratio from the\n * page model and options, calls stage.toDataURL, then restores all prior view\n * state exactly — zoom, pan, and node visibility.\n *\n * Rejects with a descriptive error when a CORS-tainted image source causes\n * the SecurityError, naming the offending src so the caller can surface it.\n *\n * The `stage` argument must be the Konva stage with the page content already\n * rendered. The caller is responsible for ensuring all async image loads have\n * settled before calling this function.\n */\nexport async function exportPageDataUrl(\n stage: KonvaStageLike,\n page: ScenePage,\n opts: ExportPageDataUrlOptions,\n): Promise<string> {\n const { cropRect, pixelRatio, mimeType, quality } = resolveExportParams(page, opts)\n\n // Collect all image node srcs BEFORE hiding anything, so the taint detector\n // has data even if the SecurityError fires mid-render.\n const imageSrcs = collectImageSrcs(stage)\n\n // Save state: which nodes we are hiding (visibility that was true → set false).\n const hiddenNodes: KonvaNodeLike[] = []\n\n for (const layer of stage.getLayers()) {\n for (const node of layer.getChildren()) {\n const name = node.name()\n if (isExportHiddenNodeName(name) && node.visible()) {\n node.visible(false)\n hiddenNodes.push(node)\n }\n }\n }\n\n // Compute the stage-coordinate crop rect for toDataURL.\n const stageScale = stage.scaleX()\n const stageCrop = documentCropToStageCoords(cropRect, stageScale, stage.x(), stage.y())\n\n let dataUrl: string\n try {\n dataUrl = stage.toDataURL({\n mimeType,\n ...(quality !== undefined ? { quality } : {}),\n pixelRatio,\n x: stageCrop.x,\n y: stageCrop.y,\n width: stageCrop.width,\n height: stageCrop.height,\n })\n } catch (err) {\n // Restore visibility before rethrowing so the editor is not left in a\n // broken state.\n for (const node of hiddenNodes) {\n node.visible(true)\n }\n\n if (err instanceof Error && err.name === 'SecurityError') {\n const taintedSrc = identifyTaintedSrc(imageSrcs)\n if (taintedSrc !== null) {\n throw new Error(\n `Export failed: image source is CORS-tainted and cannot be read by the canvas. ` +\n `Offending src: \"${taintedSrc}\". ` +\n `Ensure the image is served with Access-Control-Allow-Origin or use a proxied /api/ path.`,\n )\n }\n throw new Error(\n `Export failed: a canvas SecurityError occurred but no cross-origin image src could be identified. ` +\n `The stage may contain a tainted video or image loaded without CORS headers.`,\n )\n }\n throw err\n }\n\n // Restore visibility.\n for (const node of hiddenNodes) {\n node.visible(true)\n }\n\n return dataUrl\n}\n\n/** Collect all image-like nodes from the stage for taint identification. */\nfunction collectImageSrcs(stage: KonvaStageLike): Array<{ name: string; src: string }> {\n const result: Array<{ name: string; src: string }> = []\n for (const layer of stage.getLayers()) {\n for (const node of layer.getChildren()) {\n const src = node.getAttr('src')\n if (typeof src === 'string' && src.length > 0) {\n result.push({ name: node.name(), src })\n }\n }\n }\n return result\n}\n\n// ---------------------------------------------------------------------------\n// JSON export\n// ---------------------------------------------------------------------------\n\n/**\n * Serialize a scene document to pretty-printed JSON with schemaVersion\n * asserted. Throws when the document's schemaVersion does not match\n * SCENE_SCHEMA_VERSION — the caller must not smuggle stale documents through.\n */\nexport function exportDocumentJson(document: SceneDocument): string {\n if (document.schemaVersion !== SCENE_SCHEMA_VERSION) {\n throw new Error(\n `exportDocumentJson: document schemaVersion is ${document.schemaVersion}, ` +\n `expected ${SCENE_SCHEMA_VERSION} — upgrade the document before exporting`,\n )\n }\n return JSON.stringify(document, null, 2)\n}\n\n// ---------------------------------------------------------------------------\n// Browser download helper\n// ---------------------------------------------------------------------------\n\n/**\n * Trigger a browser download for a data URL. Safe to import in SSR — the\n * function is a no-op when `document` is not defined (e.g. server-side render\n * or test environment without a DOM). The integrator must not rely on the\n * download executing in those contexts.\n */\nexport function downloadDataUrl(dataUrl: string, filename: string): void {\n if (typeof globalThis.document === 'undefined') return\n\n const a = globalThis.document.createElement('a')\n a.href = dataUrl\n a.download = filename\n a.style.display = 'none'\n globalThis.document.body.appendChild(a)\n a.click()\n globalThis.document.body.removeChild(a)\n}\n","/**\n * Layers panel — reverse-z list of the active page's elements. Highest z-index\n * is at the top. Groups show their children indented beneath them. Clicking\n * selects an element; meta-click adds to selection. Double-clicking the name\n * opens an inline rename input. Eye and lock icons toggle visibility/locked.\n * Rows can be drag-reordered within the list (siblings only; cross-group reorder\n * is a pending integrator concern). Capped at LAYERS_PANEL_ROW_LIMIT rows.\n */\n\nimport { useCallback, useMemo, useRef, useState } from 'react'\nimport type { SceneElement, ScenePage } from '../../design-canvas/model'\nimport { flattenLayerTree, LAYERS_PANEL_ROW_LIMIT } from './layer-tree'\nimport {\n EllipseGlyph,\n EyeGlyph,\n EyeOffGlyph,\n GroupGlyph,\n ImageGlyph,\n LineGlyph,\n LockGlyph,\n RectGlyph,\n SlotGlyph,\n TextGlyph,\n UnlockGlyph,\n VideoGlyph,\n} from './glyphs'\nimport type { SceneElementKind } from '../../design-canvas/model'\n\nfunction KindIcon({ kind, className }: { kind: SceneElementKind; className?: string }) {\n switch (kind) {\n case 'rect': return <RectGlyph className={className} />\n case 'ellipse': return <EllipseGlyph className={className} />\n case 'line': return <LineGlyph className={className} />\n case 'text': return <TextGlyph className={className} />\n case 'image': return <ImageGlyph className={className} />\n case 'video': return <VideoGlyph className={className} />\n case 'group': return <GroupGlyph className={className} />\n }\n}\n\nexport interface LayersPanelProps {\n page: ScenePage\n selectedElementIds: string[]\n canWrite: boolean\n /** Emit a set_attrs command for the given element. */\n onSetAttrs(elementId: string, attrs: Partial<Pick<SceneElement, 'name' | 'visible' | 'locked'>>): void\n /** Emit a reorder_element command. */\n onReorder(elementId: string, toIndex: number): void\n onSelect(elementId: string, additive: boolean): void\n}\n\nconst INDENT_PX = 16\n\nexport function LayersPanel({ page, selectedElementIds, canWrite, onSetAttrs, onReorder, onSelect }: LayersPanelProps) {\n const rows = useMemo(() => flattenLayerTree(page), [page])\n const [renamingId, setRenamingId] = useState<string | null>(null)\n const [renameValue, setRenameValue] = useState('')\n\n // Drag-reorder state: we track the dragged row's ownerIndex and the target\n // index within the SAME owner. Cross-owner reorder is not supported here.\n const dragRowRef = useRef<{ elementId: string; ownerIndex: number; ownerLength: number } | null>(null)\n const [dragOverIndex, setDragOverIndex] = useState<number | null>(null)\n\n function startRename(element: SceneElement) {\n setRenamingId(element.id)\n setRenameValue(element.name)\n }\n\n function commitRename(elementId: string) {\n const name = renameValue.trim()\n if (name.length > 0) onSetAttrs(elementId, { name })\n setRenamingId(null)\n }\n\n const visible = rows.length > LAYERS_PANEL_ROW_LIMIT ? rows.slice(0, LAYERS_PANEL_ROW_LIMIT) : rows\n\n return (\n <div className=\"flex h-full flex-col overflow-hidden text-[var(--text-primary)]\">\n <div className=\"shrink-0 border-b border-[var(--border-default)] px-3 py-1.5 text-[11px] font-medium uppercase tracking-wide text-[var(--text-muted)]\">\n Layers\n </div>\n\n <div className=\"min-h-0 flex-1 overflow-y-auto\">\n {visible.map((row) => {\n const { element } = row\n const isSelected = selectedElementIds.includes(element.id)\n const isRenaming = renamingId === element.id\n\n return (\n <div\n key={element.id}\n data-layer-row={element.id}\n draggable={canWrite}\n onDragStart={() => {\n dragRowRef.current = {\n elementId: element.id,\n ownerIndex: row.ownerIndex,\n ownerLength: row.ownerLength,\n }\n }}\n onDragOver={(event) => {\n if (!dragRowRef.current) return\n // Only allow reorder within the same owner (same parentGroupId + depth)\n event.preventDefault()\n setDragOverIndex(row.ownerIndex)\n }}\n onDragLeave={() => setDragOverIndex(null)}\n onDrop={() => {\n const drag = dragRowRef.current\n if (!drag) return\n if (drag.elementId !== element.id) {\n onReorder(drag.elementId, row.ownerIndex)\n }\n dragRowRef.current = null\n setDragOverIndex(null)\n }}\n onDragEnd={() => {\n dragRowRef.current = null\n setDragOverIndex(null)\n }}\n onClick={(event) => onSelect(element.id, event.metaKey || event.ctrlKey)}\n className={[\n 'flex cursor-pointer items-center gap-1.5 py-1 pr-2 text-[13px] transition-colors',\n isSelected ? 'bg-[var(--brand-primary)]/15 text-[var(--text-primary)]' : 'hover:bg-[var(--border-default)]/40 text-[var(--text-secondary)]',\n dragOverIndex === row.ownerIndex ? 'border-t border-[var(--brand-primary)]' : '',\n ].join(' ')}\n style={{ paddingLeft: 8 + row.depth * INDENT_PX }}\n >\n <KindIcon kind={element.kind} className=\"h-3.5 w-3.5 shrink-0 opacity-60\" />\n\n {element.slot ? (\n <SlotGlyph className=\"h-3 w-3 shrink-0 text-[var(--brand-primary)]\" />\n ) : null}\n\n <span className=\"min-w-0 flex-1 truncate\">\n {isRenaming ? (\n <input\n autoFocus\n value={renameValue}\n onChange={(event) => setRenameValue(event.target.value)}\n onBlur={() => commitRename(element.id)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') commitRename(element.id)\n if (event.key === 'Escape') setRenamingId(null)\n event.stopPropagation()\n }}\n onClick={(event) => event.stopPropagation()}\n className=\"w-full rounded border border-[var(--border-default)] bg-[var(--bg-input)] px-1 py-0 text-[13px] text-[var(--text-primary)] outline-none focus:border-[var(--brand-primary)]\"\n />\n ) : (\n <span\n onDoubleClick={(event) => {\n event.stopPropagation()\n if (canWrite) startRename(element)\n }}\n title={element.name}\n >\n {element.name}\n </span>\n )}\n </span>\n\n {/* Visibility toggle */}\n <button\n type=\"button\"\n aria-label={element.visible ? 'Hide element' : 'Show element'}\n onClick={(event) => {\n event.stopPropagation()\n if (canWrite) onSetAttrs(element.id, { visible: !element.visible })\n }}\n disabled={!canWrite}\n className=\"shrink-0 rounded p-0.5 opacity-0 transition-opacity hover:opacity-100 focus:opacity-100 group-hover:opacity-100 [.flex:hover_&]:opacity-60\"\n >\n {element.visible\n ? <EyeGlyph className=\"h-3.5 w-3.5\" />\n : <EyeOffGlyph className=\"h-3.5 w-3.5 text-[var(--text-muted)]\" />}\n </button>\n\n {/* Lock toggle */}\n <button\n type=\"button\"\n aria-label={element.locked ? 'Unlock element' : 'Lock element'}\n onClick={(event) => {\n event.stopPropagation()\n if (canWrite) onSetAttrs(element.id, { locked: !element.locked })\n }}\n disabled={!canWrite}\n className=\"shrink-0 rounded p-0.5 opacity-0 transition-opacity hover:opacity-100 focus:opacity-100 [.flex:hover_&]:opacity-60\"\n >\n {element.locked\n ? <LockGlyph className=\"h-3.5 w-3.5 text-amber-400\" />\n : <UnlockGlyph className=\"h-3.5 w-3.5\" />}\n </button>\n </div>\n )\n })}\n\n {rows.length > LAYERS_PANEL_ROW_LIMIT ? (\n <div className=\"px-3 py-2 text-[11px] text-[var(--text-muted)]\">\n +{rows.length - LAYERS_PANEL_ROW_LIMIT} more elements — select a group to scope the list\n </div>\n ) : null}\n </div>\n </div>\n )\n}\n","/**\n * Pure layer-tree helpers: flatten a page's element array into an ordered list\n * for the LayersPanel, preserving group nesting. Extracted so render order,\n * depth, and selection math can be unit-tested independently of React.\n */\n\nimport type { SceneElement, ScenePage } from '../../design-canvas/model'\n\nexport interface LayerRow {\n element: SceneElement\n depth: number\n /** True when this row is a group whose children follow it in the list. */\n isGroup: boolean\n /** Index within its owner (page.elements or group.children). */\n ownerIndex: number\n /** Length of the owner array — needed for z-order bound math. */\n ownerLength: number\n /** Id of the containing group, or null for page-root elements. */\n parentGroupId: string | null\n}\n\n/**\n * Flatten `page.elements` into display order for the layers panel.\n *\n * Z-order is bottom→top in the element array; the layers panel shows\n * top→bottom (highest z-index first). A group row precedes its children\n * (the group is \"above\" its children in the panel, reflecting that the group\n * node itself paints last in Konva when empty; children paint inside it).\n *\n * Depth increases by 1 for each group level, starting at 0 for page-root\n * elements. Groups are expanded; collapsed state is a view concern the caller\n * tracks separately.\n */\nexport function flattenLayerTree(page: ScenePage): LayerRow[] {\n const rows: LayerRow[] = []\n\n function visit(elements: SceneElement[], depth: number, parentGroupId: string | null) {\n // Reverse so highest z-index appears at the top of the panel.\n for (let i = elements.length - 1; i >= 0; i -= 1) {\n const element = elements[i]!\n rows.push({\n element,\n depth,\n isGroup: element.kind === 'group',\n ownerIndex: i,\n ownerLength: elements.length,\n parentGroupId,\n })\n if (element.kind === 'group') {\n visit(element.children, depth + 1, element.id)\n }\n }\n }\n\n visit(page.elements, 0, null)\n return rows\n}\n\n/** The maximum number of rows the layers panel renders before truncating. */\nexport const LAYERS_PANEL_ROW_LIMIT = 500\n","/**\n * Lazy-loaded entry points for the design canvas editor. Products that do not\n * need the editor on initial load import `DesignCanvasLazy` (the batteries-\n * included composition) or `DesignCanvasChromeLazy` (raw chrome only) instead\n * of importing the components directly. Each chunk loads on first render; a\n * Suspense boundary in the product provides the fallback.\n *\n * `DesignCanvasLazy` — `DesignCanvasEditor`: chrome + workspace sharing one\n * command stack. This is what products mount.\n *\n * `DesignCanvasChromeLazy` — `DesignCanvas`: raw chrome with render-prop API.\n * Use when the product supplies its own `renderWorkspace` and `renderThumbnail`.\n */\n\nimport { lazy } from 'react'\nimport type { DesignCanvasFullProps } from './components/DesignCanvas'\nimport type { DesignCanvasProps } from './contracts'\n\nexport type { DesignCanvasFullProps }\nexport type { DesignCanvasProps }\n\n/** Batteries-included editor: chrome + workspace on one shared stack. */\nexport const DesignCanvasLazy = lazy(\n () =>\n import('./components/DesignCanvasEditor').then((m) => ({ default: m.DesignCanvasEditor })),\n)\n\n/** Raw chrome only — use when supplying a custom renderWorkspace/renderThumbnail. */\nexport const DesignCanvasChromeLazy = lazy(\n () =>\n import('./components/DesignCanvas').then((m) => ({ default: m.DesignCanvas })),\n)\n"],"mappings":"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","names":[]}