@sage-rsc/talking-head-react 1.8.0 → 1.8.2

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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsxs as Pe, jsx as ae } from "react/jsx-runtime";
2
- import { forwardRef as Ke, useRef as W, useState as pe, useEffect as Se, useCallback as U, useImperativeHandle as Je, useLayoutEffect as pt } from "react";
2
+ import { forwardRef as Ke, useRef as V, useState as pe, useEffect as Se, useCallback as U, useImperativeHandle as Je, useLayoutEffect as pt } from "react";
3
3
  import * as b from "three";
4
4
  import { OrbitControls as gt } from "three/addons/controls/OrbitControls.js";
5
5
  import { GLTFLoader as yt } from "three/addons/loaders/GLTFLoader.js";
@@ -14,8 +14,8 @@ new b.Ray();
14
14
  new b.Euler();
15
15
  const be = new b.Quaternion(), st = new b.Quaternion(), De = new b.Matrix4(), Ne = new b.Matrix4();
16
16
  new b.Vector3();
17
- const qe = new b.Vector3(0, 0, 1), Rt = new b.Vector3(1, 0, 0), vt = new b.Vector3(0, 1, 0), It = new b.Vector3(0, 0, 1);
18
- class At {
17
+ const qe = new b.Vector3(0, 0, 1), Rt = new b.Vector3(1, 0, 0), At = new b.Vector3(0, 1, 0), vt = new b.Vector3(0, 0, 1);
18
+ class It {
19
19
  constructor(n = null) {
20
20
  this.opt = Object.assign({
21
21
  warmupMs: 2e3,
@@ -192,7 +192,7 @@ class At {
192
192
  const a = this.armature.getObjectByName(s.bone);
193
193
  if (!a) throw new Error("Bone '" + s.bone + "' not found in #" + i + " exclude.");
194
194
  if (Number.isNaN(s.radius) && s.radius >= 0) throw new Error("Radius must be a non-negative number in #" + i + " exclude.");
195
- const c = {
195
+ const u = {
196
196
  bone: a,
197
197
  // Bone object
198
198
  radius: s.radius,
@@ -203,9 +203,9 @@ class At {
203
203
  };
204
204
  if (s.deltaLocal) {
205
205
  if (!Array.isArray(s.deltaLocal) || s.deltaLocal.length !== 3 || s.deltaLocal.some((l) => Number.isNaN(l))) throw new Error("deltaLocal must be an array of three numbers in #" + i + " exclude.");
206
- c.deltaLocal = [...s.deltaLocal];
206
+ u.deltaLocal = [...s.deltaLocal];
207
207
  }
208
- o.excludes.push(c);
208
+ o.excludes.push(u);
209
209
  });
210
210
  }
211
211
  this.showHelpers();
@@ -282,8 +282,8 @@ class At {
282
282
  p = this.dict[i.boneParent.name], p && (p.children || (p.children = []), p.children.push(i));
283
283
  }), this.objectsUpdate = [];
284
284
  const t = /* @__PURE__ */ new WeakSet(), o = (i) => i.parent?.isBone ? [i, ...o(i.parent)] : [i], s = (i) => {
285
- o(i).forEach((c) => {
286
- t.has(c) || (this.objectsUpdate.push(c), t.add(c));
285
+ o(i).forEach((u) => {
286
+ t.has(u) || (this.objectsUpdate.push(u), t.add(u));
287
287
  });
288
288
  };
289
289
  this.data.forEach((i) => {
@@ -308,12 +308,12 @@ class At {
308
308
  o(n?.isScene, "First parameter must be Scene."), this.scene = n, o(e?.isObject3D, "Second parameter must be the armature Object3D."), this.armature = e, o(Array.isArray(t), "Third parameter must be an array of bone configs."), this.config = t, this.config.forEach((s, i) => {
309
309
  const a = "Config item #" + i + ": ";
310
310
  o(s.bone, a + "Bone not specified.");
311
- const c = s.bone;
312
- o(typeof c == "string" && c.length > 0, a + "Bone name must be a non-empty string.");
313
- const l = this.armature.getObjectByName(c);
314
- o(l, a + "Bone '" + c + "' not found."), o(l.parent?.isBone, a + "Bone must have a parent bone."), o(this.data.every((r) => r.bone !== l), a + "Bone '" + c + "' already exists."), l.updateMatrixWorld(!0);
315
- const u = {
316
- name: c,
311
+ const u = s.bone;
312
+ o(typeof u == "string" && u.length > 0, a + "Bone name must be a non-empty string.");
313
+ const l = this.armature.getObjectByName(u);
314
+ o(l, a + "Bone '" + u + "' not found."), o(l.parent?.isBone, a + "Bone must have a parent bone."), o(this.data.every((r) => r.bone !== l), a + "Bone '" + u + "' already exists."), l.updateMatrixWorld(!0);
315
+ const c = {
316
+ name: u,
317
317
  // Bone name
318
318
  bone: l,
319
319
  // Bone object
@@ -338,9 +338,9 @@ class At {
338
338
  ea: [0, 0, 0, 0]
339
339
  // External acceleration [m/s^2]
340
340
  };
341
- u.boneParent.matrixWorld.decompose(N, be, xe), N.copy(qe).applyQuaternion(be).setY(0).normalize(), be.premultiply(st.setFromUnitVectors(qe, N).invert()).normalize(), u.qWorldInverseYaw = be.clone().normalize(), this.data.push(u), this.dict[c] = u;
341
+ c.boneParent.matrixWorld.decompose(N, be, xe), N.copy(qe).applyQuaternion(be).setY(0).normalize(), be.premultiply(st.setFromUnitVectors(qe, N).invert()).normalize(), c.qWorldInverseYaw = be.clone().normalize(), this.data.push(c), this.dict[u] = c;
342
342
  try {
343
- this.setValue(c, "type", s.type), this.setValue(c, "stiffness", s.stiffness), this.setValue(c, "damping", s.damping), this.setValue(c, "external", s.external), this.setValue(c, "limits", s.limits), this.setValue(c, "excludes", s.excludes), this.setValue(c, "deltaLocal", s.deltaLocal), this.setValue(c, "deltaWorld", s.deltaWorld), this.setValue(c, "pivot", s.pivot), this.setValue(c, "helper", s.helper);
343
+ this.setValue(u, "type", s.type), this.setValue(u, "stiffness", s.stiffness), this.setValue(u, "damping", s.damping), this.setValue(u, "external", s.external), this.setValue(u, "limits", s.limits), this.setValue(u, "excludes", s.excludes), this.setValue(u, "deltaLocal", s.deltaLocal), this.setValue(u, "deltaWorld", s.deltaWorld), this.setValue(u, "pivot", s.pivot), this.setValue(u, "helper", s.helper);
344
344
  } catch (r) {
345
345
  o(!1, a + r);
346
346
  }
@@ -369,7 +369,7 @@ class At {
369
369
  i.vBasis.y + z[1],
370
370
  i.vBasis.z - z[2]
371
371
  );
372
- else if (i.boneParent.quaternion.copy(i.qBasis), i.pivot && this.opt.isPivots && (i.boneParent.updateWorldMatrix(!1, !1), i.boneParent.matrixWorld.decompose(N, be, xe), N.copy(qe).applyQuaternion(be).setY(0).normalize(), be.premultiply(st.setFromUnitVectors(qe, N).invert()).normalize(), i.boneParent.quaternion.multiply(be.invert()), i.boneParent.quaternion.multiply(i.qWorldInverseYaw)), i.isZ && (p = Math.atan(z[0] / i.l), be.setFromAxisAngle(It, -p), i.boneParent.quaternion.multiply(be)), i.isY && (p = i.l / 3, p = p * Math.tanh(z[1] / p), i.bone.position.setLength(i.l + p)), i.isX && (p = Math.atan(z[2] / i.l), be.setFromAxisAngle(Rt, -p), i.boneParent.quaternion.multiply(be)), i.isT && (p = 1.5 * Math.tanh(z[3] * 1.5), be.setFromAxisAngle(vt, -p), i.boneParent.quaternion.multiply(be)), i.boneParent.updateWorldMatrix(!1, !0), i.excludes && this.opt.isExcludes)
372
+ else if (i.boneParent.quaternion.copy(i.qBasis), i.pivot && this.opt.isPivots && (i.boneParent.updateWorldMatrix(!1, !1), i.boneParent.matrixWorld.decompose(N, be, xe), N.copy(qe).applyQuaternion(be).setY(0).normalize(), be.premultiply(st.setFromUnitVectors(qe, N).invert()).normalize(), i.boneParent.quaternion.multiply(be.invert()), i.boneParent.quaternion.multiply(i.qWorldInverseYaw)), i.isZ && (p = Math.atan(z[0] / i.l), be.setFromAxisAngle(vt, -p), i.boneParent.quaternion.multiply(be)), i.isY && (p = i.l / 3, p = p * Math.tanh(z[1] / p), i.bone.position.setLength(i.l + p)), i.isX && (p = Math.atan(z[2] / i.l), be.setFromAxisAngle(Rt, -p), i.boneParent.quaternion.multiply(be)), i.isT && (p = 1.5 * Math.tanh(z[3] * 1.5), be.setFromAxisAngle(At, -p), i.boneParent.quaternion.multiply(be)), i.boneParent.updateWorldMatrix(!1, !0), i.excludes && this.opt.isExcludes)
373
373
  for (t = 0, s = i.excludes.length; t < s; t++)
374
374
  p = i.excludes[t], xe.set(0, 0, 0), p.deltaLocal && (xe.x += p.deltaLocal[0], xe.y += p.deltaLocal[1], xe.z += p.deltaLocal[2]), xe.applyMatrix4(p.bone.matrixWorld), Ne.copy(i.boneParent.matrixWorld).invert(), xe.applyMatrix4(Ne), N.copy(i.bone.position), !(N.distanceToSquared(xe) >= p.radiusSq) && (Ce = N.length(), Le = xe.length(), !(Le > p.radius + Ce) && (Le < Math.abs(p.radius - Ce) || (Le = (Le * Le + Ce * Ce - p.radiusSq) / (2 * Le), xe.normalize(), Ye.copy(xe).multiplyScalar(Le), Le = Math.sqrt(Ce * Ce - Le * Le), N.subVectors(N, Ye).projectOnPlane(xe).normalize().multiplyScalar(Le), Qe.subVectors(i.vBasis, Ye).projectOnPlane(xe).normalize(), Ce = Qe.dot(N), Ce < 0 && (Ce = Math.sqrt(Le * Le - Ce * Ce), Qe.multiplyScalar(Ce), N.add(Qe)), N.add(Ye).normalize(), xe.copy(i.bone.position).normalize(), be.setFromUnitVectors(xe, N), i.boneParent.quaternion.premultiply(be), i.boneParent.updateWorldMatrix(!1, !0))));
375
375
  }
@@ -408,9 +408,9 @@ class At {
408
408
  );
409
409
  }), p = this.helpers.points, p.bones.length) {
410
410
  this.helpers.isActive = !0;
411
- const e = new b.BufferGeometry(), t = p.bones.map((c) => [0, 0, 0]).flat();
411
+ const e = new b.BufferGeometry(), t = p.bones.map((u) => [0, 0, 0]).flat();
412
412
  e.setAttribute("position", new b.Float32BufferAttribute(t, 3));
413
- const o = new b.Color(this.opt.helperBoneColor1), s = new b.Color(this.opt.helperBoneColor2), i = p.pivots.map((c) => c && this.opt.isPivots ? [s.r, s.g, s.b] : [o.r, o.g, o.b]).flat();
413
+ const o = new b.Color(this.opt.helperBoneColor1), s = new b.Color(this.opt.helperBoneColor2), i = p.pivots.map((u) => u && this.opt.isPivots ? [s.r, s.g, s.b] : [o.r, o.g, o.b]).flat();
414
414
  e.setAttribute("color", new b.Float32BufferAttribute(i, 3));
415
415
  const a = new b.PointsMaterial({
416
416
  depthTest: !1,
@@ -423,9 +423,9 @@ class At {
423
423
  p.object = new b.Points(e, a), p.object.renderOrder = 998, p.object.matrix = this.armature.matrixWorld, p.object.matrixAutoUpdate = !1, this.scene.add(p.object);
424
424
  }
425
425
  if (p = this.helpers.lines, p.bones.length) {
426
- const e = new b.BufferGeometry(), t = p.bones.map((c) => [0, 0, 0, 0, 0, 0]).flat();
426
+ const e = new b.BufferGeometry(), t = p.bones.map((u) => [0, 0, 0, 0, 0, 0]).flat();
427
427
  e.setAttribute("position", new b.Float32BufferAttribute(t, 3));
428
- const o = new b.Color(this.opt.helperLinkColor1), s = new b.Color(this.opt.helperLinkColor2), i = p.bones.map((c) => [o.r, o.g, o.b, s.r, s.g, s.b]).flat();
428
+ const o = new b.Color(this.opt.helperLinkColor1), s = new b.Color(this.opt.helperLinkColor2), i = p.bones.map((u) => [o.r, o.g, o.b, s.r, s.g, s.b]).flat();
429
429
  e.setAttribute("color", new b.Float32BufferAttribute(i, 3));
430
430
  const a = new b.LineBasicMaterial({
431
431
  vertexColors: !0,
@@ -519,13 +519,13 @@ class Lt {
519
519
  phonemeBoundaries: []
520
520
  }, o = 1024, s = 512, i = Math.floor((n.length - o) / s) + 1;
521
521
  for (let a = 0; a < i; a++) {
522
- const c = a * s, l = Math.min(c + o, n.length), u = n.slice(c, l), r = this.calculateEnergy(u);
522
+ const u = a * s, l = Math.min(u + o, n.length), c = n.slice(u, l), r = this.calculateEnergy(c);
523
523
  t.energy.push(r);
524
- const h = this.calculateSpectralCentroid(u);
524
+ const h = this.calculateSpectralCentroid(c);
525
525
  t.spectralCentroid.push(h);
526
- const d = this.calculateZeroCrossingRate(u);
526
+ const d = this.calculateZeroCrossingRate(c);
527
527
  t.zeroCrossingRate.push(d);
528
- const g = this.calculateMFCC(u);
528
+ const g = this.calculateMFCC(c);
529
529
  t.mfcc.push(g);
530
530
  }
531
531
  return t.onsets = this.detectOnsets(t.energy), t.phonemeBoundaries = this.detectPhonemeBoundaries(t), t;
@@ -597,19 +597,19 @@ class Lt {
597
597
  for (; s & i; )
598
598
  s ^= i, i >>= 1;
599
599
  if (s ^= i, o < s) {
600
- const a = t[o * 2], c = t[o * 2 + 1];
601
- t[o * 2] = t[s * 2], t[o * 2 + 1] = t[s * 2 + 1], t[s * 2] = a, t[s * 2 + 1] = c;
600
+ const a = t[o * 2], u = t[o * 2 + 1];
601
+ t[o * 2] = t[s * 2], t[o * 2 + 1] = t[s * 2 + 1], t[s * 2] = a, t[s * 2 + 1] = u;
602
602
  }
603
603
  }
604
604
  for (let o = 2; o <= e; o <<= 1) {
605
605
  const s = -2 * Math.PI / o, i = Math.cos(s), a = Math.sin(s);
606
- for (let c = 0; c < e; c += o) {
607
- let l = 1, u = 0;
606
+ for (let u = 0; u < e; u += o) {
607
+ let l = 1, c = 0;
608
608
  for (let r = 0; r < o / 2; r++) {
609
- const h = t[(c + r) * 2], d = t[(c + r) * 2 + 1], g = t[(c + r + o / 2) * 2] * l - t[(c + r + o / 2) * 2 + 1] * u, R = t[(c + r + o / 2) * 2] * u + t[(c + r + o / 2) * 2 + 1] * l;
610
- t[(c + r) * 2] = h + g, t[(c + r) * 2 + 1] = d + R, t[(c + r + o / 2) * 2] = h - g, t[(c + r + o / 2) * 2 + 1] = d - R;
611
- const x = l * i - u * a, S = l * a + u * i;
612
- l = x, u = S;
609
+ const h = t[(u + r) * 2], d = t[(u + r) * 2 + 1], g = t[(u + r + o / 2) * 2] * l - t[(u + r + o / 2) * 2 + 1] * c, R = t[(u + r + o / 2) * 2] * c + t[(u + r + o / 2) * 2 + 1] * l;
610
+ t[(u + r) * 2] = h + g, t[(u + r) * 2 + 1] = d + R, t[(u + r + o / 2) * 2] = h - g, t[(u + r + o / 2) * 2 + 1] = d - R;
611
+ const x = l * i - c * a, k = l * a + c * i;
612
+ l = x, c = k;
613
613
  }
614
614
  }
615
615
  }
@@ -624,8 +624,8 @@ class Lt {
624
624
  const e = [];
625
625
  let s = -0.1;
626
626
  for (let i = 1; i < n.length; i++) {
627
- const a = n[i] - n[i - 1], c = i * 0.023;
628
- a > 0.1 && c - s > 0.1 && (e.push(c), s = c);
627
+ const a = n[i] - n[i - 1], u = i * 0.023;
628
+ a > 0.1 && u - s > 0.1 && (e.push(u), s = u);
629
629
  }
630
630
  return e;
631
631
  }
@@ -637,8 +637,8 @@ class Lt {
637
637
  detectPhonemeBoundaries(n) {
638
638
  const e = [], { energy: t, spectralCentroid: o, zeroCrossingRate: s } = n;
639
639
  for (let i = 1; i < t.length; i++) {
640
- const a = i * 0.023, c = Math.abs(t[i] - t[i - 1]), l = Math.abs(o[i] - o[i - 1]), u = Math.abs(s[i] - s[i - 1]);
641
- c + l * 0.1 + u * 0.5 > 0.2 && e.push(a);
640
+ const a = i * 0.023, u = Math.abs(t[i] - t[i - 1]), l = Math.abs(o[i] - o[i - 1]), c = Math.abs(s[i] - s[i - 1]);
641
+ u + l * 0.1 + c * 0.5 > 0.2 && e.push(a);
642
642
  }
643
643
  return e;
644
644
  }
@@ -654,14 +654,14 @@ class Lt {
654
654
  n.phonemeBoundaries, n.onsets;
655
655
  const s = [];
656
656
  let i = 0;
657
- for (let c = 0; c < o.length; c++) {
658
- const l = o[c], u = this.estimateWordDuration(l, t / o.length);
657
+ for (let u = 0; u < o.length; u++) {
658
+ const l = o[u], c = this.estimateWordDuration(l, t / o.length);
659
659
  s.push({
660
660
  word: l,
661
661
  startTime: i,
662
- endTime: i + u,
663
- duration: u
664
- }), i += u;
662
+ endTime: i + c,
663
+ duration: c
664
+ }), i += c;
665
665
  }
666
666
  const a = this.generateVisemeTimings(n, e, t);
667
667
  return {
@@ -701,27 +701,27 @@ class Lt {
701
701
  const o = [], s = n.phonemeBoundaries;
702
702
  n.onsets;
703
703
  const i = this.textToVisemes(e);
704
- let a = 0, c = 0;
704
+ let a = 0, u = 0;
705
705
  for (let l = 0; l < s.length && a < i.length; l++) {
706
- const u = s[l], r = i[a], h = n.energy[Math.floor(u / 0.023)] || 0, d = this.calculateVisemeDuration(r, h);
706
+ const c = s[l], r = i[a], h = n.energy[Math.floor(c / 0.023)] || 0, d = this.calculateVisemeDuration(r, h);
707
707
  o.push({
708
708
  viseme: r,
709
- startTime: c,
710
- endTime: c + d,
709
+ startTime: u,
710
+ endTime: u + d,
711
711
  duration: d,
712
712
  intensity: Math.min(1, h * 2)
713
713
  // Map energy to viseme intensity
714
- }), c += d, a++;
714
+ }), u += d, a++;
715
715
  }
716
716
  for (; a < i.length; ) {
717
- const l = i[a], u = this.calculateVisemeDuration(l, 0.5);
717
+ const l = i[a], c = this.calculateVisemeDuration(l, 0.5);
718
718
  o.push({
719
719
  viseme: l,
720
- startTime: c,
721
- endTime: c + u,
722
- duration: u,
720
+ startTime: u,
721
+ endTime: u + c,
722
+ duration: c,
723
723
  intensity: 0.6
724
- }), c += u, a++;
724
+ }), u += c, a++;
725
725
  }
726
726
  return o;
727
727
  }
@@ -775,16 +775,16 @@ class Lt {
775
775
  let i = 0;
776
776
  for (; i < s.length; ) {
777
777
  let a = !1;
778
- for (let c = 3; c >= 2; c--) {
779
- const l = s.substr(i, c);
778
+ for (let u = 3; u >= 2; u--) {
779
+ const l = s.substr(i, u);
780
780
  if (e[l]) {
781
- t.push(e[l]), i += c, a = !0;
781
+ t.push(e[l]), i += u, a = !0;
782
782
  break;
783
783
  }
784
784
  }
785
785
  if (!a) {
786
- const c = s[i];
787
- e[c] && t.push(e[c]), i++;
786
+ const u = s[i];
787
+ e[u] && t.push(e[u]), i++;
788
788
  }
789
789
  }
790
790
  }
@@ -1206,11 +1206,11 @@ class St {
1206
1206
  };
1207
1207
  Object.keys(this.rules).forEach((e) => {
1208
1208
  this.rules[e] = this.rules[e].map((t) => {
1209
- const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o), c = t.substring(o + 1, s), l = t.substring(s + 1, i), u = t.substring(i + 1), r = { regex: "", move: 0, visemes: [] };
1209
+ const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o), u = t.substring(o + 1, s), l = t.substring(s + 1, i), c = t.substring(i + 1), r = { regex: "", move: 0, visemes: [] };
1210
1210
  let h = "";
1211
1211
  h += [...a].map((g) => n[g] || g).join("");
1212
- const d = [...c];
1213
- return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h), u.length && u.split(" ").forEach((g) => {
1212
+ const d = [...u];
1213
+ return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h), c.length && c.split(" ").forEach((g) => {
1214
1214
  r.visemes.push(g);
1215
1215
  }), r;
1216
1216
  });
@@ -1324,8 +1324,8 @@ class St {
1324
1324
  */
1325
1325
  convertDecade(n) {
1326
1326
  const e = parseInt(n), t = !isNaN(e) && n.length === 2, o = !isNaN(e) && n.length > 2 && e > 0 && e <= 3e3, s = o && e % 1e3 === 0 ? Math.floor(e / 1e3) : null, i = o && !s ? Math.floor(e / 100) : null, a = t || o ? Math.floor(e % 100 / 10) * 10 : null;
1327
- let c = [];
1328
- return s ? c.push(this.convertNumberToWords(s).trim(), "thousands") : (i && c.push(this.convertNumberToWords(i).trim()), a ? c.push(this.decades[a] || this.convertNumberToWords(a).trim() + "s") : i ? c.push("hundreds") : c.push(n)), c.join(" ");
1327
+ let u = [];
1328
+ return s ? u.push(this.convertNumberToWords(s).trim(), "thousands") : (i && u.push(this.convertNumberToWords(i).trim()), a ? u.push(this.decades[a] || this.convertNumberToWords(a).trim() + "s") : i ? u.push("hundreds") : u.push(n)), u.join(" ");
1329
1329
  }
1330
1330
  /**
1331
1331
  * Convert ordinal number to text.
@@ -1376,9 +1376,9 @@ class St {
1376
1376
  const s = o[e.i], i = this.rules[s];
1377
1377
  if (i)
1378
1378
  for (let a = 0; a < i.length; a++) {
1379
- const c = i[a];
1380
- if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(c.regex)) {
1381
- c.visemes.forEach((r) => {
1379
+ const u = i[a];
1380
+ if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(u.regex)) {
1381
+ u.visemes.forEach((r) => {
1382
1382
  if (e.visemes.length && e.visemes[e.visemes.length - 1] === r) {
1383
1383
  const h = 0.7 * (this.visemeDurations[r] || 1);
1384
1384
  e.durations[e.durations.length - 1] += h, t += h;
@@ -1386,7 +1386,7 @@ class St {
1386
1386
  const h = this.visemeDurations[r] || 1;
1387
1387
  e.visemes.push(r), e.times.push(t), e.durations.push(h), t += h;
1388
1388
  }
1389
- }), e.i += c.move;
1389
+ }), e.i += u.move;
1390
1390
  break;
1391
1391
  }
1392
1392
  }
@@ -1616,11 +1616,11 @@ class wt {
1616
1616
  };
1617
1617
  Object.keys(this.rules).forEach((e) => {
1618
1618
  this.rules[e] = this.rules[e].map((t) => {
1619
- const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o), c = t.substring(o + 1, s), l = t.substring(s + 1, i), u = t.substring(i + 1), r = { regex: "", move: 0, visemes: [] };
1619
+ const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o), u = t.substring(o + 1, s), l = t.substring(s + 1, i), c = t.substring(i + 1), r = { regex: "", move: 0, visemes: [] };
1620
1620
  let h = "";
1621
1621
  h += [...a].map((g) => n[g] || g).join("");
1622
- const d = [...c];
1623
- return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h), u.length && u.split(" ").forEach((g) => {
1622
+ const d = [...u];
1623
+ return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h), c.length && c.split(" ").forEach((g) => {
1624
1624
  r.visemes.push(g);
1625
1625
  }), r;
1626
1626
  });
@@ -1732,8 +1732,8 @@ class wt {
1732
1732
  const s = o[e.i], i = this.rules[s];
1733
1733
  if (i) {
1734
1734
  let a = !1;
1735
- for (let c = 0; c < i.length; c++) {
1736
- const l = i[c];
1735
+ for (let u = 0; u < i.length; u++) {
1736
+ const l = i[u];
1737
1737
  if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(l.regex)) {
1738
1738
  l.visemes.forEach((h) => {
1739
1739
  if (e.visemes.length && e.visemes[e.visemes.length - 1] === h) {
@@ -2131,11 +2131,11 @@ class zt {
2131
2131
  };
2132
2132
  Object.keys(this.rules).forEach((e) => {
2133
2133
  this.rules[e] = this.rules[e].map((t) => {
2134
- const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o), c = t.substring(o + 1, s), l = t.substring(s + 1, i), u = t.substring(i + 1), r = { regex: "", move: 0, visemes: [] };
2134
+ const o = t.indexOf("["), s = t.indexOf("]"), i = t.indexOf("="), a = t.substring(0, o), u = t.substring(o + 1, s), l = t.substring(s + 1, i), c = t.substring(i + 1), r = { regex: "", move: 0, visemes: [] };
2135
2135
  let h = "";
2136
2136
  h += [...a].map((g) => n[g] || g).join("");
2137
- const d = [...c];
2138
- return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h, "i"), u.length && u.split(" ").forEach((g) => {
2137
+ const d = [...u];
2138
+ return d[0] = d[0].toLowerCase(), h += d.join(""), r.move = d.length, h += [...l].map((g) => n[g] || g).join(""), r.regex = new RegExp(h, "i"), c.length && c.split(" ").forEach((g) => {
2139
2139
  g && r.visemes.push(g);
2140
2140
  }), r;
2141
2141
  });
@@ -2267,8 +2267,8 @@ class zt {
2267
2267
  const s = o[e.i], i = this.rules[s];
2268
2268
  if (i) {
2269
2269
  let a = !1;
2270
- for (let c = 0; c < i.length; c++) {
2271
- const l = i[c];
2270
+ for (let u = 0; u < i.length; u++) {
2271
+ const l = i[u];
2272
2272
  if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(l.regex)) {
2273
2273
  l.visemes.forEach((h) => {
2274
2274
  if (e.visemes.length && e.visemes[e.visemes.length - 1] === h) {
@@ -2381,10 +2381,10 @@ class Tt {
2381
2381
  const e = [];
2382
2382
  let t = parseFloat(n);
2383
2383
  if (t === void 0) return n;
2384
- let o = (s, i, a, c, l) => {
2384
+ let o = (s, i, a, u, l) => {
2385
2385
  if (s < i) return s;
2386
- const u = Math.floor(s / i);
2387
- return e.push(a + (u === 1 ? c : this.numberToFinnishWords(u.toString()) + l)), s - u * i;
2386
+ const c = Math.floor(s / i);
2387
+ return e.push(a + (c === 1 ? u : this.numberToFinnishWords(c.toString()) + l)), s - c * i;
2388
2388
  };
2389
2389
  if (t < 0 && (e.push("miinus "), t = Math.abs(t)), t = o(t, 1e9, " ", "miljardi", " miljardia"), t = o(t, 1e6, " ", "miljoona", " miljoonaa"), t = o(t, 1e3, "", "tuhat", "tuhatta"), t = o(t, 100, " ", "sata", "sataa"), t > 20 && (t = o(t, 10, "", "", "kymmentä")), t >= 1) {
2390
2390
  let s = Math.floor(t);
@@ -2440,7 +2440,7 @@ const Mt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2440
2440
  __proto__: null,
2441
2441
  LipsyncFi: Tt
2442
2442
  }, Symbol.toStringTag, { value: "Module" }));
2443
- class Et {
2443
+ class Ft {
2444
2444
  /**
2445
2445
  * @constructor
2446
2446
  */
@@ -2559,10 +2559,10 @@ class Et {
2559
2559
  const e = [];
2560
2560
  let t = parseFloat(n);
2561
2561
  if (t === void 0) return n;
2562
- let o = (s, i, a, c, l) => {
2562
+ let o = (s, i, a, u, l) => {
2563
2563
  if (s < i) return s;
2564
- const u = Math.floor(s / i);
2565
- return u === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(u.toString())), u % 10 === 1 ? e.push(a) : u % 10 === 0 || u % 100 > 10 && u % 100 < 20 ? e.push(l) : e.push(c), s - u * i;
2564
+ const c = Math.floor(s / i);
2565
+ return c === 1 ? e.push(this.numbers[1]) : e.push(this.numberToLithuanianWords(c.toString())), c % 10 === 1 ? e.push(a) : c % 10 === 0 || c % 100 > 10 && c % 100 < 20 ? e.push(l) : e.push(u), s - c * i;
2566
2566
  };
2567
2567
  t < 0 && (e.push("minus"), t = Math.abs(t)), t = o(t, 1e9, "milijardas", "milijardai", "milijardų"), t = o(t, 1e6, "milijonas", "milijonai", "milijonų"), t = o(t, 1e3, "tūkstantis", "tūkstančiai", "tūkstančių"), t = o(t, 100, "šimtas", "šimtai", "šimtų");
2568
2568
  for (let s = this.tens.length - 1; s >= 1; s--)
@@ -2608,11 +2608,11 @@ class Et {
2608
2608
  const i = o[s].toLowerCase(), a = this.visemes[i];
2609
2609
  if (a)
2610
2610
  if (e.visemes.length && e.visemes[e.visemes.length - 1] === a) {
2611
- const c = 0.7 * (this.durations[i] || 1);
2612
- e.durations[e.durations.length - 1] += c, t += c;
2611
+ const u = 0.7 * (this.durations[i] || 1);
2612
+ e.durations[e.durations.length - 1] += u, t += u;
2613
2613
  } else {
2614
- const c = this.durations[i] || 1;
2615
- e.visemes.push(a), e.times.push(t), e.durations.push(c), t += c;
2614
+ const u = this.durations[i] || 1;
2615
+ e.visemes.push(a), e.times.push(t), e.durations.push(u), t += u;
2616
2616
  }
2617
2617
  else
2618
2618
  t += this.pauses[o[s]] || 0;
@@ -2620,21 +2620,21 @@ class Et {
2620
2620
  return e;
2621
2621
  }
2622
2622
  }
2623
- const Ft = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2623
+ const Et = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2624
2624
  __proto__: null,
2625
- LipsyncLt: Et
2625
+ LipsyncLt: Ft
2626
2626
  }, Symbol.toStringTag, { value: "Module" })), Pt = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), rt = {
2627
2627
  en: kt,
2628
2628
  de: Ct,
2629
2629
  fr: Ht,
2630
2630
  fi: Mt,
2631
- lt: Ft
2632
- }, ce = new b.Quaternion(), oe = new b.Euler(), Ue = new b.Vector3(), Ze = new b.Vector3(), at = new b.Box3();
2631
+ lt: Et
2632
+ }, ue = new b.Quaternion(), oe = new b.Euler(), Ue = new b.Vector3(), Xe = new b.Vector3(), at = new b.Box3();
2633
2633
  new b.Matrix4();
2634
2634
  new b.Matrix4();
2635
2635
  new b.Vector3();
2636
2636
  new b.Vector3(0, 0, 1);
2637
- const Ot = new b.Vector3(1, 0, 0);
2637
+ const Bt = new b.Vector3(1, 0, 0);
2638
2638
  new b.Vector3(0, 1, 0);
2639
2639
  new b.Vector3(0, 0, 1);
2640
2640
  class nt {
@@ -3569,15 +3569,15 @@ class nt {
3569
3569
  "RightArm.scale": { x: 0, y: 0, z: 0 }
3570
3570
  }
3571
3571
  }, ["Left", "Right"].forEach((a) => {
3572
- ["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((c) => {
3573
- this.poseDelta.props[a + c + ".quaternion"] = { x: 0, y: 0, z: 0 };
3574
- }), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((c) => {
3575
- this.poseDelta.props[a + c + "1.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[a + c + "2.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[a + c + "3.quaternion"] = { x: 0, y: 0, z: 0 };
3572
+ ["Leg", "UpLeg", "Arm", "ForeArm", "Hand"].forEach((u) => {
3573
+ this.poseDelta.props[a + u + ".quaternion"] = { x: 0, y: 0, z: 0 };
3574
+ }), ["HandThumb", "HandIndex", "HandMiddle", "HandRing", "HandPinky"].forEach((u) => {
3575
+ this.poseDelta.props[a + u + "1.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[a + u + "2.quaternion"] = { x: 0, y: 0, z: 0 }, this.poseDelta.props[a + u + "3.quaternion"] = { x: 0, y: 0, z: 0 };
3576
3576
  });
3577
3577
  });
3578
3578
  const t = /* @__PURE__ */ new Set();
3579
3579
  Object.values(this.poseTemplates).forEach((a) => {
3580
- Object.keys(this.propsToThreeObjects(a.props)).forEach((c) => t.add(c));
3580
+ Object.keys(this.propsToThreeObjects(a.props)).forEach((u) => t.add(u));
3581
3581
  }), Object.keys(this.poseDelta.props).forEach((a) => {
3582
3582
  t.add(a);
3583
3583
  }), this.posePropNames = [...t], this.poseName = "side", this.poseWeightOnLeft = !0, this.gesture = null, this.poseCurrentTemplate = this.poseTemplates[this.poseName], this.poseStraight = this.propsToThreeObjects(this.poseTemplates.straight.props), this.poseBase = this.poseFactory(this.poseCurrentTemplate), this.poseTarget = this.poseFactory(this.poseCurrentTemplate), this.poseAvatar = null, this.avatarHeight = 1.7, this.animTemplateEyes = {
@@ -4101,10 +4101,10 @@ class nt {
4101
4101
  RightHand: "RightForeArm",
4102
4102
  RightHandMiddle1: "RightHand"
4103
4103
  }, i = [];
4104
- Object.entries(s).forEach((a, c) => {
4104
+ Object.entries(s).forEach((a, u) => {
4105
4105
  const l = new b.Bone();
4106
4106
  l.name = a[0], a[1] ? this.ikMesh.getObjectByName(a[1]).add(l) : this.ikMesh.add(l), i.push(l);
4107
- }), this.ikMesh.bind(new b.Skeleton(i)), this.dynamicbones = new At(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
4107
+ }), this.ikMesh.bind(new b.Skeleton(i)), this.dynamicbones = new It(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
4108
4108
  }
4109
4109
  /**
4110
4110
  * Helper that re/creates the audio context and the other nodes.
@@ -4150,9 +4150,9 @@ class nt {
4150
4150
  let e = 3 * n.length / 4;
4151
4151
  n[n.length - 1] === "=" && (e--, n[n.length - 2] === "=" && e--);
4152
4152
  const t = new ArrayBuffer(e), o = new Uint8Array(t);
4153
- let s, i = 0, a, c, l, u;
4153
+ let s, i = 0, a, u, l, c;
4154
4154
  for (s = 0; s < n.length; s += 4)
4155
- a = this.b64Lookup[n.charCodeAt(s)], c = this.b64Lookup[n.charCodeAt(s + 1)], l = this.b64Lookup[n.charCodeAt(s + 2)], u = this.b64Lookup[n.charCodeAt(s + 3)], o[i++] = a << 2 | c >> 4, o[i++] = (c & 15) << 4 | l >> 2, o[i++] = (l & 3) << 6 | u & 63;
4155
+ a = this.b64Lookup[n.charCodeAt(s)], u = this.b64Lookup[n.charCodeAt(s + 1)], l = this.b64Lookup[n.charCodeAt(s + 2)], c = this.b64Lookup[n.charCodeAt(s + 3)], o[i++] = a << 2 | u >> 4, o[i++] = (u & 15) << 4 | l >> 2, o[i++] = (l & 3) << 6 | c & 63;
4156
4156
  return t;
4157
4157
  }
4158
4158
  /**
@@ -4193,8 +4193,8 @@ class nt {
4193
4193
  const e = {};
4194
4194
  for (let [t, o] of Object.entries(n)) {
4195
4195
  const s = t.split(".");
4196
- let i = Array.isArray(o.x) ? this.gaussianRandom(...o.x) : o.x, a = Array.isArray(o.y) ? this.gaussianRandom(...o.y) : o.y, c = Array.isArray(o.z) ? this.gaussianRandom(...o.z) : o.z;
4197
- s[1] === "position" || s[1] === "scale" ? e[t] = new b.Vector3(i, a, c) : s[1] === "rotation" ? (t = s[0] + ".quaternion", e[t] = new b.Quaternion().setFromEuler(new b.Euler(i, a, c, "XYZ")).normalize()) : s[1] === "quaternion" && (e[t] = new b.Quaternion(i, a, c, o.w).normalize());
4196
+ let i = Array.isArray(o.x) ? this.gaussianRandom(...o.x) : o.x, a = Array.isArray(o.y) ? this.gaussianRandom(...o.y) : o.y, u = Array.isArray(o.z) ? this.gaussianRandom(...o.z) : o.z;
4197
+ s[1] === "position" || s[1] === "scale" ? e[t] = new b.Vector3(i, a, u) : s[1] === "rotation" ? (t = s[0] + ".quaternion", e[t] = new b.Quaternion().setFromEuler(new b.Euler(i, a, u, "XYZ")).normalize()) : s[1] === "quaternion" && (e[t] = new b.Quaternion(i, a, u, o.w).normalize());
4198
4198
  }
4199
4199
  return e;
4200
4200
  }
@@ -4222,23 +4222,23 @@ class nt {
4222
4222
  n.forEach((s) => {
4223
4223
  if (!o && s.morphTargetDictionary.hasOwnProperty(e)) return;
4224
4224
  const i = s.geometry;
4225
- let a = null, c = null;
4226
- for (const [l, u] of Object.entries(t))
4225
+ let a = null, u = null;
4226
+ for (const [l, c] of Object.entries(t))
4227
4227
  if (s.morphTargetDictionary.hasOwnProperty(l)) {
4228
4228
  const r = s.morphTargetDictionary[l], h = i.morphAttributes.position[r], d = i.morphAttributes.normal?.[r];
4229
- a || (a = new b.Float32BufferAttribute(h.count * 3, 3), d && (c = new b.Float32BufferAttribute(h.count * 3, 3)));
4229
+ a || (a = new b.Float32BufferAttribute(h.count * 3, 3), d && (u = new b.Float32BufferAttribute(h.count * 3, 3)));
4230
4230
  for (let g = 0; g < h.count; g++) {
4231
- const R = a.getX(g) + h.getX(g) * u, x = a.getY(g) + h.getY(g) * u, S = a.getZ(g) + h.getZ(g) * u;
4232
- a.setXYZ(g, R, x, S);
4231
+ const R = a.getX(g) + h.getX(g) * c, x = a.getY(g) + h.getY(g) * c, k = a.getZ(g) + h.getZ(g) * c;
4232
+ a.setXYZ(g, R, x, k);
4233
4233
  }
4234
4234
  if (d)
4235
4235
  for (let g = 0; g < h.count; g++) {
4236
- const R = c.getX(g) + d.getX(g) * u, x = c.getY(g) + d.getY(g) * u, S = c.getZ(g) + d.getZ(g) * u;
4237
- c.setXYZ(g, R, x, S);
4236
+ const R = u.getX(g) + d.getX(g) * c, x = u.getY(g) + d.getY(g) * c, k = u.getZ(g) + d.getZ(g) * c;
4237
+ u.setXYZ(g, R, x, k);
4238
4238
  }
4239
4239
  }
4240
4240
  if (a) {
4241
- i.morphAttributes.position.push(a), c && i.morphAttributes.normal.push(c);
4241
+ i.morphAttributes.position.push(a), u && i.morphAttributes.normal.push(u);
4242
4242
  const l = i.morphAttributes.position.length - 1;
4243
4243
  s.morphTargetInfluences[l] = 0, s.morphTargetDictionary[e] = l;
4244
4244
  }
@@ -4268,7 +4268,7 @@ class nt {
4268
4268
  throw new Error("Blend shapes not found");
4269
4269
  const i = new Set(this.mtCustoms);
4270
4270
  this.morphs.forEach((l) => {
4271
- Object.keys(l.morphTargetDictionary).forEach((u) => i.add(u));
4271
+ Object.keys(l.morphTargetDictionary).forEach((c) => i.add(c));
4272
4272
  }), this.mtExtras.forEach((l) => {
4273
4273
  i.has(l.key) || (this.addMixedMorphTarget(this.morphs, l.key, l.mix), i.add(l.key));
4274
4274
  });
@@ -4295,16 +4295,16 @@ class nt {
4295
4295
  ms: [],
4296
4296
  is: []
4297
4297
  }, a[l].value = a[l].baseline, a[l].applied = a[l].baseline;
4298
- const u = this.mtAvatar[l];
4299
- u && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((r) => {
4300
- a[l][r] = u[r];
4298
+ const c = this.mtAvatar[l];
4299
+ c && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((r) => {
4300
+ a[l][r] = c[r];
4301
4301
  }), this.morphs.forEach((r) => {
4302
4302
  const h = r.morphTargetDictionary[l];
4303
4303
  h !== void 0 && (a[l].ms.push(r.morphTargetInfluences), a[l].is.push(h), r.morphTargetInfluences[h] = a[l].applied);
4304
4304
  });
4305
4305
  }), this.mtAvatar = a, this.poseAvatar = { props: {} }, this.posePropNames.forEach((l) => {
4306
- const u = l.split("."), r = this.armature.getObjectByName(u[0]);
4307
- this.poseAvatar.props[l] = r[u[1]], this.poseBase.props.hasOwnProperty(l) ? this.poseAvatar.props[l].copy(this.poseBase.props[l]) : this.poseBase.props[l] = this.poseAvatar.props[l].clone(), this.poseDelta.props.hasOwnProperty(l) && !this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l] = this.poseAvatar.props[l].clone()), this.poseTarget.props[l].t = this.animClock, this.poseTarget.props[l].d = 2e3;
4306
+ const c = l.split("."), r = this.armature.getObjectByName(c[0]);
4307
+ this.poseAvatar.props[l] = r[c[1]], this.poseBase.props.hasOwnProperty(l) ? this.poseAvatar.props[l].copy(this.poseBase.props[l]) : this.poseBase.props[l] = this.poseAvatar.props[l].clone(), this.poseDelta.props.hasOwnProperty(l) && !this.poseTarget.props.hasOwnProperty(l) && (this.poseTarget.props[l] = this.poseAvatar.props[l].clone()), this.poseTarget.props[l].t = this.animClock, this.poseTarget.props[l].d = 2e3;
4308
4308
  }), this.ikMesh.traverse((l) => {
4309
4309
  l.isBone && l.position.copy(this.armature.getObjectByName(l.name).position);
4310
4310
  }), this.isAvatarOnly ? this.scene && this.scene.add(this.armature) : (this.scene.add(o.scene), this.scene.add(this.lightAmbient), this.scene.add(this.lightDirect), this.scene.add(this.lightSpot), this.lightSpot.target = this.armature.getObjectByName("Head")), n.hasOwnProperty("modelDynamicBones"))
@@ -4314,8 +4314,8 @@ class nt {
4314
4314
  console.error("Dynamic bones setup failed: " + l);
4315
4315
  }
4316
4316
  this.objectLeftToeBase = this.armature.getObjectByName("LeftToeBase"), this.objectRightToeBase = this.armature.getObjectByName("RightToeBase"), this.objectLeftEye = this.armature.getObjectByName("LeftEye"), this.objectRightEye = this.armature.getObjectByName("RightEye"), this.objectLeftArm = this.armature.getObjectByName("LeftArm"), this.objectRightArm = this.armature.getObjectByName("RightArm"), this.objectHips = this.armature.getObjectByName("Hips"), this.objectHead = this.armature.getObjectByName("Head"), this.objectNeck = this.armature.getObjectByName("Neck");
4317
- const c = new b.Vector3();
4318
- this.objectLeftEye.getWorldPosition(c), this.avatarHeight = c.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.avatar.body === "M" && this.poseTemplates.wide && (this.poseName = "wide", this.setPoseFromTemplate(this.poseTemplates.wide, 0)), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
4317
+ const u = new b.Vector3();
4318
+ this.objectLeftEye.getWorldPosition(u), this.avatarHeight = u.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.avatar.body === "M" && this.poseTemplates.wide && (this.poseName = "wide", this.setPoseFromTemplate(this.poseTemplates.wide, 0)), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
4319
4319
  }
4320
4320
  /**
4321
4321
  * Get view names.
@@ -4343,22 +4343,22 @@ class nt {
4343
4343
  return;
4344
4344
  }
4345
4345
  if (this.viewName = n || this.viewName, e = e || {}, this.isAvatarOnly) return;
4346
- const t = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, o = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, i = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, a = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY, c = this.camera.fov * (Math.PI / 180);
4347
- let l = -t * Math.tan(c / 2), u = (1 - o) * Math.tan(c / 2), r = s;
4346
+ const t = e.hasOwnProperty("cameraX") ? e.cameraX : this.opt.cameraX, o = e.hasOwnProperty("cameraY") ? e.cameraY : this.opt.cameraY, s = e.hasOwnProperty("cameraDistance") ? e.cameraDistance : this.opt.cameraDistance, i = e.hasOwnProperty("cameraRotateX") ? e.cameraRotateX : this.opt.cameraRotateX, a = e.hasOwnProperty("cameraRotateY") ? e.cameraRotateY : this.opt.cameraRotateY, u = this.camera.fov * (Math.PI / 180);
4347
+ let l = -t * Math.tan(u / 2), c = (1 - o) * Math.tan(u / 2), r = s;
4348
4348
  switch (this.viewName) {
4349
4349
  case "head":
4350
- r += 2, u = u * r + 4 * this.avatarHeight / 5;
4350
+ r += 2, c = c * r + 4 * this.avatarHeight / 5;
4351
4351
  break;
4352
4352
  case "upper":
4353
- r += 4.5, u = u * r + 2 * this.avatarHeight / 3;
4353
+ r += 4.5, c = c * r + 2 * this.avatarHeight / 3;
4354
4354
  break;
4355
4355
  case "mid":
4356
- r += 8, u = u * r + this.avatarHeight / 3;
4356
+ r += 8, c = c * r + this.avatarHeight / 3;
4357
4357
  break;
4358
4358
  default:
4359
- r += 12, u = u * r;
4359
+ r += 12, c = c * r;
4360
4360
  }
4361
- l = l * r, this.controlsEnd = new b.Vector3(l, u, 0), this.cameraEnd = new b.Vector3(l, u, r).applyEuler(new b.Euler(i, a, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
4361
+ l = l * r, this.controlsEnd = new b.Vector3(l, c, 0), this.cameraEnd = new b.Vector3(l, c, r).applyEuler(new b.Euler(i, a, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
4362
4362
  }
4363
4363
  /**
4364
4364
  * Change light colors and intensities.
@@ -4414,7 +4414,7 @@ class nt {
4414
4414
  if (e.x === 0 && e.y === 0 && e.z === 0) continue;
4415
4415
  oe.set(e.x, e.y, e.z);
4416
4416
  const t = this.poseAvatar.props[n];
4417
- t.isQuaternion ? (ce.setFromEuler(oe), t.multiply(ce)) : t.isVector3 && t.add(oe);
4417
+ t.isQuaternion ? (ue.setFromEuler(oe), t.multiply(ue)) : t.isVector3 && t.add(oe);
4418
4418
  }
4419
4419
  }
4420
4420
  /**
@@ -4469,17 +4469,17 @@ class nt {
4469
4469
  "HandMiddle",
4470
4470
  "HandRing",
4471
4471
  "HandPinky"
4472
- ].forEach((u, r) => {
4473
- r === 0 ? (this.poseDelta.props[i + u + "1.quaternion"].x = 0, this.poseDelta.props[i + u + "2.quaternion"].z = (i === "Left" ? -1 : 1) * t.applied, this.poseDelta.props[i + u + "3.quaternion"].z = (i === "Left" ? -1 : 1) * t.applied) : (this.poseDelta.props[i + u + "1.quaternion"].x = t.applied, this.poseDelta.props[i + u + "2.quaternion"].x = 1.5 * t.applied, this.poseDelta.props[i + u + "3.quaternion"].x = 1.5 * t.applied);
4472
+ ].forEach((c, r) => {
4473
+ r === 0 ? (this.poseDelta.props[i + c + "1.quaternion"].x = 0, this.poseDelta.props[i + c + "2.quaternion"].z = (i === "Left" ? -1 : 1) * t.applied, this.poseDelta.props[i + c + "3.quaternion"].z = (i === "Left" ? -1 : 1) * t.applied) : (this.poseDelta.props[i + c + "1.quaternion"].x = t.applied, this.poseDelta.props[i + c + "2.quaternion"].x = 1.5 * t.applied, this.poseDelta.props[i + c + "3.quaternion"].x = 1.5 * t.applied);
4474
4474
  });
4475
4475
  break;
4476
4476
  case "chestInhale":
4477
- const a = t.applied / 20, c = { x: a, y: a / 2, z: 3 * a }, l = { x: 1 / (1 + a) - 1, y: 1 / (1 + a / 2) - 1, z: 1 / (1 + 3 * a) - 1 };
4478
- this.poseDelta.props["Spine1.scale"] = c, this.poseDelta.props["Neck.scale"] = l, this.poseDelta.props["LeftArm.scale"] = l, this.poseDelta.props["RightArm.scale"] = l;
4477
+ const a = t.applied / 20, u = { x: a, y: a / 2, z: 3 * a }, l = { x: 1 / (1 + a) - 1, y: 1 / (1 + a / 2) - 1, z: 1 / (1 + 3 * a) - 1 };
4478
+ this.poseDelta.props["Spine1.scale"] = u, this.poseDelta.props["Neck.scale"] = l, this.poseDelta.props["LeftArm.scale"] = l, this.poseDelta.props["RightArm.scale"] = l;
4479
4479
  break;
4480
4480
  default:
4481
- for (let u = 0, r = t.ms.length; u < r; u++)
4482
- t.ms[u][t.is[u]] = t.applied;
4481
+ for (let c = 0, r = t.ms.length; c < r; c++)
4482
+ t.ms[c][t.is[c]] = t.applied;
4483
4483
  }
4484
4484
  }
4485
4485
  }
@@ -4494,8 +4494,8 @@ class nt {
4494
4494
  return Object.entries(n).forEach((o, s) => {
4495
4495
  const i = o[0].split(".");
4496
4496
  if (i[1] === "position" || i[1] === "rotation" || i[1] === "quaternion") {
4497
- const a = i[1] === "quaternion" ? i[0] + ".rotation" : o[0], c = o[1].isQuaternion ? new b.Euler().setFromQuaternion(o[1]) : o[1];
4498
- t += (s ? ", " : "") + "'" + a + "':{", t += "x:" + Math.round(c.x * e) / e, t += ", y:" + Math.round(c.y * e) / e, t += ", z:" + Math.round(c.z * e) / e, t += "}";
4497
+ const a = i[1] === "quaternion" ? i[0] + ".rotation" : o[0], u = o[1].isQuaternion ? new b.Euler().setFromQuaternion(o[1]) : o[1];
4498
+ t += (s ? ", " : "") + "'" + a + "':{", t += "x:" + Math.round(u.x * e) / e, t += ", y:" + Math.round(u.y * e) / e, t += ", z:" + Math.round(u.z * e) / e, t += "}";
4499
4499
  }
4500
4500
  }), t += "}", t;
4501
4501
  }
@@ -4565,8 +4565,8 @@ class nt {
4565
4565
  if (t ? (this.poseCurrentTemplate = this.poseTemplates.oneknee, setTimeout(() => {
4566
4566
  this.setPoseFromTemplate(n, e);
4567
4567
  }, i)) : this.poseCurrentTemplate = n || this.poseCurrentTemplate, this.poseTarget = this.poseFactory(this.poseCurrentTemplate, i), this.poseWeightOnLeft = !0, (!o && !s || o && s) && (this.poseTarget.props = this.mirrorPose(this.poseTarget.props), this.poseWeightOnLeft = !this.poseWeightOnLeft), this.gesture)
4568
- for (let [a, c] of Object.entries(this.gesture))
4569
- this.poseTarget.props.hasOwnProperty(a) && (this.poseTarget.props[a].copy(c), this.poseTarget.props[a].t = c.t, this.poseTarget.props[a].d = c.d);
4568
+ for (let [a, u] of Object.entries(this.gesture))
4569
+ this.poseTarget.props.hasOwnProperty(a) && (this.poseTarget.props[a].copy(u), this.poseTarget.props[a].t = u.t, this.poseTarget.props[a].d = u.d);
4570
4570
  Object.keys(this.poseDelta.props).forEach((a) => {
4571
4571
  this.poseTarget.props.hasOwnProperty(a) || (this.poseTarget.props[a] = this.poseBase.props[a].clone(), this.poseTarget.props[a].t = this.animClock, this.poseTarget.props[a].d = i);
4572
4572
  });
@@ -4992,11 +4992,11 @@ class nt {
4992
4992
  else if (a.hasOwnProperty("alt")) {
4993
4993
  let l = a.alt[0];
4994
4994
  if (a.alt.length > 1) {
4995
- const u = Math.random();
4995
+ const c = Math.random();
4996
4996
  let r = 0;
4997
4997
  for (let h = 0; h < a.alt.length; h++) {
4998
4998
  let d = this.valueFn(a.alt[h].p);
4999
- if (r += d === void 0 ? (1 - r) / (a.alt.length - 1 - h) : d, u < r) {
4999
+ if (r += d === void 0 ? (1 - r) / (a.alt.length - 1 - h) : d, c < r) {
5000
5000
  l = a.alt[h];
5001
5001
  break;
5002
5002
  }
@@ -5006,19 +5006,19 @@ class nt {
5006
5006
  continue;
5007
5007
  } else
5008
5008
  break;
5009
- let c = this.valueFn(a.delay) || 0;
5010
- if (Array.isArray(c) && (c = this.gaussianRandom(...c)), a.hasOwnProperty("dt"))
5011
- a.dt.forEach((l, u) => {
5009
+ let u = this.valueFn(a.delay) || 0;
5010
+ if (Array.isArray(u) && (u = this.gaussianRandom(...u)), a.hasOwnProperty("dt"))
5011
+ a.dt.forEach((l, c) => {
5012
5012
  let r = this.valueFn(l);
5013
- Array.isArray(r) && (r = this.gaussianRandom(...r)), i.ts[u + 1] = i.ts[u] + r;
5013
+ Array.isArray(r) && (r = this.gaussianRandom(...r)), i.ts[c + 1] = i.ts[c] + r;
5014
5014
  });
5015
5015
  else {
5016
- let l = Object.values(a.vs).reduce((u, r) => r.length > u ? r.length : u, 0);
5016
+ let l = Object.values(a.vs).reduce((c, r) => r.length > c ? r.length : c, 0);
5017
5017
  i.ts = Array(l + 1).fill(0);
5018
5018
  }
5019
- s ? i.ts = i.ts.map((l) => c + l * t) : i.ts = i.ts.map((l) => this.animClock + c + l * t), a.vs && a.vs.pose;
5020
- for (let [l, u] of Object.entries(a.vs)) {
5021
- const r = this.getBaselineValue(l), h = u.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? l === "pose" && this.avatar && this.avatar.body === "M" && (d === "hip" || d === "side") ? "wide" : d.slice() : Array.isArray(d) ? l === "gesture" ? d.slice() : (r === void 0 ? 0 : r) + o * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (r === void 0 ? 0 : r) + o * d));
5019
+ s ? i.ts = i.ts.map((l) => u + l * t) : i.ts = i.ts.map((l) => this.animClock + u + l * t), a.vs && a.vs.pose;
5020
+ for (let [l, c] of Object.entries(a.vs)) {
5021
+ const r = this.getBaselineValue(l), h = c.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? l === "pose" && this.avatar && this.avatar.body === "M" && (d === "hip" || d === "side") ? "wide" : d.slice() : Array.isArray(d) ? l === "gesture" ? d.slice() : (r === void 0 ? 0 : r) + o * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (r === void 0 ? 0 : r) + o * d));
5022
5022
  l === "eyesRotateY" ? (i.vs.eyeLookOutLeft = [null, ...h.map((d) => d > 0 ? d : 0)], i.vs.eyeLookInLeft = [null, ...h.map((d) => d > 0 ? 0 : -d)], i.vs.eyeLookOutRight = [null, ...h.map((d) => d > 0 ? 0 : -d)], i.vs.eyeLookInRight = [null, ...h.map((d) => d > 0 ? d : 0)]) : l === "eyesRotateX" ? (i.vs.eyesLookDown = [null, ...h.map((d) => d > 0 ? d : 0)], i.vs.eyesLookUp = [null, ...h.map((d) => d > 0 ? 0 : -d)]) : i.vs[l] = [null, ...h];
5023
5023
  }
5024
5024
  for (let l of Object.keys(i.vs))
@@ -5100,8 +5100,8 @@ class nt {
5100
5100
  if (this.isSpeaking)
5101
5101
  for (a = 0, this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData), t = 2, s = 10; t < s; t++)
5102
5102
  this.volumeFrequencyData[t] > a && (a = this.volumeFrequencyData[t]);
5103
- let c = null, l = null;
5104
- const u = [];
5103
+ let u = null, l = null;
5104
+ const c = [];
5105
5105
  for (t = 0, s = this.animQueue.length; t < s; t++) {
5106
5106
  const r = this.animQueue[t];
5107
5107
  if (!(!r || !r.ts || !r.ts.length || this.animClock < r.ts[0])) {
@@ -5128,12 +5128,12 @@ class nt {
5128
5128
  g.newvalue *= 1 + a / 255 - 0.5;
5129
5129
  }
5130
5130
  g.needsUpdate = !0;
5131
- } else h === "eyeContact" && d[o] !== null && c !== !1 ? c = !!d[o] : h === "headMove" && d[o] !== null && l !== !1 ? d[o] === 0 ? l = !1 : (Math.random() < d[o] && (l = !0), d[o] = null) : d[o] !== null && (u.push({ mt: h, val: d[o] }), d[o] = null);
5131
+ } else h === "eyeContact" && d[o] !== null && u !== !1 ? u = !!d[o] : h === "headMove" && d[o] !== null && l !== !1 ? d[o] === 0 ? l = !1 : (Math.random() < d[o] && (l = !0), d[o] = null) : d[o] !== null && (c.push({ mt: h, val: d[o] }), d[o] = null);
5132
5132
  o === i ? (r.hasOwnProperty("mood") && this.setMood(r.mood), r.loop ? (i = this.isSpeaking && (r.template.name === "head" || r.template.name === "eyes") ? 4 : 1, this.animQueue[t] = this.animFactory(r.template, r.loop > 0 ? r.loop - 1 : r.loop, 1, 1 / i)) : (this.animQueue.splice(t--, 1), s--)) : r.ndx = o - 1;
5133
5133
  }
5134
5134
  }
5135
- for (let r = 0, h = u.length; r < h; r++)
5136
- switch (o = u[r].val, u[r].mt) {
5135
+ for (let r = 0, h = c.length; r < h; r++)
5136
+ switch (o = c[r].val, c[r].mt) {
5137
5137
  case "speak":
5138
5138
  this.speakText(o);
5139
5139
  break;
@@ -5179,7 +5179,7 @@ class nt {
5179
5179
  }, o.x ? new b.Vector3(o.x, o.y, o.z) : null, !0, o.d);
5180
5180
  break;
5181
5181
  }
5182
- if ((c || l) && (oe.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), oe.x = Math.max(-0.9, Math.min(0.9, 2 * oe.x - 0.5)), oe.y = Math.max(-0.9, Math.min(0.9, -2.5 * oe.y)), c ? (Object.assign(this.mtAvatar.eyesLookDown, { system: oe.x < 0 ? -oe.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: oe.x < 0 ? 0 : oe.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: oe.y < 0 ? -oe.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: oe.y < 0 ? 0 : oe.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: oe.y < 0 ? 0 : oe.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: oe.y < 0 ? -oe.y : 0, needsUpdate: !0 }), l && (t = -this.mtAvatar.bodyRotateY.value, o = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
5182
+ if ((u || l) && (oe.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), oe.x = Math.max(-0.9, Math.min(0.9, 2 * oe.x - 0.5)), oe.y = Math.max(-0.9, Math.min(0.9, -2.5 * oe.y)), u ? (Object.assign(this.mtAvatar.eyesLookDown, { system: oe.x < 0 ? -oe.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: oe.x < 0 ? 0 : oe.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: oe.y < 0 ? -oe.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: oe.y < 0 ? 0 : oe.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: oe.y < 0 ? 0 : oe.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: oe.y < 0 ? -oe.y : 0, needsUpdate: !0 }), l && (t = -this.mtAvatar.bodyRotateY.value, o = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
5183
5183
  name: "headmove",
5184
5184
  dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
5185
5185
  vs: {
@@ -5200,7 +5200,11 @@ class nt {
5200
5200
  eyeLookOutRight: [null, 0],
5201
5201
  eyeContact: [0]
5202
5202
  }
5203
- })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (t = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], o = this.mtAvatar[t], o.needsUpdate || Object.assign(o, { base: (this.mood.baseline[t] || 0) + (1 + a / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && c ? a > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = a) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), t = this.volumeHeadTarget - this.volumeHeadCurrent, o = Math.abs(t), o > 1e-4 && (i = o * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / o) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(t) * Math.min(o, i)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (ce.setFromAxisAngle(Ot, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(ce)), at.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(Ue), Ue.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Ze), Ze.sub(this.armature.position), this.objectHips.position.y -= at.min.y / 2, this.objectHips.position.x -= (Ue.x + Ze.x) / 4, this.objectHips.position.z -= (Ue.z + Ze.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
5203
+ })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (t = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], o = this.mtAvatar[t], o.needsUpdate || Object.assign(o, { base: (this.mood.baseline[t] || 0) + (1 + a / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && (this.mixer.update(e / 1e3 * this.mixer.timeScale), this.currentFBXActionForCallback && this.currentFBXActionForCallback.isRunning() && this.currentFBXActionClipDuration)) {
5204
+ const r = this.currentFBXActionForCallback.time, h = this.currentFBXActionClipDuration;
5205
+ (r >= h - 0.05 || r > 0 && !this.currentFBXActionForCallback.paused && r >= h - 0.1) && (this.currentFBXActionCallback && (this.currentFBXActionCallback(), this.currentFBXActionCallback = null), this.currentFBXActionForCallback = null, this.currentFBXActionStartTime = null, this.currentFBXActionClipDuration = null);
5206
+ }
5207
+ if (this.updatePoseDelta(), (this.isSpeaking || this.isListening) && u ? a > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = a) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), t = this.volumeHeadTarget - this.volumeHeadCurrent, o = Math.abs(t), o > 1e-4 && (i = o * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / o) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(t) * Math.min(o, i)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (ue.setFromAxisAngle(Bt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(ue)), at.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(Ue), Ue.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Xe), Xe.sub(this.armature.position), this.objectHips.position.y -= at.min.y / 2, this.objectHips.position.x -= (Ue.x + Xe.x) / 4, this.objectHips.position.z -= (Ue.z + Xe.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
5204
5208
  this.stats && this.stats.end();
5205
5209
  else {
5206
5210
  if (this.cameraClock !== null && this.cameraClock < 1e3) {
@@ -5267,24 +5271,24 @@ class nt {
5267
5271
  */
5268
5272
  speakText(n, e = null, t = null, o = null) {
5269
5273
  e = e || {};
5270
- const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, i = /[ ]/ug, a = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, c = /[\p{Extended_Pictographic}]/ug, l = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
5271
- let u = "", r = "", h = 0, d = [], g = [];
5274
+ const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, i = /[ ]/ug, a = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, u = /[\p{Extended_Pictographic}]/ug, l = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
5275
+ let c = "", r = "", h = 0, d = [], g = [];
5272
5276
  const R = Array.from(this.segmenter.segment(n), (x) => x.segment);
5273
5277
  for (let x = 0; x < R.length; x++) {
5274
- const S = x === R.length - 1, V = R[x].match(a);
5278
+ const k = x === R.length - 1, G = R[x].match(a);
5275
5279
  let m = R[x].match(s);
5276
- const D = R[x].match(c), F = R[x].match(i);
5277
- if (m && !S && !D && R[x + 1].match(s) && (m = !1), t && (u += R[x]), V && (!o || o.every((y) => x < y[0] || x > y[1])) && (r += R[x]), (F || m || S) && (r.length && (r = this.lipsyncPreProcessText(r, l), r.length && d.push({
5280
+ const D = R[x].match(u), E = R[x].match(i);
5281
+ if (m && !k && !D && R[x + 1].match(s) && (m = !1), t && (c += R[x]), G && (!o || o.every((y) => x < y[0] || x > y[1])) && (r += R[x]), (E || m || k) && (r.length && (r = this.lipsyncPreProcessText(r, l), r.length && d.push({
5278
5282
  mark: h,
5279
5283
  word: r
5280
- })), u.length && (g.push({
5284
+ })), c.length && (g.push({
5281
5285
  mark: h,
5282
5286
  template: { name: "subtitles" },
5283
5287
  ts: [0],
5284
5288
  vs: {
5285
- subtitles: [u]
5289
+ subtitles: [c]
5286
5290
  }
5287
- }), u = ""), r.length)) {
5291
+ }), c = ""), r.length)) {
5288
5292
  const y = this.lipsyncWordsToVisemes(r, l);
5289
5293
  if (y && y.visemes && y.visemes.length) {
5290
5294
  const P = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
@@ -5300,8 +5304,8 @@ class nt {
5300
5304
  }
5301
5305
  r = "", h++;
5302
5306
  }
5303
- if (m || S) {
5304
- if (d.length || S && g.length) {
5307
+ if (m || k) {
5308
+ if (d.length || k && g.length) {
5305
5309
  const y = {
5306
5310
  anim: g
5307
5311
  };
@@ -5390,25 +5394,25 @@ class nt {
5390
5394
  if (n.words) {
5391
5395
  let i = [];
5392
5396
  for (let a = 0; a < n.words.length; a++) {
5393
- const c = n.words[a], l = n.wtimes[a];
5394
- let u = n.wdurations[a];
5395
- if (c.length && (t && i.push({
5397
+ const u = n.words[a], l = n.wtimes[a];
5398
+ let c = n.wdurations[a];
5399
+ if (u.length && (t && i.push({
5396
5400
  template: { name: "subtitles" },
5397
5401
  ts: [l],
5398
5402
  vs: {
5399
- subtitles: [" " + c]
5403
+ subtitles: [" " + u]
5400
5404
  }
5401
5405
  }), !n.visemes)) {
5402
- const r = this.lipsyncPreProcessText(c, o), h = this.lipsyncWordsToVisemes(r, o);
5406
+ const r = this.lipsyncPreProcessText(u, o), h = this.lipsyncWordsToVisemes(r, o);
5403
5407
  if (h && h.visemes && h.visemes.length) {
5404
- const d = h.times[h.visemes.length - 1] + h.durations[h.visemes.length - 1], g = Math.min(u, Math.max(0, u - h.visemes.length * 150));
5405
- let R = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
5406
- if (u = Math.min(u, h.visemes.length * 200), d > 0)
5408
+ const d = h.times[h.visemes.length - 1] + h.durations[h.visemes.length - 1], g = Math.min(c, Math.max(0, c - h.visemes.length * 150));
5409
+ let R = 0.6 + this.convertRange(g, [0, c], [0, 0.4]);
5410
+ if (c = Math.min(c, h.visemes.length * 200), d > 0)
5407
5411
  for (let x = 0; x < h.visemes.length; x++) {
5408
- const S = l + h.times[x] / d * u, V = h.durations[x] / d * u;
5412
+ const k = l + h.times[x] / d * c, G = h.durations[x] / d * c;
5409
5413
  i.push({
5410
5414
  template: { name: "viseme" },
5411
- ts: [S - Math.min(60, 2 * V / 3), S + Math.min(25, V / 2), S + V + Math.min(60, V / 2)],
5415
+ ts: [k - Math.min(60, 2 * G / 3), k + Math.min(25, G / 2), k + G + Math.min(60, G / 2)],
5412
5416
  vs: {
5413
5417
  ["viseme_" + h.visemes[x]]: [null, h.visemes[x] === "PP" || h.visemes[x] === "FF" ? 0.9 : R, 0]
5414
5418
  }
@@ -5419,22 +5423,22 @@ class nt {
5419
5423
  }
5420
5424
  if (n.visemes)
5421
5425
  for (let a = 0; a < n.visemes.length; a++) {
5422
- const c = n.visemes[a], l = n.vtimes[a], u = n.vdurations[a];
5426
+ const u = n.visemes[a], l = n.vtimes[a], c = n.vdurations[a];
5423
5427
  i.push({
5424
5428
  template: { name: "viseme" },
5425
- ts: [l - 2 * u / 3, l + u / 2, l + u + u / 2],
5429
+ ts: [l - 2 * c / 3, l + c / 2, l + c + c / 2],
5426
5430
  vs: {
5427
- ["viseme_" + c]: [null, c === "PP" || c === "FF" ? 0.9 : 0.6, 0]
5431
+ ["viseme_" + u]: [null, u === "PP" || u === "FF" ? 0.9 : 0.6, 0]
5428
5432
  }
5429
5433
  });
5430
5434
  }
5431
5435
  if (n.markers)
5432
5436
  for (let a = 0; a < n.markers.length; a++) {
5433
- const c = n.markers[a], l = n.mtimes[a];
5437
+ const u = n.markers[a], l = n.mtimes[a];
5434
5438
  i.push({
5435
5439
  template: { name: "markers" },
5436
5440
  ts: [l],
5437
- vs: { function: [c] }
5441
+ vs: { function: [u] }
5438
5442
  });
5439
5443
  }
5440
5444
  i.length && (s.anim = i);
@@ -5460,7 +5464,7 @@ class nt {
5460
5464
  delay: e.delay || 0
5461
5465
  };
5462
5466
  if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
5463
- const s = this.audioCtx.resume(), i = new Promise((a, c) => setTimeout(() => c("p2"), 1e3));
5467
+ const s = this.audioCtx.resume(), i = new Promise((a, u) => setTimeout(() => u("p2"), 1e3));
5464
5468
  try {
5465
5469
  await Promise.race([s, i]);
5466
5470
  } catch {
@@ -5485,7 +5489,7 @@ class nt {
5485
5489
  template: i.template,
5486
5490
  // Trimmed timestamps are relative (ms), add base clock to make absolute
5487
5491
  // This ensures lip-sync continues from the exact resume point
5488
- ts: i.ts.map((c) => s + c),
5492
+ ts: i.ts.map((u) => s + u),
5489
5493
  vs: i.vs
5490
5494
  };
5491
5495
  this.animQueue.push(a);
@@ -5498,9 +5502,9 @@ class nt {
5498
5502
  if (this.audioPlaylist.length) {
5499
5503
  const t = this.audioPlaylist.shift();
5500
5504
  if (this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
5501
- const a = this.audioCtx.resume(), c = new Promise((l, u) => setTimeout(() => u("p2"), 1e3));
5505
+ const a = this.audioCtx.resume(), u = new Promise((l, c) => setTimeout(() => c("p2"), 1e3));
5502
5506
  try {
5503
- await Promise.race([a, c]);
5507
+ await Promise.race([a, u]);
5504
5508
  } catch {
5505
5509
  console.log("Can't play audio. Web Audio API suspended. This is often due to calling some speak method before the first user action, which is typically prevented by the browser."), this.playAudio(!0);
5506
5510
  return;
@@ -5525,8 +5529,8 @@ class nt {
5525
5529
  this.audioStartTime = this.audioCtx.currentTime + i, this.audioSpeechSource.addEventListener("ended", () => {
5526
5530
  this.audioSpeechSource.disconnect(), this.audioStartTime = null, this.currentAudioItem = null, this.isSpeaking = !0, this.playAudio(!0);
5527
5531
  }, { once: !0 }), t.anim && t.anim.forEach((a) => {
5528
- for (let c = 0; c < a.ts.length; c++)
5529
- a.ts[c] = this.animClock + a.ts[c] + s;
5532
+ for (let u = 0; u < a.ts.length; u++)
5533
+ a.ts[u] = this.animClock + a.ts[u] + s;
5530
5534
  this.animQueue.push(a);
5531
5535
  }), this.audioSpeechSource.start(i);
5532
5536
  } else
@@ -5539,29 +5543,29 @@ class nt {
5539
5543
  */
5540
5544
  async synthesizeWithBrowserTTS(n) {
5541
5545
  return new Promise((e, t) => {
5542
- const o = Array.isArray(n.text) ? n.text.map((m) => m.word).join(" ") : typeof n.text == "string" ? n.text : "", s = new SpeechSynthesisUtterance(o), i = n.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", a = (n.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, c = (n.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, l = (n.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
5543
- s.lang = i, s.rate = Math.max(0.1, Math.min(10, a)), s.pitch = Math.max(0, Math.min(2, c)), s.volume = Math.max(0, Math.min(1, l));
5544
- const u = speechSynthesis.getVoices(), r = n.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
5545
- if (r && u.length > 0) {
5546
- const m = u.find((D) => D.name.includes(r) || D.lang === i);
5546
+ const o = Array.isArray(n.text) ? n.text.map((m) => m.word).join(" ") : typeof n.text == "string" ? n.text : "", s = new SpeechSynthesisUtterance(o), i = n.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", a = (n.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, u = (n.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, l = (n.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
5547
+ s.lang = i, s.rate = Math.max(0.1, Math.min(10, a)), s.pitch = Math.max(0, Math.min(2, u)), s.volume = Math.max(0, Math.min(1, l));
5548
+ const c = speechSynthesis.getVoices(), r = n.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
5549
+ if (r && c.length > 0) {
5550
+ const m = c.find((D) => D.name.includes(r) || D.lang === i);
5547
5551
  m && (s.voice = m);
5548
5552
  }
5549
- const h = o.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (h / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", R = this.lipsyncPreProcessText(o, g), x = this.lipsyncWordsToVisemes(R, g), S = [];
5553
+ const h = o.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (h / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", R = this.lipsyncPreProcessText(o, g), x = this.lipsyncWordsToVisemes(R, g), k = [];
5550
5554
  if (x && x.visemes && x.visemes.length > 0) {
5551
5555
  const m = x.times[x.visemes.length - 1] + x.durations[x.visemes.length - 1];
5552
5556
  for (let D = 0; D < x.visemes.length; D++) {
5553
- const F = x.visemes[D], y = x.times[D] / m, P = x.durations[D] / m, L = y * h, f = P * h;
5554
- S.push({
5557
+ const E = x.visemes[D], y = x.times[D] / m, P = x.durations[D] / m, L = y * h, f = P * h;
5558
+ k.push({
5555
5559
  template: { name: "viseme" },
5556
5560
  ts: [L - Math.min(60, 2 * f / 3), L + Math.min(25, f / 2), L + f + Math.min(60, f / 2)],
5557
5561
  vs: {
5558
- ["viseme_" + F]: [null, F === "PP" || F === "FF" ? 0.9 : 0.6, 0]
5562
+ ["viseme_" + E]: [null, E === "PP" || E === "FF" ? 0.9 : 0.6, 0]
5559
5563
  }
5560
5564
  });
5561
5565
  }
5562
5566
  }
5563
- const V = [...n.anim, ...S];
5564
- this.audioPlaylist.push({ anim: V, audio: d }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio(), s.onend = () => {
5567
+ const G = [...n.anim, ...k];
5568
+ this.audioPlaylist.push({ anim: G, audio: d }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio(), s.onend = () => {
5565
5569
  e();
5566
5570
  }, s.onerror = (m) => {
5567
5571
  console.error("Speech synthesis error:", m.error), t(m.error);
@@ -5593,15 +5597,15 @@ class nt {
5593
5597
  });
5594
5598
  if (!s.ok)
5595
5599
  throw new Error(`ElevenLabs TTS error: ${s.status} ${s.statusText}`);
5596
- const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i), c = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
5600
+ const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i), u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
5597
5601
  let l;
5598
5602
  try {
5599
5603
  console.log("Lip-sync modules available:", {
5600
5604
  hasLipsync: !!this.lipsync,
5601
5605
  lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
5602
- lipsyncLang: c
5606
+ lipsyncLang: u
5603
5607
  });
5604
- const h = this.lipsyncPreProcessText(e, c), d = this.lipsyncWordsToVisemes(h, c);
5608
+ const h = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(h, u);
5605
5609
  if (console.log("Lip-sync data:", {
5606
5610
  processedText: h,
5607
5611
  lipsyncData: d,
@@ -5626,8 +5630,8 @@ class nt {
5626
5630
  const d = e.toLowerCase().split(/\s+/), g = [];
5627
5631
  for (const R of d)
5628
5632
  for (const x of R) {
5629
- let S = "aa";
5630
- "aeiou".includes(x) ? S = "aa" : "bp".includes(x) ? S = "PP" : "fv".includes(x) ? S = "FF" : "st".includes(x) ? S = "SS" : "dln".includes(x) ? S = "DD" : "kg".includes(x) ? S = "kk" : "rw".includes(x) && (S = "RR"), g.push(S);
5633
+ let k = "aa";
5634
+ "aeiou".includes(x) ? k = "aa" : "bp".includes(x) ? k = "PP" : "fv".includes(x) ? k = "FF" : "st".includes(x) ? k = "SS" : "dln".includes(x) ? k = "DD" : "kg".includes(x) ? k = "kk" : "rw".includes(x) && (k = "RR"), g.push(k);
5631
5635
  }
5632
5636
  l = {
5633
5637
  visemes: g.map((R, x) => ({
@@ -5642,11 +5646,11 @@ class nt {
5642
5646
  features: { onsets: [], boundaries: [] }
5643
5647
  };
5644
5648
  }
5645
- const u = [];
5649
+ const c = [];
5646
5650
  if (l.visemes && l.visemes.length > 0)
5647
5651
  for (let h = 0; h < l.visemes.length; h++) {
5648
5652
  const d = l.visemes[h], g = d.startTime * 1e3, R = d.duration * 1e3, x = d.intensity;
5649
- u.push({
5653
+ c.push({
5650
5654
  template: { name: "viseme" },
5651
5655
  ts: [g - Math.min(60, 2 * R / 3), g + Math.min(25, R / 2), g + R + Math.min(60, R / 2)],
5652
5656
  vs: {
@@ -5656,7 +5660,7 @@ class nt {
5656
5660
  }
5657
5661
  else
5658
5662
  console.warn("ElevenLabs: No visemes available for lip-sync animation");
5659
- const r = [...n.anim, ...u];
5663
+ const r = [...n.anim, ...c];
5660
5664
  this.audioPlaylist.push({ anim: r, audio: a }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio();
5661
5665
  }
5662
5666
  /**
@@ -5675,15 +5679,15 @@ class nt {
5675
5679
  });
5676
5680
  if (!s.ok)
5677
5681
  throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);
5678
- const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i), c = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
5682
+ const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i), u = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
5679
5683
  let l;
5680
5684
  try {
5681
5685
  console.log("Lip-sync modules available:", {
5682
5686
  hasLipsync: !!this.lipsync,
5683
5687
  lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
5684
- lipsyncLang: c
5688
+ lipsyncLang: u
5685
5689
  });
5686
- const h = this.lipsyncPreProcessText(e, c), d = this.lipsyncWordsToVisemes(h, c);
5690
+ const h = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(h, u);
5687
5691
  if (console.log("Lip-sync data:", {
5688
5692
  processedText: h,
5689
5693
  lipsyncData: d,
@@ -5708,8 +5712,8 @@ class nt {
5708
5712
  const d = e.toLowerCase().split(/\s+/), g = [];
5709
5713
  for (const R of d)
5710
5714
  for (const x of R) {
5711
- let S = "aa";
5712
- "aeiou".includes(x) ? S = "aa" : "bp".includes(x) ? S = "PP" : "fv".includes(x) ? S = "FF" : "st".includes(x) ? S = "SS" : "dln".includes(x) ? S = "DD" : "kg".includes(x) ? S = "kk" : "rw".includes(x) && (S = "RR"), g.push(S);
5715
+ let k = "aa";
5716
+ "aeiou".includes(x) ? k = "aa" : "bp".includes(x) ? k = "PP" : "fv".includes(x) ? k = "FF" : "st".includes(x) ? k = "SS" : "dln".includes(x) ? k = "DD" : "kg".includes(x) ? k = "kk" : "rw".includes(x) && (k = "RR"), g.push(k);
5713
5717
  }
5714
5718
  l = {
5715
5719
  visemes: g.map((R, x) => ({
@@ -5724,11 +5728,11 @@ class nt {
5724
5728
  features: { onsets: [], boundaries: [] }
5725
5729
  };
5726
5730
  }
5727
- const u = [];
5731
+ const c = [];
5728
5732
  if (l.visemes && l.visemes.length > 0)
5729
5733
  for (let h = 0; h < l.visemes.length; h++) {
5730
5734
  const d = l.visemes[h], g = d.startTime * 1e3, R = d.duration * 1e3, x = d.intensity;
5731
- u.push({
5735
+ c.push({
5732
5736
  template: { name: "viseme" },
5733
5737
  ts: [g - Math.min(60, 2 * R / 3), g + Math.min(25, R / 2), g + R + Math.min(60, R / 2)],
5734
5738
  vs: {
@@ -5738,7 +5742,7 @@ class nt {
5738
5742
  }
5739
5743
  else
5740
5744
  console.warn("Deepgram: No visemes available for lip-sync animation");
5741
- const r = [...n.anim, ...u];
5745
+ const r = [...n.anim, ...c];
5742
5746
  this.audioPlaylist.push({ anim: r, audio: a }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio();
5743
5747
  }
5744
5748
  /**
@@ -5763,9 +5767,9 @@ class nt {
5763
5767
  });
5764
5768
  if (!s.ok)
5765
5769
  throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);
5766
- const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i), c = await this.audioAnalyzer.analyzeAudio(a, e), l = [];
5767
- for (let r = 0; r < c.visemes.length; r++) {
5768
- const h = c.visemes[r], d = h.startTime * 1e3, g = h.duration * 1e3, R = h.intensity;
5770
+ const i = await s.arrayBuffer(), a = await this.audioCtx.decodeAudioData(i), u = await this.audioAnalyzer.analyzeAudio(a, e), l = [];
5771
+ for (let r = 0; r < u.visemes.length; r++) {
5772
+ const h = u.visemes[r], d = h.startTime * 1e3, g = h.duration * 1e3, R = h.intensity;
5769
5773
  l.push({
5770
5774
  template: { name: "viseme" },
5771
5775
  ts: [d - Math.min(60, 2 * g / 3), d + Math.min(25, g / 2), d + g + Math.min(60, g / 2)],
@@ -5774,8 +5778,8 @@ class nt {
5774
5778
  }
5775
5779
  });
5776
5780
  }
5777
- const u = [...n.anim, ...l];
5778
- this.audioPlaylist.push({ anim: u, audio: a }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio();
5781
+ const c = [...n.anim, ...l];
5782
+ this.audioPlaylist.push({ anim: c, audio: a }), this.onSubtitles = n.onSubtitles || null, this.resetLips(), n.mood && this.setMood(n.mood), this.playAudio();
5779
5783
  }
5780
5784
  /**
5781
5785
  * Synthesize speech using external TTS service (Google Cloud, etc.)
@@ -5814,24 +5818,24 @@ class nt {
5814
5818
  if (o.status === 200 && s && s.audioContent) {
5815
5819
  const i = this.b64ToArrayBuffer(s.audioContent), a = await this.audioCtx.decodeAudioData(i);
5816
5820
  this.speakWithHands();
5817
- const c = [0];
5821
+ const u = [0];
5818
5822
  let l = 0;
5819
5823
  n.text.forEach((h, d) => {
5820
5824
  if (d > 0) {
5821
- let g = c[c.length - 1];
5822
- s.timepoints[l] && (g = s.timepoints[l].timeSeconds * 1e3, s.timepoints[l].markName === "" + h.mark && l++), c.push(g);
5825
+ let g = u[u.length - 1];
5826
+ s.timepoints[l] && (g = s.timepoints[l].timeSeconds * 1e3, s.timepoints[l].markName === "" + h.mark && l++), u.push(g);
5823
5827
  }
5824
5828
  });
5825
- const u = [{ mark: 0, time: 0 }];
5826
- c.forEach((h, d) => {
5829
+ const c = [{ mark: 0, time: 0 }];
5830
+ u.forEach((h, d) => {
5827
5831
  if (d > 0) {
5828
- let g = h - c[d - 1];
5829
- u[d - 1].duration = g, u.push({ mark: d, time: h });
5832
+ let g = h - u[d - 1];
5833
+ c[d - 1].duration = g, c.push({ mark: d, time: h });
5830
5834
  }
5831
5835
  });
5832
5836
  let r = 1e3 * a.duration;
5833
- r > this.opt.ttsTrimEnd && (r = r - this.opt.ttsTrimEnd), u[u.length - 1].duration = r - u[u.length - 1].time, n.anim.forEach((h) => {
5834
- const d = u[h.mark];
5837
+ r > this.opt.ttsTrimEnd && (r = r - this.opt.ttsTrimEnd), c[c.length - 1].duration = r - c[c.length - 1].time, n.anim.forEach((h) => {
5838
+ const d = c[h.mark];
5835
5839
  if (d)
5836
5840
  for (let g = 0; g < h.ts.length; g++)
5837
5841
  h.ts[g] = d.time + h.ts[g] * d.duration + this.opt.ttsTrimStart;
@@ -5879,17 +5883,17 @@ class nt {
5879
5883
  let n = null;
5880
5884
  if (this.audioSpeechSource && this.currentAudioItem && this.audioStartTime !== null)
5881
5885
  try {
5882
- const e = this.audioCtx.currentTime, t = Math.max(0, e - this.audioStartTime), o = this.audioSpeechSource.playbackRate.value, s = t * o, i = this.currentAudioItem.audio, a = i.sampleRate, c = Math.floor(s * a);
5883
- if (c < i.length) {
5884
- const l = i.length - c, u = this.audioCtx.createBuffer(
5886
+ const e = this.audioCtx.currentTime, t = Math.max(0, e - this.audioStartTime), o = this.audioSpeechSource.playbackRate.value, s = t * o, i = this.currentAudioItem.audio, a = i.sampleRate, u = Math.floor(s * a);
5887
+ if (u < i.length) {
5888
+ const l = i.length - u, c = this.audioCtx.createBuffer(
5885
5889
  i.numberOfChannels,
5886
5890
  l,
5887
5891
  a
5888
5892
  );
5889
5893
  for (let h = 0; h < i.numberOfChannels; h++) {
5890
- const d = i.getChannelData(h), g = u.getChannelData(h);
5894
+ const d = i.getChannelData(h), g = c.getChannelData(h);
5891
5895
  for (let R = 0; R < l; R++)
5892
- g[R] = d[c + R];
5896
+ g[R] = d[u + R];
5893
5897
  }
5894
5898
  let r = null;
5895
5899
  if (this.currentAudioItem.anim) {
@@ -5900,18 +5904,18 @@ class nt {
5900
5904
  ts: [],
5901
5905
  vs: []
5902
5906
  };
5903
- for (let S = 0; S < R.ts.length; S++) {
5904
- const V = R.ts[S];
5905
- if (V > g) {
5906
- const m = V - g;
5907
- x.ts.push(m), x.vs.push(R.vs[S]);
5907
+ for (let k = 0; k < R.ts.length; k++) {
5908
+ const G = R.ts[k];
5909
+ if (G > g) {
5910
+ const m = G - g;
5911
+ x.ts.push(m), x.vs.push(R.vs[k]);
5908
5912
  }
5909
5913
  }
5910
5914
  return x.ts.length > 0 ? x : null;
5911
5915
  }).filter((R) => R !== null);
5912
5916
  }
5913
5917
  n = {
5914
- audio: u,
5918
+ audio: c,
5915
5919
  anim: r,
5916
5920
  text: this.currentAudioItem.text,
5917
5921
  delay: 0,
@@ -5963,10 +5967,10 @@ class nt {
5963
5967
  }
5964
5968
  if (!this.workletLoaded)
5965
5969
  try {
5966
- const a = this.audioCtx.audioWorklet.addModule(Pt.href), c = new Promise(
5967
- (l, u) => setTimeout(() => u(new Error("Worklet loading timed out")), 5e3)
5970
+ const a = this.audioCtx.audioWorklet.addModule(Pt.href), u = new Promise(
5971
+ (l, c) => setTimeout(() => c(new Error("Worklet loading timed out")), 5e3)
5968
5972
  );
5969
- await Promise.race([a, c]), this.workletLoaded = !0;
5973
+ await Promise.race([a, u]), this.workletLoaded = !0;
5970
5974
  } catch (a) {
5971
5975
  throw console.error("Failed to load audio worklet:", a), new Error("Failed to initialize streaming speech");
5972
5976
  }
@@ -5979,8 +5983,8 @@ class nt {
5979
5983
  if (a.data.type === "playback-started" && (this.isSpeaking = !0, this.stateName = "speaking", this.streamWaitForAudioChunks && (this.streamAudioStartTime = this.animClock), this._processStreamLipsyncQueue(), this.speakWithHands(), this.onAudioStart))
5980
5984
  try {
5981
5985
  this.onAudioStart?.();
5982
- } catch (c) {
5983
- console.error(c);
5986
+ } catch (u) {
5987
+ console.error(u);
5984
5988
  }
5985
5989
  if (a.data.type === "playback-ended" && (this._streamPause(), this.onAudioEnd))
5986
5990
  try {
@@ -6000,9 +6004,9 @@ class nt {
6000
6004
  } catch {
6001
6005
  }
6002
6006
  if (this.resetLips(), this.lookAtCamera(500), n.mood && this.setMood(n.mood), this.onSubtitles = o || null, this.audioCtx.state === "suspended" || this.audioCtx.state === "interrupted") {
6003
- const a = this.audioCtx.resume(), c = new Promise((l, u) => setTimeout(() => u("p2"), 1e3));
6007
+ const a = this.audioCtx.resume(), u = new Promise((l, c) => setTimeout(() => c("p2"), 1e3));
6004
6008
  try {
6005
- await Promise.race([a, c]);
6009
+ await Promise.race([a, u]);
6006
6010
  } catch {
6007
6011
  console.warn("Can't play audio. Web Audio API suspended. This is often due to calling some speak method before the first user action, which is typically prevented by the browser.");
6008
6012
  return;
@@ -6099,13 +6103,13 @@ class nt {
6099
6103
  subtitles: [" " + o]
6100
6104
  }
6101
6105
  }), this.streamLipsyncType == "words")) {
6102
- const a = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, c = this.lipsyncPreProcessText(o, a), l = this.lipsyncWordsToVisemes(c, a);
6106
+ const a = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, u = this.lipsyncPreProcessText(o, a), l = this.lipsyncWordsToVisemes(u, a);
6103
6107
  if (l && l.visemes && l.visemes.length) {
6104
- const u = l.times[l.visemes.length - 1] + l.durations[l.visemes.length - 1], r = Math.min(i, Math.max(0, i - l.visemes.length * 150));
6108
+ const c = l.times[l.visemes.length - 1] + l.durations[l.visemes.length - 1], r = Math.min(i, Math.max(0, i - l.visemes.length * 150));
6105
6109
  let h = 0.6 + this.convertRange(r, [0, i], [0, 0.4]);
6106
- if (i = Math.min(i, l.visemes.length * 200), u > 0)
6110
+ if (i = Math.min(i, l.visemes.length * 200), c > 0)
6107
6111
  for (let d = 0; d < l.visemes.length; d++) {
6108
- const g = e + s + l.times[d] / u * i, R = l.durations[d] / u * i;
6112
+ const g = e + s + l.times[d] / c * i, R = l.durations[d] / c * i;
6109
6113
  this.animQueue.push({
6110
6114
  template: { name: "viseme" },
6111
6115
  ts: [g - Math.min(60, 2 * R / 3), g + Math.min(25, R / 2), g + R + Math.min(60, R / 2)],
@@ -6201,7 +6205,7 @@ class nt {
6201
6205
  */
6202
6206
  lookAtCamera(n) {
6203
6207
  let e;
6204
- if (this.speakTo && (e = new b.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), Ue.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Ze.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(Ue, Ze).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
6208
+ if (this.speakTo && (e = new b.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), Ue.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Xe.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(Ue, Xe).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
6205
6209
  if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
6206
6210
  if (this.avatar.avatarIgnoreCamera) {
6207
6211
  this.lookAhead(n);
@@ -6214,14 +6218,14 @@ class nt {
6214
6218
  this.lookAt(null, null, n);
6215
6219
  return;
6216
6220
  }
6217
- this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), Ue.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Ze.setFromMatrixPosition(this.objectRightEye.matrixWorld), Ue.add(Ze).divideScalar(2), ce.copy(this.armature.quaternion), ce.multiply(this.poseTarget.props["Hips.quaternion"]), ce.multiply(this.poseTarget.props["Spine.quaternion"]), ce.multiply(this.poseTarget.props["Spine1.quaternion"]), ce.multiply(this.poseTarget.props["Spine2.quaternion"]), ce.multiply(this.poseTarget.props["Neck.quaternion"]), ce.multiply(this.poseTarget.props["Head.quaternion"]);
6221
+ this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), Ue.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Xe.setFromMatrixPosition(this.objectRightEye.matrixWorld), Ue.add(Xe).divideScalar(2), ue.copy(this.armature.quaternion), ue.multiply(this.poseTarget.props["Hips.quaternion"]), ue.multiply(this.poseTarget.props["Spine.quaternion"]), ue.multiply(this.poseTarget.props["Spine1.quaternion"]), ue.multiply(this.poseTarget.props["Spine2.quaternion"]), ue.multiply(this.poseTarget.props["Neck.quaternion"]), ue.multiply(this.poseTarget.props["Head.quaternion"]);
6218
6222
  const t = new b.Vector3().subVectors(e, Ue).normalize(), o = Math.atan2(t.x, t.z), s = Math.asin(-t.y);
6219
6223
  oe.set(s, o, 0, "YXZ");
6220
- const a = new b.Quaternion().setFromEuler(oe), c = new b.Quaternion().copy(a).multiply(ce.clone().invert());
6221
- oe.setFromQuaternion(c, "YXZ");
6222
- let l = oe.x / (40 / 24) + 0.2, u = oe.y / (9 / 4), r = Math.min(0.6, Math.max(-0.3, l)), h = Math.min(0.8, Math.max(-0.8, u)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6224
+ const a = new b.Quaternion().setFromEuler(oe), u = new b.Quaternion().copy(a).multiply(ue.clone().invert());
6225
+ oe.setFromQuaternion(u, "YXZ");
6226
+ let l = oe.x / (40 / 24) + 0.2, c = oe.y / (9 / 4), r = Math.min(0.6, Math.max(-0.3, l)), h = Math.min(0.8, Math.max(-0.8, c)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6223
6227
  if (n) {
6224
- let R = this.animQueue.findIndex((S) => S.template.name === "lookat");
6228
+ let R = this.animQueue.findIndex((k) => k.template.name === "lookat");
6225
6229
  R !== -1 && this.animQueue.splice(R, 1);
6226
6230
  const x = {
6227
6231
  name: "lookat",
@@ -6253,21 +6257,21 @@ class nt {
6253
6257
  this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
6254
6258
  const s = new b.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), i = new b.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), a = new b.Vector3().addVectors(s, i).divideScalar(2);
6255
6259
  a.project(this.camera);
6256
- let c = (a.x + 1) / 2 * o.width + o.left, l = -(a.y - 1) / 2 * o.height + o.top;
6257
- n === null && (n = c), e === null && (e = l), ce.copy(this.armature.quaternion), ce.multiply(this.poseTarget.props["Hips.quaternion"]), ce.multiply(this.poseTarget.props["Spine.quaternion"]), ce.multiply(this.poseTarget.props["Spine1.quaternion"]), ce.multiply(this.poseTarget.props["Spine2.quaternion"]), ce.multiply(this.poseTarget.props["Neck.quaternion"]), ce.multiply(this.poseTarget.props["Head.quaternion"]), oe.setFromQuaternion(ce);
6258
- let u = oe.x / (40 / 24), r = oe.y / (9 / 4), h = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - c, c), R = Math.max(window.innerHeight - l, l), x = this.convertRange(e, [l - R, l + R], [-0.3, 0.6]) - u + h, S = this.convertRange(n, [c - g, c + g], [-0.8, 0.8]) - r + d;
6259
- x = Math.min(0.6, Math.max(-0.3, x)), S = Math.min(0.8, Math.max(-0.8, S));
6260
- let V = (Math.random() - 0.5) / 4, m = (Math.random() - 0.5) / 4;
6260
+ let u = (a.x + 1) / 2 * o.width + o.left, l = -(a.y - 1) / 2 * o.height + o.top;
6261
+ n === null && (n = u), e === null && (e = l), ue.copy(this.armature.quaternion), ue.multiply(this.poseTarget.props["Hips.quaternion"]), ue.multiply(this.poseTarget.props["Spine.quaternion"]), ue.multiply(this.poseTarget.props["Spine1.quaternion"]), ue.multiply(this.poseTarget.props["Spine2.quaternion"]), ue.multiply(this.poseTarget.props["Neck.quaternion"]), ue.multiply(this.poseTarget.props["Head.quaternion"]), oe.setFromQuaternion(ue);
6262
+ let c = oe.x / (40 / 24), r = oe.y / (9 / 4), h = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - u, u), R = Math.max(window.innerHeight - l, l), x = this.convertRange(e, [l - R, l + R], [-0.3, 0.6]) - c + h, k = this.convertRange(n, [u - g, u + g], [-0.8, 0.8]) - r + d;
6263
+ x = Math.min(0.6, Math.max(-0.3, x)), k = Math.min(0.8, Math.max(-0.8, k));
6264
+ let G = (Math.random() - 0.5) / 4, m = (Math.random() - 0.5) / 4;
6261
6265
  if (t) {
6262
6266
  let D = this.animQueue.findIndex((y) => y.template.name === "lookat");
6263
6267
  D !== -1 && this.animQueue.splice(D, 1);
6264
- const F = {
6268
+ const E = {
6265
6269
  name: "lookat",
6266
6270
  dt: [750, t],
6267
6271
  vs: {
6268
- bodyRotateX: [x + V],
6269
- bodyRotateY: [S + m],
6270
- eyesRotateX: [-3 * V + 0.1],
6272
+ bodyRotateX: [x + G],
6273
+ bodyRotateY: [k + m],
6274
+ eyesRotateX: [-3 * G + 0.1],
6271
6275
  eyesRotateY: [-5 * m],
6272
6276
  browInnerUp: [[0, 0.7]],
6273
6277
  mouthLeft: [[0, 0.7]],
@@ -6276,7 +6280,7 @@ class nt {
6276
6280
  headMove: [0]
6277
6281
  }
6278
6282
  };
6279
- this.animQueue.push(this.animFactory(F));
6283
+ this.animQueue.push(this.animFactory(E));
6280
6284
  }
6281
6285
  }
6282
6286
  /**
@@ -6294,10 +6298,10 @@ class nt {
6294
6298
  s.setFromCamera(o, this.camera);
6295
6299
  const i = s.intersectObject(this.armature);
6296
6300
  if (i.length > 0) {
6297
- const a = i[0].point, c = new b.Vector3(), l = new b.Vector3();
6298
- this.objectLeftArm.getWorldPosition(c), this.objectRightArm.getWorldPosition(l);
6299
- const u = c.distanceToSquared(a), r = l.distanceToSquared(a);
6300
- u < r ? (this.ikSolve({
6301
+ const a = i[0].point, u = new b.Vector3(), l = new b.Vector3();
6302
+ this.objectLeftArm.getWorldPosition(u), this.objectRightArm.getWorldPosition(l);
6303
+ const c = u.distanceToSquared(a), r = l.distanceToSquared(a);
6304
+ c < r ? (this.ikSolve({
6301
6305
  iterations: 20,
6302
6306
  root: "LeftShoulder",
6303
6307
  effector: "LeftHandMiddle1",
@@ -6318,8 +6322,8 @@ class nt {
6318
6322
  }, a, !1, 1e3), this.setValue("handFistRight", 0));
6319
6323
  } else
6320
6324
  ["LeftArm", "LeftForeArm", "LeftHand", "RightArm", "RightForeArm", "RightHand"].forEach((a) => {
6321
- let c = a + ".quaternion";
6322
- this.poseTarget.props[c].copy(this.getPoseTemplateProp(c)), this.poseTarget.props[c].t = this.animClock, this.poseTarget.props[c].d = 1e3;
6325
+ let u = a + ".quaternion";
6326
+ this.poseTarget.props[u].copy(this.getPoseTemplateProp(u)), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = 1e3;
6323
6327
  });
6324
6328
  return i.length > 0;
6325
6329
  }
@@ -6438,26 +6442,24 @@ class nt {
6438
6442
  async playAnimation(n, e = null, t = 10, o = 0, s = 0.01, i = !1, a = null) {
6439
6443
  if (!this.armature) return;
6440
6444
  this.positionWasLocked = !i, i || this.lockAvatarPosition();
6441
- let c = this.animClips.find((l) => l.url === n + "-" + o);
6442
- if (c) {
6445
+ let u = this.animClips.find((l) => l.url === n + "-" + o);
6446
+ if (u) {
6443
6447
  let l = this.animQueue.find((h) => h.template.name === "pose");
6444
- l && (l.ts[0] = 1 / 0), Object.entries(c.pose.props).forEach((h) => {
6448
+ l && (l.ts[0] = 1 / 0), Object.entries(u.pose.props).forEach((h) => {
6445
6449
  this.poseBase.props[h[0]] = h[1].clone(), this.poseTarget.props[h[0]] = h[1].clone(), this.poseTarget.props[h[0]].t = 0, this.poseTarget.props[h[0]].d = 1e3;
6446
6450
  }), this.mixer || (this.mixer = new b.AnimationMixer(this.armature)), this.animationFinishedCallback = a;
6447
- const u = () => {
6451
+ const c = () => {
6448
6452
  this.animationFinishedCallback && (this.animationFinishedCallback(), this.animationFinishedCallback = null), this.stopAnimation();
6449
- };
6450
- this.mixer.addEventListener("finished", u, { once: !0 });
6451
- const r = this.mixer.clipAction(c.clip);
6453
+ }, r = this.mixer.clipAction(u.clip);
6452
6454
  if (t <= 0)
6453
6455
  r.setLoop(b.LoopOnce, 1);
6454
6456
  else {
6455
- const h = Math.ceil(t / c.clip.duration);
6457
+ const h = Math.ceil(t / u.clip.duration);
6456
6458
  r.setLoop(b.LoopRepeat, h);
6457
6459
  }
6458
- if (r.clampWhenFinished = !0, this.currentFBXAction && this.currentFBXAction.isRunning()) {
6460
+ if (r.clampWhenFinished = !0, this.mixer.addEventListener("finished", c, { once: !0 }), this.currentFBXActionForCallback = r, this.currentFBXActionCallback = c, this.currentFBXActionClipDuration = u.clip.duration, this.currentFBXActionStartTime = null, this.currentFBXAction && this.currentFBXAction.isRunning()) {
6459
6461
  this.currentFBXAction.fadeOut(0.3), setTimeout(() => {
6460
- this.currentFBXAction = r;
6462
+ this.currentFBXAction = r, this.currentFBXActionForCallback = r, this.currentFBXActionCallback = c, this.currentFBXActionClipDuration = u.clip.duration, this.currentFBXActionStartTime = this.mixer.time;
6461
6463
  try {
6462
6464
  r.fadeIn(0.5).play(), console.log("FBX animation started successfully (with fade transition):", n);
6463
6465
  } catch (h) {
@@ -6466,7 +6468,7 @@ class nt {
6466
6468
  }, 300);
6467
6469
  return;
6468
6470
  }
6469
- this.currentFBXAction = r;
6471
+ this.currentFBXAction = r, this.currentFBXActionStartTime = this.mixer.time;
6470
6472
  try {
6471
6473
  r.fadeIn(0.5).play(), console.log("FBX animation started successfully:", n);
6472
6474
  } catch (h) {
@@ -6482,10 +6484,10 @@ class nt {
6482
6484
  console.error(`Invalid file type for FBX animation: ${n}. Expected .fbx file.`);
6483
6485
  return;
6484
6486
  }
6485
- let u = !1;
6487
+ let c = !1;
6486
6488
  try {
6487
6489
  const d = await fetch(n, { method: "HEAD" });
6488
- if (u = d.ok, !u) {
6490
+ if (c = d.ok, !c) {
6489
6491
  console.error(`FBX file not found at ${n}. Status: ${d.status}`), console.error("Please check:"), console.error("1. File path is correct (note: path is case-sensitive)"), console.error("2. File exists in your public folder"), console.error("3. File is accessible (not blocked by server)");
6490
6492
  return;
6491
6493
  }
@@ -6591,38 +6593,38 @@ class nt {
6591
6593
  root: "Hips"
6592
6594
  };
6593
6595
  if (f[P]) {
6594
- const T = f[P];
6595
- if (g.has(T))
6596
- return T;
6596
+ const M = f[P];
6597
+ if (g.has(M))
6598
+ return M;
6597
6599
  }
6598
- for (const T of g)
6599
- if (T.toLowerCase() === L)
6600
- return T;
6601
- for (const T of g) {
6602
- const A = T.toLowerCase();
6603
- if ((L.includes("left") && A.includes("left") || L.includes("right") && A.includes("right")) && (L.includes("arm") && A.includes("arm") && !A.includes("fore") || L.includes("forearm") && A.includes("forearm") || L.includes("hand") && A.includes("hand") && !A.includes("index") && !A.includes("thumb") || L.includes("shoulder") && A.includes("shoulder")))
6604
- return T;
6600
+ for (const M of g)
6601
+ if (M.toLowerCase() === L)
6602
+ return M;
6603
+ for (const M of g) {
6604
+ const I = M.toLowerCase();
6605
+ if ((L.includes("left") && I.includes("left") || L.includes("right") && I.includes("right")) && (L.includes("arm") && I.includes("arm") && !I.includes("fore") || L.includes("forearm") && I.includes("forearm") || L.includes("hand") && I.includes("hand") && !I.includes("index") && !I.includes("thumb") || L.includes("shoulder") && I.includes("shoulder")))
6606
+ return M;
6605
6607
  }
6606
6608
  return null;
6607
- }, S = /* @__PURE__ */ new Set();
6609
+ }, k = /* @__PURE__ */ new Set();
6608
6610
  d.tracks.forEach((y) => {
6609
6611
  const P = y.name.split(".");
6610
- S.add(P[0]);
6611
- }), Array.from(S).filter(
6612
+ k.add(P[0]);
6613
+ }), Array.from(k).filter(
6612
6614
  (y) => y.toLowerCase().includes("arm") || y.toLowerCase().includes("hand") || y.toLowerCase().includes("shoulder")
6613
6615
  ), Array.from(g).filter(
6614
6616
  (y) => y.includes("Arm") || y.includes("Hand") || y.includes("Shoulder")
6615
6617
  );
6616
- const V = [], m = /* @__PURE__ */ new Set();
6618
+ const G = [], m = /* @__PURE__ */ new Set();
6617
6619
  d.tracks.forEach((y) => {
6618
- const L = y.name.replaceAll("mixamorig", "").split("."), f = L[0], T = L[1], A = x(f);
6619
- if (!(A && (A === "LeftShoulder" || A === "RightShoulder") && (T === "quaternion" || T === "rotation")))
6620
- if (A && T) {
6621
- const M = `${A}.${T}`, O = y.clone();
6622
- O.name = M, V.push(O), f !== A && R.set(f, A);
6620
+ const L = y.name.replaceAll("mixamorig", "").split("."), f = L[0], M = L[1], I = x(f);
6621
+ if (!(I && (I === "LeftShoulder" || I === "RightShoulder") && (M === "quaternion" || M === "rotation")))
6622
+ if (I && M) {
6623
+ const F = `${I}.${M}`, B = y.clone();
6624
+ B.name = F, G.push(B), f !== I && R.set(f, I);
6623
6625
  } else
6624
6626
  m.add(f), (f.toLowerCase().includes("arm") || f.toLowerCase().includes("hand") || f.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${f}" could not be mapped to avatar skeleton`);
6625
- }), V.length > 0 ? d = new b.AnimationClip(d.name, d.duration, V) : console.error("No tracks could be mapped! Animation may not work correctly.");
6627
+ }), G.length > 0 ? d = new b.AnimationClip(d.name, d.duration, G) : console.error("No tracks could be mapped! Animation may not work correctly.");
6626
6628
  const D = {};
6627
6629
  d.tracks.forEach((y) => {
6628
6630
  y.name = y.name.replaceAll("mixamorig", "");
@@ -6633,11 +6635,11 @@ class nt {
6633
6635
  D[y.name] = new b.Vector3(y.values[0], y.values[1], y.values[2]);
6634
6636
  } else P[1] === "quaternion" ? D[y.name] = new b.Quaternion(y.values[0], y.values[1], y.values[2], y.values[3]) : P[1] === "rotation" && (D[P[0] + ".quaternion"] = new b.Quaternion().setFromEuler(new b.Euler(y.values[0], y.values[1], y.values[2], "XYZ")).normalize());
6635
6637
  });
6636
- const F = { props: D };
6637
- D["Hips.position"] && (D["Hips.position"].y < 0.5 ? F.lying = !0 : F.standing = !0), this.animClips.push({
6638
+ const E = { props: D };
6639
+ D["Hips.position"] && (D["Hips.position"].y < 0.5 ? E.lying = !0 : E.standing = !0), this.animClips.push({
6638
6640
  url: n + "-" + o,
6639
6641
  clip: d,
6640
- pose: F
6642
+ pose: E
6641
6643
  }), this.playAnimation(n, e, t, o, s);
6642
6644
  } else {
6643
6645
  const d = "Animation " + n + " (ndx=" + o + ") not found";
@@ -6649,7 +6651,7 @@ class nt {
6649
6651
  * Stop running animations.
6650
6652
  */
6651
6653
  stopAnimation() {
6652
- if (this.currentFBXAction && (this.currentFBXAction.stop(), this.currentFBXAction = null), this.mixer && this.mixer._actions.length === 0 && (this.mixer = null), this.positionWasLocked && this.unlockAvatarPosition(), this.gesture)
6654
+ if (this.currentFBXAction && (this.currentFBXAction.stop(), this.currentFBXAction = null), this.currentFBXActionForCallback = null, this.currentFBXActionCallback = null, this.currentFBXActionStartTime = null, this.currentFBXActionClipDuration = null, this.mixer && this.mixer._actions.length === 0 && (this.mixer = null), this.positionWasLocked && this.unlockAvatarPosition(), this.gesture)
6653
6655
  for (let [e, t] of Object.entries(this.gesture))
6654
6656
  t.t = this.animClock, t.d = 1e3, this.poseTarget.props.hasOwnProperty(e) && (this.poseTarget.props[e].copy(t), this.poseTarget.props[e].t = this.animClock, this.poseTarget.props[e].d = 1e3);
6655
6657
  let n = this.animQueue.find((e) => e.template.name === "pose");
@@ -6667,25 +6669,25 @@ class nt {
6667
6669
  if (!this.armature) return;
6668
6670
  let i = this.poseTemplates[n];
6669
6671
  if (!i) {
6670
- const a = this.animPoses.find((c) => c.url === n + "-" + o);
6672
+ const a = this.animPoses.find((u) => u.url === n + "-" + o);
6671
6673
  a && (i = a.pose);
6672
6674
  }
6673
6675
  if (i) {
6674
6676
  this.poseName = n, this.mixer = null;
6675
- let a = this.animQueue.find((c) => c.template.name === "pose");
6677
+ let a = this.animQueue.find((u) => u.template.name === "pose");
6676
6678
  a && (a.ts[0] = this.animClock + t * 1e3 + 2e3), this.setPoseFromTemplate(i);
6677
6679
  } else {
6678
- let c = await new ot().loadAsync(n, e);
6679
- if (c && c.animations && c.animations[o]) {
6680
- let l = c.animations[o];
6681
- const u = {};
6680
+ let u = await new ot().loadAsync(n, e);
6681
+ if (u && u.animations && u.animations[o]) {
6682
+ let l = u.animations[o];
6683
+ const c = {};
6682
6684
  l.tracks.forEach((h) => {
6683
6685
  h.name = h.name.replaceAll("mixamorig", "");
6684
6686
  const d = h.name.split(".");
6685
- d[1] === "position" ? u[h.name] = new b.Vector3(h.values[0] * s, h.values[1] * s, h.values[2] * s) : d[1] === "quaternion" ? u[h.name] = new b.Quaternion(h.values[0], h.values[1], h.values[2], h.values[3]) : d[1] === "rotation" && (u[d[0] + ".quaternion"] = new b.Quaternion().setFromEuler(new b.Euler(h.values[0], h.values[1], h.values[2], "XYZ")).normalize());
6687
+ d[1] === "position" ? c[h.name] = new b.Vector3(h.values[0] * s, h.values[1] * s, h.values[2] * s) : d[1] === "quaternion" ? c[h.name] = new b.Quaternion(h.values[0], h.values[1], h.values[2], h.values[3]) : d[1] === "rotation" && (c[d[0] + ".quaternion"] = new b.Quaternion().setFromEuler(new b.Euler(h.values[0], h.values[1], h.values[2], "XYZ")).normalize());
6686
6688
  });
6687
- const r = { props: u };
6688
- u["Hips.position"] && (u["Hips.position"].y < 0.5 ? r.lying = !0 : r.standing = !0), this.animPoses.push({
6689
+ const r = { props: c };
6690
+ c["Hips.position"] && (c["Hips.position"].y < 0.5 ? r.lying = !0 : r.standing = !0), this.animPoses.push({
6689
6691
  url: n + "-" + o,
6690
6692
  pose: r
6691
6693
  }), this.playPose(n, e, t, o, s);
@@ -6714,10 +6716,10 @@ class nt {
6714
6716
  let s = this.gestureTemplates[n];
6715
6717
  if (s) {
6716
6718
  this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
6717
- let a = this.animQueue.findIndex((c) => c.template.name === "talkinghands");
6718
- a !== -1 && (this.animQueue[a].ts = this.animQueue[a].ts.map((c) => 0)), this.gesture = this.propsToThreeObjects(s), t && (this.gesture = this.mirrorPose(this.gesture)), n === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new b.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new b.Quaternion(0, 1, 0, 0), -0.25));
6719
- for (let [c, l] of Object.entries(this.gesture))
6720
- l.t = this.animClock, l.d = o, this.poseTarget.props.hasOwnProperty(c) && (this.poseTarget.props[c].copy(l), this.poseTarget.props[c].t = this.animClock, this.poseTarget.props[c].d = o);
6719
+ let a = this.animQueue.findIndex((u) => u.template.name === "talkinghands");
6720
+ a !== -1 && (this.animQueue[a].ts = this.animQueue[a].ts.map((u) => 0)), this.gesture = this.propsToThreeObjects(s), t && (this.gesture = this.mirrorPose(this.gesture)), n === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new b.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new b.Quaternion(0, 1, 0, 0), -0.25));
6721
+ for (let [u, l] of Object.entries(this.gesture))
6722
+ l.t = this.animClock, l.d = o, this.poseTarget.props.hasOwnProperty(u) && (this.poseTarget.props[u].copy(l), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = o);
6721
6723
  e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, o), 1e3 * e));
6722
6724
  }
6723
6725
  let i = this.animEmojis[n];
@@ -6725,15 +6727,15 @@ class nt {
6725
6727
  this.lookAtCamera(500);
6726
6728
  const a = this.animFactory(i);
6727
6729
  if (a.gesture = !0, e && Number.isFinite(e)) {
6728
- const c = a.ts[0], u = a.ts[a.ts.length - 1] - c;
6729
- if (e * 1e3 - u > 0) {
6730
+ const u = a.ts[0], c = a.ts[a.ts.length - 1] - u;
6731
+ if (e * 1e3 - c > 0) {
6730
6732
  const h = [];
6731
6733
  for (let R = 1; R < a.ts.length; R++) h.push(a.ts[R] - a.ts[R - 1]);
6732
- const d = i.template?.rescale || h.map((R) => R / u), g = e * 1e3 - u;
6733
- a.ts = a.ts.map((R, x, S) => x === 0 ? c : S[x - 1] + h[x - 1] + d[x - 1] * g);
6734
+ const d = i.template?.rescale || h.map((R) => R / c), g = e * 1e3 - c;
6735
+ a.ts = a.ts.map((R, x, k) => x === 0 ? u : k[x - 1] + h[x - 1] + d[x - 1] * g);
6734
6736
  } else {
6735
- const h = e * 1e3 / u;
6736
- a.ts = a.ts.map((d) => c + h * (d - c));
6737
+ const h = e * 1e3 / c;
6738
+ a.ts = a.ts.map((d) => u + h * (d - u));
6737
6739
  }
6738
6740
  }
6739
6741
  this.animQueue.push(a);
@@ -6763,21 +6765,21 @@ class nt {
6763
6765
  * @param {numeric} [d=null] If set, apply in d milliseconds
6764
6766
  */
6765
6767
  ikSolve(n, e = null, t = !1, o = null) {
6766
- const s = new b.Vector3(), i = new b.Vector3(), a = new b.Vector3(), c = new b.Vector3(), l = new b.Quaternion(), u = new b.Vector3(), r = new b.Vector3(), h = new b.Vector3(), d = this.ikMesh.getObjectByName(n.root);
6768
+ const s = new b.Vector3(), i = new b.Vector3(), a = new b.Vector3(), u = new b.Vector3(), l = new b.Quaternion(), c = new b.Vector3(), r = new b.Vector3(), h = new b.Vector3(), d = this.ikMesh.getObjectByName(n.root);
6767
6769
  d.position.setFromMatrixPosition(this.armature.getObjectByName(n.root).matrixWorld), d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(n.root).matrixWorld), e && t && e.applyQuaternion(this.armature.quaternion).add(d.position);
6768
6770
  const g = this.ikMesh.getObjectByName(n.effector), R = n.links;
6769
- R.forEach((S) => {
6770
- S.bone = this.ikMesh.getObjectByName(S.link), S.bone.quaternion.copy(this.getPoseTemplateProp(S.link + ".quaternion"));
6771
+ R.forEach((k) => {
6772
+ k.bone = this.ikMesh.getObjectByName(k.link), k.bone.quaternion.copy(this.getPoseTemplateProp(k.link + ".quaternion"));
6771
6773
  }), d.updateMatrixWorld(!0);
6772
6774
  const x = n.iterations || 10;
6773
6775
  if (e)
6774
- for (let S = 0; S < x; S++) {
6775
- let V = !1;
6776
+ for (let k = 0; k < x; k++) {
6777
+ let G = !1;
6776
6778
  for (let m = 0, D = R.length; m < D; m++) {
6777
- const F = R[m].bone;
6778
- F.matrixWorld.decompose(c, l, u), l.invert(), i.setFromMatrixPosition(g.matrixWorld), a.subVectors(i, c), a.applyQuaternion(l), a.normalize(), s.subVectors(e, c), s.applyQuaternion(l), s.normalize();
6779
+ const E = R[m].bone;
6780
+ E.matrixWorld.decompose(u, l, c), l.invert(), i.setFromMatrixPosition(g.matrixWorld), a.subVectors(i, u), a.applyQuaternion(l), a.normalize(), s.subVectors(e, u), s.applyQuaternion(l), s.normalize();
6779
6781
  let y = s.dot(a);
6780
- y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (R[m].minAngle !== void 0 && y < R[m].minAngle && (y = R[m].minAngle), R[m].maxAngle !== void 0 && y > R[m].maxAngle && (y = R[m].maxAngle), r.crossVectors(a, s), r.normalize(), ce.setFromAxisAngle(r, y), F.quaternion.multiply(ce), F.rotation.setFromVector3(h.setFromEuler(F.rotation).clamp(new b.Vector3(
6782
+ y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (R[m].minAngle !== void 0 && y < R[m].minAngle && (y = R[m].minAngle), R[m].maxAngle !== void 0 && y > R[m].maxAngle && (y = R[m].maxAngle), r.crossVectors(a, s), r.normalize(), ue.setFromAxisAngle(r, y), E.quaternion.multiply(ue), E.rotation.setFromVector3(h.setFromEuler(E.rotation).clamp(new b.Vector3(
6781
6783
  R[m].minx !== void 0 ? R[m].minx : -1 / 0,
6782
6784
  R[m].miny !== void 0 ? R[m].miny : -1 / 0,
6783
6785
  R[m].minz !== void 0 ? R[m].minz : -1 / 0
@@ -6785,12 +6787,12 @@ class nt {
6785
6787
  R[m].maxx !== void 0 ? R[m].maxx : 1 / 0,
6786
6788
  R[m].maxy !== void 0 ? R[m].maxy : 1 / 0,
6787
6789
  R[m].maxz !== void 0 ? R[m].maxz : 1 / 0
6788
- ))), F.updateMatrixWorld(!0), V = !0);
6790
+ ))), E.updateMatrixWorld(!0), G = !0);
6789
6791
  }
6790
- if (!V) break;
6792
+ if (!G) break;
6791
6793
  }
6792
- o && R.forEach((S) => {
6793
- this.poseTarget.props[S.link + ".quaternion"].copy(S.bone.quaternion), this.poseTarget.props[S.link + ".quaternion"].t = this.animClock, this.poseTarget.props[S.link + ".quaternion"].d = o;
6794
+ o && R.forEach((k) => {
6795
+ this.poseTarget.props[k.link + ".quaternion"].copy(k.bone.quaternion), this.poseTarget.props[k.link + ".quaternion"].t = this.animClock, this.poseTarget.props[k.link + ".quaternion"].d = o;
6794
6796
  });
6795
6797
  }
6796
6798
  /**
@@ -6800,7 +6802,7 @@ class nt {
6800
6802
  this.isRunning = !1, this.stop(), this.stopSpeaking(), this.streamStop(), this.isAvatarOnly ? this.armature && (this.armature.parent && this.armature.parent.remove(this.armature), this.clearThree(this.armature)) : (this.clearThree(this.scene), this.resizeobserver.disconnect(), this.renderer && (this.renderer.dispose(), this.renderer.domElement && this.renderer.domElement.parentNode && this.renderer.domElement.parentNode.removeChild(this.renderer.domElement), this.renderer = null)), this.clearThree(this.ikMesh), this.dynamicbones.dispose();
6801
6803
  }
6802
6804
  }
6803
- const Xe = {
6805
+ const Ze = {
6804
6806
  apiKey: "sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",
6805
6807
  // Replace with your actual API key (should start with sk_)
6806
6808
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
@@ -6843,10 +6845,10 @@ const Xe = {
6843
6845
  function $e() {
6844
6846
  return {
6845
6847
  service: "elevenlabs",
6846
- endpoint: Xe.endpoint,
6847
- apiKey: Xe.apiKey,
6848
- defaultVoice: Xe.defaultVoice,
6849
- voices: Xe.voices
6848
+ endpoint: Ze.endpoint,
6849
+ apiKey: Ze.apiKey,
6850
+ defaultVoice: Ze.defaultVoice,
6851
+ voices: Ze.voices
6850
6852
  };
6851
6853
  }
6852
6854
  function qt() {
@@ -6858,7 +6860,7 @@ function qt() {
6858
6860
  });
6859
6861
  }), n;
6860
6862
  }
6861
- const ut = Ke(({
6863
+ const ct = Ke(({
6862
6864
  avatarUrl: Z = "/avatars/brunette.glb",
6863
6865
  avatarBody: n = "F",
6864
6866
  mood: e = "neutral",
@@ -6867,9 +6869,9 @@ const ut = Ke(({
6867
6869
  ttsVoice: s = null,
6868
6870
  ttsApiKey: i = null,
6869
6871
  bodyMovement: a = "idle",
6870
- movementIntensity: c = 0.5,
6872
+ movementIntensity: u = 0.5,
6871
6873
  showFullAvatar: l = !0,
6872
- cameraView: u = "upper",
6874
+ cameraView: c = "upper",
6873
6875
  onReady: r = () => {
6874
6876
  },
6875
6877
  onLoading: h = () => {
@@ -6879,8 +6881,8 @@ const ut = Ke(({
6879
6881
  className: g = "",
6880
6882
  style: R = {},
6881
6883
  animations: x = {}
6882
- }, S) => {
6883
- const V = W(null), m = W(null), D = W(l), F = W(null), y = W(null), P = W(!1), L = W({ remainingText: null, originalText: null, options: null }), f = W([]), T = W(0), [A, M] = pe(!0), [O, Q] = pe(null), [_, Ie] = pe(!1), [me, Ee] = pe(!1);
6884
+ }, k) => {
6885
+ const G = V(null), m = V(null), D = V(l), E = V(null), y = V(null), P = V(!1), L = V({ remainingText: null, originalText: null, options: null }), f = V([]), M = V(0), [I, F] = pe(!0), [B, Q] = pe(null), [_, ve] = pe(!1), [me, Fe] = pe(!1);
6884
6886
  Se(() => {
6885
6887
  P.current = me;
6886
6888
  }, [me]), Se(() => {
@@ -6897,8 +6899,8 @@ const ut = Ke(({
6897
6899
  service: "elevenlabs",
6898
6900
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
6899
6901
  apiKey: i || ye.apiKey,
6900
- defaultVoice: s || ye.defaultVoice || Xe.defaultVoice,
6901
- voices: ye.voices || Xe.voices
6902
+ defaultVoice: s || ye.defaultVoice || Ze.defaultVoice,
6903
+ voices: ye.voices || Ze.voices
6902
6904
  } : Re === "deepgram" ? he = {
6903
6905
  service: "deepgram",
6904
6906
  endpoint: "https://api.deepgram.com/v1/speak",
@@ -6910,7 +6912,7 @@ const ut = Ke(({
6910
6912
  // Override API key if provided via props
6911
6913
  apiKey: i !== null ? i : ye.apiKey
6912
6914
  };
6913
- const v = {
6915
+ const A = {
6914
6916
  url: Z,
6915
6917
  body: n,
6916
6918
  avatarMood: e,
@@ -6919,17 +6921,17 @@ const ut = Ke(({
6919
6921
  lipsyncLang: "en",
6920
6922
  showFullAvatar: l,
6921
6923
  bodyMovement: a,
6922
- movementIntensity: c
6923
- }, I = {
6924
+ movementIntensity: u
6925
+ }, v = {
6924
6926
  ttsEndpoint: he.endpoint,
6925
6927
  ttsApikey: he.apiKey,
6926
6928
  ttsService: Re,
6927
6929
  lipsyncModules: ["en"],
6928
- cameraView: u
6929
- }, H = U(async () => {
6930
- if (!(!V.current || m.current))
6930
+ cameraView: c
6931
+ }, T = U(async () => {
6932
+ if (!(!G.current || m.current))
6931
6933
  try {
6932
- if (M(!0), Q(null), m.current = new nt(V.current, I), m.current.controls && (m.current.controls.enableRotate = !1, m.current.controls.enableZoom = !1, m.current.controls.enablePan = !1, m.current.controls.enableDamping = !1), x && Object.keys(x).length > 0 && (m.current.customAnimations = x), await m.current.showAvatar(v, (ne) => {
6934
+ if (F(!0), Q(null), m.current = new nt(G.current, v), m.current.controls && (m.current.controls.enableRotate = !1, m.current.controls.enableZoom = !1, m.current.controls.enablePan = !1, m.current.controls.enableDamping = !1), x && Object.keys(x).length > 0 && (m.current.customAnimations = x), await m.current.showAvatar(A, (ne) => {
6933
6935
  if (ne.lengthComputable) {
6934
6936
  const se = Math.min(100, Math.round(ne.loaded / ne.total * 100));
6935
6937
  h(se);
@@ -6945,63 +6947,63 @@ const ut = Ke(({
6945
6947
  } catch (ne) {
6946
6948
  console.warn("Error setting full body mode on initialization:", ne);
6947
6949
  }
6948
- m.current && m.current.controls && (m.current.controls.enableRotate = !1, m.current.controls.enableZoom = !1, m.current.controls.enablePan = !1, m.current.controls.enableDamping = !1, m.current.controls.update()), M(!1), Ie(!0), r(m.current);
6949
- const G = () => {
6950
+ m.current && m.current.controls && (m.current.controls.enableRotate = !1, m.current.controls.enableZoom = !1, m.current.controls.enablePan = !1, m.current.controls.enableDamping = !1, m.current.controls.update()), F(!1), ve(!0), r(m.current);
6951
+ const X = () => {
6950
6952
  document.visibilityState === "visible" ? m.current?.start() : m.current?.stop();
6951
6953
  };
6952
- return document.addEventListener("visibilitychange", G), () => {
6953
- document.removeEventListener("visibilitychange", G);
6954
+ return document.addEventListener("visibilitychange", X), () => {
6955
+ document.removeEventListener("visibilitychange", X);
6954
6956
  };
6955
6957
  } catch (C) {
6956
- console.error("Error initializing TalkingHead:", C), Q(C.message || "Failed to initialize avatar"), M(!1), d(C);
6958
+ console.error("Error initializing TalkingHead:", C), Q(C.message || "Failed to initialize avatar"), F(!1), d(C);
6957
6959
  }
6958
- }, [Z, n, e, t, o, s, i, l, a, c, u]);
6959
- Se(() => (H(), () => {
6960
+ }, [Z, n, e, t, o, s, i, l, a, u, c]);
6961
+ Se(() => (T(), () => {
6960
6962
  m.current && (m.current.stop(), m.current.dispose(), m.current = null);
6961
- }), [H]), Se(() => {
6962
- if (!V.current || !m.current) return;
6963
+ }), [T]), Se(() => {
6964
+ if (!G.current || !m.current) return;
6963
6965
  const C = new ResizeObserver((ne) => {
6964
6966
  for (const se of ne)
6965
6967
  m.current && m.current.onResize && m.current.onResize();
6966
6968
  });
6967
- C.observe(V.current);
6968
- const G = () => {
6969
+ C.observe(G.current);
6970
+ const X = () => {
6969
6971
  m.current && m.current.onResize && m.current.onResize();
6970
6972
  };
6971
- return window.addEventListener("resize", G), () => {
6972
- C.disconnect(), window.removeEventListener("resize", G);
6973
+ return window.addEventListener("resize", X), () => {
6974
+ C.disconnect(), window.removeEventListener("resize", X);
6973
6975
  };
6974
6976
  }, [_]);
6975
- const B = U(async () => {
6977
+ const O = U(async () => {
6976
6978
  if (m.current && m.current.audioCtx)
6977
6979
  try {
6978
6980
  (m.current.audioCtx.state === "suspended" || m.current.audioCtx.state === "interrupted") && (await m.current.audioCtx.resume(), console.log("Audio context resumed"));
6979
6981
  } catch (C) {
6980
6982
  console.warn("Failed to resume audio context:", C);
6981
6983
  }
6982
- }, []), Y = U(async (C, G = {}) => {
6984
+ }, []), Y = U(async (C, X = {}) => {
6983
6985
  if (m.current && _)
6984
6986
  try {
6985
- y.current && (clearInterval(y.current), y.current = null), F.current = { text: C, options: G }, L.current = { remainingText: null, originalText: null, options: null };
6987
+ y.current && (clearInterval(y.current), y.current = null), E.current = { text: C, options: X }, L.current = { remainingText: null, originalText: null, options: null };
6986
6988
  const ne = /[!\.\?\n\p{Extended_Pictographic}]/ug, se = C.split(ne).map((re) => re.trim()).filter((re) => re.length > 0);
6987
- f.current = se, T.current = 0, Ee(!1), P.current = !1, await B();
6989
+ f.current = se, M.current = 0, Fe(!1), P.current = !1, await O();
6988
6990
  const ze = {
6989
- ...G,
6990
- lipsyncLang: G.lipsyncLang || v.lipsyncLang || "en"
6991
+ ...X,
6992
+ lipsyncLang: X.lipsyncLang || A.lipsyncLang || "en"
6991
6993
  };
6992
- if (G.onSpeechEnd && m.current) {
6994
+ if (X.onSpeechEnd && m.current) {
6993
6995
  const re = m.current;
6994
- let ve = null, Fe = 0;
6995
- const Oe = 1200;
6996
+ let Ae = null, Ee = 0;
6997
+ const Be = 1200;
6996
6998
  let He = !1;
6997
- ve = setInterval(() => {
6998
- if (Fe++, P.current)
6999
+ Ae = setInterval(() => {
7000
+ if (Ee++, P.current)
6999
7001
  return;
7000
- if (Fe > Oe) {
7001
- if (ve && (clearInterval(ve), ve = null, y.current = null), !He && !P.current) {
7002
+ if (Ee > Be) {
7003
+ if (Ae && (clearInterval(Ae), Ae = null, y.current = null), !He && !P.current) {
7002
7004
  He = !0;
7003
7005
  try {
7004
- G.onSpeechEnd();
7006
+ X.onSpeechEnd();
7005
7007
  } catch (Ve) {
7006
7008
  console.error("Error in onSpeechEnd callback (timeout):", Ve);
7007
7009
  }
@@ -7011,71 +7013,71 @@ const ut = Ke(({
7011
7013
  const we = !re.speechQueue || re.speechQueue.length === 0, We = !re.audioPlaylist || re.audioPlaylist.length === 0;
7012
7014
  re && re.isSpeaking === !1 && we && We && re.isAudioPlaying === !1 && !He && !P.current && setTimeout(() => {
7013
7015
  if (re && !P.current && re.isSpeaking === !1 && (!re.speechQueue || re.speechQueue.length === 0) && (!re.audioPlaylist || re.audioPlaylist.length === 0) && re.isAudioPlaying === !1 && !He && !P.current) {
7014
- He = !0, ve && (clearInterval(ve), ve = null, y.current = null);
7016
+ He = !0, Ae && (clearInterval(Ae), Ae = null, y.current = null);
7015
7017
  try {
7016
- G.onSpeechEnd();
7018
+ X.onSpeechEnd();
7017
7019
  } catch (tt) {
7018
7020
  console.error("Error in onSpeechEnd callback:", tt);
7019
7021
  }
7020
7022
  }
7021
7023
  }, 100);
7022
- }, 100), y.current = ve;
7024
+ }, 100), y.current = Ae;
7023
7025
  }
7024
7026
  m.current.lipsync && Object.keys(m.current.lipsync).length > 0 ? (m.current.setSlowdownRate && m.current.setSlowdownRate(1.05), m.current.speakText(C, ze)) : setTimeout(async () => {
7025
- await B(), m.current && m.current.lipsync && (m.current.setSlowdownRate && m.current.setSlowdownRate(1.05), m.current.speakText(C, ze));
7027
+ await O(), m.current && m.current.lipsync && (m.current.setSlowdownRate && m.current.setSlowdownRate(1.05), m.current.speakText(C, ze));
7026
7028
  }, 100);
7027
7029
  } catch (ne) {
7028
7030
  console.error("Error speaking text:", ne), Q(ne.message || "Failed to speak text");
7029
7031
  }
7030
- }, [_, B, v.lipsyncLang]), K = U(() => {
7031
- m.current && (m.current.stopSpeaking(), m.current.setSlowdownRate && m.current.setSlowdownRate(1), F.current = null, Ee(!1));
7032
+ }, [_, O, A.lipsyncLang]), K = U(() => {
7033
+ m.current && (m.current.stopSpeaking(), m.current.setSlowdownRate && m.current.setSlowdownRate(1), E.current = null, Fe(!1));
7032
7034
  }, []), q = U(() => {
7033
7035
  if (m.current && m.current.pauseSpeaking) {
7034
7036
  const C = m.current;
7035
7037
  if (C.isSpeaking || C.audioPlaylist && C.audioPlaylist.length > 0 || C.speechQueue && C.speechQueue.length > 0) {
7036
7038
  y.current && (clearInterval(y.current), y.current = null);
7037
7039
  let ne = "";
7038
- if (F.current && f.current.length > 0) {
7039
- const se = f.current.length, ze = C.speechQueue ? C.speechQueue.filter((Oe) => Oe && Oe.text && Array.isArray(Oe.text) && Oe.text.length > 0).length : 0, re = C.audioPlaylist && C.audioPlaylist.length > 0, ve = ze + (re ? 1 : 0), Fe = se - ve;
7040
- if (ve > 0 && Fe < se && (ne = f.current.slice(Fe).join(". ").trim(), !ne && ze > 0 && C.speechQueue)) {
7040
+ if (E.current && f.current.length > 0) {
7041
+ const se = f.current.length, ze = C.speechQueue ? C.speechQueue.filter((Be) => Be && Be.text && Array.isArray(Be.text) && Be.text.length > 0).length : 0, re = C.audioPlaylist && C.audioPlaylist.length > 0, Ae = ze + (re ? 1 : 0), Ee = se - Ae;
7042
+ if (Ae > 0 && Ee < se && (ne = f.current.slice(Ee).join(". ").trim(), !ne && ze > 0 && C.speechQueue)) {
7041
7043
  const He = C.speechQueue.filter((we) => we && we.text && Array.isArray(we.text) && we.text.length > 0).map((we) => we.text.map((We) => We.word || "").filter((We) => We.length > 0).join(" ")).filter((we) => we.length > 0).join(" ");
7042
7044
  He && He.trim() && (ne = He.trim());
7043
7045
  }
7044
7046
  }
7045
- F.current && (L.current = {
7047
+ E.current && (L.current = {
7046
7048
  remainingText: ne || null,
7047
- originalText: F.current.text,
7048
- options: F.current.options
7049
- }), C.speechQueue && (C.speechQueue.length = 0), m.current.pauseSpeaking(), P.current = !0, Ee(!0);
7049
+ originalText: E.current.text,
7050
+ options: E.current.options
7051
+ }), C.speechQueue && (C.speechQueue.length = 0), m.current.pauseSpeaking(), P.current = !0, Fe(!0);
7050
7052
  }
7051
7053
  }
7052
7054
  }, []), te = U(async () => {
7053
7055
  if (!m.current || !me)
7054
7056
  return;
7055
- let C = "", G = {};
7057
+ let C = "", X = {};
7056
7058
  if (L.current && L.current.remainingText)
7057
- C = L.current.remainingText, G = L.current.options || {}, L.current = { remainingText: null, originalText: null, options: null };
7058
- else if (F.current && F.current.text)
7059
- C = F.current.text, G = F.current.options || {};
7059
+ C = L.current.remainingText, X = L.current.options || {}, L.current = { remainingText: null, originalText: null, options: null };
7060
+ else if (E.current && E.current.text)
7061
+ C = E.current.text, X = E.current.options || {};
7060
7062
  else {
7061
- console.warn("Resume called but no paused speech found"), Ee(!1), P.current = !1;
7063
+ console.warn("Resume called but no paused speech found"), Fe(!1), P.current = !1;
7062
7064
  return;
7063
7065
  }
7064
- Ee(!1), P.current = !1, await B();
7066
+ Fe(!1), P.current = !1, await O();
7065
7067
  const ne = {
7066
- ...G,
7067
- lipsyncLang: G.lipsyncLang || v.lipsyncLang || "en"
7068
+ ...X,
7069
+ lipsyncLang: X.lipsyncLang || A.lipsyncLang || "en"
7068
7070
  };
7069
7071
  try {
7070
7072
  await Y(C, ne);
7071
7073
  } catch (se) {
7072
- console.error("Error resuming speech:", se), Ee(!1), P.current = !1;
7074
+ console.error("Error resuming speech:", se), Fe(!1), P.current = !1;
7073
7075
  }
7074
- }, [B, me, Y, v]), fe = U((C) => {
7076
+ }, [O, me, Y, A]), fe = U((C) => {
7075
7077
  m.current && m.current.setMood(C);
7076
- }, []), Ae = U((C) => {
7078
+ }, []), Ie = U((C) => {
7077
7079
  m.current && m.current.setSlowdownRate && m.current.setSlowdownRate(C);
7078
- }, []), et = U((C, G = !1) => {
7080
+ }, []), et = U((C, X = !1) => {
7079
7081
  if (m.current && m.current.playAnimation) {
7080
7082
  if (x && x[C] && (C = x[C]), m.current.setShowFullAvatar)
7081
7083
  try {
@@ -7085,7 +7087,7 @@ const ut = Ke(({
7085
7087
  }
7086
7088
  if (C.includes("."))
7087
7089
  try {
7088
- m.current.playAnimation(C, null, 10, 0, 0.01, G);
7090
+ m.current.playAnimation(C, null, 10, 0, 0.01, X);
7089
7091
  } catch (se) {
7090
7092
  console.warn(`Failed to play ${C}:`, se);
7091
7093
  try {
@@ -7099,7 +7101,7 @@ const ut = Ke(({
7099
7101
  let ze = !1;
7100
7102
  for (const re of se)
7101
7103
  try {
7102
- m.current.playAnimation(C + re, null, 10, 0, 0.01, G), ze = !0;
7104
+ m.current.playAnimation(C + re, null, 10, 0, 0.01, X), ze = !0;
7103
7105
  break;
7104
7106
  } catch {
7105
7107
  }
@@ -7116,14 +7118,14 @@ const ut = Ke(({
7116
7118
  }, [x]), ke = U(() => {
7117
7119
  m.current && m.current.onResize && m.current.onResize();
7118
7120
  }, []);
7119
- return Je(S, () => ({
7121
+ return Je(k, () => ({
7120
7122
  speakText: Y,
7121
7123
  stopSpeaking: K,
7122
7124
  pauseSpeaking: q,
7123
7125
  resumeSpeaking: te,
7124
- resumeAudioContext: B,
7126
+ resumeAudioContext: O,
7125
7127
  setMood: fe,
7126
- setTimingAdjustment: Ae,
7128
+ setTimingAdjustment: Ie,
7127
7129
  playAnimation: et,
7128
7130
  isReady: _,
7129
7131
  isPaused: me,
@@ -7133,8 +7135,8 @@ const ut = Ke(({
7133
7135
  if (m.current && m.current.setShowFullAvatar && m.current.setBodyMovement)
7134
7136
  try {
7135
7137
  m.current.setShowFullAvatar(D.current), m.current.setBodyMovement(C);
7136
- } catch (G) {
7137
- console.warn("Error setting body movement:", G);
7138
+ } catch (X) {
7139
+ console.warn("Error setting body movement:", X);
7138
7140
  }
7139
7141
  },
7140
7142
  setMovementIntensity: (C) => m.current?.setMovementIntensity(C),
@@ -7150,8 +7152,8 @@ const ut = Ke(({
7150
7152
  if (m.current && m.current.setShowFullAvatar && m.current.playReaction)
7151
7153
  try {
7152
7154
  m.current.setShowFullAvatar(D.current), m.current.playReaction(C);
7153
- } catch (G) {
7154
- console.warn("Error playing reaction:", G);
7155
+ } catch (X) {
7156
+ console.warn("Error playing reaction:", X);
7155
7157
  }
7156
7158
  },
7157
7159
  playCelebration: () => {
@@ -7166,8 +7168,8 @@ const ut = Ke(({
7166
7168
  if (m.current && m.current.setShowFullAvatar)
7167
7169
  try {
7168
7170
  D.current = C, m.current.setShowFullAvatar(C);
7169
- } catch (G) {
7170
- console.warn("Error setting showFullAvatar:", G);
7171
+ } catch (X) {
7172
+ console.warn("Error setting showFullAvatar:", X);
7171
7173
  }
7172
7174
  },
7173
7175
  lockAvatarPosition: () => {
@@ -7200,7 +7202,7 @@ const ut = Ke(({
7200
7202
  /* @__PURE__ */ ae(
7201
7203
  "div",
7202
7204
  {
7203
- ref: V,
7205
+ ref: G,
7204
7206
  className: "talking-head-viewer",
7205
7207
  style: {
7206
7208
  width: "100%",
@@ -7209,7 +7211,7 @@ const ut = Ke(({
7209
7211
  }
7210
7212
  }
7211
7213
  ),
7212
- A && /* @__PURE__ */ ae("div", { className: "loading-overlay", style: {
7214
+ I && /* @__PURE__ */ ae("div", { className: "loading-overlay", style: {
7213
7215
  position: "absolute",
7214
7216
  top: "50%",
7215
7217
  left: "50%",
@@ -7218,7 +7220,7 @@ const ut = Ke(({
7218
7220
  fontSize: "18px",
7219
7221
  zIndex: 10
7220
7222
  }, children: "Loading avatar..." }),
7221
- O && /* @__PURE__ */ ae("div", { className: "error-overlay", style: {
7223
+ B && /* @__PURE__ */ ae("div", { className: "error-overlay", style: {
7222
7224
  position: "absolute",
7223
7225
  top: "50%",
7224
7226
  left: "50%",
@@ -7229,13 +7231,13 @@ const ut = Ke(({
7229
7231
  zIndex: 10,
7230
7232
  padding: "20px",
7231
7233
  borderRadius: "8px"
7232
- }, children: O })
7234
+ }, children: B })
7233
7235
  ]
7234
7236
  }
7235
7237
  );
7236
7238
  });
7237
- ut.displayName = "TalkingHeadAvatar";
7238
- const Bt = Ke(({
7239
+ ct.displayName = "TalkingHeadAvatar";
7240
+ const Ot = Ke(({
7239
7241
  text: Z = "Hello! I'm a talking avatar. How are you today?",
7240
7242
  onLoading: n = () => {
7241
7243
  },
@@ -7247,7 +7249,7 @@ const Bt = Ke(({
7247
7249
  style: s = {},
7248
7250
  avatarConfig: i = {}
7249
7251
  }, a) => {
7250
- const c = W(null), l = W(null), [u, r] = pe(!0), [h, d] = pe(null), [g, R] = pe(!1), x = $e(), S = i.ttsService || x.service, V = S === "browser" ? {
7252
+ const u = V(null), l = V(null), [c, r] = pe(!0), [h, d] = pe(null), [g, R] = pe(!1), x = $e(), k = i.ttsService || x.service, G = k === "browser" ? {
7251
7253
  endpoint: "",
7252
7254
  apiKey: null,
7253
7255
  defaultVoice: "Google US English"
@@ -7256,14 +7258,14 @@ const Bt = Ke(({
7256
7258
  // Override API key if provided via avatarConfig
7257
7259
  apiKey: i.ttsApiKey !== void 0 && i.ttsApiKey !== null ? i.ttsApiKey : x.apiKey,
7258
7260
  // Override endpoint for ElevenLabs if service is explicitly set
7259
- endpoint: S === "elevenlabs" && i.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : x.endpoint
7261
+ endpoint: k === "elevenlabs" && i.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : x.endpoint
7260
7262
  }, m = {
7261
7263
  url: "/avatars/brunette.glb",
7262
7264
  // Use brunette avatar (working glTF file)
7263
7265
  body: "F",
7264
7266
  avatarMood: "neutral",
7265
- ttsLang: S === "browser" ? "en-US" : "en",
7266
- ttsVoice: i.ttsVoice || V.defaultVoice,
7267
+ ttsLang: k === "browser" ? "en-US" : "en",
7268
+ ttsVoice: i.ttsVoice || G.defaultVoice,
7267
7269
  lipsyncLang: "en",
7268
7270
  // English lip-sync
7269
7271
  showFullAvatar: !0,
@@ -7272,68 +7274,68 @@ const Bt = Ke(({
7272
7274
  movementIntensity: 0.5,
7273
7275
  ...i
7274
7276
  }, D = {
7275
- ttsEndpoint: V.endpoint,
7276
- ttsApikey: V.apiKey,
7277
- ttsService: S,
7277
+ ttsEndpoint: G.endpoint,
7278
+ ttsApikey: G.apiKey,
7279
+ ttsService: k,
7278
7280
  lipsyncModules: ["en"],
7279
7281
  cameraView: "upper"
7280
- }, F = U(async () => {
7281
- if (!(!c.current || l.current))
7282
+ }, E = U(async () => {
7283
+ if (!(!u.current || l.current))
7282
7284
  try {
7283
- if (r(!0), d(null), l.current = new nt(c.current, D), await l.current.showAvatar(m, (O) => {
7284
- if (O.lengthComputable) {
7285
- const Q = Math.min(100, Math.round(O.loaded / O.total * 100));
7285
+ if (r(!0), d(null), l.current = new nt(u.current, D), await l.current.showAvatar(m, (B) => {
7286
+ if (B.lengthComputable) {
7287
+ const Q = Math.min(100, Math.round(B.loaded / B.total * 100));
7286
7288
  n(Q);
7287
7289
  }
7288
7290
  }), l.current.morphs && l.current.morphs.length > 0) {
7289
- const O = l.current.morphs[0].morphTargetDictionary;
7290
- console.log("Available morph targets:", Object.keys(O));
7291
- const Q = Object.keys(O).filter((_) => _.startsWith("viseme_"));
7291
+ const B = l.current.morphs[0].morphTargetDictionary;
7292
+ console.log("Available morph targets:", Object.keys(B));
7293
+ const Q = Object.keys(B).filter((_) => _.startsWith("viseme_"));
7292
7294
  console.log("Viseme morph targets found:", Q), Q.length === 0 && (console.warn("No viseme morph targets found! Lip-sync will not work properly."), console.log("Expected viseme targets: viseme_aa, viseme_E, viseme_I, viseme_O, viseme_U, viseme_PP, viseme_SS, viseme_TH, viseme_DD, viseme_FF, viseme_kk, viseme_nn, viseme_RR, viseme_CH, viseme_sil"));
7293
7295
  }
7294
- if (await new Promise((O) => {
7296
+ if (await new Promise((B) => {
7295
7297
  const Q = () => {
7296
- l.current.lipsync && Object.keys(l.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(l.current.lipsync)), O()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(Q, 100));
7298
+ l.current.lipsync && Object.keys(l.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(l.current.lipsync)), B()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(Q, 100));
7297
7299
  };
7298
7300
  Q();
7299
7301
  }), l.current && l.current.setShowFullAvatar)
7300
7302
  try {
7301
7303
  l.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
7302
- } catch (O) {
7303
- console.warn("Error setting full body mode on initialization:", O);
7304
+ } catch (B) {
7305
+ console.warn("Error setting full body mode on initialization:", B);
7304
7306
  }
7305
7307
  r(!1), R(!0), t(l.current);
7306
- const M = () => {
7308
+ const F = () => {
7307
7309
  document.visibilityState === "visible" ? l.current?.start() : l.current?.stop();
7308
7310
  };
7309
- return document.addEventListener("visibilitychange", M), () => {
7310
- document.removeEventListener("visibilitychange", M);
7311
+ return document.addEventListener("visibilitychange", F), () => {
7312
+ document.removeEventListener("visibilitychange", F);
7311
7313
  };
7312
- } catch (A) {
7313
- console.error("Error initializing TalkingHead:", A), d(A.message || "Failed to initialize avatar"), r(!1), e(A);
7314
+ } catch (I) {
7315
+ console.error("Error initializing TalkingHead:", I), d(I.message || "Failed to initialize avatar"), r(!1), e(I);
7314
7316
  }
7315
7317
  }, []);
7316
- Se(() => (F(), () => {
7318
+ Se(() => (E(), () => {
7317
7319
  l.current && (l.current.stop(), l.current.dispose(), l.current = null);
7318
- }), [F]);
7319
- const y = U((A) => {
7320
+ }), [E]);
7321
+ const y = U((I) => {
7320
7322
  if (l.current && g)
7321
7323
  try {
7322
- console.log("Speaking text:", A), console.log("Avatar config:", m), console.log("TalkingHead instance:", l.current), l.current.lipsync && Object.keys(l.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(l.current.lipsync)), l.current.setSlowdownRate && (l.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), l.current.speakText(A)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7323
- l.current && l.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), l.current.setSlowdownRate && (l.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), l.current.speakText(A)) : console.error("Lip-sync still not ready after waiting");
7324
+ console.log("Speaking text:", I), console.log("Avatar config:", m), console.log("TalkingHead instance:", l.current), l.current.lipsync && Object.keys(l.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(l.current.lipsync)), l.current.setSlowdownRate && (l.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), l.current.speakText(I)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7325
+ l.current && l.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), l.current.setSlowdownRate && (l.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), l.current.speakText(I)) : console.error("Lip-sync still not ready after waiting");
7324
7326
  }, 500));
7325
- } catch (M) {
7326
- console.error("Error speaking text:", M), d(M.message || "Failed to speak text");
7327
+ } catch (F) {
7328
+ console.error("Error speaking text:", F), d(F.message || "Failed to speak text");
7327
7329
  }
7328
7330
  else
7329
7331
  console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!l.current);
7330
7332
  }, [g, m]), P = U(() => {
7331
7333
  l.current && (l.current.stopSpeaking(), l.current.setSlowdownRate && (l.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7332
- }, []), L = U((A) => {
7333
- l.current && l.current.setMood(A);
7334
- }, []), f = U((A) => {
7335
- l.current && l.current.setSlowdownRate && (l.current.setSlowdownRate(A), console.log("Timing adjustment set to:", A));
7336
- }, []), T = U((A, M = !1) => {
7334
+ }, []), L = U((I) => {
7335
+ l.current && l.current.setMood(I);
7336
+ }, []), f = U((I) => {
7337
+ l.current && l.current.setSlowdownRate && (l.current.setSlowdownRate(I), console.log("Timing adjustment set to:", I));
7338
+ }, []), M = U((I, F = !1) => {
7337
7339
  if (l.current && l.current.playAnimation) {
7338
7340
  if (l.current.setShowFullAvatar)
7339
7341
  try {
@@ -7341,11 +7343,11 @@ const Bt = Ke(({
7341
7343
  } catch (Q) {
7342
7344
  console.warn("Error setting full body mode:", Q);
7343
7345
  }
7344
- if (A.includes("."))
7346
+ if (I.includes("."))
7345
7347
  try {
7346
- l.current.playAnimation(A, null, 10, 0, 0.01, M), console.log("Playing animation:", A);
7348
+ l.current.playAnimation(I, null, 10, 0, 0.01, F), console.log("Playing animation:", I);
7347
7349
  } catch (Q) {
7348
- console.log(`Failed to play ${A}:`, Q);
7350
+ console.log(`Failed to play ${I}:`, Q);
7349
7351
  try {
7350
7352
  l.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7351
7353
  } catch (_) {
@@ -7355,95 +7357,95 @@ const Bt = Ke(({
7355
7357
  else {
7356
7358
  const Q = [".fbx", ".glb", ".gltf"];
7357
7359
  let _ = !1;
7358
- for (const Ie of Q)
7360
+ for (const ve of Q)
7359
7361
  try {
7360
- l.current.playAnimation(A + Ie, null, 10, 0, 0.01, M), console.log("Playing animation:", A + Ie), _ = !0;
7362
+ l.current.playAnimation(I + ve, null, 10, 0, 0.01, F), console.log("Playing animation:", I + ve), _ = !0;
7361
7363
  break;
7362
7364
  } catch {
7363
- console.log(`Failed to play ${A}${Ie}, trying next format...`);
7365
+ console.log(`Failed to play ${I}${ve}, trying next format...`);
7364
7366
  }
7365
7367
  if (!_) {
7366
- console.warn("Animation system not available or animation not found:", A);
7368
+ console.warn("Animation system not available or animation not found:", I);
7367
7369
  try {
7368
7370
  l.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7369
- } catch (Ie) {
7370
- console.warn("Fallback animation also failed:", Ie);
7371
+ } catch (ve) {
7372
+ console.warn("Fallback animation also failed:", ve);
7371
7373
  }
7372
7374
  }
7373
7375
  }
7374
7376
  } else
7375
- console.warn("Animation system not available or animation not found:", A);
7377
+ console.warn("Animation system not available or animation not found:", I);
7376
7378
  }, []);
7377
7379
  return Je(a, () => ({
7378
7380
  speakText: y,
7379
7381
  stopSpeaking: P,
7380
7382
  setMood: L,
7381
7383
  setTimingAdjustment: f,
7382
- playAnimation: T,
7384
+ playAnimation: M,
7383
7385
  isReady: g,
7384
7386
  talkingHead: l.current,
7385
- setBodyMovement: (A) => {
7387
+ setBodyMovement: (I) => {
7386
7388
  if (l.current && l.current.setShowFullAvatar && l.current.setBodyMovement)
7387
7389
  try {
7388
- l.current.setShowFullAvatar(!0), l.current.setBodyMovement(A), console.log("Body movement set with full body mode:", A);
7389
- } catch (M) {
7390
- console.warn("Error setting body movement:", M);
7390
+ l.current.setShowFullAvatar(!0), l.current.setBodyMovement(I), console.log("Body movement set with full body mode:", I);
7391
+ } catch (F) {
7392
+ console.warn("Error setting body movement:", F);
7391
7393
  }
7392
7394
  },
7393
- setMovementIntensity: (A) => l.current?.setMovementIntensity(A),
7395
+ setMovementIntensity: (I) => l.current?.setMovementIntensity(I),
7394
7396
  playRandomDance: () => {
7395
7397
  if (l.current && l.current.setShowFullAvatar && l.current.playRandomDance)
7396
7398
  try {
7397
7399
  l.current.setShowFullAvatar(!0), l.current.playRandomDance(), console.log("Random dance played with full body mode");
7398
- } catch (A) {
7399
- console.warn("Error playing random dance:", A);
7400
+ } catch (I) {
7401
+ console.warn("Error playing random dance:", I);
7400
7402
  }
7401
7403
  },
7402
- playReaction: (A) => {
7404
+ playReaction: (I) => {
7403
7405
  if (l.current && l.current.setShowFullAvatar && l.current.playReaction)
7404
7406
  try {
7405
- l.current.setShowFullAvatar(!0), l.current.playReaction(A), console.log("Reaction played with full body mode:", A);
7406
- } catch (M) {
7407
- console.warn("Error playing reaction:", M);
7407
+ l.current.setShowFullAvatar(!0), l.current.playReaction(I), console.log("Reaction played with full body mode:", I);
7408
+ } catch (F) {
7409
+ console.warn("Error playing reaction:", F);
7408
7410
  }
7409
7411
  },
7410
7412
  playCelebration: () => {
7411
7413
  if (l.current && l.current.setShowFullAvatar && l.current.playCelebration)
7412
7414
  try {
7413
7415
  l.current.setShowFullAvatar(!0), l.current.playCelebration(), console.log("Celebration played with full body mode");
7414
- } catch (A) {
7415
- console.warn("Error playing celebration:", A);
7416
+ } catch (I) {
7417
+ console.warn("Error playing celebration:", I);
7416
7418
  }
7417
7419
  },
7418
- setShowFullAvatar: (A) => {
7420
+ setShowFullAvatar: (I) => {
7419
7421
  if (l.current && l.current.setShowFullAvatar)
7420
7422
  try {
7421
- l.current.setShowFullAvatar(A), console.log("Show full avatar set to:", A);
7422
- } catch (M) {
7423
- console.warn("Error setting showFullAvatar:", M);
7423
+ l.current.setShowFullAvatar(I), console.log("Show full avatar set to:", I);
7424
+ } catch (F) {
7425
+ console.warn("Error setting showFullAvatar:", F);
7424
7426
  }
7425
7427
  },
7426
7428
  lockAvatarPosition: () => {
7427
7429
  if (l.current && l.current.lockAvatarPosition)
7428
7430
  try {
7429
7431
  l.current.lockAvatarPosition();
7430
- } catch (A) {
7431
- console.warn("Error locking avatar position:", A);
7432
+ } catch (I) {
7433
+ console.warn("Error locking avatar position:", I);
7432
7434
  }
7433
7435
  },
7434
7436
  unlockAvatarPosition: () => {
7435
7437
  if (l.current && l.current.unlockAvatarPosition)
7436
7438
  try {
7437
7439
  l.current.unlockAvatarPosition();
7438
- } catch (A) {
7439
- console.warn("Error unlocking avatar position:", A);
7440
+ } catch (I) {
7441
+ console.warn("Error unlocking avatar position:", I);
7440
7442
  }
7441
7443
  }
7442
7444
  })), /* @__PURE__ */ Pe("div", { className: `talking-head-container ${o}`, style: s, children: [
7443
7445
  /* @__PURE__ */ ae(
7444
7446
  "div",
7445
7447
  {
7446
- ref: c,
7448
+ ref: u,
7447
7449
  className: "talking-head-viewer",
7448
7450
  style: {
7449
7451
  width: "100%",
@@ -7452,7 +7454,7 @@ const Bt = Ke(({
7452
7454
  }
7453
7455
  }
7454
7456
  ),
7455
- u && /* @__PURE__ */ ae("div", { className: "loading-overlay", style: {
7457
+ c && /* @__PURE__ */ ae("div", { className: "loading-overlay", style: {
7456
7458
  position: "absolute",
7457
7459
  top: "50%",
7458
7460
  left: "50%",
@@ -7475,7 +7477,7 @@ const Bt = Ke(({
7475
7477
  }, children: h })
7476
7478
  ] });
7477
7479
  });
7478
- Bt.displayName = "TalkingHeadComponent";
7480
+ Ot.displayName = "TalkingHeadComponent";
7479
7481
  async function je(Z) {
7480
7482
  try {
7481
7483
  const n = await fetch(Z);
@@ -7506,9 +7508,9 @@ async function Dt(Z, n = "F") {
7506
7508
  ];
7507
7509
  for (const a of i)
7508
7510
  try {
7509
- const c = await fetch(a);
7510
- if (c.ok) {
7511
- const l = await c.json(), r = (Array.isArray(l) ? l : l.files || []).filter((h) => typeof h == "string" && h.toLowerCase().endsWith(".fbx")).map((h) => h.startsWith("/") ? h : `${t}/${h}`);
7511
+ const u = await fetch(a);
7512
+ if (u.ok) {
7513
+ const l = await u.json(), r = (Array.isArray(l) ? l : l.files || []).filter((h) => typeof h == "string" && h.toLowerCase().endsWith(".fbx")).map((h) => h.startsWith("/") ? h : `${t}/${h}`);
7512
7514
  if (r.length > 0)
7513
7515
  return r;
7514
7516
  }
@@ -7527,10 +7529,10 @@ async function Dt(Z, n = "F") {
7527
7529
  o === "M" ? s.push(`${t}/male`, `${t}/m`) : s.push(`${t}/female`, `${t}/f`), s.push(`${t}/shared`);
7528
7530
  for (const i of s)
7529
7531
  try {
7530
- const a = `${i}/.list.json`, c = await fetch(a);
7531
- if (c.ok) {
7532
- const l = await c.json(), u = (Array.isArray(l) ? l : l.files || []).filter((r) => typeof r == "string" && r.toLowerCase().endsWith(".fbx")).map((r) => r.startsWith("/") ? r : `${i}/${r}`);
7533
- u.length > 0 && e.push(...u);
7532
+ const a = `${i}/.list.json`, u = await fetch(a);
7533
+ if (u.ok) {
7534
+ const l = await u.json(), c = (Array.isArray(l) ? l : l.files || []).filter((r) => typeof r == "string" && r.toLowerCase().endsWith(".fbx")).map((r) => r.startsWith("/") ? r : `${i}/${r}`);
7535
+ c.length > 0 && e.push(...c);
7534
7536
  }
7535
7537
  } catch {
7536
7538
  continue;
@@ -7557,9 +7559,9 @@ const Nt = Ke(({
7557
7559
  ttsService: s = null,
7558
7560
  ttsVoice: i = null,
7559
7561
  ttsApiKey: a = null,
7560
- bodyMovement: c = "idle",
7562
+ bodyMovement: u = "idle",
7561
7563
  movementIntensity: l = 0.5,
7562
- showFullAvatar: u = !1,
7564
+ showFullAvatar: c = !1,
7563
7565
  cameraView: r = "upper",
7564
7566
  onReady: h = () => {
7565
7567
  },
@@ -7571,24 +7573,24 @@ const Nt = Ke(({
7571
7573
  },
7572
7574
  onSpeechEnd: x = () => {
7573
7575
  },
7574
- className: S = "",
7575
- style: V = {},
7576
+ className: k = "",
7577
+ style: G = {},
7576
7578
  animations: m = {},
7577
7579
  autoAnimationGroup: D = null,
7578
7580
  // e.g., "talking" - will randomly select from this group when speaking
7579
- autoIdleGroup: F = null,
7581
+ autoIdleGroup: E = null,
7580
7582
  // e.g., "idle" - will randomly select from this group when idle
7581
7583
  autoSpeak: y = !1
7582
7584
  }, P) => {
7583
- const L = W(null), f = W(null), T = W(u), A = W(null), M = W(null), O = W(!1), Q = W({ remainingText: null, originalText: null, options: null }), _ = W([]), [Ie, me] = pe(!0), [Ee, ye] = pe(null), [Re, he] = pe(!1), [v, I] = pe(!1), [H, B] = pe(m), Y = W(null), K = W(!1), q = W(null), te = W(!1), fe = W([]), Ae = W([]), et = W(0), ke = W(null);
7585
+ const L = V(null), f = V(null), M = V(c), I = V(null), F = V(null), B = V(!1), Q = V({ remainingText: null, originalText: null, options: null }), _ = V([]), [ve, me] = pe(!0), [Fe, ye] = pe(null), [Re, he] = pe(!1), [A, v] = pe(!1), [T, O] = pe(m), Y = V(null), K = V(!1), q = V(null), te = V(!1), fe = V([]), Ie = V([]), et = V(0), ke = V(null);
7584
7586
  Se(() => {
7585
- O.current = v;
7586
- }, [v]);
7587
- const C = U((k) => {
7587
+ B.current = A;
7588
+ }, [A]);
7589
+ const C = U((S) => {
7588
7590
  let w = "F";
7589
- if (k) {
7590
- const E = k.toString().toUpperCase().trim();
7591
- E === "M" || E === "MALE" ? w = "M" : (E === "F" || E === "FEMALE") && (w = "F");
7591
+ if (S) {
7592
+ const H = S.toString().toUpperCase().trim();
7593
+ H === "M" || H === "MALE" ? w = "M" : (H === "F" || H === "FEMALE") && (w = "F");
7592
7594
  }
7593
7595
  return w === "M" ? "male" : "female";
7594
7596
  }, []);
@@ -7597,13 +7599,13 @@ const Nt = Ke(({
7597
7599
  if (m.manifest && m.auto)
7598
7600
  try {
7599
7601
  const w = await je(m.manifest);
7600
- B(w);
7602
+ O(w);
7601
7603
  return;
7602
7604
  } catch {
7603
7605
  }
7604
7606
  if (m.manifest && !m.auto) {
7605
- const w = await je(m.manifest), E = Object.keys(w).length > 0;
7606
- B(E ? w : m);
7607
+ const w = await je(m.manifest), H = Object.keys(w).length > 0;
7608
+ O(H ? w : m);
7607
7609
  } else if (m.auto)
7608
7610
  try {
7609
7611
  let w = null;
@@ -7613,57 +7615,57 @@ const Nt = Ke(({
7613
7615
  } catch {
7614
7616
  }
7615
7617
  if (typeof m.auto == "string") {
7616
- const E = m.auto, ee = {
7617
- talking: `${E}/talking`,
7618
- idle: `${E}/idle`
7619
- }, j = C(e);
7620
- ee[`${j}_talking`] = `${E}/${j}/talking`, ee[`${j}_idle`] = `${E}/${j}/idle`, ee.shared_talking = `${E}/shared/talking`, ee.shared_idle = `${E}/shared/idle`;
7621
- const ie = await lt(ee, e);
7622
- if (!Object.values(ie).some((X) => Array.isArray(X) && X.length > 0) && w) {
7623
- B(w);
7618
+ const H = m.auto, J = {
7619
+ talking: `${H}/talking`,
7620
+ idle: `${H}/idle`
7621
+ }, W = C(e);
7622
+ J[`${W}_talking`] = `${H}/${W}/talking`, J[`${W}_idle`] = `${H}/${W}/idle`, J.shared_talking = `${H}/shared/talking`, J.shared_idle = `${H}/shared/idle`;
7623
+ const ie = await lt(J, e);
7624
+ if (!Object.values(ie).some((j) => Array.isArray(j) && j.length > 0) && w) {
7625
+ O(w);
7624
7626
  return;
7625
7627
  }
7626
- const ue = {
7628
+ const ce = {
7627
7629
  _genderSpecific: {
7628
- [j]: {},
7630
+ [W]: {},
7629
7631
  shared: {}
7630
7632
  }
7631
7633
  };
7632
- Object.entries(ie).forEach(([X, J]) => {
7633
- if (X.includes("_")) {
7634
- const [$, ...ge] = X.split("_"), de = ge.join("_");
7635
- $ === "shared" ? (ue._genderSpecific.shared[de] || (ue._genderSpecific.shared[de] = []), ue._genderSpecific.shared[de].push(...J)) : $ === j && (ue._genderSpecific[j][de] || (ue._genderSpecific[j][de] = []), ue._genderSpecific[j][de].push(...J));
7634
+ Object.entries(ie).forEach(([j, $]) => {
7635
+ if (j.includes("_")) {
7636
+ const [ee, ...ge] = j.split("_"), de = ge.join("_");
7637
+ ee === "shared" ? (ce._genderSpecific.shared[de] || (ce._genderSpecific.shared[de] = []), ce._genderSpecific.shared[de].push(...$)) : ee === W && (ce._genderSpecific[W][de] || (ce._genderSpecific[W][de] = []), ce._genderSpecific[W][de].push(...$));
7636
7638
  } else
7637
- ue[X] = J;
7638
- }), w && (w._genderSpecific && Object.keys(w._genderSpecific).forEach((X) => {
7639
- ue._genderSpecific[X] || (ue._genderSpecific[X] = {}), Object.entries(w._genderSpecific[X]).forEach(([J, $]) => {
7640
- ue._genderSpecific[X][J] || (ue._genderSpecific[X][J] = $);
7639
+ ce[j] = $;
7640
+ }), w && (w._genderSpecific && Object.keys(w._genderSpecific).forEach((j) => {
7641
+ ce._genderSpecific[j] || (ce._genderSpecific[j] = {}), Object.entries(w._genderSpecific[j]).forEach(([$, ee]) => {
7642
+ ce._genderSpecific[j][$] || (ce._genderSpecific[j][$] = ee);
7641
7643
  });
7642
- }), Object.entries(w).forEach(([X, J]) => {
7643
- X !== "_genderSpecific" && !ue[X] && (ue[X] = J);
7644
- })), B(ue);
7644
+ }), Object.entries(w).forEach(([j, $]) => {
7645
+ j !== "_genderSpecific" && !ce[j] && (ce[j] = $);
7646
+ })), O(ce);
7645
7647
  } else if (typeof m.auto == "object") {
7646
- const E = await lt(m.auto, e), ee = Object.values(E).some((j) => Array.isArray(j) && j.length > 0);
7647
- B(!ee && w ? w : E);
7648
+ const H = await lt(m.auto, e), J = Object.values(H).some((W) => Array.isArray(W) && W.length > 0);
7649
+ O(!J && w ? w : H);
7648
7650
  }
7649
7651
  } catch (w) {
7650
7652
  if (console.error("Failed to auto-discover animations:", w), m.manifest)
7651
7653
  try {
7652
- const E = await je(m.manifest);
7653
- B(E);
7654
+ const H = await je(m.manifest);
7655
+ O(H);
7654
7656
  } catch {
7655
- B(m);
7657
+ O(m);
7656
7658
  }
7657
7659
  else
7658
- B(m);
7660
+ O(m);
7659
7661
  }
7660
7662
  else
7661
- B(m);
7663
+ O(m);
7662
7664
  })();
7663
7665
  }, [m, e, C]), Se(() => {
7664
- T.current = u;
7665
- }, [u]);
7666
- const G = $e(), ne = s || G.service;
7666
+ M.current = c;
7667
+ }, [c]);
7668
+ const X = $e(), ne = s || X.service;
7667
7669
  let se;
7668
7670
  ne === "browser" ? se = {
7669
7671
  service: "browser",
@@ -7673,18 +7675,18 @@ const Nt = Ke(({
7673
7675
  } : ne === "elevenlabs" ? se = {
7674
7676
  service: "elevenlabs",
7675
7677
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
7676
- apiKey: a || G.apiKey,
7677
- defaultVoice: i || G.defaultVoice || Xe.defaultVoice,
7678
- voices: G.voices || Xe.voices
7678
+ apiKey: a || X.apiKey,
7679
+ defaultVoice: i || X.defaultVoice || Ze.defaultVoice,
7680
+ voices: X.voices || Ze.voices
7679
7681
  } : ne === "deepgram" ? se = {
7680
7682
  service: "deepgram",
7681
7683
  endpoint: "https://api.deepgram.com/v1/speak",
7682
- apiKey: a || G.apiKey,
7683
- defaultVoice: i || G.defaultVoice || _e.defaultVoice,
7684
- voices: G.voices || _e.voices
7684
+ apiKey: a || X.apiKey,
7685
+ defaultVoice: i || X.defaultVoice || _e.defaultVoice,
7686
+ voices: X.voices || _e.voices
7685
7687
  } : se = {
7686
- ...G,
7687
- apiKey: a !== null ? a : G.apiKey
7688
+ ...X,
7689
+ apiKey: a !== null ? a : X.apiKey
7688
7690
  };
7689
7691
  const ze = {
7690
7692
  url: n,
@@ -7693,8 +7695,8 @@ const Nt = Ke(({
7693
7695
  ttsLang: ne === "browser" ? "en-US" : o,
7694
7696
  ttsVoice: i || se.defaultVoice,
7695
7697
  lipsyncLang: "en",
7696
- showFullAvatar: u,
7697
- bodyMovement: c,
7698
+ showFullAvatar: c,
7699
+ bodyMovement: u,
7698
7700
  movementIntensity: l
7699
7701
  }, re = {
7700
7702
  ttsEndpoint: se.endpoint,
@@ -7702,69 +7704,76 @@ const Nt = Ke(({
7702
7704
  ttsService: ne,
7703
7705
  lipsyncModules: ["en"],
7704
7706
  cameraView: r
7705
- }, ve = U(async () => {
7707
+ }, Ae = U(async () => {
7706
7708
  if (!(!L.current || f.current))
7707
7709
  try {
7708
7710
  me(!0), ye(null), f.current = new nt(L.current, re), await f.current.showAvatar(ze, (w) => {
7709
7711
  if (w.lengthComputable) {
7710
- const E = Math.min(100, Math.round(w.loaded / w.total * 100));
7711
- d(E);
7712
+ const H = Math.min(100, Math.round(w.loaded / w.total * 100));
7713
+ d(H);
7712
7714
  }
7713
7715
  }), me(!1), he(!0), h(f.current);
7714
- const k = () => {
7716
+ const S = () => {
7715
7717
  document.visibilityState === "visible" ? f.current?.start() : f.current?.stop();
7716
7718
  };
7717
- return document.addEventListener("visibilitychange", k), () => {
7718
- document.removeEventListener("visibilitychange", k);
7719
+ return document.addEventListener("visibilitychange", S), () => {
7720
+ document.removeEventListener("visibilitychange", S);
7719
7721
  };
7720
- } catch (k) {
7721
- console.error("Error initializing TalkingHead:", k), ye(k.message || "Failed to initialize avatar"), me(!1), g(k);
7722
+ } catch (S) {
7723
+ console.error("Error initializing TalkingHead:", S), ye(S.message || "Failed to initialize avatar"), me(!1), g(S);
7722
7724
  }
7723
7725
  }, []);
7724
- Se(() => (ve(), () => {
7726
+ Se(() => (Ae(), () => {
7725
7727
  f.current && (f.current.stop(), f.current.dispose(), f.current = null);
7726
- }), [ve]);
7727
- const Fe = U(async () => {
7728
+ }), [Ae]);
7729
+ const Ee = U(async () => {
7728
7730
  if (f.current)
7729
7731
  try {
7730
- const k = f.current.audioCtx || f.current.audioContext;
7731
- k && (k.state === "suspended" || k.state === "interrupted") && await k.resume();
7732
- } catch (k) {
7733
- console.warn("Failed to resume audio context:", k);
7732
+ const S = f.current.audioCtx || f.current.audioContext;
7733
+ S && (S.state === "suspended" || S.state === "interrupted") && await S.resume();
7734
+ } catch (S) {
7735
+ console.warn("Failed to resume audio context:", S);
7734
7736
  }
7735
- }, []), Oe = U((k) => {
7736
- if (!H)
7737
+ }, []), Be = U((S) => {
7738
+ if (!T)
7737
7739
  return [];
7738
7740
  let w = null;
7739
- if (H._genderSpecific) {
7740
- const E = C(e), ee = H._genderSpecific[E];
7741
- ee && ee[k] ? w = ee[k] : H._genderSpecific.shared && H._genderSpecific.shared[k] && (w = H._genderSpecific.shared[k]);
7741
+ if (T._genderSpecific) {
7742
+ const H = C(e), J = T._genderSpecific[H];
7743
+ if (J && J[S] && Array.isArray(J[S]) && J[S].length > 0 && (w = J[S]), !w && T._genderSpecific.shared && T._genderSpecific.shared[S]) {
7744
+ const W = T._genderSpecific.shared[S];
7745
+ Array.isArray(W) && W.length > 0 && (w = W);
7746
+ }
7742
7747
  }
7743
- return !w && H[k] && (w = H[k]), w ? Array.isArray(w) ? [...w] : typeof w == "string" ? [w] : [] : ((Object.keys(H).length > 0 || H._genderSpecific && Object.keys(H._genderSpecific).length > 0) && console.warn(`⚠️ No animations found for group "${k}". Make sure animations are configured correctly.`), []);
7744
- }, [H, e, C]), He = U((k) => {
7745
- const w = [...k];
7746
- for (let E = w.length - 1; E > 0; E--) {
7747
- const ee = Math.floor(Math.random() * (E + 1));
7748
- [w[E], w[ee]] = [w[ee], w[E]];
7748
+ if (!w && T[S]) {
7749
+ const H = T[S];
7750
+ Array.isArray(H) && H.length > 0 ? w = H : typeof H == "string" && (w = [H]);
7751
+ }
7752
+ return !w || Array.isArray(w) && w.length === 0 ? ((Object.keys(T).length > 0 || T._genderSpecific && Object.keys(T._genderSpecific).length > 0) && console.warn(`⚠️ No animations found for group "${S}" (gender: ${C(e)}). Make sure animations are configured correctly.`), []) : Array.isArray(w) ? [...w] : typeof w == "string" ? [w] : [];
7753
+ }, [T, e, C]), He = U((S) => {
7754
+ const w = [...S];
7755
+ for (let H = w.length - 1; H > 0; H--) {
7756
+ const J = Math.floor(Math.random() * (H + 1));
7757
+ [w[H], w[J]] = [w[J], w[H]];
7749
7758
  }
7750
7759
  return w;
7751
- }, []), we = U((k) => {
7752
- if (Ae.current.length === 0) {
7753
- const E = Oe(k);
7754
- if (E.length === 0)
7760
+ }, []), we = U((S) => {
7761
+ if (Ie.current.length === 0) {
7762
+ const H = Be(S);
7763
+ if (H.length === 0)
7755
7764
  return null;
7756
- Ae.current = He(E), fe.current = [];
7765
+ Ie.current = He(H), fe.current = [];
7757
7766
  }
7758
- const w = Ae.current.shift();
7767
+ const w = Ie.current.shift();
7759
7768
  return w && fe.current.push(w), w;
7760
- }, [Oe, He]), We = U((k) => k ? k.split("/").pop().replace(".fbx", "").replace(/[-_]/g, " ") : "Unknown", []), Be = U((k, w = !1, E = null) => {
7761
- if (!f.current || !K.current || q.current !== k)
7769
+ }, [Be, He]), We = U((S) => S ? S.split("/").pop().replace(".fbx", "").replace(/[-_]/g, " ") : "Unknown", []), Oe = U((S, w = !1, H = null) => {
7770
+ if (!f.current || !K.current || q.current !== S)
7762
7771
  return null;
7763
- const ee = we(k);
7764
- if (ee)
7772
+ const J = we(S);
7773
+ if (J)
7765
7774
  try {
7766
- const j = We(ee);
7767
- console.log(`🎬 Playing animation: "${j}"`);
7775
+ const W = We(J);
7776
+ console.log(`🎬 Playing animation: "${W}"`);
7768
7777
  const ie = () => {
7769
7778
  console.log("🎬 Animation finished, checking if should continue...");
7770
7779
  const le = () => {
@@ -7772,64 +7781,64 @@ const Nt = Ke(({
7772
7781
  return console.log("🎬 No talkingHeadRef, stopping animations"), !1;
7773
7782
  if (!K.current)
7774
7783
  return console.log("🎬 isSpeakingRef is false, stopping animations"), !1;
7775
- if (q.current !== k)
7776
- return console.log(`🎬 Animation group mismatch (${q.current} !== ${k}), stopping animations`), !1;
7777
- const X = f.current, J = X.isAudioPlaying === !0, $ = X.audioPlaylist && X.audioPlaylist.length > 0, ge = X.speechQueue && X.speechQueue.length > 0, de = X.isSpeaking === !0, Ge = de || J || $ || ge;
7784
+ if (q.current !== S)
7785
+ return console.log(`🎬 Animation group mismatch (${q.current} !== ${S}), stopping animations`), !1;
7786
+ const j = f.current, $ = j.isAudioPlaying === !0, ee = j.audioPlaylist && j.audioPlaylist.length > 0, ge = j.speechQueue && j.speechQueue.length > 0, de = j.isSpeaking === !0, Ge = de || $ || ee || ge;
7778
7787
  return console.log("🎬 Still speaking check:", {
7779
7788
  isSpeakingRef: K.current,
7780
7789
  isTalkingHeadSpeaking: de,
7781
- hasAudioPlaying: J,
7782
- hasAudioInPlaylist: $,
7790
+ hasAudioPlaying: $,
7791
+ hasAudioInPlaylist: ee,
7783
7792
  hasItemsInQueue: ge,
7784
7793
  shouldContinue: Ge
7785
7794
  }), Ge;
7786
7795
  };
7787
7796
  le() ? (console.log("🎬 Still speaking, continuing to next animation..."), requestAnimationFrame(() => {
7788
- le() ? (console.log("🎬 Playing next animation..."), Be(k, w, E)) : (console.log("🎬 Speech ended, stopping animations"), K.current = !1, q.current = null, E && E());
7789
- })) : (console.log("🎬 Speech has ended, stopping animations"), K.current = !1, q.current = null, E && E());
7797
+ le() ? (console.log("🎬 Playing next animation..."), Oe(S, w, H)) : (console.log("🎬 Speech ended, stopping animations"), K.current = !1, q.current = null, H && H());
7798
+ })) : (console.log("🎬 Speech has ended, stopping animations"), K.current = !1, q.current = null, H && H());
7790
7799
  };
7791
- return f.current.playAnimation(ee, null, 0, 0, 0.01, w, ie), ee;
7792
- } catch (j) {
7793
- return console.error("Failed to play animation:", j), null;
7800
+ return f.current.playAnimation(J, null, 0, 0, 0.01, w, ie), J;
7801
+ } catch (W) {
7802
+ return console.error("Failed to play animation:", W), null;
7794
7803
  }
7795
7804
  else {
7796
- const j = () => {
7797
- if (!f.current || !K.current || q.current !== k)
7805
+ const W = () => {
7806
+ if (!f.current || !K.current || q.current !== S)
7798
7807
  return !1;
7799
- const le = f.current, ue = le.isAudioPlaying === !0, X = le.audioPlaylist && le.audioPlaylist.length > 0, J = le.speechQueue && le.speechQueue.length > 0;
7800
- return le.isSpeaking === !0 || ue || X || J;
7808
+ const le = f.current, ce = le.isAudioPlaying === !0, j = le.audioPlaylist && le.audioPlaylist.length > 0, $ = le.speechQueue && le.speechQueue.length > 0;
7809
+ return le.isSpeaking === !0 || ce || j || $;
7801
7810
  };
7802
- j() && (Ae.current = [], fe.current = [], j() ? Be(k, w, E) : (K.current = !1, q.current = null));
7811
+ W() && (Ie.current = [], fe.current = [], W() ? Oe(S, w, H) : (K.current = !1, q.current = null));
7803
7812
  }
7804
7813
  return null;
7805
- }, [we, We]), Ve = U(async (k, w = {}) => {
7806
- if (!f.current || !Re || !k || k.trim() === "")
7814
+ }, [we, We]), Ve = U(async (S, w = {}) => {
7815
+ if (!f.current || !Re || !S || S.trim() === "")
7807
7816
  return;
7808
- await Fe();
7809
- const E = w.animationGroup || D;
7810
- E && !w.skipAnimation && (K.current = !0, q.current = E, Ae.current = [], fe.current = [], Be(E));
7817
+ await Ee();
7818
+ const H = w.animationGroup || D;
7819
+ H && !w.skipAnimation && (K.current = !0, q.current = H, Ie.current = [], fe.current = [], Oe(H));
7811
7820
  try {
7812
- R(k), w.onSpeechStart && w.onSpeechStart(k);
7821
+ R(S), w.onSpeechStart && w.onSpeechStart(S);
7813
7822
  } catch (ie) {
7814
7823
  console.warn("Error in onSpeechStart callback:", ie);
7815
7824
  }
7816
- Q.current = { remainingText: null, originalText: null, options: null }, _.current = [], A.current = { text: k, options: w }, M.current && (clearInterval(M.current), M.current = null), I(!1), O.current = !1, te.current = !1;
7817
- const ee = k.split(/[.!?]+/).filter((ie) => ie.trim().length > 0);
7818
- _.current = ee, et.current = 0;
7819
- const j = {
7825
+ Q.current = { remainingText: null, originalText: null, options: null }, _.current = [], I.current = { text: S, options: w }, F.current && (clearInterval(F.current), F.current = null), v(!1), B.current = !1, te.current = !1;
7826
+ const J = S.split(/[.!?]+/).filter((ie) => ie.trim().length > 0);
7827
+ _.current = J, et.current = 0;
7828
+ const W = {
7820
7829
  lipsyncLang: w.lipsyncLang || "en"
7821
7830
  };
7822
7831
  if (f.current) {
7823
7832
  const ie = f.current;
7824
7833
  let le = 0;
7825
- const ue = 1200;
7826
- M.current && (clearInterval(M.current), M.current = null);
7827
- const X = { current: !1 }, J = setInterval(() => {
7828
- if (le++, O.current)
7834
+ const ce = 1200;
7835
+ F.current && (clearInterval(F.current), F.current = null);
7836
+ const j = { current: !1 }, $ = setInterval(() => {
7837
+ if (le++, B.current)
7829
7838
  return;
7830
- if (le > ue) {
7831
- if (J && (clearInterval(J), M.current = null), !X.current && !O.current) {
7832
- X.current = !0, K.current = !1, q.current = null, Ae.current = [], fe.current = [], f.current && (f.current.isSpeaking = !1);
7839
+ if (le > ce) {
7840
+ if ($ && (clearInterval($), F.current = null), !j.current && !B.current) {
7841
+ j.current = !0, K.current = !1, q.current = null, Ie.current = [], fe.current = [], f.current && (f.current.isSpeaking = !1);
7833
7842
  try {
7834
7843
  w.onSpeechEnd && w.onSpeechEnd(), x();
7835
7844
  } catch (Te) {
@@ -7838,12 +7847,12 @@ const Nt = Ke(({
7838
7847
  }
7839
7848
  return;
7840
7849
  }
7841
- const $ = !ie.speechQueue || ie.speechQueue.length === 0, ge = !ie.audioPlaylist || ie.audioPlaylist.length === 0, de = ie.isAudioPlaying === !1;
7842
- ie && !O.current && $ && ge && de && ie.isSpeaking === !1 && !X.current && !O.current && setTimeout(() => {
7850
+ const ee = !ie.speechQueue || ie.speechQueue.length === 0, ge = !ie.audioPlaylist || ie.audioPlaylist.length === 0, de = ie.isAudioPlaying === !1;
7851
+ ie && !B.current && ee && ge && de && ie.isSpeaking === !1 && !j.current && !B.current && setTimeout(() => {
7843
7852
  const Te = f.current;
7844
7853
  if (!Te)
7845
7854
  return;
7846
- !O.current && (!Te.speechQueue || Te.speechQueue.length === 0) && (!Te.audioPlaylist || Te.audioPlaylist.length === 0) && Te.isAudioPlaying === !1 && Te.isSpeaking === !1 && !X.current && !O.current && (X.current = !0, J && (clearInterval(J), M.current = null), K.current = !1, q.current = null, Ae.current = [], fe.current = [], te.current = !0, Te && (Te.isSpeaking = !1), setTimeout(() => {
7855
+ !B.current && (!Te.speechQueue || Te.speechQueue.length === 0) && (!Te.audioPlaylist || Te.audioPlaylist.length === 0) && Te.isAudioPlaying === !1 && Te.isSpeaking === !1 && !j.current && !B.current && (j.current = !0, $ && (clearInterval($), F.current = null), K.current = !1, q.current = null, Ie.current = [], fe.current = [], te.current = !0, Te && (Te.isSpeaking = !1), setTimeout(() => {
7847
7856
  try {
7848
7857
  w.onSpeechEnd && w.onSpeechEnd(), x(), setTimeout(() => {
7849
7858
  te.current = !1;
@@ -7854,90 +7863,90 @@ const Nt = Ke(({
7854
7863
  }, 100));
7855
7864
  }, 200);
7856
7865
  }, 50);
7857
- M.current = J;
7866
+ F.current = $;
7858
7867
  }
7859
7868
  try {
7860
- f.current.speakText(k, j);
7869
+ f.current.speakText(S, W);
7861
7870
  } catch (ie) {
7862
7871
  console.error("Error speaking text:", ie), ye(ie.message || "Failed to speak text");
7863
7872
  }
7864
- }, [Re, x, Fe, D, Be]);
7873
+ }, [Re, x, Ee, D, Oe]);
7865
7874
  Se(() => {
7866
- if (!Re || !F || !f.current)
7875
+ if (!Re || !E || !f.current)
7867
7876
  return;
7868
7877
  Y.current && clearInterval(Y.current);
7869
- const k = () => {
7870
- f.current && !O.current && Be(F);
7878
+ const S = () => {
7879
+ f.current && !B.current && Oe(E);
7871
7880
  };
7872
- return k(), Y.current = setInterval(() => {
7873
- k();
7881
+ return S(), Y.current = setInterval(() => {
7882
+ S();
7874
7883
  }, 12e3 + Math.random() * 3e3), () => {
7875
7884
  Y.current && (clearInterval(Y.current), Y.current = null);
7876
7885
  };
7877
- }, [Re, F, Be]), Se(() => {
7878
- Re && Z && y && f.current && !K.current && !O.current && !te.current && Ve(Z);
7886
+ }, [Re, E, Oe]), Se(() => {
7887
+ Re && Z && y && f.current && !K.current && !B.current && !te.current && Ve(Z);
7879
7888
  }, [Re, Z, y, Ve]);
7880
7889
  const tt = U(() => {
7881
7890
  if (f.current)
7882
7891
  try {
7883
- const k = f.current.isSpeaking || !1, w = [...f.current.audioPlaylist || []], E = [...f.current.speechQueue || []];
7884
- if (k || w.length > 0 || E.length > 0) {
7885
- M.current && (clearInterval(M.current), M.current = null);
7886
- const ee = _.current;
7887
- let j = [];
7892
+ const S = f.current.isSpeaking || !1, w = [...f.current.audioPlaylist || []], H = [...f.current.speechQueue || []];
7893
+ if (S || w.length > 0 || H.length > 0) {
7894
+ F.current && (clearInterval(F.current), F.current = null);
7895
+ const J = _.current;
7896
+ let W = [];
7888
7897
  const ie = f.current.isAudioPlaying || !1;
7889
- if (ee.length > 0) {
7890
- const $ = w.length + E.length, ge = ie ? 1 : 0, de = ee.length - $ - ge, Ge = ie ? de : de + ge;
7891
- Ge < ee.length && (j = ee.slice(Ge));
7898
+ if (J.length > 0) {
7899
+ const ee = w.length + H.length, ge = ie ? 1 : 0, de = J.length - ee - ge, Ge = ie ? de : de + ge;
7900
+ Ge < J.length && (W = J.slice(Ge));
7892
7901
  } else
7893
- w.length > 0 && w.forEach(($) => {
7894
- if ($.text)
7895
- if (Array.isArray($.text)) {
7896
- const ge = $.text.map((de) => de.word).join(" ");
7897
- ge.trim() && j.push(ge);
7898
- } else $.text.trim() && j.push($.text);
7899
- }), E.length > 0 && E.forEach(($) => {
7900
- if ($.text)
7901
- if (Array.isArray($.text)) {
7902
- const ge = $.text.map((de) => de.word).join(" ");
7903
- ge.trim() && j.push(ge);
7904
- } else $.text.trim() && j.push($.text);
7902
+ w.length > 0 && w.forEach((ee) => {
7903
+ if (ee.text)
7904
+ if (Array.isArray(ee.text)) {
7905
+ const ge = ee.text.map((de) => de.word).join(" ");
7906
+ ge.trim() && W.push(ge);
7907
+ } else ee.text.trim() && W.push(ee.text);
7908
+ }), H.length > 0 && H.forEach((ee) => {
7909
+ if (ee.text)
7910
+ if (Array.isArray(ee.text)) {
7911
+ const ge = ee.text.map((de) => de.word).join(" ");
7912
+ ge.trim() && W.push(ge);
7913
+ } else ee.text.trim() && W.push(ee.text);
7905
7914
  });
7906
- const le = j.join(" ");
7915
+ const le = W.join(" ");
7907
7916
  Q.current = {
7908
7917
  remainingText: le || null,
7909
- originalText: A.current?.text || null,
7910
- options: A.current?.options || null,
7918
+ originalText: I.current?.text || null,
7919
+ options: I.current?.options || null,
7911
7920
  // Track if we're pausing mid-sentence (has currently playing audio)
7912
7921
  isMidSentence: w.length > 0
7913
7922
  };
7914
- const X = f.current.isAudioPlaying || !1 ? [...f.current.speechQueue || []] : null;
7923
+ const j = f.current.isAudioPlaying || !1 ? [...f.current.speechQueue || []] : null;
7915
7924
  f.current.speechQueue.length = 0;
7916
- const J = f.current.pauseSpeaking();
7917
- f.current.isSpeaking = !1, J && J.audio && X ? (ke.current = J, ke.current.savedSpeechQueue = X) : ke.current = J, I(!0), O.current = !0;
7925
+ const $ = f.current.pauseSpeaking();
7926
+ f.current.isSpeaking = !1, K.current = !1, q.current = null, $ && $.audio && j ? (ke.current = $, ke.current.savedSpeechQueue = j) : ke.current = $, v(!0), B.current = !0;
7918
7927
  }
7919
- } catch (k) {
7920
- console.warn("Error pausing speech:", k);
7928
+ } catch (S) {
7929
+ console.warn("Error pausing speech:", S);
7921
7930
  }
7922
7931
  }, []), ht = U(async () => {
7923
- if (!(!f.current || !v))
7932
+ if (!(!f.current || !A))
7924
7933
  try {
7925
- if (await Fe(), I(!1), O.current = !1, ke.current && ke.current.audio) {
7934
+ if (await Ee(), v(!1), B.current = !1, ke.current && ke.current.audio) {
7926
7935
  K.current = !0;
7927
- const j = Q.current?.options || A.current?.options || {}, ie = j.animationGroup || D;
7936
+ const W = Q.current?.options || I.current?.options || {}, ie = W.animationGroup || D;
7928
7937
  if (ie && (q.current = ie), ke.current.savedSpeechQueue && (f.current.speechQueue.length = 0, f.current.speechQueue.push(...ke.current.savedSpeechQueue)), f.current.isSpeaking = !0, f.current) {
7929
7938
  const le = f.current;
7930
- let ue = 0;
7931
- const X = 1200, J = { current: !1 };
7932
- M.current && (clearInterval(M.current), M.current = null);
7933
- const $ = setInterval(() => {
7934
- if (ue++, O.current)
7939
+ let ce = 0;
7940
+ const j = 1200, $ = { current: !1 };
7941
+ F.current && (clearInterval(F.current), F.current = null);
7942
+ const ee = setInterval(() => {
7943
+ if (ce++, B.current)
7935
7944
  return;
7936
- if (ue > X) {
7937
- if ($ && (clearInterval($), M.current = null), !J.current && !O.current) {
7938
- J.current = !0, K.current = !1, q.current = null, Ae.current = [], fe.current = [], f.current && (f.current.isSpeaking = !1);
7945
+ if (ce > j) {
7946
+ if (ee && (clearInterval(ee), F.current = null), !$.current && !B.current) {
7947
+ $.current = !0, K.current = !1, q.current = null, Ie.current = [], fe.current = [], f.current && (f.current.isSpeaking = !1);
7939
7948
  try {
7940
- j.onSpeechEnd && j.onSpeechEnd(), x();
7949
+ W.onSpeechEnd && W.onSpeechEnd(), x();
7941
7950
  } catch (Me) {
7942
7951
  console.error("Error in onSpeechEnd callback (timeout):", Me);
7943
7952
  }
@@ -7945,12 +7954,12 @@ const Nt = Ke(({
7945
7954
  return;
7946
7955
  }
7947
7956
  const ge = !le.speechQueue || le.speechQueue.length === 0, de = !le.audioPlaylist || le.audioPlaylist.length === 0, Ge = le.isAudioPlaying === !1;
7948
- le && !O.current && ge && de && Ge && le.isSpeaking === !1 && !J.current && !O.current && setTimeout(() => {
7957
+ le && !B.current && ge && de && Ge && le.isSpeaking === !1 && !$.current && !B.current && setTimeout(() => {
7949
7958
  const Me = f.current;
7950
7959
  if (!Me) return;
7951
- !O.current && (!Me.speechQueue || Me.speechQueue.length === 0) && (!Me.audioPlaylist || Me.audioPlaylist.length === 0) && Me.isAudioPlaying === !1 && Me.isSpeaking === !1 && !J.current && !O.current && (J.current = !0, $ && (clearInterval($), M.current = null), K.current = !1, q.current = null, Ae.current = [], fe.current = [], te.current = !0, Me && (Me.isSpeaking = !1), setTimeout(() => {
7960
+ !B.current && (!Me.speechQueue || Me.speechQueue.length === 0) && (!Me.audioPlaylist || Me.audioPlaylist.length === 0) && Me.isAudioPlaying === !1 && Me.isSpeaking === !1 && !$.current && !B.current && ($.current = !0, ee && (clearInterval(ee), F.current = null), K.current = !1, q.current = null, Ie.current = [], fe.current = [], te.current = !0, Me && (Me.isSpeaking = !1), setTimeout(() => {
7952
7961
  try {
7953
- j.onSpeechEnd && j.onSpeechEnd(), x(), setTimeout(() => {
7962
+ W.onSpeechEnd && W.onSpeechEnd(), x(), setTimeout(() => {
7954
7963
  te.current = !1;
7955
7964
  }, 500);
7956
7965
  } catch (mt) {
@@ -7959,23 +7968,23 @@ const Nt = Ke(({
7959
7968
  }, 100));
7960
7969
  }, 200);
7961
7970
  }, 50);
7962
- M.current = $;
7971
+ F.current = ee;
7963
7972
  }
7964
- await f.current.playAudio(!1, ke.current), ie && !j.skipAnimation && (Ae.current = [], fe.current = [], Be(ie)), ke.current = null;
7973
+ await f.current.playAudio(!1, ke.current), ie && !W.skipAnimation && (Ie.current = [], fe.current = [], Oe(ie)), ke.current = null;
7965
7974
  return;
7966
7975
  }
7967
- const k = Q.current?.remainingText, w = Q.current?.originalText || A.current?.text, E = Q.current?.options || A.current?.options || {}, ee = k || w;
7968
- ee && Ve(ee, E), ke.current = null;
7969
- } catch (k) {
7970
- console.warn("Error resuming speech:", k), I(!1), O.current = !1, ke.current = null;
7976
+ const S = Q.current?.remainingText, w = Q.current?.originalText || I.current?.text, H = Q.current?.options || I.current?.options || {}, J = S || w;
7977
+ J && Ve(J, H), ke.current = null;
7978
+ } catch (S) {
7979
+ console.warn("Error resuming speech:", S), v(!1), B.current = !1, ke.current = null;
7971
7980
  }
7972
- }, [v, Ve, Fe, D, Be]), dt = U(() => {
7981
+ }, [A, Ve, Ee, D, Oe]), dt = U(() => {
7973
7982
  if (f.current) {
7974
- f.current.stopSpeaking(), M.current && (clearInterval(M.current), M.current = null), K.current = !1, q.current = null, Ae.current = [], fe.current = [], I(!1), O.current = !1;
7983
+ f.current.stopSpeaking(), F.current && (clearInterval(F.current), F.current = null), K.current = !1, q.current = null, Ie.current = [], fe.current = [], v(!1), B.current = !1;
7975
7984
  try {
7976
7985
  x();
7977
- } catch (k) {
7978
- console.warn("Error in onSpeechEnd callback (stopSpeaking):", k);
7986
+ } catch (S) {
7987
+ console.warn("Error in onSpeechEnd callback (stopSpeaking):", S);
7979
7988
  }
7980
7989
  }
7981
7990
  }, [x]);
@@ -7984,25 +7993,25 @@ const Nt = Ke(({
7984
7993
  pauseSpeaking: tt,
7985
7994
  resumeSpeaking: ht,
7986
7995
  stopSpeaking: dt,
7987
- resumeAudioContext: Fe,
7988
- isPaused: () => v,
7989
- setMood: (k) => f.current?.setMood(k),
7990
- setBodyMovement: (k) => {
7991
- f.current && f.current.setBodyMovement(k);
7996
+ resumeAudioContext: Ee,
7997
+ isPaused: () => A,
7998
+ setMood: (S) => f.current?.setMood(S),
7999
+ setBodyMovement: (S) => {
8000
+ f.current && f.current.setBodyMovement(S);
7992
8001
  },
7993
- playAnimation: (k, w = !1) => {
7994
- f.current && f.current.playAnimation && f.current.playAnimation(k, null, 10, 0, 0.01, w);
8002
+ playAnimation: (S, w = !1) => {
8003
+ f.current && f.current.playAnimation && f.current.playAnimation(S, null, 10, 0, 0.01, w);
7995
8004
  },
7996
- playRandomAnimation: (k, w = !1) => Be(k, w),
7997
- getRandomAnimation: (k) => getRandomAnimation(k),
7998
- playReaction: (k) => f.current?.playReaction(k),
8005
+ playRandomAnimation: (S, w = !1) => Oe(S, w),
8006
+ getRandomAnimation: (S) => getRandomAnimation(S),
8007
+ playReaction: (S) => f.current?.playReaction(S),
7999
8008
  playCelebration: () => f.current?.playCelebration(),
8000
- setShowFullAvatar: (k) => {
8001
- f.current && (T.current = k, f.current.setShowFullAvatar(k));
8009
+ setShowFullAvatar: (S) => {
8010
+ f.current && (M.current = S, f.current.setShowFullAvatar(S));
8002
8011
  },
8003
8012
  isReady: Re,
8004
8013
  talkingHead: f.current
8005
- })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${S}`, style: V, children: [
8014
+ })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${k}`, style: G, children: [
8006
8015
  /* @__PURE__ */ ae(
8007
8016
  "div",
8008
8017
  {
@@ -8015,7 +8024,7 @@ const Nt = Ke(({
8015
8024
  }
8016
8025
  }
8017
8026
  ),
8018
- Ie && /* @__PURE__ */ ae("div", { className: "loading-overlay", style: {
8027
+ ve && /* @__PURE__ */ ae("div", { className: "loading-overlay", style: {
8019
8028
  position: "absolute",
8020
8029
  top: "50%",
8021
8030
  left: "50%",
@@ -8024,7 +8033,7 @@ const Nt = Ke(({
8024
8033
  fontSize: "18px",
8025
8034
  zIndex: 10
8026
8035
  }, children: "Loading avatar..." }),
8027
- Ee && /* @__PURE__ */ ae("div", { className: "error-overlay", style: {
8036
+ Fe && /* @__PURE__ */ ae("div", { className: "error-overlay", style: {
8028
8037
  position: "absolute",
8029
8038
  top: "50%",
8030
8039
  left: "50%",
@@ -8035,7 +8044,7 @@ const Nt = Ke(({
8035
8044
  zIndex: 10,
8036
8045
  padding: "20px",
8037
8046
  borderRadius: "8px"
8038
- }, children: Ee })
8047
+ }, children: Fe })
8039
8048
  ] });
8040
8049
  });
8041
8050
  Nt.displayName = "SimpleTalkingAvatar";
@@ -8053,9 +8062,9 @@ const Ut = Ke(({
8053
8062
  },
8054
8063
  onCustomAction: a = () => {
8055
8064
  },
8056
- autoStart: c = !1
8065
+ autoStart: u = !1
8057
8066
  }, l) => {
8058
- const u = W(null), r = W({
8067
+ const c = V(null), r = V({
8059
8068
  currentModuleIndex: 0,
8060
8069
  currentLessonIndex: 0,
8061
8070
  currentQuestionIndex: 0,
@@ -8065,18 +8074,18 @@ const Ut = Ke(({
8065
8074
  curriculumCompleted: !1,
8066
8075
  score: 0,
8067
8076
  totalQuestions: 0
8068
- }), h = W({
8077
+ }), h = V({
8069
8078
  onLessonStart: t,
8070
8079
  onLessonComplete: o,
8071
8080
  onQuestionAnswer: s,
8072
8081
  onCurriculumComplete: i,
8073
8082
  onCustomAction: a
8074
- }), d = W(null), g = W(null), R = W(null), x = W(null), S = W(null), V = W(null), m = W(null), D = W(Z?.curriculum || {
8083
+ }), d = V(null), g = V(null), R = V(null), x = V(null), k = V(null), G = V(null), m = V(null), D = V(Z?.curriculum || {
8075
8084
  title: "Default Curriculum",
8076
8085
  description: "No curriculum data provided",
8077
8086
  language: "en",
8078
8087
  modules: []
8079
- }), F = W({
8088
+ }), E = V({
8080
8089
  avatarUrl: n.avatarUrl || "/avatars/brunette.glb",
8081
8090
  avatarBody: n.avatarBody || "F",
8082
8091
  mood: n.mood || "happy",
@@ -8104,7 +8113,7 @@ const Ut = Ke(({
8104
8113
  description: "No curriculum data provided",
8105
8114
  language: "en",
8106
8115
  modules: []
8107
- }, F.current = {
8116
+ }, E.current = {
8108
8117
  avatarUrl: n.avatarUrl || "/avatars/brunette.glb",
8109
8118
  avatarBody: n.avatarBody || "F",
8110
8119
  mood: n.mood || "happy",
@@ -8119,32 +8128,32 @@ const Ut = Ke(({
8119
8128
  lipsyncLang: "en"
8120
8129
  };
8121
8130
  }, [Z, n, e]);
8122
- const y = U(() => (D.current || { modules: [] }).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex], []), P = U(() => y()?.questions[r.current.currentQuestionIndex], [y]), L = U((v, I) => I.type === "multiple_choice" || I.type === "true_false" ? v === I.answer : I.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), f = U(() => {
8131
+ const y = U(() => (D.current || { modules: [] }).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex], []), P = U(() => y()?.questions[r.current.currentQuestionIndex], [y]), L = U((A, v) => v.type === "multiple_choice" || v.type === "true_false" ? A === v.answer : v.type === "code_test" && typeof A == "object" && A !== null ? A.passed === !0 : !1, []), f = U(() => {
8123
8132
  r.current.lessonCompleted = !0, r.current.isQuestionMode = !1;
8124
- const v = r.current.totalQuestions > 0 ? Math.round(r.current.score / r.current.totalQuestions * 100) : 100;
8125
- let I = "Congratulations! You've completed this lesson";
8126
- if (r.current.totalQuestions > 0 ? I += ` You got ${r.current.score} correct out of ${r.current.totalQuestions} question${r.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : I += "! ", v >= 80 ? I += "Excellent work! You have a great understanding of this topic." : v >= 60 ? I += "Good job! You understand most of the concepts." : I += "Keep practicing! You're making progress.", h.current.onLessonComplete({
8133
+ const A = r.current.totalQuestions > 0 ? Math.round(r.current.score / r.current.totalQuestions * 100) : 100;
8134
+ let v = "Congratulations! You've completed this lesson";
8135
+ if (r.current.totalQuestions > 0 ? v += ` You got ${r.current.score} correct out of ${r.current.totalQuestions} question${r.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${A} percent. ` : v += "! ", A >= 80 ? v += "Excellent work! You have a great understanding of this topic." : A >= 60 ? v += "Good job! You understand most of the concepts." : v += "Keep practicing! You're making progress.", h.current.onLessonComplete({
8127
8136
  moduleIndex: r.current.currentModuleIndex,
8128
8137
  lessonIndex: r.current.currentLessonIndex,
8129
8138
  score: r.current.score,
8130
8139
  totalQuestions: r.current.totalQuestions,
8131
- percentage: v
8140
+ percentage: A
8132
8141
  }), h.current.onCustomAction({
8133
8142
  type: "lessonComplete",
8134
8143
  moduleIndex: r.current.currentModuleIndex,
8135
8144
  lessonIndex: r.current.currentLessonIndex,
8136
8145
  score: r.current.score,
8137
8146
  totalQuestions: r.current.totalQuestions,
8138
- percentage: v
8139
- }), u.current) {
8140
- if (u.current.setMood("happy"), e.lessonComplete)
8147
+ percentage: A
8148
+ }), c.current) {
8149
+ if (c.current.setMood("happy"), e.lessonComplete)
8141
8150
  try {
8142
- u.current.playAnimation(e.lessonComplete, !0);
8151
+ c.current.playAnimation(e.lessonComplete, !0);
8143
8152
  } catch {
8144
- u.current.playCelebration();
8153
+ c.current.playCelebration();
8145
8154
  }
8146
- const H = D.current || { modules: [] }, B = H.modules[r.current.currentModuleIndex], Y = r.current.currentLessonIndex < (B?.lessons?.length || 0) - 1, K = r.current.currentModuleIndex < (H.modules?.length || 0) - 1, q = Y || K, te = F.current || { lipsyncLang: "en" };
8147
- u.current.speakText(I, {
8155
+ const T = D.current || { modules: [] }, O = T.modules[r.current.currentModuleIndex], Y = r.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, K = r.current.currentModuleIndex < (T.modules?.length || 0) - 1, q = Y || K, te = E.current || { lipsyncLang: "en" };
8156
+ c.current.speakText(v, {
8148
8157
  lipsyncLang: te.lipsyncLang,
8149
8158
  onSpeechEnd: () => {
8150
8159
  h.current.onCustomAction({
@@ -8153,118 +8162,118 @@ const Ut = Ke(({
8153
8162
  lessonIndex: r.current.currentLessonIndex,
8154
8163
  score: r.current.score,
8155
8164
  totalQuestions: r.current.totalQuestions,
8156
- percentage: v,
8165
+ percentage: A,
8157
8166
  hasNextLesson: q
8158
8167
  });
8159
8168
  }
8160
8169
  });
8161
8170
  }
8162
- }, [e.lessonComplete]), T = U(() => {
8171
+ }, [e.lessonComplete]), M = U(() => {
8163
8172
  r.current.curriculumCompleted = !0;
8164
- const v = D.current || { modules: [] };
8173
+ const A = D.current || { modules: [] };
8165
8174
  if (h.current.onCurriculumComplete({
8166
- modules: v.modules.length,
8167
- totalLessons: v.modules.reduce((I, H) => I + H.lessons.length, 0)
8168
- }), u.current) {
8169
- if (u.current.setMood("celebrating"), e.curriculumComplete)
8175
+ modules: A.modules.length,
8176
+ totalLessons: A.modules.reduce((v, T) => v + T.lessons.length, 0)
8177
+ }), c.current) {
8178
+ if (c.current.setMood("celebrating"), e.curriculumComplete)
8170
8179
  try {
8171
- u.current.playAnimation(e.curriculumComplete, !0);
8180
+ c.current.playAnimation(e.curriculumComplete, !0);
8172
8181
  } catch {
8173
- u.current.playCelebration();
8182
+ c.current.playCelebration();
8174
8183
  }
8175
- const I = F.current || { lipsyncLang: "en" };
8176
- u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: I.lipsyncLang });
8184
+ const v = E.current || { lipsyncLang: "en" };
8185
+ c.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: v.lipsyncLang });
8177
8186
  }
8178
- }, [e.curriculumComplete]), A = U(() => {
8179
- const v = y();
8180
- r.current.isQuestionMode = !0, r.current.currentQuestionIndex = 0, r.current.totalQuestions = v?.questions?.length || 0, r.current.score = 0;
8181
- const I = P();
8182
- I && h.current.onCustomAction({
8187
+ }, [e.curriculumComplete]), I = U(() => {
8188
+ const A = y();
8189
+ r.current.isQuestionMode = !0, r.current.currentQuestionIndex = 0, r.current.totalQuestions = A?.questions?.length || 0, r.current.score = 0;
8190
+ const v = P();
8191
+ v && h.current.onCustomAction({
8183
8192
  type: "questionStart",
8184
8193
  moduleIndex: r.current.currentModuleIndex,
8185
8194
  lessonIndex: r.current.currentLessonIndex,
8186
8195
  questionIndex: r.current.currentQuestionIndex,
8187
8196
  totalQuestions: r.current.totalQuestions,
8188
- question: I,
8197
+ question: v,
8189
8198
  score: r.current.score
8190
8199
  });
8191
- const H = () => {
8192
- if (!u.current || !I) return;
8193
- if (u.current.setMood("happy"), e.questionStart)
8200
+ const T = () => {
8201
+ if (!c.current || !v) return;
8202
+ if (c.current.setMood("happy"), e.questionStart)
8194
8203
  try {
8195
- u.current.playAnimation(e.questionStart, !0);
8204
+ c.current.playAnimation(e.questionStart, !0);
8196
8205
  } catch (Y) {
8197
8206
  console.warn("Failed to play questionStart animation:", Y);
8198
8207
  }
8199
- const B = F.current || { lipsyncLang: "en" };
8200
- I.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${I.question}`, { lipsyncLang: B.lipsyncLang }) : I.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`, { lipsyncLang: B.lipsyncLang }) : I.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${I.question}`, { lipsyncLang: B.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`, { lipsyncLang: B.lipsyncLang });
8208
+ const O = E.current || { lipsyncLang: "en" };
8209
+ v.type === "code_test" ? c.current.speakText(`Let's test your coding skills! Here's your first challenge: ${v.question}`, { lipsyncLang: O.lipsyncLang }) : v.type === "multiple_choice" ? c.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: O.lipsyncLang }) : v.type === "true_false" ? c.current.speakText(`Let's start with some true or false questions. First question: ${v.question}`, { lipsyncLang: O.lipsyncLang }) : c.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: O.lipsyncLang });
8201
8210
  };
8202
- if (u.current && u.current.isReady && I)
8203
- H();
8204
- else if (u.current && u.current.isReady) {
8205
- const B = F.current || { lipsyncLang: "en" };
8206
- u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: B.lipsyncLang });
8211
+ if (c.current && c.current.isReady && v)
8212
+ T();
8213
+ else if (c.current && c.current.isReady) {
8214
+ const O = E.current || { lipsyncLang: "en" };
8215
+ c.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: O.lipsyncLang });
8207
8216
  } else {
8208
- const B = setInterval(() => {
8209
- u.current && u.current.isReady && (clearInterval(B), I && H());
8217
+ const O = setInterval(() => {
8218
+ c.current && c.current.isReady && (clearInterval(O), v && T());
8210
8219
  }, 100);
8211
8220
  setTimeout(() => {
8212
- clearInterval(B);
8221
+ clearInterval(O);
8213
8222
  }, 5e3);
8214
8223
  }
8215
- }, [e.questionStart, y, P]), M = U(() => {
8216
- const v = y();
8217
- if (r.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
8218
- u.current && u.current.stopSpeaking && u.current.stopSpeaking(), r.current.currentQuestionIndex += 1;
8219
- const I = P();
8220
- I && h.current.onCustomAction({
8224
+ }, [e.questionStart, y, P]), F = U(() => {
8225
+ const A = y();
8226
+ if (r.current.currentQuestionIndex < (A?.questions?.length || 0) - 1) {
8227
+ c.current && c.current.stopSpeaking && c.current.stopSpeaking(), r.current.currentQuestionIndex += 1;
8228
+ const v = P();
8229
+ v && h.current.onCustomAction({
8221
8230
  type: "nextQuestion",
8222
8231
  moduleIndex: r.current.currentModuleIndex,
8223
8232
  lessonIndex: r.current.currentLessonIndex,
8224
8233
  questionIndex: r.current.currentQuestionIndex,
8225
8234
  totalQuestions: r.current.totalQuestions,
8226
- question: I,
8235
+ question: v,
8227
8236
  score: r.current.score
8228
8237
  });
8229
- const H = () => {
8230
- if (!u.current || !I) return;
8231
- if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
8238
+ const T = () => {
8239
+ if (!c.current || !v) return;
8240
+ if (c.current.setMood("happy"), c.current.setBodyMovement("idle"), e.nextQuestion)
8232
8241
  try {
8233
- u.current.playAnimation(e.nextQuestion, !0);
8242
+ c.current.playAnimation(e.nextQuestion, !0);
8234
8243
  } catch (te) {
8235
8244
  console.warn("Failed to play nextQuestion animation:", te);
8236
8245
  }
8237
- const B = F.current || { lipsyncLang: "en" }, K = y()?.questions?.length || 0, q = r.current.currentQuestionIndex >= K - 1;
8238
- if (I.type === "code_test") {
8239
- const te = q ? `Great! Here's your final coding challenge: ${I.question}` : `Great! Now let's move on to your next coding challenge: ${I.question}`;
8240
- u.current.speakText(te, {
8241
- lipsyncLang: B.lipsyncLang
8246
+ const O = E.current || { lipsyncLang: "en" }, K = y()?.questions?.length || 0, q = r.current.currentQuestionIndex >= K - 1;
8247
+ if (v.type === "code_test") {
8248
+ const te = q ? `Great! Here's your final coding challenge: ${v.question}` : `Great! Now let's move on to your next coding challenge: ${v.question}`;
8249
+ c.current.speakText(te, {
8250
+ lipsyncLang: O.lipsyncLang
8242
8251
  });
8243
- } else if (I.type === "multiple_choice") {
8244
- const te = q ? `Alright! Here's your final question: ${I.question}` : `Alright! Here's your next question: ${I.question}`;
8245
- u.current.speakText(te, {
8246
- lipsyncLang: B.lipsyncLang
8252
+ } else if (v.type === "multiple_choice") {
8253
+ const te = q ? `Alright! Here's your final question: ${v.question}` : `Alright! Here's your next question: ${v.question}`;
8254
+ c.current.speakText(te, {
8255
+ lipsyncLang: O.lipsyncLang
8247
8256
  });
8248
- } else if (I.type === "true_false") {
8249
- const te = q ? `Now let's try this final one: ${I.question}` : `Now let's try this one: ${I.question}`;
8250
- u.current.speakText(te, {
8251
- lipsyncLang: B.lipsyncLang
8257
+ } else if (v.type === "true_false") {
8258
+ const te = q ? `Now let's try this final one: ${v.question}` : `Now let's try this one: ${v.question}`;
8259
+ c.current.speakText(te, {
8260
+ lipsyncLang: O.lipsyncLang
8252
8261
  });
8253
8262
  } else {
8254
- const te = q ? `Here's your final question: ${I.question}` : `Here's the next question: ${I.question}`;
8255
- u.current.speakText(te, {
8256
- lipsyncLang: B.lipsyncLang
8263
+ const te = q ? `Here's your final question: ${v.question}` : `Here's the next question: ${v.question}`;
8264
+ c.current.speakText(te, {
8265
+ lipsyncLang: O.lipsyncLang
8257
8266
  });
8258
8267
  }
8259
8268
  };
8260
- if (u.current && u.current.isReady && I)
8261
- H();
8262
- else if (I) {
8263
- const B = setInterval(() => {
8264
- u.current && u.current.isReady && (clearInterval(B), H());
8269
+ if (c.current && c.current.isReady && v)
8270
+ T();
8271
+ else if (v) {
8272
+ const O = setInterval(() => {
8273
+ c.current && c.current.isReady && (clearInterval(O), T());
8265
8274
  }, 100);
8266
8275
  setTimeout(() => {
8267
- clearInterval(B);
8276
+ clearInterval(O);
8268
8277
  }, 5e3);
8269
8278
  }
8270
8279
  } else
@@ -8275,11 +8284,11 @@ const Ut = Ke(({
8275
8284
  totalQuestions: r.current.totalQuestions,
8276
8285
  score: r.current.score
8277
8286
  });
8278
- }, [e.nextQuestion, y, P]), O = U(() => {
8279
- const v = D.current || { modules: [] }, I = v.modules[r.current.currentModuleIndex];
8280
- if (r.current.currentLessonIndex < (I?.lessons?.length || 0) - 1) {
8287
+ }, [e.nextQuestion, y, P]), B = U(() => {
8288
+ const A = D.current || { modules: [] }, v = A.modules[r.current.currentModuleIndex];
8289
+ if (r.current.currentLessonIndex < (v?.lessons?.length || 0) - 1) {
8281
8290
  r.current.currentLessonIndex += 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0;
8282
- const B = v.modules[r.current.currentModuleIndex], Y = r.current.currentLessonIndex < (B?.lessons?.length || 0) - 1, K = r.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = Y || K;
8291
+ const O = A.modules[r.current.currentModuleIndex], Y = r.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, K = r.current.currentModuleIndex < (A.modules?.length || 0) - 1, q = Y || K;
8283
8292
  h.current.onCustomAction({
8284
8293
  type: "lessonStart",
8285
8294
  moduleIndex: r.current.currentModuleIndex,
@@ -8289,10 +8298,10 @@ const Ut = Ke(({
8289
8298
  moduleIndex: r.current.currentModuleIndex,
8290
8299
  lessonIndex: r.current.currentLessonIndex,
8291
8300
  lesson: y()
8292
- }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8293
- } else if (r.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
8301
+ }), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
8302
+ } else if (r.current.currentModuleIndex < (A.modules?.length || 0) - 1) {
8294
8303
  r.current.currentModuleIndex += 1, r.current.currentLessonIndex = 0, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0;
8295
- const Y = v.modules[r.current.currentModuleIndex], K = r.current.currentLessonIndex < (Y?.lessons?.length || 0) - 1, q = r.current.currentModuleIndex < (v.modules?.length || 0) - 1, te = K || q;
8304
+ const Y = A.modules[r.current.currentModuleIndex], K = r.current.currentLessonIndex < (Y?.lessons?.length || 0) - 1, q = r.current.currentModuleIndex < (A.modules?.length || 0) - 1, te = K || q;
8296
8305
  h.current.onCustomAction({
8297
8306
  type: "lessonStart",
8298
8307
  moduleIndex: r.current.currentModuleIndex,
@@ -8302,80 +8311,80 @@ const Ut = Ke(({
8302
8311
  moduleIndex: r.current.currentModuleIndex,
8303
8312
  lessonIndex: r.current.currentLessonIndex,
8304
8313
  lesson: y()
8305
- }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8314
+ }), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
8306
8315
  } else
8307
- S.current && S.current();
8316
+ k.current && k.current();
8308
8317
  }, []), Q = U(() => {
8309
- const v = y();
8310
- let I = null;
8311
- if (v?.avatar_script && v?.body) {
8312
- const H = v.avatar_script.trim(), B = v.body.trim(), Y = H.match(/[.!?]$/) ? " " : ". ";
8313
- I = `${H}${Y}${B}`;
8318
+ const A = y();
8319
+ let v = null;
8320
+ if (A?.avatar_script && A?.body) {
8321
+ const T = A.avatar_script.trim(), O = A.body.trim(), Y = T.match(/[.!?]$/) ? " " : ". ";
8322
+ v = `${T}${Y}${O}`;
8314
8323
  } else
8315
- I = v?.avatar_script || v?.body || null;
8316
- if (u.current && u.current.isReady && I) {
8317
- r.current.isTeaching = !0, r.current.isQuestionMode = !1, r.current.score = 0, r.current.totalQuestions = 0, u.current.setMood("happy");
8318
- let H = !1;
8324
+ v = A?.avatar_script || A?.body || null;
8325
+ if (c.current && c.current.isReady && v) {
8326
+ r.current.isTeaching = !0, r.current.isQuestionMode = !1, r.current.score = 0, r.current.totalQuestions = 0, c.current.setMood("happy");
8327
+ let T = !1;
8319
8328
  if (e.teaching)
8320
8329
  try {
8321
- u.current.playAnimation(e.teaching, !0), H = !0;
8330
+ c.current.playAnimation(e.teaching, !0), T = !0;
8322
8331
  } catch (Y) {
8323
8332
  console.warn("Failed to play teaching animation:", Y);
8324
8333
  }
8325
- H || u.current.setBodyMovement("gesturing");
8326
- const B = F.current || { lipsyncLang: "en" };
8334
+ T || c.current.setBodyMovement("gesturing");
8335
+ const O = E.current || { lipsyncLang: "en" };
8327
8336
  h.current.onLessonStart({
8328
8337
  moduleIndex: r.current.currentModuleIndex,
8329
8338
  lessonIndex: r.current.currentLessonIndex,
8330
- lesson: v
8339
+ lesson: A
8331
8340
  }), h.current.onCustomAction({
8332
8341
  type: "teachingStart",
8333
8342
  moduleIndex: r.current.currentModuleIndex,
8334
8343
  lessonIndex: r.current.currentLessonIndex,
8335
- lesson: v
8336
- }), u.current.speakText(I, {
8337
- lipsyncLang: B.lipsyncLang,
8344
+ lesson: A
8345
+ }), c.current.speakText(v, {
8346
+ lipsyncLang: O.lipsyncLang,
8338
8347
  onSpeechEnd: () => {
8339
8348
  r.current.isTeaching = !1, h.current.onCustomAction({
8340
8349
  type: "teachingComplete",
8341
8350
  moduleIndex: r.current.currentModuleIndex,
8342
8351
  lessonIndex: r.current.currentLessonIndex,
8343
- lesson: v,
8344
- hasQuestions: v.questions && v.questions.length > 0
8345
- }), v?.code_example && h.current.onCustomAction({
8352
+ lesson: A,
8353
+ hasQuestions: A.questions && A.questions.length > 0
8354
+ }), A?.code_example && h.current.onCustomAction({
8346
8355
  type: "codeExampleReady",
8347
8356
  moduleIndex: r.current.currentModuleIndex,
8348
8357
  lessonIndex: r.current.currentLessonIndex,
8349
- lesson: v,
8350
- codeExample: v.code_example
8358
+ lesson: A,
8359
+ codeExample: A.code_example
8351
8360
  });
8352
8361
  }
8353
8362
  });
8354
8363
  }
8355
- }, [e.teaching, y]), _ = U((v) => {
8356
- const I = P(), H = L(v, I);
8357
- if (H && (r.current.score += 1), h.current.onQuestionAnswer({
8364
+ }, [e.teaching, y]), _ = U((A) => {
8365
+ const v = P(), T = L(A, v);
8366
+ if (T && (r.current.score += 1), h.current.onQuestionAnswer({
8358
8367
  moduleIndex: r.current.currentModuleIndex,
8359
8368
  lessonIndex: r.current.currentLessonIndex,
8360
8369
  questionIndex: r.current.currentQuestionIndex,
8361
- answer: v,
8362
- isCorrect: H,
8363
- question: I
8364
- }), u.current)
8365
- if (H) {
8366
- if (u.current.setMood("happy"), e.correct)
8370
+ answer: A,
8371
+ isCorrect: T,
8372
+ question: v
8373
+ }), c.current)
8374
+ if (T) {
8375
+ if (c.current.setMood("happy"), e.correct)
8367
8376
  try {
8368
- u.current.playReaction("happy");
8377
+ c.current.playReaction("happy");
8369
8378
  } catch {
8370
- u.current.setBodyMovement("happy");
8379
+ c.current.setBodyMovement("happy");
8371
8380
  }
8372
- u.current.setBodyMovement("gesturing");
8381
+ c.current.setBodyMovement("gesturing");
8373
8382
  const Y = y()?.questions?.length || 0;
8374
8383
  r.current.currentQuestionIndex >= Y - 1;
8375
8384
  const K = r.current.currentQuestionIndex < Y - 1;
8376
8385
  console.log("[CurriculumLearning] Answer feedback - questionIndex:", r.current.currentQuestionIndex, "totalQuestions:", Y, "hasNextQuestion:", K);
8377
- const q = I.type === "code_test" ? `Great job! Your code passed all the tests! ${I.explanation || ""}` : `Excellent! That's correct! ${I.explanation || ""}`, te = F.current || { lipsyncLang: "en" };
8378
- u.current.speakText(q, {
8386
+ const q = v.type === "code_test" ? `Great job! Your code passed all the tests! ${v.explanation || ""}` : `Excellent! That's correct! ${v.explanation || ""}`, te = E.current || { lipsyncLang: "en" };
8387
+ c.current.speakText(q, {
8379
8388
  lipsyncLang: te.lipsyncLang,
8380
8389
  onSpeechEnd: () => {
8381
8390
  h.current.onCustomAction({
@@ -8391,17 +8400,17 @@ const Ut = Ke(({
8391
8400
  }
8392
8401
  });
8393
8402
  } else {
8394
- if (u.current.setMood("sad"), e.incorrect)
8403
+ if (c.current.setMood("sad"), e.incorrect)
8395
8404
  try {
8396
- u.current.playAnimation(e.incorrect, !0);
8405
+ c.current.playAnimation(e.incorrect, !0);
8397
8406
  } catch {
8398
- u.current.setBodyMovement("idle");
8407
+ c.current.setBodyMovement("idle");
8399
8408
  }
8400
- u.current.setBodyMovement("gesturing");
8409
+ c.current.setBodyMovement("gesturing");
8401
8410
  const Y = y()?.questions?.length || 0, K = r.current.currentQuestionIndex >= Y - 1, q = r.current.currentQuestionIndex < Y - 1;
8402
8411
  console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", r.current.currentQuestionIndex, "totalQuestions:", Y, "hasNextQuestion:", q);
8403
- const te = I.type === "code_test" ? `Your code didn't pass all the tests. ${I.explanation || "Try again!"}` : `Not quite right, but don't worry! ${I.explanation || ""}${K ? "" : " Let's move on to the next question."}`, fe = F.current || { lipsyncLang: "en" };
8404
- u.current.speakText(te, {
8412
+ const te = v.type === "code_test" ? `Your code didn't pass all the tests. ${v.explanation || "Try again!"}` : `Not quite right, but don't worry! ${v.explanation || ""}${K ? "" : " Let's move on to the next question."}`, fe = E.current || { lipsyncLang: "en" };
8413
+ c.current.speakText(te, {
8405
8414
  lipsyncLang: fe.lipsyncLang,
8406
8415
  onSpeechEnd: () => {
8407
8416
  h.current.onCustomAction({
@@ -8424,78 +8433,78 @@ const Ut = Ke(({
8424
8433
  moduleIndex: r.current.currentModuleIndex,
8425
8434
  lessonIndex: r.current.currentLessonIndex,
8426
8435
  questionIndex: r.current.currentQuestionIndex,
8427
- isCorrect: H,
8436
+ isCorrect: T,
8428
8437
  hasNextQuestion: r.current.currentQuestionIndex < Y - 1,
8429
8438
  score: r.current.score,
8430
8439
  totalQuestions: r.current.totalQuestions,
8431
8440
  avatarNotReady: !0
8432
8441
  });
8433
8442
  }
8434
- }, [e.correct, e.incorrect, P, y, L]), Ie = U((v) => {
8435
- const I = P();
8436
- if (!v || typeof v != "object") {
8443
+ }, [e.correct, e.incorrect, P, y, L]), ve = U((A) => {
8444
+ const v = P();
8445
+ if (!A || typeof A != "object") {
8437
8446
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
8438
8447
  return;
8439
8448
  }
8440
- if (I?.type !== "code_test") {
8449
+ if (v?.type !== "code_test") {
8441
8450
  console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
8442
8451
  return;
8443
8452
  }
8444
- const H = {
8445
- passed: v.passed === !0,
8446
- results: v.results || [],
8447
- output: v.output || "",
8448
- error: v.error || null,
8449
- executionTime: v.executionTime || null,
8450
- testCount: v.testCount || 0,
8451
- passedCount: v.passedCount || 0,
8452
- failedCount: v.failedCount || 0
8453
+ const T = {
8454
+ passed: A.passed === !0,
8455
+ results: A.results || [],
8456
+ output: A.output || "",
8457
+ error: A.error || null,
8458
+ executionTime: A.executionTime || null,
8459
+ testCount: A.testCount || 0,
8460
+ passedCount: A.passedCount || 0,
8461
+ failedCount: A.failedCount || 0
8453
8462
  };
8454
8463
  h.current.onCustomAction({
8455
8464
  type: "codeTestSubmitted",
8456
8465
  moduleIndex: r.current.currentModuleIndex,
8457
8466
  lessonIndex: r.current.currentLessonIndex,
8458
8467
  questionIndex: r.current.currentQuestionIndex,
8459
- testResult: H,
8460
- question: I
8461
- }), m.current && m.current(H);
8468
+ testResult: T,
8469
+ question: v
8470
+ }), m.current && m.current(T);
8462
8471
  }, [P, L]), me = U(() => {
8463
8472
  if (r.current.currentQuestionIndex > 0) {
8464
8473
  r.current.currentQuestionIndex -= 1;
8465
- const v = P();
8466
- v && h.current.onCustomAction({
8474
+ const A = P();
8475
+ A && h.current.onCustomAction({
8467
8476
  type: "questionStart",
8468
8477
  moduleIndex: r.current.currentModuleIndex,
8469
8478
  lessonIndex: r.current.currentLessonIndex,
8470
8479
  questionIndex: r.current.currentQuestionIndex,
8471
8480
  totalQuestions: r.current.totalQuestions,
8472
- question: v,
8481
+ question: A,
8473
8482
  score: r.current.score
8474
8483
  });
8475
- const I = () => {
8476
- if (!u.current || !v) return;
8477
- u.current.setMood("happy"), u.current.setBodyMovement("idle");
8478
- const H = F.current || { lipsyncLang: "en" };
8479
- v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
8480
- lipsyncLang: H.lipsyncLang
8481
- }) : u.current.speakText(`Going back to: ${v.question}`, {
8482
- lipsyncLang: H.lipsyncLang
8484
+ const v = () => {
8485
+ if (!c.current || !A) return;
8486
+ c.current.setMood("happy"), c.current.setBodyMovement("idle");
8487
+ const T = E.current || { lipsyncLang: "en" };
8488
+ A.type === "code_test" ? c.current.speakText(`Let's go back to this coding challenge: ${A.question}`, {
8489
+ lipsyncLang: T.lipsyncLang
8490
+ }) : c.current.speakText(`Going back to: ${A.question}`, {
8491
+ lipsyncLang: T.lipsyncLang
8483
8492
  });
8484
8493
  };
8485
- if (u.current && u.current.isReady && v)
8486
- I();
8487
- else if (v) {
8488
- const H = setInterval(() => {
8489
- u.current && u.current.isReady && (clearInterval(H), I());
8494
+ if (c.current && c.current.isReady && A)
8495
+ v();
8496
+ else if (A) {
8497
+ const T = setInterval(() => {
8498
+ c.current && c.current.isReady && (clearInterval(T), v());
8490
8499
  }, 100);
8491
8500
  setTimeout(() => {
8492
- clearInterval(H);
8501
+ clearInterval(T);
8493
8502
  }, 5e3);
8494
8503
  }
8495
8504
  }
8496
- }, [P]), Ee = U(() => {
8497
- const v = D.current || { modules: [] };
8498
- if (v.modules[r.current.currentModuleIndex], r.current.currentLessonIndex > 0)
8505
+ }, [P]), Fe = U(() => {
8506
+ const A = D.current || { modules: [] };
8507
+ if (A.modules[r.current.currentModuleIndex], r.current.currentLessonIndex > 0)
8499
8508
  r.current.currentLessonIndex -= 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0, h.current.onCustomAction({
8500
8509
  type: "lessonStart",
8501
8510
  moduleIndex: r.current.currentModuleIndex,
@@ -8504,10 +8513,10 @@ const Ut = Ke(({
8504
8513
  moduleIndex: r.current.currentModuleIndex,
8505
8514
  lessonIndex: r.current.currentLessonIndex,
8506
8515
  lesson: y()
8507
- }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8516
+ }), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
8508
8517
  else if (r.current.currentModuleIndex > 0) {
8509
- const B = v.modules[r.current.currentModuleIndex - 1];
8510
- r.current.currentModuleIndex -= 1, r.current.currentLessonIndex = (B?.lessons?.length || 1) - 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0, h.current.onCustomAction({
8518
+ const O = A.modules[r.current.currentModuleIndex - 1];
8519
+ r.current.currentModuleIndex -= 1, r.current.currentLessonIndex = (O?.lessons?.length || 1) - 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0, h.current.onCustomAction({
8511
8520
  type: "lessonStart",
8512
8521
  moduleIndex: r.current.currentModuleIndex,
8513
8522
  lessonIndex: r.current.currentLessonIndex
@@ -8515,87 +8524,87 @@ const Ut = Ke(({
8515
8524
  moduleIndex: r.current.currentModuleIndex,
8516
8525
  lessonIndex: r.current.currentLessonIndex,
8517
8526
  lesson: y()
8518
- }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8527
+ }), c.current && (c.current.setMood("happy"), c.current.setBodyMovement("idle"));
8519
8528
  }
8520
8529
  }, [y]), ye = U(() => {
8521
8530
  r.current.currentModuleIndex = 0, r.current.currentLessonIndex = 0, r.current.currentQuestionIndex = 0, r.current.isTeaching = !1, r.current.isQuestionMode = !1, r.current.lessonCompleted = !1, r.current.curriculumCompleted = !1, r.current.score = 0, r.current.totalQuestions = 0;
8522
- }, []), Re = U((v) => {
8523
- console.log("Avatar is ready!", v);
8524
- const I = y(), H = I?.avatar_script || I?.body;
8525
- c && H && setTimeout(() => {
8531
+ }, []), Re = U((A) => {
8532
+ console.log("Avatar is ready!", A);
8533
+ const v = y(), T = v?.avatar_script || v?.body;
8534
+ u && T && setTimeout(() => {
8526
8535
  d.current && d.current();
8527
8536
  }, 10);
8528
- }, [c, y]);
8537
+ }, [u, y]);
8529
8538
  pt(() => {
8530
- d.current = Q, g.current = O, R.current = f, x.current = M, S.current = T, V.current = A, m.current = _;
8539
+ d.current = Q, g.current = B, R.current = f, x.current = F, k.current = M, G.current = I, m.current = _;
8531
8540
  }), Je(l, () => ({
8532
8541
  // Curriculum control methods
8533
8542
  startTeaching: Q,
8534
- startQuestions: A,
8543
+ startQuestions: I,
8535
8544
  handleAnswerSelect: _,
8536
- handleCodeTestResult: Ie,
8537
- nextQuestion: M,
8545
+ handleCodeTestResult: ve,
8546
+ nextQuestion: F,
8538
8547
  previousQuestion: me,
8539
- nextLesson: O,
8540
- previousLesson: Ee,
8548
+ nextLesson: B,
8549
+ previousLesson: Fe,
8541
8550
  completeLesson: f,
8542
- completeCurriculum: T,
8551
+ completeCurriculum: M,
8543
8552
  resetCurriculum: ye,
8544
8553
  getState: () => ({ ...r.current }),
8545
8554
  getCurrentQuestion: () => P(),
8546
8555
  getCurrentLesson: () => y(),
8547
8556
  // Direct access to avatar ref (always returns current value)
8548
- getAvatarRef: () => u.current,
8557
+ getAvatarRef: () => c.current,
8549
8558
  // Convenience methods that delegate to avatar (always check current ref)
8550
- speakText: async (v, I = {}) => {
8551
- await u.current?.resumeAudioContext?.();
8552
- const H = F.current || { lipsyncLang: "en" };
8553
- u.current?.speakText(v, { ...I, lipsyncLang: I.lipsyncLang || H.lipsyncLang });
8559
+ speakText: async (A, v = {}) => {
8560
+ await c.current?.resumeAudioContext?.();
8561
+ const T = E.current || { lipsyncLang: "en" };
8562
+ c.current?.speakText(A, { ...v, lipsyncLang: v.lipsyncLang || T.lipsyncLang });
8554
8563
  },
8555
8564
  resumeAudioContext: async () => {
8556
- if (u.current?.resumeAudioContext)
8557
- return await u.current.resumeAudioContext();
8558
- const v = u.current?.talkingHead;
8559
- if (v?.audioCtx) {
8560
- const I = v.audioCtx;
8561
- if (I.state === "suspended" || I.state === "interrupted")
8565
+ if (c.current?.resumeAudioContext)
8566
+ return await c.current.resumeAudioContext();
8567
+ const A = c.current?.talkingHead;
8568
+ if (A?.audioCtx) {
8569
+ const v = A.audioCtx;
8570
+ if (v.state === "suspended" || v.state === "interrupted")
8562
8571
  try {
8563
- await I.resume(), console.log("Audio context resumed via talkingHead");
8564
- } catch (H) {
8565
- console.warn("Failed to resume audio context:", H);
8572
+ await v.resume(), console.log("Audio context resumed via talkingHead");
8573
+ } catch (T) {
8574
+ console.warn("Failed to resume audio context:", T);
8566
8575
  }
8567
8576
  } else
8568
8577
  console.warn("Audio context not available yet");
8569
8578
  },
8570
- stopSpeaking: () => u.current?.stopSpeaking(),
8571
- pauseSpeaking: () => u.current?.pauseSpeaking(),
8572
- resumeSpeaking: async () => await u.current?.resumeSpeaking(),
8573
- isPaused: () => u.current && typeof u.current.isPaused < "u" ? u.current.isPaused : !1,
8574
- setMood: (v) => u.current?.setMood(v),
8575
- playAnimation: (v, I) => u.current?.playAnimation(v, I),
8576
- setBodyMovement: (v) => u.current?.setBodyMovement(v),
8577
- setMovementIntensity: (v) => u.current?.setMovementIntensity(v),
8578
- playRandomDance: () => u.current?.playRandomDance(),
8579
- playReaction: (v) => u.current?.playReaction(v),
8580
- playCelebration: () => u.current?.playCelebration(),
8581
- setShowFullAvatar: (v) => u.current?.setShowFullAvatar(v),
8582
- setTimingAdjustment: (v) => u.current?.setTimingAdjustment(v),
8583
- lockAvatarPosition: () => u.current?.lockAvatarPosition(),
8584
- unlockAvatarPosition: () => u.current?.unlockAvatarPosition(),
8579
+ stopSpeaking: () => c.current?.stopSpeaking(),
8580
+ pauseSpeaking: () => c.current?.pauseSpeaking(),
8581
+ resumeSpeaking: async () => await c.current?.resumeSpeaking(),
8582
+ isPaused: () => c.current && typeof c.current.isPaused < "u" ? c.current.isPaused : !1,
8583
+ setMood: (A) => c.current?.setMood(A),
8584
+ playAnimation: (A, v) => c.current?.playAnimation(A, v),
8585
+ setBodyMovement: (A) => c.current?.setBodyMovement(A),
8586
+ setMovementIntensity: (A) => c.current?.setMovementIntensity(A),
8587
+ playRandomDance: () => c.current?.playRandomDance(),
8588
+ playReaction: (A) => c.current?.playReaction(A),
8589
+ playCelebration: () => c.current?.playCelebration(),
8590
+ setShowFullAvatar: (A) => c.current?.setShowFullAvatar(A),
8591
+ setTimingAdjustment: (A) => c.current?.setTimingAdjustment(A),
8592
+ lockAvatarPosition: () => c.current?.lockAvatarPosition(),
8593
+ unlockAvatarPosition: () => c.current?.unlockAvatarPosition(),
8585
8594
  // Custom action trigger
8586
- triggerCustomAction: (v, I) => {
8595
+ triggerCustomAction: (A, v) => {
8587
8596
  h.current.onCustomAction({
8588
- type: v,
8589
- ...I,
8597
+ type: A,
8598
+ ...v,
8590
8599
  state: { ...r.current }
8591
8600
  });
8592
8601
  },
8593
8602
  // Responsive resize handler
8594
- handleResize: () => u.current?.handleResize(),
8603
+ handleResize: () => c.current?.handleResize(),
8595
8604
  // Avatar readiness check (always returns current value)
8596
- isAvatarReady: () => u.current?.isReady || !1
8597
- }), [Q, A, _, Ie, M, O, f, T, ye, P, y]);
8598
- const he = F.current || {
8605
+ isAvatarReady: () => c.current?.isReady || !1
8606
+ }), [Q, I, _, ve, F, B, f, M, ye, P, y]);
8607
+ const he = E.current || {
8599
8608
  avatarUrl: "/avatars/brunette.glb",
8600
8609
  avatarBody: "F",
8601
8610
  mood: "happy",
@@ -8609,9 +8618,9 @@ const Ut = Ke(({
8609
8618
  animations: e
8610
8619
  };
8611
8620
  return /* @__PURE__ */ ae("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ ae(
8612
- ut,
8621
+ ct,
8613
8622
  {
8614
- ref: u,
8623
+ ref: c,
8615
8624
  avatarUrl: he.avatarUrl,
8616
8625
  avatarBody: he.avatarBody,
8617
8626
  mood: he.mood,
@@ -8627,8 +8636,8 @@ const Ut = Ke(({
8627
8636
  onReady: Re,
8628
8637
  onLoading: () => {
8629
8638
  },
8630
- onError: (v) => {
8631
- console.error("Avatar error:", v);
8639
+ onError: (A) => {
8640
+ console.error("Avatar error:", A);
8632
8641
  }
8633
8642
  }
8634
8643
  ) });
@@ -8642,26 +8651,26 @@ function _t({
8642
8651
  onDeleteAnimations: o = null,
8643
8652
  style: s = {}
8644
8653
  }) {
8645
- const [i, a] = pe([]), [c, l] = pe(/* @__PURE__ */ new Set()), [u, r] = pe(!0), [h, d] = pe(null), [g, R] = pe("all"), [x, S] = pe("");
8654
+ const [i, a] = pe([]), [u, l] = pe(/* @__PURE__ */ new Set()), [c, r] = pe(!0), [h, d] = pe(null), [g, R] = pe("all"), [x, k] = pe("");
8646
8655
  Se(() => {
8647
8656
  (async () => {
8648
8657
  r(!0), d(null);
8649
8658
  try {
8650
- const T = await je(Z), A = [];
8651
- if (T._genderSpecific) {
8652
- const O = (n?.toUpperCase() || "F") === "M" ? "male" : "female";
8653
- T._genderSpecific[O] && Object.entries(T._genderSpecific[O]).forEach(([Q, _]) => {
8659
+ const M = await je(Z), I = [];
8660
+ if (M._genderSpecific) {
8661
+ const B = (n?.toUpperCase() || "F") === "M" ? "male" : "female";
8662
+ M._genderSpecific[B] && Object.entries(M._genderSpecific[B]).forEach(([Q, _]) => {
8654
8663
  (Array.isArray(_) ? _ : [_]).forEach((me) => {
8655
- A.push({
8664
+ I.push({
8656
8665
  path: me,
8657
8666
  group: Q,
8658
- gender: O,
8667
+ gender: B,
8659
8668
  name: me.split("/").pop().replace(".fbx", "")
8660
8669
  });
8661
8670
  });
8662
- }), T._genderSpecific.shared && Object.entries(T._genderSpecific.shared).forEach(([Q, _]) => {
8671
+ }), M._genderSpecific.shared && Object.entries(M._genderSpecific.shared).forEach(([Q, _]) => {
8663
8672
  (Array.isArray(_) ? _ : [_]).forEach((me) => {
8664
- A.push({
8673
+ I.push({
8665
8674
  path: me,
8666
8675
  group: Q,
8667
8676
  gender: "shared",
@@ -8670,53 +8679,53 @@ function _t({
8670
8679
  });
8671
8680
  });
8672
8681
  }
8673
- Object.entries(T).forEach(([M, O]) => {
8674
- M !== "_genderSpecific" && (Array.isArray(O) ? O : [O]).forEach((_) => {
8675
- typeof _ == "string" && A.push({
8682
+ Object.entries(M).forEach(([F, B]) => {
8683
+ F !== "_genderSpecific" && (Array.isArray(B) ? B : [B]).forEach((_) => {
8684
+ typeof _ == "string" && I.push({
8676
8685
  path: _,
8677
- group: M,
8686
+ group: F,
8678
8687
  gender: "root",
8679
8688
  name: _.split("/").pop().replace(".fbx", "")
8680
8689
  });
8681
8690
  });
8682
- }), a(A), r(!1);
8683
- } catch (T) {
8684
- console.error("Failed to load animations:", T), d(T.message), r(!1);
8691
+ }), a(I), r(!1);
8692
+ } catch (M) {
8693
+ console.error("Failed to load animations:", M), d(M.message), r(!1);
8685
8694
  }
8686
8695
  })();
8687
8696
  }, [Z, n]);
8688
- const V = ["all", ...new Set(i.map((f) => f.group))], m = i.filter((f) => {
8689
- const T = g === "all" || f.group === g, A = x === "" || f.name.toLowerCase().includes(x.toLowerCase()) || f.path.toLowerCase().includes(x.toLowerCase());
8690
- return T && A;
8697
+ const G = ["all", ...new Set(i.map((f) => f.group))], m = i.filter((f) => {
8698
+ const M = g === "all" || f.group === g, I = x === "" || f.name.toLowerCase().includes(x.toLowerCase()) || f.path.toLowerCase().includes(x.toLowerCase());
8699
+ return M && I;
8691
8700
  }), D = (f) => {
8692
- const T = new Set(c);
8693
- T.has(f) ? T.delete(f) : T.add(f), l(T), t && t(Array.from(T));
8694
- }, F = () => {
8695
- const f = new Set(c);
8696
- m.forEach((T) => {
8697
- f.add(T.path);
8701
+ const M = new Set(u);
8702
+ M.has(f) ? M.delete(f) : M.add(f), l(M), t && t(Array.from(M));
8703
+ }, E = () => {
8704
+ const f = new Set(u);
8705
+ m.forEach((M) => {
8706
+ f.add(M.path);
8698
8707
  }), l(f), t && t(Array.from(f));
8699
8708
  }, y = () => {
8700
- const f = new Set(c);
8701
- m.forEach((T) => {
8702
- f.delete(T.path);
8709
+ const f = new Set(u);
8710
+ m.forEach((M) => {
8711
+ f.delete(M.path);
8703
8712
  }), l(f), t && t(Array.from(f));
8704
8713
  }, P = () => {
8705
- const T = i.filter((A) => !c.has(A.path)).map((A) => A.path);
8706
- if (T.length === 0) {
8714
+ const M = i.filter((I) => !u.has(I.path)).map((I) => I.path);
8715
+ if (M.length === 0) {
8707
8716
  alert("No animations to delete. Select animations to keep, then delete will remove the unselected ones.");
8708
8717
  return;
8709
8718
  }
8710
- window.confirm(`Are you sure you want to delete ${T.length} animation(s)?
8719
+ window.confirm(`Are you sure you want to delete ${M.length} animation(s)?
8711
8720
 
8712
8721
  This will delete:
8713
- ${T.slice(0, 5).join(`
8714
- `)}${T.length > 5 ? `
8715
- ...` : ""}`) && (o && o(T), a(i.filter((A) => c.has(A.path))), l(/* @__PURE__ */ new Set()));
8722
+ ${M.slice(0, 5).join(`
8723
+ `)}${M.length > 5 ? `
8724
+ ...` : ""}`) && (o && o(M), a(i.filter((I) => u.has(I.path))), l(/* @__PURE__ */ new Set()));
8716
8725
  }, L = (f) => {
8717
8726
  e && e(f);
8718
8727
  };
8719
- return u ? /* @__PURE__ */ ae("div", { style: { padding: "20px", textAlign: "center", ...s }, children: /* @__PURE__ */ ae("p", { children: "Loading animations..." }) }) : h ? /* @__PURE__ */ ae("div", { style: { padding: "20px", color: "red", ...s }, children: /* @__PURE__ */ Pe("p", { children: [
8728
+ return c ? /* @__PURE__ */ ae("div", { style: { padding: "20px", textAlign: "center", ...s }, children: /* @__PURE__ */ ae("p", { children: "Loading animations..." }) }) : h ? /* @__PURE__ */ ae("div", { style: { padding: "20px", color: "red", ...s }, children: /* @__PURE__ */ Pe("p", { children: [
8720
8729
  "Error loading animations: ",
8721
8730
  h
8722
8731
  ] }) }) : /* @__PURE__ */ Pe("div", { style: {
@@ -8741,7 +8750,7 @@ ${T.slice(0, 5).join(`
8741
8750
  type: "text",
8742
8751
  placeholder: "Search animations...",
8743
8752
  value: x,
8744
- onChange: (f) => S(f.target.value),
8753
+ onChange: (f) => k(f.target.value),
8745
8754
  style: {
8746
8755
  padding: "8px 12px",
8747
8756
  borderRadius: "6px",
@@ -8767,13 +8776,13 @@ ${T.slice(0, 5).join(`
8767
8776
  color: "#fff",
8768
8777
  fontSize: "14px"
8769
8778
  },
8770
- children: V.map((f) => /* @__PURE__ */ ae("option", { value: f, children: f === "all" ? "All Groups" : f }, f))
8779
+ children: G.map((f) => /* @__PURE__ */ ae("option", { value: f, children: f === "all" ? "All Groups" : f }, f))
8771
8780
  }
8772
8781
  ),
8773
8782
  /* @__PURE__ */ ae(
8774
8783
  "button",
8775
8784
  {
8776
- onClick: F,
8785
+ onClick: E,
8777
8786
  style: {
8778
8787
  padding: "8px 16px",
8779
8788
  backgroundColor: "#4CAF50",
@@ -8818,7 +8827,7 @@ ${T.slice(0, 5).join(`
8818
8827
  },
8819
8828
  children: [
8820
8829
  "Delete Unselected (",
8821
- i.length - c.size,
8830
+ i.length - u.size,
8822
8831
  ")"
8823
8832
  ]
8824
8833
  }
@@ -8832,7 +8841,7 @@ ${T.slice(0, 5).join(`
8832
8841
  "Total: ",
8833
8842
  i.length,
8834
8843
  " | Selected: ",
8835
- c.size,
8844
+ u.size,
8836
8845
  " | Showing: ",
8837
8846
  m.length
8838
8847
  ] }),
@@ -8845,16 +8854,16 @@ ${T.slice(0, 5).join(`
8845
8854
  padding: "10px",
8846
8855
  backgroundColor: "#1a1a1a",
8847
8856
  borderRadius: "6px"
8848
- }, children: m.map((f, T) => {
8849
- const A = c.has(f.path);
8857
+ }, children: m.map((f, M) => {
8858
+ const I = u.has(f.path);
8850
8859
  return /* @__PURE__ */ Pe(
8851
8860
  "div",
8852
8861
  {
8853
8862
  style: {
8854
- border: `2px solid ${A ? "#4CAF50" : "#555"}`,
8863
+ border: `2px solid ${I ? "#4CAF50" : "#555"}`,
8855
8864
  borderRadius: "6px",
8856
8865
  padding: "10px",
8857
- backgroundColor: A ? "#2a4a2a" : "#222",
8866
+ backgroundColor: I ? "#2a4a2a" : "#222",
8858
8867
  cursor: "pointer",
8859
8868
  transition: "all 0.2s"
8860
8869
  },
@@ -8865,9 +8874,9 @@ ${T.slice(0, 5).join(`
8865
8874
  "input",
8866
8875
  {
8867
8876
  type: "checkbox",
8868
- checked: A,
8877
+ checked: I,
8869
8878
  onChange: () => D(f.path),
8870
- onClick: (M) => M.stopPropagation(),
8879
+ onClick: (F) => F.stopPropagation(),
8871
8880
  style: {
8872
8881
  marginRight: "8px",
8873
8882
  cursor: "pointer"
@@ -8889,8 +8898,8 @@ ${T.slice(0, 5).join(`
8889
8898
  /* @__PURE__ */ ae(
8890
8899
  "button",
8891
8900
  {
8892
- onClick: (M) => {
8893
- M.stopPropagation(), L(f.path);
8901
+ onClick: (F) => {
8902
+ F.stopPropagation(), L(f.path);
8894
8903
  },
8895
8904
  style: {
8896
8905
  width: "100%",
@@ -8907,7 +8916,7 @@ ${T.slice(0, 5).join(`
8907
8916
  )
8908
8917
  ]
8909
8918
  },
8910
- `${f.path}-${T}`
8919
+ `${f.path}-${M}`
8911
8920
  );
8912
8921
  }) }),
8913
8922
  m.length === 0 && /* @__PURE__ */ ae("div", { style: {
@@ -8917,7 +8926,7 @@ ${T.slice(0, 5).join(`
8917
8926
  }, children: "No animations found matching your filters." })
8918
8927
  ] });
8919
8928
  }
8920
- const ct = {
8929
+ const ut = {
8921
8930
  // Code-based dance animations (no FBX required)
8922
8931
  dance: {
8923
8932
  name: "dance",
@@ -9020,14 +9029,14 @@ const ct = {
9020
9029
  duration: 5e3,
9021
9030
  description: "Excited, energetic movement"
9022
9031
  }
9023
- }, Kt = (Z) => ct[Z] || null, Jt = (Z) => ct.hasOwnProperty(Z);
9032
+ }, Kt = (Z) => ut[Z] || null, Jt = (Z) => ut.hasOwnProperty(Z);
9024
9033
  export {
9025
9034
  _t as AnimationSelector,
9026
9035
  Ut as CurriculumLearning,
9027
9036
  Nt as SimpleTalkingAvatar,
9028
- ut as TalkingHeadAvatar,
9029
- Bt as TalkingHeadComponent,
9030
- ct as animations,
9037
+ ct as TalkingHeadAvatar,
9038
+ Ot as TalkingHeadComponent,
9039
+ ut as animations,
9031
9040
  $e as getActiveTTSConfig,
9032
9041
  Kt as getAnimation,
9033
9042
  qt as getVoiceOptions,