@streamoji/aitwin 0.1.8 → 0.1.9

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.
package/dist/aitwin.js CHANGED
@@ -1,73 +1,75 @@
1
- import { jsxs as Bt, jsx as it } from "react/jsx-runtime";
2
- import { forwardRef as Nt, useRef as R, useState as ke, useCallback as ie, useEffect as Te, useMemo as Vt, useImperativeHandle as $t } from "react";
3
- const Ht = "https://pub-607ad1fc22e2400eb57d17240aab857c.r2.dev", St = {
4
- publicBase: Ht
5
- }, Wt = "0.1.8", qt = {
6
- version: Wt
7
- }, Kt = {}, Pe = "https://ai.streamoji.com", jt = `${St.publicBase}/custom-faces`, Gt = `${St.publicBase}/aitwin-workers/v${qt.version}/visemeDiffPreview.worker.js`;
8
- function zt(e) {
1
+ import { jsxs as wn, jsx as vt } from "react/jsx-runtime";
2
+ import { forwardRef as gn, useRef as O, useState as Ce, useCallback as ie, useEffect as Se, useMemo as _n, useImperativeHandle as pn } from "react";
3
+ import { PipecatClient as yn } from "@pipecat-ai/client-js";
4
+ import { WebSocketTransport as kn, DailyMediaManager as En } from "@pipecat-ai/websocket-transport";
5
+ const Sn = "https://pub-607ad1fc22e2400eb57d17240aab857c.r2.dev", qt = {
6
+ publicBase: Sn
7
+ }, vn = "0.1.9", bn = {
8
+ version: vn
9
+ }, Tn = {}, be = "https://ai.streamoji.com", An = `${qt.publicBase}/custom-faces`, In = `${qt.publicBase}/aitwin-workers/v${bn.version}/visemeDiffPreview.worker.js`;
10
+ function Rn(e) {
9
11
  if (e) return e;
10
- const t = typeof import.meta < "u" ? Kt?.VITE_AITWIN_WORKER_URL : void 0;
11
- return t?.trim() ? t.trim() : Gt;
12
- }
13
- const Qt = "https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin", kt = "eng_a7f2b9c1", Ze = "eng_d4e8f3a2", be = "eng_c9b1e6d4", pe = be, Jt = /* @__PURE__ */ new Set([
14
- Ze,
15
- be
16
- ]), Tt = {
17
- [kt]: "oculus_direct",
18
- [be]: "oculus_direct",
19
- [Ze]: "inworld_word"
20
- }, st = {
21
- google: kt,
22
- inworld: Ze,
23
- cartesia: be
12
+ const t = typeof import.meta < "u" ? Tn?.VITE_AITWIN_WORKER_URL : void 0;
13
+ return t?.trim() ? t.trim() : In;
14
+ }
15
+ const Dn = "https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin", Kt = "eng_a7f2b9c1", ot = "eng_d4e8f3a2", Ae = "eng_c9b1e6d4", Te = Ae, Mn = /* @__PURE__ */ new Set([
16
+ ot,
17
+ Ae
18
+ ]), jt = {
19
+ [Kt]: "oculus_direct",
20
+ [Ae]: "oculus_direct",
21
+ [ot]: "inworld_word"
22
+ }, bt = {
23
+ google: Kt,
24
+ inworld: ot,
25
+ cartesia: Ae
24
26
  };
25
- function Yt(e) {
26
- return Tt[e];
27
+ function xn(e) {
28
+ return jt[e];
27
29
  }
28
- function Xt(e) {
29
- return e === be;
30
+ function Cn(e) {
31
+ return e === Ae;
30
32
  }
31
- function Zt(e) {
32
- if (e.ttsEngineId && e.ttsEngineId in Tt)
33
+ function Pn(e) {
34
+ if (e.ttsEngineId && e.ttsEngineId in jt)
33
35
  return e.ttsEngineId;
34
36
  const t = e.tts?.toLowerCase();
35
- return t && t in st ? st[t] : pe;
37
+ return t && t in bt ? bt[t] : Te;
36
38
  }
37
- class Ke extends Error {
39
+ class Ze extends Error {
38
40
  constructor(t = "AI twin not found") {
39
41
  super(t), this.name = "AiTwinNotFoundError";
40
42
  }
41
43
  }
42
- async function en(e, t = Qt) {
44
+ async function Bn(e, t = Dn) {
43
45
  const n = new URL(t);
44
46
  n.searchParams.set("id", e);
45
47
  const r = await fetch(n.toString());
46
48
  if (r.status === 404)
47
- throw new Ke();
49
+ throw new Ze();
48
50
  if (!r.ok)
49
51
  throw new Error(`getAiTwin failed (${r.status})`);
50
- const i = await r.json();
51
- if (!i.success)
52
- throw new Ke(i.error ?? "AI twin not found");
53
- const { tts: s, ...c } = i.data;
52
+ const s = await r.json();
53
+ if (!s.success)
54
+ throw new Ze(s.error ?? "AI twin not found");
55
+ const { tts: i, ...o } = s.data;
54
56
  return {
55
- ...c,
56
- ttsEngineId: Zt(i.data)
57
+ ...o,
58
+ ttsEngineId: Pn(s.data)
57
59
  };
58
60
  }
59
- const tn = "https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken", nn = "client_6TNvp3SCs4Og0a1ijm9TommXLql1", rn = "kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1", sn = "6TNvp3SCs4Og0a1ijm9TommXLql1", on = "Swaraj Mali";
60
- async function ot() {
61
- const e = await fetch(tn, {
61
+ const On = "https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken", Ln = "client_6TNvp3SCs4Og0a1ijm9TommXLql1", Fn = "kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1", Un = "6TNvp3SCs4Og0a1ijm9TommXLql1", Nn = "Swaraj Mali";
62
+ async function Qe() {
63
+ const e = await fetch(On, {
62
64
  method: "POST",
63
65
  headers: {
64
66
  "Content-Type": "application/json",
65
- "Client-Id": nn,
66
- "Client-Secret": rn
67
+ "Client-Id": Ln,
68
+ "Client-Secret": Fn
67
69
  },
68
70
  body: JSON.stringify({
69
- userId: sn,
70
- userName: on
71
+ userId: Un,
72
+ userName: Nn
71
73
  })
72
74
  });
73
75
  if (!e.ok)
@@ -77,7 +79,7 @@ async function ot() {
77
79
  throw new Error("getAuthToken returned no token");
78
80
  return n;
79
81
  }
80
- async function an(e, t = Pe) {
82
+ async function Vn(e, t = be) {
81
83
  const n = await fetch(`${t.replace(/\/$/, "")}/api/session-value`, {
82
84
  headers: { Authorization: `Bearer ${e}` }
83
85
  });
@@ -87,7 +89,7 @@ async function an(e, t = Pe) {
87
89
  if (!r.value) throw new Error("Session value response missing value");
88
90
  return r;
89
91
  }
90
- function cn(e) {
92
+ function $n(e) {
91
93
  const t = e.trim();
92
94
  if (t.length % 2 !== 0) throw new Error("Invalid hex key");
93
95
  const n = new Uint8Array(t.length / 2);
@@ -95,20 +97,20 @@ function cn(e) {
95
97
  n[r / 2] = Number.parseInt(t.slice(r, r + 2), 16);
96
98
  return n;
97
99
  }
98
- function Ce(e) {
100
+ function Fe(e) {
99
101
  return Uint8Array.from(e);
100
102
  }
101
- function un(e, t) {
103
+ function Hn(e, t) {
102
104
  const n = new Uint8Array(e.length + t.length);
103
105
  return n.set(e, 0), n.set(t, e.length), n;
104
106
  }
105
- async function ln(e, t) {
107
+ async function Wn(e, t) {
106
108
  if (!t) throw new Error("Asset key is required for encrypted assets");
107
109
  if (e.byteLength < 28)
108
110
  throw new Error("Encrypted payload too small");
109
- const n = new Uint8Array(e), r = Ce(n.subarray(0, 12)), i = Ce(n.subarray(12, 28)), s = Ce(n.subarray(28)), c = Ce(un(s, i)), a = await crypto.subtle.importKey(
111
+ const n = new Uint8Array(e), r = Fe(n.subarray(0, 12)), s = Fe(n.subarray(12, 28)), i = Fe(n.subarray(28)), o = Fe(Hn(i, s)), a = await crypto.subtle.importKey(
110
112
  "raw",
111
- cn(t),
113
+ $n(t),
112
114
  { name: "AES-GCM" },
113
115
  !1,
114
116
  ["decrypt"]
@@ -116,82 +118,95 @@ async function ln(e, t) {
116
118
  return crypto.subtle.decrypt(
117
119
  { name: "AES-GCM", iv: r, tagLength: 128 },
118
120
  a,
119
- c
121
+ o
120
122
  );
121
123
  }
122
- let je = null;
123
- const Ge = /* @__PURE__ */ new Set();
124
- function fn(e, t = jt) {
124
+ let et = null;
125
+ const tt = /* @__PURE__ */ new Set();
126
+ function Ue(e) {
127
+ return e.includes("/custom-faces/");
128
+ }
129
+ function He(e) {
130
+ const t = e.binBase.trim().replace(/\/$/, ""), n = e.twinBase.trim().replace(/\/$/, "");
131
+ if (!(e.encrypted || Ue(t) || Ue(n)))
132
+ return { twinBase: n, binBase: t, encrypted: !1 };
133
+ const s = Ue(t) ? t : Ue(n) ? n : t;
134
+ return { twinBase: s, binBase: s, encrypted: !0 };
135
+ }
136
+ function Ie(e) {
137
+ return He(e).encrypted;
138
+ }
139
+ function qn(e, t = An) {
125
140
  const n = `${t.replace(/\/$/, "")}/${e}`;
126
141
  return { twinBase: n, binBase: n, encrypted: !0 };
127
142
  }
128
- function dn(e) {
129
- je = e;
130
- for (const t of Ge) t();
143
+ function Kn(e) {
144
+ et = He(e);
145
+ for (const t of tt) t();
131
146
  }
132
- function hn(e, t) {
147
+ function jn(e, t) {
133
148
  const n = typeof globalThis.location < "u" ? globalThis.location.href : void 0;
134
- if (!n) return e;
135
- const r = (i) => {
149
+ if (!n) return He(e);
150
+ const r = (s) => {
136
151
  try {
137
- return new URL(i, n).href.replace(/\/$/, "");
152
+ return new URL(s, n).href.replace(/\/$/, "");
138
153
  } catch {
139
- return i;
154
+ return s;
140
155
  }
141
156
  };
142
- return {
157
+ return He({
143
158
  twinBase: r(e.twinBase),
144
159
  binBase: r(e.binBase),
145
160
  encrypted: e.encrypted
146
- };
161
+ });
147
162
  }
148
- function he() {
149
- if (!je)
163
+ function Ee() {
164
+ if (!et)
150
165
  throw new Error("Twin assets not configured; call setActiveTwinAssets first");
151
- return je;
166
+ return et;
152
167
  }
153
- function mn(e) {
154
- return Ge.add(e), () => Ge.delete(e);
168
+ function Gn(e) {
169
+ return tt.add(e), () => tt.delete(e);
155
170
  }
156
- function at() {
157
- const { encrypted: e, binBase: t, twinBase: n } = he();
158
- return e ? `${t}/sil.bin` : `${n}/sil.png`;
171
+ function Tt() {
172
+ const e = Ee();
173
+ return Ie(e) ? `${e.binBase}/sil.bin` : `${e.twinBase}/sil.png`;
159
174
  }
160
- function _n() {
161
- const { encrypted: e, binBase: t, twinBase: n } = he();
162
- return e ? `${t}/idle.bin` : `${n}/idle.mp4`;
175
+ function zn() {
176
+ const e = Ee();
177
+ return Ie(e) ? `${e.binBase}/idle.bin` : `${e.twinBase}/idle.mp4`;
163
178
  }
164
- function wn() {
165
- const { encrypted: e, binBase: t, twinBase: n } = he();
166
- return e ? t : n;
179
+ function Yn() {
180
+ const e = Ee();
181
+ return Ie(e) ? e.binBase : e.twinBase;
167
182
  }
168
- function Be() {
169
- return he().encrypted;
183
+ function Ke() {
184
+ return Ie(Ee());
170
185
  }
171
- function gn() {
172
- const { binBase: e, twinBase: t, encrypted: n } = he();
173
- return n ? `${e}/atlas.bin` : `${t}/atlas.json`;
186
+ function Jn() {
187
+ const e = Ee();
188
+ return Ie(e) ? `${e.binBase}/atlas.bin` : `${e.twinBase}/atlas.json`;
174
189
  }
175
- function yn() {
176
- const { binBase: e, twinBase: t, encrypted: n } = he();
177
- return n ? `${e}/expression_atlas.bin` : `${t}/expression_atlas.json`;
190
+ function Qn() {
191
+ const e = Ee();
192
+ return Ie(e) ? `${e.binBase}/expression_atlas.bin` : `${e.twinBase}/expression_atlas.json`;
178
193
  }
179
- function pn(e) {
194
+ function Xn(e) {
180
195
  const t = e.split(/\r?\n/);
181
196
  let n = "", r = "";
182
- for (const s of t)
183
- s.startsWith("event:") ? n = s.slice(6).trim() : s.startsWith("data:") && (r = s.slice(5).trim());
197
+ for (const i of t)
198
+ i.startsWith("event:") ? n = i.slice(6).trim() : i.startsWith("data:") && (r = i.slice(5).trim());
184
199
  if (!n) return null;
185
- let i = {};
200
+ let s = {};
186
201
  if (r)
187
202
  try {
188
- i = JSON.parse(r);
203
+ s = JSON.parse(r);
189
204
  } catch {
190
- i = { raw: r };
205
+ s = { raw: r };
191
206
  }
192
- return { event: n, data: i };
207
+ return { event: n, data: s };
193
208
  }
194
- const En = [
209
+ const Zn = [
195
210
  "aa",
196
211
  "CH",
197
212
  "DD",
@@ -207,14 +222,14 @@ const En = [
207
222
  "kk",
208
223
  "nn",
209
224
  "sil"
210
- ], Sn = new Map(
211
- En.map((e) => [e.toLowerCase(), e])
225
+ ], er = new Map(
226
+ Zn.map((e) => [e.toLowerCase(), e])
212
227
  );
213
- function kn(e) {
228
+ function tr(e) {
214
229
  const t = (e ?? "").trim();
215
- return t ? Sn.get(t.toLowerCase()) ?? "sil" : "sil";
230
+ return t ? er.get(t.toLowerCase()) ?? "sil" : "sil";
216
231
  }
217
- const Tn = {
232
+ const nr = {
218
233
  aei: ["aa", "E", "I"],
219
234
  o: ["O", "U"],
220
235
  ee: ["I"],
@@ -226,46 +241,46 @@ const Tn = {
226
241
  qw: ["U", "O"],
227
242
  cdgknstxyz: ["DD", "SS", "kk", "CH"]
228
243
  };
229
- function vn(e) {
244
+ function rr(e) {
230
245
  if (!e) return ["sil"];
231
246
  const t = e.toLowerCase();
232
- return Tn[t] ?? ["sil"];
247
+ return nr[t] ?? ["sil"];
233
248
  }
234
- function In(e, t) {
249
+ function sr(e, t) {
235
250
  const n = e.word.length;
236
251
  if (n <= 0) return 0;
237
252
  const r = e.wduration;
238
253
  if (r <= 0) return 0;
239
- const i = Math.max(0, Math.min(1, (t - e.wtime) / r));
240
- return Math.min(n - 1, Math.floor(i * n));
254
+ const s = Math.max(0, Math.min(1, (t - e.wtime) / r));
255
+ return Math.min(n - 1, Math.floor(s * n));
241
256
  }
242
- function Ne(e, t) {
257
+ function je(e, t) {
243
258
  const n = Math.max(0, Math.min(e.length - 1, t));
244
259
  return e[n] ?? "";
245
260
  }
246
- function An(e, t) {
247
- const n = e.toLowerCase(), r = Ne(n, t), i = n.slice(Math.max(0, t - 1), t + 2);
248
- return r === "i" || r === "y" ? "I" : i.includes("ee") || r === "e" || n.includes("ea") ? "E" : "aa";
261
+ function ir(e, t) {
262
+ const n = e.toLowerCase(), r = je(n, t), s = n.slice(Math.max(0, t - 1), t + 2);
263
+ return r === "i" || r === "y" ? "I" : s.includes("ee") || r === "e" || n.includes("ea") ? "E" : "aa";
249
264
  }
250
- function bn(e, t) {
265
+ function or(e, t) {
251
266
  const n = e.toLowerCase(), r = n.slice(
252
267
  Math.max(0, t - 1),
253
268
  Math.min(n.length, t + 3)
254
269
  );
255
270
  if (/oo|ou|uw/.test(r)) return "U";
256
- const i = Ne(n, t);
257
- return i === "u" || i === "w" ? "U" : "O";
271
+ const s = je(n, t);
272
+ return s === "u" || s === "w" ? "U" : "O";
258
273
  }
259
- function Rn(e, t) {
274
+ function ar(e, t) {
260
275
  const n = e.toLowerCase(), r = n.slice(Math.max(0, t - 2), t + 1);
261
276
  if (/qu/.test(r)) return "U";
262
- const i = n.slice(
277
+ const s = n.slice(
263
278
  Math.max(0, t - 1),
264
279
  Math.min(n.length, t + 3)
265
280
  );
266
- return /wo|wh/.test(i) || Ne(n, t) === "o" ? "O" : "U";
281
+ return /wo|wh/.test(s) || je(n, t) === "o" ? "O" : "U";
267
282
  }
268
- const Fe = {
283
+ const Ne = {
269
284
  d: "DD",
270
285
  t: "DD",
271
286
  n: "DD",
@@ -277,65 +292,65 @@ const Fe = {
277
292
  x: "CH",
278
293
  j: "CH"
279
294
  };
280
- function Dn(e, t) {
281
- const n = e.toLowerCase(), r = Ne(n, t);
282
- if (Fe[r]) return Fe[r];
283
- for (let i = 0; i < n.length; i++) {
284
- const s = n[i];
285
- if (Fe[s]) return Fe[s];
295
+ function cr(e, t) {
296
+ const n = e.toLowerCase(), r = je(n, t);
297
+ if (Ne[r]) return Ne[r];
298
+ for (let s = 0; s < n.length; s++) {
299
+ const i = n[s];
300
+ if (Ne[i]) return Ne[i];
286
301
  }
287
302
  return "DD";
288
303
  }
289
- function xn(e, t, n) {
290
- const r = vn(e);
304
+ function ur(e, t, n) {
305
+ const r = rr(e);
291
306
  if (r.length === 1) return r[0];
292
- const i = t.trim();
293
- if (!i) return r[0];
294
- const s = (e ?? "").toLowerCase(), c = Math.max(0, n);
295
- switch (s) {
307
+ const s = t.trim();
308
+ if (!s) return r[0];
309
+ const i = (e ?? "").toLowerCase(), o = Math.max(0, n);
310
+ switch (i) {
296
311
  case "aei":
297
- return An(i, c);
312
+ return ir(s, o);
298
313
  case "o":
299
- return bn(i, c);
314
+ return or(s, o);
300
315
  case "qw":
301
- return Rn(i, c);
316
+ return ar(s, o);
302
317
  case "cdgknstxyz":
303
- return Dn(i, c);
318
+ return cr(s, o);
304
319
  default:
305
320
  return r[0];
306
321
  }
307
322
  }
308
- function Mn(e) {
323
+ const lr = 24e3;
324
+ function fr(e) {
309
325
  let t = e.trim();
310
326
  const n = t.indexOf(",");
311
327
  t.startsWith("data:") && n >= 0 && (t = t.slice(n + 1)), t = t.replace(/\s+/g, "").replace(/-/g, "+").replace(/_/g, "/");
312
328
  const r = t.length % 4;
313
329
  return r !== 0 && (t += "=".repeat(4 - r)), t;
314
330
  }
315
- const Cn = 24e3;
316
- function Fn(e) {
331
+ function dr(e) {
317
332
  return e.length >= 4 && e[0] === 82 && e[1] === 73 && e[2] === 70 && e[3] === 70;
318
333
  }
319
- function ct(e, t, n = Cn) {
320
- const r = t.byteOffset % 2 === 0 ? t : t.slice(), i = new Int16Array(
334
+ function At(e, t, n = lr) {
335
+ const r = t.byteOffset % 2 === 0 ? t : t.slice(), s = new Int16Array(
321
336
  r.buffer,
322
337
  r.byteOffset,
323
338
  r.byteLength / 2
324
- ), s = new Float32Array(i.length);
325
- for (let a = 0; a < i.length; a++)
326
- s[a] = i[a] >= 32768 ? -(65536 - i[a]) / 32768 : i[a] / 32767;
327
- const c = e.createBuffer(1, s.length, n);
328
- return c.copyToChannel(s, 0), c;
329
- }
330
- function Ln(e) {
331
- const t = Mn(e), n = window.atob(t), r = new Uint8Array(n.length);
332
- for (let i = 0; i < n.length; i++)
333
- r[i] = n.charCodeAt(i);
339
+ ), i = new Float32Array(s.length);
340
+ for (let a = 0; a < s.length; a++)
341
+ i[a] = s[a] >= 32768 ? -(65536 - s[a]) / 32768 : s[a] / 32767;
342
+ const o = e.createBuffer(1, i.length, n);
343
+ return o.copyToChannel(i, 0), o;
344
+ }
345
+ function hr(e) {
346
+ const t = fr(e), n = window.atob(t), r = new Uint8Array(n.length);
347
+ for (let s = 0; s < n.length; s++)
348
+ r[s] = n.charCodeAt(s);
334
349
  return r;
335
350
  }
336
- async function On(e, t) {
337
- const n = Ln(t);
338
- if (Fn(n)) {
351
+ async function mr(e, t) {
352
+ const n = hr(t);
353
+ if (dr(n)) {
339
354
  const r = n.buffer.slice(
340
355
  n.byteOffset,
341
356
  n.byteOffset + n.byteLength
@@ -343,7 +358,7 @@ async function On(e, t) {
343
358
  return e.decodeAudioData(r);
344
359
  }
345
360
  if (n.length >= 2 && n.length % 2 === 0)
346
- return ct(e, n);
361
+ return At(e, n);
347
362
  try {
348
363
  const r = n.buffer.slice(
349
364
  n.byteOffset,
@@ -351,288 +366,685 @@ async function On(e, t) {
351
366
  );
352
367
  return await e.decodeAudioData(r);
353
368
  } catch {
354
- return ct(e, n);
369
+ return At(e, n);
355
370
  }
356
371
  }
357
- function vt(e, t) {
358
- let n = null;
359
- for (const r of e)
360
- t < r.vtime || t >= r.vtime + r.vduration || (!n || r.vtime >= n.vtime) && (n = r);
361
- return n ? n.viseme : "sil";
372
+ function It(e) {
373
+ let t = 0;
374
+ for (const n of e)
375
+ t = Math.max(t, n.vtime + n.vduration);
376
+ return t;
362
377
  }
363
- function Pn(e, t) {
378
+ function wr(e, t) {
364
379
  for (const n of e)
365
380
  if (t >= n.wtime && t < n.wtime + n.wduration)
366
381
  return n;
367
382
  return null;
368
383
  }
369
- function ut(e) {
370
- let t = 0;
371
- for (const n of e)
372
- t = Math.max(t, n.vtime + n.vduration);
373
- return t;
374
- }
375
- const Un = 0.5, Bn = 1.5, It = "Olivia", Nn = "f786b574-daa5-4673-aa0c-cbe3e8534c02", At = 0.85;
376
- function Vn(e, t = Pe) {
377
- const n = `${t.replace(/\/$/, "")}/avatar_ttsWithPoses`, r = [], i = [], s = [];
378
- let c = "neutral";
379
- const a = [], l = [];
380
- let d = null, _ = !1, m = !1, S = !1, o = !1, F = 0, w = 0, u = 0, g = 0, y = null, v = 1, H = "", h = pe, E = pe, D = !1;
381
- const L = /* @__PURE__ */ new Set(), z = () => {
382
- for (const p of l)
383
- p.playbackRate.value = v;
384
- }, U = () => L.forEach((p) => p()), ae = () => {
385
- y != null && (clearTimeout(y), y = null);
386
- }, me = () => {
387
- for (const p of l)
384
+ function Gt(e, t) {
385
+ const n = [], r = [];
386
+ let s = null, i = !1, o = !1, a = !1, f = !1, l = 0, m = 0, _ = 0, w = 0, k = null, E = 1, u = t, p = !1;
387
+ const d = () => {
388
+ k != null && (clearTimeout(k), k = null);
389
+ }, D = () => {
390
+ for (const g of r)
388
391
  try {
389
- p.stop();
392
+ g.stop();
390
393
  } catch {
391
394
  }
392
- l.length = 0;
393
- }, N = () => {
394
- D = !0, ae(), me(), a.length = 0, _ = !1, m = !1, S = !1, o = !1, r.length = 0, i.length = 0, s.length = 0, c = "neutral", u = 0, g = 0, w = 0, e("idle"), U();
395
- }, X = () => {
396
- !o || _ || l.length > 0 || a.length > 0 || (m = !1, ae(), e("done"), U());
397
- }, Re = () => {
398
- const p = ut(r);
399
- if (p <= 0) {
400
- e("done"), U();
395
+ r.length = 0;
396
+ }, y = () => {
397
+ for (const g of r)
398
+ g.playbackRate.value = E;
399
+ }, A = () => {
400
+ !f || i || r.length > 0 || n.length > 0 || (o = !1, d(), e.onSpeakingDone(), e.onNotify());
401
+ }, U = (g) => {
402
+ const v = It(g);
403
+ if (v <= 0) {
404
+ e.onSpeakingDone(), e.onNotify();
401
405
  return;
402
406
  }
403
- m = !0, F = performance.now(), e("speaking"), U(), ae();
404
- const V = v > 0 ? p / v : p;
405
- y = setTimeout(() => {
406
- D || (m = !1, y = null, e("done"), U());
407
- }, V);
408
- }, He = (p, V, W) => {
409
- p.length !== 0 && (W && (u = V), p.forEach((x) => {
407
+ o = !0, l = performance.now(), e.onSpeakingStart(), e.onNotify(), d();
408
+ const T = E > 0 ? v / E : v;
409
+ k = setTimeout(() => {
410
+ p || (o = !1, k = null, e.onSpeakingDone(), e.onNotify());
411
+ }, T);
412
+ }, V = (g, v, T, C) => {
413
+ v.length !== 0 && (C && (_ = T), v.forEach((x) => {
410
414
  const I = String(x.word ?? "").trim();
411
415
  if (!I) return;
412
- const Q = Math.round((x.start ?? 0) * 1e3), J = Math.round((x.duration ?? 0) * 1e3);
413
- i.push({
416
+ const $ = Math.round((x.start ?? 0) * 1e3), Y = x.duration != null ? Math.round(x.duration * 1e3) : x.end != null ? Math.max(1, Math.round((x.end - (x.start ?? 0)) * 1e3)) : 0;
417
+ g.push({
414
418
  word: I,
415
- wtime: u + Q,
416
- wduration: J,
417
- queueIndex: i.length
419
+ wtime: _ + $,
420
+ wduration: Y,
421
+ queueIndex: g.length,
422
+ gesture: x.gesture ?? null,
423
+ emphasis: x.emphasis === !0
418
424
  });
419
425
  }));
420
- }, De = (p, V, W, x) => {
421
- p.length !== 0 && (W && (u = V), p.forEach((M) => {
422
- const I = String(M.symbol ?? "").trim();
423
- if (!I) return;
424
- const Q = Math.round((M.start ?? 0) * 1e3), J = Math.max(
425
- 1,
426
- Math.round((M.duration ?? 0) * 1e3)
427
- ), P = u + Q;
428
- let O;
429
- if (Yt(x) === "oculus_direct")
430
- O = kn(I);
426
+ }, z = (g, v, T, C, x, L) => {
427
+ T.length !== 0 && (x && (_ = C), T.forEach((I) => {
428
+ const $ = String(I.symbol ?? I.viseme ?? "").trim();
429
+ if (!$) return;
430
+ const Y = Math.round((I.start ?? 0) * 1e3), ge = Math.max(1, Math.round((I.duration ?? 0) * 1e3)), re = _ + Y;
431
+ let j;
432
+ if (xn(L) === "oculus_direct")
433
+ j = tr($);
431
434
  else {
432
- const q = Pn(i, P), ce = q ? In(q, P) : 0;
433
- O = xn(
434
- I,
435
- q?.word ?? "",
436
- ce
435
+ const X = wr(v, re), Z = X ? sr(X, re) : 0;
436
+ j = ur(
437
+ $,
438
+ X?.word ?? "",
439
+ Z
437
440
  );
438
441
  }
439
- r.push({
440
- viseme: O,
442
+ g.push({
443
+ viseme: j,
441
444
  weight: 1,
442
- vtime: P,
443
- vduration: J
445
+ vtime: re,
446
+ vduration: ge
444
447
  });
445
- }), U());
446
- }, ue = (p, V, W, x, M) => {
447
- He(V, W, x), De(p, W, x, M);
448
- }, se = async (p, V, W, x) => {
449
- if (D || !p?.trim()) {
450
- (V.length > 0 || W.length > 0) && !S && ue(
451
- V,
452
- W,
453
- u,
448
+ }), e.onNotify());
449
+ }, K = (g, v, T, C, x, L, I) => {
450
+ V(v, C, x, L), z(
451
+ g,
452
+ v,
453
+ T,
454
+ x,
455
+ L,
456
+ I
457
+ );
458
+ }, S = async (g, v, T, C, x, L, I) => {
459
+ if (p || !T?.trim()) {
460
+ (C.length > 0 || x.length > 0) && !a && K(
461
+ g,
462
+ v,
463
+ C,
454
464
  x,
455
- E
465
+ _,
466
+ L,
467
+ u
456
468
  );
457
469
  return;
458
470
  }
459
- if (_) {
460
- a.push({
461
- audio: p,
462
- visemes: V,
463
- words: W,
464
- isNewSegment: x
471
+ if (i) {
472
+ n.push({
473
+ audio: T,
474
+ visemes: C,
475
+ words: x,
476
+ isNewSegment: L
465
477
  });
466
478
  return;
467
479
  }
468
- _ = !0;
480
+ i = !0;
469
481
  try {
470
- const M = window.AudioContext || window.webkitAudioContext, I = d ?? new M();
471
- I.state === "suspended" && await I.resume(), d = I;
472
- const Q = await On(I, p);
473
- S = !0;
474
- const J = I.currentTime;
475
- let P = g;
476
- const O = !m;
477
- P < J && (P = J + 0.1), g = P + Q.duration;
478
- const q = I.createBufferSource();
479
- if (q.buffer = Q, q.playbackRate.value = v, q.connect(I.destination), l.push(q), D) {
480
- l.pop();
482
+ const $ = window.AudioContext || window.webkitAudioContext;
483
+ s || (s = new $());
484
+ const Y = s;
485
+ Y.state === "suspended" && await Y.resume();
486
+ const ge = await mr(Y, T);
487
+ a = !0;
488
+ const re = Y.currentTime;
489
+ let j = w;
490
+ const X = !o;
491
+ j < re && (j = re + 0.1), w = j + ge.duration;
492
+ const Z = Y.createBufferSource();
493
+ if (Z.buffer = ge, Z.playbackRate.value = E, Z.connect(Y.destination), r.push(Z), p) {
494
+ r.pop();
481
495
  return;
482
496
  }
483
- if (O) {
484
- m = !0, e("speaking"), w = P, u = 0, r.length = 0, i.length = 0;
485
- const $ = (P - J) * 1e3;
486
- F = performance.now() + $;
497
+ if (X) {
498
+ o = !0, e.onSpeakingStart(), m = j, _ = 0, g.length = 0, v.length = 0, I?.();
499
+ const b = (j - re) * 1e3;
500
+ l = performance.now() + b;
487
501
  }
488
- q.onended = () => {
489
- const $ = l.indexOf(q);
490
- $ >= 0 && l.splice($, 1), X(), U();
491
- }, q.start(P);
492
- const ce = (P - w) * 1e3;
493
- ue(
494
- V,
495
- W,
496
- ce,
502
+ Z.onended = () => {
503
+ const b = r.indexOf(Z);
504
+ b >= 0 && r.splice(b, 1), A(), e.onNotify();
505
+ }, Z.start(j);
506
+ const c = (j - m) * 1e3;
507
+ K(
508
+ g,
509
+ v,
510
+ C,
497
511
  x,
498
- E
512
+ c,
513
+ L,
514
+ u
499
515
  );
500
- } catch (M) {
501
- console.error("[avatarTtsLipsync] audio chunk failed:", M);
516
+ } catch ($) {
517
+ console.error("[avatarChunkPlayback] audio chunk failed:", $);
502
518
  } finally {
503
- _ = !1;
504
- const M = a.shift();
505
- M ? await se(
506
- M.audio,
507
- M.visemes,
508
- M.words,
509
- M.isNewSegment
510
- ) : X();
519
+ i = !1;
520
+ const $ = n.shift();
521
+ $ ? await S(
522
+ g,
523
+ v,
524
+ $.audio,
525
+ $.visemes,
526
+ $.words,
527
+ $.isNewSegment,
528
+ I
529
+ ) : A();
511
530
  }
512
- }, xe = () => {
513
- if (o = !0, !S && r.length > 0) {
514
- Re();
515
- return;
531
+ };
532
+ return {
533
+ setStreamTtsEngineId: (g) => {
534
+ u = g;
535
+ },
536
+ setPlaybackSpeed: (g) => {
537
+ E = Math.max(0.1, Math.min(1, g)), y();
538
+ },
539
+ getPlaybackSpeed: () => E,
540
+ resetForNewStream: (g) => {
541
+ p = !1, f = !1, u = g;
542
+ },
543
+ /** Call from a user gesture before bot audio (connect / unlock). */
544
+ primeAudioContext: async () => {
545
+ const g = window.AudioContext || window.webkitAudioContext;
546
+ s || (s = new g()), s.state === "suspended" && await s.resume();
547
+ },
548
+ stop: () => {
549
+ p = !0, d(), D(), n.length = 0, i = !1, o = !1, a = !1, f = !1, _ = 0, w = 0, m = 0, l = 0;
550
+ },
551
+ markStreamComplete: (g) => {
552
+ if (f = !0, !a && g.length > 0) {
553
+ U(g);
554
+ return;
555
+ }
556
+ A();
557
+ },
558
+ playAudioChunk: S,
559
+ queueTimingsOnly: (g, v, T, C, x) => {
560
+ let L = _;
561
+ x && g.length > 0 && (L = It(g)), K(
562
+ g,
563
+ v,
564
+ T,
565
+ C,
566
+ L,
567
+ x,
568
+ u
569
+ );
570
+ },
571
+ getPlaybackElapsedMs: () => o ? a && s && m > 0 ? Math.max(
572
+ 0,
573
+ (s.currentTime - m) * 1e3
574
+ ) : Math.max(0, (performance.now() - l) * E) : 0,
575
+ isSpeaking: () => o,
576
+ getPlaybackStartPerf: () => l,
577
+ /** User spoke over the bot — drop in-flight chunks until the next utterance. */
578
+ bargeIn: () => {
579
+ p = !0, D(), n.length = 0, i = !1, o = !1, a = !1, w = 0, m = 0, l = 0, d();
580
+ },
581
+ interrupt: () => {
582
+ D(), n.length = 0, i = !1, o = !1, a = !1, w = 0, m = 0, l = 0, d();
516
583
  }
517
- X();
584
+ };
585
+ }
586
+ function at(e, t) {
587
+ let n = null;
588
+ for (const r of e)
589
+ t < r.vtime || t >= r.vtime + r.vduration || (!n || r.vtime >= n.vtime) && (n = r);
590
+ return n ? n.viseme : "sil";
591
+ }
592
+ function Us(e, t) {
593
+ for (const n of e)
594
+ if (t >= n.wtime && t < n.wtime + n.wduration)
595
+ return n;
596
+ return null;
597
+ }
598
+ const zt = 0.5, Yt = 1.5, Jt = "Olivia", gr = "f786b574-daa5-4673-aa0c-cbe3e8534c02", ct = 0.85;
599
+ function Rt(e, t = be) {
600
+ const n = `${t.replace(/\/$/, "")}/avatar_ttsWithPoses`, r = [], s = [], i = [];
601
+ let o = "neutral", a = "", f = Te;
602
+ const l = /* @__PURE__ */ new Set(), m = () => l.forEach((E) => E()), _ = Gt(
603
+ {
604
+ onSpeakingStart: () => e("speaking"),
605
+ onSpeakingDone: () => e("done"),
606
+ onNotify: m
607
+ },
608
+ Te
609
+ ), w = () => {
610
+ _.stop(), r.length = 0, s.length = 0, i.length = 0, o = "neutral", e("idle"), m();
518
611
  };
519
612
  return {
520
- setDeveloperToken: (p) => {
521
- H = p;
613
+ setDeveloperToken: (E) => {
614
+ a = E;
522
615
  },
523
- setTtsEngineId: (p) => {
524
- h = p;
616
+ setTtsEngineId: (E) => {
617
+ f = E;
525
618
  },
526
- getTtsEngineId: () => h,
527
- speak: async (p, V) => {
528
- N(), D = !1, e("loading");
529
- const W = H.trim();
530
- if (!W)
619
+ getTtsEngineId: () => f,
620
+ speak: async (E, u) => {
621
+ w(), e("loading");
622
+ const p = a.trim();
623
+ if (!p)
531
624
  throw new Error("Developer token required for avatar_ttsWithPoses");
532
- const x = V?.ttsEngineId ?? h ?? pe;
533
- E = x;
534
- const M = V?.voiceId ?? It, I = V?.speakingRate ?? At, Q = Math.max(
535
- Un,
536
- Math.min(Bn, I)
537
- ), J = {
538
- user_query: p,
539
- ttsEngineId: x,
540
- speakingRate: Q
625
+ const d = u?.ttsEngineId ?? f ?? Te;
626
+ _.resetForNewStream(d), _.setStreamTtsEngineId(d);
627
+ const D = u?.voiceId ?? Jt, y = u?.speakingRate ?? ct, A = Math.max(
628
+ zt,
629
+ Math.min(Yt, y)
630
+ ), U = {
631
+ user_query: E,
632
+ ttsEngineId: d,
633
+ speakingRate: A
541
634
  };
542
- Jt.has(x) && (J.voice_id = M);
635
+ Mn.has(d) && (U.voice_id = D);
543
636
  try {
544
- const P = await fetch(n, {
637
+ const V = await fetch(n, {
545
638
  method: "POST",
546
639
  headers: {
547
640
  "Content-Type": "application/json",
548
- Authorization: `Bearer ${W}`
641
+ Authorization: `Bearer ${p}`
549
642
  },
550
- body: JSON.stringify(J)
643
+ body: JSON.stringify(U)
551
644
  });
552
- if (!P.ok)
553
- throw new Error(`avatar_ttsWithPoses failed (${P.status})`);
554
- const O = P.body;
555
- if (!O) throw new Error("No response body");
556
- const q = O.getReader(), ce = new TextDecoder();
557
- let $ = "";
558
- const Me = async (B) => {
559
- const b = pn(B);
560
- if (b) {
561
- if (b.event === "audio") {
562
- const K = b.data.chunk, te = b.data.visemes ?? [], Z = b.data.words ?? [], j = b.data.is_new_segment ?? !1;
563
- if (K)
564
- await se(K, te, Z, j);
565
- else if (te.length > 0 || Z.length > 0) {
566
- const _e = j && r.length > 0 ? ut(r) : u;
567
- ue(te, Z, _e, j, x);
568
- }
569
- } else if (b.event === "metadata") {
570
- const K = b.data.mood;
571
- typeof K == "string" && K.trim() && (c = K.trim());
572
- const te = b.data.sentence_emotions;
573
- if (Array.isArray(te)) {
574
- s.length = 0;
575
- for (const Z of te) {
576
- if (!Z || typeof Z != "object") continue;
577
- const j = Z;
578
- s.push({
579
- sentence_index: Number(j.sentence_index ?? 0),
580
- text: String(j.text ?? ""),
581
- sentiment: typeof j.sentiment == "string" ? j.sentiment : void 0,
582
- emotion: String(j.emotion ?? c),
583
- start_word: Number(j.start_word ?? 0),
584
- end_word: Number(j.end_word ?? 0)
645
+ if (!V.ok)
646
+ throw new Error(`avatar_ttsWithPoses failed (${V.status})`);
647
+ const z = V.body;
648
+ if (!z) throw new Error("No response body");
649
+ const K = z.getReader(), S = new TextDecoder();
650
+ let M = "";
651
+ const g = async (v) => {
652
+ const T = Xn(v);
653
+ if (T) {
654
+ if (T.event === "audio") {
655
+ const C = T.data.chunk, x = T.data.visemes ?? [], L = T.data.words ?? [], I = T.data.is_new_segment ?? !1;
656
+ C ? await _.playAudioChunk(
657
+ r,
658
+ s,
659
+ C,
660
+ x,
661
+ L,
662
+ I
663
+ ) : (x.length > 0 || L.length > 0) && _.queueTimingsOnly(
664
+ r,
665
+ s,
666
+ x,
667
+ L,
668
+ I
669
+ );
670
+ } else if (T.event === "metadata") {
671
+ const C = T.data.mood;
672
+ typeof C == "string" && C.trim() && (o = C.trim());
673
+ const x = T.data.sentence_emotions;
674
+ if (Array.isArray(x)) {
675
+ i.length = 0;
676
+ for (const L of x) {
677
+ if (!L || typeof L != "object") continue;
678
+ const I = L;
679
+ i.push({
680
+ sentence_index: Number(I.sentence_index ?? 0),
681
+ text: String(I.text ?? ""),
682
+ sentiment: typeof I.sentiment == "string" ? I.sentiment : void 0,
683
+ emotion: String(I.emotion ?? o),
684
+ start_word: Number(I.start_word ?? 0),
685
+ end_word: Number(I.end_word ?? 0)
585
686
  });
586
687
  }
587
688
  }
588
- U();
589
- } else if (b.event === "error")
689
+ m();
690
+ } else if (T.event === "error")
590
691
  throw new Error(
591
- String(b.data.message ?? "avatar_ttsWithPoses stream error")
692
+ String(T.data.message ?? "avatar_ttsWithPoses stream error")
592
693
  );
593
694
  }
594
695
  };
595
696
  for (; ; ) {
596
- const { done: B, value: b } = await q.read();
597
- b && ($ += ce.decode(b, { stream: !0 }));
598
- const K = $.split(`
697
+ const { done: v, value: T } = await K.read();
698
+ T && (M += S.decode(T, { stream: !0 }));
699
+ const C = M.split(`
599
700
 
600
701
  `);
601
- $ = K.pop() ?? "";
602
- for (const te of K) await Me(te);
603
- if (B) {
604
- $.trim() && await Me($.trim()), D || xe();
702
+ M = C.pop() ?? "";
703
+ for (const x of C) await g(x);
704
+ if (v) {
705
+ M.trim() && await g(M.trim()), _.markStreamComplete(r);
605
706
  break;
606
707
  }
607
708
  }
608
- } catch (P) {
609
- throw console.error("[avatarTtsLipsync]", P), N(), e("error"), P;
709
+ } catch (V) {
710
+ throw console.error("[avatarTtsLipsync]", V), w(), e("error"), V;
610
711
  }
611
712
  },
612
- stop: N,
713
+ stop: w,
613
714
  getVisemeQueue: () => r,
614
- getWordQueue: () => i,
715
+ getWordQueue: () => s,
716
+ getSentenceEmotions: () => i,
717
+ getStreamMood: () => o,
718
+ getPlaybackElapsedMs: () => _.getPlaybackElapsedMs(),
719
+ isSpeaking: () => _.isSpeaking(),
720
+ setPlaybackSpeed: (E) => {
721
+ _.setPlaybackSpeed(E);
722
+ },
723
+ getPlaybackSpeed: () => _.getPlaybackSpeed(),
724
+ subscribe: (E) => (l.add(E), () => l.delete(E))
725
+ };
726
+ }
727
+ const Qt = 16e3, Xt = 24e3;
728
+ class _r extends En {
729
+ constructor() {
730
+ super(
731
+ !0,
732
+ !0,
733
+ void 0,
734
+ void 0,
735
+ 512,
736
+ Qt,
737
+ Xt
738
+ );
739
+ }
740
+ /** Pipecat protobuf bot audio is unused — playback comes from avatar_audio_chunk. */
741
+ bufferBotAudio(t, n) {
742
+ }
743
+ }
744
+ const pr = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
745
+ function yr(e) {
746
+ return pr.test(e.trim());
747
+ }
748
+ function kr(e) {
749
+ const t = e.replace(/\/$/, "");
750
+ return t.startsWith("https://") ? `wss://${t.slice(8)}` : t.startsWith("http://") ? `ws://${t.slice(7)}` : t;
751
+ }
752
+ function Er(e) {
753
+ if (e.wsUrl?.trim()) return e.wsUrl.trim();
754
+ const t = e.authToken?.trim();
755
+ if (!t)
756
+ throw new Error(
757
+ "Voice connect requires authToken (same JWT as SSE Authorization Bearer)."
758
+ );
759
+ const n = e.apiBase ?? be, r = new URL(`${kr(n)}/ws/voice`);
760
+ r.searchParams.set("authToken", t);
761
+ const s = e.voiceId?.trim();
762
+ s && yr(s) && r.searchParams.set("voiceId", s);
763
+ const i = e.speakingRate ?? ct;
764
+ return r.searchParams.set(
765
+ "speaking_rate",
766
+ String(Math.max(zt, Math.min(Yt, i)))
767
+ ), e.ttsStream === !1 ? r.searchParams.set("tts_stream", "false") : r.searchParams.set("tts_stream", "true"), r.toString();
768
+ }
769
+ function Dt(e, t) {
770
+ if (!Array.isArray(e)) return [];
771
+ const n = [];
772
+ for (const r of e)
773
+ !r || typeof r != "object" || n.push({
774
+ sentence_index: Number(r.sentence_index ?? 0),
775
+ text: String(r.text ?? ""),
776
+ sentiment: typeof r.sentiment == "string" ? r.sentiment : void 0,
777
+ emotion: String(r.emotion ?? t),
778
+ start_word: Number(r.start_word ?? 0),
779
+ end_word: Number(r.end_word ?? 0)
780
+ });
781
+ return n;
782
+ }
783
+ function Sr(e) {
784
+ if (!e || typeof e != "object") return null;
785
+ const t = e, n = t.data;
786
+ return n && typeof n == "object" ? n : t;
787
+ }
788
+ function vr(e, t = {}) {
789
+ const n = [], r = [], s = [], i = [];
790
+ let o = "", a = "neutral", f = Ae, l = !1, m = null, _ = null, w = { ...t }, k = 0, E = null;
791
+ const u = /* @__PURE__ */ new Set(), p = [];
792
+ let d = !1, D = null;
793
+ const y = () => u.forEach((c) => c()), A = Gt(
794
+ {
795
+ onSpeakingStart: () => e("speaking"),
796
+ onSpeakingDone: () => e("done"),
797
+ onNotify: y
798
+ },
799
+ f
800
+ ), U = () => {
801
+ if (D) return D;
802
+ const c = new MessageChannel();
803
+ return c.port1.onmessage = () => {
804
+ const b = p.shift();
805
+ b !== void 0 && $(b), p.length > 0 ? c.port2.postMessage(null) : d = !1;
806
+ }, D = c, c;
807
+ }, V = (c) => {
808
+ p.push(c), !d && (d = !0, U().port2.postMessage(null));
809
+ }, z = () => A.getPlaybackElapsedMs(), K = (c, b = o) => {
810
+ if (!w.onLipsyncDebug) return;
811
+ const B = z(), Q = n;
812
+ w.onLipsyncDebug({
813
+ event: c,
814
+ spokenText: b,
815
+ mood: a,
816
+ playbackAnchorPerf: A.getPlaybackStartPerf(),
817
+ playbackElapsedMs: B,
818
+ queueLength: Q.length,
819
+ activeViseme: at(Q, B),
820
+ segments: i.map((G) => ({
821
+ ...G,
822
+ visemes: [...G.visemes]
823
+ }))
824
+ });
825
+ }, S = (c, b) => {
826
+ w.onLipsyncDebug && (E = { event: c, spokenText: b }, k === 0 && (k = requestAnimationFrame(() => {
827
+ k = 0;
828
+ const B = E;
829
+ E = null, B && K(B.event, B.spokenText);
830
+ })));
831
+ }, M = () => {
832
+ n.length = 0, r.length = 0, i.length = 0, o = "", a = "neutral", s.length = 0;
833
+ }, g = () => {
834
+ A.stop(), M(), S("reset"), y();
835
+ }, v = () => {
836
+ g(), e("idle"), y();
837
+ }, T = (c, b) => {
838
+ typeof c.mood == "string" && c.mood.trim() && (a = c.mood.trim()), Array.isArray(c.sentence_emotions) && c.sentence_emotions.length > 0 && (b && (s.length = 0), s.push(
839
+ ...Dt(c.sentence_emotions, a)
840
+ ));
841
+ }, C = (c) => {
842
+ const b = String(c.spoken_text ?? c.text ?? "").trim();
843
+ b && (o = b), A.resetForNewStream(f), typeof c.mood == "string" && c.mood.trim() && (a = c.mood.trim()), s.length = 0, s.push(
844
+ ...Dt(c.sentence_emotions, a)
845
+ ), Array.isArray(c.gestures) && c.gestures, S("metadata", b), y();
846
+ }, x = (c, b, B, Q) => {
847
+ if (!w.onLipsyncDebug) return;
848
+ const G = n.slice(B), ue = Q.filter(
849
+ (H) => String(H.symbol ?? H.viseme ?? "").trim()
850
+ );
851
+ i.push({
852
+ spokenText: b,
853
+ audioOffsetMs: G[0]?.vtime ?? 0,
854
+ isNewSegment: !!c.is_new_segment,
855
+ chunkDurationMs: c.chunk_duration_ms != null ? Number(c.chunk_duration_ms) : null,
856
+ receivedAtMs: performance.now(),
857
+ visemes: G.map((H, _e) => {
858
+ const le = ue[_e];
859
+ return {
860
+ rawSymbol: String(le?.symbol ?? le?.viseme ?? H.viseme).trim(),
861
+ viseme: H.viseme,
862
+ startSec: Number(le?.start ?? 0),
863
+ durationSec: Number(le?.duration ?? 0),
864
+ vtimeMs: H.vtime,
865
+ vdurationMs: H.vduration
866
+ };
867
+ })
868
+ });
869
+ }, L = (c) => {
870
+ const b = String(c.spoken_text ?? c.text ?? "").trim(), B = !!c.is_new_segment || Number(c.chunk_index ?? -1) === 0, Q = c.visemes ?? [], G = c.words ?? [], ue = String(c.chunk ?? "").trim();
871
+ b && (o = b), T(c, B), B && A.resetForNewStream(f);
872
+ const H = n.length;
873
+ A.playAudioChunk(
874
+ n,
875
+ r,
876
+ ue,
877
+ Q,
878
+ G,
879
+ B,
880
+ () => {
881
+ i.length = 0;
882
+ }
883
+ ).then(() => {
884
+ x(c, b, H, Q), S("audio_chunk", b);
885
+ });
886
+ }, I = (c) => {
887
+ console.warn(
888
+ "[realtimeVoice] avatar_lipsync is deprecated — expect avatar_audio_chunk"
889
+ );
890
+ const b = String(c.spoken_text ?? c.text ?? "").trim();
891
+ b && (o = b), T(c, !!c.is_new_segment);
892
+ const B = n.length;
893
+ A.queueTimingsOnly(
894
+ n,
895
+ r,
896
+ c.visemes ?? [],
897
+ c.words ?? [],
898
+ !!c.is_new_segment
899
+ ), x(
900
+ c,
901
+ b,
902
+ B,
903
+ c.visemes ?? []
904
+ ), S("lipsync", b), y();
905
+ }, $ = (c) => {
906
+ const b = Sr(c);
907
+ if (!b) {
908
+ console.warn("[realtimeVoice] server message with no payload", c);
909
+ return;
910
+ }
911
+ const B = String(b.type ?? "unknown");
912
+ switch (B !== "avatar_metadata" && B !== "avatar_audio_chunk" && B !== "avatar_lipsync" && B !== "error" && console.debug("[realtimeVoice] server message", B, b), B) {
913
+ case "avatar_metadata":
914
+ C(b);
915
+ break;
916
+ case "avatar_audio_chunk":
917
+ L(b);
918
+ break;
919
+ case "avatar_lipsync":
920
+ I(b);
921
+ break;
922
+ case "error": {
923
+ const Q = String(b.message ?? "Voice session error");
924
+ console.error("[realtimeVoice] server error:", Q), e("error"), y();
925
+ break;
926
+ }
927
+ case "avatar_speak":
928
+ console.warn(
929
+ "[realtimeVoice] avatar_speak received; tts_stream=false Mode B is not wired yet:",
930
+ b.text
931
+ );
932
+ break;
933
+ }
934
+ }, Y = () => m || (_ = new _r(), m = new yn({
935
+ transport: new kn({
936
+ mediaManager: _,
937
+ recorderSampleRate: Qt,
938
+ playerSampleRate: Xt
939
+ }),
940
+ enableCam: !1,
941
+ enableMic: !0,
942
+ callbacks: {
943
+ onBotReady: () => {
944
+ l = !0, e("idle"), y();
945
+ },
946
+ onDisconnected: () => {
947
+ l = !1, v();
948
+ },
949
+ onError: (c) => {
950
+ const b = typeof c == "object" && c !== null && "data" in c ? String(c.data ?? c) : String(c);
951
+ console.error("[realtimeVoice]", b, c), e("error"), y();
952
+ },
953
+ onTransportStateChanged: (c) => {
954
+ c === "error" && (e("error"), y());
955
+ },
956
+ onServerMessage: (c) => {
957
+ V(c);
958
+ },
959
+ onUserStartedSpeaking: () => {
960
+ A.bargeIn(), M(), e("idle"), S("user_started"), y();
961
+ },
962
+ onBotStartedSpeaking: () => {
963
+ S("bot_started");
964
+ },
965
+ onBotStoppedSpeaking: () => {
966
+ A.markStreamComplete(n), S("bot_stopped");
967
+ },
968
+ onUserTranscript: (c) => {
969
+ w.onUserTranscript?.(c.text, !!c.final);
970
+ },
971
+ onBotOutput: (c) => {
972
+ w.onBotOutput?.(c.text);
973
+ }
974
+ }
975
+ }), m);
976
+ return {
977
+ setDeveloperToken: (c) => {
978
+ },
979
+ setTtsEngineId: (c) => {
980
+ f = c, A.setStreamTtsEngineId(c);
981
+ },
982
+ getTtsEngineId: () => f,
983
+ speak: async (c, b) => {
984
+ const B = c.trim();
985
+ if (B) {
986
+ if (!m || !l)
987
+ throw new Error(
988
+ "Realtime voice is not connected. Call connect() first."
989
+ );
990
+ g(), await m.sendText(B);
991
+ }
992
+ },
993
+ stop: () => {
994
+ g(), e("idle"), y();
995
+ },
996
+ connect: async (c) => {
997
+ if (c && (w = { ...w, ...c }), !w.authToken?.trim())
998
+ throw new Error(
999
+ "Voice connect requires authToken (same JWT as SSE Authorization Bearer)."
1000
+ );
1001
+ e("loading");
1002
+ const b = Y();
1003
+ await b.initDevices();
1004
+ const B = Er(w);
1005
+ console.info("[realtimeVoice] connecting (avatar_audio_chunk RTVI):", B);
1006
+ try {
1007
+ await b.connect({ wsUrl: B });
1008
+ } catch (Q) {
1009
+ l = !1, e("error"), y();
1010
+ const G = Q instanceof Error ? Q.message : "Realtime voice connect failed (WebSocket 101 only means upgrade OK — check authToken/origin/RTVI handshake)";
1011
+ throw new Error(`${G} — ${B}`);
1012
+ }
1013
+ l = !0, e("idle"), y();
1014
+ },
1015
+ disconnect: async () => {
1016
+ if (p.length = 0, d = !1, m)
1017
+ try {
1018
+ await m.disconnect();
1019
+ } catch (c) {
1020
+ console.error("[realtimeVoice] disconnect failed:", c);
1021
+ }
1022
+ l = !1, v();
1023
+ },
1024
+ isConnected: () => l,
1025
+ unlockAudio: async () => {
1026
+ await A.primeAudioContext();
1027
+ },
1028
+ getVisemeQueue: () => n,
1029
+ getWordQueue: () => r,
615
1030
  getSentenceEmotions: () => s,
616
- getStreamMood: () => c,
617
- getPlaybackElapsedMs: () => m ? S && d && w > 0 ? Math.max(
618
- 0,
619
- (d.currentTime - w) * 1e3
620
- ) : Math.max(0, (performance.now() - F) * v) : 0,
621
- isSpeaking: () => m,
622
- setPlaybackSpeed: (p) => {
623
- v = Math.max(0.1, Math.min(1, p)), z();
1031
+ getStreamMood: () => a,
1032
+ getPlaybackElapsedMs: z,
1033
+ isSpeaking: () => A.isSpeaking(),
1034
+ setPlaybackSpeed: (c) => {
1035
+ A.setPlaybackSpeed(c);
624
1036
  },
625
- getPlaybackSpeed: () => v,
626
- subscribe: (p) => (L.add(p), () => L.delete(p))
1037
+ getPlaybackSpeed: () => A.getPlaybackSpeed(),
1038
+ subscribe: (c) => (u.add(c), () => u.delete(c))
627
1039
  };
628
1040
  }
629
- function $n(e, t, n) {
1041
+ function br(e, t, n) {
630
1042
  return {
631
1043
  width: e.crop?.source_width ?? t,
632
1044
  height: e.crop?.source_height ?? n
633
1045
  };
634
1046
  }
635
- function Hn(e, t) {
1047
+ function Tr(e, t) {
636
1048
  const n = e.crop;
637
1049
  return {
638
1050
  x: t?.source_x ?? n?.x ?? 0,
@@ -641,57 +1053,64 @@ function Hn(e, t) {
641
1053
  height: t?.source_h ?? n?.height ?? e.frame_height ?? 0
642
1054
  };
643
1055
  }
644
- function Wn(e) {
1056
+ function Ar(e) {
645
1057
  return e ? (e.w ?? 0) > 0 && (e.h ?? 0) > 0 : !1;
646
1058
  }
647
- async function Ve(e, t) {
1059
+ async function Ge(e, t) {
648
1060
  const n = await fetch(e);
649
1061
  if (!n.ok) throw new Error(`Failed to load encrypted asset: ${e}`);
650
1062
  const r = await n.arrayBuffer();
651
- return ln(r, t);
1063
+ return Wn(r, t);
652
1064
  }
653
- async function qn(e, t) {
1065
+ async function Ir(e, t) {
654
1066
  if (!t) throw new Error("Missing asset key for encrypted JSON");
655
- const n = await Ve(e, t), r = new TextDecoder().decode(n);
1067
+ const n = await Ge(e, t), r = new TextDecoder().decode(n);
656
1068
  return JSON.parse(r);
657
1069
  }
658
- async function Kn(e) {
1070
+ async function Rr(e) {
659
1071
  const t = new Blob([e], { type: "image/webp" }), n = URL.createObjectURL(t);
660
- return new Promise((r, i) => {
661
- const s = new Image();
662
- s.decoding = "async", s.onload = () => {
663
- URL.revokeObjectURL(n), r(s);
664
- }, s.onerror = () => {
665
- URL.revokeObjectURL(n), i(new Error("Failed to decode decrypted image"));
666
- }, s.src = n;
1072
+ return new Promise((r, s) => {
1073
+ const i = new Image();
1074
+ i.decoding = "async", i.onload = () => {
1075
+ URL.revokeObjectURL(n), r(i);
1076
+ }, i.onerror = () => {
1077
+ URL.revokeObjectURL(n), s(new Error("Failed to decode decrypted image"));
1078
+ }, i.src = n;
667
1079
  });
668
1080
  }
669
- async function jn(e) {
1081
+ async function Dr(e) {
670
1082
  const t = new Blob([e], { type: "image/png" }), n = URL.createObjectURL(t);
671
- return new Promise((r, i) => {
672
- const s = new Image();
673
- s.decoding = "async", s.onload = () => {
674
- URL.revokeObjectURL(n), r(s);
675
- }, s.onerror = () => {
676
- URL.revokeObjectURL(n), i(new Error("Failed to decode decrypted PNG"));
677
- }, s.src = n;
1083
+ return new Promise((r, s) => {
1084
+ const i = new Image();
1085
+ i.decoding = "async", i.onload = () => {
1086
+ URL.revokeObjectURL(n), r(i);
1087
+ }, i.onerror = () => {
1088
+ URL.revokeObjectURL(n), s(new Error("Failed to decode decrypted PNG"));
1089
+ }, i.src = n;
678
1090
  });
679
1091
  }
680
- function Gn(e) {
1092
+ function Mr(e) {
681
1093
  const t = new Blob([e], { type: "video/mp4" });
682
1094
  return URL.createObjectURL(t);
683
1095
  }
684
- async function zn(e) {
685
- const t = _n();
686
- if (!Be()) return t;
1096
+ async function xr(e) {
1097
+ const t = zn();
1098
+ if (!Ke()) return t;
687
1099
  if (!e) throw new Error("Missing asset key for encrypted idle video");
688
- const n = await Ve(t, e);
689
- return Gn(n);
1100
+ const n = await Ge(t, e);
1101
+ return Mr(n);
690
1102
  }
691
- function bt(e, t) {
1103
+ function ut(e, t) {
692
1104
  return `${e}/${t}_minus_sil.png`;
693
1105
  }
694
- const et = 15, Gr = [
1106
+ const Zt = 5;
1107
+ function en(e) {
1108
+ const t = e?.composite_threshold;
1109
+ if (typeof t == "number" && t > 0) return t;
1110
+ const n = e?.crop?.content_threshold;
1111
+ return typeof n == "number" && n > 0 ? n : Zt;
1112
+ }
1113
+ const Ns = [
695
1114
  "aa",
696
1115
  "E",
697
1116
  "I",
@@ -706,13 +1125,13 @@ const et = 15, Gr = [
706
1125
  "RR",
707
1126
  "kk",
708
1127
  "nn"
709
- ], ze = [
1128
+ ], nt = [
710
1129
  "t01_0.17",
711
1130
  "t02_0.33",
712
1131
  "t03_0.50",
713
1132
  "t04_0.67",
714
1133
  "t05_0.83"
715
- ], Qn = ze.length, lt = /* @__PURE__ */ new Set([
1134
+ ], Cr = nt.length, Mt = /* @__PURE__ */ new Set([
716
1135
  "aa__kk",
717
1136
  "aa__nn",
718
1137
  "aa__sil",
@@ -819,59 +1238,101 @@ const et = 15, Gr = [
819
1238
  "U__nn",
820
1239
  "U__sil"
821
1240
  ]);
822
- function ft(e, t) {
1241
+ function xt(e, t) {
823
1242
  return `${e}__${t}`;
824
1243
  }
825
- function dt(e, t) {
1244
+ function Ct(e, t) {
826
1245
  return `pairs/${e}/${t}_minus_sil.png`;
827
1246
  }
828
- function Qe(e) {
1247
+ function We(e) {
829
1248
  return `${e}_minus_sil.png`;
830
1249
  }
831
- function Rt(e, t) {
1250
+ function Pr(e, t) {
1251
+ if (t.has(e)) return e;
1252
+ const n = /^pairs\/([^/]+)\//.exec(e);
1253
+ if (!n) return null;
1254
+ const r = n[1].split("__")[1];
1255
+ if (!r || r === "sil") return null;
1256
+ const s = We(r);
1257
+ return t.has(s) ? s : null;
1258
+ }
1259
+ function tn(e, t) {
1260
+ return e.filter((n) => t.has(n));
1261
+ }
1262
+ function Br(e, t, n) {
1263
+ const r = lt(e, t);
1264
+ return tn(r, n).length > 0;
1265
+ }
1266
+ function lt(e, t) {
832
1267
  if (e === t) return [];
833
- const n = [], r = ft(e, t);
834
- if (lt.has(r)) {
835
- for (const s of ze)
836
- n.push(dt(r, s));
1268
+ const n = [], r = xt(e, t);
1269
+ if (Mt.has(r)) {
1270
+ for (const i of nt)
1271
+ n.push(Ct(r, i));
837
1272
  return n;
838
1273
  }
839
- const i = ft(t, e);
840
- if (lt.has(i)) {
841
- for (let s = Qn - 1; s >= 0; s--)
842
- n.push(dt(i, ze[s]));
1274
+ const s = xt(t, e);
1275
+ if (Mt.has(s)) {
1276
+ for (let i = Cr - 1; i >= 0; i--)
1277
+ n.push(Ct(s, nt[i]));
843
1278
  return n;
844
1279
  }
845
1280
  return [];
846
1281
  }
847
- function Jn(e) {
1282
+ function Or(e) {
848
1283
  return e < 16 ? [] : e < 35 ? [2] : e < 51 ? [0, 4] : e < 67 ? [0, 2, 4] : e < 83 ? [0, 1, 2, 3] : [0, 1, 2, 3, 4];
849
1284
  }
850
- function Yn(e, t) {
851
- return Jn(t).map((r) => e[r]).filter((r) => r != null);
1285
+ function Lr(e, t) {
1286
+ return Or(t).map((r) => e[r]).filter((r) => r != null);
852
1287
  }
853
- function Xn(e, t, n, r) {
1288
+ function Fr(e, t, n, r) {
854
1289
  if (r <= 0) return 0;
855
- const s = Math.max(1, n - t) / r, c = e - t, a = Math.floor(c / s);
1290
+ const i = Math.max(1, n - t) / r, o = e - t, a = Math.floor(o / i);
856
1291
  return Math.min(r - 1, Math.max(0, a));
857
1292
  }
858
- function Zn(e, t, n) {
1293
+ function Ur(e, t, n) {
859
1294
  if (!n) return `${e}/${t}`;
860
- const r = t.split("/").pop() ?? t, i = r.includes(".") ? r.slice(0, r.lastIndexOf(".")) : r;
861
- return `${e}/${i}.bin`;
1295
+ const r = t.split("/").pop() ?? t, s = r.includes(".") ? r.slice(0, r.lastIndexOf(".")) : r;
1296
+ return `${e}/${s}.bin`;
862
1297
  }
863
- const er = [0.32, 0.24, 0.16, 0.08, 0], $e = er.map(
1298
+ const Nr = [0.32, 0.24, 0.16, 0.08, 0], Vr = Nr.map(
864
1299
  (e) => `eyes_${e.toFixed(2)}`
865
- ), tr = [
1300
+ ), $r = [
866
1301
  "eyes_0.32",
867
1302
  "eyes_0.16",
868
1303
  "eyes_0.00"
869
- ], nr = [
1304
+ ], Hr = [
870
1305
  "eyes_0.32",
871
1306
  "eyes_0.16",
872
1307
  "eyes_0.08",
873
1308
  "eyes_0.00"
874
- ], rr = {
1309
+ ], Pt = 2, Wr = -30, rt = 20, qr = {
1310
+ fear: -30,
1311
+ anger: -20,
1312
+ sad: -10,
1313
+ neutral: 0,
1314
+ love: 10,
1315
+ happy: 0,
1316
+ disgust: 20
1317
+ };
1318
+ function ft(e) {
1319
+ return `brow_${e}`;
1320
+ }
1321
+ function dt(e) {
1322
+ return qr[e];
1323
+ }
1324
+ function ke(e) {
1325
+ return Math.max(Wr, Math.min(rt, e));
1326
+ }
1327
+ function Kr(e, t) {
1328
+ if (e === t) return [];
1329
+ const n = e < t ? Pt : -Pt, r = [];
1330
+ let s = e;
1331
+ for (; s !== t; )
1332
+ s += n, r.push(s);
1333
+ return r;
1334
+ }
1335
+ const jr = {
875
1336
  fear: "fear",
876
1337
  afraid: "fear",
877
1338
  anxiety: "fear",
@@ -894,219 +1355,220 @@ const er = [0.32, 0.24, 0.16, 0.08, 0], $e = er.map(
894
1355
  disgust: "disgust",
895
1356
  disgusted: "disgust"
896
1357
  };
897
- function ye(e, t = "neutral") {
1358
+ function ve(e, t = "neutral") {
898
1359
  const n = String(e ?? "").trim().toLowerCase();
899
- return n ? rr[n] ?? t : t;
900
- }
901
- function ee(e) {
902
- return e === "neutral" ? null : bt(e, "eyes_standard");
1360
+ return n ? jr[n] ?? t : t;
903
1361
  }
904
- function Je(e, t) {
905
- return !t || t === "eyes_standard" ? ee(e) : e === "neutral" && t === "eyes_standard" ? null : bt(e, t);
1362
+ function nn(e) {
1363
+ return e === 0 ? null : ut(ft(e), "eyes_standard");
906
1364
  }
907
- function ir(e) {
908
- if (!e) return "open";
909
- const t = e.match(/\/(eyes_[^/]+)_minus_sil\.png$/);
910
- if (!t?.[1]) return "open";
911
- const n = t[1];
912
- return $e.includes(n) ? n : "open";
1365
+ function rn(e) {
1366
+ return nn(dt(e));
913
1367
  }
914
- function sr(e) {
915
- return e === "open" ? -1 : $e.indexOf(e);
1368
+ function Bt(e, t) {
1369
+ const n = ft(dt(e));
1370
+ return !t || t === "eyes_standard" ? rn(e) : e === "neutral" && t === "eyes_standard" ? null : ut(n, t);
916
1371
  }
917
- function or(e, t) {
1372
+ function Gr(e, t) {
918
1373
  const n = [];
919
1374
  for (const r of t)
920
- n.push(Je(e, r));
1375
+ n.push(Bt(e, r));
921
1376
  for (let r = t.length - 2; r >= 0; r--)
922
- n.push(Je(e, t[r]));
923
- return n.push(ee(e)), n;
1377
+ n.push(Bt(e, t[r]));
1378
+ return n.push(rn(e)), n;
924
1379
  }
925
- function ar(e, t) {
926
- if (t === "open") return [ee(e)];
927
- const n = sr(t);
928
- if (n < 0) return [ee(e)];
929
- const r = [];
930
- for (let i = n; i >= 0; i--)
931
- r.push(Je(e, $e[i]));
932
- return r.push(ee(e)), r;
933
- }
934
- const cr = [
935
- "t01_0.20",
936
- "t02_0.40",
937
- "t03_0.60",
938
- "t04_0.80"
939
- ];
940
- function ur(e, t) {
941
- return `${e}__${t}`;
1380
+ function zr(e) {
1381
+ return ut(ft(e), "eyes_standard");
942
1382
  }
943
- function lr(e, t, n) {
944
- return `pairs/${ur(e, t)}/${n}_minus_sil.png`;
1383
+ function Yr(e, t) {
1384
+ return Kr(e, t).map(zr);
945
1385
  }
946
- function fr(e, t) {
947
- return cr.map(
948
- (n) => lr(e, t, n)
949
- );
1386
+ const Jr = 6;
1387
+ function Qr(e, t) {
1388
+ for (const n of e)
1389
+ if (t >= n.wtime && t < n.wtime + n.wduration)
1390
+ return n;
1391
+ return null;
1392
+ }
1393
+ function Xr(e) {
1394
+ const t = ke(e);
1395
+ return t >= rt ? rt : ke(t + Jr);
1396
+ }
1397
+ function Zr(e, t, n) {
1398
+ const r = ke(n);
1399
+ return Qr(t, e)?.emphasis ? Xr(r) : r;
950
1400
  }
951
- function ve(e, t) {
1401
+ function Ot(e) {
1402
+ if (!e) return 0;
1403
+ const t = e.match(/^brow_(-?\d+)\//);
1404
+ if (!t?.[1]) return null;
1405
+ const n = Number.parseInt(t[1], 10);
1406
+ return Number.isFinite(n) ? ke(n) : null;
1407
+ }
1408
+ function Pe(e, t) {
952
1409
  return e + Math.random() * (t - e);
953
1410
  }
954
- function Le() {
955
- return ve(14, 32);
1411
+ function Ve() {
1412
+ return Pe(14, 32);
956
1413
  }
957
- function dr(e = {}) {
1414
+ function es(e = {}) {
958
1415
  const {
959
1416
  initialDelayMs: t = 800 + Math.random() * 1200,
960
1417
  intervalMinMs: n = 2200,
961
1418
  intervalMaxMs: r = 5800,
962
- doubleBlinkChance: i = 0.18,
963
- doubleBlinkGapMinMs: s = 120,
964
- doubleBlinkGapMaxMs: c = 220,
1419
+ doubleBlinkChance: s = 0.18,
1420
+ doubleBlinkGapMinMs: i = 120,
1421
+ doubleBlinkGapMaxMs: o = 220,
965
1422
  fullBlinkChance: a = 0.75,
966
- postEmotionChangeDelayMs: l = 380,
967
- minDwellMs: d = 550
1423
+ postEmotionChangeDelayMs: f = 380,
1424
+ minDwellMs: l = 550
968
1425
  } = e;
969
- let _ = "neutral", m = "neutral", S = 0, o = {
1426
+ let m = "neutral", _ = "neutral", w = 0, k = 0, E = 0, u = {
970
1427
  kind: "idle",
971
1428
  nextBlinkAt: performance.now() + t
972
- }, F = null, w = "__eyes_open__|neutral";
973
- function u(h, E) {
974
- F = h, w = `${h ?? "__eyes_open__"}|${E}`;
1429
+ }, p = null, d = "__eyes_open__|neutral|brow:0";
1430
+ function D(S = m) {
1431
+ d = `${p ?? "__eyes_open__"}|${S}|brow:${k}`;
1432
+ }
1433
+ function y(S, M = m) {
1434
+ p = S;
1435
+ const g = Ot(S);
1436
+ g != null ? k = g : S == null && (k = 0), D(M);
1437
+ }
1438
+ function A(S) {
1439
+ return nn(S);
975
1440
  }
976
- function g(h, E) {
977
- o = {
1441
+ function U(S, M, g) {
1442
+ const v = ke(M), T = ke(g);
1443
+ if (w = T, v === T) {
1444
+ y(A(T));
1445
+ return;
1446
+ }
1447
+ const C = [
1448
+ ...Yr(v, T),
1449
+ A(T)
1450
+ ];
1451
+ u = {
1452
+ kind: "browBlend",
1453
+ paths: C,
1454
+ index: 0,
1455
+ holdUntil: S + Ve(),
1456
+ targetBrow: T
1457
+ }, y(C[0] ?? null);
1458
+ }
1459
+ function V(S, M) {
1460
+ u = {
978
1461
  kind: "idle",
979
- nextBlinkAt: h + ve(n, r)
980
- }, m = E, u(ee(E), E);
1462
+ nextBlinkAt: S + Pe(n, r)
1463
+ }, _ = M, y(A(w), M);
981
1464
  }
982
- function y(h, E, D) {
983
- const L = D ? tr : Math.random() < a ? $e : nr;
984
- o = {
1465
+ function z(S, M, g) {
1466
+ const v = g ? $r : Math.random() < a ? Vr : Hr;
1467
+ u = {
985
1468
  kind: "playing",
986
- paths: or(E, L),
1469
+ paths: Gr(M, v),
987
1470
  index: 0,
988
- holdUntil: h + Le(),
1471
+ holdUntil: S + Ve(),
989
1472
  after: "idle",
990
- blinkEmotion: E
991
- }, m = E, u(o.paths[0] ?? null, E);
992
- }
993
- function v(h, E, D) {
994
- const L = ir(F), z = [];
995
- if (L !== "open") {
996
- const U = ar(E, L);
997
- z.push(...U.slice(0, -1));
998
- }
999
- z.push(...fr(E, D)), z.push(ee(D)), o = {
1000
- kind: "emotionBlend",
1001
- paths: z,
1002
- index: 0,
1003
- holdUntil: h + Le(),
1004
- thenEmotion: D
1005
- }, u(z[0] ?? null, E);
1473
+ blinkEmotion: M
1474
+ }, _ = M, y(u.paths[0] ?? null, M);
1006
1475
  }
1007
- function H(h) {
1008
- if (o.kind === "emotionBlend") {
1009
- for (; h >= o.holdUntil && o.index < o.paths.length - 1; )
1010
- o.index += 1, o.holdUntil = h + Le();
1011
- const E = o.paths[o.index] ?? null;
1012
- u(E, o.thenEmotion), h >= o.holdUntil && o.index >= o.paths.length - 1 && (_ = o.thenEmotion, m = o.thenEmotion, u(ee(o.thenEmotion), o.thenEmotion), o = {
1476
+ function K(S) {
1477
+ if (u.kind === "browBlend") {
1478
+ for (; S >= u.holdUntil && u.index < u.paths.length - 1; )
1479
+ u.index += 1, u.holdUntil = S + Ve();
1480
+ const M = u.paths[u.index] ?? null;
1481
+ y(M), S >= u.holdUntil && u.index >= u.paths.length - 1 && (k = u.targetBrow, w = u.targetBrow, y(A(u.targetBrow)), u = {
1013
1482
  kind: "idle",
1014
- nextBlinkAt: h + l
1483
+ nextBlinkAt: S + f
1015
1484
  });
1016
1485
  return;
1017
1486
  }
1018
- if (o.kind === "idle") {
1019
- u(ee(m), m), h >= o.nextBlinkAt && y(h, m, !1);
1487
+ if (u.kind === "idle") {
1488
+ y(A(w), _), S >= u.nextBlinkAt && z(S, _, !1);
1020
1489
  return;
1021
1490
  }
1022
- if (o.kind === "doublePause") {
1023
- u(ee(o.blinkEmotion), o.blinkEmotion), h >= o.resumeAt && y(h, o.blinkEmotion, !0);
1491
+ if (u.kind === "doublePause") {
1492
+ y(A(w), u.blinkEmotion), S >= u.resumeAt && z(S, u.blinkEmotion, !0);
1024
1493
  return;
1025
1494
  }
1026
- if (o.kind === "playing") {
1027
- for (; h >= o.holdUntil && o.index < o.paths.length - 1; )
1028
- o.index += 1, o.holdUntil = h + Le();
1029
- if (u(o.paths[o.index] ?? null, o.blinkEmotion), h >= o.holdUntil && o.index >= o.paths.length - 1) {
1030
- if (o.after === "resumeIdle") {
1031
- g(h + l, _);
1495
+ if (u.kind === "playing") {
1496
+ for (; S >= u.holdUntil && u.index < u.paths.length - 1; )
1497
+ u.index += 1, u.holdUntil = S + Ve();
1498
+ if (y(u.paths[u.index] ?? null, u.blinkEmotion), S >= u.holdUntil && u.index >= u.paths.length - 1) {
1499
+ if (u.after === "resumeIdle") {
1500
+ V(S + f, m);
1032
1501
  return;
1033
1502
  }
1034
- if (o.after === "doublePause") {
1035
- o = {
1503
+ if (u.after === "doublePause") {
1504
+ u = {
1036
1505
  kind: "doublePause",
1037
- resumeAt: h + ve(s, c),
1038
- blinkEmotion: o.blinkEmotion
1039
- }, u(ee(o.blinkEmotion), o.blinkEmotion);
1506
+ resumeAt: S + Pe(i, o),
1507
+ blinkEmotion: u.blinkEmotion
1508
+ }, y(A(w), u.blinkEmotion);
1040
1509
  return;
1041
1510
  }
1042
- if (o.after === "idle" && Math.random() < i) {
1043
- o = {
1511
+ if (u.after === "idle" && Math.random() < s) {
1512
+ u = {
1044
1513
  kind: "doublePause",
1045
- resumeAt: h + ve(s, c),
1046
- blinkEmotion: o.blinkEmotion
1047
- }, u(ee(o.blinkEmotion), o.blinkEmotion);
1514
+ resumeAt: S + Pe(i, o),
1515
+ blinkEmotion: u.blinkEmotion
1516
+ }, y(A(w), u.blinkEmotion);
1048
1517
  return;
1049
1518
  }
1050
- g(h, o.blinkEmotion);
1519
+ V(S, u.blinkEmotion);
1051
1520
  }
1052
1521
  }
1053
1522
  }
1054
1523
  return {
1055
- advance: H,
1056
- setTargetEmotion(h) {
1057
- const E = ye(h, _);
1058
- if (E === _ && o.kind !== "emotionBlend") return;
1059
- const D = performance.now();
1060
- if (d > 0 && E !== _ && o.kind !== "emotionBlend" && !(_ === "neutral" && E !== "neutral") && D - S < d)
1061
- return;
1062
- const L = _;
1063
- if (_ = E, S = D, o.kind === "playing") {
1064
- v(D, m, E);
1065
- return;
1066
- }
1067
- if (o.kind === "emotionBlend") {
1068
- o = {
1069
- ...o,
1070
- thenEmotion: E
1071
- };
1072
- return;
1073
- }
1074
- v(D, L, E);
1524
+ advance: K,
1525
+ setTargetEmotion(S) {
1526
+ const M = ve(S, m);
1527
+ if (M === m) return;
1528
+ const g = performance.now();
1529
+ l > 0 && M !== m && !(m === "neutral" && M !== "neutral") && g - E < l || (m = M, _ = M, E = g);
1075
1530
  },
1076
- getTargetEmotion: () => _,
1077
- getExpressionPath: () => F,
1078
- getDrawKey: () => w,
1531
+ setTargetEyebrow(S) {
1532
+ const M = ke(S);
1533
+ if (M === w && u.kind !== "browBlend") return;
1534
+ const g = performance.now(), v = u.kind === "browBlend" ? Ot(p) ?? k : k;
1535
+ w = M, !(M === v && u.kind !== "browBlend") && (u.kind === "playing" || u.kind === "doublePause" || U(g, v, M));
1536
+ },
1537
+ getTargetEmotion: () => m,
1538
+ getTargetEyebrow: () => w,
1539
+ getExpressionPath: () => p,
1540
+ getDrawKey: () => d,
1079
1541
  reset() {
1080
- _ = "neutral", m = "neutral", S = 0, g(
1081
- performance.now() + ve(n, r),
1542
+ m = "neutral", _ = "neutral", w = 0, k = 0, E = 0, V(
1543
+ performance.now() + Pe(n, r),
1082
1544
  "neutral"
1083
1545
  );
1084
1546
  }
1085
1547
  };
1086
1548
  }
1087
- function hr() {
1549
+ function ts() {
1088
1550
  const e = document.createElement("video");
1089
1551
  e.muted = !0, e.playsInline = !0, e.preload = "auto", e.setAttribute("playsinline", ""), e.loop = !0;
1090
1552
  let t = !1, n = null, r = "";
1091
- const i = () => {
1553
+ const s = () => {
1092
1554
  n && (URL.revokeObjectURL(n), n = null);
1093
1555
  };
1094
1556
  return {
1095
- async load(s) {
1096
- t && r === s || (i(), t = !1, r = s, s.startsWith("blob:") && (n = s), await new Promise((c, a) => {
1097
- const l = () => {
1098
- const d = e.duration;
1099
- if (!Number.isFinite(d) || d <= 0) {
1100
- a(new Error(`Idle video has invalid duration: ${s}`));
1557
+ async load(i) {
1558
+ t && r === i || (s(), t = !1, r = i, i.startsWith("blob:") && (n = i), await new Promise((o, a) => {
1559
+ const f = () => {
1560
+ const l = e.duration;
1561
+ if (!Number.isFinite(l) || l <= 0) {
1562
+ a(new Error(`Idle video has invalid duration: ${i}`));
1101
1563
  return;
1102
1564
  }
1103
- t = !0, e.currentTime = 0, c();
1565
+ t = !0, e.currentTime = 0, o();
1104
1566
  };
1105
- e.addEventListener("loadeddata", l, { once: !0 }), e.addEventListener(
1567
+ e.addEventListener("loadeddata", f, { once: !0 }), e.addEventListener(
1106
1568
  "error",
1107
- () => a(new Error(`Failed to load idle video: ${s}`)),
1569
+ () => a(new Error(`Failed to load idle video: ${i}`)),
1108
1570
  { once: !0 }
1109
- ), e.src = s, e.load();
1571
+ ), e.src = i, e.load();
1110
1572
  }));
1111
1573
  },
1112
1574
  isReady() {
@@ -1115,136 +1577,139 @@ function hr() {
1115
1577
  getVideo() {
1116
1578
  return e;
1117
1579
  },
1118
- setActive(s) {
1119
- t && (s ? e.paused && e.play().catch(() => {
1580
+ setActive(i) {
1581
+ t && (i ? e.paused && e.play().catch(() => {
1120
1582
  }) : e.paused || e.pause());
1121
1583
  },
1122
1584
  restart() {
1123
1585
  t && (e.currentTime = 0);
1124
1586
  },
1125
1587
  dispose() {
1126
- e.pause(), e.removeAttribute("src"), e.load(), i(), t = !1, r = "";
1588
+ e.pause(), e.removeAttribute("src"), e.load(), s(), t = !1, r = "";
1127
1589
  }
1128
1590
  };
1129
1591
  }
1130
- const mr = 50, Dt = 400;
1131
- function _r(e, t, n) {
1592
+ const ns = 50, sn = 400;
1593
+ function rs(e, t, n) {
1132
1594
  return e.filter((r) => {
1133
- const i = r.queueIndex ?? -1;
1134
- return i >= t && i <= n;
1595
+ const s = r.queueIndex ?? -1;
1596
+ return s >= t && s <= n;
1135
1597
  });
1136
1598
  }
1137
- function wr(e, t) {
1599
+ function ss(e, t) {
1138
1600
  const n = [];
1139
1601
  for (const r of e) {
1140
- const i = _r(
1602
+ const s = rs(
1141
1603
  t,
1142
1604
  r.start_word,
1143
1605
  r.end_word
1144
1606
  );
1145
- if (i.length === 0) continue;
1146
- const s = i[0], c = i[i.length - 1];
1607
+ if (s.length === 0) continue;
1608
+ const i = s[0], o = s[s.length - 1];
1147
1609
  n.push({
1148
1610
  sentence: r,
1149
- startMs: Math.max(0, s.wtime - mr),
1150
- endMs: c.wtime + c.wduration + Dt
1611
+ startMs: Math.max(0, i.wtime - ns),
1612
+ endMs: o.wtime + o.wduration + sn
1151
1613
  });
1152
1614
  }
1153
- return n.sort((r, i) => r.startMs - i.startMs);
1615
+ return n.sort((r, s) => r.startMs - s.startMs);
1154
1616
  }
1155
- function gr(e, t, n, r = "neutral") {
1156
- const i = ye(r);
1157
- if (t.length === 0) return i;
1617
+ function is(e, t, n, r = "neutral") {
1618
+ const s = ve(r);
1619
+ if (t.length === 0) return s;
1158
1620
  if (n.length === 0 || e < n[0].wtime)
1159
- return ye(t[0]?.emotion, i);
1160
- const s = wr(t, n);
1161
- let c = null;
1162
- for (const d of s)
1163
- e >= d.startMs && e <= d.endMs && (c = d);
1164
- if (c)
1165
- return ye(c.sentence.emotion, i);
1166
- const a = n[n.length - 1], l = a.wtime + a.wduration;
1167
- return e > l + Dt ? ye(
1621
+ return ve(t[0]?.emotion, s);
1622
+ const i = ss(t, n);
1623
+ let o = null;
1624
+ for (const l of i)
1625
+ e >= l.startMs && e <= l.endMs && (o = l);
1626
+ if (o)
1627
+ return ve(o.sentence.emotion, s);
1628
+ const a = n[n.length - 1], f = a.wtime + a.wduration;
1629
+ return e > f + sn ? ve(
1168
1630
  t[t.length - 1]?.emotion,
1169
- i
1170
- ) : i;
1171
- }
1172
- function xt(e, t, n, r, i = et) {
1173
- const s = new OffscreenCanvas(n, r), c = s.getContext("2d", { willReadFrequently: !0 });
1174
- c.drawImage(e, 0, 0, n, r);
1175
- const a = c.getImageData(0, 0, n, r), l = c.createImageData(n, r);
1176
- l.data.set(a.data);
1177
- const _ = new OffscreenCanvas(n, r).getContext("2d", { willReadFrequently: !0 });
1178
- for (const m of t) {
1179
- _.clearRect(0, 0, n, r), _.drawImage(m, 0, 0, n, r);
1180
- const S = _.getImageData(0, 0, n, r);
1181
- for (let o = 0; o < l.data.length; o += 4) {
1182
- const F = S.data[o], w = S.data[o + 1], u = S.data[o + 2];
1183
- Math.max(F, w, u) > i && (l.data[o] = F, l.data[o + 1] = w, l.data[o + 2] = u, l.data[o + 3] = 255);
1631
+ s
1632
+ ) : s;
1633
+ }
1634
+ function on(e, t, n, r, s = Zt) {
1635
+ const i = new OffscreenCanvas(n, r), o = i.getContext("2d", { willReadFrequently: !0 });
1636
+ o.drawImage(e, 0, 0, n, r);
1637
+ const a = o.getImageData(0, 0, n, r), f = o.createImageData(n, r);
1638
+ f.data.set(a.data);
1639
+ const m = new OffscreenCanvas(n, r).getContext("2d", { willReadFrequently: !0 });
1640
+ for (const _ of t) {
1641
+ m.clearRect(0, 0, n, r), m.drawImage(_, 0, 0, n, r);
1642
+ const w = m.getImageData(0, 0, n, r);
1643
+ for (let k = 0; k < f.data.length; k += 4) {
1644
+ const E = w.data[k], u = w.data[k + 1], p = w.data[k + 2];
1645
+ Math.max(E, u, p) > s && (f.data[k] = E, f.data[k + 1] = u, f.data[k + 2] = p, f.data[k + 3] = 255);
1184
1646
  }
1185
1647
  }
1186
- return c.putImageData(l, 0, 0), s;
1648
+ return o.putImageData(f, 0, 0), i;
1187
1649
  }
1188
- let de = null, Ie = null;
1189
- const Ue = /* @__PURE__ */ new Map();
1190
- function yr() {
1191
- de = null, Ie = null, Ue.clear();
1650
+ let ye = null, Be = null;
1651
+ const qe = /* @__PURE__ */ new Map();
1652
+ function os() {
1653
+ ye = null, Be = null, qe.clear();
1192
1654
  }
1193
- mn(yr);
1194
- function pr(e) {
1195
- return e ?? Ie ?? void 0;
1655
+ Gn(os);
1656
+ function as(e) {
1657
+ return e ?? Be ?? void 0;
1196
1658
  }
1197
- function tt(e) {
1659
+ function ht(e) {
1198
1660
  return new Promise((t, n) => {
1199
1661
  const r = new Image();
1200
1662
  r.decoding = "async", r.onload = () => t(r), r.onerror = () => n(new Error(`Failed to load image: ${e}`)), r.src = e;
1201
1663
  });
1202
1664
  }
1203
- async function Er(e) {
1204
- return Be() ? jn(
1205
- await Ve(at(), e ?? "")
1206
- ) : tt(at());
1207
- }
1208
- async function ht(e, t, n, r) {
1209
- const i = n ? await qn(e, r) : await fetch(e).then((d) => {
1210
- if (!d.ok) throw new Error(`Failed to load ${e}`);
1211
- return d.json();
1212
- }), s = i.sheets?.[0];
1213
- if (!s?.path) throw new Error(`${e} has no sheets[0].path`);
1214
- const c = n ? await Kn(
1215
- await Ve(
1216
- Zn(t, s.path, n),
1665
+ async function cs(e) {
1666
+ return Ke() ? Dr(
1667
+ await Ge(Tt(), e ?? "")
1668
+ ) : ht(Tt());
1669
+ }
1670
+ async function Lt(e, t, n, r) {
1671
+ const s = n ? await Ir(e, r) : await fetch(e).then((l) => {
1672
+ if (!l.ok) throw new Error(`Failed to load ${e}`);
1673
+ return l.json();
1674
+ }), i = s.sheets?.[0];
1675
+ if (!i?.path) throw new Error(`${e} has no sheets[0].path`);
1676
+ const o = n ? await Rr(
1677
+ await Ge(
1678
+ Ur(t, i.path, n),
1217
1679
  r ?? ""
1218
1680
  )
1219
- ) : await tt(`${t}/${s.path}`), a = /* @__PURE__ */ new Map();
1220
- for (const d of i.cells ?? [])
1221
- d.path && a.set(d.path, d);
1222
- const l = /* @__PURE__ */ new Map();
1223
- for (const d of i.sheets ?? [])
1224
- l.set(d.index, d);
1225
- return { atlas: c, atlasMeta: i, cellByPath: a, sheetByIndex: l, diffBase: t };
1226
- }
1227
- async function Ye(e) {
1228
- const t = pr(e), n = Be();
1681
+ ) : await ht(`${t}/${i.path}`), a = /* @__PURE__ */ new Map();
1682
+ for (const l of s.cells ?? [])
1683
+ l.path && a.set(l.path, l);
1684
+ const f = /* @__PURE__ */ new Map();
1685
+ for (const l of s.sheets ?? [])
1686
+ f.set(l.index, l);
1687
+ return { atlas: o, atlasMeta: s, cellByPath: a, sheetByIndex: f, diffBase: t };
1688
+ }
1689
+ async function st(e) {
1690
+ const t = as(e), n = Ke();
1229
1691
  if (n && !t)
1230
1692
  throw new Error("Encrypted assets enabled but no key provided");
1231
- if (de && (!n || Ie === (t ?? null))) {
1232
- const s = await de;
1233
- return Ae(s);
1693
+ if (ye && (!n || Be === (t ?? null))) {
1694
+ const i = await ye;
1695
+ return {
1696
+ ...Oe(i),
1697
+ visemePaths: [...i.viseme.cellByPath.keys()]
1698
+ };
1234
1699
  }
1235
- Ie = t ?? null, Ue.clear();
1236
- const r = wn();
1237
- de = (async () => {
1238
- const s = await Er(t), c = await ht(
1239
- gn(),
1700
+ Be = t ?? null, qe.clear();
1701
+ const r = Yn();
1702
+ ye = (async () => {
1703
+ const i = await cs(t), o = await Lt(
1704
+ Jn(),
1240
1705
  r,
1241
1706
  n,
1242
1707
  t
1243
1708
  );
1244
1709
  let a = null;
1245
1710
  try {
1246
- a = await ht(
1247
- yn(),
1711
+ a = await Lt(
1712
+ Qn(),
1248
1713
  r,
1249
1714
  n,
1250
1715
  t
@@ -1252,212 +1717,224 @@ async function Ye(e) {
1252
1717
  } catch {
1253
1718
  a = null;
1254
1719
  }
1255
- return { sil: s, viseme: c, expression: a };
1720
+ return { sil: i, viseme: o, expression: a };
1256
1721
  })();
1257
- const i = await de;
1258
- return Ae(i);
1722
+ const s = await ye;
1723
+ return { ...Oe(s), visemePaths: [...s.viseme.cellByPath.keys()] };
1259
1724
  }
1260
- async function Mt(e) {
1261
- if (await Ye(e), !de) throw new Error("Assets not loaded");
1262
- return de;
1725
+ async function an(e) {
1726
+ if (await st(e), !ye) throw new Error("Assets not loaded");
1727
+ return ye;
1263
1728
  }
1264
- function Ae(e) {
1265
- return $n(
1729
+ function Oe(e) {
1730
+ return br(
1266
1731
  e.viseme.atlasMeta,
1267
1732
  e.sil.naturalWidth,
1268
1733
  e.sil.naturalHeight
1269
1734
  );
1270
1735
  }
1271
- function Sr(e, t) {
1736
+ function us(e, t) {
1272
1737
  const n = document.createElement("canvas");
1273
1738
  return n.width = t.w, n.height = t.h, n.getContext("2d", { willReadFrequently: !0 }).drawImage(e.atlas, t.x, t.y, t.w, t.h, 0, 0, t.w, t.h), n;
1274
1739
  }
1275
- async function mt(e, t, n) {
1276
- const r = `${t.diffBase}::${n}`, i = Ue.get(r);
1277
- if (i) return i;
1278
- const s = (async () => {
1279
- const c = t.cellByPath.get(n);
1280
- if (!c) throw new Error(`No atlas cell for path: ${n}`);
1281
- const a = Hn(t.atlasMeta, c), l = Ae(e);
1282
- if (Wn(c)) {
1283
- const m = Sr(t, c), S = document.createElement("canvas");
1284
- S.width = l.width, S.height = l.height;
1285
- const o = S.getContext("2d");
1286
- return o.fillStyle = "#000", o.fillRect(0, 0, l.width, l.height), o.drawImage(m, a.x, a.y), S;
1740
+ async function Ft(e, t, n) {
1741
+ const r = `${t.diffBase}::${n}`, s = qe.get(r);
1742
+ if (s) return s;
1743
+ const i = (async () => {
1744
+ const o = t.cellByPath.get(n);
1745
+ if (!o) throw new Error(`No atlas cell for path: ${n}`);
1746
+ const a = Tr(t.atlasMeta, o), f = Oe(e);
1747
+ if (Ar(o)) {
1748
+ const _ = us(t, o), w = document.createElement("canvas");
1749
+ w.width = f.width, w.height = f.height;
1750
+ const k = w.getContext("2d");
1751
+ return k.fillStyle = "#000", k.fillRect(0, 0, f.width, f.height), k.drawImage(_, a.x, a.y), w;
1287
1752
  }
1288
- const d = `${t.diffBase}/${n}`, _ = await tt(d);
1289
- if (_.naturalWidth === l.width && _.naturalHeight === l.height)
1290
- return _;
1753
+ const l = `${t.diffBase}/${n}`, m = await ht(l);
1754
+ if (m.naturalWidth === f.width && m.naturalHeight === f.height)
1755
+ return m;
1291
1756
  throw new Error(`Diff PNG wrong size for ${n}`);
1292
1757
  })();
1293
- return Ue.set(r, s), s;
1758
+ return qe.set(r, i), i;
1294
1759
  }
1295
- async function _t(e, t, n, r = et, i, s) {
1296
- if (i) {
1297
- const { width: S, height: o } = i;
1298
- if (s && !s() || t.readyState < HTMLMediaElement.HAVE_CURRENT_DATA)
1760
+ async function Ut(e, t, n, r, s, i) {
1761
+ if (s) {
1762
+ const { width: k, height: E } = s;
1763
+ if (i && !i() || t.readyState < HTMLMediaElement.HAVE_CURRENT_DATA)
1299
1764
  return;
1300
- const F = document.createElement("canvas");
1301
- F.width = S, F.height = o;
1302
- const w = F.getContext("2d");
1303
- if (w.clearRect(0, 0, S, o), w.drawImage(t, 0, 0, S, o), s && !s()) return;
1304
- (e.width !== S || e.height !== o) && (e.width = S, e.height = o);
1305
- const u = e.getContext("2d");
1306
- u.clearRect(0, 0, S, o), u.drawImage(F, 0, 0);
1765
+ const u = document.createElement("canvas");
1766
+ u.width = k, u.height = E;
1767
+ const p = u.getContext("2d");
1768
+ if (p.clearRect(0, 0, k, E), p.drawImage(t, 0, 0, k, E), i && !i()) return;
1769
+ (e.width !== k || e.height !== E) && (e.width = k, e.height = E);
1770
+ const d = e.getContext("2d");
1771
+ d.clearRect(0, 0, k, E), d.drawImage(u, 0, 0);
1307
1772
  return;
1308
1773
  }
1309
- const c = await Mt(), { width: a, height: l } = Ae(c);
1310
- (e.width !== a || e.height !== l) && (e.width = a, e.height = l);
1311
- const d = [], _ = e.getContext("2d");
1312
- if (_.clearRect(0, 0, a, l), t.readyState < HTMLMediaElement.HAVE_CURRENT_DATA) {
1313
- const S = c.sil;
1314
- _.drawImage(S, 0, 0, a, l);
1774
+ const o = await an(), a = en(o.viseme.atlasMeta), { width: f, height: l } = Oe(o);
1775
+ (e.width !== f || e.height !== l) && (e.width = f, e.height = l);
1776
+ const m = [], _ = e.getContext("2d");
1777
+ if (_.clearRect(0, 0, f, l), t.readyState < HTMLMediaElement.HAVE_CURRENT_DATA) {
1778
+ const k = o.sil;
1779
+ _.drawImage(k, 0, 0, f, l);
1315
1780
  return;
1316
1781
  }
1317
- if (d.length === 0) {
1318
- _.drawImage(t, 0, 0, a, l);
1782
+ if (m.length === 0) {
1783
+ _.drawImage(t, 0, 0, f, l);
1319
1784
  return;
1320
1785
  }
1321
- const m = xt(t, d, a, l, r);
1322
- _.drawImage(m, 0, 0);
1323
- }
1324
- async function Xe(e, t, n = et) {
1325
- const r = await Mt(Ie ?? void 0), { width: i, height: s } = Ae(r);
1326
- (e.width !== i || e.height !== s) && (e.width = i, e.height = s);
1327
- const c = [];
1328
- t.mouthPath && c.push(await mt(r, r.viseme, t.mouthPath)), t.expressionPath && r.expression && c.push(
1329
- await mt(r, r.expression, t.expressionPath)
1786
+ const w = on(t, m, f, l, a);
1787
+ _.drawImage(w, 0, 0);
1788
+ }
1789
+ async function it(e, t, n) {
1790
+ const r = await an(Be ?? void 0), s = en(r.viseme.atlasMeta), { width: i, height: o } = Oe(r);
1791
+ (e.width !== i || e.height !== o) && (e.width = i, e.height = o);
1792
+ const a = [];
1793
+ if (t.mouthPath) {
1794
+ const m = new Set(r.viseme.cellByPath.keys()), _ = Pr(t.mouthPath, m) ?? (m.has(t.mouthPath) ? t.mouthPath : null);
1795
+ _ && a.push(await Ft(r, r.viseme, _));
1796
+ }
1797
+ t.expressionPath && r.expression && a.push(
1798
+ await Ft(r, r.expression, t.expressionPath)
1330
1799
  );
1331
- const a = e.getContext("2d");
1332
- if (a.clearRect(0, 0, i, s), c.length === 0) {
1333
- a.drawImage(r.sil, 0, 0, i, s);
1800
+ const f = e.getContext("2d");
1801
+ if (f.clearRect(0, 0, i, o), a.length === 0) {
1802
+ f.drawImage(r.sil, 0, 0, i, o);
1334
1803
  return;
1335
1804
  }
1336
- const l = xt(
1805
+ const l = on(
1337
1806
  r.sil,
1338
- c,
1807
+ a,
1339
1808
  i,
1340
- s,
1341
- n
1809
+ o,
1810
+ s
1342
1811
  );
1343
- a.drawImage(l, 0, 0);
1812
+ f.drawImage(l, 0, 0);
1344
1813
  }
1345
- async function kr(e) {
1346
- await Xe(e, { mouthPath: null, expressionPath: null });
1814
+ async function ls(e) {
1815
+ await it(e, { mouthPath: null, expressionPath: null });
1347
1816
  }
1348
- function Tr(e) {
1817
+ function fs(e) {
1349
1818
  const t = /* @__PURE__ */ new Map();
1350
1819
  for (const n of e)
1351
1820
  t.has(n.vtime) || t.set(n.vtime, n);
1352
1821
  return [...t.values()].sort((n, r) => n.vtime - r.vtime);
1353
1822
  }
1354
- function vr(e) {
1355
- const t = Tr(e), n = [];
1823
+ function ds(e) {
1824
+ const t = fs(e), n = [];
1356
1825
  for (let r = 0; r < t.length - 1; r++) {
1357
- const i = t[r].viseme, s = t[r + 1].viseme, c = t[r].vtime, a = t[r + 1].vtime;
1358
- i === s || a <= c || n.push({ from: i, to: s, fromVtime: c, toVtime: a });
1826
+ const s = t[r].viseme, i = t[r + 1].viseme, o = t[r].vtime, a = t[r + 1].vtime;
1827
+ s === i || a <= o || n.push({ from: s, to: i, fromVtime: o, toVtime: a });
1359
1828
  }
1360
1829
  return n;
1361
1830
  }
1362
- function Ir(e, t) {
1831
+ function hs(e, t) {
1363
1832
  let n = null;
1364
1833
  for (const r of e)
1365
1834
  t >= r.fromVtime && t < r.toVtime && (n = r);
1366
1835
  return n;
1367
1836
  }
1368
- function Ar(e, t) {
1837
+ function ms(e, t) {
1369
1838
  return { gapMs: Math.max(0, t - e), holdEnd: e, transStart: e };
1370
1839
  }
1371
- const Ct = 400, br = 200, Rr = 600, Dr = "__sil__";
1372
- function xr() {
1840
+ const cn = 400, ws = 200, gs = 600, _s = "__sil__";
1841
+ function ps() {
1373
1842
  return { lastDrawnKey: "" };
1374
1843
  }
1375
- function ge(e) {
1376
- e.lastDrawnKey = "";
1844
+ function me(e) {
1845
+ e.lastDrawnKey = "", e.transitionCache = void 0;
1377
1846
  }
1378
- function Mr(e) {
1847
+ function ys(e, t) {
1848
+ if (t?.transitionCache && t.transitionCache.queueLength === e.length)
1849
+ return t.transitionCache.transitions;
1850
+ const n = ds(e);
1851
+ return t && (t.transitionCache = { queueLength: e.length, transitions: n }), n;
1852
+ }
1853
+ function ks(e) {
1379
1854
  let t = "sil";
1380
1855
  for (const n of e)
1381
1856
  n.viseme !== "sil" && (t = n.viseme);
1382
1857
  return t;
1383
1858
  }
1384
- function Cr(e) {
1385
- return e === "sil" ? !1 : Rt(e, "sil").length > 0;
1859
+ function Es(e, t) {
1860
+ return e === "sil" ? !1 : t ? Br(e, "sil", t) : lt(e, "sil").length > 0;
1386
1861
  }
1387
- function Fr() {
1388
- return Ct + Rr;
1862
+ function Ss() {
1863
+ return cn + gs;
1389
1864
  }
1390
- function wt(e) {
1391
- return e ?? Dr;
1865
+ function Nt(e) {
1866
+ return e ?? _s;
1392
1867
  }
1393
- function Lr(e, t) {
1868
+ function vs(e, t, n, r) {
1394
1869
  if (e.length === 0)
1395
1870
  return { diffPath: null, label: "sil" };
1396
- const n = vr(e), r = Ir(n, t);
1397
- if (r) {
1398
- const s = r.toVtime - r.fromVtime, c = Ar(r.fromVtime, r.toVtime);
1399
- if (t >= c.transStart && t < r.toVtime) {
1400
- const a = Rt(r.from, r.to), l = Yn(a, s);
1401
- if (l.length > 0) {
1402
- const d = Xn(
1871
+ const s = ys(e, r), i = hs(s, t);
1872
+ if (i) {
1873
+ const a = i.toVtime - i.fromVtime, f = ms(i.fromVtime, i.toVtime);
1874
+ if (t >= f.transStart && t < i.toVtime) {
1875
+ let l = lt(i.from, i.to);
1876
+ n && (l = tn(l, n));
1877
+ const m = Lr(l, a);
1878
+ if (m.length > 0) {
1879
+ const _ = Fr(
1403
1880
  t,
1404
- c.transStart,
1405
- r.toVtime,
1406
- l.length
1881
+ f.transStart,
1882
+ i.toVtime,
1883
+ m.length
1407
1884
  );
1408
- return { diffPath: l[d] ?? l[l.length - 1], label: `${r.from}→${r.to}` };
1885
+ return { diffPath: m[_] ?? m[m.length - 1], label: `${i.from}→${i.to}` };
1409
1886
  }
1410
- return { diffPath: Qe(r.to), label: r.to };
1887
+ return { diffPath: We(i.to), label: i.to };
1411
1888
  }
1412
1889
  }
1413
- const i = vt(e, t);
1414
- return i === "sil" ? { diffPath: null, label: "sil" } : { diffPath: Qe(i), label: i };
1890
+ const o = at(e, t);
1891
+ return o === "sil" ? { diffPath: null, label: "sil" } : { diffPath: We(o), label: o };
1415
1892
  }
1416
- function Ft(e, t) {
1417
- const n = t ?? wt(e.expressionPath);
1418
- return `${wt(e.mouthPath)}|${n}`;
1893
+ function un(e, t) {
1894
+ const n = t ?? Nt(e.expressionPath);
1895
+ return `${Nt(e.mouthPath)}|${n}`;
1419
1896
  }
1420
- function Or(e, t, n, r, i, s, c, a) {
1421
- const l = Lr(t, n), d = {
1422
- mouthPath: l.diffPath,
1897
+ function bs(e, t, n, r, s, i, o, a, f, l) {
1898
+ const m = vs(t, n, f, i), _ = {
1899
+ mouthPath: m.diffPath,
1423
1900
  expressionPath: r
1424
- }, _ = Ft(d, i);
1425
- _ !== s.lastDrawnKey && (a(l.label), c(e, d, _, (m) => {
1426
- m === _ && (s.lastDrawnKey = _);
1901
+ }, w = un(_, s);
1902
+ w !== i.lastDrawnKey && (a(m.label), o(e, _, w, (k) => {
1903
+ k === w && (i.lastDrawnKey = w);
1427
1904
  }));
1428
1905
  }
1429
- function gt(e, t, n, r, i, s, c = null) {
1430
- const a = { mouthPath: null, expressionPath: t }, l = c != null ? `|idle@${Math.round(c * 1e3)}` : "", d = Ft(a, n) + l;
1431
- !(c != null) && d === r.lastDrawnKey || (s(
1432
- c != null ? "idle" : "sil"
1433
- ), i(e, a, d, (m) => {
1434
- m === d && (r.lastDrawnKey = d);
1906
+ function Vt(e, t, n, r, s, i, o = null) {
1907
+ const a = { mouthPath: null, expressionPath: t }, f = o != null ? `|idle@${Math.round(o * 1e3)}` : "", l = un(a, n) + f;
1908
+ !(o != null) && l === r.lastDrawnKey || (i(
1909
+ o != null ? "idle" : "sil"
1910
+ ), s(e, a, l, (_) => {
1911
+ _ === l && (r.lastDrawnKey = l);
1435
1912
  }));
1436
1913
  }
1437
- function Lt(e) {
1438
- let t = 0, n = null, r = !1, i = !1;
1439
- const s = async () => {
1914
+ function ln(e) {
1915
+ let t = 0, n = null, r = !1, s = !1;
1916
+ const i = async () => {
1440
1917
  if (!r) {
1441
1918
  r = !0;
1442
1919
  try {
1443
1920
  for (; n; ) {
1444
1921
  const a = n;
1445
1922
  n = null;
1446
- const l = ++t, d = await e(a.diffs, l, a);
1447
- n || d && l === t && a.onDisplayed?.(a.drawKey);
1923
+ const f = ++t, l = await e(a.diffs, f, a);
1924
+ n || l && f === t && a.onDisplayed?.(a.drawKey);
1448
1925
  }
1449
1926
  } finally {
1450
- r = !1, n && s();
1927
+ r = !1, n && i();
1451
1928
  }
1452
1929
  }
1453
- }, c = () => {
1454
- i || (i = !0, queueMicrotask(() => {
1455
- i = !1, s();
1930
+ }, o = () => {
1931
+ s || (s = !0, queueMicrotask(() => {
1932
+ s = !1, i();
1456
1933
  }));
1457
1934
  };
1458
1935
  return {
1459
- enqueue(a, l, d) {
1460
- n = { diffs: a, drawKey: l, onDisplayed: d }, c();
1936
+ enqueue(a, f, l) {
1937
+ n = { diffs: a, drawKey: f, onDisplayed: l }, o();
1461
1938
  },
1462
1939
  reset() {
1463
1940
  t += 1, n = null;
@@ -1470,9 +1947,9 @@ function Lt(e) {
1470
1947
  }
1471
1948
  };
1472
1949
  }
1473
- const yt = -1, pt = /* @__PURE__ */ new Map();
1474
- async function Pr(e) {
1475
- let t = pt.get(e);
1950
+ const $t = -1, Ht = /* @__PURE__ */ new Map();
1951
+ async function Ts(e) {
1952
+ let t = Ht.get(e);
1476
1953
  if (!t) {
1477
1954
  const n = await fetch(e);
1478
1955
  if (!n.ok)
@@ -1480,239 +1957,246 @@ async function Pr(e) {
1480
1957
  `Failed to fetch worker script (${n.status}): ${e}`
1481
1958
  );
1482
1959
  const r = await n.blob();
1483
- t = URL.createObjectURL(r), pt.set(e, t);
1960
+ t = URL.createObjectURL(r), Ht.set(e, t);
1484
1961
  }
1485
1962
  return new Worker(t, { name: "visemeDiffPreview" });
1486
1963
  }
1487
- function Ur() {
1964
+ function As() {
1488
1965
  return typeof Worker < "u" && typeof OffscreenCanvas < "u";
1489
1966
  }
1490
- function Br(e, t) {
1967
+ function Is(e, t) {
1491
1968
  (e.width !== t.width || e.height !== t.height) && (e.width = t.width, e.height = t.height);
1492
1969
  const n = e.getContext("2d");
1493
1970
  n && n.drawImage(t, 0, 0);
1494
1971
  }
1495
- function Et(e, t) {
1496
- let n = 0;
1497
- const r = Lt(async (i, s) => (await Ye(), await Xe(e, i), r.isLatestSeq(s)));
1972
+ function Wt(e, t) {
1973
+ let n = 0, r = null;
1974
+ const s = ln(async (i, o) => (await st(), await it(e, i), s.isLatestSeq(o)));
1498
1975
  return {
1499
1976
  usesWorker: !1,
1500
1977
  async loadAssets(i) {
1501
- return await Ye(i);
1978
+ const o = await st(i);
1979
+ return r = o.visemePaths ? new Set(o.visemePaths) : null, o;
1980
+ },
1981
+ getVisemeAtlasPaths() {
1982
+ return r;
1502
1983
  },
1503
1984
  async renderSilOnly() {
1504
- n += 1, r.reset(), await kr(e);
1985
+ n += 1, s.reset(), await ls(e);
1505
1986
  },
1506
- drawLiveFrame(i, s, c, a) {
1507
- r.enqueue(s, c, a);
1987
+ drawLiveFrame(i, o, a, f) {
1988
+ s.enqueue(o, a, f);
1508
1989
  },
1509
- async renderViseme(i, s) {
1990
+ async renderViseme(i, o) {
1510
1991
  n += 1;
1511
- const c = n;
1512
- t.onStatus?.(s), await Xe(i, {
1513
- mouthPath: Qe(s),
1992
+ const a = n;
1993
+ t.onStatus?.(o), await it(i, {
1994
+ mouthPath: We(o),
1514
1995
  expressionPath: null
1515
1996
  });
1516
1997
  },
1517
1998
  dispose() {
1518
- n += 1, r.reset();
1999
+ n += 1, s.reset();
1519
2000
  }
1520
2001
  };
1521
2002
  }
1522
- function Nr(e, t, n) {
1523
- let r = null, i = 1, s = 0, c = !1, a = !1;
1524
- const l = /* @__PURE__ */ new Map(), d = Lt(async (w, u, g) => (l.set(u, {
1525
- drawKey: g.drawKey,
1526
- onDisplayed: g.onDisplayed
1527
- }), await o(
2003
+ function Rs(e, t, n) {
2004
+ let r = null, s = 1, i = 0, o = !1, a = !1, f = null;
2005
+ const l = /* @__PURE__ */ new Map(), m = ln(async (p, d, D) => (l.set(d, {
2006
+ drawKey: D.drawKey,
2007
+ onDisplayed: D.onDisplayed
2008
+ }), await E(
1528
2009
  {
1529
2010
  type: "drawFrame",
1530
- diffPath: w.mouthPath,
1531
- expressionDiffPath: w.expressionPath,
1532
- liveSeq: u
2011
+ diffPath: p.mouthPath,
2012
+ expressionDiffPath: p.expressionPath,
2013
+ liveSeq: d
1533
2014
  },
1534
2015
  void 0,
1535
2016
  !0
1536
- ), !1)), _ = (w) => {
1537
- if (w === yt) {
1538
- let y = -1, v;
1539
- for (const [H, h] of l)
1540
- H >= y && (y = H, v = h);
1541
- y >= 0 && l.delete(y), v?.onDisplayed?.(v.drawKey);
2017
+ ), !1)), _ = (p) => {
2018
+ if (p === $t) {
2019
+ let y = -1, A;
2020
+ for (const [U, V] of l)
2021
+ U >= y && (y = U, A = V);
2022
+ y >= 0 && l.delete(y), A?.onDisplayed?.(A.drawKey);
1542
2023
  return;
1543
2024
  }
1544
- const u = -w, g = l.get(u);
1545
- l.delete(u), g?.onDisplayed?.(g.drawKey);
1546
- }, m = /* @__PURE__ */ new Map(), S = (w, u) => {
1547
- a || !r || r.postMessage(w, []);
1548
- }, o = (w, u, g = !1) => {
2025
+ const d = -p, D = l.get(d);
2026
+ l.delete(d), D?.onDisplayed?.(D.drawKey);
2027
+ }, w = /* @__PURE__ */ new Map(), k = (p, d) => {
2028
+ a || !r || r.postMessage(p, []);
2029
+ }, E = (p, d, D = !1) => {
1549
2030
  if (a) return Promise.resolve();
1550
- const y = i++;
1551
- return new Promise((v, H) => {
1552
- m.set(y, {
1553
- resolve: (h) => v(h),
1554
- reject: H,
1555
- generation: typeof w.generation == "number" ? w.generation : void 0,
1556
- expectRenderDone: g
1557
- }), S({ ...w, requestId: y });
2031
+ const y = s++;
2032
+ return new Promise((A, U) => {
2033
+ w.set(y, {
2034
+ resolve: (V) => A(V),
2035
+ reject: U,
2036
+ generation: typeof p.generation == "number" ? p.generation : void 0,
2037
+ expectRenderDone: D
2038
+ }), k({ ...p, requestId: y });
1558
2039
  });
1559
- }, F = (async () => {
1560
- r = await Pr(n), r.onmessage = (w) => {
2040
+ }, u = (async () => {
2041
+ r = await Ts(n), r.onmessage = (p) => {
1561
2042
  if (a) return;
1562
- const u = w.data;
1563
- if (u.type === "status") {
1564
- t.onStatus?.(u.label);
2043
+ const d = p.data;
2044
+ if (d.type === "status") {
2045
+ t.onStatus?.(d.label);
1565
2046
  return;
1566
2047
  }
1567
- if (u.type === "frame") {
1568
- const y = u.generation < 0;
1569
- if (!y && u.generation !== s) {
1570
- u.bitmap.close();
2048
+ if (d.type === "frame") {
2049
+ const y = d.generation < 0;
2050
+ if (!y && d.generation !== i) {
2051
+ d.bitmap.close();
1571
2052
  return;
1572
2053
  }
1573
- if (y && !(u.generation === yt)) {
1574
- const H = -u.generation;
1575
- if (!d.isLatestSeq(H)) {
1576
- u.bitmap.close();
2054
+ if (y && !(d.generation === $t)) {
2055
+ const U = -d.generation;
2056
+ if (!m.isLatestSeq(U)) {
2057
+ d.bitmap.close();
1577
2058
  return;
1578
2059
  }
1579
2060
  }
1580
2061
  if (y && t.shouldAcceptLiveFrame && !t.shouldAcceptLiveFrame()) {
1581
- u.bitmap.close();
2062
+ d.bitmap.close();
1582
2063
  return;
1583
2064
  }
1584
- Br(e, u.bitmap), u.bitmap.close(), y && _(u.generation);
2065
+ Is(e, d.bitmap), d.bitmap.close(), y && _(d.generation);
1585
2066
  return;
1586
2067
  }
1587
- const g = m.get(u.requestId);
1588
- if (g)
1589
- switch (u.type) {
2068
+ const D = w.get(d.requestId);
2069
+ if (D)
2070
+ switch (d.type) {
1590
2071
  case "ready":
1591
- m.delete(u.requestId), g.resolve();
2072
+ w.delete(d.requestId), D.resolve();
1592
2073
  break;
1593
2074
  case "loadAssetsDone":
1594
- m.delete(u.requestId), g.resolve({ width: u.width, height: u.height });
2075
+ w.delete(d.requestId), f = d.visemePaths?.length ? new Set(d.visemePaths) : null, D.resolve({ width: d.width, height: d.height, visemePaths: d.visemePaths });
1595
2076
  break;
1596
2077
  case "renderDone":
1597
- if (g.expectRenderDone && g.generation != null && u.generation !== g.generation)
2078
+ if (D.expectRenderDone && D.generation != null && d.generation !== D.generation)
1598
2079
  return;
1599
- m.delete(u.requestId), g.resolve();
2080
+ w.delete(d.requestId), D.resolve();
1600
2081
  break;
1601
2082
  case "renderAborted":
1602
- m.delete(u.requestId), g.resolve();
2083
+ w.delete(d.requestId), D.resolve();
1603
2084
  break;
1604
2085
  case "error":
1605
- m.delete(u.requestId), t.onError?.(u.message), g.reject(new Error(u.message));
2086
+ w.delete(d.requestId), t.onError?.(d.message), D.reject(new Error(d.message));
1606
2087
  break;
1607
2088
  }
1608
- }, r.onerror = (w) => {
2089
+ }, r.onerror = (p) => {
1609
2090
  if (a) return;
1610
- const u = w.message || "Worker error";
1611
- t.onError?.(u);
1612
- for (const [, g] of m)
1613
- g.reject(new Error(u));
1614
- m.clear();
1615
- }, await o({ type: "init" }), c = !0;
2091
+ const d = p.message || "Worker error";
2092
+ t.onError?.(d);
2093
+ for (const [, D] of w)
2094
+ D.reject(new Error(d));
2095
+ w.clear();
2096
+ }, await E({ type: "init" }), o = !0;
1616
2097
  })();
1617
2098
  return {
1618
2099
  usesWorker: !0,
1619
- async loadAssets(w) {
2100
+ async loadAssets(p) {
1620
2101
  if (a) return { width: 842, height: 1264 };
1621
- if (await F, a) return { width: 842, height: 1264 };
1622
- if (!c) throw new Error("Worker init failed");
1623
- return await o({
2102
+ if (await u, a) return { width: 842, height: 1264 };
2103
+ if (!o) throw new Error("Worker init failed");
2104
+ return await E({
1624
2105
  type: "loadAssets",
1625
- keyHex: w,
1626
- urls: hn(he())
2106
+ keyHex: p,
2107
+ urls: jn(Ee())
1627
2108
  }) ?? { width: 842, height: 1264 };
1628
2109
  },
2110
+ getVisemeAtlasPaths() {
2111
+ return f;
2112
+ },
1629
2113
  async renderSilOnly() {
1630
- if (a || (await F, a)) return;
1631
- s += 1, d.reset(), l.clear();
1632
- const w = s;
1633
- await o({ type: "cancelLiveDraws" }), await o(
1634
- { type: "renderSil", generation: w },
2114
+ if (a || (await u, a)) return;
2115
+ i += 1, m.reset(), l.clear();
2116
+ const p = i;
2117
+ await E({ type: "cancelLiveDraws" }), await E(
2118
+ { type: "renderSil", generation: p },
1635
2119
  void 0,
1636
2120
  !0
1637
2121
  );
1638
2122
  },
1639
- drawLiveFrame(w, u, g, y) {
1640
- a || F.then(() => {
1641
- a || d.enqueue(u, g, y);
2123
+ drawLiveFrame(p, d, D, y) {
2124
+ a || u.then(() => {
2125
+ a || m.enqueue(d, D, y);
1642
2126
  });
1643
2127
  },
1644
- async renderViseme(w, u, g = {}) {
1645
- if (a || (await F, a)) return;
1646
- s += 1, d.reset(), l.clear();
1647
- const y = s;
2128
+ async renderViseme(p, d, D = {}) {
2129
+ if (a || (await u, a)) return;
2130
+ i += 1, m.reset(), l.clear();
2131
+ const y = i;
1648
2132
  try {
1649
- await o({ type: "cancelLiveDraws" }), await o(
2133
+ await E({ type: "cancelLiveDraws" }), await E(
1650
2134
  {
1651
2135
  type: "renderViseme",
1652
2136
  generation: y,
1653
- to: u,
1654
- from: g.from,
1655
- transitionDurationMs: g.transitionDurationMs,
1656
- gapMs: g.gapMs,
1657
- threshold: g.threshold
2137
+ to: d,
2138
+ from: D.from,
2139
+ transitionDurationMs: D.transitionDurationMs,
2140
+ gapMs: D.gapMs,
2141
+ threshold: D.threshold
1658
2142
  },
1659
2143
  void 0,
1660
2144
  !0
1661
2145
  );
1662
- } catch (v) {
1663
- if (v?.name === "AbortError") return;
1664
- throw v;
2146
+ } catch (A) {
2147
+ if (A?.name === "AbortError") return;
2148
+ throw A;
1665
2149
  }
1666
2150
  },
1667
2151
  dispose() {
1668
2152
  if (!a) {
1669
- a = !0, s += 1, d.reset(), l.clear();
1670
- for (const [, w] of m)
1671
- w.resolve();
1672
- m.clear(), r?.terminate(), r = null;
2153
+ a = !0, i += 1, m.reset(), l.clear();
2154
+ for (const [, p] of w)
2155
+ p.resolve();
2156
+ w.clear(), r?.terminate(), r = null;
1673
2157
  }
1674
2158
  }
1675
2159
  };
1676
2160
  }
1677
- function Vr(e, t = {}) {
1678
- if (!Ur())
1679
- return Et(e, t);
1680
- const n = zt(t.workerScriptUrl);
2161
+ function Ds(e, t = {}) {
2162
+ if (!As())
2163
+ return Wt(e, t);
2164
+ const n = Rn(t.workerScriptUrl);
1681
2165
  try {
1682
- return Nr(e, t, n);
2166
+ return Rs(e, t, n);
1683
2167
  } catch {
1684
- return Et(e, t);
2168
+ return Wt(e, t);
1685
2169
  }
1686
2170
  }
1687
- class $r extends Error {
2171
+ class Ms extends Error {
1688
2172
  constructor(t, n) {
1689
2173
  super(`${t} timed out after ${Math.round(n / 1e3)}s`), this.name = "LoadTimeoutError";
1690
2174
  }
1691
2175
  }
1692
- function qe(e, t, n) {
1693
- return new Promise((r, i) => {
1694
- const s = globalThis.setTimeout(() => {
1695
- i(new $r(n, t));
2176
+ function Xe(e, t, n) {
2177
+ return new Promise((r, s) => {
2178
+ const i = globalThis.setTimeout(() => {
2179
+ s(new Ms(n, t));
1696
2180
  }, t);
1697
2181
  e.then(
1698
- (c) => {
1699
- globalThis.clearTimeout(s), r(c);
2182
+ (o) => {
2183
+ globalThis.clearTimeout(i), r(o);
1700
2184
  },
1701
- (c) => {
1702
- globalThis.clearTimeout(s), i(c);
2185
+ (o) => {
2186
+ globalThis.clearTimeout(i), s(o);
1703
2187
  }
1704
2188
  );
1705
2189
  });
1706
2190
  }
1707
- const Hr = {
2191
+ const xs = {
1708
2192
  position: "relative",
1709
2193
  display: "inline-block",
1710
2194
  lineHeight: 0
1711
- }, Wr = {
2195
+ }, Cs = {
1712
2196
  display: "block",
1713
2197
  maxWidth: "100%",
1714
2198
  height: "auto"
1715
- }, qr = {
2199
+ }, Ps = {
1716
2200
  position: "absolute",
1717
2201
  inset: 0,
1718
2202
  display: "flex",
@@ -1724,394 +2208,483 @@ const Hr = {
1724
2208
  fontSize: "0.875rem",
1725
2209
  textAlign: "center"
1726
2210
  };
1727
- function Oe(e) {
1728
- return Xt(e) ? Nn : It;
2211
+ function $e(e) {
2212
+ return Cn(e) ? gr : Jt;
2213
+ }
2214
+ function we(e, t) {
2215
+ return t?.isSpeaking() ? t : e.isSpeaking() ? e : t?.isConnected() ? t : e;
1729
2216
  }
1730
- const zr = Nt(function({
2217
+ const Vs = gn(function({
1731
2218
  id: t,
1732
2219
  assets: n,
1733
2220
  authToken: r,
1734
- ttsEngineId: i = pe,
1735
- voiceId: s,
1736
- speakingRate: c = At,
2221
+ ttsEngineId: s = Te,
2222
+ voiceId: i,
2223
+ speakingRate: o = ct,
1737
2224
  className: a,
1738
- style: l,
1739
- canvasStyle: d,
1740
- onStatusChange: _,
1741
- onDisplayStatus: m,
1742
- onError: S,
1743
- onReady: o,
1744
- showErrorOverlay: F = !0
1745
- }, w) {
1746
- const u = R(null), g = R(null), y = R(xr()), v = R(dr()), H = R(0), h = R(0), E = R(null), D = R(null), L = R(!1), z = R(!1), U = R(!1), ae = R("sil"), me = R(!1), N = R(
2225
+ style: f,
2226
+ canvasStyle: l,
2227
+ onStatusChange: m,
2228
+ onDisplayStatus: _,
2229
+ onError: w,
2230
+ onReady: k,
2231
+ showErrorOverlay: E = !0,
2232
+ onUserTranscript: u,
2233
+ onBotOutput: p,
2234
+ onRealtimeLipsyncDebug: d
2235
+ }, D) {
2236
+ const y = O(null), A = O(null), U = O(ps()), V = O(es()), z = O(0), K = O(0), S = O(0), M = O(null), g = O(null), v = O(!1), T = O(!1), C = O(!1), x = O("sil"), L = O(!1), I = O(
1747
2237
  null
1748
- ), X = R(!1), [Re, He] = ke("idle"), [De, ue] = ke(null), [se, xe] = ke(!1), [nt, p] = ke(!1), [V, W] = ke({ width: 842, height: 1264 }), x = R(r ?? null), M = R(null), I = R(null), Q = R(!1), J = R({ width: 842, height: 1264 }), P = R(o), O = R(m), q = R(S);
1749
- P.current = o, O.current = m, q.current = S;
1750
- const ce = ie(
1751
- (f) => {
1752
- const k = f?.ttsEngineId ?? i ?? I.current?.ttsEngineId ?? pe, T = f?.voiceId ?? s ?? I.current?.voiceId ?? Oe(k);
1753
- return { ttsEngineId: k, voiceId: T };
2238
+ ), $ = O(!1), [Y, ge] = Ce("idle"), [re, j] = Ce(null), [X, Z] = Ce(!1), [c, b] = Ce(!1), [B, Q] = Ce({ width: 842, height: 1264 }), G = O(r ?? null), ue = O(null), H = O(null), _e = O(!1), le = O({ width: 842, height: 1264 }), ze = O(null), mt = O(k), ee = O(_), wt = O(w), gt = O(u), _t = O(p), pt = O(d);
2239
+ mt.current = k, ee.current = _, wt.current = w, gt.current = u, _t.current = p, pt.current = d;
2240
+ const yt = ie(
2241
+ (h) => {
2242
+ const R = h?.ttsEngineId ?? s ?? H.current?.ttsEngineId ?? Te, P = h?.voiceId ?? i ?? H.current?.voiceId ?? $e(R);
2243
+ return { ttsEngineId: R, voiceId: P };
1754
2244
  },
1755
- [i, s]
1756
- ), $ = ie((f) => {
1757
- ue(f), q.current?.(f);
1758
- }, []), Me = ie(
1759
- (f) => {
1760
- He(f), _?.(f);
2245
+ [s, i]
2246
+ ), fe = ie((h) => {
2247
+ j(h), wt.current?.(h);
2248
+ }, []), Re = ie(
2249
+ (h) => {
2250
+ ge(h), m?.(h);
1761
2251
  },
1762
- [_]
1763
- ), B = R(
1764
- Vn(Me, Pe)
1765
- ), b = ie(() => {
1766
- E.current != null && (clearTimeout(E.current), E.current = null);
1767
- }, []), K = ie(() => {
1768
- D.current != null && (clearTimeout(D.current), D.current = null), U.current = !1;
1769
- }, []), te = ie(() => {
1770
- !X.current || !N.current || (K(), U.current = !0, D.current = setTimeout(() => {
1771
- if (D.current = null, B.current.isSpeaking()) {
1772
- U.current = !1;
2252
+ [m]
2253
+ ), W = O(
2254
+ Rt(Re, be)
2255
+ ), q = O(null);
2256
+ Se(() => (W.current = Rt(
2257
+ Re,
2258
+ be
2259
+ ), r && W.current.setDeveloperToken(r), W.current.setTtsEngineId(s), () => {
2260
+ W.current.stop();
2261
+ const h = q.current;
2262
+ h && (h.disconnect(), q.current = null);
2263
+ }), [Re, r, s]);
2264
+ const kt = ie(() => (q.current || (q.current = vr(
2265
+ Re,
2266
+ {
2267
+ speakingRate: o,
2268
+ onUserTranscript: (h, R) => gt.current?.(h, R),
2269
+ onBotOutput: (h) => _t.current?.(h),
2270
+ onLipsyncDebug: (h) => pt.current?.(h)
2271
+ }
2272
+ ), q.current.setTtsEngineId(s)), q.current), [Re, o, s]), se = ie(() => {
2273
+ M.current != null && (clearTimeout(M.current), M.current = null);
2274
+ }, []), ae = ie(() => {
2275
+ g.current != null && (clearTimeout(g.current), g.current = null), C.current = !1;
2276
+ }, []), Et = ie(() => {
2277
+ !$.current || !I.current || (ae(), C.current = !0, g.current = setTimeout(() => {
2278
+ if (g.current = null, we(
2279
+ W.current,
2280
+ q.current
2281
+ ).isSpeaking()) {
2282
+ C.current = !1;
1773
2283
  return;
1774
2284
  }
1775
- if (L.current) {
1776
- U.current = !1;
2285
+ if (v.current) {
2286
+ C.current = !1;
1777
2287
  return;
1778
2288
  }
1779
- const f = N.current;
1780
- if (!f) {
1781
- U.current = !1;
2289
+ const h = I.current;
2290
+ if (!h) {
2291
+ C.current = !1;
1782
2292
  return;
1783
2293
  }
1784
- f.restart(), f.setActive(!0);
1785
- const k = f.getVideo();
1786
- let T = !1;
1787
- const A = () => {
1788
- T || (T = !0, k.removeEventListener("playing", C), U.current = !1);
1789
- }, C = () => {
1790
- A();
2294
+ h.restart(), h.setActive(!0);
2295
+ const R = h.getVideo();
2296
+ let P = !1;
2297
+ const F = () => {
2298
+ P || (P = !0, R.removeEventListener("playing", N), C.current = !1);
2299
+ }, N = () => {
2300
+ F();
1791
2301
  };
1792
- if (k.addEventListener("playing", C, { once: !0 }), k.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA && !k.paused) {
1793
- A();
2302
+ if (R.addEventListener("playing", N, { once: !0 }), R.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA && !R.paused) {
2303
+ F();
1794
2304
  return;
1795
2305
  }
1796
- setTimeout(A, 300);
1797
- }, br));
1798
- }, [K]), Z = ie(() => {
1799
- if (b(), O.current?.("sil"), L.current = !1, !X.current || !N.current) {
1800
- U.current = !1;
2306
+ setTimeout(F, 300);
2307
+ }, ws));
2308
+ }, [ae]), Le = ie(() => {
2309
+ if (se(), ee.current?.("sil"), v.current = !1, !$.current || !I.current) {
2310
+ C.current = !1;
1801
2311
  return;
1802
2312
  }
1803
- te();
1804
- }, [b, te]), j = ie(
1805
- async (f) => {
1806
- const k = h.current, T = g.current, A = u.current, C = () => {
1807
- f?.fallbackOnly || (L.current = !1);
2313
+ Et();
2314
+ }, [se, Et]), Ye = ie(
2315
+ async (h) => {
2316
+ const R = K.current, P = A.current, F = y.current, N = () => {
2317
+ h?.fallbackOnly || (v.current = !1);
1808
2318
  };
1809
- if (!T || !A || !se) {
1810
- C();
2319
+ if (!P || !F || !X) {
2320
+ N();
1811
2321
  return;
1812
2322
  }
1813
- if (B.current.isSpeaking()) {
1814
- C();
2323
+ if (we(
2324
+ W.current,
2325
+ q.current
2326
+ ).isSpeaking()) {
2327
+ N();
1815
2328
  return;
1816
2329
  }
1817
- if (f?.fallbackOnly) {
1818
- if (!L.current || (ge(y.current), await T.renderSilOnly(), k !== h.current) || B.current.isSpeaking()) return;
1819
- Z();
2330
+ if (h?.fallbackOnly) {
2331
+ if (!v.current || (me(U.current), await P.renderSilOnly(), R !== K.current) || we(
2332
+ W.current,
2333
+ q.current
2334
+ ).isSpeaking())
2335
+ return;
2336
+ Le();
1820
2337
  return;
1821
2338
  }
1822
- const Y = ae.current !== "sil" ? ae.current : Mr(B.current.getVisemeQueue()), ne = Cr(Y);
1823
- if (ge(y.current), !ne) {
1824
- if (await T.renderSilOnly(), k !== h.current || B.current.isSpeaking()) return;
1825
- Z();
2339
+ const te = x.current !== "sil" ? x.current : ks(
2340
+ we(
2341
+ W.current,
2342
+ q.current
2343
+ ).getVisemeQueue()
2344
+ ), oe = Es(
2345
+ te,
2346
+ ze.current
2347
+ );
2348
+ if (me(U.current), !oe) {
2349
+ if (await P.renderSilOnly(), R !== K.current || we(
2350
+ W.current,
2351
+ q.current
2352
+ ).isSpeaking())
2353
+ return;
2354
+ Le();
1826
2355
  return;
1827
2356
  }
1828
2357
  try {
1829
- await T.renderViseme(A, "sil", {
1830
- from: Y,
1831
- transitionDurationMs: Ct
2358
+ await P.renderViseme(F, "sil", {
2359
+ from: te,
2360
+ transitionDurationMs: cn
1832
2361
  });
1833
- } catch (oe) {
1834
- if (oe?.name !== "AbortError")
1835
- throw oe;
2362
+ } catch (de) {
2363
+ if (de?.name !== "AbortError")
2364
+ throw de;
1836
2365
  }
1837
- if (k !== h.current) {
1838
- C();
2366
+ if (R !== K.current) {
2367
+ N();
1839
2368
  return;
1840
2369
  }
1841
- if (B.current.isSpeaking()) {
1842
- C();
2370
+ if (we(
2371
+ W.current,
2372
+ q.current
2373
+ ).isSpeaking()) {
2374
+ N();
1843
2375
  return;
1844
2376
  }
1845
- Z();
2377
+ Le();
1846
2378
  },
1847
- [se, Z]
1848
- ), _e = ie(() => {
1849
- if (z.current || L.current) return;
1850
- z.current = !0, L.current = !0, b();
1851
- const f = h.current;
1852
- j().finally(() => {
1853
- z.current = !1;
1854
- }), E.current = setTimeout(() => {
1855
- E.current = null, f === h.current && j({ fallbackOnly: !0 });
1856
- }, Fr());
1857
- }, [b, j]), rt = ie(async () => {
1858
- const f = Math.floor(Date.now() / 1e3);
1859
- if (M.current && f < M.current.expiresAt - 60)
1860
- return M.current.key;
1861
- const k = x.current ?? await ot();
1862
- x.current = k, B.current.setDeveloperToken(k);
1863
- const T = await an(k, Pe);
1864
- return M.current = {
1865
- key: T.value,
1866
- expiresAt: T.expiresAt
1867
- }, T.value;
2379
+ [X, Le]
2380
+ ), De = ie(() => {
2381
+ if (T.current || v.current) return;
2382
+ T.current = !0, v.current = !0, se();
2383
+ const h = K.current;
2384
+ Ye().finally(() => {
2385
+ T.current = !1;
2386
+ }), M.current = setTimeout(() => {
2387
+ M.current = null, h === K.current && Ye({ fallbackOnly: !0 });
2388
+ }, Ss());
2389
+ }, [se, Ye]), St = ie(async () => {
2390
+ const h = Math.floor(Date.now() / 1e3);
2391
+ if (ue.current && h < ue.current.expiresAt - 60)
2392
+ return ue.current.key;
2393
+ const R = G.current ?? await Qe();
2394
+ G.current = R, W.current.setDeveloperToken(R);
2395
+ const P = await Vn(R, be);
2396
+ return ue.current = {
2397
+ key: P.value,
2398
+ expiresAt: P.expiresAt
2399
+ }, P.value;
1868
2400
  }, []);
1869
- Te(() => {
1870
- r && (x.current = r, B.current.setDeveloperToken(r));
1871
- }, [r]), Te(() => {
1872
- B.current.setTtsEngineId(i), I.current && (I.current.ttsEngineId = i);
1873
- }, [i]), Te(() => {
1874
- const f = s ?? Oe(i);
1875
- I.current && (I.current.voiceId = f);
1876
- }, [s, i]);
1877
- const Ot = Vt(
2401
+ Se(() => {
2402
+ r && (G.current = r, W.current.setDeveloperToken(r));
2403
+ }, [r]), Se(() => {
2404
+ W.current.setTtsEngineId(s), q.current?.setTtsEngineId(s), H.current && (H.current.ttsEngineId = s);
2405
+ }, [s]), Se(() => {
2406
+ const h = i ?? $e(s);
2407
+ H.current && (H.current.voiceId = h);
2408
+ }, [i, s]);
2409
+ const fn = _n(
1878
2410
  () => n ? JSON.stringify(n) : `id:${t ?? ""}`,
1879
2411
  [n, t]
1880
2412
  );
1881
- return Te(() => {
2413
+ return Se(() => {
1882
2414
  if (!t && !n) {
1883
- $("AiTwin requires either `id` or `assets`");
2415
+ fe("AiTwin requires either `id` or `assets`");
1884
2416
  return;
1885
2417
  }
1886
- let f = !1;
1887
- Q.current = !1, xe(!1), p(!1), ue(null), I.current = null, N.current = null, X.current = !1;
1888
- const k = u.current;
1889
- if (!k) return;
1890
- let T = null;
2418
+ let h = !1;
2419
+ _e.current = !1, Z(!1), b(!1), j(null), H.current = null, I.current = null, $.current = !1;
2420
+ const R = y.current;
2421
+ if (!R) return;
2422
+ let P = null;
1891
2423
  return (async () => {
1892
2424
  try {
1893
- let A, C, Y;
2425
+ let F, N, te;
1894
2426
  if (n)
1895
- A = n, C = i, Y = s ?? Oe(C);
2427
+ F = n, N = s, te = i ?? $e(N);
1896
2428
  else {
1897
- O.current?.("getAiTwin");
1898
- const G = await qe(
1899
- en(t),
2429
+ ee.current?.("getAiTwin");
2430
+ const J = await Xe(
2431
+ Bn(t),
1900
2432
  3e4,
1901
2433
  "getAiTwin"
1902
2434
  );
1903
- if (f) return;
1904
- if (!G.faceId?.trim())
2435
+ if (h) return;
2436
+ if (!J.faceId?.trim())
1905
2437
  throw new Error("getAiTwin returned no faceId");
1906
- C = G.ttsEngineId, Y = s ?? G.voiceId ?? Oe(C), A = fn(G.faceId);
2438
+ N = J.ttsEngineId, te = i ?? J.voiceId ?? $e(N), F = qn(J.faceId);
1907
2439
  }
1908
- I.current = { ttsEngineId: C, voiceId: Y }, dn(A), N.current = hr(), T = Vr(k, {
1909
- onStatus: (G) => {
1910
- f || O.current?.(G);
2440
+ H.current = { ttsEngineId: N, voiceId: te }, Kn(F), I.current = ts(), P = Ds(R, {
2441
+ onStatus: (J) => {
2442
+ h || ee.current?.(J);
1911
2443
  },
1912
- onError: (G) => {
1913
- f || $(G);
2444
+ onError: (J) => {
2445
+ h || fe(J);
1914
2446
  },
1915
- shouldAcceptLiveFrame: () => B.current.isSpeaking() && !L.current
1916
- }), g.current = T, O.current?.("auth");
1917
- const ne = x.current ?? r ?? await qe(ot(), 3e4, "getAuthToken");
1918
- if (f) return;
1919
- x.current = ne, B.current.setDeveloperToken(ne), B.current.setTtsEngineId(C);
1920
- const oe = Be() ? await rt() : void 0;
1921
- if (f) return;
1922
- O.current?.("loadAssets");
1923
- const we = await qe(
1924
- T.loadAssets(oe),
2447
+ shouldAcceptLiveFrame: () => we(
2448
+ W.current,
2449
+ q.current
2450
+ ).isSpeaking() && !v.current
2451
+ }), A.current = P, ee.current?.("auth");
2452
+ const oe = G.current ?? r ?? await Xe(Qe(), 3e4, "getAuthToken");
2453
+ if (h) return;
2454
+ G.current = oe, W.current.setDeveloperToken(oe), W.current.setTtsEngineId(N);
2455
+ const de = Ke() ? await St() : void 0;
2456
+ if (h) return;
2457
+ ee.current?.("loadAssets");
2458
+ const ce = await Xe(
2459
+ P.loadAssets(de),
1925
2460
  18e4,
1926
2461
  "load face assets"
1927
2462
  );
1928
- if (!f && we.width > 0 && we.height > 0 && (J.current = we, W(we)), f) return;
1929
- Q.current = !0, xe(!0), P.current?.(), T.renderSilOnly().then(() => {
1930
- f || O.current?.("sil");
2463
+ if (!h && ce.width > 0 && ce.height > 0 && (le.current = ce, Q(ce)), h) return;
2464
+ ze.current = P.getVisemeAtlasPaths(), _e.current = !0, Z(!0), mt.current?.(), P.renderSilOnly().then(() => {
2465
+ h || ee.current?.("sil");
1931
2466
  }), (async () => {
1932
2467
  try {
1933
- const G = await zn(oe);
1934
- if (await N.current.load(G), f) return;
1935
- X.current = !0, p(!0), ge(y.current), N.current.setActive(!0);
1936
- const re = N.current.getVideo();
1937
- await _t(
1938
- k,
1939
- re,
2468
+ const J = await xr(de);
2469
+ if (await I.current.load(J), h) return;
2470
+ $.current = !0, b(!0), me(U.current), I.current.setActive(!0);
2471
+ const ne = I.current.getVideo();
2472
+ await Ut(
2473
+ R,
2474
+ ne,
1940
2475
  null,
1941
2476
  void 0,
1942
- J.current
1943
- ), f || O.current?.("idle");
1944
- } catch (G) {
1945
- if (f) return;
1946
- X.current = !1, p(!1), console.warn("[AiTwin] Idle video unavailable:", G);
2477
+ le.current
2478
+ ), h || ee.current?.("idle");
2479
+ } catch (J) {
2480
+ if (h) return;
2481
+ $.current = !1, b(!1), console.warn("[AiTwin] Idle video unavailable:", J);
1947
2482
  }
1948
2483
  })();
1949
- } catch (A) {
1950
- if (f) return;
1951
- if (A instanceof Ke) {
1952
- $(A.message);
2484
+ } catch (F) {
2485
+ if (h) return;
2486
+ if (F instanceof Ze) {
2487
+ fe(F.message);
1953
2488
  return;
1954
2489
  }
1955
- $(A instanceof Error ? A.message : "Failed to load AI twin");
2490
+ fe(F instanceof Error ? F.message : "Failed to load AI twin");
1956
2491
  }
1957
2492
  })(), () => {
1958
- f = !0, N.current?.dispose(), T?.dispose(), g.current = null;
2493
+ h = !0, I.current?.dispose(), P?.dispose(), A.current = null;
1959
2494
  };
1960
- }, [Ot, n, i, s, r, rt, $]), Te(() => {
1961
- const f = B.current, k = { current: !1 }, T = () => {
1962
- const A = u.current, C = g.current;
1963
- if (!A || !C || !se) {
1964
- H.current = requestAnimationFrame(T);
2495
+ }, [fn, n, s, i, r, St, fe]), Se(() => {
2496
+ const h = { current: !1 }, R = () => {
2497
+ const P = y.current, F = A.current, N = we(
2498
+ W.current,
2499
+ q.current
2500
+ );
2501
+ if (!P || !F || !X) {
2502
+ z.current = requestAnimationFrame(R);
1965
2503
  return;
1966
2504
  }
1967
- const Y = f.isSpeaking(), ne = me.current && !Y;
1968
- ne && (v.current.reset(), N.current?.setActive(!1), _e());
1969
- const oe = f.getPlaybackElapsedMs(), we = Y ? gr(
1970
- oe,
1971
- f.getSentenceEmotions(),
1972
- f.getWordQueue(),
1973
- f.getStreamMood()
1974
- ) : f.getStreamMood(), G = ne || L.current || U.current;
1975
- if (Y) {
1976
- X.current && N.current?.setActive(!1);
1977
- const re = f.getVisemeQueue();
1978
- if (re.length === 0) {
1979
- H.current = requestAnimationFrame(T);
1980
- return;
1981
- }
1982
- const le = vt(re, oe);
1983
- le !== "sil" && (ae.current = le), v.current.setTargetEmotion(we), v.current.advance(performance.now());
1984
- const fe = v.current.getExpressionPath(), Ee = v.current.getDrawKey();
1985
- Or(
1986
- A,
1987
- f.getVisemeQueue(),
1988
- oe,
1989
- fe,
1990
- Ee,
1991
- y.current,
1992
- (Se, We, Pt, Ut) => C.drawLiveFrame(Se, We, Pt, Ut),
1993
- (Se) => O.current?.(Se)
2505
+ const te = N.isSpeaking(), oe = te && !L.current, de = L.current && !te;
2506
+ oe && (se(), ae(), v.current = !1, T.current = !1, me(U.current), S.current = 0, x.current = "sil", I.current?.setActive(!1)), de && (V.current.reset(), I.current?.setActive(!1), De());
2507
+ const ce = N.getPlaybackElapsedMs(), J = de || v.current || C.current;
2508
+ if (te) {
2509
+ $.current && I.current?.setActive(!1);
2510
+ const ne = N.getVisemeQueue(), pe = ne.length > 0 ? at(ne, ce) : "sil";
2511
+ pe !== "sil" && (x.current = pe);
2512
+ const he = is(
2513
+ ce,
2514
+ N.getSentenceEmotions(),
2515
+ N.getWordQueue(),
2516
+ N.getStreamMood()
2517
+ );
2518
+ V.current.setTargetEmotion(he), V.current.setTargetEyebrow(
2519
+ Zr(
2520
+ ce,
2521
+ N.getWordQueue(),
2522
+ dt(he)
2523
+ )
2524
+ ), V.current.advance(performance.now());
2525
+ const Me = V.current.getExpressionPath(), Je = V.current.getDrawKey();
2526
+ bs(
2527
+ P,
2528
+ ne,
2529
+ ce,
2530
+ Me,
2531
+ Je,
2532
+ U.current,
2533
+ (xe, dn, hn, mn) => F.drawLiveFrame(xe, dn, hn, mn),
2534
+ (xe) => ee.current?.(xe),
2535
+ ze.current
1994
2536
  );
1995
- } else if (!G && X.current && N.current) {
1996
- const re = N.current, le = re.getVideo();
1997
- le.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA ? (re.setActive(!0), k.current || (k.current = !0, _t(
1998
- A,
1999
- le,
2537
+ } else if (!J && $.current && I.current) {
2538
+ const ne = I.current, pe = ne.getVideo();
2539
+ pe.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA ? (ne.setActive(!0), h.current || (h.current = !0, Ut(
2540
+ P,
2541
+ pe,
2000
2542
  null,
2001
2543
  void 0,
2002
- J.current,
2003
- () => !f.isSpeaking() && !L.current && !U.current
2004
- ).then(() => O.current?.("idle")).finally(() => {
2005
- k.current = !1;
2006
- }))) : gt(
2007
- A,
2544
+ le.current,
2545
+ () => !N.isSpeaking() && !v.current && !C.current
2546
+ ).then(() => ee.current?.("idle")).finally(() => {
2547
+ h.current = !1;
2548
+ }))) : Vt(
2549
+ P,
2008
2550
  null,
2009
2551
  "__sil__",
2010
- y.current,
2011
- (fe, Ee, Se, We) => C.drawLiveFrame(fe, Ee, Se, We),
2012
- (fe) => O.current?.(fe)
2552
+ U.current,
2553
+ (he, Me, Je, xe) => F.drawLiveFrame(he, Me, Je, xe),
2554
+ (he) => ee.current?.(he)
2013
2555
  );
2014
- } else G || gt(
2015
- A,
2556
+ } else J || Vt(
2557
+ P,
2016
2558
  null,
2017
2559
  "__sil__",
2018
- y.current,
2019
- (re, le, fe, Ee) => C.drawLiveFrame(re, le, fe, Ee),
2020
- (re) => O.current?.(re)
2560
+ U.current,
2561
+ (ne, pe, he, Me) => F.drawLiveFrame(ne, pe, he, Me),
2562
+ (ne) => ee.current?.(ne)
2021
2563
  );
2022
- me.current = Y, H.current = requestAnimationFrame(T);
2564
+ L.current = te, z.current = requestAnimationFrame(R);
2023
2565
  };
2024
- return H.current = requestAnimationFrame(T), () => {
2025
- cancelAnimationFrame(H.current), b(), K(), f.stop();
2566
+ return z.current = requestAnimationFrame(R), () => {
2567
+ cancelAnimationFrame(z.current), se(), ae(), W.current.stop(), q.current?.stop();
2026
2568
  };
2027
2569
  }, [
2570
+ X,
2571
+ c,
2572
+ De,
2028
2573
  se,
2029
- nt,
2030
- _e,
2031
- b,
2032
- K
2033
- ]), $t(
2034
- w,
2574
+ ae
2575
+ ]), pn(
2576
+ D,
2035
2577
  () => ({
2036
- speakText: async (f, k) => {
2037
- const T = f.trim();
2038
- if (!T) return;
2039
- const A = g.current;
2040
- if (!A || !Q.current && !se)
2578
+ speakText: async (h, R) => {
2579
+ const P = h.trim();
2580
+ if (!P) return;
2581
+ const F = A.current;
2582
+ if (!F || !_e.current && !X)
2041
2583
  throw new Error("AI twin is not ready");
2042
- const { ttsEngineId: C, voiceId: Y } = ce(k);
2043
- ue(null), h.current += 1, b(), K(), L.current = !1, z.current = !1, ae.current = "sil", ge(y.current), v.current.reset(), me.current = !1;
2584
+ const { ttsEngineId: N, voiceId: te } = yt(R);
2585
+ j(null), K.current += 1, se(), ae(), v.current = !1, T.current = !1, x.current = "sil", me(U.current), V.current.reset(), L.current = !1;
2044
2586
  try {
2045
- X.current ? (N.current?.setActive(!1), N.current?.restart(), ge(y.current)) : await A.renderSilOnly(), await B.current.speak(T, {
2046
- voiceId: Y,
2047
- speakingRate: k?.speakingRate ?? c,
2048
- ttsEngineId: C
2587
+ $.current ? (I.current?.setActive(!1), I.current?.restart(), me(U.current)) : await F.renderSilOnly(), await W.current.speak(P, {
2588
+ voiceId: te,
2589
+ speakingRate: R?.speakingRate ?? o,
2590
+ ttsEngineId: N
2049
2591
  });
2050
- } catch (ne) {
2051
- throw $(ne instanceof Error ? ne.message : "TTS failed"), ne;
2592
+ } catch (oe) {
2593
+ throw fe(oe instanceof Error ? oe.message : "TTS failed"), oe;
2052
2594
  }
2053
2595
  },
2054
2596
  stop: () => {
2055
- h.current += 1, b(), K(), L.current = !1, z.current = !1, B.current.stop(), ge(y.current), me.current = !1, _e();
2597
+ K.current += 1, se(), ae(), v.current = !1, T.current = !1, W.current.stop(), q.current?.stop(), me(U.current), L.current = !1, De();
2056
2598
  },
2057
- setTtsEngineId: (f) => {
2058
- B.current.setTtsEngineId(f), I.current && (I.current.ttsEngineId = f);
2599
+ setTtsEngineId: (h) => {
2600
+ W.current.setTtsEngineId(h), q.current?.setTtsEngineId(h), H.current && (H.current.ttsEngineId = h);
2059
2601
  },
2060
- renderViseme: async (f, k) => {
2061
- const T = g.current, A = u.current;
2062
- if (!T || !A || !Q.current)
2602
+ renderViseme: async (h, R) => {
2603
+ const P = A.current, F = y.current;
2604
+ if (!P || !F || !_e.current)
2063
2605
  throw new Error("AI twin is not ready");
2064
- await T.renderViseme(A, f, {
2065
- from: k?.from,
2066
- transitionDurationMs: k?.transitionDurationMs,
2067
- gapMs: k?.gapMs,
2068
- onStatus: (C) => O.current?.(C)
2606
+ await P.renderViseme(F, h, {
2607
+ from: R?.from,
2608
+ transitionDurationMs: R?.transitionDurationMs,
2609
+ gapMs: R?.gapMs,
2610
+ onStatus: (N) => ee.current?.(N)
2069
2611
  });
2070
2612
  },
2071
- isReady: () => Q.current,
2072
- getStatus: () => Re
2613
+ isReady: () => _e.current,
2614
+ getStatus: () => Y,
2615
+ connect: async (h = {}) => {
2616
+ j(null);
2617
+ try {
2618
+ let R = h.authToken?.trim();
2619
+ R || (R = G.current ?? r ?? await Qe(), G.current = R);
2620
+ const P = h.voiceId?.trim() ?? i ?? H.current?.voiceId, F = kt();
2621
+ await F.unlockAudio(), await F.connect({
2622
+ ...h,
2623
+ authToken: R,
2624
+ voiceId: P,
2625
+ speakingRate: h.speakingRate ?? o
2626
+ });
2627
+ } catch (R) {
2628
+ throw fe(
2629
+ R instanceof Error ? R.message : "Voice connect failed"
2630
+ ), R;
2631
+ }
2632
+ },
2633
+ disconnect: async () => {
2634
+ const h = q.current;
2635
+ h && (K.current += 1, se(), ae(), v.current = !1, T.current = !1, me(U.current), L.current = !1, await h.disconnect(), De());
2636
+ },
2637
+ isConnected: () => q.current?.isConnected() ?? !1
2073
2638
  }),
2074
2639
  [
2640
+ X,
2641
+ o,
2642
+ r,
2643
+ i,
2075
2644
  se,
2076
- c,
2077
- b,
2078
- _e,
2079
- $,
2080
- ce,
2081
- Re
2645
+ ae,
2646
+ De,
2647
+ fe,
2648
+ yt,
2649
+ kt,
2650
+ Y
2082
2651
  ]
2083
- ), /* @__PURE__ */ Bt("div", { className: a, style: { ...Hr, ...l }, children: [
2084
- /* @__PURE__ */ it(
2652
+ ), /* @__PURE__ */ wn("div", { className: a, style: { ...xs, ...f }, children: [
2653
+ /* @__PURE__ */ vt(
2085
2654
  "canvas",
2086
2655
  {
2087
- ref: u,
2088
- width: V.width,
2089
- height: V.height,
2090
- style: { ...Wr, ...d },
2656
+ ref: y,
2657
+ width: B.width,
2658
+ height: B.height,
2659
+ style: { ...Cs, ...l },
2091
2660
  "aria-label": t ? `AI twin ${t}` : "AI twin face"
2092
2661
  }
2093
2662
  ),
2094
- F && De ? /* @__PURE__ */ it("div", { style: qr, children: De }) : null
2663
+ E && re ? /* @__PURE__ */ vt("div", { style: Ps, children: re }) : null
2095
2664
  ] });
2096
2665
  });
2097
2666
  export {
2098
- zr as AiTwin,
2099
- Ke as AiTwinNotFoundError,
2100
- pe as DEFAULT_TTS_ENGINE_ID,
2101
- En as OCULUS_VISEME_IDS,
2102
- Bn as SPEAKING_RATE_MAX,
2103
- Un as SPEAKING_RATE_MIN,
2104
- be as TTS_ENGINE_CARTESIA,
2105
- kt as TTS_ENGINE_GOOGLE,
2106
- Ze as TTS_ENGINE_INWORLD,
2107
- Gr as VISEME_IDS,
2108
- Nn as VISEME_TEST_CARTESIA_VOICE_ID,
2109
- At as VISEME_TEST_SPEAKING_RATE,
2110
- It as VISEME_TEST_VOICE_ID,
2111
- Vn as createAvatarTtsLipsyncController,
2112
- en as fetchAiTwin,
2113
- ot as fetchDevAuthToken,
2114
- kn as normalizeOculusViseme,
2115
- vt as resolveVisemeAtTime,
2116
- Pn as resolveWordAtTime
2667
+ Vs as AiTwin,
2668
+ Ze as AiTwinNotFoundError,
2669
+ Te as DEFAULT_TTS_ENGINE_ID,
2670
+ Qt as MIC_SAMPLE_RATE,
2671
+ Zn as OCULUS_VISEME_IDS,
2672
+ Xt as PLAYBACK_SAMPLE_RATE,
2673
+ Yt as SPEAKING_RATE_MAX,
2674
+ zt as SPEAKING_RATE_MIN,
2675
+ Ae as TTS_ENGINE_CARTESIA,
2676
+ Kt as TTS_ENGINE_GOOGLE,
2677
+ ot as TTS_ENGINE_INWORLD,
2678
+ Ns as VISEME_IDS,
2679
+ gr as VISEME_TEST_CARTESIA_VOICE_ID,
2680
+ ct as VISEME_TEST_SPEAKING_RATE,
2681
+ Jt as VISEME_TEST_VOICE_ID,
2682
+ Er as buildVoiceWebSocketUrl,
2683
+ Rt as createAvatarTtsLipsyncController,
2684
+ vr as createRealtimeVoiceLipsyncController,
2685
+ Bn as fetchAiTwin,
2686
+ Qe as fetchDevAuthToken,
2687
+ tr as normalizeOculusViseme,
2688
+ at as resolveVisemeAtTime,
2689
+ Us as resolveWordAtTime
2117
2690
  };