@sage-rsc/talking-head-react 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsxs as Pe, jsx as pe } from "react/jsx-runtime";
2
- import { forwardRef as Me, useRef as V, useState as de, useEffect as me, useCallback as N, useImperativeHandle as Fe, useLayoutEffect as Xe } from "react";
2
+ import { forwardRef as Me, useRef as V, useState as de, useEffect as me, useCallback as O, useImperativeHandle as Fe, useLayoutEffect as Xe } from "react";
3
3
  import * as f from "three";
4
4
  import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
5
5
  import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
@@ -8,7 +8,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
10
  let m, le, ue;
11
- const w = [0, 0, 0, 0], F = new f.Vector3(), ze = new f.Vector3(), ae = new f.Vector3(), Ce = new f.Vector3();
11
+ const w = [0, 0, 0, 0], M = new f.Vector3(), ze = new f.Vector3(), ae = new f.Vector3(), Ce = new f.Vector3();
12
12
  new f.Plane();
13
13
  new f.Ray();
14
14
  new f.Euler();
@@ -321,7 +321,7 @@ class et {
321
321
  /// Bone's parent object
322
322
  vBasis: r.position.clone(),
323
323
  // Original local position
324
- vWorld: r.parent.getWorldPosition(F).clone(),
324
+ vWorld: r.parent.getWorldPosition(M).clone(),
325
325
  // World position, parent
326
326
  qBasis: r.parent.quaternion.clone(),
327
327
  // Original quaternion, parent
@@ -338,7 +338,7 @@ class et {
338
338
  ea: [0, 0, 0, 0]
339
339
  // External acceleration [m/s^2]
340
340
  };
341
- u.boneParent.matrixWorld.decompose(F, re, ae), F.copy(He).applyQuaternion(re).setY(0).normalize(), re.premultiply(Oe.setFromUnitVectors(He, F).invert()).normalize(), u.qWorldInverseYaw = re.clone().normalize(), this.data.push(u), this.dict[h] = u;
341
+ u.boneParent.matrixWorld.decompose(M, re, ae), M.copy(He).applyQuaternion(re).setY(0).normalize(), re.premultiply(Oe.setFromUnitVectors(He, M).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], F.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), F.applyMatrix4(xe), F.length() > 0.5 && (console.info("Info: Unrealistic jump of " + F.length().toFixed(2) + " meters."), F.setLength(0.5)), F.applyQuaternion(o.bone.quaternion), w[0] = F.x, w[1] = F.y, w[2] = -F.z, w[3] = F.length() / 3, o.children)
359
+ if (o = this.data[e], M.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), M.applyMatrix4(xe), M.length() > 0.5 && (console.info("Info: Unrealistic jump of " + M.length().toFixed(2) + " meters."), M.setLength(0.5)), M.applyQuaternion(o.bone.quaternion), w[0] = M.x, w[1] = M.y, w[2] = -M.z, w[3] = M.length() / 3, o.children)
360
360
  for (n = 0, s = o.children.length; n < s; n++)
361
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, F.set(
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, M.set(
363
363
  o.vBasis.x + w[0],
364
364
  o.vBasis.y + w[1],
365
365
  o.vBasis.z + w[2]
366
- ), F.applyMatrix4(fe), F.x += m[0], F.y += m[1], F.z += m[2], F.applyMatrix4(xe), w[0] += F.x - o.vBasis.x, w[1] += F.y - o.vBasis.y, w[2] += F.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)
366
+ ), M.applyMatrix4(fe), M.x += m[0], M.y += m[1], M.z += m[2], M.applyMatrix4(xe), w[0] += M.x - o.vBasis.x, w[1] += M.y - o.vBasis.y, w[2] += M.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)
367
367
  o.bone.position.set(
368
368
  o.vBasis.x + w[0],
369
369
  o.vBasis.y + w[1],
370
370
  o.vBasis.z - w[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(F, re, ae), F.copy(He).applyQuaternion(re).setY(0).normalize(), re.premultiply(Oe.setFromUnitVectors(He, F).invert()).normalize(), o.boneParent.quaternion.multiply(re.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(w[0] / o.l), re.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(re)), 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), re.setFromAxisAngle(Ke, -m), o.boneParent.quaternion.multiply(re)), o.isT && (m = 1.5 * Math.tanh(w[3] * 1.5), re.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(re)), 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(M, re, ae), M.copy(He).applyQuaternion(re).setY(0).normalize(), re.premultiply(Oe.setFromUnitVectors(He, M).invert()).normalize(), o.boneParent.quaternion.multiply(re.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(w[0] / o.l), re.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(re)), 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), re.setFromAxisAngle(Ke, -m), o.boneParent.quaternion.multiply(re)), o.isT && (m = 1.5 * Math.tanh(w[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], 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), F.copy(o.bone.position), !(F.distanceToSquared(ae) >= m.radiusSq) && (ue = F.length(), le = ae.length(), !(le > m.radius + ue) && (le < Math.abs(m.radius - ue) || (le = (le * le + ue * ue - m.radiusSq) / (2 * le), ae.normalize(), Ce.copy(ae).multiplyScalar(le), le = Math.sqrt(ue * ue - le * le), F.subVectors(F, Ce).projectOnPlane(ae).normalize().multiplyScalar(le), ze.subVectors(o.vBasis, Ce).projectOnPlane(ae).normalize(), ue = ze.dot(F), ue < 0 && (ue = Math.sqrt(le * le - ue * ue), ze.multiplyScalar(ue), F.add(ze)), F.add(Ce).normalize(), ae.copy(o.bone.position).normalize(), re.setFromUnitVectors(ae, F), o.boneParent.quaternion.premultiply(re), 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), M.copy(o.bone.position), !(M.distanceToSquared(ae) >= m.radiusSq) && (ue = M.length(), le = ae.length(), !(le > m.radius + ue) && (le < Math.abs(m.radius - ue) || (le = (le * le + ue * ue - m.radiusSq) / (2 * le), ae.normalize(), Ce.copy(ae).multiplyScalar(le), le = Math.sqrt(ue * ue - le * le), M.subVectors(M, Ce).projectOnPlane(ae).normalize().multiplyScalar(le), ze.subVectors(o.vBasis, Ce).projectOnPlane(ae).normalize(), ue = ze.dot(M), ue < 0 && (ue = Math.sqrt(le * le - ue * ue), ze.multiplyScalar(ue), M.add(ze)), M.add(Ce).normalize(), ae.copy(o.bone.position).normalize(), re.setFromUnitVectors(ae, M), o.boneParent.quaternion.premultiply(re), o.boneParent.updateWorldMatrix(!1, !0))));
375
375
  }
376
376
  this.helpers.isActive && this.updateHelpers();
377
377
  }
@@ -445,14 +445,14 @@ class et {
445
445
  xe.copy(this.armature.matrixWorld).invert();
446
446
  const t = m.object.geometry.getAttribute("position");
447
447
  for (let e = 0, n = m.bones.length; e < n; e++)
448
- fe.multiplyMatrices(xe, m.bones[e].matrixWorld), F.setFromMatrixPosition(fe), t.setXYZ(e, F.x, F.y, F.z);
448
+ fe.multiplyMatrices(xe, m.bones[e].matrixWorld), M.setFromMatrixPosition(fe), t.setXYZ(e, M.x, M.y, M.z);
449
449
  t.needsUpdate = !0, m.object.updateMatrixWorld();
450
450
  }
451
451
  if (m = this.helpers.lines, m.bones.length) {
452
452
  xe.copy(this.armature.matrixWorld).invert();
453
453
  const t = m.object.geometry.getAttribute("position");
454
454
  for (let e = 0, n = 0, i = m.bones.length; e < i; e++, n += 2)
455
- fe.multiplyMatrices(xe, m.bones[e].matrixWorld), F.setFromMatrixPosition(fe), t.setXYZ(n, F.x, F.y, F.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), F.setFromMatrixPosition(fe), t.setXYZ(n + 1, F.x, F.y, F.z);
455
+ fe.multiplyMatrices(xe, m.bones[e].matrixWorld), M.setFromMatrixPosition(fe), t.setXYZ(n, M.x, M.y, M.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), M.setFromMatrixPosition(fe), t.setXYZ(n + 1, M.x, M.y, M.z);
456
456
  t.needsUpdate = !0, m.object.updateMatrixWorld();
457
457
  }
458
458
  }
@@ -2629,7 +2629,7 @@ const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2629
2629
  fr: rt,
2630
2630
  fi: ut,
2631
2631
  lt: ct
2632
- }, J = new f.Quaternion(), Z = new f.Euler(), ve = new f.Vector3(), Re = new f.Vector3(), We = new f.Box3();
2632
+ }, K = new f.Quaternion(), Z = new f.Euler(), ve = new f.Vector3(), Re = new f.Vector3(), We = new f.Box3();
2633
2633
  new f.Matrix4();
2634
2634
  new f.Matrix4();
2635
2635
  new f.Vector3();
@@ -4400,7 +4400,7 @@ class Be {
4400
4400
  if (e.x === 0 && e.y === 0 && e.z === 0) continue;
4401
4401
  Z.set(e.x, e.y, e.z);
4402
4402
  const n = this.poseAvatar.props[t];
4403
- n.isQuaternion ? (J.setFromEuler(Z), n.multiply(J)) : n.isVector3 && n.add(Z);
4403
+ n.isQuaternion ? (K.setFromEuler(Z), n.multiply(K)) : n.isVector3 && n.add(Z);
4404
4404
  }
4405
4405
  }
4406
4406
  /**
@@ -5193,7 +5193,7 @@ 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 && (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)
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 && (K.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(K)), 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) {
@@ -5266,8 +5266,8 @@ class Be {
5266
5266
  for (let x = 0; x < b.length; x++) {
5267
5267
  const S = x === b.length - 1, G = b[x].match(l);
5268
5268
  let p = b[x].match(s);
5269
- const P = b[x].match(h), H = b[x].match(o);
5270
- if (p && !S && !P && b[x + 1].match(s) && (p = !1), n && (u += b[x]), G && (!i || i.every((y) => x < y[0] || x > y[1])) && (a += b[x]), (H || p || S) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && c.push({
5269
+ const B = b[x].match(h), H = b[x].match(o);
5270
+ if (p && !S && !B && b[x + 1].match(s) && (p = !1), n && (u += b[x]), G && (!i || i.every((y) => x < y[0] || x > y[1])) && (a += b[x]), (H || p || S) && (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({
@@ -5300,7 +5300,7 @@ class Be {
5300
5300
  };
5301
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 = [];
5302
5302
  }
5303
- if (P) {
5303
+ if (B) {
5304
5304
  let y = this.animEmojis[b[x]];
5305
5305
  y && y.link && (y = this.animEmojis[y.link]), y && this.speechQueue.push({ emoji: y });
5306
5306
  }
@@ -5483,7 +5483,7 @@ 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((P) => P.name.includes(a) || P.lang === o);
5486
+ const p = u.find((B) => B.name.includes(a) || B.lang === o);
5487
5487
  p && (s.voice = p);
5488
5488
  }
5489
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);
@@ -5498,8 +5498,8 @@ class Be {
5498
5498
  const S = [];
5499
5499
  if (x && x.visemes && x.visemes.length > 0) {
5500
5500
  const p = x.times[x.visemes.length - 1] + x.durations[x.visemes.length - 1];
5501
- for (let P = 0; P < x.visemes.length; P++) {
5502
- const H = x.visemes[P], y = x.times[P] / p, I = x.durations[P] / p, z = y * d, A = I * d;
5501
+ for (let B = 0; B < x.visemes.length; B++) {
5502
+ const H = x.visemes[B], y = x.times[B] / p, I = x.durations[B] / p, z = y * d, A = I * d;
5503
5503
  S.push({
5504
5504
  template: { name: "viseme" },
5505
5505
  ts: [z - Math.min(60, 2 * A / 3), z + Math.min(25, A / 2), z + A + Math.min(60, A / 2)],
@@ -6159,10 +6159,10 @@ 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), 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"]);
6162
+ this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), K.copy(this.armature.quaternion), K.multiply(this.poseTarget.props["Hips.quaternion"]), K.multiply(this.poseTarget.props["Spine.quaternion"]), K.multiply(this.poseTarget.props["Spine1.quaternion"]), K.multiply(this.poseTarget.props["Spine2.quaternion"]), K.multiply(this.poseTarget.props["Neck.quaternion"]), K.multiply(this.poseTarget.props["Head.quaternion"]);
6163
6163
  const n = new f.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6164
6164
  Z.set(s, i, 0, "YXZ");
6165
- const l = new f.Quaternion().setFromEuler(Z), h = new f.Quaternion().copy(l).multiply(J.clone().invert());
6165
+ const l = new f.Quaternion().setFromEuler(Z), h = new f.Quaternion().copy(l).multiply(K.clone().invert());
6166
6166
  Z.setFromQuaternion(h, "YXZ");
6167
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;
6168
6168
  if (t) {
@@ -6199,13 +6199,13 @@ class Be {
6199
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);
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), 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"]), Z.setFromQuaternion(J);
6202
+ t === null && (t = h), e === null && (e = r), K.copy(this.armature.quaternion), K.multiply(this.poseTarget.props["Hips.quaternion"]), K.multiply(this.poseTarget.props["Spine.quaternion"]), K.multiply(this.poseTarget.props["Spine1.quaternion"]), K.multiply(this.poseTarget.props["Spine2.quaternion"]), K.multiply(this.poseTarget.props["Neck.quaternion"]), K.multiply(this.poseTarget.props["Head.quaternion"]), Z.setFromQuaternion(K);
6203
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
6204
  x = Math.min(0.6, Math.max(-0.3, x)), S = Math.min(0.8, Math.max(-0.8, S));
6205
6205
  let G = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6206
6206
  if (n) {
6207
- let P = this.animQueue.findIndex((y) => y.template.name === "lookat");
6208
- P !== -1 && this.animQueue.splice(P, 1);
6207
+ let B = this.animQueue.findIndex((y) => y.template.name === "lookat");
6208
+ B !== -1 && this.animQueue.splice(B, 1);
6209
6209
  const H = {
6210
6210
  name: "lookat",
6211
6211
  dt: [750, n],
@@ -6539,37 +6539,29 @@ class Be {
6539
6539
  (I) => I.includes("Arm") || I.includes("Hand") || I.includes("Shoulder")
6540
6540
  );
6541
6541
  console.log("FBX arm/hand/shoulder bones:", S.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:", G.sort().join(", "));
6542
- const p = [], P = /* @__PURE__ */ new Set();
6542
+ const p = [], B = /* @__PURE__ */ new Set();
6543
6543
  if (d.tracks.forEach((I) => {
6544
6544
  const A = I.name.replaceAll("mixamorig", "").split("."), Y = A[0], k = A[1], C = b(Y);
6545
6545
  if (C && k) {
6546
- const _ = `${C}.${k}`, B = I.clone();
6547
- B.name = _;
6548
- const ee = C.includes("Arm") || C.includes("Hand") || C.includes("Shoulder");
6549
- C.includes("Left"), C.includes("Right");
6550
- const ie = C.includes("ForeArm") || C.includes("Forearm"), oe = C.includes("Hand") && !C.includes("Index") && !C.includes("Thumb") && !C.includes("Middle") && !C.includes("Ring") && !C.includes("Pinky");
6551
- if (ee && (k === "quaternion" || k === "rotation") && k === "quaternion" && B.values && B.values.length >= 4) {
6552
- const he = B.times.length;
6553
- for (let K = 0; K < he; K++) {
6554
- const Q = K * 4;
6555
- if (Q + 3 < B.values.length) {
6556
- let W = B.values[Q], v = B.values[Q + 1], R = B.values[Q + 2], T = B.values[Q + 3];
6557
- const M = new f.Quaternion(W, v, R, T);
6558
- if (oe) {
6559
- const O = new f.Quaternion().setFromAxisAngle(new f.Vector3(0, 1, 0), Math.PI);
6560
- M.multiply(O);
6561
- } else if (ie) {
6562
- const O = new f.Quaternion().setFromAxisAngle(new f.Vector3(0, 0, 1), Math.PI / 2);
6563
- M.multiply(O);
6564
- }
6565
- B.values[Q] = M.x, B.values[Q + 1] = M.y, B.values[Q + 2] = M.z, B.values[Q + 3] = M.w;
6546
+ const q = `${C}.${k}`, N = I.clone();
6547
+ N.name = q;
6548
+ const $ = C.includes("Arm") || C.includes("Hand") || C.includes("Shoulder"), ie = C.includes("Left");
6549
+ C.includes("Right");
6550
+ const oe = C.includes("ForeArm") || C.includes("Forearm"), he = C.includes("Hand") && !C.includes("Index") && !C.includes("Thumb") && !C.includes("Middle") && !C.includes("Ring") && !C.includes("Pinky");
6551
+ if ($ && (k === "quaternion" || k === "rotation") && k === "quaternion" && N.values && N.values.length >= 4) {
6552
+ const ee = N.times.length;
6553
+ for (let ne = 0; ne < ee; ne++) {
6554
+ const D = ne * 4;
6555
+ if (D + 3 < N.values.length) {
6556
+ let v = N.values[D], R = N.values[D + 1], T = N.values[D + 2], F = N.values[D + 3], P = new f.Quaternion(v, R, T, F);
6557
+ ie && (he ? (P.conjugate(), P = new f.Quaternion().setFromAxisAngle(new f.Vector3(0, 1, 0), Math.PI).multiply(P)) : oe && (P = new f.Quaternion().setFromAxisAngle(new f.Vector3(0, 1, 0), Math.PI).multiply(P), P = new f.Quaternion().setFromAxisAngle(new f.Vector3(1, 0, 0), Math.PI / 2).multiply(P))), N.values[D] = P.x, N.values[D + 1] = P.y, N.values[D + 2] = P.z, N.values[D + 3] = P.w;
6566
6558
  }
6567
6559
  }
6568
6560
  }
6569
- p.push(B), Y !== C && g.set(Y, C);
6561
+ p.push(N), Y !== C && g.set(Y, C);
6570
6562
  } else
6571
- P.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`);
6572
- }), P.size > 0 && console.warn(`⚠️ ${P.size} bone(s) could not be mapped:`, Array.from(P).sort().join(", ")), p.length > 0) {
6563
+ 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`);
6564
+ }), B.size > 0 && console.warn(`⚠️ ${B.size} bone(s) could not be mapped:`, Array.from(B).sort().join(", ")), p.length > 0) {
6573
6565
  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(
6574
6566
  `✓ Mapped ${g.size} bone(s):`,
6575
6567
  Array.from(g.entries()).map(([z, A]) => `${z}→${A}`).join(", ")
@@ -6730,11 +6722,11 @@ class Be {
6730
6722
  if (e)
6731
6723
  for (let S = 0; S < x; S++) {
6732
6724
  let G = !1;
6733
- for (let p = 0, P = b.length; p < P; p++) {
6725
+ for (let p = 0, B = b.length; p < B; p++) {
6734
6726
  const H = b[p].bone;
6735
6727
  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();
6736
6728
  let y = s.dot(l);
6737
- 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(), J.setFromAxisAngle(a, y), H.quaternion.multiply(J), H.rotation.setFromVector3(d.setFromEuler(H.rotation).clamp(new f.Vector3(
6729
+ 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(), K.setFromAxisAngle(a, y), H.quaternion.multiply(K), H.rotation.setFromVector3(d.setFromEuler(H.rotation).clamp(new f.Vector3(
6738
6730
  b[p].minx !== void 0 ? b[p].minx : -1 / 0,
6739
6731
  b[p].miny !== void 0 ? b[p].miny : -1 / 0,
6740
6732
  b[p].minz !== void 0 ? b[p].minz : -1 / 0
@@ -6837,117 +6829,117 @@ const Ve = Me(({
6837
6829
  style: b = {},
6838
6830
  animations: x = {}
6839
6831
  }, S) => {
6840
- const G = V(null), p = V(null), P = V(r), H = V(null), y = V(null), I = V(!1), z = V({ remainingText: null, originalText: null, options: null }), A = V([]), Y = V(0), [k, C] = de(!0), [_, B] = de(null), [ee, ie] = de(!1), [oe, he] = de(!1);
6832
+ const G = V(null), p = V(null), B = V(r), H = V(null), y = V(null), I = V(!1), z = V({ remainingText: null, originalText: null, options: null }), A = V([]), Y = V(0), [k, C] = de(!0), [q, N] = de(null), [$, ie] = de(!1), [oe, he] = de(!1);
6841
6833
  me(() => {
6842
6834
  I.current = oe;
6843
6835
  }, [oe]), me(() => {
6844
- P.current = r;
6836
+ B.current = r;
6845
6837
  }, [r]);
6846
- const K = Ee(), Q = i || K.service;
6847
- let W;
6848
- Q === "browser" ? W = {
6838
+ const ee = Ee(), ne = i || ee.service;
6839
+ let D;
6840
+ ne === "browser" ? D = {
6849
6841
  service: "browser",
6850
6842
  endpoint: "",
6851
6843
  apiKey: null,
6852
6844
  defaultVoice: "Google US English"
6853
- } : Q === "elevenlabs" ? W = {
6845
+ } : ne === "elevenlabs" ? D = {
6854
6846
  service: "elevenlabs",
6855
6847
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
6856
- apiKey: o || K.apiKey,
6857
- defaultVoice: s || K.defaultVoice || Ie.defaultVoice,
6858
- voices: K.voices || Ie.voices
6859
- } : Q === "deepgram" ? W = {
6848
+ apiKey: o || ee.apiKey,
6849
+ defaultVoice: s || ee.defaultVoice || Ie.defaultVoice,
6850
+ voices: ee.voices || Ie.voices
6851
+ } : ne === "deepgram" ? D = {
6860
6852
  service: "deepgram",
6861
6853
  endpoint: "https://api.deepgram.com/v1/speak",
6862
- apiKey: o || K.apiKey,
6863
- defaultVoice: s || K.defaultVoice || Te.defaultVoice,
6864
- voices: K.voices || Te.voices
6865
- } : W = {
6866
- ...K,
6854
+ apiKey: o || ee.apiKey,
6855
+ defaultVoice: s || ee.defaultVoice || Te.defaultVoice,
6856
+ voices: ee.voices || Te.voices
6857
+ } : D = {
6858
+ ...ee,
6867
6859
  // Override API key if provided via props
6868
- apiKey: o !== null ? o : K.apiKey
6860
+ apiKey: o !== null ? o : ee.apiKey
6869
6861
  };
6870
6862
  const v = {
6871
6863
  url: X,
6872
6864
  body: t,
6873
6865
  avatarMood: e,
6874
- ttsLang: Q === "browser" ? "en-US" : n,
6875
- ttsVoice: s || W.defaultVoice,
6866
+ ttsLang: ne === "browser" ? "en-US" : n,
6867
+ ttsVoice: s || D.defaultVoice,
6876
6868
  lipsyncLang: "en",
6877
6869
  showFullAvatar: r,
6878
6870
  bodyMovement: l,
6879
6871
  movementIntensity: h
6880
6872
  }, R = {
6881
- ttsEndpoint: W.endpoint,
6882
- ttsApikey: W.apiKey,
6883
- ttsService: Q,
6873
+ ttsEndpoint: D.endpoint,
6874
+ ttsApikey: D.apiKey,
6875
+ ttsService: ne,
6884
6876
  lipsyncModules: ["en"],
6885
6877
  cameraView: u
6886
- }, T = N(async () => {
6878
+ }, T = O(async () => {
6887
6879
  if (!(!G.current || p.current))
6888
6880
  try {
6889
- if (C(!0), B(null), p.current = new Be(G.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, (U) => {
6890
- if (U.lengthComputable) {
6891
- const ne = Math.min(100, Math.round(U.loaded / U.total * 100));
6892
- d(ne);
6881
+ if (C(!0), N(null), p.current = new Be(G.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, (W) => {
6882
+ if (W.lengthComputable) {
6883
+ const te = Math.min(100, Math.round(W.loaded / W.total * 100));
6884
+ d(te);
6893
6885
  }
6894
- }), await new Promise((U) => {
6895
- const ne = () => {
6896
- p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? U() : setTimeout(ne, 100);
6886
+ }), await new Promise((W) => {
6887
+ const te = () => {
6888
+ p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? W() : setTimeout(te, 100);
6897
6889
  };
6898
- ne();
6890
+ te();
6899
6891
  }), p.current && p.current.setShowFullAvatar)
6900
6892
  try {
6901
6893
  p.current.setShowFullAvatar(r);
6902
- } catch (U) {
6903
- console.warn("Error setting full body mode on initialization:", U);
6894
+ } catch (W) {
6895
+ console.warn("Error setting full body mode on initialization:", W);
6904
6896
  }
6905
6897
  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()), C(!1), ie(!0), a(p.current);
6906
- const D = () => {
6898
+ const U = () => {
6907
6899
  document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
6908
6900
  };
6909
- return document.addEventListener("visibilitychange", D), () => {
6910
- document.removeEventListener("visibilitychange", D);
6901
+ return document.addEventListener("visibilitychange", U), () => {
6902
+ document.removeEventListener("visibilitychange", U);
6911
6903
  };
6912
6904
  } catch (L) {
6913
- console.error("Error initializing TalkingHead:", L), B(L.message || "Failed to initialize avatar"), C(!1), c(L);
6905
+ console.error("Error initializing TalkingHead:", L), N(L.message || "Failed to initialize avatar"), C(!1), c(L);
6914
6906
  }
6915
6907
  }, [X, t, e, n, i, s, o, r, l, h, u]);
6916
6908
  me(() => (T(), () => {
6917
6909
  p.current && (p.current.stop(), p.current.dispose(), p.current = null);
6918
6910
  }), [T]), me(() => {
6919
6911
  if (!G.current || !p.current) return;
6920
- const L = new ResizeObserver((U) => {
6921
- for (const ne of U)
6912
+ const L = new ResizeObserver((W) => {
6913
+ for (const te of W)
6922
6914
  p.current && p.current.onResize && p.current.onResize();
6923
6915
  });
6924
6916
  L.observe(G.current);
6925
- const D = () => {
6917
+ const U = () => {
6926
6918
  p.current && p.current.onResize && p.current.onResize();
6927
6919
  };
6928
- return window.addEventListener("resize", D), () => {
6929
- L.disconnect(), window.removeEventListener("resize", D);
6920
+ return window.addEventListener("resize", U), () => {
6921
+ L.disconnect(), window.removeEventListener("resize", U);
6930
6922
  };
6931
- }, [ee]);
6932
- const M = N(async () => {
6923
+ }, [$]);
6924
+ const F = O(async () => {
6933
6925
  if (p.current && p.current.audioCtx)
6934
6926
  try {
6935
6927
  (p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
6936
6928
  } catch (L) {
6937
6929
  console.warn("Failed to resume audio context:", L);
6938
6930
  }
6939
- }, []), O = N(async (L, D = {}) => {
6940
- if (p.current && ee)
6931
+ }, []), P = O(async (L, U = {}) => {
6932
+ if (p.current && $)
6941
6933
  try {
6942
- y.current && (clearInterval(y.current), y.current = null), H.current = { text: L, options: D }, z.current = { remainingText: null, originalText: null, options: null };
6943
- const U = /[!\.\?\n\p{Extended_Pictographic}]/ug, ne = L.split(U).map((j) => j.trim()).filter((j) => j.length > 0);
6944
- A.current = ne, Y.current = 0, he(!1), I.current = !1, await M();
6934
+ y.current && (clearInterval(y.current), y.current = null), H.current = { text: L, options: U }, z.current = { remainingText: null, originalText: null, options: null };
6935
+ const W = /[!\.\?\n\p{Extended_Pictographic}]/ug, te = L.split(W).map((Q) => Q.trim()).filter((Q) => Q.length > 0);
6936
+ A.current = te, Y.current = 0, he(!1), I.current = !1, await F();
6945
6937
  const ge = {
6946
- ...D,
6947
- lipsyncLang: D.lipsyncLang || v.lipsyncLang || "en"
6938
+ ...U,
6939
+ lipsyncLang: U.lipsyncLang || v.lipsyncLang || "en"
6948
6940
  };
6949
- if (D.onSpeechEnd && p.current) {
6950
- const j = p.current;
6941
+ if (U.onSpeechEnd && p.current) {
6942
+ const Q = p.current;
6951
6943
  let ce = null, Se = 0;
6952
6944
  const Le = 1200;
6953
6945
  let be = !1;
@@ -6958,19 +6950,19 @@ const Ve = Me(({
6958
6950
  if (ce && (clearInterval(ce), ce = null, y.current = null), !be && !I.current) {
6959
6951
  be = !0;
6960
6952
  try {
6961
- D.onSpeechEnd();
6953
+ U.onSpeechEnd();
6962
6954
  } catch (Ne) {
6963
6955
  console.error("Error in onSpeechEnd callback (timeout):", Ne);
6964
6956
  }
6965
6957
  }
6966
6958
  return;
6967
6959
  }
6968
- const ye = !j.speechQueue || j.speechQueue.length === 0, ke = !j.audioPlaylist || j.audioPlaylist.length === 0;
6969
- j && j.isSpeaking === !1 && ye && ke && j.isAudioPlaying === !1 && !be && !I.current && setTimeout(() => {
6970
- 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) {
6960
+ const ye = !Q.speechQueue || Q.speechQueue.length === 0, ke = !Q.audioPlaylist || Q.audioPlaylist.length === 0;
6961
+ Q && Q.isSpeaking === !1 && ye && ke && Q.isAudioPlaying === !1 && !be && !I.current && setTimeout(() => {
6962
+ if (Q && !I.current && Q.isSpeaking === !1 && (!Q.speechQueue || Q.speechQueue.length === 0) && (!Q.audioPlaylist || Q.audioPlaylist.length === 0) && Q.isAudioPlaying === !1 && !be && !I.current) {
6971
6963
  be = !0, ce && (clearInterval(ce), ce = null, y.current = null);
6972
6964
  try {
6973
- D.onSpeechEnd();
6965
+ U.onSpeechEnd();
6974
6966
  } catch (Ze) {
6975
6967
  console.error("Error in onSpeechEnd callback:", Ze);
6976
6968
  }
@@ -6979,72 +6971,72 @@ const Ve = Me(({
6979
6971
  }, 100), y.current = ce;
6980
6972
  }
6981
6973
  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 () => {
6982
- await M(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
6974
+ await F(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
6983
6975
  }, 100);
6984
- } catch (U) {
6985
- console.error("Error speaking text:", U), B(U.message || "Failed to speak text");
6976
+ } catch (W) {
6977
+ console.error("Error speaking text:", W), N(W.message || "Failed to speak text");
6986
6978
  }
6987
- }, [ee, M, v.lipsyncLang]), te = N(() => {
6979
+ }, [$, F, v.lipsyncLang]), _ = O(() => {
6988
6980
  p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), H.current = null, he(!1));
6989
- }, []), q = N(() => {
6981
+ }, []), j = O(() => {
6990
6982
  if (p.current && p.current.pauseSpeaking) {
6991
6983
  const L = p.current;
6992
6984
  if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
6993
6985
  y.current && (clearInterval(y.current), y.current = null);
6994
- let U = "";
6986
+ let W = "";
6995
6987
  if (H.current && A.current.length > 0) {
6996
- const ne = 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, ce = ge + (j ? 1 : 0), Se = ne - ce;
6997
- if (ce > 0 && Se < ne && (U = A.current.slice(Se).join(". ").trim(), !U && ge > 0 && L.speechQueue)) {
6988
+ const te = A.current.length, ge = L.speechQueue ? L.speechQueue.filter((Le) => Le && Le.text && Array.isArray(Le.text) && Le.text.length > 0).length : 0, Q = L.audioPlaylist && L.audioPlaylist.length > 0, ce = ge + (Q ? 1 : 0), Se = te - ce;
6989
+ if (ce > 0 && Se < te && (W = A.current.slice(Se).join(". ").trim(), !W && ge > 0 && L.speechQueue)) {
6998
6990
  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(" ");
6999
- be && be.trim() && (U = be.trim());
6991
+ be && be.trim() && (W = be.trim());
7000
6992
  }
7001
6993
  }
7002
6994
  H.current && (z.current = {
7003
- remainingText: U || null,
6995
+ remainingText: W || null,
7004
6996
  originalText: H.current.text,
7005
6997
  options: H.current.options
7006
6998
  }), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), I.current = !0, he(!0);
7007
6999
  }
7008
7000
  }
7009
- }, []), $ = N(async () => {
7001
+ }, []), J = O(async () => {
7010
7002
  if (!p.current || !oe)
7011
7003
  return;
7012
- let L = "", D = {};
7004
+ let L = "", U = {};
7013
7005
  if (z.current && z.current.remainingText)
7014
- L = z.current.remainingText, D = z.current.options || {}, z.current = { remainingText: null, originalText: null, options: null };
7006
+ L = z.current.remainingText, U = z.current.options || {}, z.current = { remainingText: null, originalText: null, options: null };
7015
7007
  else if (H.current && H.current.text)
7016
- L = H.current.text, D = H.current.options || {};
7008
+ L = H.current.text, U = H.current.options || {};
7017
7009
  else {
7018
7010
  console.warn("Resume called but no paused speech found"), he(!1), I.current = !1;
7019
7011
  return;
7020
7012
  }
7021
- he(!1), I.current = !1, await M();
7022
- const U = {
7023
- ...D,
7024
- lipsyncLang: D.lipsyncLang || v.lipsyncLang || "en"
7013
+ he(!1), I.current = !1, await F();
7014
+ const W = {
7015
+ ...U,
7016
+ lipsyncLang: U.lipsyncLang || v.lipsyncLang || "en"
7025
7017
  };
7026
7018
  try {
7027
- await O(L, U);
7028
- } catch (ne) {
7029
- console.error("Error resuming speech:", ne), he(!1), I.current = !1;
7019
+ await P(L, W);
7020
+ } catch (te) {
7021
+ console.error("Error resuming speech:", te), he(!1), I.current = !1;
7030
7022
  }
7031
- }, [M, oe, O, v]), Ae = N((L) => {
7023
+ }, [F, oe, P, v]), Ae = O((L) => {
7032
7024
  p.current && p.current.setMood(L);
7033
- }, []), we = N((L) => {
7025
+ }, []), we = O((L) => {
7034
7026
  p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
7035
- }, []), E = N((L, D = !1) => {
7027
+ }, []), E = O((L, U = !1) => {
7036
7028
  if (p.current && p.current.playAnimation) {
7037
7029
  if (x && x[L] && (L = x[L]), p.current.setShowFullAvatar)
7038
7030
  try {
7039
- p.current.setShowFullAvatar(P.current);
7040
- } catch (ne) {
7041
- console.warn("Error setting full body mode:", ne);
7031
+ p.current.setShowFullAvatar(B.current);
7032
+ } catch (te) {
7033
+ console.warn("Error setting full body mode:", te);
7042
7034
  }
7043
7035
  if (L.includes("."))
7044
7036
  try {
7045
- p.current.playAnimation(L, null, 10, 0, 0.01, D);
7046
- } catch (ne) {
7047
- console.warn(`Failed to play ${L}:`, ne);
7037
+ p.current.playAnimation(L, null, 10, 0, 0.01, U);
7038
+ } catch (te) {
7039
+ console.warn(`Failed to play ${L}:`, te);
7048
7040
  try {
7049
7041
  p.current.setBodyMovement("idle");
7050
7042
  } catch (ge) {
@@ -7052,11 +7044,11 @@ const Ve = Me(({
7052
7044
  }
7053
7045
  }
7054
7046
  else {
7055
- const ne = [".fbx", ".glb", ".gltf"];
7047
+ const te = [".fbx", ".glb", ".gltf"];
7056
7048
  let ge = !1;
7057
- for (const j of ne)
7049
+ for (const Q of te)
7058
7050
  try {
7059
- p.current.playAnimation(L + j, null, 10, 0, 0.01, D), ge = !0;
7051
+ p.current.playAnimation(L + Q, null, 10, 0, 0.01, U), ge = !0;
7060
7052
  break;
7061
7053
  } catch {
7062
7054
  }
@@ -7064,41 +7056,41 @@ const Ve = Me(({
7064
7056
  console.warn("Animation not found:", L);
7065
7057
  try {
7066
7058
  p.current.setBodyMovement("idle");
7067
- } catch (j) {
7068
- console.warn("Fallback animation also failed:", j);
7059
+ } catch (Q) {
7060
+ console.warn("Fallback animation also failed:", Q);
7069
7061
  }
7070
7062
  }
7071
7063
  }
7072
7064
  }
7073
- }, [x]), se = N(() => {
7065
+ }, [x]), se = O(() => {
7074
7066
  p.current && p.current.onResize && p.current.onResize();
7075
7067
  }, []);
7076
7068
  return Fe(S, () => ({
7077
- speakText: O,
7078
- stopSpeaking: te,
7079
- pauseSpeaking: q,
7080
- resumeSpeaking: $,
7081
- resumeAudioContext: M,
7069
+ speakText: P,
7070
+ stopSpeaking: _,
7071
+ pauseSpeaking: j,
7072
+ resumeSpeaking: J,
7073
+ resumeAudioContext: F,
7082
7074
  setMood: Ae,
7083
7075
  setTimingAdjustment: we,
7084
7076
  playAnimation: E,
7085
- isReady: ee,
7077
+ isReady: $,
7086
7078
  isPaused: oe,
7087
7079
  talkingHead: p.current,
7088
7080
  handleResize: se,
7089
7081
  setBodyMovement: (L) => {
7090
7082
  if (p.current && p.current.setShowFullAvatar && p.current.setBodyMovement)
7091
7083
  try {
7092
- p.current.setShowFullAvatar(P.current), p.current.setBodyMovement(L);
7093
- } catch (D) {
7094
- console.warn("Error setting body movement:", D);
7084
+ p.current.setShowFullAvatar(B.current), p.current.setBodyMovement(L);
7085
+ } catch (U) {
7086
+ console.warn("Error setting body movement:", U);
7095
7087
  }
7096
7088
  },
7097
7089
  setMovementIntensity: (L) => p.current?.setMovementIntensity(L),
7098
7090
  playRandomDance: () => {
7099
7091
  if (p.current && p.current.setShowFullAvatar && p.current.playRandomDance)
7100
7092
  try {
7101
- p.current.setShowFullAvatar(P.current), p.current.playRandomDance();
7093
+ p.current.setShowFullAvatar(B.current), p.current.playRandomDance();
7102
7094
  } catch (L) {
7103
7095
  console.warn("Error playing random dance:", L);
7104
7096
  }
@@ -7106,15 +7098,15 @@ const Ve = Me(({
7106
7098
  playReaction: (L) => {
7107
7099
  if (p.current && p.current.setShowFullAvatar && p.current.playReaction)
7108
7100
  try {
7109
- p.current.setShowFullAvatar(P.current), p.current.playReaction(L);
7110
- } catch (D) {
7111
- console.warn("Error playing reaction:", D);
7101
+ p.current.setShowFullAvatar(B.current), p.current.playReaction(L);
7102
+ } catch (U) {
7103
+ console.warn("Error playing reaction:", U);
7112
7104
  }
7113
7105
  },
7114
7106
  playCelebration: () => {
7115
7107
  if (p.current && p.current.setShowFullAvatar && p.current.playCelebration)
7116
7108
  try {
7117
- p.current.setShowFullAvatar(P.current), p.current.playCelebration();
7109
+ p.current.setShowFullAvatar(B.current), p.current.playCelebration();
7118
7110
  } catch (L) {
7119
7111
  console.warn("Error playing celebration:", L);
7120
7112
  }
@@ -7122,9 +7114,9 @@ const Ve = Me(({
7122
7114
  setShowFullAvatar: (L) => {
7123
7115
  if (p.current && p.current.setShowFullAvatar)
7124
7116
  try {
7125
- P.current = L, p.current.setShowFullAvatar(L);
7126
- } catch (D) {
7127
- console.warn("Error setting showFullAvatar:", D);
7117
+ B.current = L, p.current.setShowFullAvatar(L);
7118
+ } catch (U) {
7119
+ console.warn("Error setting showFullAvatar:", U);
7128
7120
  }
7129
7121
  },
7130
7122
  lockAvatarPosition: () => {
@@ -7175,7 +7167,7 @@ const Ve = Me(({
7175
7167
  fontSize: "18px",
7176
7168
  zIndex: 10
7177
7169
  }, children: "Loading avatar..." }),
7178
- _ && /* @__PURE__ */ pe("div", { className: "error-overlay", style: {
7170
+ q && /* @__PURE__ */ pe("div", { className: "error-overlay", style: {
7179
7171
  position: "absolute",
7180
7172
  top: "50%",
7181
7173
  left: "50%",
@@ -7186,7 +7178,7 @@ const Ve = Me(({
7186
7178
  zIndex: 10,
7187
7179
  padding: "20px",
7188
7180
  borderRadius: "8px"
7189
- }, children: _ })
7181
+ }, children: q })
7190
7182
  ]
7191
7183
  }
7192
7184
  );
@@ -7228,36 +7220,36 @@ const pt = Me(({
7228
7220
  bodyMovement: "idle",
7229
7221
  movementIntensity: 0.5,
7230
7222
  ...o
7231
- }, P = {
7223
+ }, B = {
7232
7224
  ttsEndpoint: G.endpoint,
7233
7225
  ttsApikey: G.apiKey,
7234
7226
  ttsService: S,
7235
7227
  lipsyncModules: ["en"],
7236
7228
  cameraView: "upper"
7237
- }, H = N(async () => {
7229
+ }, H = O(async () => {
7238
7230
  if (!(!h.current || r.current))
7239
7231
  try {
7240
- if (a(!0), c(null), r.current = new Be(h.current, P), await r.current.showAvatar(p, (_) => {
7241
- if (_.lengthComputable) {
7242
- const B = Math.min(100, Math.round(_.loaded / _.total * 100));
7243
- t(B);
7232
+ if (a(!0), c(null), r.current = new Be(h.current, B), await r.current.showAvatar(p, (q) => {
7233
+ if (q.lengthComputable) {
7234
+ const N = Math.min(100, Math.round(q.loaded / q.total * 100));
7235
+ t(N);
7244
7236
  }
7245
7237
  }), r.current.morphs && r.current.morphs.length > 0) {
7246
- const _ = r.current.morphs[0].morphTargetDictionary;
7247
- console.log("Available morph targets:", Object.keys(_));
7248
- const B = Object.keys(_).filter((ee) => ee.startsWith("viseme_"));
7249
- console.log("Viseme morph targets found:", B), B.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"));
7238
+ const q = r.current.morphs[0].morphTargetDictionary;
7239
+ console.log("Available morph targets:", Object.keys(q));
7240
+ const N = Object.keys(q).filter(($) => $.startsWith("viseme_"));
7241
+ console.log("Viseme morph targets found:", N), N.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"));
7250
7242
  }
7251
- if (await new Promise((_) => {
7252
- const B = () => {
7253
- r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), _()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(B, 100));
7243
+ if (await new Promise((q) => {
7244
+ const N = () => {
7245
+ 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(N, 100));
7254
7246
  };
7255
- B();
7247
+ N();
7256
7248
  }), r.current && r.current.setShowFullAvatar)
7257
7249
  try {
7258
7250
  r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
7259
- } catch (_) {
7260
- console.warn("Error setting full body mode on initialization:", _);
7251
+ } catch (q) {
7252
+ console.warn("Error setting full body mode on initialization:", q);
7261
7253
  }
7262
7254
  a(!1), b(!0), n(r.current);
7263
7255
  const C = () => {
@@ -7273,7 +7265,7 @@ const pt = Me(({
7273
7265
  me(() => (H(), () => {
7274
7266
  r.current && (r.current.stop(), r.current.dispose(), r.current = null);
7275
7267
  }), [H]);
7276
- const y = N((k) => {
7268
+ const y = O((k) => {
7277
7269
  if (r.current && g)
7278
7270
  try {
7279
7271
  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(() => {
@@ -7284,42 +7276,42 @@ const pt = Me(({
7284
7276
  }
7285
7277
  else
7286
7278
  console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
7287
- }, [g, p]), I = N(() => {
7279
+ }, [g, p]), I = O(() => {
7288
7280
  r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7289
- }, []), z = N((k) => {
7281
+ }, []), z = O((k) => {
7290
7282
  r.current && r.current.setMood(k);
7291
- }, []), A = N((k) => {
7283
+ }, []), A = O((k) => {
7292
7284
  r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(k), console.log("Timing adjustment set to:", k));
7293
- }, []), Y = N((k, C = !1) => {
7285
+ }, []), Y = O((k, C = !1) => {
7294
7286
  if (r.current && r.current.playAnimation) {
7295
7287
  if (r.current.setShowFullAvatar)
7296
7288
  try {
7297
7289
  r.current.setShowFullAvatar(!0);
7298
- } catch (B) {
7299
- console.warn("Error setting full body mode:", B);
7290
+ } catch (N) {
7291
+ console.warn("Error setting full body mode:", N);
7300
7292
  }
7301
7293
  if (k.includes("."))
7302
7294
  try {
7303
7295
  r.current.playAnimation(k, null, 10, 0, 0.01, C), console.log("Playing animation:", k);
7304
- } catch (B) {
7305
- console.log(`Failed to play ${k}:`, B);
7296
+ } catch (N) {
7297
+ console.log(`Failed to play ${k}:`, N);
7306
7298
  try {
7307
7299
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7308
- } catch (ee) {
7309
- console.warn("Fallback animation also failed:", ee);
7300
+ } catch ($) {
7301
+ console.warn("Fallback animation also failed:", $);
7310
7302
  }
7311
7303
  }
7312
7304
  else {
7313
- const B = [".fbx", ".glb", ".gltf"];
7314
- let ee = !1;
7315
- for (const ie of B)
7305
+ const N = [".fbx", ".glb", ".gltf"];
7306
+ let $ = !1;
7307
+ for (const ie of N)
7316
7308
  try {
7317
- r.current.playAnimation(k + ie, null, 10, 0, 0.01, C), console.log("Playing animation:", k + ie), ee = !0;
7309
+ r.current.playAnimation(k + ie, null, 10, 0, 0.01, C), console.log("Playing animation:", k + ie), $ = !0;
7318
7310
  break;
7319
7311
  } catch {
7320
7312
  console.log(`Failed to play ${k}${ie}, trying next format...`);
7321
7313
  }
7322
- if (!ee) {
7314
+ if (!$) {
7323
7315
  console.warn("Animation system not available or animation not found:", k);
7324
7316
  try {
7325
7317
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
@@ -7458,14 +7450,14 @@ const gt = Me(({
7458
7450
  style: S = {},
7459
7451
  animations: G = {},
7460
7452
  autoSpeak: p = !1
7461
- }, P) => {
7462
- const H = V(null), y = V(null), I = V(u), z = V(null), A = V(null), Y = V(!1), k = V({ remainingText: null, originalText: null, options: null }), C = V([]), [_, B] = de(!0), [ee, ie] = de(null), [oe, he] = de(!1), [K, Q] = de(!1);
7453
+ }, B) => {
7454
+ const H = V(null), y = V(null), I = V(u), z = V(null), A = V(null), Y = V(!1), k = V({ remainingText: null, originalText: null, options: null }), C = V([]), [q, N] = de(!0), [$, ie] = de(null), [oe, he] = de(!1), [ee, ne] = de(!1);
7463
7455
  me(() => {
7464
- Y.current = K;
7465
- }, [K]), me(() => {
7456
+ Y.current = ee;
7457
+ }, [ee]), me(() => {
7466
7458
  I.current = u;
7467
7459
  }, [u]);
7468
- const W = Ee(), v = s || W.service;
7460
+ const D = Ee(), v = s || D.service;
7469
7461
  let R;
7470
7462
  v === "browser" ? R = {
7471
7463
  service: "browser",
@@ -7475,18 +7467,18 @@ const gt = Me(({
7475
7467
  } : v === "elevenlabs" ? R = {
7476
7468
  service: "elevenlabs",
7477
7469
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
7478
- apiKey: l || W.apiKey,
7479
- defaultVoice: o || W.defaultVoice || Ie.defaultVoice,
7480
- voices: W.voices || Ie.voices
7470
+ apiKey: l || D.apiKey,
7471
+ defaultVoice: o || D.defaultVoice || Ie.defaultVoice,
7472
+ voices: D.voices || Ie.voices
7481
7473
  } : v === "deepgram" ? R = {
7482
7474
  service: "deepgram",
7483
7475
  endpoint: "https://api.deepgram.com/v1/speak",
7484
- apiKey: l || W.apiKey,
7485
- defaultVoice: o || W.defaultVoice || Te.defaultVoice,
7486
- voices: W.voices || Te.voices
7476
+ apiKey: l || D.apiKey,
7477
+ defaultVoice: o || D.defaultVoice || Te.defaultVoice,
7478
+ voices: D.voices || Te.voices
7487
7479
  } : R = {
7488
- ...W,
7489
- apiKey: l !== null ? l : W.apiKey
7480
+ ...D,
7481
+ apiKey: l !== null ? l : D.apiKey
7490
7482
  };
7491
7483
  const T = {
7492
7484
  url: t,
@@ -7498,16 +7490,16 @@ const gt = Me(({
7498
7490
  showFullAvatar: u,
7499
7491
  bodyMovement: h,
7500
7492
  movementIntensity: r
7501
- }, M = {
7493
+ }, F = {
7502
7494
  ttsEndpoint: R.endpoint,
7503
7495
  ttsApikey: R.apiKey,
7504
7496
  ttsService: v,
7505
7497
  lipsyncModules: ["en"],
7506
7498
  cameraView: a
7507
- }, O = N(async () => {
7499
+ }, P = O(async () => {
7508
7500
  if (!(!H.current || y.current))
7509
7501
  try {
7510
- B(!0), ie(null), y.current = new Be(H.current, M), console.log("Avatar config being passed:", {
7502
+ N(!0), ie(null), y.current = new Be(H.current, F), console.log("Avatar config being passed:", {
7511
7503
  url: T.url,
7512
7504
  body: T.body,
7513
7505
  avatarMood: T.avatarMood
@@ -7516,7 +7508,7 @@ const gt = Me(({
7516
7508
  const L = Math.min(100, Math.round(se.loaded / se.total * 100));
7517
7509
  c(L);
7518
7510
  }
7519
- }), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), B(!1), he(!0), d(y.current);
7511
+ }), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), N(!1), he(!0), d(y.current);
7520
7512
  const E = () => {
7521
7513
  document.visibilityState === "visible" ? y.current?.start() : y.current?.stop();
7522
7514
  };
@@ -7524,13 +7516,13 @@ const gt = Me(({
7524
7516
  document.removeEventListener("visibilitychange", E);
7525
7517
  };
7526
7518
  } catch (E) {
7527
- console.error("Error initializing TalkingHead:", E), ie(E.message || "Failed to initialize avatar"), B(!1), g(E);
7519
+ console.error("Error initializing TalkingHead:", E), ie(E.message || "Failed to initialize avatar"), N(!1), g(E);
7528
7520
  }
7529
7521
  }, []);
7530
- me(() => (O(), () => {
7522
+ me(() => (P(), () => {
7531
7523
  y.current && (y.current.stop(), y.current.dispose(), y.current = null);
7532
- }), [O]);
7533
- const te = N(async () => {
7524
+ }), [P]);
7525
+ const _ = O(async () => {
7534
7526
  if (y.current)
7535
7527
  try {
7536
7528
  const E = y.current.audioCtx || y.current.audioContext;
@@ -7538,7 +7530,7 @@ const gt = Me(({
7538
7530
  } catch (E) {
7539
7531
  console.warn("Failed to resume audio context:", E);
7540
7532
  }
7541
- }, []), q = N(async (E, se = {}) => {
7533
+ }, []), j = O(async (E, se = {}) => {
7542
7534
  if (!y.current || !oe) {
7543
7535
  console.warn("Avatar not ready for speaking");
7544
7536
  return;
@@ -7547,59 +7539,59 @@ const gt = Me(({
7547
7539
  console.warn("No text provided to speak");
7548
7540
  return;
7549
7541
  }
7550
- await te(), k.current = { remainingText: null, originalText: null, options: null }, C.current = [], z.current = { text: E, options: se }, A.current && (clearInterval(A.current), A.current = null), Q(!1), Y.current = !1;
7551
- const L = E.split(/[.!?]+/).filter((U) => U.trim().length > 0);
7542
+ await _(), k.current = { remainingText: null, originalText: null, options: null }, C.current = [], z.current = { text: E, options: se }, A.current && (clearInterval(A.current), A.current = null), ne(!1), Y.current = !1;
7543
+ const L = E.split(/[.!?]+/).filter((W) => W.trim().length > 0);
7552
7544
  C.current = L;
7553
- const D = {
7545
+ const U = {
7554
7546
  lipsyncLang: se.lipsyncLang || "en",
7555
7547
  onSpeechEnd: () => {
7556
7548
  A.current && (clearInterval(A.current), A.current = null), se.onSpeechEnd && se.onSpeechEnd(), b();
7557
7549
  }
7558
7550
  };
7559
7551
  try {
7560
- y.current.speakText(E, D);
7561
- } catch (U) {
7562
- console.error("Error speaking text:", U), ie(U.message || "Failed to speak text");
7552
+ y.current.speakText(E, U);
7553
+ } catch (W) {
7554
+ console.error("Error speaking text:", W), ie(W.message || "Failed to speak text");
7563
7555
  }
7564
- }, [oe, b, te]);
7556
+ }, [oe, b, _]);
7565
7557
  me(() => {
7566
- oe && X && p && y.current && q(X);
7567
- }, [oe, X, p, q]);
7568
- const $ = N(() => {
7558
+ oe && X && p && y.current && j(X);
7559
+ }, [oe, X, p, j]);
7560
+ const J = O(() => {
7569
7561
  if (y.current)
7570
7562
  try {
7571
7563
  const E = y.current.isSpeaking || !1, se = y.current.audioPlaylist || [], L = y.current.speechQueue || [];
7572
7564
  if (E || se.length > 0 || L.length > 0) {
7573
7565
  A.current && (clearInterval(A.current), A.current = null);
7574
- let D = "";
7575
- L.length > 0 && (D = L.map((U) => U.text && Array.isArray(U.text) ? U.text.map((ne) => ne.word).join(" ") : U.text || "").join(" ")), k.current = {
7576
- remainingText: D || null,
7566
+ let U = "";
7567
+ L.length > 0 && (U = L.map((W) => W.text && Array.isArray(W.text) ? W.text.map((te) => te.word).join(" ") : W.text || "").join(" ")), k.current = {
7568
+ remainingText: U || null,
7577
7569
  originalText: z.current?.text || null,
7578
7570
  options: z.current?.options || null
7579
- }, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), Q(!0), Y.current = !0;
7571
+ }, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), ne(!0), Y.current = !0;
7580
7572
  }
7581
7573
  } catch (E) {
7582
7574
  console.warn("Error pausing speech:", E);
7583
7575
  }
7584
- }, []), Ae = N(async () => {
7585
- if (!(!y.current || !K))
7576
+ }, []), Ae = O(async () => {
7577
+ if (!(!y.current || !ee))
7586
7578
  try {
7587
- await te(), Q(!1), Y.current = !1;
7588
- const E = k.current?.remainingText, se = k.current?.originalText || z.current?.text, L = k.current?.options || z.current?.options || {}, D = E || se;
7589
- D && q(D, L);
7579
+ await _(), ne(!1), Y.current = !1;
7580
+ const E = k.current?.remainingText, se = k.current?.originalText || z.current?.text, L = k.current?.options || z.current?.options || {}, U = E || se;
7581
+ U && j(U, L);
7590
7582
  } catch (E) {
7591
- console.warn("Error resuming speech:", E), Q(!1), Y.current = !1;
7583
+ console.warn("Error resuming speech:", E), ne(!1), Y.current = !1;
7592
7584
  }
7593
- }, [K, q, te]), we = N(() => {
7594
- y.current && (y.current.stopSpeaking(), A.current && (clearInterval(A.current), A.current = null), Q(!1), Y.current = !1);
7585
+ }, [ee, j, _]), we = O(() => {
7586
+ y.current && (y.current.stopSpeaking(), A.current && (clearInterval(A.current), A.current = null), ne(!1), Y.current = !1);
7595
7587
  }, []);
7596
- return Fe(P, () => ({
7597
- speakText: q,
7598
- pauseSpeaking: $,
7588
+ return Fe(B, () => ({
7589
+ speakText: j,
7590
+ pauseSpeaking: J,
7599
7591
  resumeSpeaking: Ae,
7600
7592
  stopSpeaking: we,
7601
- resumeAudioContext: te,
7602
- isPaused: () => K,
7593
+ resumeAudioContext: _,
7594
+ isPaused: () => ee,
7603
7595
  setMood: (E) => y.current?.setMood(E),
7604
7596
  setBodyMovement: (E) => {
7605
7597
  y.current && y.current.setBodyMovement(E);
@@ -7627,7 +7619,7 @@ const gt = Me(({
7627
7619
  }
7628
7620
  }
7629
7621
  ),
7630
- _ && /* @__PURE__ */ pe("div", { className: "loading-overlay", style: {
7622
+ q && /* @__PURE__ */ pe("div", { className: "loading-overlay", style: {
7631
7623
  position: "absolute",
7632
7624
  top: "50%",
7633
7625
  left: "50%",
@@ -7636,7 +7628,7 @@ const gt = Me(({
7636
7628
  fontSize: "18px",
7637
7629
  zIndex: 10
7638
7630
  }, children: "Loading avatar..." }),
7639
- ee && /* @__PURE__ */ pe("div", { className: "error-overlay", style: {
7631
+ $ && /* @__PURE__ */ pe("div", { className: "error-overlay", style: {
7640
7632
  position: "absolute",
7641
7633
  top: "50%",
7642
7634
  left: "50%",
@@ -7647,7 +7639,7 @@ const gt = Me(({
7647
7639
  zIndex: 10,
7648
7640
  padding: "20px",
7649
7641
  borderRadius: "8px"
7650
- }, children: ee })
7642
+ }, children: $ })
7651
7643
  ] });
7652
7644
  });
7653
7645
  gt.displayName = "SimpleTalkingAvatar";
@@ -7683,7 +7675,7 @@ const yt = Me(({
7683
7675
  onQuestionAnswer: s,
7684
7676
  onCurriculumComplete: o,
7685
7677
  onCustomAction: l
7686
- }), c = V(null), g = V(null), b = V(null), x = V(null), S = V(null), G = V(null), p = V(null), P = V(X?.curriculum || {
7678
+ }), c = V(null), g = V(null), b = V(null), x = V(null), S = V(null), G = V(null), p = V(null), B = V(X?.curriculum || {
7687
7679
  title: "Default Curriculum",
7688
7680
  description: "No curriculum data provided",
7689
7681
  language: "en",
@@ -7711,7 +7703,7 @@ const yt = Me(({
7711
7703
  onCustomAction: l
7712
7704
  };
7713
7705
  }, [n, i, s, o, l]), me(() => {
7714
- P.current = X?.curriculum || {
7706
+ B.current = X?.curriculum || {
7715
7707
  title: "Default Curriculum",
7716
7708
  description: "No curriculum data provided",
7717
7709
  language: "en",
@@ -7731,7 +7723,7 @@ const yt = Me(({
7731
7723
  lipsyncLang: "en"
7732
7724
  };
7733
7725
  }, [X, t, e]);
7734
- const y = N(() => (P.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), I = N(() => y()?.questions[a.current.currentQuestionIndex], [y]), z = N((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 = N(() => {
7726
+ const y = O(() => (B.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), I = O(() => y()?.questions[a.current.currentQuestionIndex], [y]), z = O((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 = O(() => {
7735
7727
  a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
7736
7728
  const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7737
7729
  let R = "Congratulations! You've completed this lesson";
@@ -7755,9 +7747,9 @@ const yt = Me(({
7755
7747
  } catch {
7756
7748
  u.current.playCelebration();
7757
7749
  }
7758
- const T = P.current || { modules: [] }, M = T.modules[a.current.currentModuleIndex], O = a.current.currentLessonIndex < (M?.lessons?.length || 0) - 1, te = a.current.currentModuleIndex < (T.modules?.length || 0) - 1, q = O || te, $ = H.current || { lipsyncLang: "en" };
7750
+ const T = B.current || { modules: [] }, F = T.modules[a.current.currentModuleIndex], P = a.current.currentLessonIndex < (F?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (T.modules?.length || 0) - 1, j = P || _, J = H.current || { lipsyncLang: "en" };
7759
7751
  u.current.speakText(R, {
7760
- lipsyncLang: $.lipsyncLang,
7752
+ lipsyncLang: J.lipsyncLang,
7761
7753
  onSpeechEnd: () => {
7762
7754
  d.current.onCustomAction({
7763
7755
  type: "lessonCompleteFeedbackDone",
@@ -7766,14 +7758,14 @@ const yt = Me(({
7766
7758
  score: a.current.score,
7767
7759
  totalQuestions: a.current.totalQuestions,
7768
7760
  percentage: v,
7769
- hasNextLesson: q
7761
+ hasNextLesson: j
7770
7762
  });
7771
7763
  }
7772
7764
  });
7773
7765
  }
7774
- }, [e.lessonComplete]), Y = N(() => {
7766
+ }, [e.lessonComplete]), Y = O(() => {
7775
7767
  a.current.curriculumCompleted = !0;
7776
- const v = P.current || { modules: [] };
7768
+ const v = B.current || { modules: [] };
7777
7769
  if (d.current.onCurriculumComplete({
7778
7770
  modules: v.modules.length,
7779
7771
  totalLessons: v.modules.reduce((R, T) => R + T.lessons.length, 0)
@@ -7787,7 +7779,7 @@ const yt = Me(({
7787
7779
  const R = H.current || { lipsyncLang: "en" };
7788
7780
  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 });
7789
7781
  }
7790
- }, [e.curriculumComplete]), k = N(() => {
7782
+ }, [e.curriculumComplete]), k = O(() => {
7791
7783
  const v = y();
7792
7784
  a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
7793
7785
  const R = I();
@@ -7805,26 +7797,26 @@ const yt = Me(({
7805
7797
  if (u.current.setMood("happy"), e.questionStart)
7806
7798
  try {
7807
7799
  u.current.playAnimation(e.questionStart, !0);
7808
- } catch (O) {
7809
- console.warn("Failed to play questionStart animation:", O);
7800
+ } catch (P) {
7801
+ console.warn("Failed to play questionStart animation:", P);
7810
7802
  }
7811
- const M = H.current || { lipsyncLang: "en" };
7812
- R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: M.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: M.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: M.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: M.lipsyncLang });
7803
+ const F = H.current || { lipsyncLang: "en" };
7804
+ R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: F.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: F.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: F.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: F.lipsyncLang });
7813
7805
  };
7814
7806
  if (u.current && u.current.isReady && R)
7815
7807
  T();
7816
7808
  else if (u.current && u.current.isReady) {
7817
- const M = H.current || { lipsyncLang: "en" };
7818
- u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: M.lipsyncLang });
7809
+ const F = H.current || { lipsyncLang: "en" };
7810
+ u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: F.lipsyncLang });
7819
7811
  } else {
7820
- const M = setInterval(() => {
7821
- u.current && u.current.isReady && (clearInterval(M), R && T());
7812
+ const F = setInterval(() => {
7813
+ u.current && u.current.isReady && (clearInterval(F), R && T());
7822
7814
  }, 100);
7823
7815
  setTimeout(() => {
7824
- clearInterval(M);
7816
+ clearInterval(F);
7825
7817
  }, 5e3);
7826
7818
  }
7827
- }, [e.questionStart, y, I]), C = N(() => {
7819
+ }, [e.questionStart, y, I]), C = O(() => {
7828
7820
  const v = y();
7829
7821
  if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
7830
7822
  u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
@@ -7843,40 +7835,40 @@ const yt = Me(({
7843
7835
  if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
7844
7836
  try {
7845
7837
  u.current.playAnimation(e.nextQuestion, !0);
7846
- } catch ($) {
7847
- console.warn("Failed to play nextQuestion animation:", $);
7838
+ } catch (J) {
7839
+ console.warn("Failed to play nextQuestion animation:", J);
7848
7840
  }
7849
- const M = H.current || { lipsyncLang: "en" }, te = y()?.questions?.length || 0, q = a.current.currentQuestionIndex >= te - 1;
7841
+ const F = H.current || { lipsyncLang: "en" }, _ = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= _ - 1;
7850
7842
  if (R.type === "code_test") {
7851
- const $ = q ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
7852
- u.current.speakText($, {
7853
- lipsyncLang: M.lipsyncLang
7843
+ const J = j ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
7844
+ u.current.speakText(J, {
7845
+ lipsyncLang: F.lipsyncLang
7854
7846
  });
7855
7847
  } else if (R.type === "multiple_choice") {
7856
- const $ = q ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
7857
- u.current.speakText($, {
7858
- lipsyncLang: M.lipsyncLang
7848
+ const J = j ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
7849
+ u.current.speakText(J, {
7850
+ lipsyncLang: F.lipsyncLang
7859
7851
  });
7860
7852
  } else if (R.type === "true_false") {
7861
- const $ = q ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
7862
- u.current.speakText($, {
7863
- lipsyncLang: M.lipsyncLang
7853
+ const J = j ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
7854
+ u.current.speakText(J, {
7855
+ lipsyncLang: F.lipsyncLang
7864
7856
  });
7865
7857
  } else {
7866
- const $ = q ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
7867
- u.current.speakText($, {
7868
- lipsyncLang: M.lipsyncLang
7858
+ const J = j ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
7859
+ u.current.speakText(J, {
7860
+ lipsyncLang: F.lipsyncLang
7869
7861
  });
7870
7862
  }
7871
7863
  };
7872
7864
  if (u.current && u.current.isReady && R)
7873
7865
  T();
7874
7866
  else if (R) {
7875
- const M = setInterval(() => {
7876
- u.current && u.current.isReady && (clearInterval(M), T());
7867
+ const F = setInterval(() => {
7868
+ u.current && u.current.isReady && (clearInterval(F), T());
7877
7869
  }, 100);
7878
7870
  setTimeout(() => {
7879
- clearInterval(M);
7871
+ clearInterval(F);
7880
7872
  }, 5e3);
7881
7873
  }
7882
7874
  } else
@@ -7887,16 +7879,16 @@ const yt = Me(({
7887
7879
  totalQuestions: a.current.totalQuestions,
7888
7880
  score: a.current.score
7889
7881
  });
7890
- }, [e.nextQuestion, y, I]), _ = N(() => {
7891
- const v = P.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
7882
+ }, [e.nextQuestion, y, I]), q = O(() => {
7883
+ const v = B.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
7892
7884
  if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
7893
7885
  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;
7894
- const M = v.modules[a.current.currentModuleIndex], O = a.current.currentLessonIndex < (M?.lessons?.length || 0) - 1, te = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = O || te;
7886
+ const F = v.modules[a.current.currentModuleIndex], P = a.current.currentLessonIndex < (F?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = P || _;
7895
7887
  d.current.onCustomAction({
7896
7888
  type: "lessonStart",
7897
7889
  moduleIndex: a.current.currentModuleIndex,
7898
7890
  lessonIndex: a.current.currentLessonIndex,
7899
- hasNextLesson: q
7891
+ hasNextLesson: j
7900
7892
  }), d.current.onLessonStart({
7901
7893
  moduleIndex: a.current.currentModuleIndex,
7902
7894
  lessonIndex: a.current.currentLessonIndex,
@@ -7904,12 +7896,12 @@ const yt = Me(({
7904
7896
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7905
7897
  } else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
7906
7898
  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;
7907
- const O = v.modules[a.current.currentModuleIndex], te = a.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, q = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, $ = te || q;
7899
+ const P = v.modules[a.current.currentModuleIndex], _ = a.current.currentLessonIndex < (P?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, J = _ || j;
7908
7900
  d.current.onCustomAction({
7909
7901
  type: "lessonStart",
7910
7902
  moduleIndex: a.current.currentModuleIndex,
7911
7903
  lessonIndex: a.current.currentLessonIndex,
7912
- hasNextLesson: $
7904
+ hasNextLesson: J
7913
7905
  }), d.current.onLessonStart({
7914
7906
  moduleIndex: a.current.currentModuleIndex,
7915
7907
  lessonIndex: a.current.currentLessonIndex,
@@ -7917,12 +7909,12 @@ const yt = Me(({
7917
7909
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7918
7910
  } else
7919
7911
  S.current && S.current();
7920
- }, []), B = N(() => {
7912
+ }, []), N = O(() => {
7921
7913
  const v = y();
7922
7914
  let R = null;
7923
7915
  if (v?.avatar_script && v?.body) {
7924
- const T = v.avatar_script.trim(), M = v.body.trim(), O = T.match(/[.!?]$/) ? " " : ". ";
7925
- R = `${T}${O}${M}`;
7916
+ const T = v.avatar_script.trim(), F = v.body.trim(), P = T.match(/[.!?]$/) ? " " : ". ";
7917
+ R = `${T}${P}${F}`;
7926
7918
  } else
7927
7919
  R = v?.avatar_script || v?.body || null;
7928
7920
  if (u.current && u.current.isReady && R) {
@@ -7931,11 +7923,11 @@ const yt = Me(({
7931
7923
  if (e.teaching)
7932
7924
  try {
7933
7925
  u.current.playAnimation(e.teaching, !0), T = !0;
7934
- } catch (O) {
7935
- console.warn("Failed to play teaching animation:", O);
7926
+ } catch (P) {
7927
+ console.warn("Failed to play teaching animation:", P);
7936
7928
  }
7937
7929
  T || u.current.setBodyMovement("gesturing");
7938
- const M = H.current || { lipsyncLang: "en" };
7930
+ const F = H.current || { lipsyncLang: "en" };
7939
7931
  d.current.onLessonStart({
7940
7932
  moduleIndex: a.current.currentModuleIndex,
7941
7933
  lessonIndex: a.current.currentLessonIndex,
@@ -7946,7 +7938,7 @@ const yt = Me(({
7946
7938
  lessonIndex: a.current.currentLessonIndex,
7947
7939
  lesson: v
7948
7940
  }), u.current.speakText(R, {
7949
- lipsyncLang: M.lipsyncLang,
7941
+ lipsyncLang: F.lipsyncLang,
7950
7942
  onSpeechEnd: () => {
7951
7943
  a.current.isTeaching = !1, d.current.onCustomAction({
7952
7944
  type: "teachingComplete",
@@ -7964,7 +7956,7 @@ const yt = Me(({
7964
7956
  }
7965
7957
  });
7966
7958
  }
7967
- }, [e.teaching, y]), ee = N((v) => {
7959
+ }, [e.teaching, y]), $ = O((v) => {
7968
7960
  const R = I(), T = z(v, R);
7969
7961
  if (T && (a.current.score += 1), d.current.onQuestionAnswer({
7970
7962
  moduleIndex: a.current.currentModuleIndex,
@@ -7982,13 +7974,13 @@ const yt = Me(({
7982
7974
  u.current.setBodyMovement("happy");
7983
7975
  }
7984
7976
  u.current.setBodyMovement("gesturing");
7985
- const O = y()?.questions?.length || 0;
7986
- a.current.currentQuestionIndex >= O - 1;
7987
- const te = a.current.currentQuestionIndex < O - 1;
7988
- console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", O, "hasNextQuestion:", te);
7989
- const q = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, $ = H.current || { lipsyncLang: "en" };
7990
- u.current.speakText(q, {
7991
- lipsyncLang: $.lipsyncLang,
7977
+ const P = y()?.questions?.length || 0;
7978
+ a.current.currentQuestionIndex >= P - 1;
7979
+ const _ = a.current.currentQuestionIndex < P - 1;
7980
+ console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", P, "hasNextQuestion:", _);
7981
+ const j = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, J = H.current || { lipsyncLang: "en" };
7982
+ u.current.speakText(j, {
7983
+ lipsyncLang: J.lipsyncLang,
7992
7984
  onSpeechEnd: () => {
7993
7985
  d.current.onCustomAction({
7994
7986
  type: "answerFeedbackComplete",
@@ -7996,7 +7988,7 @@ const yt = Me(({
7996
7988
  lessonIndex: a.current.currentLessonIndex,
7997
7989
  questionIndex: a.current.currentQuestionIndex,
7998
7990
  isCorrect: !0,
7999
- hasNextQuestion: te,
7991
+ hasNextQuestion: _,
8000
7992
  score: a.current.score,
8001
7993
  totalQuestions: a.current.totalQuestions
8002
7994
  });
@@ -8010,10 +8002,10 @@ const yt = Me(({
8010
8002
  u.current.setBodyMovement("idle");
8011
8003
  }
8012
8004
  u.current.setBodyMovement("gesturing");
8013
- const O = y()?.questions?.length || 0, te = a.current.currentQuestionIndex >= O - 1, q = a.current.currentQuestionIndex < O - 1;
8014
- console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", O, "hasNextQuestion:", q);
8015
- const $ = 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 || ""}${te ? "" : " Let's move on to the next question."}`, Ae = H.current || { lipsyncLang: "en" };
8016
- u.current.speakText($, {
8005
+ const P = y()?.questions?.length || 0, _ = a.current.currentQuestionIndex >= P - 1, j = a.current.currentQuestionIndex < P - 1;
8006
+ console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", P, "hasNextQuestion:", j);
8007
+ const J = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""}${_ ? "" : " Let's move on to the next question."}`, Ae = H.current || { lipsyncLang: "en" };
8008
+ u.current.speakText(J, {
8017
8009
  lipsyncLang: Ae.lipsyncLang,
8018
8010
  onSpeechEnd: () => {
8019
8011
  d.current.onCustomAction({
@@ -8022,7 +8014,7 @@ const yt = Me(({
8022
8014
  lessonIndex: a.current.currentLessonIndex,
8023
8015
  questionIndex: a.current.currentQuestionIndex,
8024
8016
  isCorrect: !1,
8025
- hasNextQuestion: q,
8017
+ hasNextQuestion: j,
8026
8018
  score: a.current.score,
8027
8019
  totalQuestions: a.current.totalQuestions
8028
8020
  });
@@ -8030,20 +8022,20 @@ const yt = Me(({
8030
8022
  });
8031
8023
  }
8032
8024
  else {
8033
- const O = y()?.questions?.length || 0;
8025
+ const P = y()?.questions?.length || 0;
8034
8026
  d.current.onCustomAction({
8035
8027
  type: "answerFeedbackComplete",
8036
8028
  moduleIndex: a.current.currentModuleIndex,
8037
8029
  lessonIndex: a.current.currentLessonIndex,
8038
8030
  questionIndex: a.current.currentQuestionIndex,
8039
8031
  isCorrect: T,
8040
- hasNextQuestion: a.current.currentQuestionIndex < O - 1,
8032
+ hasNextQuestion: a.current.currentQuestionIndex < P - 1,
8041
8033
  score: a.current.score,
8042
8034
  totalQuestions: a.current.totalQuestions,
8043
8035
  avatarNotReady: !0
8044
8036
  });
8045
8037
  }
8046
- }, [e.correct, e.incorrect, I, y, z]), ie = N((v) => {
8038
+ }, [e.correct, e.incorrect, I, y, z]), ie = O((v) => {
8047
8039
  const R = I();
8048
8040
  if (!v || typeof v != "object") {
8049
8041
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
@@ -8071,7 +8063,7 @@ const yt = Me(({
8071
8063
  testResult: T,
8072
8064
  question: R
8073
8065
  }), p.current && p.current(T);
8074
- }, [I, z]), oe = N(() => {
8066
+ }, [I, z]), oe = O(() => {
8075
8067
  if (a.current.currentQuestionIndex > 0) {
8076
8068
  a.current.currentQuestionIndex -= 1;
8077
8069
  const v = I();
@@ -8105,8 +8097,8 @@ const yt = Me(({
8105
8097
  }, 5e3);
8106
8098
  }
8107
8099
  }
8108
- }, [I]), he = N(() => {
8109
- const v = P.current || { modules: [] };
8100
+ }, [I]), he = O(() => {
8101
+ const v = B.current || { modules: [] };
8110
8102
  if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
8111
8103
  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({
8112
8104
  type: "lessonStart",
@@ -8118,8 +8110,8 @@ const yt = Me(({
8118
8110
  lesson: y()
8119
8111
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8120
8112
  else if (a.current.currentModuleIndex > 0) {
8121
- const M = v.modules[a.current.currentModuleIndex - 1];
8122
- a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (M?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, d.current.onCustomAction({
8113
+ const F = v.modules[a.current.currentModuleIndex - 1];
8114
+ a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (F?.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({
8123
8115
  type: "lessonStart",
8124
8116
  moduleIndex: a.current.currentModuleIndex,
8125
8117
  lessonIndex: a.current.currentLessonIndex
@@ -8129,9 +8121,9 @@ const yt = Me(({
8129
8121
  lesson: y()
8130
8122
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8131
8123
  }
8132
- }, [y]), K = N(() => {
8124
+ }, [y]), ee = O(() => {
8133
8125
  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;
8134
- }, []), Q = N((v) => {
8126
+ }, []), ne = O((v) => {
8135
8127
  console.log("Avatar is ready!", v);
8136
8128
  const R = y(), T = R?.avatar_script || R?.body;
8137
8129
  h && T && setTimeout(() => {
@@ -8139,20 +8131,20 @@ const yt = Me(({
8139
8131
  }, 10);
8140
8132
  }, [h, y]);
8141
8133
  Xe(() => {
8142
- c.current = B, g.current = _, b.current = A, x.current = C, S.current = Y, G.current = k, p.current = ee;
8134
+ c.current = N, g.current = q, b.current = A, x.current = C, S.current = Y, G.current = k, p.current = $;
8143
8135
  }), Fe(r, () => ({
8144
8136
  // Curriculum control methods
8145
- startTeaching: B,
8137
+ startTeaching: N,
8146
8138
  startQuestions: k,
8147
- handleAnswerSelect: ee,
8139
+ handleAnswerSelect: $,
8148
8140
  handleCodeTestResult: ie,
8149
8141
  nextQuestion: C,
8150
8142
  previousQuestion: oe,
8151
- nextLesson: _,
8143
+ nextLesson: q,
8152
8144
  previousLesson: he,
8153
8145
  completeLesson: A,
8154
8146
  completeCurriculum: Y,
8155
- resetCurriculum: K,
8147
+ resetCurriculum: ee,
8156
8148
  getState: () => ({ ...a.current }),
8157
8149
  getCurrentQuestion: () => I(),
8158
8150
  getCurrentLesson: () => y(),
@@ -8206,8 +8198,8 @@ const yt = Me(({
8206
8198
  handleResize: () => u.current?.handleResize(),
8207
8199
  // Avatar readiness check (always returns current value)
8208
8200
  isAvatarReady: () => u.current?.isReady || !1
8209
- }), [B, k, ee, ie, C, _, A, Y, K, I, y]);
8210
- const W = H.current || {
8201
+ }), [N, k, $, ie, C, q, A, Y, ee, I, y]);
8202
+ const D = H.current || {
8211
8203
  avatarUrl: "/avatars/brunette.glb",
8212
8204
  avatarBody: "F",
8213
8205
  mood: "happy",
@@ -8224,19 +8216,19 @@ const yt = Me(({
8224
8216
  Ve,
8225
8217
  {
8226
8218
  ref: u,
8227
- avatarUrl: W.avatarUrl,
8228
- avatarBody: W.avatarBody,
8229
- mood: W.mood,
8230
- ttsLang: W.ttsLang,
8231
- ttsService: W.ttsService,
8232
- ttsVoice: W.ttsVoice,
8233
- ttsApiKey: W.ttsApiKey,
8234
- bodyMovement: W.bodyMovement,
8235
- movementIntensity: W.movementIntensity,
8236
- showFullAvatar: W.showFullAvatar,
8219
+ avatarUrl: D.avatarUrl,
8220
+ avatarBody: D.avatarBody,
8221
+ mood: D.mood,
8222
+ ttsLang: D.ttsLang,
8223
+ ttsService: D.ttsService,
8224
+ ttsVoice: D.ttsVoice,
8225
+ ttsApiKey: D.ttsApiKey,
8226
+ bodyMovement: D.bodyMovement,
8227
+ movementIntensity: D.movementIntensity,
8228
+ showFullAvatar: D.showFullAvatar,
8237
8229
  cameraView: "upper",
8238
- animations: W.animations,
8239
- onReady: Q,
8230
+ animations: D.animations,
8231
+ onReady: ne,
8240
8232
  onLoading: () => {
8241
8233
  },
8242
8234
  onError: (v) => {