@sage-rsc/talking-head-react 1.1.3 → 1.1.5

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,6 +1,6 @@
1
1
  import { jsxs as Pe, jsx as me } from "react/jsx-runtime";
2
- import { forwardRef as Me, useRef as N, useState as ce, useEffect as de, useCallback as T, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
3
- import * as f from "three";
2
+ import { forwardRef as Me, useRef as N, useState as ce, useEffect as de, useCallback as P, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
3
+ import * as b 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";
@@ -8,13 +8,13 @@ import { FBXLoader as Ne } from "three/addons/loaders/FBXLoader.js";
8
8
  import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
9
9
  import _e from "three/addons/libs/stats.module.js";
10
10
  let m, re, he;
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(), Oe = new f.Quaternion(), fe = new f.Matrix4(), xe = new f.Matrix4();
16
- new f.Vector3();
17
- const He = new f.Vector3(0, 0, 1), Ke = new f.Vector3(1, 0, 0), Je = new f.Vector3(0, 1, 0), $e = new f.Vector3(0, 0, 1);
11
+ const A = [0, 0, 0, 0], z = new b.Vector3(), ze = new b.Vector3(), ie = new b.Vector3(), Ce = new b.Vector3();
12
+ new b.Plane();
13
+ new b.Ray();
14
+ new b.Euler();
15
+ const oe = new b.Quaternion(), Oe = new b.Quaternion(), fe = new b.Matrix4(), xe = new b.Matrix4();
16
+ new b.Vector3();
17
+ const He = new b.Vector3(0, 0, 1), Ke = new b.Vector3(1, 0, 0), Je = new b.Vector3(0, 1, 0), $e = new b.Vector3(0, 0, 1);
18
18
  class et {
19
19
  constructor(t = null) {
20
20
  this.opt = Object.assign({
@@ -321,7 +321,7 @@ class et {
321
321
  /// Bone's parent object
322
322
  vBasis: r.position.clone(),
323
323
  // Original local position
324
- vWorld: r.parent.getWorldPosition(w).clone(),
324
+ vWorld: r.parent.getWorldPosition(z).clone(),
325
325
  // World position, parent
326
326
  qBasis: r.parent.quaternion.clone(),
327
327
  // Original quaternion, parent
@@ -338,7 +338,7 @@ class et {
338
338
  ea: [0, 0, 0, 0]
339
339
  // External acceleration [m/s^2]
340
340
  };
341
- h.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Oe.setFromUnitVectors(He, w).invert()).normalize(), h.qWorldInverseYaw = ie.clone().normalize(), this.data.push(h), this.dict[u] = h;
341
+ h.boneParent.matrixWorld.decompose(z, oe, ie), z.copy(He).applyQuaternion(oe).setY(0).normalize(), oe.premultiply(Oe.setFromUnitVectors(He, z).invert()).normalize(), h.qWorldInverseYaw = oe.clone().normalize(), this.data.push(h), this.dict[u] = h;
342
342
  try {
343
343
  this.setValue(u, "type", s.type), this.setValue(u, "stiffness", s.stiffness), this.setValue(u, "damping", s.damping), this.setValue(u, "external", s.external), this.setValue(u, "limits", s.limits), this.setValue(u, "excludes", s.excludes), this.setValue(u, "deltaLocal", s.deltaLocal), this.setValue(u, "deltaWorld", s.deltaWorld), this.setValue(u, "pivot", s.pivot), this.setValue(u, "helper", s.helper);
344
344
  } catch (a) {
@@ -356,22 +356,22 @@ class et {
356
356
  for (this.timerMs += t, t > 1e3 && (this.timerMs = 0), t /= 1e3, e = 0, i = this.objectsUpdate.length; e < i; e++)
357
357
  o = this.objectsUpdate[e], o.updateMatrix(), o.parent === null ? o.matrixWorld.copy(o.matrix) : o.matrixWorld.multiplyMatrices(o.parent.matrixWorld, o.matrix), o.matrixWorldNeedsUpdate = !1;
358
358
  for (e = 0, i = this.data.length; e < i; e++) {
359
- if (o = this.data[e], w.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), w.applyMatrix4(xe), w.length() > 0.5 && (console.info("Info: Unrealistic jump of " + w.length().toFixed(2) + " meters."), w.setLength(0.5)), w.applyQuaternion(o.bone.quaternion), A[0] = w.x, A[1] = w.y, A[2] = -w.z, A[3] = w.length() / 3, o.children)
359
+ if (o = this.data[e], z.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), z.applyMatrix4(xe), z.length() > 0.5 && (console.info("Info: Unrealistic jump of " + z.length().toFixed(2) + " meters."), z.setLength(0.5)), z.applyQuaternion(o.bone.quaternion), A[0] = z.x, A[1] = z.y, A[2] = -z.z, A[3] = z.length() / 3, o.children)
360
360
  for (n = 0, s = o.children.length; n < s; n++)
361
361
  m = o.children[n], A[0] -= m.v[0] * t / 3, A[1] -= m.v[1] * t / 3, A[2] += m.v[2] * t / 3, A[3] -= m.v[3] * t / 3;
362
- if (m = this.opt.sensitivityFactor, A[0] *= o.ext * m, A[1] *= o.ext * m, A[2] *= o.ext * m, A[3] *= o.ext * m, o.isX && (m = A[0] / t, o.ea[0] = (m - o.ev[0]) / t, o.ev[0] = m, o.a[0] = -o.k[0] * o.p[0] - o.c[0] * o.v[0] - o.ea[0], o.p[0] += o.v[0] * t + o.a[0] * t * t / 2 + A[0], m = o.v[0] + o.a[0] * t / 2, m = -o.k[0] * o.p[0] - o.c[0] * m - o.ea[0], o.v[0] = o.v[0] + (m + o.a[0]) * t / 2), o.isY && (m = A[1] / t, o.ea[1] = (m - o.ev[1]) / t, o.ev[1] = m, o.a[1] = -o.k[1] * o.p[1] - o.c[1] * o.v[1] - o.ea[1], o.p[1] += o.v[1] * t + o.a[1] * t * t / 2 + A[1], m = o.v[1] + o.a[1] * t / 2, m = -o.k[1] * o.p[1] - o.c[1] * m - o.ea[1], o.v[1] = o.v[1] + (m + o.a[1]) * t / 2), o.isZ && (m = A[2] / t, o.ea[2] = (m - o.ev[2]) / t, o.ev[2] = m, o.a[2] = -o.k[2] * o.p[2] - o.c[2] * o.v[2] - o.ea[2], o.p[2] += o.v[2] * t + o.a[2] * t * t / 2 + A[2], m = o.v[2] + o.a[2] * t / 2, m = -o.k[2] * o.p[2] - o.c[2] * m - o.ea[2], o.v[2] = o.v[2] + (m + o.a[2]) * t / 2), o.isT && (m = A[3] / t, o.ea[3] = (m - o.ev[3]) / t, o.ev[3] = m, o.a[3] = -o.k[3] * o.p[3] - o.c[3] * o.v[3] - o.ea[3], o.p[3] += o.v[3] * t + o.a[3] * t * t / 2 + A[3], m = o.v[3] + o.a[3] * t / 2, m = -o.k[3] * o.p[3] - o.c[3] * m - o.ea[3], o.v[3] = o.v[3] + (m + o.a[3]) * t / 2), this.timerMs < this.opt.warmupMs && (o.v[0] *= 1e-4, o.p[0] *= 1e-4, o.v[1] *= 1e-4, o.p[1] *= 1e-4, o.v[2] *= 1e-4, o.p[2] *= 1e-4, o.v[3] *= 1e-4, o.p[3] *= 1e-4), A[0] = o.p[0], A[1] = o.p[1], A[2] = o.p[2], A[3] = o.p[3], m = this.opt.movementFactor, A[0] *= m, A[1] *= m, A[2] *= m, A[3] *= m, o.dl && (m = o.dl, A[0] += m[0], A[1] += m[1], A[2] += m[2]), o.dw && (m = o.dw, w.set(
362
+ if (m = this.opt.sensitivityFactor, A[0] *= o.ext * m, A[1] *= o.ext * m, A[2] *= o.ext * m, A[3] *= o.ext * m, o.isX && (m = A[0] / t, o.ea[0] = (m - o.ev[0]) / t, o.ev[0] = m, o.a[0] = -o.k[0] * o.p[0] - o.c[0] * o.v[0] - o.ea[0], o.p[0] += o.v[0] * t + o.a[0] * t * t / 2 + A[0], m = o.v[0] + o.a[0] * t / 2, m = -o.k[0] * o.p[0] - o.c[0] * m - o.ea[0], o.v[0] = o.v[0] + (m + o.a[0]) * t / 2), o.isY && (m = A[1] / t, o.ea[1] = (m - o.ev[1]) / t, o.ev[1] = m, o.a[1] = -o.k[1] * o.p[1] - o.c[1] * o.v[1] - o.ea[1], o.p[1] += o.v[1] * t + o.a[1] * t * t / 2 + A[1], m = o.v[1] + o.a[1] * t / 2, m = -o.k[1] * o.p[1] - o.c[1] * m - o.ea[1], o.v[1] = o.v[1] + (m + o.a[1]) * t / 2), o.isZ && (m = A[2] / t, o.ea[2] = (m - o.ev[2]) / t, o.ev[2] = m, o.a[2] = -o.k[2] * o.p[2] - o.c[2] * o.v[2] - o.ea[2], o.p[2] += o.v[2] * t + o.a[2] * t * t / 2 + A[2], m = o.v[2] + o.a[2] * t / 2, m = -o.k[2] * o.p[2] - o.c[2] * m - o.ea[2], o.v[2] = o.v[2] + (m + o.a[2]) * t / 2), o.isT && (m = A[3] / t, o.ea[3] = (m - o.ev[3]) / t, o.ev[3] = m, o.a[3] = -o.k[3] * o.p[3] - o.c[3] * o.v[3] - o.ea[3], o.p[3] += o.v[3] * t + o.a[3] * t * t / 2 + A[3], m = o.v[3] + o.a[3] * t / 2, m = -o.k[3] * o.p[3] - o.c[3] * m - o.ea[3], o.v[3] = o.v[3] + (m + o.a[3]) * t / 2), this.timerMs < this.opt.warmupMs && (o.v[0] *= 1e-4, o.p[0] *= 1e-4, o.v[1] *= 1e-4, o.p[1] *= 1e-4, o.v[2] *= 1e-4, o.p[2] *= 1e-4, o.v[3] *= 1e-4, o.p[3] *= 1e-4), A[0] = o.p[0], A[1] = o.p[1], A[2] = o.p[2], A[3] = o.p[3], m = this.opt.movementFactor, A[0] *= m, A[1] *= m, A[2] *= m, A[3] *= m, o.dl && (m = o.dl, A[0] += m[0], A[1] += m[1], A[2] += m[2]), o.dw && (m = o.dw, z.set(
363
363
  o.vBasis.x + A[0],
364
364
  o.vBasis.y + A[1],
365
365
  o.vBasis.z + A[2]
366
- ), w.applyMatrix4(fe), w.x += m[0], w.y += m[1], w.z += m[2], w.applyMatrix4(xe), A[0] += w.x - o.vBasis.x, A[1] += w.y - o.vBasis.y, A[2] += w.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && A[0] < m[0][0] && (A[0] = m[0][0]), m[0][1] !== null && A[0] > m[0][1] && (A[0] = m[0][1])), m[1] && (m[1][0] !== null && A[1] < m[1][0] && (A[1] = m[1][0]), m[1][1] !== null && A[1] > m[1][1] && (A[1] = m[1][1])), m[2] && (m[2][0] !== null && A[2] < m[2][0] && (A[2] = m[2][0]), m[2][1] !== null && A[2] > m[2][1] && (A[2] = m[2][1])), m[3] && (m[3][0] !== null && A[3] < m[3][0] && (A[3] = m[3][0]), m[3][1] !== null && A[3] > m[3][1] && (A[3] = m[3][1]))), o.isPoint)
366
+ ), z.applyMatrix4(fe), z.x += m[0], z.y += m[1], z.z += m[2], z.applyMatrix4(xe), A[0] += z.x - o.vBasis.x, A[1] += z.y - o.vBasis.y, A[2] += z.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && A[0] < m[0][0] && (A[0] = m[0][0]), m[0][1] !== null && A[0] > m[0][1] && (A[0] = m[0][1])), m[1] && (m[1][0] !== null && A[1] < m[1][0] && (A[1] = m[1][0]), m[1][1] !== null && A[1] > m[1][1] && (A[1] = m[1][1])), m[2] && (m[2][0] !== null && A[2] < m[2][0] && (A[2] = m[2][0]), m[2][1] !== null && A[2] > m[2][1] && (A[2] = m[2][1])), m[3] && (m[3][0] !== null && A[3] < m[3][0] && (A[3] = m[3][0]), m[3][1] !== null && A[3] > m[3][1] && (A[3] = m[3][1]))), o.isPoint)
367
367
  o.bone.position.set(
368
368
  o.vBasis.x + A[0],
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(Oe.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(Ke, -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(z, oe, ie), z.copy(He).applyQuaternion(oe).setY(0).normalize(), oe.premultiply(Oe.setFromUnitVectors(He, z).invert()).normalize(), o.boneParent.quaternion.multiply(oe.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), oe.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(oe)), 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), oe.setFromAxisAngle(Ke, -m), o.boneParent.quaternion.multiply(oe)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), oe.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(oe)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
373
373
  for (n = 0, s = o.excludes.length; n < s; n++)
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) && (he = w.length(), re = ne.length(), !(re > m.radius + he) && (re < Math.abs(m.radius - he) || (re = (re * re + he * he - m.radiusSq) / (2 * re), ne.normalize(), Ce.copy(ne).multiplyScalar(re), re = Math.sqrt(he * he - re * re), w.subVectors(w, Ce).projectOnPlane(ne).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ne).normalize(), he = ze.dot(w), he < 0 && (he = Math.sqrt(re * re - he * he), ze.multiplyScalar(he), 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))));
374
+ m = o.excludes[n], ie.set(0, 0, 0), m.deltaLocal && (ie.x += m.deltaLocal[0], ie.y += m.deltaLocal[1], ie.z += m.deltaLocal[2]), ie.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ie.applyMatrix4(xe), z.copy(o.bone.position), !(z.distanceToSquared(ie) >= m.radiusSq) && (he = z.length(), re = ie.length(), !(re > m.radius + he) && (re < Math.abs(m.radius - he) || (re = (re * re + he * he - m.radiusSq) / (2 * re), ie.normalize(), Ce.copy(ie).multiplyScalar(re), re = Math.sqrt(he * he - re * re), z.subVectors(z, Ce).projectOnPlane(ie).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ie).normalize(), he = ze.dot(z), he < 0 && (he = Math.sqrt(re * re - he * he), ze.multiplyScalar(he), z.add(ze)), z.add(Ce).normalize(), ie.copy(o.bone.position).normalize(), oe.setFromUnitVectors(ie, z), o.boneParent.quaternion.premultiply(oe), o.boneParent.updateWorldMatrix(!1, !0))));
375
375
  }
376
376
  this.helpers.isActive && this.updateHelpers();
377
377
  }
@@ -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 f.SphereGeometry(m.radii[n], 6, 6), s = new f.MeshBasicMaterial({
396
+ const i = new b.SphereGeometry(m.radii[n], 6, 6), s = new b.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 f.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 b.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 f.BufferGeometry(), n = m.bones.map((u) => [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((u) => u && 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({
411
+ const e = new b.BufferGeometry(), n = m.bones.map((u) => [0, 0, 0]).flat();
412
+ e.setAttribute("position", new b.Float32BufferAttribute(n, 3));
413
+ const i = new b.Color(this.opt.helperBoneColor1), s = new b.Color(this.opt.helperBoneColor2), o = m.pivots.map((u) => u && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
414
+ e.setAttribute("color", new b.Float32BufferAttribute(o, 3));
415
+ const l = new b.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 f.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 b.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 f.BufferGeometry(), n = m.bones.map((u) => [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((u) => [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({
426
+ const e = new b.BufferGeometry(), n = m.bones.map((u) => [0, 0, 0, 0, 0, 0]).flat();
427
+ e.setAttribute("position", new b.Float32BufferAttribute(n, 3));
428
+ const i = new b.Color(this.opt.helperLinkColor1), s = new b.Color(this.opt.helperLinkColor2), o = m.bones.map((u) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
429
+ e.setAttribute("color", new b.Float32BufferAttribute(o, 3));
430
+ const l = new b.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 f.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 b.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
  /**
@@ -445,14 +445,14 @@ class et {
445
445
  xe.copy(this.armature.matrixWorld).invert();
446
446
  const t = m.object.geometry.getAttribute("position");
447
447
  for (let e = 0, n = m.bones.length; e < n; e++)
448
- fe.multiplyMatrices(xe, m.bones[e].matrixWorld), w.setFromMatrixPosition(fe), t.setXYZ(e, w.x, w.y, w.z);
448
+ fe.multiplyMatrices(xe, m.bones[e].matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(e, z.x, z.y, z.z);
449
449
  t.needsUpdate = !0, m.object.updateMatrixWorld();
450
450
  }
451
451
  if (m = this.helpers.lines, m.bones.length) {
452
452
  xe.copy(this.armature.matrixWorld).invert();
453
453
  const t = m.object.geometry.getAttribute("position");
454
454
  for (let e = 0, n = 0, i = m.bones.length; e < i; e++, n += 2)
455
- fe.multiplyMatrices(xe, m.bones[e].matrixWorld), w.setFromMatrixPosition(fe), t.setXYZ(n, w.x, w.y, w.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), w.setFromMatrixPosition(fe), t.setXYZ(n + 1, w.x, w.y, w.z);
455
+ fe.multiplyMatrices(xe, m.bones[e].matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(n, z.x, z.y, z.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(n + 1, z.x, z.y, z.z);
456
456
  t.needsUpdate = !0, m.object.updateMatrixWorld();
457
457
  }
458
458
  }
@@ -608,8 +608,8 @@ class tt {
608
608
  for (let a = 0; a < i / 2; a++) {
609
609
  const c = n[(u + a) * 2], d = n[(u + a) * 2 + 1], g = n[(u + a + i / 2) * 2] * r - n[(u + a + i / 2) * 2 + 1] * h, x = n[(u + a + i / 2) * 2] * h + n[(u + a + i / 2) * 2 + 1] * r;
610
610
  n[(u + a) * 2] = c + g, n[(u + a) * 2 + 1] = d + x, n[(u + a + i / 2) * 2] = c - g, n[(u + a + i / 2) * 2 + 1] = d - x;
611
- const b = r * o - h * l, I = r * l + h * o;
612
- r = b, h = I;
611
+ const f = r * o - h * l, R = r * l + h * o;
612
+ r = f, h = R;
613
613
  }
614
614
  }
615
615
  }
@@ -2629,15 +2629,15 @@ const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2629
2629
  fr: rt,
2630
2630
  fi: ht,
2631
2631
  lt: ct
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
- class De {
2632
+ }, Q = new b.Quaternion(), V = new b.Euler(), ve = new b.Vector3(), Re = new b.Vector3(), We = new b.Box3();
2633
+ new b.Matrix4();
2634
+ new b.Matrix4();
2635
+ new b.Vector3();
2636
+ new b.Vector3(0, 0, 1);
2637
+ const mt = new b.Vector3(1, 0, 0);
2638
+ new b.Vector3(0, 1, 0);
2639
+ new b.Vector3(0, 0, 1);
2640
+ class Be {
2641
2641
  /**
2642
2642
  * Avatar.
2643
2643
  * @typedef {Object} Avatar
@@ -4073,22 +4073,22 @@ class De {
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 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),
4076
+ this.renderer = new b.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 = b.SRGBColorSpace, this.renderer.toneMapping = b.ACESFilmicToneMapping, this.renderer.shadowMap.enabled = !1, this.nodeAvatar.appendChild(this.renderer.domElement), this.camera = new b.PerspectiveCamera(10, this.nodeAvatar.clientWidth / this.nodeAvatar.clientHeight, 0.1, 2e3), this.scene = new b.Scene(), this.lightAmbient = new b.AmbientLight(
4077
+ new b.Color(this.opt.lightAmbientColor),
4078
4078
  this.opt.lightAmbientIntensity
4079
- ), this.lightDirect = new f.DirectionalLight(
4080
- new f.Color(this.opt.lightDirectColor),
4079
+ ), this.lightDirect = new b.DirectionalLight(
4080
+ new b.Color(this.opt.lightDirectColor),
4081
4081
  this.opt.lightDirectIntensity
4082
- ), this.lightSpot = new f.SpotLight(
4083
- new f.Color(this.opt.lightSpotColor),
4082
+ ), this.lightSpot = new b.SpotLight(
4083
+ new b.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 f.PMREMGenerator(this.renderer);
4088
+ const l = new b.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 f.SkinnedMesh();
4091
+ this.ikMesh = new b.SkinnedMesh();
4092
4092
  const s = {
4093
4093
  LeftShoulder: null,
4094
4094
  LeftArm: "LeftShoulder",
@@ -4102,9 +4102,9 @@ class De {
4102
4102
  RightHandMiddle1: "RightHand"
4103
4103
  }, o = [];
4104
4104
  Object.entries(s).forEach((l, u) => {
4105
- const r = new f.Bone();
4105
+ const r = new b.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 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 = [];
4107
+ }), this.ikMesh.bind(new b.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 De {
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, u = Array.isArray(i.z) ? this.gaussianRandom(...i.z) : i.z;
4197
- s[1] === "position" || s[1] === "scale" ? e[n] = new f.Vector3(o, l, u) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new f.Quaternion().setFromEuler(new f.Euler(o, l, u, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new f.Quaternion(o, l, u, i.w).normalize());
4197
+ s[1] === "position" || s[1] === "scale" ? e[n] = new b.Vector3(o, l, u) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new b.Quaternion().setFromEuler(new b.Euler(o, l, u, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new b.Quaternion(o, l, u, i.w).normalize());
4198
4198
  }
4199
4199
  return e;
4200
4200
  }
@@ -4226,15 +4226,15 @@ class De {
4226
4226
  for (const [r, h] of Object.entries(n))
4227
4227
  if (s.morphTargetDictionary.hasOwnProperty(r)) {
4228
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 && (u = new f.Float32BufferAttribute(c.count * 3, 3)));
4229
+ l || (l = new b.Float32BufferAttribute(c.count * 3, 3), d && (u = new b.Float32BufferAttribute(c.count * 3, 3)));
4230
4230
  for (let g = 0; g < c.count; g++) {
4231
- const x = l.getX(g) + c.getX(g) * h, b = l.getY(g) + c.getY(g) * h, I = l.getZ(g) + c.getZ(g) * h;
4232
- l.setXYZ(g, x, b, I);
4231
+ const x = l.getX(g) + c.getX(g) * h, f = l.getY(g) + c.getY(g) * h, R = l.getZ(g) + c.getZ(g) * h;
4232
+ l.setXYZ(g, x, f, R);
4233
4233
  }
4234
4234
  if (d)
4235
4235
  for (let g = 0; g < c.count; g++) {
4236
- const x = u.getX(g) + d.getX(g) * h, b = u.getY(g) + d.getY(g) * h, I = u.getZ(g) + d.getZ(g) * h;
4237
- u.setXYZ(g, x, b, I);
4236
+ const x = u.getX(g) + d.getX(g) * h, f = u.getY(g) + d.getY(g) * h, R = u.getZ(g) + d.getZ(g) * h;
4237
+ u.setXYZ(g, x, f, R);
4238
4238
  }
4239
4239
  }
4240
4240
  if (l) {
@@ -4314,7 +4314,7 @@ class De {
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 u = new f.Vector3();
4317
+ const u = new b.Vector3();
4318
4318
  this.objectLeftEye.getWorldPosition(u), this.avatarHeight = u.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.avatar.body === "M" && this.poseTemplates.wide && (this.poseName = "wide", this.setPoseFromTemplate(this.poseTemplates.wide, 0), 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 De {
4358
4358
  default:
4359
4359
  a += 12, h = h * a;
4360
4360
  }
4361
- r = r * a, this.controlsEnd = new f.Vector3(r, h, 0), this.cameraEnd = new f.Vector3(r, h, 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;
4361
+ r = r * a, this.controlsEnd = new b.Vector3(r, h, 0), this.cameraEnd = new b.Vector3(r, h, a).applyEuler(new b.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 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));
4368
+ this.isAvatarOnly || (t = t || {}, t.hasOwnProperty("lightAmbientColor") && this.lightAmbient.color.set(new b.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 b.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 b.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 b.Vector3(0, 1.5, 0))), t.hasOwnProperty("lightSpotDispersion") && (this.lightSpot.angle = t.lightSpotDispersion));
4369
4369
  }
4370
4370
  /**
4371
4371
  * Render scene.
@@ -4480,7 +4480,7 @@ class De {
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], u = i[1].isQuaternion ? new f.Euler().setFromQuaternion(i[1]) : i[1];
4483
+ const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], u = i[1].isQuaternion ? new b.Euler().setFromQuaternion(i[1]) : i[1];
4484
4484
  n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(u.x * e) / e, n += ", y:" + Math.round(u.y * e) / e, n += ", z:" + Math.round(u.z * e) / e, n += "}";
4485
4485
  }
4486
4486
  }), n += "}", n;
@@ -5108,8 +5108,8 @@ class De {
5108
5108
  else {
5109
5109
  g.newvalue = d[i + 1];
5110
5110
  const x = a.ts[i + 1] - a.ts[i];
5111
- let b = 1;
5112
- 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;
5111
+ let f = 1;
5112
+ x > 1e-4 && (f = (this.animClock - a.ts[i]) / x), f < 1 && (g.easing && (f = g.easing(f)), g.newvalue = (1 - f) * d[i] + f * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(c) && delete g.ref[c], g.ref = a.vs;
5113
5113
  }
5114
5114
  if (l)
5115
5115
  switch (c) {
@@ -5157,7 +5157,7 @@ class De {
5157
5157
  { link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
5158
5158
  { link: "LeftArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
5159
5159
  ]
5160
- }, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5160
+ }, i.x ? new b.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5161
5161
  break;
5162
5162
  case "handRight":
5163
5163
  this.ikSolve({
@@ -5169,7 +5169,7 @@ class De {
5169
5169
  { link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5, maxAngle: 0.2 },
5170
5170
  { link: "RightArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
5171
5171
  ]
5172
- }, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5172
+ }, i.x ? new b.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5173
5173
  break;
5174
5174
  }
5175
5175
  if ((u || 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)), u ? (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({
@@ -5198,7 +5198,7 @@ class De {
5198
5198
  else {
5199
5199
  if (this.cameraClock !== null && this.cameraClock < 1e3) {
5200
5200
  this.cameraClock += e, this.cameraClock > 1e3 && (this.cameraClock = 1e3);
5201
- let a = new f.Spherical().setFromVector3(this.cameraStart), c = new f.Spherical().setFromVector3(this.cameraEnd);
5201
+ let a = new b.Spherical().setFromVector3(this.cameraStart), c = new b.Spherical().setFromVector3(this.cameraEnd);
5202
5202
  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();
5203
5203
  }
5204
5204
  this.controls.autoRotate && this.controls.update(), this.stats && this.stats.end(), this.render();
@@ -5262,12 +5262,12 @@ class De {
5262
5262
  e = e || {};
5263
5263
  const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, u = /[\p{Extended_Pictographic}]/ug, r = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
5264
5264
  let h = "", a = "", c = 0, d = [], g = [];
5265
- const x = Array.from(this.segmenter.segment(t), (b) => b.segment);
5266
- for (let b = 0; b < x.length; b++) {
5267
- const I = b === x.length - 1, D = x[b].match(l);
5268
- let p = x[b].match(s);
5269
- const M = x[b].match(u), z = x[b].match(o);
5270
- if (p && !I && !M && x[b + 1].match(s) && (p = !1), n && (h += x[b]), D && (!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({
5265
+ const x = Array.from(this.segmenter.segment(t), (f) => f.segment);
5266
+ for (let f = 0; f < x.length; f++) {
5267
+ const R = f === x.length - 1, F = x[f].match(l);
5268
+ let p = x[f].match(s);
5269
+ const H = x[f].match(u), k = x[f].match(o);
5270
+ if (p && !R && !H && x[f + 1].match(s) && (p = !1), n && (h += x[f]), F && (!i || i.every((y) => f < y[0] || f > y[1])) && (a += x[f]), (k || p || R) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
5271
5271
  mark: c,
5272
5272
  word: a
5273
5273
  })), h.length && (g.push({
@@ -5280,28 +5280,28 @@ class De {
5280
5280
  }), h = ""), a.length)) {
5281
5281
  const y = this.lipsyncWordsToVisemes(a, r);
5282
5282
  if (y && y.visemes && y.visemes.length) {
5283
- const E = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
5284
- for (let P = 0; P < y.visemes.length; P++)
5283
+ const T = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
5284
+ for (let E = 0; E < y.visemes.length; E++)
5285
5285
  g.push({
5286
5286
  mark: c,
5287
5287
  template: { name: "viseme" },
5288
- ts: [(y.times[P] - 0.6) / E, (y.times[P] + 0.5) / E, (y.times[P] + y.durations[P] + 0.5) / E],
5288
+ ts: [(y.times[E] - 0.6) / T, (y.times[E] + 0.5) / T, (y.times[E] + y.durations[E] + 0.5) / T],
5289
5289
  vs: {
5290
- ["viseme_" + y.visemes[P]]: [null, y.visemes[P] === "PP" || y.visemes[P] === "FF" ? 0.9 : 0.6, 0]
5290
+ ["viseme_" + y.visemes[E]]: [null, y.visemes[E] === "PP" || y.visemes[E] === "FF" ? 0.9 : 0.6, 0]
5291
5291
  }
5292
5292
  });
5293
5293
  }
5294
5294
  a = "", c++;
5295
5295
  }
5296
- if (p || I) {
5297
- if (d.length || I && g.length) {
5296
+ if (p || R) {
5297
+ if (d.length || R && g.length) {
5298
5298
  const y = {
5299
5299
  anim: g
5300
5300
  };
5301
5301
  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 = [];
5302
5302
  }
5303
- if (M) {
5304
- let y = this.animEmojis[x[b]];
5303
+ if (H) {
5304
+ let y = this.animEmojis[x[f]];
5305
5305
  y && y.link && (y = this.animEmojis[y.link]), y && this.speechQueue.push({ emoji: y });
5306
5306
  }
5307
5307
  this.speechQueue.push({ break: 100 });
@@ -5397,13 +5397,13 @@ class De {
5397
5397
  const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(h, Math.max(0, h - c.visemes.length * 150));
5398
5398
  let x = 0.6 + this.convertRange(g, [0, h], [0, 0.4]);
5399
5399
  if (h = Math.min(h, c.visemes.length * 200), d > 0)
5400
- for (let b = 0; b < c.visemes.length; b++) {
5401
- const I = r + c.times[b] / d * h, D = c.durations[b] / d * h;
5400
+ for (let f = 0; f < c.visemes.length; f++) {
5401
+ const R = r + c.times[f] / d * h, F = c.durations[f] / d * h;
5402
5402
  o.push({
5403
5403
  template: { name: "viseme" },
5404
- ts: [I - Math.min(60, 2 * D / 3), I + Math.min(25, D / 2), I + D + Math.min(60, D / 2)],
5404
+ ts: [R - Math.min(60, 2 * F / 3), R + Math.min(25, F / 2), R + F + Math.min(60, F / 2)],
5405
5405
  vs: {
5406
- ["viseme_" + c.visemes[b]]: [null, c.visemes[b] === "PP" || c.visemes[b] === "FF" ? 0.9 : x, 0]
5406
+ ["viseme_" + c.visemes[f]]: [null, c.visemes[f] === "PP" || c.visemes[f] === "FF" ? 0.9 : x, 0]
5407
5407
  }
5408
5408
  });
5409
5409
  }
@@ -5483,34 +5483,34 @@ class De {
5483
5483
  s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, u)), s.volume = Math.max(0, Math.min(1, r));
5484
5484
  const h = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
5485
5485
  if (a && h.length > 0) {
5486
- const p = h.find((M) => M.name.includes(a) || M.lang === o);
5486
+ const p = h.find((H) => H.name.includes(a) || H.lang === o);
5487
5487
  p && (s.voice = p);
5488
5488
  }
5489
- 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);
5489
+ 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), f = this.lipsyncWordsToVisemes(x, g);
5490
5490
  console.log("Browser TTS Lip-sync Debug:", {
5491
5491
  text: i,
5492
5492
  lipsyncLang: g,
5493
5493
  processedText: x,
5494
- lipsyncData: b,
5495
- hasVisemes: b && b.visemes && b.visemes.length > 0,
5494
+ lipsyncData: f,
5495
+ hasVisemes: f && f.visemes && f.visemes.length > 0,
5496
5496
  estimatedDuration: c
5497
5497
  });
5498
- const I = [];
5499
- if (b && b.visemes && b.visemes.length > 0) {
5500
- const p = b.times[b.visemes.length - 1] + b.durations[b.visemes.length - 1];
5501
- for (let M = 0; M < b.visemes.length; M++) {
5502
- const z = b.visemes[M], y = b.times[M] / p, E = b.durations[M] / p, P = y * c, W = E * c;
5503
- I.push({
5498
+ const R = [];
5499
+ if (f && f.visemes && f.visemes.length > 0) {
5500
+ const p = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
5501
+ for (let H = 0; H < f.visemes.length; H++) {
5502
+ const k = f.visemes[H], y = f.times[H] / p, T = f.durations[H] / p, E = y * c, O = T * c;
5503
+ R.push({
5504
5504
  template: { name: "viseme" },
5505
- ts: [P - Math.min(60, 2 * W / 3), P + Math.min(25, W / 2), P + W + Math.min(60, W / 2)],
5505
+ ts: [E - Math.min(60, 2 * O / 3), E + Math.min(25, O / 2), E + O + Math.min(60, O / 2)],
5506
5506
  vs: {
5507
- ["viseme_" + z]: [null, z === "PP" || z === "FF" ? 0.9 : 0.6, 0]
5507
+ ["viseme_" + k]: [null, k === "PP" || k === "FF" ? 0.9 : 0.6, 0]
5508
5508
  }
5509
5509
  });
5510
5510
  }
5511
5511
  }
5512
- const D = [...t.anim, ...I];
5513
- this.audioPlaylist.push({ anim: D, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5512
+ const F = [...t.anim, ...R];
5513
+ this.audioPlaylist.push({ anim: F, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5514
5514
  e();
5515
5515
  }, s.onerror = (p) => {
5516
5516
  console.error("Speech synthesis error:", p.error), n(p.error);
@@ -5576,15 +5576,15 @@ class De {
5576
5576
  console.error("Text-based lip-sync failed, using fallback:", c);
5577
5577
  const d = e.toLowerCase().split(/\s+/), g = [];
5578
5578
  for (const x of d)
5579
- for (const b of x) {
5580
- let I = "aa";
5581
- "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);
5579
+ for (const f of x) {
5580
+ let R = "aa";
5581
+ "aeiou".includes(f) ? R = "aa" : "bp".includes(f) ? R = "PP" : "fv".includes(f) ? R = "FF" : "st".includes(f) ? R = "SS" : "dln".includes(f) ? R = "DD" : "kg".includes(f) ? R = "kk" : "rw".includes(f) && (R = "RR"), g.push(R);
5582
5582
  }
5583
5583
  r = {
5584
- visemes: g.map((x, b) => ({
5584
+ visemes: g.map((x, f) => ({
5585
5585
  viseme: x,
5586
- startTime: b * l.duration / g.length,
5587
- endTime: (b + 1) * l.duration / g.length,
5586
+ startTime: f * l.duration / g.length,
5587
+ endTime: (f + 1) * l.duration / g.length,
5588
5588
  duration: l.duration / g.length,
5589
5589
  intensity: 0.6
5590
5590
  })),
@@ -5609,12 +5609,12 @@ class De {
5609
5609
  if (r.visemes && r.visemes.length > 0) {
5610
5610
  console.log("ElevenLabs: Generating lip-sync animation from", r.visemes.length, "visemes");
5611
5611
  for (let c = 0; c < r.visemes.length; c++) {
5612
- const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
5612
+ const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, f = d.intensity;
5613
5613
  h.push({
5614
5614
  template: { name: "viseme" },
5615
5615
  ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
5616
5616
  vs: {
5617
- ["viseme_" + d.viseme]: [null, b, 0]
5617
+ ["viseme_" + d.viseme]: [null, f, 0]
5618
5618
  }
5619
5619
  });
5620
5620
  }
@@ -5674,15 +5674,15 @@ class De {
5674
5674
  console.error("Text-based lip-sync failed, using fallback:", c);
5675
5675
  const d = e.toLowerCase().split(/\s+/), g = [];
5676
5676
  for (const x of d)
5677
- for (const b of x) {
5678
- let I = "aa";
5679
- "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);
5677
+ for (const f of x) {
5678
+ let R = "aa";
5679
+ "aeiou".includes(f) ? R = "aa" : "bp".includes(f) ? R = "PP" : "fv".includes(f) ? R = "FF" : "st".includes(f) ? R = "SS" : "dln".includes(f) ? R = "DD" : "kg".includes(f) ? R = "kk" : "rw".includes(f) && (R = "RR"), g.push(R);
5680
5680
  }
5681
5681
  r = {
5682
- visemes: g.map((x, b) => ({
5682
+ visemes: g.map((x, f) => ({
5683
5683
  viseme: x,
5684
- startTime: b * l.duration / g.length,
5685
- endTime: (b + 1) * l.duration / g.length,
5684
+ startTime: f * l.duration / g.length,
5685
+ endTime: (f + 1) * l.duration / g.length,
5686
5686
  duration: l.duration / g.length,
5687
5687
  intensity: 0.6
5688
5688
  })),
@@ -5707,12 +5707,12 @@ class De {
5707
5707
  if (r.visemes && r.visemes.length > 0) {
5708
5708
  console.log("Deepgram: Generating lip-sync animation from", r.visemes.length, "visemes");
5709
5709
  for (let c = 0; c < r.visemes.length; c++) {
5710
- const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
5710
+ const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, f = d.intensity;
5711
5711
  h.push({
5712
5712
  template: { name: "viseme" },
5713
5713
  ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
5714
5714
  vs: {
5715
- ["viseme_" + d.viseme]: [null, b, 0]
5715
+ ["viseme_" + d.viseme]: [null, f, 0]
5716
5716
  }
5717
5717
  });
5718
5718
  }
@@ -6146,7 +6146,7 @@ class De {
6146
6146
  */
6147
6147
  lookAtCamera(t) {
6148
6148
  let e;
6149
- 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) {
6149
+ if (this.speakTo && (e = new b.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), 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) {
6150
6150
  if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
6151
6151
  if (this.avatar.avatarIgnoreCamera) {
6152
6152
  this.lookAhead(t);
@@ -6160,15 +6160,15 @@ class De {
6160
6160
  return;
6161
6161
  }
6162
6162
  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"]);
6163
- const n = new f.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6163
+ const n = new b.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6164
6164
  V.set(s, i, 0, "YXZ");
6165
- const l = new f.Quaternion().setFromEuler(V), u = new f.Quaternion().copy(l).multiply(Q.clone().invert());
6165
+ const l = new b.Quaternion().setFromEuler(V), u = new b.Quaternion().copy(l).multiply(Q.clone().invert());
6166
6166
  V.setFromQuaternion(u, "YXZ");
6167
6167
  let r = V.x / (40 / 24) + 0.2, h = V.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), c = Math.min(0.8, Math.max(-0.8, h)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6168
6168
  if (t) {
6169
- let x = this.animQueue.findIndex((I) => I.template.name === "lookat");
6169
+ let x = this.animQueue.findIndex((R) => R.template.name === "lookat");
6170
6170
  x !== -1 && this.animQueue.splice(x, 1);
6171
- const b = {
6171
+ const f = {
6172
6172
  name: "lookat",
6173
6173
  dt: [750, t],
6174
6174
  vs: {
@@ -6183,7 +6183,7 @@ class De {
6183
6183
  headMove: [0]
6184
6184
  }
6185
6185
  };
6186
- this.animQueue.push(this.animFactory(b));
6186
+ this.animQueue.push(this.animFactory(f));
6187
6187
  }
6188
6188
  }
6189
6189
  /**
@@ -6196,23 +6196,23 @@ class De {
6196
6196
  if (!this.camera) return;
6197
6197
  const i = this.nodeAvatar.getBoundingClientRect();
6198
6198
  this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
6199
- 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);
6199
+ const s = new b.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new b.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new b.Vector3().addVectors(s, o).divideScalar(2);
6200
6200
  l.project(this.camera);
6201
6201
  let u = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
6202
6202
  t === null && (t = u), 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);
6203
- let h = 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 - u, u), x = Math.max(window.innerHeight - r, r), b = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - h + c, I = this.convertRange(t, [u - g, u + g], [-0.8, 0.8]) - a + d;
6204
- b = Math.min(0.6, Math.max(-0.3, b)), I = Math.min(0.8, Math.max(-0.8, I));
6205
- let D = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6203
+ let h = 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 - u, u), x = Math.max(window.innerHeight - r, r), f = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - h + c, R = this.convertRange(t, [u - g, u + g], [-0.8, 0.8]) - a + d;
6204
+ f = Math.min(0.6, Math.max(-0.3, f)), R = Math.min(0.8, Math.max(-0.8, R));
6205
+ let F = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6206
6206
  if (n) {
6207
- let M = this.animQueue.findIndex((y) => y.template.name === "lookat");
6208
- M !== -1 && this.animQueue.splice(M, 1);
6209
- const z = {
6207
+ let H = this.animQueue.findIndex((y) => y.template.name === "lookat");
6208
+ H !== -1 && this.animQueue.splice(H, 1);
6209
+ const k = {
6210
6210
  name: "lookat",
6211
6211
  dt: [750, n],
6212
6212
  vs: {
6213
- bodyRotateX: [b + D],
6214
- bodyRotateY: [I + p],
6215
- eyesRotateX: [-3 * D + 0.1],
6213
+ bodyRotateX: [f + F],
6214
+ bodyRotateY: [R + p],
6215
+ eyesRotateX: [-3 * F + 0.1],
6216
6216
  eyesRotateY: [-5 * p],
6217
6217
  browInnerUp: [[0, 0.7]],
6218
6218
  mouthLeft: [[0, 0.7]],
@@ -6221,7 +6221,7 @@ class De {
6221
6221
  headMove: [0]
6222
6222
  }
6223
6223
  };
6224
- this.animQueue.push(this.animFactory(z));
6224
+ this.animQueue.push(this.animFactory(k));
6225
6225
  }
6226
6226
  }
6227
6227
  /**
@@ -6232,14 +6232,14 @@ class De {
6232
6232
  */
6233
6233
  touchAt(t, e) {
6234
6234
  if (!this.camera) return;
6235
- const n = this.nodeAvatar.getBoundingClientRect(), i = new f.Vector2(
6235
+ const n = this.nodeAvatar.getBoundingClientRect(), i = new b.Vector2(
6236
6236
  (t - n.left) / n.width * 2 - 1,
6237
6237
  -((e - n.top) / n.height) * 2 + 1
6238
- ), s = new f.Raycaster();
6238
+ ), s = new b.Raycaster();
6239
6239
  s.setFromCamera(i, this.camera);
6240
6240
  const o = s.intersectObject(this.armature);
6241
6241
  if (o.length > 0) {
6242
- const l = o[0].point, u = new f.Vector3(), r = new f.Vector3();
6242
+ const l = o[0].point, u = new b.Vector3(), r = new b.Vector3();
6243
6243
  this.objectLeftArm.getWorldPosition(u), this.objectRightArm.getWorldPosition(r);
6244
6244
  const h = u.distanceToSquared(l), a = r.distanceToSquared(l);
6245
6245
  h < a ? (this.ikSolve({
@@ -6283,7 +6283,7 @@ class De {
6283
6283
  { link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
6284
6284
  { link: "LeftArm", minx: -1.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -1, maxz: 3 }
6285
6285
  ]
6286
- }, new f.Vector3(
6286
+ }, new b.Vector3(
6287
6287
  this.gaussianRandom(0, 0.5),
6288
6288
  this.gaussianRandom(-0.8, -0.2),
6289
6289
  this.gaussianRandom(0, 0.5)
@@ -6295,15 +6295,15 @@ class De {
6295
6295
  { link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5 },
6296
6296
  { link: "RightArm" }
6297
6297
  ]
6298
- }, new f.Vector3(
6298
+ }, new b.Vector3(
6299
6299
  this.gaussianRandom(-0.5, 0),
6300
6300
  this.gaussianRandom(-0.8, -0.2),
6301
6301
  this.gaussianRandom(0, 0.5)
6302
6302
  ), !0);
6303
6303
  const n = [], i = [];
6304
6304
  n.push(100 + Math.round(Math.random() * 500)), i.push({ duration: 1e3, props: {
6305
- "LeftHand.quaternion": new f.Quaternion().setFromEuler(new f.Euler(0, -1 - Math.random(), 0)),
6306
- "RightHand.quaternion": new f.Quaternion().setFromEuler(new f.Euler(0, 1 + Math.random(), 0))
6305
+ "LeftHand.quaternion": new b.Quaternion().setFromEuler(new b.Euler(0, -1 - Math.random(), 0)),
6306
+ "RightHand.quaternion": new b.Quaternion().setFromEuler(new b.Euler(0, 1 + Math.random(), 0))
6307
6307
  } }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm"].forEach((o) => {
6308
6308
  i[0].props[o + ".quaternion"] = this.ikMesh.getObjectByName(o).quaternion.clone();
6309
6309
  }), n.push(1e3 + Math.round(Math.random() * 500)), i.push({ duration: 2e3, props: {} }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm", "LeftHand", "RightHand"].forEach((o) => {
@@ -6432,6 +6432,9 @@ class De {
6432
6432
  L_Middle1: "LeftHandMiddle1",
6433
6433
  L_Middle2: "LeftHandMiddle2",
6434
6434
  L_Middle3: "LeftHandMiddle3",
6435
+ L_Mid1: "LeftHandMiddle1",
6436
+ L_Mid2: "LeftHandMiddle2",
6437
+ L_Mid3: "LeftHandMiddle3",
6435
6438
  L_Ring1: "LeftHandRing1",
6436
6439
  L_Ring2: "LeftHandRing2",
6437
6440
  L_Ring3: "LeftHandRing3",
@@ -6452,6 +6455,9 @@ class De {
6452
6455
  R_Middle1: "RightHandMiddle1",
6453
6456
  R_Middle2: "RightHandMiddle2",
6454
6457
  R_Middle3: "RightHandMiddle3",
6458
+ R_Mid1: "RightHandMiddle1",
6459
+ R_Mid2: "RightHandMiddle2",
6460
+ R_Mid3: "RightHandMiddle3",
6455
6461
  R_Ring1: "RightHandRing1",
6456
6462
  R_Ring2: "RightHandRing2",
6457
6463
  R_Ring3: "RightHandRing3",
@@ -6494,7 +6500,7 @@ class De {
6494
6500
  if (e.has(d))
6495
6501
  return d;
6496
6502
  }
6497
- const r = s.match(/^[rl]_middle(\d+)$/);
6503
+ const r = s.match(/^[rl]_(?:middle|mid)(\d+)$/);
6498
6504
  if (r) {
6499
6505
  const a = r[1], d = `${s.startsWith("r") ? "Right" : "Left"}HandMiddle${a}`;
6500
6506
  if (e.has(d))
@@ -6511,7 +6517,7 @@ class De {
6511
6517
  if (e.has(c))
6512
6518
  return c;
6513
6519
  }
6514
- if (s.includes("upperarmtwist") || s.includes("forearmtwist"))
6520
+ if (s.includes("upperarmtwist") || s.includes("forearmtwist") || s.includes("ribstwist") || s.includes("breast") || s.includes("twist"))
6515
6521
  return null;
6516
6522
  if (s.match(/^[rl]_forearm/)) {
6517
6523
  const c = `${s.startsWith("r") ? "Right" : "Left"}ForeArm`;
@@ -6545,7 +6551,31 @@ class De {
6545
6551
  const l = o.name.split("."), u = l[0], r = l[1], h = this.mapBoneName(u, e);
6546
6552
  if (h) {
6547
6553
  const a = `${h}.${r}`, c = o.clone();
6548
- c.name = a, n.push(c), u !== h && s.set(u, h);
6554
+ c.name = a;
6555
+ const d = h.includes("Arm") || h.includes("Hand") || h.includes("Shoulder"), g = h.includes("ForeArm");
6556
+ if (d && (r === "quaternion" || r === "rotation")) {
6557
+ if (r === "quaternion" && c.values && c.values.length >= 4) {
6558
+ const x = c.times.length;
6559
+ for (let f = 0; f < x; f++) {
6560
+ const R = f * 4;
6561
+ if (R + 3 < c.values.length) {
6562
+ let F = c.values[R], p = c.values[R + 1], H = c.values[R + 2], k = c.values[R + 3];
6563
+ if (g || h.includes("Hand")) {
6564
+ const y = Math.PI, T = Math.cos(y / 2), E = Math.sin(y / 2), O = T * k - E * F, te = T * F + E * k, S = T * p - E * H, G = T * H + E * p;
6565
+ F = te, p = S, H = G, k = O;
6566
+ }
6567
+ c.values[R] = F, c.values[R + 1] = p, c.values[R + 2] = H, c.values[R + 3] = k;
6568
+ }
6569
+ }
6570
+ } else if (r === "rotation" && c.values && c.values.length >= 3) {
6571
+ const x = c.times.length;
6572
+ for (let f = 0; f < x; f++) {
6573
+ const R = f * 3;
6574
+ R + 2 < c.values.length && (g || h.includes("Hand")) && (c.values[R + 1] += Math.PI);
6575
+ }
6576
+ }
6577
+ }
6578
+ n.push(c), u !== h && s.set(u, h);
6549
6579
  } else
6550
6580
  i.add(u);
6551
6581
  }), s.size > 0 && console.info(
@@ -6556,7 +6586,7 @@ class De {
6556
6586
  `FBX animation "${t.name}" contains tracks for ${i.size} bone(s) that couldn't be mapped:`,
6557
6587
  Array.from(i).slice(0, 10).join(", "),
6558
6588
  i.size > 10 ? "..." : ""
6559
- ), n.length > 0 ? console.info(`Filtered ${t.tracks.length} tracks down to ${n.length} valid tracks (${s.size} mapped)`) : console.error(`No valid tracks found for animation "${t.name}". All bones are missing or couldn't be mapped.`), n.length === 0 ? null : new f.AnimationClip(t.name, t.duration, n);
6589
+ ), n.length > 0 ? console.info(`Filtered ${t.tracks.length} tracks down to ${n.length} valid tracks (${s.size} mapped)`) : console.error(`No valid tracks found for animation "${t.name}". All bones are missing or couldn't be mapped.`), n.length === 0 ? null : new b.AnimationClip(t.name, t.duration, n);
6560
6590
  }
6561
6591
  async playAnimation(t, e = null, n = 10, i = 0, s = 0.01, o = !1) {
6562
6592
  if (!this.armature) return;
@@ -6566,9 +6596,9 @@ class De {
6566
6596
  let u = this.animQueue.find((a) => a.template.name === "pose");
6567
6597
  u && (u.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((a) => {
6568
6598
  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;
6569
- }), 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 });
6599
+ }), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new b.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
6570
6600
  const r = Math.ceil(n / l.clip.duration), h = this.mixer.clipAction(l.clip);
6571
- h.setLoop(f.LoopRepeat, r), h.clampWhenFinished = !0, this.currentFBXAction = h;
6601
+ h.setLoop(b.LoopRepeat, r), h.clampWhenFinished = !0, this.currentFBXAction = h;
6572
6602
  try {
6573
6603
  h.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
6574
6604
  } catch (a) {
@@ -6626,20 +6656,20 @@ class De {
6626
6656
  }
6627
6657
  c = g;
6628
6658
  const x = {};
6629
- c.tracks.forEach((I) => {
6630
- I.name = I.name.replaceAll("mixamorig", "");
6631
- const D = I.name.split(".");
6632
- if (D[1] === "position") {
6633
- for (let p = 0; p < I.values.length; p++)
6634
- I.values[p] = I.values[p] * s;
6635
- x[I.name] = new f.Vector3(I.values[0], I.values[1], I.values[2]);
6636
- } else D[1] === "quaternion" ? x[I.name] = new f.Quaternion(I.values[0], I.values[1], I.values[2], I.values[3]) : D[1] === "rotation" && (x[D[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(I.values[0], I.values[1], I.values[2], "XYZ")).normalize());
6659
+ c.tracks.forEach((R) => {
6660
+ R.name = R.name.replaceAll("mixamorig", "");
6661
+ const F = R.name.split(".");
6662
+ if (F[1] === "position") {
6663
+ for (let p = 0; p < R.values.length; p++)
6664
+ R.values[p] = R.values[p] * s;
6665
+ x[R.name] = new b.Vector3(R.values[0], R.values[1], R.values[2]);
6666
+ } else F[1] === "quaternion" ? x[R.name] = new b.Quaternion(R.values[0], R.values[1], R.values[2], R.values[3]) : F[1] === "rotation" && (x[F[0] + ".quaternion"] = new b.Quaternion().setFromEuler(new b.Euler(R.values[0], R.values[1], R.values[2], "XYZ")).normalize());
6637
6667
  });
6638
- const b = { props: x };
6639
- x["Hips.position"] && (x["Hips.position"].y < 0.5 ? b.lying = !0 : b.standing = !0), this.animClips.push({
6668
+ const f = { props: x };
6669
+ x["Hips.position"] && (x["Hips.position"].y < 0.5 ? f.lying = !0 : f.standing = !0), this.animClips.push({
6640
6670
  url: t + "-" + i,
6641
6671
  clip: c,
6642
- pose: b
6672
+ pose: f
6643
6673
  }), this.playAnimation(t, e, n, i, s);
6644
6674
  } else {
6645
6675
  const c = "Animation " + t + " (ndx=" + i + ") not found";
@@ -6684,7 +6714,7 @@ class De {
6684
6714
  r.tracks.forEach((c) => {
6685
6715
  c.name = c.name.replaceAll("mixamorig", "");
6686
6716
  const d = c.name.split(".");
6687
- d[1] === "position" ? h[c.name] = new f.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? h[c.name] = new f.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (h[d[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
6717
+ d[1] === "position" ? h[c.name] = new b.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? h[c.name] = new b.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (h[d[0] + ".quaternion"] = new b.Quaternion().setFromEuler(new b.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
6688
6718
  });
6689
6719
  const a = { props: h };
6690
6720
  h["Hips.position"] && (h["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
@@ -6717,7 +6747,7 @@ class De {
6717
6747
  if (s) {
6718
6748
  this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
6719
6749
  let l = this.animQueue.findIndex((u) => u.template.name === "talkinghands");
6720
- l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((u) => 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));
6750
+ l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((u) => 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 b.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new b.Quaternion(0, 1, 0, 0), -0.25));
6721
6751
  for (let [u, r] of Object.entries(this.gesture))
6722
6752
  r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(u) && (this.poseTarget.props[u].copy(r), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = i);
6723
6753
  e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
@@ -6732,7 +6762,7 @@ class De {
6732
6762
  const c = [];
6733
6763
  for (let x = 1; x < l.ts.length; x++) c.push(l.ts[x] - l.ts[x - 1]);
6734
6764
  const d = o.template?.rescale || c.map((x) => x / h), g = e * 1e3 - h;
6735
- l.ts = l.ts.map((x, b, I) => b === 0 ? u : I[b - 1] + c[b - 1] + d[b - 1] * g);
6765
+ l.ts = l.ts.map((x, f, R) => f === 0 ? u : R[f - 1] + c[f - 1] + d[f - 1] * g);
6736
6766
  } else {
6737
6767
  const c = e * 1e3 / h;
6738
6768
  l.ts = l.ts.map((d) => u + c * (d - u));
@@ -6765,34 +6795,34 @@ class De {
6765
6795
  * @param {numeric} [d=null] If set, apply in d milliseconds
6766
6796
  */
6767
6797
  ikSolve(t, e = null, n = !1, i = null) {
6768
- const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(), u = new f.Vector3(), r = new f.Quaternion(), h = new f.Vector3(), a = new f.Vector3(), c = new f.Vector3(), d = this.ikMesh.getObjectByName(t.root);
6798
+ const s = new b.Vector3(), o = new b.Vector3(), l = new b.Vector3(), u = new b.Vector3(), r = new b.Quaternion(), h = new b.Vector3(), a = new b.Vector3(), c = new b.Vector3(), d = this.ikMesh.getObjectByName(t.root);
6769
6799
  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);
6770
6800
  const g = this.ikMesh.getObjectByName(t.effector), x = t.links;
6771
- x.forEach((I) => {
6772
- I.bone = this.ikMesh.getObjectByName(I.link), I.bone.quaternion.copy(this.getPoseTemplateProp(I.link + ".quaternion"));
6801
+ x.forEach((R) => {
6802
+ R.bone = this.ikMesh.getObjectByName(R.link), R.bone.quaternion.copy(this.getPoseTemplateProp(R.link + ".quaternion"));
6773
6803
  }), d.updateMatrixWorld(!0);
6774
- const b = t.iterations || 10;
6804
+ const f = t.iterations || 10;
6775
6805
  if (e)
6776
- for (let I = 0; I < b; I++) {
6777
- let D = !1;
6778
- for (let p = 0, M = x.length; p < M; p++) {
6779
- const z = x[p].bone;
6780
- z.matrixWorld.decompose(u, r, h), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, u), l.applyQuaternion(r), l.normalize(), s.subVectors(e, u), s.applyQuaternion(r), s.normalize();
6806
+ for (let R = 0; R < f; R++) {
6807
+ let F = !1;
6808
+ for (let p = 0, H = x.length; p < H; p++) {
6809
+ const k = x[p].bone;
6810
+ k.matrixWorld.decompose(u, r, h), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, u), l.applyQuaternion(r), l.normalize(), s.subVectors(e, u), s.applyQuaternion(r), s.normalize();
6781
6811
  let y = s.dot(l);
6782
- 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(
6812
+ 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), k.quaternion.multiply(Q), k.rotation.setFromVector3(c.setFromEuler(k.rotation).clamp(new b.Vector3(
6783
6813
  x[p].minx !== void 0 ? x[p].minx : -1 / 0,
6784
6814
  x[p].miny !== void 0 ? x[p].miny : -1 / 0,
6785
6815
  x[p].minz !== void 0 ? x[p].minz : -1 / 0
6786
- ), new f.Vector3(
6816
+ ), new b.Vector3(
6787
6817
  x[p].maxx !== void 0 ? x[p].maxx : 1 / 0,
6788
6818
  x[p].maxy !== void 0 ? x[p].maxy : 1 / 0,
6789
6819
  x[p].maxz !== void 0 ? x[p].maxz : 1 / 0
6790
- ))), z.updateMatrixWorld(!0), D = !0);
6820
+ ))), k.updateMatrixWorld(!0), F = !0);
6791
6821
  }
6792
- if (!D) break;
6822
+ if (!F) break;
6793
6823
  }
6794
- i && x.forEach((I) => {
6795
- 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;
6824
+ i && x.forEach((R) => {
6825
+ this.poseTarget.props[R.link + ".quaternion"].copy(R.bone.quaternion), this.poseTarget.props[R.link + ".quaternion"].t = this.animClock, this.poseTarget.props[R.link + ".quaternion"].d = i;
6796
6826
  });
6797
6827
  }
6798
6828
  /**
@@ -6852,16 +6882,16 @@ function Fe() {
6852
6882
  };
6853
6883
  }
6854
6884
  function kt() {
6855
- const G = Fe(), t = [];
6856
- return Object.entries(G.voices).forEach(([e, n]) => {
6885
+ const Z = Fe(), t = [];
6886
+ return Object.entries(Z.voices).forEach(([e, n]) => {
6857
6887
  t.push({
6858
6888
  value: n,
6859
- label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${G.service})`
6889
+ label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${Z.service})`
6860
6890
  });
6861
6891
  }), t;
6862
6892
  }
6863
6893
  const Ve = Me(({
6864
- avatarUrl: G = "/avatars/brunette.glb",
6894
+ avatarUrl: Z = "/avatars/brunette.glb",
6865
6895
  avatarBody: t = "F",
6866
6896
  mood: e = "neutral",
6867
6897
  ttsLang: n = "en",
@@ -6880,142 +6910,142 @@ const Ve = Me(({
6880
6910
  },
6881
6911
  className: g = "",
6882
6912
  style: x = {},
6883
- animations: b = {}
6884
- }, I) => {
6885
- const D = N(null), p = N(null), M = N(r), z = N(null), y = N(null), E = N(!1), P = N({ remainingText: null, originalText: null, options: null }), W = N([]), oe = N(0), [S, Z] = ce(!0), [_, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
6913
+ animations: f = {}
6914
+ }, R) => {
6915
+ const F = N(null), p = N(null), H = N(r), k = N(null), y = N(null), T = N(!1), E = N({ remainingText: null, originalText: null, options: null }), O = N([]), te = N(0), [S, G] = ce(!0), [_, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
6886
6916
  de(() => {
6887
- E.current = ae;
6917
+ T.current = ae;
6888
6918
  }, [ae]), de(() => {
6889
- M.current = r;
6919
+ H.current = r;
6890
6920
  }, [r]);
6891
6921
  const ee = Fe(), le = i || ee.service;
6892
- let O;
6893
- le === "browser" ? O = {
6922
+ let U;
6923
+ le === "browser" ? U = {
6894
6924
  service: "browser",
6895
6925
  endpoint: "",
6896
6926
  apiKey: null,
6897
6927
  defaultVoice: "Google US English"
6898
- } : le === "elevenlabs" ? O = {
6928
+ } : le === "elevenlabs" ? U = {
6899
6929
  service: "elevenlabs",
6900
6930
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
6901
6931
  apiKey: o || ee.apiKey,
6902
6932
  defaultVoice: s || ee.defaultVoice || Ie.defaultVoice,
6903
6933
  voices: ee.voices || Ie.voices
6904
- } : le === "deepgram" ? O = {
6934
+ } : le === "deepgram" ? U = {
6905
6935
  service: "deepgram",
6906
6936
  endpoint: "https://api.deepgram.com/v1/speak",
6907
6937
  apiKey: o || ee.apiKey,
6908
6938
  defaultVoice: s || ee.defaultVoice || Te.defaultVoice,
6909
6939
  voices: ee.voices || Te.voices
6910
- } : O = {
6940
+ } : U = {
6911
6941
  ...ee,
6912
6942
  // Override API key if provided via props
6913
6943
  apiKey: o !== null ? o : ee.apiKey
6914
6944
  };
6915
6945
  const v = {
6916
- url: G,
6946
+ url: Z,
6917
6947
  body: t,
6918
6948
  avatarMood: e,
6919
6949
  ttsLang: le === "browser" ? "en-US" : n,
6920
- ttsVoice: s || O.defaultVoice,
6950
+ ttsVoice: s || U.defaultVoice,
6921
6951
  lipsyncLang: "en",
6922
6952
  showFullAvatar: r,
6923
6953
  bodyMovement: l,
6924
6954
  movementIntensity: u
6925
- }, R = {
6926
- ttsEndpoint: O.endpoint,
6927
- ttsApikey: O.apiKey,
6955
+ }, I = {
6956
+ ttsEndpoint: U.endpoint,
6957
+ ttsApikey: U.apiKey,
6928
6958
  ttsService: le,
6929
6959
  lipsyncModules: ["en"],
6930
6960
  cameraView: h
6931
- }, k = T(async () => {
6932
- if (!(!D.current || p.current))
6961
+ }, w = P(async () => {
6962
+ if (!(!F.current || p.current))
6933
6963
  try {
6934
- if (Z(!0), X(null), p.current = new De(D.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) => {
6935
- if (B.lengthComputable) {
6936
- const J = Math.min(100, Math.round(B.loaded / B.total * 100));
6964
+ if (G(!0), X(null), p.current = new Be(F.current, I), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), f && Object.keys(f).length > 0 && (p.current.customAnimations = f), await p.current.showAvatar(v, (D) => {
6965
+ if (D.lengthComputable) {
6966
+ const J = Math.min(100, Math.round(D.loaded / D.total * 100));
6937
6967
  c(J);
6938
6968
  }
6939
- }), await new Promise((B) => {
6969
+ }), await new Promise((D) => {
6940
6970
  const J = () => {
6941
- p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? B() : setTimeout(J, 100);
6971
+ p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? D() : setTimeout(J, 100);
6942
6972
  };
6943
6973
  J();
6944
6974
  }), p.current && p.current.setShowFullAvatar)
6945
6975
  try {
6946
6976
  p.current.setShowFullAvatar(r);
6947
- } catch (B) {
6948
- console.warn("Error setting full body mode on initialization:", B);
6977
+ } catch (D) {
6978
+ console.warn("Error setting full body mode on initialization:", D);
6949
6979
  }
6950
- 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);
6951
- const F = () => {
6980
+ 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()), G(!1), se(!0), a(p.current);
6981
+ const B = () => {
6952
6982
  document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
6953
6983
  };
6954
- return document.addEventListener("visibilitychange", F), () => {
6955
- document.removeEventListener("visibilitychange", F);
6984
+ return document.addEventListener("visibilitychange", B), () => {
6985
+ document.removeEventListener("visibilitychange", B);
6956
6986
  };
6957
6987
  } catch (L) {
6958
- console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), Z(!1), d(L);
6988
+ console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), G(!1), d(L);
6959
6989
  }
6960
- }, [G, t, e, n, i, s, o, r, l, u, h]);
6961
- de(() => (k(), () => {
6990
+ }, [Z, t, e, n, i, s, o, r, l, u, h]);
6991
+ de(() => (w(), () => {
6962
6992
  p.current && (p.current.stop(), p.current.dispose(), p.current = null);
6963
- }), [k]), de(() => {
6964
- if (!D.current || !p.current) return;
6965
- const L = new ResizeObserver((B) => {
6966
- for (const J of B)
6993
+ }), [w]), de(() => {
6994
+ if (!F.current || !p.current) return;
6995
+ const L = new ResizeObserver((D) => {
6996
+ for (const J of D)
6967
6997
  p.current && p.current.onResize && p.current.onResize();
6968
6998
  });
6969
- L.observe(D.current);
6970
- const F = () => {
6999
+ L.observe(F.current);
7000
+ const B = () => {
6971
7001
  p.current && p.current.onResize && p.current.onResize();
6972
7002
  };
6973
- return window.addEventListener("resize", F), () => {
6974
- L.disconnect(), window.removeEventListener("resize", F);
7003
+ return window.addEventListener("resize", B), () => {
7004
+ L.disconnect(), window.removeEventListener("resize", B);
6975
7005
  };
6976
7006
  }, [$]);
6977
- const H = T(async () => {
7007
+ const M = P(async () => {
6978
7008
  if (p.current && p.current.audioCtx)
6979
7009
  try {
6980
7010
  (p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
6981
7011
  } catch (L) {
6982
7012
  console.warn("Failed to resume audio context:", L);
6983
7013
  }
6984
- }, []), U = T(async (L, F = {}) => {
7014
+ }, []), W = P(async (L, B = {}) => {
6985
7015
  if (p.current && $)
6986
7016
  try {
6987
- y.current && (clearInterval(y.current), y.current = null), z.current = { text: L, options: F }, P.current = { remainingText: null, originalText: null, options: null };
6988
- const B = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(B).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
6989
- W.current = J, oe.current = 0, pe(!1), E.current = !1, await H();
7017
+ y.current && (clearInterval(y.current), y.current = null), k.current = { text: L, options: B }, E.current = { remainingText: null, originalText: null, options: null };
7018
+ const D = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(D).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
7019
+ O.current = J, te.current = 0, pe(!1), T.current = !1, await M();
6990
7020
  const ge = {
6991
- ...F,
6992
- lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
7021
+ ...B,
7022
+ lipsyncLang: B.lipsyncLang || v.lipsyncLang || "en"
6993
7023
  };
6994
- if (F.onSpeechEnd && p.current) {
7024
+ if (B.onSpeechEnd && p.current) {
6995
7025
  const Y = p.current;
6996
7026
  let ue = null, Se = 0;
6997
7027
  const Ae = 1200;
6998
7028
  let be = !1;
6999
7029
  ue = setInterval(() => {
7000
- if (Se++, E.current)
7030
+ if (Se++, T.current)
7001
7031
  return;
7002
7032
  if (Se > Ae) {
7003
- if (ue && (clearInterval(ue), ue = null, y.current = null), !be && !E.current) {
7033
+ if (ue && (clearInterval(ue), ue = null, y.current = null), !be && !T.current) {
7004
7034
  be = !0;
7005
7035
  try {
7006
- F.onSpeechEnd();
7007
- } catch (Be) {
7008
- console.error("Error in onSpeechEnd callback (timeout):", Be);
7036
+ B.onSpeechEnd();
7037
+ } catch (De) {
7038
+ console.error("Error in onSpeechEnd callback (timeout):", De);
7009
7039
  }
7010
7040
  }
7011
7041
  return;
7012
7042
  }
7013
7043
  const ye = !Y.speechQueue || Y.speechQueue.length === 0, ke = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
7014
- Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !E.current && setTimeout(() => {
7015
- 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) {
7044
+ Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !T.current && setTimeout(() => {
7045
+ if (Y && !T.current && Y.isSpeaking === !1 && (!Y.speechQueue || Y.speechQueue.length === 0) && (!Y.audioPlaylist || Y.audioPlaylist.length === 0) && Y.isAudioPlaying === !1 && !be && !T.current) {
7016
7046
  be = !0, ue && (clearInterval(ue), ue = null, y.current = null);
7017
7047
  try {
7018
- F.onSpeechEnd();
7048
+ B.onSpeechEnd();
7019
7049
  } catch (Ze) {
7020
7050
  console.error("Error in onSpeechEnd callback:", Ze);
7021
7051
  }
@@ -7024,70 +7054,70 @@ const Ve = Me(({
7024
7054
  }, 100), y.current = ue;
7025
7055
  }
7026
7056
  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 () => {
7027
- await H(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
7057
+ await M(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
7028
7058
  }, 100);
7029
- } catch (B) {
7030
- console.error("Error speaking text:", B), X(B.message || "Failed to speak text");
7059
+ } catch (D) {
7060
+ console.error("Error speaking text:", D), X(D.message || "Failed to speak text");
7031
7061
  }
7032
- }, [$, H, v.lipsyncLang]), K = T(() => {
7033
- p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, pe(!1));
7034
- }, []), j = T(() => {
7062
+ }, [$, M, v.lipsyncLang]), K = P(() => {
7063
+ p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), k.current = null, pe(!1));
7064
+ }, []), j = P(() => {
7035
7065
  if (p.current && p.current.pauseSpeaking) {
7036
7066
  const L = p.current;
7037
7067
  if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
7038
7068
  y.current && (clearInterval(y.current), y.current = null);
7039
- let B = "";
7040
- if (z.current && W.current.length > 0) {
7041
- 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, ue = ge + (Y ? 1 : 0), Se = J - ue;
7042
- if (ue > 0 && Se < J && (B = W.current.slice(Se).join(". ").trim(), !B && ge > 0 && L.speechQueue)) {
7069
+ let D = "";
7070
+ if (k.current && O.current.length > 0) {
7071
+ const J = O.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, ue = ge + (Y ? 1 : 0), Se = J - ue;
7072
+ if (ue > 0 && Se < J && (D = O.current.slice(Se).join(". ").trim(), !D && ge > 0 && L.speechQueue)) {
7043
7073
  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(" ");
7044
- be && be.trim() && (B = be.trim());
7074
+ be && be.trim() && (D = be.trim());
7045
7075
  }
7046
7076
  }
7047
- z.current && (P.current = {
7048
- remainingText: B || null,
7049
- originalText: z.current.text,
7050
- options: z.current.options
7051
- }), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), E.current = !0, pe(!0);
7077
+ k.current && (E.current = {
7078
+ remainingText: D || null,
7079
+ originalText: k.current.text,
7080
+ options: k.current.options
7081
+ }), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), T.current = !0, pe(!0);
7052
7082
  }
7053
7083
  }
7054
- }, []), q = T(async () => {
7084
+ }, []), q = P(async () => {
7055
7085
  if (!p.current || !ae)
7056
7086
  return;
7057
- let L = "", F = {};
7058
- if (P.current && P.current.remainingText)
7059
- L = P.current.remainingText, F = P.current.options || {}, P.current = { remainingText: null, originalText: null, options: null };
7060
- else if (z.current && z.current.text)
7061
- L = z.current.text, F = z.current.options || {};
7087
+ let L = "", B = {};
7088
+ if (E.current && E.current.remainingText)
7089
+ L = E.current.remainingText, B = E.current.options || {}, E.current = { remainingText: null, originalText: null, options: null };
7090
+ else if (k.current && k.current.text)
7091
+ L = k.current.text, B = k.current.options || {};
7062
7092
  else {
7063
- console.warn("Resume called but no paused speech found"), pe(!1), E.current = !1;
7093
+ console.warn("Resume called but no paused speech found"), pe(!1), T.current = !1;
7064
7094
  return;
7065
7095
  }
7066
- pe(!1), E.current = !1, await H();
7067
- const B = {
7068
- ...F,
7069
- lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
7096
+ pe(!1), T.current = !1, await M();
7097
+ const D = {
7098
+ ...B,
7099
+ lipsyncLang: B.lipsyncLang || v.lipsyncLang || "en"
7070
7100
  };
7071
7101
  try {
7072
- await U(L, B);
7102
+ await W(L, D);
7073
7103
  } catch (J) {
7074
- console.error("Error resuming speech:", J), pe(!1), E.current = !1;
7104
+ console.error("Error resuming speech:", J), pe(!1), T.current = !1;
7075
7105
  }
7076
- }, [H, ae, U, v]), Le = T((L) => {
7106
+ }, [M, ae, W, v]), Le = P((L) => {
7077
7107
  p.current && p.current.setMood(L);
7078
- }, []), we = T((L) => {
7108
+ }, []), we = P((L) => {
7079
7109
  p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
7080
- }, []), C = T((L, F = !1) => {
7110
+ }, []), C = P((L, B = !1) => {
7081
7111
  if (p.current && p.current.playAnimation) {
7082
- if (b && b[L] && (L = b[L]), p.current.setShowFullAvatar)
7112
+ if (f && f[L] && (L = f[L]), p.current.setShowFullAvatar)
7083
7113
  try {
7084
- p.current.setShowFullAvatar(M.current);
7114
+ p.current.setShowFullAvatar(H.current);
7085
7115
  } catch (J) {
7086
7116
  console.warn("Error setting full body mode:", J);
7087
7117
  }
7088
7118
  if (L.includes("."))
7089
7119
  try {
7090
- p.current.playAnimation(L, null, 10, 0, 0.01, F);
7120
+ p.current.playAnimation(L, null, 10, 0, 0.01, B);
7091
7121
  } catch (J) {
7092
7122
  console.warn(`Failed to play ${L}:`, J);
7093
7123
  try {
@@ -7101,7 +7131,7 @@ const Ve = Me(({
7101
7131
  let ge = !1;
7102
7132
  for (const Y of J)
7103
7133
  try {
7104
- p.current.playAnimation(L + Y, null, 10, 0, 0.01, F), ge = !0;
7134
+ p.current.playAnimation(L + Y, null, 10, 0, 0.01, B), ge = !0;
7105
7135
  break;
7106
7136
  } catch {
7107
7137
  }
@@ -7115,35 +7145,35 @@ const Ve = Me(({
7115
7145
  }
7116
7146
  }
7117
7147
  }
7118
- }, [b]), te = T(() => {
7148
+ }, [f]), ne = P(() => {
7119
7149
  p.current && p.current.onResize && p.current.onResize();
7120
7150
  }, []);
7121
- return Ee(I, () => ({
7122
- speakText: U,
7151
+ return Ee(R, () => ({
7152
+ speakText: W,
7123
7153
  stopSpeaking: K,
7124
7154
  pauseSpeaking: j,
7125
7155
  resumeSpeaking: q,
7126
- resumeAudioContext: H,
7156
+ resumeAudioContext: M,
7127
7157
  setMood: Le,
7128
7158
  setTimingAdjustment: we,
7129
7159
  playAnimation: C,
7130
7160
  isReady: $,
7131
7161
  isPaused: ae,
7132
7162
  talkingHead: p.current,
7133
- handleResize: te,
7163
+ handleResize: ne,
7134
7164
  setBodyMovement: (L) => {
7135
7165
  if (p.current && p.current.setShowFullAvatar && p.current.setBodyMovement)
7136
7166
  try {
7137
- p.current.setShowFullAvatar(M.current), p.current.setBodyMovement(L);
7138
- } catch (F) {
7139
- console.warn("Error setting body movement:", F);
7167
+ p.current.setShowFullAvatar(H.current), p.current.setBodyMovement(L);
7168
+ } catch (B) {
7169
+ console.warn("Error setting body movement:", B);
7140
7170
  }
7141
7171
  },
7142
7172
  setMovementIntensity: (L) => p.current?.setMovementIntensity(L),
7143
7173
  playRandomDance: () => {
7144
7174
  if (p.current && p.current.setShowFullAvatar && p.current.playRandomDance)
7145
7175
  try {
7146
- p.current.setShowFullAvatar(M.current), p.current.playRandomDance();
7176
+ p.current.setShowFullAvatar(H.current), p.current.playRandomDance();
7147
7177
  } catch (L) {
7148
7178
  console.warn("Error playing random dance:", L);
7149
7179
  }
@@ -7151,15 +7181,15 @@ const Ve = Me(({
7151
7181
  playReaction: (L) => {
7152
7182
  if (p.current && p.current.setShowFullAvatar && p.current.playReaction)
7153
7183
  try {
7154
- p.current.setShowFullAvatar(M.current), p.current.playReaction(L);
7155
- } catch (F) {
7156
- console.warn("Error playing reaction:", F);
7184
+ p.current.setShowFullAvatar(H.current), p.current.playReaction(L);
7185
+ } catch (B) {
7186
+ console.warn("Error playing reaction:", B);
7157
7187
  }
7158
7188
  },
7159
7189
  playCelebration: () => {
7160
7190
  if (p.current && p.current.setShowFullAvatar && p.current.playCelebration)
7161
7191
  try {
7162
- p.current.setShowFullAvatar(M.current), p.current.playCelebration();
7192
+ p.current.setShowFullAvatar(H.current), p.current.playCelebration();
7163
7193
  } catch (L) {
7164
7194
  console.warn("Error playing celebration:", L);
7165
7195
  }
@@ -7167,9 +7197,9 @@ const Ve = Me(({
7167
7197
  setShowFullAvatar: (L) => {
7168
7198
  if (p.current && p.current.setShowFullAvatar)
7169
7199
  try {
7170
- M.current = L, p.current.setShowFullAvatar(L);
7171
- } catch (F) {
7172
- console.warn("Error setting showFullAvatar:", F);
7200
+ H.current = L, p.current.setShowFullAvatar(L);
7201
+ } catch (B) {
7202
+ console.warn("Error setting showFullAvatar:", B);
7173
7203
  }
7174
7204
  },
7175
7205
  lockAvatarPosition: () => {
@@ -7202,7 +7232,7 @@ const Ve = Me(({
7202
7232
  /* @__PURE__ */ me(
7203
7233
  "div",
7204
7234
  {
7205
- ref: D,
7235
+ ref: F,
7206
7236
  className: "talking-head-viewer",
7207
7237
  style: {
7208
7238
  width: "100%",
@@ -7238,7 +7268,7 @@ const Ve = Me(({
7238
7268
  });
7239
7269
  Ve.displayName = "TalkingHeadAvatar";
7240
7270
  const pt = Me(({
7241
- text: G = "Hello! I'm a talking avatar. How are you today?",
7271
+ text: Z = "Hello! I'm a talking avatar. How are you today?",
7242
7272
  onLoading: t = () => {
7243
7273
  },
7244
7274
  onError: e = () => {
@@ -7249,23 +7279,23 @@ const pt = Me(({
7249
7279
  style: s = {},
7250
7280
  avatarConfig: o = {}
7251
7281
  }, l) => {
7252
- const u = N(null), r = N(null), [h, a] = ce(!0), [c, d] = ce(null), [g, x] = ce(!1), b = Fe(), I = o.ttsService || b.service, D = I === "browser" ? {
7282
+ const u = N(null), r = N(null), [h, a] = ce(!0), [c, d] = ce(null), [g, x] = ce(!1), f = Fe(), R = o.ttsService || f.service, F = R === "browser" ? {
7253
7283
  endpoint: "",
7254
7284
  apiKey: null,
7255
7285
  defaultVoice: "Google US English"
7256
7286
  } : {
7257
- ...b,
7287
+ ...f,
7258
7288
  // Override API key if provided via avatarConfig
7259
- apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : b.apiKey,
7289
+ apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : f.apiKey,
7260
7290
  // Override endpoint for ElevenLabs if service is explicitly set
7261
- endpoint: I === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : b.endpoint
7291
+ endpoint: R === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : f.endpoint
7262
7292
  }, p = {
7263
7293
  url: "/avatars/brunette.glb",
7264
7294
  // Use brunette avatar (working glTF file)
7265
7295
  body: "F",
7266
7296
  avatarMood: "neutral",
7267
- ttsLang: I === "browser" ? "en-US" : "en",
7268
- ttsVoice: o.ttsVoice || D.defaultVoice,
7297
+ ttsLang: R === "browser" ? "en-US" : "en",
7298
+ ttsVoice: o.ttsVoice || F.defaultVoice,
7269
7299
  lipsyncLang: "en",
7270
7300
  // English lip-sync
7271
7301
  showFullAvatar: !0,
@@ -7273,16 +7303,16 @@ const pt = Me(({
7273
7303
  bodyMovement: "idle",
7274
7304
  movementIntensity: 0.5,
7275
7305
  ...o
7276
- }, M = {
7277
- ttsEndpoint: D.endpoint,
7278
- ttsApikey: D.apiKey,
7279
- ttsService: I,
7306
+ }, H = {
7307
+ ttsEndpoint: F.endpoint,
7308
+ ttsApikey: F.apiKey,
7309
+ ttsService: R,
7280
7310
  lipsyncModules: ["en"],
7281
7311
  cameraView: "upper"
7282
- }, z = T(async () => {
7312
+ }, k = P(async () => {
7283
7313
  if (!(!u.current || r.current))
7284
7314
  try {
7285
- if (a(!0), d(null), r.current = new De(u.current, M), await r.current.showAvatar(p, (_) => {
7315
+ if (a(!0), d(null), r.current = new Be(u.current, H), await r.current.showAvatar(p, (_) => {
7286
7316
  if (_.lengthComputable) {
7287
7317
  const X = Math.min(100, Math.round(_.loaded / _.total * 100));
7288
7318
  t(X);
@@ -7305,37 +7335,37 @@ const pt = Me(({
7305
7335
  console.warn("Error setting full body mode on initialization:", _);
7306
7336
  }
7307
7337
  a(!1), x(!0), n(r.current);
7308
- const Z = () => {
7338
+ const G = () => {
7309
7339
  document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
7310
7340
  };
7311
- return document.addEventListener("visibilitychange", Z), () => {
7312
- document.removeEventListener("visibilitychange", Z);
7341
+ return document.addEventListener("visibilitychange", G), () => {
7342
+ document.removeEventListener("visibilitychange", G);
7313
7343
  };
7314
7344
  } catch (S) {
7315
7345
  console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), a(!1), e(S);
7316
7346
  }
7317
7347
  }, []);
7318
- de(() => (z(), () => {
7348
+ de(() => (k(), () => {
7319
7349
  r.current && (r.current.stop(), r.current.dispose(), r.current = null);
7320
- }), [z]);
7321
- const y = T((S) => {
7350
+ }), [k]);
7351
+ const y = P((S) => {
7322
7352
  if (r.current && g)
7323
7353
  try {
7324
7354
  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(() => {
7325
7355
  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");
7326
7356
  }, 500));
7327
- } catch (Z) {
7328
- console.error("Error speaking text:", Z), d(Z.message || "Failed to speak text");
7357
+ } catch (G) {
7358
+ console.error("Error speaking text:", G), d(G.message || "Failed to speak text");
7329
7359
  }
7330
7360
  else
7331
7361
  console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
7332
- }, [g, p]), E = T(() => {
7362
+ }, [g, p]), T = P(() => {
7333
7363
  r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7334
- }, []), P = T((S) => {
7364
+ }, []), E = P((S) => {
7335
7365
  r.current && r.current.setMood(S);
7336
- }, []), W = T((S) => {
7366
+ }, []), O = P((S) => {
7337
7367
  r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
7338
- }, []), oe = T((S, Z = !1) => {
7368
+ }, []), te = P((S, G = !1) => {
7339
7369
  if (r.current && r.current.playAnimation) {
7340
7370
  if (r.current.setShowFullAvatar)
7341
7371
  try {
@@ -7345,7 +7375,7 @@ const pt = Me(({
7345
7375
  }
7346
7376
  if (S.includes("."))
7347
7377
  try {
7348
- r.current.playAnimation(S, null, 10, 0, 0.01, Z), console.log("Playing animation:", S);
7378
+ r.current.playAnimation(S, null, 10, 0, 0.01, G), console.log("Playing animation:", S);
7349
7379
  } catch (X) {
7350
7380
  console.log(`Failed to play ${S}:`, X);
7351
7381
  try {
@@ -7359,7 +7389,7 @@ const pt = Me(({
7359
7389
  let $ = !1;
7360
7390
  for (const se of X)
7361
7391
  try {
7362
- r.current.playAnimation(S + se, null, 10, 0, 0.01, Z), console.log("Playing animation:", S + se), $ = !0;
7392
+ r.current.playAnimation(S + se, null, 10, 0, 0.01, G), console.log("Playing animation:", S + se), $ = !0;
7363
7393
  break;
7364
7394
  } catch {
7365
7395
  console.log(`Failed to play ${S}${se}, trying next format...`);
@@ -7378,18 +7408,18 @@ const pt = Me(({
7378
7408
  }, []);
7379
7409
  return Ee(l, () => ({
7380
7410
  speakText: y,
7381
- stopSpeaking: E,
7382
- setMood: P,
7383
- setTimingAdjustment: W,
7384
- playAnimation: oe,
7411
+ stopSpeaking: T,
7412
+ setMood: E,
7413
+ setTimingAdjustment: O,
7414
+ playAnimation: te,
7385
7415
  isReady: g,
7386
7416
  talkingHead: r.current,
7387
7417
  setBodyMovement: (S) => {
7388
7418
  if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
7389
7419
  try {
7390
7420
  r.current.setShowFullAvatar(!0), r.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
7391
- } catch (Z) {
7392
- console.warn("Error setting body movement:", Z);
7421
+ } catch (G) {
7422
+ console.warn("Error setting body movement:", G);
7393
7423
  }
7394
7424
  },
7395
7425
  setMovementIntensity: (S) => r.current?.setMovementIntensity(S),
@@ -7405,8 +7435,8 @@ const pt = Me(({
7405
7435
  if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
7406
7436
  try {
7407
7437
  r.current.setShowFullAvatar(!0), r.current.playReaction(S), console.log("Reaction played with full body mode:", S);
7408
- } catch (Z) {
7409
- console.warn("Error playing reaction:", Z);
7438
+ } catch (G) {
7439
+ console.warn("Error playing reaction:", G);
7410
7440
  }
7411
7441
  },
7412
7442
  playCelebration: () => {
@@ -7421,8 +7451,8 @@ const pt = Me(({
7421
7451
  if (r.current && r.current.setShowFullAvatar)
7422
7452
  try {
7423
7453
  r.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
7424
- } catch (Z) {
7425
- console.warn("Error setting showFullAvatar:", Z);
7454
+ } catch (G) {
7455
+ console.warn("Error setting showFullAvatar:", G);
7426
7456
  }
7427
7457
  },
7428
7458
  lockAvatarPosition: () => {
@@ -7479,7 +7509,7 @@ const pt = Me(({
7479
7509
  });
7480
7510
  pt.displayName = "TalkingHeadComponent";
7481
7511
  const gt = Me(({
7482
- text: G = null,
7512
+ text: Z = null,
7483
7513
  avatarUrl: t = "/avatars/brunette.glb",
7484
7514
  avatarBody: e = "F",
7485
7515
  mood: n = "neutral",
@@ -7499,66 +7529,66 @@ const gt = Me(({
7499
7529
  },
7500
7530
  onSpeechEnd: x = () => {
7501
7531
  },
7502
- className: b = "",
7503
- style: I = {},
7504
- animations: D = {},
7532
+ className: f = "",
7533
+ style: R = {},
7534
+ animations: F = {},
7505
7535
  autoSpeak: p = !1
7506
- }, M) => {
7507
- const z = N(null), y = N(null), E = N(h), P = N(null), W = N(null), oe = N(!1), S = N({ remainingText: null, originalText: null, options: null }), Z = N([]), [_, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
7536
+ }, H) => {
7537
+ const k = N(null), y = N(null), T = N(h), E = N(null), O = N(null), te = N(!1), S = N({ remainingText: null, originalText: null, options: null }), G = N([]), [_, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
7508
7538
  de(() => {
7509
- oe.current = ee;
7539
+ te.current = ee;
7510
7540
  }, [ee]), de(() => {
7511
- E.current = h;
7541
+ T.current = h;
7512
7542
  }, [h]);
7513
- const O = Fe(), v = s || O.service;
7514
- let R;
7515
- v === "browser" ? R = {
7543
+ const U = Fe(), v = s || U.service;
7544
+ let I;
7545
+ v === "browser" ? I = {
7516
7546
  service: "browser",
7517
7547
  endpoint: "",
7518
7548
  apiKey: null,
7519
7549
  defaultVoice: "Google US English"
7520
- } : v === "elevenlabs" ? R = {
7550
+ } : v === "elevenlabs" ? I = {
7521
7551
  service: "elevenlabs",
7522
7552
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
7523
- apiKey: l || O.apiKey,
7524
- defaultVoice: o || O.defaultVoice || Ie.defaultVoice,
7525
- voices: O.voices || Ie.voices
7526
- } : v === "deepgram" ? R = {
7553
+ apiKey: l || U.apiKey,
7554
+ defaultVoice: o || U.defaultVoice || Ie.defaultVoice,
7555
+ voices: U.voices || Ie.voices
7556
+ } : v === "deepgram" ? I = {
7527
7557
  service: "deepgram",
7528
7558
  endpoint: "https://api.deepgram.com/v1/speak",
7529
- apiKey: l || O.apiKey,
7530
- defaultVoice: o || O.defaultVoice || Te.defaultVoice,
7531
- voices: O.voices || Te.voices
7532
- } : R = {
7533
- ...O,
7534
- apiKey: l !== null ? l : O.apiKey
7559
+ apiKey: l || U.apiKey,
7560
+ defaultVoice: o || U.defaultVoice || Te.defaultVoice,
7561
+ voices: U.voices || Te.voices
7562
+ } : I = {
7563
+ ...U,
7564
+ apiKey: l !== null ? l : U.apiKey
7535
7565
  };
7536
- const k = {
7566
+ const w = {
7537
7567
  url: t,
7538
7568
  body: e,
7539
7569
  avatarMood: n,
7540
7570
  ttsLang: v === "browser" ? "en-US" : i,
7541
- ttsVoice: o || R.defaultVoice,
7571
+ ttsVoice: o || I.defaultVoice,
7542
7572
  lipsyncLang: "en",
7543
7573
  showFullAvatar: h,
7544
7574
  bodyMovement: u,
7545
7575
  movementIntensity: r
7546
- }, H = {
7547
- ttsEndpoint: R.endpoint,
7548
- ttsApikey: R.apiKey,
7576
+ }, M = {
7577
+ ttsEndpoint: I.endpoint,
7578
+ ttsApikey: I.apiKey,
7549
7579
  ttsService: v,
7550
7580
  lipsyncModules: ["en"],
7551
7581
  cameraView: a
7552
- }, U = T(async () => {
7553
- if (!(!z.current || y.current))
7582
+ }, W = P(async () => {
7583
+ if (!(!k.current || y.current))
7554
7584
  try {
7555
- X(!0), se(null), y.current = new De(z.current, H), console.log("Avatar config being passed:", {
7556
- url: k.url,
7557
- body: k.body,
7558
- avatarMood: k.avatarMood
7559
- }), await y.current.showAvatar(k, (te) => {
7560
- if (te.lengthComputable) {
7561
- const L = Math.min(100, Math.round(te.loaded / te.total * 100));
7585
+ X(!0), se(null), y.current = new Be(k.current, M), console.log("Avatar config being passed:", {
7586
+ url: w.url,
7587
+ body: w.body,
7588
+ avatarMood: w.avatarMood
7589
+ }), await y.current.showAvatar(w, (ne) => {
7590
+ if (ne.lengthComputable) {
7591
+ const L = Math.min(100, Math.round(ne.loaded / ne.total * 100));
7562
7592
  d(L);
7563
7593
  }
7564
7594
  }), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), X(!1), pe(!0), c(y.current);
@@ -7572,10 +7602,10 @@ const gt = Me(({
7572
7602
  console.error("Error initializing TalkingHead:", C), se(C.message || "Failed to initialize avatar"), X(!1), g(C);
7573
7603
  }
7574
7604
  }, []);
7575
- de(() => (U(), () => {
7605
+ de(() => (W(), () => {
7576
7606
  y.current && (y.current.stop(), y.current.dispose(), y.current = null);
7577
- }), [U]);
7578
- const K = T(async () => {
7607
+ }), [W]);
7608
+ const K = P(async () => {
7579
7609
  if (y.current)
7580
7610
  try {
7581
7611
  const C = y.current.audioCtx || y.current.audioContext;
@@ -7583,7 +7613,7 @@ const gt = Me(({
7583
7613
  } catch (C) {
7584
7614
  console.warn("Failed to resume audio context:", C);
7585
7615
  }
7586
- }, []), j = T(async (C, te = {}) => {
7616
+ }, []), j = P(async (C, ne = {}) => {
7587
7617
  if (!y.current || !ae) {
7588
7618
  console.warn("Avatar not ready for speaking");
7589
7619
  return;
@@ -7592,53 +7622,53 @@ const gt = Me(({
7592
7622
  console.warn("No text provided to speak");
7593
7623
  return;
7594
7624
  }
7595
- await K(), S.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;
7596
- const L = C.split(/[.!?]+/).filter((B) => B.trim().length > 0);
7597
- Z.current = L;
7598
- const F = {
7599
- lipsyncLang: te.lipsyncLang || "en",
7625
+ await K(), S.current = { remainingText: null, originalText: null, options: null }, G.current = [], E.current = { text: C, options: ne }, O.current && (clearInterval(O.current), O.current = null), le(!1), te.current = !1;
7626
+ const L = C.split(/[.!?]+/).filter((D) => D.trim().length > 0);
7627
+ G.current = L;
7628
+ const B = {
7629
+ lipsyncLang: ne.lipsyncLang || "en",
7600
7630
  onSpeechEnd: () => {
7601
- W.current && (clearInterval(W.current), W.current = null), te.onSpeechEnd && te.onSpeechEnd(), x();
7631
+ O.current && (clearInterval(O.current), O.current = null), ne.onSpeechEnd && ne.onSpeechEnd(), x();
7602
7632
  }
7603
7633
  };
7604
7634
  try {
7605
- y.current.speakText(C, F);
7606
- } catch (B) {
7607
- console.error("Error speaking text:", B), se(B.message || "Failed to speak text");
7635
+ y.current.speakText(C, B);
7636
+ } catch (D) {
7637
+ console.error("Error speaking text:", D), se(D.message || "Failed to speak text");
7608
7638
  }
7609
7639
  }, [ae, x, K]);
7610
7640
  de(() => {
7611
- ae && G && p && y.current && j(G);
7612
- }, [ae, G, p, j]);
7613
- const q = T(() => {
7641
+ ae && Z && p && y.current && j(Z);
7642
+ }, [ae, Z, p, j]);
7643
+ const q = P(() => {
7614
7644
  if (y.current)
7615
7645
  try {
7616
- const C = y.current.isSpeaking || !1, te = y.current.audioPlaylist || [], L = y.current.speechQueue || [];
7617
- if (C || te.length > 0 || L.length > 0) {
7618
- W.current && (clearInterval(W.current), W.current = null);
7619
- let F = "";
7620
- 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 = {
7621
- remainingText: F || null,
7622
- originalText: P.current?.text || null,
7623
- options: P.current?.options || null
7624
- }, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), le(!0), oe.current = !0;
7646
+ const C = y.current.isSpeaking || !1, ne = y.current.audioPlaylist || [], L = y.current.speechQueue || [];
7647
+ if (C || ne.length > 0 || L.length > 0) {
7648
+ O.current && (clearInterval(O.current), O.current = null);
7649
+ let B = "";
7650
+ L.length > 0 && (B = L.map((D) => D.text && Array.isArray(D.text) ? D.text.map((J) => J.word).join(" ") : D.text || "").join(" ")), S.current = {
7651
+ remainingText: B || null,
7652
+ originalText: E.current?.text || null,
7653
+ options: E.current?.options || null
7654
+ }, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), le(!0), te.current = !0;
7625
7655
  }
7626
7656
  } catch (C) {
7627
7657
  console.warn("Error pausing speech:", C);
7628
7658
  }
7629
- }, []), Le = T(async () => {
7659
+ }, []), Le = P(async () => {
7630
7660
  if (!(!y.current || !ee))
7631
7661
  try {
7632
- await K(), le(!1), oe.current = !1;
7633
- const C = S.current?.remainingText, te = S.current?.originalText || P.current?.text, L = S.current?.options || P.current?.options || {}, F = C || te;
7634
- F && j(F, L);
7662
+ await K(), le(!1), te.current = !1;
7663
+ const C = S.current?.remainingText, ne = S.current?.originalText || E.current?.text, L = S.current?.options || E.current?.options || {}, B = C || ne;
7664
+ B && j(B, L);
7635
7665
  } catch (C) {
7636
- console.warn("Error resuming speech:", C), le(!1), oe.current = !1;
7666
+ console.warn("Error resuming speech:", C), le(!1), te.current = !1;
7637
7667
  }
7638
- }, [ee, j, K]), we = T(() => {
7639
- y.current && (y.current.stopSpeaking(), W.current && (clearInterval(W.current), W.current = null), le(!1), oe.current = !1);
7668
+ }, [ee, j, K]), we = P(() => {
7669
+ y.current && (y.current.stopSpeaking(), O.current && (clearInterval(O.current), O.current = null), le(!1), te.current = !1);
7640
7670
  }, []);
7641
- return Ee(M, () => ({
7671
+ return Ee(H, () => ({
7642
7672
  speakText: j,
7643
7673
  pauseSpeaking: q,
7644
7674
  resumeSpeaking: Le,
@@ -7649,21 +7679,21 @@ const gt = Me(({
7649
7679
  setBodyMovement: (C) => {
7650
7680
  y.current && y.current.setBodyMovement(C);
7651
7681
  },
7652
- playAnimation: (C, te = !1) => {
7653
- y.current && y.current.playAnimation && y.current.playAnimation(C, null, 10, 0, 0.01, te);
7682
+ playAnimation: (C, ne = !1) => {
7683
+ y.current && y.current.playAnimation && y.current.playAnimation(C, null, 10, 0, 0.01, ne);
7654
7684
  },
7655
7685
  playReaction: (C) => y.current?.playReaction(C),
7656
7686
  playCelebration: () => y.current?.playCelebration(),
7657
7687
  setShowFullAvatar: (C) => {
7658
- y.current && (E.current = C, y.current.setShowFullAvatar(C));
7688
+ y.current && (T.current = C, y.current.setShowFullAvatar(C));
7659
7689
  },
7660
7690
  isReady: ae,
7661
7691
  talkingHead: y.current
7662
- })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${b}`, style: I, children: [
7692
+ })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${f}`, style: R, children: [
7663
7693
  /* @__PURE__ */ me(
7664
7694
  "div",
7665
7695
  {
7666
- ref: z,
7696
+ ref: k,
7667
7697
  className: "talking-head-viewer",
7668
7698
  style: {
7669
7699
  width: "100%",
@@ -7697,7 +7727,7 @@ const gt = Me(({
7697
7727
  });
7698
7728
  gt.displayName = "SimpleTalkingAvatar";
7699
7729
  const yt = Me(({
7700
- curriculumData: G = null,
7730
+ curriculumData: Z = null,
7701
7731
  avatarConfig: t = {},
7702
7732
  animations: e = {},
7703
7733
  onLessonStart: n = () => {
@@ -7728,12 +7758,12 @@ const yt = Me(({
7728
7758
  onQuestionAnswer: s,
7729
7759
  onCurriculumComplete: o,
7730
7760
  onCustomAction: l
7731
- }), d = N(null), g = N(null), x = N(null), b = N(null), I = N(null), D = N(null), p = N(null), M = N(G?.curriculum || {
7761
+ }), d = N(null), g = N(null), x = N(null), f = N(null), R = N(null), F = N(null), p = N(null), H = N(Z?.curriculum || {
7732
7762
  title: "Default Curriculum",
7733
7763
  description: "No curriculum data provided",
7734
7764
  language: "en",
7735
7765
  modules: []
7736
- }), z = N({
7766
+ }), k = N({
7737
7767
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7738
7768
  avatarBody: t.avatarBody || "F",
7739
7769
  mood: t.mood || "happy",
@@ -7756,12 +7786,12 @@ const yt = Me(({
7756
7786
  onCustomAction: l
7757
7787
  };
7758
7788
  }, [n, i, s, o, l]), de(() => {
7759
- M.current = G?.curriculum || {
7789
+ H.current = Z?.curriculum || {
7760
7790
  title: "Default Curriculum",
7761
7791
  description: "No curriculum data provided",
7762
7792
  language: "en",
7763
7793
  modules: []
7764
- }, z.current = {
7794
+ }, k.current = {
7765
7795
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7766
7796
  avatarBody: t.avatarBody || "F",
7767
7797
  mood: t.mood || "happy",
@@ -7775,12 +7805,12 @@ const yt = Me(({
7775
7805
  animations: e,
7776
7806
  lipsyncLang: "en"
7777
7807
  };
7778
- }, [G, t, e]);
7779
- 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(() => {
7808
+ }, [Z, t, e]);
7809
+ const y = P(() => (H.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), T = P(() => y()?.questions[a.current.currentQuestionIndex], [y]), E = P((v, I) => I.type === "multiple_choice" || I.type === "true_false" ? v === I.answer : I.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), O = P(() => {
7780
7810
  a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
7781
7811
  const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7782
- let R = "Congratulations! You've completed this lesson";
7783
- 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({
7812
+ let I = "Congratulations! You've completed this lesson";
7813
+ if (a.current.totalQuestions > 0 ? I += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : I += "! ", v >= 80 ? I += "Excellent work! You have a great understanding of this topic." : v >= 60 ? I += "Good job! You understand most of the concepts." : I += "Keep practicing! You're making progress.", c.current.onLessonComplete({
7784
7814
  moduleIndex: a.current.currentModuleIndex,
7785
7815
  lessonIndex: a.current.currentLessonIndex,
7786
7816
  score: a.current.score,
@@ -7800,8 +7830,8 @@ const yt = Me(({
7800
7830
  } catch {
7801
7831
  h.current.playCelebration();
7802
7832
  }
7803
- const k = M.current || { modules: [] }, H = k.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (k.modules?.length || 0) - 1, j = U || K, q = z.current || { lipsyncLang: "en" };
7804
- h.current.speakText(R, {
7833
+ const w = H.current || { modules: [] }, M = w.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (M?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (w.modules?.length || 0) - 1, j = W || K, q = k.current || { lipsyncLang: "en" };
7834
+ h.current.speakText(I, {
7805
7835
  lipsyncLang: q.lipsyncLang,
7806
7836
  onSpeechEnd: () => {
7807
7837
  c.current.onCustomAction({
@@ -7816,12 +7846,12 @@ const yt = Me(({
7816
7846
  }
7817
7847
  });
7818
7848
  }
7819
- }, [e.lessonComplete]), oe = T(() => {
7849
+ }, [e.lessonComplete]), te = P(() => {
7820
7850
  a.current.curriculumCompleted = !0;
7821
- const v = M.current || { modules: [] };
7851
+ const v = H.current || { modules: [] };
7822
7852
  if (c.current.onCurriculumComplete({
7823
7853
  modules: v.modules.length,
7824
- totalLessons: v.modules.reduce((R, k) => R + k.lessons.length, 0)
7854
+ totalLessons: v.modules.reduce((I, w) => I + w.lessons.length, 0)
7825
7855
  }), h.current) {
7826
7856
  if (h.current.setMood("celebrating"), e.curriculumComplete)
7827
7857
  try {
@@ -7829,99 +7859,99 @@ const yt = Me(({
7829
7859
  } catch {
7830
7860
  h.current.playCelebration();
7831
7861
  }
7832
- const R = z.current || { lipsyncLang: "en" };
7833
- h.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 });
7862
+ const I = k.current || { lipsyncLang: "en" };
7863
+ h.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: I.lipsyncLang });
7834
7864
  }
7835
- }, [e.curriculumComplete]), S = T(() => {
7865
+ }, [e.curriculumComplete]), S = P(() => {
7836
7866
  const v = y();
7837
7867
  a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
7838
- const R = E();
7839
- R && c.current.onCustomAction({
7868
+ const I = T();
7869
+ I && c.current.onCustomAction({
7840
7870
  type: "questionStart",
7841
7871
  moduleIndex: a.current.currentModuleIndex,
7842
7872
  lessonIndex: a.current.currentLessonIndex,
7843
7873
  questionIndex: a.current.currentQuestionIndex,
7844
7874
  totalQuestions: a.current.totalQuestions,
7845
- question: R,
7875
+ question: I,
7846
7876
  score: a.current.score
7847
7877
  });
7848
- const k = () => {
7849
- if (!h.current || !R) return;
7878
+ const w = () => {
7879
+ if (!h.current || !I) return;
7850
7880
  if (h.current.setMood("happy"), e.questionStart)
7851
7881
  try {
7852
7882
  h.current.playAnimation(e.questionStart, !0);
7853
- } catch (U) {
7854
- console.warn("Failed to play questionStart animation:", U);
7883
+ } catch (W) {
7884
+ console.warn("Failed to play questionStart animation:", W);
7855
7885
  }
7856
- const H = z.current || { lipsyncLang: "en" };
7857
- R.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang });
7886
+ const M = k.current || { lipsyncLang: "en" };
7887
+ I.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${I.question}`, { lipsyncLang: M.lipsyncLang }) : I.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`, { lipsyncLang: M.lipsyncLang }) : I.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${I.question}`, { lipsyncLang: M.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`, { lipsyncLang: M.lipsyncLang });
7858
7888
  };
7859
- if (h.current && h.current.isReady && R)
7860
- k();
7889
+ if (h.current && h.current.isReady && I)
7890
+ w();
7861
7891
  else if (h.current && h.current.isReady) {
7862
- const H = z.current || { lipsyncLang: "en" };
7863
- h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: H.lipsyncLang });
7892
+ const M = k.current || { lipsyncLang: "en" };
7893
+ h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: M.lipsyncLang });
7864
7894
  } else {
7865
- const H = setInterval(() => {
7866
- h.current && h.current.isReady && (clearInterval(H), R && k());
7895
+ const M = setInterval(() => {
7896
+ h.current && h.current.isReady && (clearInterval(M), I && w());
7867
7897
  }, 100);
7868
7898
  setTimeout(() => {
7869
- clearInterval(H);
7899
+ clearInterval(M);
7870
7900
  }, 5e3);
7871
7901
  }
7872
- }, [e.questionStart, y, E]), Z = T(() => {
7902
+ }, [e.questionStart, y, T]), G = P(() => {
7873
7903
  const v = y();
7874
7904
  if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
7875
7905
  h.current && h.current.stopSpeaking && h.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
7876
- const R = E();
7877
- R && c.current.onCustomAction({
7906
+ const I = T();
7907
+ I && c.current.onCustomAction({
7878
7908
  type: "nextQuestion",
7879
7909
  moduleIndex: a.current.currentModuleIndex,
7880
7910
  lessonIndex: a.current.currentLessonIndex,
7881
7911
  questionIndex: a.current.currentQuestionIndex,
7882
7912
  totalQuestions: a.current.totalQuestions,
7883
- question: R,
7913
+ question: I,
7884
7914
  score: a.current.score
7885
7915
  });
7886
- const k = () => {
7887
- if (!h.current || !R) return;
7916
+ const w = () => {
7917
+ if (!h.current || !I) return;
7888
7918
  if (h.current.setMood("happy"), h.current.setBodyMovement("idle"), e.nextQuestion)
7889
7919
  try {
7890
7920
  h.current.playAnimation(e.nextQuestion, !0);
7891
7921
  } catch (q) {
7892
7922
  console.warn("Failed to play nextQuestion animation:", q);
7893
7923
  }
7894
- const H = z.current || { lipsyncLang: "en" }, K = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= K - 1;
7895
- if (R.type === "code_test") {
7896
- 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}`;
7924
+ const M = k.current || { lipsyncLang: "en" }, K = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= K - 1;
7925
+ if (I.type === "code_test") {
7926
+ const q = j ? `Great! Here's your final coding challenge: ${I.question}` : `Great! Now let's move on to your next coding challenge: ${I.question}`;
7897
7927
  h.current.speakText(q, {
7898
- lipsyncLang: H.lipsyncLang
7928
+ lipsyncLang: M.lipsyncLang
7899
7929
  });
7900
- } else if (R.type === "multiple_choice") {
7901
- const q = j ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
7930
+ } else if (I.type === "multiple_choice") {
7931
+ const q = j ? `Alright! Here's your final question: ${I.question}` : `Alright! Here's your next question: ${I.question}`;
7902
7932
  h.current.speakText(q, {
7903
- lipsyncLang: H.lipsyncLang
7933
+ lipsyncLang: M.lipsyncLang
7904
7934
  });
7905
- } else if (R.type === "true_false") {
7906
- const q = j ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
7935
+ } else if (I.type === "true_false") {
7936
+ const q = j ? `Now let's try this final one: ${I.question}` : `Now let's try this one: ${I.question}`;
7907
7937
  h.current.speakText(q, {
7908
- lipsyncLang: H.lipsyncLang
7938
+ lipsyncLang: M.lipsyncLang
7909
7939
  });
7910
7940
  } else {
7911
- const q = j ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
7941
+ const q = j ? `Here's your final question: ${I.question}` : `Here's the next question: ${I.question}`;
7912
7942
  h.current.speakText(q, {
7913
- lipsyncLang: H.lipsyncLang
7943
+ lipsyncLang: M.lipsyncLang
7914
7944
  });
7915
7945
  }
7916
7946
  };
7917
- if (h.current && h.current.isReady && R)
7918
- k();
7919
- else if (R) {
7920
- const H = setInterval(() => {
7921
- h.current && h.current.isReady && (clearInterval(H), k());
7947
+ if (h.current && h.current.isReady && I)
7948
+ w();
7949
+ else if (I) {
7950
+ const M = setInterval(() => {
7951
+ h.current && h.current.isReady && (clearInterval(M), w());
7922
7952
  }, 100);
7923
7953
  setTimeout(() => {
7924
- clearInterval(H);
7954
+ clearInterval(M);
7925
7955
  }, 5e3);
7926
7956
  }
7927
7957
  } else
@@ -7932,11 +7962,11 @@ const yt = Me(({
7932
7962
  totalQuestions: a.current.totalQuestions,
7933
7963
  score: a.current.score
7934
7964
  });
7935
- }, [e.nextQuestion, y, E]), _ = T(() => {
7936
- const v = M.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
7937
- if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
7965
+ }, [e.nextQuestion, y, T]), _ = P(() => {
7966
+ const v = H.current || { modules: [] }, I = v.modules[a.current.currentModuleIndex];
7967
+ if (a.current.currentLessonIndex < (I?.lessons?.length || 0) - 1) {
7938
7968
  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;
7939
- const H = v.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = U || K;
7969
+ const M = v.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (M?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = W || K;
7940
7970
  c.current.onCustomAction({
7941
7971
  type: "lessonStart",
7942
7972
  moduleIndex: a.current.currentModuleIndex,
@@ -7949,7 +7979,7 @@ const yt = Me(({
7949
7979
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7950
7980
  } else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
7951
7981
  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;
7952
- const U = v.modules[a.current.currentModuleIndex], K = a.current.currentLessonIndex < (U?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = K || j;
7982
+ const W = v.modules[a.current.currentModuleIndex], K = a.current.currentLessonIndex < (W?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = K || j;
7953
7983
  c.current.onCustomAction({
7954
7984
  type: "lessonStart",
7955
7985
  moduleIndex: a.current.currentModuleIndex,
@@ -7961,26 +7991,26 @@ const yt = Me(({
7961
7991
  lesson: y()
7962
7992
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7963
7993
  } else
7964
- I.current && I.current();
7965
- }, []), X = T(() => {
7994
+ R.current && R.current();
7995
+ }, []), X = P(() => {
7966
7996
  const v = y();
7967
- let R = null;
7997
+ let I = null;
7968
7998
  if (v?.avatar_script && v?.body) {
7969
- const k = v.avatar_script.trim(), H = v.body.trim(), U = k.match(/[.!?]$/) ? " " : ". ";
7970
- R = `${k}${U}${H}`;
7999
+ const w = v.avatar_script.trim(), M = v.body.trim(), W = w.match(/[.!?]$/) ? " " : ". ";
8000
+ I = `${w}${W}${M}`;
7971
8001
  } else
7972
- R = v?.avatar_script || v?.body || null;
7973
- if (h.current && h.current.isReady && R) {
8002
+ I = v?.avatar_script || v?.body || null;
8003
+ if (h.current && h.current.isReady && I) {
7974
8004
  a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, h.current.setMood("happy");
7975
- let k = !1;
8005
+ let w = !1;
7976
8006
  if (e.teaching)
7977
8007
  try {
7978
- h.current.playAnimation(e.teaching, !0), k = !0;
7979
- } catch (U) {
7980
- console.warn("Failed to play teaching animation:", U);
8008
+ h.current.playAnimation(e.teaching, !0), w = !0;
8009
+ } catch (W) {
8010
+ console.warn("Failed to play teaching animation:", W);
7981
8011
  }
7982
- k || h.current.setBodyMovement("gesturing");
7983
- const H = z.current || { lipsyncLang: "en" };
8012
+ w || h.current.setBodyMovement("gesturing");
8013
+ const M = k.current || { lipsyncLang: "en" };
7984
8014
  c.current.onLessonStart({
7985
8015
  moduleIndex: a.current.currentModuleIndex,
7986
8016
  lessonIndex: a.current.currentLessonIndex,
@@ -7990,8 +8020,8 @@ const yt = Me(({
7990
8020
  moduleIndex: a.current.currentModuleIndex,
7991
8021
  lessonIndex: a.current.currentLessonIndex,
7992
8022
  lesson: v
7993
- }), h.current.speakText(R, {
7994
- lipsyncLang: H.lipsyncLang,
8023
+ }), h.current.speakText(I, {
8024
+ lipsyncLang: M.lipsyncLang,
7995
8025
  onSpeechEnd: () => {
7996
8026
  a.current.isTeaching = !1, c.current.onCustomAction({
7997
8027
  type: "teachingComplete",
@@ -8009,17 +8039,17 @@ const yt = Me(({
8009
8039
  }
8010
8040
  });
8011
8041
  }
8012
- }, [e.teaching, y]), $ = T((v) => {
8013
- const R = E(), k = P(v, R);
8014
- if (k && (a.current.score += 1), c.current.onQuestionAnswer({
8042
+ }, [e.teaching, y]), $ = P((v) => {
8043
+ const I = T(), w = E(v, I);
8044
+ if (w && (a.current.score += 1), c.current.onQuestionAnswer({
8015
8045
  moduleIndex: a.current.currentModuleIndex,
8016
8046
  lessonIndex: a.current.currentLessonIndex,
8017
8047
  questionIndex: a.current.currentQuestionIndex,
8018
8048
  answer: v,
8019
- isCorrect: k,
8020
- question: R
8049
+ isCorrect: w,
8050
+ question: I
8021
8051
  }), h.current)
8022
- if (k) {
8052
+ if (w) {
8023
8053
  if (h.current.setMood("happy"), e.correct)
8024
8054
  try {
8025
8055
  h.current.playReaction("happy");
@@ -8027,11 +8057,11 @@ const yt = Me(({
8027
8057
  h.current.setBodyMovement("happy");
8028
8058
  }
8029
8059
  h.current.setBodyMovement("gesturing");
8030
- const U = y()?.questions?.length || 0;
8031
- a.current.currentQuestionIndex >= U - 1;
8032
- const K = a.current.currentQuestionIndex < U - 1;
8033
- console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", K);
8034
- 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" };
8060
+ const W = y()?.questions?.length || 0;
8061
+ a.current.currentQuestionIndex >= W - 1;
8062
+ const K = a.current.currentQuestionIndex < W - 1;
8063
+ console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", K);
8064
+ const j = I.type === "code_test" ? `Great job! Your code passed all the tests! ${I.explanation || ""}` : `Excellent! That's correct! ${I.explanation || ""}`, q = k.current || { lipsyncLang: "en" };
8035
8065
  h.current.speakText(j, {
8036
8066
  lipsyncLang: q.lipsyncLang,
8037
8067
  onSpeechEnd: () => {
@@ -8055,9 +8085,9 @@ const yt = Me(({
8055
8085
  h.current.setBodyMovement("idle");
8056
8086
  }
8057
8087
  h.current.setBodyMovement("gesturing");
8058
- const U = y()?.questions?.length || 0, K = a.current.currentQuestionIndex >= U - 1, j = a.current.currentQuestionIndex < U - 1;
8059
- console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", j);
8060
- 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 || ""}${K ? "" : " Let's move on to the next question."}`, Le = z.current || { lipsyncLang: "en" };
8088
+ const W = y()?.questions?.length || 0, K = a.current.currentQuestionIndex >= W - 1, j = a.current.currentQuestionIndex < W - 1;
8089
+ console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", j);
8090
+ const q = I.type === "code_test" ? `Your code didn't pass all the tests. ${I.explanation || "Try again!"}` : `Not quite right, but don't worry! ${I.explanation || ""}${K ? "" : " Let's move on to the next question."}`, Le = k.current || { lipsyncLang: "en" };
8061
8091
  h.current.speakText(q, {
8062
8092
  lipsyncLang: Le.lipsyncLang,
8063
8093
  onSpeechEnd: () => {
@@ -8075,30 +8105,30 @@ const yt = Me(({
8075
8105
  });
8076
8106
  }
8077
8107
  else {
8078
- const U = y()?.questions?.length || 0;
8108
+ const W = y()?.questions?.length || 0;
8079
8109
  c.current.onCustomAction({
8080
8110
  type: "answerFeedbackComplete",
8081
8111
  moduleIndex: a.current.currentModuleIndex,
8082
8112
  lessonIndex: a.current.currentLessonIndex,
8083
8113
  questionIndex: a.current.currentQuestionIndex,
8084
- isCorrect: k,
8085
- hasNextQuestion: a.current.currentQuestionIndex < U - 1,
8114
+ isCorrect: w,
8115
+ hasNextQuestion: a.current.currentQuestionIndex < W - 1,
8086
8116
  score: a.current.score,
8087
8117
  totalQuestions: a.current.totalQuestions,
8088
8118
  avatarNotReady: !0
8089
8119
  });
8090
8120
  }
8091
- }, [e.correct, e.incorrect, E, y, P]), se = T((v) => {
8092
- const R = E();
8121
+ }, [e.correct, e.incorrect, T, y, E]), se = P((v) => {
8122
+ const I = T();
8093
8123
  if (!v || typeof v != "object") {
8094
8124
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
8095
8125
  return;
8096
8126
  }
8097
- if (R?.type !== "code_test") {
8127
+ if (I?.type !== "code_test") {
8098
8128
  console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
8099
8129
  return;
8100
8130
  }
8101
- const k = {
8131
+ const w = {
8102
8132
  passed: v.passed === !0,
8103
8133
  results: v.results || [],
8104
8134
  output: v.output || "",
@@ -8113,13 +8143,13 @@ const yt = Me(({
8113
8143
  moduleIndex: a.current.currentModuleIndex,
8114
8144
  lessonIndex: a.current.currentLessonIndex,
8115
8145
  questionIndex: a.current.currentQuestionIndex,
8116
- testResult: k,
8117
- question: R
8118
- }), p.current && p.current(k);
8119
- }, [E, P]), ae = T(() => {
8146
+ testResult: w,
8147
+ question: I
8148
+ }), p.current && p.current(w);
8149
+ }, [T, E]), ae = P(() => {
8120
8150
  if (a.current.currentQuestionIndex > 0) {
8121
8151
  a.current.currentQuestionIndex -= 1;
8122
- const v = E();
8152
+ const v = T();
8123
8153
  v && c.current.onCustomAction({
8124
8154
  type: "questionStart",
8125
8155
  moduleIndex: a.current.currentModuleIndex,
@@ -8129,29 +8159,29 @@ const yt = Me(({
8129
8159
  question: v,
8130
8160
  score: a.current.score
8131
8161
  });
8132
- const R = () => {
8162
+ const I = () => {
8133
8163
  if (!h.current || !v) return;
8134
8164
  h.current.setMood("happy"), h.current.setBodyMovement("idle");
8135
- const k = z.current || { lipsyncLang: "en" };
8165
+ const w = k.current || { lipsyncLang: "en" };
8136
8166
  v.type === "code_test" ? h.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
8137
- lipsyncLang: k.lipsyncLang
8167
+ lipsyncLang: w.lipsyncLang
8138
8168
  }) : h.current.speakText(`Going back to: ${v.question}`, {
8139
- lipsyncLang: k.lipsyncLang
8169
+ lipsyncLang: w.lipsyncLang
8140
8170
  });
8141
8171
  };
8142
8172
  if (h.current && h.current.isReady && v)
8143
- R();
8173
+ I();
8144
8174
  else if (v) {
8145
- const k = setInterval(() => {
8146
- h.current && h.current.isReady && (clearInterval(k), R());
8175
+ const w = setInterval(() => {
8176
+ h.current && h.current.isReady && (clearInterval(w), I());
8147
8177
  }, 100);
8148
8178
  setTimeout(() => {
8149
- clearInterval(k);
8179
+ clearInterval(w);
8150
8180
  }, 5e3);
8151
8181
  }
8152
8182
  }
8153
- }, [E]), pe = T(() => {
8154
- const v = M.current || { modules: [] };
8183
+ }, [T]), pe = P(() => {
8184
+ const v = H.current || { modules: [] };
8155
8185
  if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
8156
8186
  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({
8157
8187
  type: "lessonStart",
@@ -8163,8 +8193,8 @@ const yt = Me(({
8163
8193
  lesson: y()
8164
8194
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
8165
8195
  else if (a.current.currentModuleIndex > 0) {
8166
- const H = v.modules[a.current.currentModuleIndex - 1];
8167
- 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({
8196
+ const M = v.modules[a.current.currentModuleIndex - 1];
8197
+ a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (M?.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({
8168
8198
  type: "lessonStart",
8169
8199
  moduleIndex: a.current.currentModuleIndex,
8170
8200
  lessonIndex: a.current.currentLessonIndex
@@ -8174,52 +8204,52 @@ const yt = Me(({
8174
8204
  lesson: y()
8175
8205
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
8176
8206
  }
8177
- }, [y]), ee = T(() => {
8207
+ }, [y]), ee = P(() => {
8178
8208
  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;
8179
- }, []), le = T((v) => {
8209
+ }, []), le = P((v) => {
8180
8210
  console.log("Avatar is ready!", v);
8181
- const R = y(), k = R?.avatar_script || R?.body;
8182
- u && k && setTimeout(() => {
8211
+ const I = y(), w = I?.avatar_script || I?.body;
8212
+ u && w && setTimeout(() => {
8183
8213
  d.current && d.current();
8184
8214
  }, 10);
8185
8215
  }, [u, y]);
8186
8216
  Xe(() => {
8187
- d.current = X, g.current = _, x.current = W, b.current = Z, I.current = oe, D.current = S, p.current = $;
8217
+ d.current = X, g.current = _, x.current = O, f.current = G, R.current = te, F.current = S, p.current = $;
8188
8218
  }), Ee(r, () => ({
8189
8219
  // Curriculum control methods
8190
8220
  startTeaching: X,
8191
8221
  startQuestions: S,
8192
8222
  handleAnswerSelect: $,
8193
8223
  handleCodeTestResult: se,
8194
- nextQuestion: Z,
8224
+ nextQuestion: G,
8195
8225
  previousQuestion: ae,
8196
8226
  nextLesson: _,
8197
8227
  previousLesson: pe,
8198
- completeLesson: W,
8199
- completeCurriculum: oe,
8228
+ completeLesson: O,
8229
+ completeCurriculum: te,
8200
8230
  resetCurriculum: ee,
8201
8231
  getState: () => ({ ...a.current }),
8202
- getCurrentQuestion: () => E(),
8232
+ getCurrentQuestion: () => T(),
8203
8233
  getCurrentLesson: () => y(),
8204
8234
  // Direct access to avatar ref (always returns current value)
8205
8235
  getAvatarRef: () => h.current,
8206
8236
  // Convenience methods that delegate to avatar (always check current ref)
8207
- speakText: async (v, R = {}) => {
8237
+ speakText: async (v, I = {}) => {
8208
8238
  await h.current?.resumeAudioContext?.();
8209
- const k = z.current || { lipsyncLang: "en" };
8210
- h.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || k.lipsyncLang });
8239
+ const w = k.current || { lipsyncLang: "en" };
8240
+ h.current?.speakText(v, { ...I, lipsyncLang: I.lipsyncLang || w.lipsyncLang });
8211
8241
  },
8212
8242
  resumeAudioContext: async () => {
8213
8243
  if (h.current?.resumeAudioContext)
8214
8244
  return await h.current.resumeAudioContext();
8215
8245
  const v = h.current?.talkingHead;
8216
8246
  if (v?.audioCtx) {
8217
- const R = v.audioCtx;
8218
- if (R.state === "suspended" || R.state === "interrupted")
8247
+ const I = v.audioCtx;
8248
+ if (I.state === "suspended" || I.state === "interrupted")
8219
8249
  try {
8220
- await R.resume(), console.log("Audio context resumed via talkingHead");
8221
- } catch (k) {
8222
- console.warn("Failed to resume audio context:", k);
8250
+ await I.resume(), console.log("Audio context resumed via talkingHead");
8251
+ } catch (w) {
8252
+ console.warn("Failed to resume audio context:", w);
8223
8253
  }
8224
8254
  } else
8225
8255
  console.warn("Audio context not available yet");
@@ -8229,7 +8259,7 @@ const yt = Me(({
8229
8259
  resumeSpeaking: async () => await h.current?.resumeSpeaking(),
8230
8260
  isPaused: () => h.current && typeof h.current.isPaused < "u" ? h.current.isPaused : !1,
8231
8261
  setMood: (v) => h.current?.setMood(v),
8232
- playAnimation: (v, R) => h.current?.playAnimation(v, R),
8262
+ playAnimation: (v, I) => h.current?.playAnimation(v, I),
8233
8263
  setBodyMovement: (v) => h.current?.setBodyMovement(v),
8234
8264
  setMovementIntensity: (v) => h.current?.setMovementIntensity(v),
8235
8265
  playRandomDance: () => h.current?.playRandomDance(),
@@ -8240,10 +8270,10 @@ const yt = Me(({
8240
8270
  lockAvatarPosition: () => h.current?.lockAvatarPosition(),
8241
8271
  unlockAvatarPosition: () => h.current?.unlockAvatarPosition(),
8242
8272
  // Custom action trigger
8243
- triggerCustomAction: (v, R) => {
8273
+ triggerCustomAction: (v, I) => {
8244
8274
  c.current.onCustomAction({
8245
8275
  type: v,
8246
- ...R,
8276
+ ...I,
8247
8277
  state: { ...a.current }
8248
8278
  });
8249
8279
  },
@@ -8251,8 +8281,8 @@ const yt = Me(({
8251
8281
  handleResize: () => h.current?.handleResize(),
8252
8282
  // Avatar readiness check (always returns current value)
8253
8283
  isAvatarReady: () => h.current?.isReady || !1
8254
- }), [X, S, $, se, Z, _, W, oe, ee, E, y]);
8255
- const O = z.current || {
8284
+ }), [X, S, $, se, G, _, O, te, ee, T, y]);
8285
+ const U = k.current || {
8256
8286
  avatarUrl: "/avatars/brunette.glb",
8257
8287
  avatarBody: "F",
8258
8288
  mood: "happy",
@@ -8269,18 +8299,18 @@ const yt = Me(({
8269
8299
  Ve,
8270
8300
  {
8271
8301
  ref: h,
8272
- avatarUrl: O.avatarUrl,
8273
- avatarBody: O.avatarBody,
8274
- mood: O.mood,
8275
- ttsLang: O.ttsLang,
8276
- ttsService: O.ttsService,
8277
- ttsVoice: O.ttsVoice,
8278
- ttsApiKey: O.ttsApiKey,
8279
- bodyMovement: O.bodyMovement,
8280
- movementIntensity: O.movementIntensity,
8281
- showFullAvatar: O.showFullAvatar,
8302
+ avatarUrl: U.avatarUrl,
8303
+ avatarBody: U.avatarBody,
8304
+ mood: U.mood,
8305
+ ttsLang: U.ttsLang,
8306
+ ttsService: U.ttsService,
8307
+ ttsVoice: U.ttsVoice,
8308
+ ttsApiKey: U.ttsApiKey,
8309
+ bodyMovement: U.bodyMovement,
8310
+ movementIntensity: U.movementIntensity,
8311
+ showFullAvatar: U.showFullAvatar,
8282
8312
  cameraView: "upper",
8283
- animations: O.animations,
8313
+ animations: U.animations,
8284
8314
  onReady: le,
8285
8315
  onLoading: () => {
8286
8316
  },
@@ -8394,7 +8424,7 @@ const Ge = {
8394
8424
  duration: 5e3,
8395
8425
  description: "Excited, energetic movement"
8396
8426
  }
8397
- }, wt = (G) => Ge[G] || null, zt = (G) => Ge.hasOwnProperty(G);
8427
+ }, wt = (Z) => Ge[Z] || null, zt = (Z) => Ge.hasOwnProperty(Z);
8398
8428
  export {
8399
8429
  yt as CurriculumLearning,
8400
8430
  gt as SimpleTalkingAvatar,