@sage-rsc/talking-head-react 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,20 +1,20 @@
1
- import { jsxs as Pe, jsx as me } from "react/jsx-runtime";
2
- import { forwardRef as Me, useRef as O, useState as ce, useEffect as de, useCallback as B, useImperativeHandle as Fe, useLayoutEffect as Xe } from "react";
3
- import * as f from "three";
1
+ import { jsxs as Pe, jsx as ye } from "react/jsx-runtime";
2
+ import { forwardRef as Me, useRef as W, useState as pe, useEffect as ce, useCallback as N, useImperativeHandle as Fe, useLayoutEffect as Xe } from "react";
3
+ import * as y from "three";
4
4
  import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
5
5
  import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
6
6
  import { DRACOLoader as Qe } from "three/addons/loaders/DRACOLoader.js";
7
7
  import { FBXLoader as De } 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
- let m, re, ue;
11
- const w = [0, 0, 0, 0], T = new f.Vector3(), ze = new f.Vector3(), ie = new f.Vector3(), Ce = new f.Vector3();
12
- new f.Plane();
13
- new f.Ray();
14
- new f.Euler();
15
- const oe = 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);
10
+ let m, ue, he;
11
+ const C = [0, 0, 0, 0], T = new y.Vector3(), ze = new y.Vector3(), ae = new y.Vector3(), Ce = new y.Vector3();
12
+ new y.Plane();
13
+ new y.Ray();
14
+ new y.Euler();
15
+ const re = new y.Quaternion(), Oe = new y.Quaternion(), fe = new y.Matrix4(), xe = new y.Matrix4();
16
+ new y.Vector3();
17
+ const He = new y.Vector3(0, 0, 1), Ke = new y.Vector3(1, 0, 0), Je = new y.Vector3(0, 1, 0), $e = new y.Vector3(0, 0, 1);
18
18
  class et {
19
19
  constructor(t = null) {
20
20
  this.opt = Object.assign({
@@ -338,7 +338,7 @@ class et {
338
338
  ea: [0, 0, 0, 0]
339
339
  // External acceleration [m/s^2]
340
340
  };
341
- u.boneParent.matrixWorld.decompose(T, oe, ie), T.copy(He).applyQuaternion(oe).setY(0).normalize(), oe.premultiply(Oe.setFromUnitVectors(He, T).invert()).normalize(), u.qWorldInverseYaw = oe.clone().normalize(), this.data.push(u), this.dict[h] = u;
341
+ u.boneParent.matrixWorld.decompose(T, re, ae), T.copy(He).applyQuaternion(re).setY(0).normalize(), re.premultiply(Oe.setFromUnitVectors(He, T).invert()).normalize(), u.qWorldInverseYaw = re.clone().normalize(), this.data.push(u), this.dict[h] = u;
342
342
  try {
343
343
  this.setValue(h, "type", s.type), this.setValue(h, "stiffness", s.stiffness), this.setValue(h, "damping", s.damping), this.setValue(h, "external", s.external), this.setValue(h, "limits", s.limits), this.setValue(h, "excludes", s.excludes), this.setValue(h, "deltaLocal", s.deltaLocal), this.setValue(h, "deltaWorld", s.deltaWorld), this.setValue(h, "pivot", s.pivot), this.setValue(h, "helper", s.helper);
344
344
  } catch (a) {
@@ -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], T.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), T.applyMatrix4(xe), T.length() > 0.5 && (console.info("Info: Unrealistic jump of " + T.length().toFixed(2) + " meters."), T.setLength(0.5)), T.applyQuaternion(o.bone.quaternion), w[0] = T.x, w[1] = T.y, w[2] = -T.z, w[3] = T.length() / 3, o.children)
359
+ if (o = this.data[e], T.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), T.applyMatrix4(xe), T.length() > 0.5 && (console.info("Info: Unrealistic jump of " + T.length().toFixed(2) + " meters."), T.setLength(0.5)), T.applyQuaternion(o.bone.quaternion), C[0] = T.x, C[1] = T.y, C[2] = -T.z, C[3] = T.length() / 3, o.children)
360
360
  for (n = 0, s = o.children.length; n < s; n++)
361
- m = o.children[n], w[0] -= m.v[0] * t / 3, w[1] -= m.v[1] * t / 3, w[2] += m.v[2] * t / 3, w[3] -= m.v[3] * t / 3;
362
- if (m = this.opt.sensitivityFactor, w[0] *= o.ext * m, w[1] *= o.ext * m, w[2] *= o.ext * m, w[3] *= o.ext * m, o.isX && (m = w[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 + w[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 = w[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 + w[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 = w[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 + w[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 = w[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 + w[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), w[0] = o.p[0], w[1] = o.p[1], w[2] = o.p[2], w[3] = o.p[3], m = this.opt.movementFactor, w[0] *= m, w[1] *= m, w[2] *= m, w[3] *= m, o.dl && (m = o.dl, w[0] += m[0], w[1] += m[1], w[2] += m[2]), o.dw && (m = o.dw, T.set(
363
- o.vBasis.x + w[0],
364
- o.vBasis.y + w[1],
365
- o.vBasis.z + w[2]
366
- ), T.applyMatrix4(fe), T.x += m[0], T.y += m[1], T.z += m[2], T.applyMatrix4(xe), w[0] += T.x - o.vBasis.x, w[1] += T.y - o.vBasis.y, w[2] += T.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && w[0] < m[0][0] && (w[0] = m[0][0]), m[0][1] !== null && w[0] > m[0][1] && (w[0] = m[0][1])), m[1] && (m[1][0] !== null && w[1] < m[1][0] && (w[1] = m[1][0]), m[1][1] !== null && w[1] > m[1][1] && (w[1] = m[1][1])), m[2] && (m[2][0] !== null && w[2] < m[2][0] && (w[2] = m[2][0]), m[2][1] !== null && w[2] > m[2][1] && (w[2] = m[2][1])), m[3] && (m[3][0] !== null && w[3] < m[3][0] && (w[3] = m[3][0]), m[3][1] !== null && w[3] > m[3][1] && (w[3] = m[3][1]))), o.isPoint)
361
+ m = o.children[n], C[0] -= m.v[0] * t / 3, C[1] -= m.v[1] * t / 3, C[2] += m.v[2] * t / 3, C[3] -= m.v[3] * t / 3;
362
+ if (m = this.opt.sensitivityFactor, C[0] *= o.ext * m, C[1] *= o.ext * m, C[2] *= o.ext * m, C[3] *= o.ext * m, o.isX && (m = C[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 + C[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 = C[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 + C[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 = C[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 + C[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 = C[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 + C[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), C[0] = o.p[0], C[1] = o.p[1], C[2] = o.p[2], C[3] = o.p[3], m = this.opt.movementFactor, C[0] *= m, C[1] *= m, C[2] *= m, C[3] *= m, o.dl && (m = o.dl, C[0] += m[0], C[1] += m[1], C[2] += m[2]), o.dw && (m = o.dw, T.set(
363
+ o.vBasis.x + C[0],
364
+ o.vBasis.y + C[1],
365
+ o.vBasis.z + C[2]
366
+ ), T.applyMatrix4(fe), T.x += m[0], T.y += m[1], T.z += m[2], T.applyMatrix4(xe), C[0] += T.x - o.vBasis.x, C[1] += T.y - o.vBasis.y, C[2] += T.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && C[0] < m[0][0] && (C[0] = m[0][0]), m[0][1] !== null && C[0] > m[0][1] && (C[0] = m[0][1])), m[1] && (m[1][0] !== null && C[1] < m[1][0] && (C[1] = m[1][0]), m[1][1] !== null && C[1] > m[1][1] && (C[1] = m[1][1])), m[2] && (m[2][0] !== null && C[2] < m[2][0] && (C[2] = m[2][0]), m[2][1] !== null && C[2] > m[2][1] && (C[2] = m[2][1])), m[3] && (m[3][0] !== null && C[3] < m[3][0] && (C[3] = m[3][0]), m[3][1] !== null && C[3] > m[3][1] && (C[3] = m[3][1]))), o.isPoint)
367
367
  o.bone.position.set(
368
- o.vBasis.x + w[0],
369
- o.vBasis.y + w[1],
370
- o.vBasis.z - w[2]
368
+ o.vBasis.x + C[0],
369
+ o.vBasis.y + C[1],
370
+ o.vBasis.z - C[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(T, oe, ie), T.copy(He).applyQuaternion(oe).setY(0).normalize(), oe.premultiply(Oe.setFromUnitVectors(He, T).invert()).normalize(), o.boneParent.quaternion.multiply(oe.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(w[0] / o.l), oe.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(oe)), o.isY && (m = o.l / 3, m = m * Math.tanh(w[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(w[2] / o.l), oe.setFromAxisAngle(Ke, -m), o.boneParent.quaternion.multiply(oe)), o.isT && (m = 1.5 * Math.tanh(w[3] * 1.5), oe.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(oe)), 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(T, re, ae), T.copy(He).applyQuaternion(re).setY(0).normalize(), re.premultiply(Oe.setFromUnitVectors(He, T).invert()).normalize(), o.boneParent.quaternion.multiply(re.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(C[0] / o.l), re.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(re)), o.isY && (m = o.l / 3, m = m * Math.tanh(C[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(C[2] / o.l), re.setFromAxisAngle(Ke, -m), o.boneParent.quaternion.multiply(re)), o.isT && (m = 1.5 * Math.tanh(C[3] * 1.5), re.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(re)), 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], 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), T.copy(o.bone.position), !(T.distanceToSquared(ie) >= m.radiusSq) && (ue = T.length(), re = ie.length(), !(re > m.radius + ue) && (re < Math.abs(m.radius - ue) || (re = (re * re + ue * ue - m.radiusSq) / (2 * re), ie.normalize(), Ce.copy(ie).multiplyScalar(re), re = Math.sqrt(ue * ue - re * re), T.subVectors(T, Ce).projectOnPlane(ie).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ie).normalize(), ue = ze.dot(T), ue < 0 && (ue = Math.sqrt(re * re - ue * ue), ze.multiplyScalar(ue), T.add(ze)), T.add(Ce).normalize(), ie.copy(o.bone.position).normalize(), oe.setFromUnitVectors(ie, T), o.boneParent.quaternion.premultiply(oe), o.boneParent.updateWorldMatrix(!1, !0))));
374
+ m = o.excludes[n], ae.set(0, 0, 0), m.deltaLocal && (ae.x += m.deltaLocal[0], ae.y += m.deltaLocal[1], ae.z += m.deltaLocal[2]), ae.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ae.applyMatrix4(xe), T.copy(o.bone.position), !(T.distanceToSquared(ae) >= m.radiusSq) && (he = T.length(), ue = ae.length(), !(ue > m.radius + he) && (ue < Math.abs(m.radius - he) || (ue = (ue * ue + he * he - m.radiusSq) / (2 * ue), ae.normalize(), Ce.copy(ae).multiplyScalar(ue), ue = Math.sqrt(he * he - ue * ue), T.subVectors(T, Ce).projectOnPlane(ae).normalize().multiplyScalar(ue), ze.subVectors(o.vBasis, Ce).projectOnPlane(ae).normalize(), he = ze.dot(T), he < 0 && (he = Math.sqrt(ue * ue - he * he), ze.multiplyScalar(he), T.add(ze)), T.add(Ce).normalize(), ae.copy(o.bone.position).normalize(), re.setFromUnitVectors(ae, T), o.boneParent.quaternion.premultiply(re), 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 y.SphereGeometry(m.radii[n], 6, 6), s = new y.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 y.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((h) => [0, 0, 0]).flat();
412
- e.setAttribute("position", new f.Float32BufferAttribute(n, 3));
413
- const i = new f.Color(this.opt.helperBoneColor1), s = new f.Color(this.opt.helperBoneColor2), o = m.pivots.map((h) => h && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
414
- e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
415
- const l = new f.PointsMaterial({
411
+ const e = new y.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0]).flat();
412
+ e.setAttribute("position", new y.Float32BufferAttribute(n, 3));
413
+ const i = new y.Color(this.opt.helperBoneColor1), s = new y.Color(this.opt.helperBoneColor2), o = m.pivots.map((h) => h && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
414
+ e.setAttribute("color", new y.Float32BufferAttribute(o, 3));
415
+ const l = new y.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 y.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((h) => [0, 0, 0, 0, 0, 0]).flat();
427
- e.setAttribute("position", new f.Float32BufferAttribute(n, 3));
428
- const i = new f.Color(this.opt.helperLinkColor1), s = new f.Color(this.opt.helperLinkColor2), o = m.bones.map((h) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
429
- e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
430
- const l = new f.LineBasicMaterial({
426
+ const e = new y.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0, 0, 0, 0]).flat();
427
+ e.setAttribute("position", new y.Float32BufferAttribute(n, 3));
428
+ const i = new y.Color(this.opt.helperLinkColor1), s = new y.Color(this.opt.helperLinkColor2), o = m.bones.map((h) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
429
+ e.setAttribute("color", new y.Float32BufferAttribute(o, 3));
430
+ const l = new y.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 y.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
  /**
@@ -606,10 +606,10 @@ class tt {
606
606
  for (let h = 0; h < e; h += i) {
607
607
  let r = 1, u = 0;
608
608
  for (let a = 0; a < i / 2; a++) {
609
- const d = n[(h + a) * 2], c = n[(h + a) * 2 + 1], g = n[(h + a + i / 2) * 2] * r - n[(h + a + i / 2) * 2 + 1] * u, b = n[(h + a + i / 2) * 2] * u + n[(h + a + i / 2) * 2 + 1] * r;
610
- n[(h + a) * 2] = d + g, n[(h + a) * 2 + 1] = c + b, n[(h + a + i / 2) * 2] = d - g, n[(h + a + i / 2) * 2 + 1] = c - b;
611
- const x = r * o - u * l, S = r * l + u * o;
612
- r = x, u = S;
609
+ const d = n[(h + a) * 2], c = n[(h + a) * 2 + 1], g = n[(h + a + i / 2) * 2] * r - n[(h + a + i / 2) * 2 + 1] * u, x = n[(h + a + i / 2) * 2] * u + n[(h + a + i / 2) * 2 + 1] * r;
610
+ n[(h + a) * 2] = d + g, n[(h + a) * 2 + 1] = c + x, n[(h + a + i / 2) * 2] = d - g, n[(h + a + i / 2) * 2 + 1] = c - x;
611
+ const f = r * o - u * l, k = r * l + u * o;
612
+ r = f, u = k;
613
613
  }
614
614
  }
615
615
  }
@@ -2629,14 +2629,14 @@ const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2629
2629
  fr: rt,
2630
2630
  fi: ut,
2631
2631
  lt: ct
2632
- }, _ = new f.Quaternion(), Z = 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);
2632
+ }, J = new y.Quaternion(), G = new y.Euler(), ve = new y.Vector3(), Re = new y.Vector3(), We = new y.Box3();
2633
+ new y.Matrix4();
2634
+ new y.Matrix4();
2635
+ new y.Vector3();
2636
+ new y.Vector3(0, 0, 1);
2637
+ const mt = new y.Vector3(1, 0, 0);
2638
+ new y.Vector3(0, 1, 0);
2639
+ new y.Vector3(0, 0, 1);
2640
2640
  class Be {
2641
2641
  /**
2642
2642
  * Avatar.
@@ -4073,22 +4073,22 @@ class Be {
4073
4073
  if (this.isAvatarOnly = this.opt.avatarOnly, this.isAvatarOnly)
4074
4074
  this.scene = this.opt.avatarOnlyScene, this.camera = this.opt.avatarOnlyCamera;
4075
4075
  else {
4076
- this.renderer = new 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 y.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 = y.SRGBColorSpace, this.renderer.toneMapping = y.ACESFilmicToneMapping, this.renderer.shadowMap.enabled = !1, this.nodeAvatar.appendChild(this.renderer.domElement), this.camera = new y.PerspectiveCamera(10, this.nodeAvatar.clientWidth / this.nodeAvatar.clientHeight, 0.1, 2e3), this.scene = new y.Scene(), this.lightAmbient = new y.AmbientLight(
4077
+ new y.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 y.DirectionalLight(
4080
+ new y.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 y.SpotLight(
4083
+ new y.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 y.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 y.SkinnedMesh();
4092
4092
  const s = {
4093
4093
  LeftShoulder: null,
4094
4094
  LeftArm: "LeftShoulder",
@@ -4102,9 +4102,9 @@ class Be {
4102
4102
  RightHandMiddle1: "RightHand"
4103
4103
  }, o = [];
4104
4104
  Object.entries(s).forEach((l, h) => {
4105
- const r = new f.Bone();
4105
+ const r = new y.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 y.Skeleton(o)), this.dynamicbones = new et(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
4108
4108
  }
4109
4109
  /**
4110
4110
  * Helper that re/creates the audio context and the other nodes.
@@ -4194,7 +4194,7 @@ class Be {
4194
4194
  for (let [n, i] of Object.entries(t)) {
4195
4195
  const s = n.split(".");
4196
4196
  let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y, h = Array.isArray(i.z) ? this.gaussianRandom(...i.z) : i.z;
4197
- s[1] === "position" || s[1] === "scale" ? e[n] = new f.Vector3(o, l, h) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new f.Quaternion().setFromEuler(new f.Euler(o, l, h, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new f.Quaternion(o, l, h, i.w).normalize());
4197
+ s[1] === "position" || s[1] === "scale" ? e[n] = new y.Vector3(o, l, h) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new y.Quaternion().setFromEuler(new y.Euler(o, l, h, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new y.Quaternion(o, l, h, i.w).normalize());
4198
4198
  }
4199
4199
  return e;
4200
4200
  }
@@ -4226,15 +4226,15 @@ class Be {
4226
4226
  for (const [r, u] of Object.entries(n))
4227
4227
  if (s.morphTargetDictionary.hasOwnProperty(r)) {
4228
4228
  const a = s.morphTargetDictionary[r], d = o.morphAttributes.position[a], c = o.morphAttributes.normal?.[a];
4229
- l || (l = new f.Float32BufferAttribute(d.count * 3, 3), c && (h = new f.Float32BufferAttribute(d.count * 3, 3)));
4229
+ l || (l = new y.Float32BufferAttribute(d.count * 3, 3), c && (h = new y.Float32BufferAttribute(d.count * 3, 3)));
4230
4230
  for (let g = 0; g < d.count; g++) {
4231
- const b = l.getX(g) + d.getX(g) * u, x = l.getY(g) + d.getY(g) * u, S = l.getZ(g) + d.getZ(g) * u;
4232
- l.setXYZ(g, b, x, S);
4231
+ const x = l.getX(g) + d.getX(g) * u, f = l.getY(g) + d.getY(g) * u, k = l.getZ(g) + d.getZ(g) * u;
4232
+ l.setXYZ(g, x, f, k);
4233
4233
  }
4234
4234
  if (c)
4235
4235
  for (let g = 0; g < d.count; g++) {
4236
- const b = h.getX(g) + c.getX(g) * u, x = h.getY(g) + c.getY(g) * u, S = h.getZ(g) + c.getZ(g) * u;
4237
- h.setXYZ(g, b, x, S);
4236
+ const x = h.getX(g) + c.getX(g) * u, f = h.getY(g) + c.getY(g) * u, k = h.getZ(g) + c.getZ(g) * u;
4237
+ h.setXYZ(g, x, f, k);
4238
4238
  }
4239
4239
  }
4240
4240
  if (l) {
@@ -4314,7 +4314,7 @@ class Be {
4314
4314
  console.error("Dynamic bones setup failed: " + r);
4315
4315
  }
4316
4316
  this.objectLeftToeBase = this.armature.getObjectByName("LeftToeBase"), this.objectRightToeBase = this.armature.getObjectByName("RightToeBase"), this.objectLeftEye = this.armature.getObjectByName("LeftEye"), this.objectRightEye = this.armature.getObjectByName("RightEye"), this.objectLeftArm = this.armature.getObjectByName("LeftArm"), this.objectRightArm = this.armature.getObjectByName("RightArm"), this.objectHips = this.armature.getObjectByName("Hips"), this.objectHead = this.armature.getObjectByName("Head"), this.objectNeck = this.armature.getObjectByName("Neck");
4317
- const h = new f.Vector3();
4317
+ const h = new y.Vector3();
4318
4318
  this.objectLeftEye.getWorldPosition(h), this.avatarHeight = h.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.avatar.body === "M" && this.poseTemplates.wide && (this.poseName = "wide", this.setPoseFromTemplate(this.poseTemplates.wide, 0), console.log("Set initial male-appropriate pose: wide")), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
4319
4319
  }
4320
4320
  /**
@@ -4358,14 +4358,14 @@ class Be {
4358
4358
  default:
4359
4359
  a += 12, u = u * a;
4360
4360
  }
4361
- r = r * a, this.controlsEnd = new f.Vector3(r, u, 0), this.cameraEnd = new f.Vector3(r, u, a).applyEuler(new f.Euler(o, l, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
4361
+ r = r * a, this.controlsEnd = new y.Vector3(r, u, 0), this.cameraEnd = new y.Vector3(r, u, a).applyEuler(new y.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 y.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 y.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 y.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 y.Vector3(0, 1.5, 0))), t.hasOwnProperty("lightSpotDispersion") && (this.lightSpot.angle = t.lightSpotDispersion));
4369
4369
  }
4370
4370
  /**
4371
4371
  * Render scene.
@@ -4398,9 +4398,9 @@ class Be {
4398
4398
  updatePoseDelta() {
4399
4399
  for (const [t, e] of Object.entries(this.poseDelta.props)) {
4400
4400
  if (e.x === 0 && e.y === 0 && e.z === 0) continue;
4401
- Z.set(e.x, e.y, e.z);
4401
+ G.set(e.x, e.y, e.z);
4402
4402
  const n = this.poseAvatar.props[t];
4403
- n.isQuaternion ? (_.setFromEuler(Z), n.multiply(_)) : n.isVector3 && n.add(Z);
4403
+ n.isQuaternion ? (J.setFromEuler(G), n.multiply(J)) : n.isVector3 && n.add(G);
4404
4404
  }
4405
4405
  }
4406
4406
  /**
@@ -4480,7 +4480,7 @@ class Be {
4480
4480
  return Object.entries(t).forEach((i, s) => {
4481
4481
  const o = i[0].split(".");
4482
4482
  if (o[1] === "position" || o[1] === "rotation" || o[1] === "quaternion") {
4483
- const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], h = i[1].isQuaternion ? new f.Euler().setFromQuaternion(i[1]) : i[1];
4483
+ const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], h = i[1].isQuaternion ? new y.Euler().setFromQuaternion(i[1]) : i[1];
4484
4484
  n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(h.x * e) / e, n += ", y:" + Math.round(h.y * e) / e, n += ", z:" + Math.round(h.z * e) / e, n += "}";
4485
4485
  }
4486
4486
  }), n += "}", n;
@@ -5107,9 +5107,9 @@ class Be {
5107
5107
  g.newvalue = c[i];
5108
5108
  else {
5109
5109
  g.newvalue = c[i + 1];
5110
- const b = a.ts[i + 1] - a.ts[i];
5111
- let x = 1;
5112
- b > 1e-4 && (x = (this.animClock - a.ts[i]) / b), x < 1 && (g.easing && (x = g.easing(x)), g.newvalue = (1 - x) * c[i] + x * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(d) && delete g.ref[d], g.ref = a.vs;
5110
+ const x = a.ts[i + 1] - a.ts[i];
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) * c[i] + f * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(d) && delete g.ref[d], g.ref = a.vs;
5113
5113
  }
5114
5114
  if (l)
5115
5115
  switch (d) {
@@ -5157,7 +5157,7 @@ class Be {
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 y.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5161
5161
  break;
5162
5162
  case "handRight":
5163
5163
  this.ikSolve({
@@ -5169,10 +5169,10 @@ class Be {
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 y.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5173
5173
  break;
5174
5174
  }
5175
- if ((h || r) && (Z.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), Z.x = Math.max(-0.9, Math.min(0.9, 2 * Z.x - 0.5)), Z.y = Math.max(-0.9, Math.min(0.9, -2.5 * Z.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: Z.x < 0 ? -Z.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: Z.x < 0 ? 0 : Z.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: Z.y < 0 ? -Z.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: Z.y < 0 ? 0 : Z.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: Z.y < 0 ? 0 : Z.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: Z.y < 0 ? -Z.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
5175
+ if ((h || r) && (G.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), G.x = Math.max(-0.9, Math.min(0.9, 2 * G.x - 0.5)), G.y = Math.max(-0.9, Math.min(0.9, -2.5 * G.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: G.x < 0 ? -G.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: G.x < 0 ? 0 : G.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: G.y < 0 ? -G.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: G.y < 0 ? 0 : G.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: G.y < 0 ? 0 : G.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: G.y < 0 ? -G.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
5176
5176
  name: "headmove",
5177
5177
  dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
5178
5178
  vs: {
@@ -5193,12 +5193,12 @@ class Be {
5193
5193
  eyeLookOutRight: [null, 0],
5194
5194
  eyeContact: [0]
5195
5195
  }
5196
- })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (_.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(_)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Re), Re.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (ve.x + Re.x) / 4, this.objectHips.position.z -= (ve.z + Re.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
5196
+ })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (J.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(J)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Re), Re.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (ve.x + Re.x) / 4, this.objectHips.position.z -= (ve.z + Re.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
5197
5197
  this.stats && this.stats.end();
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), d = new f.Spherical().setFromVector3(this.cameraEnd);
5201
+ let a = new y.Spherical().setFromVector3(this.cameraStart), d = new y.Spherical().setFromVector3(this.cameraEnd);
5202
5202
  a.phi += this.easing(this.cameraClock / 1e3) * (d.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (d.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (d.radius - a.radius), a.makeSafe(), this.camera.position.setFromSpherical(a), this.controlsStart.x !== this.controlsEnd.x ? this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd, this.easing(this.cameraClock / 1e3))) : (a.setFromVector3(this.controlsStart), d.setFromVector3(this.controlsEnd), a.phi += this.easing(this.cameraClock / 1e3) * (d.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (d.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (d.radius - a.radius), a.makeSafe(), this.controls.target.setFromSpherical(a)), this.controls.update();
5203
5203
  }
5204
5204
  this.controls.autoRotate && this.controls.update(), this.stats && this.stats.end(), this.render();
@@ -5262,12 +5262,12 @@ class Be {
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, h = /[\p{Extended_Pictographic}]/ug, r = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
5264
5264
  let u = "", a = "", d = 0, c = [], g = [];
5265
- const b = Array.from(this.segmenter.segment(t), (x) => x.segment);
5266
- for (let x = 0; x < b.length; x++) {
5267
- const S = x === b.length - 1, U = b[x].match(l);
5268
- let p = b[x].match(s);
5269
- const F = b[x].match(h), C = b[x].match(o);
5270
- if (p && !S && !F && b[x + 1].match(s) && (p = !1), n && (u += b[x]), U && (!i || i.every((y) => x < y[0] || x > y[1])) && (a += b[x]), (C || p || S) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && c.push({
5265
+ const x = Array.from(this.segmenter.segment(t), (f) => f.segment);
5266
+ for (let f = 0; f < x.length; f++) {
5267
+ const k = f === x.length - 1, O = x[f].match(l);
5268
+ let p = x[f].match(s);
5269
+ const B = x[f].match(h), H = x[f].match(o);
5270
+ if (p && !k && !B && x[f + 1].match(s) && (p = !1), n && (u += x[f]), O && (!i || i.every((v) => f < v[0] || f > v[1])) && (a += x[f]), (H || p || k) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && c.push({
5271
5271
  mark: d,
5272
5272
  word: a
5273
5273
  })), u.length && (g.push({
@@ -5278,31 +5278,31 @@ class Be {
5278
5278
  subtitles: [u]
5279
5279
  }
5280
5280
  }), u = ""), a.length)) {
5281
- const y = this.lipsyncWordsToVisemes(a, r);
5282
- if (y && y.visemes && y.visemes.length) {
5283
- const I = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
5284
- for (let z = 0; z < y.visemes.length; z++)
5281
+ const v = this.lipsyncWordsToVisemes(a, r);
5282
+ if (v && v.visemes && v.visemes.length) {
5283
+ const L = v.times[v.visemes.length - 1] + v.durations[v.visemes.length - 1];
5284
+ for (let I = 0; I < v.visemes.length; I++)
5285
5285
  g.push({
5286
5286
  mark: d,
5287
5287
  template: { name: "viseme" },
5288
- ts: [(y.times[z] - 0.6) / I, (y.times[z] + 0.5) / I, (y.times[z] + y.durations[z] + 0.5) / I],
5288
+ ts: [(v.times[I] - 0.6) / L, (v.times[I] + 0.5) / L, (v.times[I] + v.durations[I] + 0.5) / L],
5289
5289
  vs: {
5290
- ["viseme_" + y.visemes[z]]: [null, y.visemes[z] === "PP" || y.visemes[z] === "FF" ? 0.9 : 0.6, 0]
5290
+ ["viseme_" + v.visemes[I]]: [null, v.visemes[I] === "PP" || v.visemes[I] === "FF" ? 0.9 : 0.6, 0]
5291
5291
  }
5292
5292
  });
5293
5293
  }
5294
5294
  a = "", d++;
5295
5295
  }
5296
- if (p || S) {
5297
- if (c.length || S && g.length) {
5298
- const y = {
5296
+ if (p || k) {
5297
+ if (c.length || k && g.length) {
5298
+ const v = {
5299
5299
  anim: g
5300
5300
  };
5301
- n && (y.onSubtitles = n), c.length && !e.avatarMute && (y.text = c, 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), c = [], a = "", d = 0, g = [];
5301
+ n && (v.onSubtitles = n), c.length && !e.avatarMute && (v.text = c, e.avatarMood && (v.mood = e.avatarMood), e.ttsLang && (v.lang = e.ttsLang), e.ttsVoice && (v.voice = e.ttsVoice), e.ttsRate && (v.rate = e.ttsRate), e.ttsVoice && (v.pitch = e.ttsPitch), e.ttsVolume && (v.volume = e.ttsVolume)), this.speechQueue.push(v), c = [], a = "", d = 0, g = [];
5302
5302
  }
5303
- if (F) {
5304
- let y = this.animEmojis[b[x]];
5305
- y && y.link && (y = this.animEmojis[y.link]), y && this.speechQueue.push({ emoji: y });
5303
+ if (B) {
5304
+ let v = this.animEmojis[x[f]];
5305
+ v && v.link && (v = this.animEmojis[v.link]), v && this.speechQueue.push({ emoji: v });
5306
5306
  }
5307
5307
  this.speechQueue.push({ break: 100 });
5308
5308
  }
@@ -5395,15 +5395,15 @@ class Be {
5395
5395
  const a = this.lipsyncPreProcessText(h, i), d = this.lipsyncWordsToVisemes(a, i);
5396
5396
  if (d && d.visemes && d.visemes.length) {
5397
5397
  const c = d.times[d.visemes.length - 1] + d.durations[d.visemes.length - 1], g = Math.min(u, Math.max(0, u - d.visemes.length * 150));
5398
- let b = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
5398
+ let x = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
5399
5399
  if (u = Math.min(u, d.visemes.length * 200), c > 0)
5400
- for (let x = 0; x < d.visemes.length; x++) {
5401
- const S = r + d.times[x] / c * u, U = d.durations[x] / c * u;
5400
+ for (let f = 0; f < d.visemes.length; f++) {
5401
+ const k = r + d.times[f] / c * u, O = d.durations[f] / c * u;
5402
5402
  o.push({
5403
5403
  template: { name: "viseme" },
5404
- ts: [S - Math.min(60, 2 * U / 3), S + Math.min(25, U / 2), S + U + Math.min(60, U / 2)],
5404
+ ts: [k - Math.min(60, 2 * O / 3), k + Math.min(25, O / 2), k + O + Math.min(60, O / 2)],
5405
5405
  vs: {
5406
- ["viseme_" + d.visemes[x]]: [null, d.visemes[x] === "PP" || d.visemes[x] === "FF" ? 0.9 : b, 0]
5406
+ ["viseme_" + d.visemes[f]]: [null, d.visemes[f] === "PP" || d.visemes[f] === "FF" ? 0.9 : x, 0]
5407
5407
  }
5408
5408
  });
5409
5409
  }
@@ -5483,34 +5483,34 @@ class Be {
5483
5483
  s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, h)), s.volume = Math.max(0, Math.min(1, r));
5484
5484
  const u = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
5485
5485
  if (a && u.length > 0) {
5486
- const p = u.find((F) => F.name.includes(a) || F.lang === o);
5486
+ const p = u.find((B) => B.name.includes(a) || B.lang === o);
5487
5487
  p && (s.voice = p);
5488
5488
  }
5489
- const d = i.length * 100 / s.rate, c = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (d / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", b = this.lipsyncPreProcessText(i, g), x = this.lipsyncWordsToVisemes(b, g);
5489
+ const d = i.length * 100 / s.rate, c = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (d / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", 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
- processedText: b,
5494
- lipsyncData: x,
5495
- hasVisemes: x && x.visemes && x.visemes.length > 0,
5493
+ processedText: x,
5494
+ lipsyncData: f,
5495
+ hasVisemes: f && f.visemes && f.visemes.length > 0,
5496
5496
  estimatedDuration: d
5497
5497
  });
5498
- const S = [];
5499
- if (x && x.visemes && x.visemes.length > 0) {
5500
- const p = x.times[x.visemes.length - 1] + x.durations[x.visemes.length - 1];
5501
- for (let F = 0; F < x.visemes.length; F++) {
5502
- const C = x.visemes[F], y = x.times[F] / p, I = x.durations[F] / p, z = y * d, A = I * d;
5503
- S.push({
5498
+ const k = [];
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 B = 0; B < f.visemes.length; B++) {
5502
+ const H = f.visemes[B], v = f.times[B] / p, L = f.durations[B] / p, I = v * d, z = L * d;
5503
+ k.push({
5504
5504
  template: { name: "viseme" },
5505
- ts: [z - Math.min(60, 2 * A / 3), z + Math.min(25, A / 2), z + A + Math.min(60, A / 2)],
5505
+ ts: [I - Math.min(60, 2 * z / 3), I + Math.min(25, z / 2), I + z + Math.min(60, z / 2)],
5506
5506
  vs: {
5507
- ["viseme_" + C]: [null, C === "PP" || C === "FF" ? 0.9 : 0.6, 0]
5507
+ ["viseme_" + H]: [null, H === "PP" || H === "FF" ? 0.9 : 0.6, 0]
5508
5508
  }
5509
5509
  });
5510
5510
  }
5511
5511
  }
5512
- const U = [...t.anim, ...S];
5513
- this.audioPlaylist.push({ anim: U, audio: c }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5512
+ const O = [...t.anim, ...k];
5513
+ this.audioPlaylist.push({ anim: O, audio: c }), 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);
@@ -5559,10 +5559,10 @@ class Be {
5559
5559
  hasVisemes: c && c.visemes && c.visemes.length > 0
5560
5560
  }), c && c.visemes && c.visemes.length > 0)
5561
5561
  r = {
5562
- visemes: c.visemes.map((g, b) => ({
5562
+ visemes: c.visemes.map((g, x) => ({
5563
5563
  viseme: g,
5564
- startTime: b * l.duration / c.visemes.length,
5565
- endTime: (b + 1) * l.duration / c.visemes.length,
5564
+ startTime: x * l.duration / c.visemes.length,
5565
+ endTime: (x + 1) * l.duration / c.visemes.length,
5566
5566
  duration: l.duration / c.visemes.length,
5567
5567
  intensity: 0.7
5568
5568
  })),
@@ -5575,16 +5575,16 @@ class Be {
5575
5575
  } catch (d) {
5576
5576
  console.error("Text-based lip-sync failed, using fallback:", d);
5577
5577
  const c = e.toLowerCase().split(/\s+/), g = [];
5578
- for (const b of c)
5579
- for (const x of b) {
5580
- let S = "aa";
5581
- "aeiou".includes(x) ? S = "aa" : "bp".includes(x) ? S = "PP" : "fv".includes(x) ? S = "FF" : "st".includes(x) ? S = "SS" : "dln".includes(x) ? S = "DD" : "kg".includes(x) ? S = "kk" : "rw".includes(x) && (S = "RR"), g.push(S);
5578
+ for (const x of c)
5579
+ for (const f of x) {
5580
+ let k = "aa";
5581
+ "aeiou".includes(f) ? k = "aa" : "bp".includes(f) ? k = "PP" : "fv".includes(f) ? k = "FF" : "st".includes(f) ? k = "SS" : "dln".includes(f) ? k = "DD" : "kg".includes(f) ? k = "kk" : "rw".includes(f) && (k = "RR"), g.push(k);
5582
5582
  }
5583
5583
  r = {
5584
- visemes: g.map((b, x) => ({
5585
- viseme: b,
5586
- startTime: x * l.duration / g.length,
5587
- endTime: (x + 1) * l.duration / g.length,
5584
+ visemes: g.map((x, f) => ({
5585
+ viseme: x,
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 Be {
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 d = 0; d < r.visemes.length; d++) {
5612
- const c = r.visemes[d], g = c.startTime * 1e3, b = c.duration * 1e3, x = c.intensity;
5612
+ const c = r.visemes[d], g = c.startTime * 1e3, x = c.duration * 1e3, f = c.intensity;
5613
5613
  u.push({
5614
5614
  template: { name: "viseme" },
5615
- ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
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_" + c.viseme]: [null, x, 0]
5617
+ ["viseme_" + c.viseme]: [null, f, 0]
5618
5618
  }
5619
5619
  });
5620
5620
  }
@@ -5657,10 +5657,10 @@ class Be {
5657
5657
  hasVisemes: c && c.visemes && c.visemes.length > 0
5658
5658
  }), c && c.visemes && c.visemes.length > 0)
5659
5659
  r = {
5660
- visemes: c.visemes.map((g, b) => ({
5660
+ visemes: c.visemes.map((g, x) => ({
5661
5661
  viseme: g,
5662
- startTime: b * l.duration / c.visemes.length,
5663
- endTime: (b + 1) * l.duration / c.visemes.length,
5662
+ startTime: x * l.duration / c.visemes.length,
5663
+ endTime: (x + 1) * l.duration / c.visemes.length,
5664
5664
  duration: l.duration / c.visemes.length,
5665
5665
  intensity: 0.7
5666
5666
  })),
@@ -5673,16 +5673,16 @@ class Be {
5673
5673
  } catch (d) {
5674
5674
  console.error("Text-based lip-sync failed, using fallback:", d);
5675
5675
  const c = e.toLowerCase().split(/\s+/), g = [];
5676
- for (const b of c)
5677
- for (const x of b) {
5678
- let S = "aa";
5679
- "aeiou".includes(x) ? S = "aa" : "bp".includes(x) ? S = "PP" : "fv".includes(x) ? S = "FF" : "st".includes(x) ? S = "SS" : "dln".includes(x) ? S = "DD" : "kg".includes(x) ? S = "kk" : "rw".includes(x) && (S = "RR"), g.push(S);
5676
+ for (const x of c)
5677
+ for (const f of x) {
5678
+ let k = "aa";
5679
+ "aeiou".includes(f) ? k = "aa" : "bp".includes(f) ? k = "PP" : "fv".includes(f) ? k = "FF" : "st".includes(f) ? k = "SS" : "dln".includes(f) ? k = "DD" : "kg".includes(f) ? k = "kk" : "rw".includes(f) && (k = "RR"), g.push(k);
5680
5680
  }
5681
5681
  r = {
5682
- visemes: g.map((b, x) => ({
5683
- viseme: b,
5684
- startTime: x * l.duration / g.length,
5685
- endTime: (x + 1) * l.duration / g.length,
5682
+ visemes: g.map((x, f) => ({
5683
+ viseme: x,
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 Be {
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 d = 0; d < r.visemes.length; d++) {
5710
- const c = r.visemes[d], g = c.startTime * 1e3, b = c.duration * 1e3, x = c.intensity;
5710
+ const c = r.visemes[d], g = c.startTime * 1e3, x = c.duration * 1e3, f = c.intensity;
5711
5711
  u.push({
5712
5712
  template: { name: "viseme" },
5713
- ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
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_" + c.viseme]: [null, x, 0]
5715
+ ["viseme_" + c.viseme]: [null, f, 0]
5716
5716
  }
5717
5717
  });
5718
5718
  }
@@ -5759,12 +5759,12 @@ class Be {
5759
5759
  });
5760
5760
  const r = [];
5761
5761
  for (let a = 0; a < h.visemes.length; a++) {
5762
- const d = h.visemes[a], c = d.startTime * 1e3, g = d.duration * 1e3, b = d.intensity;
5762
+ const d = h.visemes[a], c = d.startTime * 1e3, g = d.duration * 1e3, x = d.intensity;
5763
5763
  r.push({
5764
5764
  template: { name: "viseme" },
5765
5765
  ts: [c - Math.min(60, 2 * g / 3), c + Math.min(25, g / 2), c + g + Math.min(60, g / 2)],
5766
5766
  vs: {
5767
- ["viseme_" + d.viseme]: [null, b, 0]
5767
+ ["viseme_" + d.viseme]: [null, x, 0]
5768
5768
  }
5769
5769
  });
5770
5770
  }
@@ -6050,10 +6050,10 @@ class Be {
6050
6050
  let d = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
6051
6051
  if (o = Math.min(o, r.visemes.length * 200), u > 0)
6052
6052
  for (let c = 0; c < r.visemes.length; c++) {
6053
- const g = e + s + r.times[c] / u * o, b = r.durations[c] / u * o;
6053
+ const g = e + s + r.times[c] / u * o, x = r.durations[c] / u * o;
6054
6054
  this.animQueue.push({
6055
6055
  template: { name: "viseme" },
6056
- ts: [g - Math.min(60, 2 * b / 3), g + Math.min(25, b / 2), g + b + Math.min(60, b / 2)],
6056
+ ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
6057
6057
  vs: {
6058
6058
  ["viseme_" + r.visemes[c]]: [null, r.visemes[c] === "PP" || r.visemes[c] === "FF" ? 0.9 : d, 0]
6059
6059
  }
@@ -6146,7 +6146,7 @@ class Be {
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 y.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);
@@ -6159,16 +6159,16 @@ class Be {
6159
6159
  this.lookAt(null, null, t);
6160
6160
  return;
6161
6161
  }
6162
- this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), _.copy(this.armature.quaternion), _.multiply(this.poseTarget.props["Hips.quaternion"]), _.multiply(this.poseTarget.props["Spine.quaternion"]), _.multiply(this.poseTarget.props["Spine1.quaternion"]), _.multiply(this.poseTarget.props["Spine2.quaternion"]), _.multiply(this.poseTarget.props["Neck.quaternion"]), _.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);
6164
- Z.set(s, i, 0, "YXZ");
6165
- const l = new f.Quaternion().setFromEuler(Z), h = new f.Quaternion().copy(l).multiply(_.clone().invert());
6166
- Z.setFromQuaternion(h, "YXZ");
6167
- let r = Z.x / (40 / 24) + 0.2, u = Z.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), d = Math.min(0.8, Math.max(-0.8, u)), c = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6162
+ this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), J.copy(this.armature.quaternion), J.multiply(this.poseTarget.props["Hips.quaternion"]), J.multiply(this.poseTarget.props["Spine.quaternion"]), J.multiply(this.poseTarget.props["Spine1.quaternion"]), J.multiply(this.poseTarget.props["Spine2.quaternion"]), J.multiply(this.poseTarget.props["Neck.quaternion"]), J.multiply(this.poseTarget.props["Head.quaternion"]);
6163
+ const n = new y.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6164
+ G.set(s, i, 0, "YXZ");
6165
+ const l = new y.Quaternion().setFromEuler(G), h = new y.Quaternion().copy(l).multiply(J.clone().invert());
6166
+ G.setFromQuaternion(h, "YXZ");
6167
+ let r = G.x / (40 / 24) + 0.2, u = G.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), d = Math.min(0.8, Math.max(-0.8, u)), c = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6168
6168
  if (t) {
6169
- let b = this.animQueue.findIndex((S) => S.template.name === "lookat");
6170
- b !== -1 && this.animQueue.splice(b, 1);
6171
- const x = {
6169
+ let x = this.animQueue.findIndex((k) => k.template.name === "lookat");
6170
+ x !== -1 && this.animQueue.splice(x, 1);
6171
+ const f = {
6172
6172
  name: "lookat",
6173
6173
  dt: [750, t],
6174
6174
  vs: {
@@ -6183,7 +6183,7 @@ class Be {
6183
6183
  headMove: [0]
6184
6184
  }
6185
6185
  };
6186
- this.animQueue.push(this.animFactory(x));
6186
+ this.animQueue.push(this.animFactory(f));
6187
6187
  }
6188
6188
  }
6189
6189
  /**
@@ -6196,23 +6196,23 @@ class Be {
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 y.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new y.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new y.Vector3().addVectors(s, o).divideScalar(2);
6200
6200
  l.project(this.camera);
6201
6201
  let h = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
6202
- t === null && (t = h), e === null && (e = r), _.copy(this.armature.quaternion), _.multiply(this.poseTarget.props["Hips.quaternion"]), _.multiply(this.poseTarget.props["Spine.quaternion"]), _.multiply(this.poseTarget.props["Spine1.quaternion"]), _.multiply(this.poseTarget.props["Spine2.quaternion"]), _.multiply(this.poseTarget.props["Neck.quaternion"]), _.multiply(this.poseTarget.props["Head.quaternion"]), Z.setFromQuaternion(_);
6203
- let u = Z.x / (40 / 24), a = Z.y / (9 / 4), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - h, h), b = Math.max(window.innerHeight - r, r), x = this.convertRange(e, [r - b, r + b], [-0.3, 0.6]) - u + d, S = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + c;
6204
- x = Math.min(0.6, Math.max(-0.3, x)), S = Math.min(0.8, Math.max(-0.8, S));
6205
- let U = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6202
+ t === null && (t = h), e === null && (e = r), J.copy(this.armature.quaternion), J.multiply(this.poseTarget.props["Hips.quaternion"]), J.multiply(this.poseTarget.props["Spine.quaternion"]), J.multiply(this.poseTarget.props["Spine1.quaternion"]), J.multiply(this.poseTarget.props["Spine2.quaternion"]), J.multiply(this.poseTarget.props["Neck.quaternion"]), J.multiply(this.poseTarget.props["Head.quaternion"]), G.setFromQuaternion(J);
6203
+ let u = G.x / (40 / 24), a = G.y / (9 / 4), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - h, h), x = Math.max(window.innerHeight - r, r), f = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - u + d, k = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + c;
6204
+ f = Math.min(0.6, Math.max(-0.3, f)), k = Math.min(0.8, Math.max(-0.8, k));
6205
+ let O = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6206
6206
  if (n) {
6207
- let F = this.animQueue.findIndex((y) => y.template.name === "lookat");
6208
- F !== -1 && this.animQueue.splice(F, 1);
6209
- const C = {
6207
+ let B = this.animQueue.findIndex((v) => v.template.name === "lookat");
6208
+ B !== -1 && this.animQueue.splice(B, 1);
6209
+ const H = {
6210
6210
  name: "lookat",
6211
6211
  dt: [750, n],
6212
6212
  vs: {
6213
- bodyRotateX: [x + U],
6214
- bodyRotateY: [S + p],
6215
- eyesRotateX: [-3 * U + 0.1],
6213
+ bodyRotateX: [f + O],
6214
+ bodyRotateY: [k + p],
6215
+ eyesRotateX: [-3 * O + 0.1],
6216
6216
  eyesRotateY: [-5 * p],
6217
6217
  browInnerUp: [[0, 0.7]],
6218
6218
  mouthLeft: [[0, 0.7]],
@@ -6221,7 +6221,7 @@ class Be {
6221
6221
  headMove: [0]
6222
6222
  }
6223
6223
  };
6224
- this.animQueue.push(this.animFactory(C));
6224
+ this.animQueue.push(this.animFactory(H));
6225
6225
  }
6226
6226
  }
6227
6227
  /**
@@ -6232,14 +6232,14 @@ class Be {
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 y.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 y.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, h = new f.Vector3(), r = new f.Vector3();
6242
+ const l = o[0].point, h = new y.Vector3(), r = new y.Vector3();
6243
6243
  this.objectLeftArm.getWorldPosition(h), this.objectRightArm.getWorldPosition(r);
6244
6244
  const u = h.distanceToSquared(l), a = r.distanceToSquared(l);
6245
6245
  u < a ? (this.ikSolve({
@@ -6283,7 +6283,7 @@ class Be {
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 y.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 Be {
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 y.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 y.Quaternion().setFromEuler(new y.Euler(0, -1 - Math.random(), 0)),
6306
+ "RightHand.quaternion": new y.Quaternion().setFromEuler(new y.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) => {
@@ -6388,9 +6388,9 @@ class Be {
6388
6388
  let h = this.animQueue.find((a) => a.template.name === "pose");
6389
6389
  h && (h.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((a) => {
6390
6390
  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;
6391
- }), 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 });
6391
+ }), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new y.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
6392
6392
  const r = Math.ceil(n / l.clip.duration), u = this.mixer.clipAction(l.clip);
6393
- u.setLoop(f.LoopRepeat, r), u.clampWhenFinished = !0, this.currentFBXAction = u;
6393
+ u.setLoop(y.LoopRepeat, r), u.clampWhenFinished = !0, this.currentFBXAction = u;
6394
6394
  try {
6395
6395
  u.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
6396
6396
  } catch (a) {
@@ -6427,13 +6427,13 @@ class Be {
6427
6427
  suggestion: "Make sure the file is a valid FBX file and the path is correct"
6428
6428
  }), d.message && d.message.includes("version number") && (console.error("FBX Loader Error: Cannot find version number"), console.error("This error usually means:"), console.error("1. The file is not a valid FBX file (might be GLB, corrupted, or wrong format)"), console.error("2. The file might be corrupted"), console.error("3. The file path might be incorrect"), console.error("4. The server returned an HTML error page instead of the FBX file"), console.error("5. The file might not exist at that path"), console.error(""), console.error("Solution: Please verify:"), console.error(` - File exists at: ${t}`), console.error(" - File is a valid FBX binary file"), console.error(" - File path matches your public folder structure"), console.error(" - File is not corrupted"));
6429
6429
  try {
6430
- const c = await fetch(t), g = c.headers.get("content-type"), b = await c.text();
6430
+ const c = await fetch(t), g = c.headers.get("content-type"), x = await c.text();
6431
6431
  console.error("Response details:", {
6432
6432
  status: c.status,
6433
6433
  contentType: g,
6434
- firstBytes: b.substring(0, 100),
6435
- isHTML: b.trim().startsWith("<!DOCTYPE") || b.trim().startsWith("<html")
6436
- }), (b.trim().startsWith("<!DOCTYPE") || b.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
6434
+ firstBytes: x.substring(0, 100),
6435
+ isHTML: x.trim().startsWith("<!DOCTYPE") || x.trim().startsWith("<html")
6436
+ }), (x.trim().startsWith("<!DOCTYPE") || x.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
6437
6437
  } catch (c) {
6438
6438
  console.error("Could not fetch file for debugging:", c);
6439
6439
  }
@@ -6442,37 +6442,37 @@ class Be {
6442
6442
  if (a && a.animations && a.animations[i]) {
6443
6443
  let d = a.animations[i];
6444
6444
  const c = /* @__PURE__ */ new Set();
6445
- this.armature && this.armature.traverse((I) => {
6446
- (I.isBone || I.type === "Bone") && c.add(I.name);
6445
+ this.armature && this.armature.traverse((L) => {
6446
+ (L.isBone || L.type === "Bone") && c.add(L.name);
6447
6447
  });
6448
- const g = /* @__PURE__ */ new Map(), b = (I) => {
6448
+ const g = /* @__PURE__ */ new Map(), x = (L) => {
6449
+ if (c.has(L))
6450
+ return L;
6451
+ let I = L.replace(/^mixamorig/i, "").replace(/^CC_Base_/i, "").replace(/^RPM_/i, "");
6449
6452
  if (c.has(I))
6450
6453
  return I;
6451
- let z = I.replace(/^mixamorig/i, "").replace(/^CC_Base_/i, "").replace(/^RPM_/i, "");
6452
- if (c.has(z))
6453
- return z;
6454
- const A = z.toLowerCase();
6455
- if (A.includes("left") && A.includes("arm")) {
6456
- if (A.includes("fore") || A.includes("lower")) {
6454
+ const z = I.toLowerCase();
6455
+ if (z.includes("left") && z.includes("arm")) {
6456
+ if (z.includes("fore") || z.includes("lower")) {
6457
6457
  if (c.has("LeftForeArm")) return "LeftForeArm";
6458
6458
  if (c.has("LeftForearm")) return "LeftForearm";
6459
- } else if (!A.includes("fore") && !A.includes("hand") && c.has("LeftArm"))
6459
+ } else if (!z.includes("fore") && !z.includes("hand") && c.has("LeftArm"))
6460
6460
  return "LeftArm";
6461
6461
  }
6462
- if (A.includes("right") && A.includes("arm")) {
6463
- if (A.includes("fore") || A.includes("lower")) {
6462
+ if (z.includes("right") && z.includes("arm")) {
6463
+ if (z.includes("fore") || z.includes("lower")) {
6464
6464
  if (c.has("RightForeArm")) return "RightForeArm";
6465
6465
  if (c.has("RightForearm")) return "RightForearm";
6466
- } else if (!A.includes("fore") && !A.includes("hand") && c.has("RightArm"))
6466
+ } else if (!z.includes("fore") && !z.includes("hand") && c.has("RightArm"))
6467
6467
  return "RightArm";
6468
6468
  }
6469
- if (A.includes("left") && A.includes("hand") && !A.includes("index") && !A.includes("thumb") && !A.includes("middle") && !A.includes("ring") && !A.includes("pinky") && c.has("LeftHand"))
6469
+ if (z.includes("left") && z.includes("hand") && !z.includes("index") && !z.includes("thumb") && !z.includes("middle") && !z.includes("ring") && !z.includes("pinky") && c.has("LeftHand"))
6470
6470
  return "LeftHand";
6471
- if (A.includes("right") && A.includes("hand") && !A.includes("index") && !A.includes("thumb") && !A.includes("middle") && !A.includes("ring") && !A.includes("pinky") && c.has("RightHand"))
6471
+ if (z.includes("right") && z.includes("hand") && !z.includes("index") && !z.includes("thumb") && !z.includes("middle") && !z.includes("ring") && !z.includes("pinky") && c.has("RightHand"))
6472
6472
  return "RightHand";
6473
- if (A.includes("left") && (A.includes("shoulder") || A.includes("clavicle")) && c.has("LeftShoulder"))
6473
+ if (z.includes("left") && (z.includes("shoulder") || z.includes("clavicle")) && c.has("LeftShoulder"))
6474
6474
  return "LeftShoulder";
6475
- if (A.includes("right") && (A.includes("shoulder") || A.includes("clavicle")) && c.has("RightShoulder"))
6475
+ if (z.includes("right") && (z.includes("shoulder") || z.includes("clavicle")) && c.has("RightShoulder"))
6476
6476
  return "RightShoulder";
6477
6477
  const Y = {
6478
6478
  // Arm bones - exact matches
@@ -6514,65 +6514,65 @@ class Be {
6514
6514
  Root: "Hips",
6515
6515
  root: "Hips"
6516
6516
  };
6517
- if (Y[z]) {
6518
- const k = Y[z];
6519
- if (c.has(k))
6520
- return k;
6517
+ if (Y[I]) {
6518
+ const S = Y[I];
6519
+ if (c.has(S))
6520
+ return S;
6521
6521
  }
6522
- for (const k of c)
6523
- if (k.toLowerCase() === A)
6524
- return k;
6525
- for (const k of c) {
6526
- const E = k.toLowerCase();
6527
- if ((A.includes("left") && E.includes("left") || A.includes("right") && E.includes("right")) && (A.includes("arm") && E.includes("arm") && !E.includes("fore") || A.includes("forearm") && E.includes("forearm") || A.includes("hand") && E.includes("hand") && !E.includes("index") && !E.includes("thumb") || A.includes("shoulder") && E.includes("shoulder")))
6528
- return k;
6522
+ for (const S of c)
6523
+ if (S.toLowerCase() === z)
6524
+ return S;
6525
+ for (const S of c) {
6526
+ const F = S.toLowerCase();
6527
+ if ((z.includes("left") && F.includes("left") || z.includes("right") && F.includes("right")) && (z.includes("arm") && F.includes("arm") && !F.includes("fore") || z.includes("forearm") && F.includes("forearm") || z.includes("hand") && F.includes("hand") && !F.includes("index") && !F.includes("thumb") || z.includes("shoulder") && F.includes("shoulder")))
6528
+ return S;
6529
6529
  }
6530
6530
  return null;
6531
- }, x = /* @__PURE__ */ new Set();
6532
- d.tracks.forEach((I) => {
6533
- const z = I.name.split(".");
6534
- x.add(z[0]);
6535
- }), console.log("=== Ready Player Me Animation Bone Analysis ==="), console.log("FBX bone names:", Array.from(x).sort().join(", ")), console.log("Avatar skeleton bone names:", Array.from(c).sort().join(", "));
6536
- const S = Array.from(x).filter(
6537
- (I) => I.toLowerCase().includes("arm") || I.toLowerCase().includes("hand") || I.toLowerCase().includes("shoulder")
6538
- ), U = Array.from(c).filter(
6539
- (I) => I.includes("Arm") || I.includes("Hand") || I.includes("Shoulder")
6531
+ }, f = /* @__PURE__ */ new Set();
6532
+ d.tracks.forEach((L) => {
6533
+ const I = L.name.split(".");
6534
+ f.add(I[0]);
6535
+ }), console.log("=== Ready Player Me Animation Bone Analysis ==="), console.log("FBX bone names:", Array.from(f).sort().join(", ")), console.log("Avatar skeleton bone names:", Array.from(c).sort().join(", "));
6536
+ const k = Array.from(f).filter(
6537
+ (L) => L.toLowerCase().includes("arm") || L.toLowerCase().includes("hand") || L.toLowerCase().includes("shoulder")
6538
+ ), O = Array.from(c).filter(
6539
+ (L) => L.includes("Arm") || L.includes("Hand") || L.includes("Shoulder")
6540
6540
  );
6541
- console.log("FBX arm/hand/shoulder bones:", S.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:", U.sort().join(", "));
6542
- const p = [], F = /* @__PURE__ */ new Set();
6543
- if (d.tracks.forEach((I) => {
6544
- const A = I.name.replaceAll("mixamorig", "").split("."), Y = A[0], k = A[1], E = b(Y);
6545
- if (E && k) {
6546
- const q = `${E}.${k}`, G = I.clone();
6547
- G.name = q, p.push(G), Y !== E && g.set(Y, E);
6541
+ console.log("FBX arm/hand/shoulder bones:", k.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:", O.sort().join(", "));
6542
+ const p = [], B = /* @__PURE__ */ new Set();
6543
+ if (d.tracks.forEach((L) => {
6544
+ const z = L.name.replaceAll("mixamorig", "").split("."), Y = z[0], S = z[1], F = x(Y);
6545
+ if (F && S) {
6546
+ const X = `${F}.${S}`, Z = L.clone();
6547
+ Z.name = X, p.push(Z), Y !== F && g.set(Y, F);
6548
6548
  } else
6549
- F.add(Y), (Y.toLowerCase().includes("arm") || Y.toLowerCase().includes("hand") || Y.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${Y}" could not be mapped to avatar skeleton`);
6550
- }), F.size > 0 && console.warn(`⚠️ ${F.size} bone(s) could not be mapped:`, Array.from(F).sort().join(", ")), p.length > 0) {
6551
- d = new f.AnimationClip(d.name, d.duration, p), console.log(`✓ Created animation with ${p.length} mapped tracks (from ${d.tracks.length} original tracks)`), g.size > 0 && console.log(
6549
+ B.add(Y), (Y.toLowerCase().includes("arm") || Y.toLowerCase().includes("hand") || Y.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${Y}" could not be mapped to avatar skeleton`);
6550
+ }), B.size > 0 && console.warn(`⚠️ ${B.size} bone(s) could not be mapped:`, Array.from(B).sort().join(", ")), p.length > 0) {
6551
+ d = new y.AnimationClip(d.name, d.duration, p), console.log(`✓ Created animation with ${p.length} mapped tracks (from ${d.tracks.length} original tracks)`), g.size > 0 && console.log(
6552
6552
  `✓ Mapped ${g.size} bone(s):`,
6553
- Array.from(g.entries()).map(([z, A]) => `${z}→${A}`).join(", ")
6553
+ Array.from(g.entries()).map(([I, z]) => `${I}→${z}`).join(", ")
6554
6554
  );
6555
- const I = Array.from(g.values()).filter(
6556
- (z) => z.includes("Arm") || z.includes("Hand") || z.includes("Shoulder")
6555
+ const L = Array.from(g.values()).filter(
6556
+ (I) => I.includes("Arm") || I.includes("Hand") || I.includes("Shoulder")
6557
6557
  );
6558
- I.length > 0 ? console.log(`✓ Arm bones mapped: ${I.join(", ")}`) : console.warn("⚠️ No arm bones were mapped! This may cause arm rigging issues.");
6558
+ L.length > 0 ? console.log(`✓ Arm bones mapped: ${L.join(", ")}`) : console.warn("⚠️ No arm bones were mapped! This may cause arm rigging issues.");
6559
6559
  } else
6560
6560
  console.error("❌ No tracks could be mapped! Animation may not work correctly.");
6561
- const C = {};
6562
- d.tracks.forEach((I) => {
6563
- I.name = I.name.replaceAll("mixamorig", "");
6564
- const z = I.name.split(".");
6565
- if (z[1] === "position") {
6566
- for (let A = 0; A < I.values.length; A++)
6567
- I.values[A] = I.values[A] * s;
6568
- C[I.name] = new f.Vector3(I.values[0], I.values[1], I.values[2]);
6569
- } else z[1] === "quaternion" ? C[I.name] = new f.Quaternion(I.values[0], I.values[1], I.values[2], I.values[3]) : z[1] === "rotation" && (C[z[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(I.values[0], I.values[1], I.values[2], "XYZ")).normalize());
6561
+ const H = {};
6562
+ d.tracks.forEach((L) => {
6563
+ L.name = L.name.replaceAll("mixamorig", "");
6564
+ const I = L.name.split(".");
6565
+ if (I[1] === "position") {
6566
+ for (let z = 0; z < L.values.length; z++)
6567
+ L.values[z] = L.values[z] * s;
6568
+ H[L.name] = new y.Vector3(L.values[0], L.values[1], L.values[2]);
6569
+ } else I[1] === "quaternion" ? H[L.name] = new y.Quaternion(L.values[0], L.values[1], L.values[2], L.values[3]) : I[1] === "rotation" && (H[I[0] + ".quaternion"] = new y.Quaternion().setFromEuler(new y.Euler(L.values[0], L.values[1], L.values[2], "XYZ")).normalize());
6570
6570
  });
6571
- const y = { props: C };
6572
- C["Hips.position"] && (C["Hips.position"].y < 0.5 ? y.lying = !0 : y.standing = !0), this.animClips.push({
6571
+ const v = { props: H };
6572
+ H["Hips.position"] && (H["Hips.position"].y < 0.5 ? v.lying = !0 : v.standing = !0), this.animClips.push({
6573
6573
  url: t + "-" + i,
6574
6574
  clip: d,
6575
- pose: y
6575
+ pose: v
6576
6576
  }), this.playAnimation(t, e, n, i, s);
6577
6577
  } else {
6578
6578
  const d = "Animation " + t + " (ndx=" + i + ") not found";
@@ -6617,7 +6617,7 @@ class Be {
6617
6617
  r.tracks.forEach((d) => {
6618
6618
  d.name = d.name.replaceAll("mixamorig", "");
6619
6619
  const c = d.name.split(".");
6620
- c[1] === "position" ? u[d.name] = new f.Vector3(d.values[0] * s, d.values[1] * s, d.values[2] * s) : c[1] === "quaternion" ? u[d.name] = new f.Quaternion(d.values[0], d.values[1], d.values[2], d.values[3]) : c[1] === "rotation" && (u[c[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(d.values[0], d.values[1], d.values[2], "XYZ")).normalize());
6620
+ c[1] === "position" ? u[d.name] = new y.Vector3(d.values[0] * s, d.values[1] * s, d.values[2] * s) : c[1] === "quaternion" ? u[d.name] = new y.Quaternion(d.values[0], d.values[1], d.values[2], d.values[3]) : c[1] === "rotation" && (u[c[0] + ".quaternion"] = new y.Quaternion().setFromEuler(new y.Euler(d.values[0], d.values[1], d.values[2], "XYZ")).normalize());
6621
6621
  });
6622
6622
  const a = { props: u };
6623
6623
  u["Hips.position"] && (u["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
@@ -6650,7 +6650,7 @@ class Be {
6650
6650
  if (s) {
6651
6651
  this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
6652
6652
  let l = this.animQueue.findIndex((h) => h.template.name === "talkinghands");
6653
- l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((h) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25));
6653
+ l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((h) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new y.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new y.Quaternion(0, 1, 0, 0), -0.25));
6654
6654
  for (let [h, r] of Object.entries(this.gesture))
6655
6655
  r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(h) && (this.poseTarget.props[h].copy(r), this.poseTarget.props[h].t = this.animClock, this.poseTarget.props[h].d = i);
6656
6656
  e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
@@ -6663,9 +6663,9 @@ class Be {
6663
6663
  const h = l.ts[0], u = l.ts[l.ts.length - 1] - h;
6664
6664
  if (e * 1e3 - u > 0) {
6665
6665
  const d = [];
6666
- for (let b = 1; b < l.ts.length; b++) d.push(l.ts[b] - l.ts[b - 1]);
6667
- const c = o.template?.rescale || d.map((b) => b / u), g = e * 1e3 - u;
6668
- l.ts = l.ts.map((b, x, S) => x === 0 ? h : S[x - 1] + d[x - 1] + c[x - 1] * g);
6666
+ for (let x = 1; x < l.ts.length; x++) d.push(l.ts[x] - l.ts[x - 1]);
6667
+ const c = o.template?.rescale || d.map((x) => x / u), g = e * 1e3 - u;
6668
+ l.ts = l.ts.map((x, f, k) => f === 0 ? h : k[f - 1] + d[f - 1] + c[f - 1] * g);
6669
6669
  } else {
6670
6670
  const d = e * 1e3 / u;
6671
6671
  l.ts = l.ts.map((c) => h + d * (c - h));
@@ -6698,34 +6698,34 @@ class Be {
6698
6698
  * @param {numeric} [d=null] If set, apply in d milliseconds
6699
6699
  */
6700
6700
  ikSolve(t, e = null, n = !1, i = null) {
6701
- const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(), h = new f.Vector3(), r = new f.Quaternion(), u = new f.Vector3(), a = new f.Vector3(), d = new f.Vector3(), c = this.ikMesh.getObjectByName(t.root);
6701
+ const s = new y.Vector3(), o = new y.Vector3(), l = new y.Vector3(), h = new y.Vector3(), r = new y.Quaternion(), u = new y.Vector3(), a = new y.Vector3(), d = new y.Vector3(), c = this.ikMesh.getObjectByName(t.root);
6702
6702
  c.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), c.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && n && e.applyQuaternion(this.armature.quaternion).add(c.position);
6703
- const g = this.ikMesh.getObjectByName(t.effector), b = t.links;
6704
- b.forEach((S) => {
6705
- S.bone = this.ikMesh.getObjectByName(S.link), S.bone.quaternion.copy(this.getPoseTemplateProp(S.link + ".quaternion"));
6703
+ const g = this.ikMesh.getObjectByName(t.effector), x = t.links;
6704
+ x.forEach((k) => {
6705
+ k.bone = this.ikMesh.getObjectByName(k.link), k.bone.quaternion.copy(this.getPoseTemplateProp(k.link + ".quaternion"));
6706
6706
  }), c.updateMatrixWorld(!0);
6707
- const x = t.iterations || 10;
6707
+ const f = t.iterations || 10;
6708
6708
  if (e)
6709
- for (let S = 0; S < x; S++) {
6710
- let U = !1;
6711
- for (let p = 0, F = b.length; p < F; p++) {
6712
- const C = b[p].bone;
6713
- C.matrixWorld.decompose(h, r, u), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, h), l.applyQuaternion(r), l.normalize(), s.subVectors(e, h), s.applyQuaternion(r), s.normalize();
6714
- let y = s.dot(l);
6715
- y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (b[p].minAngle !== void 0 && y < b[p].minAngle && (y = b[p].minAngle), b[p].maxAngle !== void 0 && y > b[p].maxAngle && (y = b[p].maxAngle), a.crossVectors(l, s), a.normalize(), _.setFromAxisAngle(a, y), C.quaternion.multiply(_), C.rotation.setFromVector3(d.setFromEuler(C.rotation).clamp(new f.Vector3(
6716
- b[p].minx !== void 0 ? b[p].minx : -1 / 0,
6717
- b[p].miny !== void 0 ? b[p].miny : -1 / 0,
6718
- b[p].minz !== void 0 ? b[p].minz : -1 / 0
6719
- ), new f.Vector3(
6720
- b[p].maxx !== void 0 ? b[p].maxx : 1 / 0,
6721
- b[p].maxy !== void 0 ? b[p].maxy : 1 / 0,
6722
- b[p].maxz !== void 0 ? b[p].maxz : 1 / 0
6723
- ))), C.updateMatrixWorld(!0), U = !0);
6709
+ for (let k = 0; k < f; k++) {
6710
+ let O = !1;
6711
+ for (let p = 0, B = x.length; p < B; p++) {
6712
+ const H = x[p].bone;
6713
+ H.matrixWorld.decompose(h, r, u), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, h), l.applyQuaternion(r), l.normalize(), s.subVectors(e, h), s.applyQuaternion(r), s.normalize();
6714
+ let v = s.dot(l);
6715
+ v > 1 ? v = 1 : v < -1 && (v = -1), v = Math.acos(v), !(v < 1e-5) && (x[p].minAngle !== void 0 && v < x[p].minAngle && (v = x[p].minAngle), x[p].maxAngle !== void 0 && v > x[p].maxAngle && (v = x[p].maxAngle), a.crossVectors(l, s), a.normalize(), J.setFromAxisAngle(a, v), H.quaternion.multiply(J), H.rotation.setFromVector3(d.setFromEuler(H.rotation).clamp(new y.Vector3(
6716
+ x[p].minx !== void 0 ? x[p].minx : -1 / 0,
6717
+ x[p].miny !== void 0 ? x[p].miny : -1 / 0,
6718
+ x[p].minz !== void 0 ? x[p].minz : -1 / 0
6719
+ ), new y.Vector3(
6720
+ x[p].maxx !== void 0 ? x[p].maxx : 1 / 0,
6721
+ x[p].maxy !== void 0 ? x[p].maxy : 1 / 0,
6722
+ x[p].maxz !== void 0 ? x[p].maxz : 1 / 0
6723
+ ))), H.updateMatrixWorld(!0), O = !0);
6724
6724
  }
6725
- if (!U) break;
6725
+ if (!O) break;
6726
6726
  }
6727
- i && b.forEach((S) => {
6728
- this.poseTarget.props[S.link + ".quaternion"].copy(S.bone.quaternion), this.poseTarget.props[S.link + ".quaternion"].t = this.animClock, this.poseTarget.props[S.link + ".quaternion"].d = i;
6727
+ i && x.forEach((k) => {
6728
+ this.poseTarget.props[k.link + ".quaternion"].copy(k.bone.quaternion), this.poseTarget.props[k.link + ".quaternion"].t = this.animClock, this.poseTarget.props[k.link + ".quaternion"].d = i;
6729
6729
  });
6730
6730
  }
6731
6731
  /**
@@ -6784,17 +6784,17 @@ function Ee() {
6784
6784
  voices: Ie.voices
6785
6785
  };
6786
6786
  }
6787
- function kt() {
6788
- const X = Ee(), t = [];
6789
- return Object.entries(X.voices).forEach(([e, n]) => {
6787
+ function wt() {
6788
+ const V = Ee(), t = [];
6789
+ return Object.entries(V.voices).forEach(([e, n]) => {
6790
6790
  t.push({
6791
6791
  value: n,
6792
- label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${X.service})`
6792
+ label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${V.service})`
6793
6793
  });
6794
6794
  }), t;
6795
6795
  }
6796
6796
  const Ve = Me(({
6797
- avatarUrl: X = "/avatars/brunette.glb",
6797
+ avatarUrl: V = "/avatars/brunette.glb",
6798
6798
  avatarBody: t = "F",
6799
6799
  mood: e = "neutral",
6800
6800
  ttsLang: n = "en",
@@ -6812,313 +6812,313 @@ const Ve = Me(({
6812
6812
  onError: c = () => {
6813
6813
  },
6814
6814
  className: g = "",
6815
- style: b = {},
6816
- animations: x = {}
6817
- }, S) => {
6818
- const U = O(null), p = O(null), F = O(r), C = O(null), y = O(null), I = O(!1), z = O({ remainingText: null, originalText: null, options: null }), A = O([]), Y = O(0), [k, E] = ce(!0), [q, G] = ce(null), [ee, se] = ce(!1), [ae, pe] = ce(!1);
6819
- de(() => {
6820
- I.current = ae;
6821
- }, [ae]), de(() => {
6822
- F.current = r;
6815
+ style: x = {},
6816
+ animations: f = {}
6817
+ }, k) => {
6818
+ const O = W(null), p = W(null), B = W(r), H = W(null), v = W(null), L = W(!1), I = W({ remainingText: null, originalText: null, options: null }), z = W([]), Y = W(0), [S, F] = pe(!0), [X, Z] = pe(null), [ne, le] = pe(!1), [ge, de] = pe(!1);
6819
+ ce(() => {
6820
+ L.current = ge;
6821
+ }, [ge]), ce(() => {
6822
+ B.current = r;
6823
6823
  }, [r]);
6824
- const te = Ee(), le = i || te.service;
6825
- let W;
6826
- le === "browser" ? W = {
6824
+ const $ = Ee(), be = i || $.service;
6825
+ let j;
6826
+ be === "browser" ? j = {
6827
6827
  service: "browser",
6828
6828
  endpoint: "",
6829
6829
  apiKey: null,
6830
6830
  defaultVoice: "Google US English"
6831
- } : le === "elevenlabs" ? W = {
6831
+ } : be === "elevenlabs" ? j = {
6832
6832
  service: "elevenlabs",
6833
6833
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
6834
- apiKey: o || te.apiKey,
6835
- defaultVoice: s || te.defaultVoice || Ie.defaultVoice,
6836
- voices: te.voices || Ie.voices
6837
- } : le === "deepgram" ? W = {
6834
+ apiKey: o || $.apiKey,
6835
+ defaultVoice: s || $.defaultVoice || Ie.defaultVoice,
6836
+ voices: $.voices || Ie.voices
6837
+ } : be === "deepgram" ? j = {
6838
6838
  service: "deepgram",
6839
6839
  endpoint: "https://api.deepgram.com/v1/speak",
6840
- apiKey: o || te.apiKey,
6841
- defaultVoice: s || te.defaultVoice || Te.defaultVoice,
6842
- voices: te.voices || Te.voices
6843
- } : W = {
6844
- ...te,
6840
+ apiKey: o || $.apiKey,
6841
+ defaultVoice: s || $.defaultVoice || Te.defaultVoice,
6842
+ voices: $.voices || Te.voices
6843
+ } : j = {
6844
+ ...$,
6845
6845
  // Override API key if provided via props
6846
- apiKey: o !== null ? o : te.apiKey
6846
+ apiKey: o !== null ? o : $.apiKey
6847
6847
  };
6848
- const v = {
6849
- url: X,
6848
+ const b = {
6849
+ url: V,
6850
6850
  body: t,
6851
6851
  avatarMood: e,
6852
- ttsLang: le === "browser" ? "en-US" : n,
6853
- ttsVoice: s || W.defaultVoice,
6852
+ ttsLang: be === "browser" ? "en-US" : n,
6853
+ ttsVoice: s || j.defaultVoice,
6854
6854
  lipsyncLang: "en",
6855
6855
  showFullAvatar: r,
6856
6856
  bodyMovement: l,
6857
6857
  movementIntensity: h
6858
6858
  }, R = {
6859
- ttsEndpoint: W.endpoint,
6860
- ttsApikey: W.apiKey,
6861
- ttsService: le,
6859
+ ttsEndpoint: j.endpoint,
6860
+ ttsApikey: j.apiKey,
6861
+ ttsService: be,
6862
6862
  lipsyncModules: ["en"],
6863
6863
  cameraView: u
6864
- }, H = B(async () => {
6865
- if (!(!U.current || p.current))
6864
+ }, M = N(async () => {
6865
+ if (!(!O.current || p.current))
6866
6866
  try {
6867
- if (E(!0), G(null), p.current = new Be(U.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), x && Object.keys(x).length > 0 && (p.current.customAnimations = x), await p.current.showAvatar(v, (D) => {
6868
- if (D.lengthComputable) {
6869
- const $ = Math.min(100, Math.round(D.loaded / D.total * 100));
6870
- d($);
6867
+ if (F(!0), Z(null), p.current = new Be(O.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), f && Object.keys(f).length > 0 && (p.current.customAnimations = f), await p.current.showAvatar(b, (_) => {
6868
+ if (_.lengthComputable) {
6869
+ const te = Math.min(100, Math.round(_.loaded / _.total * 100));
6870
+ d(te);
6871
6871
  }
6872
- }), await new Promise((D) => {
6873
- const $ = () => {
6874
- p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? D() : setTimeout($, 100);
6872
+ }), await new Promise((_) => {
6873
+ const te = () => {
6874
+ p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? _() : setTimeout(te, 100);
6875
6875
  };
6876
- $();
6876
+ te();
6877
6877
  }), p.current && p.current.setShowFullAvatar)
6878
6878
  try {
6879
6879
  p.current.setShowFullAvatar(r);
6880
- } catch (D) {
6881
- console.warn("Error setting full body mode on initialization:", D);
6880
+ } catch (_) {
6881
+ console.warn("Error setting full body mode on initialization:", _);
6882
6882
  }
6883
- 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()), E(!1), se(!0), a(p.current);
6884
- const N = () => {
6883
+ 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()), F(!1), le(!0), a(p.current);
6884
+ const U = () => {
6885
6885
  document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
6886
6886
  };
6887
- return document.addEventListener("visibilitychange", N), () => {
6888
- document.removeEventListener("visibilitychange", N);
6887
+ return document.addEventListener("visibilitychange", U), () => {
6888
+ document.removeEventListener("visibilitychange", U);
6889
6889
  };
6890
- } catch (L) {
6891
- console.error("Error initializing TalkingHead:", L), G(L.message || "Failed to initialize avatar"), E(!1), c(L);
6890
+ } catch (w) {
6891
+ console.error("Error initializing TalkingHead:", w), Z(w.message || "Failed to initialize avatar"), F(!1), c(w);
6892
6892
  }
6893
- }, [X, t, e, n, i, s, o, r, l, h, u]);
6894
- de(() => (H(), () => {
6893
+ }, [V, t, e, n, i, s, o, r, l, h, u]);
6894
+ ce(() => (M(), () => {
6895
6895
  p.current && (p.current.stop(), p.current.dispose(), p.current = null);
6896
- }), [H]), de(() => {
6897
- if (!U.current || !p.current) return;
6898
- const L = new ResizeObserver((D) => {
6899
- for (const $ of D)
6896
+ }), [M]), ce(() => {
6897
+ if (!O.current || !p.current) return;
6898
+ const w = new ResizeObserver((_) => {
6899
+ for (const te of _)
6900
6900
  p.current && p.current.onResize && p.current.onResize();
6901
6901
  });
6902
- L.observe(U.current);
6903
- const N = () => {
6902
+ w.observe(O.current);
6903
+ const U = () => {
6904
6904
  p.current && p.current.onResize && p.current.onResize();
6905
6905
  };
6906
- return window.addEventListener("resize", N), () => {
6907
- L.disconnect(), window.removeEventListener("resize", N);
6906
+ return window.addEventListener("resize", U), () => {
6907
+ w.disconnect(), window.removeEventListener("resize", U);
6908
6908
  };
6909
- }, [ee]);
6910
- const P = B(async () => {
6909
+ }, [ne]);
6910
+ const E = N(async () => {
6911
6911
  if (p.current && p.current.audioCtx)
6912
6912
  try {
6913
6913
  (p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
6914
- } catch (L) {
6915
- console.warn("Failed to resume audio context:", L);
6914
+ } catch (w) {
6915
+ console.warn("Failed to resume audio context:", w);
6916
6916
  }
6917
- }, []), V = B(async (L, N = {}) => {
6918
- if (p.current && ee)
6917
+ }, []), D = N(async (w, U = {}) => {
6918
+ if (p.current && ne)
6919
6919
  try {
6920
- y.current && (clearInterval(y.current), y.current = null), C.current = { text: L, options: N }, z.current = { remainingText: null, originalText: null, options: null };
6921
- const D = /[!\.\?\n\p{Extended_Pictographic}]/ug, $ = L.split(D).map((j) => j.trim()).filter((j) => j.length > 0);
6922
- A.current = $, Y.current = 0, pe(!1), I.current = !1, await P();
6923
- const ge = {
6924
- ...N,
6925
- lipsyncLang: N.lipsyncLang || v.lipsyncLang || "en"
6920
+ v.current && (clearInterval(v.current), v.current = null), H.current = { text: w, options: U }, I.current = { remainingText: null, originalText: null, options: null };
6921
+ const _ = /[!\.\?\n\p{Extended_Pictographic}]/ug, te = w.split(_).map((A) => A.trim()).filter((A) => A.length > 0);
6922
+ z.current = te, Y.current = 0, de(!1), L.current = !1, await E();
6923
+ const me = {
6924
+ ...U,
6925
+ lipsyncLang: U.lipsyncLang || b.lipsyncLang || "en"
6926
6926
  };
6927
- if (N.onSpeechEnd && p.current) {
6928
- const j = p.current;
6929
- let he = null, Se = 0;
6930
- const Le = 1200;
6931
- let be = !1;
6932
- he = setInterval(() => {
6933
- if (Se++, I.current)
6927
+ if (U.onSpeechEnd && p.current) {
6928
+ const A = p.current;
6929
+ let P = null, K = 0;
6930
+ const ie = 1200;
6931
+ let se = !1;
6932
+ P = setInterval(() => {
6933
+ if (K++, L.current)
6934
6934
  return;
6935
- if (Se > Le) {
6936
- if (he && (clearInterval(he), he = null, y.current = null), !be && !I.current) {
6937
- be = !0;
6935
+ if (K > ie) {
6936
+ if (P && (clearInterval(P), P = null, v.current = null), !se && !L.current) {
6937
+ se = !0;
6938
6938
  try {
6939
- N.onSpeechEnd();
6939
+ U.onSpeechEnd();
6940
6940
  } catch (Ne) {
6941
6941
  console.error("Error in onSpeechEnd callback (timeout):", Ne);
6942
6942
  }
6943
6943
  }
6944
6944
  return;
6945
6945
  }
6946
- const ye = !j.speechQueue || j.speechQueue.length === 0, ke = !j.audioPlaylist || j.audioPlaylist.length === 0;
6947
- j && j.isSpeaking === !1 && ye && ke && j.isAudioPlaying === !1 && !be && !I.current && setTimeout(() => {
6948
- if (j && !I.current && j.isSpeaking === !1 && (!j.speechQueue || j.speechQueue.length === 0) && (!j.audioPlaylist || j.audioPlaylist.length === 0) && j.isAudioPlaying === !1 && !be && !I.current) {
6949
- be = !0, he && (clearInterval(he), he = null, y.current = null);
6946
+ const oe = !A.speechQueue || A.speechQueue.length === 0, we = !A.audioPlaylist || A.audioPlaylist.length === 0;
6947
+ A && A.isSpeaking === !1 && oe && we && A.isAudioPlaying === !1 && !se && !L.current && setTimeout(() => {
6948
+ if (A && !L.current && A.isSpeaking === !1 && (!A.speechQueue || A.speechQueue.length === 0) && (!A.audioPlaylist || A.audioPlaylist.length === 0) && A.isAudioPlaying === !1 && !se && !L.current) {
6949
+ se = !0, P && (clearInterval(P), P = null, v.current = null);
6950
6950
  try {
6951
- N.onSpeechEnd();
6951
+ U.onSpeechEnd();
6952
6952
  } catch (Ze) {
6953
6953
  console.error("Error in onSpeechEnd callback:", Ze);
6954
6954
  }
6955
6955
  }
6956
6956
  }, 100);
6957
- }, 100), y.current = he;
6957
+ }, 100), v.current = P;
6958
6958
  }
6959
- 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 () => {
6960
- await P(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
6959
+ p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(w, me)) : setTimeout(async () => {
6960
+ await E(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(w, me));
6961
6961
  }, 100);
6962
- } catch (D) {
6963
- console.error("Error speaking text:", D), G(D.message || "Failed to speak text");
6962
+ } catch (_) {
6963
+ console.error("Error speaking text:", _), Z(_.message || "Failed to speak text");
6964
6964
  }
6965
- }, [ee, P, v.lipsyncLang]), J = B(() => {
6966
- p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), C.current = null, pe(!1));
6967
- }, []), Q = B(() => {
6965
+ }, [ne, E, b.lipsyncLang]), ee = N(() => {
6966
+ p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), H.current = null, de(!1));
6967
+ }, []), Q = N(() => {
6968
6968
  if (p.current && p.current.pauseSpeaking) {
6969
- const L = p.current;
6970
- if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
6971
- y.current && (clearInterval(y.current), y.current = null);
6972
- let D = "";
6973
- if (C.current && A.current.length > 0) {
6974
- const $ = A.current.length, ge = L.speechQueue ? L.speechQueue.filter((Le) => Le && Le.text && Array.isArray(Le.text) && Le.text.length > 0).length : 0, j = L.audioPlaylist && L.audioPlaylist.length > 0, he = ge + (j ? 1 : 0), Se = $ - he;
6975
- if (he > 0 && Se < $ && (D = A.current.slice(Se).join(". ").trim(), !D && ge > 0 && L.speechQueue)) {
6976
- 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(" ");
6977
- be && be.trim() && (D = be.trim());
6969
+ const w = p.current;
6970
+ if (w.isSpeaking || w.audioPlaylist && w.audioPlaylist.length > 0 || w.speechQueue && w.speechQueue.length > 0) {
6971
+ v.current && (clearInterval(v.current), v.current = null);
6972
+ let _ = "";
6973
+ if (H.current && z.current.length > 0) {
6974
+ const te = z.current.length, me = w.speechQueue ? w.speechQueue.filter((ie) => ie && ie.text && Array.isArray(ie.text) && ie.text.length > 0).length : 0, A = w.audioPlaylist && w.audioPlaylist.length > 0, P = me + (A ? 1 : 0), K = te - P;
6975
+ if (P > 0 && K < te && (_ = z.current.slice(K).join(". ").trim(), !_ && me > 0 && w.speechQueue)) {
6976
+ const se = w.speechQueue.filter((oe) => oe && oe.text && Array.isArray(oe.text) && oe.text.length > 0).map((oe) => oe.text.map((we) => we.word || "").filter((we) => we.length > 0).join(" ")).filter((oe) => oe.length > 0).join(" ");
6977
+ se && se.trim() && (_ = se.trim());
6978
6978
  }
6979
6979
  }
6980
- C.current && (z.current = {
6981
- remainingText: D || null,
6982
- originalText: C.current.text,
6983
- options: C.current.options
6984
- }), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), I.current = !0, pe(!0);
6980
+ H.current && (I.current = {
6981
+ remainingText: _ || null,
6982
+ originalText: H.current.text,
6983
+ options: H.current.options
6984
+ }), w.speechQueue && (w.speechQueue.length = 0), p.current.pauseSpeaking(), L.current = !0, de(!0);
6985
6985
  }
6986
6986
  }
6987
- }, []), K = B(async () => {
6988
- if (!p.current || !ae)
6987
+ }, []), q = N(async () => {
6988
+ if (!p.current || !ge)
6989
6989
  return;
6990
- let L = "", N = {};
6991
- if (z.current && z.current.remainingText)
6992
- L = z.current.remainingText, N = z.current.options || {}, z.current = { remainingText: null, originalText: null, options: null };
6993
- else if (C.current && C.current.text)
6994
- L = C.current.text, N = C.current.options || {};
6990
+ let w = "", U = {};
6991
+ if (I.current && I.current.remainingText)
6992
+ w = I.current.remainingText, U = I.current.options || {}, I.current = { remainingText: null, originalText: null, options: null };
6993
+ else if (H.current && H.current.text)
6994
+ w = H.current.text, U = H.current.options || {};
6995
6995
  else {
6996
- console.warn("Resume called but no paused speech found"), pe(!1), I.current = !1;
6996
+ console.warn("Resume called but no paused speech found"), de(!1), L.current = !1;
6997
6997
  return;
6998
6998
  }
6999
- pe(!1), I.current = !1, await P();
7000
- const D = {
7001
- ...N,
7002
- lipsyncLang: N.lipsyncLang || v.lipsyncLang || "en"
6999
+ de(!1), L.current = !1, await E();
7000
+ const _ = {
7001
+ ...U,
7002
+ lipsyncLang: U.lipsyncLang || b.lipsyncLang || "en"
7003
7003
  };
7004
7004
  try {
7005
- await V(L, D);
7006
- } catch ($) {
7007
- console.error("Error resuming speech:", $), pe(!1), I.current = !1;
7005
+ await D(w, _);
7006
+ } catch (te) {
7007
+ console.error("Error resuming speech:", te), de(!1), L.current = !1;
7008
7008
  }
7009
- }, [P, ae, V, v]), Ae = B((L) => {
7010
- p.current && p.current.setMood(L);
7011
- }, []), we = B((L) => {
7012
- p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
7013
- }, []), M = B((L, N = !1) => {
7009
+ }, [E, ge, D, b]), Ae = N((w) => {
7010
+ p.current && p.current.setMood(w);
7011
+ }, []), Se = N((w) => {
7012
+ p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(w);
7013
+ }, []), Le = N((w, U = !1) => {
7014
7014
  if (p.current && p.current.playAnimation) {
7015
- if (x && x[L] && (L = x[L]), p.current.setShowFullAvatar)
7015
+ if (f && f[w] && (w = f[w]), p.current.setShowFullAvatar)
7016
7016
  try {
7017
- p.current.setShowFullAvatar(F.current);
7018
- } catch ($) {
7019
- console.warn("Error setting full body mode:", $);
7017
+ p.current.setShowFullAvatar(B.current);
7018
+ } catch (te) {
7019
+ console.warn("Error setting full body mode:", te);
7020
7020
  }
7021
- if (L.includes("."))
7021
+ if (w.includes("."))
7022
7022
  try {
7023
- p.current.playAnimation(L, null, 10, 0, 0.01, N);
7024
- } catch ($) {
7025
- console.warn(`Failed to play ${L}:`, $);
7023
+ p.current.playAnimation(w, null, 10, 0, 0.01, U);
7024
+ } catch (te) {
7025
+ console.warn(`Failed to play ${w}:`, te);
7026
7026
  try {
7027
7027
  p.current.setBodyMovement("idle");
7028
- } catch (ge) {
7029
- console.warn("Fallback animation also failed:", ge);
7028
+ } catch (me) {
7029
+ console.warn("Fallback animation also failed:", me);
7030
7030
  }
7031
7031
  }
7032
7032
  else {
7033
- const $ = [".fbx", ".glb", ".gltf"];
7034
- let ge = !1;
7035
- for (const j of $)
7033
+ const te = [".fbx", ".glb", ".gltf"];
7034
+ let me = !1;
7035
+ for (const A of te)
7036
7036
  try {
7037
- p.current.playAnimation(L + j, null, 10, 0, 0.01, N), ge = !0;
7037
+ p.current.playAnimation(w + A, null, 10, 0, 0.01, U), me = !0;
7038
7038
  break;
7039
7039
  } catch {
7040
7040
  }
7041
- if (!ge) {
7042
- console.warn("Animation not found:", L);
7041
+ if (!me) {
7042
+ console.warn("Animation not found:", w);
7043
7043
  try {
7044
7044
  p.current.setBodyMovement("idle");
7045
- } catch (j) {
7046
- console.warn("Fallback animation also failed:", j);
7045
+ } catch (A) {
7046
+ console.warn("Fallback animation also failed:", A);
7047
7047
  }
7048
7048
  }
7049
7049
  }
7050
7050
  }
7051
- }, [x]), ne = B(() => {
7051
+ }, [f]), ke = N(() => {
7052
7052
  p.current && p.current.onResize && p.current.onResize();
7053
7053
  }, []);
7054
- return Fe(S, () => ({
7055
- speakText: V,
7056
- stopSpeaking: J,
7054
+ return Fe(k, () => ({
7055
+ speakText: D,
7056
+ stopSpeaking: ee,
7057
7057
  pauseSpeaking: Q,
7058
- resumeSpeaking: K,
7059
- resumeAudioContext: P,
7058
+ resumeSpeaking: q,
7059
+ resumeAudioContext: E,
7060
7060
  setMood: Ae,
7061
- setTimingAdjustment: we,
7062
- playAnimation: M,
7063
- isReady: ee,
7064
- isPaused: ae,
7061
+ setTimingAdjustment: Se,
7062
+ playAnimation: Le,
7063
+ isReady: ne,
7064
+ isPaused: ge,
7065
7065
  talkingHead: p.current,
7066
- handleResize: ne,
7067
- setBodyMovement: (L) => {
7066
+ handleResize: ke,
7067
+ setBodyMovement: (w) => {
7068
7068
  if (p.current && p.current.setShowFullAvatar && p.current.setBodyMovement)
7069
7069
  try {
7070
- p.current.setShowFullAvatar(F.current), p.current.setBodyMovement(L);
7071
- } catch (N) {
7072
- console.warn("Error setting body movement:", N);
7070
+ p.current.setShowFullAvatar(B.current), p.current.setBodyMovement(w);
7071
+ } catch (U) {
7072
+ console.warn("Error setting body movement:", U);
7073
7073
  }
7074
7074
  },
7075
- setMovementIntensity: (L) => p.current?.setMovementIntensity(L),
7075
+ setMovementIntensity: (w) => p.current?.setMovementIntensity(w),
7076
7076
  playRandomDance: () => {
7077
7077
  if (p.current && p.current.setShowFullAvatar && p.current.playRandomDance)
7078
7078
  try {
7079
- p.current.setShowFullAvatar(F.current), p.current.playRandomDance();
7080
- } catch (L) {
7081
- console.warn("Error playing random dance:", L);
7079
+ p.current.setShowFullAvatar(B.current), p.current.playRandomDance();
7080
+ } catch (w) {
7081
+ console.warn("Error playing random dance:", w);
7082
7082
  }
7083
7083
  },
7084
- playReaction: (L) => {
7084
+ playReaction: (w) => {
7085
7085
  if (p.current && p.current.setShowFullAvatar && p.current.playReaction)
7086
7086
  try {
7087
- p.current.setShowFullAvatar(F.current), p.current.playReaction(L);
7088
- } catch (N) {
7089
- console.warn("Error playing reaction:", N);
7087
+ p.current.setShowFullAvatar(B.current), p.current.playReaction(w);
7088
+ } catch (U) {
7089
+ console.warn("Error playing reaction:", U);
7090
7090
  }
7091
7091
  },
7092
7092
  playCelebration: () => {
7093
7093
  if (p.current && p.current.setShowFullAvatar && p.current.playCelebration)
7094
7094
  try {
7095
- p.current.setShowFullAvatar(F.current), p.current.playCelebration();
7096
- } catch (L) {
7097
- console.warn("Error playing celebration:", L);
7095
+ p.current.setShowFullAvatar(B.current), p.current.playCelebration();
7096
+ } catch (w) {
7097
+ console.warn("Error playing celebration:", w);
7098
7098
  }
7099
7099
  },
7100
- setShowFullAvatar: (L) => {
7100
+ setShowFullAvatar: (w) => {
7101
7101
  if (p.current && p.current.setShowFullAvatar)
7102
7102
  try {
7103
- F.current = L, p.current.setShowFullAvatar(L);
7104
- } catch (N) {
7105
- console.warn("Error setting showFullAvatar:", N);
7103
+ B.current = w, p.current.setShowFullAvatar(w);
7104
+ } catch (U) {
7105
+ console.warn("Error setting showFullAvatar:", U);
7106
7106
  }
7107
7107
  },
7108
7108
  lockAvatarPosition: () => {
7109
7109
  if (p.current && p.current.lockAvatarPosition)
7110
7110
  try {
7111
7111
  p.current.lockAvatarPosition();
7112
- } catch (L) {
7113
- console.warn("Error locking avatar position:", L);
7112
+ } catch (w) {
7113
+ console.warn("Error locking avatar position:", w);
7114
7114
  }
7115
7115
  },
7116
7116
  unlockAvatarPosition: () => {
7117
7117
  if (p.current && p.current.unlockAvatarPosition)
7118
7118
  try {
7119
7119
  p.current.unlockAvatarPosition();
7120
- } catch (L) {
7121
- console.warn("Error unlocking avatar position:", L);
7120
+ } catch (w) {
7121
+ console.warn("Error unlocking avatar position:", w);
7122
7122
  }
7123
7123
  }
7124
7124
  })), /* @__PURE__ */ Pe(
@@ -7129,13 +7129,13 @@ const Ve = Me(({
7129
7129
  width: "100%",
7130
7130
  height: "100%",
7131
7131
  position: "relative",
7132
- ...b
7132
+ ...x
7133
7133
  },
7134
7134
  children: [
7135
- /* @__PURE__ */ me(
7135
+ /* @__PURE__ */ ye(
7136
7136
  "div",
7137
7137
  {
7138
- ref: U,
7138
+ ref: O,
7139
7139
  className: "talking-head-viewer",
7140
7140
  style: {
7141
7141
  width: "100%",
@@ -7144,7 +7144,7 @@ const Ve = Me(({
7144
7144
  }
7145
7145
  }
7146
7146
  ),
7147
- k && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7147
+ S && /* @__PURE__ */ ye("div", { className: "loading-overlay", style: {
7148
7148
  position: "absolute",
7149
7149
  top: "50%",
7150
7150
  left: "50%",
@@ -7153,7 +7153,7 @@ const Ve = Me(({
7153
7153
  fontSize: "18px",
7154
7154
  zIndex: 10
7155
7155
  }, children: "Loading avatar..." }),
7156
- q && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
7156
+ X && /* @__PURE__ */ ye("div", { className: "error-overlay", style: {
7157
7157
  position: "absolute",
7158
7158
  top: "50%",
7159
7159
  left: "50%",
@@ -7164,14 +7164,14 @@ const Ve = Me(({
7164
7164
  zIndex: 10,
7165
7165
  padding: "20px",
7166
7166
  borderRadius: "8px"
7167
- }, children: q })
7167
+ }, children: X })
7168
7168
  ]
7169
7169
  }
7170
7170
  );
7171
7171
  });
7172
7172
  Ve.displayName = "TalkingHeadAvatar";
7173
7173
  const pt = Me(({
7174
- text: X = "Hello! I'm a talking avatar. How are you today?",
7174
+ text: V = "Hello! I'm a talking avatar. How are you today?",
7175
7175
  onLoading: t = () => {
7176
7176
  },
7177
7177
  onError: e = () => {
@@ -7182,23 +7182,23 @@ const pt = Me(({
7182
7182
  style: s = {},
7183
7183
  avatarConfig: o = {}
7184
7184
  }, l) => {
7185
- const h = O(null), r = O(null), [u, a] = ce(!0), [d, c] = ce(null), [g, b] = ce(!1), x = Ee(), S = o.ttsService || x.service, U = S === "browser" ? {
7185
+ const h = W(null), r = W(null), [u, a] = pe(!0), [d, c] = pe(null), [g, x] = pe(!1), f = Ee(), k = o.ttsService || f.service, O = k === "browser" ? {
7186
7186
  endpoint: "",
7187
7187
  apiKey: null,
7188
7188
  defaultVoice: "Google US English"
7189
7189
  } : {
7190
- ...x,
7190
+ ...f,
7191
7191
  // Override API key if provided via avatarConfig
7192
- apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : x.apiKey,
7192
+ apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : f.apiKey,
7193
7193
  // Override endpoint for ElevenLabs if service is explicitly set
7194
- endpoint: S === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : x.endpoint
7194
+ endpoint: k === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : f.endpoint
7195
7195
  }, p = {
7196
7196
  url: "/avatars/brunette.glb",
7197
7197
  // Use brunette avatar (working glTF file)
7198
7198
  body: "F",
7199
7199
  avatarMood: "neutral",
7200
- ttsLang: S === "browser" ? "en-US" : "en",
7201
- ttsVoice: o.ttsVoice || U.defaultVoice,
7200
+ ttsLang: k === "browser" ? "en-US" : "en",
7201
+ ttsVoice: o.ttsVoice || O.defaultVoice,
7202
7202
  lipsyncLang: "en",
7203
7203
  // English lip-sync
7204
7204
  showFullAvatar: !0,
@@ -7206,176 +7206,176 @@ const pt = Me(({
7206
7206
  bodyMovement: "idle",
7207
7207
  movementIntensity: 0.5,
7208
7208
  ...o
7209
- }, F = {
7210
- ttsEndpoint: U.endpoint,
7211
- ttsApikey: U.apiKey,
7212
- ttsService: S,
7209
+ }, B = {
7210
+ ttsEndpoint: O.endpoint,
7211
+ ttsApikey: O.apiKey,
7212
+ ttsService: k,
7213
7213
  lipsyncModules: ["en"],
7214
7214
  cameraView: "upper"
7215
- }, C = B(async () => {
7215
+ }, H = N(async () => {
7216
7216
  if (!(!h.current || r.current))
7217
7217
  try {
7218
- if (a(!0), c(null), r.current = new Be(h.current, F), await r.current.showAvatar(p, (q) => {
7219
- if (q.lengthComputable) {
7220
- const G = Math.min(100, Math.round(q.loaded / q.total * 100));
7221
- t(G);
7218
+ if (a(!0), c(null), r.current = new Be(h.current, B), await r.current.showAvatar(p, (X) => {
7219
+ if (X.lengthComputable) {
7220
+ const Z = Math.min(100, Math.round(X.loaded / X.total * 100));
7221
+ t(Z);
7222
7222
  }
7223
7223
  }), r.current.morphs && r.current.morphs.length > 0) {
7224
- const q = r.current.morphs[0].morphTargetDictionary;
7225
- console.log("Available morph targets:", Object.keys(q));
7226
- const G = Object.keys(q).filter((ee) => ee.startsWith("viseme_"));
7227
- console.log("Viseme morph targets found:", G), G.length === 0 && (console.warn("No viseme morph targets found! Lip-sync will not work properly."), console.log("Expected viseme targets: viseme_aa, viseme_E, viseme_I, viseme_O, viseme_U, viseme_PP, viseme_SS, viseme_TH, viseme_DD, viseme_FF, viseme_kk, viseme_nn, viseme_RR, viseme_CH, viseme_sil"));
7224
+ const X = r.current.morphs[0].morphTargetDictionary;
7225
+ console.log("Available morph targets:", Object.keys(X));
7226
+ const Z = Object.keys(X).filter((ne) => ne.startsWith("viseme_"));
7227
+ console.log("Viseme morph targets found:", Z), Z.length === 0 && (console.warn("No viseme morph targets found! Lip-sync will not work properly."), console.log("Expected viseme targets: viseme_aa, viseme_E, viseme_I, viseme_O, viseme_U, viseme_PP, viseme_SS, viseme_TH, viseme_DD, viseme_FF, viseme_kk, viseme_nn, viseme_RR, viseme_CH, viseme_sil"));
7228
7228
  }
7229
- if (await new Promise((q) => {
7230
- const G = () => {
7231
- r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), q()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(G, 100));
7229
+ if (await new Promise((X) => {
7230
+ const Z = () => {
7231
+ r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), X()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(Z, 100));
7232
7232
  };
7233
- G();
7233
+ Z();
7234
7234
  }), r.current && r.current.setShowFullAvatar)
7235
7235
  try {
7236
7236
  r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
7237
- } catch (q) {
7238
- console.warn("Error setting full body mode on initialization:", q);
7237
+ } catch (X) {
7238
+ console.warn("Error setting full body mode on initialization:", X);
7239
7239
  }
7240
- a(!1), b(!0), n(r.current);
7241
- const E = () => {
7240
+ a(!1), x(!0), n(r.current);
7241
+ const F = () => {
7242
7242
  document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
7243
7243
  };
7244
- return document.addEventListener("visibilitychange", E), () => {
7245
- document.removeEventListener("visibilitychange", E);
7244
+ return document.addEventListener("visibilitychange", F), () => {
7245
+ document.removeEventListener("visibilitychange", F);
7246
7246
  };
7247
- } catch (k) {
7248
- console.error("Error initializing TalkingHead:", k), c(k.message || "Failed to initialize avatar"), a(!1), e(k);
7247
+ } catch (S) {
7248
+ console.error("Error initializing TalkingHead:", S), c(S.message || "Failed to initialize avatar"), a(!1), e(S);
7249
7249
  }
7250
7250
  }, []);
7251
- de(() => (C(), () => {
7251
+ ce(() => (H(), () => {
7252
7252
  r.current && (r.current.stop(), r.current.dispose(), r.current = null);
7253
- }), [C]);
7254
- const y = B((k) => {
7253
+ }), [H]);
7254
+ const v = N((S) => {
7255
7255
  if (r.current && g)
7256
7256
  try {
7257
- console.log("Speaking text:", k), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(k)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7258
- r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(k)) : console.error("Lip-sync still not ready after waiting");
7257
+ 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(() => {
7258
+ 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");
7259
7259
  }, 500));
7260
- } catch (E) {
7261
- console.error("Error speaking text:", E), c(E.message || "Failed to speak text");
7260
+ } catch (F) {
7261
+ console.error("Error speaking text:", F), c(F.message || "Failed to speak text");
7262
7262
  }
7263
7263
  else
7264
7264
  console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
7265
- }, [g, p]), I = B(() => {
7265
+ }, [g, p]), L = N(() => {
7266
7266
  r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7267
- }, []), z = B((k) => {
7268
- r.current && r.current.setMood(k);
7269
- }, []), A = B((k) => {
7270
- r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(k), console.log("Timing adjustment set to:", k));
7271
- }, []), Y = B((k, E = !1) => {
7267
+ }, []), I = N((S) => {
7268
+ r.current && r.current.setMood(S);
7269
+ }, []), z = N((S) => {
7270
+ r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
7271
+ }, []), Y = N((S, F = !1) => {
7272
7272
  if (r.current && r.current.playAnimation) {
7273
7273
  if (r.current.setShowFullAvatar)
7274
7274
  try {
7275
7275
  r.current.setShowFullAvatar(!0);
7276
- } catch (G) {
7277
- console.warn("Error setting full body mode:", G);
7276
+ } catch (Z) {
7277
+ console.warn("Error setting full body mode:", Z);
7278
7278
  }
7279
- if (k.includes("."))
7279
+ if (S.includes("."))
7280
7280
  try {
7281
- r.current.playAnimation(k, null, 10, 0, 0.01, E), console.log("Playing animation:", k);
7282
- } catch (G) {
7283
- console.log(`Failed to play ${k}:`, G);
7281
+ r.current.playAnimation(S, null, 10, 0, 0.01, F), console.log("Playing animation:", S);
7282
+ } catch (Z) {
7283
+ console.log(`Failed to play ${S}:`, Z);
7284
7284
  try {
7285
7285
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7286
- } catch (ee) {
7287
- console.warn("Fallback animation also failed:", ee);
7286
+ } catch (ne) {
7287
+ console.warn("Fallback animation also failed:", ne);
7288
7288
  }
7289
7289
  }
7290
7290
  else {
7291
- const G = [".fbx", ".glb", ".gltf"];
7292
- let ee = !1;
7293
- for (const se of G)
7291
+ const Z = [".fbx", ".glb", ".gltf"];
7292
+ let ne = !1;
7293
+ for (const le of Z)
7294
7294
  try {
7295
- r.current.playAnimation(k + se, null, 10, 0, 0.01, E), console.log("Playing animation:", k + se), ee = !0;
7295
+ r.current.playAnimation(S + le, null, 10, 0, 0.01, F), console.log("Playing animation:", S + le), ne = !0;
7296
7296
  break;
7297
7297
  } catch {
7298
- console.log(`Failed to play ${k}${se}, trying next format...`);
7298
+ console.log(`Failed to play ${S}${le}, trying next format...`);
7299
7299
  }
7300
- if (!ee) {
7301
- console.warn("Animation system not available or animation not found:", k);
7300
+ if (!ne) {
7301
+ console.warn("Animation system not available or animation not found:", S);
7302
7302
  try {
7303
7303
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7304
- } catch (se) {
7305
- console.warn("Fallback animation also failed:", se);
7304
+ } catch (le) {
7305
+ console.warn("Fallback animation also failed:", le);
7306
7306
  }
7307
7307
  }
7308
7308
  }
7309
7309
  } else
7310
- console.warn("Animation system not available or animation not found:", k);
7310
+ console.warn("Animation system not available or animation not found:", S);
7311
7311
  }, []);
7312
7312
  return Fe(l, () => ({
7313
- speakText: y,
7314
- stopSpeaking: I,
7315
- setMood: z,
7316
- setTimingAdjustment: A,
7313
+ speakText: v,
7314
+ stopSpeaking: L,
7315
+ setMood: I,
7316
+ setTimingAdjustment: z,
7317
7317
  playAnimation: Y,
7318
7318
  isReady: g,
7319
7319
  talkingHead: r.current,
7320
- setBodyMovement: (k) => {
7320
+ setBodyMovement: (S) => {
7321
7321
  if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
7322
7322
  try {
7323
- r.current.setShowFullAvatar(!0), r.current.setBodyMovement(k), console.log("Body movement set with full body mode:", k);
7324
- } catch (E) {
7325
- console.warn("Error setting body movement:", E);
7323
+ r.current.setShowFullAvatar(!0), r.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
7324
+ } catch (F) {
7325
+ console.warn("Error setting body movement:", F);
7326
7326
  }
7327
7327
  },
7328
- setMovementIntensity: (k) => r.current?.setMovementIntensity(k),
7328
+ setMovementIntensity: (S) => r.current?.setMovementIntensity(S),
7329
7329
  playRandomDance: () => {
7330
7330
  if (r.current && r.current.setShowFullAvatar && r.current.playRandomDance)
7331
7331
  try {
7332
7332
  r.current.setShowFullAvatar(!0), r.current.playRandomDance(), console.log("Random dance played with full body mode");
7333
- } catch (k) {
7334
- console.warn("Error playing random dance:", k);
7333
+ } catch (S) {
7334
+ console.warn("Error playing random dance:", S);
7335
7335
  }
7336
7336
  },
7337
- playReaction: (k) => {
7337
+ playReaction: (S) => {
7338
7338
  if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
7339
7339
  try {
7340
- r.current.setShowFullAvatar(!0), r.current.playReaction(k), console.log("Reaction played with full body mode:", k);
7341
- } catch (E) {
7342
- console.warn("Error playing reaction:", E);
7340
+ r.current.setShowFullAvatar(!0), r.current.playReaction(S), console.log("Reaction played with full body mode:", S);
7341
+ } catch (F) {
7342
+ console.warn("Error playing reaction:", F);
7343
7343
  }
7344
7344
  },
7345
7345
  playCelebration: () => {
7346
7346
  if (r.current && r.current.setShowFullAvatar && r.current.playCelebration)
7347
7347
  try {
7348
7348
  r.current.setShowFullAvatar(!0), r.current.playCelebration(), console.log("Celebration played with full body mode");
7349
- } catch (k) {
7350
- console.warn("Error playing celebration:", k);
7349
+ } catch (S) {
7350
+ console.warn("Error playing celebration:", S);
7351
7351
  }
7352
7352
  },
7353
- setShowFullAvatar: (k) => {
7353
+ setShowFullAvatar: (S) => {
7354
7354
  if (r.current && r.current.setShowFullAvatar)
7355
7355
  try {
7356
- r.current.setShowFullAvatar(k), console.log("Show full avatar set to:", k);
7357
- } catch (E) {
7358
- console.warn("Error setting showFullAvatar:", E);
7356
+ r.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
7357
+ } catch (F) {
7358
+ console.warn("Error setting showFullAvatar:", F);
7359
7359
  }
7360
7360
  },
7361
7361
  lockAvatarPosition: () => {
7362
7362
  if (r.current && r.current.lockAvatarPosition)
7363
7363
  try {
7364
7364
  r.current.lockAvatarPosition();
7365
- } catch (k) {
7366
- console.warn("Error locking avatar position:", k);
7365
+ } catch (S) {
7366
+ console.warn("Error locking avatar position:", S);
7367
7367
  }
7368
7368
  },
7369
7369
  unlockAvatarPosition: () => {
7370
7370
  if (r.current && r.current.unlockAvatarPosition)
7371
7371
  try {
7372
7372
  r.current.unlockAvatarPosition();
7373
- } catch (k) {
7374
- console.warn("Error unlocking avatar position:", k);
7373
+ } catch (S) {
7374
+ console.warn("Error unlocking avatar position:", S);
7375
7375
  }
7376
7376
  }
7377
7377
  })), /* @__PURE__ */ Pe("div", { className: `talking-head-container ${i}`, style: s, children: [
7378
- /* @__PURE__ */ me(
7378
+ /* @__PURE__ */ ye(
7379
7379
  "div",
7380
7380
  {
7381
7381
  ref: h,
@@ -7387,7 +7387,7 @@ const pt = Me(({
7387
7387
  }
7388
7388
  }
7389
7389
  ),
7390
- u && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7390
+ u && /* @__PURE__ */ ye("div", { className: "loading-overlay", style: {
7391
7391
  position: "absolute",
7392
7392
  top: "50%",
7393
7393
  left: "50%",
@@ -7396,7 +7396,7 @@ const pt = Me(({
7396
7396
  fontSize: "18px",
7397
7397
  zIndex: 10
7398
7398
  }, children: "Loading avatar..." }),
7399
- d && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
7399
+ d && /* @__PURE__ */ ye("div", { className: "error-overlay", style: {
7400
7400
  position: "absolute",
7401
7401
  top: "50%",
7402
7402
  left: "50%",
@@ -7411,8 +7411,15 @@ const pt = Me(({
7411
7411
  ] });
7412
7412
  });
7413
7413
  pt.displayName = "TalkingHeadComponent";
7414
- const gt = Me(({
7415
- text: X = null,
7414
+ async function gt(V) {
7415
+ try {
7416
+ return (await (await fetch(V)).json()).animations || {};
7417
+ } catch (t) {
7418
+ return console.error("Failed to load animation manifest:", t), {};
7419
+ }
7420
+ }
7421
+ const yt = Me(({
7422
+ text: V = null,
7416
7423
  avatarUrl: t = "/avatars/brunette.glb",
7417
7424
  avatarBody: e = "F",
7418
7425
  mood: n = "neutral",
@@ -7430,173 +7437,223 @@ const gt = Me(({
7430
7437
  },
7431
7438
  onError: g = () => {
7432
7439
  },
7433
- onSpeechEnd: b = () => {
7440
+ onSpeechEnd: x = () => {
7434
7441
  },
7435
- className: x = "",
7436
- style: S = {},
7437
- animations: U = {},
7438
- autoSpeak: p = !1
7439
- }, F) => {
7440
- const C = O(null), y = O(null), I = O(u), z = O(null), A = O(null), Y = O(!1), k = O({ remainingText: null, originalText: null, options: null }), E = O([]), [q, G] = ce(!0), [ee, se] = ce(null), [ae, pe] = ce(!1), [te, le] = ce(!1);
7441
- de(() => {
7442
- Y.current = te;
7443
- }, [te]), de(() => {
7444
- I.current = u;
7442
+ className: f = "",
7443
+ style: k = {},
7444
+ animations: O = {},
7445
+ autoAnimationGroup: p = null,
7446
+ // e.g., "talking" - will randomly select from this group when speaking
7447
+ autoIdleGroup: B = null,
7448
+ // e.g., "idle" - will randomly select from this group when idle
7449
+ autoSpeak: H = !1
7450
+ }, v) => {
7451
+ const L = W(null), I = W(null), z = W(u), Y = W(null), S = W(null), F = W(!1), X = W({ remainingText: null, originalText: null, options: null }), Z = W([]), [ne, le] = pe(!0), [ge, de] = pe(null), [$, be] = pe(!1), [j, b] = pe(!1), [R, M] = pe(O), E = W(null);
7452
+ ce(() => {
7453
+ F.current = j;
7454
+ }, [j]), ce(() => {
7455
+ (async () => {
7456
+ if (O.manifest)
7457
+ try {
7458
+ const P = await gt(O.manifest);
7459
+ M(P), console.log("Loaded animations from manifest:", P);
7460
+ } catch (P) {
7461
+ console.error("Failed to load animation manifest:", P), M(O);
7462
+ }
7463
+ else
7464
+ M(O);
7465
+ })();
7466
+ }, [O]), ce(() => {
7467
+ z.current = u;
7445
7468
  }, [u]);
7446
- const W = Ee(), v = s || W.service;
7447
- let R;
7448
- v === "browser" ? R = {
7469
+ const D = Ee(), ee = s || D.service;
7470
+ let Q;
7471
+ ee === "browser" ? Q = {
7449
7472
  service: "browser",
7450
7473
  endpoint: "",
7451
7474
  apiKey: null,
7452
7475
  defaultVoice: "Google US English"
7453
- } : v === "elevenlabs" ? R = {
7476
+ } : ee === "elevenlabs" ? Q = {
7454
7477
  service: "elevenlabs",
7455
7478
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
7456
- apiKey: l || W.apiKey,
7457
- defaultVoice: o || W.defaultVoice || Ie.defaultVoice,
7458
- voices: W.voices || Ie.voices
7459
- } : v === "deepgram" ? R = {
7479
+ apiKey: l || D.apiKey,
7480
+ defaultVoice: o || D.defaultVoice || Ie.defaultVoice,
7481
+ voices: D.voices || Ie.voices
7482
+ } : ee === "deepgram" ? Q = {
7460
7483
  service: "deepgram",
7461
7484
  endpoint: "https://api.deepgram.com/v1/speak",
7462
- apiKey: l || W.apiKey,
7463
- defaultVoice: o || W.defaultVoice || Te.defaultVoice,
7464
- voices: W.voices || Te.voices
7465
- } : R = {
7466
- ...W,
7467
- apiKey: l !== null ? l : W.apiKey
7485
+ apiKey: l || D.apiKey,
7486
+ defaultVoice: o || D.defaultVoice || Te.defaultVoice,
7487
+ voices: D.voices || Te.voices
7488
+ } : Q = {
7489
+ ...D,
7490
+ apiKey: l !== null ? l : D.apiKey
7468
7491
  };
7469
- const H = {
7492
+ const q = {
7470
7493
  url: t,
7471
7494
  body: e,
7472
7495
  avatarMood: n,
7473
- ttsLang: v === "browser" ? "en-US" : i,
7474
- ttsVoice: o || R.defaultVoice,
7496
+ ttsLang: ee === "browser" ? "en-US" : i,
7497
+ ttsVoice: o || Q.defaultVoice,
7475
7498
  lipsyncLang: "en",
7476
7499
  showFullAvatar: u,
7477
7500
  bodyMovement: h,
7478
7501
  movementIntensity: r
7479
- }, P = {
7480
- ttsEndpoint: R.endpoint,
7481
- ttsApikey: R.apiKey,
7482
- ttsService: v,
7502
+ }, Ae = {
7503
+ ttsEndpoint: Q.endpoint,
7504
+ ttsApikey: Q.apiKey,
7505
+ ttsService: ee,
7483
7506
  lipsyncModules: ["en"],
7484
7507
  cameraView: a
7485
- }, V = B(async () => {
7486
- if (!(!C.current || y.current))
7508
+ }, Se = N(async () => {
7509
+ if (!(!L.current || I.current))
7487
7510
  try {
7488
- G(!0), se(null), y.current = new Be(C.current, P), console.log("Avatar config being passed:", {
7489
- url: H.url,
7490
- body: H.body,
7491
- avatarMood: H.avatarMood
7492
- }), await y.current.showAvatar(H, (ne) => {
7493
- if (ne.lengthComputable) {
7494
- const L = Math.min(100, Math.round(ne.loaded / ne.total * 100));
7495
- c(L);
7511
+ le(!0), de(null), I.current = new Be(L.current, Ae), console.log("Avatar config being passed:", {
7512
+ url: q.url,
7513
+ body: q.body,
7514
+ avatarMood: q.avatarMood
7515
+ }), await I.current.showAvatar(q, (P) => {
7516
+ if (P.lengthComputable) {
7517
+ const K = Math.min(100, Math.round(P.loaded / P.total * 100));
7518
+ c(K);
7496
7519
  }
7497
- }), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), G(!1), pe(!0), d(y.current);
7498
- const M = () => {
7499
- document.visibilityState === "visible" ? y.current?.start() : y.current?.stop();
7520
+ }), I.current?.avatar && console.log("Avatar body after initialization:", I.current.avatar.body), le(!1), be(!0), d(I.current);
7521
+ const A = () => {
7522
+ document.visibilityState === "visible" ? I.current?.start() : I.current?.stop();
7500
7523
  };
7501
- return document.addEventListener("visibilitychange", M), () => {
7502
- document.removeEventListener("visibilitychange", M);
7524
+ return document.addEventListener("visibilitychange", A), () => {
7525
+ document.removeEventListener("visibilitychange", A);
7503
7526
  };
7504
- } catch (M) {
7505
- console.error("Error initializing TalkingHead:", M), se(M.message || "Failed to initialize avatar"), G(!1), g(M);
7527
+ } catch (A) {
7528
+ console.error("Error initializing TalkingHead:", A), de(A.message || "Failed to initialize avatar"), le(!1), g(A);
7506
7529
  }
7507
7530
  }, []);
7508
- de(() => (V(), () => {
7509
- y.current && (y.current.stop(), y.current.dispose(), y.current = null);
7510
- }), [V]);
7511
- const J = B(async () => {
7512
- if (y.current)
7531
+ ce(() => (Se(), () => {
7532
+ I.current && (I.current.stop(), I.current.dispose(), I.current = null);
7533
+ }), [Se]);
7534
+ const Le = N(async () => {
7535
+ if (I.current)
7513
7536
  try {
7514
- const M = y.current.audioCtx || y.current.audioContext;
7515
- M && (M.state === "suspended" || M.state === "interrupted") && (await M.resume(), console.log("Audio context resumed"));
7516
- } catch (M) {
7517
- console.warn("Failed to resume audio context:", M);
7537
+ const A = I.current.audioCtx || I.current.audioContext;
7538
+ A && (A.state === "suspended" || A.state === "interrupted") && (await A.resume(), console.log("Audio context resumed"));
7539
+ } catch (A) {
7540
+ console.warn("Failed to resume audio context:", A);
7518
7541
  }
7519
- }, []), Q = B(async (M, ne = {}) => {
7520
- if (!y.current || !ae) {
7542
+ }, []), ke = N((A) => {
7543
+ if (!R || !R[A])
7544
+ return null;
7545
+ const P = R[A];
7546
+ if (Array.isArray(P) && P.length > 0) {
7547
+ const K = Math.floor(Math.random() * P.length);
7548
+ return P[K];
7549
+ }
7550
+ return typeof P == "string" ? P : null;
7551
+ }, [R]), w = N((A, P = !1) => {
7552
+ const K = ke(A);
7553
+ if (K && I.current)
7554
+ try {
7555
+ return I.current.playAnimation(K, null, 10, 0, 0.01, P), console.log(`Playing random animation from "${A}" group:`, K), K;
7556
+ } catch (ie) {
7557
+ return console.warn(`Failed to play random animation from "${A}" group:`, ie), null;
7558
+ }
7559
+ return null;
7560
+ }, [ke]), U = N(async (A, P = {}) => {
7561
+ if (!I.current || !$) {
7521
7562
  console.warn("Avatar not ready for speaking");
7522
7563
  return;
7523
7564
  }
7524
- if (!M || M.trim() === "") {
7565
+ if (!A || A.trim() === "") {
7525
7566
  console.warn("No text provided to speak");
7526
7567
  return;
7527
7568
  }
7528
- await J(), k.current = { remainingText: null, originalText: null, options: null }, E.current = [], z.current = { text: M, options: ne }, A.current && (clearInterval(A.current), A.current = null), le(!1), Y.current = !1;
7529
- const L = M.split(/[.!?]+/).filter((D) => D.trim().length > 0);
7530
- E.current = L;
7531
- const N = {
7532
- lipsyncLang: ne.lipsyncLang || "en",
7569
+ await Le();
7570
+ const K = P.animationGroup || p;
7571
+ K && !P.skipAnimation && w(K), X.current = { remainingText: null, originalText: null, options: null }, Z.current = [], Y.current = { text: A, options: P }, S.current && (clearInterval(S.current), S.current = null), b(!1), F.current = !1;
7572
+ const ie = A.split(/[.!?]+/).filter((oe) => oe.trim().length > 0);
7573
+ Z.current = ie;
7574
+ const se = {
7575
+ lipsyncLang: P.lipsyncLang || "en",
7533
7576
  onSpeechEnd: () => {
7534
- A.current && (clearInterval(A.current), A.current = null), ne.onSpeechEnd && ne.onSpeechEnd(), b();
7577
+ S.current && (clearInterval(S.current), S.current = null), P.onSpeechEnd && P.onSpeechEnd(), x();
7535
7578
  }
7536
7579
  };
7537
7580
  try {
7538
- y.current.speakText(M, N);
7539
- } catch (D) {
7540
- console.error("Error speaking text:", D), se(D.message || "Failed to speak text");
7581
+ I.current.speakText(A, se);
7582
+ } catch (oe) {
7583
+ console.error("Error speaking text:", oe), de(oe.message || "Failed to speak text");
7541
7584
  }
7542
- }, [ae, b, J]);
7543
- de(() => {
7544
- ae && X && p && y.current && Q(X);
7545
- }, [ae, X, p, Q]);
7546
- const K = B(() => {
7547
- if (y.current)
7585
+ }, [$, x, Le, p, w]);
7586
+ ce(() => {
7587
+ if (!$ || !B || !I.current)
7588
+ return;
7589
+ E.current && clearInterval(E.current);
7590
+ const A = () => {
7591
+ I.current && !F.current && w(B);
7592
+ };
7593
+ return A(), E.current = setInterval(() => {
7594
+ A();
7595
+ }, 12e3 + Math.random() * 3e3), () => {
7596
+ E.current && (clearInterval(E.current), E.current = null);
7597
+ };
7598
+ }, [$, B, w]), ce(() => {
7599
+ $ && V && H && I.current && U(V);
7600
+ }, [$, V, H, U]);
7601
+ const _ = N(() => {
7602
+ if (I.current)
7548
7603
  try {
7549
- const M = y.current.isSpeaking || !1, ne = y.current.audioPlaylist || [], L = y.current.speechQueue || [];
7550
- if (M || ne.length > 0 || L.length > 0) {
7551
- A.current && (clearInterval(A.current), A.current = null);
7552
- let N = "";
7553
- L.length > 0 && (N = L.map((D) => D.text && Array.isArray(D.text) ? D.text.map(($) => $.word).join(" ") : D.text || "").join(" ")), k.current = {
7554
- remainingText: N || null,
7555
- originalText: z.current?.text || null,
7556
- options: z.current?.options || null
7557
- }, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), le(!0), Y.current = !0;
7604
+ const A = I.current.isSpeaking || !1, P = I.current.audioPlaylist || [], K = I.current.speechQueue || [];
7605
+ if (A || P.length > 0 || K.length > 0) {
7606
+ S.current && (clearInterval(S.current), S.current = null);
7607
+ let ie = "";
7608
+ K.length > 0 && (ie = K.map((se) => se.text && Array.isArray(se.text) ? se.text.map((oe) => oe.word).join(" ") : se.text || "").join(" ")), X.current = {
7609
+ remainingText: ie || null,
7610
+ originalText: Y.current?.text || null,
7611
+ options: Y.current?.options || null
7612
+ }, I.current.speechQueue.length = 0, I.current.pauseSpeaking(), b(!0), F.current = !0;
7558
7613
  }
7559
- } catch (M) {
7560
- console.warn("Error pausing speech:", M);
7614
+ } catch (A) {
7615
+ console.warn("Error pausing speech:", A);
7561
7616
  }
7562
- }, []), Ae = B(async () => {
7563
- if (!(!y.current || !te))
7617
+ }, []), te = N(async () => {
7618
+ if (!(!I.current || !j))
7564
7619
  try {
7565
- await J(), le(!1), Y.current = !1;
7566
- const M = k.current?.remainingText, ne = k.current?.originalText || z.current?.text, L = k.current?.options || z.current?.options || {}, N = M || ne;
7567
- N && Q(N, L);
7568
- } catch (M) {
7569
- console.warn("Error resuming speech:", M), le(!1), Y.current = !1;
7620
+ await Le(), b(!1), F.current = !1;
7621
+ const A = X.current?.remainingText, P = X.current?.originalText || Y.current?.text, K = X.current?.options || Y.current?.options || {}, ie = A || P;
7622
+ ie && U(ie, K);
7623
+ } catch (A) {
7624
+ console.warn("Error resuming speech:", A), b(!1), F.current = !1;
7570
7625
  }
7571
- }, [te, Q, J]), we = B(() => {
7572
- y.current && (y.current.stopSpeaking(), A.current && (clearInterval(A.current), A.current = null), le(!1), Y.current = !1);
7626
+ }, [j, U, Le]), me = N(() => {
7627
+ I.current && (I.current.stopSpeaking(), S.current && (clearInterval(S.current), S.current = null), b(!1), F.current = !1);
7573
7628
  }, []);
7574
- return Fe(F, () => ({
7575
- speakText: Q,
7576
- pauseSpeaking: K,
7577
- resumeSpeaking: Ae,
7578
- stopSpeaking: we,
7579
- resumeAudioContext: J,
7580
- isPaused: () => te,
7581
- setMood: (M) => y.current?.setMood(M),
7582
- setBodyMovement: (M) => {
7583
- y.current && y.current.setBodyMovement(M);
7629
+ return Fe(v, () => ({
7630
+ speakText: U,
7631
+ pauseSpeaking: _,
7632
+ resumeSpeaking: te,
7633
+ stopSpeaking: me,
7634
+ resumeAudioContext: Le,
7635
+ isPaused: () => j,
7636
+ setMood: (A) => I.current?.setMood(A),
7637
+ setBodyMovement: (A) => {
7638
+ I.current && I.current.setBodyMovement(A);
7584
7639
  },
7585
- playAnimation: (M, ne = !1) => {
7586
- y.current && y.current.playAnimation && y.current.playAnimation(M, null, 10, 0, 0.01, ne);
7640
+ playAnimation: (A, P = !1) => {
7641
+ I.current && I.current.playAnimation && I.current.playAnimation(A, null, 10, 0, 0.01, P);
7587
7642
  },
7588
- playReaction: (M) => y.current?.playReaction(M),
7589
- playCelebration: () => y.current?.playCelebration(),
7590
- setShowFullAvatar: (M) => {
7591
- y.current && (I.current = M, y.current.setShowFullAvatar(M));
7643
+ playRandomAnimation: (A, P = !1) => w(A, P),
7644
+ getRandomAnimation: (A) => ke(A),
7645
+ playReaction: (A) => I.current?.playReaction(A),
7646
+ playCelebration: () => I.current?.playCelebration(),
7647
+ setShowFullAvatar: (A) => {
7648
+ I.current && (z.current = A, I.current.setShowFullAvatar(A));
7592
7649
  },
7593
- isReady: ae,
7594
- talkingHead: y.current
7595
- })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${x}`, style: S, children: [
7596
- /* @__PURE__ */ me(
7650
+ isReady: $,
7651
+ talkingHead: I.current
7652
+ })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${f}`, style: k, children: [
7653
+ /* @__PURE__ */ ye(
7597
7654
  "div",
7598
7655
  {
7599
- ref: C,
7656
+ ref: L,
7600
7657
  className: "talking-head-viewer",
7601
7658
  style: {
7602
7659
  width: "100%",
@@ -7605,7 +7662,7 @@ const gt = Me(({
7605
7662
  }
7606
7663
  }
7607
7664
  ),
7608
- q && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7665
+ ne && /* @__PURE__ */ ye("div", { className: "loading-overlay", style: {
7609
7666
  position: "absolute",
7610
7667
  top: "50%",
7611
7668
  left: "50%",
@@ -7614,7 +7671,7 @@ const gt = Me(({
7614
7671
  fontSize: "18px",
7615
7672
  zIndex: 10
7616
7673
  }, children: "Loading avatar..." }),
7617
- ee && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
7674
+ ge && /* @__PURE__ */ ye("div", { className: "error-overlay", style: {
7618
7675
  position: "absolute",
7619
7676
  top: "50%",
7620
7677
  left: "50%",
@@ -7625,12 +7682,12 @@ const gt = Me(({
7625
7682
  zIndex: 10,
7626
7683
  padding: "20px",
7627
7684
  borderRadius: "8px"
7628
- }, children: ee })
7685
+ }, children: ge })
7629
7686
  ] });
7630
7687
  });
7631
- gt.displayName = "SimpleTalkingAvatar";
7632
- const yt = Me(({
7633
- curriculumData: X = null,
7688
+ yt.displayName = "SimpleTalkingAvatar";
7689
+ const ft = Me(({
7690
+ curriculumData: V = null,
7634
7691
  avatarConfig: t = {},
7635
7692
  animations: e = {},
7636
7693
  onLessonStart: n = () => {
@@ -7645,7 +7702,7 @@ const yt = Me(({
7645
7702
  },
7646
7703
  autoStart: h = !1
7647
7704
  }, r) => {
7648
- const u = O(null), a = O({
7705
+ const u = W(null), a = W({
7649
7706
  currentModuleIndex: 0,
7650
7707
  currentLessonIndex: 0,
7651
7708
  currentQuestionIndex: 0,
@@ -7655,18 +7712,18 @@ const yt = Me(({
7655
7712
  curriculumCompleted: !1,
7656
7713
  score: 0,
7657
7714
  totalQuestions: 0
7658
- }), d = O({
7715
+ }), d = W({
7659
7716
  onLessonStart: n,
7660
7717
  onLessonComplete: i,
7661
7718
  onQuestionAnswer: s,
7662
7719
  onCurriculumComplete: o,
7663
7720
  onCustomAction: l
7664
- }), c = O(null), g = O(null), b = O(null), x = O(null), S = O(null), U = O(null), p = O(null), F = O(X?.curriculum || {
7721
+ }), c = W(null), g = W(null), x = W(null), f = W(null), k = W(null), O = W(null), p = W(null), B = W(V?.curriculum || {
7665
7722
  title: "Default Curriculum",
7666
7723
  description: "No curriculum data provided",
7667
7724
  language: "en",
7668
7725
  modules: []
7669
- }), C = O({
7726
+ }), H = W({
7670
7727
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7671
7728
  avatarBody: t.avatarBody || "F",
7672
7729
  mood: t.mood || "happy",
@@ -7680,7 +7737,7 @@ const yt = Me(({
7680
7737
  animations: e,
7681
7738
  lipsyncLang: "en"
7682
7739
  });
7683
- de(() => {
7740
+ ce(() => {
7684
7741
  d.current = {
7685
7742
  onLessonStart: n,
7686
7743
  onLessonComplete: i,
@@ -7688,13 +7745,13 @@ const yt = Me(({
7688
7745
  onCurriculumComplete: o,
7689
7746
  onCustomAction: l
7690
7747
  };
7691
- }, [n, i, s, o, l]), de(() => {
7692
- F.current = X?.curriculum || {
7748
+ }, [n, i, s, o, l]), ce(() => {
7749
+ B.current = V?.curriculum || {
7693
7750
  title: "Default Curriculum",
7694
7751
  description: "No curriculum data provided",
7695
7752
  language: "en",
7696
7753
  modules: []
7697
- }, C.current = {
7754
+ }, H.current = {
7698
7755
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7699
7756
  avatarBody: t.avatarBody || "F",
7700
7757
  mood: t.mood || "happy",
@@ -7708,24 +7765,24 @@ const yt = Me(({
7708
7765
  animations: e,
7709
7766
  lipsyncLang: "en"
7710
7767
  };
7711
- }, [X, t, e]);
7712
- const y = B(() => (F.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), I = B(() => y()?.questions[a.current.currentQuestionIndex], [y]), z = B((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, []), A = B(() => {
7768
+ }, [V, t, e]);
7769
+ const v = N(() => (B.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), L = N(() => v()?.questions[a.current.currentQuestionIndex], [v]), I = N((b, R) => R.type === "multiple_choice" || R.type === "true_false" ? b === R.answer : R.type === "code_test" && typeof b == "object" && b !== null ? b.passed === !0 : !1, []), z = N(() => {
7713
7770
  a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
7714
- const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7771
+ const b = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7715
7772
  let R = "Congratulations! You've completed this lesson";
7716
- if (a.current.totalQuestions > 0 ? R += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : R += "! ", v >= 80 ? R += "Excellent work! You have a great understanding of this topic." : v >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", d.current.onLessonComplete({
7773
+ 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 ${b} percent. ` : R += "! ", b >= 80 ? R += "Excellent work! You have a great understanding of this topic." : b >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", d.current.onLessonComplete({
7717
7774
  moduleIndex: a.current.currentModuleIndex,
7718
7775
  lessonIndex: a.current.currentLessonIndex,
7719
7776
  score: a.current.score,
7720
7777
  totalQuestions: a.current.totalQuestions,
7721
- percentage: v
7778
+ percentage: b
7722
7779
  }), d.current.onCustomAction({
7723
7780
  type: "lessonComplete",
7724
7781
  moduleIndex: a.current.currentModuleIndex,
7725
7782
  lessonIndex: a.current.currentLessonIndex,
7726
7783
  score: a.current.score,
7727
7784
  totalQuestions: a.current.totalQuestions,
7728
- percentage: v
7785
+ percentage: b
7729
7786
  }), u.current) {
7730
7787
  if (u.current.setMood("happy"), e.lessonComplete)
7731
7788
  try {
@@ -7733,9 +7790,9 @@ const yt = Me(({
7733
7790
  } catch {
7734
7791
  u.current.playCelebration();
7735
7792
  }
7736
- const H = F.current || { modules: [] }, P = H.modules[a.current.currentModuleIndex], V = a.current.currentLessonIndex < (P?.lessons?.length || 0) - 1, J = a.current.currentModuleIndex < (H.modules?.length || 0) - 1, Q = V || J, K = C.current || { lipsyncLang: "en" };
7793
+ const M = B.current || { modules: [] }, E = M.modules[a.current.currentModuleIndex], D = a.current.currentLessonIndex < (E?.lessons?.length || 0) - 1, ee = a.current.currentModuleIndex < (M.modules?.length || 0) - 1, Q = D || ee, q = H.current || { lipsyncLang: "en" };
7737
7794
  u.current.speakText(R, {
7738
- lipsyncLang: K.lipsyncLang,
7795
+ lipsyncLang: q.lipsyncLang,
7739
7796
  onSpeechEnd: () => {
7740
7797
  d.current.onCustomAction({
7741
7798
  type: "lessonCompleteFeedbackDone",
@@ -7743,18 +7800,18 @@ const yt = Me(({
7743
7800
  lessonIndex: a.current.currentLessonIndex,
7744
7801
  score: a.current.score,
7745
7802
  totalQuestions: a.current.totalQuestions,
7746
- percentage: v,
7803
+ percentage: b,
7747
7804
  hasNextLesson: Q
7748
7805
  });
7749
7806
  }
7750
7807
  });
7751
7808
  }
7752
- }, [e.lessonComplete]), Y = B(() => {
7809
+ }, [e.lessonComplete]), Y = N(() => {
7753
7810
  a.current.curriculumCompleted = !0;
7754
- const v = F.current || { modules: [] };
7811
+ const b = B.current || { modules: [] };
7755
7812
  if (d.current.onCurriculumComplete({
7756
- modules: v.modules.length,
7757
- totalLessons: v.modules.reduce((R, H) => R + H.lessons.length, 0)
7813
+ modules: b.modules.length,
7814
+ totalLessons: b.modules.reduce((R, M) => R + M.lessons.length, 0)
7758
7815
  }), u.current) {
7759
7816
  if (u.current.setMood("celebrating"), e.curriculumComplete)
7760
7817
  try {
@@ -7762,13 +7819,13 @@ const yt = Me(({
7762
7819
  } catch {
7763
7820
  u.current.playCelebration();
7764
7821
  }
7765
- const R = C.current || { lipsyncLang: "en" };
7822
+ const R = H.current || { lipsyncLang: "en" };
7766
7823
  u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: R.lipsyncLang });
7767
7824
  }
7768
- }, [e.curriculumComplete]), k = B(() => {
7769
- const v = y();
7770
- a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
7771
- const R = I();
7825
+ }, [e.curriculumComplete]), S = N(() => {
7826
+ const b = v();
7827
+ a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = b?.questions?.length || 0, a.current.score = 0;
7828
+ const R = L();
7772
7829
  R && d.current.onCustomAction({
7773
7830
  type: "questionStart",
7774
7831
  moduleIndex: a.current.currentModuleIndex,
@@ -7778,35 +7835,35 @@ const yt = Me(({
7778
7835
  question: R,
7779
7836
  score: a.current.score
7780
7837
  });
7781
- const H = () => {
7838
+ const M = () => {
7782
7839
  if (!u.current || !R) return;
7783
7840
  if (u.current.setMood("happy"), e.questionStart)
7784
7841
  try {
7785
7842
  u.current.playAnimation(e.questionStart, !0);
7786
- } catch (V) {
7787
- console.warn("Failed to play questionStart animation:", V);
7843
+ } catch (D) {
7844
+ console.warn("Failed to play questionStart animation:", D);
7788
7845
  }
7789
- const P = C.current || { lipsyncLang: "en" };
7790
- R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: P.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: P.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: P.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: P.lipsyncLang });
7846
+ const E = H.current || { lipsyncLang: "en" };
7847
+ R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: E.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: E.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: E.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: E.lipsyncLang });
7791
7848
  };
7792
7849
  if (u.current && u.current.isReady && R)
7793
- H();
7850
+ M();
7794
7851
  else if (u.current && u.current.isReady) {
7795
- const P = C.current || { lipsyncLang: "en" };
7796
- u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: P.lipsyncLang });
7852
+ const E = H.current || { lipsyncLang: "en" };
7853
+ u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: E.lipsyncLang });
7797
7854
  } else {
7798
- const P = setInterval(() => {
7799
- u.current && u.current.isReady && (clearInterval(P), R && H());
7855
+ const E = setInterval(() => {
7856
+ u.current && u.current.isReady && (clearInterval(E), R && M());
7800
7857
  }, 100);
7801
7858
  setTimeout(() => {
7802
- clearInterval(P);
7859
+ clearInterval(E);
7803
7860
  }, 5e3);
7804
7861
  }
7805
- }, [e.questionStart, y, I]), E = B(() => {
7806
- const v = y();
7807
- if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
7862
+ }, [e.questionStart, v, L]), F = N(() => {
7863
+ const b = v();
7864
+ if (a.current.currentQuestionIndex < (b?.questions?.length || 0) - 1) {
7808
7865
  u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
7809
- const R = I();
7866
+ const R = L();
7810
7867
  R && d.current.onCustomAction({
7811
7868
  type: "nextQuestion",
7812
7869
  moduleIndex: a.current.currentModuleIndex,
@@ -7816,45 +7873,45 @@ const yt = Me(({
7816
7873
  question: R,
7817
7874
  score: a.current.score
7818
7875
  });
7819
- const H = () => {
7876
+ const M = () => {
7820
7877
  if (!u.current || !R) return;
7821
7878
  if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
7822
7879
  try {
7823
7880
  u.current.playAnimation(e.nextQuestion, !0);
7824
- } catch (K) {
7825
- console.warn("Failed to play nextQuestion animation:", K);
7881
+ } catch (q) {
7882
+ console.warn("Failed to play nextQuestion animation:", q);
7826
7883
  }
7827
- const P = C.current || { lipsyncLang: "en" }, J = y()?.questions?.length || 0, Q = a.current.currentQuestionIndex >= J - 1;
7884
+ const E = H.current || { lipsyncLang: "en" }, ee = v()?.questions?.length || 0, Q = a.current.currentQuestionIndex >= ee - 1;
7828
7885
  if (R.type === "code_test") {
7829
- const K = Q ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
7830
- u.current.speakText(K, {
7831
- lipsyncLang: P.lipsyncLang
7886
+ const q = Q ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
7887
+ u.current.speakText(q, {
7888
+ lipsyncLang: E.lipsyncLang
7832
7889
  });
7833
7890
  } else if (R.type === "multiple_choice") {
7834
- const K = Q ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
7835
- u.current.speakText(K, {
7836
- lipsyncLang: P.lipsyncLang
7891
+ const q = Q ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
7892
+ u.current.speakText(q, {
7893
+ lipsyncLang: E.lipsyncLang
7837
7894
  });
7838
7895
  } else if (R.type === "true_false") {
7839
- const K = Q ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
7840
- u.current.speakText(K, {
7841
- lipsyncLang: P.lipsyncLang
7896
+ const q = Q ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
7897
+ u.current.speakText(q, {
7898
+ lipsyncLang: E.lipsyncLang
7842
7899
  });
7843
7900
  } else {
7844
- const K = Q ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
7845
- u.current.speakText(K, {
7846
- lipsyncLang: P.lipsyncLang
7901
+ const q = Q ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
7902
+ u.current.speakText(q, {
7903
+ lipsyncLang: E.lipsyncLang
7847
7904
  });
7848
7905
  }
7849
7906
  };
7850
7907
  if (u.current && u.current.isReady && R)
7851
- H();
7908
+ M();
7852
7909
  else if (R) {
7853
- const P = setInterval(() => {
7854
- u.current && u.current.isReady && (clearInterval(P), H());
7910
+ const E = setInterval(() => {
7911
+ u.current && u.current.isReady && (clearInterval(E), M());
7855
7912
  }, 100);
7856
7913
  setTimeout(() => {
7857
- clearInterval(P);
7914
+ clearInterval(E);
7858
7915
  }, 5e3);
7859
7916
  }
7860
7917
  } else
@@ -7865,11 +7922,11 @@ const yt = Me(({
7865
7922
  totalQuestions: a.current.totalQuestions,
7866
7923
  score: a.current.score
7867
7924
  });
7868
- }, [e.nextQuestion, y, I]), q = B(() => {
7869
- const v = F.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
7925
+ }, [e.nextQuestion, v, L]), X = N(() => {
7926
+ const b = B.current || { modules: [] }, R = b.modules[a.current.currentModuleIndex];
7870
7927
  if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
7871
7928
  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;
7872
- const P = v.modules[a.current.currentModuleIndex], V = a.current.currentLessonIndex < (P?.lessons?.length || 0) - 1, J = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, Q = V || J;
7929
+ const E = b.modules[a.current.currentModuleIndex], D = a.current.currentLessonIndex < (E?.lessons?.length || 0) - 1, ee = a.current.currentModuleIndex < (b.modules?.length || 0) - 1, Q = D || ee;
7873
7930
  d.current.onCustomAction({
7874
7931
  type: "lessonStart",
7875
7932
  moduleIndex: a.current.currentModuleIndex,
@@ -7878,81 +7935,81 @@ const yt = Me(({
7878
7935
  }), d.current.onLessonStart({
7879
7936
  moduleIndex: a.current.currentModuleIndex,
7880
7937
  lessonIndex: a.current.currentLessonIndex,
7881
- lesson: y()
7938
+ lesson: v()
7882
7939
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7883
- } else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
7940
+ } else if (a.current.currentModuleIndex < (b.modules?.length || 0) - 1) {
7884
7941
  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;
7885
- const V = v.modules[a.current.currentModuleIndex], J = a.current.currentLessonIndex < (V?.lessons?.length || 0) - 1, Q = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, K = J || Q;
7942
+ const D = b.modules[a.current.currentModuleIndex], ee = a.current.currentLessonIndex < (D?.lessons?.length || 0) - 1, Q = a.current.currentModuleIndex < (b.modules?.length || 0) - 1, q = ee || Q;
7886
7943
  d.current.onCustomAction({
7887
7944
  type: "lessonStart",
7888
7945
  moduleIndex: a.current.currentModuleIndex,
7889
7946
  lessonIndex: a.current.currentLessonIndex,
7890
- hasNextLesson: K
7947
+ hasNextLesson: q
7891
7948
  }), d.current.onLessonStart({
7892
7949
  moduleIndex: a.current.currentModuleIndex,
7893
7950
  lessonIndex: a.current.currentLessonIndex,
7894
- lesson: y()
7951
+ lesson: v()
7895
7952
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7896
7953
  } else
7897
- S.current && S.current();
7898
- }, []), G = B(() => {
7899
- const v = y();
7954
+ k.current && k.current();
7955
+ }, []), Z = N(() => {
7956
+ const b = v();
7900
7957
  let R = null;
7901
- if (v?.avatar_script && v?.body) {
7902
- const H = v.avatar_script.trim(), P = v.body.trim(), V = H.match(/[.!?]$/) ? " " : ". ";
7903
- R = `${H}${V}${P}`;
7958
+ if (b?.avatar_script && b?.body) {
7959
+ const M = b.avatar_script.trim(), E = b.body.trim(), D = M.match(/[.!?]$/) ? " " : ". ";
7960
+ R = `${M}${D}${E}`;
7904
7961
  } else
7905
- R = v?.avatar_script || v?.body || null;
7962
+ R = b?.avatar_script || b?.body || null;
7906
7963
  if (u.current && u.current.isReady && R) {
7907
7964
  a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, u.current.setMood("happy");
7908
- let H = !1;
7965
+ let M = !1;
7909
7966
  if (e.teaching)
7910
7967
  try {
7911
- u.current.playAnimation(e.teaching, !0), H = !0;
7912
- } catch (V) {
7913
- console.warn("Failed to play teaching animation:", V);
7968
+ u.current.playAnimation(e.teaching, !0), M = !0;
7969
+ } catch (D) {
7970
+ console.warn("Failed to play teaching animation:", D);
7914
7971
  }
7915
- H || u.current.setBodyMovement("gesturing");
7916
- const P = C.current || { lipsyncLang: "en" };
7972
+ M || u.current.setBodyMovement("gesturing");
7973
+ const E = H.current || { lipsyncLang: "en" };
7917
7974
  d.current.onLessonStart({
7918
7975
  moduleIndex: a.current.currentModuleIndex,
7919
7976
  lessonIndex: a.current.currentLessonIndex,
7920
- lesson: v
7977
+ lesson: b
7921
7978
  }), d.current.onCustomAction({
7922
7979
  type: "teachingStart",
7923
7980
  moduleIndex: a.current.currentModuleIndex,
7924
7981
  lessonIndex: a.current.currentLessonIndex,
7925
- lesson: v
7982
+ lesson: b
7926
7983
  }), u.current.speakText(R, {
7927
- lipsyncLang: P.lipsyncLang,
7984
+ lipsyncLang: E.lipsyncLang,
7928
7985
  onSpeechEnd: () => {
7929
7986
  a.current.isTeaching = !1, d.current.onCustomAction({
7930
7987
  type: "teachingComplete",
7931
7988
  moduleIndex: a.current.currentModuleIndex,
7932
7989
  lessonIndex: a.current.currentLessonIndex,
7933
- lesson: v,
7934
- hasQuestions: v.questions && v.questions.length > 0
7935
- }), v?.code_example && d.current.onCustomAction({
7990
+ lesson: b,
7991
+ hasQuestions: b.questions && b.questions.length > 0
7992
+ }), b?.code_example && d.current.onCustomAction({
7936
7993
  type: "codeExampleReady",
7937
7994
  moduleIndex: a.current.currentModuleIndex,
7938
7995
  lessonIndex: a.current.currentLessonIndex,
7939
- lesson: v,
7940
- codeExample: v.code_example
7996
+ lesson: b,
7997
+ codeExample: b.code_example
7941
7998
  });
7942
7999
  }
7943
8000
  });
7944
8001
  }
7945
- }, [e.teaching, y]), ee = B((v) => {
7946
- const R = I(), H = z(v, R);
7947
- if (H && (a.current.score += 1), d.current.onQuestionAnswer({
8002
+ }, [e.teaching, v]), ne = N((b) => {
8003
+ const R = L(), M = I(b, R);
8004
+ if (M && (a.current.score += 1), d.current.onQuestionAnswer({
7948
8005
  moduleIndex: a.current.currentModuleIndex,
7949
8006
  lessonIndex: a.current.currentLessonIndex,
7950
8007
  questionIndex: a.current.currentQuestionIndex,
7951
- answer: v,
7952
- isCorrect: H,
8008
+ answer: b,
8009
+ isCorrect: M,
7953
8010
  question: R
7954
8011
  }), u.current)
7955
- if (H) {
8012
+ if (M) {
7956
8013
  if (u.current.setMood("happy"), e.correct)
7957
8014
  try {
7958
8015
  u.current.playReaction("happy");
@@ -7960,13 +8017,13 @@ const yt = Me(({
7960
8017
  u.current.setBodyMovement("happy");
7961
8018
  }
7962
8019
  u.current.setBodyMovement("gesturing");
7963
- const V = y()?.questions?.length || 0;
7964
- a.current.currentQuestionIndex >= V - 1;
7965
- const J = a.current.currentQuestionIndex < V - 1;
7966
- console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", V, "hasNextQuestion:", J);
7967
- const Q = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, K = C.current || { lipsyncLang: "en" };
8020
+ const D = v()?.questions?.length || 0;
8021
+ a.current.currentQuestionIndex >= D - 1;
8022
+ const ee = a.current.currentQuestionIndex < D - 1;
8023
+ console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", D, "hasNextQuestion:", ee);
8024
+ const Q = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, q = H.current || { lipsyncLang: "en" };
7968
8025
  u.current.speakText(Q, {
7969
- lipsyncLang: K.lipsyncLang,
8026
+ lipsyncLang: q.lipsyncLang,
7970
8027
  onSpeechEnd: () => {
7971
8028
  d.current.onCustomAction({
7972
8029
  type: "answerFeedbackComplete",
@@ -7974,7 +8031,7 @@ const yt = Me(({
7974
8031
  lessonIndex: a.current.currentLessonIndex,
7975
8032
  questionIndex: a.current.currentQuestionIndex,
7976
8033
  isCorrect: !0,
7977
- hasNextQuestion: J,
8034
+ hasNextQuestion: ee,
7978
8035
  score: a.current.score,
7979
8036
  totalQuestions: a.current.totalQuestions
7980
8037
  });
@@ -7988,10 +8045,10 @@ const yt = Me(({
7988
8045
  u.current.setBodyMovement("idle");
7989
8046
  }
7990
8047
  u.current.setBodyMovement("gesturing");
7991
- const V = y()?.questions?.length || 0, J = a.current.currentQuestionIndex >= V - 1, Q = a.current.currentQuestionIndex < V - 1;
7992
- console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", V, "hasNextQuestion:", Q);
7993
- const K = 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 || ""}${J ? "" : " Let's move on to the next question."}`, Ae = C.current || { lipsyncLang: "en" };
7994
- u.current.speakText(K, {
8048
+ const D = v()?.questions?.length || 0, ee = a.current.currentQuestionIndex >= D - 1, Q = a.current.currentQuestionIndex < D - 1;
8049
+ console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", D, "hasNextQuestion:", Q);
8050
+ 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 || ""}${ee ? "" : " Let's move on to the next question."}`, Ae = H.current || { lipsyncLang: "en" };
8051
+ u.current.speakText(q, {
7995
8052
  lipsyncLang: Ae.lipsyncLang,
7996
8053
  onSpeechEnd: () => {
7997
8054
  d.current.onCustomAction({
@@ -8008,22 +8065,22 @@ const yt = Me(({
8008
8065
  });
8009
8066
  }
8010
8067
  else {
8011
- const V = y()?.questions?.length || 0;
8068
+ const D = v()?.questions?.length || 0;
8012
8069
  d.current.onCustomAction({
8013
8070
  type: "answerFeedbackComplete",
8014
8071
  moduleIndex: a.current.currentModuleIndex,
8015
8072
  lessonIndex: a.current.currentLessonIndex,
8016
8073
  questionIndex: a.current.currentQuestionIndex,
8017
- isCorrect: H,
8018
- hasNextQuestion: a.current.currentQuestionIndex < V - 1,
8074
+ isCorrect: M,
8075
+ hasNextQuestion: a.current.currentQuestionIndex < D - 1,
8019
8076
  score: a.current.score,
8020
8077
  totalQuestions: a.current.totalQuestions,
8021
8078
  avatarNotReady: !0
8022
8079
  });
8023
8080
  }
8024
- }, [e.correct, e.incorrect, I, y, z]), se = B((v) => {
8025
- const R = I();
8026
- if (!v || typeof v != "object") {
8081
+ }, [e.correct, e.incorrect, L, v, I]), le = N((b) => {
8082
+ const R = L();
8083
+ if (!b || typeof b != "object") {
8027
8084
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
8028
8085
  return;
8029
8086
  }
@@ -8031,61 +8088,61 @@ const yt = Me(({
8031
8088
  console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
8032
8089
  return;
8033
8090
  }
8034
- const H = {
8035
- passed: v.passed === !0,
8036
- results: v.results || [],
8037
- output: v.output || "",
8038
- error: v.error || null,
8039
- executionTime: v.executionTime || null,
8040
- testCount: v.testCount || 0,
8041
- passedCount: v.passedCount || 0,
8042
- failedCount: v.failedCount || 0
8091
+ const M = {
8092
+ passed: b.passed === !0,
8093
+ results: b.results || [],
8094
+ output: b.output || "",
8095
+ error: b.error || null,
8096
+ executionTime: b.executionTime || null,
8097
+ testCount: b.testCount || 0,
8098
+ passedCount: b.passedCount || 0,
8099
+ failedCount: b.failedCount || 0
8043
8100
  };
8044
8101
  d.current.onCustomAction({
8045
8102
  type: "codeTestSubmitted",
8046
8103
  moduleIndex: a.current.currentModuleIndex,
8047
8104
  lessonIndex: a.current.currentLessonIndex,
8048
8105
  questionIndex: a.current.currentQuestionIndex,
8049
- testResult: H,
8106
+ testResult: M,
8050
8107
  question: R
8051
- }), p.current && p.current(H);
8052
- }, [I, z]), ae = B(() => {
8108
+ }), p.current && p.current(M);
8109
+ }, [L, I]), ge = N(() => {
8053
8110
  if (a.current.currentQuestionIndex > 0) {
8054
8111
  a.current.currentQuestionIndex -= 1;
8055
- const v = I();
8056
- v && d.current.onCustomAction({
8112
+ const b = L();
8113
+ b && d.current.onCustomAction({
8057
8114
  type: "questionStart",
8058
8115
  moduleIndex: a.current.currentModuleIndex,
8059
8116
  lessonIndex: a.current.currentLessonIndex,
8060
8117
  questionIndex: a.current.currentQuestionIndex,
8061
8118
  totalQuestions: a.current.totalQuestions,
8062
- question: v,
8119
+ question: b,
8063
8120
  score: a.current.score
8064
8121
  });
8065
8122
  const R = () => {
8066
- if (!u.current || !v) return;
8123
+ if (!u.current || !b) return;
8067
8124
  u.current.setMood("happy"), u.current.setBodyMovement("idle");
8068
- const H = C.current || { lipsyncLang: "en" };
8069
- v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
8070
- lipsyncLang: H.lipsyncLang
8071
- }) : u.current.speakText(`Going back to: ${v.question}`, {
8072
- lipsyncLang: H.lipsyncLang
8125
+ const M = H.current || { lipsyncLang: "en" };
8126
+ b.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${b.question}`, {
8127
+ lipsyncLang: M.lipsyncLang
8128
+ }) : u.current.speakText(`Going back to: ${b.question}`, {
8129
+ lipsyncLang: M.lipsyncLang
8073
8130
  });
8074
8131
  };
8075
- if (u.current && u.current.isReady && v)
8132
+ if (u.current && u.current.isReady && b)
8076
8133
  R();
8077
- else if (v) {
8078
- const H = setInterval(() => {
8079
- u.current && u.current.isReady && (clearInterval(H), R());
8134
+ else if (b) {
8135
+ const M = setInterval(() => {
8136
+ u.current && u.current.isReady && (clearInterval(M), R());
8080
8137
  }, 100);
8081
8138
  setTimeout(() => {
8082
- clearInterval(H);
8139
+ clearInterval(M);
8083
8140
  }, 5e3);
8084
8141
  }
8085
8142
  }
8086
- }, [I]), pe = B(() => {
8087
- const v = F.current || { modules: [] };
8088
- if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
8143
+ }, [L]), de = N(() => {
8144
+ const b = B.current || { modules: [] };
8145
+ if (b.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
8089
8146
  a.current.currentLessonIndex -= 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, d.current.onCustomAction({
8090
8147
  type: "lessonStart",
8091
8148
  moduleIndex: a.current.currentModuleIndex,
@@ -8093,66 +8150,66 @@ const yt = Me(({
8093
8150
  }), d.current.onLessonStart({
8094
8151
  moduleIndex: a.current.currentModuleIndex,
8095
8152
  lessonIndex: a.current.currentLessonIndex,
8096
- lesson: y()
8153
+ lesson: v()
8097
8154
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8098
8155
  else if (a.current.currentModuleIndex > 0) {
8099
- const P = v.modules[a.current.currentModuleIndex - 1];
8100
- a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (P?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, d.current.onCustomAction({
8156
+ const E = b.modules[a.current.currentModuleIndex - 1];
8157
+ a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (E?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, d.current.onCustomAction({
8101
8158
  type: "lessonStart",
8102
8159
  moduleIndex: a.current.currentModuleIndex,
8103
8160
  lessonIndex: a.current.currentLessonIndex
8104
8161
  }), d.current.onLessonStart({
8105
8162
  moduleIndex: a.current.currentModuleIndex,
8106
8163
  lessonIndex: a.current.currentLessonIndex,
8107
- lesson: y()
8164
+ lesson: v()
8108
8165
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8109
8166
  }
8110
- }, [y]), te = B(() => {
8167
+ }, [v]), $ = N(() => {
8111
8168
  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;
8112
- }, []), le = B((v) => {
8113
- console.log("Avatar is ready!", v);
8114
- const R = y(), H = R?.avatar_script || R?.body;
8115
- h && H && setTimeout(() => {
8169
+ }, []), be = N((b) => {
8170
+ console.log("Avatar is ready!", b);
8171
+ const R = v(), M = R?.avatar_script || R?.body;
8172
+ h && M && setTimeout(() => {
8116
8173
  c.current && c.current();
8117
8174
  }, 10);
8118
- }, [h, y]);
8175
+ }, [h, v]);
8119
8176
  Xe(() => {
8120
- c.current = G, g.current = q, b.current = A, x.current = E, S.current = Y, U.current = k, p.current = ee;
8177
+ c.current = Z, g.current = X, x.current = z, f.current = F, k.current = Y, O.current = S, p.current = ne;
8121
8178
  }), Fe(r, () => ({
8122
8179
  // Curriculum control methods
8123
- startTeaching: G,
8124
- startQuestions: k,
8125
- handleAnswerSelect: ee,
8126
- handleCodeTestResult: se,
8127
- nextQuestion: E,
8128
- previousQuestion: ae,
8129
- nextLesson: q,
8130
- previousLesson: pe,
8131
- completeLesson: A,
8180
+ startTeaching: Z,
8181
+ startQuestions: S,
8182
+ handleAnswerSelect: ne,
8183
+ handleCodeTestResult: le,
8184
+ nextQuestion: F,
8185
+ previousQuestion: ge,
8186
+ nextLesson: X,
8187
+ previousLesson: de,
8188
+ completeLesson: z,
8132
8189
  completeCurriculum: Y,
8133
- resetCurriculum: te,
8190
+ resetCurriculum: $,
8134
8191
  getState: () => ({ ...a.current }),
8135
- getCurrentQuestion: () => I(),
8136
- getCurrentLesson: () => y(),
8192
+ getCurrentQuestion: () => L(),
8193
+ getCurrentLesson: () => v(),
8137
8194
  // Direct access to avatar ref (always returns current value)
8138
8195
  getAvatarRef: () => u.current,
8139
8196
  // Convenience methods that delegate to avatar (always check current ref)
8140
- speakText: async (v, R = {}) => {
8197
+ speakText: async (b, R = {}) => {
8141
8198
  await u.current?.resumeAudioContext?.();
8142
- const H = C.current || { lipsyncLang: "en" };
8143
- u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || H.lipsyncLang });
8199
+ const M = H.current || { lipsyncLang: "en" };
8200
+ u.current?.speakText(b, { ...R, lipsyncLang: R.lipsyncLang || M.lipsyncLang });
8144
8201
  },
8145
8202
  resumeAudioContext: async () => {
8146
8203
  if (u.current?.resumeAudioContext)
8147
8204
  return await u.current.resumeAudioContext();
8148
- const v = u.current?.talkingHead;
8149
- if (v?.audioCtx) {
8150
- const R = v.audioCtx;
8205
+ const b = u.current?.talkingHead;
8206
+ if (b?.audioCtx) {
8207
+ const R = b.audioCtx;
8151
8208
  if (R.state === "suspended" || R.state === "interrupted")
8152
8209
  try {
8153
8210
  await R.resume(), console.log("Audio context resumed via talkingHead");
8154
- } catch (H) {
8155
- console.warn("Failed to resume audio context:", H);
8211
+ } catch (M) {
8212
+ console.warn("Failed to resume audio context:", M);
8156
8213
  }
8157
8214
  } else
8158
8215
  console.warn("Audio context not available yet");
@@ -8161,21 +8218,21 @@ const yt = Me(({
8161
8218
  pauseSpeaking: () => u.current?.pauseSpeaking(),
8162
8219
  resumeSpeaking: async () => await u.current?.resumeSpeaking(),
8163
8220
  isPaused: () => u.current && typeof u.current.isPaused < "u" ? u.current.isPaused : !1,
8164
- setMood: (v) => u.current?.setMood(v),
8165
- playAnimation: (v, R) => u.current?.playAnimation(v, R),
8166
- setBodyMovement: (v) => u.current?.setBodyMovement(v),
8167
- setMovementIntensity: (v) => u.current?.setMovementIntensity(v),
8221
+ setMood: (b) => u.current?.setMood(b),
8222
+ playAnimation: (b, R) => u.current?.playAnimation(b, R),
8223
+ setBodyMovement: (b) => u.current?.setBodyMovement(b),
8224
+ setMovementIntensity: (b) => u.current?.setMovementIntensity(b),
8168
8225
  playRandomDance: () => u.current?.playRandomDance(),
8169
- playReaction: (v) => u.current?.playReaction(v),
8226
+ playReaction: (b) => u.current?.playReaction(b),
8170
8227
  playCelebration: () => u.current?.playCelebration(),
8171
- setShowFullAvatar: (v) => u.current?.setShowFullAvatar(v),
8172
- setTimingAdjustment: (v) => u.current?.setTimingAdjustment(v),
8228
+ setShowFullAvatar: (b) => u.current?.setShowFullAvatar(b),
8229
+ setTimingAdjustment: (b) => u.current?.setTimingAdjustment(b),
8173
8230
  lockAvatarPosition: () => u.current?.lockAvatarPosition(),
8174
8231
  unlockAvatarPosition: () => u.current?.unlockAvatarPosition(),
8175
8232
  // Custom action trigger
8176
- triggerCustomAction: (v, R) => {
8233
+ triggerCustomAction: (b, R) => {
8177
8234
  d.current.onCustomAction({
8178
- type: v,
8235
+ type: b,
8179
8236
  ...R,
8180
8237
  state: { ...a.current }
8181
8238
  });
@@ -8184,8 +8241,8 @@ const yt = Me(({
8184
8241
  handleResize: () => u.current?.handleResize(),
8185
8242
  // Avatar readiness check (always returns current value)
8186
8243
  isAvatarReady: () => u.current?.isReady || !1
8187
- }), [G, k, ee, se, E, q, A, Y, te, I, y]);
8188
- const W = C.current || {
8244
+ }), [Z, S, ne, le, F, X, z, Y, $, L, v]);
8245
+ const j = H.current || {
8189
8246
  avatarUrl: "/avatars/brunette.glb",
8190
8247
  avatarBody: "F",
8191
8248
  mood: "happy",
@@ -8198,32 +8255,32 @@ const yt = Me(({
8198
8255
  showFullAvatar: !1,
8199
8256
  animations: e
8200
8257
  };
8201
- return /* @__PURE__ */ me("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ me(
8258
+ return /* @__PURE__ */ ye("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ ye(
8202
8259
  Ve,
8203
8260
  {
8204
8261
  ref: u,
8205
- avatarUrl: W.avatarUrl,
8206
- avatarBody: W.avatarBody,
8207
- mood: W.mood,
8208
- ttsLang: W.ttsLang,
8209
- ttsService: W.ttsService,
8210
- ttsVoice: W.ttsVoice,
8211
- ttsApiKey: W.ttsApiKey,
8212
- bodyMovement: W.bodyMovement,
8213
- movementIntensity: W.movementIntensity,
8214
- showFullAvatar: W.showFullAvatar,
8262
+ avatarUrl: j.avatarUrl,
8263
+ avatarBody: j.avatarBody,
8264
+ mood: j.mood,
8265
+ ttsLang: j.ttsLang,
8266
+ ttsService: j.ttsService,
8267
+ ttsVoice: j.ttsVoice,
8268
+ ttsApiKey: j.ttsApiKey,
8269
+ bodyMovement: j.bodyMovement,
8270
+ movementIntensity: j.movementIntensity,
8271
+ showFullAvatar: j.showFullAvatar,
8215
8272
  cameraView: "upper",
8216
- animations: W.animations,
8217
- onReady: le,
8273
+ animations: j.animations,
8274
+ onReady: be,
8218
8275
  onLoading: () => {
8219
8276
  },
8220
- onError: (v) => {
8221
- console.error("Avatar error:", v);
8277
+ onError: (b) => {
8278
+ console.error("Avatar error:", b);
8222
8279
  }
8223
8280
  }
8224
8281
  ) });
8225
8282
  });
8226
- yt.displayName = "CurriculumLearning";
8283
+ ft.displayName = "CurriculumLearning";
8227
8284
  const Ge = {
8228
8285
  // Code-based dance animations (no FBX required)
8229
8286
  dance: {
@@ -8327,15 +8384,15 @@ const Ge = {
8327
8384
  duration: 5e3,
8328
8385
  description: "Excited, energetic movement"
8329
8386
  }
8330
- }, wt = (X) => Ge[X] || null, zt = (X) => Ge.hasOwnProperty(X);
8387
+ }, zt = (V) => Ge[V] || null, Ct = (V) => Ge.hasOwnProperty(V);
8331
8388
  export {
8332
- yt as CurriculumLearning,
8333
- gt as SimpleTalkingAvatar,
8389
+ ft as CurriculumLearning,
8390
+ yt as SimpleTalkingAvatar,
8334
8391
  Ve as TalkingHeadAvatar,
8335
8392
  pt as TalkingHeadComponent,
8336
8393
  Ge as animations,
8337
8394
  Ee as getActiveTTSConfig,
8338
- wt as getAnimation,
8339
- kt as getVoiceOptions,
8340
- zt as hasAnimation
8395
+ zt as getAnimation,
8396
+ wt as getVoiceOptions,
8397
+ Ct as hasAnimation
8341
8398
  };