@sage-rsc/talking-head-react 1.0.84 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,20 +1,20 @@
1
1
  import { jsxs as Pe, jsx as me } from "react/jsx-runtime";
2
2
  import { forwardRef as Me, useRef as O, useState as ce, useEffect as de, useCallback as T, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
3
- import * as x from "three";
3
+ import * as f from "three";
4
4
  import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
5
5
  import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
6
6
  import { DRACOLoader as Qe } from "three/addons/loaders/DRACOLoader.js";
7
- import { FBXLoader as De } from "three/addons/loaders/FBXLoader.js";
7
+ import { FBXLoader as Oe } from "three/addons/loaders/FBXLoader.js";
8
8
  import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
9
9
  import Ke from "three/addons/libs/stats.module.js";
10
10
  let m, re, ue;
11
- const A = [0, 0, 0, 0], w = new x.Vector3(), ze = new x.Vector3(), ne = new x.Vector3(), Ce = new x.Vector3();
12
- new x.Plane();
13
- new x.Ray();
14
- new x.Euler();
15
- const ie = new x.Quaternion(), Ne = new x.Quaternion(), fe = new x.Matrix4(), xe = new x.Matrix4();
16
- new x.Vector3();
17
- const He = new x.Vector3(0, 0, 1), _e = new x.Vector3(1, 0, 0), Je = new x.Vector3(0, 1, 0), $e = new x.Vector3(0, 0, 1);
11
+ const A = [0, 0, 0, 0], w = new f.Vector3(), ze = new f.Vector3(), ne = new f.Vector3(), Ce = new f.Vector3();
12
+ new f.Plane();
13
+ new f.Ray();
14
+ new f.Euler();
15
+ const ie = new f.Quaternion(), De = new f.Quaternion(), fe = new f.Matrix4(), xe = new f.Matrix4();
16
+ new f.Vector3();
17
+ const He = new f.Vector3(0, 0, 1), _e = new f.Vector3(1, 0, 0), Je = new f.Vector3(0, 1, 0), $e = new f.Vector3(0, 0, 1);
18
18
  class et {
19
19
  constructor(t = null) {
20
20
  this.opt = Object.assign({
@@ -338,7 +338,7 @@ class et {
338
338
  ea: [0, 0, 0, 0]
339
339
  // External acceleration [m/s^2]
340
340
  };
341
- u.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Ne.setFromUnitVectors(He, w).invert()).normalize(), u.qWorldInverseYaw = ie.clone().normalize(), this.data.push(u), this.dict[h] = u;
341
+ u.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(De.setFromUnitVectors(He, w).invert()).normalize(), u.qWorldInverseYaw = ie.clone().normalize(), this.data.push(u), this.dict[h] = u;
342
342
  try {
343
343
  this.setValue(h, "type", s.type), this.setValue(h, "stiffness", s.stiffness), this.setValue(h, "damping", s.damping), this.setValue(h, "external", s.external), this.setValue(h, "limits", s.limits), this.setValue(h, "excludes", s.excludes), this.setValue(h, "deltaLocal", s.deltaLocal), this.setValue(h, "deltaWorld", s.deltaWorld), this.setValue(h, "pivot", s.pivot), this.setValue(h, "helper", s.helper);
344
344
  } catch (a) {
@@ -369,7 +369,7 @@ class et {
369
369
  o.vBasis.y + A[1],
370
370
  o.vBasis.z - A[2]
371
371
  );
372
- else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Ne.setFromUnitVectors(He, w).invert()).normalize(), o.boneParent.quaternion.multiply(ie.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), ie.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(ie)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), ie.setFromAxisAngle(_e, -m), o.boneParent.quaternion.multiply(ie)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), ie.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(ie)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
372
+ else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(De.setFromUnitVectors(He, w).invert()).normalize(), o.boneParent.quaternion.multiply(ie.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), ie.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(ie)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), ie.setFromAxisAngle(_e, -m), o.boneParent.quaternion.multiply(ie)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), ie.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(ie)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
373
373
  for (n = 0, s = o.excludes.length; n < s; n++)
374
374
  m = o.excludes[n], ne.set(0, 0, 0), m.deltaLocal && (ne.x += m.deltaLocal[0], ne.y += m.deltaLocal[1], ne.z += m.deltaLocal[2]), ne.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ne.applyMatrix4(xe), w.copy(o.bone.position), !(w.distanceToSquared(ne) >= m.radiusSq) && (ue = w.length(), re = ne.length(), !(re > m.radius + ue) && (re < Math.abs(m.radius - ue) || (re = (re * re + ue * ue - m.radiusSq) / (2 * re), ne.normalize(), Ce.copy(ne).multiplyScalar(re), re = Math.sqrt(ue * ue - re * re), w.subVectors(w, Ce).projectOnPlane(ne).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ne).normalize(), ue = ze.dot(w), ue < 0 && (ue = Math.sqrt(re * re - ue * ue), ze.multiplyScalar(ue), w.add(ze)), w.add(Ce).normalize(), ne.copy(o.bone.position).normalize(), ie.setFromUnitVectors(ne, w), o.boneParent.quaternion.premultiply(ie), o.boneParent.updateWorldMatrix(!1, !0))));
375
375
  }
@@ -393,7 +393,7 @@ class et {
393
393
  i || (m.excludes.bones.push(n.bone), m.excludes.radii.push(n.radius), m.excludes.deltaLocals.push(n.deltaLocal ? [...n.deltaLocal] : null), m.excludes.objects.push(null));
394
394
  }));
395
395
  }), m = this.helpers.excludes, this.opt.isExcludes && m.bones.length && m.bones.forEach((e, n) => {
396
- const i = new x.SphereGeometry(m.radii[n], 6, 6), s = new x.MeshBasicMaterial({
396
+ const i = new f.SphereGeometry(m.radii[n], 6, 6), s = new f.MeshBasicMaterial({
397
397
  depthTest: !1,
398
398
  depthWrite: !1,
399
399
  toneMapped: !1,
@@ -401,18 +401,18 @@ class et {
401
401
  wireframe: !0,
402
402
  color: this.opt.helperExcludesColor
403
403
  });
404
- m.objects[n] = new x.Mesh(i, s), m.objects[n].renderOrder = 997, e.add(m.objects[n]), m.deltaLocals[n] && m.objects[n].position.set(
404
+ m.objects[n] = new f.Mesh(i, s), m.objects[n].renderOrder = 997, e.add(m.objects[n]), m.deltaLocals[n] && m.objects[n].position.set(
405
405
  m.deltaLocals[n][0],
406
406
  m.deltaLocals[n][1],
407
407
  m.deltaLocals[n][2]
408
408
  );
409
409
  }), m = this.helpers.points, m.bones.length) {
410
410
  this.helpers.isActive = !0;
411
- const e = new x.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0]).flat();
412
- e.setAttribute("position", new x.Float32BufferAttribute(n, 3));
413
- const i = new x.Color(this.opt.helperBoneColor1), s = new x.Color(this.opt.helperBoneColor2), o = m.pivots.map((h) => h && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
414
- e.setAttribute("color", new x.Float32BufferAttribute(o, 3));
415
- const l = new x.PointsMaterial({
411
+ const e = new f.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0]).flat();
412
+ e.setAttribute("position", new f.Float32BufferAttribute(n, 3));
413
+ const i = new f.Color(this.opt.helperBoneColor1), s = new f.Color(this.opt.helperBoneColor2), o = m.pivots.map((h) => h && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
414
+ e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
415
+ const l = new f.PointsMaterial({
416
416
  depthTest: !1,
417
417
  depthWrite: !1,
418
418
  toneMapped: !1,
@@ -420,21 +420,21 @@ class et {
420
420
  size: 0.2,
421
421
  vertexColors: !0
422
422
  });
423
- m.object = new x.Points(e, l), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
423
+ m.object = new f.Points(e, l), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
424
424
  }
425
425
  if (m = this.helpers.lines, m.bones.length) {
426
- const e = new x.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0, 0, 0, 0]).flat();
427
- e.setAttribute("position", new x.Float32BufferAttribute(n, 3));
428
- const i = new x.Color(this.opt.helperLinkColor1), s = new x.Color(this.opt.helperLinkColor2), o = m.bones.map((h) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
429
- e.setAttribute("color", new x.Float32BufferAttribute(o, 3));
430
- const l = new x.LineBasicMaterial({
426
+ const e = new f.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0, 0, 0, 0]).flat();
427
+ e.setAttribute("position", new f.Float32BufferAttribute(n, 3));
428
+ const i = new f.Color(this.opt.helperLinkColor1), s = new f.Color(this.opt.helperLinkColor2), o = m.bones.map((h) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
429
+ e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
430
+ const l = new f.LineBasicMaterial({
431
431
  vertexColors: !0,
432
432
  depthTest: !1,
433
433
  depthWrite: !1,
434
434
  toneMapped: !1,
435
435
  transparent: !0
436
436
  });
437
- m.object = new x.LineSegments(e, l), m.object.renderOrder = 999, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
437
+ m.object = new f.LineSegments(e, l), m.object.renderOrder = 999, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
438
438
  }
439
439
  }
440
440
  /**
@@ -521,10 +521,10 @@ class tt {
521
521
  for (let l = 0; l < o; l++) {
522
522
  const h = l * s, r = Math.min(h + i, t.length), u = t.slice(h, r), a = this.calculateEnergy(u);
523
523
  n.energy.push(a);
524
- const d = this.calculateSpectralCentroid(u);
525
- n.spectralCentroid.push(d);
526
- const c = this.calculateZeroCrossingRate(u);
527
- n.zeroCrossingRate.push(c);
524
+ const c = this.calculateSpectralCentroid(u);
525
+ n.spectralCentroid.push(c);
526
+ const d = this.calculateZeroCrossingRate(u);
527
+ n.zeroCrossingRate.push(d);
528
528
  const g = this.calculateMFCC(u);
529
529
  n.mfcc.push(g);
530
530
  }
@@ -606,8 +606,8 @@ class tt {
606
606
  for (let h = 0; h < e; h += i) {
607
607
  let r = 1, u = 0;
608
608
  for (let a = 0; a < i / 2; a++) {
609
- const d = n[(h + a) * 2], c = n[(h + a) * 2 + 1], g = n[(h + a + i / 2) * 2] * r - n[(h + a + i / 2) * 2 + 1] * u, y = n[(h + a + i / 2) * 2] * u + n[(h + a + i / 2) * 2 + 1] * r;
610
- n[(h + a) * 2] = d + g, n[(h + a) * 2 + 1] = c + y, n[(h + a + i / 2) * 2] = d - g, n[(h + a + i / 2) * 2 + 1] = c - y;
609
+ const c = n[(h + a) * 2], d = n[(h + a) * 2 + 1], g = n[(h + a + i / 2) * 2] * r - n[(h + a + i / 2) * 2 + 1] * u, x = n[(h + a + i / 2) * 2] * u + n[(h + a + i / 2) * 2 + 1] * r;
610
+ n[(h + a) * 2] = c + g, n[(h + a) * 2 + 1] = d + x, n[(h + a + i / 2) * 2] = c - g, n[(h + a + i / 2) * 2 + 1] = d - x;
611
611
  const b = r * o - u * l, I = r * l + u * o;
612
612
  r = b, u = I;
613
613
  }
@@ -703,15 +703,15 @@ class tt {
703
703
  const o = this.textToVisemes(e);
704
704
  let l = 0, h = 0;
705
705
  for (let r = 0; r < s.length && l < o.length; r++) {
706
- const u = s[r], a = o[l], d = t.energy[Math.floor(u / 0.023)] || 0, c = this.calculateVisemeDuration(a, d);
706
+ const u = s[r], a = o[l], c = t.energy[Math.floor(u / 0.023)] || 0, d = this.calculateVisemeDuration(a, c);
707
707
  i.push({
708
708
  viseme: a,
709
709
  startTime: h,
710
- endTime: h + c,
711
- duration: c,
712
- intensity: Math.min(1, d * 2)
710
+ endTime: h + d,
711
+ duration: d,
712
+ intensity: Math.min(1, c * 2)
713
713
  // Map energy to viseme intensity
714
- }), h += c, l++;
714
+ }), h += d, l++;
715
715
  }
716
716
  for (; l < o.length; ) {
717
717
  const r = o[l], u = this.calculateVisemeDuration(r, 0.5);
@@ -1207,10 +1207,10 @@ class nt {
1207
1207
  Object.keys(this.rules).forEach((e) => {
1208
1208
  this.rules[e] = this.rules[e].map((n) => {
1209
1209
  const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), h = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
1210
- let d = "";
1211
- d += [...l].map((g) => t[g] || g).join("");
1212
- const c = [...h];
1213
- return c[0] = c[0].toLowerCase(), d += c.join(""), a.move = c.length, d += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(d), u.length && u.split(" ").forEach((g) => {
1210
+ let c = "";
1211
+ c += [...l].map((g) => t[g] || g).join("");
1212
+ const d = [...h];
1213
+ return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c), u.length && u.split(" ").forEach((g) => {
1214
1214
  a.visemes.push(g);
1215
1215
  }), a;
1216
1216
  });
@@ -1380,11 +1380,11 @@ class nt {
1380
1380
  if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(h.regex)) {
1381
1381
  h.visemes.forEach((a) => {
1382
1382
  if (e.visemes.length && e.visemes[e.visemes.length - 1] === a) {
1383
- const d = 0.7 * (this.visemeDurations[a] || 1);
1384
- e.durations[e.durations.length - 1] += d, n += d;
1383
+ const c = 0.7 * (this.visemeDurations[a] || 1);
1384
+ e.durations[e.durations.length - 1] += c, n += c;
1385
1385
  } else {
1386
- const d = this.visemeDurations[a] || 1;
1387
- e.visemes.push(a), e.times.push(n), e.durations.push(d), n += d;
1386
+ const c = this.visemeDurations[a] || 1;
1387
+ e.visemes.push(a), e.times.push(n), e.durations.push(c), n += c;
1388
1388
  }
1389
1389
  }), e.i += h.move;
1390
1390
  break;
@@ -1617,10 +1617,10 @@ class ot {
1617
1617
  Object.keys(this.rules).forEach((e) => {
1618
1618
  this.rules[e] = this.rules[e].map((n) => {
1619
1619
  const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), h = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
1620
- let d = "";
1621
- d += [...l].map((g) => t[g] || g).join("");
1622
- const c = [...h];
1623
- return c[0] = c[0].toLowerCase(), d += c.join(""), a.move = c.length, d += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(d), u.length && u.split(" ").forEach((g) => {
1620
+ let c = "";
1621
+ c += [...l].map((g) => t[g] || g).join("");
1622
+ const d = [...h];
1623
+ return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c), u.length && u.split(" ").forEach((g) => {
1624
1624
  a.visemes.push(g);
1625
1625
  }), a;
1626
1626
  });
@@ -1735,13 +1735,13 @@ class ot {
1735
1735
  for (let h = 0; h < o.length; h++) {
1736
1736
  const r = o[h];
1737
1737
  if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(r.regex)) {
1738
- r.visemes.forEach((d) => {
1739
- if (e.visemes.length && e.visemes[e.visemes.length - 1] === d) {
1740
- const c = 0.7 * (this.visemeDurations[d] || 1);
1741
- e.durations[e.durations.length - 1] += c, n += c;
1738
+ r.visemes.forEach((c) => {
1739
+ if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
1740
+ const d = 0.7 * (this.visemeDurations[c] || 1);
1741
+ e.durations[e.durations.length - 1] += d, n += d;
1742
1742
  } else {
1743
- const c = this.visemeDurations[d] || 1;
1744
- e.visemes.push(d), e.times.push(n), e.durations.push(c), n += c;
1743
+ const d = this.visemeDurations[c] || 1;
1744
+ e.visemes.push(c), e.times.push(n), e.durations.push(d), n += d;
1745
1745
  }
1746
1746
  }), e.i += r.move, l = !0;
1747
1747
  break;
@@ -2132,10 +2132,10 @@ class at {
2132
2132
  Object.keys(this.rules).forEach((e) => {
2133
2133
  this.rules[e] = this.rules[e].map((n) => {
2134
2134
  const i = n.indexOf("["), s = n.indexOf("]"), o = n.indexOf("="), l = n.substring(0, i), h = n.substring(i + 1, s), r = n.substring(s + 1, o), u = n.substring(o + 1), a = { regex: "", move: 0, visemes: [] };
2135
- let d = "";
2136
- d += [...l].map((g) => t[g] || g).join("");
2137
- const c = [...h];
2138
- return c[0] = c[0].toLowerCase(), d += c.join(""), a.move = c.length, d += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(d, "i"), u.length && u.split(" ").forEach((g) => {
2135
+ let c = "";
2136
+ c += [...l].map((g) => t[g] || g).join("");
2137
+ const d = [...h];
2138
+ return d[0] = d[0].toLowerCase(), c += d.join(""), a.move = d.length, c += [...r].map((g) => t[g] || g).join(""), a.regex = new RegExp(c, "i"), u.length && u.split(" ").forEach((g) => {
2139
2139
  g && a.visemes.push(g);
2140
2140
  }), a;
2141
2141
  });
@@ -2270,13 +2270,13 @@ class at {
2270
2270
  for (let h = 0; h < o.length; h++) {
2271
2271
  const r = o[h];
2272
2272
  if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(r.regex)) {
2273
- r.visemes.forEach((d) => {
2274
- if (e.visemes.length && e.visemes[e.visemes.length - 1] === d) {
2275
- const c = 0.7 * (this.visemeDurations[d] || 1);
2276
- e.durations[e.durations.length - 1] += c, n += c;
2273
+ r.visemes.forEach((c) => {
2274
+ if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
2275
+ const d = 0.7 * (this.visemeDurations[c] || 1);
2276
+ e.durations[e.durations.length - 1] += d, n += d;
2277
2277
  } else {
2278
- const c = this.visemeDurations[d] || 1;
2279
- e.visemes.push(d), e.times.push(n), e.durations.push(c), n += c;
2278
+ const d = this.visemeDurations[c] || 1;
2279
+ e.visemes.push(c), e.times.push(n), e.durations.push(d), n += d;
2280
2280
  }
2281
2281
  }), e.i += r.move, l = !0;
2282
2282
  break;
@@ -2629,14 +2629,14 @@ const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2629
2629
  fr: rt,
2630
2630
  fi: ut,
2631
2631
  lt: ct
2632
- }, Q = new x.Quaternion(), W = new x.Euler(), ve = new x.Vector3(), Re = new x.Vector3(), We = new x.Box3();
2633
- new x.Matrix4();
2634
- new x.Matrix4();
2635
- new x.Vector3();
2636
- new x.Vector3(0, 0, 1);
2637
- const mt = new x.Vector3(1, 0, 0);
2638
- new x.Vector3(0, 1, 0);
2639
- new x.Vector3(0, 0, 1);
2632
+ }, Q = new f.Quaternion(), V = new f.Euler(), ve = new f.Vector3(), Re = new f.Vector3(), We = new f.Box3();
2633
+ new f.Matrix4();
2634
+ new f.Matrix4();
2635
+ new f.Vector3();
2636
+ new f.Vector3(0, 0, 1);
2637
+ const mt = new f.Vector3(1, 0, 0);
2638
+ new f.Vector3(0, 1, 0);
2639
+ new f.Vector3(0, 0, 1);
2640
2640
  class Be {
2641
2641
  /**
2642
2642
  * Avatar.
@@ -4073,22 +4073,22 @@ class Be {
4073
4073
  if (this.isAvatarOnly = this.opt.avatarOnly, this.isAvatarOnly)
4074
4074
  this.scene = this.opt.avatarOnlyScene, this.camera = this.opt.avatarOnlyCamera;
4075
4075
  else {
4076
- this.renderer = new x.WebGLRenderer({ antialias: !0, alpha: !0 }), this.renderer.setPixelRatio(this.opt.modelPixelRatio * window.devicePixelRatio), this.renderer.setSize(this.nodeAvatar.clientWidth, this.nodeAvatar.clientHeight), this.renderer.outputColorSpace = x.SRGBColorSpace, this.renderer.toneMapping = x.ACESFilmicToneMapping, this.renderer.shadowMap.enabled = !1, this.nodeAvatar.appendChild(this.renderer.domElement), this.camera = new x.PerspectiveCamera(10, this.nodeAvatar.clientWidth / this.nodeAvatar.clientHeight, 0.1, 2e3), this.scene = new x.Scene(), this.lightAmbient = new x.AmbientLight(
4077
- new x.Color(this.opt.lightAmbientColor),
4076
+ this.renderer = new f.WebGLRenderer({ antialias: !0, alpha: !0 }), this.renderer.setPixelRatio(this.opt.modelPixelRatio * window.devicePixelRatio), this.renderer.setSize(this.nodeAvatar.clientWidth, this.nodeAvatar.clientHeight), this.renderer.outputColorSpace = f.SRGBColorSpace, this.renderer.toneMapping = f.ACESFilmicToneMapping, this.renderer.shadowMap.enabled = !1, this.nodeAvatar.appendChild(this.renderer.domElement), this.camera = new f.PerspectiveCamera(10, this.nodeAvatar.clientWidth / this.nodeAvatar.clientHeight, 0.1, 2e3), this.scene = new f.Scene(), this.lightAmbient = new f.AmbientLight(
4077
+ new f.Color(this.opt.lightAmbientColor),
4078
4078
  this.opt.lightAmbientIntensity
4079
- ), this.lightDirect = new x.DirectionalLight(
4080
- new x.Color(this.opt.lightDirectColor),
4079
+ ), this.lightDirect = new f.DirectionalLight(
4080
+ new f.Color(this.opt.lightDirectColor),
4081
4081
  this.opt.lightDirectIntensity
4082
- ), this.lightSpot = new x.SpotLight(
4083
- new x.Color(this.opt.lightSpotColor),
4082
+ ), this.lightSpot = new f.SpotLight(
4083
+ new f.Color(this.opt.lightSpotColor),
4084
4084
  this.opt.lightSpotIntensity,
4085
4085
  0,
4086
4086
  this.opt.lightSpotDispersion
4087
4087
  ), this.setLighting(this.opt);
4088
- const l = new x.PMREMGenerator(this.renderer);
4088
+ const l = new f.PMREMGenerator(this.renderer);
4089
4089
  l.compileEquirectangularShader(), this.scene.environment = l.fromScene(new qe()).texture, this.resizeobserver = new ResizeObserver(this.onResize.bind(this)), this.resizeobserver.observe(this.nodeAvatar), this.controls = new Ye(this.camera, this.renderer.domElement), this.controls.enableZoom = this.opt.cameraZoomEnable, this.controls.enableRotate = this.opt.cameraRotateEnable, this.controls.enablePan = this.opt.cameraPanEnable, this.controls.minDistance = 2, this.controls.maxDistance = 2e3, this.controls.autoRotateSpeed = 0, this.controls.autoRotate = !1, this.controls.update(), this.cameraClock = null;
4090
4090
  }
4091
- this.ikMesh = new x.SkinnedMesh();
4091
+ this.ikMesh = new f.SkinnedMesh();
4092
4092
  const s = {
4093
4093
  LeftShoulder: null,
4094
4094
  LeftArm: "LeftShoulder",
@@ -4102,9 +4102,9 @@ class Be {
4102
4102
  RightHandMiddle1: "RightHand"
4103
4103
  }, o = [];
4104
4104
  Object.entries(s).forEach((l, h) => {
4105
- const r = new x.Bone();
4105
+ const r = new f.Bone();
4106
4106
  r.name = l[0], l[1] ? this.ikMesh.getObjectByName(l[1]).add(r) : this.ikMesh.add(r), o.push(r);
4107
- }), this.ikMesh.bind(new x.Skeleton(o)), this.dynamicbones = new et(), 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 f.Skeleton(o)), this.dynamicbones = new et(), 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.
@@ -4194,7 +4194,7 @@ class Be {
4194
4194
  for (let [n, i] of Object.entries(t)) {
4195
4195
  const s = n.split(".");
4196
4196
  let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y, h = Array.isArray(i.z) ? this.gaussianRandom(...i.z) : i.z;
4197
- s[1] === "position" || s[1] === "scale" ? e[n] = new x.Vector3(o, l, h) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new x.Quaternion().setFromEuler(new x.Euler(o, l, h, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new x.Quaternion(o, l, h, i.w).normalize());
4197
+ s[1] === "position" || s[1] === "scale" ? e[n] = new f.Vector3(o, l, h) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new f.Quaternion().setFromEuler(new f.Euler(o, l, h, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new f.Quaternion(o, l, h, i.w).normalize());
4198
4198
  }
4199
4199
  return e;
4200
4200
  }
@@ -4225,16 +4225,16 @@ class Be {
4225
4225
  let l = null, h = null;
4226
4226
  for (const [r, u] of Object.entries(n))
4227
4227
  if (s.morphTargetDictionary.hasOwnProperty(r)) {
4228
- const a = s.morphTargetDictionary[r], d = o.morphAttributes.position[a], c = o.morphAttributes.normal?.[a];
4229
- l || (l = new x.Float32BufferAttribute(d.count * 3, 3), c && (h = new x.Float32BufferAttribute(d.count * 3, 3)));
4230
- for (let g = 0; g < d.count; g++) {
4231
- const y = l.getX(g) + d.getX(g) * u, b = l.getY(g) + d.getY(g) * u, I = l.getZ(g) + d.getZ(g) * u;
4232
- l.setXYZ(g, y, b, I);
4228
+ const a = s.morphTargetDictionary[r], c = o.morphAttributes.position[a], d = o.morphAttributes.normal?.[a];
4229
+ l || (l = new f.Float32BufferAttribute(c.count * 3, 3), d && (h = new f.Float32BufferAttribute(c.count * 3, 3)));
4230
+ for (let g = 0; g < c.count; g++) {
4231
+ const x = l.getX(g) + c.getX(g) * u, b = l.getY(g) + c.getY(g) * u, I = l.getZ(g) + c.getZ(g) * u;
4232
+ l.setXYZ(g, x, b, I);
4233
4233
  }
4234
- if (c)
4235
- for (let g = 0; g < d.count; g++) {
4236
- const y = h.getX(g) + c.getX(g) * u, b = h.getY(g) + c.getY(g) * u, I = h.getZ(g) + c.getZ(g) * u;
4237
- h.setXYZ(g, y, b, I);
4234
+ if (d)
4235
+ for (let g = 0; g < c.count; g++) {
4236
+ const x = h.getX(g) + d.getX(g) * u, b = h.getY(g) + d.getY(g) * u, I = h.getZ(g) + d.getZ(g) * u;
4237
+ h.setXYZ(g, x, b, I);
4238
4238
  }
4239
4239
  }
4240
4240
  if (l) {
@@ -4299,8 +4299,8 @@ class Be {
4299
4299
  u && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((a) => {
4300
4300
  l[r][a] = u[a];
4301
4301
  }), this.morphs.forEach((a) => {
4302
- const d = a.morphTargetDictionary[r];
4303
- d !== void 0 && (l[r].ms.push(a.morphTargetInfluences), l[r].is.push(d), a.morphTargetInfluences[d] = l[r].applied);
4302
+ const c = a.morphTargetDictionary[r];
4303
+ c !== void 0 && (l[r].ms.push(a.morphTargetInfluences), l[r].is.push(c), a.morphTargetInfluences[c] = l[r].applied);
4304
4304
  });
4305
4305
  }), this.mtAvatar = l, this.poseAvatar = { props: {} }, this.posePropNames.forEach((r) => {
4306
4306
  const u = r.split("."), a = this.armature.getObjectByName(u[0]);
@@ -4314,7 +4314,7 @@ class Be {
4314
4314
  console.error("Dynamic bones setup failed: " + r);
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 h = new x.Vector3();
4317
+ const h = new f.Vector3();
4318
4318
  this.objectLeftEye.getWorldPosition(h), this.avatarHeight = h.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), console.log("Set initial male-appropriate pose: wide")), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
4319
4319
  }
4320
4320
  /**
@@ -4358,14 +4358,14 @@ class Be {
4358
4358
  default:
4359
4359
  a += 12, u = u * a;
4360
4360
  }
4361
- r = r * a, this.controlsEnd = new x.Vector3(r, u, 0), this.cameraEnd = new x.Vector3(r, u, a).applyEuler(new x.Euler(o, l, 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
+ r = r * a, this.controlsEnd = new f.Vector3(r, u, 0), this.cameraEnd = new f.Vector3(r, u, a).applyEuler(new f.Euler(o, l, 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.
4365
4365
  * @param {Object} opt Options
4366
4366
  */
4367
4367
  setLighting(t) {
4368
- this.isAvatarOnly || (t = t || {}, t.hasOwnProperty("lightAmbientColor") && this.lightAmbient.color.set(new x.Color(t.lightAmbientColor)), t.hasOwnProperty("lightAmbientIntensity") && (this.lightAmbient.intensity = t.lightAmbientIntensity, this.lightAmbient.visible = t.lightAmbientIntensity !== 0), t.hasOwnProperty("lightDirectColor") && this.lightDirect.color.set(new x.Color(t.lightDirectColor)), t.hasOwnProperty("lightDirectIntensity") && (this.lightDirect.intensity = t.lightDirectIntensity, this.lightDirect.visible = t.lightDirectIntensity !== 0), t.hasOwnProperty("lightDirectPhi") && t.hasOwnProperty("lightDirectTheta") && this.lightDirect.position.setFromSphericalCoords(2, t.lightDirectPhi, t.lightDirectTheta), t.hasOwnProperty("lightSpotColor") && this.lightSpot.color.set(new x.Color(t.lightSpotColor)), t.hasOwnProperty("lightSpotIntensity") && (this.lightSpot.intensity = t.lightSpotIntensity, this.lightSpot.visible = t.lightSpotIntensity !== 0), t.hasOwnProperty("lightSpotPhi") && t.hasOwnProperty("lightSpotTheta") && (this.lightSpot.position.setFromSphericalCoords(2, t.lightSpotPhi, t.lightSpotTheta), this.lightSpot.position.add(new x.Vector3(0, 1.5, 0))), t.hasOwnProperty("lightSpotDispersion") && (this.lightSpot.angle = t.lightSpotDispersion));
4368
+ this.isAvatarOnly || (t = t || {}, t.hasOwnProperty("lightAmbientColor") && this.lightAmbient.color.set(new f.Color(t.lightAmbientColor)), t.hasOwnProperty("lightAmbientIntensity") && (this.lightAmbient.intensity = t.lightAmbientIntensity, this.lightAmbient.visible = t.lightAmbientIntensity !== 0), t.hasOwnProperty("lightDirectColor") && this.lightDirect.color.set(new f.Color(t.lightDirectColor)), t.hasOwnProperty("lightDirectIntensity") && (this.lightDirect.intensity = t.lightDirectIntensity, this.lightDirect.visible = t.lightDirectIntensity !== 0), t.hasOwnProperty("lightDirectPhi") && t.hasOwnProperty("lightDirectTheta") && this.lightDirect.position.setFromSphericalCoords(2, t.lightDirectPhi, t.lightDirectTheta), t.hasOwnProperty("lightSpotColor") && this.lightSpot.color.set(new f.Color(t.lightSpotColor)), t.hasOwnProperty("lightSpotIntensity") && (this.lightSpot.intensity = t.lightSpotIntensity, this.lightSpot.visible = t.lightSpotIntensity !== 0), t.hasOwnProperty("lightSpotPhi") && t.hasOwnProperty("lightSpotTheta") && (this.lightSpot.position.setFromSphericalCoords(2, t.lightSpotPhi, t.lightSpotTheta), this.lightSpot.position.add(new f.Vector3(0, 1.5, 0))), t.hasOwnProperty("lightSpotDispersion") && (this.lightSpot.angle = t.lightSpotDispersion));
4369
4369
  }
4370
4370
  /**
4371
4371
  * Render scene.
@@ -4398,9 +4398,9 @@ class Be {
4398
4398
  updatePoseDelta() {
4399
4399
  for (const [t, e] of Object.entries(this.poseDelta.props)) {
4400
4400
  if (e.x === 0 && e.y === 0 && e.z === 0) continue;
4401
- W.set(e.x, e.y, e.z);
4401
+ V.set(e.x, e.y, e.z);
4402
4402
  const n = this.poseAvatar.props[t];
4403
- n.isQuaternion ? (Q.setFromEuler(W), n.multiply(Q)) : n.isVector3 && n.add(W);
4403
+ n.isQuaternion ? (Q.setFromEuler(V), n.multiply(Q)) : n.isVector3 && n.add(V);
4404
4404
  }
4405
4405
  }
4406
4406
  /**
@@ -4480,7 +4480,7 @@ class Be {
4480
4480
  return Object.entries(t).forEach((i, s) => {
4481
4481
  const o = i[0].split(".");
4482
4482
  if (o[1] === "position" || o[1] === "rotation" || o[1] === "quaternion") {
4483
- const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], h = i[1].isQuaternion ? new x.Euler().setFromQuaternion(i[1]) : i[1];
4483
+ const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], h = i[1].isQuaternion ? new f.Euler().setFromQuaternion(i[1]) : i[1];
4484
4484
  n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(h.x * e) / e, n += ", y:" + Math.round(h.y * e) / e, n += ", z:" + Math.round(h.z * e) / e, n += "}";
4485
4485
  }
4486
4486
  }), n += "}", n;
@@ -4999,10 +4999,10 @@ class Be {
4999
4999
  if (l.alt.length > 1) {
5000
5000
  const u = Math.random();
5001
5001
  let a = 0;
5002
- for (let d = 0; d < l.alt.length; d++) {
5003
- let c = this.valueFn(l.alt[d].p);
5004
- if (a += c === void 0 ? (1 - a) / (l.alt.length - 1 - d) : c, u < a) {
5005
- r = l.alt[d];
5002
+ for (let c = 0; c < l.alt.length; c++) {
5003
+ let d = this.valueFn(l.alt[c].p);
5004
+ if (a += d === void 0 ? (1 - a) / (l.alt.length - 1 - c) : d, u < a) {
5005
+ r = l.alt[c];
5006
5006
  break;
5007
5007
  }
5008
5008
  }
@@ -5023,8 +5023,8 @@ class Be {
5023
5023
  }
5024
5024
  s ? o.ts = o.ts.map((r) => h + r * n) : o.ts = o.ts.map((r) => this.animClock + h + r * n), l.vs && l.vs.pose && console.log("Pose being selected from vs.pose:", l.vs.pose, "for avatar body:", this.avatar?.body);
5025
5025
  for (let [r, u] of Object.entries(l.vs)) {
5026
- const a = this.getBaselineValue(r), d = u.map((c) => (c = this.valueFn(c), c === null ? null : typeof c == "function" ? c : typeof c == "string" || c instanceof String ? r === "pose" && this.avatar && this.avatar.body === "M" && (c === "hip" || c === "side") ? (console.log("Intercepting pose", c, "in animation factory, overriding to wide for male avatar"), "wide") : c.slice() : Array.isArray(c) ? r === "gesture" ? c.slice() : (a === void 0 ? 0 : a) + i * this.gaussianRandom(...c) : typeof c == "boolean" ? c : c instanceof Object && c.constructor === Object ? Object.assign({}, c) : (a === void 0 ? 0 : a) + i * c));
5027
- r === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...d.map((c) => c > 0 ? c : 0)], o.vs.eyeLookInLeft = [null, ...d.map((c) => c > 0 ? 0 : -c)], o.vs.eyeLookOutRight = [null, ...d.map((c) => c > 0 ? 0 : -c)], o.vs.eyeLookInRight = [null, ...d.map((c) => c > 0 ? c : 0)]) : r === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...d.map((c) => c > 0 ? c : 0)], o.vs.eyesLookUp = [null, ...d.map((c) => c > 0 ? 0 : -c)]) : o.vs[r] = [null, ...d];
5026
+ const a = this.getBaselineValue(r), c = u.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? r === "pose" && this.avatar && this.avatar.body === "M" && (d === "hip" || d === "side") ? (console.log("Intercepting pose", d, "in animation factory, overriding to wide for male avatar"), "wide") : d.slice() : Array.isArray(d) ? r === "gesture" ? d.slice() : (a === void 0 ? 0 : a) + i * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (a === void 0 ? 0 : a) + i * d));
5027
+ r === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyeLookInLeft = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookOutRight = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookInRight = [null, ...c.map((d) => d > 0 ? d : 0)]) : r === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyesLookUp = [null, ...c.map((d) => d > 0 ? 0 : -d)]) : o.vs[r] = [null, ...c];
5028
5028
  }
5029
5029
  for (let r of Object.keys(o.vs))
5030
5030
  for (; o.vs[r].length <= o.ts.length; ) o.vs[r].push(o.vs[r][o.vs[r].length - 1]);
@@ -5111,20 +5111,20 @@ class Be {
5111
5111
  const a = this.animQueue[n];
5112
5112
  if (!(!a || !a.ts || !a.ts.length || this.animClock < a.ts[0])) {
5113
5113
  for (i = a.ndx || 0, o = a.ts.length; i < o && !(this.animClock < a.ts[i]); i++)
5114
- for (let [d, c] of Object.entries(a.vs))
5115
- if (this.mtAvatar.hasOwnProperty(d)) {
5116
- if (c[i + 1] === null) continue;
5117
- const g = this.mtAvatar[d];
5118
- if (c[i] === null && (c[i] = g.value), i === o - 1)
5119
- g.newvalue = c[i];
5114
+ for (let [c, d] of Object.entries(a.vs))
5115
+ if (this.mtAvatar.hasOwnProperty(c)) {
5116
+ if (d[i + 1] === null) continue;
5117
+ const g = this.mtAvatar[c];
5118
+ if (d[i] === null && (d[i] = g.value), i === o - 1)
5119
+ g.newvalue = d[i];
5120
5120
  else {
5121
- g.newvalue = c[i + 1];
5122
- const y = a.ts[i + 1] - a.ts[i];
5121
+ g.newvalue = d[i + 1];
5122
+ const x = a.ts[i + 1] - a.ts[i];
5123
5123
  let b = 1;
5124
- y > 1e-4 && (b = (this.animClock - a.ts[i]) / y), b < 1 && (g.easing && (b = g.easing(b)), g.newvalue = (1 - b) * c[i] + b * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(d) && delete g.ref[d], g.ref = a.vs;
5124
+ x > 1e-4 && (b = (this.animClock - a.ts[i]) / x), b < 1 && (g.easing && (b = g.easing(b)), g.newvalue = (1 - b) * d[i] + b * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(c) && delete g.ref[c], g.ref = a.vs;
5125
5125
  }
5126
5126
  if (l)
5127
- switch (d) {
5127
+ switch (c) {
5128
5128
  case "viseme_aa":
5129
5129
  case "viseme_E":
5130
5130
  case "viseme_I":
@@ -5133,11 +5133,11 @@ class Be {
5133
5133
  g.newvalue *= 1 + l / 255 - 0.5;
5134
5134
  }
5135
5135
  g.needsUpdate = !0;
5136
- } else d === "eyeContact" && c[i] !== null && h !== !1 ? h = !!c[i] : d === "headMove" && c[i] !== null && r !== !1 ? c[i] === 0 ? r = !1 : (Math.random() < c[i] && (r = !0), c[i] = null) : c[i] !== null && (u.push({ mt: d, val: c[i] }), c[i] = null);
5136
+ } else c === "eyeContact" && d[i] !== null && h !== !1 ? h = !!d[i] : c === "headMove" && d[i] !== null && r !== !1 ? d[i] === 0 ? r = !1 : (Math.random() < d[i] && (r = !0), d[i] = null) : d[i] !== null && (u.push({ mt: c, val: d[i] }), d[i] = null);
5137
5137
  i === o ? (a.hasOwnProperty("mood") && this.setMood(a.mood), a.loop ? (o = this.isSpeaking && (a.template.name === "head" || a.template.name === "eyes") ? 4 : 1, this.animQueue[n] = this.animFactory(a.template, a.loop > 0 ? a.loop - 1 : a.loop, 1, 1 / o)) : (this.animQueue.splice(n--, 1), s--)) : a.ndx = i - 1;
5138
5138
  }
5139
5139
  }
5140
- for (let a = 0, d = u.length; a < d; a++)
5140
+ for (let a = 0, c = u.length; a < c; a++)
5141
5141
  switch (i = u[a].val, u[a].mt) {
5142
5142
  case "speak":
5143
5143
  this.speakText(i);
@@ -5155,8 +5155,8 @@ class Be {
5155
5155
  i && typeof i == "function" && i();
5156
5156
  break;
5157
5157
  case "moveto":
5158
- Object.entries(i.props).forEach((c) => {
5159
- c[1] ? this.poseTarget.props[c[0]].copy(c[1]) : this.poseTarget.props[c[0]].copy(this.getPoseTemplateProp(c[0])), this.poseTarget.props[c[0]].t = this.animClock, this.poseTarget.props[c[0]].d = c[1] && c[1].d ? c[1].d : c.duration || 2e3;
5158
+ Object.entries(i.props).forEach((d) => {
5159
+ d[1] ? this.poseTarget.props[d[0]].copy(d[1]) : this.poseTarget.props[d[0]].copy(this.getPoseTemplateProp(d[0])), this.poseTarget.props[d[0]].t = this.animClock, this.poseTarget.props[d[0]].d = d[1] && d[1].d ? d[1].d : d.duration || 2e3;
5160
5160
  });
5161
5161
  break;
5162
5162
  case "handLeft":
@@ -5169,7 +5169,7 @@ class Be {
5169
5169
  { link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
5170
5170
  { link: "LeftArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
5171
5171
  ]
5172
- }, i.x ? new x.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5172
+ }, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5173
5173
  break;
5174
5174
  case "handRight":
5175
5175
  this.ikSolve({
@@ -5181,10 +5181,10 @@ class Be {
5181
5181
  { link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5, maxAngle: 0.2 },
5182
5182
  { link: "RightArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
5183
5183
  ]
5184
- }, i.x ? new x.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5184
+ }, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5185
5185
  break;
5186
5186
  }
5187
- if ((h || r) && (W.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), W.x = Math.max(-0.9, Math.min(0.9, 2 * W.x - 0.5)), W.y = Math.max(-0.9, Math.min(0.9, -2.5 * W.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: W.x < 0 ? -W.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: W.x < 0 ? 0 : W.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: W.y < 0 ? -W.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: W.y < 0 ? 0 : W.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: W.y < 0 ? 0 : W.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: W.y < 0 ? -W.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
5187
+ if ((h || r) && (V.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), V.x = Math.max(-0.9, Math.min(0.9, 2 * V.x - 0.5)), V.y = Math.max(-0.9, Math.min(0.9, -2.5 * V.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: V.x < 0 ? -V.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: V.x < 0 ? 0 : V.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: V.y < 0 ? -V.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: V.y < 0 ? 0 : V.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: V.y < 0 ? 0 : V.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: V.y < 0 ? -V.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
5188
5188
  name: "headmove",
5189
5189
  dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
5190
5190
  vs: {
@@ -5210,8 +5210,8 @@ class Be {
5210
5210
  else {
5211
5211
  if (this.cameraClock !== null && this.cameraClock < 1e3) {
5212
5212
  this.cameraClock += e, this.cameraClock > 1e3 && (this.cameraClock = 1e3);
5213
- let a = new x.Spherical().setFromVector3(this.cameraStart), d = new x.Spherical().setFromVector3(this.cameraEnd);
5214
- a.phi += this.easing(this.cameraClock / 1e3) * (d.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (d.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (d.radius - a.radius), a.makeSafe(), this.camera.position.setFromSpherical(a), this.controlsStart.x !== this.controlsEnd.x ? this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd, this.easing(this.cameraClock / 1e3))) : (a.setFromVector3(this.controlsStart), d.setFromVector3(this.controlsEnd), a.phi += this.easing(this.cameraClock / 1e3) * (d.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (d.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (d.radius - a.radius), a.makeSafe(), this.controls.target.setFromSpherical(a)), this.controls.update();
5213
+ let a = new f.Spherical().setFromVector3(this.cameraStart), c = new f.Spherical().setFromVector3(this.cameraEnd);
5214
+ a.phi += this.easing(this.cameraClock / 1e3) * (c.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (c.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (c.radius - a.radius), a.makeSafe(), this.camera.position.setFromSpherical(a), this.controlsStart.x !== this.controlsEnd.x ? this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd, this.easing(this.cameraClock / 1e3))) : (a.setFromVector3(this.controlsStart), c.setFromVector3(this.controlsEnd), a.phi += this.easing(this.cameraClock / 1e3) * (c.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (c.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (c.radius - a.radius), a.makeSafe(), this.controls.target.setFromSpherical(a)), this.controls.update();
5215
5215
  }
5216
5216
  this.controls.autoRotate && this.controls.update(), this.stats && this.stats.end(), this.render();
5217
5217
  }
@@ -5273,48 +5273,48 @@ class Be {
5273
5273
  speakText(t, e = null, n = null, i = null) {
5274
5274
  e = e || {};
5275
5275
  const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, h = /[\p{Extended_Pictographic}]/ug, r = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
5276
- let u = "", a = "", d = 0, c = [], g = [];
5277
- const y = Array.from(this.segmenter.segment(t), (b) => b.segment);
5278
- for (let b = 0; b < y.length; b++) {
5279
- const I = b === y.length - 1, V = y[b].match(l);
5280
- let p = y[b].match(s);
5281
- const M = y[b].match(h), z = y[b].match(o);
5282
- if (p && !I && !M && y[b + 1].match(s) && (p = !1), n && (u += y[b]), V && (!i || i.every((f) => b < f[0] || b > f[1])) && (a += y[b]), (z || p || I) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && c.push({
5283
- mark: d,
5276
+ let u = "", a = "", c = 0, d = [], g = [];
5277
+ const x = Array.from(this.segmenter.segment(t), (b) => b.segment);
5278
+ for (let b = 0; b < x.length; b++) {
5279
+ const I = b === x.length - 1, B = x[b].match(l);
5280
+ let p = x[b].match(s);
5281
+ const M = x[b].match(h), z = x[b].match(o);
5282
+ if (p && !I && !M && x[b + 1].match(s) && (p = !1), n && (u += x[b]), B && (!i || i.every((y) => b < y[0] || b > y[1])) && (a += x[b]), (z || p || I) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
5283
+ mark: c,
5284
5284
  word: a
5285
5285
  })), u.length && (g.push({
5286
- mark: d,
5286
+ mark: c,
5287
5287
  template: { name: "subtitles" },
5288
5288
  ts: [0],
5289
5289
  vs: {
5290
5290
  subtitles: [u]
5291
5291
  }
5292
5292
  }), u = ""), a.length)) {
5293
- const f = this.lipsyncWordsToVisemes(a, r);
5294
- if (f && f.visemes && f.visemes.length) {
5295
- const E = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
5296
- for (let P = 0; P < f.visemes.length; P++)
5293
+ const y = this.lipsyncWordsToVisemes(a, r);
5294
+ if (y && y.visemes && y.visemes.length) {
5295
+ const E = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
5296
+ for (let P = 0; P < y.visemes.length; P++)
5297
5297
  g.push({
5298
- mark: d,
5298
+ mark: c,
5299
5299
  template: { name: "viseme" },
5300
- ts: [(f.times[P] - 0.6) / E, (f.times[P] + 0.5) / E, (f.times[P] + f.durations[P] + 0.5) / E],
5300
+ ts: [(y.times[P] - 0.6) / E, (y.times[P] + 0.5) / E, (y.times[P] + y.durations[P] + 0.5) / E],
5301
5301
  vs: {
5302
- ["viseme_" + f.visemes[P]]: [null, f.visemes[P] === "PP" || f.visemes[P] === "FF" ? 0.9 : 0.6, 0]
5302
+ ["viseme_" + y.visemes[P]]: [null, y.visemes[P] === "PP" || y.visemes[P] === "FF" ? 0.9 : 0.6, 0]
5303
5303
  }
5304
5304
  });
5305
5305
  }
5306
- a = "", d++;
5306
+ a = "", c++;
5307
5307
  }
5308
5308
  if (p || I) {
5309
- if (c.length || I && g.length) {
5310
- const f = {
5309
+ if (d.length || I && g.length) {
5310
+ const y = {
5311
5311
  anim: g
5312
5312
  };
5313
- n && (f.onSubtitles = n), c.length && !e.avatarMute && (f.text = c, e.avatarMood && (f.mood = e.avatarMood), e.ttsLang && (f.lang = e.ttsLang), e.ttsVoice && (f.voice = e.ttsVoice), e.ttsRate && (f.rate = e.ttsRate), e.ttsVoice && (f.pitch = e.ttsPitch), e.ttsVolume && (f.volume = e.ttsVolume)), this.speechQueue.push(f), c = [], a = "", d = 0, g = [];
5313
+ n && (y.onSubtitles = n), d.length && !e.avatarMute && (y.text = d, e.avatarMood && (y.mood = e.avatarMood), e.ttsLang && (y.lang = e.ttsLang), e.ttsVoice && (y.voice = e.ttsVoice), e.ttsRate && (y.rate = e.ttsRate), e.ttsVoice && (y.pitch = e.ttsPitch), e.ttsVolume && (y.volume = e.ttsVolume)), this.speechQueue.push(y), d = [], a = "", c = 0, g = [];
5314
5314
  }
5315
5315
  if (M) {
5316
- let f = this.animEmojis[y[b]];
5317
- f && f.link && (f = this.animEmojis[f.link]), f && this.speechQueue.push({ emoji: f });
5316
+ let y = this.animEmojis[x[b]];
5317
+ y && y.link && (y = this.animEmojis[y.link]), y && this.speechQueue.push({ emoji: y });
5318
5318
  }
5319
5319
  this.speechQueue.push({ break: 100 });
5320
5320
  }
@@ -5404,18 +5404,18 @@ class Be {
5404
5404
  subtitles: [" " + h]
5405
5405
  }
5406
5406
  }), !t.visemes)) {
5407
- const a = this.lipsyncPreProcessText(h, i), d = this.lipsyncWordsToVisemes(a, i);
5408
- if (d && d.visemes && d.visemes.length) {
5409
- const c = d.times[d.visemes.length - 1] + d.durations[d.visemes.length - 1], g = Math.min(u, Math.max(0, u - d.visemes.length * 150));
5410
- let y = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
5411
- if (u = Math.min(u, d.visemes.length * 200), c > 0)
5412
- for (let b = 0; b < d.visemes.length; b++) {
5413
- const I = r + d.times[b] / c * u, V = d.durations[b] / c * u;
5407
+ const a = this.lipsyncPreProcessText(h, i), c = this.lipsyncWordsToVisemes(a, i);
5408
+ if (c && c.visemes && c.visemes.length) {
5409
+ const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(u, Math.max(0, u - c.visemes.length * 150));
5410
+ let x = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
5411
+ if (u = Math.min(u, c.visemes.length * 200), d > 0)
5412
+ for (let b = 0; b < c.visemes.length; b++) {
5413
+ const I = r + c.times[b] / d * u, B = c.durations[b] / d * u;
5414
5414
  o.push({
5415
5415
  template: { name: "viseme" },
5416
- ts: [I - Math.min(60, 2 * V / 3), I + Math.min(25, V / 2), I + V + Math.min(60, V / 2)],
5416
+ ts: [I - Math.min(60, 2 * B / 3), I + Math.min(25, B / 2), I + B + Math.min(60, B / 2)],
5417
5417
  vs: {
5418
- ["viseme_" + d.visemes[b]]: [null, d.visemes[b] === "PP" || d.visemes[b] === "FF" ? 0.9 : y, 0]
5418
+ ["viseme_" + c.visemes[b]]: [null, c.visemes[b] === "PP" || c.visemes[b] === "FF" ? 0.9 : x, 0]
5419
5419
  }
5420
5420
  });
5421
5421
  }
@@ -5498,31 +5498,31 @@ class Be {
5498
5498
  const p = u.find((M) => M.name.includes(a) || M.lang === o);
5499
5499
  p && (s.voice = p);
5500
5500
  }
5501
- const d = i.length * 100 / s.rate, c = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (d / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", y = this.lipsyncPreProcessText(i, g), b = this.lipsyncWordsToVisemes(y, g);
5501
+ const c = i.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", x = this.lipsyncPreProcessText(i, g), b = this.lipsyncWordsToVisemes(x, g);
5502
5502
  console.log("Browser TTS Lip-sync Debug:", {
5503
5503
  text: i,
5504
5504
  lipsyncLang: g,
5505
- processedText: y,
5505
+ processedText: x,
5506
5506
  lipsyncData: b,
5507
5507
  hasVisemes: b && b.visemes && b.visemes.length > 0,
5508
- estimatedDuration: d
5508
+ estimatedDuration: c
5509
5509
  });
5510
5510
  const I = [];
5511
5511
  if (b && b.visemes && b.visemes.length > 0) {
5512
5512
  const p = b.times[b.visemes.length - 1] + b.durations[b.visemes.length - 1];
5513
5513
  for (let M = 0; M < b.visemes.length; M++) {
5514
- const z = b.visemes[M], f = b.times[M] / p, E = b.durations[M] / p, P = f * d, U = E * d;
5514
+ const z = b.visemes[M], y = b.times[M] / p, E = b.durations[M] / p, P = y * c, W = E * c;
5515
5515
  I.push({
5516
5516
  template: { name: "viseme" },
5517
- ts: [P - Math.min(60, 2 * U / 3), P + Math.min(25, U / 2), P + U + Math.min(60, U / 2)],
5517
+ ts: [P - Math.min(60, 2 * W / 3), P + Math.min(25, W / 2), P + W + Math.min(60, W / 2)],
5518
5518
  vs: {
5519
5519
  ["viseme_" + z]: [null, z === "PP" || z === "FF" ? 0.9 : 0.6, 0]
5520
5520
  }
5521
5521
  });
5522
5522
  }
5523
5523
  }
5524
- const V = [...t.anim, ...I];
5525
- this.audioPlaylist.push({ anim: V, audio: c }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5524
+ const B = [...t.anim, ...I];
5525
+ this.audioPlaylist.push({ anim: B, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5526
5526
  e();
5527
5527
  }, s.onerror = (p) => {
5528
5528
  console.error("Speech synthesis error:", p.error), n(p.error);
@@ -5534,7 +5534,7 @@ class Be {
5534
5534
  * @param {Object} line Speech line object
5535
5535
  */
5536
5536
  async synthesizeWithElevenLabsTTS(t) {
5537
- const e = t.text.map((d) => d.word).join(" "), n = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice || "21m00Tcm4TlvDq8ikWAM", i = {
5537
+ const e = t.text.map((c) => c.word).join(" "), n = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice || "21m00Tcm4TlvDq8ikWAM", i = {
5538
5538
  text: e,
5539
5539
  model_id: "eleven_monolingual_v1",
5540
5540
  voice_settings: {
@@ -5564,18 +5564,18 @@ class Be {
5564
5564
  lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
5565
5565
  lipsyncLang: h
5566
5566
  });
5567
- const d = this.lipsyncPreProcessText(e, h), c = this.lipsyncWordsToVisemes(d, h);
5567
+ const c = this.lipsyncPreProcessText(e, h), d = this.lipsyncWordsToVisemes(c, h);
5568
5568
  if (console.log("Lip-sync data:", {
5569
- processedText: d,
5570
- lipsyncData: c,
5571
- hasVisemes: c && c.visemes && c.visemes.length > 0
5572
- }), c && c.visemes && c.visemes.length > 0)
5569
+ processedText: c,
5570
+ lipsyncData: d,
5571
+ hasVisemes: d && d.visemes && d.visemes.length > 0
5572
+ }), d && d.visemes && d.visemes.length > 0)
5573
5573
  r = {
5574
- visemes: c.visemes.map((g, y) => ({
5574
+ visemes: d.visemes.map((g, x) => ({
5575
5575
  viseme: g,
5576
- startTime: y * l.duration / c.visemes.length,
5577
- endTime: (y + 1) * l.duration / c.visemes.length,
5578
- duration: l.duration / c.visemes.length,
5576
+ startTime: x * l.duration / d.visemes.length,
5577
+ endTime: (x + 1) * l.duration / d.visemes.length,
5578
+ duration: l.duration / d.visemes.length,
5579
5579
  intensity: 0.7
5580
5580
  })),
5581
5581
  words: [],
@@ -5584,17 +5584,17 @@ class Be {
5584
5584
  };
5585
5585
  else
5586
5586
  throw new Error("No visemes generated from text");
5587
- } catch (d) {
5588
- console.error("Text-based lip-sync failed, using fallback:", d);
5589
- const c = e.toLowerCase().split(/\s+/), g = [];
5590
- for (const y of c)
5591
- for (const b of y) {
5587
+ } catch (c) {
5588
+ console.error("Text-based lip-sync failed, using fallback:", c);
5589
+ const d = e.toLowerCase().split(/\s+/), g = [];
5590
+ for (const x of d)
5591
+ for (const b of x) {
5592
5592
  let I = "aa";
5593
5593
  "aeiou".includes(b) ? I = "aa" : "bp".includes(b) ? I = "PP" : "fv".includes(b) ? I = "FF" : "st".includes(b) ? I = "SS" : "dln".includes(b) ? I = "DD" : "kg".includes(b) ? I = "kk" : "rw".includes(b) && (I = "RR"), g.push(I);
5594
5594
  }
5595
5595
  r = {
5596
- visemes: g.map((y, b) => ({
5597
- viseme: y,
5596
+ visemes: g.map((x, b) => ({
5597
+ viseme: x,
5598
5598
  startTime: b * l.duration / g.length,
5599
5599
  endTime: (b + 1) * l.duration / g.length,
5600
5600
  duration: l.duration / g.length,
@@ -5620,13 +5620,13 @@ class Be {
5620
5620
  const u = [];
5621
5621
  if (r.visemes && r.visemes.length > 0) {
5622
5622
  console.log("ElevenLabs: Generating lip-sync animation from", r.visemes.length, "visemes");
5623
- for (let d = 0; d < r.visemes.length; d++) {
5624
- const c = r.visemes[d], g = c.startTime * 1e3, y = c.duration * 1e3, b = c.intensity;
5623
+ for (let c = 0; c < r.visemes.length; c++) {
5624
+ const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
5625
5625
  u.push({
5626
5626
  template: { name: "viseme" },
5627
- ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
5627
+ ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
5628
5628
  vs: {
5629
- ["viseme_" + c.viseme]: [null, b, 0]
5629
+ ["viseme_" + d.viseme]: [null, b, 0]
5630
5630
  }
5631
5631
  });
5632
5632
  }
@@ -5641,7 +5641,7 @@ class Be {
5641
5641
  * @param {Object} line Speech line object
5642
5642
  */
5643
5643
  async synthesizeWithDeepgramTTS(t) {
5644
- const e = t.text.map((d) => d.word).join(" "), n = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice || "aura-2-thalia-en", i = `${this.opt.ttsEndpoint}?model=${n}`, s = await fetch(i, {
5644
+ const e = t.text.map((c) => c.word).join(" "), n = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice || "aura-2-thalia-en", i = `${this.opt.ttsEndpoint}?model=${n}`, s = await fetch(i, {
5645
5645
  method: "POST",
5646
5646
  headers: {
5647
5647
  Authorization: `Token ${this.opt.ttsApikey}`,
@@ -5662,18 +5662,18 @@ class Be {
5662
5662
  lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
5663
5663
  lipsyncLang: h
5664
5664
  });
5665
- const d = this.lipsyncPreProcessText(e, h), c = this.lipsyncWordsToVisemes(d, h);
5665
+ const c = this.lipsyncPreProcessText(e, h), d = this.lipsyncWordsToVisemes(c, h);
5666
5666
  if (console.log("Lip-sync data:", {
5667
- processedText: d,
5668
- lipsyncData: c,
5669
- hasVisemes: c && c.visemes && c.visemes.length > 0
5670
- }), c && c.visemes && c.visemes.length > 0)
5667
+ processedText: c,
5668
+ lipsyncData: d,
5669
+ hasVisemes: d && d.visemes && d.visemes.length > 0
5670
+ }), d && d.visemes && d.visemes.length > 0)
5671
5671
  r = {
5672
- visemes: c.visemes.map((g, y) => ({
5672
+ visemes: d.visemes.map((g, x) => ({
5673
5673
  viseme: g,
5674
- startTime: y * l.duration / c.visemes.length,
5675
- endTime: (y + 1) * l.duration / c.visemes.length,
5676
- duration: l.duration / c.visemes.length,
5674
+ startTime: x * l.duration / d.visemes.length,
5675
+ endTime: (x + 1) * l.duration / d.visemes.length,
5676
+ duration: l.duration / d.visemes.length,
5677
5677
  intensity: 0.7
5678
5678
  })),
5679
5679
  words: [],
@@ -5682,17 +5682,17 @@ class Be {
5682
5682
  };
5683
5683
  else
5684
5684
  throw new Error("No visemes generated from text");
5685
- } catch (d) {
5686
- console.error("Text-based lip-sync failed, using fallback:", d);
5687
- const c = e.toLowerCase().split(/\s+/), g = [];
5688
- for (const y of c)
5689
- for (const b of y) {
5685
+ } catch (c) {
5686
+ console.error("Text-based lip-sync failed, using fallback:", c);
5687
+ const d = e.toLowerCase().split(/\s+/), g = [];
5688
+ for (const x of d)
5689
+ for (const b of x) {
5690
5690
  let I = "aa";
5691
5691
  "aeiou".includes(b) ? I = "aa" : "bp".includes(b) ? I = "PP" : "fv".includes(b) ? I = "FF" : "st".includes(b) ? I = "SS" : "dln".includes(b) ? I = "DD" : "kg".includes(b) ? I = "kk" : "rw".includes(b) && (I = "RR"), g.push(I);
5692
5692
  }
5693
5693
  r = {
5694
- visemes: g.map((y, b) => ({
5695
- viseme: y,
5694
+ visemes: g.map((x, b) => ({
5695
+ viseme: x,
5696
5696
  startTime: b * l.duration / g.length,
5697
5697
  endTime: (b + 1) * l.duration / g.length,
5698
5698
  duration: l.duration / g.length,
@@ -5718,13 +5718,13 @@ class Be {
5718
5718
  const u = [];
5719
5719
  if (r.visemes && r.visemes.length > 0) {
5720
5720
  console.log("Deepgram: Generating lip-sync animation from", r.visemes.length, "visemes");
5721
- for (let d = 0; d < r.visemes.length; d++) {
5722
- const c = r.visemes[d], g = c.startTime * 1e3, y = c.duration * 1e3, b = c.intensity;
5721
+ for (let c = 0; c < r.visemes.length; c++) {
5722
+ const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
5723
5723
  u.push({
5724
5724
  template: { name: "viseme" },
5725
- ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
5725
+ ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
5726
5726
  vs: {
5727
- ["viseme_" + c.viseme]: [null, b, 0]
5727
+ ["viseme_" + d.viseme]: [null, b, 0]
5728
5728
  }
5729
5729
  });
5730
5730
  }
@@ -5771,12 +5771,12 @@ class Be {
5771
5771
  });
5772
5772
  const r = [];
5773
5773
  for (let a = 0; a < h.visemes.length; a++) {
5774
- const d = h.visemes[a], c = d.startTime * 1e3, g = d.duration * 1e3, y = d.intensity;
5774
+ const c = h.visemes[a], d = c.startTime * 1e3, g = c.duration * 1e3, x = c.intensity;
5775
5775
  r.push({
5776
5776
  template: { name: "viseme" },
5777
- ts: [c - Math.min(60, 2 * g / 3), c + Math.min(25, g / 2), c + g + Math.min(60, g / 2)],
5777
+ ts: [d - Math.min(60, 2 * g / 3), d + Math.min(25, g / 2), d + g + Math.min(60, g / 2)],
5778
5778
  vs: {
5779
- ["viseme_" + d.viseme]: [null, y, 0]
5779
+ ["viseme_" + c.viseme]: [null, x, 0]
5780
5780
  }
5781
5781
  });
5782
5782
  }
@@ -5822,25 +5822,25 @@ class Be {
5822
5822
  this.speakWithHands();
5823
5823
  const h = [0];
5824
5824
  let r = 0;
5825
- t.text.forEach((d, c) => {
5826
- if (c > 0) {
5825
+ t.text.forEach((c, d) => {
5826
+ if (d > 0) {
5827
5827
  let g = h[h.length - 1];
5828
- s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + d.mark && r++), h.push(g);
5828
+ s.timepoints[r] && (g = s.timepoints[r].timeSeconds * 1e3, s.timepoints[r].markName === "" + c.mark && r++), h.push(g);
5829
5829
  }
5830
5830
  });
5831
5831
  const u = [{ mark: 0, time: 0 }];
5832
- h.forEach((d, c) => {
5833
- if (c > 0) {
5834
- let g = d - h[c - 1];
5835
- u[c - 1].duration = g, u.push({ mark: c, time: d });
5832
+ h.forEach((c, d) => {
5833
+ if (d > 0) {
5834
+ let g = c - h[d - 1];
5835
+ u[d - 1].duration = g, u.push({ mark: d, time: c });
5836
5836
  }
5837
5837
  });
5838
5838
  let a = 1e3 * l.duration;
5839
- a > this.opt.ttsTrimEnd && (a = a - this.opt.ttsTrimEnd), u[u.length - 1].duration = a - u[u.length - 1].time, t.anim.forEach((d) => {
5840
- const c = u[d.mark];
5841
- if (c)
5842
- for (let g = 0; g < d.ts.length; g++)
5843
- d.ts[g] = c.time + d.ts[g] * c.duration + this.opt.ttsTrimStart;
5839
+ a > this.opt.ttsTrimEnd && (a = a - this.opt.ttsTrimEnd), u[u.length - 1].duration = a - u[u.length - 1].time, t.anim.forEach((c) => {
5840
+ const d = u[c.mark];
5841
+ if (d)
5842
+ for (let g = 0; g < c.ts.length; g++)
5843
+ c.ts[g] = d.time + c.ts[g] * d.duration + this.opt.ttsTrimStart;
5844
5844
  }), this.audioPlaylist.push({ anim: t.anim, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
5845
5845
  } else
5846
5846
  this.startSpeaking(!0);
@@ -6059,15 +6059,15 @@ class Be {
6059
6059
  const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, h = this.lipsyncPreProcessText(i, l), r = this.lipsyncWordsToVisemes(h, l);
6060
6060
  if (r && r.visemes && r.visemes.length) {
6061
6061
  const u = r.times[r.visemes.length - 1] + r.durations[r.visemes.length - 1], a = Math.min(o, Math.max(0, o - r.visemes.length * 150));
6062
- let d = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
6062
+ let c = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
6063
6063
  if (o = Math.min(o, r.visemes.length * 200), u > 0)
6064
- for (let c = 0; c < r.visemes.length; c++) {
6065
- const g = e + s + r.times[c] / u * o, y = r.durations[c] / u * o;
6064
+ for (let d = 0; d < r.visemes.length; d++) {
6065
+ const g = e + s + r.times[d] / u * o, x = r.durations[d] / u * o;
6066
6066
  this.animQueue.push({
6067
6067
  template: { name: "viseme" },
6068
- ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
6068
+ ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
6069
6069
  vs: {
6070
- ["viseme_" + r.visemes[c]]: [null, r.visemes[c] === "PP" || r.visemes[c] === "FF" ? 0.9 : d, 0]
6070
+ ["viseme_" + r.visemes[d]]: [null, r.visemes[d] === "PP" || r.visemes[d] === "FF" ? 0.9 : c, 0]
6071
6071
  }
6072
6072
  });
6073
6073
  }
@@ -6158,7 +6158,7 @@ class Be {
6158
6158
  */
6159
6159
  lookAtCamera(t) {
6160
6160
  let e;
6161
- if (this.speakTo && (e = new x.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(ve, Re).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) {
6161
+ if (this.speakTo && (e = new f.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(ve, Re).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) {
6162
6162
  if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
6163
6163
  if (this.avatar.avatarIgnoreCamera) {
6164
6164
  this.lookAhead(t);
@@ -6172,21 +6172,21 @@ class Be {
6172
6172
  return;
6173
6173
  }
6174
6174
  this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]);
6175
- const n = new x.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6176
- W.set(s, i, 0, "YXZ");
6177
- const l = new x.Quaternion().setFromEuler(W), h = new x.Quaternion().copy(l).multiply(Q.clone().invert());
6178
- W.setFromQuaternion(h, "YXZ");
6179
- let r = W.x / (40 / 24) + 0.2, u = W.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), d = Math.min(0.8, Math.max(-0.8, u)), c = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6175
+ const n = new f.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6176
+ V.set(s, i, 0, "YXZ");
6177
+ const l = new f.Quaternion().setFromEuler(V), h = new f.Quaternion().copy(l).multiply(Q.clone().invert());
6178
+ V.setFromQuaternion(h, "YXZ");
6179
+ let r = V.x / (40 / 24) + 0.2, u = V.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), c = Math.min(0.8, Math.max(-0.8, u)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6180
6180
  if (t) {
6181
- let y = this.animQueue.findIndex((I) => I.template.name === "lookat");
6182
- y !== -1 && this.animQueue.splice(y, 1);
6181
+ let x = this.animQueue.findIndex((I) => I.template.name === "lookat");
6182
+ x !== -1 && this.animQueue.splice(x, 1);
6183
6183
  const b = {
6184
6184
  name: "lookat",
6185
6185
  dt: [750, t],
6186
6186
  vs: {
6187
- bodyRotateX: [a + c],
6188
- bodyRotateY: [d + g],
6189
- eyesRotateX: [-3 * c + 0.1],
6187
+ bodyRotateX: [a + d],
6188
+ bodyRotateY: [c + g],
6189
+ eyesRotateX: [-3 * d + 0.1],
6190
6190
  eyesRotateY: [-5 * g],
6191
6191
  browInnerUp: [[0, 0.7]],
6192
6192
  mouthLeft: [[0, 0.7]],
@@ -6208,23 +6208,23 @@ class Be {
6208
6208
  if (!this.camera) return;
6209
6209
  const i = this.nodeAvatar.getBoundingClientRect();
6210
6210
  this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
6211
- const s = new x.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new x.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new x.Vector3().addVectors(s, o).divideScalar(2);
6211
+ const s = new f.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new f.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new f.Vector3().addVectors(s, o).divideScalar(2);
6212
6212
  l.project(this.camera);
6213
6213
  let h = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
6214
- t === null && (t = h), e === null && (e = r), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]), W.setFromQuaternion(Q);
6215
- let u = W.x / (40 / 24), a = W.y / (9 / 4), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - h, h), y = Math.max(window.innerHeight - r, r), b = this.convertRange(e, [r - y, r + y], [-0.3, 0.6]) - u + d, I = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + c;
6214
+ t === null && (t = h), e === null && (e = r), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]), V.setFromQuaternion(Q);
6215
+ let u = V.x / (40 / 24), a = V.y / (9 / 4), c = 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 - h, h), x = Math.max(window.innerHeight - r, r), b = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - u + c, I = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + d;
6216
6216
  b = Math.min(0.6, Math.max(-0.3, b)), I = Math.min(0.8, Math.max(-0.8, I));
6217
- let V = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6217
+ let B = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6218
6218
  if (n) {
6219
- let M = this.animQueue.findIndex((f) => f.template.name === "lookat");
6219
+ let M = this.animQueue.findIndex((y) => y.template.name === "lookat");
6220
6220
  M !== -1 && this.animQueue.splice(M, 1);
6221
6221
  const z = {
6222
6222
  name: "lookat",
6223
6223
  dt: [750, n],
6224
6224
  vs: {
6225
- bodyRotateX: [b + V],
6225
+ bodyRotateX: [b + B],
6226
6226
  bodyRotateY: [I + p],
6227
- eyesRotateX: [-3 * V + 0.1],
6227
+ eyesRotateX: [-3 * B + 0.1],
6228
6228
  eyesRotateY: [-5 * p],
6229
6229
  browInnerUp: [[0, 0.7]],
6230
6230
  mouthLeft: [[0, 0.7]],
@@ -6244,14 +6244,14 @@ class Be {
6244
6244
  */
6245
6245
  touchAt(t, e) {
6246
6246
  if (!this.camera) return;
6247
- const n = this.nodeAvatar.getBoundingClientRect(), i = new x.Vector2(
6247
+ const n = this.nodeAvatar.getBoundingClientRect(), i = new f.Vector2(
6248
6248
  (t - n.left) / n.width * 2 - 1,
6249
6249
  -((e - n.top) / n.height) * 2 + 1
6250
- ), s = new x.Raycaster();
6250
+ ), s = new f.Raycaster();
6251
6251
  s.setFromCamera(i, this.camera);
6252
6252
  const o = s.intersectObject(this.armature);
6253
6253
  if (o.length > 0) {
6254
- const l = o[0].point, h = new x.Vector3(), r = new x.Vector3();
6254
+ const l = o[0].point, h = new f.Vector3(), r = new f.Vector3();
6255
6255
  this.objectLeftArm.getWorldPosition(h), this.objectRightArm.getWorldPosition(r);
6256
6256
  const u = h.distanceToSquared(l), a = r.distanceToSquared(l);
6257
6257
  u < a ? (this.ikSolve({
@@ -6295,7 +6295,7 @@ class Be {
6295
6295
  { link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
6296
6296
  { link: "LeftArm", minx: -1.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -1, maxz: 3 }
6297
6297
  ]
6298
- }, new x.Vector3(
6298
+ }, new f.Vector3(
6299
6299
  this.gaussianRandom(0, 0.5),
6300
6300
  this.gaussianRandom(-0.8, -0.2),
6301
6301
  this.gaussianRandom(0, 0.5)
@@ -6307,15 +6307,15 @@ class Be {
6307
6307
  { link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5 },
6308
6308
  { link: "RightArm" }
6309
6309
  ]
6310
- }, new x.Vector3(
6310
+ }, new f.Vector3(
6311
6311
  this.gaussianRandom(-0.5, 0),
6312
6312
  this.gaussianRandom(-0.8, -0.2),
6313
6313
  this.gaussianRandom(0, 0.5)
6314
6314
  ), !0);
6315
6315
  const n = [], i = [];
6316
6316
  n.push(100 + Math.round(Math.random() * 500)), i.push({ duration: 1e3, props: {
6317
- "LeftHand.quaternion": new x.Quaternion().setFromEuler(new x.Euler(0, -1 - Math.random(), 0)),
6318
- "RightHand.quaternion": new x.Quaternion().setFromEuler(new x.Euler(0, 1 + Math.random(), 0))
6317
+ "LeftHand.quaternion": new f.Quaternion().setFromEuler(new f.Euler(0, -1 - Math.random(), 0)),
6318
+ "RightHand.quaternion": new f.Quaternion().setFromEuler(new f.Euler(0, 1 + Math.random(), 0))
6319
6319
  } }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm"].forEach((o) => {
6320
6320
  i[0].props[o + ".quaternion"] = this.ikMesh.getObjectByName(o).quaternion.clone();
6321
6321
  }), n.push(1e3 + Math.round(Math.random() * 500)), i.push({ duration: 2e3, props: {} }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm", "LeftHand", "RightHand"].forEach((o) => {
@@ -6392,6 +6392,29 @@ class Be {
6392
6392
  * @param {number} [ndx=0] Index of the clip
6393
6393
  * @param {number} [scale=0.01] Position scale factor
6394
6394
  */
6395
+ /**
6396
+ * Get all bone names from the avatar's armature
6397
+ * @returns {Set<string>} Set of bone names
6398
+ */
6399
+ getAvailableBoneNames() {
6400
+ const t = /* @__PURE__ */ new Set();
6401
+ return this.armature && this.armature.traverse((e) => {
6402
+ (e.isBone || e.type === "Bone") && t.add(e.name);
6403
+ }), t;
6404
+ }
6405
+ /**
6406
+ * Filter animation tracks to only include bones that exist in the avatar
6407
+ * @param {THREE.AnimationClip} clip - Animation clip to filter
6408
+ * @param {Set<string>} availableBones - Set of available bone names
6409
+ * @returns {THREE.AnimationClip} Filtered animation clip
6410
+ */
6411
+ filterAnimationTracks(t, e) {
6412
+ const n = [], i = /* @__PURE__ */ new Set();
6413
+ return t.tracks.forEach((s) => {
6414
+ const l = s.name.split(".")[0];
6415
+ e.has(l) ? n.push(s) : i.add(l);
6416
+ }), i.size > 0 ? (console.warn(`FBX animation "${t.name}" contains tracks for ${i.size} bone(s) not found in avatar skeleton:`, Array.from(i).slice(0, 10).join(", "), i.size > 10 ? "..." : ""), console.info(`Filtered ${t.tracks.length} tracks down to ${n.length} valid tracks`)) : n.length > 0 && console.info(`FBX animation "${t.name}" is fully compatible: all ${n.length} tracks match avatar skeleton`), n.length === 0 ? (console.error(`No valid tracks found for animation "${t.name}". All bones are missing from avatar skeleton.`), null) : new f.AnimationClip(t.name, t.duration, n);
6417
+ }
6395
6418
  async playAnimation(t, e = null, n = 10, i = 0, s = 0.01, o = !1) {
6396
6419
  if (!this.armature) return;
6397
6420
  this.positionWasLocked = !o, o ? console.log("Position locking disabled for FBX animation:", t) : (this.lockAvatarPosition(), console.log("Position locked immediately before FBX animation:", t));
@@ -6400,9 +6423,9 @@ class Be {
6400
6423
  let h = this.animQueue.find((a) => a.template.name === "pose");
6401
6424
  h && (h.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((a) => {
6402
6425
  this.poseBase.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]].t = 0, this.poseTarget.props[a[0]].d = 1e3;
6403
- }), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new x.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
6426
+ }), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new f.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
6404
6427
  const r = Math.ceil(n / l.clip.duration), u = this.mixer.clipAction(l.clip);
6405
- u.setLoop(x.LoopRepeat, r), u.clampWhenFinished = !0, this.currentFBXAction = u;
6428
+ u.setLoop(f.LoopRepeat, r), u.clampWhenFinished = !0, this.currentFBXAction = u;
6406
6429
  try {
6407
6430
  u.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
6408
6431
  } catch (a) {
@@ -6420,58 +6443,64 @@ class Be {
6420
6443
  }
6421
6444
  let r = !1;
6422
6445
  try {
6423
- const d = await fetch(t, { method: "HEAD" });
6424
- if (r = d.ok, !r) {
6425
- console.error(`FBX file not found at ${t}. 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)");
6446
+ const c = await fetch(t, { method: "HEAD" });
6447
+ if (r = c.ok, !r) {
6448
+ console.error(`FBX file not found at ${t}. Status: ${c.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)");
6426
6449
  return;
6427
6450
  }
6428
- } catch (d) {
6429
- console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, d);
6451
+ } catch (c) {
6452
+ console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, c);
6430
6453
  }
6431
- const u = new De();
6454
+ const u = new Oe();
6432
6455
  let a;
6433
6456
  try {
6434
6457
  a = await u.loadAsync(t, e);
6435
- } catch (d) {
6436
- console.error(`Failed to load FBX animation from ${t}:`, d), console.error("Error details:", {
6437
- message: d.message,
6458
+ } catch (c) {
6459
+ console.error(`Failed to load FBX animation from ${t}:`, c), console.error("Error details:", {
6460
+ message: c.message,
6438
6461
  url: t,
6439
6462
  suggestion: "Make sure the file is a valid FBX file and the path is correct"
6440
- }), d.message && d.message.includes("version number") && (console.error("FBX Loader Error: Cannot find version number"), console.error("This error usually means:"), console.error("1. The file is not a valid FBX file (might be GLB, corrupted, or wrong format)"), console.error("2. The file might be corrupted"), console.error("3. The file path might be incorrect"), console.error("4. The server returned an HTML error page instead of the FBX file"), console.error("5. The file might not exist at that path"), console.error(""), console.error("Solution: Please verify:"), console.error(` - File exists at: ${t}`), console.error(" - File is a valid FBX binary file"), console.error(" - File path matches your public folder structure"), console.error(" - File is not corrupted"));
6463
+ }), c.message && c.message.includes("version number") && (console.error("FBX Loader Error: Cannot find version number"), console.error("This error usually means:"), console.error("1. The file is not a valid FBX file (might be GLB, corrupted, or wrong format)"), console.error("2. The file might be corrupted"), console.error("3. The file path might be incorrect"), console.error("4. The server returned an HTML error page instead of the FBX file"), console.error("5. The file might not exist at that path"), console.error(""), console.error("Solution: Please verify:"), console.error(` - File exists at: ${t}`), console.error(" - File is a valid FBX binary file"), console.error(" - File path matches your public folder structure"), console.error(" - File is not corrupted"));
6441
6464
  try {
6442
- const c = await fetch(t), g = c.headers.get("content-type"), y = await c.text();
6465
+ const d = await fetch(t), g = d.headers.get("content-type"), x = await d.text();
6443
6466
  console.error("Response details:", {
6444
- status: c.status,
6467
+ status: d.status,
6445
6468
  contentType: g,
6446
- firstBytes: y.substring(0, 100),
6447
- isHTML: y.trim().startsWith("<!DOCTYPE") || y.trim().startsWith("<html")
6448
- }), (y.trim().startsWith("<!DOCTYPE") || y.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
6449
- } catch (c) {
6450
- console.error("Could not fetch file for debugging:", c);
6469
+ firstBytes: x.substring(0, 100),
6470
+ isHTML: x.trim().startsWith("<!DOCTYPE") || x.trim().startsWith("<html")
6471
+ }), (x.trim().startsWith("<!DOCTYPE") || x.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
6472
+ } catch (d) {
6473
+ console.error("Could not fetch file for debugging:", d);
6451
6474
  }
6452
6475
  return;
6453
6476
  }
6454
6477
  if (a && a.animations && a.animations[i]) {
6455
- let d = a.animations[i];
6456
- const c = {};
6457
- d.tracks.forEach((y) => {
6458
- y.name = y.name.replaceAll("mixamorig", "");
6459
- const b = y.name.split(".");
6460
- if (b[1] === "position") {
6461
- for (let I = 0; I < y.values.length; I++)
6462
- y.values[I] = y.values[I] * s;
6463
- c[y.name] = new x.Vector3(y.values[0], y.values[1], y.values[2]);
6464
- } else b[1] === "quaternion" ? c[y.name] = new x.Quaternion(y.values[0], y.values[1], y.values[2], y.values[3]) : b[1] === "rotation" && (c[b[0] + ".quaternion"] = new x.Quaternion().setFromEuler(new x.Euler(y.values[0], y.values[1], y.values[2], "XYZ")).normalize());
6478
+ let c = a.animations[i];
6479
+ const d = this.getAvailableBoneNames(), g = this.filterAnimationTracks(c, d);
6480
+ if (!g) {
6481
+ console.error(`Cannot play FBX animation "${t}": No compatible bones found.`);
6482
+ return;
6483
+ }
6484
+ c = g;
6485
+ const x = {};
6486
+ c.tracks.forEach((I) => {
6487
+ I.name = I.name.replaceAll("mixamorig", "");
6488
+ const B = I.name.split(".");
6489
+ if (B[1] === "position") {
6490
+ for (let p = 0; p < I.values.length; p++)
6491
+ I.values[p] = I.values[p] * s;
6492
+ x[I.name] = new f.Vector3(I.values[0], I.values[1], I.values[2]);
6493
+ } else B[1] === "quaternion" ? x[I.name] = new f.Quaternion(I.values[0], I.values[1], I.values[2], I.values[3]) : B[1] === "rotation" && (x[B[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(I.values[0], I.values[1], I.values[2], "XYZ")).normalize());
6465
6494
  });
6466
- const g = { props: c };
6467
- c["Hips.position"] && (c["Hips.position"].y < 0.5 ? g.lying = !0 : g.standing = !0), this.animClips.push({
6495
+ const b = { props: x };
6496
+ x["Hips.position"] && (x["Hips.position"].y < 0.5 ? b.lying = !0 : b.standing = !0), this.animClips.push({
6468
6497
  url: t + "-" + i,
6469
- clip: d,
6470
- pose: g
6498
+ clip: c,
6499
+ pose: b
6471
6500
  }), this.playAnimation(t, e, n, i, s);
6472
6501
  } else {
6473
- const d = "Animation " + t + " (ndx=" + i + ") not found";
6474
- console.error(d), a && a.animations ? console.error(`FBX file loaded but has ${a.animations.length} animation(s), requested index ${i}`) : console.error(a ? "FBX file loaded but contains no animations" : "FBX file failed to load or is invalid");
6502
+ const c = "Animation " + t + " (ndx=" + i + ") not found";
6503
+ console.error(c), a && a.animations ? console.error(`FBX file loaded but has ${a.animations.length} animation(s), requested index ${i}`) : console.error(a ? "FBX file loaded but contains no animations" : "FBX file failed to load or is invalid");
6475
6504
  }
6476
6505
  }
6477
6506
  }
@@ -6505,14 +6534,14 @@ class Be {
6505
6534
  let l = this.animQueue.find((h) => h.template.name === "pose");
6506
6535
  l && (l.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(o);
6507
6536
  } else {
6508
- let h = await new De().loadAsync(t, e);
6537
+ let h = await new Oe().loadAsync(t, e);
6509
6538
  if (h && h.animations && h.animations[i]) {
6510
6539
  let r = h.animations[i];
6511
6540
  const u = {};
6512
- r.tracks.forEach((d) => {
6513
- d.name = d.name.replaceAll("mixamorig", "");
6514
- const c = d.name.split(".");
6515
- c[1] === "position" ? u[d.name] = new x.Vector3(d.values[0] * s, d.values[1] * s, d.values[2] * s) : c[1] === "quaternion" ? u[d.name] = new x.Quaternion(d.values[0], d.values[1], d.values[2], d.values[3]) : c[1] === "rotation" && (u[c[0] + ".quaternion"] = new x.Quaternion().setFromEuler(new x.Euler(d.values[0], d.values[1], d.values[2], "XYZ")).normalize());
6541
+ r.tracks.forEach((c) => {
6542
+ c.name = c.name.replaceAll("mixamorig", "");
6543
+ const d = c.name.split(".");
6544
+ d[1] === "position" ? u[c.name] = new f.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? u[c.name] = new f.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (u[d[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
6516
6545
  });
6517
6546
  const a = { props: u };
6518
6547
  u["Hips.position"] && (u["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
@@ -6545,7 +6574,7 @@ class Be {
6545
6574
  if (s) {
6546
6575
  this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
6547
6576
  let l = this.animQueue.findIndex((h) => h.template.name === "talkinghands");
6548
- l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((h) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new x.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new x.Quaternion(0, 1, 0, 0), -0.25));
6577
+ l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((h) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25));
6549
6578
  for (let [h, r] of Object.entries(this.gesture))
6550
6579
  r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(h) && (this.poseTarget.props[h].copy(r), this.poseTarget.props[h].t = this.animClock, this.poseTarget.props[h].d = i);
6551
6580
  e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
@@ -6557,13 +6586,13 @@ class Be {
6557
6586
  if (l.gesture = !0, e && Number.isFinite(e)) {
6558
6587
  const h = l.ts[0], u = l.ts[l.ts.length - 1] - h;
6559
6588
  if (e * 1e3 - u > 0) {
6560
- const d = [];
6561
- for (let y = 1; y < l.ts.length; y++) d.push(l.ts[y] - l.ts[y - 1]);
6562
- const c = o.template?.rescale || d.map((y) => y / u), g = e * 1e3 - u;
6563
- l.ts = l.ts.map((y, b, I) => b === 0 ? h : I[b - 1] + d[b - 1] + c[b - 1] * g);
6589
+ const c = [];
6590
+ for (let x = 1; x < l.ts.length; x++) c.push(l.ts[x] - l.ts[x - 1]);
6591
+ const d = o.template?.rescale || c.map((x) => x / u), g = e * 1e3 - u;
6592
+ l.ts = l.ts.map((x, b, I) => b === 0 ? h : I[b - 1] + c[b - 1] + d[b - 1] * g);
6564
6593
  } else {
6565
- const d = e * 1e3 / u;
6566
- l.ts = l.ts.map((c) => h + d * (c - h));
6594
+ const c = e * 1e3 / u;
6595
+ l.ts = l.ts.map((d) => h + c * (d - h));
6567
6596
  }
6568
6597
  }
6569
6598
  this.animQueue.push(l);
@@ -6593,33 +6622,33 @@ class Be {
6593
6622
  * @param {numeric} [d=null] If set, apply in d milliseconds
6594
6623
  */
6595
6624
  ikSolve(t, e = null, n = !1, i = null) {
6596
- const s = new x.Vector3(), o = new x.Vector3(), l = new x.Vector3(), h = new x.Vector3(), r = new x.Quaternion(), u = new x.Vector3(), a = new x.Vector3(), d = new x.Vector3(), c = this.ikMesh.getObjectByName(t.root);
6597
- c.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), c.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && n && e.applyQuaternion(this.armature.quaternion).add(c.position);
6598
- const g = this.ikMesh.getObjectByName(t.effector), y = t.links;
6599
- y.forEach((I) => {
6625
+ const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(), h = new f.Vector3(), r = new f.Quaternion(), u = new f.Vector3(), a = new f.Vector3(), c = new f.Vector3(), d = this.ikMesh.getObjectByName(t.root);
6626
+ d.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && n && e.applyQuaternion(this.armature.quaternion).add(d.position);
6627
+ const g = this.ikMesh.getObjectByName(t.effector), x = t.links;
6628
+ x.forEach((I) => {
6600
6629
  I.bone = this.ikMesh.getObjectByName(I.link), I.bone.quaternion.copy(this.getPoseTemplateProp(I.link + ".quaternion"));
6601
- }), c.updateMatrixWorld(!0);
6630
+ }), d.updateMatrixWorld(!0);
6602
6631
  const b = t.iterations || 10;
6603
6632
  if (e)
6604
6633
  for (let I = 0; I < b; I++) {
6605
- let V = !1;
6606
- for (let p = 0, M = y.length; p < M; p++) {
6607
- const z = y[p].bone;
6634
+ let B = !1;
6635
+ for (let p = 0, M = x.length; p < M; p++) {
6636
+ const z = x[p].bone;
6608
6637
  z.matrixWorld.decompose(h, r, u), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, h), l.applyQuaternion(r), l.normalize(), s.subVectors(e, h), s.applyQuaternion(r), s.normalize();
6609
- let f = s.dot(l);
6610
- f > 1 ? f = 1 : f < -1 && (f = -1), f = Math.acos(f), !(f < 1e-5) && (y[p].minAngle !== void 0 && f < y[p].minAngle && (f = y[p].minAngle), y[p].maxAngle !== void 0 && f > y[p].maxAngle && (f = y[p].maxAngle), a.crossVectors(l, s), a.normalize(), Q.setFromAxisAngle(a, f), z.quaternion.multiply(Q), z.rotation.setFromVector3(d.setFromEuler(z.rotation).clamp(new x.Vector3(
6611
- y[p].minx !== void 0 ? y[p].minx : -1 / 0,
6612
- y[p].miny !== void 0 ? y[p].miny : -1 / 0,
6613
- y[p].minz !== void 0 ? y[p].minz : -1 / 0
6614
- ), new x.Vector3(
6615
- y[p].maxx !== void 0 ? y[p].maxx : 1 / 0,
6616
- y[p].maxy !== void 0 ? y[p].maxy : 1 / 0,
6617
- y[p].maxz !== void 0 ? y[p].maxz : 1 / 0
6618
- ))), z.updateMatrixWorld(!0), V = !0);
6638
+ let y = s.dot(l);
6639
+ y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (x[p].minAngle !== void 0 && y < x[p].minAngle && (y = x[p].minAngle), x[p].maxAngle !== void 0 && y > x[p].maxAngle && (y = x[p].maxAngle), a.crossVectors(l, s), a.normalize(), Q.setFromAxisAngle(a, y), z.quaternion.multiply(Q), z.rotation.setFromVector3(c.setFromEuler(z.rotation).clamp(new f.Vector3(
6640
+ x[p].minx !== void 0 ? x[p].minx : -1 / 0,
6641
+ x[p].miny !== void 0 ? x[p].miny : -1 / 0,
6642
+ x[p].minz !== void 0 ? x[p].minz : -1 / 0
6643
+ ), new f.Vector3(
6644
+ x[p].maxx !== void 0 ? x[p].maxx : 1 / 0,
6645
+ x[p].maxy !== void 0 ? x[p].maxy : 1 / 0,
6646
+ x[p].maxz !== void 0 ? x[p].maxz : 1 / 0
6647
+ ))), z.updateMatrixWorld(!0), B = !0);
6619
6648
  }
6620
- if (!V) break;
6649
+ if (!B) break;
6621
6650
  }
6622
- i && y.forEach((I) => {
6651
+ i && x.forEach((I) => {
6623
6652
  this.poseTarget.props[I.link + ".quaternion"].copy(I.bone.quaternion), this.poseTarget.props[I.link + ".quaternion"].t = this.animClock, this.poseTarget.props[I.link + ".quaternion"].d = i;
6624
6653
  });
6625
6654
  }
@@ -6679,7 +6708,7 @@ function Fe() {
6679
6708
  voices: Ie.voices
6680
6709
  };
6681
6710
  }
6682
- function kt() {
6711
+ function St() {
6683
6712
  const G = Fe(), t = [];
6684
6713
  return Object.entries(G.voices).forEach(([e, n]) => {
6685
6714
  t.push({
@@ -6702,15 +6731,15 @@ const Ve = Me(({
6702
6731
  cameraView: u = "upper",
6703
6732
  onReady: a = () => {
6704
6733
  },
6705
- onLoading: d = () => {
6734
+ onLoading: c = () => {
6706
6735
  },
6707
- onError: c = () => {
6736
+ onError: d = () => {
6708
6737
  },
6709
6738
  className: g = "",
6710
- style: y = {},
6739
+ style: x = {},
6711
6740
  animations: b = {}
6712
6741
  }, I) => {
6713
- const V = O(null), p = O(null), M = O(r), z = O(null), f = O(null), E = O(!1), P = O({ remainingText: null, originalText: null, options: null }), U = O([]), oe = O(0), [S, Z] = ce(!0), [K, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
6742
+ const B = O(null), p = O(null), M = O(r), z = O(null), y = O(null), E = O(!1), P = O({ remainingText: null, originalText: null, options: null }), W = O([]), oe = O(0), [k, Z] = ce(!0), [K, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
6714
6743
  de(() => {
6715
6744
  E.current = ae;
6716
6745
  }, [ae]), de(() => {
@@ -6756,24 +6785,24 @@ const Ve = Me(({
6756
6785
  ttsService: le,
6757
6786
  lipsyncModules: ["en"],
6758
6787
  cameraView: u
6759
- }, k = T(async () => {
6760
- if (!(!V.current || p.current))
6788
+ }, S = T(async () => {
6789
+ if (!(!B.current || p.current))
6761
6790
  try {
6762
- if (Z(!0), X(null), p.current = new Be(V.current, R), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), b && Object.keys(b).length > 0 && (p.current.customAnimations = b), await p.current.showAvatar(v, (B) => {
6763
- if (B.lengthComputable) {
6764
- const J = Math.min(100, Math.round(B.loaded / B.total * 100));
6765
- d(J);
6791
+ if (Z(!0), X(null), p.current = new Be(B.current, R), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), b && Object.keys(b).length > 0 && (p.current.customAnimations = b), await p.current.showAvatar(v, (N) => {
6792
+ if (N.lengthComputable) {
6793
+ const J = Math.min(100, Math.round(N.loaded / N.total * 100));
6794
+ c(J);
6766
6795
  }
6767
- }), await new Promise((B) => {
6796
+ }), await new Promise((N) => {
6768
6797
  const J = () => {
6769
- p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? B() : setTimeout(J, 100);
6798
+ p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? N() : setTimeout(J, 100);
6770
6799
  };
6771
6800
  J();
6772
6801
  }), p.current && p.current.setShowFullAvatar)
6773
6802
  try {
6774
6803
  p.current.setShowFullAvatar(r);
6775
- } catch (B) {
6776
- console.warn("Error setting full body mode on initialization:", B);
6804
+ } catch (N) {
6805
+ console.warn("Error setting full body mode on initialization:", N);
6777
6806
  }
6778
6807
  p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), Z(!1), se(!0), a(p.current);
6779
6808
  const F = () => {
@@ -6783,18 +6812,18 @@ const Ve = Me(({
6783
6812
  document.removeEventListener("visibilitychange", F);
6784
6813
  };
6785
6814
  } catch (L) {
6786
- console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), Z(!1), c(L);
6815
+ console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), Z(!1), d(L);
6787
6816
  }
6788
6817
  }, [G, t, e, n, i, s, o, r, l, h, u]);
6789
- de(() => (k(), () => {
6818
+ de(() => (S(), () => {
6790
6819
  p.current && (p.current.stop(), p.current.dispose(), p.current = null);
6791
- }), [k]), de(() => {
6792
- if (!V.current || !p.current) return;
6793
- const L = new ResizeObserver((B) => {
6794
- for (const J of B)
6820
+ }), [S]), de(() => {
6821
+ if (!B.current || !p.current) return;
6822
+ const L = new ResizeObserver((N) => {
6823
+ for (const J of N)
6795
6824
  p.current && p.current.onResize && p.current.onResize();
6796
6825
  });
6797
- L.observe(V.current);
6826
+ L.observe(B.current);
6798
6827
  const F = () => {
6799
6828
  p.current && p.current.onResize && p.current.onResize();
6800
6829
  };
@@ -6809,39 +6838,39 @@ const Ve = Me(({
6809
6838
  } catch (L) {
6810
6839
  console.warn("Failed to resume audio context:", L);
6811
6840
  }
6812
- }, []), N = T(async (L, F = {}) => {
6841
+ }, []), U = T(async (L, F = {}) => {
6813
6842
  if (p.current && $)
6814
6843
  try {
6815
- f.current && (clearInterval(f.current), f.current = null), z.current = { text: L, options: F }, P.current = { remainingText: null, originalText: null, options: null };
6816
- const B = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(B).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
6817
- U.current = J, oe.current = 0, pe(!1), E.current = !1, await H();
6844
+ y.current && (clearInterval(y.current), y.current = null), z.current = { text: L, options: F }, P.current = { remainingText: null, originalText: null, options: null };
6845
+ const N = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(N).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
6846
+ W.current = J, oe.current = 0, pe(!1), E.current = !1, await H();
6818
6847
  const ge = {
6819
6848
  ...F,
6820
6849
  lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
6821
6850
  };
6822
6851
  if (F.onSpeechEnd && p.current) {
6823
6852
  const Y = p.current;
6824
- let he = null, Se = 0;
6853
+ let he = null, ke = 0;
6825
6854
  const Ae = 1200;
6826
6855
  let be = !1;
6827
6856
  he = setInterval(() => {
6828
- if (Se++, E.current)
6857
+ if (ke++, E.current)
6829
6858
  return;
6830
- if (Se > Ae) {
6831
- if (he && (clearInterval(he), he = null, f.current = null), !be && !E.current) {
6859
+ if (ke > Ae) {
6860
+ if (he && (clearInterval(he), he = null, y.current = null), !be && !E.current) {
6832
6861
  be = !0;
6833
6862
  try {
6834
6863
  F.onSpeechEnd();
6835
- } catch (Oe) {
6836
- console.error("Error in onSpeechEnd callback (timeout):", Oe);
6864
+ } catch (Ne) {
6865
+ console.error("Error in onSpeechEnd callback (timeout):", Ne);
6837
6866
  }
6838
6867
  }
6839
6868
  return;
6840
6869
  }
6841
- const ye = !Y.speechQueue || Y.speechQueue.length === 0, ke = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
6842
- Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !E.current && setTimeout(() => {
6870
+ const ye = !Y.speechQueue || Y.speechQueue.length === 0, Se = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
6871
+ Y && Y.isSpeaking === !1 && ye && Se && Y.isAudioPlaying === !1 && !be && !E.current && setTimeout(() => {
6843
6872
  if (Y && !E.current && Y.isSpeaking === !1 && (!Y.speechQueue || Y.speechQueue.length === 0) && (!Y.audioPlaylist || Y.audioPlaylist.length === 0) && Y.isAudioPlaying === !1 && !be && !E.current) {
6844
- be = !0, he && (clearInterval(he), he = null, f.current = null);
6873
+ be = !0, he && (clearInterval(he), he = null, y.current = null);
6845
6874
  try {
6846
6875
  F.onSpeechEnd();
6847
6876
  } catch (Ze) {
@@ -6849,13 +6878,13 @@ const Ve = Me(({
6849
6878
  }
6850
6879
  }
6851
6880
  }, 100);
6852
- }, 100), f.current = he;
6881
+ }, 100), y.current = he;
6853
6882
  }
6854
6883
  p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge)) : setTimeout(async () => {
6855
6884
  await H(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
6856
6885
  }, 100);
6857
- } catch (B) {
6858
- console.error("Error speaking text:", B), X(B.message || "Failed to speak text");
6886
+ } catch (N) {
6887
+ console.error("Error speaking text:", N), X(N.message || "Failed to speak text");
6859
6888
  }
6860
6889
  }, [$, H, v.lipsyncLang]), _ = T(() => {
6861
6890
  p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, pe(!1));
@@ -6863,17 +6892,17 @@ const Ve = Me(({
6863
6892
  if (p.current && p.current.pauseSpeaking) {
6864
6893
  const L = p.current;
6865
6894
  if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
6866
- f.current && (clearInterval(f.current), f.current = null);
6867
- let B = "";
6868
- if (z.current && U.current.length > 0) {
6869
- const J = U.current.length, ge = L.speechQueue ? L.speechQueue.filter((Ae) => Ae && Ae.text && Array.isArray(Ae.text) && Ae.text.length > 0).length : 0, Y = L.audioPlaylist && L.audioPlaylist.length > 0, he = ge + (Y ? 1 : 0), Se = J - he;
6870
- if (he > 0 && Se < J && (B = U.current.slice(Se).join(". ").trim(), !B && ge > 0 && L.speechQueue)) {
6871
- const be = L.speechQueue.filter((ye) => ye && ye.text && Array.isArray(ye.text) && ye.text.length > 0).map((ye) => ye.text.map((ke) => ke.word || "").filter((ke) => ke.length > 0).join(" ")).filter((ye) => ye.length > 0).join(" ");
6872
- be && be.trim() && (B = be.trim());
6895
+ y.current && (clearInterval(y.current), y.current = null);
6896
+ let N = "";
6897
+ if (z.current && W.current.length > 0) {
6898
+ const J = W.current.length, ge = L.speechQueue ? L.speechQueue.filter((Ae) => Ae && Ae.text && Array.isArray(Ae.text) && Ae.text.length > 0).length : 0, Y = L.audioPlaylist && L.audioPlaylist.length > 0, he = ge + (Y ? 1 : 0), ke = J - he;
6899
+ if (he > 0 && ke < J && (N = W.current.slice(ke).join(". ").trim(), !N && ge > 0 && L.speechQueue)) {
6900
+ const be = L.speechQueue.filter((ye) => ye && ye.text && Array.isArray(ye.text) && ye.text.length > 0).map((ye) => ye.text.map((Se) => Se.word || "").filter((Se) => Se.length > 0).join(" ")).filter((ye) => ye.length > 0).join(" ");
6901
+ be && be.trim() && (N = be.trim());
6873
6902
  }
6874
6903
  }
6875
6904
  z.current && (P.current = {
6876
- remainingText: B || null,
6905
+ remainingText: N || null,
6877
6906
  originalText: z.current.text,
6878
6907
  options: z.current.options
6879
6908
  }), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), E.current = !0, pe(!0);
@@ -6892,16 +6921,16 @@ const Ve = Me(({
6892
6921
  return;
6893
6922
  }
6894
6923
  pe(!1), E.current = !1, await H();
6895
- const B = {
6924
+ const N = {
6896
6925
  ...F,
6897
6926
  lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
6898
6927
  };
6899
6928
  try {
6900
- await N(L, B);
6929
+ await U(L, N);
6901
6930
  } catch (J) {
6902
6931
  console.error("Error resuming speech:", J), pe(!1), E.current = !1;
6903
6932
  }
6904
- }, [H, ae, N, v]), Le = T((L) => {
6933
+ }, [H, ae, U, v]), Le = T((L) => {
6905
6934
  p.current && p.current.setMood(L);
6906
6935
  }, []), we = T((L) => {
6907
6936
  p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
@@ -6947,7 +6976,7 @@ const Ve = Me(({
6947
6976
  p.current && p.current.onResize && p.current.onResize();
6948
6977
  }, []);
6949
6978
  return Ee(I, () => ({
6950
- speakText: N,
6979
+ speakText: U,
6951
6980
  stopSpeaking: _,
6952
6981
  pauseSpeaking: j,
6953
6982
  resumeSpeaking: q,
@@ -7024,13 +7053,13 @@ const Ve = Me(({
7024
7053
  width: "100%",
7025
7054
  height: "100%",
7026
7055
  position: "relative",
7027
- ...y
7056
+ ...x
7028
7057
  },
7029
7058
  children: [
7030
7059
  /* @__PURE__ */ me(
7031
7060
  "div",
7032
7061
  {
7033
- ref: V,
7062
+ ref: B,
7034
7063
  className: "talking-head-viewer",
7035
7064
  style: {
7036
7065
  width: "100%",
@@ -7039,7 +7068,7 @@ const Ve = Me(({
7039
7068
  }
7040
7069
  }
7041
7070
  ),
7042
- S && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7071
+ k && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7043
7072
  position: "absolute",
7044
7073
  top: "50%",
7045
7074
  left: "50%",
@@ -7077,7 +7106,7 @@ const pt = Me(({
7077
7106
  style: s = {},
7078
7107
  avatarConfig: o = {}
7079
7108
  }, l) => {
7080
- const h = O(null), r = O(null), [u, a] = ce(!0), [d, c] = ce(null), [g, y] = ce(!1), b = Fe(), I = o.ttsService || b.service, V = I === "browser" ? {
7109
+ const h = O(null), r = O(null), [u, a] = ce(!0), [c, d] = ce(null), [g, x] = ce(!1), b = Fe(), I = o.ttsService || b.service, B = I === "browser" ? {
7081
7110
  endpoint: "",
7082
7111
  apiKey: null,
7083
7112
  defaultVoice: "Google US English"
@@ -7093,7 +7122,7 @@ const pt = Me(({
7093
7122
  body: "F",
7094
7123
  avatarMood: "neutral",
7095
7124
  ttsLang: I === "browser" ? "en-US" : "en",
7096
- ttsVoice: o.ttsVoice || V.defaultVoice,
7125
+ ttsVoice: o.ttsVoice || B.defaultVoice,
7097
7126
  lipsyncLang: "en",
7098
7127
  // English lip-sync
7099
7128
  showFullAvatar: !0,
@@ -7102,15 +7131,15 @@ const pt = Me(({
7102
7131
  movementIntensity: 0.5,
7103
7132
  ...o
7104
7133
  }, M = {
7105
- ttsEndpoint: V.endpoint,
7106
- ttsApikey: V.apiKey,
7134
+ ttsEndpoint: B.endpoint,
7135
+ ttsApikey: B.apiKey,
7107
7136
  ttsService: I,
7108
7137
  lipsyncModules: ["en"],
7109
7138
  cameraView: "upper"
7110
7139
  }, z = T(async () => {
7111
7140
  if (!(!h.current || r.current))
7112
7141
  try {
7113
- if (a(!0), c(null), r.current = new Be(h.current, M), await r.current.showAvatar(p, (K) => {
7142
+ if (a(!0), d(null), r.current = new Be(h.current, M), await r.current.showAvatar(p, (K) => {
7114
7143
  if (K.lengthComputable) {
7115
7144
  const X = Math.min(100, Math.round(K.loaded / K.total * 100));
7116
7145
  t(X);
@@ -7132,38 +7161,38 @@ const pt = Me(({
7132
7161
  } catch (K) {
7133
7162
  console.warn("Error setting full body mode on initialization:", K);
7134
7163
  }
7135
- a(!1), y(!0), n(r.current);
7164
+ a(!1), x(!0), n(r.current);
7136
7165
  const Z = () => {
7137
7166
  document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
7138
7167
  };
7139
7168
  return document.addEventListener("visibilitychange", Z), () => {
7140
7169
  document.removeEventListener("visibilitychange", Z);
7141
7170
  };
7142
- } catch (S) {
7143
- console.error("Error initializing TalkingHead:", S), c(S.message || "Failed to initialize avatar"), a(!1), e(S);
7171
+ } catch (k) {
7172
+ console.error("Error initializing TalkingHead:", k), d(k.message || "Failed to initialize avatar"), a(!1), e(k);
7144
7173
  }
7145
7174
  }, []);
7146
7175
  de(() => (z(), () => {
7147
7176
  r.current && (r.current.stop(), r.current.dispose(), r.current = null);
7148
7177
  }), [z]);
7149
- const f = T((S) => {
7178
+ const y = T((k) => {
7150
7179
  if (r.current && g)
7151
7180
  try {
7152
- console.log("Speaking text:", S), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7153
- r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : console.error("Lip-sync still not ready after waiting");
7181
+ console.log("Speaking text:", k), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(k)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7182
+ r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(k)) : console.error("Lip-sync still not ready after waiting");
7154
7183
  }, 500));
7155
7184
  } catch (Z) {
7156
- console.error("Error speaking text:", Z), c(Z.message || "Failed to speak text");
7185
+ console.error("Error speaking text:", Z), d(Z.message || "Failed to speak text");
7157
7186
  }
7158
7187
  else
7159
7188
  console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
7160
7189
  }, [g, p]), E = T(() => {
7161
7190
  r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7162
- }, []), P = T((S) => {
7163
- r.current && r.current.setMood(S);
7164
- }, []), U = T((S) => {
7165
- r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
7166
- }, []), oe = T((S, Z = !1) => {
7191
+ }, []), P = T((k) => {
7192
+ r.current && r.current.setMood(k);
7193
+ }, []), W = T((k) => {
7194
+ r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(k), console.log("Timing adjustment set to:", k));
7195
+ }, []), oe = T((k, Z = !1) => {
7167
7196
  if (r.current && r.current.playAnimation) {
7168
7197
  if (r.current.setShowFullAvatar)
7169
7198
  try {
@@ -7171,11 +7200,11 @@ const pt = Me(({
7171
7200
  } catch (X) {
7172
7201
  console.warn("Error setting full body mode:", X);
7173
7202
  }
7174
- if (S.includes("."))
7203
+ if (k.includes("."))
7175
7204
  try {
7176
- r.current.playAnimation(S, null, 10, 0, 0.01, Z), console.log("Playing animation:", S);
7205
+ r.current.playAnimation(k, null, 10, 0, 0.01, Z), console.log("Playing animation:", k);
7177
7206
  } catch (X) {
7178
- console.log(`Failed to play ${S}:`, X);
7207
+ console.log(`Failed to play ${k}:`, X);
7179
7208
  try {
7180
7209
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7181
7210
  } catch ($) {
@@ -7187,13 +7216,13 @@ const pt = Me(({
7187
7216
  let $ = !1;
7188
7217
  for (const se of X)
7189
7218
  try {
7190
- r.current.playAnimation(S + se, null, 10, 0, 0.01, Z), console.log("Playing animation:", S + se), $ = !0;
7219
+ r.current.playAnimation(k + se, null, 10, 0, 0.01, Z), console.log("Playing animation:", k + se), $ = !0;
7191
7220
  break;
7192
7221
  } catch {
7193
- console.log(`Failed to play ${S}${se}, trying next format...`);
7222
+ console.log(`Failed to play ${k}${se}, trying next format...`);
7194
7223
  }
7195
7224
  if (!$) {
7196
- console.warn("Animation system not available or animation not found:", S);
7225
+ console.warn("Animation system not available or animation not found:", k);
7197
7226
  try {
7198
7227
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7199
7228
  } catch (se) {
@@ -7202,37 +7231,37 @@ const pt = Me(({
7202
7231
  }
7203
7232
  }
7204
7233
  } else
7205
- console.warn("Animation system not available or animation not found:", S);
7234
+ console.warn("Animation system not available or animation not found:", k);
7206
7235
  }, []);
7207
7236
  return Ee(l, () => ({
7208
- speakText: f,
7237
+ speakText: y,
7209
7238
  stopSpeaking: E,
7210
7239
  setMood: P,
7211
- setTimingAdjustment: U,
7240
+ setTimingAdjustment: W,
7212
7241
  playAnimation: oe,
7213
7242
  isReady: g,
7214
7243
  talkingHead: r.current,
7215
- setBodyMovement: (S) => {
7244
+ setBodyMovement: (k) => {
7216
7245
  if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
7217
7246
  try {
7218
- r.current.setShowFullAvatar(!0), r.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
7247
+ r.current.setShowFullAvatar(!0), r.current.setBodyMovement(k), console.log("Body movement set with full body mode:", k);
7219
7248
  } catch (Z) {
7220
7249
  console.warn("Error setting body movement:", Z);
7221
7250
  }
7222
7251
  },
7223
- setMovementIntensity: (S) => r.current?.setMovementIntensity(S),
7252
+ setMovementIntensity: (k) => r.current?.setMovementIntensity(k),
7224
7253
  playRandomDance: () => {
7225
7254
  if (r.current && r.current.setShowFullAvatar && r.current.playRandomDance)
7226
7255
  try {
7227
7256
  r.current.setShowFullAvatar(!0), r.current.playRandomDance(), console.log("Random dance played with full body mode");
7228
- } catch (S) {
7229
- console.warn("Error playing random dance:", S);
7257
+ } catch (k) {
7258
+ console.warn("Error playing random dance:", k);
7230
7259
  }
7231
7260
  },
7232
- playReaction: (S) => {
7261
+ playReaction: (k) => {
7233
7262
  if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
7234
7263
  try {
7235
- r.current.setShowFullAvatar(!0), r.current.playReaction(S), console.log("Reaction played with full body mode:", S);
7264
+ r.current.setShowFullAvatar(!0), r.current.playReaction(k), console.log("Reaction played with full body mode:", k);
7236
7265
  } catch (Z) {
7237
7266
  console.warn("Error playing reaction:", Z);
7238
7267
  }
@@ -7241,14 +7270,14 @@ const pt = Me(({
7241
7270
  if (r.current && r.current.setShowFullAvatar && r.current.playCelebration)
7242
7271
  try {
7243
7272
  r.current.setShowFullAvatar(!0), r.current.playCelebration(), console.log("Celebration played with full body mode");
7244
- } catch (S) {
7245
- console.warn("Error playing celebration:", S);
7273
+ } catch (k) {
7274
+ console.warn("Error playing celebration:", k);
7246
7275
  }
7247
7276
  },
7248
- setShowFullAvatar: (S) => {
7277
+ setShowFullAvatar: (k) => {
7249
7278
  if (r.current && r.current.setShowFullAvatar)
7250
7279
  try {
7251
- r.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
7280
+ r.current.setShowFullAvatar(k), console.log("Show full avatar set to:", k);
7252
7281
  } catch (Z) {
7253
7282
  console.warn("Error setting showFullAvatar:", Z);
7254
7283
  }
@@ -7257,16 +7286,16 @@ const pt = Me(({
7257
7286
  if (r.current && r.current.lockAvatarPosition)
7258
7287
  try {
7259
7288
  r.current.lockAvatarPosition();
7260
- } catch (S) {
7261
- console.warn("Error locking avatar position:", S);
7289
+ } catch (k) {
7290
+ console.warn("Error locking avatar position:", k);
7262
7291
  }
7263
7292
  },
7264
7293
  unlockAvatarPosition: () => {
7265
7294
  if (r.current && r.current.unlockAvatarPosition)
7266
7295
  try {
7267
7296
  r.current.unlockAvatarPosition();
7268
- } catch (S) {
7269
- console.warn("Error unlocking avatar position:", S);
7297
+ } catch (k) {
7298
+ console.warn("Error unlocking avatar position:", k);
7270
7299
  }
7271
7300
  }
7272
7301
  })), /* @__PURE__ */ Pe("div", { className: `talking-head-container ${i}`, style: s, children: [
@@ -7291,7 +7320,7 @@ const pt = Me(({
7291
7320
  fontSize: "18px",
7292
7321
  zIndex: 10
7293
7322
  }, children: "Loading avatar..." }),
7294
- d && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
7323
+ c && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
7295
7324
  position: "absolute",
7296
7325
  top: "50%",
7297
7326
  left: "50%",
@@ -7302,7 +7331,7 @@ const pt = Me(({
7302
7331
  zIndex: 10,
7303
7332
  padding: "20px",
7304
7333
  borderRadius: "8px"
7305
- }, children: d })
7334
+ }, children: c })
7306
7335
  ] });
7307
7336
  });
7308
7337
  pt.displayName = "TalkingHeadComponent";
@@ -7319,20 +7348,20 @@ const gt = Me(({
7319
7348
  movementIntensity: r = 0.5,
7320
7349
  showFullAvatar: u = !1,
7321
7350
  cameraView: a = "upper",
7322
- onReady: d = () => {
7351
+ onReady: c = () => {
7323
7352
  },
7324
- onLoading: c = () => {
7353
+ onLoading: d = () => {
7325
7354
  },
7326
7355
  onError: g = () => {
7327
7356
  },
7328
- onSpeechEnd: y = () => {
7357
+ onSpeechEnd: x = () => {
7329
7358
  },
7330
7359
  className: b = "",
7331
7360
  style: I = {},
7332
- animations: V = {},
7361
+ animations: B = {},
7333
7362
  autoSpeak: p = !1
7334
7363
  }, M) => {
7335
- const z = O(null), f = O(null), E = O(u), P = O(null), U = O(null), oe = O(!1), S = O({ remainingText: null, originalText: null, options: null }), Z = O([]), [K, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
7364
+ const z = O(null), y = O(null), E = O(u), P = O(null), W = O(null), oe = O(!1), k = O({ remainingText: null, originalText: null, options: null }), Z = O([]), [K, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
7336
7365
  de(() => {
7337
7366
  oe.current = ee;
7338
7367
  }, [ee]), de(() => {
@@ -7361,7 +7390,7 @@ const gt = Me(({
7361
7390
  ...D,
7362
7391
  apiKey: l !== null ? l : D.apiKey
7363
7392
  };
7364
- const k = {
7393
+ const S = {
7365
7394
  url: t,
7366
7395
  body: e,
7367
7396
  avatarMood: n,
@@ -7377,21 +7406,21 @@ const gt = Me(({
7377
7406
  ttsService: v,
7378
7407
  lipsyncModules: ["en"],
7379
7408
  cameraView: a
7380
- }, N = T(async () => {
7381
- if (!(!z.current || f.current))
7409
+ }, U = T(async () => {
7410
+ if (!(!z.current || y.current))
7382
7411
  try {
7383
- X(!0), se(null), f.current = new Be(z.current, H), console.log("Avatar config being passed:", {
7384
- url: k.url,
7385
- body: k.body,
7386
- avatarMood: k.avatarMood
7387
- }), await f.current.showAvatar(k, (te) => {
7412
+ X(!0), se(null), y.current = new Be(z.current, H), console.log("Avatar config being passed:", {
7413
+ url: S.url,
7414
+ body: S.body,
7415
+ avatarMood: S.avatarMood
7416
+ }), await y.current.showAvatar(S, (te) => {
7388
7417
  if (te.lengthComputable) {
7389
7418
  const L = Math.min(100, Math.round(te.loaded / te.total * 100));
7390
- c(L);
7419
+ d(L);
7391
7420
  }
7392
- }), f.current?.avatar && console.log("Avatar body after initialization:", f.current.avatar.body), X(!1), pe(!0), d(f.current);
7421
+ }), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), X(!1), pe(!0), c(y.current);
7393
7422
  const C = () => {
7394
- document.visibilityState === "visible" ? f.current?.start() : f.current?.stop();
7423
+ document.visibilityState === "visible" ? y.current?.start() : y.current?.stop();
7395
7424
  };
7396
7425
  return document.addEventListener("visibilitychange", C), () => {
7397
7426
  document.removeEventListener("visibilitychange", C);
@@ -7400,19 +7429,19 @@ const gt = Me(({
7400
7429
  console.error("Error initializing TalkingHead:", C), se(C.message || "Failed to initialize avatar"), X(!1), g(C);
7401
7430
  }
7402
7431
  }, []);
7403
- de(() => (N(), () => {
7404
- f.current && (f.current.stop(), f.current.dispose(), f.current = null);
7405
- }), [N]);
7432
+ de(() => (U(), () => {
7433
+ y.current && (y.current.stop(), y.current.dispose(), y.current = null);
7434
+ }), [U]);
7406
7435
  const _ = T(async () => {
7407
- if (f.current)
7436
+ if (y.current)
7408
7437
  try {
7409
- const C = f.current.audioCtx || f.current.audioContext;
7438
+ const C = y.current.audioCtx || y.current.audioContext;
7410
7439
  C && (C.state === "suspended" || C.state === "interrupted") && (await C.resume(), console.log("Audio context resumed"));
7411
7440
  } catch (C) {
7412
7441
  console.warn("Failed to resume audio context:", C);
7413
7442
  }
7414
7443
  }, []), j = T(async (C, te = {}) => {
7415
- if (!f.current || !ae) {
7444
+ if (!y.current || !ae) {
7416
7445
  console.warn("Avatar not ready for speaking");
7417
7446
  return;
7418
7447
  }
@@ -7420,51 +7449,51 @@ const gt = Me(({
7420
7449
  console.warn("No text provided to speak");
7421
7450
  return;
7422
7451
  }
7423
- await _(), S.current = { remainingText: null, originalText: null, options: null }, Z.current = [], P.current = { text: C, options: te }, U.current && (clearInterval(U.current), U.current = null), le(!1), oe.current = !1;
7424
- const L = C.split(/[.!?]+/).filter((B) => B.trim().length > 0);
7452
+ await _(), k.current = { remainingText: null, originalText: null, options: null }, Z.current = [], P.current = { text: C, options: te }, W.current && (clearInterval(W.current), W.current = null), le(!1), oe.current = !1;
7453
+ const L = C.split(/[.!?]+/).filter((N) => N.trim().length > 0);
7425
7454
  Z.current = L;
7426
7455
  const F = {
7427
7456
  lipsyncLang: te.lipsyncLang || "en",
7428
7457
  onSpeechEnd: () => {
7429
- U.current && (clearInterval(U.current), U.current = null), te.onSpeechEnd && te.onSpeechEnd(), y();
7458
+ W.current && (clearInterval(W.current), W.current = null), te.onSpeechEnd && te.onSpeechEnd(), x();
7430
7459
  }
7431
7460
  };
7432
7461
  try {
7433
- f.current.speakText(C, F);
7434
- } catch (B) {
7435
- console.error("Error speaking text:", B), se(B.message || "Failed to speak text");
7462
+ y.current.speakText(C, F);
7463
+ } catch (N) {
7464
+ console.error("Error speaking text:", N), se(N.message || "Failed to speak text");
7436
7465
  }
7437
- }, [ae, y, _]);
7466
+ }, [ae, x, _]);
7438
7467
  de(() => {
7439
- ae && G && p && f.current && j(G);
7468
+ ae && G && p && y.current && j(G);
7440
7469
  }, [ae, G, p, j]);
7441
7470
  const q = T(() => {
7442
- if (f.current)
7471
+ if (y.current)
7443
7472
  try {
7444
- const C = f.current.isSpeaking || !1, te = f.current.audioPlaylist || [], L = f.current.speechQueue || [];
7473
+ const C = y.current.isSpeaking || !1, te = y.current.audioPlaylist || [], L = y.current.speechQueue || [];
7445
7474
  if (C || te.length > 0 || L.length > 0) {
7446
- U.current && (clearInterval(U.current), U.current = null);
7475
+ W.current && (clearInterval(W.current), W.current = null);
7447
7476
  let F = "";
7448
- L.length > 0 && (F = L.map((B) => B.text && Array.isArray(B.text) ? B.text.map((J) => J.word).join(" ") : B.text || "").join(" ")), S.current = {
7477
+ L.length > 0 && (F = L.map((N) => N.text && Array.isArray(N.text) ? N.text.map((J) => J.word).join(" ") : N.text || "").join(" ")), k.current = {
7449
7478
  remainingText: F || null,
7450
7479
  originalText: P.current?.text || null,
7451
7480
  options: P.current?.options || null
7452
- }, f.current.speechQueue.length = 0, f.current.pauseSpeaking(), le(!0), oe.current = !0;
7481
+ }, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), le(!0), oe.current = !0;
7453
7482
  }
7454
7483
  } catch (C) {
7455
7484
  console.warn("Error pausing speech:", C);
7456
7485
  }
7457
7486
  }, []), Le = T(async () => {
7458
- if (!(!f.current || !ee))
7487
+ if (!(!y.current || !ee))
7459
7488
  try {
7460
7489
  await _(), le(!1), oe.current = !1;
7461
- const C = S.current?.remainingText, te = S.current?.originalText || P.current?.text, L = S.current?.options || P.current?.options || {}, F = C || te;
7490
+ const C = k.current?.remainingText, te = k.current?.originalText || P.current?.text, L = k.current?.options || P.current?.options || {}, F = C || te;
7462
7491
  F && j(F, L);
7463
7492
  } catch (C) {
7464
7493
  console.warn("Error resuming speech:", C), le(!1), oe.current = !1;
7465
7494
  }
7466
7495
  }, [ee, j, _]), we = T(() => {
7467
- f.current && (f.current.stopSpeaking(), U.current && (clearInterval(U.current), U.current = null), le(!1), oe.current = !1);
7496
+ y.current && (y.current.stopSpeaking(), W.current && (clearInterval(W.current), W.current = null), le(!1), oe.current = !1);
7468
7497
  }, []);
7469
7498
  return Ee(M, () => ({
7470
7499
  speakText: j,
@@ -7473,20 +7502,20 @@ const gt = Me(({
7473
7502
  stopSpeaking: we,
7474
7503
  resumeAudioContext: _,
7475
7504
  isPaused: () => ee,
7476
- setMood: (C) => f.current?.setMood(C),
7505
+ setMood: (C) => y.current?.setMood(C),
7477
7506
  setBodyMovement: (C) => {
7478
- f.current && f.current.setBodyMovement(C);
7507
+ y.current && y.current.setBodyMovement(C);
7479
7508
  },
7480
7509
  playAnimation: (C, te = !1) => {
7481
- f.current && f.current.playAnimation && f.current.playAnimation(C, null, 10, 0, 0.01, te);
7510
+ y.current && y.current.playAnimation && y.current.playAnimation(C, null, 10, 0, 0.01, te);
7482
7511
  },
7483
- playReaction: (C) => f.current?.playReaction(C),
7484
- playCelebration: () => f.current?.playCelebration(),
7512
+ playReaction: (C) => y.current?.playReaction(C),
7513
+ playCelebration: () => y.current?.playCelebration(),
7485
7514
  setShowFullAvatar: (C) => {
7486
- f.current && (E.current = C, f.current.setShowFullAvatar(C));
7515
+ y.current && (E.current = C, y.current.setShowFullAvatar(C));
7487
7516
  },
7488
7517
  isReady: ae,
7489
- talkingHead: f.current
7518
+ talkingHead: y.current
7490
7519
  })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${b}`, style: I, children: [
7491
7520
  /* @__PURE__ */ me(
7492
7521
  "div",
@@ -7550,13 +7579,13 @@ const yt = Me(({
7550
7579
  curriculumCompleted: !1,
7551
7580
  score: 0,
7552
7581
  totalQuestions: 0
7553
- }), d = O({
7582
+ }), c = O({
7554
7583
  onLessonStart: n,
7555
7584
  onLessonComplete: i,
7556
7585
  onQuestionAnswer: s,
7557
7586
  onCurriculumComplete: o,
7558
7587
  onCustomAction: l
7559
- }), c = O(null), g = O(null), y = O(null), b = O(null), I = O(null), V = O(null), p = O(null), M = O(G?.curriculum || {
7588
+ }), d = O(null), g = O(null), x = O(null), b = O(null), I = O(null), B = O(null), p = O(null), M = O(G?.curriculum || {
7560
7589
  title: "Default Curriculum",
7561
7590
  description: "No curriculum data provided",
7562
7591
  language: "en",
@@ -7576,7 +7605,7 @@ const yt = Me(({
7576
7605
  lipsyncLang: "en"
7577
7606
  });
7578
7607
  de(() => {
7579
- d.current = {
7608
+ c.current = {
7580
7609
  onLessonStart: n,
7581
7610
  onLessonComplete: i,
7582
7611
  onQuestionAnswer: s,
@@ -7604,17 +7633,17 @@ const yt = Me(({
7604
7633
  lipsyncLang: "en"
7605
7634
  };
7606
7635
  }, [G, t, e]);
7607
- const f = T(() => (M.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), E = T(() => f()?.questions[a.current.currentQuestionIndex], [f]), P = T((v, R) => R.type === "multiple_choice" || R.type === "true_false" ? v === R.answer : R.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), U = T(() => {
7636
+ const y = T(() => (M.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), E = T(() => y()?.questions[a.current.currentQuestionIndex], [y]), P = T((v, R) => R.type === "multiple_choice" || R.type === "true_false" ? v === R.answer : R.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), W = T(() => {
7608
7637
  a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
7609
7638
  const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7610
7639
  let R = "Congratulations! You've completed this lesson";
7611
- if (a.current.totalQuestions > 0 ? R += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : R += "! ", v >= 80 ? R += "Excellent work! You have a great understanding of this topic." : v >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", d.current.onLessonComplete({
7640
+ if (a.current.totalQuestions > 0 ? R += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : R += "! ", v >= 80 ? R += "Excellent work! You have a great understanding of this topic." : v >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", c.current.onLessonComplete({
7612
7641
  moduleIndex: a.current.currentModuleIndex,
7613
7642
  lessonIndex: a.current.currentLessonIndex,
7614
7643
  score: a.current.score,
7615
7644
  totalQuestions: a.current.totalQuestions,
7616
7645
  percentage: v
7617
- }), d.current.onCustomAction({
7646
+ }), c.current.onCustomAction({
7618
7647
  type: "lessonComplete",
7619
7648
  moduleIndex: a.current.currentModuleIndex,
7620
7649
  lessonIndex: a.current.currentLessonIndex,
@@ -7628,11 +7657,11 @@ const yt = Me(({
7628
7657
  } catch {
7629
7658
  u.current.playCelebration();
7630
7659
  }
7631
- const k = M.current || { modules: [] }, H = k.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (k.modules?.length || 0) - 1, j = N || _, q = z.current || { lipsyncLang: "en" };
7660
+ const S = M.current || { modules: [] }, H = S.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (S.modules?.length || 0) - 1, j = U || _, q = z.current || { lipsyncLang: "en" };
7632
7661
  u.current.speakText(R, {
7633
7662
  lipsyncLang: q.lipsyncLang,
7634
7663
  onSpeechEnd: () => {
7635
- d.current.onCustomAction({
7664
+ c.current.onCustomAction({
7636
7665
  type: "lessonCompleteFeedbackDone",
7637
7666
  moduleIndex: a.current.currentModuleIndex,
7638
7667
  lessonIndex: a.current.currentLessonIndex,
@@ -7647,9 +7676,9 @@ const yt = Me(({
7647
7676
  }, [e.lessonComplete]), oe = T(() => {
7648
7677
  a.current.curriculumCompleted = !0;
7649
7678
  const v = M.current || { modules: [] };
7650
- if (d.current.onCurriculumComplete({
7679
+ if (c.current.onCurriculumComplete({
7651
7680
  modules: v.modules.length,
7652
- totalLessons: v.modules.reduce((R, k) => R + k.lessons.length, 0)
7681
+ totalLessons: v.modules.reduce((R, S) => R + S.lessons.length, 0)
7653
7682
  }), u.current) {
7654
7683
  if (u.current.setMood("celebrating"), e.curriculumComplete)
7655
7684
  try {
@@ -7660,11 +7689,11 @@ const yt = Me(({
7660
7689
  const R = z.current || { lipsyncLang: "en" };
7661
7690
  u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: R.lipsyncLang });
7662
7691
  }
7663
- }, [e.curriculumComplete]), S = T(() => {
7664
- const v = f();
7692
+ }, [e.curriculumComplete]), k = T(() => {
7693
+ const v = y();
7665
7694
  a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
7666
7695
  const R = E();
7667
- R && d.current.onCustomAction({
7696
+ R && c.current.onCustomAction({
7668
7697
  type: "questionStart",
7669
7698
  moduleIndex: a.current.currentModuleIndex,
7670
7699
  lessonIndex: a.current.currentLessonIndex,
@@ -7673,36 +7702,36 @@ const yt = Me(({
7673
7702
  question: R,
7674
7703
  score: a.current.score
7675
7704
  });
7676
- const k = () => {
7705
+ const S = () => {
7677
7706
  if (!u.current || !R) return;
7678
7707
  if (u.current.setMood("happy"), e.questionStart)
7679
7708
  try {
7680
7709
  u.current.playAnimation(e.questionStart, !0);
7681
- } catch (N) {
7682
- console.warn("Failed to play questionStart animation:", N);
7710
+ } catch (U) {
7711
+ console.warn("Failed to play questionStart animation:", U);
7683
7712
  }
7684
7713
  const H = z.current || { lipsyncLang: "en" };
7685
7714
  R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang });
7686
7715
  };
7687
7716
  if (u.current && u.current.isReady && R)
7688
- k();
7717
+ S();
7689
7718
  else if (u.current && u.current.isReady) {
7690
7719
  const H = z.current || { lipsyncLang: "en" };
7691
7720
  u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: H.lipsyncLang });
7692
7721
  } else {
7693
7722
  const H = setInterval(() => {
7694
- u.current && u.current.isReady && (clearInterval(H), R && k());
7723
+ u.current && u.current.isReady && (clearInterval(H), R && S());
7695
7724
  }, 100);
7696
7725
  setTimeout(() => {
7697
7726
  clearInterval(H);
7698
7727
  }, 5e3);
7699
7728
  }
7700
- }, [e.questionStart, f, E]), Z = T(() => {
7701
- const v = f();
7729
+ }, [e.questionStart, y, E]), Z = T(() => {
7730
+ const v = y();
7702
7731
  if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
7703
7732
  u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
7704
7733
  const R = E();
7705
- R && d.current.onCustomAction({
7734
+ R && c.current.onCustomAction({
7706
7735
  type: "nextQuestion",
7707
7736
  moduleIndex: a.current.currentModuleIndex,
7708
7737
  lessonIndex: a.current.currentLessonIndex,
@@ -7711,7 +7740,7 @@ const yt = Me(({
7711
7740
  question: R,
7712
7741
  score: a.current.score
7713
7742
  });
7714
- const k = () => {
7743
+ const S = () => {
7715
7744
  if (!u.current || !R) return;
7716
7745
  if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
7717
7746
  try {
@@ -7719,7 +7748,7 @@ const yt = Me(({
7719
7748
  } catch (q) {
7720
7749
  console.warn("Failed to play nextQuestion animation:", q);
7721
7750
  }
7722
- const H = z.current || { lipsyncLang: "en" }, _ = f()?.questions?.length || 0, j = a.current.currentQuestionIndex >= _ - 1;
7751
+ const H = z.current || { lipsyncLang: "en" }, _ = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= _ - 1;
7723
7752
  if (R.type === "code_test") {
7724
7753
  const q = j ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
7725
7754
  u.current.speakText(q, {
@@ -7743,77 +7772,77 @@ const yt = Me(({
7743
7772
  }
7744
7773
  };
7745
7774
  if (u.current && u.current.isReady && R)
7746
- k();
7775
+ S();
7747
7776
  else if (R) {
7748
7777
  const H = setInterval(() => {
7749
- u.current && u.current.isReady && (clearInterval(H), k());
7778
+ u.current && u.current.isReady && (clearInterval(H), S());
7750
7779
  }, 100);
7751
7780
  setTimeout(() => {
7752
7781
  clearInterval(H);
7753
7782
  }, 5e3);
7754
7783
  }
7755
7784
  } else
7756
- d.current.onCustomAction({
7785
+ c.current.onCustomAction({
7757
7786
  type: "allQuestionsComplete",
7758
7787
  moduleIndex: a.current.currentModuleIndex,
7759
7788
  lessonIndex: a.current.currentLessonIndex,
7760
7789
  totalQuestions: a.current.totalQuestions,
7761
7790
  score: a.current.score
7762
7791
  });
7763
- }, [e.nextQuestion, f, E]), K = T(() => {
7792
+ }, [e.nextQuestion, y, E]), K = T(() => {
7764
7793
  const v = M.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
7765
7794
  if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
7766
7795
  a.current.currentLessonIndex += 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
7767
- const H = v.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = N || _;
7768
- d.current.onCustomAction({
7796
+ const H = v.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = U || _;
7797
+ c.current.onCustomAction({
7769
7798
  type: "lessonStart",
7770
7799
  moduleIndex: a.current.currentModuleIndex,
7771
7800
  lessonIndex: a.current.currentLessonIndex,
7772
7801
  hasNextLesson: j
7773
- }), d.current.onLessonStart({
7802
+ }), c.current.onLessonStart({
7774
7803
  moduleIndex: a.current.currentModuleIndex,
7775
7804
  lessonIndex: a.current.currentLessonIndex,
7776
- lesson: f()
7805
+ lesson: y()
7777
7806
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7778
7807
  } else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
7779
7808
  a.current.currentModuleIndex += 1, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
7780
- const N = v.modules[a.current.currentModuleIndex], _ = a.current.currentLessonIndex < (N?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = _ || j;
7781
- d.current.onCustomAction({
7809
+ const U = v.modules[a.current.currentModuleIndex], _ = a.current.currentLessonIndex < (U?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = _ || j;
7810
+ c.current.onCustomAction({
7782
7811
  type: "lessonStart",
7783
7812
  moduleIndex: a.current.currentModuleIndex,
7784
7813
  lessonIndex: a.current.currentLessonIndex,
7785
7814
  hasNextLesson: q
7786
- }), d.current.onLessonStart({
7815
+ }), c.current.onLessonStart({
7787
7816
  moduleIndex: a.current.currentModuleIndex,
7788
7817
  lessonIndex: a.current.currentLessonIndex,
7789
- lesson: f()
7818
+ lesson: y()
7790
7819
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7791
7820
  } else
7792
7821
  I.current && I.current();
7793
7822
  }, []), X = T(() => {
7794
- const v = f();
7823
+ const v = y();
7795
7824
  let R = null;
7796
7825
  if (v?.avatar_script && v?.body) {
7797
- const k = v.avatar_script.trim(), H = v.body.trim(), N = k.match(/[.!?]$/) ? " " : ". ";
7798
- R = `${k}${N}${H}`;
7826
+ const S = v.avatar_script.trim(), H = v.body.trim(), U = S.match(/[.!?]$/) ? " " : ". ";
7827
+ R = `${S}${U}${H}`;
7799
7828
  } else
7800
7829
  R = v?.avatar_script || v?.body || null;
7801
7830
  if (u.current && u.current.isReady && R) {
7802
7831
  a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, u.current.setMood("happy");
7803
- let k = !1;
7832
+ let S = !1;
7804
7833
  if (e.teaching)
7805
7834
  try {
7806
- u.current.playAnimation(e.teaching, !0), k = !0;
7807
- } catch (N) {
7808
- console.warn("Failed to play teaching animation:", N);
7835
+ u.current.playAnimation(e.teaching, !0), S = !0;
7836
+ } catch (U) {
7837
+ console.warn("Failed to play teaching animation:", U);
7809
7838
  }
7810
- k || u.current.setBodyMovement("gesturing");
7839
+ S || u.current.setBodyMovement("gesturing");
7811
7840
  const H = z.current || { lipsyncLang: "en" };
7812
- d.current.onLessonStart({
7841
+ c.current.onLessonStart({
7813
7842
  moduleIndex: a.current.currentModuleIndex,
7814
7843
  lessonIndex: a.current.currentLessonIndex,
7815
7844
  lesson: v
7816
- }), d.current.onCustomAction({
7845
+ }), c.current.onCustomAction({
7817
7846
  type: "teachingStart",
7818
7847
  moduleIndex: a.current.currentModuleIndex,
7819
7848
  lessonIndex: a.current.currentLessonIndex,
@@ -7821,13 +7850,13 @@ const yt = Me(({
7821
7850
  }), u.current.speakText(R, {
7822
7851
  lipsyncLang: H.lipsyncLang,
7823
7852
  onSpeechEnd: () => {
7824
- a.current.isTeaching = !1, d.current.onCustomAction({
7853
+ a.current.isTeaching = !1, c.current.onCustomAction({
7825
7854
  type: "teachingComplete",
7826
7855
  moduleIndex: a.current.currentModuleIndex,
7827
7856
  lessonIndex: a.current.currentLessonIndex,
7828
7857
  lesson: v,
7829
7858
  hasQuestions: v.questions && v.questions.length > 0
7830
- }), v?.code_example && d.current.onCustomAction({
7859
+ }), v?.code_example && c.current.onCustomAction({
7831
7860
  type: "codeExampleReady",
7832
7861
  moduleIndex: a.current.currentModuleIndex,
7833
7862
  lessonIndex: a.current.currentLessonIndex,
@@ -7837,17 +7866,17 @@ const yt = Me(({
7837
7866
  }
7838
7867
  });
7839
7868
  }
7840
- }, [e.teaching, f]), $ = T((v) => {
7841
- const R = E(), k = P(v, R);
7842
- if (k && (a.current.score += 1), d.current.onQuestionAnswer({
7869
+ }, [e.teaching, y]), $ = T((v) => {
7870
+ const R = E(), S = P(v, R);
7871
+ if (S && (a.current.score += 1), c.current.onQuestionAnswer({
7843
7872
  moduleIndex: a.current.currentModuleIndex,
7844
7873
  lessonIndex: a.current.currentLessonIndex,
7845
7874
  questionIndex: a.current.currentQuestionIndex,
7846
7875
  answer: v,
7847
- isCorrect: k,
7876
+ isCorrect: S,
7848
7877
  question: R
7849
7878
  }), u.current)
7850
- if (k) {
7879
+ if (S) {
7851
7880
  if (u.current.setMood("happy"), e.correct)
7852
7881
  try {
7853
7882
  u.current.playReaction("happy");
@@ -7855,15 +7884,15 @@ const yt = Me(({
7855
7884
  u.current.setBodyMovement("happy");
7856
7885
  }
7857
7886
  u.current.setBodyMovement("gesturing");
7858
- const N = f()?.questions?.length || 0;
7859
- a.current.currentQuestionIndex >= N - 1;
7860
- const _ = a.current.currentQuestionIndex < N - 1;
7861
- console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", _);
7887
+ const U = y()?.questions?.length || 0;
7888
+ a.current.currentQuestionIndex >= U - 1;
7889
+ const _ = a.current.currentQuestionIndex < U - 1;
7890
+ console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", _);
7862
7891
  const j = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, q = z.current || { lipsyncLang: "en" };
7863
7892
  u.current.speakText(j, {
7864
7893
  lipsyncLang: q.lipsyncLang,
7865
7894
  onSpeechEnd: () => {
7866
- d.current.onCustomAction({
7895
+ c.current.onCustomAction({
7867
7896
  type: "answerFeedbackComplete",
7868
7897
  moduleIndex: a.current.currentModuleIndex,
7869
7898
  lessonIndex: a.current.currentLessonIndex,
@@ -7883,13 +7912,13 @@ const yt = Me(({
7883
7912
  u.current.setBodyMovement("idle");
7884
7913
  }
7885
7914
  u.current.setBodyMovement("gesturing");
7886
- const N = f()?.questions?.length || 0, _ = a.current.currentQuestionIndex >= N - 1, j = a.current.currentQuestionIndex < N - 1;
7887
- console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", j);
7915
+ const U = y()?.questions?.length || 0, _ = a.current.currentQuestionIndex >= U - 1, j = a.current.currentQuestionIndex < U - 1;
7916
+ console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", j);
7888
7917
  const q = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""}${_ ? "" : " Let's move on to the next question."}`, Le = z.current || { lipsyncLang: "en" };
7889
7918
  u.current.speakText(q, {
7890
7919
  lipsyncLang: Le.lipsyncLang,
7891
7920
  onSpeechEnd: () => {
7892
- d.current.onCustomAction({
7921
+ c.current.onCustomAction({
7893
7922
  type: "answerFeedbackComplete",
7894
7923
  moduleIndex: a.current.currentModuleIndex,
7895
7924
  lessonIndex: a.current.currentLessonIndex,
@@ -7903,20 +7932,20 @@ const yt = Me(({
7903
7932
  });
7904
7933
  }
7905
7934
  else {
7906
- const N = f()?.questions?.length || 0;
7907
- d.current.onCustomAction({
7935
+ const U = y()?.questions?.length || 0;
7936
+ c.current.onCustomAction({
7908
7937
  type: "answerFeedbackComplete",
7909
7938
  moduleIndex: a.current.currentModuleIndex,
7910
7939
  lessonIndex: a.current.currentLessonIndex,
7911
7940
  questionIndex: a.current.currentQuestionIndex,
7912
- isCorrect: k,
7913
- hasNextQuestion: a.current.currentQuestionIndex < N - 1,
7941
+ isCorrect: S,
7942
+ hasNextQuestion: a.current.currentQuestionIndex < U - 1,
7914
7943
  score: a.current.score,
7915
7944
  totalQuestions: a.current.totalQuestions,
7916
7945
  avatarNotReady: !0
7917
7946
  });
7918
7947
  }
7919
- }, [e.correct, e.incorrect, E, f, P]), se = T((v) => {
7948
+ }, [e.correct, e.incorrect, E, y, P]), se = T((v) => {
7920
7949
  const R = E();
7921
7950
  if (!v || typeof v != "object") {
7922
7951
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
@@ -7926,7 +7955,7 @@ const yt = Me(({
7926
7955
  console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
7927
7956
  return;
7928
7957
  }
7929
- const k = {
7958
+ const S = {
7930
7959
  passed: v.passed === !0,
7931
7960
  results: v.results || [],
7932
7961
  output: v.output || "",
@@ -7936,19 +7965,19 @@ const yt = Me(({
7936
7965
  passedCount: v.passedCount || 0,
7937
7966
  failedCount: v.failedCount || 0
7938
7967
  };
7939
- d.current.onCustomAction({
7968
+ c.current.onCustomAction({
7940
7969
  type: "codeTestSubmitted",
7941
7970
  moduleIndex: a.current.currentModuleIndex,
7942
7971
  lessonIndex: a.current.currentLessonIndex,
7943
7972
  questionIndex: a.current.currentQuestionIndex,
7944
- testResult: k,
7973
+ testResult: S,
7945
7974
  question: R
7946
- }), p.current && p.current(k);
7975
+ }), p.current && p.current(S);
7947
7976
  }, [E, P]), ae = T(() => {
7948
7977
  if (a.current.currentQuestionIndex > 0) {
7949
7978
  a.current.currentQuestionIndex -= 1;
7950
7979
  const v = E();
7951
- v && d.current.onCustomAction({
7980
+ v && c.current.onCustomAction({
7952
7981
  type: "questionStart",
7953
7982
  moduleIndex: a.current.currentModuleIndex,
7954
7983
  lessonIndex: a.current.currentLessonIndex,
@@ -7960,82 +7989,82 @@ const yt = Me(({
7960
7989
  const R = () => {
7961
7990
  if (!u.current || !v) return;
7962
7991
  u.current.setMood("happy"), u.current.setBodyMovement("idle");
7963
- const k = z.current || { lipsyncLang: "en" };
7992
+ const S = z.current || { lipsyncLang: "en" };
7964
7993
  v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
7965
- lipsyncLang: k.lipsyncLang
7994
+ lipsyncLang: S.lipsyncLang
7966
7995
  }) : u.current.speakText(`Going back to: ${v.question}`, {
7967
- lipsyncLang: k.lipsyncLang
7996
+ lipsyncLang: S.lipsyncLang
7968
7997
  });
7969
7998
  };
7970
7999
  if (u.current && u.current.isReady && v)
7971
8000
  R();
7972
8001
  else if (v) {
7973
- const k = setInterval(() => {
7974
- u.current && u.current.isReady && (clearInterval(k), R());
8002
+ const S = setInterval(() => {
8003
+ u.current && u.current.isReady && (clearInterval(S), R());
7975
8004
  }, 100);
7976
8005
  setTimeout(() => {
7977
- clearInterval(k);
8006
+ clearInterval(S);
7978
8007
  }, 5e3);
7979
8008
  }
7980
8009
  }
7981
8010
  }, [E]), pe = T(() => {
7982
8011
  const v = M.current || { modules: [] };
7983
8012
  if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
7984
- a.current.currentLessonIndex -= 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, d.current.onCustomAction({
8013
+ a.current.currentLessonIndex -= 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
7985
8014
  type: "lessonStart",
7986
8015
  moduleIndex: a.current.currentModuleIndex,
7987
8016
  lessonIndex: a.current.currentLessonIndex
7988
- }), d.current.onLessonStart({
8017
+ }), c.current.onLessonStart({
7989
8018
  moduleIndex: a.current.currentModuleIndex,
7990
8019
  lessonIndex: a.current.currentLessonIndex,
7991
- lesson: f()
8020
+ lesson: y()
7992
8021
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7993
8022
  else if (a.current.currentModuleIndex > 0) {
7994
8023
  const H = v.modules[a.current.currentModuleIndex - 1];
7995
- a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (H?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, d.current.onCustomAction({
8024
+ a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (H?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
7996
8025
  type: "lessonStart",
7997
8026
  moduleIndex: a.current.currentModuleIndex,
7998
8027
  lessonIndex: a.current.currentLessonIndex
7999
- }), d.current.onLessonStart({
8028
+ }), c.current.onLessonStart({
8000
8029
  moduleIndex: a.current.currentModuleIndex,
8001
8030
  lessonIndex: a.current.currentLessonIndex,
8002
- lesson: f()
8031
+ lesson: y()
8003
8032
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8004
8033
  }
8005
- }, [f]), ee = T(() => {
8034
+ }, [y]), ee = T(() => {
8006
8035
  a.current.currentModuleIndex = 0, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.isTeaching = !1, a.current.isQuestionMode = !1, a.current.lessonCompleted = !1, a.current.curriculumCompleted = !1, a.current.score = 0, a.current.totalQuestions = 0;
8007
8036
  }, []), le = T((v) => {
8008
8037
  console.log("Avatar is ready!", v);
8009
- const R = f(), k = R?.avatar_script || R?.body;
8010
- h && k && setTimeout(() => {
8011
- c.current && c.current();
8038
+ const R = y(), S = R?.avatar_script || R?.body;
8039
+ h && S && setTimeout(() => {
8040
+ d.current && d.current();
8012
8041
  }, 10);
8013
- }, [h, f]);
8042
+ }, [h, y]);
8014
8043
  Xe(() => {
8015
- c.current = X, g.current = K, y.current = U, b.current = Z, I.current = oe, V.current = S, p.current = $;
8044
+ d.current = X, g.current = K, x.current = W, b.current = Z, I.current = oe, B.current = k, p.current = $;
8016
8045
  }), Ee(r, () => ({
8017
8046
  // Curriculum control methods
8018
8047
  startTeaching: X,
8019
- startQuestions: S,
8048
+ startQuestions: k,
8020
8049
  handleAnswerSelect: $,
8021
8050
  handleCodeTestResult: se,
8022
8051
  nextQuestion: Z,
8023
8052
  previousQuestion: ae,
8024
8053
  nextLesson: K,
8025
8054
  previousLesson: pe,
8026
- completeLesson: U,
8055
+ completeLesson: W,
8027
8056
  completeCurriculum: oe,
8028
8057
  resetCurriculum: ee,
8029
8058
  getState: () => ({ ...a.current }),
8030
8059
  getCurrentQuestion: () => E(),
8031
- getCurrentLesson: () => f(),
8060
+ getCurrentLesson: () => y(),
8032
8061
  // Direct access to avatar ref (always returns current value)
8033
8062
  getAvatarRef: () => u.current,
8034
8063
  // Convenience methods that delegate to avatar (always check current ref)
8035
8064
  speakText: async (v, R = {}) => {
8036
8065
  await u.current?.resumeAudioContext?.();
8037
- const k = z.current || { lipsyncLang: "en" };
8038
- u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || k.lipsyncLang });
8066
+ const S = z.current || { lipsyncLang: "en" };
8067
+ u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || S.lipsyncLang });
8039
8068
  },
8040
8069
  resumeAudioContext: async () => {
8041
8070
  if (u.current?.resumeAudioContext)
@@ -8046,8 +8075,8 @@ const yt = Me(({
8046
8075
  if (R.state === "suspended" || R.state === "interrupted")
8047
8076
  try {
8048
8077
  await R.resume(), console.log("Audio context resumed via talkingHead");
8049
- } catch (k) {
8050
- console.warn("Failed to resume audio context:", k);
8078
+ } catch (S) {
8079
+ console.warn("Failed to resume audio context:", S);
8051
8080
  }
8052
8081
  } else
8053
8082
  console.warn("Audio context not available yet");
@@ -8069,7 +8098,7 @@ const yt = Me(({
8069
8098
  unlockAvatarPosition: () => u.current?.unlockAvatarPosition(),
8070
8099
  // Custom action trigger
8071
8100
  triggerCustomAction: (v, R) => {
8072
- d.current.onCustomAction({
8101
+ c.current.onCustomAction({
8073
8102
  type: v,
8074
8103
  ...R,
8075
8104
  state: { ...a.current }
@@ -8079,7 +8108,7 @@ const yt = Me(({
8079
8108
  handleResize: () => u.current?.handleResize(),
8080
8109
  // Avatar readiness check (always returns current value)
8081
8110
  isAvatarReady: () => u.current?.isReady || !1
8082
- }), [X, S, $, se, Z, K, U, oe, ee, E, f]);
8111
+ }), [X, k, $, se, Z, K, W, oe, ee, E, y]);
8083
8112
  const D = z.current || {
8084
8113
  avatarUrl: "/avatars/brunette.glb",
8085
8114
  avatarBody: "F",
@@ -8231,6 +8260,6 @@ export {
8231
8260
  Ge as animations,
8232
8261
  Fe as getActiveTTSConfig,
8233
8262
  wt as getAnimation,
8234
- kt as getVoiceOptions,
8263
+ St as getVoiceOptions,
8235
8264
  zt as hasAnimation
8236
8265
  };