@streamoji/aitwin 0.1.7 → 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 It, jsx as Qe } from "react/jsx-runtime";
2
- import { forwardRef as Tt, useRef as B, useState as me, useCallback as ne, useEffect as oe, useMemo as At, useImperativeHandle as bt } from "react";
3
- const Rt = "https://pub-607ad1fc22e2400eb57d17240aab857c.r2.dev", dt = {
4
- publicBase: Rt
5
- }, Dt = "0.1.7", xt = {
6
- version: Dt
7
- }, Ct = {}, Re = "https://ai.streamoji.com", Mt = `${dt.publicBase}/custom-faces`, Ft = `${dt.publicBase}/aitwin-workers/v${xt.version}/visemeDiffPreview.worker.js`;
8
- function Ot(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" ? Ct?.VITE_AITWIN_WORKER_URL : void 0;
11
- return t?.trim() ? t.trim() : Ft;
12
- }
13
- const Pt = "https://us-central1-streamoji-265f4.cloudfunctions.net/getAiTwin", ht = "eng_a7f2b9c1", Ke = "eng_d4e8f3a2", pe = "eng_c9b1e6d4", ce = pe, Lt = /* @__PURE__ */ new Set([
14
- Ke,
15
- pe
16
- ]), mt = {
17
- [ht]: "oculus_direct",
18
- [pe]: "oculus_direct",
19
- [Ke]: "inworld_word"
20
- }, Je = {
21
- google: ht,
22
- inworld: Ke,
23
- cartesia: pe
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 Ut(e) {
26
- return mt[e];
27
+ function xn(e) {
28
+ return jt[e];
27
29
  }
28
- function Bt(e) {
29
- return e === pe;
30
+ function Cn(e) {
31
+ return e === Ae;
30
32
  }
31
- function Nt(e) {
32
- if (e.ttsEngineId && e.ttsEngineId in mt)
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 Je ? Je[t] : ce;
37
+ return t && t in bt ? bt[t] : Te;
36
38
  }
37
- class Ue 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 $t(e, t = Pt) {
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 Ue();
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 Ue(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: Nt(i.data)
57
+ ...o,
58
+ ttsEngineId: Pn(s.data)
57
59
  };
58
60
  }
59
- const Vt = "https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken", Ht = "client_6TNvp3SCs4Og0a1ijm9TommXLql1", Wt = "kk8Fq8EmexzP10jMIEwY3R44M5RKUEm1", qt = "6TNvp3SCs4Og0a1ijm9TommXLql1", Kt = "Swaraj Mali";
60
- async function Ye() {
61
- const e = await fetch(Vt, {
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": Ht,
66
- "Client-Secret": Wt
67
+ "Client-Id": Ln,
68
+ "Client-Secret": Fn
67
69
  },
68
70
  body: JSON.stringify({
69
- userId: qt,
70
- userName: Kt
71
+ userId: Un,
72
+ userName: Nn
71
73
  })
72
74
  });
73
75
  if (!e.ok)
@@ -77,7 +79,7 @@ async function Ye() {
77
79
  throw new Error("getAuthToken returned no token");
78
80
  return n;
79
81
  }
80
- async function jt(e, t = Re) {
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 jt(e, t = Re) {
87
89
  if (!r.value) throw new Error("Session value response missing value");
88
90
  return r;
89
91
  }
90
- function Gt(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 Gt(e) {
95
97
  n[r / 2] = Number.parseInt(t.slice(r, r + 2), 16);
96
98
  return n;
97
99
  }
98
- function Ie(e) {
100
+ function Fe(e) {
99
101
  return Uint8Array.from(e);
100
102
  }
101
- function zt(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 Qt(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 = Ie(n.subarray(0, 12)), i = Ie(n.subarray(12, 28)), s = Ie(n.subarray(28)), c = Ie(zt(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
- Gt(t),
113
+ $n(t),
112
114
  { name: "AES-GCM" },
113
115
  !1,
114
116
  ["decrypt"]
@@ -116,82 +118,95 @@ async function Qt(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 Be = null;
123
- const Ne = /* @__PURE__ */ new Set();
124
- function Jt(e, t = Mt) {
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 Yt(e) {
129
- Be = e;
130
- for (const t of Ne) t();
143
+ function Kn(e) {
144
+ et = He(e);
145
+ for (const t of tt) t();
131
146
  }
132
- function Xt(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 ie() {
149
- if (!Be)
163
+ function Ee() {
164
+ if (!et)
150
165
  throw new Error("Twin assets not configured; call setActiveTwinAssets first");
151
- return Be;
166
+ return et;
152
167
  }
153
- function Zt(e) {
154
- return Ne.add(e), () => Ne.delete(e);
168
+ function Gn(e) {
169
+ return tt.add(e), () => tt.delete(e);
155
170
  }
156
- function Xe() {
157
- const { binBase: e, twinBase: t, encrypted: n } = ie();
158
- return n ? `${e}/sil.bin` : `${t}/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 en() {
161
- const { binBase: e, twinBase: t, encrypted: n } = ie();
162
- return n ? `${e}/idle.bin` : `${t}/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 tn() {
165
- const { encrypted: e, binBase: t, twinBase: n } = ie();
166
- return e ? t : n;
179
+ function Yn() {
180
+ const e = Ee();
181
+ return Ie(e) ? e.binBase : e.twinBase;
167
182
  }
168
- function je() {
169
- return ie().encrypted;
183
+ function Ke() {
184
+ return Ie(Ee());
170
185
  }
171
- function nn() {
172
- const { binBase: e, twinBase: t, encrypted: n } = ie();
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 rn() {
176
- const { binBase: e, twinBase: t, encrypted: n } = ie();
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 sn(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 on = [
209
+ const Zn = [
195
210
  "aa",
196
211
  "CH",
197
212
  "DD",
@@ -207,14 +222,14 @@ const on = [
207
222
  "kk",
208
223
  "nn",
209
224
  "sil"
210
- ], an = new Map(
211
- on.map((e) => [e.toLowerCase(), e])
225
+ ], er = new Map(
226
+ Zn.map((e) => [e.toLowerCase(), e])
212
227
  );
213
- function cn(e) {
228
+ function tr(e) {
214
229
  const t = (e ?? "").trim();
215
- return t ? an.get(t.toLowerCase()) ?? "sil" : "sil";
230
+ return t ? er.get(t.toLowerCase()) ?? "sil" : "sil";
216
231
  }
217
- const un = {
232
+ const nr = {
218
233
  aei: ["aa", "E", "I"],
219
234
  o: ["O", "U"],
220
235
  ee: ["I"],
@@ -226,46 +241,46 @@ const un = {
226
241
  qw: ["U", "O"],
227
242
  cdgknstxyz: ["DD", "SS", "kk", "CH"]
228
243
  };
229
- function ln(e) {
244
+ function rr(e) {
230
245
  if (!e) return ["sil"];
231
246
  const t = e.toLowerCase();
232
- return un[t] ?? ["sil"];
247
+ return nr[t] ?? ["sil"];
233
248
  }
234
- function fn(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 xe(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 dn(e, t) {
247
- const n = e.toLowerCase(), r = xe(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 hn(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 = xe(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 mn(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) || xe(n, t) === "o" ? "O" : "U";
281
+ return /wo|wh/.test(s) || je(n, t) === "o" ? "O" : "U";
267
282
  }
268
- const Te = {
283
+ const Ne = {
269
284
  d: "DD",
270
285
  t: "DD",
271
286
  n: "DD",
@@ -277,65 +292,65 @@ const Te = {
277
292
  x: "CH",
278
293
  j: "CH"
279
294
  };
280
- function _n(e, t) {
281
- const n = e.toLowerCase(), r = xe(n, t);
282
- if (Te[r]) return Te[r];
283
- for (let i = 0; i < n.length; i++) {
284
- const s = n[i];
285
- if (Te[s]) return Te[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 wn(e, t, n) {
290
- const r = ln(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 dn(i, c);
312
+ return ir(s, o);
298
313
  case "o":
299
- return hn(i, c);
314
+ return or(s, o);
300
315
  case "qw":
301
- return mn(i, c);
316
+ return ar(s, o);
302
317
  case "cdgknstxyz":
303
- return _n(i, c);
318
+ return cr(s, o);
304
319
  default:
305
320
  return r[0];
306
321
  }
307
322
  }
308
- function gn(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 yn = 24e3;
316
- function pn(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 Ze(e, t, n = yn) {
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 En(e) {
331
- const t = gn(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 kn(e, t) {
337
- const n = En(t);
338
- if (pn(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 kn(e, t) {
343
358
  return e.decodeAudioData(r);
344
359
  }
345
360
  if (n.length >= 2 && n.length % 2 === 0)
346
- return Ze(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 kn(e, t) {
351
366
  );
352
367
  return await e.decodeAudioData(r);
353
368
  } catch {
354
- return Ze(e, n);
369
+ return At(e, n);
355
370
  }
356
371
  }
357
- function Sn(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 vn(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 et(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 In = 0.5, Tn = 1.5, _t = "Olivia", An = "f786b574-daa5-4673-aa0c-cbe3e8534c02", wt = 0.85;
376
- function bn(e, t = Re) {
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, D = 0, w = 0, u = 0, g = 0, p = null, A = 1, V = "", y = ce, E = ce, x = !1;
381
- const R = /* @__PURE__ */ new Set(), W = () => {
382
- for (const h of l)
383
- h.playbackRate.value = A;
384
- }, q = () => R.forEach((h) => h()), ue = () => {
385
- p != null && (clearTimeout(p), p = null);
386
- }, Ee = () => {
387
- for (const h 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
- h.stop();
392
+ g.stop();
390
393
  } catch {
391
394
  }
392
- l.length = 0;
393
- }, Z = () => {
394
- x = !0, ue(), Ee(), 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"), q();
395
- }, K = () => {
396
- !o || _ || l.length > 0 || a.length > 0 || (m = !1, ue(), e("done"), q());
397
- }, ke = () => {
398
- const h = et(r);
399
- if (h <= 0) {
400
- e("done"), q();
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, D = performance.now(), e("speaking"), q(), ue();
404
- const C = A > 0 ? h / A : h;
405
- p = setTimeout(() => {
406
- x || (m = !1, p = null, e("done"), q());
407
- }, C);
408
- }, Fe = (h, C, N) => {
409
- h.length !== 0 && (N && (u = C), h.forEach((O) => {
410
- const L = String(O.word ?? "").trim();
411
- if (!L) return;
412
- const Q = Math.round((O.start ?? 0) * 1e3), $ = Math.round((O.duration ?? 0) * 1e3);
413
- i.push({
414
- word: L,
415
- wtime: u + Q,
416
- wduration: $,
417
- queueIndex: i.length
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) => {
414
+ const I = String(x.word ?? "").trim();
415
+ if (!I) return;
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({
418
+ word: I,
419
+ wtime: _ + $,
420
+ wduration: Y,
421
+ queueIndex: g.length,
422
+ gesture: x.gesture ?? null,
423
+ emphasis: x.emphasis === !0
418
424
  });
419
425
  }));
420
- }, le = (h, C, N, O) => {
421
- h.length !== 0 && (N && (u = C), h.forEach((v) => {
422
- const L = String(v.symbol ?? "").trim();
423
- if (!L) return;
424
- const Q = Math.round((v.start ?? 0) * 1e3), $ = Math.max(
425
- 1,
426
- Math.round((v.duration ?? 0) * 1e3)
427
- ), P = u + Q;
428
- let M;
429
- if (Ut(O) === "oculus_direct")
430
- M = cn(L);
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 F = vn(i, P), J = F ? fn(F, P) : 0;
433
- M = wn(
434
- L,
435
- F?.word ?? "",
436
- J
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: M,
442
+ g.push({
443
+ viseme: j,
441
444
  weight: 1,
442
- vtime: P,
443
- vduration: $
445
+ vtime: re,
446
+ vduration: ge
444
447
  });
445
- }), q());
446
- }, se = (h, C, N, O, v) => {
447
- Fe(C, N, O), le(h, N, O, v);
448
- }, Se = async (h, C, N, O) => {
449
- if (x || !h?.trim()) {
450
- (C.length > 0 || N.length > 0) && !S && se(
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,
451
463
  C,
452
- N,
453
- u,
454
- O,
455
- E
464
+ x,
465
+ _,
466
+ L,
467
+ u
456
468
  );
457
469
  return;
458
470
  }
459
- if (_) {
460
- a.push({
461
- audio: h,
471
+ if (i) {
472
+ n.push({
473
+ audio: T,
462
474
  visemes: C,
463
- words: N,
464
- isNewSegment: O
475
+ words: x,
476
+ isNewSegment: L
465
477
  });
466
478
  return;
467
479
  }
468
- _ = !0;
480
+ i = !0;
469
481
  try {
470
- const v = window.AudioContext || window.webkitAudioContext, L = d ?? new v();
471
- L.state === "suspended" && await L.resume(), d = L;
472
- const Q = await kn(L, h);
473
- S = !0;
474
- const $ = L.currentTime;
475
- let P = g;
476
- const M = !m;
477
- P < $ && (P = $ + 0.1), g = P + Q.duration;
478
- const F = L.createBufferSource();
479
- if (F.buffer = Q, F.playbackRate.value = A, F.connect(L.destination), l.push(F), x) {
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 (M) {
484
- m = !0, e("speaking"), w = P, u = 0, r.length = 0, i.length = 0;
485
- const H = (P - $) * 1e3;
486
- D = performance.now() + H;
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
- F.onended = () => {
489
- const H = l.indexOf(F);
490
- H >= 0 && l.splice(H, 1), K(), q();
491
- }, F.start(P);
492
- const J = (P - w) * 1e3;
493
- se(
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,
494
510
  C,
495
- N,
496
- J,
497
- O,
498
- E
511
+ x,
512
+ c,
513
+ L,
514
+ u
499
515
  );
500
- } catch (v) {
501
- console.error("[avatarTtsLipsync] audio chunk failed:", v);
516
+ } catch ($) {
517
+ console.error("[avatarChunkPlayback] audio chunk failed:", $);
502
518
  } finally {
503
- _ = !1;
504
- const v = a.shift();
505
- v ? await Se(
506
- v.audio,
507
- v.visemes,
508
- v.words,
509
- v.isNewSegment
510
- ) : K();
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
- }, ee = () => {
513
- if (o = !0, !S && r.length > 0) {
514
- ke();
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
- K();
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: (h) => {
521
- V = h;
613
+ setDeveloperToken: (E) => {
614
+ a = E;
522
615
  },
523
- setTtsEngineId: (h) => {
524
- y = h;
616
+ setTtsEngineId: (E) => {
617
+ f = E;
525
618
  },
526
- getTtsEngineId: () => y,
527
- speak: async (h, C) => {
528
- Z(), x = !1, e("loading");
529
- const N = V.trim();
530
- if (!N)
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 O = C?.ttsEngineId ?? y ?? ce;
533
- E = O;
534
- const v = C?.voiceId ?? _t, L = C?.speakingRate ?? wt, Q = Math.max(
535
- In,
536
- Math.min(Tn, L)
537
- ), $ = {
538
- user_query: h,
539
- ttsEngineId: O,
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
- Lt.has(O) && ($.voice_id = v);
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 ${N}`
641
+ Authorization: `Bearer ${p}`
549
642
  },
550
- body: JSON.stringify($)
643
+ body: JSON.stringify(U)
551
644
  });
552
- if (!P.ok)
553
- throw new Error(`avatar_ttsWithPoses failed (${P.status})`);
554
- const M = P.body;
555
- if (!M) throw new Error("No response body");
556
- const F = M.getReader(), J = new TextDecoder();
557
- let H = "";
558
- const de = async (he) => {
559
- const f = sn(he);
560
- if (f) {
561
- if (f.event === "audio") {
562
- const k = f.data.chunk, I = f.data.visemes ?? [], T = f.data.words ?? [], b = f.data.is_new_segment ?? !1;
563
- if (k)
564
- await Se(k, I, T, b);
565
- else if (I.length > 0 || T.length > 0) {
566
- const j = b && r.length > 0 ? et(r) : u;
567
- se(I, T, j, b, O);
568
- }
569
- } else if (f.event === "metadata") {
570
- const k = f.data.mood;
571
- typeof k == "string" && k.trim() && (c = k.trim());
572
- const I = f.data.sentence_emotions;
573
- if (Array.isArray(I)) {
574
- s.length = 0;
575
- for (const T of I) {
576
- if (!T || typeof T != "object") continue;
577
- const b = T;
578
- s.push({
579
- sentence_index: Number(b.sentence_index ?? 0),
580
- text: String(b.text ?? ""),
581
- sentiment: typeof b.sentiment == "string" ? b.sentiment : void 0,
582
- emotion: String(b.emotion ?? c),
583
- start_word: Number(b.start_word ?? 0),
584
- end_word: Number(b.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
- q();
589
- } else if (f.event === "error")
689
+ m();
690
+ } else if (T.event === "error")
590
691
  throw new Error(
591
- String(f.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: he, value: f } = await F.read();
597
- f && (H += J.decode(f, { stream: !0 }));
598
- const k = H.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
- H = k.pop() ?? "";
602
- for (const I of k) await de(I);
603
- if (he) {
604
- H.trim() && await de(H.trim()), x || ee();
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), Z(), e("error"), P;
709
+ } catch (V) {
710
+ throw console.error("[avatarTtsLipsync]", V), w(), e("error"), V;
610
711
  }
611
712
  },
612
- stop: Z,
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() - D) * A) : 0,
621
- isSpeaking: () => m,
622
- setPlaybackSpeed: (h) => {
623
- A = Math.max(0.1, Math.min(1, h)), W();
1031
+ getStreamMood: () => a,
1032
+ getPlaybackElapsedMs: z,
1033
+ isSpeaking: () => A.isSpeaking(),
1034
+ setPlaybackSpeed: (c) => {
1035
+ A.setPlaybackSpeed(c);
624
1036
  },
625
- getPlaybackSpeed: () => A,
626
- subscribe: (h) => (R.add(h), () => R.delete(h))
1037
+ getPlaybackSpeed: () => A.getPlaybackSpeed(),
1038
+ subscribe: (c) => (u.add(c), () => u.delete(c))
627
1039
  };
628
1040
  }
629
- function Rn(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 Dn(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,53 +1053,64 @@ function Dn(e, t) {
641
1053
  height: t?.source_h ?? n?.height ?? e.frame_height ?? 0
642
1054
  };
643
1055
  }
644
- function xn(e) {
1056
+ function Ar(e) {
645
1057
  return e ? (e.w ?? 0) > 0 && (e.h ?? 0) > 0 : !1;
646
1058
  }
647
- async function Ce(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 Qt(r, t);
1063
+ return Wn(r, t);
652
1064
  }
653
- async function Cn(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 Ce(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 Mn(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 Fn(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
- async function On(e) {
681
- const t = en();
682
- if (!je()) return t;
1092
+ function Mr(e) {
1093
+ const t = new Blob([e], { type: "video/mp4" });
1094
+ return URL.createObjectURL(t);
1095
+ }
1096
+ async function xr(e) {
1097
+ const t = zn();
1098
+ if (!Ke()) return t;
683
1099
  if (!e) throw new Error("Missing asset key for encrypted idle video");
684
- const n = await Ce(t, e);
685
- return URL.createObjectURL(new Blob([n], { type: "video/mp4" }));
1100
+ const n = await Ge(t, e);
1101
+ return Mr(n);
686
1102
  }
687
- function gt(e, t) {
1103
+ function ut(e, t) {
688
1104
  return `${e}/${t}_minus_sil.png`;
689
1105
  }
690
- const Ge = 15, Dr = [
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 = [
691
1114
  "aa",
692
1115
  "E",
693
1116
  "I",
@@ -702,13 +1125,13 @@ const Ge = 15, Dr = [
702
1125
  "RR",
703
1126
  "kk",
704
1127
  "nn"
705
- ], $e = [
1128
+ ], nt = [
706
1129
  "t01_0.17",
707
1130
  "t02_0.33",
708
1131
  "t03_0.50",
709
1132
  "t04_0.67",
710
1133
  "t05_0.83"
711
- ], Pn = $e.length, tt = /* @__PURE__ */ new Set([
1134
+ ], Cr = nt.length, Mt = /* @__PURE__ */ new Set([
712
1135
  "aa__kk",
713
1136
  "aa__nn",
714
1137
  "aa__sil",
@@ -815,59 +1238,101 @@ const Ge = 15, Dr = [
815
1238
  "U__nn",
816
1239
  "U__sil"
817
1240
  ]);
818
- function nt(e, t) {
1241
+ function xt(e, t) {
819
1242
  return `${e}__${t}`;
820
1243
  }
821
- function rt(e, t) {
1244
+ function Ct(e, t) {
822
1245
  return `pairs/${e}/${t}_minus_sil.png`;
823
1246
  }
824
- function Ve(e) {
1247
+ function We(e) {
825
1248
  return `${e}_minus_sil.png`;
826
1249
  }
827
- function Ln(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) {
828
1267
  if (e === t) return [];
829
- const n = [], r = nt(e, t);
830
- if (tt.has(r)) {
831
- for (const s of $e)
832
- n.push(rt(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));
833
1272
  return n;
834
1273
  }
835
- const i = nt(t, e);
836
- if (tt.has(i)) {
837
- for (let s = Pn - 1; s >= 0; s--)
838
- n.push(rt(i, $e[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]));
839
1278
  return n;
840
1279
  }
841
1280
  return [];
842
1281
  }
843
- function Un(e) {
1282
+ function Or(e) {
844
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];
845
1284
  }
846
- function Bn(e, t) {
847
- return Un(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);
848
1287
  }
849
- function Nn(e, t, n, r) {
1288
+ function Fr(e, t, n, r) {
850
1289
  if (r <= 0) return 0;
851
- 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);
852
1291
  return Math.min(r - 1, Math.max(0, a));
853
1292
  }
854
- function $n(e, t, n) {
1293
+ function Ur(e, t, n) {
855
1294
  if (!n) return `${e}/${t}`;
856
- const r = t.split("/").pop() ?? t, i = r.includes(".") ? r.slice(0, r.lastIndexOf(".")) : r;
857
- 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`;
858
1297
  }
859
- const Vn = [0.32, 0.24, 0.16, 0.08, 0], Me = Vn.map(
1298
+ const Nr = [0.32, 0.24, 0.16, 0.08, 0], Vr = Nr.map(
860
1299
  (e) => `eyes_${e.toFixed(2)}`
861
- ), Hn = [
1300
+ ), $r = [
862
1301
  "eyes_0.32",
863
1302
  "eyes_0.16",
864
1303
  "eyes_0.00"
865
- ], Wn = [
1304
+ ], Hr = [
866
1305
  "eyes_0.32",
867
1306
  "eyes_0.16",
868
1307
  "eyes_0.08",
869
1308
  "eyes_0.00"
870
- ], qn = {
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 = {
871
1336
  fear: "fear",
872
1337
  afraid: "fear",
873
1338
  anxiety: "fear",
@@ -890,219 +1355,220 @@ const Vn = [0.32, 0.24, 0.16, 0.08, 0], Me = Vn.map(
890
1355
  disgust: "disgust",
891
1356
  disgusted: "disgust"
892
1357
  };
893
- function ae(e, t = "neutral") {
1358
+ function ve(e, t = "neutral") {
894
1359
  const n = String(e ?? "").trim().toLowerCase();
895
- return n ? qn[n] ?? t : t;
1360
+ return n ? jr[n] ?? t : t;
896
1361
  }
897
- function z(e) {
898
- return e === "neutral" ? null : gt(e, "eyes_standard");
1362
+ function nn(e) {
1363
+ return e === 0 ? null : ut(ft(e), "eyes_standard");
899
1364
  }
900
- function He(e, t) {
901
- return !t || t === "eyes_standard" ? z(e) : e === "neutral" && t === "eyes_standard" ? null : gt(e, t);
1365
+ function rn(e) {
1366
+ return nn(dt(e));
902
1367
  }
903
- function Kn(e) {
904
- if (!e) return "open";
905
- const t = e.match(/\/(eyes_[^/]+)_minus_sil\.png$/);
906
- if (!t?.[1]) return "open";
907
- const n = t[1];
908
- return Me.includes(n) ? n : "open";
909
- }
910
- function jn(e) {
911
- return e === "open" ? -1 : Me.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);
912
1371
  }
913
- function Gn(e, t) {
1372
+ function Gr(e, t) {
914
1373
  const n = [];
915
1374
  for (const r of t)
916
- n.push(He(e, r));
1375
+ n.push(Bt(e, r));
917
1376
  for (let r = t.length - 2; r >= 0; r--)
918
- n.push(He(e, t[r]));
919
- return n.push(z(e)), n;
920
- }
921
- function zn(e, t) {
922
- if (t === "open") return [z(e)];
923
- const n = jn(t);
924
- if (n < 0) return [z(e)];
925
- const r = [];
926
- for (let i = n; i >= 0; i--)
927
- r.push(He(e, Me[i]));
928
- return r.push(z(e)), r;
929
- }
930
- const Qn = [
931
- "t01_0.20",
932
- "t02_0.40",
933
- "t03_0.60",
934
- "t04_0.80"
935
- ];
936
- function Jn(e, t) {
937
- return `${e}__${t}`;
1377
+ n.push(Bt(e, t[r]));
1378
+ return n.push(rn(e)), n;
938
1379
  }
939
- function Yn(e, t, n) {
940
- return `pairs/${Jn(e, t)}/${n}_minus_sil.png`;
1380
+ function zr(e) {
1381
+ return ut(ft(e), "eyes_standard");
941
1382
  }
942
- function Xn(e, t) {
943
- return Qn.map(
944
- (n) => Yn(e, t, n)
945
- );
1383
+ function Yr(e, t) {
1384
+ return Kr(e, t).map(zr);
946
1385
  }
947
- function we(e, t) {
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;
1400
+ }
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) {
948
1409
  return e + Math.random() * (t - e);
949
1410
  }
950
- function Ae() {
951
- return we(14, 32);
1411
+ function Ve() {
1412
+ return Pe(14, 32);
952
1413
  }
953
- function Zn(e = {}) {
1414
+ function es(e = {}) {
954
1415
  const {
955
1416
  initialDelayMs: t = 800 + Math.random() * 1200,
956
1417
  intervalMinMs: n = 2200,
957
1418
  intervalMaxMs: r = 5800,
958
- doubleBlinkChance: i = 0.18,
959
- doubleBlinkGapMinMs: s = 120,
960
- doubleBlinkGapMaxMs: c = 220,
1419
+ doubleBlinkChance: s = 0.18,
1420
+ doubleBlinkGapMinMs: i = 120,
1421
+ doubleBlinkGapMaxMs: o = 220,
961
1422
  fullBlinkChance: a = 0.75,
962
- postEmotionChangeDelayMs: l = 380,
963
- minDwellMs: d = 550
1423
+ postEmotionChangeDelayMs: f = 380,
1424
+ minDwellMs: l = 550
964
1425
  } = e;
965
- let _ = "neutral", m = "neutral", S = 0, o = {
1426
+ let m = "neutral", _ = "neutral", w = 0, k = 0, E = 0, u = {
966
1427
  kind: "idle",
967
1428
  nextBlinkAt: performance.now() + t
968
- }, D = null, w = "__eyes_open__|neutral";
969
- function u(y, E) {
970
- D = y, w = `${y ?? "__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);
971
1437
  }
972
- function g(y, E) {
973
- o = {
1438
+ function A(S) {
1439
+ return nn(S);
1440
+ }
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 = {
974
1461
  kind: "idle",
975
- nextBlinkAt: y + we(n, r)
976
- }, m = E, u(z(E), E);
1462
+ nextBlinkAt: S + Pe(n, r)
1463
+ }, _ = M, y(A(w), M);
977
1464
  }
978
- function p(y, E, x) {
979
- const R = x ? Hn : Math.random() < a ? Me : Wn;
980
- o = {
1465
+ function z(S, M, g) {
1466
+ const v = g ? $r : Math.random() < a ? Vr : Hr;
1467
+ u = {
981
1468
  kind: "playing",
982
- paths: Gn(E, R),
1469
+ paths: Gr(M, v),
983
1470
  index: 0,
984
- holdUntil: y + Ae(),
1471
+ holdUntil: S + Ve(),
985
1472
  after: "idle",
986
- blinkEmotion: E
987
- }, m = E, u(o.paths[0] ?? null, E);
988
- }
989
- function A(y, E, x) {
990
- const R = Kn(D), W = [];
991
- if (R !== "open") {
992
- const q = zn(E, R);
993
- W.push(...q.slice(0, -1));
994
- }
995
- W.push(...Xn(E, x)), W.push(z(x)), o = {
996
- kind: "emotionBlend",
997
- paths: W,
998
- index: 0,
999
- holdUntil: y + Ae(),
1000
- thenEmotion: x
1001
- }, u(W[0] ?? null, E);
1473
+ blinkEmotion: M
1474
+ }, _ = M, y(u.paths[0] ?? null, M);
1002
1475
  }
1003
- function V(y) {
1004
- if (o.kind === "emotionBlend") {
1005
- for (; y >= o.holdUntil && o.index < o.paths.length - 1; )
1006
- o.index += 1, o.holdUntil = y + Ae();
1007
- const E = o.paths[o.index] ?? null;
1008
- u(E, o.thenEmotion), y >= o.holdUntil && o.index >= o.paths.length - 1 && (_ = o.thenEmotion, m = o.thenEmotion, u(z(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 = {
1009
1482
  kind: "idle",
1010
- nextBlinkAt: y + l
1483
+ nextBlinkAt: S + f
1011
1484
  });
1012
1485
  return;
1013
1486
  }
1014
- if (o.kind === "idle") {
1015
- u(z(m), m), y >= o.nextBlinkAt && p(y, m, !1);
1487
+ if (u.kind === "idle") {
1488
+ y(A(w), _), S >= u.nextBlinkAt && z(S, _, !1);
1016
1489
  return;
1017
1490
  }
1018
- if (o.kind === "doublePause") {
1019
- u(z(o.blinkEmotion), o.blinkEmotion), y >= o.resumeAt && p(y, o.blinkEmotion, !0);
1491
+ if (u.kind === "doublePause") {
1492
+ y(A(w), u.blinkEmotion), S >= u.resumeAt && z(S, u.blinkEmotion, !0);
1020
1493
  return;
1021
1494
  }
1022
- if (o.kind === "playing") {
1023
- for (; y >= o.holdUntil && o.index < o.paths.length - 1; )
1024
- o.index += 1, o.holdUntil = y + Ae();
1025
- if (u(o.paths[o.index] ?? null, o.blinkEmotion), y >= o.holdUntil && o.index >= o.paths.length - 1) {
1026
- if (o.after === "resumeIdle") {
1027
- g(y + 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);
1028
1501
  return;
1029
1502
  }
1030
- if (o.after === "doublePause") {
1031
- o = {
1503
+ if (u.after === "doublePause") {
1504
+ u = {
1032
1505
  kind: "doublePause",
1033
- resumeAt: y + we(s, c),
1034
- blinkEmotion: o.blinkEmotion
1035
- }, u(z(o.blinkEmotion), o.blinkEmotion);
1506
+ resumeAt: S + Pe(i, o),
1507
+ blinkEmotion: u.blinkEmotion
1508
+ }, y(A(w), u.blinkEmotion);
1036
1509
  return;
1037
1510
  }
1038
- if (o.after === "idle" && Math.random() < i) {
1039
- o = {
1511
+ if (u.after === "idle" && Math.random() < s) {
1512
+ u = {
1040
1513
  kind: "doublePause",
1041
- resumeAt: y + we(s, c),
1042
- blinkEmotion: o.blinkEmotion
1043
- }, u(z(o.blinkEmotion), o.blinkEmotion);
1514
+ resumeAt: S + Pe(i, o),
1515
+ blinkEmotion: u.blinkEmotion
1516
+ }, y(A(w), u.blinkEmotion);
1044
1517
  return;
1045
1518
  }
1046
- g(y, o.blinkEmotion);
1519
+ V(S, u.blinkEmotion);
1047
1520
  }
1048
1521
  }
1049
1522
  }
1050
1523
  return {
1051
- advance: V,
1052
- setTargetEmotion(y) {
1053
- const E = ae(y, _);
1054
- if (E === _ && o.kind !== "emotionBlend") return;
1055
- const x = performance.now();
1056
- if (d > 0 && E !== _ && o.kind !== "emotionBlend" && !(_ === "neutral" && E !== "neutral") && x - S < d)
1057
- return;
1058
- const R = _;
1059
- if (_ = E, S = x, o.kind === "playing") {
1060
- A(x, m, E);
1061
- return;
1062
- }
1063
- if (o.kind === "emotionBlend") {
1064
- o = {
1065
- ...o,
1066
- thenEmotion: E
1067
- };
1068
- return;
1069
- }
1070
- A(x, R, 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);
1530
+ },
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));
1071
1536
  },
1072
- getTargetEmotion: () => _,
1073
- getExpressionPath: () => D,
1074
- getDrawKey: () => w,
1537
+ getTargetEmotion: () => m,
1538
+ getTargetEyebrow: () => w,
1539
+ getExpressionPath: () => p,
1540
+ getDrawKey: () => d,
1075
1541
  reset() {
1076
- _ = "neutral", m = "neutral", S = 0, g(
1077
- performance.now() + we(n, r),
1542
+ m = "neutral", _ = "neutral", w = 0, k = 0, E = 0, V(
1543
+ performance.now() + Pe(n, r),
1078
1544
  "neutral"
1079
1545
  );
1080
1546
  }
1081
1547
  };
1082
1548
  }
1083
- function er() {
1549
+ function ts() {
1084
1550
  const e = document.createElement("video");
1085
1551
  e.muted = !0, e.playsInline = !0, e.preload = "auto", e.setAttribute("playsinline", ""), e.loop = !0;
1086
1552
  let t = !1, n = null, r = "";
1087
- const i = () => {
1553
+ const s = () => {
1088
1554
  n && (URL.revokeObjectURL(n), n = null);
1089
1555
  };
1090
1556
  return {
1091
- async load(s) {
1092
- t && r === s || (i(), t = !1, r = s, s.startsWith("blob:") && (n = s), await new Promise((c, a) => {
1093
- const l = () => {
1094
- const d = e.duration;
1095
- if (!Number.isFinite(d) || d <= 0) {
1096
- 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}`));
1097
1563
  return;
1098
1564
  }
1099
- t = !0, e.currentTime = 0, c();
1565
+ t = !0, e.currentTime = 0, o();
1100
1566
  };
1101
- e.addEventListener("loadeddata", l, { once: !0 }), e.addEventListener(
1567
+ e.addEventListener("loadeddata", f, { once: !0 }), e.addEventListener(
1102
1568
  "error",
1103
- () => a(new Error(`Failed to load idle video: ${s}`)),
1569
+ () => a(new Error(`Failed to load idle video: ${i}`)),
1104
1570
  { once: !0 }
1105
- ), e.src = s, e.load();
1571
+ ), e.src = i, e.load();
1106
1572
  }));
1107
1573
  },
1108
1574
  isReady() {
@@ -1111,133 +1577,139 @@ function er() {
1111
1577
  getVideo() {
1112
1578
  return e;
1113
1579
  },
1114
- setActive(s) {
1115
- t && (s ? e.paused && e.play().catch(() => {
1580
+ setActive(i) {
1581
+ t && (i ? e.paused && e.play().catch(() => {
1116
1582
  }) : e.paused || e.pause());
1117
1583
  },
1118
1584
  restart() {
1119
1585
  t && (e.currentTime = 0);
1120
1586
  },
1121
1587
  dispose() {
1122
- e.pause(), e.removeAttribute("src"), e.load(), i(), t = !1, r = "";
1588
+ e.pause(), e.removeAttribute("src"), e.load(), s(), t = !1, r = "";
1123
1589
  }
1124
1590
  };
1125
1591
  }
1126
- const tr = 50, yt = 400;
1127
- function nr(e, t, n) {
1592
+ const ns = 50, sn = 400;
1593
+ function rs(e, t, n) {
1128
1594
  return e.filter((r) => {
1129
- const i = r.queueIndex ?? -1;
1130
- return i >= t && i <= n;
1595
+ const s = r.queueIndex ?? -1;
1596
+ return s >= t && s <= n;
1131
1597
  });
1132
1598
  }
1133
- function rr(e, t) {
1599
+ function ss(e, t) {
1134
1600
  const n = [];
1135
1601
  for (const r of e) {
1136
- const i = nr(
1602
+ const s = rs(
1137
1603
  t,
1138
1604
  r.start_word,
1139
1605
  r.end_word
1140
1606
  );
1141
- if (i.length === 0) continue;
1142
- 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];
1143
1609
  n.push({
1144
1610
  sentence: r,
1145
- startMs: Math.max(0, s.wtime - tr),
1146
- endMs: c.wtime + c.wduration + yt
1611
+ startMs: Math.max(0, i.wtime - ns),
1612
+ endMs: o.wtime + o.wduration + sn
1147
1613
  });
1148
1614
  }
1149
- return n.sort((r, i) => r.startMs - i.startMs);
1615
+ return n.sort((r, s) => r.startMs - s.startMs);
1150
1616
  }
1151
- function ir(e, t, n, r = "neutral") {
1152
- const i = ae(r);
1153
- 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;
1154
1620
  if (n.length === 0 || e < n[0].wtime)
1155
- return ae(t[0]?.emotion, i);
1156
- const s = rr(t, n);
1157
- let c = null;
1158
- for (const d of s)
1159
- e >= d.startMs && e <= d.endMs && (c = d);
1160
- if (c)
1161
- return ae(c.sentence.emotion, i);
1162
- const a = n[n.length - 1], l = a.wtime + a.wduration;
1163
- return e > l + yt ? ae(
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(
1164
1630
  t[t.length - 1]?.emotion,
1165
- i
1166
- ) : i;
1167
- }
1168
- function pt(e, t, n, r, i = Ge) {
1169
- const s = new OffscreenCanvas(n, r), c = s.getContext("2d", { willReadFrequently: !0 });
1170
- c.drawImage(e, 0, 0, n, r);
1171
- const a = c.getImageData(0, 0, n, r), l = c.createImageData(n, r);
1172
- l.data.set(a.data);
1173
- const _ = new OffscreenCanvas(n, r).getContext("2d", { willReadFrequently: !0 });
1174
- for (const m of t) {
1175
- _.clearRect(0, 0, n, r), _.drawImage(m, 0, 0, n, r);
1176
- const S = _.getImageData(0, 0, n, r);
1177
- for (let o = 0; o < l.data.length; o += 4) {
1178
- const D = S.data[o], w = S.data[o + 1], u = S.data[o + 2];
1179
- Math.max(D, w, u) > i && (l.data[o] = D, 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);
1180
1646
  }
1181
1647
  }
1182
- return c.putImageData(l, 0, 0), s;
1648
+ return o.putImageData(f, 0, 0), i;
1183
1649
  }
1184
- let re = null, ge = null;
1185
- const De = /* @__PURE__ */ new Map();
1186
- function sr() {
1187
- re = null, ge = null, De.clear();
1650
+ let ye = null, Be = null;
1651
+ const qe = /* @__PURE__ */ new Map();
1652
+ function os() {
1653
+ ye = null, Be = null, qe.clear();
1188
1654
  }
1189
- Zt(sr);
1190
- function or(e) {
1191
- return e ?? ge ?? void 0;
1655
+ Gn(os);
1656
+ function as(e) {
1657
+ return e ?? Be ?? void 0;
1192
1658
  }
1193
- function ze(e) {
1659
+ function ht(e) {
1194
1660
  return new Promise((t, n) => {
1195
1661
  const r = new Image();
1196
1662
  r.decoding = "async", r.onload = () => t(r), r.onerror = () => n(new Error(`Failed to load image: ${e}`)), r.src = e;
1197
1663
  });
1198
1664
  }
1199
- async function it(e, t, n, r) {
1200
- const i = n ? await Cn(e, r) : await fetch(e).then((d) => {
1201
- if (!d.ok) throw new Error(`Failed to load ${e}`);
1202
- return d.json();
1203
- }), s = i.sheets?.[0];
1204
- if (!s?.path) throw new Error(`${e} has no sheets[0].path`);
1205
- const c = n ? await Mn(
1206
- await Ce(
1207
- $n(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),
1208
1679
  r ?? ""
1209
1680
  )
1210
- ) : await ze(`${t}/${s.path}`), a = /* @__PURE__ */ new Map();
1211
- for (const d of i.cells ?? [])
1212
- d.path && a.set(d.path, d);
1213
- const l = /* @__PURE__ */ new Map();
1214
- for (const d of i.sheets ?? [])
1215
- l.set(d.index, d);
1216
- return { atlas: c, atlasMeta: i, cellByPath: a, sheetByIndex: l, diffBase: t };
1217
- }
1218
- async function We(e) {
1219
- const t = or(e), n = je();
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();
1220
1691
  if (n && !t)
1221
1692
  throw new Error("Encrypted assets enabled but no key provided");
1222
- if (re && (!n || ge === (t ?? null))) {
1223
- const s = await re;
1224
- return ye(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
+ };
1225
1699
  }
1226
- ge = t ?? null, De.clear();
1227
- const r = tn();
1228
- re = (async () => {
1229
- const s = n ? await Fn(
1230
- await Ce(Xe(), t ?? "")
1231
- ) : await ze(Xe()), c = await it(
1232
- nn(),
1700
+ Be = t ?? null, qe.clear();
1701
+ const r = Yn();
1702
+ ye = (async () => {
1703
+ const i = await cs(t), o = await Lt(
1704
+ Jn(),
1233
1705
  r,
1234
1706
  n,
1235
1707
  t
1236
1708
  );
1237
1709
  let a = null;
1238
1710
  try {
1239
- a = await it(
1240
- rn(),
1711
+ a = await Lt(
1712
+ Qn(),
1241
1713
  r,
1242
1714
  n,
1243
1715
  t
@@ -1245,200 +1717,224 @@ async function We(e) {
1245
1717
  } catch {
1246
1718
  a = null;
1247
1719
  }
1248
- return { sil: s, viseme: c, expression: a };
1720
+ return { sil: i, viseme: o, expression: a };
1249
1721
  })();
1250
- const i = await re;
1251
- return ye(i);
1722
+ const s = await ye;
1723
+ return { ...Oe(s), visemePaths: [...s.viseme.cellByPath.keys()] };
1252
1724
  }
1253
- async function Et(e) {
1254
- if (await We(e), !re) throw new Error("Assets not loaded");
1255
- return re;
1725
+ async function an(e) {
1726
+ if (await st(e), !ye) throw new Error("Assets not loaded");
1727
+ return ye;
1256
1728
  }
1257
- function ye(e) {
1258
- return Rn(
1729
+ function Oe(e) {
1730
+ return br(
1259
1731
  e.viseme.atlasMeta,
1260
1732
  e.sil.naturalWidth,
1261
1733
  e.sil.naturalHeight
1262
1734
  );
1263
1735
  }
1264
- function ar(e, t) {
1736
+ function us(e, t) {
1265
1737
  const n = document.createElement("canvas");
1266
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;
1267
1739
  }
1268
- async function st(e, t, n) {
1269
- const r = `${t.diffBase}::${n}`, i = De.get(r);
1270
- if (i) return i;
1271
- const s = (async () => {
1272
- const c = t.cellByPath.get(n);
1273
- if (!c) throw new Error(`No atlas cell for path: ${n}`);
1274
- const a = Dn(t.atlasMeta, c), l = ye(e);
1275
- if (xn(c)) {
1276
- const m = ar(t, c), S = document.createElement("canvas");
1277
- S.width = l.width, S.height = l.height;
1278
- const o = S.getContext("2d");
1279
- 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;
1280
1752
  }
1281
- const d = `${t.diffBase}/${n}`, _ = await ze(d);
1282
- if (_.naturalWidth === l.width && _.naturalHeight === l.height)
1283
- return _;
1753
+ const l = `${t.diffBase}/${n}`, m = await ht(l);
1754
+ if (m.naturalWidth === f.width && m.naturalHeight === f.height)
1755
+ return m;
1284
1756
  throw new Error(`Diff PNG wrong size for ${n}`);
1285
1757
  })();
1286
- return De.set(r, s), s;
1758
+ return qe.set(r, i), i;
1287
1759
  }
1288
- async function ot(e, t, n, r = Ge, i, s) {
1289
- if (i) {
1290
- const { width: S, height: o } = i;
1291
- 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)
1292
1764
  return;
1293
- const D = document.createElement("canvas");
1294
- D.width = S, D.height = o;
1295
- const w = D.getContext("2d");
1296
- if (w.clearRect(0, 0, S, o), w.drawImage(t, 0, 0, S, o), s && !s()) return;
1297
- (e.width !== S || e.height !== o) && (e.width = S, e.height = o);
1298
- const u = e.getContext("2d");
1299
- u.clearRect(0, 0, S, o), u.drawImage(D, 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);
1300
1772
  return;
1301
1773
  }
1302
- const c = await Et(), { width: a, height: l } = ye(c);
1303
- (e.width !== a || e.height !== l) && (e.width = a, e.height = l);
1304
- const d = [], _ = e.getContext("2d");
1305
- if (_.clearRect(0, 0, a, l), t.readyState < HTMLMediaElement.HAVE_CURRENT_DATA) {
1306
- const S = c.sil;
1307
- _.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);
1308
1780
  return;
1309
1781
  }
1310
- if (d.length === 0) {
1311
- _.drawImage(t, 0, 0, a, l);
1782
+ if (m.length === 0) {
1783
+ _.drawImage(t, 0, 0, f, l);
1312
1784
  return;
1313
1785
  }
1314
- const m = pt(t, d, a, l, r);
1315
- _.drawImage(m, 0, 0);
1316
- }
1317
- async function qe(e, t, n = Ge) {
1318
- const r = await Et(ge ?? void 0), { width: i, height: s } = ye(r);
1319
- (e.width !== i || e.height !== s) && (e.width = i, e.height = s);
1320
- const c = [];
1321
- t.mouthPath && c.push(await st(r, r.viseme, t.mouthPath)), t.expressionPath && r.expression && c.push(
1322
- await st(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)
1323
1799
  );
1324
- const a = e.getContext("2d");
1325
- if (a.clearRect(0, 0, i, s), c.length === 0) {
1326
- 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);
1327
1803
  return;
1328
1804
  }
1329
- const l = pt(
1805
+ const l = on(
1330
1806
  r.sil,
1331
- c,
1807
+ a,
1332
1808
  i,
1333
- s,
1334
- n
1809
+ o,
1810
+ s
1335
1811
  );
1336
- a.drawImage(l, 0, 0);
1812
+ f.drawImage(l, 0, 0);
1337
1813
  }
1338
- async function cr(e) {
1339
- await qe(e, { mouthPath: null, expressionPath: null });
1814
+ async function ls(e) {
1815
+ await it(e, { mouthPath: null, expressionPath: null });
1340
1816
  }
1341
- function ur(e) {
1817
+ function fs(e) {
1342
1818
  const t = /* @__PURE__ */ new Map();
1343
1819
  for (const n of e)
1344
1820
  t.has(n.vtime) || t.set(n.vtime, n);
1345
1821
  return [...t.values()].sort((n, r) => n.vtime - r.vtime);
1346
1822
  }
1347
- function lr(e) {
1348
- const t = ur(e), n = [];
1823
+ function ds(e) {
1824
+ const t = fs(e), n = [];
1349
1825
  for (let r = 0; r < t.length - 1; r++) {
1350
- const i = t[r].viseme, s = t[r + 1].viseme, c = t[r].vtime, a = t[r + 1].vtime;
1351
- 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 });
1352
1828
  }
1353
1829
  return n;
1354
1830
  }
1355
- function fr(e, t) {
1831
+ function hs(e, t) {
1356
1832
  let n = null;
1357
1833
  for (const r of e)
1358
1834
  t >= r.fromVtime && t < r.toVtime && (n = r);
1359
1835
  return n;
1360
1836
  }
1361
- function dr(e, t) {
1837
+ function ms(e, t) {
1362
1838
  return { gapMs: Math.max(0, t - e), holdEnd: e, transStart: e };
1363
1839
  }
1364
- const hr = 500, mr = "__sil__";
1365
- function _r() {
1840
+ const cn = 400, ws = 200, gs = 600, _s = "__sil__";
1841
+ function ps() {
1366
1842
  return { lastDrawnKey: "" };
1367
1843
  }
1368
- function _e(e) {
1369
- e.lastDrawnKey = "";
1844
+ function me(e) {
1845
+ e.lastDrawnKey = "", e.transitionCache = void 0;
1370
1846
  }
1371
- function at(e) {
1372
- return e ?? mr;
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;
1373
1852
  }
1374
- function wr(e, t) {
1853
+ function ks(e) {
1854
+ let t = "sil";
1855
+ for (const n of e)
1856
+ n.viseme !== "sil" && (t = n.viseme);
1857
+ return t;
1858
+ }
1859
+ function Es(e, t) {
1860
+ return e === "sil" ? !1 : t ? Br(e, "sil", t) : lt(e, "sil").length > 0;
1861
+ }
1862
+ function Ss() {
1863
+ return cn + gs;
1864
+ }
1865
+ function Nt(e) {
1866
+ return e ?? _s;
1867
+ }
1868
+ function vs(e, t, n, r) {
1375
1869
  if (e.length === 0)
1376
1870
  return { diffPath: null, label: "sil" };
1377
- const n = lr(e), r = fr(n, t);
1378
- if (r) {
1379
- const s = r.toVtime - r.fromVtime, c = dr(r.fromVtime, r.toVtime);
1380
- if (t >= c.transStart && t < r.toVtime) {
1381
- const a = Ln(r.from, r.to), l = Bn(a, s);
1382
- if (l.length > 0) {
1383
- const d = Nn(
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(
1384
1880
  t,
1385
- c.transStart,
1386
- r.toVtime,
1387
- l.length
1881
+ f.transStart,
1882
+ i.toVtime,
1883
+ m.length
1388
1884
  );
1389
- 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}` };
1390
1886
  }
1391
- return { diffPath: Ve(r.to), label: r.to };
1887
+ return { diffPath: We(i.to), label: i.to };
1392
1888
  }
1393
1889
  }
1394
- const i = Sn(e, t);
1395
- return i === "sil" ? { diffPath: null, label: "sil" } : { diffPath: Ve(i), label: i };
1890
+ const o = at(e, t);
1891
+ return o === "sil" ? { diffPath: null, label: "sil" } : { diffPath: We(o), label: o };
1396
1892
  }
1397
- function kt(e, t) {
1398
- const n = t ?? at(e.expressionPath);
1399
- return `${at(e.mouthPath)}|${n}`;
1893
+ function un(e, t) {
1894
+ const n = t ?? Nt(e.expressionPath);
1895
+ return `${Nt(e.mouthPath)}|${n}`;
1400
1896
  }
1401
- function gr(e, t, n, r, i, s, c, a) {
1402
- const l = wr(t, n), d = {
1403
- 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,
1404
1900
  expressionPath: r
1405
- }, _ = kt(d, i);
1406
- _ !== s.lastDrawnKey && (a(l.label), c(e, d, _, (m) => {
1407
- m === _ && (s.lastDrawnKey = _);
1901
+ }, w = un(_, s);
1902
+ w !== i.lastDrawnKey && (a(m.label), o(e, _, w, (k) => {
1903
+ k === w && (i.lastDrawnKey = w);
1408
1904
  }));
1409
1905
  }
1410
- function ct(e, t, n, r, i, s, c = null) {
1411
- const a = { mouthPath: null, expressionPath: t }, l = c != null ? `|idle@${Math.round(c * 1e3)}` : "", d = kt(a, n) + l;
1412
- !(c != null) && d === r.lastDrawnKey || (s(
1413
- c != null ? "idle" : "sil"
1414
- ), i(e, a, d, (m) => {
1415
- 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);
1416
1912
  }));
1417
1913
  }
1418
- function St(e) {
1419
- let t = 0, n = null, r = !1, i = !1;
1420
- const s = async () => {
1914
+ function ln(e) {
1915
+ let t = 0, n = null, r = !1, s = !1;
1916
+ const i = async () => {
1421
1917
  if (!r) {
1422
1918
  r = !0;
1423
1919
  try {
1424
1920
  for (; n; ) {
1425
1921
  const a = n;
1426
1922
  n = null;
1427
- const l = ++t, d = await e(a.diffs, l, a);
1428
- 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);
1429
1925
  }
1430
1926
  } finally {
1431
- r = !1, n && s();
1927
+ r = !1, n && i();
1432
1928
  }
1433
1929
  }
1434
- }, c = () => {
1435
- i || (i = !0, queueMicrotask(() => {
1436
- i = !1, s();
1930
+ }, o = () => {
1931
+ s || (s = !0, queueMicrotask(() => {
1932
+ s = !1, i();
1437
1933
  }));
1438
1934
  };
1439
1935
  return {
1440
- enqueue(a, l, d) {
1441
- n = { diffs: a, drawKey: l, onDisplayed: d }, c();
1936
+ enqueue(a, f, l) {
1937
+ n = { diffs: a, drawKey: f, onDisplayed: l }, o();
1442
1938
  },
1443
1939
  reset() {
1444
1940
  t += 1, n = null;
@@ -1451,9 +1947,9 @@ function St(e) {
1451
1947
  }
1452
1948
  };
1453
1949
  }
1454
- const ut = -1, lt = /* @__PURE__ */ new Map();
1455
- async function yr(e) {
1456
- let t = lt.get(e);
1950
+ const $t = -1, Ht = /* @__PURE__ */ new Map();
1951
+ async function Ts(e) {
1952
+ let t = Ht.get(e);
1457
1953
  if (!t) {
1458
1954
  const n = await fetch(e);
1459
1955
  if (!n.ok)
@@ -1461,181 +1957,188 @@ async function yr(e) {
1461
1957
  `Failed to fetch worker script (${n.status}): ${e}`
1462
1958
  );
1463
1959
  const r = await n.blob();
1464
- t = URL.createObjectURL(r), lt.set(e, t);
1960
+ t = URL.createObjectURL(r), Ht.set(e, t);
1465
1961
  }
1466
1962
  return new Worker(t, { name: "visemeDiffPreview" });
1467
1963
  }
1468
- function pr() {
1964
+ function As() {
1469
1965
  return typeof Worker < "u" && typeof OffscreenCanvas < "u";
1470
1966
  }
1471
- function Er(e, t) {
1967
+ function Is(e, t) {
1472
1968
  (e.width !== t.width || e.height !== t.height) && (e.width = t.width, e.height = t.height);
1473
1969
  const n = e.getContext("2d");
1474
1970
  n && n.drawImage(t, 0, 0);
1475
1971
  }
1476
- function ft(e, t) {
1477
- let n = 0;
1478
- const r = St(async (i, s) => (await We(), await qe(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)));
1479
1975
  return {
1480
1976
  usesWorker: !1,
1481
1977
  async loadAssets(i) {
1482
- return await We(i);
1978
+ const o = await st(i);
1979
+ return r = o.visemePaths ? new Set(o.visemePaths) : null, o;
1980
+ },
1981
+ getVisemeAtlasPaths() {
1982
+ return r;
1483
1983
  },
1484
1984
  async renderSilOnly() {
1485
- n += 1, r.reset(), await cr(e);
1985
+ n += 1, s.reset(), await ls(e);
1486
1986
  },
1487
- drawLiveFrame(i, s, c, a) {
1488
- r.enqueue(s, c, a);
1987
+ drawLiveFrame(i, o, a, f) {
1988
+ s.enqueue(o, a, f);
1489
1989
  },
1490
- async renderViseme(i, s) {
1990
+ async renderViseme(i, o) {
1491
1991
  n += 1;
1492
- const c = n;
1493
- t.onStatus?.(s), await qe(i, {
1494
- mouthPath: Ve(s),
1992
+ const a = n;
1993
+ t.onStatus?.(o), await it(i, {
1994
+ mouthPath: We(o),
1495
1995
  expressionPath: null
1496
1996
  });
1497
1997
  },
1498
1998
  dispose() {
1499
- n += 1, r.reset();
1999
+ n += 1, s.reset();
1500
2000
  }
1501
2001
  };
1502
2002
  }
1503
- function kr(e, t, n) {
1504
- let r = null, i = 1, s = 0, c = !1, a = !1;
1505
- const l = /* @__PURE__ */ new Map(), d = St(async (w, u, g) => (l.set(u, {
1506
- drawKey: g.drawKey,
1507
- onDisplayed: g.onDisplayed
1508
- }), 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(
1509
2009
  {
1510
2010
  type: "drawFrame",
1511
- diffPath: w.mouthPath,
1512
- expressionDiffPath: w.expressionPath,
1513
- liveSeq: u
2011
+ diffPath: p.mouthPath,
2012
+ expressionDiffPath: p.expressionPath,
2013
+ liveSeq: d
1514
2014
  },
1515
2015
  void 0,
1516
2016
  !0
1517
- ), !1)), _ = (w) => {
1518
- if (w === ut) {
1519
- let p = -1, A;
1520
- for (const [V, y] of l)
1521
- V >= p && (p = V, A = y);
1522
- p >= 0 && l.delete(p), A?.onDisplayed?.(A.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);
1523
2023
  return;
1524
2024
  }
1525
- const u = -w, g = l.get(u);
1526
- l.delete(u), g?.onDisplayed?.(g.drawKey);
1527
- }, m = /* @__PURE__ */ new Map(), S = (w, u) => {
1528
- a || !r || r.postMessage(w, []);
1529
- }, 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) => {
1530
2030
  if (a) return Promise.resolve();
1531
- const p = i++;
1532
- return new Promise((A, V) => {
1533
- m.set(p, {
1534
- resolve: (y) => A(y),
1535
- reject: V,
1536
- generation: typeof w.generation == "number" ? w.generation : void 0,
1537
- expectRenderDone: g
1538
- }), S({ ...w, requestId: p });
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 });
1539
2039
  });
1540
- }, D = (async () => {
1541
- r = await yr(n), r.onmessage = (w) => {
2040
+ }, u = (async () => {
2041
+ r = await Ts(n), r.onmessage = (p) => {
1542
2042
  if (a) return;
1543
- const u = w.data;
1544
- if (u.type === "status") {
1545
- t.onStatus?.(u.label);
2043
+ const d = p.data;
2044
+ if (d.type === "status") {
2045
+ t.onStatus?.(d.label);
1546
2046
  return;
1547
2047
  }
1548
- if (u.type === "frame") {
1549
- const p = u.generation < 0;
1550
- if (!p && u.generation !== s) {
1551
- u.bitmap.close();
2048
+ if (d.type === "frame") {
2049
+ const y = d.generation < 0;
2050
+ if (!y && d.generation !== i) {
2051
+ d.bitmap.close();
1552
2052
  return;
1553
2053
  }
1554
- if (p && !(u.generation === ut)) {
1555
- const V = -u.generation;
1556
- if (!d.isLatestSeq(V)) {
1557
- u.bitmap.close();
2054
+ if (y && !(d.generation === $t)) {
2055
+ const U = -d.generation;
2056
+ if (!m.isLatestSeq(U)) {
2057
+ d.bitmap.close();
1558
2058
  return;
1559
2059
  }
1560
2060
  }
1561
- if (p && t.shouldAcceptLiveFrame && !t.shouldAcceptLiveFrame()) {
1562
- u.bitmap.close();
2061
+ if (y && t.shouldAcceptLiveFrame && !t.shouldAcceptLiveFrame()) {
2062
+ d.bitmap.close();
1563
2063
  return;
1564
2064
  }
1565
- Er(e, u.bitmap), u.bitmap.close(), p && _(u.generation);
2065
+ Is(e, d.bitmap), d.bitmap.close(), y && _(d.generation);
1566
2066
  return;
1567
2067
  }
1568
- const g = m.get(u.requestId);
1569
- if (g)
1570
- switch (u.type) {
2068
+ const D = w.get(d.requestId);
2069
+ if (D)
2070
+ switch (d.type) {
1571
2071
  case "ready":
1572
- m.delete(u.requestId), g.resolve();
2072
+ w.delete(d.requestId), D.resolve();
1573
2073
  break;
1574
2074
  case "loadAssetsDone":
1575
- 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 });
1576
2076
  break;
1577
2077
  case "renderDone":
1578
- if (g.expectRenderDone && g.generation != null && u.generation !== g.generation)
2078
+ if (D.expectRenderDone && D.generation != null && d.generation !== D.generation)
1579
2079
  return;
1580
- m.delete(u.requestId), g.resolve();
2080
+ w.delete(d.requestId), D.resolve();
1581
2081
  break;
1582
2082
  case "renderAborted":
1583
- m.delete(u.requestId), g.resolve();
2083
+ w.delete(d.requestId), D.resolve();
1584
2084
  break;
1585
2085
  case "error":
1586
- 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));
1587
2087
  break;
1588
2088
  }
1589
- }, r.onerror = (w) => {
2089
+ }, r.onerror = (p) => {
1590
2090
  if (a) return;
1591
- const u = w.message || "Worker error";
1592
- t.onError?.(u);
1593
- for (const [, g] of m)
1594
- g.reject(new Error(u));
1595
- m.clear();
1596
- }, 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;
1597
2097
  })();
1598
2098
  return {
1599
2099
  usesWorker: !0,
1600
- async loadAssets(w) {
2100
+ async loadAssets(p) {
1601
2101
  if (a) return { width: 842, height: 1264 };
1602
- if (await D, a) return { width: 842, height: 1264 };
1603
- if (!c) throw new Error("Worker init failed");
1604
- 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({
1605
2105
  type: "loadAssets",
1606
- keyHex: w,
1607
- urls: Xt(ie())
2106
+ keyHex: p,
2107
+ urls: jn(Ee())
1608
2108
  }) ?? { width: 842, height: 1264 };
1609
2109
  },
2110
+ getVisemeAtlasPaths() {
2111
+ return f;
2112
+ },
1610
2113
  async renderSilOnly() {
1611
- if (a || (await D, a)) return;
1612
- s += 1, d.reset(), l.clear();
1613
- const w = s;
1614
- await o(
1615
- { 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 },
1616
2119
  void 0,
1617
2120
  !0
1618
2121
  );
1619
2122
  },
1620
- drawLiveFrame(w, u, g, p) {
1621
- a || D.then(() => {
1622
- a || d.enqueue(u, g, p);
2123
+ drawLiveFrame(p, d, D, y) {
2124
+ a || u.then(() => {
2125
+ a || m.enqueue(d, D, y);
1623
2126
  });
1624
2127
  },
1625
- async renderViseme(w, u, g = {}) {
1626
- if (a || (await D, a)) return;
1627
- s += 1;
1628
- const p = 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;
1629
2132
  try {
1630
- await o(
2133
+ await E({ type: "cancelLiveDraws" }), await E(
1631
2134
  {
1632
2135
  type: "renderViseme",
1633
- generation: p,
1634
- to: u,
1635
- from: g.from,
1636
- transitionDurationMs: g.transitionDurationMs,
1637
- gapMs: g.gapMs,
1638
- threshold: g.threshold
2136
+ generation: y,
2137
+ to: d,
2138
+ from: D.from,
2139
+ transitionDurationMs: D.transitionDurationMs,
2140
+ gapMs: D.gapMs,
2141
+ threshold: D.threshold
1639
2142
  },
1640
2143
  void 0,
1641
2144
  !0
@@ -1647,53 +2150,53 @@ function kr(e, t, n) {
1647
2150
  },
1648
2151
  dispose() {
1649
2152
  if (!a) {
1650
- a = !0, s += 1, d.reset(), l.clear();
1651
- for (const [, w] of m)
1652
- w.resolve();
1653
- 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;
1654
2157
  }
1655
2158
  }
1656
2159
  };
1657
2160
  }
1658
- function Sr(e, t = {}) {
1659
- if (!pr())
1660
- return ft(e, t);
1661
- const n = Ot(t.workerScriptUrl);
2161
+ function Ds(e, t = {}) {
2162
+ if (!As())
2163
+ return Wt(e, t);
2164
+ const n = Rn(t.workerScriptUrl);
1662
2165
  try {
1663
- return kr(e, t, n);
2166
+ return Rs(e, t, n);
1664
2167
  } catch {
1665
- return ft(e, t);
2168
+ return Wt(e, t);
1666
2169
  }
1667
2170
  }
1668
- class vr extends Error {
2171
+ class Ms extends Error {
1669
2172
  constructor(t, n) {
1670
2173
  super(`${t} timed out after ${Math.round(n / 1e3)}s`), this.name = "LoadTimeoutError";
1671
2174
  }
1672
2175
  }
1673
- function Le(e, t, n) {
1674
- return new Promise((r, i) => {
1675
- const s = globalThis.setTimeout(() => {
1676
- i(new vr(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));
1677
2180
  }, t);
1678
2181
  e.then(
1679
- (c) => {
1680
- globalThis.clearTimeout(s), r(c);
2182
+ (o) => {
2183
+ globalThis.clearTimeout(i), r(o);
1681
2184
  },
1682
- (c) => {
1683
- globalThis.clearTimeout(s), i(c);
2185
+ (o) => {
2186
+ globalThis.clearTimeout(i), s(o);
1684
2187
  }
1685
2188
  );
1686
2189
  });
1687
2190
  }
1688
- const Ir = {
2191
+ const xs = {
1689
2192
  position: "relative",
1690
2193
  display: "inline-block",
1691
2194
  lineHeight: 0
1692
- }, Tr = {
2195
+ }, Cs = {
1693
2196
  display: "block",
1694
2197
  maxWidth: "100%",
1695
2198
  height: "auto"
1696
- }, Ar = {
2199
+ }, Ps = {
1697
2200
  position: "absolute",
1698
2201
  inset: 0,
1699
2202
  display: "flex",
@@ -1705,305 +2208,483 @@ const Ir = {
1705
2208
  fontSize: "0.875rem",
1706
2209
  textAlign: "center"
1707
2210
  };
1708
- function be(e) {
1709
- return Bt(e) ? An : _t;
2211
+ function $e(e) {
2212
+ return Cn(e) ? gr : Jt;
1710
2213
  }
1711
- const xr = Tt(function({
2214
+ function we(e, t) {
2215
+ return t?.isSpeaking() ? t : e.isSpeaking() ? e : t?.isConnected() ? t : e;
2216
+ }
2217
+ const Vs = gn(function({
1712
2218
  id: t,
1713
2219
  assets: n,
1714
2220
  authToken: r,
1715
- ttsEngineId: i = ce,
1716
- voiceId: s,
1717
- speakingRate: c = wt,
2221
+ ttsEngineId: s = Te,
2222
+ voiceId: i,
2223
+ speakingRate: o = ct,
1718
2224
  className: a,
1719
- style: l,
1720
- canvasStyle: d,
1721
- onStatusChange: _,
1722
- onDisplayStatus: m,
1723
- onError: S,
1724
- onReady: o,
1725
- showErrorOverlay: D = !0
1726
- }, w) {
1727
- const u = B(null), g = B(null), p = B(_r()), A = B(Zn()), V = B(0), y = B(0), E = B(null), x = B(!1), R = B(
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(
1728
2237
  null
1729
- ), W = B(!1), [q, ue] = me("idle"), [Ee, Z] = me(null), [K, ke] = me(!1), [Fe, le] = me(!1), [se, Se] = me({ width: 842, height: 1264 }), ee = B(r ?? null), fe = B(null), h = B(null), C = B(!1), N = B({ width: 842, height: 1264 }), O = B(o), v = B(m), L = B(S);
1730
- O.current = o, v.current = m, L.current = S;
1731
- const Q = ne(
1732
- (f) => {
1733
- const k = f?.ttsEngineId ?? i ?? h.current?.ttsEngineId ?? ce, I = f?.voiceId ?? s ?? h.current?.voiceId ?? be(k);
1734
- return { ttsEngineId: k, voiceId: I };
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 };
1735
2244
  },
1736
- [i, s]
1737
- ), $ = ne((f) => {
1738
- Z(f), L.current?.(f);
1739
- }, []), P = ne(
1740
- (f) => {
1741
- ue(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);
1742
2251
  },
1743
- [_]
1744
- ), M = B(
1745
- bn(P, Re)
1746
- ), F = ne(() => {
1747
- E.current != null && (clearTimeout(E.current), E.current = null);
1748
- }, []), J = ne(async () => {
1749
- const f = y.current, k = g.current;
1750
- !k || !K || M.current.isSpeaking() || (_e(p.current), await k.renderSilOnly(), f === y.current && (M.current.isSpeaking() || (v.current?.("sil"), W.current && R.current && (R.current.restart(), R.current.setActive(!0)))));
1751
- }, [K]), H = ne(() => {
1752
- F();
1753
- const f = y.current;
1754
- J(), E.current = setTimeout(() => {
1755
- E.current = null, f === y.current && J();
1756
- }, hr);
1757
- }, [F, J]), de = ne(async () => {
1758
- const f = Math.floor(Date.now() / 1e3);
1759
- if (fe.current && f < fe.current.expiresAt - 60)
1760
- return fe.current.key;
1761
- const k = ee.current ?? await Ye();
1762
- ee.current = k, M.current.setDeveloperToken(k);
1763
- const I = await jt(k, Re);
1764
- return fe.current = {
1765
- key: I.value,
1766
- expiresAt: I.expiresAt
1767
- }, I.value;
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;
2283
+ return;
2284
+ }
2285
+ if (v.current) {
2286
+ C.current = !1;
2287
+ return;
2288
+ }
2289
+ const h = I.current;
2290
+ if (!h) {
2291
+ C.current = !1;
2292
+ return;
2293
+ }
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();
2301
+ };
2302
+ if (R.addEventListener("playing", N, { once: !0 }), R.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA && !R.paused) {
2303
+ F();
2304
+ return;
2305
+ }
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;
2311
+ return;
2312
+ }
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);
2318
+ };
2319
+ if (!P || !F || !X) {
2320
+ N();
2321
+ return;
2322
+ }
2323
+ if (we(
2324
+ W.current,
2325
+ q.current
2326
+ ).isSpeaking()) {
2327
+ N();
2328
+ return;
2329
+ }
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();
2337
+ return;
2338
+ }
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();
2355
+ return;
2356
+ }
2357
+ try {
2358
+ await P.renderViseme(F, "sil", {
2359
+ from: te,
2360
+ transitionDurationMs: cn
2361
+ });
2362
+ } catch (de) {
2363
+ if (de?.name !== "AbortError")
2364
+ throw de;
2365
+ }
2366
+ if (R !== K.current) {
2367
+ N();
2368
+ return;
2369
+ }
2370
+ if (we(
2371
+ W.current,
2372
+ q.current
2373
+ ).isSpeaking()) {
2374
+ N();
2375
+ return;
2376
+ }
2377
+ Le();
2378
+ },
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;
1768
2400
  }, []);
1769
- oe(() => {
1770
- r && (ee.current = r, M.current.setDeveloperToken(r));
1771
- }, [r]), oe(() => {
1772
- M.current.setTtsEngineId(i), h.current && (h.current.ttsEngineId = i);
1773
- }, [i]), oe(() => {
1774
- const f = s ?? be(i);
1775
- h.current && (h.current.voiceId = f);
1776
- }, [s, i]);
1777
- const he = At(
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(
1778
2410
  () => n ? JSON.stringify(n) : `id:${t ?? ""}`,
1779
2411
  [n, t]
1780
2412
  );
1781
- return oe(() => {
2413
+ return Se(() => {
1782
2414
  if (!t && !n) {
1783
- $("AiTwin requires either `id` or `assets`");
2415
+ fe("AiTwin requires either `id` or `assets`");
1784
2416
  return;
1785
2417
  }
1786
- let f = !1;
1787
- C.current = !1, ke(!1), le(!1), Z(null), h.current = null, R.current = null, W.current = !1;
1788
- const k = u.current;
1789
- if (!k) return;
1790
- let I = 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;
1791
2423
  return (async () => {
1792
2424
  try {
1793
- let T, b, j;
2425
+ let F, N, te;
1794
2426
  if (n)
1795
- T = n, b = i, j = s ?? be(b);
2427
+ F = n, N = s, te = i ?? $e(N);
1796
2428
  else {
1797
- v.current?.("getAiTwin");
1798
- const U = await Le(
1799
- $t(t),
2429
+ ee.current?.("getAiTwin");
2430
+ const J = await Xe(
2431
+ Bn(t),
1800
2432
  3e4,
1801
2433
  "getAiTwin"
1802
2434
  );
1803
- if (f) return;
1804
- if (!U.faceId?.trim())
2435
+ if (h) return;
2436
+ if (!J.faceId?.trim())
1805
2437
  throw new Error("getAiTwin returned no faceId");
1806
- b = U.ttsEngineId, j = s ?? U.voiceId ?? be(b), T = Jt(U.faceId);
2438
+ N = J.ttsEngineId, te = i ?? J.voiceId ?? $e(N), F = qn(J.faceId);
1807
2439
  }
1808
- h.current = { ttsEngineId: b, voiceId: j }, Yt(T), R.current = er(), I = Sr(k, {
1809
- onStatus: (U) => {
1810
- f || v.current?.(U);
2440
+ H.current = { ttsEngineId: N, voiceId: te }, Kn(F), I.current = ts(), P = Ds(R, {
2441
+ onStatus: (J) => {
2442
+ h || ee.current?.(J);
1811
2443
  },
1812
- onError: (U) => {
1813
- f || $(U);
2444
+ onError: (J) => {
2445
+ h || fe(J);
1814
2446
  },
1815
- shouldAcceptLiveFrame: () => M.current.isSpeaking()
1816
- }), g.current = I, v.current?.("auth");
1817
- const Y = ee.current ?? r ?? await Le(Ye(), 3e4, "getAuthToken");
1818
- if (f) return;
1819
- ee.current = Y, M.current.setDeveloperToken(Y), M.current.setTtsEngineId(b);
1820
- const ve = je() ? await de() : void 0;
1821
- if (f) return;
1822
- v.current?.("loadAssets");
1823
- const G = await Le(
1824
- I.loadAssets(ve),
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),
1825
2460
  18e4,
1826
2461
  "load face assets"
1827
2462
  );
1828
- if (!f && G.width > 0 && G.height > 0 && (N.current = G, Se(G)), f) return;
1829
- C.current = !0, ke(!0), O.current?.(), I.renderSilOnly().then(() => {
1830
- f || v.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");
1831
2466
  }), (async () => {
1832
2467
  try {
1833
- const U = await On(ve);
1834
- if (await R.current.load(U), f) return;
1835
- W.current = !0, le(!0), _e(p.current), R.current.setActive(!0);
1836
- const X = R.current.getVideo();
1837
- await ot(
1838
- k,
1839
- X,
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,
1840
2475
  null,
1841
2476
  void 0,
1842
- N.current
1843
- ), f || v.current?.("idle");
1844
- } catch (U) {
1845
- if (f) return;
1846
- W.current = !1, le(!1), console.warn("[AiTwin] Idle video unavailable:", U);
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);
1847
2482
  }
1848
2483
  })();
1849
- } catch (T) {
1850
- if (f) return;
1851
- if (T instanceof Ue) {
1852
- $(T.message);
2484
+ } catch (F) {
2485
+ if (h) return;
2486
+ if (F instanceof Ze) {
2487
+ fe(F.message);
1853
2488
  return;
1854
2489
  }
1855
- $(T instanceof Error ? T.message : "Failed to load AI twin");
2490
+ fe(F instanceof Error ? F.message : "Failed to load AI twin");
1856
2491
  }
1857
2492
  })(), () => {
1858
- f = !0, R.current?.dispose(), I?.dispose(), g.current = null;
2493
+ h = !0, I.current?.dispose(), P?.dispose(), A.current = null;
1859
2494
  };
1860
- }, [he, n, i, s, r, de, $]), oe(() => {
1861
- q === "done" && K && !M.current.isSpeaking() && H();
1862
- }, [q, K, H]), oe(() => {
1863
- const f = M.current, k = { current: !1 }, I = () => {
1864
- const T = u.current, b = g.current;
1865
- if (!T || !b || !K) {
1866
- V.current = requestAnimationFrame(I);
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);
1867
2503
  return;
1868
2504
  }
1869
- const j = f.isSpeaking(), Y = f.getPlaybackElapsedMs(), ve = j ? ir(
1870
- Y,
1871
- f.getSentenceEmotions(),
1872
- f.getWordQueue(),
1873
- f.getStreamMood()
1874
- ) : f.getStreamMood();
1875
- if (j) {
1876
- if (W.current && R.current?.setActive(!1), f.getVisemeQueue().length === 0) {
1877
- V.current = requestAnimationFrame(I);
1878
- return;
1879
- }
1880
- A.current.setTargetEmotion(ve), A.current.advance(performance.now());
1881
- const U = A.current.getExpressionPath(), X = A.current.getDrawKey();
1882
- gr(
1883
- T,
1884
- f.getVisemeQueue(),
1885
- Y,
1886
- U,
1887
- X,
1888
- p.current,
1889
- (te, Oe, Pe, vt) => b.drawLiveFrame(te, Oe, Pe, vt),
1890
- (te) => v.current?.(te)
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()
1891
2517
  );
1892
- } else if (W.current && R.current) {
1893
- const G = R.current, U = G.getVideo();
1894
- U.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA ? (G.setActive(!0), k.current || (k.current = !0, ot(
1895
- T,
1896
- U,
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
2536
+ );
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,
1897
2542
  null,
1898
2543
  void 0,
1899
- N.current,
1900
- () => !f.isSpeaking()
1901
- ).then(() => v.current?.("idle")).finally(() => {
1902
- k.current = !1;
1903
- }))) : ct(
1904
- T,
1905
- null,
1906
- "__sil__",
1907
- p.current,
1908
- (X, te, Oe, Pe) => b.drawLiveFrame(X, te, Oe, Pe),
1909
- (X) => v.current?.(X)
1910
- );
1911
- } else
1912
- ct(
1913
- T,
2544
+ le.current,
2545
+ () => !N.isSpeaking() && !v.current && !C.current
2546
+ ).then(() => ee.current?.("idle")).finally(() => {
2547
+ h.current = !1;
2548
+ }))) : Vt(
2549
+ P,
1914
2550
  null,
1915
2551
  "__sil__",
1916
- p.current,
1917
- (G, U, X, te) => b.drawLiveFrame(G, U, X, te),
1918
- (G) => v.current?.(G)
2552
+ U.current,
2553
+ (he, Me, Je, xe) => F.drawLiveFrame(he, Me, Je, xe),
2554
+ (he) => ee.current?.(he)
1919
2555
  );
1920
- x.current && !j && (A.current.reset(), R.current?.setActive(!1), H()), x.current = j, V.current = requestAnimationFrame(I);
2556
+ } else J || Vt(
2557
+ P,
2558
+ null,
2559
+ "__sil__",
2560
+ U.current,
2561
+ (ne, pe, he, Me) => F.drawLiveFrame(ne, pe, he, Me),
2562
+ (ne) => ee.current?.(ne)
2563
+ );
2564
+ L.current = te, z.current = requestAnimationFrame(R);
1921
2565
  };
1922
- return V.current = requestAnimationFrame(I), () => {
1923
- cancelAnimationFrame(V.current), F(), f.stop();
2566
+ return z.current = requestAnimationFrame(R), () => {
2567
+ cancelAnimationFrame(z.current), se(), ae(), W.current.stop(), q.current?.stop();
1924
2568
  };
1925
- }, [K, Fe, H, F]), bt(
1926
- w,
2569
+ }, [
2570
+ X,
2571
+ c,
2572
+ De,
2573
+ se,
2574
+ ae
2575
+ ]), pn(
2576
+ D,
1927
2577
  () => ({
1928
- speakText: async (f, k) => {
1929
- const I = f.trim();
1930
- if (!I) return;
1931
- const T = g.current;
1932
- if (!T || !C.current && !K)
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)
1933
2583
  throw new Error("AI twin is not ready");
1934
- const { ttsEngineId: b, voiceId: j } = Q(k);
1935
- Z(null), y.current += 1, F(), _e(p.current), A.current.reset(), x.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;
1936
2586
  try {
1937
- W.current ? (R.current?.setActive(!1), R.current?.restart(), _e(p.current)) : await T.renderSilOnly(), await M.current.speak(I, {
1938
- voiceId: j,
1939
- speakingRate: k?.speakingRate ?? c,
1940
- ttsEngineId: b
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
1941
2591
  });
1942
- } catch (Y) {
1943
- throw $(Y instanceof Error ? Y.message : "TTS failed"), Y;
2592
+ } catch (oe) {
2593
+ throw fe(oe instanceof Error ? oe.message : "TTS failed"), oe;
1944
2594
  }
1945
2595
  },
1946
2596
  stop: () => {
1947
- y.current += 1, F(), M.current.stop(), _e(p.current), x.current = !1, H();
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();
1948
2598
  },
1949
- setTtsEngineId: (f) => {
1950
- M.current.setTtsEngineId(f), h.current && (h.current.ttsEngineId = f);
2599
+ setTtsEngineId: (h) => {
2600
+ W.current.setTtsEngineId(h), q.current?.setTtsEngineId(h), H.current && (H.current.ttsEngineId = h);
1951
2601
  },
1952
- renderViseme: async (f, k) => {
1953
- const I = g.current, T = u.current;
1954
- if (!I || !T || !C.current)
2602
+ renderViseme: async (h, R) => {
2603
+ const P = A.current, F = y.current;
2604
+ if (!P || !F || !_e.current)
1955
2605
  throw new Error("AI twin is not ready");
1956
- await I.renderViseme(T, f, {
1957
- from: k?.from,
1958
- transitionDurationMs: k?.transitionDurationMs,
1959
- gapMs: k?.gapMs,
1960
- onStatus: (b) => v.current?.(b)
2606
+ await P.renderViseme(F, h, {
2607
+ from: R?.from,
2608
+ transitionDurationMs: R?.transitionDurationMs,
2609
+ gapMs: R?.gapMs,
2610
+ onStatus: (N) => ee.current?.(N)
1961
2611
  });
1962
2612
  },
1963
- isReady: () => C.current,
1964
- getStatus: () => q
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
1965
2638
  }),
1966
2639
  [
1967
- K,
1968
- c,
1969
- F,
1970
- H,
1971
- $,
1972
- Q,
1973
- q
2640
+ X,
2641
+ o,
2642
+ r,
2643
+ i,
2644
+ se,
2645
+ ae,
2646
+ De,
2647
+ fe,
2648
+ yt,
2649
+ kt,
2650
+ Y
1974
2651
  ]
1975
- ), /* @__PURE__ */ It("div", { className: a, style: { ...Ir, ...l }, children: [
1976
- /* @__PURE__ */ Qe(
2652
+ ), /* @__PURE__ */ wn("div", { className: a, style: { ...xs, ...f }, children: [
2653
+ /* @__PURE__ */ vt(
1977
2654
  "canvas",
1978
2655
  {
1979
- ref: u,
1980
- width: se.width,
1981
- height: se.height,
1982
- style: { ...Tr, ...d },
2656
+ ref: y,
2657
+ width: B.width,
2658
+ height: B.height,
2659
+ style: { ...Cs, ...l },
1983
2660
  "aria-label": t ? `AI twin ${t}` : "AI twin face"
1984
2661
  }
1985
2662
  ),
1986
- D && Ee ? /* @__PURE__ */ Qe("div", { style: Ar, children: Ee }) : null
2663
+ E && re ? /* @__PURE__ */ vt("div", { style: Ps, children: re }) : null
1987
2664
  ] });
1988
2665
  });
1989
2666
  export {
1990
- xr as AiTwin,
1991
- Ue as AiTwinNotFoundError,
1992
- ce as DEFAULT_TTS_ENGINE_ID,
1993
- on as OCULUS_VISEME_IDS,
1994
- Tn as SPEAKING_RATE_MAX,
1995
- In as SPEAKING_RATE_MIN,
1996
- pe as TTS_ENGINE_CARTESIA,
1997
- ht as TTS_ENGINE_GOOGLE,
1998
- Ke as TTS_ENGINE_INWORLD,
1999
- Dr as VISEME_IDS,
2000
- An as VISEME_TEST_CARTESIA_VOICE_ID,
2001
- wt as VISEME_TEST_SPEAKING_RATE,
2002
- _t as VISEME_TEST_VOICE_ID,
2003
- bn as createAvatarTtsLipsyncController,
2004
- $t as fetchAiTwin,
2005
- Ye as fetchDevAuthToken,
2006
- cn as normalizeOculusViseme,
2007
- Sn as resolveVisemeAtTime,
2008
- vn 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
2009
2690
  };