@snowcone-app/canvas 0.11.1 → 0.12.1

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 (29) hide show
  1. package/dist/{CanvasStateV1-D3THl2Zc.js → CanvasStateV1-CKsfggNP.js} +3 -3
  2. package/dist/{CanvasStateV1-D3THl2Zc.js.map → CanvasStateV1-CKsfggNP.js.map} +1 -1
  3. package/dist/{HybridHistoryManager-DANuzx7G.js → HybridHistoryManager-NL3zyEl4.js} +21 -21
  4. package/dist/{HybridHistoryManager-DANuzx7G.js.map → HybridHistoryManager-NL3zyEl4.js.map} +1 -1
  5. package/dist/{ImportManager-NCtkY5Z0.js → ImportManager-eotl7r5d.js} +2 -2
  6. package/dist/{ImportManager-NCtkY5Z0.js.map → ImportManager-eotl7r5d.js.map} +1 -1
  7. package/dist/{ThemeContext-U-VDtIiS.js → ThemeContext-Cl1JPVLZ.js} +2 -2
  8. package/dist/{ThemeContext-U-VDtIiS.js.map → ThemeContext-Cl1JPVLZ.js.map} +1 -1
  9. package/dist/advanced.mjs +8 -8
  10. package/dist/api/embed.d.ts +3 -1
  11. package/dist/api/stable.d.ts +3 -1
  12. package/dist/components/embed-realtime/context.d.ts +9 -0
  13. package/dist/components/embed-realtime/usePieceGuideBundle.d.ts +48 -0
  14. package/dist/design/template-fields.d.ts +39 -1
  15. package/dist/embed.mjs +215 -155
  16. package/dist/embed.mjs.map +1 -1
  17. package/dist/hooks/useDeadBindingWarning.d.ts +2 -2
  18. package/dist/hooks/useFontBinding.d.ts +23 -0
  19. package/dist/index.mjs +24 -23
  20. package/dist/internals.mjs +4 -4
  21. package/dist/template-fields-IgDV7PRY.js +1627 -0
  22. package/dist/template-fields-IgDV7PRY.js.map +1 -0
  23. package/dist/testing.mjs +2 -2
  24. package/dist/utils/UnifiedFontService.d.ts +7 -0
  25. package/dist/{validation-C857Ptxn.js → validation-BpmNOvuY.js} +14 -4
  26. package/dist/{validation-C857Ptxn.js.map → validation-BpmNOvuY.js.map} +1 -1
  27. package/package.json +3 -3
  28. package/dist/template-fields-C8Tj67ek.js +0 -1585
  29. package/dist/template-fields-C8Tj67ek.js.map +0 -1
@@ -0,0 +1,1627 @@
1
+ import { c as nt, y as K, z as Oe, I as Ht, T as Pt, C as Ye } from "./HybridHistoryManager-NL3zyEl4.js";
2
+ import { jsxs as Z, jsx as w, Fragment as de } from "react/jsx-runtime";
3
+ import { useCallback as P, useMemo as ot, useRef as F, useEffect as C, Component as Xe, useState as _, forwardRef as ue, useImperativeHandle as Ve } from "react";
4
+ import { u as fe, T as _t, E as je, c as dt, b as At } from "./ThemeContext-Cl1JPVLZ.js";
5
+ import { ag as te, ah as ee, a8 as Ke, a9 as re, a5 as Ge, O as qe, x as Je, y as Qe, H as Ze, G as _e, k as tr, q as er, a3 as rr, R as ne, s as nr, l as or, t as ar, r as ir, v as sr, u as cr, g as lr, X as dr, N as ur, a as fr, n as hr, ai as mr } from "./validation-BpmNOvuY.js";
6
+ import { C as Tt, E as gr } from "./ImportManager-eotl7r5d.js";
7
+ import { d as pr, o as ct, s as $, n as br, l as Y, u as oe, a as yr } from "./schemas-B4UXytQB.js";
8
+ const ae = nt("useCommands");
9
+ function xr() {
10
+ const e = fe(), {
11
+ undo: t,
12
+ redo: r,
13
+ canUndo: o,
14
+ canRedo: n,
15
+ executeElementUpdate: a,
16
+ executeAddElement: i,
17
+ executeRemoveElement: s,
18
+ executeReorderElement: c,
19
+ executeCommandBatch: d,
20
+ executeCreateArtboard: x,
21
+ executeDeleteArtboard: I,
22
+ executeUpdateArtboard: R
23
+ } = e, k = P(() => {
24
+ ae.warn("[useCommands] clearHistory is not yet implemented in EditorContext");
25
+ }, []), T = P((p) => {
26
+ ae.warn("[useCommands] clearArtboardHistory is not yet implemented in EditorContext");
27
+ }, []);
28
+ return {
29
+ // Undo/Redo
30
+ undo: t,
31
+ redo: r,
32
+ canUndo: o,
33
+ canRedo: n,
34
+ // History management
35
+ clearHistory: k,
36
+ clearArtboardHistory: T,
37
+ // Command execution
38
+ executeElementUpdate: a,
39
+ executeAddElement: i,
40
+ executeRemoveElement: s,
41
+ executeReorderElement: c,
42
+ executeCreateArtboard: x,
43
+ executeDeleteArtboard: I,
44
+ executeUpdateArtboard: R,
45
+ // Batch execution
46
+ executeCommandBatch: d
47
+ };
48
+ }
49
+ const vr = () => {
50
+ const { undo: e, redo: t, canUndo: r, canRedo: o } = xr();
51
+ return /* @__PURE__ */ Z("div", { className: "sc-undo-redo", style: { display: "inline-flex", gap: 4 }, children: [
52
+ /* @__PURE__ */ w(
53
+ te,
54
+ {
55
+ icon: ee.undo,
56
+ onClick: e,
57
+ disabled: !r,
58
+ tooltip: "Undo",
59
+ "aria-label": "Undo"
60
+ }
61
+ ),
62
+ /* @__PURE__ */ w(
63
+ te,
64
+ {
65
+ icon: ee.redo,
66
+ onClick: t,
67
+ disabled: !o,
68
+ tooltip: "Redo",
69
+ "aria-label": "Redo"
70
+ }
71
+ )
72
+ ] });
73
+ }, he = nt("KitLayout"), lt = "canvas", Dt = 320;
74
+ let ie = !1;
75
+ function wr() {
76
+ ie || (ie = !0, Ke({
77
+ LayersPanel: qe,
78
+ EffectsPanel: Je,
79
+ ExportPanel: Qe,
80
+ ImagePanel: Ze,
81
+ GlyphPanel: _e,
82
+ ArtboardTabs: tr,
83
+ ContextualToolbars: er,
84
+ ZoomControls: rr,
85
+ MenuButton: ne,
86
+ CropPanel: nr
87
+ }), re("add-element-menu", {
88
+ component: ne,
89
+ label: "Add Element",
90
+ icon: "gravity-ui:plus",
91
+ position: "topbar"
92
+ }), re("undo-redo-controls", {
93
+ component: vr,
94
+ label: "Undo / Redo",
95
+ icon: "lucide:undo-2",
96
+ position: "topbar"
97
+ }));
98
+ }
99
+ function wt({ ids: e }) {
100
+ return !e || e.length === 0 ? null : /* @__PURE__ */ w(de, { children: e.map((t) => {
101
+ var n;
102
+ if (t === lt) return null;
103
+ const r = Ge(t);
104
+ if (!r)
105
+ return typeof K < "u" && ((n = K.env) == null ? void 0 : n.NODE_ENV) === "development" && he.warn(
106
+ `Kit layout references unknown section "${t}" — skipping. Register it with registerSection("${t}", { ... }).`
107
+ ), null;
108
+ const o = r.component;
109
+ return /* @__PURE__ */ w(o, {}, t);
110
+ }) });
111
+ }
112
+ function Er({ kit: e, canvas: t }) {
113
+ var I, R, k, T;
114
+ wr();
115
+ const r = e.layout.slots, o = !!((I = r.topbar) != null && I.some((p) => p !== lt)), n = !!((R = r.left) != null && R.some((p) => p !== lt)), a = !!((k = r.right) != null && k.some((p) => p !== lt)), i = !!((T = r.bottombar) != null && T.some((p) => p !== lt)), s = ot(
116
+ () => !o && !n && !a && !i,
117
+ [o, n, a, i]
118
+ ), c = F(null), d = o || n || a || i, x = F(!1);
119
+ return C(() => {
120
+ var b;
121
+ if (typeof K > "u" || ((b = K.env) == null ? void 0 : b.NODE_ENV) !== "development" || !d) return;
122
+ const p = c.current;
123
+ if (!p || typeof ResizeObserver > "u") return;
124
+ const N = (E) => {
125
+ E > 0 && E < Dt && !x.current ? (x.current = !0, he.warn(
126
+ `Kit "${e.name}" declares chrome (toolbar / panels) but its container is only ${Math.round(E)}px wide — below the ~${Dt}px needed to render it, so the toolbar / panels are suppressed and the editor looks like a bare canvas. Give the editor more container width, or pass kit="embed-only" if a chrome-less canvas is intended.`
127
+ )) : E >= Dt && (x.current = !1);
128
+ };
129
+ N(p.getBoundingClientRect().width);
130
+ const S = new ResizeObserver((E) => {
131
+ for (const v of E) N(v.contentRect.width);
132
+ });
133
+ return S.observe(p), () => S.disconnect();
134
+ }, [d, e.name]), s ? /* @__PURE__ */ w(de, { children: t }) : /* @__PURE__ */ Z("div", { ref: c, className: "sc-kit-layout", style: { display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }, children: [
135
+ o && /* @__PURE__ */ w(
136
+ "div",
137
+ {
138
+ className: "sc-kit-topbar toolbar",
139
+ style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", flexShrink: 0 },
140
+ children: /* @__PURE__ */ w(wt, { ids: r.topbar })
141
+ }
142
+ ),
143
+ /* @__PURE__ */ Z("div", { className: "sc-kit-body", style: { display: "flex", flex: 1, minHeight: 0 }, children: [
144
+ n && /* @__PURE__ */ w("div", { className: "sc-kit-left", style: { flexShrink: 0, overflow: "auto" }, children: /* @__PURE__ */ w(wt, { ids: r.left }) }),
145
+ /* @__PURE__ */ w("div", { className: "sc-kit-canvas", style: { flex: 1, minWidth: 0, position: "relative" }, children: t }),
146
+ a && /* @__PURE__ */ w("div", { className: "sc-kit-right", style: { flexShrink: 0, overflow: "auto" }, children: /* @__PURE__ */ w(wt, { ids: r.right }) })
147
+ ] }),
148
+ i && /* @__PURE__ */ w(
149
+ "div",
150
+ {
151
+ className: "sc-kit-bottombar toolbar",
152
+ style: { display: "flex", alignItems: "center", gap: 8, flexShrink: 0 },
153
+ children: /* @__PURE__ */ w(wt, { ids: r.bottombar })
154
+ }
155
+ )
156
+ ] });
157
+ }
158
+ const Ar = nt("ErrorBoundary");
159
+ class kr extends Xe {
160
+ constructor(t) {
161
+ super(t), this.resetError = () => {
162
+ this.setState({
163
+ hasError: !1,
164
+ error: null
165
+ });
166
+ }, this.state = {
167
+ hasError: !1,
168
+ error: null
169
+ };
170
+ }
171
+ static getDerivedStateFromError(t) {
172
+ return {
173
+ hasError: !0,
174
+ error: t
175
+ };
176
+ }
177
+ componentDidCatch(t, r) {
178
+ if (Ar.error("Caught error:", t, r), this.props.onError && this.props.onError(t, r), this.props.onCanvasError) {
179
+ const o = {
180
+ category: "unknown",
181
+ message: t.message,
182
+ originalError: t,
183
+ recoverable: !1
184
+ };
185
+ this.props.onCanvasError(o);
186
+ }
187
+ }
188
+ render() {
189
+ return this.state.hasError && this.state.error ? this.props.renderError ? this.props.renderError(this.state.error, this.resetError) : this.props.fallback ? typeof this.props.fallback == "function" ? this.props.fallback(this.state.error, this.resetError) : this.props.fallback : /* @__PURE__ */ Z(
190
+ "div",
191
+ {
192
+ style: {
193
+ padding: "24px",
194
+ border: "2px solid var(--danger)",
195
+ borderRadius: "8px",
196
+ backgroundColor: "color-mix(in oklch, var(--danger) 10%, var(--background))",
197
+ color: "var(--danger)",
198
+ fontFamily: "system-ui, sans-serif"
199
+ },
200
+ children: [
201
+ /* @__PURE__ */ w("h2", { style: { margin: "0 0 16px 0", fontSize: "18px", fontWeight: 600 }, children: "Something went wrong" }),
202
+ /* @__PURE__ */ w(
203
+ "pre",
204
+ {
205
+ style: {
206
+ margin: "0 0 16px 0",
207
+ padding: "12px",
208
+ backgroundColor: "color-mix(in oklch, var(--danger) 15%, var(--background))",
209
+ borderRadius: "4px",
210
+ fontSize: "14px",
211
+ overflow: "auto",
212
+ maxHeight: "200px"
213
+ },
214
+ children: this.state.error.message
215
+ }
216
+ ),
217
+ /* @__PURE__ */ w(
218
+ "button",
219
+ {
220
+ onClick: this.resetError,
221
+ style: {
222
+ padding: "8px 16px",
223
+ backgroundColor: "var(--danger)",
224
+ color: "var(--danger-foreground)",
225
+ border: "none",
226
+ borderRadius: "4px",
227
+ fontSize: "14px",
228
+ fontWeight: 500,
229
+ cursor: "pointer"
230
+ },
231
+ children: "Try again"
232
+ }
233
+ )
234
+ ]
235
+ }
236
+ ) : this.props.children;
237
+ }
238
+ }
239
+ const Sr = nt("useAutoExport");
240
+ function Rr(e) {
241
+ const { config: t, historyManager: r, artboards: o, elements: n, onExport: a, onExportScheduled: i, isCanvasReady: s = !1 } = e, c = F(null), d = F(!1), x = F({
242
+ totalExports: 0,
243
+ skippedExports: 0,
244
+ lastExportTime: null,
245
+ avgExportInterval: 0
246
+ }), [I, R] = _(x.current), k = F(a);
247
+ k.current = a, C(() => {
248
+ const b = new or({
249
+ ...ar,
250
+ ...t
251
+ });
252
+ return b.onExport(async () => {
253
+ try {
254
+ await k.current(), x.current = b.getStats();
255
+ } catch (E) {
256
+ Sr.error("[useAutoExport] Export failed:", E);
257
+ }
258
+ }), c.current = b, () => {
259
+ b.destroy();
260
+ };
261
+ }, []), C(() => {
262
+ s && d.current && c.current && (d.current = !1, c.current.forceExport());
263
+ }, [s]), C(() => {
264
+ c.current && t && c.current.updateConfig(t);
265
+ }, [t == null ? void 0 : t.enabled, t == null ? void 0 : t.debounceMs, t == null ? void 0 : t.maxWaitMs]), C(() => {
266
+ c.current && i && c.current.onExportScheduled(i);
267
+ }, [i]), C(() => {
268
+ if (!r || !c.current)
269
+ return;
270
+ const b = r.onCommandExecuted(() => {
271
+ if (c.current) {
272
+ if (!s) {
273
+ d.current = !0;
274
+ return;
275
+ }
276
+ c.current.scheduleExport();
277
+ }
278
+ });
279
+ return () => {
280
+ b();
281
+ };
282
+ }, [r, s]), C(() => {
283
+ if (c.current) {
284
+ if (!s) {
285
+ d.current = !0;
286
+ return;
287
+ }
288
+ c.current.scheduleExport();
289
+ }
290
+ }, [n, o, s]), C(() => Oe((E) => {
291
+ if (!c.current || !s) return;
292
+ n.some((W) => W.id === E) && c.current.scheduleExport();
293
+ }), [n, s]);
294
+ const T = P((b) => {
295
+ c.current && c.current.updateConfig(b);
296
+ }, []), p = P(async () => {
297
+ c.current && (await c.current.forceExport(), x.current = c.current.getStats(), R(x.current));
298
+ }, []), N = P(() => {
299
+ c.current && (c.current.resetStats(), x.current = c.current.getStats(), R(x.current));
300
+ }, []), S = P(() => {
301
+ c.current && c.current.resetChangeDetection();
302
+ }, []);
303
+ return {
304
+ stats: I,
305
+ updateConfig: T,
306
+ forceExport: p,
307
+ resetStats: N,
308
+ resetChangeDetection: S
309
+ };
310
+ }
311
+ const me = nt("useContentReady");
312
+ function Cr(e) {
313
+ var r;
314
+ const t = /* @__PURE__ */ new Set();
315
+ for (const o of e)
316
+ if ("fontFamily" in o && typeof o.fontFamily == "string" && o.fontFamily && t.add(o.fontFamily), "getRichText" in o && typeof o.getRichText == "function")
317
+ try {
318
+ const n = o.getRichText();
319
+ if (n != null && n.spans)
320
+ for (const a of n.spans)
321
+ (r = a.style) != null && r.fontFamily && t.add(a.style.fontFamily);
322
+ } catch {
323
+ }
324
+ return Array.from(t);
325
+ }
326
+ async function Ir(e) {
327
+ if (e.length === 0 || typeof document > "u" || !document.fonts) return;
328
+ const t = [];
329
+ for (const r of e) {
330
+ const o = `16px "${r}"`;
331
+ t.push(document.fonts.load(o));
332
+ }
333
+ await Promise.all(t), document.fonts.ready && await Promise.race([
334
+ document.fonts.ready,
335
+ new Promise((r) => setTimeout(r, 250))
336
+ ]), me.debug(`Awaited ${t.length} font(s)`);
337
+ }
338
+ function Mr() {
339
+ return new Promise((e) => requestAnimationFrame(() => e()));
340
+ }
341
+ function Fr(e) {
342
+ const { isCanvasReady: t, elements: r, hasInitialElements: o, initialElementsLoaded: n } = e, [a, i] = _(!1), s = F(!1);
343
+ return C(() => {
344
+ if (a || !t || o && !n || o && r.length === 0 || s.current) return;
345
+ s.current = !0;
346
+ let c = !1;
347
+ return (async () => {
348
+ try {
349
+ const d = Cr(r);
350
+ if (d.length > 0 && (await Ir(d), c) || (await Mr(), c)) return;
351
+ i(!0);
352
+ } catch (d) {
353
+ me.error("Error during content readiness check:", d), c || i(!0);
354
+ } finally {
355
+ s.current = !1;
356
+ }
357
+ })(), () => {
358
+ c = !0, s.current = !1;
359
+ };
360
+ }, [t, r, o, n, a]), a;
361
+ }
362
+ const Tr = {
363
+ // Vertical alignments (map to top/center/bottom center)
364
+ "far-top": "t",
365
+ top: "t",
366
+ center: "c",
367
+ bottom: "b",
368
+ "far-bottom": "b",
369
+ // Horizontal alignments (map to left/center/right middle)
370
+ "far-left": "l",
371
+ left: "l",
372
+ right: "r",
373
+ "far-right": "r",
374
+ // Direct 9-point values
375
+ tl: "tl",
376
+ t: "t",
377
+ tr: "tr",
378
+ l: "l",
379
+ c: "c",
380
+ r: "r",
381
+ bl: "bl",
382
+ b: "b",
383
+ br: "br"
384
+ };
385
+ function Dr(e) {
386
+ return e && Tr[e] || "c";
387
+ }
388
+ function Nr(e, t) {
389
+ const r = t.scaleMode || "cover", o = (r === "contain" ? t.marginTop : 0) || 0, n = (r === "contain" ? t.marginRight : 0) || 0, a = (r === "contain" ? t.marginBottom : 0) || 0, i = (r === "contain" ? t.marginLeft : 0) || 0, s = t.width - i - n, c = t.height - o - a, d = s / e.width, x = c / e.height, I = r === "contain" ? Math.min(d, x) : Math.max(d, x), R = t.scale || 1, k = I * R, T = e.width * k, p = e.height * k, N = t.align || "c";
390
+ let S = 0, b = 0;
391
+ const E = T - s, v = p - c;
392
+ switch (N) {
393
+ // Top row
394
+ case "tl":
395
+ S = 0, b = 0;
396
+ break;
397
+ case "t":
398
+ S = -E / 2, b = 0;
399
+ break;
400
+ case "tr":
401
+ S = -E, b = 0;
402
+ break;
403
+ // Middle row
404
+ case "l":
405
+ S = 0, b = -v / 2;
406
+ break;
407
+ case "c":
408
+ // Center (default)
409
+ default:
410
+ S = -E / 2, b = -v / 2;
411
+ break;
412
+ case "r":
413
+ S = -E, b = -v / 2;
414
+ break;
415
+ // Bottom row
416
+ case "bl":
417
+ S = 0, b = -v;
418
+ break;
419
+ case "b":
420
+ S = -E / 2, b = -v;
421
+ break;
422
+ case "br":
423
+ S = -E, b = -v;
424
+ break;
425
+ }
426
+ S += i, b += o;
427
+ const W = t.offsetX || 0, B = t.offsetY || 0, X = E, ut = v;
428
+ return S += W * X, b += B * ut, S = Math.round(S), b = Math.round(b), {
429
+ // Final scale to apply to artwork
430
+ scale: k,
431
+ // Final artwork dimensions after scaling
432
+ width: Math.round(T),
433
+ height: Math.round(p),
434
+ // Position to draw artwork (relative to artboard origin)
435
+ x: S,
436
+ y: b,
437
+ // Debug info
438
+ debug: {
439
+ coverScale: I,
440
+ userScale: R,
441
+ overflow: { x: E, y: v },
442
+ alignment: N,
443
+ appliedOffset: { x: W * X, y: B * ut }
444
+ }
445
+ };
446
+ }
447
+ const Br = {
448
+ timeout: 3e4,
449
+ retries: 1,
450
+ retryDelay: 1e3,
451
+ validateUrl: !0
452
+ };
453
+ function $r(e) {
454
+ try {
455
+ const t = new URL(e);
456
+ return ["http:", "https:", "data:", "blob:"].includes(t.protocol);
457
+ } catch {
458
+ return !1;
459
+ }
460
+ }
461
+ async function Hr(e, t = {}) {
462
+ const r = { ...Br, ...t };
463
+ if (r.validateUrl && !$r(e))
464
+ return {
465
+ success: !1,
466
+ error: new Error(`Invalid image URL: ${e}`)
467
+ };
468
+ let o;
469
+ for (let n = 0; n <= r.retries; n++)
470
+ try {
471
+ return await Pr(e, r.timeout);
472
+ } catch (a) {
473
+ o = a instanceof Error ? a : new Error(String(a)), n < r.retries && await Ur(r.retryDelay);
474
+ }
475
+ return {
476
+ success: !1,
477
+ error: o || new Error("Failed to load image after retries")
478
+ };
479
+ }
480
+ function Pr(e, t) {
481
+ return new Promise((r) => {
482
+ const o = new Image();
483
+ o.crossOrigin = "anonymous";
484
+ let n = null, a = !1;
485
+ const i = () => {
486
+ n && (clearTimeout(n), n = null);
487
+ }, s = () => {
488
+ if (a) return;
489
+ a = !0, i();
490
+ const d = o.naturalWidth || o.width, x = o.naturalHeight || o.height;
491
+ r({
492
+ success: !0,
493
+ element: o,
494
+ width: d,
495
+ height: x,
496
+ aspectRatio: x > 0 ? d / x : 1
497
+ });
498
+ }, c = (d) => {
499
+ a || (a = !0, i(), r({
500
+ success: !1,
501
+ error: new Error(d)
502
+ }));
503
+ };
504
+ o.onload = s, o.onerror = () => {
505
+ c(`Failed to load image: ${e}`);
506
+ }, n = setTimeout(() => {
507
+ c(`Image load timed out after ${t}ms: ${e}`);
508
+ }, t), o.src = e;
509
+ });
510
+ }
511
+ async function Wr(e, t, r = {}, o = {}) {
512
+ var R, k, T, p, N, S, b;
513
+ const n = await Hr(e, o);
514
+ if (!n.success || !n.width || !n.height)
515
+ return {
516
+ success: !1,
517
+ error: n.error || new Error("Failed to get image dimensions")
518
+ };
519
+ const a = {
520
+ width: t.artboard.width,
521
+ height: t.artboard.height,
522
+ scale: t.scale,
523
+ align: Dr(t.alignment),
524
+ offsetX: t.offsetX,
525
+ offsetY: t.offsetY,
526
+ scaleMode: t.scaleMode,
527
+ marginTop: t.marginTop,
528
+ marginRight: t.marginRight,
529
+ marginBottom: t.marginBottom,
530
+ marginLeft: t.marginLeft
531
+ }, i = Nr(
532
+ { width: n.width, height: n.height },
533
+ a
534
+ ), s = t.artboard.x + i.x, c = t.artboard.y + i.y, d = s + i.width / 2, x = c + i.height / 2;
535
+ return {
536
+ success: !0,
537
+ element: new Ht({
538
+ ...r,
539
+ x: d,
540
+ y: x,
541
+ imageUrl: e,
542
+ imageAspectRatio: n.aspectRatio,
543
+ preserveDimensions: !0,
544
+ // Don't recalculate dimensions on image load
545
+ transformData: {
546
+ type: "image",
547
+ width: i.width,
548
+ height: i.height,
549
+ cropX: ((R = r.transformData) == null ? void 0 : R.cropX) ?? 0,
550
+ cropY: ((k = r.transformData) == null ? void 0 : k.cropY) ?? 0,
551
+ cropWidth: ((T = r.transformData) == null ? void 0 : T.cropWidth) ?? 1,
552
+ cropHeight: ((p = r.transformData) == null ? void 0 : p.cropHeight) ?? 1,
553
+ flipHorizontal: ((N = r.transformData) == null ? void 0 : N.flipHorizontal) ?? !1,
554
+ flipVertical: ((S = r.transformData) == null ? void 0 : S.flipVertical) ?? !1,
555
+ borderRadius: ((b = r.transformData) == null ? void 0 : b.borderRadius) ?? 0
556
+ }
557
+ }),
558
+ placement: {
559
+ artworkSize: { width: n.width, height: n.height },
560
+ finalSize: { width: i.width, height: i.height },
561
+ position: { x: d, y: x },
562
+ scale: i.scale
563
+ }
564
+ };
565
+ }
566
+ function Ur(e) {
567
+ return new Promise((t) => setTimeout(t, e));
568
+ }
569
+ const J = nt("SnowconeCanvas");
570
+ function Nt(e, t, r, o) {
571
+ if (o <= 0 || !isFinite(o))
572
+ return r;
573
+ const n = e * r, a = t * r;
574
+ if (Math.max(n, a) <= o)
575
+ return r;
576
+ const s = Math.max(e, t), c = o / s;
577
+ return Math.min(c, r);
578
+ }
579
+ const ge = ue((e, t) => {
580
+ const {
581
+ exportConfig: r,
582
+ imageConfig: o,
583
+ layoutConfig: n,
584
+ kit: a,
585
+ artboards: i,
586
+ activeArtboard: s,
587
+ onArtboardChange: c,
588
+ initialElements: d,
589
+ onChange: x,
590
+ onSelectionChange: I,
591
+ autoExportInterval: R,
592
+ onExport: k,
593
+ onExportScheduled: T,
594
+ onExportStatus: p,
595
+ onExportReady: N,
596
+ onImageLoad: S,
597
+ onImageError: b,
598
+ onError: E,
599
+ onReady: v,
600
+ className: W,
601
+ style: B,
602
+ enableShortcuts: X,
603
+ overlay: ut
604
+ } = e, zt = R, at = e.autoExportConfig ?? (r == null ? void 0 : r.autoExportConfig), tt = e.autoExportFormat ?? (r == null ? void 0 : r.format) ?? "dataUrl", kt = e.autoExportAll ?? (r == null ? void 0 : r.exportAll) ?? !1, G = e.exportScale ?? (r == null ? void 0 : r.scale) ?? 2, z = e.maxExportSize ?? (r == null ? void 0 : r.maxSize) ?? 4e3, ft = e.exportImageFormat ?? (r == null ? void 0 : r.imageFormat) ?? "png", ht = e.exportImageQuality ?? (r == null ? void 0 : r.imageQuality) ?? 0.92, L = e.initialImage ?? (o == null ? void 0 : o.src), Lt = e.initialImageAlignment ?? (o == null ? void 0 : o.alignment) ?? "center", Ot = e.initialImageScale ?? (o == null ? void 0 : o.scale) ?? 1, Yt = e.initialImageScaleMode ?? (o == null ? void 0 : o.scaleMode) ?? "cover", xe = e.width ?? (n == null ? void 0 : n.width) ?? 1200, ve = e.height ?? (n == null ? void 0 : n.height) ?? 1200, we = e.viewPadding ?? (n == null ? void 0 : n.viewPadding) ?? 0.9, Ee = e.artboardBorderRadius ?? (n == null ? void 0 : n.artboardBorderRadius) ?? 0, Ae = e.fixedMargin ?? (n == null ? void 0 : n.fixedMargin), ke = e.maxHeight ?? (n == null ? void 0 : n.maxHeight), Se = e.showRotationHandle ?? (n == null ? void 0 : n.showRotationHandle) ?? !0, Re = e.hideCanvas ?? (n == null ? void 0 : n.hideCanvas) ?? !1, Xt = e.canvasWrapperClassName ?? (n == null ? void 0 : n.canvasWrapperClassName), Vt = e.canvasWrapperStyle ?? (n == null ? void 0 : n.canvasWrapperStyle), Ce = e.canvasCutouts ?? (n == null ? void 0 : n.canvasCutouts), jt = e.pieceGuides, Ie = e.pieceFocus, Me = X ?? !0, it = ot(() => ir(a ?? "pro-studio"), [a]);
605
+ C(() => {
606
+ var l;
607
+ if (typeof K < "u" && ((l = K.env) == null ? void 0 : l.NODE_ENV) === "development" && it) {
608
+ const u = sr(it);
609
+ u.valid || J.warn("Kit validation warnings:", u.errors), u.warnings.length > 0 && J.warn("Kit validation warnings:", u.warnings);
610
+ }
611
+ }, [it]);
612
+ const mt = F(E);
613
+ mt.current = E;
614
+ const U = P((l) => {
615
+ var u;
616
+ J.error(`[${l.category}] ${l.message}`, l.originalError), (u = mt.current) == null || u.call(mt, l);
617
+ }, []);
618
+ C(() => (Tt.onRenderError = U, () => {
619
+ Tt.onRenderError === U && (Tt.onRenderError = null);
620
+ }), [U]);
621
+ const {
622
+ elements: q,
623
+ setElements: gt,
624
+ selectedId: Kt,
625
+ artboardManager: M,
626
+ refreshArtboards: Fe,
627
+ historyManager: Te,
628
+ isCanvasReady: St,
629
+ setCanvasReady: pt
630
+ } = fe(), { createArtboard: De, selectArtboard: Ne, artboards: H } = cr(), { exportArtboard: et, exportAllArtboards: bt, exportArtboardAsBlob: rt, exportAllArtboardsAsBlobs: yt } = lr();
631
+ Ve(t, () => ({
632
+ exportArtboards: async (l = {}) => {
633
+ const u = l.format || tt, A = l.scale || G, f = l.all ?? !1;
634
+ let m = A;
635
+ if (z > 0 && isFinite(z))
636
+ for (const h of H) {
637
+ const y = Nt(h.width, h.height, A, z);
638
+ m = Math.min(m, y);
639
+ }
640
+ const g = { scale: m, format: ft, quality: ht };
641
+ if (f) {
642
+ const h = u === "blob" ? await yt(g) : await bt(g), y = {};
643
+ for (const [D, O] of Object.entries(h)) {
644
+ const V = H.find((st) => st.id === D);
645
+ V && (y[V.name] = O);
646
+ }
647
+ return y;
648
+ } else {
649
+ const h = M.getActiveArtboard();
650
+ if (!h)
651
+ throw new Error("[SnowconeCanvas] No active artboard found");
652
+ if (u === "blob") {
653
+ const y = await rt(h.id, g);
654
+ return { [h.name]: y };
655
+ } else {
656
+ const y = await et(h.id, g);
657
+ return { [h.name]: y };
658
+ }
659
+ }
660
+ }
661
+ }), [et, bt, rt, yt, tt, G, z, ft, ht, M, H]), C(() => {
662
+ N && N(async () => {
663
+ const u = M.getActiveArtboard();
664
+ if (!u)
665
+ throw new Error("[SnowconeCanvas] No active artboard found");
666
+ const A = Nt(
667
+ u.width,
668
+ u.height,
669
+ G,
670
+ z
671
+ ), f = tt === "blob" ? await rt(u.id, { scale: A }) : await et(u.id, { scale: A });
672
+ return { [u.name]: f };
673
+ });
674
+ }, [N, et, rt, M, tt, G, z]);
675
+ const [Gt, xt] = _("idle"), [qt, Rt] = _(null), Ct = F(void 0), It = F(!1), Jt = F(!1), [Be, $e] = _(!1), He = F(0), Pe = F(0), Mt = F(!1);
676
+ C(() => {
677
+ if (It.current) return;
678
+ It.current = !0;
679
+ const l = i || [{ name: "Design", width: xe, height: ve }], u = M.getAllArtboards();
680
+ if (u.length > 0) {
681
+ const A = l[0], f = u[0], m = jt ? "transparent" : void 0, g = (h) => h.exportBackground ?? (!!h.backgroundColor && h.backgroundColor !== "transparent");
682
+ f.name = A.name, f.width = A.width, f.height = A.height, f.clipShape = A.clipShape, f.exportBackground = g(A), A.backgroundColor ? f.backgroundColor = A.backgroundColor : m && (f.backgroundColor = m);
683
+ for (let h = 1; h < l.length; h++)
684
+ De(l[h].width, l[h].height, {
685
+ name: l[h].name,
686
+ backgroundColor: l[h].backgroundColor ?? m,
687
+ exportBackground: g(l[h]),
688
+ clipShape: l[h].clipShape
689
+ });
690
+ !s && l.length > 1 && M.setActiveArtboard(f.id);
691
+ }
692
+ Fe();
693
+ }, []), C(() => {
694
+ if (!(!d || d.length === 0) && !Jt.current && It.current) {
695
+ Jt.current = !0, $e(!0);
696
+ try {
697
+ const l = gr.createManyFromJSON(d), u = M.getAllArtboards();
698
+ if (u.length > 0) {
699
+ const f = new Map(u.map((m) => [m.name, m]));
700
+ l.forEach((m, g) => {
701
+ var D;
702
+ const h = (D = d[g]) == null ? void 0 : D.artboard, y = h && f.get(h) || u[0];
703
+ M.addElementToArtboard(m.id, y.id);
704
+ });
705
+ }
706
+ gt(l);
707
+ const A = /* @__PURE__ */ new Set();
708
+ for (const f of l) {
709
+ const m = f.fontFamily;
710
+ typeof m == "string" && m.trim().length > 0 && A.add(m);
711
+ }
712
+ if (A.size > 0 && typeof document < "u") {
713
+ const f = document.fonts ?? null, m = Array.from(A).map((g) => {
714
+ const h = `font-${g.replace(/\s+/g, "-").toLowerCase()}`;
715
+ let y = document.getElementById(h);
716
+ return y || (y = document.createElement("link"), y.id = h, y.rel = "stylesheet", y.href = `https://fonts.googleapis.com/css2?family=${g.replace(
717
+ /\s+/g,
718
+ "+"
719
+ )}:wght@400;700&display=swap`, document.head.appendChild(y)), new Promise((D) => {
720
+ if (y.sheet) {
721
+ D(g);
722
+ return;
723
+ }
724
+ const O = () => D(g);
725
+ y.addEventListener("load", O, { once: !0 }), y.addEventListener("error", O, { once: !0 }), setTimeout(O, 4e3);
726
+ });
727
+ });
728
+ Promise.all(m).then((g) => {
729
+ if (f)
730
+ return Promise.all(
731
+ g.flatMap((h) => [
732
+ f.load(`400 16px "${h}"`).catch(() => {
733
+ }),
734
+ f.load(`700 16px "${h}"`).catch(() => {
735
+ })
736
+ ])
737
+ );
738
+ }).then(() => {
739
+ gt((g) => g.slice());
740
+ });
741
+ }
742
+ } catch (l) {
743
+ J.error("Failed to load initial elements:", l);
744
+ const u = l instanceof Error ? l : new Error(String(l));
745
+ U({
746
+ category: "import",
747
+ message: `Failed to load initial elements: ${u.message}`,
748
+ originalError: u,
749
+ recoverable: !0
750
+ });
751
+ }
752
+ }
753
+ }, [d, M, gt, U]), C(() => {
754
+ if (!s) {
755
+ Mt.current = !0;
756
+ return;
757
+ }
758
+ const l = H.find((u) => u.name === s);
759
+ if (l) {
760
+ const u = M.getActiveArtboard();
761
+ (u == null ? void 0 : u.name) !== s && Ne(l.id), Mt.current = !0;
762
+ }
763
+ }, [s, H]), C(() => {
764
+ if (!L || Ct.current === L) return;
765
+ if (q.length > 0) {
766
+ Ct.current = L;
767
+ return;
768
+ }
769
+ Ct.current = L, (async () => {
770
+ xt("loading"), Rt(null);
771
+ try {
772
+ const u = M.getAllArtboards();
773
+ if (u.length === 0)
774
+ throw new Error("No artboards available");
775
+ const A = [];
776
+ for (const f of u) {
777
+ const m = i == null ? void 0 : i.find((y) => y.name === f.name), g = (m == null ? void 0 : m.scaleMode) || Yt, h = await Wr(
778
+ L,
779
+ {
780
+ artboard: {
781
+ width: f.width,
782
+ height: f.height,
783
+ x: f.x,
784
+ y: f.y
785
+ },
786
+ alignment: (m == null ? void 0 : m.fitAlign) || Lt,
787
+ scale: Ot,
788
+ scaleMode: g,
789
+ marginTop: m == null ? void 0 : m.fitMarginTop,
790
+ marginRight: m == null ? void 0 : m.fitMarginRight,
791
+ marginBottom: m == null ? void 0 : m.fitMarginBottom,
792
+ marginLeft: m == null ? void 0 : m.fitMarginLeft
793
+ }
794
+ );
795
+ h.success && h.element ? (M.addElementToArtboard(h.element.id, f.id), A.push(h.element)) : J.error("Failed to load image for artboard:", f.name, h.error);
796
+ }
797
+ if (A.length > 0)
798
+ gt((f) => [...f, ...A]), xt("success"), S == null || S(L);
799
+ else {
800
+ const f = new Error("Failed to load image into any artboard");
801
+ xt("error"), Rt(f), b == null || b(L, f), U({
802
+ category: "image",
803
+ message: f.message,
804
+ originalError: f,
805
+ recoverable: !0
806
+ });
807
+ }
808
+ } catch (u) {
809
+ const A = u instanceof Error ? u : new Error(String(u));
810
+ xt("error"), Rt(A), b == null || b(L, A), U({
811
+ category: "image",
812
+ message: A.message,
813
+ originalError: A,
814
+ recoverable: !0
815
+ });
816
+ }
817
+ })();
818
+ }, [L, Lt, Ot, Yt]);
819
+ const vt = F(I);
820
+ vt.current = I, C(() => {
821
+ var l;
822
+ (l = vt.current) == null || l.call(vt, Kt);
823
+ }, [Kt]);
824
+ const Qt = F(x);
825
+ Qt.current = x, C(() => {
826
+ const l = Qt.current;
827
+ if (!l) return;
828
+ const u = M.getActiveArtboard(), A = {
829
+ // Stamp each element with the NAME of the artboard it lives on (the
830
+ // manager is the membership source of truth). Without this the public
831
+ // state is flat and a multi-placement design cannot round-trip: restore
832
+ // collapses everything onto the first artboard, and per-placement render
833
+ // states can't be derived from onChange. Pinned by
834
+ // SnowconeCanvas.artboard-membership.test.tsx.
835
+ elements: q.map((f) => {
836
+ const m = f.toJSON(), g = M.getArtboardForElement(f.id);
837
+ return g ? { ...m, artboard: g.name } : m;
838
+ }),
839
+ artboards: H.map((f) => ({
840
+ name: f.name,
841
+ width: f.width,
842
+ height: f.height,
843
+ clipShape: f.clipShape,
844
+ backgroundColor: f.backgroundColor,
845
+ // Carried so serializeStateForServer / saved states keep an
846
+ // explicitly-set background renderable (mockup matches editor).
847
+ exportBackground: f.exportBackground
848
+ })),
849
+ activeArtboard: (u == null ? void 0 : u.name) || "Design"
850
+ };
851
+ l(A);
852
+ }, [q, H]), C(() => {
853
+ if (!c || !Mt.current) return;
854
+ const l = M.getActiveArtboard();
855
+ l && c(l.name);
856
+ }, [M.getActiveArtboardId()]);
857
+ const We = P(async () => {
858
+ if (!k && !p) return;
859
+ const l = ++Pe.current, u = Date.now();
860
+ let A = G;
861
+ if (z > 0 && isFinite(z))
862
+ for (const g of H) {
863
+ const h = Nt(g.width, g.height, G, z);
864
+ A = Math.min(A, h);
865
+ }
866
+ const f = M.getActiveArtboard(), m = (f == null ? void 0 : f.id) ?? "unknown";
867
+ p == null || p({ status: "rendering", artboardId: m }), He.current = u;
868
+ try {
869
+ let g;
870
+ const h = {
871
+ format: ft,
872
+ scale: A,
873
+ quality: ht
874
+ };
875
+ if (tt === "blob")
876
+ if (kt) {
877
+ const y = await yt(h);
878
+ g = {};
879
+ for (const [D, O] of Object.entries(y)) {
880
+ const V = H.find((st) => st.id === D);
881
+ V && (g[V.name] = O);
882
+ }
883
+ } else {
884
+ const y = M.getActiveArtboard();
885
+ if (!y) return;
886
+ const D = await rt(y.id, h);
887
+ g = { [y.name]: D };
888
+ }
889
+ else if (kt) {
890
+ const y = await bt(h);
891
+ g = {};
892
+ for (const [D, O] of Object.entries(y)) {
893
+ const V = H.find((st) => st.id === D);
894
+ V && (g[V.name] = O);
895
+ }
896
+ } else {
897
+ const y = M.getActiveArtboard();
898
+ if (!y) return;
899
+ const D = await et(y.id, h);
900
+ g = { [y.name]: D };
901
+ }
902
+ k == null || k(g), p == null || p({ status: "complete", artboardId: m, result: g });
903
+ } catch (g) {
904
+ const h = g instanceof Error ? g.message : String(g);
905
+ if (h.includes("Canvas ref not available"))
906
+ return;
907
+ const y = Date.now() - u;
908
+ J.error("Export failed (export #" + l + "):", {
909
+ duration: `${y}ms`,
910
+ error: h
911
+ });
912
+ const D = g instanceof Error ? g : new Error(h);
913
+ p == null || p({ status: "error", artboardId: m, error: D }), U({
914
+ category: "export",
915
+ message: D.message,
916
+ originalError: D,
917
+ artboardId: m,
918
+ recoverable: !0
919
+ });
920
+ }
921
+ }, [k, p, kt, tt, G, z, ft, ht, et, bt, rt, yt, H, M, q, at, U]);
922
+ C(() => {
923
+ zt !== void 0 && zt > 0 && J.warn(
924
+ "autoExportInterval is deprecated and ignored. Use autoExportConfig={{ enabled: true, debounceMs: 100, maxWaitMs: 1000 }} instead."
925
+ );
926
+ }, []), C(() => {
927
+ }, [q]);
928
+ const Ue = P(() => {
929
+ if (T == null || T(), p) {
930
+ const l = M.getActiveArtboard();
931
+ p({ status: "scheduled", artboardId: (l == null ? void 0 : l.id) ?? "unknown" });
932
+ }
933
+ }, [T, p, M]), ze = !!d && d.length > 0, Ft = Fr({
934
+ isCanvasReady: St,
935
+ elements: q,
936
+ hasInitialElements: ze,
937
+ initialElementsLoaded: Be
938
+ }), Zt = F(!1);
939
+ C(() => {
940
+ Ft && !Zt.current && (Zt.current = !0, v == null || v());
941
+ }, [Ft, v]), Rr({
942
+ config: at ? {
943
+ enabled: at.enabled ?? !0,
944
+ debounceMs: at.debounceMs ?? 100,
945
+ maxWaitMs: at.maxWaitMs ?? 1e3
946
+ } : {
947
+ enabled: !1
948
+ // Only use smart export if autoExportConfig is provided
949
+ },
950
+ historyManager: Te,
951
+ artboards: H,
952
+ elements: q,
953
+ onExport: We,
954
+ onExportScheduled: Ue,
955
+ isCanvasReady: Ft
956
+ // Gate exports until content is fully ready (fonts loaded, elements deserialized)
957
+ }), C(() => {
958
+ if (H.length > 0 && !St) {
959
+ const l = requestAnimationFrame(() => {
960
+ pt(!0);
961
+ });
962
+ return () => cancelAnimationFrame(l);
963
+ }
964
+ }, [H.length, St, pt]), C(() => () => {
965
+ pt(!1);
966
+ }, [pt]);
967
+ const Le = P((l) => {
968
+ U({
969
+ category: "unknown",
970
+ message: l.message,
971
+ originalError: l,
972
+ recoverable: !1
973
+ });
974
+ }, [U]);
975
+ return Gt === "loading" ? /* @__PURE__ */ w(
976
+ "div",
977
+ {
978
+ className: W,
979
+ style: {
980
+ ...B,
981
+ display: "flex",
982
+ alignItems: "center",
983
+ justifyContent: "center",
984
+ backgroundColor: "var(--surface, #f5f5f5)"
985
+ },
986
+ children: /* @__PURE__ */ w(dr, { size: 48 })
987
+ }
988
+ ) : Gt === "error" && qt ? /* @__PURE__ */ w(
989
+ "div",
990
+ {
991
+ className: W,
992
+ style: {
993
+ ...B,
994
+ display: "flex",
995
+ alignItems: "center",
996
+ justifyContent: "center",
997
+ backgroundColor: "var(--surface, #f5f5f5)",
998
+ color: "var(--danger, #dc2626)",
999
+ padding: "1rem"
1000
+ },
1001
+ children: /* @__PURE__ */ Z("div", { className: "text-center", children: [
1002
+ /* @__PURE__ */ w("div", { className: "font-medium", children: "Failed to load image" }),
1003
+ /* @__PURE__ */ w("div", { className: "text-sm mt-1 opacity-70", children: qt.message })
1004
+ ] })
1005
+ }
1006
+ ) : /* @__PURE__ */ w(ur, { kit: it, children: /* @__PURE__ */ w("div", { className: `app-modern ${W || ""}`, style: { ...B, position: "relative" }, children: /* @__PURE__ */ Z(
1007
+ kr,
1008
+ {
1009
+ onError: Le,
1010
+ fallback: (l, u) => /* @__PURE__ */ Z(
1011
+ "div",
1012
+ {
1013
+ style: {
1014
+ display: "flex",
1015
+ flexDirection: "column",
1016
+ alignItems: "center",
1017
+ justifyContent: "center",
1018
+ padding: "24px",
1019
+ minHeight: "200px",
1020
+ backgroundColor: "var(--surface, #f5f5f5)",
1021
+ color: "var(--foreground, #333)",
1022
+ fontFamily: "system-ui, sans-serif",
1023
+ textAlign: "center"
1024
+ },
1025
+ children: [
1026
+ /* @__PURE__ */ w("div", { style: { fontSize: "18px", fontWeight: 600, marginBottom: "8px" }, children: "Something went wrong" }),
1027
+ /* @__PURE__ */ w("div", { style: { fontSize: "14px", opacity: 0.7, marginBottom: "16px", maxWidth: "400px" }, children: l.message }),
1028
+ /* @__PURE__ */ w(
1029
+ "button",
1030
+ {
1031
+ onClick: u,
1032
+ style: {
1033
+ padding: "8px 20px",
1034
+ backgroundColor: "var(--primary, #333)",
1035
+ color: "var(--primary-foreground, #fff)",
1036
+ border: "none",
1037
+ borderRadius: "6px",
1038
+ fontSize: "14px",
1039
+ fontWeight: 500,
1040
+ cursor: "pointer"
1041
+ },
1042
+ children: "Try again"
1043
+ }
1044
+ )
1045
+ ]
1046
+ }
1047
+ ),
1048
+ children: [
1049
+ !Re && /* @__PURE__ */ (() => {
1050
+ const l = /* @__PURE__ */ w(
1051
+ hr,
1052
+ {
1053
+ style: { width: "100%" },
1054
+ fitPadding: we,
1055
+ artboardBorderRadius: Ee,
1056
+ fixedMargin: Ae,
1057
+ maxHeight: ke,
1058
+ showRotationHandle: Se,
1059
+ enableShortcuts: Me,
1060
+ canvasCutouts: Ce,
1061
+ pieceGuides: jt,
1062
+ pieceFocus: Ie
1063
+ }
1064
+ );
1065
+ return /* @__PURE__ */ w(Er, { kit: it, canvas: Xt || Vt ? /* @__PURE__ */ w("div", { className: Xt, style: Vt, children: l }) : l });
1066
+ })(),
1067
+ ut
1068
+ ]
1069
+ }
1070
+ ) }) });
1071
+ });
1072
+ ge.displayName = "SnowconeCanvasInner";
1073
+ const zr = ue((e, t) => {
1074
+ var c;
1075
+ const { inheritTheme: r, externalProvider: o, services: n } = e, a = e.viewPadding ?? ((c = e.layoutConfig) == null ? void 0 : c.viewPadding), i = /* @__PURE__ */ w(ge, { ref: t, ...e }), s = o ? /* @__PURE__ */ w(_t, { defaultTheme: "light", passive: r, children: i }) : /* @__PURE__ */ w(_t, { defaultTheme: "light", passive: r, children: /* @__PURE__ */ w(je, { viewPadding: a, children: i }) });
1076
+ return n ? /* @__PURE__ */ w(fr, { services: n, children: s }) : s;
1077
+ });
1078
+ zr.displayName = "SnowconeCanvas";
1079
+ const Lr = 3e3, se = {
1080
+ text: "useTextBinding",
1081
+ image: "useImageBinding",
1082
+ font: "useFontBinding"
1083
+ }, Or = {
1084
+ text: "setText",
1085
+ image: "setImageUrl",
1086
+ font: "setFontFamily"
1087
+ }, Yr = {
1088
+ text: "text",
1089
+ image: "image",
1090
+ font: "text"
1091
+ }, Bt = /* @__PURE__ */ new Set();
1092
+ function ce(e) {
1093
+ return e instanceof Pt ? "text" : e instanceof Ht ? "image" : "other";
1094
+ }
1095
+ function Xr(e, t, r) {
1096
+ const o = `[${se[e]}]`, n = `the binding is dead (isConnected: false, ${Or[e]} is a no-op)`, a = Yr[e], i = r.getAllByName(t);
1097
+ if (i.length > 0) {
1098
+ const d = [...new Set(i.map(ce))], x = a === "text" ? "image" : "text", I = d.length === 1 && d[0] === x ? ` Bind it with ${se[x]}("${t}") instead.` : "";
1099
+ return `${o} the layer named "${t}" is ${d.join("/")}, not ${a} — ${n}.${I}`;
1100
+ }
1101
+ const s = r.getAll().filter((d) => d.name).map((d) => `"${d.name}" (${ce(d)})`), c = s.length ? `Named layers on this canvas: ${s.join(", ")}. Check the name for a typo.` : `No element on this canvas has a name — name one via design().${a}(…, { name: '${t}' }) or the element's \`name\` property.`;
1102
+ return `${o} no ${a} layer named "${t}" exists — ${n}. ${c}`;
1103
+ }
1104
+ function Wt(e, t, r, o) {
1105
+ C(() => {
1106
+ var i;
1107
+ if (o || typeof K > "u" || ((i = K.env) == null ? void 0 : i.NODE_ENV) === "production") return;
1108
+ const n = `${e}:${t}`;
1109
+ if (Bt.has(n)) return;
1110
+ const a = setTimeout(() => {
1111
+ Bt.has(n) || (Bt.add(n), console.warn(Xr(e, t, r)));
1112
+ }, Lr);
1113
+ return () => clearTimeout(a);
1114
+ }, [e, t, r, o]);
1115
+ }
1116
+ const Vr = () => {
1117
+ }, jr = [];
1118
+ function pn(e) {
1119
+ const { elementStore: t } = dt(), { executeElementUpdate: r } = At(), o = ot(() => t.getAllByName(e).filter((i) => i instanceof Pt), [t, e]), n = P(
1120
+ (a) => {
1121
+ for (const i of o) {
1122
+ const s = i.clone();
1123
+ s.setText(a), r(i, s);
1124
+ }
1125
+ },
1126
+ [o, r]
1127
+ );
1128
+ return Wt("text", e, t, o.length > 0), o.length === 0 ? { text: "", setText: Vr, element: null, elements: jr, isConnected: !1 } : {
1129
+ text: o[0].getText(),
1130
+ setText: n,
1131
+ element: o[0],
1132
+ elements: o,
1133
+ isConnected: !0
1134
+ };
1135
+ }
1136
+ const Kr = () => {
1137
+ }, Gr = [];
1138
+ function qr(e, t, r) {
1139
+ const o = e / t;
1140
+ if (r >= o) {
1141
+ const n = t, a = n * r, i = e / a;
1142
+ return {
1143
+ width: a,
1144
+ height: n,
1145
+ cropX: (1 - i) / 2,
1146
+ cropY: 0,
1147
+ cropWidth: i,
1148
+ cropHeight: 1
1149
+ };
1150
+ } else {
1151
+ const n = e, a = n / r, i = t / a;
1152
+ return {
1153
+ width: n,
1154
+ height: a,
1155
+ cropX: 0,
1156
+ cropY: (1 - i) / 2,
1157
+ cropWidth: 1,
1158
+ cropHeight: i
1159
+ };
1160
+ }
1161
+ }
1162
+ function bn(e, t) {
1163
+ const r = (t == null ? void 0 : t.fit) ?? "cover", { elementStore: o, setElements: n } = dt(), { executeElementUpdate: a } = At(), i = ot(() => o.getAllByName(e).filter((k) => k instanceof Ht), [o, e]), s = F(/* @__PURE__ */ new Map());
1164
+ for (const R of i)
1165
+ if (!s.current.has(R.id)) {
1166
+ const k = R.transformData;
1167
+ s.current.set(R.id, {
1168
+ width: k.width * k.cropWidth,
1169
+ height: k.height * k.cropHeight
1170
+ });
1171
+ }
1172
+ const c = F(i);
1173
+ c.current = i;
1174
+ const d = F(a);
1175
+ d.current = a;
1176
+ const x = F(n);
1177
+ x.current = n;
1178
+ const I = P(
1179
+ (R) => {
1180
+ const k = c.current, T = d.current;
1181
+ for (const p of k) {
1182
+ const N = s.current.get(p.id);
1183
+ if (!N) continue;
1184
+ const { width: S, height: b } = N, E = p.clone();
1185
+ E.imageLoaded = !1, E.imageElement = null, E.isCropping = !1, E.imageUrl = R, r === "cover" ? (E.preserveDimensions = !0, E.onLoadCallback = (v) => {
1186
+ const W = v.imageAspectRatio || 1, B = qr(S, b, W);
1187
+ v.transformData.width = B.width, v.transformData.height = B.height, v.transformData.cropX = B.cropX, v.transformData.cropY = B.cropY, v.transformData.cropWidth = B.cropWidth, v.transformData.cropHeight = B.cropHeight, T(p, v);
1188
+ }) : (E.preserveDimensions = !1, E.onLoadCallback = (v) => {
1189
+ const W = v.transformData.width, B = v.transformData.height, X = Math.min(S / W, b / B, 1);
1190
+ X < 1 && (v.transformData.width = W * X, v.transformData.height = B * X), v.transformData.cropX = 0, v.transformData.cropY = 0, v.transformData.cropWidth = 1, v.transformData.cropHeight = 1, T(p, v);
1191
+ }), E.loadImage(R);
1192
+ }
1193
+ },
1194
+ [r]
1195
+ // Stable deps only — imageElements/executeElementUpdate/setElements accessed via refs
1196
+ );
1197
+ return Wt("image", e, o, i.length > 0), i.length === 0 ? { imageUrl: "", setImageUrl: Kr, element: null, elements: Gr, isConnected: !1 } : {
1198
+ imageUrl: i[0].imageUrl,
1199
+ setImageUrl: I,
1200
+ element: i[0],
1201
+ elements: i,
1202
+ isConnected: !0
1203
+ };
1204
+ }
1205
+ const Jr = [];
1206
+ function Et(e) {
1207
+ let t = e.trim().toUpperCase();
1208
+ return t.length === 4 && t.startsWith("#") && (t = "#" + t[1] + t[1] + t[2] + t[2] + t[3] + t[3]), t;
1209
+ }
1210
+ function j(e, t) {
1211
+ return typeof e == "string" && Et(e) === t;
1212
+ }
1213
+ function pe(e, t) {
1214
+ var o, n, a;
1215
+ const r = e;
1216
+ return j(r.color, t) || j((o = r.transformData) == null ? void 0 : o.fillColor, t) || j((n = r.transformData) == null ? void 0 : n.strokeColor, t) || ((a = r.stroke) == null ? void 0 : a.enabled) === !0 && j(r.stroke.color, t);
1217
+ }
1218
+ function Qr(e, t, r) {
1219
+ var i, s, c;
1220
+ if (!pe(e, t)) return null;
1221
+ const o = e.clone(), n = e, a = o;
1222
+ return j(n.color, t) && (typeof a.setColor == "function" ? a.setColor(r) : a.color = r), j((i = n.transformData) == null ? void 0 : i.fillColor, t) && (a.transformData = { ...a.transformData, fillColor: r }), j((s = n.transformData) == null ? void 0 : s.strokeColor, t) && (a.transformData = { ...a.transformData, strokeColor: r }), ((c = n.stroke) == null ? void 0 : c.enabled) === !0 && j(n.stroke.color, t) && (a.stroke = { ...a.stroke, color: r }), o;
1223
+ }
1224
+ function yn(e) {
1225
+ const { elementStore: t } = dt(), { executeElementUpdate: r } = At(), [o, n] = _(() => Et(e)), [a, i] = _(e);
1226
+ e !== a && (i(e), n(Et(e)));
1227
+ const s = ot(
1228
+ () => t.getAll().filter((d) => pe(d, o)),
1229
+ [t, o]
1230
+ ), c = P(
1231
+ (d) => {
1232
+ const x = Et(d);
1233
+ if (x !== o) {
1234
+ for (const I of t.getAll()) {
1235
+ const R = Qr(I, o, d);
1236
+ R && r(I, R);
1237
+ }
1238
+ n(x);
1239
+ }
1240
+ },
1241
+ [t, o, r]
1242
+ );
1243
+ return s.length === 0 ? { color: o, setColor: c, elements: Jr, isConnected: !1 } : { color: o, setColor: c, elements: s, isConnected: !0 };
1244
+ }
1245
+ const Zr = () => {
1246
+ }, _r = [];
1247
+ function xn(e) {
1248
+ const { elementStore: t } = dt(), { executeElementUpdate: r } = At(), o = ot(() => t.getAllByName(e).filter((i) => i instanceof Pt), [t, e]), n = P(
1249
+ (a) => {
1250
+ mr.loadGoogleFontByName(a);
1251
+ for (const i of o) {
1252
+ if (i.fontFamily === a) continue;
1253
+ Ye.clearCache(i.fontFamily);
1254
+ const s = i.clone();
1255
+ s.fontFamily = a, r(i, s);
1256
+ }
1257
+ },
1258
+ [o, r]
1259
+ );
1260
+ return Wt("font", e, t, o.length > 0), o.length === 0 ? { fontFamily: "", setFontFamily: Zr, element: null, elements: _r, isConnected: !1 } : {
1261
+ fontFamily: o[0].fontFamily,
1262
+ setFontFamily: n,
1263
+ element: o[0],
1264
+ elements: o,
1265
+ isConnected: !0
1266
+ };
1267
+ }
1268
+ function vn(e) {
1269
+ const { elementStore: t } = dt();
1270
+ return e ? t.getByName(e) ?? null : null;
1271
+ }
1272
+ const tn = 1;
1273
+ function Q(e) {
1274
+ return typeof e == "number" && Number.isFinite(e) ? Math.round(e * 100) / 100 : e;
1275
+ }
1276
+ function be(e) {
1277
+ return {
1278
+ ...e,
1279
+ ...e.x !== void 0 && { x: Q(e.x) },
1280
+ ...e.y !== void 0 && { y: Q(e.y) },
1281
+ ...e.width !== void 0 && { width: Q(e.width) },
1282
+ ...e.height !== void 0 && { height: Q(e.height) },
1283
+ ...e.rotation !== void 0 && { rotation: Q(e.rotation) }
1284
+ };
1285
+ }
1286
+ function en(e) {
1287
+ var o;
1288
+ const t = (o = e.artboards) != null && o.length ? e.artboards : [{ name: "Front", width: 800, height: 800 }], r = t.map(() => []);
1289
+ for (const n of e.elements || []) {
1290
+ const a = n == null ? void 0 : n.artboard, i = typeof a == "string" ? t.findIndex((s) => (s.name || "Front") === a) : -1;
1291
+ r[i >= 0 ? i : 0].push(rn(n));
1292
+ }
1293
+ return {
1294
+ schemaVersion: tn,
1295
+ artboards: t.map((n, a) => ({
1296
+ id: `artboard-${a + 1}`,
1297
+ name: n.name || "Front",
1298
+ x: 0,
1299
+ y: 0,
1300
+ width: Q(n.width || 800),
1301
+ height: Q(n.height || 800),
1302
+ backgroundColor: n.backgroundColor || "transparent",
1303
+ // Pass the artboard's flag through — the server worker only paints the
1304
+ // background when this is true. Hardcoding `false` here silently dropped
1305
+ // explicitly-set artboard backgrounds from every realtime mockup while
1306
+ // the editor kept showing them (WYSIWYG drift).
1307
+ exportBackground: n.exportBackground ?? !1,
1308
+ elements: r[a],
1309
+ distressTexture: n.distressTexture,
1310
+ imageMask: n.imageMask
1311
+ }))
1312
+ };
1313
+ }
1314
+ function rn(e) {
1315
+ const t = e.type || e.transformType;
1316
+ if (t === "image")
1317
+ return nn(e);
1318
+ const { artboard: r, ...o } = e;
1319
+ return be({
1320
+ ...o,
1321
+ type: t
1322
+ });
1323
+ }
1324
+ function nn(e) {
1325
+ var d;
1326
+ const t = e.transformData || {}, r = e.masks && e.masks.length > 0, o = t.width || 0, n = t.height || 0, a = r ? o : o * (t.cropWidth ?? 1), i = r ? n : n * (t.cropHeight ?? 1), s = {
1327
+ id: e.id,
1328
+ type: "image",
1329
+ x: e.x || 0,
1330
+ y: e.y || 0,
1331
+ width: a,
1332
+ height: i,
1333
+ rotation: e.rotation || 0,
1334
+ imageUrl: e.imageUrl,
1335
+ imageAspectRatio: e.imageAspectRatio
1336
+ };
1337
+ return !r && (t.cropX !== 0 || t.cropY !== 0 || t.cropWidth !== 1 || t.cropHeight !== 1) && (s.cropX = t.cropX, s.cropY = t.cropY, s.cropWidth = t.cropWidth, s.cropHeight = t.cropHeight, s.needsCropPixelConversion = !0), t.flipHorizontal && (s.flipHorizontal = t.flipHorizontal), t.flipVertical && (s.flipVertical = t.flipVertical), t.borderRadius && (s.borderRadius = t.borderRadius), e.opacity !== void 0 && (s.opacity = e.opacity), e.distressEffect && (s.distressEffect = e.distressEffect), ((d = e.masks) == null ? void 0 : d.length) > 0 && (s.masks = e.masks), e.blendMode && (s.blendMode = e.blendMode), e.knockoutParts && (s.knockoutParts = e.knockoutParts), e.stroke && (s.stroke = e.stroke), be(s);
1338
+ }
1339
+ const le = "center";
1340
+ function on(e) {
1341
+ return e === "top-left" || e === "left" || e === "bottom-left" ? "left" : e === "top-right" || e === "right" || e === "bottom-right" ? "right" : "center";
1342
+ }
1343
+ function an(e) {
1344
+ return e === "top-left" || e === "top" || e === "top-right" ? "top" : e === "bottom-left" || e === "bottom" || e === "bottom-right" ? "bottom" : "middle";
1345
+ }
1346
+ function $t(e, t, r, o, n, a) {
1347
+ const i = on(e), s = an(e), c = i === "left" ? t / 2 + a : i === "right" ? o - t / 2 - a : o / 2, d = s === "top" ? r / 2 + a : s === "bottom" ? n - r / 2 - a : n / 2;
1348
+ return { x: c, y: d };
1349
+ }
1350
+ function sn(e, t, r) {
1351
+ const o = t / r;
1352
+ if (e >= o) {
1353
+ const i = r * e, s = t / i;
1354
+ return {
1355
+ width: i,
1356
+ height: r,
1357
+ cropX: (1 - s) / 2,
1358
+ cropY: 0,
1359
+ cropWidth: s,
1360
+ cropHeight: 1
1361
+ };
1362
+ }
1363
+ const n = t / e, a = r / n;
1364
+ return {
1365
+ width: t,
1366
+ height: n,
1367
+ cropX: 0,
1368
+ cropY: (1 - a) / 2,
1369
+ cropWidth: 1,
1370
+ cropHeight: a
1371
+ };
1372
+ }
1373
+ class Ut {
1374
+ constructor(t) {
1375
+ if (this.els = [], this.idCounter = 0, !(t.width > 0) || !(t.height > 0))
1376
+ throw new Error("design(): artboard width and height must be positive numbers");
1377
+ this.artboard = {
1378
+ name: t.name || "Front",
1379
+ width: t.width,
1380
+ height: t.height,
1381
+ backgroundColor: t.backgroundColor
1382
+ };
1383
+ }
1384
+ /**
1385
+ * Seed a builder from a previously saved canvas state — the editor shape
1386
+ * `<SnowconeCanvas onChange>` emits (and `toJSON()` produces).
1387
+ *
1388
+ * This is how a saved editable template re-enters the turnkey embed path:
1389
+ * load the template's state JSON, lift it back into a `DesignBuilder`, and
1390
+ * hand it to `<RealtimeEmbed design={…}>`. The active artboard becomes the
1391
+ * builder's artboard; elements tagged for other artboards are skipped
1392
+ * (untagged elements are assumed to belong to the active one).
1393
+ */
1394
+ static fromState(t) {
1395
+ const r = t.artboards.find((n) => n.name === t.activeArtboard) ?? t.artboards[0];
1396
+ if (!r)
1397
+ throw new Error("DesignBuilder.fromState(): state has no artboards");
1398
+ const o = new Ut({
1399
+ name: r.name,
1400
+ width: r.width,
1401
+ height: r.height,
1402
+ backgroundColor: r.backgroundColor
1403
+ });
1404
+ for (const n of t.elements)
1405
+ n.artboard && n.artboard !== r.name || o.els.push({ ...n });
1406
+ return o;
1407
+ }
1408
+ nextId(t) {
1409
+ return `${t}-${++this.idCounter}`;
1410
+ }
1411
+ /** Full-bleed background image (fills the whole artboard). Cover-fit (no
1412
+ * distortion) when `aspectRatio` is supplied. Inserted at the bottom of the
1413
+ * stack regardless of call order. */
1414
+ background(t, r = {}) {
1415
+ const { width: o, height: n } = this.artboard;
1416
+ let a;
1417
+ if (r.aspectRatio && r.aspectRatio > 0) {
1418
+ const s = sn(r.aspectRatio, o, n);
1419
+ a = {
1420
+ type: "image",
1421
+ width: s.width,
1422
+ height: s.height,
1423
+ cropX: s.cropX,
1424
+ cropY: s.cropY,
1425
+ cropWidth: s.cropWidth,
1426
+ cropHeight: s.cropHeight,
1427
+ flipHorizontal: !1,
1428
+ flipVertical: !1,
1429
+ borderRadius: 0
1430
+ };
1431
+ } else
1432
+ a = {
1433
+ type: "image",
1434
+ width: o,
1435
+ height: n,
1436
+ cropX: 0,
1437
+ cropY: 0,
1438
+ cropWidth: 1,
1439
+ cropHeight: 1,
1440
+ flipHorizontal: !1,
1441
+ flipVertical: !1,
1442
+ borderRadius: 0
1443
+ };
1444
+ const i = {
1445
+ id: this.nextId("bg"),
1446
+ transformType: "image",
1447
+ x: o / 2,
1448
+ y: n / 2,
1449
+ rotation: 0,
1450
+ opacity: r.opacity ?? 1,
1451
+ imageUrl: t,
1452
+ imageAspectRatio: r.aspectRatio,
1453
+ transformData: a,
1454
+ name: r.name ?? "Background"
1455
+ };
1456
+ return this.els.unshift(i), this;
1457
+ }
1458
+ /** An anchored image element (not full-bleed). */
1459
+ image(t, r = {}) {
1460
+ const { width: o, height: n } = this.artboard, a = r.width ?? Math.round(o / 3), i = r.height ?? (r.aspectRatio ? Math.round(a / r.aspectRatio) : a), { x: s, y: c } = $t(r.anchor ?? le, a, i, o, n, r.padding ?? 0), d = {
1461
+ id: this.nextId("img"),
1462
+ transformType: "image",
1463
+ x: s,
1464
+ y: c,
1465
+ rotation: r.rotation ?? 0,
1466
+ opacity: r.opacity ?? 1,
1467
+ imageUrl: t,
1468
+ imageAspectRatio: r.aspectRatio,
1469
+ transformData: {
1470
+ type: "image",
1471
+ width: a,
1472
+ height: i,
1473
+ cropX: 0,
1474
+ cropY: 0,
1475
+ cropWidth: 1,
1476
+ cropHeight: 1,
1477
+ flipHorizontal: !1,
1478
+ flipVertical: !1,
1479
+ borderRadius: 0
1480
+ },
1481
+ ...r.name ? { name: r.name } : {}
1482
+ };
1483
+ return this.els.push(d), this;
1484
+ }
1485
+ /** An anchored text layer. Horizontal centring is exact (textAlign); vertical
1486
+ * anchoring uses the font size as the line-height estimate. */
1487
+ text(t, r = {}) {
1488
+ const { width: o, height: n } = this.artboard, a = r.fontSize ?? Math.round(this.artboard.height / 12), { x: i, y: s } = $t(r.anchor ?? "top", 0, a, o, n, r.padding ?? Math.round(n / 20)), c = {
1489
+ id: this.nextId("text"),
1490
+ transformType: "custom",
1491
+ x: i,
1492
+ y: s,
1493
+ rotation: r.rotation ?? 0,
1494
+ text: t,
1495
+ fontSize: a,
1496
+ fontFamily: r.fontFamily ?? "Anton",
1497
+ color: r.color ?? "#ffffff",
1498
+ textAlign: r.textAlign ?? "center",
1499
+ bold: r.bold ?? !1,
1500
+ italic: r.italic ?? !1,
1501
+ transformData: { type: "custom" },
1502
+ ...r.name ? { name: r.name } : {}
1503
+ };
1504
+ return this.els.push(c), this;
1505
+ }
1506
+ /** An anchored vector shape. */
1507
+ shape(t, r = {}) {
1508
+ const { width: o, height: n } = this.artboard, a = r.size ?? Math.round(o / 6), i = typeof a == "number" ? a : a.width, s = typeof a == "number" ? a : a.height, { x: c, y: d } = $t(r.anchor ?? le, i, s, o, n, r.padding ?? 0), x = {
1509
+ type: "shape",
1510
+ shapeType: t,
1511
+ width: i,
1512
+ height: s,
1513
+ fillColor: r.fill ?? "#000000",
1514
+ fillOpacity: r.opacity ?? 1,
1515
+ ...r.points !== void 0 ? { points: r.points } : {},
1516
+ ...r.sides !== void 0 ? { sides: r.sides } : {}
1517
+ }, I = {
1518
+ id: this.nextId("shape"),
1519
+ transformType: "shape",
1520
+ x: c,
1521
+ y: d,
1522
+ rotation: r.rotation ?? 0,
1523
+ transformData: x,
1524
+ ...r.name ? { name: r.name } : {}
1525
+ };
1526
+ return this.els.push(I), this;
1527
+ }
1528
+ /** The composed elements, in render order (background first). Editor shape. */
1529
+ get elements() {
1530
+ return this.els.map((t) => ({ ...t }));
1531
+ }
1532
+ /** Editor-shape canvas state for `<SnowconeCanvas initialElements=… />` and
1533
+ * `serializeStateForServer`. `activeArtboard` is the artboard name. */
1534
+ toJSON() {
1535
+ return {
1536
+ elements: this.elements,
1537
+ artboards: [{
1538
+ name: this.artboard.name,
1539
+ width: this.artboard.width,
1540
+ height: this.artboard.height,
1541
+ // A background set on a design is part of the design: flag it
1542
+ // renderable so exports and server renders paint it, matching the
1543
+ // editor (the export worker skips it without `exportBackground`).
1544
+ ...this.artboard.backgroundColor ? {
1545
+ backgroundColor: this.artboard.backgroundColor,
1546
+ exportBackground: this.artboard.backgroundColor !== "transparent"
1547
+ } : {}
1548
+ }],
1549
+ activeArtboard: this.artboard.name
1550
+ };
1551
+ }
1552
+ /** Server-render payload for `RenderSession.renderState(placement, …)`.
1553
+ * Equivalent to `serializeStateForServer(design.toJSON())`. */
1554
+ toServerRequest() {
1555
+ return en(this.toJSON());
1556
+ }
1557
+ }
1558
+ function wn(e) {
1559
+ return new Ut(e);
1560
+ }
1561
+ const ye = "personalization", cn = pr("type", [
1562
+ ct({
1563
+ type: Y("text"),
1564
+ name: $().min(1),
1565
+ label: $(),
1566
+ placeholder: $().optional(),
1567
+ maxLength: br().int().positive().optional(),
1568
+ group: $().optional()
1569
+ }),
1570
+ ct({
1571
+ type: Y("image"),
1572
+ name: $().min(1),
1573
+ label: $(),
1574
+ placeholder: $().optional(),
1575
+ fit: oe([Y("cover"), Y("contain")]).optional(),
1576
+ group: $().optional()
1577
+ }),
1578
+ ct({
1579
+ type: Y("color"),
1580
+ color: $().min(1),
1581
+ label: $(),
1582
+ group: $().optional()
1583
+ }),
1584
+ ct({
1585
+ type: Y("select"),
1586
+ name: $().min(1),
1587
+ label: $(),
1588
+ property: oe([Y("text"), Y("imageUrl"), Y("fontFamily")]),
1589
+ options: yr(ct({ label: $(), value: $() })).min(1),
1590
+ group: $().optional()
1591
+ })
1592
+ ]);
1593
+ function En(e) {
1594
+ if (!e || typeof e != "object") return [];
1595
+ const t = e[ye];
1596
+ if (!Array.isArray(t)) return [];
1597
+ const r = [];
1598
+ for (const o of t) {
1599
+ if (!o || typeof o != "object") continue;
1600
+ const n = "type" in o ? o : { ...o, type: "text" }, a = cn.safeParse(n);
1601
+ a.success && r.push(a.data);
1602
+ }
1603
+ return r;
1604
+ }
1605
+ function An(e, t) {
1606
+ return { ...e, [ye]: t };
1607
+ }
1608
+ export {
1609
+ tn as C,
1610
+ Ut as D,
1611
+ kr as E,
1612
+ zr as S,
1613
+ ye as T,
1614
+ yn as a,
1615
+ xr as b,
1616
+ Fr as c,
1617
+ wn as d,
1618
+ vn as e,
1619
+ xn as f,
1620
+ bn as g,
1621
+ pn as h,
1622
+ En as r,
1623
+ en as s,
1624
+ Rr as u,
1625
+ An as w
1626
+ };
1627
+ //# sourceMappingURL=template-fields-IgDV7PRY.js.map