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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,20 +1,20 @@
1
1
  import { jsxs as Pe, jsx as me } from "react/jsx-runtime";
2
2
  import { forwardRef as Me, useRef as O, useState as ce, useEffect as de, useCallback as T, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
3
- import * as x from "three";
3
+ import * as f from "three";
4
4
  import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
5
5
  import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
6
6
  import { DRACOLoader as Qe } from "three/addons/loaders/DRACOLoader.js";
7
- import { FBXLoader as De } from "three/addons/loaders/FBXLoader.js";
7
+ import { FBXLoader as Oe } from "three/addons/loaders/FBXLoader.js";
8
8
  import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
9
9
  import Ke from "three/addons/libs/stats.module.js";
10
10
  let m, re, ue;
11
- const A = [0, 0, 0, 0], w = new x.Vector3(), ze = new x.Vector3(), ne = new x.Vector3(), Ce = new x.Vector3();
12
- new x.Plane();
13
- new x.Ray();
14
- new x.Euler();
15
- const ie = new x.Quaternion(), Ne = new x.Quaternion(), fe = new x.Matrix4(), xe = new x.Matrix4();
16
- new x.Vector3();
17
- const He = new x.Vector3(0, 0, 1), _e = new x.Vector3(1, 0, 0), Je = new x.Vector3(0, 1, 0), $e = new x.Vector3(0, 0, 1);
11
+ const A = [0, 0, 0, 0], w = new f.Vector3(), ze = new f.Vector3(), ne = new f.Vector3(), Ce = new f.Vector3();
12
+ new f.Plane();
13
+ new f.Ray();
14
+ new f.Euler();
15
+ const ie = new f.Quaternion(), De = new f.Quaternion(), fe = new f.Matrix4(), xe = new f.Matrix4();
16
+ new f.Vector3();
17
+ const He = new f.Vector3(0, 0, 1), _e = new f.Vector3(1, 0, 0), Je = new f.Vector3(0, 1, 0), $e = new f.Vector3(0, 0, 1);
18
18
  class et {
19
19
  constructor(t = null) {
20
20
  this.opt = Object.assign({
@@ -338,7 +338,7 @@ class et {
338
338
  ea: [0, 0, 0, 0]
339
339
  // External acceleration [m/s^2]
340
340
  };
341
- u.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Ne.setFromUnitVectors(He, w).invert()).normalize(), u.qWorldInverseYaw = ie.clone().normalize(), this.data.push(u), this.dict[h] = u;
341
+ u.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(De.setFromUnitVectors(He, w).invert()).normalize(), u.qWorldInverseYaw = ie.clone().normalize(), this.data.push(u), this.dict[h] = u;
342
342
  try {
343
343
  this.setValue(h, "type", s.type), this.setValue(h, "stiffness", s.stiffness), this.setValue(h, "damping", s.damping), this.setValue(h, "external", s.external), this.setValue(h, "limits", s.limits), this.setValue(h, "excludes", s.excludes), this.setValue(h, "deltaLocal", s.deltaLocal), this.setValue(h, "deltaWorld", s.deltaWorld), this.setValue(h, "pivot", s.pivot), this.setValue(h, "helper", s.helper);
344
344
  } catch (a) {
@@ -369,7 +369,7 @@ class et {
369
369
  o.vBasis.y + A[1],
370
370
  o.vBasis.z - A[2]
371
371
  );
372
- else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Ne.setFromUnitVectors(He, w).invert()).normalize(), o.boneParent.quaternion.multiply(ie.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), ie.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(ie)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), ie.setFromAxisAngle(_e, -m), o.boneParent.quaternion.multiply(ie)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), ie.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(ie)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
372
+ else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(De.setFromUnitVectors(He, w).invert()).normalize(), o.boneParent.quaternion.multiply(ie.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), ie.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(ie)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), ie.setFromAxisAngle(_e, -m), o.boneParent.quaternion.multiply(ie)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), ie.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(ie)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
373
373
  for (n = 0, s = o.excludes.length; n < s; n++)
374
374
  m = o.excludes[n], ne.set(0, 0, 0), m.deltaLocal && (ne.x += m.deltaLocal[0], ne.y += m.deltaLocal[1], ne.z += m.deltaLocal[2]), ne.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ne.applyMatrix4(xe), w.copy(o.bone.position), !(w.distanceToSquared(ne) >= m.radiusSq) && (ue = w.length(), re = ne.length(), !(re > m.radius + ue) && (re < Math.abs(m.radius - ue) || (re = (re * re + ue * ue - m.radiusSq) / (2 * re), ne.normalize(), Ce.copy(ne).multiplyScalar(re), re = Math.sqrt(ue * ue - re * re), w.subVectors(w, Ce).projectOnPlane(ne).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ne).normalize(), ue = ze.dot(w), ue < 0 && (ue = Math.sqrt(re * re - ue * ue), ze.multiplyScalar(ue), w.add(ze)), w.add(Ce).normalize(), ne.copy(o.bone.position).normalize(), ie.setFromUnitVectors(ne, w), o.boneParent.quaternion.premultiply(ie), o.boneParent.updateWorldMatrix(!1, !0))));
375
375
  }
@@ -393,7 +393,7 @@ class et {
393
393
  i || (m.excludes.bones.push(n.bone), m.excludes.radii.push(n.radius), m.excludes.deltaLocals.push(n.deltaLocal ? [...n.deltaLocal] : null), m.excludes.objects.push(null));
394
394
  }));
395
395
  }), m = this.helpers.excludes, this.opt.isExcludes && m.bones.length && m.bones.forEach((e, n) => {
396
- const i = new x.SphereGeometry(m.radii[n], 6, 6), s = new x.MeshBasicMaterial({
396
+ const i = new f.SphereGeometry(m.radii[n], 6, 6), s = new f.MeshBasicMaterial({
397
397
  depthTest: !1,
398
398
  depthWrite: !1,
399
399
  toneMapped: !1,
@@ -401,18 +401,18 @@ class et {
401
401
  wireframe: !0,
402
402
  color: this.opt.helperExcludesColor
403
403
  });
404
- m.objects[n] = new x.Mesh(i, s), m.objects[n].renderOrder = 997, e.add(m.objects[n]), m.deltaLocals[n] && m.objects[n].position.set(
404
+ m.objects[n] = new f.Mesh(i, s), m.objects[n].renderOrder = 997, e.add(m.objects[n]), m.deltaLocals[n] && m.objects[n].position.set(
405
405
  m.deltaLocals[n][0],
406
406
  m.deltaLocals[n][1],
407
407
  m.deltaLocals[n][2]
408
408
  );
409
409
  }), m = this.helpers.points, m.bones.length) {
410
410
  this.helpers.isActive = !0;
411
- const e = new x.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0]).flat();
412
- e.setAttribute("position", new x.Float32BufferAttribute(n, 3));
413
- const i = new x.Color(this.opt.helperBoneColor1), s = new x.Color(this.opt.helperBoneColor2), o = m.pivots.map((h) => h && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
414
- e.setAttribute("color", new x.Float32BufferAttribute(o, 3));
415
- const l = new x.PointsMaterial({
411
+ const e = new f.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0]).flat();
412
+ e.setAttribute("position", new f.Float32BufferAttribute(n, 3));
413
+ const i = new f.Color(this.opt.helperBoneColor1), s = new f.Color(this.opt.helperBoneColor2), o = m.pivots.map((h) => h && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
414
+ e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
415
+ const l = new f.PointsMaterial({
416
416
  depthTest: !1,
417
417
  depthWrite: !1,
418
418
  toneMapped: !1,
@@ -420,21 +420,21 @@ class et {
420
420
  size: 0.2,
421
421
  vertexColors: !0
422
422
  });
423
- m.object = new x.Points(e, l), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
423
+ m.object = new f.Points(e, l), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
424
424
  }
425
425
  if (m = this.helpers.lines, m.bones.length) {
426
- const e = new x.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0, 0, 0, 0]).flat();
427
- e.setAttribute("position", new x.Float32BufferAttribute(n, 3));
428
- const i = new x.Color(this.opt.helperLinkColor1), s = new x.Color(this.opt.helperLinkColor2), o = m.bones.map((h) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
429
- e.setAttribute("color", new x.Float32BufferAttribute(o, 3));
430
- const l = new x.LineBasicMaterial({
426
+ const e = new f.BufferGeometry(), n = m.bones.map((h) => [0, 0, 0, 0, 0, 0]).flat();
427
+ e.setAttribute("position", new f.Float32BufferAttribute(n, 3));
428
+ const i = new f.Color(this.opt.helperLinkColor1), s = new f.Color(this.opt.helperLinkColor2), o = m.bones.map((h) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
429
+ e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
430
+ const l = new f.LineBasicMaterial({
431
431
  vertexColors: !0,
432
432
  depthTest: !1,
433
433
  depthWrite: !1,
434
434
  toneMapped: !1,
435
435
  transparent: !0
436
436
  });
437
- m.object = new x.LineSegments(e, l), m.object.renderOrder = 999, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
437
+ m.object = new f.LineSegments(e, l), m.object.renderOrder = 999, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
438
438
  }
439
439
  }
440
440
  /**
@@ -606,8 +606,8 @@ class tt {
606
606
  for (let h = 0; h < e; h += i) {
607
607
  let r = 1, u = 0;
608
608
  for (let a = 0; a < i / 2; a++) {
609
- const c = n[(h + a) * 2], d = n[(h + a) * 2 + 1], g = n[(h + a + i / 2) * 2] * r - n[(h + a + i / 2) * 2 + 1] * u, y = n[(h + a + i / 2) * 2] * u + n[(h + a + i / 2) * 2 + 1] * r;
610
- n[(h + a) * 2] = c + g, n[(h + a) * 2 + 1] = d + y, n[(h + a + i / 2) * 2] = c - g, n[(h + a + i / 2) * 2 + 1] = d - y;
609
+ const c = n[(h + a) * 2], d = n[(h + a) * 2 + 1], g = n[(h + a + i / 2) * 2] * r - n[(h + a + i / 2) * 2 + 1] * u, x = n[(h + a + i / 2) * 2] * u + n[(h + a + i / 2) * 2 + 1] * r;
610
+ n[(h + a) * 2] = c + g, n[(h + a) * 2 + 1] = d + x, n[(h + a + i / 2) * 2] = c - g, n[(h + a + i / 2) * 2 + 1] = d - x;
611
611
  const b = r * o - u * l, I = r * l + u * o;
612
612
  r = b, u = I;
613
613
  }
@@ -2629,14 +2629,14 @@ const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2629
2629
  fr: rt,
2630
2630
  fi: ut,
2631
2631
  lt: ct
2632
- }, Q = new x.Quaternion(), W = new x.Euler(), ve = new x.Vector3(), Re = new x.Vector3(), We = new x.Box3();
2633
- new x.Matrix4();
2634
- new x.Matrix4();
2635
- new x.Vector3();
2636
- new x.Vector3(0, 0, 1);
2637
- const mt = new x.Vector3(1, 0, 0);
2638
- new x.Vector3(0, 1, 0);
2639
- new x.Vector3(0, 0, 1);
2632
+ }, Q = new f.Quaternion(), V = new f.Euler(), ve = new f.Vector3(), Re = new f.Vector3(), We = new f.Box3();
2633
+ new f.Matrix4();
2634
+ new f.Matrix4();
2635
+ new f.Vector3();
2636
+ new f.Vector3(0, 0, 1);
2637
+ const mt = new f.Vector3(1, 0, 0);
2638
+ new f.Vector3(0, 1, 0);
2639
+ new f.Vector3(0, 0, 1);
2640
2640
  class Be {
2641
2641
  /**
2642
2642
  * Avatar.
@@ -3636,14 +3636,23 @@ class Be {
3636
3636
  anims: [
3637
3637
  { name: "breathing", delay: 1500, dt: [1200, 500, 1e3], vs: { chestInhale: [0.5, 0.5, 0] } },
3638
3638
  { name: "pose", alt: [
3639
- { p: 0.5, delay: [5e3, 3e4], vs: { pose: ["side"] } },
3639
+ {
3640
+ p: 0.5,
3641
+ delay: [5e3, 3e4],
3642
+ vs: { pose: ["side"] },
3643
+ M: { delay: [5e3, 3e4], vs: { pose: ["wide"] } }
3644
+ },
3640
3645
  {
3641
3646
  p: 0.3,
3642
3647
  delay: [5e3, 3e4],
3643
3648
  vs: { pose: ["hip"] },
3644
3649
  M: { delay: [5e3, 3e4], vs: { pose: ["wide"] } }
3645
3650
  },
3646
- { delay: [5e3, 3e4], vs: { pose: ["straight"] } }
3651
+ {
3652
+ delay: [5e3, 3e4],
3653
+ vs: { pose: ["straight"] },
3654
+ M: { delay: [5e3, 3e4], vs: { pose: ["wide"] } }
3655
+ }
3647
3656
  ] },
3648
3657
  {
3649
3658
  name: "head",
@@ -3665,12 +3674,17 @@ class Be {
3665
3674
  name: "pose",
3666
3675
  idle: {
3667
3676
  alt: [
3668
- { p: 0.6, delay: [5e3, 3e4], vs: { pose: ["side"] } },
3677
+ {
3678
+ p: 0.6,
3679
+ delay: [5e3, 3e4],
3680
+ vs: { pose: ["side"] },
3681
+ M: { delay: [5e3, 3e4], vs: { pose: ["wide"] } }
3682
+ },
3669
3683
  {
3670
3684
  p: 0.2,
3671
3685
  delay: [5e3, 3e4],
3672
3686
  vs: { pose: ["hip"] },
3673
- M: { delay: [5e3, 3e4], vs: { pose: ["side"] } }
3687
+ M: { delay: [5e3, 3e4], vs: { pose: ["wide"] } }
3674
3688
  },
3675
3689
  { p: 0.1, delay: [5e3, 3e4], vs: { pose: ["straight"] } },
3676
3690
  { delay: [5e3, 1e4], vs: { pose: ["wide"] } },
@@ -3679,8 +3693,18 @@ class Be {
3679
3693
  },
3680
3694
  speaking: {
3681
3695
  alt: [
3682
- { p: 0.4, delay: [5e3, 3e4], vs: { pose: ["side"] } },
3683
- { p: 0.4, delay: [5e3, 3e4], vs: { pose: ["straight"] } },
3696
+ {
3697
+ p: 0.4,
3698
+ delay: [5e3, 3e4],
3699
+ vs: { pose: ["side"] },
3700
+ M: { delay: [5e3, 3e4], vs: { pose: ["wide"] } }
3701
+ },
3702
+ {
3703
+ p: 0.4,
3704
+ delay: [5e3, 3e4],
3705
+ vs: { pose: ["straight"] },
3706
+ M: { delay: [5e3, 3e4], vs: { pose: ["wide"] } }
3707
+ },
3684
3708
  {
3685
3709
  delay: [5e3, 2e4],
3686
3710
  vs: { pose: ["hip"] },
@@ -4049,22 +4073,22 @@ class Be {
4049
4073
  if (this.isAvatarOnly = this.opt.avatarOnly, this.isAvatarOnly)
4050
4074
  this.scene = this.opt.avatarOnlyScene, this.camera = this.opt.avatarOnlyCamera;
4051
4075
  else {
4052
- this.renderer = new x.WebGLRenderer({ antialias: !0, alpha: !0 }), this.renderer.setPixelRatio(this.opt.modelPixelRatio * window.devicePixelRatio), this.renderer.setSize(this.nodeAvatar.clientWidth, this.nodeAvatar.clientHeight), this.renderer.outputColorSpace = x.SRGBColorSpace, this.renderer.toneMapping = x.ACESFilmicToneMapping, this.renderer.shadowMap.enabled = !1, this.nodeAvatar.appendChild(this.renderer.domElement), this.camera = new x.PerspectiveCamera(10, this.nodeAvatar.clientWidth / this.nodeAvatar.clientHeight, 0.1, 2e3), this.scene = new x.Scene(), this.lightAmbient = new x.AmbientLight(
4053
- new x.Color(this.opt.lightAmbientColor),
4076
+ this.renderer = new f.WebGLRenderer({ antialias: !0, alpha: !0 }), this.renderer.setPixelRatio(this.opt.modelPixelRatio * window.devicePixelRatio), this.renderer.setSize(this.nodeAvatar.clientWidth, this.nodeAvatar.clientHeight), this.renderer.outputColorSpace = f.SRGBColorSpace, this.renderer.toneMapping = f.ACESFilmicToneMapping, this.renderer.shadowMap.enabled = !1, this.nodeAvatar.appendChild(this.renderer.domElement), this.camera = new f.PerspectiveCamera(10, this.nodeAvatar.clientWidth / this.nodeAvatar.clientHeight, 0.1, 2e3), this.scene = new f.Scene(), this.lightAmbient = new f.AmbientLight(
4077
+ new f.Color(this.opt.lightAmbientColor),
4054
4078
  this.opt.lightAmbientIntensity
4055
- ), this.lightDirect = new x.DirectionalLight(
4056
- new x.Color(this.opt.lightDirectColor),
4079
+ ), this.lightDirect = new f.DirectionalLight(
4080
+ new f.Color(this.opt.lightDirectColor),
4057
4081
  this.opt.lightDirectIntensity
4058
- ), this.lightSpot = new x.SpotLight(
4059
- new x.Color(this.opt.lightSpotColor),
4082
+ ), this.lightSpot = new f.SpotLight(
4083
+ new f.Color(this.opt.lightSpotColor),
4060
4084
  this.opt.lightSpotIntensity,
4061
4085
  0,
4062
4086
  this.opt.lightSpotDispersion
4063
4087
  ), this.setLighting(this.opt);
4064
- const l = new x.PMREMGenerator(this.renderer);
4088
+ const l = new f.PMREMGenerator(this.renderer);
4065
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;
4066
4090
  }
4067
- this.ikMesh = new x.SkinnedMesh();
4091
+ this.ikMesh = new f.SkinnedMesh();
4068
4092
  const s = {
4069
4093
  LeftShoulder: null,
4070
4094
  LeftArm: "LeftShoulder",
@@ -4078,9 +4102,9 @@ class Be {
4078
4102
  RightHandMiddle1: "RightHand"
4079
4103
  }, o = [];
4080
4104
  Object.entries(s).forEach((l, h) => {
4081
- const r = new x.Bone();
4105
+ const r = new f.Bone();
4082
4106
  r.name = l[0], l[1] ? this.ikMesh.getObjectByName(l[1]).add(r) : this.ikMesh.add(r), o.push(r);
4083
- }), this.ikMesh.bind(new x.Skeleton(o)), this.dynamicbones = new et(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
4107
+ }), this.ikMesh.bind(new f.Skeleton(o)), this.dynamicbones = new et(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
4084
4108
  }
4085
4109
  /**
4086
4110
  * Helper that re/creates the audio context and the other nodes.
@@ -4170,7 +4194,7 @@ class Be {
4170
4194
  for (let [n, i] of Object.entries(t)) {
4171
4195
  const s = n.split(".");
4172
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;
4173
- s[1] === "position" || s[1] === "scale" ? e[n] = new x.Vector3(o, l, h) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new x.Quaternion().setFromEuler(new x.Euler(o, l, h, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new x.Quaternion(o, l, h, i.w).normalize());
4197
+ s[1] === "position" || s[1] === "scale" ? e[n] = new f.Vector3(o, l, h) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new f.Quaternion().setFromEuler(new f.Euler(o, l, h, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new f.Quaternion(o, l, h, i.w).normalize());
4174
4198
  }
4175
4199
  return e;
4176
4200
  }
@@ -4202,15 +4226,15 @@ class Be {
4202
4226
  for (const [r, u] of Object.entries(n))
4203
4227
  if (s.morphTargetDictionary.hasOwnProperty(r)) {
4204
4228
  const a = s.morphTargetDictionary[r], c = o.morphAttributes.position[a], d = o.morphAttributes.normal?.[a];
4205
- l || (l = new x.Float32BufferAttribute(c.count * 3, 3), d && (h = new x.Float32BufferAttribute(c.count * 3, 3)));
4229
+ l || (l = new f.Float32BufferAttribute(c.count * 3, 3), d && (h = new f.Float32BufferAttribute(c.count * 3, 3)));
4206
4230
  for (let g = 0; g < c.count; g++) {
4207
- const y = l.getX(g) + c.getX(g) * u, b = l.getY(g) + c.getY(g) * u, I = l.getZ(g) + c.getZ(g) * u;
4208
- l.setXYZ(g, y, b, I);
4231
+ const x = l.getX(g) + c.getX(g) * u, b = l.getY(g) + c.getY(g) * u, I = l.getZ(g) + c.getZ(g) * u;
4232
+ l.setXYZ(g, x, b, I);
4209
4233
  }
4210
4234
  if (d)
4211
4235
  for (let g = 0; g < c.count; g++) {
4212
- const y = h.getX(g) + d.getX(g) * u, b = h.getY(g) + d.getY(g) * u, I = h.getZ(g) + d.getZ(g) * u;
4213
- h.setXYZ(g, y, b, I);
4236
+ const x = h.getX(g) + d.getX(g) * u, b = h.getY(g) + d.getY(g) * u, I = h.getZ(g) + d.getZ(g) * u;
4237
+ h.setXYZ(g, x, b, I);
4214
4238
  }
4215
4239
  }
4216
4240
  if (l) {
@@ -4290,7 +4314,7 @@ class Be {
4290
4314
  console.error("Dynamic bones setup failed: " + r);
4291
4315
  }
4292
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");
4293
- const h = new x.Vector3();
4317
+ const h = new f.Vector3();
4294
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();
4295
4319
  }
4296
4320
  /**
@@ -4334,14 +4358,14 @@ class Be {
4334
4358
  default:
4335
4359
  a += 12, u = u * a;
4336
4360
  }
4337
- r = r * a, this.controlsEnd = new x.Vector3(r, u, 0), this.cameraEnd = new x.Vector3(r, u, a).applyEuler(new x.Euler(o, l, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
4361
+ r = r * a, this.controlsEnd = new f.Vector3(r, u, 0), this.cameraEnd = new f.Vector3(r, u, a).applyEuler(new f.Euler(o, l, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
4338
4362
  }
4339
4363
  /**
4340
4364
  * Change light colors and intensities.
4341
4365
  * @param {Object} opt Options
4342
4366
  */
4343
4367
  setLighting(t) {
4344
- this.isAvatarOnly || (t = t || {}, t.hasOwnProperty("lightAmbientColor") && this.lightAmbient.color.set(new x.Color(t.lightAmbientColor)), t.hasOwnProperty("lightAmbientIntensity") && (this.lightAmbient.intensity = t.lightAmbientIntensity, this.lightAmbient.visible = t.lightAmbientIntensity !== 0), t.hasOwnProperty("lightDirectColor") && this.lightDirect.color.set(new x.Color(t.lightDirectColor)), t.hasOwnProperty("lightDirectIntensity") && (this.lightDirect.intensity = t.lightDirectIntensity, this.lightDirect.visible = t.lightDirectIntensity !== 0), t.hasOwnProperty("lightDirectPhi") && t.hasOwnProperty("lightDirectTheta") && this.lightDirect.position.setFromSphericalCoords(2, t.lightDirectPhi, t.lightDirectTheta), t.hasOwnProperty("lightSpotColor") && this.lightSpot.color.set(new x.Color(t.lightSpotColor)), t.hasOwnProperty("lightSpotIntensity") && (this.lightSpot.intensity = t.lightSpotIntensity, this.lightSpot.visible = t.lightSpotIntensity !== 0), t.hasOwnProperty("lightSpotPhi") && t.hasOwnProperty("lightSpotTheta") && (this.lightSpot.position.setFromSphericalCoords(2, t.lightSpotPhi, t.lightSpotTheta), this.lightSpot.position.add(new x.Vector3(0, 1.5, 0))), t.hasOwnProperty("lightSpotDispersion") && (this.lightSpot.angle = t.lightSpotDispersion));
4368
+ this.isAvatarOnly || (t = t || {}, t.hasOwnProperty("lightAmbientColor") && this.lightAmbient.color.set(new f.Color(t.lightAmbientColor)), t.hasOwnProperty("lightAmbientIntensity") && (this.lightAmbient.intensity = t.lightAmbientIntensity, this.lightAmbient.visible = t.lightAmbientIntensity !== 0), t.hasOwnProperty("lightDirectColor") && this.lightDirect.color.set(new f.Color(t.lightDirectColor)), t.hasOwnProperty("lightDirectIntensity") && (this.lightDirect.intensity = t.lightDirectIntensity, this.lightDirect.visible = t.lightDirectIntensity !== 0), t.hasOwnProperty("lightDirectPhi") && t.hasOwnProperty("lightDirectTheta") && this.lightDirect.position.setFromSphericalCoords(2, t.lightDirectPhi, t.lightDirectTheta), t.hasOwnProperty("lightSpotColor") && this.lightSpot.color.set(new f.Color(t.lightSpotColor)), t.hasOwnProperty("lightSpotIntensity") && (this.lightSpot.intensity = t.lightSpotIntensity, this.lightSpot.visible = t.lightSpotIntensity !== 0), t.hasOwnProperty("lightSpotPhi") && t.hasOwnProperty("lightSpotTheta") && (this.lightSpot.position.setFromSphericalCoords(2, t.lightSpotPhi, t.lightSpotTheta), this.lightSpot.position.add(new f.Vector3(0, 1.5, 0))), t.hasOwnProperty("lightSpotDispersion") && (this.lightSpot.angle = t.lightSpotDispersion));
4345
4369
  }
4346
4370
  /**
4347
4371
  * Render scene.
@@ -4374,9 +4398,9 @@ class Be {
4374
4398
  updatePoseDelta() {
4375
4399
  for (const [t, e] of Object.entries(this.poseDelta.props)) {
4376
4400
  if (e.x === 0 && e.y === 0 && e.z === 0) continue;
4377
- W.set(e.x, e.y, e.z);
4401
+ V.set(e.x, e.y, e.z);
4378
4402
  const n = this.poseAvatar.props[t];
4379
- n.isQuaternion ? (Q.setFromEuler(W), n.multiply(Q)) : n.isVector3 && n.add(W);
4403
+ n.isQuaternion ? (Q.setFromEuler(V), n.multiply(Q)) : n.isVector3 && n.add(V);
4380
4404
  }
4381
4405
  }
4382
4406
  /**
@@ -4456,7 +4480,7 @@ class Be {
4456
4480
  return Object.entries(t).forEach((i, s) => {
4457
4481
  const o = i[0].split(".");
4458
4482
  if (o[1] === "position" || o[1] === "rotation" || o[1] === "quaternion") {
4459
- const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], h = i[1].isQuaternion ? new x.Euler().setFromQuaternion(i[1]) : i[1];
4483
+ const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], h = i[1].isQuaternion ? new f.Euler().setFromQuaternion(i[1]) : i[1];
4460
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 += "}";
4461
4485
  }
4462
4486
  }), n += "}", n;
@@ -4999,7 +5023,7 @@ class Be {
4999
5023
  }
5000
5024
  s ? o.ts = o.ts.map((r) => h + r * n) : o.ts = o.ts.map((r) => this.animClock + h + r * n), l.vs && l.vs.pose && console.log("Pose being selected from vs.pose:", l.vs.pose, "for avatar body:", this.avatar?.body);
5001
5025
  for (let [r, u] of Object.entries(l.vs)) {
5002
- const a = this.getBaselineValue(r), c = u.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? r === "pose" && this.avatar && this.avatar.body === "M" && d === "hip" ? (console.log("Intercepting hip pose in animation factory, overriding to wide"), "wide") : d.slice() : Array.isArray(d) ? r === "gesture" ? d.slice() : (a === void 0 ? 0 : a) + i * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (a === void 0 ? 0 : a) + i * d));
5026
+ const a = this.getBaselineValue(r), c = u.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? r === "pose" && this.avatar && this.avatar.body === "M" && (d === "hip" || d === "side") ? (console.log("Intercepting pose", d, "in animation factory, overriding to wide for male avatar"), "wide") : d.slice() : Array.isArray(d) ? r === "gesture" ? d.slice() : (a === void 0 ? 0 : a) + i * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (a === void 0 ? 0 : a) + i * d));
5003
5027
  r === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyeLookInLeft = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookOutRight = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookInRight = [null, ...c.map((d) => d > 0 ? d : 0)]) : r === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyesLookUp = [null, ...c.map((d) => d > 0 ? 0 : -d)]) : o.vs[r] = [null, ...c];
5004
5028
  }
5005
5029
  for (let r of Object.keys(o.vs))
@@ -5095,9 +5119,9 @@ class Be {
5095
5119
  g.newvalue = d[i];
5096
5120
  else {
5097
5121
  g.newvalue = d[i + 1];
5098
- const y = a.ts[i + 1] - a.ts[i];
5122
+ const x = a.ts[i + 1] - a.ts[i];
5099
5123
  let b = 1;
5100
- y > 1e-4 && (b = (this.animClock - a.ts[i]) / y), b < 1 && (g.easing && (b = g.easing(b)), g.newvalue = (1 - b) * d[i] + b * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(c) && delete g.ref[c], g.ref = a.vs;
5124
+ x > 1e-4 && (b = (this.animClock - a.ts[i]) / x), b < 1 && (g.easing && (b = g.easing(b)), g.newvalue = (1 - b) * d[i] + b * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(c) && delete g.ref[c], g.ref = a.vs;
5101
5125
  }
5102
5126
  if (l)
5103
5127
  switch (c) {
@@ -5122,7 +5146,7 @@ class Be {
5122
5146
  this.onSubtitles && typeof this.onSubtitles == "function" && this.onSubtitles(i);
5123
5147
  break;
5124
5148
  case "pose":
5125
- this.avatar && this.avatar.body === "M" && i === "hip" && (this.poseTemplates.wide ? (i = "wide", console.log("Overriding hip pose to wide for male avatar")) : this.poseTemplates.side && (i = "side", console.log("Overriding hip pose to side for male avatar"))), this.poseName = i, console.log("Setting pose to:", this.poseName, "for avatar body:", this.avatar?.body, "state:", this.stateName), this.setPoseFromTemplate(this.poseTemplates[this.poseName]);
5149
+ this.avatar && this.avatar.body === "M" && (i === "hip" || i === "side") && this.poseTemplates.wide && (i = "wide", console.log("Overriding pose", i === "hip" ? "hip" : "side", "to wide for male avatar")), this.poseName = i, console.log("Setting pose to:", this.poseName, "for avatar body:", this.avatar?.body, "state:", this.stateName), this.setPoseFromTemplate(this.poseTemplates[this.poseName]);
5126
5150
  break;
5127
5151
  case "gesture":
5128
5152
  this.playGesture(...i);
@@ -5145,7 +5169,7 @@ class Be {
5145
5169
  { link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
5146
5170
  { link: "LeftArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
5147
5171
  ]
5148
- }, i.x ? new x.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5172
+ }, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5149
5173
  break;
5150
5174
  case "handRight":
5151
5175
  this.ikSolve({
@@ -5157,10 +5181,10 @@ class Be {
5157
5181
  { link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5, maxAngle: 0.2 },
5158
5182
  { link: "RightArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
5159
5183
  ]
5160
- }, i.x ? new x.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5184
+ }, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5161
5185
  break;
5162
5186
  }
5163
- if ((h || r) && (W.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), W.x = Math.max(-0.9, Math.min(0.9, 2 * W.x - 0.5)), W.y = Math.max(-0.9, Math.min(0.9, -2.5 * W.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: W.x < 0 ? -W.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: W.x < 0 ? 0 : W.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: W.y < 0 ? -W.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: W.y < 0 ? 0 : W.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: W.y < 0 ? 0 : W.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: W.y < 0 ? -W.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
5187
+ if ((h || r) && (V.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), V.x = Math.max(-0.9, Math.min(0.9, 2 * V.x - 0.5)), V.y = Math.max(-0.9, Math.min(0.9, -2.5 * V.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: V.x < 0 ? -V.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: V.x < 0 ? 0 : V.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: V.y < 0 ? -V.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: V.y < 0 ? 0 : V.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: V.y < 0 ? 0 : V.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: V.y < 0 ? -V.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
5164
5188
  name: "headmove",
5165
5189
  dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
5166
5190
  vs: {
@@ -5186,7 +5210,7 @@ class Be {
5186
5210
  else {
5187
5211
  if (this.cameraClock !== null && this.cameraClock < 1e3) {
5188
5212
  this.cameraClock += e, this.cameraClock > 1e3 && (this.cameraClock = 1e3);
5189
- let a = new x.Spherical().setFromVector3(this.cameraStart), c = new x.Spherical().setFromVector3(this.cameraEnd);
5213
+ let a = new f.Spherical().setFromVector3(this.cameraStart), c = new f.Spherical().setFromVector3(this.cameraEnd);
5190
5214
  a.phi += this.easing(this.cameraClock / 1e3) * (c.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (c.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (c.radius - a.radius), a.makeSafe(), this.camera.position.setFromSpherical(a), this.controlsStart.x !== this.controlsEnd.x ? this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd, this.easing(this.cameraClock / 1e3))) : (a.setFromVector3(this.controlsStart), c.setFromVector3(this.controlsEnd), a.phi += this.easing(this.cameraClock / 1e3) * (c.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (c.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (c.radius - a.radius), a.makeSafe(), this.controls.target.setFromSpherical(a)), this.controls.update();
5191
5215
  }
5192
5216
  this.controls.autoRotate && this.controls.update(), this.stats && this.stats.end(), this.render();
@@ -5250,12 +5274,12 @@ class Be {
5250
5274
  e = e || {};
5251
5275
  const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, h = /[\p{Extended_Pictographic}]/ug, r = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
5252
5276
  let u = "", a = "", c = 0, d = [], g = [];
5253
- const y = Array.from(this.segmenter.segment(t), (b) => b.segment);
5254
- for (let b = 0; b < y.length; b++) {
5255
- const I = b === y.length - 1, V = y[b].match(l);
5256
- let p = y[b].match(s);
5257
- const M = y[b].match(h), z = y[b].match(o);
5258
- if (p && !I && !M && y[b + 1].match(s) && (p = !1), n && (u += y[b]), V && (!i || i.every((f) => b < f[0] || b > f[1])) && (a += y[b]), (z || p || I) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
5277
+ const x = Array.from(this.segmenter.segment(t), (b) => b.segment);
5278
+ for (let b = 0; b < x.length; b++) {
5279
+ const I = b === x.length - 1, B = x[b].match(l);
5280
+ let p = x[b].match(s);
5281
+ const M = x[b].match(h), z = x[b].match(o);
5282
+ if (p && !I && !M && x[b + 1].match(s) && (p = !1), n && (u += x[b]), B && (!i || i.every((y) => b < y[0] || b > y[1])) && (a += x[b]), (z || p || I) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
5259
5283
  mark: c,
5260
5284
  word: a
5261
5285
  })), u.length && (g.push({
@@ -5266,16 +5290,16 @@ class Be {
5266
5290
  subtitles: [u]
5267
5291
  }
5268
5292
  }), u = ""), a.length)) {
5269
- const f = this.lipsyncWordsToVisemes(a, r);
5270
- if (f && f.visemes && f.visemes.length) {
5271
- const E = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
5272
- for (let P = 0; P < f.visemes.length; P++)
5293
+ const y = this.lipsyncWordsToVisemes(a, r);
5294
+ if (y && y.visemes && y.visemes.length) {
5295
+ const E = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
5296
+ for (let P = 0; P < y.visemes.length; P++)
5273
5297
  g.push({
5274
5298
  mark: c,
5275
5299
  template: { name: "viseme" },
5276
- ts: [(f.times[P] - 0.6) / E, (f.times[P] + 0.5) / E, (f.times[P] + f.durations[P] + 0.5) / E],
5300
+ ts: [(y.times[P] - 0.6) / E, (y.times[P] + 0.5) / E, (y.times[P] + y.durations[P] + 0.5) / E],
5277
5301
  vs: {
5278
- ["viseme_" + f.visemes[P]]: [null, f.visemes[P] === "PP" || f.visemes[P] === "FF" ? 0.9 : 0.6, 0]
5302
+ ["viseme_" + y.visemes[P]]: [null, y.visemes[P] === "PP" || y.visemes[P] === "FF" ? 0.9 : 0.6, 0]
5279
5303
  }
5280
5304
  });
5281
5305
  }
@@ -5283,14 +5307,14 @@ class Be {
5283
5307
  }
5284
5308
  if (p || I) {
5285
5309
  if (d.length || I && g.length) {
5286
- const f = {
5310
+ const y = {
5287
5311
  anim: g
5288
5312
  };
5289
- n && (f.onSubtitles = n), d.length && !e.avatarMute && (f.text = d, e.avatarMood && (f.mood = e.avatarMood), e.ttsLang && (f.lang = e.ttsLang), e.ttsVoice && (f.voice = e.ttsVoice), e.ttsRate && (f.rate = e.ttsRate), e.ttsVoice && (f.pitch = e.ttsPitch), e.ttsVolume && (f.volume = e.ttsVolume)), this.speechQueue.push(f), d = [], a = "", c = 0, g = [];
5313
+ n && (y.onSubtitles = n), d.length && !e.avatarMute && (y.text = d, e.avatarMood && (y.mood = e.avatarMood), e.ttsLang && (y.lang = e.ttsLang), e.ttsVoice && (y.voice = e.ttsVoice), e.ttsRate && (y.rate = e.ttsRate), e.ttsVoice && (y.pitch = e.ttsPitch), e.ttsVolume && (y.volume = e.ttsVolume)), this.speechQueue.push(y), d = [], a = "", c = 0, g = [];
5290
5314
  }
5291
5315
  if (M) {
5292
- let f = this.animEmojis[y[b]];
5293
- f && f.link && (f = this.animEmojis[f.link]), f && this.speechQueue.push({ emoji: f });
5316
+ let y = this.animEmojis[x[b]];
5317
+ y && y.link && (y = this.animEmojis[y.link]), y && this.speechQueue.push({ emoji: y });
5294
5318
  }
5295
5319
  this.speechQueue.push({ break: 100 });
5296
5320
  }
@@ -5383,15 +5407,15 @@ class Be {
5383
5407
  const a = this.lipsyncPreProcessText(h, i), c = this.lipsyncWordsToVisemes(a, i);
5384
5408
  if (c && c.visemes && c.visemes.length) {
5385
5409
  const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(u, Math.max(0, u - c.visemes.length * 150));
5386
- let y = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
5410
+ let x = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
5387
5411
  if (u = Math.min(u, c.visemes.length * 200), d > 0)
5388
5412
  for (let b = 0; b < c.visemes.length; b++) {
5389
- const I = r + c.times[b] / d * u, V = c.durations[b] / d * u;
5413
+ const I = r + c.times[b] / d * u, B = c.durations[b] / d * u;
5390
5414
  o.push({
5391
5415
  template: { name: "viseme" },
5392
- ts: [I - Math.min(60, 2 * V / 3), I + Math.min(25, V / 2), I + V + Math.min(60, V / 2)],
5416
+ ts: [I - Math.min(60, 2 * B / 3), I + Math.min(25, B / 2), I + B + Math.min(60, B / 2)],
5393
5417
  vs: {
5394
- ["viseme_" + c.visemes[b]]: [null, c.visemes[b] === "PP" || c.visemes[b] === "FF" ? 0.9 : y, 0]
5418
+ ["viseme_" + c.visemes[b]]: [null, c.visemes[b] === "PP" || c.visemes[b] === "FF" ? 0.9 : x, 0]
5395
5419
  }
5396
5420
  });
5397
5421
  }
@@ -5474,11 +5498,11 @@ class Be {
5474
5498
  const p = u.find((M) => M.name.includes(a) || M.lang === o);
5475
5499
  p && (s.voice = p);
5476
5500
  }
5477
- const c = i.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", y = this.lipsyncPreProcessText(i, g), b = this.lipsyncWordsToVisemes(y, g);
5501
+ const c = i.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", x = this.lipsyncPreProcessText(i, g), b = this.lipsyncWordsToVisemes(x, g);
5478
5502
  console.log("Browser TTS Lip-sync Debug:", {
5479
5503
  text: i,
5480
5504
  lipsyncLang: g,
5481
- processedText: y,
5505
+ processedText: x,
5482
5506
  lipsyncData: b,
5483
5507
  hasVisemes: b && b.visemes && b.visemes.length > 0,
5484
5508
  estimatedDuration: c
@@ -5487,18 +5511,18 @@ class Be {
5487
5511
  if (b && b.visemes && b.visemes.length > 0) {
5488
5512
  const p = b.times[b.visemes.length - 1] + b.durations[b.visemes.length - 1];
5489
5513
  for (let M = 0; M < b.visemes.length; M++) {
5490
- const z = b.visemes[M], f = b.times[M] / p, E = b.durations[M] / p, P = f * c, U = E * c;
5514
+ const z = b.visemes[M], y = b.times[M] / p, E = b.durations[M] / p, P = y * c, W = E * c;
5491
5515
  I.push({
5492
5516
  template: { name: "viseme" },
5493
- ts: [P - Math.min(60, 2 * U / 3), P + Math.min(25, U / 2), P + U + Math.min(60, U / 2)],
5517
+ ts: [P - Math.min(60, 2 * W / 3), P + Math.min(25, W / 2), P + W + Math.min(60, W / 2)],
5494
5518
  vs: {
5495
5519
  ["viseme_" + z]: [null, z === "PP" || z === "FF" ? 0.9 : 0.6, 0]
5496
5520
  }
5497
5521
  });
5498
5522
  }
5499
5523
  }
5500
- const V = [...t.anim, ...I];
5501
- this.audioPlaylist.push({ anim: V, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5524
+ const B = [...t.anim, ...I];
5525
+ this.audioPlaylist.push({ anim: B, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5502
5526
  e();
5503
5527
  }, s.onerror = (p) => {
5504
5528
  console.error("Speech synthesis error:", p.error), n(p.error);
@@ -5547,10 +5571,10 @@ class Be {
5547
5571
  hasVisemes: d && d.visemes && d.visemes.length > 0
5548
5572
  }), d && d.visemes && d.visemes.length > 0)
5549
5573
  r = {
5550
- visemes: d.visemes.map((g, y) => ({
5574
+ visemes: d.visemes.map((g, x) => ({
5551
5575
  viseme: g,
5552
- startTime: y * l.duration / d.visemes.length,
5553
- endTime: (y + 1) * l.duration / d.visemes.length,
5576
+ startTime: x * l.duration / d.visemes.length,
5577
+ endTime: (x + 1) * l.duration / d.visemes.length,
5554
5578
  duration: l.duration / d.visemes.length,
5555
5579
  intensity: 0.7
5556
5580
  })),
@@ -5563,14 +5587,14 @@ class Be {
5563
5587
  } catch (c) {
5564
5588
  console.error("Text-based lip-sync failed, using fallback:", c);
5565
5589
  const d = e.toLowerCase().split(/\s+/), g = [];
5566
- for (const y of d)
5567
- for (const b of y) {
5590
+ for (const x of d)
5591
+ for (const b of x) {
5568
5592
  let I = "aa";
5569
5593
  "aeiou".includes(b) ? I = "aa" : "bp".includes(b) ? I = "PP" : "fv".includes(b) ? I = "FF" : "st".includes(b) ? I = "SS" : "dln".includes(b) ? I = "DD" : "kg".includes(b) ? I = "kk" : "rw".includes(b) && (I = "RR"), g.push(I);
5570
5594
  }
5571
5595
  r = {
5572
- visemes: g.map((y, b) => ({
5573
- viseme: y,
5596
+ visemes: g.map((x, b) => ({
5597
+ viseme: x,
5574
5598
  startTime: b * l.duration / g.length,
5575
5599
  endTime: (b + 1) * l.duration / g.length,
5576
5600
  duration: l.duration / g.length,
@@ -5597,10 +5621,10 @@ class Be {
5597
5621
  if (r.visemes && r.visemes.length > 0) {
5598
5622
  console.log("ElevenLabs: Generating lip-sync animation from", r.visemes.length, "visemes");
5599
5623
  for (let c = 0; c < r.visemes.length; c++) {
5600
- const d = r.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3, b = d.intensity;
5624
+ const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
5601
5625
  u.push({
5602
5626
  template: { name: "viseme" },
5603
- ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
5627
+ ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
5604
5628
  vs: {
5605
5629
  ["viseme_" + d.viseme]: [null, b, 0]
5606
5630
  }
@@ -5645,10 +5669,10 @@ class Be {
5645
5669
  hasVisemes: d && d.visemes && d.visemes.length > 0
5646
5670
  }), d && d.visemes && d.visemes.length > 0)
5647
5671
  r = {
5648
- visemes: d.visemes.map((g, y) => ({
5672
+ visemes: d.visemes.map((g, x) => ({
5649
5673
  viseme: g,
5650
- startTime: y * l.duration / d.visemes.length,
5651
- endTime: (y + 1) * l.duration / d.visemes.length,
5674
+ startTime: x * l.duration / d.visemes.length,
5675
+ endTime: (x + 1) * l.duration / d.visemes.length,
5652
5676
  duration: l.duration / d.visemes.length,
5653
5677
  intensity: 0.7
5654
5678
  })),
@@ -5661,14 +5685,14 @@ class Be {
5661
5685
  } catch (c) {
5662
5686
  console.error("Text-based lip-sync failed, using fallback:", c);
5663
5687
  const d = e.toLowerCase().split(/\s+/), g = [];
5664
- for (const y of d)
5665
- for (const b of y) {
5688
+ for (const x of d)
5689
+ for (const b of x) {
5666
5690
  let I = "aa";
5667
5691
  "aeiou".includes(b) ? I = "aa" : "bp".includes(b) ? I = "PP" : "fv".includes(b) ? I = "FF" : "st".includes(b) ? I = "SS" : "dln".includes(b) ? I = "DD" : "kg".includes(b) ? I = "kk" : "rw".includes(b) && (I = "RR"), g.push(I);
5668
5692
  }
5669
5693
  r = {
5670
- visemes: g.map((y, b) => ({
5671
- viseme: y,
5694
+ visemes: g.map((x, b) => ({
5695
+ viseme: x,
5672
5696
  startTime: b * l.duration / g.length,
5673
5697
  endTime: (b + 1) * l.duration / g.length,
5674
5698
  duration: l.duration / g.length,
@@ -5695,10 +5719,10 @@ class Be {
5695
5719
  if (r.visemes && r.visemes.length > 0) {
5696
5720
  console.log("Deepgram: Generating lip-sync animation from", r.visemes.length, "visemes");
5697
5721
  for (let c = 0; c < r.visemes.length; c++) {
5698
- const d = r.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3, b = d.intensity;
5722
+ const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
5699
5723
  u.push({
5700
5724
  template: { name: "viseme" },
5701
- ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
5725
+ ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
5702
5726
  vs: {
5703
5727
  ["viseme_" + d.viseme]: [null, b, 0]
5704
5728
  }
@@ -5747,12 +5771,12 @@ class Be {
5747
5771
  });
5748
5772
  const r = [];
5749
5773
  for (let a = 0; a < h.visemes.length; a++) {
5750
- const c = h.visemes[a], d = c.startTime * 1e3, g = c.duration * 1e3, y = c.intensity;
5774
+ const c = h.visemes[a], d = c.startTime * 1e3, g = c.duration * 1e3, x = c.intensity;
5751
5775
  r.push({
5752
5776
  template: { name: "viseme" },
5753
5777
  ts: [d - Math.min(60, 2 * g / 3), d + Math.min(25, g / 2), d + g + Math.min(60, g / 2)],
5754
5778
  vs: {
5755
- ["viseme_" + c.viseme]: [null, y, 0]
5779
+ ["viseme_" + c.viseme]: [null, x, 0]
5756
5780
  }
5757
5781
  });
5758
5782
  }
@@ -6038,10 +6062,10 @@ class Be {
6038
6062
  let c = 0.6 + this.convertRange(a, [0, o], [0, 0.4]);
6039
6063
  if (o = Math.min(o, r.visemes.length * 200), u > 0)
6040
6064
  for (let d = 0; d < r.visemes.length; d++) {
6041
- const g = e + s + r.times[d] / u * o, y = r.durations[d] / u * o;
6065
+ const g = e + s + r.times[d] / u * o, x = r.durations[d] / u * o;
6042
6066
  this.animQueue.push({
6043
6067
  template: { name: "viseme" },
6044
- ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
6068
+ ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
6045
6069
  vs: {
6046
6070
  ["viseme_" + r.visemes[d]]: [null, r.visemes[d] === "PP" || r.visemes[d] === "FF" ? 0.9 : c, 0]
6047
6071
  }
@@ -6134,7 +6158,7 @@ class Be {
6134
6158
  */
6135
6159
  lookAtCamera(t) {
6136
6160
  let e;
6137
- if (this.speakTo && (e = new x.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(ve, Re).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
6161
+ if (this.speakTo && (e = new f.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(ve, Re).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
6138
6162
  if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
6139
6163
  if (this.avatar.avatarIgnoreCamera) {
6140
6164
  this.lookAhead(t);
@@ -6148,14 +6172,14 @@ class Be {
6148
6172
  return;
6149
6173
  }
6150
6174
  this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]);
6151
- const n = new x.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6152
- W.set(s, i, 0, "YXZ");
6153
- const l = new x.Quaternion().setFromEuler(W), h = new x.Quaternion().copy(l).multiply(Q.clone().invert());
6154
- W.setFromQuaternion(h, "YXZ");
6155
- let r = W.x / (40 / 24) + 0.2, u = W.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), c = Math.min(0.8, Math.max(-0.8, u)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6175
+ const n = new f.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6176
+ V.set(s, i, 0, "YXZ");
6177
+ const l = new f.Quaternion().setFromEuler(V), h = new f.Quaternion().copy(l).multiply(Q.clone().invert());
6178
+ V.setFromQuaternion(h, "YXZ");
6179
+ let r = V.x / (40 / 24) + 0.2, u = V.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), c = Math.min(0.8, Math.max(-0.8, u)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6156
6180
  if (t) {
6157
- let y = this.animQueue.findIndex((I) => I.template.name === "lookat");
6158
- y !== -1 && this.animQueue.splice(y, 1);
6181
+ let x = this.animQueue.findIndex((I) => I.template.name === "lookat");
6182
+ x !== -1 && this.animQueue.splice(x, 1);
6159
6183
  const b = {
6160
6184
  name: "lookat",
6161
6185
  dt: [750, t],
@@ -6184,23 +6208,23 @@ class Be {
6184
6208
  if (!this.camera) return;
6185
6209
  const i = this.nodeAvatar.getBoundingClientRect();
6186
6210
  this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
6187
- const s = new x.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new x.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new x.Vector3().addVectors(s, o).divideScalar(2);
6211
+ const s = new f.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new f.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new f.Vector3().addVectors(s, o).divideScalar(2);
6188
6212
  l.project(this.camera);
6189
6213
  let h = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
6190
- t === null && (t = h), e === null && (e = r), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]), W.setFromQuaternion(Q);
6191
- let u = W.x / (40 / 24), a = W.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - h, h), y = Math.max(window.innerHeight - r, r), b = this.convertRange(e, [r - y, r + y], [-0.3, 0.6]) - u + c, I = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + d;
6214
+ t === null && (t = h), e === null && (e = r), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]), V.setFromQuaternion(Q);
6215
+ let u = V.x / (40 / 24), a = V.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - h, h), x = Math.max(window.innerHeight - r, r), b = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - u + c, I = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + d;
6192
6216
  b = Math.min(0.6, Math.max(-0.3, b)), I = Math.min(0.8, Math.max(-0.8, I));
6193
- let V = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6217
+ let B = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6194
6218
  if (n) {
6195
- let M = this.animQueue.findIndex((f) => f.template.name === "lookat");
6219
+ let M = this.animQueue.findIndex((y) => y.template.name === "lookat");
6196
6220
  M !== -1 && this.animQueue.splice(M, 1);
6197
6221
  const z = {
6198
6222
  name: "lookat",
6199
6223
  dt: [750, n],
6200
6224
  vs: {
6201
- bodyRotateX: [b + V],
6225
+ bodyRotateX: [b + B],
6202
6226
  bodyRotateY: [I + p],
6203
- eyesRotateX: [-3 * V + 0.1],
6227
+ eyesRotateX: [-3 * B + 0.1],
6204
6228
  eyesRotateY: [-5 * p],
6205
6229
  browInnerUp: [[0, 0.7]],
6206
6230
  mouthLeft: [[0, 0.7]],
@@ -6220,14 +6244,14 @@ class Be {
6220
6244
  */
6221
6245
  touchAt(t, e) {
6222
6246
  if (!this.camera) return;
6223
- const n = this.nodeAvatar.getBoundingClientRect(), i = new x.Vector2(
6247
+ const n = this.nodeAvatar.getBoundingClientRect(), i = new f.Vector2(
6224
6248
  (t - n.left) / n.width * 2 - 1,
6225
6249
  -((e - n.top) / n.height) * 2 + 1
6226
- ), s = new x.Raycaster();
6250
+ ), s = new f.Raycaster();
6227
6251
  s.setFromCamera(i, this.camera);
6228
6252
  const o = s.intersectObject(this.armature);
6229
6253
  if (o.length > 0) {
6230
- const l = o[0].point, h = new x.Vector3(), r = new x.Vector3();
6254
+ const l = o[0].point, h = new f.Vector3(), r = new f.Vector3();
6231
6255
  this.objectLeftArm.getWorldPosition(h), this.objectRightArm.getWorldPosition(r);
6232
6256
  const u = h.distanceToSquared(l), a = r.distanceToSquared(l);
6233
6257
  u < a ? (this.ikSolve({
@@ -6271,7 +6295,7 @@ class Be {
6271
6295
  { link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
6272
6296
  { link: "LeftArm", minx: -1.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -1, maxz: 3 }
6273
6297
  ]
6274
- }, new x.Vector3(
6298
+ }, new f.Vector3(
6275
6299
  this.gaussianRandom(0, 0.5),
6276
6300
  this.gaussianRandom(-0.8, -0.2),
6277
6301
  this.gaussianRandom(0, 0.5)
@@ -6283,15 +6307,15 @@ class Be {
6283
6307
  { link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5 },
6284
6308
  { link: "RightArm" }
6285
6309
  ]
6286
- }, new x.Vector3(
6310
+ }, new f.Vector3(
6287
6311
  this.gaussianRandom(-0.5, 0),
6288
6312
  this.gaussianRandom(-0.8, -0.2),
6289
6313
  this.gaussianRandom(0, 0.5)
6290
6314
  ), !0);
6291
6315
  const n = [], i = [];
6292
6316
  n.push(100 + Math.round(Math.random() * 500)), i.push({ duration: 1e3, props: {
6293
- "LeftHand.quaternion": new x.Quaternion().setFromEuler(new x.Euler(0, -1 - Math.random(), 0)),
6294
- "RightHand.quaternion": new x.Quaternion().setFromEuler(new x.Euler(0, 1 + Math.random(), 0))
6317
+ "LeftHand.quaternion": new f.Quaternion().setFromEuler(new f.Euler(0, -1 - Math.random(), 0)),
6318
+ "RightHand.quaternion": new f.Quaternion().setFromEuler(new f.Euler(0, 1 + Math.random(), 0))
6295
6319
  } }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm"].forEach((o) => {
6296
6320
  i[0].props[o + ".quaternion"] = this.ikMesh.getObjectByName(o).quaternion.clone();
6297
6321
  }), n.push(1e3 + Math.round(Math.random() * 500)), i.push({ duration: 2e3, props: {} }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm", "LeftHand", "RightHand"].forEach((o) => {
@@ -6368,6 +6392,29 @@ class Be {
6368
6392
  * @param {number} [ndx=0] Index of the clip
6369
6393
  * @param {number} [scale=0.01] Position scale factor
6370
6394
  */
6395
+ /**
6396
+ * Get all bone names from the avatar's armature
6397
+ * @returns {Set<string>} Set of bone names
6398
+ */
6399
+ getAvailableBoneNames() {
6400
+ const t = /* @__PURE__ */ new Set();
6401
+ return this.armature && this.armature.traverse((e) => {
6402
+ (e.isBone || e.type === "Bone") && t.add(e.name);
6403
+ }), t;
6404
+ }
6405
+ /**
6406
+ * Filter animation tracks to only include bones that exist in the avatar
6407
+ * @param {THREE.AnimationClip} clip - Animation clip to filter
6408
+ * @param {Set<string>} availableBones - Set of available bone names
6409
+ * @returns {THREE.AnimationClip} Filtered animation clip
6410
+ */
6411
+ filterAnimationTracks(t, e) {
6412
+ const n = [], i = /* @__PURE__ */ new Set();
6413
+ return t.tracks.forEach((s) => {
6414
+ const l = s.name.split(".")[0];
6415
+ e.has(l) ? n.push(s) : i.add(l);
6416
+ }), i.size > 0 ? (console.warn(`FBX animation "${t.name}" contains tracks for ${i.size} bone(s) not found in avatar skeleton:`, Array.from(i).slice(0, 10).join(", "), i.size > 10 ? "..." : ""), console.info(`Filtered ${t.tracks.length} tracks down to ${n.length} valid tracks`)) : n.length > 0 && console.info(`FBX animation "${t.name}" is fully compatible: all ${n.length} tracks match avatar skeleton`), n.length === 0 ? (console.error(`No valid tracks found for animation "${t.name}". All bones are missing from avatar skeleton.`), null) : new f.AnimationClip(t.name, t.duration, n);
6417
+ }
6371
6418
  async playAnimation(t, e = null, n = 10, i = 0, s = 0.01, o = !1) {
6372
6419
  if (!this.armature) return;
6373
6420
  this.positionWasLocked = !o, o ? console.log("Position locking disabled for FBX animation:", t) : (this.lockAvatarPosition(), console.log("Position locked immediately before FBX animation:", t));
@@ -6376,9 +6423,9 @@ class Be {
6376
6423
  let h = this.animQueue.find((a) => a.template.name === "pose");
6377
6424
  h && (h.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((a) => {
6378
6425
  this.poseBase.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]] = a[1].clone(), this.poseTarget.props[a[0]].t = 0, this.poseTarget.props[a[0]].d = 1e3;
6379
- }), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new x.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
6426
+ }), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new f.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
6380
6427
  const r = Math.ceil(n / l.clip.duration), u = this.mixer.clipAction(l.clip);
6381
- u.setLoop(x.LoopRepeat, r), u.clampWhenFinished = !0, this.currentFBXAction = u;
6428
+ u.setLoop(f.LoopRepeat, r), u.clampWhenFinished = !0, this.currentFBXAction = u;
6382
6429
  try {
6383
6430
  u.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
6384
6431
  } catch (a) {
@@ -6404,7 +6451,7 @@ class Be {
6404
6451
  } catch (c) {
6405
6452
  console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, c);
6406
6453
  }
6407
- const u = new De();
6454
+ const u = new Oe();
6408
6455
  let a;
6409
6456
  try {
6410
6457
  a = await u.loadAsync(t, e);
@@ -6415,13 +6462,13 @@ class Be {
6415
6462
  suggestion: "Make sure the file is a valid FBX file and the path is correct"
6416
6463
  }), c.message && c.message.includes("version number") && (console.error("FBX Loader Error: Cannot find version number"), console.error("This error usually means:"), console.error("1. The file is not a valid FBX file (might be GLB, corrupted, or wrong format)"), console.error("2. The file might be corrupted"), console.error("3. The file path might be incorrect"), console.error("4. The server returned an HTML error page instead of the FBX file"), console.error("5. The file might not exist at that path"), console.error(""), console.error("Solution: Please verify:"), console.error(` - File exists at: ${t}`), console.error(" - File is a valid FBX binary file"), console.error(" - File path matches your public folder structure"), console.error(" - File is not corrupted"));
6417
6464
  try {
6418
- const d = await fetch(t), g = d.headers.get("content-type"), y = await d.text();
6465
+ const d = await fetch(t), g = d.headers.get("content-type"), x = await d.text();
6419
6466
  console.error("Response details:", {
6420
6467
  status: d.status,
6421
6468
  contentType: g,
6422
- firstBytes: y.substring(0, 100),
6423
- isHTML: y.trim().startsWith("<!DOCTYPE") || y.trim().startsWith("<html")
6424
- }), (y.trim().startsWith("<!DOCTYPE") || y.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
6469
+ firstBytes: x.substring(0, 100),
6470
+ isHTML: x.trim().startsWith("<!DOCTYPE") || x.trim().startsWith("<html")
6471
+ }), (x.trim().startsWith("<!DOCTYPE") || x.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
6425
6472
  } catch (d) {
6426
6473
  console.error("Could not fetch file for debugging:", d);
6427
6474
  }
@@ -6429,21 +6476,27 @@ class Be {
6429
6476
  }
6430
6477
  if (a && a.animations && a.animations[i]) {
6431
6478
  let c = a.animations[i];
6432
- const d = {};
6433
- c.tracks.forEach((y) => {
6434
- y.name = y.name.replaceAll("mixamorig", "");
6435
- const b = y.name.split(".");
6436
- if (b[1] === "position") {
6437
- for (let I = 0; I < y.values.length; I++)
6438
- y.values[I] = y.values[I] * s;
6439
- d[y.name] = new x.Vector3(y.values[0], y.values[1], y.values[2]);
6440
- } else b[1] === "quaternion" ? d[y.name] = new x.Quaternion(y.values[0], y.values[1], y.values[2], y.values[3]) : b[1] === "rotation" && (d[b[0] + ".quaternion"] = new x.Quaternion().setFromEuler(new x.Euler(y.values[0], y.values[1], y.values[2], "XYZ")).normalize());
6479
+ const d = this.getAvailableBoneNames(), g = this.filterAnimationTracks(c, d);
6480
+ if (!g) {
6481
+ console.error(`Cannot play FBX animation "${t}": No compatible bones found.`);
6482
+ return;
6483
+ }
6484
+ c = g;
6485
+ const x = {};
6486
+ c.tracks.forEach((I) => {
6487
+ I.name = I.name.replaceAll("mixamorig", "");
6488
+ const B = I.name.split(".");
6489
+ if (B[1] === "position") {
6490
+ for (let p = 0; p < I.values.length; p++)
6491
+ I.values[p] = I.values[p] * s;
6492
+ x[I.name] = new f.Vector3(I.values[0], I.values[1], I.values[2]);
6493
+ } else B[1] === "quaternion" ? x[I.name] = new f.Quaternion(I.values[0], I.values[1], I.values[2], I.values[3]) : B[1] === "rotation" && (x[B[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(I.values[0], I.values[1], I.values[2], "XYZ")).normalize());
6441
6494
  });
6442
- const g = { props: d };
6443
- d["Hips.position"] && (d["Hips.position"].y < 0.5 ? g.lying = !0 : g.standing = !0), this.animClips.push({
6495
+ const b = { props: x };
6496
+ x["Hips.position"] && (x["Hips.position"].y < 0.5 ? b.lying = !0 : b.standing = !0), this.animClips.push({
6444
6497
  url: t + "-" + i,
6445
6498
  clip: c,
6446
- pose: g
6499
+ pose: b
6447
6500
  }), this.playAnimation(t, e, n, i, s);
6448
6501
  } else {
6449
6502
  const c = "Animation " + t + " (ndx=" + i + ") not found";
@@ -6481,14 +6534,14 @@ class Be {
6481
6534
  let l = this.animQueue.find((h) => h.template.name === "pose");
6482
6535
  l && (l.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(o);
6483
6536
  } else {
6484
- let h = await new De().loadAsync(t, e);
6537
+ let h = await new Oe().loadAsync(t, e);
6485
6538
  if (h && h.animations && h.animations[i]) {
6486
6539
  let r = h.animations[i];
6487
6540
  const u = {};
6488
6541
  r.tracks.forEach((c) => {
6489
6542
  c.name = c.name.replaceAll("mixamorig", "");
6490
6543
  const d = c.name.split(".");
6491
- d[1] === "position" ? u[c.name] = new x.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? u[c.name] = new x.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (u[d[0] + ".quaternion"] = new x.Quaternion().setFromEuler(new x.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
6544
+ d[1] === "position" ? u[c.name] = new f.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? u[c.name] = new f.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (u[d[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
6492
6545
  });
6493
6546
  const a = { props: u };
6494
6547
  u["Hips.position"] && (u["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
@@ -6521,7 +6574,7 @@ class Be {
6521
6574
  if (s) {
6522
6575
  this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
6523
6576
  let l = this.animQueue.findIndex((h) => h.template.name === "talkinghands");
6524
- l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((h) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new x.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new x.Quaternion(0, 1, 0, 0), -0.25));
6577
+ l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((h) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25));
6525
6578
  for (let [h, r] of Object.entries(this.gesture))
6526
6579
  r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(h) && (this.poseTarget.props[h].copy(r), this.poseTarget.props[h].t = this.animClock, this.poseTarget.props[h].d = i);
6527
6580
  e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
@@ -6534,9 +6587,9 @@ class Be {
6534
6587
  const h = l.ts[0], u = l.ts[l.ts.length - 1] - h;
6535
6588
  if (e * 1e3 - u > 0) {
6536
6589
  const c = [];
6537
- for (let y = 1; y < l.ts.length; y++) c.push(l.ts[y] - l.ts[y - 1]);
6538
- const d = o.template?.rescale || c.map((y) => y / u), g = e * 1e3 - u;
6539
- l.ts = l.ts.map((y, b, I) => b === 0 ? h : I[b - 1] + c[b - 1] + d[b - 1] * g);
6590
+ for (let x = 1; x < l.ts.length; x++) c.push(l.ts[x] - l.ts[x - 1]);
6591
+ const d = o.template?.rescale || c.map((x) => x / u), g = e * 1e3 - u;
6592
+ l.ts = l.ts.map((x, b, I) => b === 0 ? h : I[b - 1] + c[b - 1] + d[b - 1] * g);
6540
6593
  } else {
6541
6594
  const c = e * 1e3 / u;
6542
6595
  l.ts = l.ts.map((d) => h + c * (d - h));
@@ -6569,33 +6622,33 @@ class Be {
6569
6622
  * @param {numeric} [d=null] If set, apply in d milliseconds
6570
6623
  */
6571
6624
  ikSolve(t, e = null, n = !1, i = null) {
6572
- const s = new x.Vector3(), o = new x.Vector3(), l = new x.Vector3(), h = new x.Vector3(), r = new x.Quaternion(), u = new x.Vector3(), a = new x.Vector3(), c = new x.Vector3(), d = this.ikMesh.getObjectByName(t.root);
6625
+ const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(), h = new f.Vector3(), r = new f.Quaternion(), u = new f.Vector3(), a = new f.Vector3(), c = new f.Vector3(), d = this.ikMesh.getObjectByName(t.root);
6573
6626
  d.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && n && e.applyQuaternion(this.armature.quaternion).add(d.position);
6574
- const g = this.ikMesh.getObjectByName(t.effector), y = t.links;
6575
- y.forEach((I) => {
6627
+ const g = this.ikMesh.getObjectByName(t.effector), x = t.links;
6628
+ x.forEach((I) => {
6576
6629
  I.bone = this.ikMesh.getObjectByName(I.link), I.bone.quaternion.copy(this.getPoseTemplateProp(I.link + ".quaternion"));
6577
6630
  }), d.updateMatrixWorld(!0);
6578
6631
  const b = t.iterations || 10;
6579
6632
  if (e)
6580
6633
  for (let I = 0; I < b; I++) {
6581
- let V = !1;
6582
- for (let p = 0, M = y.length; p < M; p++) {
6583
- const z = y[p].bone;
6634
+ let B = !1;
6635
+ for (let p = 0, M = x.length; p < M; p++) {
6636
+ const z = x[p].bone;
6584
6637
  z.matrixWorld.decompose(h, r, u), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, h), l.applyQuaternion(r), l.normalize(), s.subVectors(e, h), s.applyQuaternion(r), s.normalize();
6585
- let f = s.dot(l);
6586
- f > 1 ? f = 1 : f < -1 && (f = -1), f = Math.acos(f), !(f < 1e-5) && (y[p].minAngle !== void 0 && f < y[p].minAngle && (f = y[p].minAngle), y[p].maxAngle !== void 0 && f > y[p].maxAngle && (f = y[p].maxAngle), a.crossVectors(l, s), a.normalize(), Q.setFromAxisAngle(a, f), z.quaternion.multiply(Q), z.rotation.setFromVector3(c.setFromEuler(z.rotation).clamp(new x.Vector3(
6587
- y[p].minx !== void 0 ? y[p].minx : -1 / 0,
6588
- y[p].miny !== void 0 ? y[p].miny : -1 / 0,
6589
- y[p].minz !== void 0 ? y[p].minz : -1 / 0
6590
- ), new x.Vector3(
6591
- y[p].maxx !== void 0 ? y[p].maxx : 1 / 0,
6592
- y[p].maxy !== void 0 ? y[p].maxy : 1 / 0,
6593
- y[p].maxz !== void 0 ? y[p].maxz : 1 / 0
6594
- ))), z.updateMatrixWorld(!0), V = !0);
6638
+ let y = s.dot(l);
6639
+ y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (x[p].minAngle !== void 0 && y < x[p].minAngle && (y = x[p].minAngle), x[p].maxAngle !== void 0 && y > x[p].maxAngle && (y = x[p].maxAngle), a.crossVectors(l, s), a.normalize(), Q.setFromAxisAngle(a, y), z.quaternion.multiply(Q), z.rotation.setFromVector3(c.setFromEuler(z.rotation).clamp(new f.Vector3(
6640
+ x[p].minx !== void 0 ? x[p].minx : -1 / 0,
6641
+ x[p].miny !== void 0 ? x[p].miny : -1 / 0,
6642
+ x[p].minz !== void 0 ? x[p].minz : -1 / 0
6643
+ ), new f.Vector3(
6644
+ x[p].maxx !== void 0 ? x[p].maxx : 1 / 0,
6645
+ x[p].maxy !== void 0 ? x[p].maxy : 1 / 0,
6646
+ x[p].maxz !== void 0 ? x[p].maxz : 1 / 0
6647
+ ))), z.updateMatrixWorld(!0), B = !0);
6595
6648
  }
6596
- if (!V) break;
6649
+ if (!B) break;
6597
6650
  }
6598
- i && y.forEach((I) => {
6651
+ i && x.forEach((I) => {
6599
6652
  this.poseTarget.props[I.link + ".quaternion"].copy(I.bone.quaternion), this.poseTarget.props[I.link + ".quaternion"].t = this.animClock, this.poseTarget.props[I.link + ".quaternion"].d = i;
6600
6653
  });
6601
6654
  }
@@ -6655,7 +6708,7 @@ function Fe() {
6655
6708
  voices: Ie.voices
6656
6709
  };
6657
6710
  }
6658
- function kt() {
6711
+ function St() {
6659
6712
  const G = Fe(), t = [];
6660
6713
  return Object.entries(G.voices).forEach(([e, n]) => {
6661
6714
  t.push({
@@ -6683,10 +6736,10 @@ const Ve = Me(({
6683
6736
  onError: d = () => {
6684
6737
  },
6685
6738
  className: g = "",
6686
- style: y = {},
6739
+ style: x = {},
6687
6740
  animations: b = {}
6688
6741
  }, I) => {
6689
- const V = O(null), p = O(null), M = O(r), z = O(null), f = O(null), E = O(!1), P = O({ remainingText: null, originalText: null, options: null }), U = O([]), oe = O(0), [S, Z] = ce(!0), [K, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
6742
+ const B = O(null), p = O(null), M = O(r), z = O(null), y = O(null), E = O(!1), P = O({ remainingText: null, originalText: null, options: null }), W = O([]), oe = O(0), [k, Z] = ce(!0), [K, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
6690
6743
  de(() => {
6691
6744
  E.current = ae;
6692
6745
  }, [ae]), de(() => {
@@ -6732,24 +6785,24 @@ const Ve = Me(({
6732
6785
  ttsService: le,
6733
6786
  lipsyncModules: ["en"],
6734
6787
  cameraView: u
6735
- }, k = T(async () => {
6736
- if (!(!V.current || p.current))
6788
+ }, S = T(async () => {
6789
+ if (!(!B.current || p.current))
6737
6790
  try {
6738
- if (Z(!0), X(null), p.current = new Be(V.current, R), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), b && Object.keys(b).length > 0 && (p.current.customAnimations = b), await p.current.showAvatar(v, (B) => {
6739
- if (B.lengthComputable) {
6740
- const J = Math.min(100, Math.round(B.loaded / B.total * 100));
6791
+ if (Z(!0), X(null), p.current = new Be(B.current, R), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), b && Object.keys(b).length > 0 && (p.current.customAnimations = b), await p.current.showAvatar(v, (N) => {
6792
+ if (N.lengthComputable) {
6793
+ const J = Math.min(100, Math.round(N.loaded / N.total * 100));
6741
6794
  c(J);
6742
6795
  }
6743
- }), await new Promise((B) => {
6796
+ }), await new Promise((N) => {
6744
6797
  const J = () => {
6745
- p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? B() : setTimeout(J, 100);
6798
+ p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? N() : setTimeout(J, 100);
6746
6799
  };
6747
6800
  J();
6748
6801
  }), p.current && p.current.setShowFullAvatar)
6749
6802
  try {
6750
6803
  p.current.setShowFullAvatar(r);
6751
- } catch (B) {
6752
- console.warn("Error setting full body mode on initialization:", B);
6804
+ } catch (N) {
6805
+ console.warn("Error setting full body mode on initialization:", N);
6753
6806
  }
6754
6807
  p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), Z(!1), se(!0), a(p.current);
6755
6808
  const F = () => {
@@ -6762,15 +6815,15 @@ const Ve = Me(({
6762
6815
  console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), Z(!1), d(L);
6763
6816
  }
6764
6817
  }, [G, t, e, n, i, s, o, r, l, h, u]);
6765
- de(() => (k(), () => {
6818
+ de(() => (S(), () => {
6766
6819
  p.current && (p.current.stop(), p.current.dispose(), p.current = null);
6767
- }), [k]), de(() => {
6768
- if (!V.current || !p.current) return;
6769
- const L = new ResizeObserver((B) => {
6770
- for (const J of B)
6820
+ }), [S]), de(() => {
6821
+ if (!B.current || !p.current) return;
6822
+ const L = new ResizeObserver((N) => {
6823
+ for (const J of N)
6771
6824
  p.current && p.current.onResize && p.current.onResize();
6772
6825
  });
6773
- L.observe(V.current);
6826
+ L.observe(B.current);
6774
6827
  const F = () => {
6775
6828
  p.current && p.current.onResize && p.current.onResize();
6776
6829
  };
@@ -6785,39 +6838,39 @@ const Ve = Me(({
6785
6838
  } catch (L) {
6786
6839
  console.warn("Failed to resume audio context:", L);
6787
6840
  }
6788
- }, []), N = T(async (L, F = {}) => {
6841
+ }, []), U = T(async (L, F = {}) => {
6789
6842
  if (p.current && $)
6790
6843
  try {
6791
- f.current && (clearInterval(f.current), f.current = null), z.current = { text: L, options: F }, P.current = { remainingText: null, originalText: null, options: null };
6792
- const B = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(B).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
6793
- U.current = J, oe.current = 0, pe(!1), E.current = !1, await H();
6844
+ y.current && (clearInterval(y.current), y.current = null), z.current = { text: L, options: F }, P.current = { remainingText: null, originalText: null, options: null };
6845
+ const N = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(N).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
6846
+ W.current = J, oe.current = 0, pe(!1), E.current = !1, await H();
6794
6847
  const ge = {
6795
6848
  ...F,
6796
6849
  lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
6797
6850
  };
6798
6851
  if (F.onSpeechEnd && p.current) {
6799
6852
  const Y = p.current;
6800
- let he = null, Se = 0;
6853
+ let he = null, ke = 0;
6801
6854
  const Ae = 1200;
6802
6855
  let be = !1;
6803
6856
  he = setInterval(() => {
6804
- if (Se++, E.current)
6857
+ if (ke++, E.current)
6805
6858
  return;
6806
- if (Se > Ae) {
6807
- if (he && (clearInterval(he), he = null, f.current = null), !be && !E.current) {
6859
+ if (ke > Ae) {
6860
+ if (he && (clearInterval(he), he = null, y.current = null), !be && !E.current) {
6808
6861
  be = !0;
6809
6862
  try {
6810
6863
  F.onSpeechEnd();
6811
- } catch (Oe) {
6812
- console.error("Error in onSpeechEnd callback (timeout):", Oe);
6864
+ } catch (Ne) {
6865
+ console.error("Error in onSpeechEnd callback (timeout):", Ne);
6813
6866
  }
6814
6867
  }
6815
6868
  return;
6816
6869
  }
6817
- const ye = !Y.speechQueue || Y.speechQueue.length === 0, ke = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
6818
- Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !E.current && setTimeout(() => {
6870
+ const ye = !Y.speechQueue || Y.speechQueue.length === 0, Se = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
6871
+ Y && Y.isSpeaking === !1 && ye && Se && Y.isAudioPlaying === !1 && !be && !E.current && setTimeout(() => {
6819
6872
  if (Y && !E.current && Y.isSpeaking === !1 && (!Y.speechQueue || Y.speechQueue.length === 0) && (!Y.audioPlaylist || Y.audioPlaylist.length === 0) && Y.isAudioPlaying === !1 && !be && !E.current) {
6820
- be = !0, he && (clearInterval(he), he = null, f.current = null);
6873
+ be = !0, he && (clearInterval(he), he = null, y.current = null);
6821
6874
  try {
6822
6875
  F.onSpeechEnd();
6823
6876
  } catch (Ze) {
@@ -6825,13 +6878,13 @@ const Ve = Me(({
6825
6878
  }
6826
6879
  }
6827
6880
  }, 100);
6828
- }, 100), f.current = he;
6881
+ }, 100), y.current = he;
6829
6882
  }
6830
6883
  p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge)) : setTimeout(async () => {
6831
6884
  await H(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
6832
6885
  }, 100);
6833
- } catch (B) {
6834
- console.error("Error speaking text:", B), X(B.message || "Failed to speak text");
6886
+ } catch (N) {
6887
+ console.error("Error speaking text:", N), X(N.message || "Failed to speak text");
6835
6888
  }
6836
6889
  }, [$, H, v.lipsyncLang]), _ = T(() => {
6837
6890
  p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, pe(!1));
@@ -6839,17 +6892,17 @@ const Ve = Me(({
6839
6892
  if (p.current && p.current.pauseSpeaking) {
6840
6893
  const L = p.current;
6841
6894
  if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
6842
- f.current && (clearInterval(f.current), f.current = null);
6843
- let B = "";
6844
- if (z.current && U.current.length > 0) {
6845
- const J = U.current.length, ge = L.speechQueue ? L.speechQueue.filter((Ae) => Ae && Ae.text && Array.isArray(Ae.text) && Ae.text.length > 0).length : 0, Y = L.audioPlaylist && L.audioPlaylist.length > 0, he = ge + (Y ? 1 : 0), Se = J - he;
6846
- if (he > 0 && Se < J && (B = U.current.slice(Se).join(". ").trim(), !B && ge > 0 && L.speechQueue)) {
6847
- 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(" ");
6848
- be && be.trim() && (B = be.trim());
6895
+ y.current && (clearInterval(y.current), y.current = null);
6896
+ let N = "";
6897
+ if (z.current && W.current.length > 0) {
6898
+ const J = W.current.length, ge = L.speechQueue ? L.speechQueue.filter((Ae) => Ae && Ae.text && Array.isArray(Ae.text) && Ae.text.length > 0).length : 0, Y = L.audioPlaylist && L.audioPlaylist.length > 0, he = ge + (Y ? 1 : 0), ke = J - he;
6899
+ if (he > 0 && ke < J && (N = W.current.slice(ke).join(". ").trim(), !N && ge > 0 && L.speechQueue)) {
6900
+ const be = L.speechQueue.filter((ye) => ye && ye.text && Array.isArray(ye.text) && ye.text.length > 0).map((ye) => ye.text.map((Se) => Se.word || "").filter((Se) => Se.length > 0).join(" ")).filter((ye) => ye.length > 0).join(" ");
6901
+ be && be.trim() && (N = be.trim());
6849
6902
  }
6850
6903
  }
6851
6904
  z.current && (P.current = {
6852
- remainingText: B || null,
6905
+ remainingText: N || null,
6853
6906
  originalText: z.current.text,
6854
6907
  options: z.current.options
6855
6908
  }), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), E.current = !0, pe(!0);
@@ -6868,16 +6921,16 @@ const Ve = Me(({
6868
6921
  return;
6869
6922
  }
6870
6923
  pe(!1), E.current = !1, await H();
6871
- const B = {
6924
+ const N = {
6872
6925
  ...F,
6873
6926
  lipsyncLang: F.lipsyncLang || v.lipsyncLang || "en"
6874
6927
  };
6875
6928
  try {
6876
- await N(L, B);
6929
+ await U(L, N);
6877
6930
  } catch (J) {
6878
6931
  console.error("Error resuming speech:", J), pe(!1), E.current = !1;
6879
6932
  }
6880
- }, [H, ae, N, v]), Le = T((L) => {
6933
+ }, [H, ae, U, v]), Le = T((L) => {
6881
6934
  p.current && p.current.setMood(L);
6882
6935
  }, []), we = T((L) => {
6883
6936
  p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
@@ -6923,7 +6976,7 @@ const Ve = Me(({
6923
6976
  p.current && p.current.onResize && p.current.onResize();
6924
6977
  }, []);
6925
6978
  return Ee(I, () => ({
6926
- speakText: N,
6979
+ speakText: U,
6927
6980
  stopSpeaking: _,
6928
6981
  pauseSpeaking: j,
6929
6982
  resumeSpeaking: q,
@@ -7000,13 +7053,13 @@ const Ve = Me(({
7000
7053
  width: "100%",
7001
7054
  height: "100%",
7002
7055
  position: "relative",
7003
- ...y
7056
+ ...x
7004
7057
  },
7005
7058
  children: [
7006
7059
  /* @__PURE__ */ me(
7007
7060
  "div",
7008
7061
  {
7009
- ref: V,
7062
+ ref: B,
7010
7063
  className: "talking-head-viewer",
7011
7064
  style: {
7012
7065
  width: "100%",
@@ -7015,7 +7068,7 @@ const Ve = Me(({
7015
7068
  }
7016
7069
  }
7017
7070
  ),
7018
- S && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7071
+ k && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7019
7072
  position: "absolute",
7020
7073
  top: "50%",
7021
7074
  left: "50%",
@@ -7053,7 +7106,7 @@ const pt = Me(({
7053
7106
  style: s = {},
7054
7107
  avatarConfig: o = {}
7055
7108
  }, l) => {
7056
- const h = O(null), r = O(null), [u, a] = ce(!0), [c, d] = ce(null), [g, y] = ce(!1), b = Fe(), I = o.ttsService || b.service, V = I === "browser" ? {
7109
+ const h = O(null), r = O(null), [u, a] = ce(!0), [c, d] = ce(null), [g, x] = ce(!1), b = Fe(), I = o.ttsService || b.service, B = I === "browser" ? {
7057
7110
  endpoint: "",
7058
7111
  apiKey: null,
7059
7112
  defaultVoice: "Google US English"
@@ -7069,7 +7122,7 @@ const pt = Me(({
7069
7122
  body: "F",
7070
7123
  avatarMood: "neutral",
7071
7124
  ttsLang: I === "browser" ? "en-US" : "en",
7072
- ttsVoice: o.ttsVoice || V.defaultVoice,
7125
+ ttsVoice: o.ttsVoice || B.defaultVoice,
7073
7126
  lipsyncLang: "en",
7074
7127
  // English lip-sync
7075
7128
  showFullAvatar: !0,
@@ -7078,8 +7131,8 @@ const pt = Me(({
7078
7131
  movementIntensity: 0.5,
7079
7132
  ...o
7080
7133
  }, M = {
7081
- ttsEndpoint: V.endpoint,
7082
- ttsApikey: V.apiKey,
7134
+ ttsEndpoint: B.endpoint,
7135
+ ttsApikey: B.apiKey,
7083
7136
  ttsService: I,
7084
7137
  lipsyncModules: ["en"],
7085
7138
  cameraView: "upper"
@@ -7108,25 +7161,25 @@ const pt = Me(({
7108
7161
  } catch (K) {
7109
7162
  console.warn("Error setting full body mode on initialization:", K);
7110
7163
  }
7111
- a(!1), y(!0), n(r.current);
7164
+ a(!1), x(!0), n(r.current);
7112
7165
  const Z = () => {
7113
7166
  document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
7114
7167
  };
7115
7168
  return document.addEventListener("visibilitychange", Z), () => {
7116
7169
  document.removeEventListener("visibilitychange", Z);
7117
7170
  };
7118
- } catch (S) {
7119
- console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), a(!1), e(S);
7171
+ } catch (k) {
7172
+ console.error("Error initializing TalkingHead:", k), d(k.message || "Failed to initialize avatar"), a(!1), e(k);
7120
7173
  }
7121
7174
  }, []);
7122
7175
  de(() => (z(), () => {
7123
7176
  r.current && (r.current.stop(), r.current.dispose(), r.current = null);
7124
7177
  }), [z]);
7125
- const f = T((S) => {
7178
+ const y = T((k) => {
7126
7179
  if (r.current && g)
7127
7180
  try {
7128
- 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(() => {
7129
- r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : console.error("Lip-sync still not ready after waiting");
7181
+ console.log("Speaking text:", k), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(k)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7182
+ r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(k)) : console.error("Lip-sync still not ready after waiting");
7130
7183
  }, 500));
7131
7184
  } catch (Z) {
7132
7185
  console.error("Error speaking text:", Z), d(Z.message || "Failed to speak text");
@@ -7135,11 +7188,11 @@ const pt = Me(({
7135
7188
  console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
7136
7189
  }, [g, p]), E = T(() => {
7137
7190
  r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7138
- }, []), P = T((S) => {
7139
- r.current && r.current.setMood(S);
7140
- }, []), U = T((S) => {
7141
- r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
7142
- }, []), oe = T((S, Z = !1) => {
7191
+ }, []), P = T((k) => {
7192
+ r.current && r.current.setMood(k);
7193
+ }, []), W = T((k) => {
7194
+ r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(k), console.log("Timing adjustment set to:", k));
7195
+ }, []), oe = T((k, Z = !1) => {
7143
7196
  if (r.current && r.current.playAnimation) {
7144
7197
  if (r.current.setShowFullAvatar)
7145
7198
  try {
@@ -7147,11 +7200,11 @@ const pt = Me(({
7147
7200
  } catch (X) {
7148
7201
  console.warn("Error setting full body mode:", X);
7149
7202
  }
7150
- if (S.includes("."))
7203
+ if (k.includes("."))
7151
7204
  try {
7152
- r.current.playAnimation(S, null, 10, 0, 0.01, Z), console.log("Playing animation:", S);
7205
+ r.current.playAnimation(k, null, 10, 0, 0.01, Z), console.log("Playing animation:", k);
7153
7206
  } catch (X) {
7154
- console.log(`Failed to play ${S}:`, X);
7207
+ console.log(`Failed to play ${k}:`, X);
7155
7208
  try {
7156
7209
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7157
7210
  } catch ($) {
@@ -7163,13 +7216,13 @@ const pt = Me(({
7163
7216
  let $ = !1;
7164
7217
  for (const se of X)
7165
7218
  try {
7166
- r.current.playAnimation(S + se, null, 10, 0, 0.01, Z), console.log("Playing animation:", S + se), $ = !0;
7219
+ r.current.playAnimation(k + se, null, 10, 0, 0.01, Z), console.log("Playing animation:", k + se), $ = !0;
7167
7220
  break;
7168
7221
  } catch {
7169
- console.log(`Failed to play ${S}${se}, trying next format...`);
7222
+ console.log(`Failed to play ${k}${se}, trying next format...`);
7170
7223
  }
7171
7224
  if (!$) {
7172
- console.warn("Animation system not available or animation not found:", S);
7225
+ console.warn("Animation system not available or animation not found:", k);
7173
7226
  try {
7174
7227
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7175
7228
  } catch (se) {
@@ -7178,37 +7231,37 @@ const pt = Me(({
7178
7231
  }
7179
7232
  }
7180
7233
  } else
7181
- console.warn("Animation system not available or animation not found:", S);
7234
+ console.warn("Animation system not available or animation not found:", k);
7182
7235
  }, []);
7183
7236
  return Ee(l, () => ({
7184
- speakText: f,
7237
+ speakText: y,
7185
7238
  stopSpeaking: E,
7186
7239
  setMood: P,
7187
- setTimingAdjustment: U,
7240
+ setTimingAdjustment: W,
7188
7241
  playAnimation: oe,
7189
7242
  isReady: g,
7190
7243
  talkingHead: r.current,
7191
- setBodyMovement: (S) => {
7244
+ setBodyMovement: (k) => {
7192
7245
  if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
7193
7246
  try {
7194
- r.current.setShowFullAvatar(!0), r.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
7247
+ r.current.setShowFullAvatar(!0), r.current.setBodyMovement(k), console.log("Body movement set with full body mode:", k);
7195
7248
  } catch (Z) {
7196
7249
  console.warn("Error setting body movement:", Z);
7197
7250
  }
7198
7251
  },
7199
- setMovementIntensity: (S) => r.current?.setMovementIntensity(S),
7252
+ setMovementIntensity: (k) => r.current?.setMovementIntensity(k),
7200
7253
  playRandomDance: () => {
7201
7254
  if (r.current && r.current.setShowFullAvatar && r.current.playRandomDance)
7202
7255
  try {
7203
7256
  r.current.setShowFullAvatar(!0), r.current.playRandomDance(), console.log("Random dance played with full body mode");
7204
- } catch (S) {
7205
- console.warn("Error playing random dance:", S);
7257
+ } catch (k) {
7258
+ console.warn("Error playing random dance:", k);
7206
7259
  }
7207
7260
  },
7208
- playReaction: (S) => {
7261
+ playReaction: (k) => {
7209
7262
  if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
7210
7263
  try {
7211
- r.current.setShowFullAvatar(!0), r.current.playReaction(S), console.log("Reaction played with full body mode:", S);
7264
+ r.current.setShowFullAvatar(!0), r.current.playReaction(k), console.log("Reaction played with full body mode:", k);
7212
7265
  } catch (Z) {
7213
7266
  console.warn("Error playing reaction:", Z);
7214
7267
  }
@@ -7217,14 +7270,14 @@ const pt = Me(({
7217
7270
  if (r.current && r.current.setShowFullAvatar && r.current.playCelebration)
7218
7271
  try {
7219
7272
  r.current.setShowFullAvatar(!0), r.current.playCelebration(), console.log("Celebration played with full body mode");
7220
- } catch (S) {
7221
- console.warn("Error playing celebration:", S);
7273
+ } catch (k) {
7274
+ console.warn("Error playing celebration:", k);
7222
7275
  }
7223
7276
  },
7224
- setShowFullAvatar: (S) => {
7277
+ setShowFullAvatar: (k) => {
7225
7278
  if (r.current && r.current.setShowFullAvatar)
7226
7279
  try {
7227
- r.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
7280
+ r.current.setShowFullAvatar(k), console.log("Show full avatar set to:", k);
7228
7281
  } catch (Z) {
7229
7282
  console.warn("Error setting showFullAvatar:", Z);
7230
7283
  }
@@ -7233,16 +7286,16 @@ const pt = Me(({
7233
7286
  if (r.current && r.current.lockAvatarPosition)
7234
7287
  try {
7235
7288
  r.current.lockAvatarPosition();
7236
- } catch (S) {
7237
- console.warn("Error locking avatar position:", S);
7289
+ } catch (k) {
7290
+ console.warn("Error locking avatar position:", k);
7238
7291
  }
7239
7292
  },
7240
7293
  unlockAvatarPosition: () => {
7241
7294
  if (r.current && r.current.unlockAvatarPosition)
7242
7295
  try {
7243
7296
  r.current.unlockAvatarPosition();
7244
- } catch (S) {
7245
- console.warn("Error unlocking avatar position:", S);
7297
+ } catch (k) {
7298
+ console.warn("Error unlocking avatar position:", k);
7246
7299
  }
7247
7300
  }
7248
7301
  })), /* @__PURE__ */ Pe("div", { className: `talking-head-container ${i}`, style: s, children: [
@@ -7301,14 +7354,14 @@ const gt = Me(({
7301
7354
  },
7302
7355
  onError: g = () => {
7303
7356
  },
7304
- onSpeechEnd: y = () => {
7357
+ onSpeechEnd: x = () => {
7305
7358
  },
7306
7359
  className: b = "",
7307
7360
  style: I = {},
7308
- animations: V = {},
7361
+ animations: B = {},
7309
7362
  autoSpeak: p = !1
7310
7363
  }, M) => {
7311
- const z = O(null), f = O(null), E = O(u), P = O(null), U = O(null), oe = O(!1), S = O({ remainingText: null, originalText: null, options: null }), Z = O([]), [K, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
7364
+ const z = O(null), y = O(null), E = O(u), P = O(null), W = O(null), oe = O(!1), k = O({ remainingText: null, originalText: null, options: null }), Z = O([]), [K, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
7312
7365
  de(() => {
7313
7366
  oe.current = ee;
7314
7367
  }, [ee]), de(() => {
@@ -7337,7 +7390,7 @@ const gt = Me(({
7337
7390
  ...D,
7338
7391
  apiKey: l !== null ? l : D.apiKey
7339
7392
  };
7340
- const k = {
7393
+ const S = {
7341
7394
  url: t,
7342
7395
  body: e,
7343
7396
  avatarMood: n,
@@ -7353,21 +7406,21 @@ const gt = Me(({
7353
7406
  ttsService: v,
7354
7407
  lipsyncModules: ["en"],
7355
7408
  cameraView: a
7356
- }, N = T(async () => {
7357
- if (!(!z.current || f.current))
7409
+ }, U = T(async () => {
7410
+ if (!(!z.current || y.current))
7358
7411
  try {
7359
- X(!0), se(null), f.current = new Be(z.current, H), console.log("Avatar config being passed:", {
7360
- url: k.url,
7361
- body: k.body,
7362
- avatarMood: k.avatarMood
7363
- }), await f.current.showAvatar(k, (te) => {
7412
+ X(!0), se(null), y.current = new Be(z.current, H), console.log("Avatar config being passed:", {
7413
+ url: S.url,
7414
+ body: S.body,
7415
+ avatarMood: S.avatarMood
7416
+ }), await y.current.showAvatar(S, (te) => {
7364
7417
  if (te.lengthComputable) {
7365
7418
  const L = Math.min(100, Math.round(te.loaded / te.total * 100));
7366
7419
  d(L);
7367
7420
  }
7368
- }), f.current?.avatar && console.log("Avatar body after initialization:", f.current.avatar.body), X(!1), pe(!0), c(f.current);
7421
+ }), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), X(!1), pe(!0), c(y.current);
7369
7422
  const C = () => {
7370
- document.visibilityState === "visible" ? f.current?.start() : f.current?.stop();
7423
+ document.visibilityState === "visible" ? y.current?.start() : y.current?.stop();
7371
7424
  };
7372
7425
  return document.addEventListener("visibilitychange", C), () => {
7373
7426
  document.removeEventListener("visibilitychange", C);
@@ -7376,19 +7429,19 @@ const gt = Me(({
7376
7429
  console.error("Error initializing TalkingHead:", C), se(C.message || "Failed to initialize avatar"), X(!1), g(C);
7377
7430
  }
7378
7431
  }, []);
7379
- de(() => (N(), () => {
7380
- f.current && (f.current.stop(), f.current.dispose(), f.current = null);
7381
- }), [N]);
7432
+ de(() => (U(), () => {
7433
+ y.current && (y.current.stop(), y.current.dispose(), y.current = null);
7434
+ }), [U]);
7382
7435
  const _ = T(async () => {
7383
- if (f.current)
7436
+ if (y.current)
7384
7437
  try {
7385
- const C = f.current.audioCtx || f.current.audioContext;
7438
+ const C = y.current.audioCtx || y.current.audioContext;
7386
7439
  C && (C.state === "suspended" || C.state === "interrupted") && (await C.resume(), console.log("Audio context resumed"));
7387
7440
  } catch (C) {
7388
7441
  console.warn("Failed to resume audio context:", C);
7389
7442
  }
7390
7443
  }, []), j = T(async (C, te = {}) => {
7391
- if (!f.current || !ae) {
7444
+ if (!y.current || !ae) {
7392
7445
  console.warn("Avatar not ready for speaking");
7393
7446
  return;
7394
7447
  }
@@ -7396,51 +7449,51 @@ const gt = Me(({
7396
7449
  console.warn("No text provided to speak");
7397
7450
  return;
7398
7451
  }
7399
- await _(), S.current = { remainingText: null, originalText: null, options: null }, Z.current = [], P.current = { text: C, options: te }, U.current && (clearInterval(U.current), U.current = null), le(!1), oe.current = !1;
7400
- const L = C.split(/[.!?]+/).filter((B) => B.trim().length > 0);
7452
+ await _(), k.current = { remainingText: null, originalText: null, options: null }, Z.current = [], P.current = { text: C, options: te }, W.current && (clearInterval(W.current), W.current = null), le(!1), oe.current = !1;
7453
+ const L = C.split(/[.!?]+/).filter((N) => N.trim().length > 0);
7401
7454
  Z.current = L;
7402
7455
  const F = {
7403
7456
  lipsyncLang: te.lipsyncLang || "en",
7404
7457
  onSpeechEnd: () => {
7405
- U.current && (clearInterval(U.current), U.current = null), te.onSpeechEnd && te.onSpeechEnd(), y();
7458
+ W.current && (clearInterval(W.current), W.current = null), te.onSpeechEnd && te.onSpeechEnd(), x();
7406
7459
  }
7407
7460
  };
7408
7461
  try {
7409
- f.current.speakText(C, F);
7410
- } catch (B) {
7411
- console.error("Error speaking text:", B), se(B.message || "Failed to speak text");
7462
+ y.current.speakText(C, F);
7463
+ } catch (N) {
7464
+ console.error("Error speaking text:", N), se(N.message || "Failed to speak text");
7412
7465
  }
7413
- }, [ae, y, _]);
7466
+ }, [ae, x, _]);
7414
7467
  de(() => {
7415
- ae && G && p && f.current && j(G);
7468
+ ae && G && p && y.current && j(G);
7416
7469
  }, [ae, G, p, j]);
7417
7470
  const q = T(() => {
7418
- if (f.current)
7471
+ if (y.current)
7419
7472
  try {
7420
- const C = f.current.isSpeaking || !1, te = f.current.audioPlaylist || [], L = f.current.speechQueue || [];
7473
+ const C = y.current.isSpeaking || !1, te = y.current.audioPlaylist || [], L = y.current.speechQueue || [];
7421
7474
  if (C || te.length > 0 || L.length > 0) {
7422
- U.current && (clearInterval(U.current), U.current = null);
7475
+ W.current && (clearInterval(W.current), W.current = null);
7423
7476
  let F = "";
7424
- L.length > 0 && (F = L.map((B) => B.text && Array.isArray(B.text) ? B.text.map((J) => J.word).join(" ") : B.text || "").join(" ")), S.current = {
7477
+ L.length > 0 && (F = L.map((N) => N.text && Array.isArray(N.text) ? N.text.map((J) => J.word).join(" ") : N.text || "").join(" ")), k.current = {
7425
7478
  remainingText: F || null,
7426
7479
  originalText: P.current?.text || null,
7427
7480
  options: P.current?.options || null
7428
- }, f.current.speechQueue.length = 0, f.current.pauseSpeaking(), le(!0), oe.current = !0;
7481
+ }, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), le(!0), oe.current = !0;
7429
7482
  }
7430
7483
  } catch (C) {
7431
7484
  console.warn("Error pausing speech:", C);
7432
7485
  }
7433
7486
  }, []), Le = T(async () => {
7434
- if (!(!f.current || !ee))
7487
+ if (!(!y.current || !ee))
7435
7488
  try {
7436
7489
  await _(), le(!1), oe.current = !1;
7437
- const C = S.current?.remainingText, te = S.current?.originalText || P.current?.text, L = S.current?.options || P.current?.options || {}, F = C || te;
7490
+ const C = k.current?.remainingText, te = k.current?.originalText || P.current?.text, L = k.current?.options || P.current?.options || {}, F = C || te;
7438
7491
  F && j(F, L);
7439
7492
  } catch (C) {
7440
7493
  console.warn("Error resuming speech:", C), le(!1), oe.current = !1;
7441
7494
  }
7442
7495
  }, [ee, j, _]), we = T(() => {
7443
- f.current && (f.current.stopSpeaking(), U.current && (clearInterval(U.current), U.current = null), le(!1), oe.current = !1);
7496
+ y.current && (y.current.stopSpeaking(), W.current && (clearInterval(W.current), W.current = null), le(!1), oe.current = !1);
7444
7497
  }, []);
7445
7498
  return Ee(M, () => ({
7446
7499
  speakText: j,
@@ -7449,20 +7502,20 @@ const gt = Me(({
7449
7502
  stopSpeaking: we,
7450
7503
  resumeAudioContext: _,
7451
7504
  isPaused: () => ee,
7452
- setMood: (C) => f.current?.setMood(C),
7505
+ setMood: (C) => y.current?.setMood(C),
7453
7506
  setBodyMovement: (C) => {
7454
- f.current && f.current.setBodyMovement(C);
7507
+ y.current && y.current.setBodyMovement(C);
7455
7508
  },
7456
7509
  playAnimation: (C, te = !1) => {
7457
- f.current && f.current.playAnimation && f.current.playAnimation(C, null, 10, 0, 0.01, te);
7510
+ y.current && y.current.playAnimation && y.current.playAnimation(C, null, 10, 0, 0.01, te);
7458
7511
  },
7459
- playReaction: (C) => f.current?.playReaction(C),
7460
- playCelebration: () => f.current?.playCelebration(),
7512
+ playReaction: (C) => y.current?.playReaction(C),
7513
+ playCelebration: () => y.current?.playCelebration(),
7461
7514
  setShowFullAvatar: (C) => {
7462
- f.current && (E.current = C, f.current.setShowFullAvatar(C));
7515
+ y.current && (E.current = C, y.current.setShowFullAvatar(C));
7463
7516
  },
7464
7517
  isReady: ae,
7465
- talkingHead: f.current
7518
+ talkingHead: y.current
7466
7519
  })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${b}`, style: I, children: [
7467
7520
  /* @__PURE__ */ me(
7468
7521
  "div",
@@ -7532,7 +7585,7 @@ const yt = Me(({
7532
7585
  onQuestionAnswer: s,
7533
7586
  onCurriculumComplete: o,
7534
7587
  onCustomAction: l
7535
- }), d = O(null), g = O(null), y = O(null), b = O(null), I = O(null), V = O(null), p = O(null), M = O(G?.curriculum || {
7588
+ }), d = O(null), g = O(null), x = O(null), b = O(null), I = O(null), B = O(null), p = O(null), M = O(G?.curriculum || {
7536
7589
  title: "Default Curriculum",
7537
7590
  description: "No curriculum data provided",
7538
7591
  language: "en",
@@ -7580,7 +7633,7 @@ const yt = Me(({
7580
7633
  lipsyncLang: "en"
7581
7634
  };
7582
7635
  }, [G, t, e]);
7583
- const f = T(() => (M.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), E = T(() => f()?.questions[a.current.currentQuestionIndex], [f]), P = T((v, R) => R.type === "multiple_choice" || R.type === "true_false" ? v === R.answer : R.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), U = T(() => {
7636
+ const y = T(() => (M.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), E = T(() => y()?.questions[a.current.currentQuestionIndex], [y]), P = T((v, R) => R.type === "multiple_choice" || R.type === "true_false" ? v === R.answer : R.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), W = T(() => {
7584
7637
  a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
7585
7638
  const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7586
7639
  let R = "Congratulations! You've completed this lesson";
@@ -7604,7 +7657,7 @@ const yt = Me(({
7604
7657
  } catch {
7605
7658
  u.current.playCelebration();
7606
7659
  }
7607
- const k = M.current || { modules: [] }, H = k.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (k.modules?.length || 0) - 1, j = N || _, q = z.current || { lipsyncLang: "en" };
7660
+ const S = M.current || { modules: [] }, H = S.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (S.modules?.length || 0) - 1, j = U || _, q = z.current || { lipsyncLang: "en" };
7608
7661
  u.current.speakText(R, {
7609
7662
  lipsyncLang: q.lipsyncLang,
7610
7663
  onSpeechEnd: () => {
@@ -7625,7 +7678,7 @@ const yt = Me(({
7625
7678
  const v = M.current || { modules: [] };
7626
7679
  if (c.current.onCurriculumComplete({
7627
7680
  modules: v.modules.length,
7628
- totalLessons: v.modules.reduce((R, k) => R + k.lessons.length, 0)
7681
+ totalLessons: v.modules.reduce((R, S) => R + S.lessons.length, 0)
7629
7682
  }), u.current) {
7630
7683
  if (u.current.setMood("celebrating"), e.curriculumComplete)
7631
7684
  try {
@@ -7636,8 +7689,8 @@ const yt = Me(({
7636
7689
  const R = z.current || { lipsyncLang: "en" };
7637
7690
  u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: R.lipsyncLang });
7638
7691
  }
7639
- }, [e.curriculumComplete]), S = T(() => {
7640
- const v = f();
7692
+ }, [e.curriculumComplete]), k = T(() => {
7693
+ const v = y();
7641
7694
  a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
7642
7695
  const R = E();
7643
7696
  R && c.current.onCustomAction({
@@ -7649,32 +7702,32 @@ const yt = Me(({
7649
7702
  question: R,
7650
7703
  score: a.current.score
7651
7704
  });
7652
- const k = () => {
7705
+ const S = () => {
7653
7706
  if (!u.current || !R) return;
7654
7707
  if (u.current.setMood("happy"), e.questionStart)
7655
7708
  try {
7656
7709
  u.current.playAnimation(e.questionStart, !0);
7657
- } catch (N) {
7658
- console.warn("Failed to play questionStart animation:", N);
7710
+ } catch (U) {
7711
+ console.warn("Failed to play questionStart animation:", U);
7659
7712
  }
7660
7713
  const H = z.current || { lipsyncLang: "en" };
7661
7714
  R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang });
7662
7715
  };
7663
7716
  if (u.current && u.current.isReady && R)
7664
- k();
7717
+ S();
7665
7718
  else if (u.current && u.current.isReady) {
7666
7719
  const H = z.current || { lipsyncLang: "en" };
7667
7720
  u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: H.lipsyncLang });
7668
7721
  } else {
7669
7722
  const H = setInterval(() => {
7670
- u.current && u.current.isReady && (clearInterval(H), R && k());
7723
+ u.current && u.current.isReady && (clearInterval(H), R && S());
7671
7724
  }, 100);
7672
7725
  setTimeout(() => {
7673
7726
  clearInterval(H);
7674
7727
  }, 5e3);
7675
7728
  }
7676
- }, [e.questionStart, f, E]), Z = T(() => {
7677
- const v = f();
7729
+ }, [e.questionStart, y, E]), Z = T(() => {
7730
+ const v = y();
7678
7731
  if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
7679
7732
  u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
7680
7733
  const R = E();
@@ -7687,7 +7740,7 @@ const yt = Me(({
7687
7740
  question: R,
7688
7741
  score: a.current.score
7689
7742
  });
7690
- const k = () => {
7743
+ const S = () => {
7691
7744
  if (!u.current || !R) return;
7692
7745
  if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
7693
7746
  try {
@@ -7695,7 +7748,7 @@ const yt = Me(({
7695
7748
  } catch (q) {
7696
7749
  console.warn("Failed to play nextQuestion animation:", q);
7697
7750
  }
7698
- const H = z.current || { lipsyncLang: "en" }, _ = f()?.questions?.length || 0, j = a.current.currentQuestionIndex >= _ - 1;
7751
+ const H = z.current || { lipsyncLang: "en" }, _ = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= _ - 1;
7699
7752
  if (R.type === "code_test") {
7700
7753
  const q = j ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
7701
7754
  u.current.speakText(q, {
@@ -7719,10 +7772,10 @@ const yt = Me(({
7719
7772
  }
7720
7773
  };
7721
7774
  if (u.current && u.current.isReady && R)
7722
- k();
7775
+ S();
7723
7776
  else if (R) {
7724
7777
  const H = setInterval(() => {
7725
- u.current && u.current.isReady && (clearInterval(H), k());
7778
+ u.current && u.current.isReady && (clearInterval(H), S());
7726
7779
  }, 100);
7727
7780
  setTimeout(() => {
7728
7781
  clearInterval(H);
@@ -7736,11 +7789,11 @@ const yt = Me(({
7736
7789
  totalQuestions: a.current.totalQuestions,
7737
7790
  score: a.current.score
7738
7791
  });
7739
- }, [e.nextQuestion, f, E]), K = T(() => {
7792
+ }, [e.nextQuestion, y, E]), K = T(() => {
7740
7793
  const v = M.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
7741
7794
  if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
7742
7795
  a.current.currentLessonIndex += 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
7743
- const H = v.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = N || _;
7796
+ const H = v.modules[a.current.currentModuleIndex], U = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = U || _;
7744
7797
  c.current.onCustomAction({
7745
7798
  type: "lessonStart",
7746
7799
  moduleIndex: a.current.currentModuleIndex,
@@ -7749,11 +7802,11 @@ const yt = Me(({
7749
7802
  }), c.current.onLessonStart({
7750
7803
  moduleIndex: a.current.currentModuleIndex,
7751
7804
  lessonIndex: a.current.currentLessonIndex,
7752
- lesson: f()
7805
+ lesson: y()
7753
7806
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7754
7807
  } else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
7755
7808
  a.current.currentModuleIndex += 1, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
7756
- const N = v.modules[a.current.currentModuleIndex], _ = a.current.currentLessonIndex < (N?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = _ || j;
7809
+ const U = v.modules[a.current.currentModuleIndex], _ = a.current.currentLessonIndex < (U?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = _ || j;
7757
7810
  c.current.onCustomAction({
7758
7811
  type: "lessonStart",
7759
7812
  moduleIndex: a.current.currentModuleIndex,
@@ -7762,28 +7815,28 @@ const yt = Me(({
7762
7815
  }), c.current.onLessonStart({
7763
7816
  moduleIndex: a.current.currentModuleIndex,
7764
7817
  lessonIndex: a.current.currentLessonIndex,
7765
- lesson: f()
7818
+ lesson: y()
7766
7819
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7767
7820
  } else
7768
7821
  I.current && I.current();
7769
7822
  }, []), X = T(() => {
7770
- const v = f();
7823
+ const v = y();
7771
7824
  let R = null;
7772
7825
  if (v?.avatar_script && v?.body) {
7773
- const k = v.avatar_script.trim(), H = v.body.trim(), N = k.match(/[.!?]$/) ? " " : ". ";
7774
- R = `${k}${N}${H}`;
7826
+ const S = v.avatar_script.trim(), H = v.body.trim(), U = S.match(/[.!?]$/) ? " " : ". ";
7827
+ R = `${S}${U}${H}`;
7775
7828
  } else
7776
7829
  R = v?.avatar_script || v?.body || null;
7777
7830
  if (u.current && u.current.isReady && R) {
7778
7831
  a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, u.current.setMood("happy");
7779
- let k = !1;
7832
+ let S = !1;
7780
7833
  if (e.teaching)
7781
7834
  try {
7782
- u.current.playAnimation(e.teaching, !0), k = !0;
7783
- } catch (N) {
7784
- console.warn("Failed to play teaching animation:", N);
7835
+ u.current.playAnimation(e.teaching, !0), S = !0;
7836
+ } catch (U) {
7837
+ console.warn("Failed to play teaching animation:", U);
7785
7838
  }
7786
- k || u.current.setBodyMovement("gesturing");
7839
+ S || u.current.setBodyMovement("gesturing");
7787
7840
  const H = z.current || { lipsyncLang: "en" };
7788
7841
  c.current.onLessonStart({
7789
7842
  moduleIndex: a.current.currentModuleIndex,
@@ -7813,17 +7866,17 @@ const yt = Me(({
7813
7866
  }
7814
7867
  });
7815
7868
  }
7816
- }, [e.teaching, f]), $ = T((v) => {
7817
- const R = E(), k = P(v, R);
7818
- if (k && (a.current.score += 1), c.current.onQuestionAnswer({
7869
+ }, [e.teaching, y]), $ = T((v) => {
7870
+ const R = E(), S = P(v, R);
7871
+ if (S && (a.current.score += 1), c.current.onQuestionAnswer({
7819
7872
  moduleIndex: a.current.currentModuleIndex,
7820
7873
  lessonIndex: a.current.currentLessonIndex,
7821
7874
  questionIndex: a.current.currentQuestionIndex,
7822
7875
  answer: v,
7823
- isCorrect: k,
7876
+ isCorrect: S,
7824
7877
  question: R
7825
7878
  }), u.current)
7826
- if (k) {
7879
+ if (S) {
7827
7880
  if (u.current.setMood("happy"), e.correct)
7828
7881
  try {
7829
7882
  u.current.playReaction("happy");
@@ -7831,10 +7884,10 @@ const yt = Me(({
7831
7884
  u.current.setBodyMovement("happy");
7832
7885
  }
7833
7886
  u.current.setBodyMovement("gesturing");
7834
- const N = f()?.questions?.length || 0;
7835
- a.current.currentQuestionIndex >= N - 1;
7836
- const _ = a.current.currentQuestionIndex < N - 1;
7837
- console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", _);
7887
+ const U = y()?.questions?.length || 0;
7888
+ a.current.currentQuestionIndex >= U - 1;
7889
+ const _ = a.current.currentQuestionIndex < U - 1;
7890
+ console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", _);
7838
7891
  const j = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, q = z.current || { lipsyncLang: "en" };
7839
7892
  u.current.speakText(j, {
7840
7893
  lipsyncLang: q.lipsyncLang,
@@ -7859,8 +7912,8 @@ const yt = Me(({
7859
7912
  u.current.setBodyMovement("idle");
7860
7913
  }
7861
7914
  u.current.setBodyMovement("gesturing");
7862
- const N = f()?.questions?.length || 0, _ = a.current.currentQuestionIndex >= N - 1, j = a.current.currentQuestionIndex < N - 1;
7863
- console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", j);
7915
+ const U = y()?.questions?.length || 0, _ = a.current.currentQuestionIndex >= U - 1, j = a.current.currentQuestionIndex < U - 1;
7916
+ console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", U, "hasNextQuestion:", j);
7864
7917
  const q = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""}${_ ? "" : " Let's move on to the next question."}`, Le = z.current || { lipsyncLang: "en" };
7865
7918
  u.current.speakText(q, {
7866
7919
  lipsyncLang: Le.lipsyncLang,
@@ -7879,20 +7932,20 @@ const yt = Me(({
7879
7932
  });
7880
7933
  }
7881
7934
  else {
7882
- const N = f()?.questions?.length || 0;
7935
+ const U = y()?.questions?.length || 0;
7883
7936
  c.current.onCustomAction({
7884
7937
  type: "answerFeedbackComplete",
7885
7938
  moduleIndex: a.current.currentModuleIndex,
7886
7939
  lessonIndex: a.current.currentLessonIndex,
7887
7940
  questionIndex: a.current.currentQuestionIndex,
7888
- isCorrect: k,
7889
- hasNextQuestion: a.current.currentQuestionIndex < N - 1,
7941
+ isCorrect: S,
7942
+ hasNextQuestion: a.current.currentQuestionIndex < U - 1,
7890
7943
  score: a.current.score,
7891
7944
  totalQuestions: a.current.totalQuestions,
7892
7945
  avatarNotReady: !0
7893
7946
  });
7894
7947
  }
7895
- }, [e.correct, e.incorrect, E, f, P]), se = T((v) => {
7948
+ }, [e.correct, e.incorrect, E, y, P]), se = T((v) => {
7896
7949
  const R = E();
7897
7950
  if (!v || typeof v != "object") {
7898
7951
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
@@ -7902,7 +7955,7 @@ const yt = Me(({
7902
7955
  console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
7903
7956
  return;
7904
7957
  }
7905
- const k = {
7958
+ const S = {
7906
7959
  passed: v.passed === !0,
7907
7960
  results: v.results || [],
7908
7961
  output: v.output || "",
@@ -7917,9 +7970,9 @@ const yt = Me(({
7917
7970
  moduleIndex: a.current.currentModuleIndex,
7918
7971
  lessonIndex: a.current.currentLessonIndex,
7919
7972
  questionIndex: a.current.currentQuestionIndex,
7920
- testResult: k,
7973
+ testResult: S,
7921
7974
  question: R
7922
- }), p.current && p.current(k);
7975
+ }), p.current && p.current(S);
7923
7976
  }, [E, P]), ae = T(() => {
7924
7977
  if (a.current.currentQuestionIndex > 0) {
7925
7978
  a.current.currentQuestionIndex -= 1;
@@ -7936,21 +7989,21 @@ const yt = Me(({
7936
7989
  const R = () => {
7937
7990
  if (!u.current || !v) return;
7938
7991
  u.current.setMood("happy"), u.current.setBodyMovement("idle");
7939
- const k = z.current || { lipsyncLang: "en" };
7992
+ const S = z.current || { lipsyncLang: "en" };
7940
7993
  v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
7941
- lipsyncLang: k.lipsyncLang
7994
+ lipsyncLang: S.lipsyncLang
7942
7995
  }) : u.current.speakText(`Going back to: ${v.question}`, {
7943
- lipsyncLang: k.lipsyncLang
7996
+ lipsyncLang: S.lipsyncLang
7944
7997
  });
7945
7998
  };
7946
7999
  if (u.current && u.current.isReady && v)
7947
8000
  R();
7948
8001
  else if (v) {
7949
- const k = setInterval(() => {
7950
- u.current && u.current.isReady && (clearInterval(k), R());
8002
+ const S = setInterval(() => {
8003
+ u.current && u.current.isReady && (clearInterval(S), R());
7951
8004
  }, 100);
7952
8005
  setTimeout(() => {
7953
- clearInterval(k);
8006
+ clearInterval(S);
7954
8007
  }, 5e3);
7955
8008
  }
7956
8009
  }
@@ -7964,7 +8017,7 @@ const yt = Me(({
7964
8017
  }), c.current.onLessonStart({
7965
8018
  moduleIndex: a.current.currentModuleIndex,
7966
8019
  lessonIndex: a.current.currentLessonIndex,
7967
- lesson: f()
8020
+ lesson: y()
7968
8021
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7969
8022
  else if (a.current.currentModuleIndex > 0) {
7970
8023
  const H = v.modules[a.current.currentModuleIndex - 1];
@@ -7975,43 +8028,43 @@ const yt = Me(({
7975
8028
  }), c.current.onLessonStart({
7976
8029
  moduleIndex: a.current.currentModuleIndex,
7977
8030
  lessonIndex: a.current.currentLessonIndex,
7978
- lesson: f()
8031
+ lesson: y()
7979
8032
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7980
8033
  }
7981
- }, [f]), ee = T(() => {
8034
+ }, [y]), ee = T(() => {
7982
8035
  a.current.currentModuleIndex = 0, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.isTeaching = !1, a.current.isQuestionMode = !1, a.current.lessonCompleted = !1, a.current.curriculumCompleted = !1, a.current.score = 0, a.current.totalQuestions = 0;
7983
8036
  }, []), le = T((v) => {
7984
8037
  console.log("Avatar is ready!", v);
7985
- const R = f(), k = R?.avatar_script || R?.body;
7986
- h && k && setTimeout(() => {
8038
+ const R = y(), S = R?.avatar_script || R?.body;
8039
+ h && S && setTimeout(() => {
7987
8040
  d.current && d.current();
7988
8041
  }, 10);
7989
- }, [h, f]);
8042
+ }, [h, y]);
7990
8043
  Xe(() => {
7991
- d.current = X, g.current = K, y.current = U, b.current = Z, I.current = oe, V.current = S, p.current = $;
8044
+ d.current = X, g.current = K, x.current = W, b.current = Z, I.current = oe, B.current = k, p.current = $;
7992
8045
  }), Ee(r, () => ({
7993
8046
  // Curriculum control methods
7994
8047
  startTeaching: X,
7995
- startQuestions: S,
8048
+ startQuestions: k,
7996
8049
  handleAnswerSelect: $,
7997
8050
  handleCodeTestResult: se,
7998
8051
  nextQuestion: Z,
7999
8052
  previousQuestion: ae,
8000
8053
  nextLesson: K,
8001
8054
  previousLesson: pe,
8002
- completeLesson: U,
8055
+ completeLesson: W,
8003
8056
  completeCurriculum: oe,
8004
8057
  resetCurriculum: ee,
8005
8058
  getState: () => ({ ...a.current }),
8006
8059
  getCurrentQuestion: () => E(),
8007
- getCurrentLesson: () => f(),
8060
+ getCurrentLesson: () => y(),
8008
8061
  // Direct access to avatar ref (always returns current value)
8009
8062
  getAvatarRef: () => u.current,
8010
8063
  // Convenience methods that delegate to avatar (always check current ref)
8011
8064
  speakText: async (v, R = {}) => {
8012
8065
  await u.current?.resumeAudioContext?.();
8013
- const k = z.current || { lipsyncLang: "en" };
8014
- u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || k.lipsyncLang });
8066
+ const S = z.current || { lipsyncLang: "en" };
8067
+ u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || S.lipsyncLang });
8015
8068
  },
8016
8069
  resumeAudioContext: async () => {
8017
8070
  if (u.current?.resumeAudioContext)
@@ -8022,8 +8075,8 @@ const yt = Me(({
8022
8075
  if (R.state === "suspended" || R.state === "interrupted")
8023
8076
  try {
8024
8077
  await R.resume(), console.log("Audio context resumed via talkingHead");
8025
- } catch (k) {
8026
- console.warn("Failed to resume audio context:", k);
8078
+ } catch (S) {
8079
+ console.warn("Failed to resume audio context:", S);
8027
8080
  }
8028
8081
  } else
8029
8082
  console.warn("Audio context not available yet");
@@ -8055,7 +8108,7 @@ const yt = Me(({
8055
8108
  handleResize: () => u.current?.handleResize(),
8056
8109
  // Avatar readiness check (always returns current value)
8057
8110
  isAvatarReady: () => u.current?.isReady || !1
8058
- }), [X, S, $, se, Z, K, U, oe, ee, E, f]);
8111
+ }), [X, k, $, se, Z, K, W, oe, ee, E, y]);
8059
8112
  const D = z.current || {
8060
8113
  avatarUrl: "/avatars/brunette.glb",
8061
8114
  avatarBody: "F",
@@ -8207,6 +8260,6 @@ export {
8207
8260
  Ge as animations,
8208
8261
  Fe as getActiveTTSConfig,
8209
8262
  wt as getAnimation,
8210
- kt as getVoiceOptions,
8263
+ St as getVoiceOptions,
8211
8264
  zt as hasAnimation
8212
8265
  };