@sage-rsc/talking-head-react 1.3.4 → 1.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { jsxs as Pe, jsx as ye } from "react/jsx-runtime";
2
2
  import { forwardRef as Me, useRef as W, useState as pe, useEffect as ce, useCallback as O, useImperativeHandle as Fe, useLayoutEffect as Xe } from "react";
3
3
  import * as y from "three";
4
- import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
5
- import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
4
+ import { OrbitControls as je } from "three/addons/controls/OrbitControls.js";
5
+ import { GLTFLoader as Ye } from "three/addons/loaders/GLTFLoader.js";
6
6
  import { DRACOLoader as Qe } from "three/addons/loaders/DRACOLoader.js";
7
7
  import { FBXLoader as De } from "three/addons/loaders/FBXLoader.js";
8
8
  import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
@@ -2629,7 +2629,7 @@ const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2629
2629
  fr: rt,
2630
2630
  fi: ut,
2631
2631
  lt: ct
2632
- }, J = new y.Quaternion(), G = new y.Euler(), ve = new y.Vector3(), Re = new y.Vector3(), We = new y.Box3();
2632
+ }, $ = new y.Quaternion(), Z = new y.Euler(), ve = new y.Vector3(), Re = new y.Vector3(), We = new y.Box3();
2633
2633
  new y.Matrix4();
2634
2634
  new y.Matrix4();
2635
2635
  new y.Vector3();
@@ -4086,7 +4086,7 @@ class Be {
4086
4086
  this.opt.lightSpotDispersion
4087
4087
  ), this.setLighting(this.opt);
4088
4088
  const l = new y.PMREMGenerator(this.renderer);
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;
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 je(this.camera, this.renderer.domElement), this.controls.enableZoom = this.opt.cameraZoomEnable, this.controls.enableRotate = this.opt.cameraRotateEnable, this.controls.enablePan = this.opt.cameraPanEnable, this.controls.minDistance = 2, this.controls.maxDistance = 2e3, this.controls.autoRotateSpeed = 0, this.controls.autoRotate = !1, this.controls.update(), this.cameraClock = null;
4090
4090
  }
4091
4091
  this.ikMesh = new y.SkinnedMesh();
4092
4092
  const s = {
@@ -4252,7 +4252,7 @@ class Be {
4252
4252
  async showAvatar(t, e = null) {
4253
4253
  if (!t || !t.hasOwnProperty("url"))
4254
4254
  throw new Error("Invalid parameter. The avatar must have at least 'url' specified.");
4255
- const n = new je();
4255
+ const n = new Ye();
4256
4256
  if (this.dracoEnabled) {
4257
4257
  const r = new Qe();
4258
4258
  r.setDecoderPath(this.dracoDecoderPath), n.setDRACOLoader(r);
@@ -4398,9 +4398,9 @@ class Be {
4398
4398
  updatePoseDelta() {
4399
4399
  for (const [t, e] of Object.entries(this.poseDelta.props)) {
4400
4400
  if (e.x === 0 && e.y === 0 && e.z === 0) continue;
4401
- G.set(e.x, e.y, e.z);
4401
+ Z.set(e.x, e.y, e.z);
4402
4402
  const n = this.poseAvatar.props[t];
4403
- n.isQuaternion ? (J.setFromEuler(G), n.multiply(J)) : n.isVector3 && n.add(G);
4403
+ n.isQuaternion ? ($.setFromEuler(Z), n.multiply($)) : n.isVector3 && n.add(Z);
4404
4404
  }
4405
4405
  }
4406
4406
  /**
@@ -5172,7 +5172,7 @@ class Be {
5172
5172
  }, i.x ? new y.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5173
5173
  break;
5174
5174
  }
5175
- if ((h || r) && (G.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), G.x = Math.max(-0.9, Math.min(0.9, 2 * G.x - 0.5)), G.y = Math.max(-0.9, Math.min(0.9, -2.5 * G.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: G.x < 0 ? -G.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: G.x < 0 ? 0 : G.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: G.y < 0 ? -G.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: G.y < 0 ? 0 : G.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: G.y < 0 ? 0 : G.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: G.y < 0 ? -G.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
5175
+ if ((h || r) && (Z.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), Z.x = Math.max(-0.9, Math.min(0.9, 2 * Z.x - 0.5)), Z.y = Math.max(-0.9, Math.min(0.9, -2.5 * Z.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: Z.x < 0 ? -Z.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: Z.x < 0 ? 0 : Z.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: Z.y < 0 ? -Z.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: Z.y < 0 ? 0 : Z.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: Z.y < 0 ? 0 : Z.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: Z.y < 0 ? -Z.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
5176
5176
  name: "headmove",
5177
5177
  dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
5178
5178
  vs: {
@@ -5193,7 +5193,7 @@ class Be {
5193
5193
  eyeLookOutRight: [null, 0],
5194
5194
  eyeContact: [0]
5195
5195
  }
5196
- })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (J.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(J)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Re), Re.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (ve.x + Re.x) / 4, this.objectHips.position.z -= (ve.z + Re.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
5196
+ })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && ($.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply($)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Re), Re.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (ve.x + Re.x) / 4, this.objectHips.position.z -= (ve.z + Re.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
5197
5197
  this.stats && this.stats.end();
5198
5198
  else {
5199
5199
  if (this.cameraClock !== null && this.cameraClock < 1e3) {
@@ -5264,10 +5264,10 @@ class Be {
5264
5264
  let u = "", a = "", d = 0, c = [], g = [];
5265
5265
  const x = Array.from(this.segmenter.segment(t), (f) => f.segment);
5266
5266
  for (let f = 0; f < x.length; f++) {
5267
- const k = f === x.length - 1, N = x[f].match(l);
5267
+ const k = f === x.length - 1, D = x[f].match(l);
5268
5268
  let p = x[f].match(s);
5269
- const B = x[f].match(h), H = x[f].match(o);
5270
- if (p && !k && !B && x[f + 1].match(s) && (p = !1), n && (u += x[f]), N && (!i || i.every((R) => f < R[0] || f > R[1])) && (a += x[f]), (H || p || k) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && c.push({
5269
+ const B = x[f].match(h), T = x[f].match(o);
5270
+ if (p && !k && !B && x[f + 1].match(s) && (p = !1), n && (u += x[f]), D && (!i || i.every((R) => f < R[0] || f > R[1])) && (a += x[f]), (T || p || k) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && c.push({
5271
5271
  mark: d,
5272
5272
  word: a
5273
5273
  })), u.length && (g.push({
@@ -5398,10 +5398,10 @@ class Be {
5398
5398
  let x = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
5399
5399
  if (u = Math.min(u, d.visemes.length * 200), c > 0)
5400
5400
  for (let f = 0; f < d.visemes.length; f++) {
5401
- const k = r + d.times[f] / c * u, N = d.durations[f] / c * u;
5401
+ const k = r + d.times[f] / c * u, D = d.durations[f] / c * u;
5402
5402
  o.push({
5403
5403
  template: { name: "viseme" },
5404
- ts: [k - Math.min(60, 2 * N / 3), k + Math.min(25, N / 2), k + N + Math.min(60, N / 2)],
5404
+ ts: [k - Math.min(60, 2 * D / 3), k + Math.min(25, D / 2), k + D + Math.min(60, D / 2)],
5405
5405
  vs: {
5406
5406
  ["viseme_" + d.visemes[f]]: [null, d.visemes[f] === "PP" || d.visemes[f] === "FF" ? 0.9 : x, 0]
5407
5407
  }
@@ -5499,18 +5499,18 @@ class Be {
5499
5499
  if (f && f.visemes && f.visemes.length > 0) {
5500
5500
  const p = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
5501
5501
  for (let B = 0; B < f.visemes.length; B++) {
5502
- const H = f.visemes[B], R = f.times[B] / p, L = f.durations[B] / p, I = R * d, z = L * d;
5502
+ const T = f.visemes[B], R = f.times[B] / p, L = f.durations[B] / p, I = R * d, z = L * d;
5503
5503
  k.push({
5504
5504
  template: { name: "viseme" },
5505
5505
  ts: [I - Math.min(60, 2 * z / 3), I + Math.min(25, z / 2), I + z + Math.min(60, z / 2)],
5506
5506
  vs: {
5507
- ["viseme_" + H]: [null, H === "PP" || H === "FF" ? 0.9 : 0.6, 0]
5507
+ ["viseme_" + T]: [null, T === "PP" || T === "FF" ? 0.9 : 0.6, 0]
5508
5508
  }
5509
5509
  });
5510
5510
  }
5511
5511
  }
5512
- const N = [...t.anim, ...k];
5513
- this.audioPlaylist.push({ anim: N, audio: c }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5512
+ const D = [...t.anim, ...k];
5513
+ this.audioPlaylist.push({ anim: D, audio: c }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5514
5514
  e();
5515
5515
  }, s.onerror = (p) => {
5516
5516
  console.error("Speech synthesis error:", p.error), n(p.error);
@@ -6159,12 +6159,12 @@ class Be {
6159
6159
  this.lookAt(null, null, t);
6160
6160
  return;
6161
6161
  }
6162
- this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), J.copy(this.armature.quaternion), J.multiply(this.poseTarget.props["Hips.quaternion"]), J.multiply(this.poseTarget.props["Spine.quaternion"]), J.multiply(this.poseTarget.props["Spine1.quaternion"]), J.multiply(this.poseTarget.props["Spine2.quaternion"]), J.multiply(this.poseTarget.props["Neck.quaternion"]), J.multiply(this.poseTarget.props["Head.quaternion"]);
6162
+ this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), $.copy(this.armature.quaternion), $.multiply(this.poseTarget.props["Hips.quaternion"]), $.multiply(this.poseTarget.props["Spine.quaternion"]), $.multiply(this.poseTarget.props["Spine1.quaternion"]), $.multiply(this.poseTarget.props["Spine2.quaternion"]), $.multiply(this.poseTarget.props["Neck.quaternion"]), $.multiply(this.poseTarget.props["Head.quaternion"]);
6163
6163
  const n = new y.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6164
- G.set(s, i, 0, "YXZ");
6165
- const l = new y.Quaternion().setFromEuler(G), h = new y.Quaternion().copy(l).multiply(J.clone().invert());
6166
- G.setFromQuaternion(h, "YXZ");
6167
- let r = G.x / (40 / 24) + 0.2, u = G.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), d = Math.min(0.8, Math.max(-0.8, u)), c = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6164
+ Z.set(s, i, 0, "YXZ");
6165
+ const l = new y.Quaternion().setFromEuler(Z), h = new y.Quaternion().copy(l).multiply($.clone().invert());
6166
+ Z.setFromQuaternion(h, "YXZ");
6167
+ let r = Z.x / (40 / 24) + 0.2, u = Z.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), d = Math.min(0.8, Math.max(-0.8, u)), c = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6168
6168
  if (t) {
6169
6169
  let x = this.animQueue.findIndex((k) => k.template.name === "lookat");
6170
6170
  x !== -1 && this.animQueue.splice(x, 1);
@@ -6199,20 +6199,20 @@ class Be {
6199
6199
  const s = new y.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new y.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new y.Vector3().addVectors(s, o).divideScalar(2);
6200
6200
  l.project(this.camera);
6201
6201
  let h = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
6202
- t === null && (t = h), e === null && (e = r), J.copy(this.armature.quaternion), J.multiply(this.poseTarget.props["Hips.quaternion"]), J.multiply(this.poseTarget.props["Spine.quaternion"]), J.multiply(this.poseTarget.props["Spine1.quaternion"]), J.multiply(this.poseTarget.props["Spine2.quaternion"]), J.multiply(this.poseTarget.props["Neck.quaternion"]), J.multiply(this.poseTarget.props["Head.quaternion"]), G.setFromQuaternion(J);
6203
- let u = G.x / (40 / 24), a = G.y / (9 / 4), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - h, h), x = Math.max(window.innerHeight - r, r), f = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - u + d, k = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + c;
6202
+ t === null && (t = h), e === null && (e = r), $.copy(this.armature.quaternion), $.multiply(this.poseTarget.props["Hips.quaternion"]), $.multiply(this.poseTarget.props["Spine.quaternion"]), $.multiply(this.poseTarget.props["Spine1.quaternion"]), $.multiply(this.poseTarget.props["Spine2.quaternion"]), $.multiply(this.poseTarget.props["Neck.quaternion"]), $.multiply(this.poseTarget.props["Head.quaternion"]), Z.setFromQuaternion($);
6203
+ let u = Z.x / (40 / 24), a = Z.y / (9 / 4), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - h, h), x = Math.max(window.innerHeight - r, r), f = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - u + d, k = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + c;
6204
6204
  f = Math.min(0.6, Math.max(-0.3, f)), k = Math.min(0.8, Math.max(-0.8, k));
6205
- let N = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6205
+ let D = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6206
6206
  if (n) {
6207
6207
  let B = this.animQueue.findIndex((R) => R.template.name === "lookat");
6208
6208
  B !== -1 && this.animQueue.splice(B, 1);
6209
- const H = {
6209
+ const T = {
6210
6210
  name: "lookat",
6211
6211
  dt: [750, n],
6212
6212
  vs: {
6213
- bodyRotateX: [f + N],
6213
+ bodyRotateX: [f + D],
6214
6214
  bodyRotateY: [k + p],
6215
- eyesRotateX: [-3 * N + 0.1],
6215
+ eyesRotateX: [-3 * D + 0.1],
6216
6216
  eyesRotateY: [-5 * p],
6217
6217
  browInnerUp: [[0, 0.7]],
6218
6218
  mouthLeft: [[0, 0.7]],
@@ -6221,7 +6221,7 @@ class Be {
6221
6221
  headMove: [0]
6222
6222
  }
6223
6223
  };
6224
- this.animQueue.push(this.animFactory(H));
6224
+ this.animQueue.push(this.animFactory(T));
6225
6225
  }
6226
6226
  }
6227
6227
  /**
@@ -6535,16 +6535,16 @@ class Be {
6535
6535
  }), console.log("=== Ready Player Me Animation Bone Analysis ==="), console.log("FBX bone names:", Array.from(f).sort().join(", ")), console.log("Avatar skeleton bone names:", Array.from(c).sort().join(", "));
6536
6536
  const k = Array.from(f).filter(
6537
6537
  (L) => L.toLowerCase().includes("arm") || L.toLowerCase().includes("hand") || L.toLowerCase().includes("shoulder")
6538
- ), N = Array.from(c).filter(
6538
+ ), D = Array.from(c).filter(
6539
6539
  (L) => L.includes("Arm") || L.includes("Hand") || L.includes("Shoulder")
6540
6540
  );
6541
- console.log("FBX arm/hand/shoulder bones:", k.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:", N.sort().join(", "));
6541
+ console.log("FBX arm/hand/shoulder bones:", k.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:", D.sort().join(", "));
6542
6542
  const p = [], B = /* @__PURE__ */ new Set();
6543
6543
  if (d.tracks.forEach((L) => {
6544
6544
  const z = L.name.replaceAll("mixamorig", "").split("."), Y = z[0], S = z[1], E = x(Y);
6545
6545
  if (E && S) {
6546
- const X = `${E}.${S}`, Z = L.clone();
6547
- Z.name = X, p.push(Z), Y !== E && g.set(Y, E);
6546
+ const j = `${E}.${S}`, X = L.clone();
6547
+ X.name = j, p.push(X), Y !== E && g.set(Y, E);
6548
6548
  } else
6549
6549
  B.add(Y), (Y.toLowerCase().includes("arm") || Y.toLowerCase().includes("hand") || Y.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${Y}" could not be mapped to avatar skeleton`);
6550
6550
  }), B.size > 0 && console.warn(`⚠️ ${B.size} bone(s) could not be mapped:`, Array.from(B).sort().join(", ")), p.length > 0) {
@@ -6558,18 +6558,18 @@ class Be {
6558
6558
  L.length > 0 ? console.log(`✓ Arm bones mapped: ${L.join(", ")}`) : console.warn("⚠️ No arm bones were mapped! This may cause arm rigging issues.");
6559
6559
  } else
6560
6560
  console.error("❌ No tracks could be mapped! Animation may not work correctly.");
6561
- const H = {};
6561
+ const T = {};
6562
6562
  d.tracks.forEach((L) => {
6563
6563
  L.name = L.name.replaceAll("mixamorig", "");
6564
6564
  const I = L.name.split(".");
6565
6565
  if (I[1] === "position") {
6566
6566
  for (let z = 0; z < L.values.length; z++)
6567
6567
  L.values[z] = L.values[z] * s;
6568
- H[L.name] = new y.Vector3(L.values[0], L.values[1], L.values[2]);
6569
- } else I[1] === "quaternion" ? H[L.name] = new y.Quaternion(L.values[0], L.values[1], L.values[2], L.values[3]) : I[1] === "rotation" && (H[I[0] + ".quaternion"] = new y.Quaternion().setFromEuler(new y.Euler(L.values[0], L.values[1], L.values[2], "XYZ")).normalize());
6568
+ T[L.name] = new y.Vector3(L.values[0], L.values[1], L.values[2]);
6569
+ } else I[1] === "quaternion" ? T[L.name] = new y.Quaternion(L.values[0], L.values[1], L.values[2], L.values[3]) : I[1] === "rotation" && (T[I[0] + ".quaternion"] = new y.Quaternion().setFromEuler(new y.Euler(L.values[0], L.values[1], L.values[2], "XYZ")).normalize());
6570
6570
  });
6571
- const R = { props: H };
6572
- H["Hips.position"] && (H["Hips.position"].y < 0.5 ? R.lying = !0 : R.standing = !0), this.animClips.push({
6571
+ const R = { props: T };
6572
+ T["Hips.position"] && (T["Hips.position"].y < 0.5 ? R.lying = !0 : R.standing = !0), this.animClips.push({
6573
6573
  url: t + "-" + i,
6574
6574
  clip: d,
6575
6575
  pose: R
@@ -6707,12 +6707,12 @@ class Be {
6707
6707
  const f = t.iterations || 10;
6708
6708
  if (e)
6709
6709
  for (let k = 0; k < f; k++) {
6710
- let N = !1;
6710
+ let D = !1;
6711
6711
  for (let p = 0, B = x.length; p < B; p++) {
6712
- const H = x[p].bone;
6713
- H.matrixWorld.decompose(h, r, u), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, h), l.applyQuaternion(r), l.normalize(), s.subVectors(e, h), s.applyQuaternion(r), s.normalize();
6712
+ const T = x[p].bone;
6713
+ T.matrixWorld.decompose(h, r, u), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, h), l.applyQuaternion(r), l.normalize(), s.subVectors(e, h), s.applyQuaternion(r), s.normalize();
6714
6714
  let R = s.dot(l);
6715
- R > 1 ? R = 1 : R < -1 && (R = -1), R = Math.acos(R), !(R < 1e-5) && (x[p].minAngle !== void 0 && R < x[p].minAngle && (R = x[p].minAngle), x[p].maxAngle !== void 0 && R > x[p].maxAngle && (R = x[p].maxAngle), a.crossVectors(l, s), a.normalize(), J.setFromAxisAngle(a, R), H.quaternion.multiply(J), H.rotation.setFromVector3(d.setFromEuler(H.rotation).clamp(new y.Vector3(
6715
+ R > 1 ? R = 1 : R < -1 && (R = -1), R = Math.acos(R), !(R < 1e-5) && (x[p].minAngle !== void 0 && R < x[p].minAngle && (R = x[p].minAngle), x[p].maxAngle !== void 0 && R > x[p].maxAngle && (R = x[p].maxAngle), a.crossVectors(l, s), a.normalize(), $.setFromAxisAngle(a, R), T.quaternion.multiply($), T.rotation.setFromVector3(d.setFromEuler(T.rotation).clamp(new y.Vector3(
6716
6716
  x[p].minx !== void 0 ? x[p].minx : -1 / 0,
6717
6717
  x[p].miny !== void 0 ? x[p].miny : -1 / 0,
6718
6718
  x[p].minz !== void 0 ? x[p].minz : -1 / 0
@@ -6720,9 +6720,9 @@ class Be {
6720
6720
  x[p].maxx !== void 0 ? x[p].maxx : 1 / 0,
6721
6721
  x[p].maxy !== void 0 ? x[p].maxy : 1 / 0,
6722
6722
  x[p].maxz !== void 0 ? x[p].maxz : 1 / 0
6723
- ))), H.updateMatrixWorld(!0), N = !0);
6723
+ ))), T.updateMatrixWorld(!0), D = !0);
6724
6724
  }
6725
- if (!N) break;
6725
+ if (!D) break;
6726
6726
  }
6727
6727
  i && x.forEach((k) => {
6728
6728
  this.poseTarget.props[k.link + ".quaternion"].copy(k.bone.quaternion), this.poseTarget.props[k.link + ".quaternion"].t = this.animClock, this.poseTarget.props[k.link + ".quaternion"].d = i;
@@ -6815,70 +6815,70 @@ const Ve = Me(({
6815
6815
  style: x = {},
6816
6816
  animations: f = {}
6817
6817
  }, k) => {
6818
- const N = W(null), p = W(null), B = W(r), H = W(null), R = W(null), L = W(!1), I = W({ remainingText: null, originalText: null, options: null }), z = W([]), Y = W(0), [S, E] = pe(!0), [X, Z] = pe(null), [oe, le] = pe(!1), [ge, de] = pe(!1);
6818
+ const D = W(null), p = W(null), B = W(r), T = W(null), R = W(null), L = W(!1), I = W({ remainingText: null, originalText: null, options: null }), z = W([]), Y = W(0), [S, E] = pe(!0), [j, X] = pe(null), [oe, le] = pe(!1), [ge, de] = pe(!1);
6819
6819
  ce(() => {
6820
6820
  L.current = ge;
6821
6821
  }, [ge]), ce(() => {
6822
6822
  B.current = r;
6823
6823
  }, [r]);
6824
- const $ = Ee(), be = i || $.service;
6825
- let j;
6826
- be === "browser" ? j = {
6824
+ const ee = Ee(), be = i || ee.service;
6825
+ let Q;
6826
+ be === "browser" ? Q = {
6827
6827
  service: "browser",
6828
6828
  endpoint: "",
6829
6829
  apiKey: null,
6830
6830
  defaultVoice: "Google US English"
6831
- } : be === "elevenlabs" ? j = {
6831
+ } : be === "elevenlabs" ? Q = {
6832
6832
  service: "elevenlabs",
6833
6833
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
6834
- apiKey: o || $.apiKey,
6835
- defaultVoice: s || $.defaultVoice || Ie.defaultVoice,
6836
- voices: $.voices || Ie.voices
6837
- } : be === "deepgram" ? j = {
6834
+ apiKey: o || ee.apiKey,
6835
+ defaultVoice: s || ee.defaultVoice || Ie.defaultVoice,
6836
+ voices: ee.voices || Ie.voices
6837
+ } : be === "deepgram" ? Q = {
6838
6838
  service: "deepgram",
6839
6839
  endpoint: "https://api.deepgram.com/v1/speak",
6840
- apiKey: o || $.apiKey,
6841
- defaultVoice: s || $.defaultVoice || Te.defaultVoice,
6842
- voices: $.voices || Te.voices
6843
- } : j = {
6844
- ...$,
6840
+ apiKey: o || ee.apiKey,
6841
+ defaultVoice: s || ee.defaultVoice || Te.defaultVoice,
6842
+ voices: ee.voices || Te.voices
6843
+ } : Q = {
6844
+ ...ee,
6845
6845
  // Override API key if provided via props
6846
- apiKey: o !== null ? o : $.apiKey
6846
+ apiKey: o !== null ? o : ee.apiKey
6847
6847
  };
6848
6848
  const b = {
6849
6849
  url: V,
6850
6850
  body: t,
6851
6851
  avatarMood: e,
6852
6852
  ttsLang: be === "browser" ? "en-US" : n,
6853
- ttsVoice: s || j.defaultVoice,
6853
+ ttsVoice: s || Q.defaultVoice,
6854
6854
  lipsyncLang: "en",
6855
6855
  showFullAvatar: r,
6856
6856
  bodyMovement: l,
6857
6857
  movementIntensity: h
6858
6858
  }, v = {
6859
- ttsEndpoint: j.endpoint,
6860
- ttsApikey: j.apiKey,
6859
+ ttsEndpoint: Q.endpoint,
6860
+ ttsApikey: Q.apiKey,
6861
6861
  ttsService: be,
6862
6862
  lipsyncModules: ["en"],
6863
6863
  cameraView: u
6864
6864
  }, F = O(async () => {
6865
- if (!(!N.current || p.current))
6865
+ if (!(!D.current || p.current))
6866
6866
  try {
6867
- if (E(!0), Z(null), p.current = new Be(N.current, v), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), f && Object.keys(f).length > 0 && (p.current.customAnimations = f), await p.current.showAvatar(b, (_) => {
6868
- if (_.lengthComputable) {
6869
- const te = Math.min(100, Math.round(_.loaded / _.total * 100));
6870
- d(te);
6867
+ if (E(!0), X(null), p.current = new Be(D.current, v), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), f && Object.keys(f).length > 0 && (p.current.customAnimations = f), await p.current.showAvatar(b, (K) => {
6868
+ if (K.lengthComputable) {
6869
+ const ne = Math.min(100, Math.round(K.loaded / K.total * 100));
6870
+ d(ne);
6871
6871
  }
6872
- }), await new Promise((_) => {
6873
- const te = () => {
6874
- p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? _() : setTimeout(te, 100);
6872
+ }), await new Promise((K) => {
6873
+ const ne = () => {
6874
+ p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? K() : setTimeout(ne, 100);
6875
6875
  };
6876
- te();
6876
+ ne();
6877
6877
  }), p.current && p.current.setShowFullAvatar)
6878
6878
  try {
6879
6879
  p.current.setShowFullAvatar(r);
6880
- } catch (_) {
6881
- console.warn("Error setting full body mode on initialization:", _);
6880
+ } catch (K) {
6881
+ console.warn("Error setting full body mode on initialization:", K);
6882
6882
  }
6883
6883
  p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), E(!1), le(!0), a(p.current);
6884
6884
  const U = () => {
@@ -6888,18 +6888,18 @@ const Ve = Me(({
6888
6888
  document.removeEventListener("visibilitychange", U);
6889
6889
  };
6890
6890
  } catch (w) {
6891
- console.error("Error initializing TalkingHead:", w), Z(w.message || "Failed to initialize avatar"), E(!1), c(w);
6891
+ console.error("Error initializing TalkingHead:", w), X(w.message || "Failed to initialize avatar"), E(!1), c(w);
6892
6892
  }
6893
6893
  }, [V, t, e, n, i, s, o, r, l, h, u]);
6894
6894
  ce(() => (F(), () => {
6895
6895
  p.current && (p.current.stop(), p.current.dispose(), p.current = null);
6896
6896
  }), [F]), ce(() => {
6897
- if (!N.current || !p.current) return;
6898
- const w = new ResizeObserver((_) => {
6899
- for (const te of _)
6897
+ if (!D.current || !p.current) return;
6898
+ const w = new ResizeObserver((K) => {
6899
+ for (const ne of K)
6900
6900
  p.current && p.current.onResize && p.current.onResize();
6901
6901
  });
6902
- w.observe(N.current);
6902
+ w.observe(D.current);
6903
6903
  const U = () => {
6904
6904
  p.current && p.current.onResize && p.current.onResize();
6905
6905
  };
@@ -6914,26 +6914,26 @@ const Ve = Me(({
6914
6914
  } catch (w) {
6915
6915
  console.warn("Failed to resume audio context:", w);
6916
6916
  }
6917
- }, []), D = O(async (w, U = {}) => {
6917
+ }, []), N = O(async (w, U = {}) => {
6918
6918
  if (p.current && oe)
6919
6919
  try {
6920
- R.current && (clearInterval(R.current), R.current = null), H.current = { text: w, options: U }, I.current = { remainingText: null, originalText: null, options: null };
6921
- const _ = /[!\.\?\n\p{Extended_Pictographic}]/ug, te = w.split(_).map((A) => A.trim()).filter((A) => A.length > 0);
6922
- z.current = te, Y.current = 0, de(!1), L.current = !1, await P();
6920
+ R.current && (clearInterval(R.current), R.current = null), T.current = { text: w, options: U }, I.current = { remainingText: null, originalText: null, options: null };
6921
+ const K = /[!\.\?\n\p{Extended_Pictographic}]/ug, ne = w.split(K).map((A) => A.trim()).filter((A) => A.length > 0);
6922
+ z.current = ne, Y.current = 0, de(!1), L.current = !1, await P();
6923
6923
  const me = {
6924
6924
  ...U,
6925
6925
  lipsyncLang: U.lipsyncLang || b.lipsyncLang || "en"
6926
6926
  };
6927
6927
  if (U.onSpeechEnd && p.current) {
6928
6928
  const A = p.current;
6929
- let T = null, K = 0;
6930
- const ne = 1200;
6929
+ let H = null, G = 0;
6930
+ const J = 1200;
6931
6931
  let ie = !1;
6932
- T = setInterval(() => {
6933
- if (K++, L.current)
6932
+ H = setInterval(() => {
6933
+ if (G++, L.current)
6934
6934
  return;
6935
- if (K > ne) {
6936
- if (T && (clearInterval(T), T = null, R.current = null), !ie && !L.current) {
6935
+ if (G > J) {
6936
+ if (H && (clearInterval(H), H = null, R.current = null), !ie && !L.current) {
6937
6937
  ie = !0;
6938
6938
  try {
6939
6939
  U.onSpeechEnd();
@@ -6946,7 +6946,7 @@ const Ve = Me(({
6946
6946
  const se = !A.speechQueue || A.speechQueue.length === 0, we = !A.audioPlaylist || A.audioPlaylist.length === 0;
6947
6947
  A && A.isSpeaking === !1 && se && we && A.isAudioPlaying === !1 && !ie && !L.current && setTimeout(() => {
6948
6948
  if (A && !L.current && A.isSpeaking === !1 && (!A.speechQueue || A.speechQueue.length === 0) && (!A.audioPlaylist || A.audioPlaylist.length === 0) && A.isAudioPlaying === !1 && !ie && !L.current) {
6949
- ie = !0, T && (clearInterval(T), T = null, R.current = null);
6949
+ ie = !0, H && (clearInterval(H), H = null, R.current = null);
6950
6950
  try {
6951
6951
  U.onSpeechEnd();
6952
6952
  } catch (Ze) {
@@ -6954,59 +6954,59 @@ const Ve = Me(({
6954
6954
  }
6955
6955
  }
6956
6956
  }, 100);
6957
- }, 100), R.current = T;
6957
+ }, 100), R.current = H;
6958
6958
  }
6959
6959
  p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(w, me)) : setTimeout(async () => {
6960
6960
  await P(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(w, me));
6961
6961
  }, 100);
6962
- } catch (_) {
6963
- console.error("Error speaking text:", _), Z(_.message || "Failed to speak text");
6962
+ } catch (K) {
6963
+ console.error("Error speaking text:", K), X(K.message || "Failed to speak text");
6964
6964
  }
6965
- }, [oe, P, b.lipsyncLang]), ee = O(() => {
6966
- p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), H.current = null, de(!1));
6967
- }, []), Q = O(() => {
6965
+ }, [oe, P, b.lipsyncLang]), te = O(() => {
6966
+ p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), T.current = null, de(!1));
6967
+ }, []), q = O(() => {
6968
6968
  if (p.current && p.current.pauseSpeaking) {
6969
6969
  const w = p.current;
6970
6970
  if (w.isSpeaking || w.audioPlaylist && w.audioPlaylist.length > 0 || w.speechQueue && w.speechQueue.length > 0) {
6971
6971
  R.current && (clearInterval(R.current), R.current = null);
6972
- let _ = "";
6973
- if (H.current && z.current.length > 0) {
6974
- const te = z.current.length, me = w.speechQueue ? w.speechQueue.filter((ne) => ne && ne.text && Array.isArray(ne.text) && ne.text.length > 0).length : 0, A = w.audioPlaylist && w.audioPlaylist.length > 0, T = me + (A ? 1 : 0), K = te - T;
6975
- if (T > 0 && K < te && (_ = z.current.slice(K).join(". ").trim(), !_ && me > 0 && w.speechQueue)) {
6972
+ let K = "";
6973
+ if (T.current && z.current.length > 0) {
6974
+ const ne = z.current.length, me = w.speechQueue ? w.speechQueue.filter((J) => J && J.text && Array.isArray(J.text) && J.text.length > 0).length : 0, A = w.audioPlaylist && w.audioPlaylist.length > 0, H = me + (A ? 1 : 0), G = ne - H;
6975
+ if (H > 0 && G < ne && (K = z.current.slice(G).join(". ").trim(), !K && me > 0 && w.speechQueue)) {
6976
6976
  const ie = w.speechQueue.filter((se) => se && se.text && Array.isArray(se.text) && se.text.length > 0).map((se) => se.text.map((we) => we.word || "").filter((we) => we.length > 0).join(" ")).filter((se) => se.length > 0).join(" ");
6977
- ie && ie.trim() && (_ = ie.trim());
6977
+ ie && ie.trim() && (K = ie.trim());
6978
6978
  }
6979
6979
  }
6980
- H.current && (I.current = {
6981
- remainingText: _ || null,
6982
- originalText: H.current.text,
6983
- options: H.current.options
6980
+ T.current && (I.current = {
6981
+ remainingText: K || null,
6982
+ originalText: T.current.text,
6983
+ options: T.current.options
6984
6984
  }), w.speechQueue && (w.speechQueue.length = 0), p.current.pauseSpeaking(), L.current = !0, de(!0);
6985
6985
  }
6986
6986
  }
6987
- }, []), q = O(async () => {
6987
+ }, []), _ = O(async () => {
6988
6988
  if (!p.current || !ge)
6989
6989
  return;
6990
6990
  let w = "", U = {};
6991
6991
  if (I.current && I.current.remainingText)
6992
6992
  w = I.current.remainingText, U = I.current.options || {}, I.current = { remainingText: null, originalText: null, options: null };
6993
- else if (H.current && H.current.text)
6994
- w = H.current.text, U = H.current.options || {};
6993
+ else if (T.current && T.current.text)
6994
+ w = T.current.text, U = T.current.options || {};
6995
6995
  else {
6996
6996
  console.warn("Resume called but no paused speech found"), de(!1), L.current = !1;
6997
6997
  return;
6998
6998
  }
6999
6999
  de(!1), L.current = !1, await P();
7000
- const _ = {
7000
+ const K = {
7001
7001
  ...U,
7002
7002
  lipsyncLang: U.lipsyncLang || b.lipsyncLang || "en"
7003
7003
  };
7004
7004
  try {
7005
- await D(w, _);
7006
- } catch (te) {
7007
- console.error("Error resuming speech:", te), de(!1), L.current = !1;
7005
+ await N(w, K);
7006
+ } catch (ne) {
7007
+ console.error("Error resuming speech:", ne), de(!1), L.current = !1;
7008
7008
  }
7009
- }, [P, ge, D, b]), Ae = O((w) => {
7009
+ }, [P, ge, N, b]), Ae = O((w) => {
7010
7010
  p.current && p.current.setMood(w);
7011
7011
  }, []), Se = O((w) => {
7012
7012
  p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(w);
@@ -7015,14 +7015,14 @@ const Ve = Me(({
7015
7015
  if (f && f[w] && (w = f[w]), p.current.setShowFullAvatar)
7016
7016
  try {
7017
7017
  p.current.setShowFullAvatar(B.current);
7018
- } catch (te) {
7019
- console.warn("Error setting full body mode:", te);
7018
+ } catch (ne) {
7019
+ console.warn("Error setting full body mode:", ne);
7020
7020
  }
7021
7021
  if (w.includes("."))
7022
7022
  try {
7023
7023
  p.current.playAnimation(w, null, 10, 0, 0.01, U);
7024
- } catch (te) {
7025
- console.warn(`Failed to play ${w}:`, te);
7024
+ } catch (ne) {
7025
+ console.warn(`Failed to play ${w}:`, ne);
7026
7026
  try {
7027
7027
  p.current.setBodyMovement("idle");
7028
7028
  } catch (me) {
@@ -7030,9 +7030,9 @@ const Ve = Me(({
7030
7030
  }
7031
7031
  }
7032
7032
  else {
7033
- const te = [".fbx", ".glb", ".gltf"];
7033
+ const ne = [".fbx", ".glb", ".gltf"];
7034
7034
  let me = !1;
7035
- for (const A of te)
7035
+ for (const A of ne)
7036
7036
  try {
7037
7037
  p.current.playAnimation(w + A, null, 10, 0, 0.01, U), me = !0;
7038
7038
  break;
@@ -7052,10 +7052,10 @@ const Ve = Me(({
7052
7052
  p.current && p.current.onResize && p.current.onResize();
7053
7053
  }, []);
7054
7054
  return Fe(k, () => ({
7055
- speakText: D,
7056
- stopSpeaking: ee,
7057
- pauseSpeaking: Q,
7058
- resumeSpeaking: q,
7055
+ speakText: N,
7056
+ stopSpeaking: te,
7057
+ pauseSpeaking: q,
7058
+ resumeSpeaking: _,
7059
7059
  resumeAudioContext: P,
7060
7060
  setMood: Ae,
7061
7061
  setTimingAdjustment: Se,
@@ -7135,7 +7135,7 @@ const Ve = Me(({
7135
7135
  /* @__PURE__ */ ye(
7136
7136
  "div",
7137
7137
  {
7138
- ref: N,
7138
+ ref: D,
7139
7139
  className: "talking-head-viewer",
7140
7140
  style: {
7141
7141
  width: "100%",
@@ -7153,7 +7153,7 @@ const Ve = Me(({
7153
7153
  fontSize: "18px",
7154
7154
  zIndex: 10
7155
7155
  }, children: "Loading avatar..." }),
7156
- X && /* @__PURE__ */ ye("div", { className: "error-overlay", style: {
7156
+ j && /* @__PURE__ */ ye("div", { className: "error-overlay", style: {
7157
7157
  position: "absolute",
7158
7158
  top: "50%",
7159
7159
  left: "50%",
@@ -7164,7 +7164,7 @@ const Ve = Me(({
7164
7164
  zIndex: 10,
7165
7165
  padding: "20px",
7166
7166
  borderRadius: "8px"
7167
- }, children: X })
7167
+ }, children: j })
7168
7168
  ]
7169
7169
  }
7170
7170
  );
@@ -7182,7 +7182,7 @@ const pt = Me(({
7182
7182
  style: s = {},
7183
7183
  avatarConfig: o = {}
7184
7184
  }, l) => {
7185
- const h = W(null), r = W(null), [u, a] = pe(!0), [d, c] = pe(null), [g, x] = pe(!1), f = Ee(), k = o.ttsService || f.service, N = k === "browser" ? {
7185
+ const h = W(null), r = W(null), [u, a] = pe(!0), [d, c] = pe(null), [g, x] = pe(!1), f = Ee(), k = o.ttsService || f.service, D = k === "browser" ? {
7186
7186
  endpoint: "",
7187
7187
  apiKey: null,
7188
7188
  defaultVoice: "Google US English"
@@ -7198,7 +7198,7 @@ const pt = Me(({
7198
7198
  body: "F",
7199
7199
  avatarMood: "neutral",
7200
7200
  ttsLang: k === "browser" ? "en-US" : "en",
7201
- ttsVoice: o.ttsVoice || N.defaultVoice,
7201
+ ttsVoice: o.ttsVoice || D.defaultVoice,
7202
7202
  lipsyncLang: "en",
7203
7203
  // English lip-sync
7204
7204
  showFullAvatar: !0,
@@ -7207,35 +7207,35 @@ const pt = Me(({
7207
7207
  movementIntensity: 0.5,
7208
7208
  ...o
7209
7209
  }, B = {
7210
- ttsEndpoint: N.endpoint,
7211
- ttsApikey: N.apiKey,
7210
+ ttsEndpoint: D.endpoint,
7211
+ ttsApikey: D.apiKey,
7212
7212
  ttsService: k,
7213
7213
  lipsyncModules: ["en"],
7214
7214
  cameraView: "upper"
7215
- }, H = O(async () => {
7215
+ }, T = O(async () => {
7216
7216
  if (!(!h.current || r.current))
7217
7217
  try {
7218
- if (a(!0), c(null), r.current = new Be(h.current, B), await r.current.showAvatar(p, (X) => {
7219
- if (X.lengthComputable) {
7220
- const Z = Math.min(100, Math.round(X.loaded / X.total * 100));
7221
- t(Z);
7218
+ if (a(!0), c(null), r.current = new Be(h.current, B), await r.current.showAvatar(p, (j) => {
7219
+ if (j.lengthComputable) {
7220
+ const X = Math.min(100, Math.round(j.loaded / j.total * 100));
7221
+ t(X);
7222
7222
  }
7223
7223
  }), r.current.morphs && r.current.morphs.length > 0) {
7224
- const X = r.current.morphs[0].morphTargetDictionary;
7225
- console.log("Available morph targets:", Object.keys(X));
7226
- const Z = Object.keys(X).filter((oe) => oe.startsWith("viseme_"));
7227
- console.log("Viseme morph targets found:", Z), Z.length === 0 && (console.warn("No viseme morph targets found! Lip-sync will not work properly."), console.log("Expected viseme targets: viseme_aa, viseme_E, viseme_I, viseme_O, viseme_U, viseme_PP, viseme_SS, viseme_TH, viseme_DD, viseme_FF, viseme_kk, viseme_nn, viseme_RR, viseme_CH, viseme_sil"));
7224
+ const j = r.current.morphs[0].morphTargetDictionary;
7225
+ console.log("Available morph targets:", Object.keys(j));
7226
+ const X = Object.keys(j).filter((oe) => oe.startsWith("viseme_"));
7227
+ console.log("Viseme morph targets found:", X), X.length === 0 && (console.warn("No viseme morph targets found! Lip-sync will not work properly."), console.log("Expected viseme targets: viseme_aa, viseme_E, viseme_I, viseme_O, viseme_U, viseme_PP, viseme_SS, viseme_TH, viseme_DD, viseme_FF, viseme_kk, viseme_nn, viseme_RR, viseme_CH, viseme_sil"));
7228
7228
  }
7229
- if (await new Promise((X) => {
7230
- const Z = () => {
7231
- r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), X()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(Z, 100));
7229
+ if (await new Promise((j) => {
7230
+ const X = () => {
7231
+ r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), j()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(X, 100));
7232
7232
  };
7233
- Z();
7233
+ X();
7234
7234
  }), r.current && r.current.setShowFullAvatar)
7235
7235
  try {
7236
7236
  r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
7237
- } catch (X) {
7238
- console.warn("Error setting full body mode on initialization:", X);
7237
+ } catch (j) {
7238
+ console.warn("Error setting full body mode on initialization:", j);
7239
7239
  }
7240
7240
  a(!1), x(!0), n(r.current);
7241
7241
  const E = () => {
@@ -7248,9 +7248,9 @@ const pt = Me(({
7248
7248
  console.error("Error initializing TalkingHead:", S), c(S.message || "Failed to initialize avatar"), a(!1), e(S);
7249
7249
  }
7250
7250
  }, []);
7251
- ce(() => (H(), () => {
7251
+ ce(() => (T(), () => {
7252
7252
  r.current && (r.current.stop(), r.current.dispose(), r.current = null);
7253
- }), [H]);
7253
+ }), [T]);
7254
7254
  const R = O((S) => {
7255
7255
  if (r.current && g)
7256
7256
  try {
@@ -7273,14 +7273,14 @@ const pt = Me(({
7273
7273
  if (r.current.setShowFullAvatar)
7274
7274
  try {
7275
7275
  r.current.setShowFullAvatar(!0);
7276
- } catch (Z) {
7277
- console.warn("Error setting full body mode:", Z);
7276
+ } catch (X) {
7277
+ console.warn("Error setting full body mode:", X);
7278
7278
  }
7279
7279
  if (S.includes("."))
7280
7280
  try {
7281
7281
  r.current.playAnimation(S, null, 10, 0, 0.01, E), console.log("Playing animation:", S);
7282
- } catch (Z) {
7283
- console.log(`Failed to play ${S}:`, Z);
7282
+ } catch (X) {
7283
+ console.log(`Failed to play ${S}:`, X);
7284
7284
  try {
7285
7285
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7286
7286
  } catch (oe) {
@@ -7288,9 +7288,9 @@ const pt = Me(({
7288
7288
  }
7289
7289
  }
7290
7290
  else {
7291
- const Z = [".fbx", ".glb", ".gltf"];
7291
+ const X = [".fbx", ".glb", ".gltf"];
7292
7292
  let oe = !1;
7293
- for (const le of Z)
7293
+ for (const le of X)
7294
7294
  try {
7295
7295
  r.current.playAnimation(S + le, null, 10, 0, 0.01, E), console.log("Playing animation:", S + le), oe = !0;
7296
7296
  break;
@@ -7413,9 +7413,20 @@ const pt = Me(({
7413
7413
  pt.displayName = "TalkingHeadComponent";
7414
7414
  async function gt(V) {
7415
7415
  try {
7416
- return (await (await fetch(V)).json()).animations || {};
7416
+ console.log(`📥 Loading animation manifest from: ${V}`);
7417
+ const t = await fetch(V);
7418
+ if (!t.ok)
7419
+ throw new Error(`Failed to fetch manifest: ${t.status} ${t.statusText}`);
7420
+ const e = await t.json();
7421
+ console.log("📦 Raw manifest loaded:", e);
7422
+ const n = e.animations || {};
7423
+ return console.log("✅ Processed animations object:", n), n._genderSpecific && console.log("👥 Gender-specific structure detected:", {
7424
+ male: Object.keys(n._genderSpecific.male || {}),
7425
+ female: Object.keys(n._genderSpecific.female || {}),
7426
+ shared: Object.keys(n._genderSpecific.shared || {})
7427
+ }), n;
7417
7428
  } catch (t) {
7418
- return console.error("Failed to load animation manifest:", t), {};
7429
+ return console.error("Failed to load animation manifest:", t), {};
7419
7430
  }
7420
7431
  }
7421
7432
  const yt = Me(({
@@ -7441,84 +7452,86 @@ const yt = Me(({
7441
7452
  },
7442
7453
  className: f = "",
7443
7454
  style: k = {},
7444
- animations: N = {},
7455
+ animations: D = {},
7445
7456
  autoAnimationGroup: p = null,
7446
7457
  // e.g., "talking" - will randomly select from this group when speaking
7447
7458
  autoIdleGroup: B = null,
7448
7459
  // e.g., "idle" - will randomly select from this group when idle
7449
- autoSpeak: H = !1
7460
+ autoSpeak: T = !1
7450
7461
  }, R) => {
7451
- const L = W(null), I = W(null), z = W(u), Y = W(null), S = W(null), E = W(!1), X = W({ remainingText: null, originalText: null, options: null }), Z = W([]), [oe, le] = pe(!0), [ge, de] = pe(null), [$, be] = pe(!1), [j, b] = pe(!1), [v, F] = pe(N), P = W(null);
7462
+ const L = W(null), I = W(null), z = W(u), Y = W(null), S = W(null), E = W(!1), j = W({ remainingText: null, originalText: null, options: null }), X = W([]), [oe, le] = pe(!0), [ge, de] = pe(null), [ee, be] = pe(!1), [Q, b] = pe(!1), [v, F] = pe(D), P = W(null);
7452
7463
  ce(() => {
7453
- E.current = j;
7454
- }, [j]), ce(() => {
7464
+ E.current = Q;
7465
+ }, [Q]), ce(() => {
7455
7466
  (async () => {
7456
- if (N.manifest)
7467
+ if (D.manifest)
7457
7468
  try {
7458
- const T = await gt(N.manifest);
7459
- F(T), console.log("Loaded animations from manifest:", T), T._genderSpecific && console.log("Gender-specific animations detected:", {
7460
- male: Object.keys(T._genderSpecific.male || {}),
7461
- female: Object.keys(T._genderSpecific.female || {})
7462
- });
7463
- } catch (T) {
7464
- console.error("Failed to load animation manifest:", T), F(N);
7469
+ console.log("🔄 Loading animations from manifest:", D.manifest);
7470
+ const H = await gt(D.manifest);
7471
+ F(H), console.log("✅ Animations loaded and set:", H), H._genderSpecific ? console.log("👥 Gender-specific animations detected:", {
7472
+ male: Object.keys(H._genderSpecific.male || {}),
7473
+ female: Object.keys(H._genderSpecific.female || {}),
7474
+ shared: Object.keys(H._genderSpecific.shared || {})
7475
+ }) : console.log("⚠️ No gender-specific animations found in manifest");
7476
+ } catch (H) {
7477
+ console.error("❌ Failed to load animation manifest:", H), F(D);
7465
7478
  }
7466
7479
  else
7467
- F(N);
7480
+ console.log("📝 Using animations from props (no manifest):", D), F(D);
7468
7481
  })();
7469
- }, [N]), ce(() => {
7482
+ }, [D]), ce(() => {
7470
7483
  z.current = u;
7471
7484
  }, [u]);
7472
- const D = Ee(), ee = s || D.service;
7473
- let Q;
7474
- ee === "browser" ? Q = {
7485
+ const N = Ee(), te = s || N.service;
7486
+ let q;
7487
+ te === "browser" ? q = {
7475
7488
  service: "browser",
7476
7489
  endpoint: "",
7477
7490
  apiKey: null,
7478
7491
  defaultVoice: "Google US English"
7479
- } : ee === "elevenlabs" ? Q = {
7492
+ } : te === "elevenlabs" ? q = {
7480
7493
  service: "elevenlabs",
7481
7494
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
7482
- apiKey: l || D.apiKey,
7483
- defaultVoice: o || D.defaultVoice || Ie.defaultVoice,
7484
- voices: D.voices || Ie.voices
7485
- } : ee === "deepgram" ? Q = {
7495
+ apiKey: l || N.apiKey,
7496
+ defaultVoice: o || N.defaultVoice || Ie.defaultVoice,
7497
+ voices: N.voices || Ie.voices
7498
+ } : te === "deepgram" ? q = {
7486
7499
  service: "deepgram",
7487
7500
  endpoint: "https://api.deepgram.com/v1/speak",
7488
- apiKey: l || D.apiKey,
7489
- defaultVoice: o || D.defaultVoice || Te.defaultVoice,
7490
- voices: D.voices || Te.voices
7491
- } : Q = {
7492
- ...D,
7493
- apiKey: l !== null ? l : D.apiKey
7501
+ apiKey: l || N.apiKey,
7502
+ defaultVoice: o || N.defaultVoice || Te.defaultVoice,
7503
+ voices: N.voices || Te.voices
7504
+ } : q = {
7505
+ ...N,
7506
+ apiKey: l !== null ? l : N.apiKey
7494
7507
  };
7495
- const q = {
7508
+ const _ = {
7496
7509
  url: t,
7497
7510
  body: e,
7498
7511
  avatarMood: n,
7499
- ttsLang: ee === "browser" ? "en-US" : i,
7500
- ttsVoice: o || Q.defaultVoice,
7512
+ ttsLang: te === "browser" ? "en-US" : i,
7513
+ ttsVoice: o || q.defaultVoice,
7501
7514
  lipsyncLang: "en",
7502
7515
  showFullAvatar: u,
7503
7516
  bodyMovement: h,
7504
7517
  movementIntensity: r
7505
7518
  }, Ae = {
7506
- ttsEndpoint: Q.endpoint,
7507
- ttsApikey: Q.apiKey,
7508
- ttsService: ee,
7519
+ ttsEndpoint: q.endpoint,
7520
+ ttsApikey: q.apiKey,
7521
+ ttsService: te,
7509
7522
  lipsyncModules: ["en"],
7510
7523
  cameraView: a
7511
7524
  }, Se = O(async () => {
7512
7525
  if (!(!L.current || I.current))
7513
7526
  try {
7514
7527
  le(!0), de(null), I.current = new Be(L.current, Ae), console.log("Avatar config being passed:", {
7515
- url: q.url,
7516
- body: q.body,
7517
- avatarMood: q.avatarMood
7518
- }), await I.current.showAvatar(q, (T) => {
7519
- if (T.lengthComputable) {
7520
- const K = Math.min(100, Math.round(T.loaded / T.total * 100));
7521
- c(K);
7528
+ url: _.url,
7529
+ body: _.body,
7530
+ avatarMood: _.avatarMood
7531
+ }), await I.current.showAvatar(_, (H) => {
7532
+ if (H.lengthComputable) {
7533
+ const G = Math.min(100, Math.round(H.loaded / H.total * 100));
7534
+ c(G);
7522
7535
  }
7523
7536
  }), I.current?.avatar && console.log("Avatar body after initialization:", I.current.avatar.body), le(!1), be(!0), d(I.current);
7524
7537
  const A = () => {
@@ -7543,29 +7556,40 @@ const yt = Me(({
7543
7556
  console.warn("Failed to resume audio context:", A);
7544
7557
  }
7545
7558
  }, []), ke = O((A) => {
7546
- if (!v || !v[A])
7547
- return null;
7548
- let T = v[A];
7559
+ if (!v)
7560
+ return console.warn("No animations loaded"), null;
7561
+ let H = null;
7549
7562
  if (v._genderSpecific) {
7550
- const ne = (e?.toUpperCase() || "F") === "M" ? "male" : "female", ie = v._genderSpecific[ne];
7551
- ie && ie[A] ? (T = ie[A], console.log(`Using ${ne} animations for "${A}"`)) : v._genderSpecific.shared && v._genderSpecific.shared[A] && (T = v._genderSpecific.shared[A], console.log(`Using shared animations for "${A}"`));
7563
+ const J = (e?.toUpperCase() || "F") === "M" ? "male" : "female", ie = v._genderSpecific[J];
7564
+ ie && ie[A] ? (H = ie[A], console.log(`Using ${J} animations for "${A}":`, H)) : v._genderSpecific.shared && v._genderSpecific.shared[A] && (H = v._genderSpecific.shared[A], console.log(`Using shared animations for "${A}":`, H));
7552
7565
  }
7553
- if (Array.isArray(T) && T.length > 0) {
7554
- const K = Math.floor(Math.random() * T.length);
7555
- return T[K];
7566
+ if (!H && v[A] && (H = v[A], console.log(`Using root-level animations for "${A}":`, H)), !H) {
7567
+ if (console.warn(`Animation group "${A}" not found. Available groups:`, Object.keys(v).filter((G) => G !== "_genderSpecific")), v._genderSpecific) {
7568
+ const J = (e?.toUpperCase() || "F") === "M" ? "male" : "female";
7569
+ console.warn(`Gender-specific groups (${J}):`, Object.keys(v._genderSpecific[J] || {}));
7570
+ }
7571
+ return null;
7556
7572
  }
7557
- return typeof T == "string" ? T : null;
7558
- }, [v, e]), w = O((A, T = !1) => {
7559
- const K = ke(A);
7560
- if (K && I.current)
7573
+ if (Array.isArray(H) && H.length > 0) {
7574
+ const G = Math.floor(Math.random() * H.length);
7575
+ return H[G];
7576
+ }
7577
+ return typeof H == "string" ? H : (console.warn(`Animation group "${A}" is not a valid format (expected array or string):`, H), null);
7578
+ }, [v, e]), w = O((A, H = !1) => {
7579
+ if (!I.current)
7580
+ return console.warn("TalkingHead not initialized yet"), null;
7581
+ const G = ke(A);
7582
+ if (G)
7561
7583
  try {
7562
- return I.current.playAnimation(K, null, 10, 0, 0.01, T), console.log(`Playing random animation from "${A}" group:`, K), K;
7563
- } catch (ne) {
7564
- return console.warn(`Failed to play random animation from "${A}" group:`, ne), null;
7584
+ return I.current.playAnimation(G, null, 10, 0, 0.01, H), console.log(`✅ Playing random animation from "${A}" group:`, G), G;
7585
+ } catch (J) {
7586
+ return console.error(`❌ Failed to play random animation from "${A}" group:`, J), null;
7565
7587
  }
7588
+ else
7589
+ console.warn(`⚠️ No animation found for group "${A}"`);
7566
7590
  return null;
7567
- }, [ke]), U = O(async (A, T = {}) => {
7568
- if (!I.current || !$) {
7591
+ }, [ke]), U = O(async (A, H = {}) => {
7592
+ if (!I.current || !ee) {
7569
7593
  console.warn("Avatar not ready for speaking");
7570
7594
  return;
7571
7595
  }
@@ -7574,14 +7598,14 @@ const yt = Me(({
7574
7598
  return;
7575
7599
  }
7576
7600
  await Le();
7577
- const K = T.animationGroup || p;
7578
- K && !T.skipAnimation && w(K), X.current = { remainingText: null, originalText: null, options: null }, Z.current = [], Y.current = { text: A, options: T }, S.current && (clearInterval(S.current), S.current = null), b(!1), E.current = !1;
7579
- const ne = A.split(/[.!?]+/).filter((se) => se.trim().length > 0);
7580
- Z.current = ne;
7601
+ const G = H.animationGroup || p;
7602
+ G && !H.skipAnimation ? (console.log(`🎬 Attempting to play animation from group: "${G}"`), console.log(`📊 Current avatarBody: "${e}", loadedAnimations:`, v), w(G)) : console.log(`⏭️ Skipping animation (group: ${G}, skipAnimation: ${H.skipAnimation})`), j.current = { remainingText: null, originalText: null, options: null }, X.current = [], Y.current = { text: A, options: H }, S.current && (clearInterval(S.current), S.current = null), b(!1), E.current = !1;
7603
+ const J = A.split(/[.!?]+/).filter((se) => se.trim().length > 0);
7604
+ X.current = J;
7581
7605
  const ie = {
7582
- lipsyncLang: T.lipsyncLang || "en",
7606
+ lipsyncLang: H.lipsyncLang || "en",
7583
7607
  onSpeechEnd: () => {
7584
- S.current && (clearInterval(S.current), S.current = null), T.onSpeechEnd && T.onSpeechEnd(), x();
7608
+ S.current && (clearInterval(S.current), S.current = null), H.onSpeechEnd && H.onSpeechEnd(), x();
7585
7609
  }
7586
7610
  };
7587
7611
  try {
@@ -7589,9 +7613,9 @@ const yt = Me(({
7589
7613
  } catch (se) {
7590
7614
  console.error("Error speaking text:", se), de(se.message || "Failed to speak text");
7591
7615
  }
7592
- }, [$, x, Le, p, w]);
7616
+ }, [ee, x, Le, p, w]);
7593
7617
  ce(() => {
7594
- if (!$ || !B || !I.current)
7618
+ if (!ee || !B || !I.current)
7595
7619
  return;
7596
7620
  P.current && clearInterval(P.current);
7597
7621
  const A = () => {
@@ -7602,18 +7626,18 @@ const yt = Me(({
7602
7626
  }, 12e3 + Math.random() * 3e3), () => {
7603
7627
  P.current && (clearInterval(P.current), P.current = null);
7604
7628
  };
7605
- }, [$, B, w]), ce(() => {
7606
- $ && V && H && I.current && U(V);
7607
- }, [$, V, H, U]);
7608
- const _ = O(() => {
7629
+ }, [ee, B, w]), ce(() => {
7630
+ ee && V && T && I.current && U(V);
7631
+ }, [ee, V, T, U]);
7632
+ const K = O(() => {
7609
7633
  if (I.current)
7610
7634
  try {
7611
- const A = I.current.isSpeaking || !1, T = I.current.audioPlaylist || [], K = I.current.speechQueue || [];
7612
- if (A || T.length > 0 || K.length > 0) {
7635
+ const A = I.current.isSpeaking || !1, H = I.current.audioPlaylist || [], G = I.current.speechQueue || [];
7636
+ if (A || H.length > 0 || G.length > 0) {
7613
7637
  S.current && (clearInterval(S.current), S.current = null);
7614
- let ne = "";
7615
- K.length > 0 && (ne = K.map((ie) => ie.text && Array.isArray(ie.text) ? ie.text.map((se) => se.word).join(" ") : ie.text || "").join(" ")), X.current = {
7616
- remainingText: ne || null,
7638
+ let J = "";
7639
+ G.length > 0 && (J = G.map((ie) => ie.text && Array.isArray(ie.text) ? ie.text.map((se) => se.word).join(" ") : ie.text || "").join(" ")), j.current = {
7640
+ remainingText: J || null,
7617
7641
  originalText: Y.current?.text || null,
7618
7642
  options: Y.current?.options || null
7619
7643
  }, I.current.speechQueue.length = 0, I.current.pauseSpeaking(), b(!0), E.current = !0;
@@ -7621,40 +7645,40 @@ const yt = Me(({
7621
7645
  } catch (A) {
7622
7646
  console.warn("Error pausing speech:", A);
7623
7647
  }
7624
- }, []), te = O(async () => {
7625
- if (!(!I.current || !j))
7648
+ }, []), ne = O(async () => {
7649
+ if (!(!I.current || !Q))
7626
7650
  try {
7627
7651
  await Le(), b(!1), E.current = !1;
7628
- const A = X.current?.remainingText, T = X.current?.originalText || Y.current?.text, K = X.current?.options || Y.current?.options || {}, ne = A || T;
7629
- ne && U(ne, K);
7652
+ const A = j.current?.remainingText, H = j.current?.originalText || Y.current?.text, G = j.current?.options || Y.current?.options || {}, J = A || H;
7653
+ J && U(J, G);
7630
7654
  } catch (A) {
7631
7655
  console.warn("Error resuming speech:", A), b(!1), E.current = !1;
7632
7656
  }
7633
- }, [j, U, Le]), me = O(() => {
7657
+ }, [Q, U, Le]), me = O(() => {
7634
7658
  I.current && (I.current.stopSpeaking(), S.current && (clearInterval(S.current), S.current = null), b(!1), E.current = !1);
7635
7659
  }, []);
7636
7660
  return Fe(R, () => ({
7637
7661
  speakText: U,
7638
- pauseSpeaking: _,
7639
- resumeSpeaking: te,
7662
+ pauseSpeaking: K,
7663
+ resumeSpeaking: ne,
7640
7664
  stopSpeaking: me,
7641
7665
  resumeAudioContext: Le,
7642
- isPaused: () => j,
7666
+ isPaused: () => Q,
7643
7667
  setMood: (A) => I.current?.setMood(A),
7644
7668
  setBodyMovement: (A) => {
7645
7669
  I.current && I.current.setBodyMovement(A);
7646
7670
  },
7647
- playAnimation: (A, T = !1) => {
7648
- I.current && I.current.playAnimation && I.current.playAnimation(A, null, 10, 0, 0.01, T);
7671
+ playAnimation: (A, H = !1) => {
7672
+ I.current && I.current.playAnimation && I.current.playAnimation(A, null, 10, 0, 0.01, H);
7649
7673
  },
7650
- playRandomAnimation: (A, T = !1) => w(A, T),
7674
+ playRandomAnimation: (A, H = !1) => w(A, H),
7651
7675
  getRandomAnimation: (A) => ke(A),
7652
7676
  playReaction: (A) => I.current?.playReaction(A),
7653
7677
  playCelebration: () => I.current?.playCelebration(),
7654
7678
  setShowFullAvatar: (A) => {
7655
7679
  I.current && (z.current = A, I.current.setShowFullAvatar(A));
7656
7680
  },
7657
- isReady: $,
7681
+ isReady: ee,
7658
7682
  talkingHead: I.current
7659
7683
  })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${f}`, style: k, children: [
7660
7684
  /* @__PURE__ */ ye(
@@ -7725,12 +7749,12 @@ const ft = Me(({
7725
7749
  onQuestionAnswer: s,
7726
7750
  onCurriculumComplete: o,
7727
7751
  onCustomAction: l
7728
- }), c = W(null), g = W(null), x = W(null), f = W(null), k = W(null), N = W(null), p = W(null), B = W(V?.curriculum || {
7752
+ }), c = W(null), g = W(null), x = W(null), f = W(null), k = W(null), D = W(null), p = W(null), B = W(V?.curriculum || {
7729
7753
  title: "Default Curriculum",
7730
7754
  description: "No curriculum data provided",
7731
7755
  language: "en",
7732
7756
  modules: []
7733
- }), H = W({
7757
+ }), T = W({
7734
7758
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7735
7759
  avatarBody: t.avatarBody || "F",
7736
7760
  mood: t.mood || "happy",
@@ -7758,7 +7782,7 @@ const ft = Me(({
7758
7782
  description: "No curriculum data provided",
7759
7783
  language: "en",
7760
7784
  modules: []
7761
- }, H.current = {
7785
+ }, T.current = {
7762
7786
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7763
7787
  avatarBody: t.avatarBody || "F",
7764
7788
  mood: t.mood || "happy",
@@ -7797,9 +7821,9 @@ const ft = Me(({
7797
7821
  } catch {
7798
7822
  u.current.playCelebration();
7799
7823
  }
7800
- const F = B.current || { modules: [] }, P = F.modules[a.current.currentModuleIndex], D = a.current.currentLessonIndex < (P?.lessons?.length || 0) - 1, ee = a.current.currentModuleIndex < (F.modules?.length || 0) - 1, Q = D || ee, q = H.current || { lipsyncLang: "en" };
7824
+ const F = B.current || { modules: [] }, P = F.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (P?.lessons?.length || 0) - 1, te = a.current.currentModuleIndex < (F.modules?.length || 0) - 1, q = N || te, _ = T.current || { lipsyncLang: "en" };
7801
7825
  u.current.speakText(v, {
7802
- lipsyncLang: q.lipsyncLang,
7826
+ lipsyncLang: _.lipsyncLang,
7803
7827
  onSpeechEnd: () => {
7804
7828
  d.current.onCustomAction({
7805
7829
  type: "lessonCompleteFeedbackDone",
@@ -7808,7 +7832,7 @@ const ft = Me(({
7808
7832
  score: a.current.score,
7809
7833
  totalQuestions: a.current.totalQuestions,
7810
7834
  percentage: b,
7811
- hasNextLesson: Q
7835
+ hasNextLesson: q
7812
7836
  });
7813
7837
  }
7814
7838
  });
@@ -7826,7 +7850,7 @@ const ft = Me(({
7826
7850
  } catch {
7827
7851
  u.current.playCelebration();
7828
7852
  }
7829
- const v = H.current || { lipsyncLang: "en" };
7853
+ const v = T.current || { lipsyncLang: "en" };
7830
7854
  u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: v.lipsyncLang });
7831
7855
  }
7832
7856
  }, [e.curriculumComplete]), S = O(() => {
@@ -7847,16 +7871,16 @@ const ft = Me(({
7847
7871
  if (u.current.setMood("happy"), e.questionStart)
7848
7872
  try {
7849
7873
  u.current.playAnimation(e.questionStart, !0);
7850
- } catch (D) {
7851
- console.warn("Failed to play questionStart animation:", D);
7874
+ } catch (N) {
7875
+ console.warn("Failed to play questionStart animation:", N);
7852
7876
  }
7853
- const P = H.current || { lipsyncLang: "en" };
7877
+ const P = T.current || { lipsyncLang: "en" };
7854
7878
  v.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${v.question}`, { lipsyncLang: P.lipsyncLang }) : v.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: P.lipsyncLang }) : v.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${v.question}`, { lipsyncLang: P.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: P.lipsyncLang });
7855
7879
  };
7856
7880
  if (u.current && u.current.isReady && v)
7857
7881
  F();
7858
7882
  else if (u.current && u.current.isReady) {
7859
- const P = H.current || { lipsyncLang: "en" };
7883
+ const P = T.current || { lipsyncLang: "en" };
7860
7884
  u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: P.lipsyncLang });
7861
7885
  } else {
7862
7886
  const P = setInterval(() => {
@@ -7885,28 +7909,28 @@ const ft = Me(({
7885
7909
  if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
7886
7910
  try {
7887
7911
  u.current.playAnimation(e.nextQuestion, !0);
7888
- } catch (q) {
7889
- console.warn("Failed to play nextQuestion animation:", q);
7912
+ } catch (_) {
7913
+ console.warn("Failed to play nextQuestion animation:", _);
7890
7914
  }
7891
- const P = H.current || { lipsyncLang: "en" }, ee = R()?.questions?.length || 0, Q = a.current.currentQuestionIndex >= ee - 1;
7915
+ const P = T.current || { lipsyncLang: "en" }, te = R()?.questions?.length || 0, q = a.current.currentQuestionIndex >= te - 1;
7892
7916
  if (v.type === "code_test") {
7893
- const q = Q ? `Great! Here's your final coding challenge: ${v.question}` : `Great! Now let's move on to your next coding challenge: ${v.question}`;
7894
- u.current.speakText(q, {
7917
+ const _ = q ? `Great! Here's your final coding challenge: ${v.question}` : `Great! Now let's move on to your next coding challenge: ${v.question}`;
7918
+ u.current.speakText(_, {
7895
7919
  lipsyncLang: P.lipsyncLang
7896
7920
  });
7897
7921
  } else if (v.type === "multiple_choice") {
7898
- const q = Q ? `Alright! Here's your final question: ${v.question}` : `Alright! Here's your next question: ${v.question}`;
7899
- u.current.speakText(q, {
7922
+ const _ = q ? `Alright! Here's your final question: ${v.question}` : `Alright! Here's your next question: ${v.question}`;
7923
+ u.current.speakText(_, {
7900
7924
  lipsyncLang: P.lipsyncLang
7901
7925
  });
7902
7926
  } else if (v.type === "true_false") {
7903
- const q = Q ? `Now let's try this final one: ${v.question}` : `Now let's try this one: ${v.question}`;
7904
- u.current.speakText(q, {
7927
+ const _ = q ? `Now let's try this final one: ${v.question}` : `Now let's try this one: ${v.question}`;
7928
+ u.current.speakText(_, {
7905
7929
  lipsyncLang: P.lipsyncLang
7906
7930
  });
7907
7931
  } else {
7908
- const q = Q ? `Here's your final question: ${v.question}` : `Here's the next question: ${v.question}`;
7909
- u.current.speakText(q, {
7932
+ const _ = q ? `Here's your final question: ${v.question}` : `Here's the next question: ${v.question}`;
7933
+ u.current.speakText(_, {
7910
7934
  lipsyncLang: P.lipsyncLang
7911
7935
  });
7912
7936
  }
@@ -7929,16 +7953,16 @@ const ft = Me(({
7929
7953
  totalQuestions: a.current.totalQuestions,
7930
7954
  score: a.current.score
7931
7955
  });
7932
- }, [e.nextQuestion, R, L]), X = O(() => {
7956
+ }, [e.nextQuestion, R, L]), j = O(() => {
7933
7957
  const b = B.current || { modules: [] }, v = b.modules[a.current.currentModuleIndex];
7934
7958
  if (a.current.currentLessonIndex < (v?.lessons?.length || 0) - 1) {
7935
7959
  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;
7936
- const P = b.modules[a.current.currentModuleIndex], D = a.current.currentLessonIndex < (P?.lessons?.length || 0) - 1, ee = a.current.currentModuleIndex < (b.modules?.length || 0) - 1, Q = D || ee;
7960
+ const P = b.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (P?.lessons?.length || 0) - 1, te = a.current.currentModuleIndex < (b.modules?.length || 0) - 1, q = N || te;
7937
7961
  d.current.onCustomAction({
7938
7962
  type: "lessonStart",
7939
7963
  moduleIndex: a.current.currentModuleIndex,
7940
7964
  lessonIndex: a.current.currentLessonIndex,
7941
- hasNextLesson: Q
7965
+ hasNextLesson: q
7942
7966
  }), d.current.onLessonStart({
7943
7967
  moduleIndex: a.current.currentModuleIndex,
7944
7968
  lessonIndex: a.current.currentLessonIndex,
@@ -7946,12 +7970,12 @@ const ft = Me(({
7946
7970
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7947
7971
  } else if (a.current.currentModuleIndex < (b.modules?.length || 0) - 1) {
7948
7972
  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;
7949
- const D = b.modules[a.current.currentModuleIndex], ee = a.current.currentLessonIndex < (D?.lessons?.length || 0) - 1, Q = a.current.currentModuleIndex < (b.modules?.length || 0) - 1, q = ee || Q;
7973
+ const N = b.modules[a.current.currentModuleIndex], te = a.current.currentLessonIndex < (N?.lessons?.length || 0) - 1, q = a.current.currentModuleIndex < (b.modules?.length || 0) - 1, _ = te || q;
7950
7974
  d.current.onCustomAction({
7951
7975
  type: "lessonStart",
7952
7976
  moduleIndex: a.current.currentModuleIndex,
7953
7977
  lessonIndex: a.current.currentLessonIndex,
7954
- hasNextLesson: q
7978
+ hasNextLesson: _
7955
7979
  }), d.current.onLessonStart({
7956
7980
  moduleIndex: a.current.currentModuleIndex,
7957
7981
  lessonIndex: a.current.currentLessonIndex,
@@ -7959,12 +7983,12 @@ const ft = Me(({
7959
7983
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
7960
7984
  } else
7961
7985
  k.current && k.current();
7962
- }, []), Z = O(() => {
7986
+ }, []), X = O(() => {
7963
7987
  const b = R();
7964
7988
  let v = null;
7965
7989
  if (b?.avatar_script && b?.body) {
7966
- const F = b.avatar_script.trim(), P = b.body.trim(), D = F.match(/[.!?]$/) ? " " : ". ";
7967
- v = `${F}${D}${P}`;
7990
+ const F = b.avatar_script.trim(), P = b.body.trim(), N = F.match(/[.!?]$/) ? " " : ". ";
7991
+ v = `${F}${N}${P}`;
7968
7992
  } else
7969
7993
  v = b?.avatar_script || b?.body || null;
7970
7994
  if (u.current && u.current.isReady && v) {
@@ -7973,11 +7997,11 @@ const ft = Me(({
7973
7997
  if (e.teaching)
7974
7998
  try {
7975
7999
  u.current.playAnimation(e.teaching, !0), F = !0;
7976
- } catch (D) {
7977
- console.warn("Failed to play teaching animation:", D);
8000
+ } catch (N) {
8001
+ console.warn("Failed to play teaching animation:", N);
7978
8002
  }
7979
8003
  F || u.current.setBodyMovement("gesturing");
7980
- const P = H.current || { lipsyncLang: "en" };
8004
+ const P = T.current || { lipsyncLang: "en" };
7981
8005
  d.current.onLessonStart({
7982
8006
  moduleIndex: a.current.currentModuleIndex,
7983
8007
  lessonIndex: a.current.currentLessonIndex,
@@ -8024,13 +8048,13 @@ const ft = Me(({
8024
8048
  u.current.setBodyMovement("happy");
8025
8049
  }
8026
8050
  u.current.setBodyMovement("gesturing");
8027
- const D = R()?.questions?.length || 0;
8028
- a.current.currentQuestionIndex >= D - 1;
8029
- const ee = a.current.currentQuestionIndex < D - 1;
8030
- console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", D, "hasNextQuestion:", ee);
8031
- const Q = v.type === "code_test" ? `Great job! Your code passed all the tests! ${v.explanation || ""}` : `Excellent! That's correct! ${v.explanation || ""}`, q = H.current || { lipsyncLang: "en" };
8032
- u.current.speakText(Q, {
8033
- lipsyncLang: q.lipsyncLang,
8051
+ const N = R()?.questions?.length || 0;
8052
+ a.current.currentQuestionIndex >= N - 1;
8053
+ const te = a.current.currentQuestionIndex < N - 1;
8054
+ console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", te);
8055
+ const q = v.type === "code_test" ? `Great job! Your code passed all the tests! ${v.explanation || ""}` : `Excellent! That's correct! ${v.explanation || ""}`, _ = T.current || { lipsyncLang: "en" };
8056
+ u.current.speakText(q, {
8057
+ lipsyncLang: _.lipsyncLang,
8034
8058
  onSpeechEnd: () => {
8035
8059
  d.current.onCustomAction({
8036
8060
  type: "answerFeedbackComplete",
@@ -8038,7 +8062,7 @@ const ft = Me(({
8038
8062
  lessonIndex: a.current.currentLessonIndex,
8039
8063
  questionIndex: a.current.currentQuestionIndex,
8040
8064
  isCorrect: !0,
8041
- hasNextQuestion: ee,
8065
+ hasNextQuestion: te,
8042
8066
  score: a.current.score,
8043
8067
  totalQuestions: a.current.totalQuestions
8044
8068
  });
@@ -8052,10 +8076,10 @@ const ft = Me(({
8052
8076
  u.current.setBodyMovement("idle");
8053
8077
  }
8054
8078
  u.current.setBodyMovement("gesturing");
8055
- const D = R()?.questions?.length || 0, ee = a.current.currentQuestionIndex >= D - 1, Q = a.current.currentQuestionIndex < D - 1;
8056
- console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", D, "hasNextQuestion:", Q);
8057
- const q = v.type === "code_test" ? `Your code didn't pass all the tests. ${v.explanation || "Try again!"}` : `Not quite right, but don't worry! ${v.explanation || ""}${ee ? "" : " Let's move on to the next question."}`, Ae = H.current || { lipsyncLang: "en" };
8058
- u.current.speakText(q, {
8079
+ const N = R()?.questions?.length || 0, te = a.current.currentQuestionIndex >= N - 1, q = a.current.currentQuestionIndex < N - 1;
8080
+ console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", q);
8081
+ const _ = v.type === "code_test" ? `Your code didn't pass all the tests. ${v.explanation || "Try again!"}` : `Not quite right, but don't worry! ${v.explanation || ""}${te ? "" : " Let's move on to the next question."}`, Ae = T.current || { lipsyncLang: "en" };
8082
+ u.current.speakText(_, {
8059
8083
  lipsyncLang: Ae.lipsyncLang,
8060
8084
  onSpeechEnd: () => {
8061
8085
  d.current.onCustomAction({
@@ -8064,7 +8088,7 @@ const ft = Me(({
8064
8088
  lessonIndex: a.current.currentLessonIndex,
8065
8089
  questionIndex: a.current.currentQuestionIndex,
8066
8090
  isCorrect: !1,
8067
- hasNextQuestion: Q,
8091
+ hasNextQuestion: q,
8068
8092
  score: a.current.score,
8069
8093
  totalQuestions: a.current.totalQuestions
8070
8094
  });
@@ -8072,14 +8096,14 @@ const ft = Me(({
8072
8096
  });
8073
8097
  }
8074
8098
  else {
8075
- const D = R()?.questions?.length || 0;
8099
+ const N = R()?.questions?.length || 0;
8076
8100
  d.current.onCustomAction({
8077
8101
  type: "answerFeedbackComplete",
8078
8102
  moduleIndex: a.current.currentModuleIndex,
8079
8103
  lessonIndex: a.current.currentLessonIndex,
8080
8104
  questionIndex: a.current.currentQuestionIndex,
8081
8105
  isCorrect: F,
8082
- hasNextQuestion: a.current.currentQuestionIndex < D - 1,
8106
+ hasNextQuestion: a.current.currentQuestionIndex < N - 1,
8083
8107
  score: a.current.score,
8084
8108
  totalQuestions: a.current.totalQuestions,
8085
8109
  avatarNotReady: !0
@@ -8129,7 +8153,7 @@ const ft = Me(({
8129
8153
  const v = () => {
8130
8154
  if (!u.current || !b) return;
8131
8155
  u.current.setMood("happy"), u.current.setBodyMovement("idle");
8132
- const F = H.current || { lipsyncLang: "en" };
8156
+ const F = T.current || { lipsyncLang: "en" };
8133
8157
  b.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${b.question}`, {
8134
8158
  lipsyncLang: F.lipsyncLang
8135
8159
  }) : u.current.speakText(`Going back to: ${b.question}`, {
@@ -8171,7 +8195,7 @@ const ft = Me(({
8171
8195
  lesson: R()
8172
8196
  }), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
8173
8197
  }
8174
- }, [R]), $ = O(() => {
8198
+ }, [R]), ee = O(() => {
8175
8199
  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;
8176
8200
  }, []), be = O((b) => {
8177
8201
  console.log("Avatar is ready!", b);
@@ -8181,20 +8205,20 @@ const ft = Me(({
8181
8205
  }, 10);
8182
8206
  }, [h, R]);
8183
8207
  Xe(() => {
8184
- c.current = Z, g.current = X, x.current = z, f.current = E, k.current = Y, N.current = S, p.current = oe;
8208
+ c.current = X, g.current = j, x.current = z, f.current = E, k.current = Y, D.current = S, p.current = oe;
8185
8209
  }), Fe(r, () => ({
8186
8210
  // Curriculum control methods
8187
- startTeaching: Z,
8211
+ startTeaching: X,
8188
8212
  startQuestions: S,
8189
8213
  handleAnswerSelect: oe,
8190
8214
  handleCodeTestResult: le,
8191
8215
  nextQuestion: E,
8192
8216
  previousQuestion: ge,
8193
- nextLesson: X,
8217
+ nextLesson: j,
8194
8218
  previousLesson: de,
8195
8219
  completeLesson: z,
8196
8220
  completeCurriculum: Y,
8197
- resetCurriculum: $,
8221
+ resetCurriculum: ee,
8198
8222
  getState: () => ({ ...a.current }),
8199
8223
  getCurrentQuestion: () => L(),
8200
8224
  getCurrentLesson: () => R(),
@@ -8203,7 +8227,7 @@ const ft = Me(({
8203
8227
  // Convenience methods that delegate to avatar (always check current ref)
8204
8228
  speakText: async (b, v = {}) => {
8205
8229
  await u.current?.resumeAudioContext?.();
8206
- const F = H.current || { lipsyncLang: "en" };
8230
+ const F = T.current || { lipsyncLang: "en" };
8207
8231
  u.current?.speakText(b, { ...v, lipsyncLang: v.lipsyncLang || F.lipsyncLang });
8208
8232
  },
8209
8233
  resumeAudioContext: async () => {
@@ -8248,8 +8272,8 @@ const ft = Me(({
8248
8272
  handleResize: () => u.current?.handleResize(),
8249
8273
  // Avatar readiness check (always returns current value)
8250
8274
  isAvatarReady: () => u.current?.isReady || !1
8251
- }), [Z, S, oe, le, E, X, z, Y, $, L, R]);
8252
- const j = H.current || {
8275
+ }), [X, S, oe, le, E, j, z, Y, ee, L, R]);
8276
+ const Q = T.current || {
8253
8277
  avatarUrl: "/avatars/brunette.glb",
8254
8278
  avatarBody: "F",
8255
8279
  mood: "happy",
@@ -8266,18 +8290,18 @@ const ft = Me(({
8266
8290
  Ve,
8267
8291
  {
8268
8292
  ref: u,
8269
- avatarUrl: j.avatarUrl,
8270
- avatarBody: j.avatarBody,
8271
- mood: j.mood,
8272
- ttsLang: j.ttsLang,
8273
- ttsService: j.ttsService,
8274
- ttsVoice: j.ttsVoice,
8275
- ttsApiKey: j.ttsApiKey,
8276
- bodyMovement: j.bodyMovement,
8277
- movementIntensity: j.movementIntensity,
8278
- showFullAvatar: j.showFullAvatar,
8293
+ avatarUrl: Q.avatarUrl,
8294
+ avatarBody: Q.avatarBody,
8295
+ mood: Q.mood,
8296
+ ttsLang: Q.ttsLang,
8297
+ ttsService: Q.ttsService,
8298
+ ttsVoice: Q.ttsVoice,
8299
+ ttsApiKey: Q.ttsApiKey,
8300
+ bodyMovement: Q.bodyMovement,
8301
+ movementIntensity: Q.movementIntensity,
8302
+ showFullAvatar: Q.showFullAvatar,
8279
8303
  cameraView: "upper",
8280
- animations: j.animations,
8304
+ animations: Q.animations,
8281
8305
  onReady: be,
8282
8306
  onLoading: () => {
8283
8307
  },