@snowcone-app/canvas 0.21.2 → 0.22.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 (47) hide show
  1. package/STYLING_CONTRACT.md +31 -7
  2. package/dist/{CanvasRenderer-B0szG0Us.js → CanvasRenderer-6_HhR4-q.js} +170 -189
  3. package/dist/CanvasRenderer-6_HhR4-q.js.map +1 -0
  4. package/dist/{ContextualToolbars-BYnovWnN.js → ContextualToolbars-BDEt9ND0.js} +1619 -1846
  5. package/dist/ContextualToolbars-BDEt9ND0.js.map +1 -0
  6. package/dist/{EditorCanvasImpl-BmLHjXe7.js → EditorCanvasImpl-BH_bKy-F.js} +5 -5
  7. package/dist/{EditorCanvasImpl-BmLHjXe7.js.map → EditorCanvasImpl-BH_bKy-F.js.map} +1 -1
  8. package/dist/ImagePanel-BwqFDKvW.js +951 -0
  9. package/dist/ImagePanel-BwqFDKvW.js.map +1 -0
  10. package/dist/{SnowconeCanvas-Bj2773ym.js → SnowconeCanvas-Cx7nXlBI.js} +19 -18
  11. package/dist/{SnowconeCanvas-Bj2773ym.js.map → SnowconeCanvas-Cx7nXlBI.js.map} +1 -1
  12. package/dist/{UnifiedFontService-C8gaspRD.js → UnifiedFontService-CC3CSmH5.js} +1042 -984
  13. package/dist/UnifiedFontService-CC3CSmH5.js.map +1 -0
  14. package/dist/advanced.mjs +97 -96
  15. package/dist/advanced.mjs.map +1 -1
  16. package/dist/api/embed.d.ts +3 -1
  17. package/dist/components/editor/EditorCanvas.d.ts +9 -0
  18. package/dist/components/editor/EditorRoot.d.ts +11 -0
  19. package/dist/components/editor/LazyImageBrowser.d.ts +7 -0
  20. package/dist/components/editor/commerceStore.d.ts +13 -0
  21. package/dist/components/embed-realtime/validateEmbed.d.ts +10 -4
  22. package/dist/custom-icons-BW6hqmkL.js +236 -0
  23. package/dist/custom-icons-BW6hqmkL.js.map +1 -0
  24. package/dist/design/product-config.d.ts +48 -0
  25. package/dist/editorErrors-B2mb1sVN.js.map +1 -1
  26. package/dist/{embed-pM7ZkFuz.js → embed-8ecUMMH-.js} +550 -441
  27. package/dist/embed-8ecUMMH-.js.map +1 -0
  28. package/dist/embed.mjs +30 -29
  29. package/dist/errors/editorError.d.ts +3 -0
  30. package/dist/guards-8rkFAMBs.js +24 -0
  31. package/dist/guards-8rkFAMBs.js.map +1 -0
  32. package/dist/index.mjs +5 -5
  33. package/dist/internals.mjs +1 -1
  34. package/dist/style.css +1 -1
  35. package/dist/{template-fields-BsnHMf1i.js → template-fields-C2pSfMBh.js} +57 -39
  36. package/dist/template-fields-C2pSfMBh.js.map +1 -0
  37. package/dist/validation-C9Fe9ahK.js +8367 -0
  38. package/dist/validation-C9Fe9ahK.js.map +1 -0
  39. package/example/package.json +1 -1
  40. package/package.json +1 -1
  41. package/dist/CanvasRenderer-B0szG0Us.js.map +0 -1
  42. package/dist/ContextualToolbars-BYnovWnN.js.map +0 -1
  43. package/dist/UnifiedFontService-C8gaspRD.js.map +0 -1
  44. package/dist/embed-pM7ZkFuz.js.map +0 -1
  45. package/dist/template-fields-BsnHMf1i.js.map +0 -1
  46. package/dist/validation-DdVeWnlo.js +0 -9308
  47. package/dist/validation-DdVeWnlo.js.map +0 -1
@@ -1,91 +1,91 @@
1
- import { E as ye, o as be, p as ve, C as xe, q, r as we, t as Ee, v as Se, w as ke, x as Ie, g as Re, e as Ce } from "./UnifiedFontService-C8gaspRD.js";
2
- import { y as N } from "./FontAnalyzer-CwIpgTGd.js";
3
- import { jsx as s, jsxs as k, Fragment as oe } from "react/jsx-runtime";
4
- import { useContext as Oe, createContext as Ne, useRef as C, useState as I, useMemo as O, useSyncExternalStore as B, useEffect as A, Component as Te, forwardRef as se, useId as X, useLayoutEffect as W, useCallback as j } from "react";
5
- import { assertVariantSelected as $e, RenderSession as _e, createCartDetail as De } from "@snowcone-app/sdk";
6
- import { i as ie, g as F, B as Ve, E as Ae, r as Fe } from "./editorErrors-B2mb1sVN.js";
7
- import { u as Be, p as Ue } from "./usePieceGuideBundle-CbJJg66S.js";
8
- import { s as Z, i as Le } from "./design-builder-CT4DHIPe.js";
9
- import { D as Pe, C as je, g as qe, e as Me } from "./template-fields-BsnHMf1i.js";
1
+ import { E as Ee, o as xe, p as ke, C as Ie, q as M, r as Re, t as Se, v as Ce, w as Oe, x as Ne, g as Te, e as _e } from "./UnifiedFontService-CC3CSmH5.js";
2
+ import { y as $ } from "./FontAnalyzer-CwIpgTGd.js";
3
+ import { jsx as o, jsxs as C, Fragment as $e } from "react/jsx-runtime";
4
+ import { useContext as De, createContext as Ae, useRef as R, useState as O, useMemo as T, useSyncExternalStore as j, useEffect as B, Component as Be, forwardRef as ce, useId as ne, useLayoutEffect as W, useCallback as q } from "react";
5
+ import { assertVariantSelected as Le, RenderSession as Ve, createCartDetail as Ue } from "@snowcone-app/sdk";
6
+ import { i as le, g as _, B as Fe, E as je, r as qe } from "./editorErrors-B2mb1sVN.js";
7
+ import { u as Me, p as ze } from "./usePieceGuideBundle-CbJJg66S.js";
8
+ import { s as re, i as Pe } from "./design-builder-CT4DHIPe.js";
9
+ import { D as He, C as Ke, g as Ge, e as We } from "./template-fields-C2pSfMBh.js";
10
10
  import "./CanvasStateV1-DmZ1Qvvn.js";
11
- const ae = Ne(void 0);
12
- function G() {
13
- const t = Oe(ae);
11
+ const ue = Ae(void 0);
12
+ function Q() {
13
+ const t = De(ue);
14
14
  if (!t)
15
15
  throw new Error(
16
16
  "useRealtimeMockups / <RealtimeCanvas> / <RealtimeMockup> must be rendered inside <RealtimeEmbed>. Wrap them: <RealtimeEmbed shop=… product=… design=… grantUrl=…>…</RealtimeEmbed>"
17
17
  );
18
18
  return t;
19
19
  }
20
- const ze = "[RealtimeEmbed]";
21
- function He(t) {
22
- var r, o;
20
+ const Qe = "[RealtimeEmbed]";
21
+ function Je(t) {
22
+ var r, s;
23
23
  if ((r = t == null ? void 0 : t.requiredPlacements) != null && r.length)
24
24
  return t.requiredPlacements.filter((a) => !a.autoFilledByVariant).map((a) => a.label);
25
25
  const e = new Set(
26
- (((o = t == null ? void 0 : t.options) == null ? void 0 : o.combinations) ?? []).map((a) => a.variantId).filter((a) => typeof a == "string" && a !== "")
26
+ (((s = t == null ? void 0 : t.options) == null ? void 0 : s.combinations) ?? []).map((a) => a.variantId).filter((a) => typeof a == "string" && a !== "")
27
27
  );
28
28
  return !!(t != null && t.variantId) || e.size > 1 ? [] : (t == null ? void 0 : t.placements) ?? [];
29
29
  }
30
- function ce({ shop: t, product: e, design: n, hasGrant: r }) {
31
- var l, m;
32
- const o = [];
33
- if (t || o.push({
30
+ function me({ shop: t, product: e, design: n, hasGrant: r }) {
31
+ var f, u;
32
+ const s = [];
33
+ if (t || s.push({
34
34
  severity: "error",
35
35
  issue: "missing-shop",
36
36
  message: "`shop` is required (your publishable shop id)."
37
- }), r || o.push({
37
+ }), r || s.push({
38
38
  severity: "error",
39
39
  issue: "missing-grant",
40
40
  message: "no grant source — pass `grantUrl` (a proxy to mintRealtimeGrant) or `grant`. Without it the session can never authorize and no mockup renders."
41
- }), (l = e == null ? void 0 : e.mockupIds) != null && l.length || o.push({
41
+ }), (f = e == null ? void 0 : e.mockupIds) != null && f.length || s.push({
42
42
  severity: "error",
43
43
  issue: "empty-mockup-ids",
44
44
  message: 'product.mockupIds is empty — pass the catalog scene codes (product.mockups[].id) you want rendered, e.g. ["FV1qjO"].'
45
45
  }), e != null && e.options)
46
46
  try {
47
- $e(e);
48
- } catch (f) {
49
- o.push({
47
+ Le(e);
48
+ } catch (m) {
49
+ s.push({
50
50
  severity: "error",
51
51
  issue: "variant-required",
52
- message: f instanceof Error ? f.message : String(f)
52
+ message: m instanceof Error ? m.message : String(m)
53
53
  });
54
54
  }
55
- const a = n.toJSON(), c = a.activeArtboard, u = He(e);
56
- u.length > 1 && o.push({
55
+ const a = n.toJSON(), d = a.activeArtboard, c = Je(e);
56
+ c.length > 1 && s.push({
57
57
  severity: "error",
58
58
  issue: "multi-placement",
59
- message: `product ${e.productId} requires placements [${u.join(", ")}] but this embed renders a single placement ("${c}"). The render will time out waiting for the others. This product needs the eject path — see https://developers.snowcone.app/embed-mode#eject.`
60
- }), (m = e == null ? void 0 : e.placements) != null && m.length && !e.placements.includes(c) && o.push({
59
+ message: `product ${e.productId} requires placements [${c.join(", ")}] but this embed renders a single placement ("${d}"). The render will time out waiting for the others. This product needs the eject path — see https://developers.snowcone.app/embed-mode#eject.`
60
+ }), (u = e == null ? void 0 : e.placements) != null && u.length && !e.placements.includes(d) && s.push({
61
61
  severity: "error",
62
62
  issue: "placement-mismatch",
63
- message: `the design's placement "${c}" is not in product.placements [${e.placements.join(", ")}]. The canvas artboard name and renderState placement must equal a real product placement label, or the server renders a blank mockup. Fix the \`name\` passed to design({ name }).`
63
+ message: `the design's placement "${d}" is not in product.placements [${e.placements.join(", ")}]. The canvas artboard name and renderState placement must equal a real product placement label, or the server renders a blank mockup. Fix the \`name\` passed to design({ name }).`
64
64
  });
65
- const d = a.elements.map((f) => f.name).filter((f) => !!f), i = d.filter((f, h) => d.indexOf(f) !== h);
66
- return i.length && o.push({
65
+ const l = a.elements.map((m) => m.name).filter((m) => !!m), i = l.filter((m, y) => l.indexOf(m) !== y);
66
+ return i.length && s.push({
67
67
  severity: "warn",
68
68
  issue: "duplicate-layer-names",
69
69
  message: `duplicate layer name(s) [${[...new Set(i)].join(", ")}] — useTextBinding(name) / useImageBinding(name) bind to the FIRST match, so a duplicate name makes a control edit the wrong layer. Keep names unique.`
70
- }), o;
70
+ }), s;
71
71
  }
72
- function Ke(t) {
73
- for (const e of ce(t))
74
- (e.severity === "error" && e.issue !== "placement-mismatch" ? console.error : console.warn)(`${ze} ${e.message}`);
72
+ function Ye(t) {
73
+ for (const e of me(t))
74
+ (e.severity === "error" && e.issue !== "placement-mismatch" ? console.error : console.warn)(`${Qe} ${e.message}`);
75
75
  }
76
- const le = 8e3;
77
- function We(t) {
78
- return `[RealtimeEmbed] No mockup after ${Math.round(le / 1e3)}s. Common causes: a variant product missing \`variantId\` (pass \`product.options\` so the embed can flag it up front), a multi-placement product (the server waits for every required placement but <RealtimeEmbed> sends only "${t}" — pass \`product.requiredPlacements\` so this is flagged at mount; such products need the eject path), an unreachable or non-public asset URL in the design, or the placement "${t}" not existing on the product. The render may still arrive — this is a heads-up, not a failure.`;
76
+ const pe = 8e3;
77
+ function Xe(t) {
78
+ return `[RealtimeEmbed] No mockup after ${Math.round(pe / 1e3)}s. Common causes: a variant product missing \`variantId\` (pass \`product.options\` so the embed can flag it up front), a multi-placement product (the server waits for every required placement but <RealtimeEmbed> sends only "${t}" — pass \`product.requiredPlacements\` so this is flagged at mount; such products need the eject path), an unreachable or non-public asset URL in the design, or the placement "${t}" not existing on the product. The render may still arrive — this is a heads-up, not a failure.`;
79
79
  }
80
- function Ge(t) {
80
+ function Ze(t) {
81
81
  if ("grantUrl" in t && t.grantUrl)
82
82
  return { grantUrl: t.grantUrl };
83
83
  const e = t.grant;
84
84
  return typeof e == "function" ? { getToken: e } : { getToken: () => Promise.resolve(e) };
85
85
  }
86
- function de({ error: t, onRetry: e }) {
87
- const n = ie(t) ? t.code : "EDITOR_ERROR";
88
- return /* @__PURE__ */ k(
86
+ function fe({ error: t, onRetry: e }) {
87
+ const n = le(t) ? t.code : "EDITOR_ERROR";
88
+ return /* @__PURE__ */ C(
89
89
  "div",
90
90
  {
91
91
  "data-sc-part": "error",
@@ -101,12 +101,12 @@ function de({ error: t, onRetry: e }) {
101
101
  lineHeight: 1.5
102
102
  },
103
103
  children: [
104
- /* @__PURE__ */ k("p", { style: { margin: 0, fontWeight: 700 }, children: [
104
+ /* @__PURE__ */ C("p", { style: { margin: 0, fontWeight: 700 }, children: [
105
105
  "Editor failed: ",
106
106
  n
107
107
  ] }),
108
- /* @__PURE__ */ s("p", { style: { margin: "4px 0 0" }, children: t.message }),
109
- e ? /* @__PURE__ */ s(
108
+ /* @__PURE__ */ o("p", { style: { margin: "4px 0 0" }, children: t.message }),
109
+ e ? /* @__PURE__ */ o(
110
110
  "button",
111
111
  {
112
112
  type: "button",
@@ -130,7 +130,7 @@ function de({ error: t, onRetry: e }) {
130
130
  }
131
131
  );
132
132
  }
133
- class Qe extends Te {
133
+ class et extends Be {
134
134
  constructor() {
135
135
  super(...arguments), this.state = { caught: null };
136
136
  }
@@ -139,181 +139,208 @@ class Qe extends Te {
139
139
  }
140
140
  componentDidCatch(e) {
141
141
  var n;
142
- Fe(e), typeof N < "u" && ((n = N.env) == null ? void 0 : n.NODE_ENV) !== "production" && console.error("[Editor.Root] contained a composition error:", e);
142
+ qe(e), typeof $ < "u" && ((n = $.env) == null ? void 0 : n.NODE_ENV) !== "production" && console.error("[Editor.Root] contained a composition error:", e);
143
143
  }
144
144
  render() {
145
- return this.state.caught ? /* @__PURE__ */ s(de, { error: this.state.caught }) : this.props.children;
145
+ return this.state.caught ? /* @__PURE__ */ o(fe, { error: this.state.caught }) : this.props.children;
146
146
  }
147
147
  }
148
- function Je({ reportedError: t, onRetry: e, children: n }) {
148
+ function tt({ reportedError: t, onRetry: e, children: n }) {
149
149
  if (t) {
150
- const r = ie(t) && t.code === "E_CHUNK_LOAD_FAILED";
151
- return /* @__PURE__ */ s(de, { error: t, onRetry: r ? e : void 0 });
150
+ const r = le(t) && t.code === "E_CHUNK_LOAD_FAILED";
151
+ return /* @__PURE__ */ o(fe, { error: t, onRetry: r ? e : void 0 });
152
152
  }
153
- return /* @__PURE__ */ s(Qe, { reportedError: null, onRetry: e, children: n });
153
+ return /* @__PURE__ */ o(et, { reportedError: null, onRetry: e, children: n });
154
154
  }
155
- function Ye(t) {
155
+ function nt(t) {
156
156
  const {
157
157
  shop: e,
158
158
  product: n,
159
159
  design: r,
160
- throttleMs: o = 200,
160
+ throttleMs: s = 200,
161
161
  onMockups: a,
162
- onRenderError: c,
163
- wsUrl: u,
164
- services: d,
165
- children: i,
166
- internals: l,
162
+ onRenderError: d,
163
+ onIssue: c,
164
+ wsUrl: l,
165
+ services: i,
166
+ children: f,
167
+ internals: u,
167
168
  __validation: m = "throw"
168
- } = t, f = O(() => r.toJSON().activeArtboard, [r]);
169
- B(
170
- l.commerce.subscribe,
171
- l.commerce.getVersion,
172
- l.commerce.getVersion
169
+ } = t, y = T(() => r.toJSON().activeArtboard, [r]), b = T(() => {
170
+ const p = r.toJSON().artboards[0];
171
+ if (p)
172
+ return {
173
+ name: p.name,
174
+ width: p.width,
175
+ height: p.height,
176
+ ...p.backgroundColor ? { backgroundColor: p.backgroundColor } : {}
177
+ };
178
+ }, [r]);
179
+ j(
180
+ u.commerce.subscribe,
181
+ u.commerce.getVersion,
182
+ u.commerce.getVersion
173
183
  );
174
- const h = l.commerce.resolvedVariantId(), p = Be(h ?? n.variantId ?? n.defaultGvid), w = O(() => {
175
- if (!p) return null;
176
- const g = r.toJSON().artboards[0];
177
- return Ue(p, g) ?? null;
178
- }, [p, r]), E = C(a), b = C(c);
179
- E.current = a, b.current = c;
180
- const [T, R] = I([]), [D, x] = I(!0), [$, _] = I(null), U = !!("grantUrl" in t && t.grantUrl || "grant" in t && t.grant), P = Ge(t), pe = "grantUrl" in P ? P.grantUrl : "getToken", ee = `${n.productId}|${n.mockupIds.join(",")}|${n.variantId ?? ""}`, M = `${e}|${ee}|${f}|${U}`;
181
- O(() => {
182
- var S;
183
- if (m !== "throw") return;
184
- const g = ce({ shop: e, product: n, design: r, hasGrant: U }), y = g.find((L) => L.severity === "error");
185
- if (y)
186
- throw new F("E_EMBED_CONFIG", y.message, {
187
- issue: y.issue,
184
+ const v = u.commerce.renderVariantId(), w = Me(v ?? n.variantId ?? n.defaultGvid), h = T(() => {
185
+ if (!w) return null;
186
+ const p = r.toJSON().artboards[0];
187
+ return ze(w, p) ?? null;
188
+ }, [w, r]), x = R(a), g = R(d), N = R(c);
189
+ x.current = a, g.current = d, N.current = c;
190
+ const [S, L] = O([]), [D, V] = O(!0), [z, P] = O(null), J = !!("grantUrl" in t && t.grantUrl || "grant" in t && t.grant), Y = Ze(t), be = "grantUrl" in Y ? Y.grantUrl : "getToken", ie = `${n.productId}|${n.mockupIds.join(",")}|${n.variantId ?? ""}`, F = `${e}|${ie}|${y}|${J}`, X = T(() => {
191
+ var I;
192
+ const p = me({ shop: e, product: n, design: r, hasGrant: J });
193
+ if (m !== "throw") return p;
194
+ const E = p.find((A) => A.severity === "error");
195
+ if (E)
196
+ throw new _("E_EMBED_CONFIG", E.message, {
197
+ issue: E.issue,
188
198
  docSlug: "embed-mode"
189
199
  });
190
- for (const L of g)
191
- typeof N < "u" && ((S = N.env) == null ? void 0 : S.NODE_ENV) !== "production" && console.warn(`[Editor.Root] ${L.message}`);
192
- }, [M, m]);
193
- const te = C(null);
194
- A(() => {
195
- var g;
196
- if (m === "warn" && typeof N < "u" && ((g = N.env) == null ? void 0 : g.NODE_ENV) !== "production") {
197
- if (te.current === M) return;
198
- te.current = M, Ke({ shop: e, product: n, design: r, hasGrant: U });
200
+ for (const A of p)
201
+ typeof $ < "u" && ((I = $.env) == null ? void 0 : I.NODE_ENV) !== "production" && console.warn(`[Editor.Root] ${A.message}`);
202
+ return p;
203
+ }, [F, m]), se = R(null);
204
+ B(() => {
205
+ var p;
206
+ if (X.length !== 0 && se.current !== F) {
207
+ se.current = F;
208
+ for (const E of X) (p = N.current) == null || p.call(N, E);
209
+ }
210
+ }, [X, F]);
211
+ const oe = R(null);
212
+ B(() => {
213
+ var p;
214
+ if (m === "warn" && typeof $ < "u" && ((p = $.env) == null ? void 0 : p.NODE_ENV) !== "production") {
215
+ if (oe.current === F) return;
216
+ oe.current = F, Ye({ shop: e, product: n, design: r, hasGrant: J });
199
217
  }
200
- }, [M, m]);
201
- const z = O(
218
+ }, [F, m]);
219
+ const H = T(
202
220
  () => {
203
221
  try {
204
- return { session: new _e({ shop: e, product: n, wsUrl: u, ...P }) };
205
- } catch (g) {
206
- return { error: g instanceof Error ? g.message : String(g) };
222
+ return { session: new Ve({ shop: e, product: n, wsUrl: l, ...Y }) };
223
+ } catch (p) {
224
+ return { error: p instanceof Error ? p.message : String(p) };
207
225
  }
208
226
  },
209
227
  // eslint-disable-next-line react-hooks/exhaustive-deps
210
- [e, ee, f, u, pe]
211
- ), v = "session" in z ? z.session : null, H = "error" in z ? z.error : null, K = O(() => (g, y = o) => {
212
- v && (_(null), x(!0), v.renderState(f, g, y).catch((S) => {
213
- var re;
214
- const L = S instanceof Error ? S.message : String(S);
215
- _(L), x(!1), (re = b.current) == null || re.call(b, L);
228
+ [e, ie, y, l, be]
229
+ ), k = "session" in H ? H.session : null, K = "error" in H ? H.error : null, G = T(() => (p, E = s) => {
230
+ k && (P(null), V(!0), k.renderState(y, p, E).catch((I) => {
231
+ var de;
232
+ const A = I instanceof Error ? I.message : String(I);
233
+ P(A), V(!1), (de = g.current) == null || de.call(g, A);
216
234
  }));
217
- }, [v, f, o]);
218
- A(() => {
219
- var g;
220
- if (H) {
221
- _(H), x(!1), (g = b.current) == null || g.call(b, H);
235
+ }, [k, y, s]);
236
+ B(() => {
237
+ var p;
238
+ if (K) {
239
+ P(K), V(!1), (p = g.current) == null || p.call(g, K);
222
240
  return;
223
241
  }
224
- if (v)
225
- return v.onMockups((y) => {
226
- var S;
227
- R(y), x(!1), (S = E.current) == null || S.call(E, y);
228
- }), v.onError((y) => {
229
- var S;
230
- _(y), x(!1), (S = b.current) == null || S.call(b, y);
231
- }), K(r.toServerRequest()), () => v.close();
232
- }, [v, H]);
233
- const Q = C({
242
+ if (k)
243
+ return k.onMockups((E) => {
244
+ var I;
245
+ L(E), V(!1), (I = x.current) == null || I.call(x, E);
246
+ }), k.onError((E) => {
247
+ var I;
248
+ P(E), V(!1), (I = g.current) == null || I.call(g, E);
249
+ }), G(r.toServerRequest()), () => k.close();
250
+ }, [k, K]);
251
+ const Z = R({
234
252
  session: null,
235
253
  variantId: void 0
236
254
  });
237
- A(() => {
238
- if (!v || !h) return;
239
- const g = Q.current, y = g.session === v ? g.variantId : n.variantId;
240
- if (h === y) {
241
- Q.current = { session: v, variantId: y };
255
+ B(() => {
256
+ if (!k || !v) return;
257
+ const p = Z.current, E = p.session === k ? p.variantId : n.variantId;
258
+ if (v === E) {
259
+ Z.current = { session: k, variantId: E };
242
260
  return;
243
261
  }
244
- Q.current = { session: v, variantId: h }, v.setProduct({ ...n, variantId: h }), K(Z(l.store.getState()));
245
- }, [v, h]), A(() => {
246
- var y;
247
- if (!D || typeof N > "u" || ((y = N.env) == null ? void 0 : y.NODE_ENV) === "production") return;
248
- const g = setTimeout(() => console.warn(We(f)), le);
249
- return () => clearTimeout(g);
250
- }, [D, f]);
251
- const ge = O(
262
+ Z.current = { session: k, variantId: v }, k.setProduct({ ...n, variantId: v }), G(re(u.store.getState()));
263
+ }, [k, v]), B(() => {
264
+ if (!D) return;
265
+ const p = setTimeout(() => {
266
+ var I, A;
267
+ const E = Xe(y);
268
+ typeof $ < "u" && ((I = $.env) == null ? void 0 : I.NODE_ENV) !== "production" && console.warn(E), (A = N.current) == null || A.call(N, { severity: "warn", issue: "slow-render", message: E });
269
+ }, pe);
270
+ return () => clearTimeout(p);
271
+ }, [D, y]);
272
+ const ve = T(
252
273
  () => ({
253
- session: v,
274
+ session: k,
254
275
  design: r,
255
- placement: f,
276
+ placement: y,
256
277
  product: n,
257
- mockups: T,
278
+ mockups: S,
258
279
  isRendering: D,
259
- error: $,
260
- throttleMs: o,
261
- pieceGuides: w,
262
- pushRender: K,
263
- stateStore: l.store
280
+ error: z,
281
+ throttleMs: s,
282
+ pieceGuides: h,
283
+ pushRender: G,
284
+ stateStore: u.store
264
285
  }),
265
- [v, r, f, n, T, D, $, o, w, K, l.store]
266
- ), he = B(
267
- l.registry.subscribe,
268
- l.registry.getVersion,
269
- l.registry.getVersion
286
+ [k, r, y, n, S, D, z, s, h, G, u.store]
287
+ ), we = j(
288
+ u.registry.subscribe,
289
+ u.registry.getVersion,
290
+ u.registry.getVersion
270
291
  );
271
- O(() => l.registry.validate(), [l.registry, he]);
272
- const ne = /* @__PURE__ */ s(ve.Provider, { value: l, children: /* @__PURE__ */ s(ae.Provider, { value: ge, children: /* @__PURE__ */ s(Ve.Provider, { value: l.registry, children: /* @__PURE__ */ s(Ae, { children: i }) }) }) });
273
- return d ? /* @__PURE__ */ s(xe, { services: d, children: ne }) : ne;
292
+ T(() => u.registry.validate(), [u.registry, we]);
293
+ const ae = /* @__PURE__ */ o(ke.Provider, { value: u, children: /* @__PURE__ */ o(ue.Provider, { value: ve, children: /* @__PURE__ */ o(Fe.Provider, { value: u.registry, children: /* @__PURE__ */ o(
294
+ je,
295
+ {
296
+ ...b ? { initialArtboardConfig: b } : {},
297
+ children: f
298
+ }
299
+ ) }) }) });
300
+ return i ? /* @__PURE__ */ o(Ie, { services: i, children: ae }) : ae;
274
301
  }
275
- function ue(t) {
276
- const { design: e, product: n } = t, r = `${n.productId}|${n.variantId ?? ""}`, o = C(null), a = C(null), [c, u] = I(null);
277
- (o.current === null || o.current.design !== e) && (o.current = {
302
+ function he(t) {
303
+ const { design: e, product: n } = t, r = `${n.productId}|${n.variantId ?? ""}`, s = R(null), a = R(null), [d, c] = O(null);
304
+ (s.current === null || s.current.design !== e) && (s.current = {
278
305
  design: e,
279
306
  internals: {
280
- store: new Pe(e.toJSON()),
281
- registry: new ye()
307
+ store: new He(e.toJSON()),
308
+ registry: new Ee()
282
309
  }
283
- }), (a.current === null || a.current.productIdentity !== r) && (a.current = { productIdentity: r, commerce: new je(n) });
284
- const d = O(
310
+ }), (a.current === null || a.current.productIdentity !== r) && (a.current = { productIdentity: r, commerce: new Ke(n) });
311
+ const l = T(
285
312
  () => ({
286
- ...o.current.internals,
313
+ ...s.current.internals,
287
314
  commerce: a.current.commerce,
288
- ...be(u)
315
+ ...xe(c)
289
316
  }),
290
317
  // eslint-disable-next-line react-hooks/exhaustive-deps
291
- [o.current.internals, a.current.commerce]
318
+ [s.current.internals, a.current.commerce]
292
319
  );
293
320
  return (
294
321
  // `display: contents` — the .sc-root scope without a layout box, so the
295
322
  // host's grid/flex sees the parts directly (and the legacy RealtimeEmbed
296
323
  // wrapper, which had no DOM at all, stays layout-identical).
297
- /* @__PURE__ */ s("div", { className: "sc-root", style: { display: "contents" }, "data-sc-part": "root", children: /* @__PURE__ */ s(Je, { reportedError: c, onRetry: () => u(null), children: /* @__PURE__ */ s(Ye, { ...t, internals: d }) }) })
324
+ /* @__PURE__ */ o("div", { className: "sc-root", style: { display: "contents" }, "data-sc-part": "root", children: /* @__PURE__ */ o(tt, { reportedError: d, onRetry: () => c(null), children: /* @__PURE__ */ o(nt, { ...t, internals: l }) }) })
298
325
  );
299
326
  }
300
- let Xe = () => import("./EditorCanvasImpl-BmLHjXe7.js").then((t) => t.EditorCanvasImpl);
301
- function me() {
302
- return Xe();
327
+ let rt = () => import("./EditorCanvasImpl-BH_bKy-F.js").then((t) => t.EditorCanvasImpl);
328
+ function ge() {
329
+ return rt();
303
330
  }
304
- const Ze = se(function({ children: e, maxHeight: n, className: r, style: o }, a) {
305
- const c = q("Editor.Canvas"), u = X();
306
- W(() => c.registry.registerCanvas(u), [c.registry, u]);
307
- const [d, i] = I(null);
308
- return A(() => {
309
- let l = !1;
310
- return me().then(
331
+ const it = ce(function({ children: e, maxHeight: n, floatingToolbar: r = !0, className: s, style: a }, d) {
332
+ const c = M("Editor.Canvas"), l = ne();
333
+ W(() => c.registry.registerCanvas(l), [c.registry, l]);
334
+ const [i, f] = O(null);
335
+ return B(() => {
336
+ let u = !1;
337
+ return ge().then(
311
338
  (m) => {
312
- l || i(() => m);
339
+ u || f(() => m);
313
340
  },
314
341
  (m) => {
315
- l || c.reportRuntimeError(
316
- new F(
342
+ u || c.reportRuntimeError(
343
+ new _(
317
344
  "E_CHUNK_LOAD_FAILED",
318
345
  `the editor's rendering chunk failed to load (${m instanceof Error ? m.message : String(m)}). This is a network/CDN failure, not a composition mistake — retry, or check the deployment serves the @snowcone-app/canvas lazy chunks.`,
319
346
  { cause: m instanceof Error ? m.message : String(m), docSlug: "embed-mode" }
@@ -321,102 +348,127 @@ const Ze = se(function({ children: e, maxHeight: n, className: r, style: o }, a)
321
348
  );
322
349
  }
323
350
  ), () => {
324
- l = !0;
351
+ u = !0;
325
352
  };
326
- }, [c]), d ? (
353
+ }, [c]), i ? (
327
354
  // `builtinControls`: the canvas owns the floating contextual toolbar
328
- // unless a docked <Editor.Controls> is mounted (ADR-0085 §5). Only here —
329
- // the legacy <RealtimeCanvas> wrapper stays chrome-less.
330
- /* @__PURE__ */ s(d, { ref: a, kit: "embed-only", partAttr: "canvas", builtinControls: !0, maxHeight: n, className: r, style: o, children: e })
331
- ) : /* @__PURE__ */ s(
355
+ // unless the host opts out via `floatingToolbar={false}` or a docked
356
+ // <Editor.Controls> is mounted (ADR-0085 §5). Only here — the legacy
357
+ // <RealtimeCanvas> wrapper stays chrome-less.
358
+ /* @__PURE__ */ o(
359
+ i,
360
+ {
361
+ ref: d,
362
+ kit: "embed-only",
363
+ partAttr: "canvas",
364
+ builtinControls: r,
365
+ maxHeight: n,
366
+ className: s,
367
+ style: a,
368
+ children: e
369
+ }
370
+ )
371
+ ) : /* @__PURE__ */ o(
332
372
  "div",
333
373
  {
334
374
  "data-sc-part": "canvas",
335
375
  "data-sc-state": "loading",
336
- className: r,
337
- style: { minHeight: n ?? 200, ...o },
376
+ className: s,
377
+ style: { minHeight: n ?? 200, ...a },
338
378
  "aria-busy": "true"
339
379
  }
340
380
  );
341
- }), et = 1.2, J = [1200, 1400, 1600, 1800, 2e3, 2500, 3e3, 4e3];
342
- function tt(t) {
343
- for (const e of J)
381
+ }), st = 1.2, ee = [1200, 1400, 1600, 1800, 2e3, 2500, 3e3, 4e3];
382
+ function ot(t) {
383
+ for (const e of ee)
344
384
  if (e >= t) return e;
345
- return J[J.length - 1];
385
+ return ee[ee.length - 1];
346
386
  }
347
- function nt(t, e) {
348
- if (!(t > 0) || !(e > 0) || e <= t * et) return null;
349
- const n = tt(e);
387
+ function at(t, e) {
388
+ if (!(t > 0) || !(e > 0) || e <= t * st) return null;
389
+ const n = ot(e);
350
390
  return `[RealtimeMockup] mockup rendered at ${t}px but displayed at ~${e} device px — the preview will look soft. Pass \`product.width\` (e.g. ${n}) on the embed for a crisp preview.`;
351
391
  }
352
- function fe({
392
+ function ye({
353
393
  mockupId: t,
354
394
  fallback: e = null,
355
395
  alt: n = "Live product mockup",
356
396
  className: r,
357
- style: o
397
+ style: s
358
398
  }) {
359
- const { mockups: a, error: c } = G(), u = C(/* @__PURE__ */ new Set()), d = t ? a.find((l) => l.mockupId === t && l.imageUrl) : a.find((l) => l.imageUrl);
360
- if (!(d != null && d.imageUrl))
361
- return c ? /* @__PURE__ */ s("div", { "data-sc-part": "preview-error", role: "alert", "data-sc-error": c, className: r, style: o, children: e ?? `Render failed: ${c}` }) : /* @__PURE__ */ s(oe, { children: e });
362
- const i = (l) => {
399
+ const { mockups: a, error: d, isRendering: c } = Q(), l = R(/* @__PURE__ */ new Set()), i = t ? a.find((u) => u.mockupId === t && u.imageUrl) : a.find((u) => u.imageUrl);
400
+ if (!(i != null && i.imageUrl))
401
+ return d ? /* @__PURE__ */ o(
402
+ "div",
403
+ {
404
+ "data-sc-part": "preview-error",
405
+ "data-sc-preview-state": "error",
406
+ role: "alert",
407
+ "data-sc-error": d,
408
+ className: r,
409
+ style: s,
410
+ children: e ?? `Render failed: ${d}`
411
+ }
412
+ ) : /* @__PURE__ */ o("div", { "data-sc-part": "preview", "data-sc-preview-state": "rendering", "aria-busy": "true", style: { display: "contents" }, children: e });
413
+ const f = (u) => {
363
414
  var w;
364
- if (typeof N > "u" || ((w = N.env) == null ? void 0 : w.NODE_ENV) === "production" || typeof window > "u" || u.current.has(d.mockupId)) return;
365
- const m = l.currentTarget, f = m.getBoundingClientRect().width;
366
- if (f <= 0) return;
367
- const h = Math.round(f * (window.devicePixelRatio || 1)), p = nt(m.naturalWidth, h);
368
- p && (u.current.add(d.mockupId), console.warn(p));
415
+ if (typeof $ > "u" || ((w = $.env) == null ? void 0 : w.NODE_ENV) === "production" || typeof window > "u" || l.current.has(i.mockupId)) return;
416
+ const m = u.currentTarget, y = m.getBoundingClientRect().width;
417
+ if (y <= 0) return;
418
+ const b = Math.round(y * (window.devicePixelRatio || 1)), v = at(m.naturalWidth, b);
419
+ v && (l.current.add(i.mockupId), console.warn(v));
369
420
  };
370
421
  return (
371
422
  // eslint-disable-next-line @next/next/no-img-element
372
- /* @__PURE__ */ s(
423
+ /* @__PURE__ */ o(
373
424
  "img",
374
425
  {
375
426
  "data-sc-part": "preview",
376
- src: d.imageUrl,
427
+ "data-sc-preview-state": c ? "rendering" : "ready",
428
+ src: i.imageUrl,
377
429
  alt: n,
378
430
  className: r,
379
- style: o,
380
- onLoad: i
431
+ style: s,
432
+ onLoad: f
381
433
  }
382
434
  )
383
435
  );
384
436
  }
385
- function rt(t) {
386
- const { layer: e, optional: n = !1, placeholder: r, className: o, style: a } = t, c = q("Editor.TextField"), { pushRender: u, throttleMs: d, stateStore: i } = G(), l = X(), m = C(null);
387
- if (!Le(e))
388
- throw new F(
437
+ function dt(t) {
438
+ const { layer: e, optional: n = !1, placeholder: r, className: s, style: a } = t, d = M("Editor.TextField"), { pushRender: c, throttleMs: l, stateStore: i } = Q(), f = ne(), u = R(null);
439
+ if (!Pe(e))
440
+ throw new _(
389
441
  "E_LAYER_TOKEN_REQUIRED",
390
442
  `the \`layer\` prop must be a token minted by the design — pass layer={design.layer("name")}, not ${typeof e == "string" ? `the bare string "${e}"` : "a plain value"}. Tokens validate the name against the design's layers at mint time.`,
391
443
  { received: typeof e == "string" ? e : typeof e, docSlug: "embed-mode" }
392
444
  );
393
- if (m.current !== e.name) {
394
- const p = i.layerKindOf(e.name);
395
- if (p === void 0)
396
- throw new F(
445
+ if (u.current !== e.name) {
446
+ const b = i.layerKindOf(e.name);
447
+ if (b === void 0)
448
+ throw new _(
397
449
  "E_LAYER_NOT_FOUND",
398
450
  `no layer "${e.name}" in this Root's design — the token was minted from a different design than the one passed to <Editor.Root design={…}>. Bindable layers here: ${JSON.stringify(i.bindableLayerNames())}.`,
399
451
  { layerName: e.name, validNames: i.bindableLayerNames(), docSlug: "embed-mode" }
400
452
  );
401
- if (p !== "text")
402
- throw new F(
453
+ if (b !== "text")
454
+ throw new _(
403
455
  "E_LAYER_WRONG_KIND",
404
- `layer "${e.name}" is ${p === null ? "not a bindable kind" : `an ${p} layer`} — <Editor.TextField> binds text layers only.`,
405
- { layerName: e.name, actualKind: p, docSlug: "embed-mode" }
456
+ `layer "${e.name}" is ${b === null ? "not a bindable kind" : `an ${b} layer`} — <Editor.TextField> binds text layers only.`,
457
+ { layerName: e.name, actualKind: b, docSlug: "embed-mode" }
406
458
  );
407
- m.current = e.name;
459
+ u.current = e.name;
408
460
  }
409
- W(() => c.registry.registerTextField(l, { name: e.name, optional: n }), [c.registry, l, e.name, n]);
410
- const f = B(
461
+ W(() => d.registry.registerTextField(f, { name: e.name, optional: n }), [d.registry, f, e.name, n]);
462
+ const m = j(
411
463
  i.subscribe,
412
464
  () => i.textOf(e.name) ?? "",
413
465
  () => i.textOf(e.name) ?? ""
414
- ), h = j(
415
- (p) => {
416
- const w = p.target.value, E = c.registry.getCanvasBridge();
417
- if (E) {
418
- E.setTextByName(e.name, w) || c.reportInvariant(
419
- new F(
466
+ ), y = q(
467
+ (b) => {
468
+ const v = b.target.value, w = d.registry.getCanvasBridge();
469
+ if (w) {
470
+ w.setTextByName(e.name, v) || d.reportInvariant(
471
+ new _(
420
472
  "E_LAYER_NOT_FOUND",
421
473
  `layer "${e.name}" no longer exists in the mounted canvas — it was removed or renamed after this <Editor.TextField> bound to it. Bound layers must not be renamed or deleted while a field is mounted (ADR-0085 §3).`,
422
474
  { layerName: e.name, docSlug: "embed-mode" }
@@ -424,26 +476,26 @@ function rt(t) {
424
476
  );
425
477
  return;
426
478
  }
427
- i.updateTextLayer(e.name, w), u(Z(i.getState()), d);
479
+ i.updateTextLayer(e.name, v), c(re(i.getState()), l);
428
480
  },
429
- [c, e.name, i, u, d]
481
+ [d, e.name, i, c, l]
430
482
  );
431
- return /* @__PURE__ */ s(
483
+ return /* @__PURE__ */ o(
432
484
  "input",
433
485
  {
434
486
  "data-sc-part": "textfield",
435
487
  "data-sc-layer": e.name,
436
488
  type: "text",
437
- value: f,
438
- onChange: h,
489
+ value: m,
490
+ onChange: y,
439
491
  placeholder: r,
440
492
  "aria-label": t["aria-label"] ?? e.name,
441
- className: o,
493
+ className: s,
442
494
  style: a
443
495
  }
444
496
  );
445
497
  }
446
- function ot(t) {
498
+ function ct(t) {
447
499
  const e = [];
448
500
  for (const n of t.missingOptionKeys)
449
501
  e.push(`option:${n}`);
@@ -455,114 +507,114 @@ function ot(t) {
455
507
  e.push(`layer:${n.name}`);
456
508
  continue;
457
509
  }
458
- const o = (t.seedTextOf(n.name) ?? "").trim();
459
- o.length > 0 && r === o && e.push(`layer-seed:${n.name}`);
510
+ const s = (t.seedTextOf(n.name) ?? "").trim();
511
+ s.length > 0 && r === s && e.push(`layer-seed:${n.name}`);
460
512
  }
461
513
  return t.hasRenderableElement || e.push("empty-design"), (!Number.isInteger(t.quantity) || t.quantity < 1) && e.push("quantity"), e;
462
514
  }
463
- function st(t, e) {
515
+ function lt(t, e) {
464
516
  const n = e.getCombinations(), r = e.getAttributes();
465
517
  if (Object.keys(r).length === 0 || n.length === 0) return null;
466
- const o = Object.fromEntries(
467
- Object.entries(r).map(([a, c]) => [a, { ...c, choices: qe(c) }])
518
+ const s = Object.fromEntries(
519
+ Object.entries(r).map(([a, d]) => [a, { ...d, choices: Ge(d) }])
468
520
  );
469
- return De({
521
+ return Ue({
470
522
  productId: t.productId,
471
523
  quantity: e.getQuantity(),
472
524
  selection: e.getSelection(),
473
525
  combinations: n,
474
- attributes: o
526
+ attributes: s
475
527
  });
476
528
  }
477
- function it(t) {
478
- const { onAddToCart: e, defaultQuantity: n, children: r, className: o, style: a } = t, c = q("Editor.Buy"), { product: u, stateStore: d } = G(), i = c.commerce;
479
- if (!(u != null && u.productId))
480
- throw new F(
529
+ function ut(t) {
530
+ const { onAddToCart: e, defaultQuantity: n, children: r, className: s, style: a } = t, d = M("Editor.Buy"), { product: c, stateStore: l } = Q(), i = d.commerce;
531
+ if (!(c != null && c.productId))
532
+ throw new _(
481
533
  "E_BUY_NO_PRODUCT",
482
534
  "<Editor.Buy> has no product context — pass `product` (with `productId`) on <Editor.Root product={…}>. Buy assembles its cart payload from the Root product and the live design state.",
483
535
  { docSlug: "embed-mode" }
484
536
  );
485
- const l = C(!1);
537
+ const f = R(!1);
486
538
  W(() => {
487
- l.current || (l.current = !0, typeof n == "number" && i.setQuantity(n));
539
+ f.current || (f.current = !0, typeof n == "number" && i.setQuantity(n));
488
540
  }, [i]);
489
- const m = B(d.subscribe, d.getState, d.getState), f = B(i.subscribe, i.getVersion, i.getVersion), h = B(
490
- c.registry.subscribe,
491
- c.registry.getVersion,
492
- c.registry.getVersion
493
- ), p = i.getQuantity(), w = O(
494
- () => ot({
495
- quantity: p,
541
+ const u = j(l.subscribe, l.getState, l.getState), m = j(i.subscribe, i.getVersion, i.getVersion), y = j(
542
+ d.registry.subscribe,
543
+ d.registry.getVersion,
544
+ d.registry.getVersion
545
+ ), b = i.getQuantity(), v = T(
546
+ () => ct({
547
+ quantity: b,
496
548
  missingOptionKeys: i.missingOptionKeys(),
497
549
  selectionValid: i.selectionValid(),
498
- textFields: c.registry.getTextFields(),
499
- textOf: (x) => d.textOf(x),
500
- seedTextOf: (x) => d.seedTextOf(x),
501
- hasRenderableElement: d.hasRenderableElement()
550
+ textFields: d.registry.getTextFields(),
551
+ textOf: (S) => l.textOf(S),
552
+ seedTextOf: (S) => l.seedTextOf(S),
553
+ hasRenderableElement: l.hasRenderableElement()
502
554
  }),
503
555
  // eslint-disable-next-line react-hooks/exhaustive-deps
504
- [i, p, m, f, h]
505
- ), E = w.length === 0, [b, T] = I(!1), R = C(!1), D = j(() => {
506
- if (R.current || !E) return;
507
- R.current = !0, T(!0);
508
- const x = d.getState(), $ = i.resolvedVariantId(), _ = {
509
- productId: u.productId,
510
- ...$ ? { variantId: $ } : {},
556
+ [i, b, u, m, y]
557
+ ), w = v.length === 0, [h, x] = O(!1), g = R(!1), N = q(() => {
558
+ if (g.current || !w) return;
559
+ g.current = !0, x(!0);
560
+ const S = l.getState(), L = i.resolvedVariantId(), D = {
561
+ productId: c.productId,
562
+ ...L ? { variantId: L } : {},
511
563
  quantity: i.getQuantity(),
512
564
  selection: i.getSelection(),
513
- cartDetail: st(u, i),
514
- designState: x,
515
- serverRequest: Z(x)
565
+ cartDetail: lt(c, i),
566
+ designState: S,
567
+ serverRequest: re(S)
516
568
  };
517
- let U;
569
+ let V;
518
570
  try {
519
- U = e(_);
520
- } catch (P) {
521
- throw R.current = !1, T(!1), P;
571
+ V = e(D);
572
+ } catch (z) {
573
+ throw g.current = !1, x(!1), z;
522
574
  }
523
- Promise.resolve(U).finally(() => {
524
- R.current = !1, T(!1);
575
+ Promise.resolve(V).finally(() => {
576
+ g.current = !1, x(!1);
525
577
  });
526
- }, [E, u, i, d, e]);
527
- return /* @__PURE__ */ s(
578
+ }, [w, c, i, l, e]);
579
+ return /* @__PURE__ */ o(
528
580
  "button",
529
581
  {
530
582
  type: "button",
531
583
  "data-sc-part": "buy",
532
- "data-sc-buy-state": b ? "busy" : E ? "ready" : "incomplete",
533
- "data-sc-buy-missing": w.join(",") || void 0,
534
- disabled: !E || b,
535
- "aria-busy": b || void 0,
536
- onClick: D,
537
- className: o,
584
+ "data-sc-buy-state": h ? "busy" : w ? "ready" : "incomplete",
585
+ "data-sc-buy-missing": v.join(",") || void 0,
586
+ disabled: !w || h,
587
+ "aria-busy": h || void 0,
588
+ onClick: N,
589
+ className: s,
538
590
  style: a,
539
591
  children: r ?? "Add to cart"
540
592
  }
541
593
  );
542
594
  }
543
- function at({
595
+ function mt({
544
596
  placement: t = "docked",
545
597
  className: e,
546
598
  style: n
547
599
  }) {
548
- const r = q("Editor.Controls");
549
- we("Editor.Controls");
550
- const o = X();
600
+ const r = M("Editor.Controls");
601
+ Re("Editor.Controls");
602
+ const s = ne();
551
603
  W(
552
- () => r.registry.registerControls(o, t),
553
- [r.registry, o, t]
604
+ () => r.registry.registerControls(s, t),
605
+ [r.registry, s, t]
554
606
  );
555
- const a = t === "docked", [c, u] = I(null);
556
- return A(() => {
607
+ const a = t === "docked", [d, c] = O(null);
608
+ return B(() => {
557
609
  if (!a) return;
558
- let d = !1;
559
- return import("./ContextualToolbars-BYnovWnN.js").then((i) => i.x).then(
610
+ let l = !1;
611
+ return import("./ContextualToolbars-BDEt9ND0.js").then((i) => i.s).then(
560
612
  (i) => {
561
- d || u(() => i.ContextualToolbars);
613
+ l || c(() => i.ContextualToolbars);
562
614
  },
563
615
  (i) => {
564
- d || r.reportRuntimeError(
565
- new F(
616
+ l || r.reportRuntimeError(
617
+ new _(
566
618
  "E_CHUNK_LOAD_FAILED",
567
619
  `the editor's controls chunk failed to load (${i instanceof Error ? i.message : String(i)}). This is a network/CDN failure, not a composition mistake — retry, or check the deployment serves the @snowcone-app/canvas lazy chunks.`,
568
620
  { cause: i instanceof Error ? i.message : String(i), docSlug: "embed-mode" }
@@ -570,23 +622,23 @@ function at({
570
622
  );
571
623
  }
572
624
  ), () => {
573
- d = !0;
625
+ l = !0;
574
626
  };
575
- }, [a, r]), a ? /* @__PURE__ */ s(
627
+ }, [a, r]), a ? /* @__PURE__ */ o(
576
628
  "div",
577
629
  {
578
630
  "data-sc-part": "controls",
579
631
  "data-sc-placement": "docked",
580
632
  className: e,
581
633
  style: n,
582
- "aria-busy": c ? void 0 : "true",
583
- children: c ? /* @__PURE__ */ s(c, { mode: "embedded" }) : null
634
+ "aria-busy": d ? void 0 : "true",
635
+ children: d ? /* @__PURE__ */ o(d, { mode: "embedded" }) : null
584
636
  }
585
637
  ) : null;
586
638
  }
587
- function ct() {
588
- const e = q("useProductSelection").commerce, n = B(e.subscribe, e.getVersion, e.getVersion), r = j((a, c) => e.select(a, c), [e]), o = j((a) => e.setQuantity(a), [e]);
589
- return O(
639
+ function pt() {
640
+ const e = M("useProductSelection").commerce, n = j(e.subscribe, e.getVersion, e.getVersion), r = q((a, d) => e.select(a, d), [e]), s = q((a) => e.setQuantity(a), [e]);
641
+ return T(
590
642
  () => ({
591
643
  attributes: e.getAttributes(),
592
644
  selection: e.getSelection(),
@@ -595,72 +647,128 @@ function ct() {
595
647
  variantId: e.resolvedVariantId(),
596
648
  price: e.resolvedPrice(),
597
649
  quantity: e.getQuantity(),
598
- setQuantity: o,
650
+ setQuantity: s,
599
651
  complete: e.selectionValid(),
600
652
  missing: e.missingOptionKeys()
601
653
  }),
602
654
  // eslint-disable-next-line react-hooks/exhaustive-deps
603
- [e, r, o, n]
655
+ [e, r, s, n]
604
656
  );
605
657
  }
606
- const V = {
658
+ const U = {
607
659
  /** The one provider boundary — session, design, live state, error boundary. */
608
- Root: ue,
660
+ Root: he,
609
661
  /** The editable artboard (the ONE lazy renderer boundary — D9). */
610
- Canvas: Ze,
662
+ Canvas: it,
611
663
  /** Live product mockup. ×N under one Root is valid. */
612
- Preview: fe,
664
+ Preview: ye,
613
665
  /** Form input bound to a design text layer by typed token (T1). */
614
- TextField: rt,
666
+ TextField: dt,
615
667
  /** Smart commerce part: completeness + payload assembly; submit = host callback. */
616
- Buy: it,
668
+ Buy: ut,
617
669
  /** Layer list. The one editor part that works canvas-free (ADR-0085 §4). */
618
- Layers: Ie,
670
+ Layers: Ne,
619
671
  /** Morphing contextual zone — ONE coarse part; placement docked|floating (§5). */
620
- Controls: at,
672
+ Controls: mt,
621
673
  /** Undo/redo controls. Requires Editor.Canvas. */
622
- History: ke,
674
+ History: Oe,
623
675
  /** The one ⋯ overflow menu. Requires Editor.Canvas. */
624
- Menu: Se,
676
+ Menu: Ce,
625
677
  /** The ⊕ add-element menu. Requires Editor.Canvas. */
626
- Add: Ee
678
+ Add: Se
627
679
  };
628
- function Rt(t) {
629
- return /* @__PURE__ */ s(ue, { ...t, __validation: "warn" });
680
+ function $t(t) {
681
+ return /* @__PURE__ */ o(he, { ...t, __validation: "warn" });
630
682
  }
631
- const Ct = se(
683
+ const Dt = ce(
632
684
  function(e, n) {
633
- const { children: r, className: o, style: a, maxHeight: c, ...u } = e, [d, i] = I(null);
634
- return A(() => {
635
- let l = !1;
636
- return me().then(
637
- (m) => {
638
- l || i(() => m);
685
+ const { children: r, className: s, style: a, maxHeight: d, ...c } = e, [l, i] = O(null);
686
+ return B(() => {
687
+ let f = !1;
688
+ return ge().then(
689
+ (u) => {
690
+ f || i(() => u);
639
691
  },
640
- (m) => {
641
- console.error("[RealtimeCanvas] failed to load the rendering chunk:", m);
692
+ (u) => {
693
+ console.error("[RealtimeCanvas] failed to load the rendering chunk:", u);
642
694
  }
643
695
  ), () => {
644
- l = !0;
696
+ f = !0;
645
697
  };
646
- }, []), d ? /* @__PURE__ */ s(d, { ref: n, selfScope: !0, maxHeight: c, className: o, style: a, ...u, children: r }) : /* @__PURE__ */ s(
698
+ }, []), l ? /* @__PURE__ */ o(l, { ref: n, selfScope: !0, maxHeight: d, className: s, style: a, ...c, children: r }) : /* @__PURE__ */ o(
647
699
  "div",
648
700
  {
649
- className: `sc-root${o ? ` ${o}` : ""}`,
650
- style: { minHeight: c ?? 200, ...a },
701
+ className: `sc-root${s ? ` ${s}` : ""}`,
702
+ style: { minHeight: d ?? 200, ...a },
651
703
  "aria-busy": "true"
652
704
  }
653
705
  );
654
706
  }
655
707
  );
656
- function Ot(t) {
657
- return /* @__PURE__ */ s(fe, { ...t });
708
+ function At(t) {
709
+ return /* @__PURE__ */ o(ye, { ...t });
658
710
  }
659
- function Nt() {
660
- const { mockups: t, isRendering: e, error: n } = G();
711
+ function Bt() {
712
+ const { mockups: t, isRendering: e, error: n } = Q();
661
713
  return { mockups: t, isRendering: e, error: n };
662
714
  }
663
- function lt(t) {
715
+ function ft(t) {
716
+ return t.type !== "color" && typeof t.width == "number" && t.width > 0 && typeof t.height == "number" && t.height > 0;
717
+ }
718
+ function Lt(t, e = {}) {
719
+ var m, y, b, v, w;
720
+ const n = (t.placements ?? []).filter(ft), r = n.map((h) => h.label), s = e.placement ? n.find((h) => h.label === e.placement) : n[0];
721
+ if (!s)
722
+ throw e.placement ? new _(
723
+ "E_PRODUCT_NOT_RENDERABLE",
724
+ `product ${t.id} has no renderable placement "${e.placement}". Renderable image placements: [${r.join(", ")}].`,
725
+ { productId: t.id, requested: e.placement, validNames: r, docSlug: "embed-mode" }
726
+ ) : new _(
727
+ "E_PRODUCT_NOT_RENDERABLE",
728
+ `product ${t.id} has no renderable image placement (a non-color placement with width/height). The catalog payload may be incomplete — fetch it via getProduct(), not a search hit.`,
729
+ { productId: t.id, docSlug: "embed-mode" }
730
+ );
731
+ const a = ((m = t.options) == null ? void 0 : m.attributes) ?? {}, c = Object.values(a).some(
732
+ (h) => {
733
+ var x;
734
+ return (x = h == null ? void 0 : h.choices) == null ? void 0 : x.some((g) => g == null ? void 0 : g.hex);
735
+ }
736
+ ) ? (v = (b = (y = t.options) == null ? void 0 : y.combinations) == null ? void 0 : b.find(
737
+ (h) => typeof h.variantId == "string" && h.variantId !== ""
738
+ )) == null ? void 0 : v.variantId : void 0, l = t.mockups ?? [], i = c ? l.filter((h) => {
739
+ var x;
740
+ return (x = h.gvids) == null ? void 0 : x.includes(c);
741
+ }) : l, f = (i.length > 0 ? i : l).map((h) => h.id);
742
+ if (f.length === 0)
743
+ throw new _(
744
+ "E_PRODUCT_NOT_RENDERABLE",
745
+ `product ${t.id} has no mockup scenes — nothing to render a preview into.`,
746
+ { productId: t.id, docSlug: "embed-mode" }
747
+ );
748
+ return {
749
+ product: {
750
+ productId: t.id,
751
+ mockupIds: f,
752
+ ...typeof c == "string" ? { variantId: c } : {},
753
+ options: t.options,
754
+ placements: (w = t.placements) == null ? void 0 : w.map((h) => h.label),
755
+ mockups: l,
756
+ requiredPlacements: t.requiredPlacements,
757
+ ...t.defaultGvid ? { defaultGvid: t.defaultGvid } : {},
758
+ ...typeof e.width == "number" ? { width: e.width } : {}
759
+ },
760
+ placement: {
761
+ label: s.label,
762
+ width: s.width,
763
+ height: s.height,
764
+ aspectRatio: s.width / s.height
765
+ },
766
+ placementLabels: r,
767
+ primaryMockupId: f[0],
768
+ variantId: c
769
+ };
770
+ }
771
+ function ht(t) {
664
772
  return new Intl.NumberFormat("en-US", {
665
773
  style: "currency",
666
774
  currency: "USD",
@@ -668,7 +776,7 @@ function lt(t) {
668
776
  maximumFractionDigits: t % 100 === 0 ? 0 : 2
669
777
  }).format(t / 100);
670
778
  }
671
- const dt = {
779
+ const gt = {
672
780
  display: "inline-flex",
673
781
  alignItems: "center",
674
782
  justifyContent: "center",
@@ -683,7 +791,7 @@ const dt = {
683
791
  fontSize: 16,
684
792
  lineHeight: 1,
685
793
  cursor: "pointer"
686
- }, ut = {
794
+ }, yt = {
687
795
  display: "flex",
688
796
  alignItems: "center",
689
797
  gap: 10,
@@ -699,55 +807,55 @@ const dt = {
699
807
  textAlign: "left",
700
808
  cursor: "pointer"
701
809
  };
702
- function Y({
810
+ function te({
703
811
  label: t,
704
812
  onSelect: e
705
813
  }) {
706
- return /* @__PURE__ */ s(
814
+ return /* @__PURE__ */ o(
707
815
  "button",
708
816
  {
709
817
  type: "button",
710
818
  role: "menuitem",
711
819
  "data-sc-part": "snowcone-editor-menu-item",
712
- style: ut,
820
+ style: yt,
713
821
  onClick: e,
714
822
  children: t
715
823
  }
716
824
  );
717
825
  }
718
- function mt({
826
+ function bt({
719
827
  fullscreen: t,
720
828
  onToggleFullscreen: e,
721
829
  viewCount: n,
722
830
  viewIndex: r,
723
- onSelectView: o,
831
+ onSelectView: s,
724
832
  onExport: a
725
833
  }) {
726
- const [c, u] = I(!1), d = () => u(!1);
727
- return /* @__PURE__ */ k("div", { style: { position: "relative" }, children: [
728
- /* @__PURE__ */ s(
834
+ const [d, c] = O(!1), l = () => c(!1);
835
+ return /* @__PURE__ */ C("div", { style: { position: "relative" }, children: [
836
+ /* @__PURE__ */ o(
729
837
  "button",
730
838
  {
731
839
  type: "button",
732
840
  "aria-label": "Editor menu",
733
841
  "aria-haspopup": "menu",
734
- "aria-expanded": c,
842
+ "aria-expanded": d,
735
843
  "data-sc-part": "snowcone-editor-menu",
736
- style: dt,
737
- onClick: () => u((i) => !i),
844
+ style: gt,
845
+ onClick: () => c((i) => !i),
738
846
  children: "⋮"
739
847
  }
740
848
  ),
741
- c ? /* @__PURE__ */ k(oe, { children: [
742
- /* @__PURE__ */ s(
849
+ d ? /* @__PURE__ */ C($e, { children: [
850
+ /* @__PURE__ */ o(
743
851
  "div",
744
852
  {
745
853
  style: { position: "fixed", inset: 0, zIndex: 39 },
746
- onClick: d,
854
+ onClick: l,
747
855
  "aria-hidden": "true"
748
856
  }
749
857
  ),
750
- /* @__PURE__ */ k(
858
+ /* @__PURE__ */ C(
751
859
  "div",
752
860
  {
753
861
  role: "menu",
@@ -766,31 +874,31 @@ function mt({
766
874
  zIndex: 40
767
875
  },
768
876
  children: [
769
- /* @__PURE__ */ s(
770
- Y,
877
+ /* @__PURE__ */ o(
878
+ te,
771
879
  {
772
880
  label: t ? "Exit fullscreen" : "Fullscreen",
773
881
  onSelect: () => {
774
- d(), e();
882
+ l(), e();
775
883
  }
776
884
  }
777
885
  ),
778
- n > 1 ? Array.from({ length: n }, (i, l) => /* @__PURE__ */ s(
779
- Y,
886
+ n > 1 ? Array.from({ length: n }, (i, f) => /* @__PURE__ */ o(
887
+ te,
780
888
  {
781
- label: `View ${l + 1}${l === r ? " ✓" : ""}`,
889
+ label: `View ${f + 1}${f === r ? " ✓" : ""}`,
782
890
  onSelect: () => {
783
- d(), o(l);
891
+ l(), s(f);
784
892
  }
785
893
  },
786
- l
894
+ f
787
895
  )) : null,
788
- /* @__PURE__ */ s(
789
- Y,
896
+ /* @__PURE__ */ o(
897
+ te,
790
898
  {
791
899
  label: "Export PNG",
792
900
  onSelect: () => {
793
- d(), a();
901
+ l(), a();
794
902
  }
795
903
  }
796
904
  )
@@ -800,19 +908,19 @@ function mt({
800
908
  ] }) : null
801
909
  ] });
802
910
  }
803
- function ft() {
804
- const { flatLayers: t, selectLayer: e, generateAllPreviews: n } = Re({ previewSize: 96 });
805
- return A(() => {
911
+ function vt() {
912
+ const { flatLayers: t, selectLayer: e, generateAllPreviews: n } = Te({ previewSize: 96 });
913
+ return B(() => {
806
914
  t.length > 0 && n();
807
- }, [t.length, n]), /* @__PURE__ */ k(
915
+ }, [t.length, n]), /* @__PURE__ */ C(
808
916
  "div",
809
917
  {
810
918
  "data-sc-part": "snowcone-editor-idle-dock",
811
919
  style: { display: "flex", alignItems: "center", justifyContent: "center", gap: 8, minHeight: 44 },
812
920
  children: [
813
- /* @__PURE__ */ s(V.Add, {}),
814
- t.length > 0 ? /* @__PURE__ */ s("div", { style: { width: 1, height: 28, background: "rgba(0,0,0,0.1)", flexShrink: 0 }, "aria-hidden": "true" }) : null,
815
- t.map((r) => /* @__PURE__ */ s(
921
+ /* @__PURE__ */ o(U.Add, {}),
922
+ t.length > 0 ? /* @__PURE__ */ o("div", { style: { width: 1, height: 28, background: "rgba(0,0,0,0.1)", flexShrink: 0 }, "aria-hidden": "true" }) : null,
923
+ t.map((r) => /* @__PURE__ */ o(
816
924
  "button",
817
925
  {
818
926
  type: "button",
@@ -835,8 +943,8 @@ function ft() {
835
943
  },
836
944
  children: r.previewUrl ? (
837
945
  // eslint-disable-next-line @next/next/no-img-element
838
- /* @__PURE__ */ s("img", { src: r.previewUrl, alt: "", style: { width: "100%", height: "100%", objectFit: "contain" } })
839
- ) : /* @__PURE__ */ s(
946
+ /* @__PURE__ */ o("img", { src: r.previewUrl, alt: "", style: { width: "100%", height: "100%", objectFit: "contain" } })
947
+ ) : /* @__PURE__ */ o(
840
948
  "span",
841
949
  {
842
950
  style: {
@@ -857,13 +965,13 @@ function ft() {
857
965
  }
858
966
  );
859
967
  }
860
- function pt({
968
+ function wt({
861
969
  onAddToCart: t,
862
970
  defaultQuantity: e
863
971
  }) {
864
- const { price: n, complete: r } = ct();
865
- return /* @__PURE__ */ k(
866
- V.Buy,
972
+ const { price: n, complete: r } = pt();
973
+ return /* @__PURE__ */ C(
974
+ U.Buy,
867
975
  {
868
976
  onAddToCart: t,
869
977
  ...typeof e == "number" ? { defaultQuantity: e } : {},
@@ -886,36 +994,36 @@ function pt({
886
994
  },
887
995
  children: [
888
996
  "Add to cart",
889
- typeof n == "number" ? ` · ${lt(n)}` : ""
997
+ typeof n == "number" ? ` · ${ht(n)}` : ""
890
998
  ]
891
999
  }
892
1000
  );
893
1001
  }
894
- function gt({
1002
+ function Et({
895
1003
  title: t,
896
1004
  height: e,
897
1005
  mockupIds: n,
898
1006
  onAddToCart: r,
899
- defaultQuantity: o,
1007
+ defaultQuantity: s,
900
1008
  className: a,
901
- style: c
1009
+ style: d
902
1010
  }) {
903
- const [u, d] = I(!1), [i, l] = I(0), [m, f] = I(!1), h = C(null), p = Me(), w = n[Math.min(i, n.length - 1)], E = j(async () => {
904
- var _;
905
- const R = await ((_ = h.current) == null ? void 0 : _.exportArtboards({ format: "dataUrl" }));
906
- if (!R) return;
907
- const [D, x] = Object.entries(R)[0] ?? [];
908
- if (typeof x != "string") return;
909
- const $ = document.createElement("a");
910
- $.href = x, $.download = `${D ?? "design"}.png`, $.click();
911
- }, []), b = {
1011
+ const [c, l] = O(!1), [i, f] = O(0), [u, m] = O(!1), y = R(null), b = We(), v = n[Math.min(i, n.length - 1)], w = q(async () => {
1012
+ var D;
1013
+ const g = await ((D = y.current) == null ? void 0 : D.exportArtboards({ format: "dataUrl" }));
1014
+ if (!g) return;
1015
+ const [N, S] = Object.entries(g)[0] ?? [];
1016
+ if (typeof S != "string") return;
1017
+ const L = document.createElement("a");
1018
+ L.href = S, L.download = `${N ?? "design"}.png`, L.click();
1019
+ }, []), h = {
912
1020
  display: "flex",
913
1021
  flexDirection: "column",
914
1022
  overflow: "hidden",
915
1023
  background: "var(--sc-color-surface, #fff)",
916
1024
  color: "var(--sc-color-foreground, #111)",
917
1025
  fontFamily: "ui-sans-serif, system-ui, sans-serif",
918
- ...u ? {
1026
+ ...c ? {
919
1027
  position: "fixed",
920
1028
  inset: 0,
921
1029
  zIndex: 9999,
@@ -928,8 +1036,8 @@ function gt({
928
1036
  border: "1px solid rgba(0,0,0,0.08)",
929
1037
  boxShadow: "0 1px 3px rgba(0,0,0,0.08)"
930
1038
  },
931
- ...c
932
- }, T = {
1039
+ ...d
1040
+ }, x = {
933
1041
  position: "absolute",
934
1042
  top: 8,
935
1043
  right: 12,
@@ -944,15 +1052,15 @@ function gt({
944
1052
  cursor: "pointer",
945
1053
  zIndex: 2
946
1054
  };
947
- return /* @__PURE__ */ k(
1055
+ return /* @__PURE__ */ C(
948
1056
  "div",
949
1057
  {
950
1058
  "data-sc-part": "snowcone-editor",
951
- "data-sc-fullscreen": u ? "true" : void 0,
1059
+ "data-sc-fullscreen": c ? "true" : void 0,
952
1060
  className: a,
953
- style: b,
1061
+ style: h,
954
1062
  children: [
955
- /* @__PURE__ */ k(
1063
+ /* @__PURE__ */ C(
956
1064
  "div",
957
1065
  {
958
1066
  "data-sc-part": "snowcone-editor-header",
@@ -964,35 +1072,35 @@ function gt({
964
1072
  flexShrink: 0
965
1073
  },
966
1074
  children: [
967
- /* @__PURE__ */ s("span", { style: { fontSize: 14, fontWeight: 700, marginRight: "auto" }, children: t }),
968
- /* @__PURE__ */ s(V.History, {}),
969
- /* @__PURE__ */ s(
970
- mt,
1075
+ /* @__PURE__ */ o("span", { style: { fontSize: 14, fontWeight: 700, marginRight: "auto" }, children: t }),
1076
+ /* @__PURE__ */ o(U.History, {}),
1077
+ /* @__PURE__ */ o(
1078
+ bt,
971
1079
  {
972
- fullscreen: u,
973
- onToggleFullscreen: () => d((R) => !R),
1080
+ fullscreen: c,
1081
+ onToggleFullscreen: () => l((g) => !g),
974
1082
  viewCount: n.length,
975
1083
  viewIndex: i,
976
- onSelectView: l,
977
- onExport: () => void E()
1084
+ onSelectView: f,
1085
+ onExport: () => void w()
978
1086
  }
979
1087
  ),
980
- /* @__PURE__ */ s(pt, { onAddToCart: r, defaultQuantity: o })
1088
+ /* @__PURE__ */ o(wt, { onAddToCart: r, defaultQuantity: s })
981
1089
  ]
982
1090
  }
983
1091
  ),
984
- /* @__PURE__ */ k(
1092
+ /* @__PURE__ */ C(
985
1093
  "div",
986
1094
  {
987
1095
  "data-sc-part": "snowcone-editor-stage",
988
1096
  style: { position: "relative", flex: 1, minHeight: 0, padding: "4px 12px" },
989
1097
  children: [
990
- /* @__PURE__ */ s(V.Canvas, { ref: h, style: { height: "100%" } }),
991
- m ? (
1098
+ /* @__PURE__ */ o(U.Canvas, { ref: y, style: { height: "100%" } }),
1099
+ u ? (
992
1100
  // Swapped: the mockup IS the stage; the corner chip returns to the
993
1101
  // artwork. The canvas stays mounted underneath (no document
994
1102
  // teardown), just covered.
995
- /* @__PURE__ */ k(
1103
+ /* @__PURE__ */ C(
996
1104
  "div",
997
1105
  {
998
1106
  "data-sc-part": "snowcone-editor-swap-stage",
@@ -1007,24 +1115,24 @@ function gt({
1007
1115
  padding: 8
1008
1116
  },
1009
1117
  children: [
1010
- /* @__PURE__ */ s(
1011
- V.Preview,
1118
+ /* @__PURE__ */ o(
1119
+ U.Preview,
1012
1120
  {
1013
- mockupId: w,
1121
+ mockupId: v,
1014
1122
  alt: "Product mockup",
1015
- fallback: /* @__PURE__ */ s("div", { "aria-busy": "true", children: "Rendering…" }),
1123
+ fallback: /* @__PURE__ */ o("div", { "aria-busy": "true", children: "Rendering…" }),
1016
1124
  style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain", borderRadius: 12 }
1017
1125
  }
1018
1126
  ),
1019
- /* @__PURE__ */ s(
1127
+ /* @__PURE__ */ o(
1020
1128
  "button",
1021
1129
  {
1022
1130
  type: "button",
1023
1131
  "aria-label": "Back to artwork",
1024
1132
  "data-sc-part": "snowcone-editor-swap-back",
1025
- onClick: () => f(!1),
1133
+ onClick: () => m(!1),
1026
1134
  style: {
1027
- ...T,
1135
+ ...x,
1028
1136
  display: "flex",
1029
1137
  alignItems: "center",
1030
1138
  justifyContent: "center",
@@ -1039,20 +1147,20 @@ function gt({
1039
1147
  ]
1040
1148
  }
1041
1149
  )
1042
- ) : /* @__PURE__ */ s(
1150
+ ) : /* @__PURE__ */ o(
1043
1151
  "button",
1044
1152
  {
1045
1153
  type: "button",
1046
1154
  "aria-label": "Show product mockup",
1047
1155
  "data-sc-part": "snowcone-editor-pip",
1048
- onClick: () => f(!0),
1049
- style: T,
1050
- children: /* @__PURE__ */ s(
1051
- V.Preview,
1156
+ onClick: () => m(!0),
1157
+ style: x,
1158
+ children: /* @__PURE__ */ o(
1159
+ U.Preview,
1052
1160
  {
1053
- mockupId: w,
1161
+ mockupId: v,
1054
1162
  alt: "Product mockup preview",
1055
- fallback: /* @__PURE__ */ s("span", { style: { fontSize: 10, opacity: 0.5 }, "aria-busy": "true", children: "mockup…" }),
1163
+ fallback: /* @__PURE__ */ o("span", { style: { fontSize: 10, opacity: 0.5 }, "aria-busy": "true", children: "mockup…" }),
1056
1164
  style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
1057
1165
  }
1058
1166
  )
@@ -1061,15 +1169,15 @@ function gt({
1061
1169
  ]
1062
1170
  }
1063
1171
  ),
1064
- /* @__PURE__ */ k(
1172
+ /* @__PURE__ */ C(
1065
1173
  "div",
1066
1174
  {
1067
1175
  "data-sc-part": "snowcone-editor-zone",
1068
- "data-sc-zone-state": p ? "selected" : "idle",
1176
+ "data-sc-zone-state": b ? "selected" : "idle",
1069
1177
  style: { flexShrink: 0, padding: "4px 16px 14px" },
1070
1178
  children: [
1071
- /* @__PURE__ */ s("div", { style: { display: p ? void 0 : "none" }, children: /* @__PURE__ */ s(V.Controls, { placement: "docked" }) }),
1072
- p ? null : /* @__PURE__ */ s(ft, {})
1179
+ /* @__PURE__ */ o("div", { style: { display: b ? void 0 : "none" }, children: /* @__PURE__ */ o(U.Controls, { placement: "docked" }) }),
1180
+ b ? null : /* @__PURE__ */ o(vt, {})
1073
1181
  ]
1074
1182
  }
1075
1183
  )
@@ -1077,41 +1185,42 @@ function gt({
1077
1185
  }
1078
1186
  );
1079
1187
  }
1080
- function Tt(t) {
1188
+ function Vt(t) {
1081
1189
  const {
1082
1190
  onAddToCart: e,
1083
1191
  defaultQuantity: n,
1084
1192
  title: r = "Editor",
1085
- height: o = 480,
1193
+ height: s = 480,
1086
1194
  className: a,
1087
- style: c,
1088
- ...u
1195
+ style: d,
1196
+ ...c
1089
1197
  } = t;
1090
- return /* @__PURE__ */ s(V.Root, { ...u, children: /* @__PURE__ */ s(
1091
- gt,
1198
+ return /* @__PURE__ */ o(U.Root, { ...c, children: /* @__PURE__ */ o(
1199
+ Et,
1092
1200
  {
1093
1201
  title: r,
1094
- height: o,
1095
- mockupIds: u.product.mockupIds,
1202
+ height: s,
1203
+ mockupIds: c.product.mockupIds,
1096
1204
  onAddToCart: e,
1097
1205
  ...typeof n == "number" ? { defaultQuantity: n } : {},
1098
1206
  className: a,
1099
- style: c
1207
+ style: d
1100
1208
  }
1101
1209
  ) });
1102
1210
  }
1103
- Ce();
1211
+ _e();
1104
1212
  export {
1105
- V as E,
1106
- Ct as R,
1107
- Tt as S,
1108
- Rt as a,
1109
- Ot as b,
1110
- ce as c,
1111
- ct as d,
1112
- Nt as e,
1113
- lt as f,
1114
- G as u,
1115
- Ke as v
1213
+ U as E,
1214
+ Dt as R,
1215
+ Vt as S,
1216
+ $t as a,
1217
+ At as b,
1218
+ me as c,
1219
+ pt as d,
1220
+ Bt as e,
1221
+ ht as f,
1222
+ Lt as p,
1223
+ Q as u,
1224
+ Ye as v
1116
1225
  };
1117
- //# sourceMappingURL=embed-pM7ZkFuz.js.map
1226
+ //# sourceMappingURL=embed-8ecUMMH-.js.map