@liforma/client 0.4.13 → 0.4.15

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 (88) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +4 -4
  3. package/dist/next/index.js +704 -623
  4. package/dist/next/index.js.map +1 -1
  5. package/dist/next/react/ExperienceThumbnail.d.ts.map +1 -1
  6. package/dist/next/thumbnail/index.d.ts +1 -0
  7. package/dist/next/thumbnail/index.d.ts.map +1 -1
  8. package/dist/next/thumbnail/locationPlate.d.ts +3 -3
  9. package/dist/next/thumbnail/locationPlate.d.ts.map +1 -1
  10. package/dist/next/thumbnail/plateDelivery.d.ts +18 -0
  11. package/dist/next/thumbnail/plateDelivery.d.ts.map +1 -0
  12. package/dist/next/thumbnail/plateDelivery.test.d.ts +2 -0
  13. package/dist/next/thumbnail/plateDelivery.test.d.ts.map +1 -0
  14. package/dist/next/thumbnail/toGalleryThumbUrl.d.ts +1 -1
  15. package/dist/next/thumbnail.js +147 -91
  16. package/dist/next/thumbnail.js.map +1 -1
  17. package/dist/next/v2/embed/iframeHost.d.ts.map +1 -1
  18. package/dist/next/v2/embed/protocol.d.ts +7 -7
  19. package/dist/next/v2/embed/protocol.d.ts.map +1 -1
  20. package/dist/next/v2/experience.d.ts +11 -5
  21. package/dist/next/v2/experience.d.ts.map +1 -1
  22. package/dist/next/v2/shims/embedBaseUrl.d.ts +4 -1
  23. package/dist/next/v2/shims/embedBaseUrl.d.ts.map +1 -1
  24. package/dist/next/v2/types/sessionLaunch.d.ts +6 -0
  25. package/dist/next/v2/types/sessionLaunch.d.ts.map +1 -1
  26. package/dist/npm/index.js +494 -469
  27. package/dist/npm/index.js.map +1 -1
  28. package/dist/npm/thumbnail/index.d.ts +1 -0
  29. package/dist/npm/thumbnail/index.d.ts.map +1 -1
  30. package/dist/npm/thumbnail/index.js +106 -70
  31. package/dist/npm/thumbnail/index.js.map +1 -1
  32. package/dist/npm/thumbnail/locationPlate.d.ts +3 -3
  33. package/dist/npm/thumbnail/locationPlate.d.ts.map +1 -1
  34. package/dist/npm/thumbnail/plateDelivery.d.ts +18 -0
  35. package/dist/npm/thumbnail/plateDelivery.d.ts.map +1 -0
  36. package/dist/npm/thumbnail/toGalleryThumbUrl.d.ts +1 -1
  37. package/dist/npm/v2/embed/iframeHost.d.ts.map +1 -1
  38. package/dist/npm/v2/embed/protocol.d.ts +7 -7
  39. package/dist/npm/v2/embed/protocol.d.ts.map +1 -1
  40. package/dist/npm/v2/experience.d.ts +11 -5
  41. package/dist/npm/v2/experience.d.ts.map +1 -1
  42. package/dist/npm/v2/index.d.ts +1 -1
  43. package/dist/npm/v2/index.d.ts.map +1 -1
  44. package/dist/npm/v2/liforma-experience-thumbnail.d.ts.map +1 -1
  45. package/dist/npm/v2/npm.d.ts +1 -1
  46. package/dist/npm/v2/npm.d.ts.map +1 -1
  47. package/dist/npm/v2/shims/embedBaseUrl.d.ts +4 -1
  48. package/dist/npm/v2/shims/embedBaseUrl.d.ts.map +1 -1
  49. package/dist/npm/v2/types/index.d.ts +1 -1
  50. package/dist/npm/v2/types/index.d.ts.map +1 -1
  51. package/dist/npm/v2/types/sessionLaunch.d.ts +6 -0
  52. package/dist/npm/v2/types/sessionLaunch.d.ts.map +1 -1
  53. package/dist/react/component/experienceComponentLaunch.d.ts.map +1 -1
  54. package/dist/react/component/experienceComponentRuntime.d.ts +3 -1
  55. package/dist/react/component/experienceComponentRuntime.d.ts.map +1 -1
  56. package/dist/react/component/experienceComponentTypes.d.ts +9 -4
  57. package/dist/react/component/experienceComponentTypes.d.ts.map +1 -1
  58. package/dist/react/index.js +733 -640
  59. package/dist/react/index.js.map +1 -1
  60. package/dist/react/react/Experience.d.ts.map +1 -1
  61. package/dist/react/react/ExperienceThumbnail.d.ts.map +1 -1
  62. package/dist/react/thumbnail/index.d.ts +1 -0
  63. package/dist/react/thumbnail/index.d.ts.map +1 -1
  64. package/dist/react/thumbnail/locationPlate.d.ts +3 -3
  65. package/dist/react/thumbnail/locationPlate.d.ts.map +1 -1
  66. package/dist/react/thumbnail/plateDelivery.d.ts +18 -0
  67. package/dist/react/thumbnail/plateDelivery.d.ts.map +1 -0
  68. package/dist/react/thumbnail/plateDelivery.test.d.ts +2 -0
  69. package/dist/react/thumbnail/plateDelivery.test.d.ts.map +1 -0
  70. package/dist/react/thumbnail/toGalleryThumbUrl.d.ts +1 -1
  71. package/dist/react/thumbnail.js +147 -91
  72. package/dist/react/thumbnail.js.map +1 -1
  73. package/dist/react/v2/embed/iframeHost.d.ts.map +1 -1
  74. package/dist/react/v2/embed/protocol.d.ts +7 -7
  75. package/dist/react/v2/embed/protocol.d.ts.map +1 -1
  76. package/dist/react/v2/experience.d.ts +11 -5
  77. package/dist/react/v2/experience.d.ts.map +1 -1
  78. package/dist/react/v2/shims/embedBaseUrl.d.ts +4 -1
  79. package/dist/react/v2/shims/embedBaseUrl.d.ts.map +1 -1
  80. package/dist/react/v2/types/sessionLaunch.d.ts +6 -0
  81. package/dist/react/v2/types/sessionLaunch.d.ts.map +1 -1
  82. package/dist/sdk/v2/client.js +3 -3
  83. package/dist/sdk/v2/client.js.map +1 -1
  84. package/dist/sdk/v2/thumbnail.js +2 -2
  85. package/dist/sdk/v2/thumbnail.js.map +1 -1
  86. package/dist/svelte/Experience.svelte +12 -0
  87. package/dist/svelte/ExperienceThumbnail.svelte +49 -8
  88. package/package.json +4 -1
package/dist/npm/index.js CHANGED
@@ -35,12 +35,12 @@ function r(e) {
35
35
  }
36
36
  //#endregion
37
37
  //#region src/thumbnail/locationPlate.ts
38
- var i = /(-)(\d+x\d+)(\.webp)(\?|$)/i;
38
+ var i = /(-)(\d+x\d+)(\.(?:webp|avif))(\?|$)/i;
39
39
  function a(e, t) {
40
40
  let n = e.trim();
41
41
  return n && n.replace(i, (e, n, r, i, a) => `${n}${t}${i}${a}`);
42
42
  }
43
- var o = /-(256x256|400x450|800x450|836x971|1672x941|167x94)$/i;
43
+ var o = /-(256x256|400x225|400x450|800x450|836x971|1672x941|167x94)$/i;
44
44
  function s(e) {
45
45
  return e?.trim().replace(/\/$/, "") || "https://cdn.liforma.ai";
46
46
  }
@@ -156,52 +156,52 @@ var D = 0, O = [];
156
156
  function ee() {
157
157
  return E() ? 4 : Infinity;
158
158
  }
159
- function k() {
159
+ function te() {
160
160
  return E() ? 160 : 0;
161
161
  }
162
- function te() {
162
+ function ne() {
163
163
  let e = ee();
164
164
  for (; D < e && O.length > 0;) {
165
165
  let e = O.shift();
166
166
  if (!e || e.cancelled) continue;
167
167
  D += 1, e.start();
168
- let t = k();
168
+ let t = te();
169
169
  if (t <= 0) {
170
170
  D = Math.max(0, D - 1);
171
171
  continue;
172
172
  }
173
173
  window.setTimeout(() => {
174
- D = Math.max(0, D - 1), te();
174
+ D = Math.max(0, D - 1), ne();
175
175
  }, t);
176
176
  }
177
177
  }
178
- function A(e) {
178
+ function re(e) {
179
179
  if (!E()) return e(), () => {};
180
180
  let t = {
181
181
  start: e,
182
182
  cancelled: !1
183
183
  };
184
- return O.push(t), te(), () => {
184
+ return O.push(t), ne(), () => {
185
185
  t.cancelled = !0;
186
186
  };
187
187
  }
188
188
  //#endregion
189
189
  //#region src/thumbnail/lazyLoad.ts
190
- function j() {
190
+ function k() {
191
191
  return E() ? "96px 0px" : "280px 0px";
192
192
  }
193
- function M(e) {
193
+ function A(e) {
194
194
  let t = e.trim().split(/\s+/)[0] ?? "0px", n = Number.parseFloat(t);
195
195
  return Number.isFinite(n) ? Math.abs(n) : 280;
196
196
  }
197
- function N(e, t) {
197
+ function j(e, t) {
198
198
  if (typeof window > "u") return !1;
199
199
  let n = e.getBoundingClientRect();
200
200
  return n.bottom >= -t && n.top <= window.innerHeight + t;
201
201
  }
202
- function P(e, t) {
203
- let { onVisibleChange: n } = t, r = t.rootMargin ?? j(), i = M(r), a = !1, o = !1, s = null, c = () => {
204
- o || (s?.(), s = A(() => {
202
+ function M(e, t) {
203
+ let { onVisibleChange: n } = t, r = t.rootMargin ?? k(), i = A(r), a = !1, o = !1, s = null, c = () => {
204
+ o || (s?.(), s = re(() => {
205
205
  s = null, o = !0, n(!0);
206
206
  }));
207
207
  }, l = (e) => {
@@ -223,11 +223,11 @@ function P(e, t) {
223
223
  rootMargin: r,
224
224
  threshold: 0
225
225
  });
226
- return u.observe(e), N(e, i) && l(!0), () => {
226
+ return u.observe(e), j(e, i) && l(!0), () => {
227
227
  s?.(), s = null, u.disconnect();
228
228
  };
229
229
  }
230
- function ne(e, t) {
230
+ function ie(e, t) {
231
231
  let n = () => t();
232
232
  return e.complete ? queueMicrotask(n) : (e.addEventListener("load", n, { once: !0 }), e.addEventListener("error", n, { once: !0 })), () => {
233
233
  e.removeEventListener("load", n), e.removeEventListener("error", n);
@@ -235,49 +235,49 @@ function ne(e, t) {
235
235
  }
236
236
  //#endregion
237
237
  //#region src/thumbnail/scrollParallax.ts
238
- function re() {
238
+ function ae() {
239
239
  return typeof window > "u" || window.matchMedia("(prefers-reduced-motion: reduce)").matches ? !1 : window.matchMedia("(hover: none), (pointer: coarse)").matches;
240
240
  }
241
- function F(e, t) {
241
+ function N(e, t) {
242
242
  return ((e.top + e.height / 2) / Math.max(t, 1) - .5) * 2;
243
243
  }
244
- var I = /* @__PURE__ */ new Set(), L = !1, R = 0;
245
- function z() {
246
- if (R = 0, I.size === 0 || typeof window > "u") return;
244
+ var P = /* @__PURE__ */ new Set(), F = !1, I = 0;
245
+ function L() {
246
+ if (I = 0, P.size === 0 || typeof window > "u") return;
247
247
  let e = window.innerHeight;
248
- for (let t of I) {
248
+ for (let t of P) {
249
249
  if (t.pointerActive?.()) continue;
250
250
  let n = t.element.getBoundingClientRect();
251
- n.bottom < -64 || n.top > e + 64 || t.onParallax(F(n, e));
251
+ n.bottom < -64 || n.top > e + 64 || t.onParallax(N(n, e));
252
252
  }
253
253
  }
254
- function B() {
255
- R === 0 && (R = requestAnimationFrame(z));
254
+ function R() {
255
+ I === 0 && (I = requestAnimationFrame(L));
256
256
  }
257
- function ie() {
258
- L || typeof window > "u" || (L = !0, window.addEventListener("scroll", B, { passive: !0 }), window.addEventListener("resize", B, { passive: !0 }));
257
+ function oe() {
258
+ F || typeof window > "u" || (F = !0, window.addEventListener("scroll", R, { passive: !0 }), window.addEventListener("resize", R, { passive: !0 }));
259
259
  }
260
- function ae() {
261
- I.size > 0 || !L || typeof window > "u" || (L = !1, R !== 0 && (cancelAnimationFrame(R), R = 0), window.removeEventListener("scroll", B), window.removeEventListener("resize", B));
260
+ function se() {
261
+ P.size > 0 || !F || typeof window > "u" || (F = !1, I !== 0 && (cancelAnimationFrame(I), I = 0), window.removeEventListener("scroll", R), window.removeEventListener("resize", R));
262
262
  }
263
- function oe(e, t) {
264
- if (!re()) return () => {};
263
+ function ce(e, t) {
264
+ if (!ae()) return () => {};
265
265
  let n = {
266
266
  element: e,
267
267
  onParallax: t.onParallax,
268
268
  pointerActive: t.pointerActive
269
269
  };
270
- return I.add(n), ie(), n.pointerActive?.() || t.onParallax(F(e.getBoundingClientRect(), window.innerHeight)), () => {
271
- I.delete(n), ae();
270
+ return P.add(n), oe(), n.pointerActive?.() || t.onParallax(N(e.getBoundingClientRect(), window.innerHeight)), () => {
271
+ P.delete(n), se();
272
272
  };
273
273
  }
274
274
  //#endregion
275
275
  //#region src/thumbnail/attachThumbnailParallax.ts
276
- function se(e) {
276
+ function le(e) {
277
277
  let t = 0, n = 0, r = !1, i = !1, a = !1, o = () => {
278
278
  let a = r || i;
279
279
  e.classList.toggle("liforma-et--parallax", a), e.classList.toggle("liforma-et--scroll-parallax", i), e.style.setProperty("--liforma-et-parallax-x", String(t)), e.style.setProperty("--liforma-et-parallax-y", String(n));
280
- }, s = oe(e, {
280
+ }, s = ce(e, {
281
281
  onParallax: (e) => {
282
282
  i = !0, a || (t = e, n = 0, o());
283
283
  },
@@ -290,7 +290,7 @@ function se(e) {
290
290
  a = !0, e.pointerType === "mouse" && (r = !0), o();
291
291
  }, u = () => {
292
292
  let s = a;
293
- a = !1, r = !1, i && s ? (t = F(e.getBoundingClientRect(), window.innerHeight), n = 0) : i || (t = 0, n = 0), o();
293
+ a = !1, r = !1, i && s ? (t = N(e.getBoundingClientRect(), window.innerHeight), n = 0) : i || (t = 0, n = 0), o();
294
294
  }, d = (e) => {
295
295
  e.pointerType === "mouse" && (r = !0, o());
296
296
  }, f = () => {
@@ -302,45 +302,45 @@ function se(e) {
302
302
  }
303
303
  //#endregion
304
304
  //#region src/thumbnail/styles.ts
305
- var ce = ":host {\n display: block;\n width: 100%;\n height: 100%;\n min-height: 0;\n}\n\n.liforma-et {\n --liforma-et-parallax-x: 0;\n --liforma-et-parallax-y: 0;\n --liforma-et-bg-scale: 1;\n --liforma-et-fg-scale: 1;\n --liforma-et-avatar-scale: 1;\n --liforma-et-bg-shift: 0px;\n --liforma-et-fg-shift: 0px;\n --liforma-et-avatar-shift: 0px;\n --liforma-et-reveal-duration: 420ms;\n\n box-sizing: border-box;\n position: relative;\n display: block;\n width: 100%;\n height: 100%;\n min-height: 0;\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: 0;\n overflow: hidden;\n background: #111;\n color: inherit;\n text-decoration: none;\n cursor: inherit;\n -webkit-tap-highlight-color: transparent;\n}\n\na.liforma-et,\nbutton.liforma-et {\n cursor: pointer;\n}\n\nbutton.liforma-et {\n font: inherit;\n appearance: none;\n}\n\n.liforma-et__placeholder {\n position: absolute;\n inset: 0;\n z-index: 0;\n background:\n radial-gradient(120% 90% at 50% 0%, rgba(255, 255, 255, 0.06), transparent 58%),\n linear-gradient(180deg, #1a1a1a 0%, #101010 100%);\n opacity: 1;\n transition: opacity var(--liforma-et-reveal-duration) ease;\n}\n\n.liforma-et--revealed .liforma-et__placeholder {\n opacity: 0;\n}\n\n.liforma-et__media {\n opacity: 0;\n transition: opacity var(--liforma-et-reveal-duration) ease;\n}\n\n.liforma-et__media--ready {\n opacity: 1;\n}\n\n.liforma-et__background {\n position: absolute;\n inset: 0;\n z-index: 1;\n width: 100%;\n height: 100%;\n object-fit: cover;\n object-position: center center;\n transform: translate(\n calc(var(--liforma-et-parallax-x) * var(--liforma-et-bg-shift)),\n calc(var(--liforma-et-parallax-y) * var(--liforma-et-bg-shift))\n )\n scale(var(--liforma-et-bg-scale));\n transform-origin: center center;\n transition:\n opacity var(--liforma-et-reveal-duration) ease,\n transform 160ms ease;\n}\n\n.liforma-et__avatar {\n position: relative;\n z-index: 2;\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n object-position: center bottom;\n transform: scale(var(--liforma-et-avatar-scale))\n translate(\n calc(var(--liforma-et-parallax-x) * var(--liforma-et-avatar-shift)),\n calc(var(--liforma-et-parallax-y) * var(--liforma-et-avatar-shift))\n );\n transform-origin: center center;\n transition:\n opacity var(--liforma-et-reveal-duration) ease,\n transform 160ms ease;\n}\n\n/* Gallery plates are typically square in a square tile — contain vs cover is a no-op\n without a zoom. Scale the whole scene from the upper third so Face matches\n player fit (location + avatar crop together). */\n.liforma-et--fit-face {\n --liforma-et-avatar-scale: 1.85;\n --liforma-et-bg-scale: 1.85;\n --liforma-et-fg-scale: 1.85;\n}\n\n.liforma-et--fit-face .liforma-et__avatar,\n.liforma-et--fit-face .liforma-et__background,\n.liforma-et--fit-face .liforma-et__foreground {\n transform-origin: 50% 18%;\n}\n\n.liforma-et--fit-face .liforma-et__avatar {\n object-fit: cover;\n object-position: 50% 18%;\n}\n\n/* Bust / medium: less zoom than face so upper chest stays in frame (player 3.75H window). */\n.liforma-et--fit-medium {\n --liforma-et-avatar-scale: 1.35;\n --liforma-et-bg-scale: 1.35;\n --liforma-et-fg-scale: 1.35;\n}\n\n.liforma-et--fit-medium .liforma-et__avatar,\n.liforma-et--fit-medium .liforma-et__background,\n.liforma-et--fit-medium .liforma-et__foreground {\n transform-origin: 50% 28%;\n}\n\n.liforma-et--fit-medium .liforma-et__avatar {\n object-fit: cover;\n object-position: 50% 28%;\n}\n\n.liforma-et__foreground {\n position: absolute;\n inset: 0;\n z-index: 3;\n width: 100%;\n height: 100%;\n object-fit: cover;\n object-position: center center;\n pointer-events: none;\n transform: translate(\n calc(var(--liforma-et-parallax-x) * var(--liforma-et-fg-shift) * -1),\n calc(var(--liforma-et-parallax-y) * var(--liforma-et-fg-shift) * -1)\n )\n scale(var(--liforma-et-fg-scale));\n transform-origin: center center;\n transition:\n opacity var(--liforma-et-reveal-duration) ease,\n transform 160ms ease;\n}\n\n.liforma-et--parallax {\n --liforma-et-bg-scale: 1.08;\n --liforma-et-fg-scale: 1.05;\n --liforma-et-avatar-scale: 1.08;\n --liforma-et-bg-shift: 10px;\n --liforma-et-fg-shift: 4px;\n --liforma-et-avatar-shift: 4px;\n}\n\n/* Promote layers only while parallax is active — avoids N compositor surfaces on galleries. */\n.liforma-et--parallax .liforma-et__background,\n.liforma-et--parallax .liforma-et__foreground,\n.liforma-et--parallax .liforma-et__avatar {\n will-change: transform;\n}\n\n.liforma-et--parallax.liforma-et--fit-face {\n --liforma-et-avatar-scale: 1.95;\n --liforma-et-bg-scale: 1.95;\n --liforma-et-fg-scale: 1.95;\n --liforma-et-avatar-shift: 0px;\n}\n\n.liforma-et--parallax.liforma-et--fit-medium {\n --liforma-et-avatar-scale: 1.42;\n --liforma-et-bg-scale: 1.42;\n --liforma-et-fg-scale: 1.42;\n --liforma-et-avatar-shift: 0px;\n}\n\n.liforma-et--scroll-parallax .liforma-et__background,\n.liforma-et--scroll-parallax .liforma-et__foreground,\n.liforma-et--scroll-parallax .liforma-et__avatar {\n transition: opacity var(--liforma-et-reveal-duration) ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .liforma-et {\n --liforma-et-reveal-duration: 0ms;\n }\n\n .liforma-et--parallax {\n --liforma-et-bg-scale: 1;\n --liforma-et-fg-scale: 1;\n --liforma-et-avatar-scale: 1;\n --liforma-et-bg-shift: 0px;\n --liforma-et-fg-shift: 0px;\n --liforma-et-avatar-shift: 0px;\n }\n\n .liforma-et--parallax.liforma-et--fit-face {\n --liforma-et-avatar-scale: 1.85;\n --liforma-et-bg-scale: 1.85;\n --liforma-et-fg-scale: 1.85;\n }\n\n .liforma-et__background,\n .liforma-et__foreground,\n .liforma-et__avatar {\n transition: none;\n }\n}", le = !1;
306
- function V(e) {
307
- if (typeof document > "u" || le) return;
305
+ var ue = ":host {\n display: block;\n width: 100%;\n height: 100%;\n min-height: 0;\n}\n\n.liforma-et {\n --liforma-et-parallax-x: 0;\n --liforma-et-parallax-y: 0;\n --liforma-et-bg-scale: 1;\n --liforma-et-fg-scale: 1;\n --liforma-et-avatar-scale: 1;\n --liforma-et-bg-shift: 0px;\n --liforma-et-fg-shift: 0px;\n --liforma-et-avatar-shift: 0px;\n --liforma-et-reveal-duration: 420ms;\n\n box-sizing: border-box;\n position: relative;\n display: block;\n width: 100%;\n height: 100%;\n min-height: 0;\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: 0;\n overflow: hidden;\n background: #111;\n color: inherit;\n text-decoration: none;\n cursor: inherit;\n -webkit-tap-highlight-color: transparent;\n}\n\na.liforma-et,\nbutton.liforma-et {\n cursor: pointer;\n}\n\nbutton.liforma-et {\n font: inherit;\n appearance: none;\n}\n\n.liforma-et__placeholder {\n position: absolute;\n inset: 0;\n z-index: 0;\n background:\n radial-gradient(120% 90% at 50% 0%, rgba(255, 255, 255, 0.06), transparent 58%),\n linear-gradient(180deg, #1a1a1a 0%, #101010 100%);\n opacity: 1;\n transition: opacity var(--liforma-et-reveal-duration) ease;\n}\n\n.liforma-et--revealed .liforma-et__placeholder {\n opacity: 0;\n}\n\n.liforma-et__media {\n opacity: 0;\n transition: opacity var(--liforma-et-reveal-duration) ease;\n}\n\n.liforma-et__media--ready {\n opacity: 1;\n}\n\n.liforma-et__background {\n position: absolute;\n inset: 0;\n z-index: 1;\n width: 100%;\n height: 100%;\n object-fit: cover;\n object-position: center center;\n transform: translate(\n calc(var(--liforma-et-parallax-x) * var(--liforma-et-bg-shift)),\n calc(var(--liforma-et-parallax-y) * var(--liforma-et-bg-shift))\n )\n scale(var(--liforma-et-bg-scale));\n transform-origin: center center;\n transition:\n opacity var(--liforma-et-reveal-duration) ease,\n transform 160ms ease;\n}\n\n.liforma-et__avatar {\n position: relative;\n z-index: 2;\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n object-position: center bottom;\n transform: scale(var(--liforma-et-avatar-scale))\n translate(\n calc(var(--liforma-et-parallax-x) * var(--liforma-et-avatar-shift)),\n calc(var(--liforma-et-parallax-y) * var(--liforma-et-avatar-shift))\n );\n transform-origin: center center;\n transition:\n opacity var(--liforma-et-reveal-duration) ease,\n transform 160ms ease;\n}\n\n/* Gallery plates are typically square in a square tile — contain vs cover is a no-op\n without a zoom. Scale the whole scene from the upper third so Face matches\n player fit (location + avatar crop together). */\n.liforma-et--fit-face {\n --liforma-et-avatar-scale: 1.85;\n --liforma-et-bg-scale: 1.85;\n --liforma-et-fg-scale: 1.85;\n}\n\n.liforma-et--fit-face .liforma-et__avatar,\n.liforma-et--fit-face .liforma-et__background,\n.liforma-et--fit-face .liforma-et__foreground {\n transform-origin: 50% 18%;\n}\n\n.liforma-et--fit-face .liforma-et__avatar {\n object-fit: cover;\n object-position: 50% 18%;\n}\n\n/* Bust / medium: less zoom than face so upper chest stays in frame (player 3.75H window). */\n.liforma-et--fit-medium {\n --liforma-et-avatar-scale: 1.35;\n --liforma-et-bg-scale: 1.35;\n --liforma-et-fg-scale: 1.35;\n}\n\n.liforma-et--fit-medium .liforma-et__avatar,\n.liforma-et--fit-medium .liforma-et__background,\n.liforma-et--fit-medium .liforma-et__foreground {\n transform-origin: 50% 28%;\n}\n\n.liforma-et--fit-medium .liforma-et__avatar {\n object-fit: cover;\n object-position: 50% 28%;\n}\n\n.liforma-et__foreground {\n position: absolute;\n inset: 0;\n z-index: 3;\n width: 100%;\n height: 100%;\n object-fit: cover;\n object-position: center center;\n pointer-events: none;\n transform: translate(\n calc(var(--liforma-et-parallax-x) * var(--liforma-et-fg-shift) * -1),\n calc(var(--liforma-et-parallax-y) * var(--liforma-et-fg-shift) * -1)\n )\n scale(var(--liforma-et-fg-scale));\n transform-origin: center center;\n transition:\n opacity var(--liforma-et-reveal-duration) ease,\n transform 160ms ease;\n}\n\n.liforma-et--parallax {\n --liforma-et-bg-scale: 1.08;\n --liforma-et-fg-scale: 1.05;\n --liforma-et-avatar-scale: 1.08;\n --liforma-et-bg-shift: 10px;\n --liforma-et-fg-shift: 4px;\n --liforma-et-avatar-shift: 4px;\n}\n\n/* Promote layers only while parallax is active — avoids N compositor surfaces on galleries. */\n.liforma-et--parallax .liforma-et__background,\n.liforma-et--parallax .liforma-et__foreground,\n.liforma-et--parallax .liforma-et__avatar {\n will-change: transform;\n}\n\n.liforma-et--parallax.liforma-et--fit-face {\n --liforma-et-avatar-scale: 1.95;\n --liforma-et-bg-scale: 1.95;\n --liforma-et-fg-scale: 1.95;\n --liforma-et-avatar-shift: 0px;\n}\n\n.liforma-et--parallax.liforma-et--fit-medium {\n --liforma-et-avatar-scale: 1.42;\n --liforma-et-bg-scale: 1.42;\n --liforma-et-fg-scale: 1.42;\n --liforma-et-avatar-shift: 0px;\n}\n\n.liforma-et--scroll-parallax .liforma-et__background,\n.liforma-et--scroll-parallax .liforma-et__foreground,\n.liforma-et--scroll-parallax .liforma-et__avatar {\n transition: opacity var(--liforma-et-reveal-duration) ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .liforma-et {\n --liforma-et-reveal-duration: 0ms;\n }\n\n .liforma-et--parallax {\n --liforma-et-bg-scale: 1;\n --liforma-et-fg-scale: 1;\n --liforma-et-avatar-scale: 1;\n --liforma-et-bg-shift: 0px;\n --liforma-et-fg-shift: 0px;\n --liforma-et-avatar-shift: 0px;\n }\n\n .liforma-et--parallax.liforma-et--fit-face {\n --liforma-et-avatar-scale: 1.85;\n --liforma-et-bg-scale: 1.85;\n --liforma-et-fg-scale: 1.85;\n }\n\n .liforma-et__background,\n .liforma-et__foreground,\n .liforma-et__avatar {\n transition: none;\n }\n}", de = !1;
306
+ function z(e) {
307
+ if (typeof document > "u" || de) return;
308
308
  if (document.querySelector("style[data-liforma-et]")) {
309
- le = !0;
309
+ de = !0;
310
310
  return;
311
311
  }
312
312
  let t = document.createElement("style");
313
- t.setAttribute("data-liforma-et", ""), t.textContent = e, document.head.appendChild(t), le = !0;
313
+ t.setAttribute("data-liforma-et", ""), t.textContent = e, document.head.appendChild(t), de = !0;
314
314
  }
315
315
  //#endregion
316
316
  //#region src/widget/styles.ts
317
- var ue = "\n.liforma-ew {\n box-sizing: border-box;\n position: relative;\n display: block;\n width: 100%;\n height: 100%;\n min-height: 0;\n margin: 0;\n padding: 0;\n border: 0;\n}\n\n/* Optional self-positioned FAB (position=bottom-right|bottom-left).\n * Cap at 50vmin so small phones don't get an oversized thumb (desktop 224px stays). */\n.liforma-ew[data-position='bottom-right'],\n.liforma-ew[data-position='bottom-left'] {\n position: fixed;\n width: min(var(--liforma-ew-fab-size, 224px), 50vmin);\n height: min(var(--liforma-ew-fab-size, 224px), 50vmin);\n bottom: var(--liforma-ew-offset, 16px);\n z-index: 2147482900;\n}\n\n.liforma-ew[data-position='bottom-right'] {\n right: var(--liforma-ew-offset, 16px);\n left: auto;\n}\n\n.liforma-ew[data-position='bottom-left'] {\n left: var(--liforma-ew-offset, 16px);\n right: auto;\n}\n\n/* While open, collapse the FAB box so a corner hole / thumb never remains. */\n.liforma-ew[data-position='bottom-right'][data-state='expanded'],\n.liforma-ew[data-position='bottom-right'][data-state='docked'],\n.liforma-ew[data-position='bottom-left'][data-state='expanded'],\n.liforma-ew[data-position='bottom-left'][data-state='docked'] {\n width: 0;\n height: 0;\n min-width: 0;\n min-height: 0;\n overflow: visible;\n pointer-events: none;\n}\n\n.liforma-ew[data-state='expanded'] .liforma-ew__warm,\n.liforma-ew[data-state='docked'] .liforma-ew__warm,\n.liforma-ew[data-state='expanded'] .liforma-ew__overlay,\n.liforma-ew[data-state='expanded'] .liforma-ew__toolbar,\n.liforma-ew[data-state='docked'] .liforma-ew__toolbar {\n pointer-events: auto;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__overlay {\n pointer-events: none;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__panel {\n pointer-events: auto;\n}\n\n.liforma-ew__hit {\n box-sizing: border-box;\n display: block;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n border: 0;\n background: transparent;\n cursor: pointer;\n font: inherit;\n appearance: none;\n -webkit-tap-highlight-color: transparent;\n transform: scale(1);\n transform-origin: center center;\n transition:\n transform 180ms ease,\n filter 180ms ease;\n will-change: transform;\n}\n\n/* Author display must not defeat the HTML hidden attribute. */\n.liforma-ew__hit[hidden] {\n display: none !important;\n}\n\n.liforma-ew__hit:focus-visible {\n outline: 2px solid #5b8def;\n outline-offset: 3px;\n border-radius: 0.75rem;\n}\n\n@media (hover: hover) and (pointer: fine) {\n /* Scale the thumb whenever the collapsed FAB is hovered — including via the warm iframe hit layer. */\n .liforma-ew[data-state='collapsed'] .liforma-ew__hit:not(:disabled):hover,\n .liforma-ew[data-state='collapsed']:has(.liforma-ew__warm:hover) .liforma-ew__hit {\n transform: scale(1.06);\n }\n\n .liforma-ew[data-state='collapsed'] .liforma-ew__hit:not(:disabled):hover .liforma-et,\n .liforma-ew[data-state='collapsed']:has(.liforma-ew__warm:hover) .liforma-et {\n box-shadow: 0 12px 36px rgba(0, 0, 0, 0.34);\n }\n}\n\n.liforma-ew__face {\n width: 100%;\n height: 100%;\n min-height: 0;\n position: relative;\n}\n\n.liforma-ew__face-status {\n position: absolute;\n inset: 0;\n z-index: 1;\n display: grid;\n place-items: center;\n padding: 0.5rem;\n text-align: center;\n font: 600 0.75rem/1.3 system-ui, sans-serif;\n color: #e8ecf4;\n background: rgba(10, 12, 18, 0.72);\n border-radius: 0.75rem;\n pointer-events: none;\n}\n\n.liforma-ew__face-status[hidden] {\n display: none !important;\n}\n\n.liforma-ew__hit:disabled {\n cursor: default;\n opacity: 0.85;\n}\n\n.liforma-ew__face .liforma-et {\n border-radius: 0.75rem;\n box-shadow: 0 8px 28px rgba(0, 0, 0, 0.28);\n transition: box-shadow 180ms ease;\n}\n\n.liforma-ew__warm {\n box-sizing: border-box;\n position: absolute;\n inset: 0;\n z-index: 2;\n border-radius: 0.75rem;\n overflow: hidden;\n background: transparent;\n pointer-events: none;\n opacity: 1;\n transition: opacity 1000ms ease;\n}\n\n/*\n * Collapsed: keep the warm iframe as an invisible hit target only.\n * Painting it over the thumb causes a “ghost enlarge” (face scales under a static iframe).\n */\n.liforma-ew[data-state='collapsed'] .liforma-ew__warm {\n opacity: 0;\n transition: none;\n}\n\n.liforma-ew[data-warm='true'] .liforma-ew__warm {\n pointer-events: auto;\n}\n\n.liforma-ew[data-warm='true']:not([data-live='true']) .liforma-ew__hit {\n pointer-events: none;\n}\n\n.liforma-ew[data-live='true'][data-state='collapsed'] .liforma-ew__hit {\n pointer-events: auto;\n}\n\n.liforma-ew[data-live='true'] .liforma-ew__warm,\n.liforma-ew[data-live='true'] .liforma-ew__stage {\n /* Hidden under the thumb / until post-resize fade-in (matches cold avatar reveal). */\n opacity: 0;\n}\n\n.liforma-ew[data-live='true'].liforma-ew--session-revealed[data-state='expanded'] .liforma-ew__warm,\n.liforma-ew[data-live='true'].liforma-ew--session-revealed[data-state='expanded'] .liforma-ew__stage,\n.liforma-ew[data-live='true'].liforma-ew--session-revealed[data-state='docked'] .liforma-ew__warm,\n.liforma-ew[data-live='true'].liforma-ew--session-revealed[data-state='docked'] .liforma-ew__stage {\n opacity: 1;\n}\n\n.liforma-ew--session-concealing .liforma-ew__warm,\n.liforma-ew--session-concealing .liforma-ew__stage {\n transition-duration: 280ms;\n}\n\n/* Instant hide while dock/maximize geometry settles (player morph resize ~160ms). */\n.liforma-ew--layout-settling .liforma-ew__warm,\n.liforma-ew--layout-settling .liforma-ew__stage {\n opacity: 0 !important;\n transition: none !important;\n}\n\n.liforma-ew[data-live='true'][data-state='collapsed'] .liforma-ew__warm {\n /* Keep the live iframe under the thumb; FAB click resumes the shell. */\n pointer-events: none;\n opacity: 0;\n /* Instant hide when collapsed so the FAB never shows a resized live mesh. */\n transition: none;\n}\n\n.liforma-ew[data-state='expanded'] .liforma-ew__warm {\n position: fixed;\n /* Match overlay panel inset so the warm iframe fills the conversation shell. */\n inset: clamp(12px, 3vw, 28px);\n z-index: 2147483001;\n width: auto;\n height: auto;\n border-radius: 16px;\n pointer-events: auto;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__warm {\n position: fixed;\n inset: auto;\n z-index: 2147483001;\n border-radius: 16px;\n pointer-events: auto;\n /* left/top/width/height set inline from dock geometry */\n}\n\n.liforma-ew__toolbar {\n display: none;\n position: fixed;\n z-index: 2147483002;\n pointer-events: auto;\n box-sizing: border-box;\n align-items: center;\n gap: 0.35rem;\n padding: 0.35rem 0.4rem;\n border-radius: 999px;\n background: rgba(12, 14, 20, 0.72);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);\n}\n\n.liforma-ew[data-state='expanded'] .liforma-ew__toolbar {\n display: flex;\n top: calc(clamp(12px, 3vw, 28px) + 10px);\n right: calc(clamp(12px, 3vw, 28px) + 10px);\n left: auto;\n cursor: default;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__toolbar {\n display: flex;\n /* left/top set inline to track the panel; strip remains a drag handle */\n cursor: grab;\n touch-action: none;\n user-select: none;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__panel,\n.liforma-ew[data-state='docked'] .liforma-ew__warm,\n.liforma-ew[data-state='docked'] .liforma-ew__stage {\n /* Player also reports surface drags via postMessage when docked. */\n cursor: grab;\n touch-action: none;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__toolbar.liforma-ew__toolbar--dragging,\n.liforma-ew--dock-dragging,\n.liforma-ew--dock-dragging .liforma-ew__toolbar,\n.liforma-ew--dock-dragging .liforma-ew__panel,\n.liforma-ew--dock-dragging .liforma-ew__warm,\n.liforma-ew--dock-dragging .liforma-ew__stage {\n cursor: grabbing;\n}\n\n\n.liforma-ew__toolbar[hidden] {\n display: none !important;\n}\n\n.liforma-ew__icon-btn {\n appearance: none;\n box-sizing: border-box;\n display: inline-grid;\n place-items: center;\n width: 2rem;\n height: 2rem;\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: 999px;\n color: #f5f7fb;\n background: transparent;\n cursor: pointer;\n}\n\n.liforma-ew__icon-btn:hover {\n background: rgba(255, 255, 255, 0.12);\n}\n\n.liforma-ew__icon-btn[aria-pressed='true'] {\n background: rgba(255, 255, 255, 0.2);\n}\n\n.liforma-ew__icon-btn:focus-visible {\n outline: 2px solid #5b8def;\n outline-offset: 2px;\n}\n\n.liforma-ew__icon-btn svg {\n width: 1.05rem;\n height: 1.05rem;\n display: block;\n}\n\n.liforma-ew__drag-grip {\n display: none;\n width: 0.85rem;\n height: 1.25rem;\n margin: 0 0.15rem 0 0.25rem;\n background:\n radial-gradient(circle, currentColor 1.1px, transparent 1.2px) 0 0 / 0.35rem 0.35rem,\n radial-gradient(circle, currentColor 1.1px, transparent 1.2px) 0.35rem 0 / 0.35rem 0.35rem;\n background-repeat: repeat-y;\n opacity: 0.55;\n color: #f5f7fb;\n pointer-events: none;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__drag-grip {\n display: block;\n}\n\n.liforma-ew__dock-toggle[hidden] {\n display: none !important;\n}\n\n.liforma-ew__overlay {\n position: fixed;\n inset: 0;\n z-index: 2147483000;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: clamp(12px, 3vw, 28px);\n box-sizing: border-box;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__overlay {\n padding: 0;\n align-items: stretch;\n justify-content: stretch;\n pointer-events: none;\n background: transparent;\n}\n\n.liforma-ew__overlay[hidden] {\n display: none !important;\n}\n\n.liforma-ew__backdrop {\n position: absolute;\n inset: 0;\n border: 0;\n padding: 0;\n margin: 0;\n background: rgba(6, 8, 14, 0.62);\n cursor: pointer;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__backdrop {\n display: none !important;\n}\n\n.liforma-ew__panel {\n position: relative;\n z-index: 1;\n display: flex;\n flex-direction: column;\n /* Fill the overlay so player loading / start UI centers in the visible window. */\n width: var(--liforma-ew-max-w, 100%);\n height: var(--liforma-ew-max-h, 100%);\n max-width: 100%;\n max-height: 100%;\n border-radius: 16px;\n overflow: hidden;\n background: #030508;\n box-shadow: 0 24px 80px rgba(0, 0, 0, 0.45);\n /* Warm iframe sits above as a sibling; keep panel as chrome shell. */\n pointer-events: none;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__panel {\n position: fixed;\n inset: auto;\n max-width: none;\n max-height: none;\n pointer-events: auto;\n /* left/top/width/height set inline from dock geometry */\n}\n\n.liforma-ew:not([data-warm='true']) .liforma-ew__panel {\n pointer-events: auto;\n}\n\n.liforma-ew__stage {\n position: relative;\n flex: 1;\n min-height: 0;\n width: 100%;\n height: 100%;\n background: #030508;\n opacity: 1;\n transition: opacity 1000ms ease;\n}\n\n.liforma-ew__status {\n position: absolute;\n inset: 0;\n z-index: 1;\n display: grid;\n place-items: center;\n padding: 1.5rem;\n text-align: center;\n color: #d7dde8;\n font: 500 0.9375rem/1.45 system-ui, sans-serif;\n background: rgba(3, 5, 8, 0.92);\n pointer-events: none;\n}\n\n.liforma-ew__status[hidden] {\n display: none !important;\n}\n\n/* Mobile expanded: ~90% viewport, no reduce control. */\n@media (max-width: 767px) {\n .liforma-ew[data-state='expanded'] .liforma-ew__overlay {\n padding: 5vh 5vw;\n }\n\n .liforma-ew[data-state='expanded'] .liforma-ew__panel {\n width: 90vw;\n height: 90vh;\n max-width: 90vw;\n max-height: 90vh;\n }\n\n .liforma-ew[data-state='expanded'] .liforma-ew__warm {\n inset: 5vh 5vw;\n }\n\n .liforma-ew[data-state='expanded'] .liforma-ew__toolbar {\n top: calc(5vh + 10px);\n right: calc(5vw + 10px);\n }\n\n .liforma-ew__dock-toggle {\n display: none !important;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .liforma-ew__hit {\n transition: none;\n will-change: auto;\n }\n\n .liforma-ew[data-state='collapsed'] .liforma-ew__hit:not(:disabled):hover,\n .liforma-ew[data-state='collapsed']:has(.liforma-ew__warm:hover) .liforma-ew__hit {\n transform: none;\n }\n\n .liforma-ew__face .liforma-et {\n box-shadow: none;\n transition: none;\n }\n\n .liforma-ew__warm,\n .liforma-ew__stage {\n transition: none;\n }\n}\n", de = "liforma-experience-widget-styles";
318
- function fe(e = ue) {
317
+ var fe = "\n.liforma-ew {\n box-sizing: border-box;\n position: relative;\n display: block;\n width: 100%;\n height: 100%;\n min-height: 0;\n margin: 0;\n padding: 0;\n border: 0;\n}\n\n/* Optional self-positioned FAB (position=bottom-right|bottom-left).\n * Cap at 50vmin so small phones don't get an oversized thumb (desktop 224px stays). */\n.liforma-ew[data-position='bottom-right'],\n.liforma-ew[data-position='bottom-left'] {\n position: fixed;\n width: min(var(--liforma-ew-fab-size, 224px), 50vmin);\n height: min(var(--liforma-ew-fab-size, 224px), 50vmin);\n bottom: var(--liforma-ew-offset, 16px);\n z-index: 2147482900;\n}\n\n.liforma-ew[data-position='bottom-right'] {\n right: var(--liforma-ew-offset, 16px);\n left: auto;\n}\n\n.liforma-ew[data-position='bottom-left'] {\n left: var(--liforma-ew-offset, 16px);\n right: auto;\n}\n\n/* While open, collapse the FAB box so a corner hole / thumb never remains. */\n.liforma-ew[data-position='bottom-right'][data-state='expanded'],\n.liforma-ew[data-position='bottom-right'][data-state='docked'],\n.liforma-ew[data-position='bottom-left'][data-state='expanded'],\n.liforma-ew[data-position='bottom-left'][data-state='docked'] {\n width: 0;\n height: 0;\n min-width: 0;\n min-height: 0;\n overflow: visible;\n pointer-events: none;\n}\n\n.liforma-ew[data-state='expanded'] .liforma-ew__warm,\n.liforma-ew[data-state='docked'] .liforma-ew__warm,\n.liforma-ew[data-state='expanded'] .liforma-ew__overlay,\n.liforma-ew[data-state='expanded'] .liforma-ew__toolbar,\n.liforma-ew[data-state='docked'] .liforma-ew__toolbar {\n pointer-events: auto;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__overlay {\n pointer-events: none;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__panel {\n pointer-events: auto;\n}\n\n.liforma-ew__hit {\n box-sizing: border-box;\n display: block;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n border: 0;\n background: transparent;\n cursor: pointer;\n font: inherit;\n appearance: none;\n -webkit-tap-highlight-color: transparent;\n transform: scale(1);\n transform-origin: center center;\n transition:\n transform 180ms ease,\n filter 180ms ease;\n will-change: transform;\n}\n\n/* Author display must not defeat the HTML hidden attribute. */\n.liforma-ew__hit[hidden] {\n display: none !important;\n}\n\n.liforma-ew__hit:focus-visible {\n outline: 2px solid #5b8def;\n outline-offset: 3px;\n border-radius: 0.75rem;\n}\n\n@media (hover: hover) and (pointer: fine) {\n /* Scale the thumb whenever the collapsed FAB is hovered — including via the warm iframe hit layer. */\n .liforma-ew[data-state='collapsed'] .liforma-ew__hit:not(:disabled):hover,\n .liforma-ew[data-state='collapsed']:has(.liforma-ew__warm:hover) .liforma-ew__hit {\n transform: scale(1.06);\n }\n\n .liforma-ew[data-state='collapsed'] .liforma-ew__hit:not(:disabled):hover .liforma-et,\n .liforma-ew[data-state='collapsed']:has(.liforma-ew__warm:hover) .liforma-et {\n box-shadow: 0 12px 36px rgba(0, 0, 0, 0.34);\n }\n}\n\n.liforma-ew__face {\n width: 100%;\n height: 100%;\n min-height: 0;\n position: relative;\n}\n\n.liforma-ew__face-status {\n position: absolute;\n inset: 0;\n z-index: 1;\n display: grid;\n place-items: center;\n padding: 0.5rem;\n text-align: center;\n font: 600 0.75rem/1.3 system-ui, sans-serif;\n color: #e8ecf4;\n background: rgba(10, 12, 18, 0.72);\n border-radius: 0.75rem;\n pointer-events: none;\n}\n\n.liforma-ew__face-status[hidden] {\n display: none !important;\n}\n\n.liforma-ew__hit:disabled {\n cursor: default;\n opacity: 0.85;\n}\n\n.liforma-ew__face .liforma-et {\n border-radius: 0.75rem;\n box-shadow: 0 8px 28px rgba(0, 0, 0, 0.28);\n transition: box-shadow 180ms ease;\n}\n\n.liforma-ew__warm {\n box-sizing: border-box;\n position: absolute;\n inset: 0;\n z-index: 2;\n border-radius: 0.75rem;\n overflow: hidden;\n background: transparent;\n pointer-events: none;\n opacity: 1;\n transition: opacity 1000ms ease;\n}\n\n/*\n * Collapsed: keep the warm iframe as an invisible hit target only.\n * Painting it over the thumb causes a “ghost enlarge” (face scales under a static iframe).\n */\n.liforma-ew[data-state='collapsed'] .liforma-ew__warm {\n opacity: 0;\n transition: none;\n}\n\n.liforma-ew[data-warm='true'] .liforma-ew__warm {\n pointer-events: auto;\n}\n\n.liforma-ew[data-warm='true']:not([data-live='true']) .liforma-ew__hit {\n pointer-events: none;\n}\n\n.liforma-ew[data-live='true'][data-state='collapsed'] .liforma-ew__hit {\n pointer-events: auto;\n}\n\n.liforma-ew[data-live='true'] .liforma-ew__warm,\n.liforma-ew[data-live='true'] .liforma-ew__stage {\n /* Hidden under the thumb / until post-resize fade-in (matches cold avatar reveal). */\n opacity: 0;\n}\n\n.liforma-ew[data-live='true'].liforma-ew--session-revealed[data-state='expanded'] .liforma-ew__warm,\n.liforma-ew[data-live='true'].liforma-ew--session-revealed[data-state='expanded'] .liforma-ew__stage,\n.liforma-ew[data-live='true'].liforma-ew--session-revealed[data-state='docked'] .liforma-ew__warm,\n.liforma-ew[data-live='true'].liforma-ew--session-revealed[data-state='docked'] .liforma-ew__stage {\n opacity: 1;\n}\n\n.liforma-ew--session-concealing .liforma-ew__warm,\n.liforma-ew--session-concealing .liforma-ew__stage {\n transition-duration: 280ms;\n}\n\n/* Instant hide while dock/maximize geometry settles (player morph resize ~160ms). */\n.liforma-ew--layout-settling .liforma-ew__warm,\n.liforma-ew--layout-settling .liforma-ew__stage {\n opacity: 0 !important;\n transition: none !important;\n}\n\n.liforma-ew[data-live='true'][data-state='collapsed'] .liforma-ew__warm {\n /* Keep the live iframe under the thumb; FAB click resumes the shell. */\n pointer-events: none;\n opacity: 0;\n /* Instant hide when collapsed so the FAB never shows a resized live mesh. */\n transition: none;\n}\n\n.liforma-ew[data-state='expanded'] .liforma-ew__warm {\n position: fixed;\n /* Match overlay panel inset so the warm iframe fills the conversation shell. */\n inset: clamp(12px, 3vw, 28px);\n z-index: 2147483001;\n width: auto;\n height: auto;\n border-radius: 16px;\n pointer-events: auto;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__warm {\n position: fixed;\n inset: auto;\n z-index: 2147483001;\n border-radius: 16px;\n pointer-events: auto;\n /* left/top/width/height set inline from dock geometry */\n}\n\n.liforma-ew__toolbar {\n display: none;\n position: fixed;\n z-index: 2147483002;\n pointer-events: auto;\n box-sizing: border-box;\n align-items: center;\n gap: 0.35rem;\n padding: 0.35rem 0.4rem;\n border-radius: 999px;\n background: rgba(12, 14, 20, 0.72);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);\n}\n\n.liforma-ew[data-state='expanded'] .liforma-ew__toolbar {\n display: flex;\n top: calc(clamp(12px, 3vw, 28px) + 10px);\n right: calc(clamp(12px, 3vw, 28px) + 10px);\n left: auto;\n cursor: default;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__toolbar {\n display: flex;\n /* left/top set inline to track the panel; strip remains a drag handle */\n cursor: grab;\n touch-action: none;\n user-select: none;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__panel,\n.liforma-ew[data-state='docked'] .liforma-ew__warm,\n.liforma-ew[data-state='docked'] .liforma-ew__stage {\n /* Player also reports surface drags via postMessage when docked. */\n cursor: grab;\n touch-action: none;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__toolbar.liforma-ew__toolbar--dragging,\n.liforma-ew--dock-dragging,\n.liforma-ew--dock-dragging .liforma-ew__toolbar,\n.liforma-ew--dock-dragging .liforma-ew__panel,\n.liforma-ew--dock-dragging .liforma-ew__warm,\n.liforma-ew--dock-dragging .liforma-ew__stage {\n cursor: grabbing;\n}\n\n\n.liforma-ew__toolbar[hidden] {\n display: none !important;\n}\n\n.liforma-ew__icon-btn {\n appearance: none;\n box-sizing: border-box;\n display: inline-grid;\n place-items: center;\n width: 2rem;\n height: 2rem;\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: 999px;\n color: #f5f7fb;\n background: transparent;\n cursor: pointer;\n}\n\n.liforma-ew__icon-btn:hover {\n background: rgba(255, 255, 255, 0.12);\n}\n\n.liforma-ew__icon-btn[aria-pressed='true'] {\n background: rgba(255, 255, 255, 0.2);\n}\n\n.liforma-ew__icon-btn:focus-visible {\n outline: 2px solid #5b8def;\n outline-offset: 2px;\n}\n\n.liforma-ew__icon-btn svg {\n width: 1.05rem;\n height: 1.05rem;\n display: block;\n}\n\n.liforma-ew__drag-grip {\n display: none;\n width: 0.85rem;\n height: 1.25rem;\n margin: 0 0.15rem 0 0.25rem;\n background:\n radial-gradient(circle, currentColor 1.1px, transparent 1.2px) 0 0 / 0.35rem 0.35rem,\n radial-gradient(circle, currentColor 1.1px, transparent 1.2px) 0.35rem 0 / 0.35rem 0.35rem;\n background-repeat: repeat-y;\n opacity: 0.55;\n color: #f5f7fb;\n pointer-events: none;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__drag-grip {\n display: block;\n}\n\n.liforma-ew__dock-toggle[hidden] {\n display: none !important;\n}\n\n.liforma-ew__overlay {\n position: fixed;\n inset: 0;\n z-index: 2147483000;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: clamp(12px, 3vw, 28px);\n box-sizing: border-box;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__overlay {\n padding: 0;\n align-items: stretch;\n justify-content: stretch;\n pointer-events: none;\n background: transparent;\n}\n\n.liforma-ew__overlay[hidden] {\n display: none !important;\n}\n\n.liforma-ew__backdrop {\n position: absolute;\n inset: 0;\n border: 0;\n padding: 0;\n margin: 0;\n background: rgba(6, 8, 14, 0.62);\n cursor: pointer;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__backdrop {\n display: none !important;\n}\n\n.liforma-ew__panel {\n position: relative;\n z-index: 1;\n display: flex;\n flex-direction: column;\n /* Fill the overlay so player loading / start UI centers in the visible window. */\n width: var(--liforma-ew-max-w, 100%);\n height: var(--liforma-ew-max-h, 100%);\n max-width: 100%;\n max-height: 100%;\n border-radius: 16px;\n overflow: hidden;\n background: #030508;\n box-shadow: 0 24px 80px rgba(0, 0, 0, 0.45);\n /* Warm iframe sits above as a sibling; keep panel as chrome shell. */\n pointer-events: none;\n}\n\n.liforma-ew[data-state='docked'] .liforma-ew__panel {\n position: fixed;\n inset: auto;\n max-width: none;\n max-height: none;\n pointer-events: auto;\n /* left/top/width/height set inline from dock geometry */\n}\n\n.liforma-ew:not([data-warm='true']) .liforma-ew__panel {\n pointer-events: auto;\n}\n\n.liforma-ew__stage {\n position: relative;\n flex: 1;\n min-height: 0;\n width: 100%;\n height: 100%;\n background: #030508;\n opacity: 1;\n transition: opacity 1000ms ease;\n}\n\n.liforma-ew__status {\n position: absolute;\n inset: 0;\n z-index: 1;\n display: grid;\n place-items: center;\n padding: 1.5rem;\n text-align: center;\n color: #d7dde8;\n font: 500 0.9375rem/1.45 system-ui, sans-serif;\n background: rgba(3, 5, 8, 0.92);\n pointer-events: none;\n}\n\n.liforma-ew__status[hidden] {\n display: none !important;\n}\n\n/* Mobile expanded: ~90% viewport, no reduce control. */\n@media (max-width: 767px) {\n .liforma-ew[data-state='expanded'] .liforma-ew__overlay {\n padding: 5vh 5vw;\n }\n\n .liforma-ew[data-state='expanded'] .liforma-ew__panel {\n width: 90vw;\n height: 90vh;\n max-width: 90vw;\n max-height: 90vh;\n }\n\n .liforma-ew[data-state='expanded'] .liforma-ew__warm {\n inset: 5vh 5vw;\n }\n\n .liforma-ew[data-state='expanded'] .liforma-ew__toolbar {\n top: calc(5vh + 10px);\n right: calc(5vw + 10px);\n }\n\n .liforma-ew__dock-toggle {\n display: none !important;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .liforma-ew__hit {\n transition: none;\n will-change: auto;\n }\n\n .liforma-ew[data-state='collapsed'] .liforma-ew__hit:not(:disabled):hover,\n .liforma-ew[data-state='collapsed']:has(.liforma-ew__warm:hover) .liforma-ew__hit {\n transform: none;\n }\n\n .liforma-ew__face .liforma-et {\n box-shadow: none;\n transition: none;\n }\n\n .liforma-ew__warm,\n .liforma-ew__stage {\n transition: none;\n }\n}\n", pe = "liforma-experience-widget-styles";
318
+ function me(e = fe) {
319
319
  if (typeof document > "u") return;
320
- let t = document.getElementById(de);
320
+ let t = document.getElementById(pe);
321
321
  if (t) {
322
322
  t.textContent = e;
323
323
  return;
324
324
  }
325
325
  let n = document.createElement("style");
326
- n.id = de, n.textContent = e, document.head.append(n);
326
+ n.id = pe, n.textContent = e, document.head.append(n);
327
327
  }
328
328
  //#endregion
329
329
  //#region src/shims/apiBaseUrl.ts
330
- var pe = "https://api.liforma.ai", me = "http://localhost:3001";
331
- function he() {
330
+ var he = "https://api.liforma.ai", ge = "http://localhost:3001";
331
+ function _e() {
332
332
  let e = globalThis.__LIFORMA_API_BASE_URL;
333
333
  if (e?.trim()) return e.trim().replace(/\/$/, "");
334
334
  if (typeof document > "u") return null;
335
335
  let t = (document.querySelector("script[data-liforma-sdk][src*=\"client.js\"]") ?? document.querySelector("script[src*=\"/sdk/v2/client.js\"]"))?.getAttribute("data-api-base-url")?.trim();
336
336
  return t ? t.replace(/\/$/, "") : null;
337
337
  }
338
- function H() {
339
- return he() || (y() ? me : pe);
338
+ function B() {
339
+ return _e() || (y() ? ge : he);
340
340
  }
341
341
  //#endregion
342
342
  //#region src/v2/api/fetchExperiencePreview.ts
343
- function ge(e) {
343
+ function ve(e) {
344
344
  if (!e || typeof e != "object") return null;
345
345
  let t = e, n = typeof t.avatarImage == "string" ? t.avatarImage.trim() : "";
346
346
  return n ? {
@@ -349,10 +349,10 @@ function ge(e) {
349
349
  ...typeof t.foregroundImage == "string" && t.foregroundImage.trim() ? { foregroundImage: t.foregroundImage.trim() } : {}
350
350
  } : null;
351
351
  }
352
- async function _e(e, t) {
352
+ async function ye(e, t) {
353
353
  let n = e.trim();
354
354
  if (!n) throw Error("Experience preview requires experienceId.");
355
- let r = (t?.apiBaseUrl ?? H()).replace(/\/$/, ""), i = await fetch(`${r}/v1/experiences/${encodeURIComponent(n)}/preview`, {
355
+ let r = (t?.apiBaseUrl ?? B()).replace(/\/$/, ""), i = await fetch(`${r}/v1/experiences/${encodeURIComponent(n)}/preview`, {
356
356
  method: "GET",
357
357
  headers: { Accept: "application/json" },
358
358
  signal: t?.signal
@@ -372,7 +372,7 @@ async function _e(e, t) {
372
372
  throw Error("Experience preview returned invalid JSON.");
373
373
  }
374
374
  if (!a || typeof a != "object") throw Error("Experience preview returned an invalid payload.");
375
- let o = a, s = typeof o.experienceId == "string" ? o.experienceId.trim() : n, c = typeof o.title == "string" ? o.title.trim() : "", l = ge(o.galleryThumb);
375
+ let o = a, s = typeof o.experienceId == "string" ? o.experienceId.trim() : n, c = typeof o.title == "string" ? o.title.trim() : "", l = ve(o.galleryThumb);
376
376
  if (!l) throw Error("Experience preview is missing gallery thumb images.");
377
377
  return {
378
378
  experienceId: s || n,
@@ -382,7 +382,7 @@ async function _e(e, t) {
382
382
  }
383
383
  //#endregion
384
384
  //#region src/v2/errors/LiformaError.ts
385
- var U = class extends Error {
385
+ var V = class extends Error {
386
386
  code;
387
387
  requestId;
388
388
  status;
@@ -391,16 +391,16 @@ var U = class extends Error {
391
391
  super(e, t?.cause === void 0 ? void 0 : { cause: t.cause }), this.name = "LiformaError", this.code = t?.code?.trim() || "UNKNOWN", this.requestId = t?.requestId?.trim() || void 0, this.status = t?.status, this.details = t?.details;
392
392
  }
393
393
  };
394
- function ve(e) {
394
+ function be(e) {
395
395
  if (!(!e || typeof e != "object" || Array.isArray(e))) return e;
396
396
  }
397
- function ye(e, t, n) {
397
+ function xe(e, t, n) {
398
398
  let r = n?.get("Liforma-Request-Id")?.trim() || void 0, i;
399
399
  try {
400
400
  i = JSON.parse(t);
401
401
  } catch {}
402
- let a = i?.error && typeof i.error == "object" ? i.error : void 0, o = a?.code ?? i?.code, s = a?.message ?? i?.message, c = a?.requestId ?? i?.requestId ?? r, l = typeof o == "string" && o.trim() ? o.trim() : "HTTP_ERROR", u = typeof s == "string" && s.trim() ? s.trim() : t.trim().slice(0, 500) || `Request failed (${e})`, d = typeof c == "string" && c.trim() ? c.trim() : r, { code: f, message: p, requestId: m, ...h } = ve(a) ?? ve(i) ?? {};
403
- return new U(u, {
402
+ let a = i?.error && typeof i.error == "object" ? i.error : void 0, o = a?.code ?? i?.code, s = a?.message ?? i?.message, c = a?.requestId ?? i?.requestId ?? r, l = typeof o == "string" && o.trim() ? o.trim() : "HTTP_ERROR", u = typeof s == "string" && s.trim() ? s.trim() : t.trim().slice(0, 500) || `Request failed (${e})`, d = typeof c == "string" && c.trim() ? c.trim() : r, { code: f, message: p, requestId: m, ...h } = be(a) ?? be(i) ?? {};
403
+ return new V(u, {
404
404
  code: l,
405
405
  requestId: d,
406
406
  status: e,
@@ -409,37 +409,37 @@ function ye(e, t, n) {
409
409
  }
410
410
  //#endregion
411
411
  //#region src/v2/api/captureAttribution.ts
412
- var be = 128, W = /[\u0000-\u001f\u007f]/g;
413
- function G(e) {
412
+ var Se = 128, H = /[\u0000-\u001f\u007f]/g;
413
+ function U(e) {
414
414
  if (!e) return;
415
- let t = e.replace(W, "").trim();
416
- if (t) return t.slice(0, be);
415
+ let t = e.replace(H, "").trim();
416
+ if (t) return t.slice(0, Se);
417
417
  }
418
- function xe(e) {
418
+ function Ce(e) {
419
419
  let t = new URLSearchParams((e ?? "").startsWith("?") ? (e ?? "").slice(1) : e ?? "");
420
420
  return {
421
- ...G(t.get("utm_source")) ? { utmSource: G(t.get("utm_source")) } : {},
422
- ...G(t.get("utm_medium")) ? { utmMedium: G(t.get("utm_medium")) } : {},
423
- ...G(t.get("utm_campaign")) ? { utmCampaign: G(t.get("utm_campaign")) } : {},
424
- ...G(t.get("utm_content")) ? { utmContent: G(t.get("utm_content")) } : {},
425
- ...G(t.get("utm_term")) ? { utmTerm: G(t.get("utm_term")) } : {}
421
+ ...U(t.get("utm_source")) ? { utmSource: U(t.get("utm_source")) } : {},
422
+ ...U(t.get("utm_medium")) ? { utmMedium: U(t.get("utm_medium")) } : {},
423
+ ...U(t.get("utm_campaign")) ? { utmCampaign: U(t.get("utm_campaign")) } : {},
424
+ ...U(t.get("utm_content")) ? { utmContent: U(t.get("utm_content")) } : {},
425
+ ...U(t.get("utm_term")) ? { utmTerm: U(t.get("utm_term")) } : {}
426
426
  };
427
427
  }
428
- function Se(e) {
428
+ function we(e) {
429
429
  if (e === !1) return;
430
430
  if (e && typeof e == "object") {
431
431
  let t = {
432
- ...G(e.utmSource) ? { utmSource: G(e.utmSource) } : {},
433
- ...G(e.utmMedium) ? { utmMedium: G(e.utmMedium) } : {},
434
- ...G(e.utmCampaign) ? { utmCampaign: G(e.utmCampaign) } : {},
435
- ...G(e.utmContent) ? { utmContent: G(e.utmContent) } : {},
436
- ...G(e.utmTerm) ? { utmTerm: G(e.utmTerm) } : {},
437
- ...G(e.referrer) ? { referrer: G(e.referrer) } : {}
432
+ ...U(e.utmSource) ? { utmSource: U(e.utmSource) } : {},
433
+ ...U(e.utmMedium) ? { utmMedium: U(e.utmMedium) } : {},
434
+ ...U(e.utmCampaign) ? { utmCampaign: U(e.utmCampaign) } : {},
435
+ ...U(e.utmContent) ? { utmContent: U(e.utmContent) } : {},
436
+ ...U(e.utmTerm) ? { utmTerm: U(e.utmTerm) } : {},
437
+ ...U(e.referrer) ? { referrer: U(e.referrer) } : {}
438
438
  };
439
439
  return Object.keys(t).length ? t : void 0;
440
440
  }
441
441
  if (typeof window > "u") return;
442
- let t = xe(window.location?.search), n = G(document.referrer || void 0), r = {
442
+ let t = Ce(window.location?.search), n = U(document.referrer || void 0), r = {
443
443
  ...t,
444
444
  ...n ? { referrer: n } : {}
445
445
  };
@@ -447,19 +447,19 @@ function Se(e) {
447
447
  }
448
448
  //#endregion
449
449
  //#region src/v2/api/sessionEndpointRequest.ts
450
- function Ce(e) {
450
+ function Te(e) {
451
451
  let t = e.locale?.trim();
452
452
  if (t) return t;
453
453
  let n = e.language?.trim();
454
454
  if (n) return n;
455
455
  if (typeof navigator < "u" && navigator.language?.trim()) return navigator.language.trim();
456
456
  }
457
- function we(e) {
457
+ function Ee(e) {
458
458
  let t = e.secondaryLocale?.trim(), n = e.learningLocale?.trim();
459
459
  if (t && n && t !== n) throw Error("secondaryLocale and learningLocale disagree; pass only one or make them equal.");
460
460
  return t || n || void 0;
461
461
  }
462
- function Te(e, t) {
462
+ function De(e, t) {
463
463
  let n = e.trim();
464
464
  if (!n) throw Error("sessionEndpoint must not be empty.");
465
465
  if (typeof location > "u") throw Error("sessionEndpoint is only available in a browser.");
@@ -467,7 +467,7 @@ function Te(e, t) {
467
467
  if (r.origin !== location.origin) throw Error("sessionEndpoint must be same-origin.");
468
468
  let i = t.experienceId.trim();
469
469
  if (!i) throw Error("sessionEndpoint requires experienceId.");
470
- let a = Ce(t), o = we(t), s = t.idempotencyKey?.trim();
470
+ let a = Te(t), o = Ee(t), s = t.idempotencyKey?.trim();
471
471
  return {
472
472
  url: r.toString(),
473
473
  init: {
@@ -486,7 +486,7 @@ function Te(e, t) {
486
486
  ...t.speechInputMode ? { speechInputMode: t.speechInputMode } : {},
487
487
  ...t.speechOnly === void 0 ? {} : { speechOnly: t.speechOnly },
488
488
  ...(() => {
489
- let e = Se(t.attribution);
489
+ let e = we(t.attribution);
490
490
  return e ? { attribution: e } : {};
491
491
  })(),
492
492
  ...t.alreadyConverted?.length ? { alreadyConverted: [...t.alreadyConverted] } : {}
@@ -496,16 +496,19 @@ function Te(e, t) {
496
496
  }
497
497
  //#endregion
498
498
  //#region src/v2/types/sessionLaunch.ts
499
- function K(e) {
499
+ function W(e, t) {
500
+ return t === void 0 ? {} : { [e]: t };
501
+ }
502
+ function G(e) {
500
503
  return !!e && typeof e == "object" && !Array.isArray(e);
501
504
  }
502
- function q(e) {
505
+ function K(e) {
503
506
  return typeof e == "boolean";
504
507
  }
505
- function Ee(e) {
506
- if (!K(e)) return null;
508
+ function Oe(e) {
509
+ if (!G(e)) return null;
507
510
  let t = e.speech, n = e.conversation, r = e.avatar, i = e.tools;
508
- return !K(t) || !K(n) || !K(r) || !K(i) || !q(t.input) || !q(t.output) || !q(t.externalAudio) || !q(n.managed) || !q(r.enabled) || !q(i.enabled) ? null : {
511
+ return !G(t) || !G(n) || !G(r) || !G(i) || !K(t.input) || !K(t.output) || !K(t.externalAudio) || !K(n.managed) || !K(r.enabled) || !K(i.enabled) ? null : {
509
512
  speech: {
510
513
  input: t.input,
511
514
  output: t.output,
@@ -516,8 +519,8 @@ function Ee(e) {
516
519
  tools: { enabled: i.enabled }
517
520
  };
518
521
  }
519
- function De(e) {
520
- return !K(e) || !q(e.avatar) || !q(e.speechInput) || !q(e.speechOutput) || !q(e.tools) || !q(e.externalAudio) ? null : {
522
+ function ke(e) {
523
+ return !G(e) || !K(e.avatar) || !K(e.speechInput) || !K(e.speechOutput) || !K(e.tools) || !K(e.externalAudio) ? null : {
521
524
  speech: {
522
525
  input: e.speechInput,
523
526
  output: e.speechOutput,
@@ -528,12 +531,12 @@ function De(e) {
528
531
  tools: { enabled: e.tools }
529
532
  };
530
533
  }
531
- function Oe(e) {
532
- return Ee(e) ?? De(e);
534
+ function Ae(e) {
535
+ return Oe(e) ?? ke(e);
533
536
  }
534
- function ke(e) {
535
- if (!K(e)) throw Error("Session Launch response is missing session.");
536
- let t = typeof e.id == "string" ? e.id.trim() : "", n = typeof e.experienceId == "string" ? e.experienceId.trim() : "", r = typeof e.experienceRevisionId == "string" ? e.experienceRevisionId.trim() : "", i = typeof e.expiresAt == "string" ? e.expiresAt.trim() : "", a = typeof e.locale == "string" ? e.locale.trim() : "", o = typeof e.secondaryLocale == "string" && e.secondaryLocale.trim() ? e.secondaryLocale.trim() : void 0, s = e.mode === "conversation" || e.mode === "presenter" ? e.mode : null, c = Oe(e.capabilities), l = J(e.localeVoiceFallbacks), u = e.status === "active" || e.status === "ended" ? e.status : void 0, d = typeof e.createdAt == "string" && e.createdAt.trim() ? e.createdAt.trim() : void 0;
537
+ function q(e) {
538
+ if (!G(e)) throw Error("Session Launch response is missing session.");
539
+ let t = typeof e.id == "string" ? e.id.trim() : "", n = typeof e.experienceId == "string" ? e.experienceId.trim() : "", r = typeof e.experienceRevisionId == "string" ? e.experienceRevisionId.trim() : "", i = typeof e.expiresAt == "string" ? e.expiresAt.trim() : "", a = typeof e.locale == "string" ? e.locale.trim() : "", o = typeof e.secondaryLocale == "string" && e.secondaryLocale.trim() ? e.secondaryLocale.trim() : void 0, s = e.mode === "conversation" || e.mode === "presenter" ? e.mode : null, c = Ae(e.capabilities), l = je(e.localeVoiceFallbacks), u = e.status === "active" || e.status === "ended" ? e.status : void 0, d = typeof e.createdAt == "string" && e.createdAt.trim() ? e.createdAt.trim() : void 0;
537
540
  if (!t || !n || !r || !i || !a || !s || !c) throw Error("Session Launch response has an invalid session object.");
538
541
  return {
539
542
  id: t,
@@ -549,11 +552,11 @@ function ke(e) {
549
552
  ...d ? { createdAt: d } : {}
550
553
  };
551
554
  }
552
- function J(e) {
555
+ function je(e) {
553
556
  if (!Array.isArray(e) || e.length === 0) return;
554
557
  let t = [];
555
558
  for (let n of e) {
556
- if (!K(n)) continue;
559
+ if (!G(n)) continue;
557
560
  let e = n.axis === "locale" || n.axis === "secondaryLocale" ? n.axis : null, r = typeof n.requested == "string" ? n.requested.trim() : "", i = typeof n.resolved == "string" ? n.resolved.trim() : "";
558
561
  !e || !r || !i || n.reason !== "voice_unsupported" || t.push({
559
562
  axis: e,
@@ -564,104 +567,104 @@ function J(e) {
564
567
  }
565
568
  return t.length > 0 ? t : void 0;
566
569
  }
567
- function Ae(e) {
570
+ function J(e) {
568
571
  let t = e.localeVoiceFallbacks;
569
572
  if (t?.length) for (let e of t) {
570
573
  let t = e.axis === "secondaryLocale" ? "secondaryLocale" : "locale";
571
574
  console.warn(`[liforma] Session ${t} fell back to ${e.resolved} because the voice does not support ${e.requested}.`);
572
575
  }
573
576
  }
574
- function je(e) {
575
- if (!K(e)) throw Error("Session Launch response must be a JSON object.");
577
+ function Me(e) {
578
+ if (!G(e)) throw Error("Session Launch response must be a JSON object.");
576
579
  let t = typeof e.launch == "string" ? e.launch.trim() : "";
577
580
  if (!t) throw Error("Session Launch response is missing launch.");
578
- let n = ke(e.session);
579
- return Ae(n), {
581
+ let n = q(e.session);
582
+ return J(n), {
580
583
  session: n,
581
584
  launch: t
582
585
  };
583
586
  }
584
587
  //#endregion
585
588
  //#region src/v2/api/mintPublicSession.ts
586
- function Me() {
589
+ function Ne() {
587
590
  try {
588
591
  if (typeof globalThis.location?.origin == "string" && globalThis.location.origin) return globalThis.location.origin;
589
592
  } catch {}
590
593
  }
591
- function Ne(e) {
594
+ function Pe(e) {
592
595
  return e ? e.trim().toUpperCase().replace(/-/g, "_") : "";
593
596
  }
594
- function Pe(e, t) {
595
- let n = Me(), r = Ne(t.code), i = t.message.trim(), a = t.details ?? {};
597
+ function Fe(e, t) {
598
+ let n = Ne(), r = Pe(t.code), i = t.message.trim(), a = t.details ?? {};
596
599
  if (r === "ORIGIN_NOT_ALLOWED" || /^Origin not allowed/i.test(i) && n) {
597
600
  if (i.includes(e) && i.includes("allowed origin")) return t;
598
601
  let r = typeof a.origin == "string" && a.origin || n || "(unknown origin)";
599
- return new U(`Your origin ${r} is not an allowed origin for experience ${e}. If you own this experience, sign in to the Liforma developer portal (app.liforma.ai), open Workspace → Settings → Origins, add ${r} to the list of allowed origins, and ensure “Allow public client-only embeds” is enabled.`, {
602
+ return new V(`Your origin ${r} is not an allowed origin for experience ${e}. If you own this experience, sign in to the Liforma developer portal (app.liforma.ai), open Workspace → Settings → Origins, add ${r} to the list of allowed origins, and ensure “Allow public client-only embeds” is enabled.`, {
600
603
  code: "ORIGIN_NOT_ALLOWED",
601
604
  requestId: t.requestId,
602
605
  status: t.status,
603
606
  details: a
604
607
  });
605
608
  }
606
- return r === "BROWSER_EMBEDS_DISABLED" || /^Browser embeds are not enabled/i.test(i) ? i.includes("Allow public client-only embeds") ? t : new U(`Browser embeds are not enabled for experience ${e}. If you own this experience, sign in to the Liforma developer portal (app.liforma.ai), open Workspace → Settings → Origins, and enable “Allow public client-only embeds”.`, {
609
+ return r === "BROWSER_EMBEDS_DISABLED" || /^Browser embeds are not enabled/i.test(i) ? i.includes("Allow public client-only embeds") ? t : new V(`Browser embeds are not enabled for experience ${e}. If you own this experience, sign in to the Liforma developer portal (app.liforma.ai), open Workspace → Settings → Origins, and enable “Allow public client-only embeds”.`, {
607
610
  code: "BROWSER_EMBEDS_DISABLED",
608
611
  requestId: t.requestId,
609
612
  status: t.status,
610
613
  details: a
611
- }) : r === "EXPERIENCE_UNAVAILABLE" || /^Experience is not available\.?$/i.test(i) || /^Unknown experience\.?$/i.test(i) ? i.includes("No playable experience found") ? t : new U(`No playable experience found for “${e}”. Check that the experience id is correct (it should look like exp_…), and that the experience exists and is published in the Liforma developer portal (app.liforma.ai). Deleted, archived, and unpublished experiences cannot be started from a browser embed.`, {
614
+ }) : r === "EXPERIENCE_UNAVAILABLE" || /^Experience is not available\.?$/i.test(i) || /^Unknown experience\.?$/i.test(i) ? i.includes("No playable experience found") ? t : new V(`No playable experience found for “${e}”. Check that the experience id is correct (it should look like exp_…), and that the experience exists and is published in the Liforma developer portal (app.liforma.ai). Deleted, archived, and unpublished experiences cannot be started from a browser embed.`, {
612
615
  code: "EXPERIENCE_UNAVAILABLE",
613
616
  requestId: t.requestId,
614
617
  status: t.status,
615
618
  details: a
616
619
  }) : t;
617
620
  }
618
- function Fe(e) {
621
+ function Ie(e) {
619
622
  let t = e?.locale?.trim();
620
623
  if (t) return t;
621
624
  let n = e?.language?.trim();
622
625
  if (n) return n;
623
626
  if (typeof navigator < "u" && navigator.language?.trim()) return navigator.language.trim();
624
627
  }
625
- function Ie(e) {
628
+ function Le(e) {
626
629
  let t = e?.secondaryLocale?.trim(), n = e?.learningLocale?.trim();
627
- if (t && n && t !== n) throw new U("secondaryLocale and learningLocale disagree; pass only one or make them equal.", { code: "INVALID_BODY" });
630
+ if (t && n && t !== n) throw new V("secondaryLocale and learningLocale disagree; pass only one or make them equal.", { code: "INVALID_BODY" });
628
631
  return t || n || void 0;
629
632
  }
630
- function Le(e, t) {
631
- let n = { experienceId: e }, r = Fe(t);
633
+ function Re(e, t) {
634
+ let n = { experienceId: e }, r = Ie(t);
632
635
  r && (n.locale = r);
633
- let i = Ie(t);
636
+ let i = Le(t);
634
637
  i && (n.secondaryLocale = i), t?.mode && (n.mode = t.mode), t?.speechInputMode && (n.speechInputMode = t.speechInputMode), t?.speechOnly !== void 0 && (n.speechOnly = t.speechOnly);
635
- let a = Se(t?.attribution);
638
+ let a = we(t?.attribution);
636
639
  return a && (n.attribution = a), t?.alreadyConverted?.length && (n.alreadyConverted = [...t.alreadyConverted]), n;
637
640
  }
638
- async function Re(e, t) {
639
- let n = H(), r = t?.idempotencyKey?.trim(), i = await fetch(`${n}/v1/browser-sessions`, {
641
+ async function ze(e, t) {
642
+ let n = B(), r = t?.idempotencyKey?.trim(), i = await fetch(`${n}/v1/browser-sessions`, {
640
643
  method: "POST",
641
644
  headers: {
642
645
  "Content-Type": "application/json",
643
646
  ...r ? { "Idempotency-Key": r } : {}
644
647
  },
645
- body: JSON.stringify(Le(e, t))
648
+ body: JSON.stringify(Re(e, t))
646
649
  });
647
650
  if (!i.ok) {
648
651
  let t = await i.text();
649
- throw Pe(e, ye(i.status, t, i.headers));
652
+ throw Fe(e, xe(i.status, t, i.headers));
650
653
  }
651
654
  let a;
652
655
  try {
653
656
  a = await i.json();
654
657
  } catch {
655
- throw new U("Browser session mint returned invalid JSON.", {
658
+ throw new V("Browser session mint returned invalid JSON.", {
656
659
  code: "INVALID_RESPONSE",
657
660
  status: i.status,
658
661
  requestId: i.headers.get("Liforma-Request-Id") ?? void 0
659
662
  });
660
663
  }
661
- return je(a);
664
+ return Me(a);
662
665
  }
663
- async function ze(e, t) {
664
- let n = Te(e, t), r = new AbortController(), i = () => r.abort(t.signal?.reason);
666
+ async function Be(e, t) {
667
+ let n = De(e, t), r = new AbortController(), i = () => r.abort(t.signal?.reason);
665
668
  t.signal?.aborted ? i() : t.signal?.addEventListener("abort", i, { once: !0 });
666
669
  let a = globalThis.setTimeout(() => r.abort(new DOMException("Session endpoint timed out.", "TimeoutError")), t.timeoutMs ?? 3e4), o;
667
670
  try {
@@ -674,9 +677,9 @@ async function ze(e, t) {
674
677
  }
675
678
  if (!o.ok) {
676
679
  let e = await o.text();
677
- throw ye(o.status, e, o.headers);
680
+ throw xe(o.status, e, o.headers);
678
681
  }
679
- if (!o.headers.get("content-type")?.toLowerCase().includes("application/json")) throw new U("Session endpoint must return a JSON Session Launch response.", {
682
+ if (!o.headers.get("content-type")?.toLowerCase().includes("application/json")) throw new V("Session endpoint must return a JSON Session Launch response.", {
680
683
  code: "INVALID_RESPONSE",
681
684
  status: o.status,
682
685
  requestId: o.headers.get("Liforma-Request-Id") ?? void 0
@@ -685,20 +688,20 @@ async function ze(e, t) {
685
688
  try {
686
689
  s = await o.json();
687
690
  } catch {
688
- throw new U("Session endpoint returned invalid JSON.", {
691
+ throw new V("Session endpoint returned invalid JSON.", {
689
692
  code: "INVALID_RESPONSE",
690
693
  status: o.status,
691
694
  requestId: o.headers.get("Liforma-Request-Id") ?? void 0
692
695
  });
693
696
  }
694
- return je(s);
697
+ return Me(s);
695
698
  }
696
699
  //#endregion
697
700
  //#region src/v2/conversationProcessor.ts
698
- function Be(e) {
701
+ function Ve(e) {
699
702
  return typeof e != "object" || !e ? !1 : typeof e[Symbol.asyncIterator] == "function";
700
703
  }
701
- function Ve(e) {
704
+ function He(e) {
702
705
  if (typeof e == "string") {
703
706
  let t = e.trim();
704
707
  if (!t) throw Error("conversationProcessor returned empty text.");
@@ -712,24 +715,24 @@ function Ve(e) {
712
715
  ...e.behavior ? { behavior: e.behavior } : {}
713
716
  };
714
717
  }
715
- async function He(e, t) {
718
+ async function Ue(e, t) {
716
719
  let n = await e(t);
717
- return Be(n) ? {
720
+ return Ve(n) ? {
718
721
  kind: "stream",
719
722
  stream: n
720
723
  } : {
721
724
  kind: "complete",
722
- speech: Ve(n)
725
+ speech: He(n)
723
726
  };
724
727
  }
725
728
  //#endregion
726
729
  //#region src/v2/embed/playerReachability.ts
727
- var Ue = "3002";
728
- function We(e) {
730
+ var We = "3002";
731
+ function Ge(e) {
729
732
  let t = new URL(e);
730
- return t.hostname === "localhost" || t.hostname === "127.0.0.1" ? `Cannot connect to the Liforma player at ${e} — nothing is listening on port ${t.port || Ue}. Start the player dev server in player.liforma.ai (npm run dev).` : `Cannot connect to the Liforma player at ${e}. The embed did not load; check your network connection and player URL configuration.`;
733
+ return t.hostname === "localhost" || t.hostname === "127.0.0.1" ? `Cannot connect to the Liforma player at ${e} — nothing is listening on port ${t.port || We}. Start the player dev server in player.liforma.ai (npm run dev).` : `Cannot connect to the Liforma player at ${e}. The embed did not load; check your network connection and player URL configuration.`;
731
734
  }
732
- async function Ge(e, t) {
735
+ async function Ke(e, t) {
733
736
  try {
734
737
  await fetch(e, {
735
738
  method: "GET",
@@ -737,25 +740,25 @@ async function Ge(e, t) {
737
740
  signal: AbortSignal.timeout(8e3)
738
741
  });
739
742
  } catch {
740
- throw Error(We(t));
743
+ throw Error(Ge(t));
741
744
  }
742
745
  }
743
- function Ke(e, t, n, r) {
746
+ function qe(e, t, n, r) {
744
747
  try {
745
748
  r && r.length > 0 ? e.postMessage(t, n, r) : e.postMessage(t, n);
746
749
  } catch (e) {
747
- throw e instanceof DOMException && e.name === "SecurityError" ? Error(We(n), { cause: e }) : e;
750
+ throw e instanceof DOMException && e.name === "SecurityError" ? Error(Ge(n), { cause: e }) : e;
748
751
  }
749
752
  }
750
- var qe = new Set([1, 2]);
751
- function Je(e) {
752
- return typeof e == "number" && qe.has(e);
753
+ var Je = new Set([1, 2]);
754
+ function Ye(e) {
755
+ return typeof e == "number" && Je.has(e);
753
756
  }
754
- var Ye = new Set(/* @__PURE__ */ "close.stateUpdate.commandResult.userTranscript.characterSpeechStarted.characterSpeechEnded.characterFocusChanged.conversationUpdate.listeningState.userSpeechStarted.userSpeechEnded.modeChange.activityChange.feedback.feedbackFailed.message.started.embedReady.widgetReady.widgetExpand.widgetCollapse.widgetAudioSettings.widgetDragStart.widgetDragMove.widgetDragEnd.fullWindow.theatre.interactionChange".split("."));
755
- function Xe(e) {
757
+ var Xe = new Set(/* @__PURE__ */ "close.stateUpdate.commandResult.userTranscript.characterSpeechStarted.characterSpeechEnded.characterFocusChanged.conversationUpdate.listeningState.userSpeechStarted.userSpeechEnded.modeChange.activityChange.feedback.feedbackFailed.message.started.embedReady.widgetReady.widgetExpand.widgetCollapse.widgetAudioSettings.widgetDragStart.widgetDragMove.widgetDragEnd.fullWindow.theatre.interactionChange".split("."));
758
+ function Ze(e) {
756
759
  if (!e || typeof e != "object") return null;
757
760
  let t = e;
758
- if (!Je(t.schemaVersion) || !t.type || !Ye.has(t.type)) return null;
761
+ if (!Ye(t.schemaVersion) || !t.type || !Xe.has(t.type)) return null;
759
762
  if (t.type === "embedReady" || t.type === "widgetReady" || t.type === "widgetExpand" || t.type === "widgetCollapse") return t;
760
763
  if (t.type === "fullWindow" || t.type === "theatre") {
761
764
  let e = t.payload;
@@ -778,10 +781,13 @@ function Xe(e) {
778
781
  let n = t.payload;
779
782
  return !n || typeof n != "object" ? null : t;
780
783
  }
781
- function Ze(e, t, n) {
784
+ function Qe(e, t) {
785
+ return t === void 0 ? {} : { [e]: t };
786
+ }
787
+ function $e(e, t, n) {
782
788
  let r = e.trim();
783
789
  if (!r) throw Error("createLaunchMessage requires a non-empty launch string.");
784
- let i = n?.startButton, a = n?.theme, o = n?.showFeedback, s = n?.interaction, c = n?.theatreButton, l = n?.theatre;
790
+ let i = n?.startButton, a = n?.theme, o = n?.showFeedback, s = n?.interaction, c = n?.theatre;
785
791
  return {
786
792
  type: "launch",
787
793
  schemaVersion: 2,
@@ -792,32 +798,34 @@ function Ze(e, t, n) {
792
798
  ...a ? { theme: a } : {},
793
799
  ...o === void 0 ? {} : { showFeedback: o },
794
800
  ...s ? { interaction: s } : {},
795
- ...c ? { theatreButton: !0 } : {},
796
- ...l === void 0 ? {} : { theatre: l }
801
+ ...Qe("settingsButton", n?.settingsButton),
802
+ ...Qe("theatreButton", n?.theatreButton),
803
+ ...Qe("fullscreenButton", n?.fullscreenButton),
804
+ ...c === void 0 ? {} : { theatre: c }
797
805
  }
798
806
  };
799
807
  }
800
- function Qe() {
808
+ function et() {
801
809
  return {
802
810
  type: "parentHello",
803
811
  schemaVersion: 2
804
812
  };
805
813
  }
806
- function $e(e) {
814
+ function tt(e) {
807
815
  return {
808
816
  type: "widgetSetChrome",
809
817
  schemaVersion: 2,
810
818
  payload: { mode: e }
811
819
  };
812
820
  }
813
- function et() {
821
+ function nt() {
814
822
  return {
815
823
  type: "widgetToggleAudioSettings",
816
824
  schemaVersion: 2,
817
825
  payload: {}
818
826
  };
819
827
  }
820
- function tt(e) {
828
+ function rt(e) {
821
829
  return {
822
830
  type: "setTheatre",
823
831
  schemaVersion: 2,
@@ -826,8 +834,8 @@ function tt(e) {
826
834
  }
827
835
  //#endregion
828
836
  //#region src/v2/embed/fullWindowHost.ts
829
- var nt = "2147483000";
830
- function rt(e) {
837
+ var it = "2147483000";
838
+ function at(e) {
831
839
  let { style: t } = e;
832
840
  return {
833
841
  position: t.position,
@@ -845,11 +853,11 @@ function rt(e) {
845
853
  maxHeight: t.maxHeight
846
854
  };
847
855
  }
848
- function it(e) {
856
+ function ot(e) {
849
857
  let { style: t } = e;
850
- t.position = "fixed", t.top = "0", t.right = "0", t.bottom = "0", t.left = "0", t.inset = "0", t.width = "100vw", t.width = "100dvw", t.height = "100vh", t.height = "100dvh", t.zIndex = nt, t.margin = "0", t.borderRadius = "0", t.maxWidth = "none", t.maxHeight = "none", e.dataset.liformaFullWindow = "1";
858
+ t.position = "fixed", t.top = "0", t.right = "0", t.bottom = "0", t.left = "0", t.inset = "0", t.width = "100vw", t.width = "100dvw", t.height = "100vh", t.height = "100dvh", t.zIndex = it, t.margin = "0", t.borderRadius = "0", t.maxWidth = "none", t.maxHeight = "none", e.dataset.liformaFullWindow = "1";
851
859
  }
852
- function at(e, t) {
860
+ function st(e, t) {
853
861
  if (delete e.dataset.liformaFullWindow, !t) {
854
862
  e.style.position = "", e.style.top = "", e.style.right = "", e.style.bottom = "", e.style.left = "", e.style.inset = "", e.style.width = "", e.style.height = "", e.style.zIndex = "", e.style.margin = "", e.style.borderRadius = "", e.style.maxWidth = "", e.style.maxHeight = "";
855
863
  return;
@@ -859,20 +867,20 @@ function at(e, t) {
859
867
  }
860
868
  //#endregion
861
869
  //#region src/v2/embed/iframeHost.ts
862
- function ot(e) {
870
+ function ct(e) {
863
871
  return e;
864
872
  }
865
873
  function Y() {
866
874
  return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? `cmd_${crypto.randomUUID().replace(/-/g, "").slice(0, 12)}` : `cmd_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
867
875
  }
868
- var st = 3e4;
869
- function ct(e) {
876
+ var lt = 3e4;
877
+ function ut(e) {
870
878
  let t = e.container;
871
879
  getComputedStyle(t).position === "static" && (t.style.position = "relative");
872
880
  let n = document.createElement("iframe");
873
- n.src = e.src, n.title = "Liforma experience", n.setAttribute("allow", "microphone; autoplay; clipboard-read; clipboard-write; fullscreen"), n.setAttribute("allowfullscreen", ""), n.style.cssText = e.transparent ? "display:block;position:absolute;inset:0;width:100%;height:100%;border:0;background:transparent;" : "display:block;position:absolute;inset:0;width:100%;height:100%;border:0;background:#030508;", e.transparent && n.setAttribute("allowtransparency", "true");
881
+ n.src = e.src, n.title = "Liforma experience", n.setAttribute("allow", "microphone; autoplay; clipboard-read; clipboard-write; fullscreen"), n.setAttribute("allowfullscreen", ""), n.style.cssText = e.transparent ? "display:block;position:absolute;inset:0;width:100%;height:100%;border:0;background:transparent;" : "display:block;position:absolute;inset:0;width:100%;height:100%;border:0;background:#030508;", e.transparent && n.setAttribute("allowtransparency", "true"), n.setAttribute("fetchpriority", "high"), "fetchPriority" in n && (n.fetchPriority = "high");
874
882
  let r = !1, i = !1, a = null, o = null, s = (r) => {
875
- i !== r && (i = r, r ? (a = rt(n), o = document.body.style.overflow, document.body.append(n), it(n), document.body.style.overflow = "hidden") : (t.append(n), at(n, a), a = null, o !== null && (document.body.style.overflow = o, o = null)), e.onFullWindowChange?.(r));
883
+ i !== r && (i = r, r ? (a = at(n), o = document.body.style.overflow, document.body.append(n), ot(n), document.body.style.overflow = "hidden") : (t.append(n), st(n, a), a = null, o !== null && (document.body.style.overflow = o, o = null)), e.onFullWindowChange?.(r));
876
884
  }, c = /* @__PURE__ */ new Map(), l = null, u = 0, d = 0, f = [], p = null, m = null, h = new Promise((e, t) => {
877
885
  p = e, m = t;
878
886
  }), g = () => {
@@ -883,10 +891,10 @@ function ct(e) {
883
891
  let i = Date.now();
884
892
  if (d > 0 && i - d < 250) return;
885
893
  d = i, g();
886
- let a = Ze(t.launch, t.session, t.chrome), o = () => {
894
+ let a = $e(t.launch, t.session, t.chrome), o = () => {
887
895
  if (r) return;
888
896
  let t = n.contentWindow;
889
- t && Ke(t, a, e.playerOrigin);
897
+ t && qe(t, a, e.playerOrigin);
890
898
  };
891
899
  o();
892
900
  for (let e = 1; e <= 12; e += 1) f.push(window.setTimeout(o, e * 75));
@@ -894,17 +902,17 @@ function ct(e) {
894
902
  r || !l || _(l);
895
903
  }, y = () => {
896
904
  if (u += 1, u === 1) {
897
- Ge(e.src, e.playerOrigin).then(() => p?.(), (e) => m?.(e instanceof Error ? e : Error(String(e))));
905
+ Ke(e.src, e.playerOrigin).then(() => p?.(), (e) => m?.(e instanceof Error ? e : Error(String(e))));
898
906
  return;
899
907
  }
900
908
  d = 0, v();
901
909
  }, b = () => {
902
- u > 0 || m?.(Error(We(e.playerOrigin)));
910
+ u > 0 || m?.(Error(Ge(e.playerOrigin)));
903
911
  };
904
912
  n.addEventListener("load", y), n.addEventListener("error", b);
905
913
  let x = (t) => {
906
914
  if (r || t.source !== n.contentWindow || t.origin !== e.playerOrigin) return;
907
- let i = Xe(t.data);
915
+ let i = Ze(t.data);
908
916
  if (i) switch (i.type) {
909
917
  case "close":
910
918
  e.onClose?.(i.payload);
@@ -943,7 +951,7 @@ function ct(e) {
943
951
  e.onUserSpeechEnded?.(i.payload);
944
952
  break;
945
953
  case "modeChange":
946
- e.onActivityChange?.(ot(i.payload.mode));
954
+ e.onActivityChange?.(ct(i.payload.mode));
947
955
  break;
948
956
  case "activityChange":
949
957
  e.onActivityChange?.(i.payload.activity);
@@ -1002,8 +1010,8 @@ function ct(e) {
1002
1010
  let S = (t, i) => {
1003
1011
  if (r) return;
1004
1012
  let a = n.contentWindow;
1005
- if (!a) throw Error(We(e.playerOrigin));
1006
- Ke(a, t, e.playerOrigin, i);
1013
+ if (!a) throw Error(Ge(e.playerOrigin));
1014
+ qe(a, t, e.playerOrigin, i);
1007
1015
  }, C = (e, t = 12e4, n) => {
1008
1016
  let r = e.type !== "parentHello" && e.payload && "correlationId" in e.payload ? e.payload.correlationId : Y();
1009
1017
  return e.type !== "parentHello" && e.payload && "correlationId" in e.payload || e.type !== "parentHello" && e.payload && (e.payload.correlationId = r), new Promise((i, a) => {
@@ -1020,7 +1028,7 @@ function ct(e) {
1020
1028
  return h;
1021
1029
  },
1022
1030
  postParentHello() {
1023
- S(Qe());
1031
+ S(et());
1024
1032
  },
1025
1033
  postLaunch(e, t, n) {
1026
1034
  r || (l = {
@@ -1042,13 +1050,13 @@ function ct(e) {
1042
1050
  throw Error("postManifest is deprecated; use postLaunch with an opaque launch string from SessionLaunchResponse.");
1043
1051
  },
1044
1052
  postWidgetSetChrome(e) {
1045
- S($e(e));
1053
+ S(tt(e));
1046
1054
  },
1047
1055
  postWidgetToggleAudioSettings() {
1048
- S(et());
1056
+ S(nt());
1049
1057
  },
1050
1058
  postSetTheatre(e) {
1051
- S(tt(e));
1059
+ S(rt(e));
1052
1060
  },
1053
1061
  speak(e) {
1054
1062
  return C({
@@ -1170,7 +1178,7 @@ function ct(e) {
1170
1178
  audio: e.audio,
1171
1179
  byteLength: e.byteLength
1172
1180
  }
1173
- }, st, [e.audio]);
1181
+ }, lt, [e.audio]);
1174
1182
  },
1175
1183
  speechUtteranceSetTranscript(e) {
1176
1184
  return C({
@@ -1332,7 +1340,7 @@ function ct(e) {
1332
1340
  }
1333
1341
  //#endregion
1334
1342
  //#region src/v2/embed/readyGate.ts
1335
- function lt(e) {
1343
+ function dt(e) {
1336
1344
  let t, n = !1, r = !1, i = () => {
1337
1345
  r || !n || t === void 0 || (r = !0, e(t));
1338
1346
  };
@@ -1347,9 +1355,9 @@ function lt(e) {
1347
1355
  }
1348
1356
  //#endregion
1349
1357
  //#region src/v2/sdkRelease.ts
1350
- var ut = `sdk@${{
1358
+ var ft = `sdk@${{
1351
1359
  name: "@liforma/client",
1352
- version: "0.4.13",
1360
+ version: "0.4.15",
1353
1361
  type: "module",
1354
1362
  description: "Liforma browser SDK — Experience sessions, speech API, and Svelte embed component.",
1355
1363
  license: "MIT",
@@ -1510,6 +1518,8 @@ var ut = `sdk@${{
1510
1518
  "generate:location-discontinuities": "node scripts/generate-location-discontinuities.mjs",
1511
1519
  "build:locations": "node scripts/build-locations.mjs",
1512
1520
  "publish:locations": "node scripts/publish-locations.mjs",
1521
+ "publish:location-400x225": "node scripts/build-location-400x225.mjs",
1522
+ "test:location-400x225": "node scripts/test-location-400x225.mjs",
1513
1523
  "verify:locations": "node scripts/verify-location-sources.mjs",
1514
1524
  "publish:models": "node scripts/publish-models.mjs",
1515
1525
  "publish:models:krea-int8": "node scripts/_upload-model-prefix.mjs text-to-image/lf-t2i-turbo-int8",
@@ -1539,6 +1549,7 @@ var ut = `sdk@${{
1539
1549
  "preview:test": "npm run build && npm run preview"
1540
1550
  },
1541
1551
  dependencies: {
1552
+ "@jsquash/avif": "^1.3.0",
1542
1553
  "@jsquash/webp": "^1.5.0",
1543
1554
  zod: "^4.4.3"
1544
1555
  },
@@ -1568,50 +1579,54 @@ var ut = `sdk@${{
1568
1579
  vitest: "^4.1.10",
1569
1580
  wrangler: "^4.101.0"
1570
1581
  }
1571
- }.version}`, dt = "https://player.liforma.ai/embed", ft = "http://localhost:3002/embed";
1572
- function pt() {
1582
+ }.version}`, pt = "https://player.liforma.ai/embed", mt = "http://localhost:3002/embed";
1583
+ function ht() {
1573
1584
  let e = globalThis.__LIFORMA_PLAYER_EMBED_URL;
1574
1585
  if (e?.trim()) return e.trim().replace(/\/$/, "");
1575
1586
  if (typeof document > "u") return null;
1576
1587
  let t = (document.querySelector("script[data-liforma-sdk][src*=\"client.js\"]") ?? document.querySelector("script[src*=\"/sdk/v2/client.js\"]"))?.getAttribute("data-player-embed-url")?.trim();
1577
1588
  return t ? t.replace(/\/$/, "") : null;
1578
1589
  }
1579
- function mt() {
1580
- let e = pt();
1581
- return e ? e.endsWith("/embed") ? e : `${e}/embed` : y() ? ft : dt;
1590
+ function gt() {
1591
+ let e = ht();
1592
+ return e ? e.endsWith("/embed") ? e : `${e}/embed` : y() ? mt : pt;
1582
1593
  }
1583
- function ht(e, t) {
1594
+ function _t(e, t) {
1584
1595
  return e?.trim() || t?.trim() || void 0;
1585
1596
  }
1586
- function gt(e, t, n, r, i, a, o, s, c, l, u) {
1587
- let d = (e ?? mt()).replace(/\/$/, ""), f = d.endsWith("/embed") ? d : `${d}/embed`, p = new URL(f), m = n?.trim();
1588
- m && p.searchParams.set("backdropId", m);
1589
- let h = r?.trim();
1590
- return h && p.searchParams.set("avatarId", h), (i === "face" || i === "medium") && p.searchParams.set("fit", i), c === "pip" && p.searchParams.set("stage", "pip"), l === "set" && p.searchParams.set("pipBackground", "set"), u === !1 && p.searchParams.set("pipShadow", "0"), a === "widget" && p.searchParams.set("ui", "widget"), o && p.searchParams.set("close", "1"), t && p.searchParams.set("debug", "true"), (s === 2 || s === 3 || s === 4) && p.searchParams.set("cast", String(s)), _t(p.toString());
1591
- }
1592
- function _t(e) {
1597
+ function vt(e, t, n, r, i, a, o, s, c, l, u, d, f) {
1598
+ let p = (e ?? gt()).replace(/\/$/, ""), m = p.endsWith("/embed") ? p : `${p}/embed`, h = new URL(m), g = n?.trim();
1599
+ g && h.searchParams.set("backdropId", g);
1600
+ let _ = r?.trim();
1601
+ _ && h.searchParams.set("avatarId", _);
1602
+ let v = d?.trim();
1603
+ v && h.searchParams.set("previewBg", v);
1604
+ let y = f?.trim();
1605
+ return y && h.searchParams.set("previewFg", y), (i === "face" || i === "medium") && h.searchParams.set("fit", i), c === "pip" && h.searchParams.set("stage", "pip"), l === "set" && h.searchParams.set("pipBackground", "set"), u === !1 && h.searchParams.set("pipShadow", "0"), a === "widget" && h.searchParams.set("ui", "widget"), o && h.searchParams.set("close", "1"), t && h.searchParams.set("debug", "true"), (s === 2 || s === 3 || s === 4) && h.searchParams.set("cast", String(s)), yt(h.toString());
1606
+ }
1607
+ function yt(e) {
1593
1608
  if (typeof location > "u") return e;
1594
1609
  let t = new URL(e);
1595
1610
  return t.searchParams.set("parentOrigin", location.origin), t.toString();
1596
1611
  }
1597
- function vt(e) {
1612
+ function bt(e) {
1598
1613
  return new URL(e).origin;
1599
1614
  }
1600
1615
  //#endregion
1601
1616
  //#region src/v2/experienceEvents.ts
1602
- function yt() {
1617
+ function xt() {
1603
1618
  return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? `evt_${crypto.randomUUID().replace(/-/g, "").slice(0, 12)}` : `evt_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
1604
1619
  }
1605
- function bt(e, t, n) {
1620
+ function St(e, t, n) {
1606
1621
  return {
1607
- id: yt(),
1622
+ id: xt(),
1608
1623
  type: e,
1609
1624
  sessionId: t,
1610
1625
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1611
1626
  data: n
1612
1627
  };
1613
1628
  }
1614
- function xt() {
1629
+ function Ct() {
1615
1630
  return {
1616
1631
  ready: /* @__PURE__ */ new Set(),
1617
1632
  started: /* @__PURE__ */ new Set(),
@@ -1632,32 +1647,32 @@ function xt() {
1632
1647
  conversationProcessorError: /* @__PURE__ */ new Set()
1633
1648
  };
1634
1649
  }
1635
- function St(e, t, n) {
1650
+ function wt(e, t, n) {
1636
1651
  return e[t].add(n), () => e[t].delete(n);
1637
1652
  }
1638
- function Ct(e, t, n) {
1653
+ function Tt(e, t, n) {
1639
1654
  for (let r of e[t]) r(n);
1640
1655
  }
1641
- function wt(e) {
1656
+ function Et(e) {
1642
1657
  for (let t of Object.keys(e)) e[t].clear();
1643
1658
  }
1644
1659
  //#endregion
1645
1660
  //#region src/v2/speech/types.ts
1646
- function Tt(e) {
1661
+ function Dt(e) {
1647
1662
  return "data" in e && "format" in e && e.format != null && !("track" in e);
1648
1663
  }
1649
- function Et(e) {
1664
+ function Ot(e) {
1650
1665
  return "url" in e && typeof e.url == "string";
1651
1666
  }
1652
- function Dt(e) {
1667
+ function kt(e) {
1653
1668
  if (!("track" in e)) return !1;
1654
1669
  let t = e.track;
1655
1670
  return typeof t != "object" || !t ? !1 : typeof MediaStreamTrack < "u" && t instanceof MediaStreamTrack ? !0 : "kind" in t && "readyState" in t;
1656
1671
  }
1657
- function Ot(e) {
1658
- return !Tt(e) && !Et(e) && !Dt(e) && "encoding" in e && typeof e.encoding == "string";
1672
+ function At(e) {
1673
+ return !Dt(e) && !Ot(e) && !kt(e) && "encoding" in e && typeof e.encoding == "string";
1659
1674
  }
1660
- var kt = [
1675
+ var jt = [
1661
1676
  8e3,
1662
1677
  16e3,
1663
1678
  22050,
@@ -1675,14 +1690,14 @@ var kt = [
1675
1690
  MAX_UTTERANCE_DURATION_MS: 9e4,
1676
1691
  MAX_PENDING_WRITES: 8,
1677
1692
  DEFAULT_WRITE_TIMEOUT_MS: 5e3
1678
- }, At = class extends Error {
1693
+ }, Mt = class extends Error {
1679
1694
  operation;
1680
1695
  requiredCapability;
1681
1696
  name = "UnsupportedSpeechOperationError";
1682
1697
  constructor(e, t) {
1683
1698
  super(`Speech operation "${e}" requires capability "${t}".`), this.operation = e, this.requiredCapability = t;
1684
1699
  }
1685
- }, jt = class extends Error {
1700
+ }, Nt = class extends Error {
1686
1701
  name = "SpeechUtteranceClosedError";
1687
1702
  constructor(e = "Cannot write to a closed or cancelled speech utterance.") {
1688
1703
  super(e);
@@ -1692,72 +1707,72 @@ var kt = [
1692
1707
  constructor(e, t) {
1693
1708
  super(e, t);
1694
1709
  }
1695
- }, Mt = class extends Error {
1710
+ }, Pt = class extends Error {
1696
1711
  name = "SpeechBufferTimeoutError";
1697
1712
  constructor(e = "Timed out waiting for speech buffer capacity.") {
1698
1713
  super(e);
1699
1714
  }
1700
1715
  };
1701
- function Nt(e = "none") {
1716
+ function Ft(e = "none") {
1702
1717
  return {
1703
1718
  mode: e,
1704
1719
  trackedDurationMs: 0,
1705
1720
  fallbackDurationMs: 0
1706
1721
  };
1707
1722
  }
1708
- function Pt(e) {
1709
- return kt.includes(e);
1723
+ function It(e) {
1724
+ return jt.includes(e);
1710
1725
  }
1711
- function Ft(e) {
1726
+ function Lt(e) {
1712
1727
  if (e.encoding !== "pcm_s16le") throw new Z(`Unsupported audio encoding: ${e.encoding}`);
1713
1728
  if (e.channels !== 1) throw new Z(`Unsupported channel count: ${e.channels}`);
1714
- if (!Pt(e.sampleRate)) throw new Z(`Unsupported sample rate: ${e.sampleRate}`);
1729
+ if (!It(e.sampleRate)) throw new Z(`Unsupported sample rate: ${e.sampleRate}`);
1715
1730
  }
1716
- function It(e) {
1717
- if (Tt(e)) {
1718
- Ft(e.format);
1731
+ function Rt(e) {
1732
+ if (Dt(e)) {
1733
+ Lt(e.format);
1719
1734
  return;
1720
1735
  }
1721
- if (Et(e)) {
1736
+ if (Ot(e)) {
1722
1737
  if (!e.url.trim()) throw new Z("Audio URL must be non-empty.");
1723
- if (e.sampleRate !== void 0 && !Pt(e.sampleRate)) throw new Z(`Unsupported sample rate: ${e.sampleRate}`);
1738
+ if (e.sampleRate !== void 0 && !It(e.sampleRate)) throw new Z(`Unsupported sample rate: ${e.sampleRate}`);
1724
1739
  return;
1725
1740
  }
1726
- if (Dt(e)) {
1741
+ if (kt(e)) {
1727
1742
  if (e.track.kind !== "audio") throw new Z("speech.play track must be an audio MediaStreamTrack.");
1728
- if (e.sampleRate !== void 0 && !Pt(e.sampleRate)) throw new Z(`Unsupported sample rate: ${e.sampleRate}`);
1743
+ if (e.sampleRate !== void 0 && !It(e.sampleRate)) throw new Z(`Unsupported sample rate: ${e.sampleRate}`);
1729
1744
  return;
1730
1745
  }
1731
- if (Ot(e)) {
1746
+ if (At(e)) {
1732
1747
  let t = e.encoding.trim().toLowerCase();
1733
1748
  if (!t) throw new Z("Encoded audio MIME type is required.");
1734
1749
  if (t === "pcm_s16le") throw new Z("Use format: { encoding: \"pcm_s16le\", … } for raw PCM.");
1735
- if (e.sampleRate !== void 0 && !Pt(e.sampleRate)) throw new Z(`Unsupported sample rate: ${e.sampleRate}`);
1750
+ if (e.sampleRate !== void 0 && !It(e.sampleRate)) throw new Z(`Unsupported sample rate: ${e.sampleRate}`);
1736
1751
  return;
1737
1752
  }
1738
1753
  throw new Z("Unsupported speech.play audio shape.");
1739
1754
  }
1740
- function Lt(e) {
1741
- if (e.format) return Ft(e.format), e.format;
1755
+ function zt(e) {
1756
+ if (e.format) return Lt(e.format), e.format;
1742
1757
  if (e.track) {
1743
1758
  let t = {
1744
1759
  encoding: "pcm_s16le",
1745
1760
  sampleRate: e.sampleRate ?? 24e3,
1746
1761
  channels: 1
1747
1762
  };
1748
- return Ft(t), t;
1763
+ return Lt(t), t;
1749
1764
  }
1750
1765
  throw new Z("createUtterance requires format or track.");
1751
1766
  }
1752
- function Rt(e) {
1767
+ function Bt(e) {
1753
1768
  return e instanceof Uint8Array ? e : new Uint8Array(e);
1754
1769
  }
1755
- function zt(e) {
1770
+ function Vt(e) {
1756
1771
  return e === "replace-active" || e === "replace-all" ? "interrupt" : "enqueue";
1757
1772
  }
1758
1773
  //#endregion
1759
1774
  //#region src/byo/pcm.ts
1760
- function Bt(e) {
1775
+ function Ht(e) {
1761
1776
  let t = new Uint8Array(e.length * 2), n = new DataView(t.buffer);
1762
1777
  for (let t = 0; t < e.length; t++) {
1763
1778
  let r = Math.max(-1, Math.min(1, e[t]));
@@ -1767,11 +1782,11 @@ function Bt(e) {
1767
1782
  }
1768
1783
  //#endregion
1769
1784
  //#region src/byo/resample.ts
1770
- function Vt(e, t, n, r, i) {
1785
+ function Ut(e, t, n, r, i) {
1771
1786
  let a = -.5 * e + 1.5 * t - 1.5 * n + .5 * r, o = e - 2.5 * t + 2 * n - .5 * r, s = -.5 * e + .5 * n, c = t;
1772
1787
  return ((a * i + o) * i + s) * i + c;
1773
1788
  }
1774
- function Ht(e, t) {
1789
+ function Wt(e, t) {
1775
1790
  if (!(e > 0) || !(t > 0)) throw Error("Resampler rates must be positive");
1776
1791
  if (e === t) return {
1777
1792
  fromRate: e,
@@ -1794,7 +1809,7 @@ function Ht(e, t) {
1794
1809
  let a = [];
1795
1810
  for (; i + 2 < r.length - 1;) {
1796
1811
  let e = Math.floor(i), t = i - e, o = Math.max(0, e - 1), s = Math.min(r.length - 1, e + 1), c = Math.min(r.length - 1, e + 2);
1797
- a.push(Vt(r[o], r[e], r[s], r[c], t)), i += n;
1812
+ a.push(Ut(r[o], r[e], r[s], r[c], t)), i += n;
1798
1813
  }
1799
1814
  let o = Math.max(0, Math.floor(i) - 1);
1800
1815
  return o > 0 && (r = r.subarray(o), i -= o), a.length ? Float32Array.from(a) : new Float32Array();
@@ -1806,7 +1821,7 @@ function Ht(e, t) {
1806
1821
  }
1807
1822
  //#endregion
1808
1823
  //#region src/byo/audioCapture.ts
1809
- var Ut = "liforma-pcm-capture", Wt = `
1824
+ var Gt = "liforma-pcm-capture", Kt = `
1810
1825
  class LiformaPcmCaptureProcessor extends AudioWorkletProcessor {
1811
1826
  process(inputs) {
1812
1827
  const ch = inputs[0] && inputs[0][0];
@@ -1818,29 +1833,29 @@ class LiformaPcmCaptureProcessor extends AudioWorkletProcessor {
1818
1833
  return true;
1819
1834
  }
1820
1835
  }
1821
- registerProcessor('${Ut}', LiformaPcmCaptureProcessor);
1822
- `, Gt = null;
1823
- function Kt() {
1824
- return Gt ||= URL.createObjectURL(new Blob([Wt], { type: "application/javascript" })), Gt;
1836
+ registerProcessor('${Gt}', LiformaPcmCaptureProcessor);
1837
+ `, qt = null;
1838
+ function Jt() {
1839
+ return qt ||= URL.createObjectURL(new Blob([Kt], { type: "application/javascript" })), qt;
1825
1840
  }
1826
- function qt() {
1841
+ function Yt() {
1827
1842
  return window.AudioContext || window.webkitAudioContext || null;
1828
1843
  }
1829
- async function Jt(e) {
1830
- let { mediaStream: t, targetSampleRate: n, onPcm: r, shouldSend: i, onLog: a } = e, o = qt();
1844
+ async function Xt(e) {
1845
+ let { mediaStream: t, targetSampleRate: n, onPcm: r, shouldSend: i, onLog: a } = e, o = Yt();
1831
1846
  if (!o) throw Error("Web Audio is required for audio capture");
1832
1847
  let s = new o(), c = s.createMediaStreamSource(t), l = s.createGain();
1833
1848
  l.gain.value = 0;
1834
- let u = s.sampleRate, d = Ht(u, n), f = !1, p = !1, m = (e) => {
1849
+ let u = s.sampleRate, d = Wt(u, n), f = !1, p = !1, m = (e) => {
1835
1850
  if (f || i && !i()) return;
1836
1851
  let t = d.push(e);
1837
- t.length !== 0 && r(Bt(t));
1852
+ t.length !== 0 && r(Ht(t));
1838
1853
  }, h = () => void 0;
1839
1854
  return await (async () => {
1840
1855
  if (typeof s.audioWorklet?.addModule != "function") return !1;
1841
1856
  try {
1842
- await s.audioWorklet.addModule(Kt());
1843
- let e = new AudioWorkletNode(s, Ut, {
1857
+ await s.audioWorklet.addModule(Jt());
1858
+ let e = new AudioWorkletNode(s, Gt, {
1844
1859
  numberOfInputs: 1,
1845
1860
  numberOfOutputs: 1,
1846
1861
  outputChannelCount: [1]
@@ -1890,7 +1905,7 @@ async function Jt(e) {
1890
1905
  }
1891
1906
  //#endregion
1892
1907
  //#region src/v2/speech/captureMediaStreamTrack.ts
1893
- async function Yt(e) {
1908
+ async function Zt(e) {
1894
1909
  let { track: t, utterance: n, sampleRate: r, signal: i } = e;
1895
1910
  if (typeof MediaStreamTrack > "u" || !(t instanceof MediaStreamTrack)) throw new Z("MediaStreamTrack is not available in this environment.");
1896
1911
  if (t.kind !== "audio") throw new Z("speech.play track must be an audio MediaStreamTrack.");
@@ -1899,13 +1914,13 @@ async function Yt(e) {
1899
1914
  s || (s = !0, c?.stop(), c = null);
1900
1915
  };
1901
1916
  try {
1902
- c = await Jt({
1917
+ c = await Xt({
1903
1918
  mediaStream: a,
1904
1919
  targetSampleRate: r,
1905
1920
  shouldSend: () => !s && !i?.aborted,
1906
1921
  onPcm: (e) => {
1907
1922
  if (s || i?.aborted) return;
1908
- let t = Rt(e);
1923
+ let t = Bt(e);
1909
1924
  o = o.then(async () => {
1910
1925
  if (s || i?.aborted) return;
1911
1926
  let e = 0;
@@ -1934,10 +1949,10 @@ async function Yt(e) {
1934
1949
  }
1935
1950
  //#endregion
1936
1951
  //#region src/v2/speech/speechController.ts
1937
- async function Xt(e, t) {
1938
- if (Dt(e)) throw new Z("MediaStreamTrack play is handled on the host before embed.");
1939
- if (Tt(e)) {
1940
- let t = Rt(e.data);
1952
+ async function Qt(e, t) {
1953
+ if (kt(e)) throw new Z("MediaStreamTrack play is handled on the host before embed.");
1954
+ if (Dt(e)) {
1955
+ let t = Bt(e.data);
1941
1956
  if (t.byteLength & 1) throw new Z("PCM byte length must be even.");
1942
1957
  return {
1943
1958
  kind: "pcm",
@@ -1945,17 +1960,17 @@ async function Xt(e, t) {
1945
1960
  format: e.format
1946
1961
  };
1947
1962
  }
1948
- if (Et(e)) return {
1963
+ if (Ot(e)) return {
1949
1964
  kind: "url",
1950
1965
  url: e.url.trim(),
1951
1966
  ...e.sampleRate === void 0 ? {} : { sampleRate: e.sampleRate }
1952
1967
  };
1953
- if (!Ot(e)) throw new Z("Unsupported speech.play audio shape.");
1968
+ if (!At(e)) throw new Z("Unsupported speech.play audio shape.");
1954
1969
  let n;
1955
1970
  if (typeof Blob < "u" && e.data instanceof Blob) {
1956
1971
  if (t?.aborted) throw new DOMException("Play aborted.", "AbortError");
1957
1972
  n = new Uint8Array(await e.data.arrayBuffer());
1958
- } else n = Rt(e.data);
1973
+ } else n = Bt(e.data);
1959
1974
  return {
1960
1975
  kind: "encoded",
1961
1976
  data: n.slice().buffer,
@@ -1963,10 +1978,10 @@ async function Xt(e, t) {
1963
1978
  ...e.sampleRate === void 0 ? {} : { sampleRate: e.sampleRate }
1964
1979
  };
1965
1980
  }
1966
- function Zt() {
1981
+ function $t() {
1967
1982
  return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? `utt_${crypto.randomUUID().replace(/-/g, "").slice(0, 12)}` : `utt_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
1968
1983
  }
1969
- function Qt(e, t = "completed") {
1984
+ function en(e, t = "completed") {
1970
1985
  return {
1971
1986
  utteranceId: e.speechId,
1972
1987
  characterId: e.characterId,
@@ -1980,13 +1995,13 @@ function Qt(e, t = "completed") {
1980
1995
  }
1981
1996
  };
1982
1997
  }
1983
- function $t(e) {
1998
+ function tn(e) {
1984
1999
  return e instanceof Error ? e : new Z(String(e));
1985
2000
  }
1986
- function en(e) {
2001
+ function nn(e) {
1987
2002
  return e instanceof DOMException && e.name === "AbortError" || e instanceof Error && e.name === "AbortError";
1988
2003
  }
1989
- var tn = class {
2004
+ var rn = class {
1990
2005
  id;
1991
2006
  characterId;
1992
2007
  result;
@@ -2015,14 +2030,14 @@ var tn = class {
2015
2030
  queue: e.queue,
2016
2031
  ...e.transcript === void 0 ? {} : { transcript: e.transcript }
2017
2032
  }).catch((e) => {
2018
- throw this.fail($t(e)), $t(e);
2033
+ throw this.fail(tn(e)), tn(e);
2019
2034
  }), this.signal?.addEventListener("abort", () => {
2020
2035
  this.cancel();
2021
2036
  }, { once: !0 });
2022
2037
  }
2023
2038
  async write(e, t) {
2024
- if (this.closed || this.settled || (await this.beginPromise.catch(() => void 0), this.closed || this.settled)) throw new jt();
2025
- let n = Rt(e);
2039
+ if (this.closed || this.settled || (await this.beginPromise.catch(() => void 0), this.closed || this.settled)) throw new Nt();
2040
+ let n = Bt(e);
2026
2041
  if (n.byteLength & 1) throw new Z("PCM chunk byte length must be even (complete s16 samples).");
2027
2042
  if (n.byteLength > X.MAX_CHUNK_BYTES) throw new Z(`PCM chunk exceeds MAX_CHUNK_BYTES (${X.MAX_CHUNK_BYTES}).`);
2028
2043
  if (n.byteLength === 0) return;
@@ -2031,13 +2046,13 @@ var tn = class {
2031
2046
  let i = n.byteLength / 2 / this.sampleRate * 1e3;
2032
2047
  if (this.bufferedMs + i > X.MAX_UTTERANCE_DURATION_MS) throw this.releaseWriteSlot(), new Z("Utterance exceeds MAX_UTTERANCE_DURATION_MS.");
2033
2048
  let a = async () => {
2034
- if (this.closed || this.settled) throw new jt();
2049
+ if (this.closed || this.settled) throw new Nt();
2035
2050
  let e = this.requireHost(), t = n.slice(), i = e.speechUtteranceWrite({
2036
2051
  utteranceId: this.id,
2037
2052
  audio: t.buffer,
2038
2053
  byteLength: t.byteLength
2039
2054
  }), a = await Promise.race([i, new Promise((e, t) => {
2040
- setTimeout(() => t(new Mt()), r);
2055
+ setTimeout(() => t(new Pt()), r);
2041
2056
  })]);
2042
2057
  this.bufferedMs = Math.max(0, a.bufferedMs);
2043
2058
  }, o = this.writeChain.then(a, a);
@@ -2049,7 +2064,7 @@ var tn = class {
2049
2064
  }
2050
2065
  }
2051
2066
  async setTranscript(e) {
2052
- if (this.closed || this.settled || (await this.beginPromise.catch(() => void 0), this.closed || this.settled)) throw new jt();
2067
+ if (this.closed || this.settled || (await this.beginPromise.catch(() => void 0), this.closed || this.settled)) throw new Nt();
2053
2068
  await this.requireHost().speechUtteranceSetTranscript({
2054
2069
  utteranceId: this.id,
2055
2070
  transcript: e
@@ -2066,7 +2081,7 @@ var tn = class {
2066
2081
  });
2067
2082
  return this.resolve(t), t;
2068
2083
  } catch (e) {
2069
- let t = $t(e);
2084
+ let t = tn(e);
2070
2085
  throw this.fail(t), t;
2071
2086
  }
2072
2087
  }
@@ -2084,11 +2099,11 @@ var tn = class {
2084
2099
  characterId: this.characterId,
2085
2100
  status: "cancelled",
2086
2101
  durationMs: 0,
2087
- animation: Nt("none")
2102
+ animation: Ft("none")
2088
2103
  };
2089
2104
  return this.resolve(t), t;
2090
2105
  } catch (e) {
2091
- let t = $t(e);
2106
+ let t = tn(e);
2092
2107
  throw this.fail(t), t;
2093
2108
  }
2094
2109
  }
@@ -2101,7 +2116,7 @@ var tn = class {
2101
2116
  return e;
2102
2117
  }
2103
2118
  resolve(e) {
2104
- this.settled || (this.settled = !0, this.settleResolve(Object.freeze(e)), this.flushWriteWaiters(new jt()));
2119
+ this.settled || (this.settled = !0, this.settleResolve(Object.freeze(e)), this.flushWriteWaiters(new Nt()));
2105
2120
  }
2106
2121
  fail(e) {
2107
2122
  this.settled || (this.settled = !0, this.settleReject(e), this.flushWriteWaiters(e));
@@ -2113,7 +2128,7 @@ var tn = class {
2113
2128
  }
2114
2129
  await new Promise((t, n) => {
2115
2130
  let r = setTimeout(() => {
2116
- n(new Mt());
2131
+ n(new Pt());
2117
2132
  }, e);
2118
2133
  this.pendingWriteWaiters.push({
2119
2134
  resolve: () => {
@@ -2132,13 +2147,13 @@ var tn = class {
2132
2147
  for (; this.pendingWriteWaiters.length > 0;) this.pendingWriteWaiters.shift()?.reject(e);
2133
2148
  }
2134
2149
  };
2135
- function nn(e) {
2150
+ function an(e) {
2136
2151
  let t = null, n = (t, n) => {
2137
- if (!e.getCapabilities()[n]) throw new At(t, n);
2152
+ if (!e.getCapabilities()[n]) throw new Mt(t, n);
2138
2153
  }, r = {
2139
2154
  async speak(r) {
2140
2155
  if (e.assertSessionStarted(), n("speak", "textSpeech"), r.signal?.aborted) throw new DOMException("Speak aborted.", "AbortError");
2141
- let i = zt(r.queue ?? "append");
2156
+ let i = Vt(r.queue ?? "append");
2142
2157
  i === "interrupt" && (e.onProcessorInterrupt?.(), t &&= (t.cancel(), null));
2143
2158
  let a = e.getIframeHost();
2144
2159
  if (!a) throw new Z("Speech session is not attached.");
@@ -2158,41 +2173,41 @@ function nn(e) {
2158
2173
  return;
2159
2174
  }
2160
2175
  t.addEventListener("abort", s, { once: !0 }), o.then((e) => {
2161
- t.removeEventListener("abort", s), n(Qt(e, "completed"));
2176
+ t.removeEventListener("abort", s), n(en(e, "completed"));
2162
2177
  }, (a) => {
2163
- if (t.removeEventListener("abort", s), en(a)) {
2178
+ if (t.removeEventListener("abort", s), nn(a)) {
2164
2179
  n({
2165
2180
  utteranceId: "utt_interrupted",
2166
2181
  characterId: r.characterId ?? e.getActiveCharacterId(),
2167
2182
  status: "interrupted",
2168
2183
  durationMs: 0,
2169
2184
  transcript: r.text,
2170
- animation: Nt("none")
2185
+ animation: Ft("none")
2171
2186
  });
2172
2187
  return;
2173
2188
  }
2174
- i($t(a));
2189
+ i(tn(a));
2175
2190
  });
2176
2191
  });
2177
2192
  }
2178
2193
  try {
2179
- return Qt(await o, "completed");
2194
+ return en(await o, "completed");
2180
2195
  } catch (t) {
2181
- if (en(t)) return {
2196
+ if (nn(t)) return {
2182
2197
  utteranceId: "utt_interrupted",
2183
2198
  characterId: r.characterId ?? e.getActiveCharacterId(),
2184
2199
  status: "interrupted",
2185
2200
  durationMs: 0,
2186
2201
  transcript: r.text,
2187
- animation: Nt("none")
2202
+ animation: Ft("none")
2188
2203
  };
2189
- throw $t(t);
2204
+ throw tn(t);
2190
2205
  }
2191
2206
  },
2192
2207
  async play(i) {
2193
- if (e.assertSessionStarted(), n("play", "externalSpeechAudio"), It(i.audio), i.signal?.aborted) throw new DOMException("Play aborted.", "AbortError");
2208
+ if (e.assertSessionStarted(), n("play", "externalSpeechAudio"), Rt(i.audio), i.signal?.aborted) throw new DOMException("Play aborted.", "AbortError");
2194
2209
  let a = i.queue ?? "append";
2195
- if ((a === "replace-active" || a === "replace-all") && (e.onProcessorInterrupt?.(), t &&= (t.cancel(), null)), Dt(i.audio)) {
2210
+ if ((a === "replace-active" || a === "replace-all") && (e.onProcessorInterrupt?.(), t &&= (t.cancel(), null)), kt(i.audio)) {
2196
2211
  let e = i.audio.sampleRate ?? 24e3;
2197
2212
  return r.createUtterance({
2198
2213
  format: {
@@ -2208,7 +2223,7 @@ function nn(e) {
2208
2223
  }
2209
2224
  let o = e.getIframeHost();
2210
2225
  if (!o) throw new Z("Speech session is not attached.");
2211
- let s = await Xt(i.audio, i.signal);
2226
+ let s = await Qt(i.audio, i.signal);
2212
2227
  return o.speechPlay({
2213
2228
  source: s,
2214
2229
  characterId: i.characterId,
@@ -2220,13 +2235,13 @@ function nn(e) {
2220
2235
  },
2221
2236
  createUtterance(r) {
2222
2237
  e.assertSessionStarted(), n("createUtterance", "externalSpeechAudio");
2223
- let i = Lt(r);
2238
+ let i = zt(r);
2224
2239
  if (r.track && r.track.kind !== "audio") throw new Z("createUtterance track must be an audio MediaStreamTrack.");
2225
2240
  let a = r.queue ?? "replace-active";
2226
2241
  if (a !== "replace-active" && a !== "replace-all") throw new Z("createUtterance queue must be replace-active or replace-all.");
2227
2242
  e.onProcessorInterrupt?.(), t &&= (t.cancel(), null);
2228
- let o = new tn({
2229
- id: Zt(),
2243
+ let o = new rn({
2244
+ id: $t(),
2230
2245
  characterId: r.characterId ?? e.getActiveCharacterId(),
2231
2246
  format: i,
2232
2247
  queue: a,
@@ -2238,7 +2253,7 @@ function nn(e) {
2238
2253
  t === o && (t = null);
2239
2254
  }), r.track && (async () => {
2240
2255
  try {
2241
- if (await Yt({
2256
+ if (await Zt({
2242
2257
  track: r.track,
2243
2258
  utterance: o,
2244
2259
  sampleRate: i.sampleRate,
@@ -2266,16 +2281,16 @@ function nn(e) {
2266
2281
  }
2267
2282
  //#endregion
2268
2283
  //#region src/v2/types/sessionInteraction.ts
2269
- function rn(e) {
2284
+ function on(e) {
2270
2285
  let t = e?.trim();
2271
2286
  return t === "full" || t === "face" || t === "medium" ? t : void 0;
2272
2287
  }
2273
2288
  //#endregion
2274
2289
  //#region src/v2/experience.ts
2275
- function an(e) {
2290
+ function sn(e) {
2276
2291
  return !!(e.showClose === !0 || e.returnUrl?.trim() || e.closeButton === !0 || e.closeButton && typeof e.closeButton == "object" && e.closeButton.visible !== !1);
2277
2292
  }
2278
- var on = class e {
2293
+ var cn = class e {
2279
2294
  bootstrap;
2280
2295
  conversationProcessor;
2281
2296
  iframeHost = null;
@@ -2295,17 +2310,17 @@ var on = class e {
2295
2310
  pendingTheatre = null;
2296
2311
  lastInteraction = null;
2297
2312
  closeHandlers = [];
2298
- eventRegistry = xt();
2313
+ eventRegistry = Ct();
2299
2314
  readyEnvelope = null;
2300
2315
  startedEnvelope = null;
2301
2316
  sessionMintedEnvelope = null;
2302
2317
  conversationCache = [];
2303
2318
  speech;
2304
2319
  constructor(e) {
2305
- this.bootstrap = e, this.conversationProcessor = e.conversationProcessor ?? null, this.resolvedSession = e.kind === "launch" ? e.session ?? null : null, this.launchToken = e.kind === "launch" ? e.launch : null, this.speech = nn({
2320
+ this.bootstrap = e, this.conversationProcessor = e.conversationProcessor ?? null, this.resolvedSession = e.kind === "launch" ? e.session ?? null : null, this.launchToken = e.kind === "launch" ? e.launch : null, this.speech = an({
2306
2321
  getIframeHost: () => this.iframeHost,
2307
2322
  assertSessionStarted: () => this.assertSessionStarted(),
2308
- getCapabilities: () => sn(this.resolvedSession),
2323
+ getCapabilities: () => ln(this.resolvedSession),
2309
2324
  getActiveCharacterId: () => "character_unknown",
2310
2325
  onProcessorInterrupt: () => {
2311
2326
  this.processorAbortController?.abort(), this.processorAbortController = null;
@@ -2326,6 +2341,8 @@ var on = class e {
2326
2341
  embedBaseUrl: t.embedBaseUrl,
2327
2342
  debug: t.debug,
2328
2343
  speechOnly: t.speechOnly,
2344
+ previewBackground: t.previewBackground,
2345
+ previewForeground: t.previewForeground,
2329
2346
  ui: t.ui,
2330
2347
  onStart: t.onStart,
2331
2348
  onUserTranscript: t.onUserTranscript,
@@ -2349,6 +2366,8 @@ var on = class e {
2349
2366
  mode: t.mode,
2350
2367
  speechInputMode: t.speechInputMode,
2351
2368
  speechOnly: t.speechOnly,
2369
+ previewBackground: t.previewBackground,
2370
+ previewForeground: t.previewForeground,
2352
2371
  attribution: t.attribution,
2353
2372
  alreadyConverted: t.alreadyConverted,
2354
2373
  ui: t.ui,
@@ -2372,6 +2391,8 @@ var on = class e {
2372
2391
  mode: t.mode,
2373
2392
  speechInputMode: t.speechInputMode,
2374
2393
  speechOnly: t.speechOnly,
2394
+ previewBackground: t.previewBackground,
2395
+ previewForeground: t.previewForeground,
2375
2396
  attribution: t.attribution,
2376
2397
  alreadyConverted: t.alreadyConverted,
2377
2398
  ui: t.ui,
@@ -2388,7 +2409,7 @@ var on = class e {
2388
2409
  return null;
2389
2410
  }
2390
2411
  on(e, t) {
2391
- let n = St(this.eventRegistry, e, t);
2412
+ let n = wt(this.eventRegistry, e, t);
2392
2413
  return e === "ready" && this.readyEnvelope && queueMicrotask(() => t(this.readyEnvelope)), e === "started" && this.startedEnvelope && queueMicrotask(() => t(this.startedEnvelope)), e === "sessionMinted" && this.sessionMintedEnvelope && queueMicrotask(() => t(this.sessionMintedEnvelope)), n;
2393
2414
  }
2394
2415
  async attach(e) {
@@ -2402,13 +2423,13 @@ var on = class e {
2402
2423
  if (this.closed) throw Error("Session has ended.");
2403
2424
  if (this.attached && this.iframeHost) return this.createPlayerFacade();
2404
2425
  this.iframeHost &&= (this.iframeHost.destroy(), null), this.attachReturnUrl = e.returnUrl?.trim() || null;
2405
- let t = this.bootstrap.embedBaseUrl ?? mt(), n = this.bootstrap.debug === !0, r = this.bootstrap.speechOnly === !0, i = gt(t, n, r ? void 0 : ht(this.bootstrap.backdropId, this.bootstrap.locationId), r ? void 0 : this.bootstrap.avatarId, e.fit, this.bootstrap.ui, an(e), this.bootstrap.kind === "launch" ? void 0 : this.bootstrap.castSize, e.stage, e.pipBackground, e.pipShadow), a = vt(i), o = null, s = new Promise((e) => {
2426
+ let t = this.bootstrap.embedBaseUrl ?? gt(), n = this.bootstrap.debug === !0, r = this.bootstrap.speechOnly === !0, i = vt(t, n, r ? void 0 : _t(this.bootstrap.backdropId, this.bootstrap.locationId), r ? void 0 : this.bootstrap.avatarId, e.fit, this.bootstrap.ui, sn(e), this.bootstrap.kind === "launch" ? void 0 : this.bootstrap.castSize, e.stage, e.pipBackground, e.pipShadow, r ? void 0 : this.bootstrap.previewBackground, r ? void 0 : this.bootstrap.previewForeground), a = bt(i), o = null, s = new Promise((e) => {
2406
2427
  o = e;
2407
2428
  }), c = null, l = new Promise((e) => {
2408
2429
  c = e;
2409
- }), u = lt((e) => {
2430
+ }), u = dt((e) => {
2410
2431
  this.readyEnvelope ||= (this.resolvedSession = e, this.emitWrapped("ready", { session: e }));
2411
- }), d = this.bootstrap.onUserTranscript, f = ct({
2432
+ }), d = this.bootstrap.onUserTranscript, f = ut({
2412
2433
  container: e.container,
2413
2434
  src: i,
2414
2435
  playerOrigin: a,
@@ -2475,7 +2496,7 @@ var on = class e {
2475
2496
  onTheatreChange: (t) => e.onTheatreChange?.(t)
2476
2497
  });
2477
2498
  this.iframeHost = f;
2478
- let p = this.resolveMintInteraction(), m = this.bootstrap.kind === "sessionEndpoint" ? (this.endpointAbortController = new AbortController(), ze(this.bootstrap.sessionEndpoint, {
2499
+ let p = this.resolveMintInteraction(), m = this.bootstrap.kind === "sessionEndpoint" ? (this.endpointAbortController = new AbortController(), Be(this.bootstrap.sessionEndpoint, {
2479
2500
  experienceId: this.bootstrap.experienceId,
2480
2501
  locale: this.bootstrap.locale,
2481
2502
  secondaryLocale: this.bootstrap.secondaryLocale,
@@ -2487,7 +2508,7 @@ var on = class e {
2487
2508
  attribution: this.bootstrap.attribution,
2488
2509
  alreadyConverted: this.bootstrap.alreadyConverted,
2489
2510
  signal: this.endpointAbortController.signal
2490
- })) : this.bootstrap.kind === "public" ? Re(this.bootstrap.experienceId, {
2511
+ })) : this.bootstrap.kind === "public" ? ze(this.bootstrap.experienceId, {
2491
2512
  locale: this.bootstrap.locale,
2492
2513
  secondaryLocale: this.bootstrap.secondaryLocale,
2493
2514
  learningLocale: this.bootstrap.learningLocale,
@@ -2511,7 +2532,7 @@ var on = class e {
2511
2532
  operation: "attach",
2512
2533
  message: e instanceof Error ? e.message : String(e),
2513
2534
  stack: e instanceof Error ? e.stack : void 0,
2514
- release: ut
2535
+ release: ft
2515
2536
  });
2516
2537
  } catch {}
2517
2538
  throw f.destroy(), this.iframeHost === f && (this.iframeHost = null), e;
@@ -2523,19 +2544,23 @@ var on = class e {
2523
2544
  if (!g) throw f.destroy(), this.iframeHost === f && (this.iframeHost = null), Error("Session Launch response did not include a launch token.");
2524
2545
  this.launchToken = g;
2525
2546
  let v = _ ?? (this.bootstrap.kind === "launch" ? this.bootstrap.session : void 0);
2526
- return v && !this.sessionMintedEnvelope && (this.resolvedSession = v, this.sessionMintedEnvelope = this.emitWrapped("sessionMinted", { session: v })), _ ? (this.resolvedSession = _, this.bootstrap.kind === "launch" && Ae(_), f.postLaunch(g, _, {
2547
+ return v && !this.sessionMintedEnvelope && (this.resolvedSession = v, this.sessionMintedEnvelope = this.emitWrapped("sessionMinted", { session: v })), _ ? (this.resolvedSession = _, this.bootstrap.kind === "launch" && J(_), f.postLaunch(g, _, {
2527
2548
  startButton: e.startButton,
2528
2549
  theme: e.theme,
2529
2550
  showFeedback: e.showFeedback,
2530
2551
  interaction: e.interaction,
2531
- ...e.theatreButton ? { theatreButton: !0 } : {},
2552
+ ...W("settingsButton", e.settingsButton),
2553
+ ...W("theatreButton", e.theatreButton),
2554
+ ...W("fullscreenButton", e.fullscreenButton),
2532
2555
  ...e.theatre === void 0 ? {} : { theatre: e.theatre }
2533
2556
  }), u.setValue(_)) : f.postLaunch(g, void 0, {
2534
2557
  startButton: e.startButton,
2535
2558
  theme: e.theme,
2536
2559
  showFeedback: e.showFeedback,
2537
2560
  interaction: e.interaction,
2538
- ...e.theatreButton ? { theatreButton: !0 } : {},
2561
+ ...W("settingsButton", e.settingsButton),
2562
+ ...W("theatreButton", e.theatreButton),
2563
+ ...W("fullscreenButton", e.fullscreenButton),
2539
2564
  ...e.theatre === void 0 ? {} : { theatre: e.theatre }
2540
2565
  }), await Promise.race([s, new Promise((e, t) => {
2541
2566
  setTimeout(() => t(/* @__PURE__ */ Error("Timed out waiting for player loading UI.")), 12e4);
@@ -2547,7 +2572,7 @@ var on = class e {
2547
2572
  operation: "attach",
2548
2573
  message: e instanceof Error ? e.message : String(e),
2549
2574
  stack: e instanceof Error ? e.stack : void 0,
2550
- release: ut
2575
+ release: ft
2551
2576
  });
2552
2577
  } catch {}
2553
2578
  throw e;
@@ -2561,7 +2586,7 @@ var on = class e {
2561
2586
  operation: "attach",
2562
2587
  message: e instanceof Error ? e.message : String(e),
2563
2588
  stack: e instanceof Error ? e.stack : void 0,
2564
- release: ut
2589
+ release: ft
2565
2590
  });
2566
2591
  } catch {}
2567
2592
  throw e;
@@ -2593,7 +2618,7 @@ var on = class e {
2593
2618
  this.assertSessionStarted(), await this.iframeHost.focusCharacter(e);
2594
2619
  }
2595
2620
  async setFit(e) {
2596
- let t = rn(e);
2621
+ let t = on(e);
2597
2622
  if (!t) throw Error("setFit requires \"full\", \"medium\", or \"face\".");
2598
2623
  if (this.closed) throw Error("Session has ended.");
2599
2624
  this.pendingFit = t, !(!this.attached || !this.iframeHost) && await this.iframeHost.setFit(t);
@@ -2643,7 +2668,7 @@ var on = class e {
2643
2668
  this.close();
2644
2669
  }
2645
2670
  destroy() {
2646
- this.closed || (this.closed = !0, this.processorAbortController?.abort(), this.processorAbortController = null, this.endpointAbortController?.abort(), this.endpointAbortController = null, this.attachInFlight = null, this.iframeHost?.destroy(), this.iframeHost = null, wt(this.eventRegistry), this.readyEnvelope = null, this.startedEnvelope = null, this.closeHandlers.length = 0, this.lastInteraction = null, this.attached = !1);
2671
+ this.closed || (this.closed = !0, this.processorAbortController?.abort(), this.processorAbortController = null, this.endpointAbortController?.abort(), this.endpointAbortController = null, this.attachInFlight = null, this.iframeHost?.destroy(), this.iframeHost = null, Et(this.eventRegistry), this.readyEnvelope = null, this.startedEnvelope = null, this.closeHandlers.length = 0, this.lastInteraction = null, this.attached = !1);
2647
2672
  }
2648
2673
  resolveMintInteraction() {
2649
2674
  return this.bootstrap.kind === "launch" ? {} : {
@@ -2655,8 +2680,8 @@ var on = class e {
2655
2680
  return this.resolvedSession?.id ?? "";
2656
2681
  }
2657
2682
  emitWrapped(e, t) {
2658
- let n = bt(e, this.getSessionId(), t);
2659
- return Ct(this.eventRegistry, e, n), n;
2683
+ let n = St(e, this.getSessionId(), t);
2684
+ return Tt(this.eventRegistry, e, n), n;
2660
2685
  }
2661
2686
  queueProcessorTurn(e) {
2662
2687
  if (!e.isFinal || !e.text.trim() || !this.conversationProcessor) return;
@@ -2665,7 +2690,7 @@ var on = class e {
2665
2690
  let n = this.processorAbortController.signal;
2666
2691
  this.processorChain = this.processorChain.then(async () => {
2667
2692
  if (!n.aborted) try {
2668
- let r = await He(t, {
2693
+ let r = await Ue(t, {
2669
2694
  utteranceId: e.utteranceId,
2670
2695
  text: e.text,
2671
2696
  conversation: this.conversationCache,
@@ -2715,7 +2740,7 @@ var on = class e {
2715
2740
  };
2716
2741
  }
2717
2742
  };
2718
- function sn(e) {
2743
+ function ln(e) {
2719
2744
  return e ? {
2720
2745
  textSpeech: e.capabilities.speech.output,
2721
2746
  externalSpeechAudio: e.capabilities.speech.externalAudio
@@ -2726,26 +2751,26 @@ function sn(e) {
2726
2751
  }
2727
2752
  //#endregion
2728
2753
  //#region src/widget/dockGeometry.ts
2729
- var cn = "(min-width: 768px)", ln = 24, un = .5, dn = 1200, fn = .85, pn = 9 / 16;
2730
- function mn() {
2754
+ var un = "(min-width: 768px)", dn = 24, fn = .5, pn = 1200, mn = .85, hn = 9 / 16;
2755
+ function gn() {
2731
2756
  if (typeof window > "u") return 800;
2732
2757
  let e = window.screen?.availHeight;
2733
2758
  return typeof e == "number" && e > 0 ? e : window.innerHeight;
2734
2759
  }
2735
- function hn(e = typeof window < "u" ? window.innerWidth : 1280, t = typeof window < "u" ? window.innerHeight : 800, n = ln, r = typeof window < "u" ? mn() : 800) {
2736
- let i = Math.max(160, Math.min(t - n * 2, t * fn)), a = Math.max(120, e - n * 2), o = Math.min(r * un, dn, i), s = o * pn;
2737
- return s > a && (s = a, o = s / pn, o > i && (o = i, s = o * pn)), {
2760
+ function _n(e = typeof window < "u" ? window.innerWidth : 1280, t = typeof window < "u" ? window.innerHeight : 800, n = dn, r = typeof window < "u" ? gn() : 800) {
2761
+ let i = Math.max(160, Math.min(t - n * 2, t * mn)), a = Math.max(120, e - n * 2), o = Math.min(r * fn, pn, i), s = o * hn;
2762
+ return s > a && (s = a, o = s / hn, o > i && (o = i, s = o * hn)), {
2738
2763
  width: Math.round(s),
2739
2764
  height: Math.round(o)
2740
2765
  };
2741
2766
  }
2742
- function gn(e, t = typeof window < "u" ? window.innerWidth : 1280, n = typeof window < "u" ? window.innerHeight : 800, r = ln) {
2767
+ function vn(e, t = typeof window < "u" ? window.innerWidth : 1280, n = typeof window < "u" ? window.innerHeight : 800, r = dn) {
2743
2768
  return {
2744
2769
  left: Math.max(r, t - e.width - r),
2745
2770
  top: Math.max(r, n - e.height - r)
2746
2771
  };
2747
2772
  }
2748
- function _n(e, t, n, r = typeof window < "u" ? window.innerWidth : 1280, i = typeof window < "u" ? window.innerHeight : 800, a = ln) {
2773
+ function yn(e, t, n, r = typeof window < "u" ? window.innerWidth : 1280, i = typeof window < "u" ? window.innerHeight : 800, a = dn) {
2749
2774
  let o = Math.max(a, r - n.width - a), s = Math.max(a, i - n.height - a);
2750
2775
  return {
2751
2776
  left: Math.min(Math.max(a, e), o),
@@ -2753,14 +2778,14 @@ function _n(e, t, n, r = typeof window < "u" ? window.innerWidth : 1280, i = typ
2753
2778
  };
2754
2779
  }
2755
2780
  function Q(e = typeof window < "u" ? window.matchMedia.bind(window) : () => ({ matches: !0 })) {
2756
- return e(cn).matches;
2781
+ return e(un).matches;
2757
2782
  }
2758
2783
  //#endregion
2759
2784
  //#region src/widget/mountExperienceWidget.ts
2760
- function vn(e) {
2785
+ function bn(e) {
2761
2786
  return e === "bottom-right" || e === "bottom-left" ? e : "static";
2762
2787
  }
2763
- function yn(e) {
2788
+ function xn(e) {
2764
2789
  if (typeof e == "number" && Number.isFinite(e)) return `${e}px`;
2765
2790
  let t = typeof e == "string" ? e.trim() : "";
2766
2791
  return t ? /^\d+(\.\d+)?$/.test(t) ? `${t}px` : t : "16px";
@@ -2768,9 +2793,9 @@ function yn(e) {
2768
2793
  function $(e) {
2769
2794
  return e === "expanded" || e === "docked";
2770
2795
  }
2771
- var bn = "<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 0 0-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 0 0-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 0 0-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 0 0-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 0 0 1.066-2.573c-.94-1.543.826-3.31 2.37-2.37c1 .608 2.296.07 2.572-1.065\"/><path d=\"M9 12a3 3 0 1 0 6 0a3 3 0 0 0-6 0\"/></svg>", xn = "<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"><path fill=\"currentColor\" d=\"M18.3 5.71a1 1 0 0 0-1.41 0L12 10.59 7.11 5.7A1 1 0 0 0 5.7 7.11L10.59 12l-4.9 4.89a1 1 0 1 0 1.42 1.42L12 13.41l4.89 4.9a1 1 0 0 0 1.42-1.42L13.41 12l4.9-4.89a1 1 0 0 0-.01-1.4Z\"/></svg>", Sn = "<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 10h-4V6m6-2l-6 6m-8 4h4v4m0-4l-6 6\"/></svg>", Cn = "<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M16 4h4v4m-6 2l6-6M8 20H4v-4m0 4l6-6\"/></svg>";
2772
- function wn(e, t, n) {
2773
- V(ce);
2796
+ var Sn = "<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 0 0-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 0 0-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 0 0-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 0 0-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 0 0 1.066-2.573c-.94-1.543.826-3.31 2.37-2.37c1 .608 2.296.07 2.572-1.065\"/><path d=\"M9 12a3 3 0 1 0 6 0a3 3 0 0 0-6 0\"/></svg>", Cn = "<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"><path fill=\"currentColor\" d=\"M18.3 5.71a1 1 0 0 0-1.41 0L12 10.59 7.11 5.7A1 1 0 0 0 5.7 7.11L10.59 12l-4.9 4.89a1 1 0 1 0 1.42 1.42L12 13.41l4.89 4.9a1 1 0 0 0 1.42-1.42L13.41 12l4.9-4.89a1 1 0 0 0-.01-1.4Z\"/></svg>", wn = "<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 10h-4V6m6-2l-6 6m-8 4h4v4m0-4l-6 6\"/></svg>", Tn = "<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M16 4h4v4m-6 2l6-6M8 20H4v-4m0 4l6-6\"/></svg>";
2797
+ function En(e, t, n) {
2798
+ z(ue);
2774
2799
  let r = v({
2775
2800
  galleryThumb: t.galleryThumb,
2776
2801
  avatarImage: t.avatarImage,
@@ -2797,9 +2822,9 @@ function wn(e, t, n) {
2797
2822
  let e = document.createElement("img");
2798
2823
  e.className = "liforma-et__foreground liforma-et__media", e.alt = "", e.decoding = "async", e.src = r.foregroundImage, e.addEventListener("load", () => o(e), { once: !0 }), i.append(e);
2799
2824
  }
2800
- return e.replaceChildren(i), n?.parallax === !1 ? () => {} : se(i);
2825
+ return e.replaceChildren(i), n?.parallax === !1 ? () => {} : le(i);
2801
2826
  }
2802
- function Tn(e) {
2827
+ function Dn(e) {
2803
2828
  return e.startButton ? {
2804
2829
  ...e.startButton,
2805
2830
  label: e.startButton.label ?? e.startButtonLabel ?? "Tap to talk",
@@ -2811,7 +2836,7 @@ function Tn(e) {
2811
2836
  variant: "primary"
2812
2837
  };
2813
2838
  }
2814
- function En(e) {
2839
+ function On(e) {
2815
2840
  let t = !1, n = () => {
2816
2841
  t || e();
2817
2842
  }, r = () => {
@@ -2831,12 +2856,12 @@ function En(e) {
2831
2856
  t = !0, window.removeEventListener("load", r), i?.();
2832
2857
  };
2833
2858
  }
2834
- function Dn(e, t) {
2835
- fe(ue);
2859
+ function kn(e, t) {
2860
+ me(fe);
2836
2861
  let n = t.experienceId?.trim();
2837
2862
  if (!n) throw Error("ExperienceWidget requires experienceId.");
2838
- let r = t.prefetch ?? "onExpand", i = vn(t.position), a = document.createElement("div");
2839
- a.className = "liforma-ew", a.dataset.state = "collapsed", a.dataset.prefetch = r, a.dataset.position = i, a.style.setProperty("--liforma-ew-max-w", t.expandedMaxWidth ?? "100%"), a.style.setProperty("--liforma-ew-max-h", t.expandedMaxHeight ?? "100%"), i !== "static" && a.style.setProperty("--liforma-ew-offset", yn(t.offset));
2863
+ let r = t.prefetch ?? "onExpand", i = bn(t.position), a = document.createElement("div");
2864
+ a.className = "liforma-ew", a.dataset.state = "collapsed", a.dataset.prefetch = r, a.dataset.position = i, a.style.setProperty("--liforma-ew-max-w", t.expandedMaxWidth ?? "100%"), a.style.setProperty("--liforma-ew-max-h", t.expandedMaxHeight ?? "100%"), i !== "static" && a.style.setProperty("--liforma-ew-offset", xn(t.offset));
2840
2865
  let o = document.createElement("button");
2841
2866
  o.type = "button", o.className = "liforma-ew__hit", o.setAttribute("aria-label", t.alt), o.disabled = !0;
2842
2867
  let s = document.createElement("div");
@@ -2856,138 +2881,138 @@ function Dn(e, t) {
2856
2881
  let m = document.createElement("span");
2857
2882
  m.className = "liforma-ew__drag-grip", m.setAttribute("aria-hidden", "true");
2858
2883
  let h = document.createElement("button");
2859
- h.type = "button", h.className = "liforma-ew__icon-btn liforma-ew__dock-toggle", h.innerHTML = Sn, h.setAttribute("aria-label", "Reduce");
2884
+ h.type = "button", h.className = "liforma-ew__icon-btn liforma-ew__dock-toggle", h.innerHTML = wn, h.setAttribute("aria-label", "Reduce");
2860
2885
  let g = document.createElement("button");
2861
- g.type = "button", g.className = "liforma-ew__icon-btn liforma-ew__settings", g.innerHTML = bn, g.setAttribute("aria-label", "Audio settings"), g.setAttribute("aria-pressed", "false");
2886
+ g.type = "button", g.className = "liforma-ew__icon-btn liforma-ew__settings", g.innerHTML = Sn, g.setAttribute("aria-label", "Audio settings"), g.setAttribute("aria-pressed", "false");
2862
2887
  let _ = document.createElement("button");
2863
- _.type = "button", _.className = "liforma-ew__icon-btn liforma-ew__close", _.innerHTML = xn, _.setAttribute("aria-label", "Close"), p.append(m, h, g, _);
2888
+ _.type = "button", _.className = "liforma-ew__icon-btn liforma-ew__close", _.innerHTML = Cn, _.setAttribute("aria-label", "Close"), p.append(m, h, g, _);
2864
2889
  let v = document.createElement("div");
2865
2890
  v.className = "liforma-ew__stage";
2866
2891
  let y = document.createElement("div");
2867
2892
  y.className = "liforma-ew__status", y.hidden = !0, f.append(v, y), u.append(d, f), a.append(o, l, u, p), e.replaceChildren(a);
2868
- let b = null, x = !1, S = !1, C = !1, w = !1, T = !1, E = !1, D = !1, O = 0, ee = "", k = null, te = null, A = null, j = null, M = null, N = null, P = null, ne = 0, re = 0, F = null, I = !1, L = new AbortController(), R = t.parallax !== !1, z = () => {
2893
+ let b = null, x = !1, S = !1, C = !1, w = !1, T = !1, E = !1, D = !1, O = 0, ee = "", te = null, ne = null, re = null, k = null, A = null, j = null, M = null, ie = 0, ae = 0, N = null, P = !1, F = new AbortController(), I = t.parallax !== !1, L = () => {
2869
2894
  let e = a.dataset.state;
2870
2895
  return e === "expanded" || e === "docked" || e === "collapsed" ? e : "collapsed";
2871
- }, B = () => {
2872
- A !== null && (clearTimeout(A), A = null);
2873
- }, ie = () => {
2874
- j !== null && (clearTimeout(j), j = null), a.classList.remove("liforma-ew--layout-settling");
2875
- }, ae = () => {
2896
+ }, R = () => {
2897
+ re !== null && (clearTimeout(re), re = null);
2898
+ }, oe = () => {
2899
+ k !== null && (clearTimeout(k), k = null), a.classList.remove("liforma-ew--layout-settling");
2900
+ }, se = () => {
2876
2901
  for (let e of [
2877
2902
  f,
2878
2903
  l,
2879
2904
  p
2880
2905
  ]) e.style.removeProperty("left"), e.style.removeProperty("top"), e.style.removeProperty("width"), e.style.removeProperty("height"), e.style.removeProperty("right"), e.style.removeProperty("bottom");
2881
2906
  p.classList.remove("liforma-ew__toolbar--dragging"), a.classList.remove("liforma-ew--dock-dragging");
2882
- }, oe = (e, t, n, r) => {
2907
+ }, ce = (e, t, n, r) => {
2883
2908
  let i = (i) => {
2884
2909
  i.style.left = `${e}px`, i.style.top = `${t}px`, i.style.width = `${n}px`, i.style.height = `${r}px`, i.style.right = "auto", i.style.bottom = "auto";
2885
2910
  };
2886
2911
  i(f), i(l);
2887
2912
  let a = p.offsetWidth || 120;
2888
2913
  p.style.left = `${e + n - a - 10}px`, p.style.top = `${t + 10}px`, p.style.right = "auto", p.style.bottom = "auto", p.style.width = "auto", p.style.height = "auto";
2889
- }, se = (e, t) => {
2890
- if (z() !== "docked") return;
2891
- let n = hn(), r = _n(e - ne, t - re, n);
2892
- M = r.left, N = r.top, oe(r.left, r.top, n.width, n.height);
2893
- }, ce = (e, t) => {
2894
- if (z() !== "docked" || !Number.isFinite(e) || !Number.isFinite(t) || e === 0 && t === 0) return;
2895
- let n = hn(), r = M ?? f.getBoundingClientRect().left, i = N ?? f.getBoundingClientRect().top, a = _n(r + e, i + t, n);
2896
- M = a.left, N = a.top, oe(a.left, a.top, n.width, n.height);
2897
- }, le = (e) => {
2898
- F === "toolbar" && (P === null || e.pointerId !== P || (e.preventDefault(), se(e.clientX, e.clientY)));
2899
- }, V = (e) => {
2900
- if (P === null || e && e.pointerId !== P) return;
2901
- let t = F;
2902
- P = null, F = null, p.classList.remove("liforma-ew__toolbar--dragging"), a.classList.remove("liforma-ew--dock-dragging"), t === "toolbar" && I && (I = !1, window.removeEventListener("pointermove", le), window.removeEventListener("pointerup", V), window.removeEventListener("pointercancel", V));
2903
- }, de = (e, t, n) => {
2904
- if (S || z() !== "docked" || !Q() || P !== null) return;
2905
- P = n, F = "toolbar", p.classList.add("liforma-ew__toolbar--dragging"), a.classList.add("liforma-ew--dock-dragging");
2914
+ }, le = (e, t) => {
2915
+ if (L() !== "docked") return;
2916
+ let n = _n(), r = yn(e - ie, t - ae, n);
2917
+ A = r.left, j = r.top, ce(r.left, r.top, n.width, n.height);
2918
+ }, ue = (e, t) => {
2919
+ if (L() !== "docked" || !Number.isFinite(e) || !Number.isFinite(t) || e === 0 && t === 0) return;
2920
+ let n = _n(), r = A ?? f.getBoundingClientRect().left, i = j ?? f.getBoundingClientRect().top, a = yn(r + e, i + t, n);
2921
+ A = a.left, j = a.top, ce(a.left, a.top, n.width, n.height);
2922
+ }, de = (e) => {
2923
+ N === "toolbar" && (M === null || e.pointerId !== M || (e.preventDefault(), le(e.clientX, e.clientY)));
2924
+ }, z = (e) => {
2925
+ if (M === null || e && e.pointerId !== M) return;
2926
+ let t = N;
2927
+ M = null, N = null, p.classList.remove("liforma-ew__toolbar--dragging"), a.classList.remove("liforma-ew--dock-dragging"), t === "toolbar" && P && (P = !1, window.removeEventListener("pointermove", de), window.removeEventListener("pointerup", z), window.removeEventListener("pointercancel", z));
2928
+ }, pe = (e, t, n) => {
2929
+ if (S || L() !== "docked" || !Q() || M !== null) return;
2930
+ M = n, N = "toolbar", p.classList.add("liforma-ew__toolbar--dragging"), a.classList.add("liforma-ew--dock-dragging");
2906
2931
  let r = f.getBoundingClientRect();
2907
- ne = e - r.left, re = t - r.top, I || (I = !0, window.addEventListener("pointermove", le), window.addEventListener("pointerup", V), window.addEventListener("pointercancel", V));
2908
- }, pe = (e) => {
2909
- if (S || z() !== "docked" || !Q() || P !== null) return;
2910
- P = e.pointerId, F = "player", p.classList.add("liforma-ew__toolbar--dragging"), a.classList.add("liforma-ew--dock-dragging");
2911
- let t = f.getBoundingClientRect();
2912
- M = t.left, N = t.top;
2913
- }, me = (e) => {
2914
- F === "player" && (P === null || e.pointerId !== P || ce(e.dx, e.dy));
2932
+ ie = e - r.left, ae = t - r.top, P || (P = !0, window.addEventListener("pointermove", de), window.addEventListener("pointerup", z), window.addEventListener("pointercancel", z));
2915
2933
  }, he = (e) => {
2916
- F === "player" && (P === null || e.pointerId !== P || V());
2917
- }, H = () => {
2918
- let e = Q(), t = z();
2934
+ if (S || L() !== "docked" || !Q() || M !== null) return;
2935
+ M = e.pointerId, N = "player", p.classList.add("liforma-ew__toolbar--dragging"), a.classList.add("liforma-ew--dock-dragging");
2936
+ let t = f.getBoundingClientRect();
2937
+ A = t.left, j = t.top;
2938
+ }, ge = (e) => {
2939
+ N === "player" && (M === null || e.pointerId !== M || ue(e.dx, e.dy));
2940
+ }, _e = (e) => {
2941
+ N === "player" && (M === null || e.pointerId !== M || z());
2942
+ }, B = () => {
2943
+ let e = Q(), t = L();
2919
2944
  if (!e || t !== "expanded" && t !== "docked") {
2920
2945
  h.hidden = !0;
2921
2946
  return;
2922
2947
  }
2923
- h.hidden = !1, t === "docked" ? (h.innerHTML = Cn, h.setAttribute("aria-label", "Maximize")) : (h.innerHTML = Sn, h.setAttribute("aria-label", "Reduce"));
2924
- }, ge = (e) => {
2925
- let t = hn(), n = e && M !== null && N !== null ? _n(M, N, t) : gn(t);
2926
- n = _n(n.left, n.top, t), M = n.left, N = n.top, oe(n.left, n.top, t.width, t.height), H();
2927
- }, U = () => {
2948
+ h.hidden = !1, t === "docked" ? (h.innerHTML = Tn, h.setAttribute("aria-label", "Maximize")) : (h.innerHTML = wn, h.setAttribute("aria-label", "Reduce"));
2949
+ }, ve = (e) => {
2950
+ let t = _n(), n = e && A !== null && j !== null ? yn(A, j, t) : vn(t);
2951
+ n = yn(n.left, n.top, t), A = n.left, j = n.top, ce(n.left, n.top, t.width, t.height), B();
2952
+ }, V = () => {
2928
2953
  a.classList.remove("liforma-ew--session-revealed"), requestAnimationFrame(() => {
2929
2954
  requestAnimationFrame(() => {
2930
2955
  S || !$(a.dataset.state) || a.classList.add("liforma-ew--session-revealed");
2931
2956
  });
2932
2957
  });
2933
- }, ve = (e) => {
2934
- if (ie(), a.classList.remove("liforma-ew--session-revealed"), a.classList.add("liforma-ew--layout-settling"), e(), !D) {
2958
+ }, be = (e) => {
2959
+ if (oe(), a.classList.remove("liforma-ew--session-revealed"), a.classList.add("liforma-ew--layout-settling"), e(), !D) {
2935
2960
  a.classList.remove("liforma-ew--layout-settling");
2936
2961
  return;
2937
2962
  }
2938
- j = setTimeout(() => {
2939
- if (j = null, S || !$(a.dataset.state)) {
2963
+ k = setTimeout(() => {
2964
+ if (k = null, S || !$(a.dataset.state)) {
2940
2965
  a.classList.remove("liforma-ew--layout-settling");
2941
2966
  return;
2942
2967
  }
2943
- a.classList.remove("liforma-ew--layout-settling"), U();
2968
+ a.classList.remove("liforma-ew--layout-settling"), V();
2944
2969
  }, 220);
2945
- }, ye = () => (a.classList.add("liforma-ew--session-concealing"), a.classList.remove("liforma-ew--session-revealed"), new Promise((e) => {
2946
- B(), A = setTimeout(() => {
2947
- A = null, a.classList.remove("liforma-ew--session-concealing"), e();
2970
+ }, xe = () => (a.classList.add("liforma-ew--session-concealing"), a.classList.remove("liforma-ew--session-revealed"), new Promise((e) => {
2971
+ R(), re = setTimeout(() => {
2972
+ re = null, a.classList.remove("liforma-ew--session-concealing"), e();
2948
2973
  }, 280);
2949
- })), be = {
2974
+ })), Se = {
2950
2975
  galleryThumb: t.galleryThumb,
2951
2976
  avatarImage: t.avatarImage,
2952
2977
  backgroundImage: t.backgroundImage,
2953
2978
  foregroundImage: t.foregroundImage,
2954
2979
  fallbackImage: t.fallbackImage
2955
- }, W = (e) => {
2980
+ }, H = (e) => {
2956
2981
  if (!e) {
2957
2982
  y.hidden = !0, y.textContent = "";
2958
2983
  return;
2959
2984
  }
2960
2985
  y.hidden = !1, y.textContent = e;
2961
- }, G = (e) => {
2986
+ }, U = (e) => {
2962
2987
  if (!e) {
2963
2988
  c.hidden = !0, c.textContent = "";
2964
2989
  return;
2965
2990
  }
2966
2991
  c.hidden = !1, c.textContent = e, s.contains(c) || s.append(c);
2967
- }, xe = () => {
2968
- C = !0, o.disabled = !1, G(null), r === "onExpand" && t.onPrefetchReady?.();
2969
- }, Se = () => {
2970
- w = !0, a.dataset.warm = "true", l.hidden = !1, D || (o.tabIndex = -1, o.setAttribute("aria-hidden", "true")), t.onPrefetchReady?.();
2971
- }, Ce = (e) => {
2972
- k?.(), k = null;
2973
- let t = wn(s, e, { parallax: R });
2974
- return t ? (k = t, !0) : !1;
2992
+ }, Ce = () => {
2993
+ C = !0, o.disabled = !1, U(null), r === "onExpand" && t.onPrefetchReady?.();
2975
2994
  }, we = () => {
2976
- if (Ce(be)) {
2977
- xe();
2995
+ w = !0, a.dataset.warm = "true", l.hidden = !1, D || (o.tabIndex = -1, o.setAttribute("aria-hidden", "true")), t.onPrefetchReady?.();
2996
+ }, Te = (e) => {
2997
+ te?.(), te = null;
2998
+ let t = En(s, e, { parallax: I });
2999
+ return t ? (te = t, !0) : !1;
3000
+ }, Ee = () => {
3001
+ if (Te(Se)) {
3002
+ Ce();
2978
3003
  return;
2979
3004
  }
2980
- G("Loading…"), _e(n, { signal: L.signal }).then((e) => {
3005
+ U("Loading…"), ye(n, { signal: F.signal }).then((e) => {
2981
3006
  if (!S) {
2982
- if (!Ce({ galleryThumb: e.galleryThumb })) throw Error("Experience preview is missing gallery thumb images.");
2983
- xe();
3007
+ if (!Te({ galleryThumb: e.galleryThumb })) throw Error("Experience preview is missing gallery thumb images.");
3008
+ Ce();
2984
3009
  }
2985
3010
  }).catch((e) => {
2986
- if (S || L.signal.aborted) return;
3011
+ if (S || F.signal.aborted) return;
2987
3012
  let n = e instanceof Error ? e : Error(String(e));
2988
- G("Preview unavailable"), o.disabled = !0, t.onError?.(n), console.error("[ExperienceWidget]", n);
3013
+ U("Preview unavailable"), o.disabled = !0, t.onError?.(n), console.error("[ExperienceWidget]", n);
2989
3014
  });
2990
- }, Te = () => ({
3015
+ }, De = () => ({
2991
3016
  experienceId: n,
2992
3017
  ui: "widget",
2993
3018
  ...t.sessionEndpoint ? { sessionEndpoint: t.sessionEndpoint } : {},
@@ -3000,71 +3025,71 @@ function Dn(e, t) {
3000
3025
  ...t.speechOnly === void 0 ? {} : { speechOnly: t.speechOnly },
3001
3026
  ...t.alreadyConverted?.length ? { alreadyConverted: t.alreadyConverted } : {},
3002
3027
  ...t.embedBaseUrl ? { embedBaseUrl: t.embedBaseUrl } : {}
3003
- }), K = () => ({
3028
+ }), W = () => ({
3004
3029
  ...t.fit ? { fit: t.fit } : {},
3005
- startButton: Tn(t),
3030
+ startButton: Dn(t),
3006
3031
  ...t.showFeedback === void 0 ? {} : { showFeedback: t.showFeedback },
3007
3032
  ...t.interaction ? { interaction: t.interaction } : {}
3008
- }), q = (e = !0) => {
3009
- o.hidden = !0, u.hidden = !1, p.hidden = !1, u.setAttribute("aria-modal", "true"), ae(), a.dataset.state = "expanded", W(null), typeof document < "u" && (ee = document.body.style.overflow, document.body.style.overflow = "hidden"), H(), e && t.onExpanded?.();
3010
- }, Ee = () => {
3011
- o.hidden = !0, u.hidden = !1, p.hidden = !1, u.setAttribute("aria-modal", "false"), a.dataset.state = "docked", W(null), typeof document < "u" && (document.body.style.overflow = ee), ge(!0), H(), b?.setWidgetChrome("docked");
3012
- }, De = (e) => {
3033
+ }), G = (e = !0) => {
3034
+ o.hidden = !0, u.hidden = !1, p.hidden = !1, u.setAttribute("aria-modal", "true"), se(), a.dataset.state = "expanded", H(null), typeof document < "u" && (ee = document.body.style.overflow, document.body.style.overflow = "hidden"), B(), e && t.onExpanded?.();
3035
+ }, K = () => {
3036
+ o.hidden = !0, u.hidden = !1, p.hidden = !1, u.setAttribute("aria-modal", "false"), a.dataset.state = "docked", H(null), typeof document < "u" && (document.body.style.overflow = ee), ve(!0), B(), b?.setWidgetChrome("docked");
3037
+ }, Oe = (e) => {
3013
3038
  e.on("started", () => {
3014
- S || (D = !0, a.dataset.live = "true", W(null), t.onStarted?.(), $(a.dataset.state) && U());
3039
+ S || (D = !0, a.dataset.live = "true", H(null), t.onStarted?.(), $(a.dataset.state) && V());
3015
3040
  }), e.on("feedback", (e) => {
3016
3041
  S || t.onFeedback?.(e);
3017
3042
  }), e.on("feedbackFailed", (e) => {
3018
3043
  S || t.onFeedbackFailed?.(e);
3019
3044
  });
3020
- }, Oe = () => {
3021
- ie(), u.hidden = !0, p.hidden = !0, ae(), a.dataset.state = "collapsed", a.classList.remove("liforma-ew--session-revealed"), a.classList.remove("liforma-ew--session-concealing"), g.setAttribute("aria-pressed", "false"), o.hidden = !1, o.tabIndex = 0, o.removeAttribute("aria-hidden"), C && (o.disabled = !1), W(null), typeof document < "u" && (document.body.style.overflow = ee), H();
3022
3045
  }, ke = () => {
3023
- B(), ie(), O += 1, x = !1, w = !1, T = !1, E = !1, D = !1;
3046
+ oe(), u.hidden = !0, p.hidden = !0, se(), a.dataset.state = "collapsed", a.classList.remove("liforma-ew--session-revealed"), a.classList.remove("liforma-ew--session-concealing"), g.setAttribute("aria-pressed", "false"), o.hidden = !1, o.tabIndex = 0, o.removeAttribute("aria-hidden"), C && (o.disabled = !1), H(null), typeof document < "u" && (document.body.style.overflow = ee), B();
3047
+ }, Ae = () => {
3048
+ R(), oe(), O += 1, x = !1, w = !1, T = !1, E = !1, D = !1;
3024
3049
  let e = b;
3025
3050
  b = null, e?.destroy(), v.replaceChildren(), l.replaceChildren(), l.hidden = !0, delete a.dataset.warm, delete a.dataset.live, a.classList.remove("liforma-ew--session-revealed");
3026
- }, J = () => {
3051
+ }, q = () => {
3027
3052
  if (!S && $(a.dataset.state)) {
3028
- if (V(), x = !1, b && E) {
3053
+ if (z(), x = !1, b && E) {
3029
3054
  let e = b;
3030
3055
  (async () => {
3031
- D && (await ye(), S || b !== e) || (w && e.setWidgetChrome("collapsed"), Oe(), D ? (a.dataset.live = "true", o.tabIndex = 0, o.removeAttribute("aria-hidden"), o.disabled = !1) : w && Se(), t.onCollapsed?.(), t.onClose?.());
3056
+ D && (await xe(), S || b !== e) || (w && e.setWidgetChrome("collapsed"), ke(), D ? (a.dataset.live = "true", o.tabIndex = 0, o.removeAttribute("aria-hidden"), o.disabled = !1) : w && we(), t.onCollapsed?.(), t.onClose?.());
3032
3057
  })();
3033
3058
  return;
3034
3059
  }
3035
- ke(), Oe(), t.onCollapsed?.(), t.onClose?.();
3060
+ Ae(), ke(), t.onCollapsed?.(), t.onClose?.();
3036
3061
  }
3037
- }, Ae = () => {
3038
- S || Q() && z() === "expanded" && ve(() => {
3039
- Ee();
3040
- });
3041
3062
  }, je = () => {
3042
- S || z() === "docked" && (V(), ve(() => {
3043
- ae(), q(!1), b?.setWidgetChrome("expanded");
3063
+ S || Q() && L() === "expanded" && be(() => {
3064
+ K();
3065
+ });
3066
+ }, J = () => {
3067
+ S || L() === "docked" && (z(), be(() => {
3068
+ se(), G(!1), b?.setWidgetChrome("expanded");
3044
3069
  }));
3045
3070
  }, Me = () => {
3046
- !b || !D || (B(), a.classList.remove("liforma-ew--session-revealed"), q(), b.setWidgetChrome("expanded"), x = !1, U());
3071
+ !b || !D || (R(), a.classList.remove("liforma-ew--session-revealed"), G(), b.setWidgetChrome("expanded"), x = !1, V());
3047
3072
  }, Ne = () => {
3048
- !b || !E || D || (B(), a.classList.remove("liforma-ew--session-revealed"), q(), x = !1, w || b.setWidgetChrome("expanded"));
3073
+ !b || !E || D || (R(), a.classList.remove("liforma-ew--session-revealed"), G(), x = !1, w || b.setWidgetChrome("expanded"));
3049
3074
  }, Pe = (e) => {
3050
- S || e !== O && !D || (B(), a.classList.remove("liforma-ew--session-revealed"), q(), x = !1, D && U());
3075
+ S || e !== O && !D || (R(), a.classList.remove("liforma-ew--session-revealed"), G(), x = !1, D && V());
3051
3076
  }, Fe = () => {
3052
3077
  if (S || T || w || b || $(a.dataset.state)) return;
3053
3078
  T = !0;
3054
3079
  let e = O;
3055
3080
  l.hidden = !1, (async () => {
3056
3081
  try {
3057
- let t = await on.startSession(Te());
3082
+ let t = await cn.startSession(De());
3058
3083
  if (S || e !== O) {
3059
3084
  t.destroy();
3060
3085
  return;
3061
3086
  }
3062
- b = t, De(t);
3087
+ b = t, Oe(t);
3063
3088
  let n = await t.attach({
3064
3089
  container: l,
3065
- ...K(),
3090
+ ...W(),
3066
3091
  onWidgetReady: () => {
3067
- S || e !== O || (T = !1, E = !0, $(a.dataset.state) ? t.setWidgetChrome("expanded") : Se());
3092
+ S || e !== O || (T = !1, E = !0, $(a.dataset.state) ? t.setWidgetChrome("expanded") : we());
3068
3093
  },
3069
3094
  onWidgetExpand: () => {
3070
3095
  Pe(e);
@@ -3073,16 +3098,16 @@ function Dn(e, t) {
3073
3098
  S || ze(e);
3074
3099
  },
3075
3100
  onWidgetDragStart: (e) => {
3076
- S || pe(e);
3101
+ S || he(e);
3077
3102
  },
3078
3103
  onWidgetDragMove: (e) => {
3079
- S || me(e);
3104
+ S || ge(e);
3080
3105
  },
3081
3106
  onWidgetDragEnd: (e) => {
3082
- S || he(e);
3107
+ S || _e(e);
3083
3108
  },
3084
3109
  onPlayerStatusChange: (e) => {
3085
- S || e === "error" && $(a.dataset.state) && W("Could not load the experience.");
3110
+ S || e === "error" && $(a.dataset.state) && H("Could not load the experience.");
3086
3111
  }
3087
3112
  });
3088
3113
  if (S || e !== O) {
@@ -3090,7 +3115,7 @@ function Dn(e, t) {
3090
3115
  return;
3091
3116
  }
3092
3117
  n.on("close", () => {
3093
- S || J();
3118
+ S || q();
3094
3119
  });
3095
3120
  } catch (n) {
3096
3121
  if (S || e !== O) return;
@@ -3112,30 +3137,30 @@ function Dn(e, t) {
3112
3137
  let e = ++O;
3113
3138
  x = !0, w = !1, T = !1, E = !1, D = !1, delete a.dataset.warm, delete a.dataset.live, l.hidden = !0, l.replaceChildren(), b &&= (b.destroy(), null), (async () => {
3114
3139
  try {
3115
- q();
3116
- let t = await on.startSession(Te());
3140
+ G();
3141
+ let t = await cn.startSession(De());
3117
3142
  if (S || e !== O) {
3118
3143
  t.destroy();
3119
3144
  return;
3120
3145
  }
3121
- b = t, De(t);
3146
+ b = t, Oe(t);
3122
3147
  let n = await t.attach({
3123
3148
  container: v,
3124
- ...K(),
3149
+ ...W(),
3125
3150
  onWidgetAudioSettings: (e) => {
3126
3151
  S || ze(e);
3127
3152
  },
3128
3153
  onWidgetDragStart: (e) => {
3129
- S || pe(e);
3154
+ S || he(e);
3130
3155
  },
3131
3156
  onWidgetDragMove: (e) => {
3132
- S || me(e);
3157
+ S || ge(e);
3133
3158
  },
3134
3159
  onWidgetDragEnd: (e) => {
3135
- S || he(e);
3160
+ S || _e(e);
3136
3161
  },
3137
3162
  onPlayerStatusChange: (e) => {
3138
- S || (e === "error" ? W("Could not load the experience.") : $(a.dataset.state) && W(null));
3163
+ S || (e === "error" ? H("Could not load the experience.") : $(a.dataset.state) && H(null));
3139
3164
  }
3140
3165
  });
3141
3166
  if (S || e !== O) {
@@ -3143,12 +3168,12 @@ function Dn(e, t) {
3143
3168
  return;
3144
3169
  }
3145
3170
  E = !0, t.setWidgetChrome("expanded"), n.on("close", () => {
3146
- S || J();
3171
+ S || q();
3147
3172
  });
3148
3173
  } catch (n) {
3149
3174
  if (S || e !== O) return;
3150
3175
  let r = n instanceof Error ? n : Error(String(n));
3151
- W(r.message), t.onError?.(r), console.error("[ExperienceWidget]", r);
3176
+ H(r.message), t.onError?.(r), console.error("[ExperienceWidget]", r);
3152
3177
  } finally {
3153
3178
  e === O && (x = !1);
3154
3179
  }
@@ -3164,60 +3189,60 @@ function Dn(e, t) {
3164
3189
  return;
3165
3190
  }
3166
3191
  if (T || b) {
3167
- q();
3192
+ G();
3168
3193
  return;
3169
3194
  }
3170
3195
  Ie();
3171
3196
  }
3172
3197
  }, Re = (e) => {
3173
- if (e.stopPropagation(), z() === "expanded") {
3174
- Ae();
3198
+ if (e.stopPropagation(), L() === "expanded") {
3199
+ je();
3175
3200
  return;
3176
3201
  }
3177
- z() === "docked" && je();
3202
+ L() === "docked" && J();
3178
3203
  }, ze = (e) => {
3179
3204
  g.setAttribute("aria-pressed", e ? "true" : "false");
3180
3205
  }, Be = (e) => {
3181
3206
  e.stopPropagation(), $(a.dataset.state) && b?.toggleAudioSettings();
3182
3207
  }, Ve = (e) => {
3183
- z() === "docked" && Q() && (e.target?.closest("button") || (e.preventDefault(), de(e.clientX, e.clientY, e.pointerId)));
3208
+ L() === "docked" && Q() && (e.target?.closest("button") || (e.preventDefault(), pe(e.clientX, e.clientY, e.pointerId)));
3184
3209
  }, He = (e) => {
3185
- e.key === "Escape" && $(a.dataset.state) && (e.preventDefault(), J());
3210
+ e.key === "Escape" && $(a.dataset.state) && (e.preventDefault(), q());
3186
3211
  }, Ue = () => {
3187
3212
  if (!S) {
3188
- if (z() === "docked") {
3213
+ if (L() === "docked") {
3189
3214
  if (!Q()) {
3190
- je();
3215
+ J();
3191
3216
  return;
3192
3217
  }
3193
- D ? ve(() => {
3194
- ge(!0);
3195
- }) : ge(!0);
3218
+ D ? be(() => {
3219
+ ve(!0);
3220
+ }) : ve(!0);
3196
3221
  return;
3197
3222
  }
3198
- H();
3223
+ B();
3199
3224
  }
3200
- }, We = typeof window < "u" ? window.matchMedia(cn) : null, Ge = () => {
3225
+ }, We = typeof window < "u" ? window.matchMedia(un) : null, Ge = () => {
3201
3226
  if (!S) {
3202
- if (z() === "docked" && !Q()) {
3203
- je();
3227
+ if (L() === "docked" && !Q()) {
3228
+ J();
3204
3229
  return;
3205
3230
  }
3206
- H();
3231
+ B();
3207
3232
  }
3208
3233
  };
3209
- return o.addEventListener("click", Le), d.addEventListener("click", J), _.addEventListener("click", (e) => {
3210
- e.stopPropagation(), J();
3211
- }), h.addEventListener("click", Re), g.addEventListener("click", Be), p.addEventListener("pointerdown", Ve), window.addEventListener("keydown", He), window.addEventListener("resize", Ue), We?.addEventListener("change", Ge), we(), H(), r === "eager" ? queueMicrotask(() => {
3234
+ return o.addEventListener("click", Le), d.addEventListener("click", q), _.addEventListener("click", (e) => {
3235
+ e.stopPropagation(), q();
3236
+ }), h.addEventListener("click", Re), g.addEventListener("click", Be), p.addEventListener("pointerdown", Ve), window.addEventListener("keydown", He), window.addEventListener("resize", Ue), We?.addEventListener("change", Ge), Ee(), B(), r === "eager" ? queueMicrotask(() => {
3212
3237
  S || Fe();
3213
- }) : r === "idle" && (te = En(() => {
3238
+ }) : r === "idle" && (ne = On(() => {
3214
3239
  S || Fe();
3215
3240
  })), {
3216
3241
  root: a,
3217
3242
  expand: Le,
3218
- collapse: J,
3219
- dock: Ae,
3220
- maximize: je,
3243
+ collapse: q,
3244
+ dock: je,
3245
+ maximize: J,
3221
3246
  prefetch() {
3222
3247
  if (r === "onExpand") {
3223
3248
  Fe();
@@ -3226,11 +3251,11 @@ function Dn(e, t) {
3226
3251
  Fe();
3227
3252
  },
3228
3253
  destroy() {
3229
- S || (S = !0, V(), te?.(), te = null, L.abort(), k?.(), k = null, window.removeEventListener("keydown", He), window.removeEventListener("resize", Ue), We?.removeEventListener("change", Ge), ke(), Oe(), e.replaceChildren());
3254
+ S || (S = !0, z(), ne?.(), ne = null, F.abort(), te?.(), te = null, window.removeEventListener("keydown", He), window.removeEventListener("resize", Ue), We?.removeEventListener("change", Ge), Ae(), ke(), e.replaceChildren());
3230
3255
  }
3231
3256
  };
3232
3257
  }
3233
3258
  //#endregion
3234
- export { ce as EXPERIENCE_THUMBNAIL_CSS, ue as EXPERIENCE_WIDGET_CSS, on as Experience, U as LiformaError, X as SPEECH_LIMITS, Mt as SpeechBufferTimeoutError, Z as SpeechRuntimeError, jt as SpeechUtteranceClosedError, At as UnsupportedSpeechOperationError, ne as attachImageReady, P as attachLazyThumb, oe as attachScrollLinkedParallax, w as buildHostedLaunchUrl, V as ensureExperienceThumbnailStyles, fe as ensureExperienceWidgetStyles, _e as fetchExperiencePreview, j as getDefaultLazyRootMargin, F as horizontalParallaxFromViewportY, ye as liformaErrorFromResponse, Dn as mountExperienceWidget, n as navigateOnExperienceClose, T as resolveThumbnailHref, S as resolveThumbnailInteraction, v as resolveThumbnailLayers, r as thumbnailFitClass, _ as toGalleryThumbUrl, Ae as warnLocaleVoiceFallbacks };
3259
+ export { ue as EXPERIENCE_THUMBNAIL_CSS, fe as EXPERIENCE_WIDGET_CSS, cn as Experience, V as LiformaError, X as SPEECH_LIMITS, Pt as SpeechBufferTimeoutError, Z as SpeechRuntimeError, Nt as SpeechUtteranceClosedError, Mt as UnsupportedSpeechOperationError, ie as attachImageReady, M as attachLazyThumb, ce as attachScrollLinkedParallax, w as buildHostedLaunchUrl, z as ensureExperienceThumbnailStyles, me as ensureExperienceWidgetStyles, ye as fetchExperiencePreview, k as getDefaultLazyRootMargin, N as horizontalParallaxFromViewportY, xe as liformaErrorFromResponse, kn as mountExperienceWidget, n as navigateOnExperienceClose, T as resolveThumbnailHref, S as resolveThumbnailInteraction, v as resolveThumbnailLayers, r as thumbnailFitClass, _ as toGalleryThumbUrl, J as warnLocaleVoiceFallbacks };
3235
3260
 
3236
3261
  //# sourceMappingURL=index.js.map