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

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
- import { forwardRef as Me, useRef as N, useState as ce, useEffect as de, useCallback as P, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
3
- import * as b from "three";
2
+ import { forwardRef as Me, useRef as O, useState as ce, useEffect as de, useCallback as F, useImperativeHandle as Ee, useLayoutEffect as Xe } from "react";
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 Ne } from "three/addons/loaders/FBXLoader.js";
8
- import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
9
- import _e from "three/addons/libs/stats.module.js";
10
- let m, re, he;
11
- const A = [0, 0, 0, 0], z = new b.Vector3(), ze = new b.Vector3(), ie = new b.Vector3(), Ce = new b.Vector3();
12
- new b.Plane();
13
- new b.Ray();
14
- new b.Euler();
15
- const oe = new b.Quaternion(), Oe = new b.Quaternion(), fe = new b.Matrix4(), xe = new b.Matrix4();
16
- new b.Vector3();
17
- const He = new b.Vector3(0, 0, 1), Ke = new b.Vector3(1, 0, 0), Je = new b.Vector3(0, 1, 0), $e = new b.Vector3(0, 0, 1);
7
+ import { FBXLoader as Be } from "three/addons/loaders/FBXLoader.js";
8
+ import { RoomEnvironment as _e } from "three/addons/environments/RoomEnvironment.js";
9
+ import qe from "three/addons/libs/stats.module.js";
10
+ let p, re, he;
11
+ const A = [0, 0, 0, 0], z = new f.Vector3(), ze = new f.Vector3(), ie = new f.Vector3(), Ce = new f.Vector3();
12
+ new f.Plane();
13
+ new f.Ray();
14
+ new f.Euler();
15
+ const oe = new f.Quaternion(), Oe = new f.Quaternion(), fe = new f.Matrix4(), xe = new f.Matrix4();
16
+ new f.Vector3();
17
+ const He = new f.Vector3(0, 0, 1), Ke = new f.Vector3(1, 0, 0), $e = new f.Vector3(0, 1, 0), Je = new f.Vector3(0, 0, 1);
18
18
  class et {
19
19
  constructor(t = null) {
20
20
  this.opt = Object.assign({
@@ -264,7 +264,7 @@ class et {
264
264
  "pivot",
265
265
  "helper"
266
266
  ].forEach((n) => {
267
- m = this.getValue(t.name, n), m && (e[n] = m);
267
+ p = this.getValue(t.name, n), p && (e[n] = p);
268
268
  }), e;
269
269
  });
270
270
  }
@@ -279,7 +279,7 @@ class et {
279
279
  this.armature.traverse((o) => {
280
280
  e.has(o) || (e.set(o, t), t++);
281
281
  }), this.data.sort((o, l) => e.get(o.bone) - e.get(l.bone)), this.data.forEach((o) => {
282
- m = this.dict[o.boneParent.name], m && (m.children || (m.children = []), m.children.push(o));
282
+ p = this.dict[o.boneParent.name], p && (p.children || (p.children = []), p.children.push(o));
283
283
  }), this.objectsUpdate = [];
284
284
  const n = /* @__PURE__ */ new WeakSet(), i = (o) => o.parent?.isBone ? [o, ...i(o.parent)] : [o], s = (o) => {
285
285
  i(o).forEach((u) => {
@@ -358,20 +358,20 @@ class et {
358
358
  for (e = 0, i = this.data.length; e < i; e++) {
359
359
  if (o = this.data[e], z.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), z.applyMatrix4(xe), z.length() > 0.5 && (console.info("Info: Unrealistic jump of " + z.length().toFixed(2) + " meters."), z.setLength(0.5)), z.applyQuaternion(o.bone.quaternion), A[0] = z.x, A[1] = z.y, A[2] = -z.z, A[3] = z.length() / 3, o.children)
360
360
  for (n = 0, s = o.children.length; n < s; n++)
361
- m = o.children[n], A[0] -= m.v[0] * t / 3, A[1] -= m.v[1] * t / 3, A[2] += m.v[2] * t / 3, A[3] -= m.v[3] * t / 3;
362
- if (m = this.opt.sensitivityFactor, A[0] *= o.ext * m, A[1] *= o.ext * m, A[2] *= o.ext * m, A[3] *= o.ext * m, o.isX && (m = A[0] / t, o.ea[0] = (m - o.ev[0]) / t, o.ev[0] = m, o.a[0] = -o.k[0] * o.p[0] - o.c[0] * o.v[0] - o.ea[0], o.p[0] += o.v[0] * t + o.a[0] * t * t / 2 + A[0], m = o.v[0] + o.a[0] * t / 2, m = -o.k[0] * o.p[0] - o.c[0] * m - o.ea[0], o.v[0] = o.v[0] + (m + o.a[0]) * t / 2), o.isY && (m = A[1] / t, o.ea[1] = (m - o.ev[1]) / t, o.ev[1] = m, o.a[1] = -o.k[1] * o.p[1] - o.c[1] * o.v[1] - o.ea[1], o.p[1] += o.v[1] * t + o.a[1] * t * t / 2 + A[1], m = o.v[1] + o.a[1] * t / 2, m = -o.k[1] * o.p[1] - o.c[1] * m - o.ea[1], o.v[1] = o.v[1] + (m + o.a[1]) * t / 2), o.isZ && (m = A[2] / t, o.ea[2] = (m - o.ev[2]) / t, o.ev[2] = m, o.a[2] = -o.k[2] * o.p[2] - o.c[2] * o.v[2] - o.ea[2], o.p[2] += o.v[2] * t + o.a[2] * t * t / 2 + A[2], m = o.v[2] + o.a[2] * t / 2, m = -o.k[2] * o.p[2] - o.c[2] * m - o.ea[2], o.v[2] = o.v[2] + (m + o.a[2]) * t / 2), o.isT && (m = A[3] / t, o.ea[3] = (m - o.ev[3]) / t, o.ev[3] = m, o.a[3] = -o.k[3] * o.p[3] - o.c[3] * o.v[3] - o.ea[3], o.p[3] += o.v[3] * t + o.a[3] * t * t / 2 + A[3], m = o.v[3] + o.a[3] * t / 2, m = -o.k[3] * o.p[3] - o.c[3] * m - o.ea[3], o.v[3] = o.v[3] + (m + o.a[3]) * t / 2), this.timerMs < this.opt.warmupMs && (o.v[0] *= 1e-4, o.p[0] *= 1e-4, o.v[1] *= 1e-4, o.p[1] *= 1e-4, o.v[2] *= 1e-4, o.p[2] *= 1e-4, o.v[3] *= 1e-4, o.p[3] *= 1e-4), A[0] = o.p[0], A[1] = o.p[1], A[2] = o.p[2], A[3] = o.p[3], m = this.opt.movementFactor, A[0] *= m, A[1] *= m, A[2] *= m, A[3] *= m, o.dl && (m = o.dl, A[0] += m[0], A[1] += m[1], A[2] += m[2]), o.dw && (m = o.dw, z.set(
361
+ p = o.children[n], A[0] -= p.v[0] * t / 3, A[1] -= p.v[1] * t / 3, A[2] += p.v[2] * t / 3, A[3] -= p.v[3] * t / 3;
362
+ if (p = this.opt.sensitivityFactor, A[0] *= o.ext * p, A[1] *= o.ext * p, A[2] *= o.ext * p, A[3] *= o.ext * p, o.isX && (p = A[0] / t, o.ea[0] = (p - o.ev[0]) / t, o.ev[0] = p, o.a[0] = -o.k[0] * o.p[0] - o.c[0] * o.v[0] - o.ea[0], o.p[0] += o.v[0] * t + o.a[0] * t * t / 2 + A[0], p = o.v[0] + o.a[0] * t / 2, p = -o.k[0] * o.p[0] - o.c[0] * p - o.ea[0], o.v[0] = o.v[0] + (p + o.a[0]) * t / 2), o.isY && (p = A[1] / t, o.ea[1] = (p - o.ev[1]) / t, o.ev[1] = p, o.a[1] = -o.k[1] * o.p[1] - o.c[1] * o.v[1] - o.ea[1], o.p[1] += o.v[1] * t + o.a[1] * t * t / 2 + A[1], p = o.v[1] + o.a[1] * t / 2, p = -o.k[1] * o.p[1] - o.c[1] * p - o.ea[1], o.v[1] = o.v[1] + (p + o.a[1]) * t / 2), o.isZ && (p = A[2] / t, o.ea[2] = (p - o.ev[2]) / t, o.ev[2] = p, o.a[2] = -o.k[2] * o.p[2] - o.c[2] * o.v[2] - o.ea[2], o.p[2] += o.v[2] * t + o.a[2] * t * t / 2 + A[2], p = o.v[2] + o.a[2] * t / 2, p = -o.k[2] * o.p[2] - o.c[2] * p - o.ea[2], o.v[2] = o.v[2] + (p + o.a[2]) * t / 2), o.isT && (p = A[3] / t, o.ea[3] = (p - o.ev[3]) / t, o.ev[3] = p, o.a[3] = -o.k[3] * o.p[3] - o.c[3] * o.v[3] - o.ea[3], o.p[3] += o.v[3] * t + o.a[3] * t * t / 2 + A[3], p = o.v[3] + o.a[3] * t / 2, p = -o.k[3] * o.p[3] - o.c[3] * p - o.ea[3], o.v[3] = o.v[3] + (p + o.a[3]) * t / 2), this.timerMs < this.opt.warmupMs && (o.v[0] *= 1e-4, o.p[0] *= 1e-4, o.v[1] *= 1e-4, o.p[1] *= 1e-4, o.v[2] *= 1e-4, o.p[2] *= 1e-4, o.v[3] *= 1e-4, o.p[3] *= 1e-4), A[0] = o.p[0], A[1] = o.p[1], A[2] = o.p[2], A[3] = o.p[3], p = this.opt.movementFactor, A[0] *= p, A[1] *= p, A[2] *= p, A[3] *= p, o.dl && (p = o.dl, A[0] += p[0], A[1] += p[1], A[2] += p[2]), o.dw && (p = o.dw, z.set(
363
363
  o.vBasis.x + A[0],
364
364
  o.vBasis.y + A[1],
365
365
  o.vBasis.z + A[2]
366
- ), z.applyMatrix4(fe), z.x += m[0], z.y += m[1], z.z += m[2], z.applyMatrix4(xe), A[0] += z.x - o.vBasis.x, A[1] += z.y - o.vBasis.y, A[2] += z.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && A[0] < m[0][0] && (A[0] = m[0][0]), m[0][1] !== null && A[0] > m[0][1] && (A[0] = m[0][1])), m[1] && (m[1][0] !== null && A[1] < m[1][0] && (A[1] = m[1][0]), m[1][1] !== null && A[1] > m[1][1] && (A[1] = m[1][1])), m[2] && (m[2][0] !== null && A[2] < m[2][0] && (A[2] = m[2][0]), m[2][1] !== null && A[2] > m[2][1] && (A[2] = m[2][1])), m[3] && (m[3][0] !== null && A[3] < m[3][0] && (A[3] = m[3][0]), m[3][1] !== null && A[3] > m[3][1] && (A[3] = m[3][1]))), o.isPoint)
366
+ ), z.applyMatrix4(fe), z.x += p[0], z.y += p[1], z.z += p[2], z.applyMatrix4(xe), A[0] += z.x - o.vBasis.x, A[1] += z.y - o.vBasis.y, A[2] += z.z - o.vBasis.z), o.limits && this.opt.isLimits && (p = o.limits, p[0] && (p[0][0] !== null && A[0] < p[0][0] && (A[0] = p[0][0]), p[0][1] !== null && A[0] > p[0][1] && (A[0] = p[0][1])), p[1] && (p[1][0] !== null && A[1] < p[1][0] && (A[1] = p[1][0]), p[1][1] !== null && A[1] > p[1][1] && (A[1] = p[1][1])), p[2] && (p[2][0] !== null && A[2] < p[2][0] && (A[2] = p[2][0]), p[2][1] !== null && A[2] > p[2][1] && (A[2] = p[2][1])), p[3] && (p[3][0] !== null && A[3] < p[3][0] && (A[3] = p[3][0]), p[3][1] !== null && A[3] > p[3][1] && (A[3] = p[3][1]))), o.isPoint)
367
367
  o.bone.position.set(
368
368
  o.vBasis.x + A[0],
369
369
  o.vBasis.y + A[1],
370
370
  o.vBasis.z - A[2]
371
371
  );
372
- else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(z, oe, ie), z.copy(He).applyQuaternion(oe).setY(0).normalize(), oe.premultiply(Oe.setFromUnitVectors(He, z).invert()).normalize(), o.boneParent.quaternion.multiply(oe.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), oe.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(oe)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), oe.setFromAxisAngle(Ke, -m), o.boneParent.quaternion.multiply(oe)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), oe.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(oe)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
372
+ else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(z, oe, ie), z.copy(He).applyQuaternion(oe).setY(0).normalize(), oe.premultiply(Oe.setFromUnitVectors(He, z).invert()).normalize(), o.boneParent.quaternion.multiply(oe.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (p = Math.atan(A[0] / o.l), oe.setFromAxisAngle(Je, -p), o.boneParent.quaternion.multiply(oe)), o.isY && (p = o.l / 3, p = p * Math.tanh(A[1] / p), o.bone.position.setLength(o.l + p)), o.isX && (p = Math.atan(A[2] / o.l), oe.setFromAxisAngle(Ke, -p), o.boneParent.quaternion.multiply(oe)), o.isT && (p = 1.5 * Math.tanh(A[3] * 1.5), oe.setFromAxisAngle($e, -p), o.boneParent.quaternion.multiply(oe)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
373
373
  for (n = 0, s = o.excludes.length; n < s; n++)
374
- m = o.excludes[n], ie.set(0, 0, 0), m.deltaLocal && (ie.x += m.deltaLocal[0], ie.y += m.deltaLocal[1], ie.z += m.deltaLocal[2]), ie.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ie.applyMatrix4(xe), z.copy(o.bone.position), !(z.distanceToSquared(ie) >= m.radiusSq) && (he = z.length(), re = ie.length(), !(re > m.radius + he) && (re < Math.abs(m.radius - he) || (re = (re * re + he * he - m.radiusSq) / (2 * re), ie.normalize(), Ce.copy(ie).multiplyScalar(re), re = Math.sqrt(he * he - re * re), z.subVectors(z, Ce).projectOnPlane(ie).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ie).normalize(), he = ze.dot(z), he < 0 && (he = Math.sqrt(re * re - he * he), ze.multiplyScalar(he), z.add(ze)), z.add(Ce).normalize(), ie.copy(o.bone.position).normalize(), oe.setFromUnitVectors(ie, z), o.boneParent.quaternion.premultiply(oe), o.boneParent.updateWorldMatrix(!1, !0))));
374
+ p = o.excludes[n], ie.set(0, 0, 0), p.deltaLocal && (ie.x += p.deltaLocal[0], ie.y += p.deltaLocal[1], ie.z += p.deltaLocal[2]), ie.applyMatrix4(p.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ie.applyMatrix4(xe), z.copy(o.bone.position), !(z.distanceToSquared(ie) >= p.radiusSq) && (he = z.length(), re = ie.length(), !(re > p.radius + he) && (re < Math.abs(p.radius - he) || (re = (re * re + he * he - p.radiusSq) / (2 * re), ie.normalize(), Ce.copy(ie).multiplyScalar(re), re = Math.sqrt(he * he - re * re), z.subVectors(z, Ce).projectOnPlane(ie).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ie).normalize(), he = ze.dot(z), he < 0 && (he = Math.sqrt(re * re - he * he), ze.multiplyScalar(he), z.add(ze)), z.add(Ce).normalize(), ie.copy(o.bone.position).normalize(), oe.setFromUnitVectors(ie, z), o.boneParent.quaternion.premultiply(oe), o.boneParent.updateWorldMatrix(!1, !0))));
375
375
  }
376
376
  this.helpers.isActive && this.updateHelpers();
377
377
  }
@@ -382,18 +382,18 @@ class et {
382
382
  * @param {boolean} [keepSetting=false] If true, keep the previos all setting
383
383
  */
384
384
  showHelpers(t) {
385
- if (this.hideHelpers(), this.helpers.isShowAll = t === void 0 ? this.helpers.isShowAll : t === !0, m = this.helpers, this.data.forEach((e) => {
386
- (this.helpers.isShowAll || e.helper === !0) && (m.points.bones.push(e.bone), m.points.pivots.push(e.pivot), e.type !== 0 && m.lines.bones.push(e.bone), e.excludes && e.excludes.forEach((n) => {
385
+ if (this.hideHelpers(), this.helpers.isShowAll = t === void 0 ? this.helpers.isShowAll : t === !0, p = this.helpers, this.data.forEach((e) => {
386
+ (this.helpers.isShowAll || e.helper === !0) && (p.points.bones.push(e.bone), p.points.pivots.push(e.pivot), e.type !== 0 && p.lines.bones.push(e.bone), e.excludes && e.excludes.forEach((n) => {
387
387
  let i = !1;
388
- for (let s = 0; s < m.excludes.bones.length; s++)
389
- if (m.excludes.bones[s] === n.bone && m.excludes.radii[s] === n.radius && !(m.excludes.deltaLocals[s] === null && n.deltaLocal !== null) && !(m.excludes.deltaLocals[s] !== null && n.deltaLocal === null) && !(m.excludes.deltaLocals[s] !== null && m.excludes.deltaLocals[s].some((o, l) => o !== n.deltaLocal[l]))) {
388
+ for (let s = 0; s < p.excludes.bones.length; s++)
389
+ if (p.excludes.bones[s] === n.bone && p.excludes.radii[s] === n.radius && !(p.excludes.deltaLocals[s] === null && n.deltaLocal !== null) && !(p.excludes.deltaLocals[s] !== null && n.deltaLocal === null) && !(p.excludes.deltaLocals[s] !== null && p.excludes.deltaLocals[s].some((o, l) => o !== n.deltaLocal[l]))) {
390
390
  i = !0;
391
391
  break;
392
392
  }
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));
393
+ i || (p.excludes.bones.push(n.bone), p.excludes.radii.push(n.radius), p.excludes.deltaLocals.push(n.deltaLocal ? [...n.deltaLocal] : null), p.excludes.objects.push(null));
394
394
  }));
395
- }), m = this.helpers.excludes, this.opt.isExcludes && m.bones.length && m.bones.forEach((e, n) => {
396
- const i = new b.SphereGeometry(m.radii[n], 6, 6), s = new b.MeshBasicMaterial({
395
+ }), p = this.helpers.excludes, this.opt.isExcludes && p.bones.length && p.bones.forEach((e, n) => {
396
+ const i = new f.SphereGeometry(p.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 b.Mesh(i, s), m.objects[n].renderOrder = 997, e.add(m.objects[n]), m.deltaLocals[n] && m.objects[n].position.set(
405
- m.deltaLocals[n][0],
406
- m.deltaLocals[n][1],
407
- m.deltaLocals[n][2]
404
+ p.objects[n] = new f.Mesh(i, s), p.objects[n].renderOrder = 997, e.add(p.objects[n]), p.deltaLocals[n] && p.objects[n].position.set(
405
+ p.deltaLocals[n][0],
406
+ p.deltaLocals[n][1],
407
+ p.deltaLocals[n][2]
408
408
  );
409
- }), m = this.helpers.points, m.bones.length) {
409
+ }), p = this.helpers.points, p.bones.length) {
410
410
  this.helpers.isActive = !0;
411
- const e = new b.BufferGeometry(), n = m.bones.map((u) => [0, 0, 0]).flat();
412
- e.setAttribute("position", new b.Float32BufferAttribute(n, 3));
413
- const i = new b.Color(this.opt.helperBoneColor1), s = new b.Color(this.opt.helperBoneColor2), o = m.pivots.map((u) => u && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
414
- e.setAttribute("color", new b.Float32BufferAttribute(o, 3));
415
- const l = new b.PointsMaterial({
411
+ const e = new f.BufferGeometry(), n = p.bones.map((u) => [0, 0, 0]).flat();
412
+ e.setAttribute("position", new f.Float32BufferAttribute(n, 3));
413
+ const i = new f.Color(this.opt.helperBoneColor1), s = new f.Color(this.opt.helperBoneColor2), o = p.pivots.map((u) => u && this.opt.isPivots ? [s.r, s.g, s.b] : [i.r, i.g, i.b]).flat();
414
+ e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
415
+ const l = new f.PointsMaterial({
416
416
  depthTest: !1,
417
417
  depthWrite: !1,
418
418
  toneMapped: !1,
@@ -420,40 +420,40 @@ class et {
420
420
  size: 0.2,
421
421
  vertexColors: !0
422
422
  });
423
- m.object = new b.Points(e, l), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
423
+ p.object = new f.Points(e, l), p.object.renderOrder = 998, p.object.matrix = this.armature.matrixWorld, p.object.matrixAutoUpdate = !1, this.scene.add(p.object);
424
424
  }
425
- if (m = this.helpers.lines, m.bones.length) {
426
- const e = new b.BufferGeometry(), n = m.bones.map((u) => [0, 0, 0, 0, 0, 0]).flat();
427
- e.setAttribute("position", new b.Float32BufferAttribute(n, 3));
428
- const i = new b.Color(this.opt.helperLinkColor1), s = new b.Color(this.opt.helperLinkColor2), o = m.bones.map((u) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
429
- e.setAttribute("color", new b.Float32BufferAttribute(o, 3));
430
- const l = new b.LineBasicMaterial({
425
+ if (p = this.helpers.lines, p.bones.length) {
426
+ const e = new f.BufferGeometry(), n = p.bones.map((u) => [0, 0, 0, 0, 0, 0]).flat();
427
+ e.setAttribute("position", new f.Float32BufferAttribute(n, 3));
428
+ const i = new f.Color(this.opt.helperLinkColor1), s = new f.Color(this.opt.helperLinkColor2), o = p.bones.map((u) => [i.r, i.g, i.b, s.r, s.g, s.b]).flat();
429
+ e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
430
+ const l = new f.LineBasicMaterial({
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 b.LineSegments(e, l), m.object.renderOrder = 999, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
437
+ p.object = new f.LineSegments(e, l), p.object.renderOrder = 999, p.object.matrix = this.armature.matrixWorld, p.object.matrixAutoUpdate = !1, this.scene.add(p.object);
438
438
  }
439
439
  }
440
440
  /**
441
441
  * Update the positions of dynamic bone helpers.
442
442
  */
443
443
  updateHelpers() {
444
- if (m = this.helpers.points, m.bones.length) {
444
+ if (p = this.helpers.points, p.bones.length) {
445
445
  xe.copy(this.armature.matrixWorld).invert();
446
- const t = m.object.geometry.getAttribute("position");
447
- for (let e = 0, n = m.bones.length; e < n; e++)
448
- fe.multiplyMatrices(xe, m.bones[e].matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(e, z.x, z.y, z.z);
449
- t.needsUpdate = !0, m.object.updateMatrixWorld();
446
+ const t = p.object.geometry.getAttribute("position");
447
+ for (let e = 0, n = p.bones.length; e < n; e++)
448
+ fe.multiplyMatrices(xe, p.bones[e].matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(e, z.x, z.y, z.z);
449
+ t.needsUpdate = !0, p.object.updateMatrixWorld();
450
450
  }
451
- if (m = this.helpers.lines, m.bones.length) {
451
+ if (p = this.helpers.lines, p.bones.length) {
452
452
  xe.copy(this.armature.matrixWorld).invert();
453
- const t = m.object.geometry.getAttribute("position");
454
- for (let e = 0, n = 0, i = m.bones.length; e < i; e++, n += 2)
455
- fe.multiplyMatrices(xe, m.bones[e].matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(n, z.x, z.y, z.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(n + 1, z.x, z.y, z.z);
456
- t.needsUpdate = !0, m.object.updateMatrixWorld();
453
+ const t = p.object.geometry.getAttribute("position");
454
+ for (let e = 0, n = 0, i = p.bones.length; e < i; e++, n += 2)
455
+ fe.multiplyMatrices(xe, p.bones[e].matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(n, z.x, z.y, z.z), fe.multiplyMatrices(xe, p.bones[e].parent.matrixWorld), z.setFromMatrixPosition(fe), t.setXYZ(n + 1, z.x, z.y, z.z);
456
+ t.needsUpdate = !0, p.object.updateMatrixWorld();
457
457
  }
458
458
  }
459
459
  /**
@@ -462,9 +462,9 @@ class et {
462
462
  hideHelpers() {
463
463
  [this.helpers.points, this.helpers.lines].forEach((t) => {
464
464
  t.bones = [], t.object && (this.scene.remove(t.object), t.object.geometry.dispose(), t.object.material.dispose(), t.object = null);
465
- }), m = this.helpers.excludes, m.objects.forEach((t, e) => {
466
- t && (m.bones[e].remove(t), t.geometry.dispose(), t.material.dispose());
467
- }), m.bones = [], m.deltaLocals = [], m.radii = [], m.objects = [], this.helpers.isActive = !1;
465
+ }), p = this.helpers.excludes, p.objects.forEach((t, e) => {
466
+ t && (p.bones[e].remove(t), t.geometry.dispose(), t.material.dispose());
467
+ }), p.bones = [], p.deltaLocals = [], p.radii = [], p.objects = [], this.helpers.isActive = !1;
468
468
  }
469
469
  /**
470
470
  * Start dynamic bones.
@@ -608,8 +608,8 @@ class tt {
608
608
  for (let a = 0; a < i / 2; a++) {
609
609
  const c = n[(u + a) * 2], d = n[(u + a) * 2 + 1], g = n[(u + a + i / 2) * 2] * r - n[(u + a + i / 2) * 2 + 1] * h, x = n[(u + a + i / 2) * 2] * h + n[(u + a + i / 2) * 2 + 1] * r;
610
610
  n[(u + a) * 2] = c + g, n[(u + a) * 2 + 1] = d + x, n[(u + a + i / 2) * 2] = c - g, n[(u + a + i / 2) * 2 + 1] = d - x;
611
- const f = r * o - h * l, R = r * l + h * o;
612
- r = f, h = R;
611
+ const b = r * o - h * l, I = r * l + h * o;
612
+ r = b, h = I;
613
613
  }
614
614
  }
615
615
  }
@@ -2629,15 +2629,15 @@ const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2629
2629
  fr: rt,
2630
2630
  fi: ht,
2631
2631
  lt: ct
2632
- }, Q = new b.Quaternion(), V = new b.Euler(), ve = new b.Vector3(), Re = new b.Vector3(), We = new b.Box3();
2633
- new b.Matrix4();
2634
- new b.Matrix4();
2635
- new b.Vector3();
2636
- new b.Vector3(0, 0, 1);
2637
- const mt = new b.Vector3(1, 0, 0);
2638
- new b.Vector3(0, 1, 0);
2639
- new b.Vector3(0, 0, 1);
2640
- class Be {
2632
+ }, _ = new f.Quaternion(), V = new f.Euler(), Re = new f.Vector3(), ve = new f.Vector3(), We = new f.Box3();
2633
+ new f.Matrix4();
2634
+ new f.Matrix4();
2635
+ new f.Vector3();
2636
+ new f.Vector3(0, 0, 1);
2637
+ const mt = new f.Vector3(1, 0, 0);
2638
+ new f.Vector3(0, 1, 0);
2639
+ new f.Vector3(0, 0, 1);
2640
+ class Ne {
2641
2641
  /**
2642
2642
  * Avatar.
2643
2643
  * @typedef {Object} Avatar
@@ -2763,7 +2763,7 @@ class Be {
2763
2763
  avatarOnlyCamera: null,
2764
2764
  statsNode: null,
2765
2765
  statsStyle: null
2766
- }, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new _e(), this.opt.statsStyle && (this.stats.dom.style.cssText = this.opt.statsStyle), this.opt.statsNode.appendChild(this.stats.dom)), this.poseTemplates = {
2766
+ }, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new qe(), this.opt.statsStyle && (this.stats.dom.style.cssText = this.opt.statsStyle), this.opt.statsNode.appendChild(this.stats.dom)), this.poseTemplates = {
2767
2767
  side: {
2768
2768
  standing: !0,
2769
2769
  props: {
@@ -4073,22 +4073,22 @@ class Be {
4073
4073
  if (this.isAvatarOnly = this.opt.avatarOnly, this.isAvatarOnly)
4074
4074
  this.scene = this.opt.avatarOnlyScene, this.camera = this.opt.avatarOnlyCamera;
4075
4075
  else {
4076
- this.renderer = new b.WebGLRenderer({ antialias: !0, alpha: !0 }), this.renderer.setPixelRatio(this.opt.modelPixelRatio * window.devicePixelRatio), this.renderer.setSize(this.nodeAvatar.clientWidth, this.nodeAvatar.clientHeight), this.renderer.outputColorSpace = b.SRGBColorSpace, this.renderer.toneMapping = b.ACESFilmicToneMapping, this.renderer.shadowMap.enabled = !1, this.nodeAvatar.appendChild(this.renderer.domElement), this.camera = new b.PerspectiveCamera(10, this.nodeAvatar.clientWidth / this.nodeAvatar.clientHeight, 0.1, 2e3), this.scene = new b.Scene(), this.lightAmbient = new b.AmbientLight(
4077
- new b.Color(this.opt.lightAmbientColor),
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),
4078
4078
  this.opt.lightAmbientIntensity
4079
- ), this.lightDirect = new b.DirectionalLight(
4080
- new b.Color(this.opt.lightDirectColor),
4079
+ ), this.lightDirect = new f.DirectionalLight(
4080
+ new f.Color(this.opt.lightDirectColor),
4081
4081
  this.opt.lightDirectIntensity
4082
- ), this.lightSpot = new b.SpotLight(
4083
- new b.Color(this.opt.lightSpotColor),
4082
+ ), this.lightSpot = new f.SpotLight(
4083
+ new f.Color(this.opt.lightSpotColor),
4084
4084
  this.opt.lightSpotIntensity,
4085
4085
  0,
4086
4086
  this.opt.lightSpotDispersion
4087
4087
  ), this.setLighting(this.opt);
4088
- const l = new b.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;
4088
+ const l = new f.PMREMGenerator(this.renderer);
4089
+ l.compileEquirectangularShader(), this.scene.environment = l.fromScene(new _e()).texture, this.resizeobserver = new ResizeObserver(this.onResize.bind(this)), this.resizeobserver.observe(this.nodeAvatar), this.controls = new Ye(this.camera, this.renderer.domElement), this.controls.enableZoom = this.opt.cameraZoomEnable, this.controls.enableRotate = this.opt.cameraRotateEnable, this.controls.enablePan = this.opt.cameraPanEnable, this.controls.minDistance = 2, this.controls.maxDistance = 2e3, this.controls.autoRotateSpeed = 0, this.controls.autoRotate = !1, this.controls.update(), this.cameraClock = null;
4090
4090
  }
4091
- this.ikMesh = new b.SkinnedMesh();
4091
+ this.ikMesh = new f.SkinnedMesh();
4092
4092
  const s = {
4093
4093
  LeftShoulder: null,
4094
4094
  LeftArm: "LeftShoulder",
@@ -4102,9 +4102,9 @@ class Be {
4102
4102
  RightHandMiddle1: "RightHand"
4103
4103
  }, o = [];
4104
4104
  Object.entries(s).forEach((l, u) => {
4105
- const r = new b.Bone();
4105
+ const r = new f.Bone();
4106
4106
  r.name = l[0], l[1] ? this.ikMesh.getObjectByName(l[1]).add(r) : this.ikMesh.add(r), o.push(r);
4107
- }), this.ikMesh.bind(new b.Skeleton(o)), this.dynamicbones = new et(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
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 = [];
4108
4108
  }
4109
4109
  /**
4110
4110
  * Helper that re/creates the audio context and the other nodes.
@@ -4194,7 +4194,7 @@ class Be {
4194
4194
  for (let [n, i] of Object.entries(t)) {
4195
4195
  const s = n.split(".");
4196
4196
  let o = Array.isArray(i.x) ? this.gaussianRandom(...i.x) : i.x, l = Array.isArray(i.y) ? this.gaussianRandom(...i.y) : i.y, u = Array.isArray(i.z) ? this.gaussianRandom(...i.z) : i.z;
4197
- s[1] === "position" || s[1] === "scale" ? e[n] = new b.Vector3(o, l, u) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new b.Quaternion().setFromEuler(new b.Euler(o, l, u, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new b.Quaternion(o, l, u, i.w).normalize());
4197
+ s[1] === "position" || s[1] === "scale" ? e[n] = new f.Vector3(o, l, u) : s[1] === "rotation" ? (n = s[0] + ".quaternion", e[n] = new f.Quaternion().setFromEuler(new f.Euler(o, l, u, "XYZ")).normalize()) : s[1] === "quaternion" && (e[n] = new f.Quaternion(o, l, u, i.w).normalize());
4198
4198
  }
4199
4199
  return e;
4200
4200
  }
@@ -4226,15 +4226,15 @@ class Be {
4226
4226
  for (const [r, h] of Object.entries(n))
4227
4227
  if (s.morphTargetDictionary.hasOwnProperty(r)) {
4228
4228
  const a = s.morphTargetDictionary[r], c = o.morphAttributes.position[a], d = o.morphAttributes.normal?.[a];
4229
- l || (l = new b.Float32BufferAttribute(c.count * 3, 3), d && (u = new b.Float32BufferAttribute(c.count * 3, 3)));
4229
+ l || (l = new f.Float32BufferAttribute(c.count * 3, 3), d && (u = new f.Float32BufferAttribute(c.count * 3, 3)));
4230
4230
  for (let g = 0; g < c.count; g++) {
4231
- const x = l.getX(g) + c.getX(g) * h, f = l.getY(g) + c.getY(g) * h, R = l.getZ(g) + c.getZ(g) * h;
4232
- l.setXYZ(g, x, f, R);
4231
+ const x = l.getX(g) + c.getX(g) * h, b = l.getY(g) + c.getY(g) * h, I = l.getZ(g) + c.getZ(g) * h;
4232
+ l.setXYZ(g, x, b, I);
4233
4233
  }
4234
4234
  if (d)
4235
4235
  for (let g = 0; g < c.count; g++) {
4236
- const x = u.getX(g) + d.getX(g) * h, f = u.getY(g) + d.getY(g) * h, R = u.getZ(g) + d.getZ(g) * h;
4237
- u.setXYZ(g, x, f, R);
4236
+ const x = u.getX(g) + d.getX(g) * h, b = u.getY(g) + d.getY(g) * h, I = u.getZ(g) + d.getZ(g) * h;
4237
+ u.setXYZ(g, x, b, I);
4238
4238
  }
4239
4239
  }
4240
4240
  if (l) {
@@ -4314,7 +4314,7 @@ class Be {
4314
4314
  console.error("Dynamic bones setup failed: " + r);
4315
4315
  }
4316
4316
  this.objectLeftToeBase = this.armature.getObjectByName("LeftToeBase"), this.objectRightToeBase = this.armature.getObjectByName("RightToeBase"), this.objectLeftEye = this.armature.getObjectByName("LeftEye"), this.objectRightEye = this.armature.getObjectByName("RightEye"), this.objectLeftArm = this.armature.getObjectByName("LeftArm"), this.objectRightArm = this.armature.getObjectByName("RightArm"), this.objectHips = this.armature.getObjectByName("Hips"), this.objectHead = this.armature.getObjectByName("Head"), this.objectNeck = this.armature.getObjectByName("Neck");
4317
- const u = new b.Vector3();
4317
+ const u = new f.Vector3();
4318
4318
  this.objectLeftEye.getWorldPosition(u), this.avatarHeight = u.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.avatar.body === "M" && this.poseTemplates.wide && (this.poseName = "wide", this.setPoseFromTemplate(this.poseTemplates.wide, 0), console.log("Set initial male-appropriate pose: wide")), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
4319
4319
  }
4320
4320
  /**
@@ -4358,14 +4358,14 @@ class Be {
4358
4358
  default:
4359
4359
  a += 12, h = h * a;
4360
4360
  }
4361
- r = r * a, this.controlsEnd = new b.Vector3(r, h, 0), this.cameraEnd = new b.Vector3(r, h, a).applyEuler(new b.Euler(o, l, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
4361
+ r = r * a, this.controlsEnd = new f.Vector3(r, h, 0), this.cameraEnd = new f.Vector3(r, h, a).applyEuler(new f.Euler(o, l, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
4362
4362
  }
4363
4363
  /**
4364
4364
  * Change light colors and intensities.
4365
4365
  * @param {Object} opt Options
4366
4366
  */
4367
4367
  setLighting(t) {
4368
- this.isAvatarOnly || (t = t || {}, t.hasOwnProperty("lightAmbientColor") && this.lightAmbient.color.set(new b.Color(t.lightAmbientColor)), t.hasOwnProperty("lightAmbientIntensity") && (this.lightAmbient.intensity = t.lightAmbientIntensity, this.lightAmbient.visible = t.lightAmbientIntensity !== 0), t.hasOwnProperty("lightDirectColor") && this.lightDirect.color.set(new b.Color(t.lightDirectColor)), t.hasOwnProperty("lightDirectIntensity") && (this.lightDirect.intensity = t.lightDirectIntensity, this.lightDirect.visible = t.lightDirectIntensity !== 0), t.hasOwnProperty("lightDirectPhi") && t.hasOwnProperty("lightDirectTheta") && this.lightDirect.position.setFromSphericalCoords(2, t.lightDirectPhi, t.lightDirectTheta), t.hasOwnProperty("lightSpotColor") && this.lightSpot.color.set(new b.Color(t.lightSpotColor)), t.hasOwnProperty("lightSpotIntensity") && (this.lightSpot.intensity = t.lightSpotIntensity, this.lightSpot.visible = t.lightSpotIntensity !== 0), t.hasOwnProperty("lightSpotPhi") && t.hasOwnProperty("lightSpotTheta") && (this.lightSpot.position.setFromSphericalCoords(2, t.lightSpotPhi, t.lightSpotTheta), this.lightSpot.position.add(new b.Vector3(0, 1.5, 0))), t.hasOwnProperty("lightSpotDispersion") && (this.lightSpot.angle = t.lightSpotDispersion));
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));
4369
4369
  }
4370
4370
  /**
4371
4371
  * Render scene.
@@ -4400,7 +4400,7 @@ class Be {
4400
4400
  if (e.x === 0 && e.y === 0 && e.z === 0) continue;
4401
4401
  V.set(e.x, e.y, e.z);
4402
4402
  const n = this.poseAvatar.props[t];
4403
- n.isQuaternion ? (Q.setFromEuler(V), n.multiply(Q)) : n.isVector3 && n.add(V);
4403
+ n.isQuaternion ? (_.setFromEuler(V), n.multiply(_)) : n.isVector3 && n.add(V);
4404
4404
  }
4405
4405
  }
4406
4406
  /**
@@ -4480,7 +4480,7 @@ class Be {
4480
4480
  return Object.entries(t).forEach((i, s) => {
4481
4481
  const o = i[0].split(".");
4482
4482
  if (o[1] === "position" || o[1] === "rotation" || o[1] === "quaternion") {
4483
- const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], u = i[1].isQuaternion ? new b.Euler().setFromQuaternion(i[1]) : i[1];
4483
+ const l = o[1] === "quaternion" ? o[0] + ".rotation" : i[0], u = i[1].isQuaternion ? new f.Euler().setFromQuaternion(i[1]) : i[1];
4484
4484
  n += (s ? ", " : "") + "'" + l + "':{", n += "x:" + Math.round(u.x * e) / e, n += ", y:" + Math.round(u.y * e) / e, n += ", z:" + Math.round(u.z * e) / e, n += "}";
4485
4485
  }
4486
4486
  }), n += "}", n;
@@ -5108,8 +5108,8 @@ class Be {
5108
5108
  else {
5109
5109
  g.newvalue = d[i + 1];
5110
5110
  const x = a.ts[i + 1] - a.ts[i];
5111
- let f = 1;
5112
- x > 1e-4 && (f = (this.animClock - a.ts[i]) / x), f < 1 && (g.easing && (f = g.easing(f)), g.newvalue = (1 - f) * d[i] + f * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(c) && delete g.ref[c], g.ref = a.vs;
5111
+ let b = 1;
5112
+ x > 1e-4 && (b = (this.animClock - a.ts[i]) / x), b < 1 && (g.easing && (b = g.easing(b)), g.newvalue = (1 - b) * d[i] + b * g.newvalue), g.ref && g.ref !== a.vs && g.ref.hasOwnProperty(c) && delete g.ref[c], g.ref = a.vs;
5113
5113
  }
5114
5114
  if (l)
5115
5115
  switch (c) {
@@ -5157,7 +5157,7 @@ class Be {
5157
5157
  { link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
5158
5158
  { link: "LeftArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
5159
5159
  ]
5160
- }, i.x ? new b.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5160
+ }, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
5161
5161
  break;
5162
5162
  case "handRight":
5163
5163
  this.ikSolve({
@@ -5169,7 +5169,7 @@ class Be {
5169
5169
  { link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5, maxAngle: 0.2 },
5170
5170
  { link: "RightArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
5171
5171
  ]
5172
- }, i.x ? new b.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);
5173
5173
  break;
5174
5174
  }
5175
5175
  if ((u || r) && (V.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), V.x = Math.max(-0.9, Math.min(0.9, 2 * V.x - 0.5)), V.y = Math.max(-0.9, Math.min(0.9, -2.5 * V.y)), u ? (Object.assign(this.mtAvatar.eyesLookDown, { system: V.x < 0 ? -V.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: V.x < 0 ? 0 : V.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: V.y < 0 ? -V.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: V.y < 0 ? 0 : V.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: V.y < 0 ? 0 : V.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: V.y < 0 ? -V.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
@@ -5193,12 +5193,12 @@ class Be {
5193
5193
  eyeLookOutRight: [null, 0],
5194
5194
  eyeContact: [0]
5195
5195
  }
5196
- })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && u ? 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 && (Q.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(Q)), 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) && u ? 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(Re), Re.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (Re.x + ve.x) / 4, this.objectHips.position.z -= (Re.z + ve.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
5197
5197
  this.stats && this.stats.end();
5198
5198
  else {
5199
5199
  if (this.cameraClock !== null && this.cameraClock < 1e3) {
5200
5200
  this.cameraClock += e, this.cameraClock > 1e3 && (this.cameraClock = 1e3);
5201
- let a = new b.Spherical().setFromVector3(this.cameraStart), c = new b.Spherical().setFromVector3(this.cameraEnd);
5201
+ let a = new f.Spherical().setFromVector3(this.cameraStart), c = new f.Spherical().setFromVector3(this.cameraEnd);
5202
5202
  a.phi += this.easing(this.cameraClock / 1e3) * (c.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (c.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (c.radius - a.radius), a.makeSafe(), this.camera.position.setFromSpherical(a), this.controlsStart.x !== this.controlsEnd.x ? this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd, this.easing(this.cameraClock / 1e3))) : (a.setFromVector3(this.controlsStart), c.setFromVector3(this.controlsEnd), a.phi += this.easing(this.cameraClock / 1e3) * (c.phi - a.phi), a.theta += this.easing(this.cameraClock / 1e3) * (c.theta - a.theta), a.radius += this.easing(this.cameraClock / 1e3) * (c.radius - a.radius), a.makeSafe(), this.controls.target.setFromSpherical(a)), this.controls.update();
5203
5203
  }
5204
5204
  this.controls.autoRotate && this.controls.update(), this.stats && this.stats.end(), this.render();
@@ -5262,12 +5262,12 @@ class Be {
5262
5262
  e = e || {};
5263
5263
  const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, l = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, u = /[\p{Extended_Pictographic}]/ug, r = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
5264
5264
  let h = "", a = "", c = 0, d = [], g = [];
5265
- const x = Array.from(this.segmenter.segment(t), (f) => f.segment);
5266
- for (let f = 0; f < x.length; f++) {
5267
- const R = f === x.length - 1, F = x[f].match(l);
5268
- let p = x[f].match(s);
5269
- const H = x[f].match(u), k = x[f].match(o);
5270
- if (p && !R && !H && x[f + 1].match(s) && (p = !1), n && (h += x[f]), F && (!i || i.every((y) => f < y[0] || f > y[1])) && (a += x[f]), (k || p || R) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
5265
+ const x = Array.from(this.segmenter.segment(t), (b) => b.segment);
5266
+ for (let b = 0; b < x.length; b++) {
5267
+ const I = b === x.length - 1, H = x[b].match(l);
5268
+ let m = x[b].match(s);
5269
+ const T = x[b].match(u), k = x[b].match(o);
5270
+ if (m && !I && !T && x[b + 1].match(s) && (m = !1), n && (h += x[b]), H && (!i || i.every((y) => b < y[0] || b > y[1])) && (a += x[b]), (k || m || I) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
5271
5271
  mark: c,
5272
5272
  word: a
5273
5273
  })), h.length && (g.push({
@@ -5280,28 +5280,28 @@ class Be {
5280
5280
  }), h = ""), a.length)) {
5281
5281
  const y = this.lipsyncWordsToVisemes(a, r);
5282
5282
  if (y && y.visemes && y.visemes.length) {
5283
- const T = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
5284
- for (let E = 0; E < y.visemes.length; E++)
5283
+ const M = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
5284
+ for (let P = 0; P < y.visemes.length; P++)
5285
5285
  g.push({
5286
5286
  mark: c,
5287
5287
  template: { name: "viseme" },
5288
- ts: [(y.times[E] - 0.6) / T, (y.times[E] + 0.5) / T, (y.times[E] + y.durations[E] + 0.5) / T],
5288
+ ts: [(y.times[P] - 0.6) / M, (y.times[P] + 0.5) / M, (y.times[P] + y.durations[P] + 0.5) / M],
5289
5289
  vs: {
5290
- ["viseme_" + y.visemes[E]]: [null, y.visemes[E] === "PP" || y.visemes[E] === "FF" ? 0.9 : 0.6, 0]
5290
+ ["viseme_" + y.visemes[P]]: [null, y.visemes[P] === "PP" || y.visemes[P] === "FF" ? 0.9 : 0.6, 0]
5291
5291
  }
5292
5292
  });
5293
5293
  }
5294
5294
  a = "", c++;
5295
5295
  }
5296
- if (p || R) {
5297
- if (d.length || R && g.length) {
5296
+ if (m || I) {
5297
+ if (d.length || I && g.length) {
5298
5298
  const y = {
5299
5299
  anim: g
5300
5300
  };
5301
5301
  n && (y.onSubtitles = n), d.length && !e.avatarMute && (y.text = d, e.avatarMood && (y.mood = e.avatarMood), e.ttsLang && (y.lang = e.ttsLang), e.ttsVoice && (y.voice = e.ttsVoice), e.ttsRate && (y.rate = e.ttsRate), e.ttsVoice && (y.pitch = e.ttsPitch), e.ttsVolume && (y.volume = e.ttsVolume)), this.speechQueue.push(y), d = [], a = "", c = 0, g = [];
5302
5302
  }
5303
- if (H) {
5304
- let y = this.animEmojis[x[f]];
5303
+ if (T) {
5304
+ let y = this.animEmojis[x[b]];
5305
5305
  y && y.link && (y = this.animEmojis[y.link]), y && this.speechQueue.push({ emoji: y });
5306
5306
  }
5307
5307
  this.speechQueue.push({ break: 100 });
@@ -5397,13 +5397,13 @@ class Be {
5397
5397
  const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(h, Math.max(0, h - c.visemes.length * 150));
5398
5398
  let x = 0.6 + this.convertRange(g, [0, h], [0, 0.4]);
5399
5399
  if (h = Math.min(h, c.visemes.length * 200), d > 0)
5400
- for (let f = 0; f < c.visemes.length; f++) {
5401
- const R = r + c.times[f] / d * h, F = c.durations[f] / d * h;
5400
+ for (let b = 0; b < c.visemes.length; b++) {
5401
+ const I = r + c.times[b] / d * h, H = c.durations[b] / d * h;
5402
5402
  o.push({
5403
5403
  template: { name: "viseme" },
5404
- ts: [R - Math.min(60, 2 * F / 3), R + Math.min(25, F / 2), R + F + Math.min(60, F / 2)],
5404
+ ts: [I - Math.min(60, 2 * H / 3), I + Math.min(25, H / 2), I + H + Math.min(60, H / 2)],
5405
5405
  vs: {
5406
- ["viseme_" + c.visemes[f]]: [null, c.visemes[f] === "PP" || c.visemes[f] === "FF" ? 0.9 : x, 0]
5406
+ ["viseme_" + c.visemes[b]]: [null, c.visemes[b] === "PP" || c.visemes[b] === "FF" ? 0.9 : x, 0]
5407
5407
  }
5408
5408
  });
5409
5409
  }
@@ -5479,41 +5479,41 @@ class Be {
5479
5479
  */
5480
5480
  async synthesizeWithBrowserTTS(t) {
5481
5481
  return new Promise((e, n) => {
5482
- const i = t.text.map((p) => p.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", l = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, u = (t.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, r = (t.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
5482
+ const i = t.text.map((m) => m.word).join(" "), s = new SpeechSynthesisUtterance(i), o = t.lang || this.avatar.ttsLang || this.opt.ttsLang || "en-US", l = (t.rate || this.avatar.ttsRate || this.opt.ttsRate || 1) + this.mood.speech.deltaRate, u = (t.pitch || this.avatar.ttsPitch || this.opt.ttsPitch || 1) + this.mood.speech.deltaPitch, r = (t.volume || this.avatar.ttsVolume || this.opt.ttsVolume || 1) + this.mood.speech.deltaVolume;
5483
5483
  s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, u)), s.volume = Math.max(0, Math.min(1, r));
5484
5484
  const h = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
5485
5485
  if (a && h.length > 0) {
5486
- const p = h.find((H) => H.name.includes(a) || H.lang === o);
5487
- p && (s.voice = p);
5486
+ const m = h.find((T) => T.name.includes(a) || T.lang === o);
5487
+ m && (s.voice = m);
5488
5488
  }
5489
- const c = i.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", x = this.lipsyncPreProcessText(i, g), f = this.lipsyncWordsToVisemes(x, g);
5489
+ const c = i.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", x = this.lipsyncPreProcessText(i, g), b = this.lipsyncWordsToVisemes(x, g);
5490
5490
  console.log("Browser TTS Lip-sync Debug:", {
5491
5491
  text: i,
5492
5492
  lipsyncLang: g,
5493
5493
  processedText: x,
5494
- lipsyncData: f,
5495
- hasVisemes: f && f.visemes && f.visemes.length > 0,
5494
+ lipsyncData: b,
5495
+ hasVisemes: b && b.visemes && b.visemes.length > 0,
5496
5496
  estimatedDuration: c
5497
5497
  });
5498
- const R = [];
5499
- if (f && f.visemes && f.visemes.length > 0) {
5500
- const p = f.times[f.visemes.length - 1] + f.durations[f.visemes.length - 1];
5501
- for (let H = 0; H < f.visemes.length; H++) {
5502
- const k = f.visemes[H], y = f.times[H] / p, T = f.durations[H] / p, E = y * c, O = T * c;
5503
- R.push({
5498
+ const I = [];
5499
+ if (b && b.visemes && b.visemes.length > 0) {
5500
+ const m = b.times[b.visemes.length - 1] + b.durations[b.visemes.length - 1];
5501
+ for (let T = 0; T < b.visemes.length; T++) {
5502
+ const k = b.visemes[T], y = b.times[T] / m, M = b.durations[T] / m, P = y * c, D = M * c;
5503
+ I.push({
5504
5504
  template: { name: "viseme" },
5505
- ts: [E - Math.min(60, 2 * O / 3), E + Math.min(25, O / 2), E + O + Math.min(60, O / 2)],
5505
+ ts: [P - Math.min(60, 2 * D / 3), P + Math.min(25, D / 2), P + D + Math.min(60, D / 2)],
5506
5506
  vs: {
5507
5507
  ["viseme_" + k]: [null, k === "PP" || k === "FF" ? 0.9 : 0.6, 0]
5508
5508
  }
5509
5509
  });
5510
5510
  }
5511
5511
  }
5512
- const F = [...t.anim, ...R];
5513
- this.audioPlaylist.push({ anim: F, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5512
+ const H = [...t.anim, ...I];
5513
+ this.audioPlaylist.push({ anim: H, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5514
5514
  e();
5515
- }, s.onerror = (p) => {
5516
- console.error("Speech synthesis error:", p.error), n(p.error);
5515
+ }, s.onerror = (m) => {
5516
+ console.error("Speech synthesis error:", m.error), n(m.error);
5517
5517
  }, speechSynthesis.speak(s);
5518
5518
  });
5519
5519
  }
@@ -5576,15 +5576,15 @@ class Be {
5576
5576
  console.error("Text-based lip-sync failed, using fallback:", c);
5577
5577
  const d = e.toLowerCase().split(/\s+/), g = [];
5578
5578
  for (const x of d)
5579
- for (const f of x) {
5580
- let R = "aa";
5581
- "aeiou".includes(f) ? R = "aa" : "bp".includes(f) ? R = "PP" : "fv".includes(f) ? R = "FF" : "st".includes(f) ? R = "SS" : "dln".includes(f) ? R = "DD" : "kg".includes(f) ? R = "kk" : "rw".includes(f) && (R = "RR"), g.push(R);
5579
+ for (const b of x) {
5580
+ let I = "aa";
5581
+ "aeiou".includes(b) ? I = "aa" : "bp".includes(b) ? I = "PP" : "fv".includes(b) ? I = "FF" : "st".includes(b) ? I = "SS" : "dln".includes(b) ? I = "DD" : "kg".includes(b) ? I = "kk" : "rw".includes(b) && (I = "RR"), g.push(I);
5582
5582
  }
5583
5583
  r = {
5584
- visemes: g.map((x, f) => ({
5584
+ visemes: g.map((x, b) => ({
5585
5585
  viseme: x,
5586
- startTime: f * l.duration / g.length,
5587
- endTime: (f + 1) * l.duration / g.length,
5586
+ startTime: b * l.duration / g.length,
5587
+ endTime: (b + 1) * l.duration / g.length,
5588
5588
  duration: l.duration / g.length,
5589
5589
  intensity: 0.6
5590
5590
  })),
@@ -5609,12 +5609,12 @@ class Be {
5609
5609
  if (r.visemes && r.visemes.length > 0) {
5610
5610
  console.log("ElevenLabs: Generating lip-sync animation from", r.visemes.length, "visemes");
5611
5611
  for (let c = 0; c < r.visemes.length; c++) {
5612
- const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, f = d.intensity;
5612
+ const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
5613
5613
  h.push({
5614
5614
  template: { name: "viseme" },
5615
5615
  ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
5616
5616
  vs: {
5617
- ["viseme_" + d.viseme]: [null, f, 0]
5617
+ ["viseme_" + d.viseme]: [null, b, 0]
5618
5618
  }
5619
5619
  });
5620
5620
  }
@@ -5674,15 +5674,15 @@ class Be {
5674
5674
  console.error("Text-based lip-sync failed, using fallback:", c);
5675
5675
  const d = e.toLowerCase().split(/\s+/), g = [];
5676
5676
  for (const x of d)
5677
- for (const f of x) {
5678
- let R = "aa";
5679
- "aeiou".includes(f) ? R = "aa" : "bp".includes(f) ? R = "PP" : "fv".includes(f) ? R = "FF" : "st".includes(f) ? R = "SS" : "dln".includes(f) ? R = "DD" : "kg".includes(f) ? R = "kk" : "rw".includes(f) && (R = "RR"), g.push(R);
5677
+ for (const b of x) {
5678
+ let I = "aa";
5679
+ "aeiou".includes(b) ? I = "aa" : "bp".includes(b) ? I = "PP" : "fv".includes(b) ? I = "FF" : "st".includes(b) ? I = "SS" : "dln".includes(b) ? I = "DD" : "kg".includes(b) ? I = "kk" : "rw".includes(b) && (I = "RR"), g.push(I);
5680
5680
  }
5681
5681
  r = {
5682
- visemes: g.map((x, f) => ({
5682
+ visemes: g.map((x, b) => ({
5683
5683
  viseme: x,
5684
- startTime: f * l.duration / g.length,
5685
- endTime: (f + 1) * l.duration / g.length,
5684
+ startTime: b * l.duration / g.length,
5685
+ endTime: (b + 1) * l.duration / g.length,
5686
5686
  duration: l.duration / g.length,
5687
5687
  intensity: 0.6
5688
5688
  })),
@@ -5707,12 +5707,12 @@ class Be {
5707
5707
  if (r.visemes && r.visemes.length > 0) {
5708
5708
  console.log("Deepgram: Generating lip-sync animation from", r.visemes.length, "visemes");
5709
5709
  for (let c = 0; c < r.visemes.length; c++) {
5710
- const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, f = d.intensity;
5710
+ const d = r.visemes[c], g = d.startTime * 1e3, x = d.duration * 1e3, b = d.intensity;
5711
5711
  h.push({
5712
5712
  template: { name: "viseme" },
5713
5713
  ts: [g - Math.min(60, 2 * x / 3), g + Math.min(25, x / 2), g + x + Math.min(60, x / 2)],
5714
5714
  vs: {
5715
- ["viseme_" + d.viseme]: [null, f, 0]
5715
+ ["viseme_" + d.viseme]: [null, b, 0]
5716
5716
  }
5717
5717
  });
5718
5718
  }
@@ -6146,7 +6146,7 @@ class Be {
6146
6146
  */
6147
6147
  lookAtCamera(t) {
6148
6148
  let e;
6149
- if (this.speakTo && (e = new b.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(ve, Re).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
6149
+ if (this.speakTo && (e = new f.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), Re.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), ve.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(Re, ve).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
6150
6150
  if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
6151
6151
  if (this.avatar.avatarIgnoreCamera) {
6152
6152
  this.lookAhead(t);
@@ -6159,16 +6159,16 @@ class Be {
6159
6159
  this.lookAt(null, null, t);
6160
6160
  return;
6161
6161
  }
6162
- this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]);
6163
- const n = new b.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6162
+ this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), Re.setFromMatrixPosition(this.objectLeftEye.matrixWorld), ve.setFromMatrixPosition(this.objectRightEye.matrixWorld), Re.add(ve).divideScalar(2), _.copy(this.armature.quaternion), _.multiply(this.poseTarget.props["Hips.quaternion"]), _.multiply(this.poseTarget.props["Spine.quaternion"]), _.multiply(this.poseTarget.props["Spine1.quaternion"]), _.multiply(this.poseTarget.props["Spine2.quaternion"]), _.multiply(this.poseTarget.props["Neck.quaternion"]), _.multiply(this.poseTarget.props["Head.quaternion"]);
6163
+ const n = new f.Vector3().subVectors(e, Re).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
6164
6164
  V.set(s, i, 0, "YXZ");
6165
- const l = new b.Quaternion().setFromEuler(V), u = new b.Quaternion().copy(l).multiply(Q.clone().invert());
6165
+ const l = new f.Quaternion().setFromEuler(V), u = new f.Quaternion().copy(l).multiply(_.clone().invert());
6166
6166
  V.setFromQuaternion(u, "YXZ");
6167
6167
  let r = V.x / (40 / 24) + 0.2, h = V.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), c = Math.min(0.8, Math.max(-0.8, h)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6168
6168
  if (t) {
6169
- let x = this.animQueue.findIndex((R) => R.template.name === "lookat");
6169
+ let x = this.animQueue.findIndex((I) => I.template.name === "lookat");
6170
6170
  x !== -1 && this.animQueue.splice(x, 1);
6171
- const f = {
6171
+ const b = {
6172
6172
  name: "lookat",
6173
6173
  dt: [750, t],
6174
6174
  vs: {
@@ -6183,7 +6183,7 @@ class Be {
6183
6183
  headMove: [0]
6184
6184
  }
6185
6185
  };
6186
- this.animQueue.push(this.animFactory(f));
6186
+ this.animQueue.push(this.animFactory(b));
6187
6187
  }
6188
6188
  }
6189
6189
  /**
@@ -6196,24 +6196,24 @@ class Be {
6196
6196
  if (!this.camera) return;
6197
6197
  const i = this.nodeAvatar.getBoundingClientRect();
6198
6198
  this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
6199
- const s = new b.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new b.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new b.Vector3().addVectors(s, o).divideScalar(2);
6199
+ const s = new f.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new f.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new f.Vector3().addVectors(s, o).divideScalar(2);
6200
6200
  l.project(this.camera);
6201
6201
  let u = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
6202
- t === null && (t = u), e === null && (e = r), Q.copy(this.armature.quaternion), Q.multiply(this.poseTarget.props["Hips.quaternion"]), Q.multiply(this.poseTarget.props["Spine.quaternion"]), Q.multiply(this.poseTarget.props["Spine1.quaternion"]), Q.multiply(this.poseTarget.props["Spine2.quaternion"]), Q.multiply(this.poseTarget.props["Neck.quaternion"]), Q.multiply(this.poseTarget.props["Head.quaternion"]), V.setFromQuaternion(Q);
6203
- let h = V.x / (40 / 24), a = V.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - u, u), x = Math.max(window.innerHeight - r, r), f = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - h + c, R = this.convertRange(t, [u - g, u + g], [-0.8, 0.8]) - a + d;
6204
- f = Math.min(0.6, Math.max(-0.3, f)), R = Math.min(0.8, Math.max(-0.8, R));
6205
- let F = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6202
+ t === null && (t = u), 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"]), V.setFromQuaternion(_);
6203
+ let h = V.x / (40 / 24), a = V.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - u, u), x = Math.max(window.innerHeight - r, r), b = this.convertRange(e, [r - x, r + x], [-0.3, 0.6]) - h + c, I = this.convertRange(t, [u - g, u + g], [-0.8, 0.8]) - a + d;
6204
+ b = Math.min(0.6, Math.max(-0.3, b)), I = Math.min(0.8, Math.max(-0.8, I));
6205
+ let H = (Math.random() - 0.5) / 4, m = (Math.random() - 0.5) / 4;
6206
6206
  if (n) {
6207
- let H = this.animQueue.findIndex((y) => y.template.name === "lookat");
6208
- H !== -1 && this.animQueue.splice(H, 1);
6207
+ let T = this.animQueue.findIndex((y) => y.template.name === "lookat");
6208
+ T !== -1 && this.animQueue.splice(T, 1);
6209
6209
  const k = {
6210
6210
  name: "lookat",
6211
6211
  dt: [750, n],
6212
6212
  vs: {
6213
- bodyRotateX: [f + F],
6214
- bodyRotateY: [R + p],
6215
- eyesRotateX: [-3 * F + 0.1],
6216
- eyesRotateY: [-5 * p],
6213
+ bodyRotateX: [b + H],
6214
+ bodyRotateY: [I + m],
6215
+ eyesRotateX: [-3 * H + 0.1],
6216
+ eyesRotateY: [-5 * m],
6217
6217
  browInnerUp: [[0, 0.7]],
6218
6218
  mouthLeft: [[0, 0.7]],
6219
6219
  mouthRight: [[0, 0.7]],
@@ -6232,14 +6232,14 @@ class Be {
6232
6232
  */
6233
6233
  touchAt(t, e) {
6234
6234
  if (!this.camera) return;
6235
- const n = this.nodeAvatar.getBoundingClientRect(), i = new b.Vector2(
6235
+ const n = this.nodeAvatar.getBoundingClientRect(), i = new f.Vector2(
6236
6236
  (t - n.left) / n.width * 2 - 1,
6237
6237
  -((e - n.top) / n.height) * 2 + 1
6238
- ), s = new b.Raycaster();
6238
+ ), s = new f.Raycaster();
6239
6239
  s.setFromCamera(i, this.camera);
6240
6240
  const o = s.intersectObject(this.armature);
6241
6241
  if (o.length > 0) {
6242
- const l = o[0].point, u = new b.Vector3(), r = new b.Vector3();
6242
+ const l = o[0].point, u = new f.Vector3(), r = new f.Vector3();
6243
6243
  this.objectLeftArm.getWorldPosition(u), this.objectRightArm.getWorldPosition(r);
6244
6244
  const h = u.distanceToSquared(l), a = r.distanceToSquared(l);
6245
6245
  h < a ? (this.ikSolve({
@@ -6283,7 +6283,7 @@ class Be {
6283
6283
  { link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
6284
6284
  { link: "LeftArm", minx: -1.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -1, maxz: 3 }
6285
6285
  ]
6286
- }, new b.Vector3(
6286
+ }, new f.Vector3(
6287
6287
  this.gaussianRandom(0, 0.5),
6288
6288
  this.gaussianRandom(-0.8, -0.2),
6289
6289
  this.gaussianRandom(0, 0.5)
@@ -6295,15 +6295,15 @@ class Be {
6295
6295
  { link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5 },
6296
6296
  { link: "RightArm" }
6297
6297
  ]
6298
- }, new b.Vector3(
6298
+ }, new f.Vector3(
6299
6299
  this.gaussianRandom(-0.5, 0),
6300
6300
  this.gaussianRandom(-0.8, -0.2),
6301
6301
  this.gaussianRandom(0, 0.5)
6302
6302
  ), !0);
6303
6303
  const n = [], i = [];
6304
6304
  n.push(100 + Math.round(Math.random() * 500)), i.push({ duration: 1e3, props: {
6305
- "LeftHand.quaternion": new b.Quaternion().setFromEuler(new b.Euler(0, -1 - Math.random(), 0)),
6306
- "RightHand.quaternion": new b.Quaternion().setFromEuler(new b.Euler(0, 1 + Math.random(), 0))
6305
+ "LeftHand.quaternion": new f.Quaternion().setFromEuler(new f.Euler(0, -1 - Math.random(), 0)),
6306
+ "RightHand.quaternion": new f.Quaternion().setFromEuler(new f.Euler(0, 1 + Math.random(), 0))
6307
6307
  } }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm"].forEach((o) => {
6308
6308
  i[0].props[o + ".quaternion"] = this.ikMesh.getObjectByName(o).quaternion.clone();
6309
6309
  }), n.push(1e3 + Math.round(Math.random() * 500)), i.push({ duration: 2e3, props: {} }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm", "LeftHand", "RightHand"].forEach((o) => {
@@ -6421,11 +6421,22 @@ class Be {
6421
6421
  Spine01: "Spine1",
6422
6422
  Spine02: "Spine2",
6423
6423
  Spine03: "Spine2",
6424
+ Spine1: "Spine1",
6425
+ Spine2: "Spine2",
6426
+ Spine: "Spine1",
6427
+ // Head and neck
6428
+ Head: "Head",
6429
+ Neck: "Neck",
6430
+ Neck1: "Neck",
6431
+ Neck2: "Neck",
6424
6432
  // Left arm mapping
6425
6433
  L_Upperarm: "LeftArm",
6426
6434
  L_Forearm: "LeftForeArm",
6427
6435
  L_Hand: "LeftHand",
6428
6436
  L_Shoulder: "LeftShoulder",
6437
+ L_Clavicle: "LeftShoulder",
6438
+ L_UpperArm: "LeftArm",
6439
+ L_ForeArm: "LeftForeArm",
6429
6440
  L_Index1: "LeftHandIndex1",
6430
6441
  L_Index2: "LeftHandIndex2",
6431
6442
  L_Index3: "LeftHandIndex3",
@@ -6449,6 +6460,9 @@ class Be {
6449
6460
  R_Forearm: "RightForeArm",
6450
6461
  R_Hand: "RightHand",
6451
6462
  R_Shoulder: "RightShoulder",
6463
+ R_Clavicle: "RightShoulder",
6464
+ R_UpperArm: "RightArm",
6465
+ R_ForeArm: "RightForeArm",
6452
6466
  R_Index1: "RightHandIndex1",
6453
6467
  R_Index2: "RightHandIndex2",
6454
6468
  R_Index3: "RightHandIndex3",
@@ -6471,9 +6485,17 @@ class Be {
6471
6485
  L_Thigh: "LeftUpLeg",
6472
6486
  L_Calf: "LeftLeg",
6473
6487
  L_Foot: "LeftFoot",
6488
+ L_UpLeg: "LeftUpLeg",
6489
+ L_Leg: "LeftLeg",
6474
6490
  R_Thigh: "RightUpLeg",
6475
6491
  R_Calf: "RightLeg",
6476
- R_Foot: "RightFoot"
6492
+ R_Foot: "RightFoot",
6493
+ R_UpLeg: "RightUpLeg",
6494
+ R_Leg: "RightLeg",
6495
+ // Root/Hips
6496
+ Hips: "Hips",
6497
+ Root: "Hips",
6498
+ Pelvis: "Hips"
6477
6499
  };
6478
6500
  if (i[n]) {
6479
6501
  const a = i[n];
@@ -6529,9 +6551,37 @@ class Be {
6529
6551
  if (e.has(c))
6530
6552
  return c;
6531
6553
  }
6554
+ if (s.match(/^[rl]_clavicle/)) {
6555
+ const c = `${s.startsWith("r") ? "Right" : "Left"}Shoulder`;
6556
+ if (e.has(c))
6557
+ return c;
6558
+ }
6559
+ if (s.match(/^[rl]_shoulder/)) {
6560
+ const c = `${s.startsWith("r") ? "Right" : "Left"}Shoulder`;
6561
+ if (e.has(c))
6562
+ return c;
6563
+ }
6564
+ if (s.match(/^spine0?(\d+)$/)) {
6565
+ const a = s.match(/^spine0?(\d+)$/)[1];
6566
+ if (a === "1") {
6567
+ if (e.has("Spine1")) return "Spine1";
6568
+ } else if ((a === "2" || a === "3") && e.has("Spine2"))
6569
+ return "Spine2";
6570
+ }
6571
+ if (s.match(/^neck\d*$/) && e.has("Neck"))
6572
+ return "Neck";
6573
+ if (s === "head" && e.has("Head"))
6574
+ return "Head";
6575
+ if (s.match(/^(hips|pelvis|root)$/) && e.has("Hips"))
6576
+ return "Hips";
6532
6577
  for (const a of e)
6533
6578
  if (a.toLowerCase() === s)
6534
6579
  return a;
6580
+ for (const a of e) {
6581
+ const c = a.toLowerCase();
6582
+ if ((c.includes(s) || s.includes(c)) && (c === s || c.replace(/[^a-z0-9]/g, "") === s.replace(/[^a-z0-9]/g, "")))
6583
+ return a;
6584
+ }
6535
6585
  return null;
6536
6586
  }
6537
6587
  /**
@@ -6542,51 +6592,65 @@ class Be {
6542
6592
  * @returns {THREE.AnimationClip} Filtered animation clip with mapped bone names
6543
6593
  */
6544
6594
  filterAnimationTracks(t, e) {
6545
- const n = [], i = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map();
6546
- return this._loggedAvailableBones || (console.log(
6547
- "Available avatar bones:",
6548
- Array.from(e).sort().slice(0, 50).join(", "),
6549
- e.size > 50 ? `... (${e.size} total)` : ""
6550
- ), this._loggedAvailableBones = !0), t.tracks.forEach((o) => {
6551
- const l = o.name.split("."), u = l[0], r = l[1], h = this.mapBoneName(u, e);
6552
- if (h) {
6553
- const a = `${h}.${r}`, c = o.clone();
6554
- c.name = a;
6555
- const d = h.includes("Arm") || h.includes("Hand") || h.includes("Shoulder"), g = h.includes("ForeArm");
6556
- if (d && (r === "quaternion" || r === "rotation")) {
6557
- if (r === "quaternion" && c.values && c.values.length >= 4) {
6558
- const x = c.times.length;
6559
- for (let f = 0; f < x; f++) {
6560
- const R = f * 4;
6561
- if (R + 3 < c.values.length) {
6562
- let F = c.values[R], p = c.values[R + 1], H = c.values[R + 2], k = c.values[R + 3];
6563
- if (g || h.includes("Hand")) {
6564
- const y = Math.PI, T = Math.cos(y / 2), E = Math.sin(y / 2), O = T * k - E * F, te = T * F + E * k, S = T * p - E * H, G = T * H + E * p;
6565
- F = te, p = S, H = G, k = O;
6595
+ const n = [], i = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Set();
6596
+ this._loggedAvailableBones || (console.log("Available avatar bones:", Array.from(e).sort().join(", ")), this._loggedAvailableBones = !0), t.tracks.forEach((u) => {
6597
+ const h = u.name.split(".")[0];
6598
+ o.add(h);
6599
+ }), console.log(`
6600
+ === FBX Animation "${t.name}" Bone Analysis ===`), console.log("FBX bone names in animation:", Array.from(o).sort().join(", ")), console.log(`Total FBX bones: ${o.size}, Avatar bones: ${e.size}
6601
+ `), t.tracks.forEach((u) => {
6602
+ const r = u.name.split("."), h = r[0], a = r[1], c = this.mapBoneName(h, e);
6603
+ if (c) {
6604
+ const d = `${c}.${a}`, g = u.clone();
6605
+ g.name = d;
6606
+ const x = c.includes("Arm") || c.includes("Hand") || c.includes("Shoulder"), b = c.includes("ForeArm");
6607
+ if (x && (a === "quaternion" || a === "rotation")) {
6608
+ if (a === "quaternion" && g.values && g.values.length >= 4) {
6609
+ const I = g.times.length;
6610
+ for (let H = 0; H < I; H++) {
6611
+ const m = H * 4;
6612
+ if (m + 3 < g.values.length) {
6613
+ let T = g.values[m], k = g.values[m + 1], y = g.values[m + 2], M = g.values[m + 3];
6614
+ if (b || c.includes("Hand")) {
6615
+ const P = Math.PI, D = Math.cos(P / 2), J = Math.sin(P / 2), S = D * M - J * T, G = D * T + J * M, Q = D * k - J * y, Z = D * y + J * k;
6616
+ T = G, k = Q, y = Z, M = S;
6566
6617
  }
6567
- c.values[R] = F, c.values[R + 1] = p, c.values[R + 2] = H, c.values[R + 3] = k;
6618
+ g.values[m] = T, g.values[m + 1] = k, g.values[m + 2] = y, g.values[m + 3] = M;
6568
6619
  }
6569
6620
  }
6570
- } else if (r === "rotation" && c.values && c.values.length >= 3) {
6571
- const x = c.times.length;
6572
- for (let f = 0; f < x; f++) {
6573
- const R = f * 3;
6574
- R + 2 < c.values.length && (g || h.includes("Hand")) && (c.values[R + 1] += Math.PI);
6621
+ } else if (a === "rotation" && g.values && g.values.length >= 3) {
6622
+ const I = g.times.length;
6623
+ for (let H = 0; H < I; H++) {
6624
+ const m = H * 3;
6625
+ m + 2 < g.values.length && (b || c.includes("Hand")) && (g.values[m + 1] += Math.PI);
6575
6626
  }
6576
6627
  }
6577
6628
  }
6578
- n.push(c), u !== h && s.set(u, h);
6629
+ n.push(g), h !== c && s.set(h, c);
6579
6630
  } else
6580
- i.add(u);
6581
- }), s.size > 0 && console.info(
6582
- `FBX animation "${t.name}": Mapped ${s.size} bone(s) to avatar skeleton:`,
6583
- Array.from(s.entries()).slice(0, 5).map(([o, l]) => `${o} → ${l}`).join(", "),
6584
- s.size > 5 ? "..." : ""
6585
- ), i.size > 0 && console.warn(
6586
- `FBX animation "${t.name}" contains tracks for ${i.size} bone(s) that couldn't be mapped:`,
6587
- Array.from(i).slice(0, 10).join(", "),
6588
- i.size > 10 ? "..." : ""
6589
- ), n.length > 0 ? console.info(`Filtered ${t.tracks.length} tracks down to ${n.length} valid tracks (${s.size} mapped)`) : console.error(`No valid tracks found for animation "${t.name}". All bones are missing or couldn't be mapped.`), n.length === 0 ? null : new b.AnimationClip(t.name, t.duration, n);
6631
+ i.add(h);
6632
+ }), console.log(`
6633
+ === Mapping Results for "${t.name}" ===`), s.size > 0 && (console.info(`✓ Successfully mapped ${s.size} bone(s):`), Array.from(s.entries()).forEach(([u, r]) => {
6634
+ console.log(` ${u} → ${r}`);
6635
+ })), i.size > 0 && (console.warn(`
6636
+ Could not map ${i.size} bone(s):`), Array.from(i).sort().forEach((u) => {
6637
+ console.log(` - ${u}`);
6638
+ const r = u.replace(/^(CC_Base_|mixamorig)/i, "").replace(/^[RL]_/, (a) => a.toLowerCase()), h = [];
6639
+ for (const a of e) {
6640
+ const c = a.toLowerCase(), d = r.toLowerCase();
6641
+ (c.includes(d) || d.includes(c)) && h.push(a);
6642
+ }
6643
+ h.length > 0 && console.log(` → Possible matches: ${h.slice(0, 3).join(", ")}`);
6644
+ }));
6645
+ const l = /* @__PURE__ */ new Set();
6646
+ return o.forEach((u) => {
6647
+ e.has(u) && !s.has(u) && l.add(u);
6648
+ }), l.size > 0 && (console.info(`
6649
+ ✓ Direct matches (no mapping needed): ${l.size} bone(s)`), Array.from(l).sort().slice(0, 10).forEach((u) => {
6650
+ console.log(` - ${u}`);
6651
+ }), l.size > 10 && console.log(` ... and ${l.size - 10} more`)), console.log(`
6652
+ === Summary ===`), console.log(`Total FBX tracks: ${t.tracks.length}`), console.log(`Valid tracks: ${n.length}`), console.log(`Mapped bones: ${s.size}`), console.log(`Direct matches: ${l.size}`), console.log(`Missing bones: ${i.size}`), console.log(`========================================
6653
+ `), n.length === 0 && console.error(`No valid tracks found for animation "${t.name}". All bones are missing or couldn't be mapped.`), n.length === 0 ? null : new f.AnimationClip(t.name, t.duration, n);
6590
6654
  }
6591
6655
  async playAnimation(t, e = null, n = 10, i = 0, s = 0.01, o = !1) {
6592
6656
  if (!this.armature) return;
@@ -6596,9 +6660,9 @@ class Be {
6596
6660
  let u = this.animQueue.find((a) => a.template.name === "pose");
6597
6661
  u && (u.ts[0] = 1 / 0), Object.entries(l.pose.props).forEach((a) => {
6598
6662
  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;
6599
- }), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new b.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
6663
+ }), 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 });
6600
6664
  const r = Math.ceil(n / l.clip.duration), h = this.mixer.clipAction(l.clip);
6601
- h.setLoop(b.LoopRepeat, r), h.clampWhenFinished = !0, this.currentFBXAction = h;
6665
+ h.setLoop(f.LoopRepeat, r), h.clampWhenFinished = !0, this.currentFBXAction = h;
6602
6666
  try {
6603
6667
  h.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
6604
6668
  } catch (a) {
@@ -6624,7 +6688,7 @@ class Be {
6624
6688
  } catch (c) {
6625
6689
  console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, c);
6626
6690
  }
6627
- const h = new Ne();
6691
+ const h = new Be();
6628
6692
  let a;
6629
6693
  try {
6630
6694
  a = await h.loadAsync(t, e);
@@ -6656,20 +6720,20 @@ class Be {
6656
6720
  }
6657
6721
  c = g;
6658
6722
  const x = {};
6659
- c.tracks.forEach((R) => {
6660
- R.name = R.name.replaceAll("mixamorig", "");
6661
- const F = R.name.split(".");
6662
- if (F[1] === "position") {
6663
- for (let p = 0; p < R.values.length; p++)
6664
- R.values[p] = R.values[p] * s;
6665
- x[R.name] = new b.Vector3(R.values[0], R.values[1], R.values[2]);
6666
- } else F[1] === "quaternion" ? x[R.name] = new b.Quaternion(R.values[0], R.values[1], R.values[2], R.values[3]) : F[1] === "rotation" && (x[F[0] + ".quaternion"] = new b.Quaternion().setFromEuler(new b.Euler(R.values[0], R.values[1], R.values[2], "XYZ")).normalize());
6723
+ c.tracks.forEach((I) => {
6724
+ I.name = I.name.replaceAll("mixamorig", "");
6725
+ const H = I.name.split(".");
6726
+ if (H[1] === "position") {
6727
+ for (let m = 0; m < I.values.length; m++)
6728
+ I.values[m] = I.values[m] * s;
6729
+ x[I.name] = new f.Vector3(I.values[0], I.values[1], I.values[2]);
6730
+ } else H[1] === "quaternion" ? x[I.name] = new f.Quaternion(I.values[0], I.values[1], I.values[2], I.values[3]) : H[1] === "rotation" && (x[H[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(I.values[0], I.values[1], I.values[2], "XYZ")).normalize());
6667
6731
  });
6668
- const f = { props: x };
6669
- x["Hips.position"] && (x["Hips.position"].y < 0.5 ? f.lying = !0 : f.standing = !0), this.animClips.push({
6732
+ const b = { props: x };
6733
+ x["Hips.position"] && (x["Hips.position"].y < 0.5 ? b.lying = !0 : b.standing = !0), this.animClips.push({
6670
6734
  url: t + "-" + i,
6671
6735
  clip: c,
6672
- pose: f
6736
+ pose: b
6673
6737
  }), this.playAnimation(t, e, n, i, s);
6674
6738
  } else {
6675
6739
  const c = "Animation " + t + " (ndx=" + i + ") not found";
@@ -6707,14 +6771,14 @@ class Be {
6707
6771
  let l = this.animQueue.find((u) => u.template.name === "pose");
6708
6772
  l && (l.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(o);
6709
6773
  } else {
6710
- let u = await new Ne().loadAsync(t, e);
6774
+ let u = await new Be().loadAsync(t, e);
6711
6775
  if (u && u.animations && u.animations[i]) {
6712
6776
  let r = u.animations[i];
6713
6777
  const h = {};
6714
6778
  r.tracks.forEach((c) => {
6715
6779
  c.name = c.name.replaceAll("mixamorig", "");
6716
6780
  const d = c.name.split(".");
6717
- d[1] === "position" ? h[c.name] = new b.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? h[c.name] = new b.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (h[d[0] + ".quaternion"] = new b.Quaternion().setFromEuler(new b.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
6781
+ d[1] === "position" ? h[c.name] = new f.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? h[c.name] = new f.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (h[d[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
6718
6782
  });
6719
6783
  const a = { props: h };
6720
6784
  h["Hips.position"] && (h["Hips.position"].y < 0.5 ? a.lying = !0 : a.standing = !0), this.animPoses.push({
@@ -6747,7 +6811,7 @@ class Be {
6747
6811
  if (s) {
6748
6812
  this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
6749
6813
  let l = this.animQueue.findIndex((u) => u.template.name === "talkinghands");
6750
- l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((u) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new b.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new b.Quaternion(0, 1, 0, 0), -0.25));
6814
+ l !== -1 && (this.animQueue[l].ts = this.animQueue[l].ts.map((u) => 0)), this.gesture = this.propsToThreeObjects(s), n && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25));
6751
6815
  for (let [u, r] of Object.entries(this.gesture))
6752
6816
  r.t = this.animClock, r.d = i, this.poseTarget.props.hasOwnProperty(u) && (this.poseTarget.props[u].copy(r), this.poseTarget.props[u].t = this.animClock, this.poseTarget.props[u].d = i);
6753
6817
  e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, i), 1e3 * e));
@@ -6762,7 +6826,7 @@ class Be {
6762
6826
  const c = [];
6763
6827
  for (let x = 1; x < l.ts.length; x++) c.push(l.ts[x] - l.ts[x - 1]);
6764
6828
  const d = o.template?.rescale || c.map((x) => x / h), g = e * 1e3 - h;
6765
- l.ts = l.ts.map((x, f, R) => f === 0 ? u : R[f - 1] + c[f - 1] + d[f - 1] * g);
6829
+ l.ts = l.ts.map((x, b, I) => b === 0 ? u : I[b - 1] + c[b - 1] + d[b - 1] * g);
6766
6830
  } else {
6767
6831
  const c = e * 1e3 / h;
6768
6832
  l.ts = l.ts.map((d) => u + c * (d - u));
@@ -6795,34 +6859,34 @@ class Be {
6795
6859
  * @param {numeric} [d=null] If set, apply in d milliseconds
6796
6860
  */
6797
6861
  ikSolve(t, e = null, n = !1, i = null) {
6798
- const s = new b.Vector3(), o = new b.Vector3(), l = new b.Vector3(), u = new b.Vector3(), r = new b.Quaternion(), h = new b.Vector3(), a = new b.Vector3(), c = new b.Vector3(), d = this.ikMesh.getObjectByName(t.root);
6862
+ const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(), u = new f.Vector3(), r = new f.Quaternion(), h = new f.Vector3(), a = new f.Vector3(), c = new f.Vector3(), d = this.ikMesh.getObjectByName(t.root);
6799
6863
  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);
6800
6864
  const g = this.ikMesh.getObjectByName(t.effector), x = t.links;
6801
- x.forEach((R) => {
6802
- R.bone = this.ikMesh.getObjectByName(R.link), R.bone.quaternion.copy(this.getPoseTemplateProp(R.link + ".quaternion"));
6865
+ x.forEach((I) => {
6866
+ I.bone = this.ikMesh.getObjectByName(I.link), I.bone.quaternion.copy(this.getPoseTemplateProp(I.link + ".quaternion"));
6803
6867
  }), d.updateMatrixWorld(!0);
6804
- const f = t.iterations || 10;
6868
+ const b = t.iterations || 10;
6805
6869
  if (e)
6806
- for (let R = 0; R < f; R++) {
6807
- let F = !1;
6808
- for (let p = 0, H = x.length; p < H; p++) {
6809
- const k = x[p].bone;
6870
+ for (let I = 0; I < b; I++) {
6871
+ let H = !1;
6872
+ for (let m = 0, T = x.length; m < T; m++) {
6873
+ const k = x[m].bone;
6810
6874
  k.matrixWorld.decompose(u, r, h), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, u), l.applyQuaternion(r), l.normalize(), s.subVectors(e, u), s.applyQuaternion(r), s.normalize();
6811
6875
  let y = s.dot(l);
6812
- y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (x[p].minAngle !== void 0 && y < x[p].minAngle && (y = x[p].minAngle), x[p].maxAngle !== void 0 && y > x[p].maxAngle && (y = x[p].maxAngle), a.crossVectors(l, s), a.normalize(), Q.setFromAxisAngle(a, y), k.quaternion.multiply(Q), k.rotation.setFromVector3(c.setFromEuler(k.rotation).clamp(new b.Vector3(
6813
- x[p].minx !== void 0 ? x[p].minx : -1 / 0,
6814
- x[p].miny !== void 0 ? x[p].miny : -1 / 0,
6815
- x[p].minz !== void 0 ? x[p].minz : -1 / 0
6816
- ), new b.Vector3(
6817
- x[p].maxx !== void 0 ? x[p].maxx : 1 / 0,
6818
- x[p].maxy !== void 0 ? x[p].maxy : 1 / 0,
6819
- x[p].maxz !== void 0 ? x[p].maxz : 1 / 0
6820
- ))), k.updateMatrixWorld(!0), F = !0);
6876
+ y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (x[m].minAngle !== void 0 && y < x[m].minAngle && (y = x[m].minAngle), x[m].maxAngle !== void 0 && y > x[m].maxAngle && (y = x[m].maxAngle), a.crossVectors(l, s), a.normalize(), _.setFromAxisAngle(a, y), k.quaternion.multiply(_), k.rotation.setFromVector3(c.setFromEuler(k.rotation).clamp(new f.Vector3(
6877
+ x[m].minx !== void 0 ? x[m].minx : -1 / 0,
6878
+ x[m].miny !== void 0 ? x[m].miny : -1 / 0,
6879
+ x[m].minz !== void 0 ? x[m].minz : -1 / 0
6880
+ ), new f.Vector3(
6881
+ x[m].maxx !== void 0 ? x[m].maxx : 1 / 0,
6882
+ x[m].maxy !== void 0 ? x[m].maxy : 1 / 0,
6883
+ x[m].maxz !== void 0 ? x[m].maxz : 1 / 0
6884
+ ))), k.updateMatrixWorld(!0), H = !0);
6821
6885
  }
6822
- if (!F) break;
6886
+ if (!H) break;
6823
6887
  }
6824
- i && x.forEach((R) => {
6825
- this.poseTarget.props[R.link + ".quaternion"].copy(R.bone.quaternion), this.poseTarget.props[R.link + ".quaternion"].t = this.animClock, this.poseTarget.props[R.link + ".quaternion"].d = i;
6888
+ i && x.forEach((I) => {
6889
+ 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;
6826
6890
  });
6827
6891
  }
6828
6892
  /**
@@ -6882,16 +6946,16 @@ function Fe() {
6882
6946
  };
6883
6947
  }
6884
6948
  function kt() {
6885
- const Z = Fe(), t = [];
6886
- return Object.entries(Z.voices).forEach(([e, n]) => {
6949
+ const X = Fe(), t = [];
6950
+ return Object.entries(X.voices).forEach(([e, n]) => {
6887
6951
  t.push({
6888
6952
  value: n,
6889
- label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${Z.service})`
6953
+ label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${X.service})`
6890
6954
  });
6891
6955
  }), t;
6892
6956
  }
6893
6957
  const Ve = Me(({
6894
- avatarUrl: Z = "/avatars/brunette.glb",
6958
+ avatarUrl: X = "/avatars/brunette.glb",
6895
6959
  avatarBody: t = "F",
6896
6960
  mood: e = "neutral",
6897
6961
  ttsLang: n = "en",
@@ -6910,15 +6974,15 @@ const Ve = Me(({
6910
6974
  },
6911
6975
  className: g = "",
6912
6976
  style: x = {},
6913
- animations: f = {}
6914
- }, R) => {
6915
- const F = N(null), p = N(null), H = N(r), k = N(null), y = N(null), T = N(!1), E = N({ remainingText: null, originalText: null, options: null }), O = N([]), te = N(0), [S, G] = ce(!0), [_, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
6977
+ animations: b = {}
6978
+ }, I) => {
6979
+ const H = O(null), m = O(null), T = O(r), k = O(null), y = O(null), M = O(!1), P = O({ remainingText: null, originalText: null, options: null }), D = O([]), J = O(0), [S, G] = ce(!0), [Q, Z] = ce(null), [ee, se] = ce(!1), [ae, pe] = ce(!1);
6916
6980
  de(() => {
6917
- T.current = ae;
6981
+ M.current = ae;
6918
6982
  }, [ae]), de(() => {
6919
- H.current = r;
6983
+ T.current = r;
6920
6984
  }, [r]);
6921
- const ee = Fe(), le = i || ee.service;
6985
+ const te = Fe(), le = i || te.service;
6922
6986
  let U;
6923
6987
  le === "browser" ? U = {
6924
6988
  service: "browser",
@@ -6928,22 +6992,22 @@ const Ve = Me(({
6928
6992
  } : le === "elevenlabs" ? U = {
6929
6993
  service: "elevenlabs",
6930
6994
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
6931
- apiKey: o || ee.apiKey,
6932
- defaultVoice: s || ee.defaultVoice || Ie.defaultVoice,
6933
- voices: ee.voices || Ie.voices
6995
+ apiKey: o || te.apiKey,
6996
+ defaultVoice: s || te.defaultVoice || Ie.defaultVoice,
6997
+ voices: te.voices || Ie.voices
6934
6998
  } : le === "deepgram" ? U = {
6935
6999
  service: "deepgram",
6936
7000
  endpoint: "https://api.deepgram.com/v1/speak",
6937
- apiKey: o || ee.apiKey,
6938
- defaultVoice: s || ee.defaultVoice || Te.defaultVoice,
6939
- voices: ee.voices || Te.voices
7001
+ apiKey: o || te.apiKey,
7002
+ defaultVoice: s || te.defaultVoice || Te.defaultVoice,
7003
+ voices: te.voices || Te.voices
6940
7004
  } : U = {
6941
- ...ee,
7005
+ ...te,
6942
7006
  // Override API key if provided via props
6943
- apiKey: o !== null ? o : ee.apiKey
7007
+ apiKey: o !== null ? o : te.apiKey
6944
7008
  };
6945
- const v = {
6946
- url: Z,
7009
+ const R = {
7010
+ url: X,
6947
7011
  body: t,
6948
7012
  avatarMood: e,
6949
7013
  ttsLang: le === "browser" ? "en-US" : n,
@@ -6952,88 +7016,88 @@ const Ve = Me(({
6952
7016
  showFullAvatar: r,
6953
7017
  bodyMovement: l,
6954
7018
  movementIntensity: u
6955
- }, I = {
7019
+ }, v = {
6956
7020
  ttsEndpoint: U.endpoint,
6957
7021
  ttsApikey: U.apiKey,
6958
7022
  ttsService: le,
6959
7023
  lipsyncModules: ["en"],
6960
7024
  cameraView: h
6961
- }, w = P(async () => {
6962
- if (!(!F.current || p.current))
7025
+ }, w = F(async () => {
7026
+ if (!(!H.current || m.current))
6963
7027
  try {
6964
- if (G(!0), X(null), p.current = new Be(F.current, I), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), f && Object.keys(f).length > 0 && (p.current.customAnimations = f), await p.current.showAvatar(v, (D) => {
6965
- if (D.lengthComputable) {
6966
- const J = Math.min(100, Math.round(D.loaded / D.total * 100));
6967
- c(J);
7028
+ if (G(!0), Z(null), m.current = new Ne(H.current, v), m.current.controls && (m.current.controls.enableRotate = !1, m.current.controls.enableZoom = !1, m.current.controls.enablePan = !1, m.current.controls.enableDamping = !1), b && Object.keys(b).length > 0 && (m.current.customAnimations = b), await m.current.showAvatar(R, (B) => {
7029
+ if (B.lengthComputable) {
7030
+ const $ = Math.min(100, Math.round(B.loaded / B.total * 100));
7031
+ c($);
6968
7032
  }
6969
- }), await new Promise((D) => {
6970
- const J = () => {
6971
- p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? D() : setTimeout(J, 100);
7033
+ }), await new Promise((B) => {
7034
+ const $ = () => {
7035
+ m.current.lipsync && Object.keys(m.current.lipsync).length > 0 ? B() : setTimeout($, 100);
6972
7036
  };
6973
- J();
6974
- }), p.current && p.current.setShowFullAvatar)
7037
+ $();
7038
+ }), m.current && m.current.setShowFullAvatar)
6975
7039
  try {
6976
- p.current.setShowFullAvatar(r);
6977
- } catch (D) {
6978
- console.warn("Error setting full body mode on initialization:", D);
7040
+ m.current.setShowFullAvatar(r);
7041
+ } catch (B) {
7042
+ console.warn("Error setting full body mode on initialization:", B);
6979
7043
  }
6980
- p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), G(!1), se(!0), a(p.current);
6981
- const B = () => {
6982
- document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
7044
+ m.current && m.current.controls && (m.current.controls.enableRotate = !1, m.current.controls.enableZoom = !1, m.current.controls.enablePan = !1, m.current.controls.enableDamping = !1, m.current.controls.update()), G(!1), se(!0), a(m.current);
7045
+ const N = () => {
7046
+ document.visibilityState === "visible" ? m.current?.start() : m.current?.stop();
6983
7047
  };
6984
- return document.addEventListener("visibilitychange", B), () => {
6985
- document.removeEventListener("visibilitychange", B);
7048
+ return document.addEventListener("visibilitychange", N), () => {
7049
+ document.removeEventListener("visibilitychange", N);
6986
7050
  };
6987
7051
  } catch (L) {
6988
- console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), G(!1), d(L);
7052
+ console.error("Error initializing TalkingHead:", L), Z(L.message || "Failed to initialize avatar"), G(!1), d(L);
6989
7053
  }
6990
- }, [Z, t, e, n, i, s, o, r, l, u, h]);
7054
+ }, [X, t, e, n, i, s, o, r, l, u, h]);
6991
7055
  de(() => (w(), () => {
6992
- p.current && (p.current.stop(), p.current.dispose(), p.current = null);
7056
+ m.current && (m.current.stop(), m.current.dispose(), m.current = null);
6993
7057
  }), [w]), de(() => {
6994
- if (!F.current || !p.current) return;
6995
- const L = new ResizeObserver((D) => {
6996
- for (const J of D)
6997
- p.current && p.current.onResize && p.current.onResize();
7058
+ if (!H.current || !m.current) return;
7059
+ const L = new ResizeObserver((B) => {
7060
+ for (const $ of B)
7061
+ m.current && m.current.onResize && m.current.onResize();
6998
7062
  });
6999
- L.observe(F.current);
7000
- const B = () => {
7001
- p.current && p.current.onResize && p.current.onResize();
7063
+ L.observe(H.current);
7064
+ const N = () => {
7065
+ m.current && m.current.onResize && m.current.onResize();
7002
7066
  };
7003
- return window.addEventListener("resize", B), () => {
7004
- L.disconnect(), window.removeEventListener("resize", B);
7067
+ return window.addEventListener("resize", N), () => {
7068
+ L.disconnect(), window.removeEventListener("resize", N);
7005
7069
  };
7006
- }, [$]);
7007
- const M = P(async () => {
7008
- if (p.current && p.current.audioCtx)
7070
+ }, [ee]);
7071
+ const E = F(async () => {
7072
+ if (m.current && m.current.audioCtx)
7009
7073
  try {
7010
- (p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
7074
+ (m.current.audioCtx.state === "suspended" || m.current.audioCtx.state === "interrupted") && (await m.current.audioCtx.resume(), console.log("Audio context resumed"));
7011
7075
  } catch (L) {
7012
7076
  console.warn("Failed to resume audio context:", L);
7013
7077
  }
7014
- }, []), W = P(async (L, B = {}) => {
7015
- if (p.current && $)
7078
+ }, []), W = F(async (L, N = {}) => {
7079
+ if (m.current && ee)
7016
7080
  try {
7017
- y.current && (clearInterval(y.current), y.current = null), k.current = { text: L, options: B }, E.current = { remainingText: null, originalText: null, options: null };
7018
- const D = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(D).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
7019
- O.current = J, te.current = 0, pe(!1), T.current = !1, await M();
7081
+ y.current && (clearInterval(y.current), y.current = null), k.current = { text: L, options: N }, P.current = { remainingText: null, originalText: null, options: null };
7082
+ const B = /[!\.\?\n\p{Extended_Pictographic}]/ug, $ = L.split(B).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
7083
+ D.current = $, J.current = 0, pe(!1), M.current = !1, await E();
7020
7084
  const ge = {
7021
- ...B,
7022
- lipsyncLang: B.lipsyncLang || v.lipsyncLang || "en"
7085
+ ...N,
7086
+ lipsyncLang: N.lipsyncLang || R.lipsyncLang || "en"
7023
7087
  };
7024
- if (B.onSpeechEnd && p.current) {
7025
- const Y = p.current;
7088
+ if (N.onSpeechEnd && m.current) {
7089
+ const Y = m.current;
7026
7090
  let ue = null, Se = 0;
7027
7091
  const Ae = 1200;
7028
7092
  let be = !1;
7029
7093
  ue = setInterval(() => {
7030
- if (Se++, T.current)
7094
+ if (Se++, M.current)
7031
7095
  return;
7032
7096
  if (Se > Ae) {
7033
- if (ue && (clearInterval(ue), ue = null, y.current = null), !be && !T.current) {
7097
+ if (ue && (clearInterval(ue), ue = null, y.current = null), !be && !M.current) {
7034
7098
  be = !0;
7035
7099
  try {
7036
- B.onSpeechEnd();
7100
+ N.onSpeechEnd();
7037
7101
  } catch (De) {
7038
7102
  console.error("Error in onSpeechEnd callback (timeout):", De);
7039
7103
  }
@@ -7041,11 +7105,11 @@ const Ve = Me(({
7041
7105
  return;
7042
7106
  }
7043
7107
  const ye = !Y.speechQueue || Y.speechQueue.length === 0, ke = !Y.audioPlaylist || Y.audioPlaylist.length === 0;
7044
- Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !T.current && setTimeout(() => {
7045
- if (Y && !T.current && Y.isSpeaking === !1 && (!Y.speechQueue || Y.speechQueue.length === 0) && (!Y.audioPlaylist || Y.audioPlaylist.length === 0) && Y.isAudioPlaying === !1 && !be && !T.current) {
7108
+ Y && Y.isSpeaking === !1 && ye && ke && Y.isAudioPlaying === !1 && !be && !M.current && setTimeout(() => {
7109
+ if (Y && !M.current && Y.isSpeaking === !1 && (!Y.speechQueue || Y.speechQueue.length === 0) && (!Y.audioPlaylist || Y.audioPlaylist.length === 0) && Y.isAudioPlaying === !1 && !be && !M.current) {
7046
7110
  be = !0, ue && (clearInterval(ue), ue = null, y.current = null);
7047
7111
  try {
7048
- B.onSpeechEnd();
7112
+ N.onSpeechEnd();
7049
7113
  } catch (Ze) {
7050
7114
  console.error("Error in onSpeechEnd callback:", Ze);
7051
7115
  }
@@ -7053,167 +7117,167 @@ const Ve = Me(({
7053
7117
  }, 100);
7054
7118
  }, 100), y.current = ue;
7055
7119
  }
7056
- p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge)) : setTimeout(async () => {
7057
- await M(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
7120
+ m.current.lipsync && Object.keys(m.current.lipsync).length > 0 ? (m.current.setSlowdownRate && m.current.setSlowdownRate(1.05), m.current.speakText(L, ge)) : setTimeout(async () => {
7121
+ await E(), m.current && m.current.lipsync && (m.current.setSlowdownRate && m.current.setSlowdownRate(1.05), m.current.speakText(L, ge));
7058
7122
  }, 100);
7059
- } catch (D) {
7060
- console.error("Error speaking text:", D), X(D.message || "Failed to speak text");
7123
+ } catch (B) {
7124
+ console.error("Error speaking text:", B), Z(B.message || "Failed to speak text");
7061
7125
  }
7062
- }, [$, M, v.lipsyncLang]), K = P(() => {
7063
- p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), k.current = null, pe(!1));
7064
- }, []), j = P(() => {
7065
- if (p.current && p.current.pauseSpeaking) {
7066
- const L = p.current;
7126
+ }, [ee, E, R.lipsyncLang]), K = F(() => {
7127
+ m.current && (m.current.stopSpeaking(), m.current.setSlowdownRate && m.current.setSlowdownRate(1), k.current = null, pe(!1));
7128
+ }, []), j = F(() => {
7129
+ if (m.current && m.current.pauseSpeaking) {
7130
+ const L = m.current;
7067
7131
  if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
7068
7132
  y.current && (clearInterval(y.current), y.current = null);
7069
- let D = "";
7070
- if (k.current && O.current.length > 0) {
7071
- const J = O.current.length, ge = L.speechQueue ? L.speechQueue.filter((Ae) => Ae && Ae.text && Array.isArray(Ae.text) && Ae.text.length > 0).length : 0, Y = L.audioPlaylist && L.audioPlaylist.length > 0, ue = ge + (Y ? 1 : 0), Se = J - ue;
7072
- if (ue > 0 && Se < J && (D = O.current.slice(Se).join(". ").trim(), !D && ge > 0 && L.speechQueue)) {
7133
+ let B = "";
7134
+ if (k.current && D.current.length > 0) {
7135
+ const $ = D.current.length, ge = L.speechQueue ? L.speechQueue.filter((Ae) => Ae && Ae.text && Array.isArray(Ae.text) && Ae.text.length > 0).length : 0, Y = L.audioPlaylist && L.audioPlaylist.length > 0, ue = ge + (Y ? 1 : 0), Se = $ - ue;
7136
+ if (ue > 0 && Se < $ && (B = D.current.slice(Se).join(". ").trim(), !B && ge > 0 && L.speechQueue)) {
7073
7137
  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(" ");
7074
- be && be.trim() && (D = be.trim());
7138
+ be && be.trim() && (B = be.trim());
7075
7139
  }
7076
7140
  }
7077
- k.current && (E.current = {
7078
- remainingText: D || null,
7141
+ k.current && (P.current = {
7142
+ remainingText: B || null,
7079
7143
  originalText: k.current.text,
7080
7144
  options: k.current.options
7081
- }), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), T.current = !0, pe(!0);
7145
+ }), L.speechQueue && (L.speechQueue.length = 0), m.current.pauseSpeaking(), M.current = !0, pe(!0);
7082
7146
  }
7083
7147
  }
7084
- }, []), q = P(async () => {
7085
- if (!p.current || !ae)
7148
+ }, []), q = F(async () => {
7149
+ if (!m.current || !ae)
7086
7150
  return;
7087
- let L = "", B = {};
7088
- if (E.current && E.current.remainingText)
7089
- L = E.current.remainingText, B = E.current.options || {}, E.current = { remainingText: null, originalText: null, options: null };
7151
+ let L = "", N = {};
7152
+ if (P.current && P.current.remainingText)
7153
+ L = P.current.remainingText, N = P.current.options || {}, P.current = { remainingText: null, originalText: null, options: null };
7090
7154
  else if (k.current && k.current.text)
7091
- L = k.current.text, B = k.current.options || {};
7155
+ L = k.current.text, N = k.current.options || {};
7092
7156
  else {
7093
- console.warn("Resume called but no paused speech found"), pe(!1), T.current = !1;
7157
+ console.warn("Resume called but no paused speech found"), pe(!1), M.current = !1;
7094
7158
  return;
7095
7159
  }
7096
- pe(!1), T.current = !1, await M();
7097
- const D = {
7098
- ...B,
7099
- lipsyncLang: B.lipsyncLang || v.lipsyncLang || "en"
7160
+ pe(!1), M.current = !1, await E();
7161
+ const B = {
7162
+ ...N,
7163
+ lipsyncLang: N.lipsyncLang || R.lipsyncLang || "en"
7100
7164
  };
7101
7165
  try {
7102
- await W(L, D);
7103
- } catch (J) {
7104
- console.error("Error resuming speech:", J), pe(!1), T.current = !1;
7166
+ await W(L, B);
7167
+ } catch ($) {
7168
+ console.error("Error resuming speech:", $), pe(!1), M.current = !1;
7105
7169
  }
7106
- }, [M, ae, W, v]), Le = P((L) => {
7107
- p.current && p.current.setMood(L);
7108
- }, []), we = P((L) => {
7109
- p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
7110
- }, []), C = P((L, B = !1) => {
7111
- if (p.current && p.current.playAnimation) {
7112
- if (f && f[L] && (L = f[L]), p.current.setShowFullAvatar)
7170
+ }, [E, ae, W, R]), Le = F((L) => {
7171
+ m.current && m.current.setMood(L);
7172
+ }, []), we = F((L) => {
7173
+ m.current && m.current.setSlowdownRate && m.current.setSlowdownRate(L);
7174
+ }, []), C = F((L, N = !1) => {
7175
+ if (m.current && m.current.playAnimation) {
7176
+ if (b && b[L] && (L = b[L]), m.current.setShowFullAvatar)
7113
7177
  try {
7114
- p.current.setShowFullAvatar(H.current);
7115
- } catch (J) {
7116
- console.warn("Error setting full body mode:", J);
7178
+ m.current.setShowFullAvatar(T.current);
7179
+ } catch ($) {
7180
+ console.warn("Error setting full body mode:", $);
7117
7181
  }
7118
7182
  if (L.includes("."))
7119
7183
  try {
7120
- p.current.playAnimation(L, null, 10, 0, 0.01, B);
7121
- } catch (J) {
7122
- console.warn(`Failed to play ${L}:`, J);
7184
+ m.current.playAnimation(L, null, 10, 0, 0.01, N);
7185
+ } catch ($) {
7186
+ console.warn(`Failed to play ${L}:`, $);
7123
7187
  try {
7124
- p.current.setBodyMovement("idle");
7188
+ m.current.setBodyMovement("idle");
7125
7189
  } catch (ge) {
7126
7190
  console.warn("Fallback animation also failed:", ge);
7127
7191
  }
7128
7192
  }
7129
7193
  else {
7130
- const J = [".fbx", ".glb", ".gltf"];
7194
+ const $ = [".fbx", ".glb", ".gltf"];
7131
7195
  let ge = !1;
7132
- for (const Y of J)
7196
+ for (const Y of $)
7133
7197
  try {
7134
- p.current.playAnimation(L + Y, null, 10, 0, 0.01, B), ge = !0;
7198
+ m.current.playAnimation(L + Y, null, 10, 0, 0.01, N), ge = !0;
7135
7199
  break;
7136
7200
  } catch {
7137
7201
  }
7138
7202
  if (!ge) {
7139
7203
  console.warn("Animation not found:", L);
7140
7204
  try {
7141
- p.current.setBodyMovement("idle");
7205
+ m.current.setBodyMovement("idle");
7142
7206
  } catch (Y) {
7143
7207
  console.warn("Fallback animation also failed:", Y);
7144
7208
  }
7145
7209
  }
7146
7210
  }
7147
7211
  }
7148
- }, [f]), ne = P(() => {
7149
- p.current && p.current.onResize && p.current.onResize();
7212
+ }, [b]), ne = F(() => {
7213
+ m.current && m.current.onResize && m.current.onResize();
7150
7214
  }, []);
7151
- return Ee(R, () => ({
7215
+ return Ee(I, () => ({
7152
7216
  speakText: W,
7153
7217
  stopSpeaking: K,
7154
7218
  pauseSpeaking: j,
7155
7219
  resumeSpeaking: q,
7156
- resumeAudioContext: M,
7220
+ resumeAudioContext: E,
7157
7221
  setMood: Le,
7158
7222
  setTimingAdjustment: we,
7159
7223
  playAnimation: C,
7160
- isReady: $,
7224
+ isReady: ee,
7161
7225
  isPaused: ae,
7162
- talkingHead: p.current,
7226
+ talkingHead: m.current,
7163
7227
  handleResize: ne,
7164
7228
  setBodyMovement: (L) => {
7165
- if (p.current && p.current.setShowFullAvatar && p.current.setBodyMovement)
7229
+ if (m.current && m.current.setShowFullAvatar && m.current.setBodyMovement)
7166
7230
  try {
7167
- p.current.setShowFullAvatar(H.current), p.current.setBodyMovement(L);
7168
- } catch (B) {
7169
- console.warn("Error setting body movement:", B);
7231
+ m.current.setShowFullAvatar(T.current), m.current.setBodyMovement(L);
7232
+ } catch (N) {
7233
+ console.warn("Error setting body movement:", N);
7170
7234
  }
7171
7235
  },
7172
- setMovementIntensity: (L) => p.current?.setMovementIntensity(L),
7236
+ setMovementIntensity: (L) => m.current?.setMovementIntensity(L),
7173
7237
  playRandomDance: () => {
7174
- if (p.current && p.current.setShowFullAvatar && p.current.playRandomDance)
7238
+ if (m.current && m.current.setShowFullAvatar && m.current.playRandomDance)
7175
7239
  try {
7176
- p.current.setShowFullAvatar(H.current), p.current.playRandomDance();
7240
+ m.current.setShowFullAvatar(T.current), m.current.playRandomDance();
7177
7241
  } catch (L) {
7178
7242
  console.warn("Error playing random dance:", L);
7179
7243
  }
7180
7244
  },
7181
7245
  playReaction: (L) => {
7182
- if (p.current && p.current.setShowFullAvatar && p.current.playReaction)
7246
+ if (m.current && m.current.setShowFullAvatar && m.current.playReaction)
7183
7247
  try {
7184
- p.current.setShowFullAvatar(H.current), p.current.playReaction(L);
7185
- } catch (B) {
7186
- console.warn("Error playing reaction:", B);
7248
+ m.current.setShowFullAvatar(T.current), m.current.playReaction(L);
7249
+ } catch (N) {
7250
+ console.warn("Error playing reaction:", N);
7187
7251
  }
7188
7252
  },
7189
7253
  playCelebration: () => {
7190
- if (p.current && p.current.setShowFullAvatar && p.current.playCelebration)
7254
+ if (m.current && m.current.setShowFullAvatar && m.current.playCelebration)
7191
7255
  try {
7192
- p.current.setShowFullAvatar(H.current), p.current.playCelebration();
7256
+ m.current.setShowFullAvatar(T.current), m.current.playCelebration();
7193
7257
  } catch (L) {
7194
7258
  console.warn("Error playing celebration:", L);
7195
7259
  }
7196
7260
  },
7197
7261
  setShowFullAvatar: (L) => {
7198
- if (p.current && p.current.setShowFullAvatar)
7262
+ if (m.current && m.current.setShowFullAvatar)
7199
7263
  try {
7200
- H.current = L, p.current.setShowFullAvatar(L);
7201
- } catch (B) {
7202
- console.warn("Error setting showFullAvatar:", B);
7264
+ T.current = L, m.current.setShowFullAvatar(L);
7265
+ } catch (N) {
7266
+ console.warn("Error setting showFullAvatar:", N);
7203
7267
  }
7204
7268
  },
7205
7269
  lockAvatarPosition: () => {
7206
- if (p.current && p.current.lockAvatarPosition)
7270
+ if (m.current && m.current.lockAvatarPosition)
7207
7271
  try {
7208
- p.current.lockAvatarPosition();
7272
+ m.current.lockAvatarPosition();
7209
7273
  } catch (L) {
7210
7274
  console.warn("Error locking avatar position:", L);
7211
7275
  }
7212
7276
  },
7213
7277
  unlockAvatarPosition: () => {
7214
- if (p.current && p.current.unlockAvatarPosition)
7278
+ if (m.current && m.current.unlockAvatarPosition)
7215
7279
  try {
7216
- p.current.unlockAvatarPosition();
7280
+ m.current.unlockAvatarPosition();
7217
7281
  } catch (L) {
7218
7282
  console.warn("Error unlocking avatar position:", L);
7219
7283
  }
@@ -7232,7 +7296,7 @@ const Ve = Me(({
7232
7296
  /* @__PURE__ */ me(
7233
7297
  "div",
7234
7298
  {
7235
- ref: F,
7299
+ ref: H,
7236
7300
  className: "talking-head-viewer",
7237
7301
  style: {
7238
7302
  width: "100%",
@@ -7250,7 +7314,7 @@ const Ve = Me(({
7250
7314
  fontSize: "18px",
7251
7315
  zIndex: 10
7252
7316
  }, children: "Loading avatar..." }),
7253
- _ && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
7317
+ Q && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
7254
7318
  position: "absolute",
7255
7319
  top: "50%",
7256
7320
  left: "50%",
@@ -7261,14 +7325,14 @@ const Ve = Me(({
7261
7325
  zIndex: 10,
7262
7326
  padding: "20px",
7263
7327
  borderRadius: "8px"
7264
- }, children: _ })
7328
+ }, children: Q })
7265
7329
  ]
7266
7330
  }
7267
7331
  );
7268
7332
  });
7269
7333
  Ve.displayName = "TalkingHeadAvatar";
7270
7334
  const pt = Me(({
7271
- text: Z = "Hello! I'm a talking avatar. How are you today?",
7335
+ text: X = "Hello! I'm a talking avatar. How are you today?",
7272
7336
  onLoading: t = () => {
7273
7337
  },
7274
7338
  onError: e = () => {
@@ -7279,23 +7343,23 @@ const pt = Me(({
7279
7343
  style: s = {},
7280
7344
  avatarConfig: o = {}
7281
7345
  }, l) => {
7282
- const u = N(null), r = N(null), [h, a] = ce(!0), [c, d] = ce(null), [g, x] = ce(!1), f = Fe(), R = o.ttsService || f.service, F = R === "browser" ? {
7346
+ const u = O(null), r = O(null), [h, a] = ce(!0), [c, d] = ce(null), [g, x] = ce(!1), b = Fe(), I = o.ttsService || b.service, H = I === "browser" ? {
7283
7347
  endpoint: "",
7284
7348
  apiKey: null,
7285
7349
  defaultVoice: "Google US English"
7286
7350
  } : {
7287
- ...f,
7351
+ ...b,
7288
7352
  // Override API key if provided via avatarConfig
7289
- apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : f.apiKey,
7353
+ apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : b.apiKey,
7290
7354
  // Override endpoint for ElevenLabs if service is explicitly set
7291
- endpoint: R === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : f.endpoint
7292
- }, p = {
7355
+ endpoint: I === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : b.endpoint
7356
+ }, m = {
7293
7357
  url: "/avatars/brunette.glb",
7294
7358
  // Use brunette avatar (working glTF file)
7295
7359
  body: "F",
7296
7360
  avatarMood: "neutral",
7297
- ttsLang: R === "browser" ? "en-US" : "en",
7298
- ttsVoice: o.ttsVoice || F.defaultVoice,
7361
+ ttsLang: I === "browser" ? "en-US" : "en",
7362
+ ttsVoice: o.ttsVoice || H.defaultVoice,
7299
7363
  lipsyncLang: "en",
7300
7364
  // English lip-sync
7301
7365
  showFullAvatar: !0,
@@ -7303,36 +7367,36 @@ const pt = Me(({
7303
7367
  bodyMovement: "idle",
7304
7368
  movementIntensity: 0.5,
7305
7369
  ...o
7306
- }, H = {
7307
- ttsEndpoint: F.endpoint,
7308
- ttsApikey: F.apiKey,
7309
- ttsService: R,
7370
+ }, T = {
7371
+ ttsEndpoint: H.endpoint,
7372
+ ttsApikey: H.apiKey,
7373
+ ttsService: I,
7310
7374
  lipsyncModules: ["en"],
7311
7375
  cameraView: "upper"
7312
- }, k = P(async () => {
7376
+ }, k = F(async () => {
7313
7377
  if (!(!u.current || r.current))
7314
7378
  try {
7315
- if (a(!0), d(null), r.current = new Be(u.current, H), await r.current.showAvatar(p, (_) => {
7316
- if (_.lengthComputable) {
7317
- const X = Math.min(100, Math.round(_.loaded / _.total * 100));
7318
- t(X);
7379
+ if (a(!0), d(null), r.current = new Ne(u.current, T), await r.current.showAvatar(m, (Q) => {
7380
+ if (Q.lengthComputable) {
7381
+ const Z = Math.min(100, Math.round(Q.loaded / Q.total * 100));
7382
+ t(Z);
7319
7383
  }
7320
7384
  }), r.current.morphs && r.current.morphs.length > 0) {
7321
- const _ = r.current.morphs[0].morphTargetDictionary;
7322
- console.log("Available morph targets:", Object.keys(_));
7323
- const X = Object.keys(_).filter(($) => $.startsWith("viseme_"));
7324
- 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"));
7385
+ const Q = r.current.morphs[0].morphTargetDictionary;
7386
+ console.log("Available morph targets:", Object.keys(Q));
7387
+ const Z = Object.keys(Q).filter((ee) => ee.startsWith("viseme_"));
7388
+ 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"));
7325
7389
  }
7326
- if (await new Promise((_) => {
7327
- const X = () => {
7328
- r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), _()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(X, 100));
7390
+ if (await new Promise((Q) => {
7391
+ const Z = () => {
7392
+ r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), Q()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(Z, 100));
7329
7393
  };
7330
- X();
7394
+ Z();
7331
7395
  }), r.current && r.current.setShowFullAvatar)
7332
7396
  try {
7333
7397
  r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
7334
- } catch (_) {
7335
- console.warn("Error setting full body mode on initialization:", _);
7398
+ } catch (Q) {
7399
+ console.warn("Error setting full body mode on initialization:", Q);
7336
7400
  }
7337
7401
  a(!1), x(!0), n(r.current);
7338
7402
  const G = () => {
@@ -7348,10 +7412,10 @@ const pt = Me(({
7348
7412
  de(() => (k(), () => {
7349
7413
  r.current && (r.current.stop(), r.current.dispose(), r.current = null);
7350
7414
  }), [k]);
7351
- const y = P((S) => {
7415
+ const y = F((S) => {
7352
7416
  if (r.current && g)
7353
7417
  try {
7354
- console.log("Speaking text:", S), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7418
+ console.log("Speaking text:", S), console.log("Avatar config:", m), 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(() => {
7355
7419
  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");
7356
7420
  }, 500));
7357
7421
  } catch (G) {
@@ -7359,42 +7423,42 @@ const pt = Me(({
7359
7423
  }
7360
7424
  else
7361
7425
  console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
7362
- }, [g, p]), T = P(() => {
7426
+ }, [g, m]), M = F(() => {
7363
7427
  r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7364
- }, []), E = P((S) => {
7428
+ }, []), P = F((S) => {
7365
7429
  r.current && r.current.setMood(S);
7366
- }, []), O = P((S) => {
7430
+ }, []), D = F((S) => {
7367
7431
  r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
7368
- }, []), te = P((S, G = !1) => {
7432
+ }, []), J = F((S, G = !1) => {
7369
7433
  if (r.current && r.current.playAnimation) {
7370
7434
  if (r.current.setShowFullAvatar)
7371
7435
  try {
7372
7436
  r.current.setShowFullAvatar(!0);
7373
- } catch (X) {
7374
- console.warn("Error setting full body mode:", X);
7437
+ } catch (Z) {
7438
+ console.warn("Error setting full body mode:", Z);
7375
7439
  }
7376
7440
  if (S.includes("."))
7377
7441
  try {
7378
7442
  r.current.playAnimation(S, null, 10, 0, 0.01, G), console.log("Playing animation:", S);
7379
- } catch (X) {
7380
- console.log(`Failed to play ${S}:`, X);
7443
+ } catch (Z) {
7444
+ console.log(`Failed to play ${S}:`, Z);
7381
7445
  try {
7382
7446
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
7383
- } catch ($) {
7384
- console.warn("Fallback animation also failed:", $);
7447
+ } catch (ee) {
7448
+ console.warn("Fallback animation also failed:", ee);
7385
7449
  }
7386
7450
  }
7387
7451
  else {
7388
- const X = [".fbx", ".glb", ".gltf"];
7389
- let $ = !1;
7390
- for (const se of X)
7452
+ const Z = [".fbx", ".glb", ".gltf"];
7453
+ let ee = !1;
7454
+ for (const se of Z)
7391
7455
  try {
7392
- r.current.playAnimation(S + se, null, 10, 0, 0.01, G), console.log("Playing animation:", S + se), $ = !0;
7456
+ r.current.playAnimation(S + se, null, 10, 0, 0.01, G), console.log("Playing animation:", S + se), ee = !0;
7393
7457
  break;
7394
7458
  } catch {
7395
7459
  console.log(`Failed to play ${S}${se}, trying next format...`);
7396
7460
  }
7397
- if (!$) {
7461
+ if (!ee) {
7398
7462
  console.warn("Animation system not available or animation not found:", S);
7399
7463
  try {
7400
7464
  r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
@@ -7408,10 +7472,10 @@ const pt = Me(({
7408
7472
  }, []);
7409
7473
  return Ee(l, () => ({
7410
7474
  speakText: y,
7411
- stopSpeaking: T,
7412
- setMood: E,
7413
- setTimingAdjustment: O,
7414
- playAnimation: te,
7475
+ stopSpeaking: M,
7476
+ setMood: P,
7477
+ setTimingAdjustment: D,
7478
+ playAnimation: J,
7415
7479
  isReady: g,
7416
7480
  talkingHead: r.current,
7417
7481
  setBodyMovement: (S) => {
@@ -7509,7 +7573,7 @@ const pt = Me(({
7509
7573
  });
7510
7574
  pt.displayName = "TalkingHeadComponent";
7511
7575
  const gt = Me(({
7512
- text: Z = null,
7576
+ text: X = null,
7513
7577
  avatarUrl: t = "/avatars/brunette.glb",
7514
7578
  avatarBody: e = "F",
7515
7579
  mood: n = "neutral",
@@ -7529,37 +7593,37 @@ const gt = Me(({
7529
7593
  },
7530
7594
  onSpeechEnd: x = () => {
7531
7595
  },
7532
- className: f = "",
7533
- style: R = {},
7534
- animations: F = {},
7535
- autoSpeak: p = !1
7536
- }, H) => {
7537
- const k = N(null), y = N(null), T = N(h), E = N(null), O = N(null), te = N(!1), S = N({ remainingText: null, originalText: null, options: null }), G = N([]), [_, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
7596
+ className: b = "",
7597
+ style: I = {},
7598
+ animations: H = {},
7599
+ autoSpeak: m = !1
7600
+ }, T) => {
7601
+ const k = O(null), y = O(null), M = O(h), P = O(null), D = O(null), J = O(!1), S = O({ remainingText: null, originalText: null, options: null }), G = O([]), [Q, Z] = ce(!0), [ee, se] = ce(null), [ae, pe] = ce(!1), [te, le] = ce(!1);
7538
7602
  de(() => {
7539
- te.current = ee;
7540
- }, [ee]), de(() => {
7541
- T.current = h;
7603
+ J.current = te;
7604
+ }, [te]), de(() => {
7605
+ M.current = h;
7542
7606
  }, [h]);
7543
- const U = Fe(), v = s || U.service;
7544
- let I;
7545
- v === "browser" ? I = {
7607
+ const U = Fe(), R = s || U.service;
7608
+ let v;
7609
+ R === "browser" ? v = {
7546
7610
  service: "browser",
7547
7611
  endpoint: "",
7548
7612
  apiKey: null,
7549
7613
  defaultVoice: "Google US English"
7550
- } : v === "elevenlabs" ? I = {
7614
+ } : R === "elevenlabs" ? v = {
7551
7615
  service: "elevenlabs",
7552
7616
  endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
7553
7617
  apiKey: l || U.apiKey,
7554
7618
  defaultVoice: o || U.defaultVoice || Ie.defaultVoice,
7555
7619
  voices: U.voices || Ie.voices
7556
- } : v === "deepgram" ? I = {
7620
+ } : R === "deepgram" ? v = {
7557
7621
  service: "deepgram",
7558
7622
  endpoint: "https://api.deepgram.com/v1/speak",
7559
7623
  apiKey: l || U.apiKey,
7560
7624
  defaultVoice: o || U.defaultVoice || Te.defaultVoice,
7561
7625
  voices: U.voices || Te.voices
7562
- } : I = {
7626
+ } : v = {
7563
7627
  ...U,
7564
7628
  apiKey: l !== null ? l : U.apiKey
7565
7629
  };
@@ -7567,22 +7631,22 @@ const gt = Me(({
7567
7631
  url: t,
7568
7632
  body: e,
7569
7633
  avatarMood: n,
7570
- ttsLang: v === "browser" ? "en-US" : i,
7571
- ttsVoice: o || I.defaultVoice,
7634
+ ttsLang: R === "browser" ? "en-US" : i,
7635
+ ttsVoice: o || v.defaultVoice,
7572
7636
  lipsyncLang: "en",
7573
7637
  showFullAvatar: h,
7574
7638
  bodyMovement: u,
7575
7639
  movementIntensity: r
7576
- }, M = {
7577
- ttsEndpoint: I.endpoint,
7578
- ttsApikey: I.apiKey,
7579
- ttsService: v,
7640
+ }, E = {
7641
+ ttsEndpoint: v.endpoint,
7642
+ ttsApikey: v.apiKey,
7643
+ ttsService: R,
7580
7644
  lipsyncModules: ["en"],
7581
7645
  cameraView: a
7582
- }, W = P(async () => {
7646
+ }, W = F(async () => {
7583
7647
  if (!(!k.current || y.current))
7584
7648
  try {
7585
- X(!0), se(null), y.current = new Be(k.current, M), console.log("Avatar config being passed:", {
7649
+ Z(!0), se(null), y.current = new Ne(k.current, E), console.log("Avatar config being passed:", {
7586
7650
  url: w.url,
7587
7651
  body: w.body,
7588
7652
  avatarMood: w.avatarMood
@@ -7591,7 +7655,7 @@ const gt = Me(({
7591
7655
  const L = Math.min(100, Math.round(ne.loaded / ne.total * 100));
7592
7656
  d(L);
7593
7657
  }
7594
- }), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), X(!1), pe(!0), c(y.current);
7658
+ }), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), Z(!1), pe(!0), c(y.current);
7595
7659
  const C = () => {
7596
7660
  document.visibilityState === "visible" ? y.current?.start() : y.current?.stop();
7597
7661
  };
@@ -7599,13 +7663,13 @@ const gt = Me(({
7599
7663
  document.removeEventListener("visibilitychange", C);
7600
7664
  };
7601
7665
  } catch (C) {
7602
- console.error("Error initializing TalkingHead:", C), se(C.message || "Failed to initialize avatar"), X(!1), g(C);
7666
+ console.error("Error initializing TalkingHead:", C), se(C.message || "Failed to initialize avatar"), Z(!1), g(C);
7603
7667
  }
7604
7668
  }, []);
7605
7669
  de(() => (W(), () => {
7606
7670
  y.current && (y.current.stop(), y.current.dispose(), y.current = null);
7607
7671
  }), [W]);
7608
- const K = P(async () => {
7672
+ const K = F(async () => {
7609
7673
  if (y.current)
7610
7674
  try {
7611
7675
  const C = y.current.audioCtx || y.current.audioContext;
@@ -7613,7 +7677,7 @@ const gt = Me(({
7613
7677
  } catch (C) {
7614
7678
  console.warn("Failed to resume audio context:", C);
7615
7679
  }
7616
- }, []), j = P(async (C, ne = {}) => {
7680
+ }, []), j = F(async (C, ne = {}) => {
7617
7681
  if (!y.current || !ae) {
7618
7682
  console.warn("Avatar not ready for speaking");
7619
7683
  return;
@@ -7622,59 +7686,59 @@ const gt = Me(({
7622
7686
  console.warn("No text provided to speak");
7623
7687
  return;
7624
7688
  }
7625
- await K(), S.current = { remainingText: null, originalText: null, options: null }, G.current = [], E.current = { text: C, options: ne }, O.current && (clearInterval(O.current), O.current = null), le(!1), te.current = !1;
7626
- const L = C.split(/[.!?]+/).filter((D) => D.trim().length > 0);
7689
+ await K(), S.current = { remainingText: null, originalText: null, options: null }, G.current = [], P.current = { text: C, options: ne }, D.current && (clearInterval(D.current), D.current = null), le(!1), J.current = !1;
7690
+ const L = C.split(/[.!?]+/).filter((B) => B.trim().length > 0);
7627
7691
  G.current = L;
7628
- const B = {
7692
+ const N = {
7629
7693
  lipsyncLang: ne.lipsyncLang || "en",
7630
7694
  onSpeechEnd: () => {
7631
- O.current && (clearInterval(O.current), O.current = null), ne.onSpeechEnd && ne.onSpeechEnd(), x();
7695
+ D.current && (clearInterval(D.current), D.current = null), ne.onSpeechEnd && ne.onSpeechEnd(), x();
7632
7696
  }
7633
7697
  };
7634
7698
  try {
7635
- y.current.speakText(C, B);
7636
- } catch (D) {
7637
- console.error("Error speaking text:", D), se(D.message || "Failed to speak text");
7699
+ y.current.speakText(C, N);
7700
+ } catch (B) {
7701
+ console.error("Error speaking text:", B), se(B.message || "Failed to speak text");
7638
7702
  }
7639
7703
  }, [ae, x, K]);
7640
7704
  de(() => {
7641
- ae && Z && p && y.current && j(Z);
7642
- }, [ae, Z, p, j]);
7643
- const q = P(() => {
7705
+ ae && X && m && y.current && j(X);
7706
+ }, [ae, X, m, j]);
7707
+ const q = F(() => {
7644
7708
  if (y.current)
7645
7709
  try {
7646
7710
  const C = y.current.isSpeaking || !1, ne = y.current.audioPlaylist || [], L = y.current.speechQueue || [];
7647
7711
  if (C || ne.length > 0 || L.length > 0) {
7648
- O.current && (clearInterval(O.current), O.current = null);
7649
- let B = "";
7650
- L.length > 0 && (B = L.map((D) => D.text && Array.isArray(D.text) ? D.text.map((J) => J.word).join(" ") : D.text || "").join(" ")), S.current = {
7651
- remainingText: B || null,
7652
- originalText: E.current?.text || null,
7653
- options: E.current?.options || null
7654
- }, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), le(!0), te.current = !0;
7712
+ D.current && (clearInterval(D.current), D.current = null);
7713
+ let N = "";
7714
+ L.length > 0 && (N = L.map((B) => B.text && Array.isArray(B.text) ? B.text.map(($) => $.word).join(" ") : B.text || "").join(" ")), S.current = {
7715
+ remainingText: N || null,
7716
+ originalText: P.current?.text || null,
7717
+ options: P.current?.options || null
7718
+ }, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), le(!0), J.current = !0;
7655
7719
  }
7656
7720
  } catch (C) {
7657
7721
  console.warn("Error pausing speech:", C);
7658
7722
  }
7659
- }, []), Le = P(async () => {
7660
- if (!(!y.current || !ee))
7723
+ }, []), Le = F(async () => {
7724
+ if (!(!y.current || !te))
7661
7725
  try {
7662
- await K(), le(!1), te.current = !1;
7663
- const C = S.current?.remainingText, ne = S.current?.originalText || E.current?.text, L = S.current?.options || E.current?.options || {}, B = C || ne;
7664
- B && j(B, L);
7726
+ await K(), le(!1), J.current = !1;
7727
+ const C = S.current?.remainingText, ne = S.current?.originalText || P.current?.text, L = S.current?.options || P.current?.options || {}, N = C || ne;
7728
+ N && j(N, L);
7665
7729
  } catch (C) {
7666
- console.warn("Error resuming speech:", C), le(!1), te.current = !1;
7730
+ console.warn("Error resuming speech:", C), le(!1), J.current = !1;
7667
7731
  }
7668
- }, [ee, j, K]), we = P(() => {
7669
- y.current && (y.current.stopSpeaking(), O.current && (clearInterval(O.current), O.current = null), le(!1), te.current = !1);
7732
+ }, [te, j, K]), we = F(() => {
7733
+ y.current && (y.current.stopSpeaking(), D.current && (clearInterval(D.current), D.current = null), le(!1), J.current = !1);
7670
7734
  }, []);
7671
- return Ee(H, () => ({
7735
+ return Ee(T, () => ({
7672
7736
  speakText: j,
7673
7737
  pauseSpeaking: q,
7674
7738
  resumeSpeaking: Le,
7675
7739
  stopSpeaking: we,
7676
7740
  resumeAudioContext: K,
7677
- isPaused: () => ee,
7741
+ isPaused: () => te,
7678
7742
  setMood: (C) => y.current?.setMood(C),
7679
7743
  setBodyMovement: (C) => {
7680
7744
  y.current && y.current.setBodyMovement(C);
@@ -7685,11 +7749,11 @@ const gt = Me(({
7685
7749
  playReaction: (C) => y.current?.playReaction(C),
7686
7750
  playCelebration: () => y.current?.playCelebration(),
7687
7751
  setShowFullAvatar: (C) => {
7688
- y.current && (T.current = C, y.current.setShowFullAvatar(C));
7752
+ y.current && (M.current = C, y.current.setShowFullAvatar(C));
7689
7753
  },
7690
7754
  isReady: ae,
7691
7755
  talkingHead: y.current
7692
- })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${f}`, style: R, children: [
7756
+ })), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${b}`, style: I, children: [
7693
7757
  /* @__PURE__ */ me(
7694
7758
  "div",
7695
7759
  {
@@ -7702,7 +7766,7 @@ const gt = Me(({
7702
7766
  }
7703
7767
  }
7704
7768
  ),
7705
- _ && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7769
+ Q && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
7706
7770
  position: "absolute",
7707
7771
  top: "50%",
7708
7772
  left: "50%",
@@ -7711,7 +7775,7 @@ const gt = Me(({
7711
7775
  fontSize: "18px",
7712
7776
  zIndex: 10
7713
7777
  }, children: "Loading avatar..." }),
7714
- $ && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
7778
+ ee && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
7715
7779
  position: "absolute",
7716
7780
  top: "50%",
7717
7781
  left: "50%",
@@ -7722,12 +7786,12 @@ const gt = Me(({
7722
7786
  zIndex: 10,
7723
7787
  padding: "20px",
7724
7788
  borderRadius: "8px"
7725
- }, children: $ })
7789
+ }, children: ee })
7726
7790
  ] });
7727
7791
  });
7728
7792
  gt.displayName = "SimpleTalkingAvatar";
7729
7793
  const yt = Me(({
7730
- curriculumData: Z = null,
7794
+ curriculumData: X = null,
7731
7795
  avatarConfig: t = {},
7732
7796
  animations: e = {},
7733
7797
  onLessonStart: n = () => {
@@ -7742,7 +7806,7 @@ const yt = Me(({
7742
7806
  },
7743
7807
  autoStart: u = !1
7744
7808
  }, r) => {
7745
- const h = N(null), a = N({
7809
+ const h = O(null), a = O({
7746
7810
  currentModuleIndex: 0,
7747
7811
  currentLessonIndex: 0,
7748
7812
  currentQuestionIndex: 0,
@@ -7752,18 +7816,18 @@ const yt = Me(({
7752
7816
  curriculumCompleted: !1,
7753
7817
  score: 0,
7754
7818
  totalQuestions: 0
7755
- }), c = N({
7819
+ }), c = O({
7756
7820
  onLessonStart: n,
7757
7821
  onLessonComplete: i,
7758
7822
  onQuestionAnswer: s,
7759
7823
  onCurriculumComplete: o,
7760
7824
  onCustomAction: l
7761
- }), d = N(null), g = N(null), x = N(null), f = N(null), R = N(null), F = N(null), p = N(null), H = N(Z?.curriculum || {
7825
+ }), d = O(null), g = O(null), x = O(null), b = O(null), I = O(null), H = O(null), m = O(null), T = O(X?.curriculum || {
7762
7826
  title: "Default Curriculum",
7763
7827
  description: "No curriculum data provided",
7764
7828
  language: "en",
7765
7829
  modules: []
7766
- }), k = N({
7830
+ }), k = O({
7767
7831
  avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
7768
7832
  avatarBody: t.avatarBody || "F",
7769
7833
  mood: t.mood || "happy",
@@ -7786,7 +7850,7 @@ const yt = Me(({
7786
7850
  onCustomAction: l
7787
7851
  };
7788
7852
  }, [n, i, s, o, l]), de(() => {
7789
- H.current = Z?.curriculum || {
7853
+ T.current = X?.curriculum || {
7790
7854
  title: "Default Curriculum",
7791
7855
  description: "No curriculum data provided",
7792
7856
  language: "en",
@@ -7805,24 +7869,24 @@ const yt = Me(({
7805
7869
  animations: e,
7806
7870
  lipsyncLang: "en"
7807
7871
  };
7808
- }, [Z, t, e]);
7809
- const y = P(() => (H.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), T = P(() => y()?.questions[a.current.currentQuestionIndex], [y]), E = P((v, I) => I.type === "multiple_choice" || I.type === "true_false" ? v === I.answer : I.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), O = P(() => {
7872
+ }, [X, t, e]);
7873
+ const y = F(() => (T.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), M = F(() => y()?.questions[a.current.currentQuestionIndex], [y]), P = F((R, v) => v.type === "multiple_choice" || v.type === "true_false" ? R === v.answer : v.type === "code_test" && typeof R == "object" && R !== null ? R.passed === !0 : !1, []), D = F(() => {
7810
7874
  a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
7811
- const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7812
- let I = "Congratulations! You've completed this lesson";
7813
- if (a.current.totalQuestions > 0 ? I += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${v} percent. ` : I += "! ", v >= 80 ? I += "Excellent work! You have a great understanding of this topic." : v >= 60 ? I += "Good job! You understand most of the concepts." : I += "Keep practicing! You're making progress.", c.current.onLessonComplete({
7875
+ const R = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
7876
+ let v = "Congratulations! You've completed this lesson";
7877
+ if (a.current.totalQuestions > 0 ? v += ` You got ${a.current.score} correct out of ${a.current.totalQuestions} question${a.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${R} percent. ` : v += "! ", R >= 80 ? v += "Excellent work! You have a great understanding of this topic." : R >= 60 ? v += "Good job! You understand most of the concepts." : v += "Keep practicing! You're making progress.", c.current.onLessonComplete({
7814
7878
  moduleIndex: a.current.currentModuleIndex,
7815
7879
  lessonIndex: a.current.currentLessonIndex,
7816
7880
  score: a.current.score,
7817
7881
  totalQuestions: a.current.totalQuestions,
7818
- percentage: v
7882
+ percentage: R
7819
7883
  }), c.current.onCustomAction({
7820
7884
  type: "lessonComplete",
7821
7885
  moduleIndex: a.current.currentModuleIndex,
7822
7886
  lessonIndex: a.current.currentLessonIndex,
7823
7887
  score: a.current.score,
7824
7888
  totalQuestions: a.current.totalQuestions,
7825
- percentage: v
7889
+ percentage: R
7826
7890
  }), h.current) {
7827
7891
  if (h.current.setMood("happy"), e.lessonComplete)
7828
7892
  try {
@@ -7830,8 +7894,8 @@ const yt = Me(({
7830
7894
  } catch {
7831
7895
  h.current.playCelebration();
7832
7896
  }
7833
- const w = H.current || { modules: [] }, M = w.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (M?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (w.modules?.length || 0) - 1, j = W || K, q = k.current || { lipsyncLang: "en" };
7834
- h.current.speakText(I, {
7897
+ const w = T.current || { modules: [] }, E = w.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (E?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (w.modules?.length || 0) - 1, j = W || K, q = k.current || { lipsyncLang: "en" };
7898
+ h.current.speakText(v, {
7835
7899
  lipsyncLang: q.lipsyncLang,
7836
7900
  onSpeechEnd: () => {
7837
7901
  c.current.onCustomAction({
@@ -7840,18 +7904,18 @@ const yt = Me(({
7840
7904
  lessonIndex: a.current.currentLessonIndex,
7841
7905
  score: a.current.score,
7842
7906
  totalQuestions: a.current.totalQuestions,
7843
- percentage: v,
7907
+ percentage: R,
7844
7908
  hasNextLesson: j
7845
7909
  });
7846
7910
  }
7847
7911
  });
7848
7912
  }
7849
- }, [e.lessonComplete]), te = P(() => {
7913
+ }, [e.lessonComplete]), J = F(() => {
7850
7914
  a.current.curriculumCompleted = !0;
7851
- const v = H.current || { modules: [] };
7915
+ const R = T.current || { modules: [] };
7852
7916
  if (c.current.onCurriculumComplete({
7853
- modules: v.modules.length,
7854
- totalLessons: v.modules.reduce((I, w) => I + w.lessons.length, 0)
7917
+ modules: R.modules.length,
7918
+ totalLessons: R.modules.reduce((v, w) => v + w.lessons.length, 0)
7855
7919
  }), h.current) {
7856
7920
  if (h.current.setMood("celebrating"), e.curriculumComplete)
7857
7921
  try {
@@ -7859,99 +7923,99 @@ const yt = Me(({
7859
7923
  } catch {
7860
7924
  h.current.playCelebration();
7861
7925
  }
7862
- const I = k.current || { lipsyncLang: "en" };
7863
- h.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: I.lipsyncLang });
7926
+ const v = k.current || { lipsyncLang: "en" };
7927
+ h.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 });
7864
7928
  }
7865
- }, [e.curriculumComplete]), S = P(() => {
7866
- const v = y();
7867
- a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
7868
- const I = T();
7869
- I && c.current.onCustomAction({
7929
+ }, [e.curriculumComplete]), S = F(() => {
7930
+ const R = y();
7931
+ a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = R?.questions?.length || 0, a.current.score = 0;
7932
+ const v = M();
7933
+ v && c.current.onCustomAction({
7870
7934
  type: "questionStart",
7871
7935
  moduleIndex: a.current.currentModuleIndex,
7872
7936
  lessonIndex: a.current.currentLessonIndex,
7873
7937
  questionIndex: a.current.currentQuestionIndex,
7874
7938
  totalQuestions: a.current.totalQuestions,
7875
- question: I,
7939
+ question: v,
7876
7940
  score: a.current.score
7877
7941
  });
7878
7942
  const w = () => {
7879
- if (!h.current || !I) return;
7943
+ if (!h.current || !v) return;
7880
7944
  if (h.current.setMood("happy"), e.questionStart)
7881
7945
  try {
7882
7946
  h.current.playAnimation(e.questionStart, !0);
7883
7947
  } catch (W) {
7884
7948
  console.warn("Failed to play questionStart animation:", W);
7885
7949
  }
7886
- const M = k.current || { lipsyncLang: "en" };
7887
- I.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${I.question}`, { lipsyncLang: M.lipsyncLang }) : I.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`, { lipsyncLang: M.lipsyncLang }) : I.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${I.question}`, { lipsyncLang: M.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`, { lipsyncLang: M.lipsyncLang });
7950
+ const E = k.current || { lipsyncLang: "en" };
7951
+ v.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${v.question}`, { lipsyncLang: E.lipsyncLang }) : v.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: E.lipsyncLang }) : v.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${v.question}`, { lipsyncLang: E.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: E.lipsyncLang });
7888
7952
  };
7889
- if (h.current && h.current.isReady && I)
7953
+ if (h.current && h.current.isReady && v)
7890
7954
  w();
7891
7955
  else if (h.current && h.current.isReady) {
7892
- const M = k.current || { lipsyncLang: "en" };
7893
- h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: M.lipsyncLang });
7956
+ const E = k.current || { lipsyncLang: "en" };
7957
+ h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: E.lipsyncLang });
7894
7958
  } else {
7895
- const M = setInterval(() => {
7896
- h.current && h.current.isReady && (clearInterval(M), I && w());
7959
+ const E = setInterval(() => {
7960
+ h.current && h.current.isReady && (clearInterval(E), v && w());
7897
7961
  }, 100);
7898
7962
  setTimeout(() => {
7899
- clearInterval(M);
7963
+ clearInterval(E);
7900
7964
  }, 5e3);
7901
7965
  }
7902
- }, [e.questionStart, y, T]), G = P(() => {
7903
- const v = y();
7904
- if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
7966
+ }, [e.questionStart, y, M]), G = F(() => {
7967
+ const R = y();
7968
+ if (a.current.currentQuestionIndex < (R?.questions?.length || 0) - 1) {
7905
7969
  h.current && h.current.stopSpeaking && h.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
7906
- const I = T();
7907
- I && c.current.onCustomAction({
7970
+ const v = M();
7971
+ v && c.current.onCustomAction({
7908
7972
  type: "nextQuestion",
7909
7973
  moduleIndex: a.current.currentModuleIndex,
7910
7974
  lessonIndex: a.current.currentLessonIndex,
7911
7975
  questionIndex: a.current.currentQuestionIndex,
7912
7976
  totalQuestions: a.current.totalQuestions,
7913
- question: I,
7977
+ question: v,
7914
7978
  score: a.current.score
7915
7979
  });
7916
7980
  const w = () => {
7917
- if (!h.current || !I) return;
7981
+ if (!h.current || !v) return;
7918
7982
  if (h.current.setMood("happy"), h.current.setBodyMovement("idle"), e.nextQuestion)
7919
7983
  try {
7920
7984
  h.current.playAnimation(e.nextQuestion, !0);
7921
7985
  } catch (q) {
7922
7986
  console.warn("Failed to play nextQuestion animation:", q);
7923
7987
  }
7924
- const M = k.current || { lipsyncLang: "en" }, K = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= K - 1;
7925
- if (I.type === "code_test") {
7926
- const q = j ? `Great! Here's your final coding challenge: ${I.question}` : `Great! Now let's move on to your next coding challenge: ${I.question}`;
7988
+ const E = k.current || { lipsyncLang: "en" }, K = y()?.questions?.length || 0, j = a.current.currentQuestionIndex >= K - 1;
7989
+ if (v.type === "code_test") {
7990
+ const q = j ? `Great! Here's your final coding challenge: ${v.question}` : `Great! Now let's move on to your next coding challenge: ${v.question}`;
7927
7991
  h.current.speakText(q, {
7928
- lipsyncLang: M.lipsyncLang
7992
+ lipsyncLang: E.lipsyncLang
7929
7993
  });
7930
- } else if (I.type === "multiple_choice") {
7931
- const q = j ? `Alright! Here's your final question: ${I.question}` : `Alright! Here's your next question: ${I.question}`;
7994
+ } else if (v.type === "multiple_choice") {
7995
+ const q = j ? `Alright! Here's your final question: ${v.question}` : `Alright! Here's your next question: ${v.question}`;
7932
7996
  h.current.speakText(q, {
7933
- lipsyncLang: M.lipsyncLang
7997
+ lipsyncLang: E.lipsyncLang
7934
7998
  });
7935
- } else if (I.type === "true_false") {
7936
- const q = j ? `Now let's try this final one: ${I.question}` : `Now let's try this one: ${I.question}`;
7999
+ } else if (v.type === "true_false") {
8000
+ const q = j ? `Now let's try this final one: ${v.question}` : `Now let's try this one: ${v.question}`;
7937
8001
  h.current.speakText(q, {
7938
- lipsyncLang: M.lipsyncLang
8002
+ lipsyncLang: E.lipsyncLang
7939
8003
  });
7940
8004
  } else {
7941
- const q = j ? `Here's your final question: ${I.question}` : `Here's the next question: ${I.question}`;
8005
+ const q = j ? `Here's your final question: ${v.question}` : `Here's the next question: ${v.question}`;
7942
8006
  h.current.speakText(q, {
7943
- lipsyncLang: M.lipsyncLang
8007
+ lipsyncLang: E.lipsyncLang
7944
8008
  });
7945
8009
  }
7946
8010
  };
7947
- if (h.current && h.current.isReady && I)
8011
+ if (h.current && h.current.isReady && v)
7948
8012
  w();
7949
- else if (I) {
7950
- const M = setInterval(() => {
7951
- h.current && h.current.isReady && (clearInterval(M), w());
8013
+ else if (v) {
8014
+ const E = setInterval(() => {
8015
+ h.current && h.current.isReady && (clearInterval(E), w());
7952
8016
  }, 100);
7953
8017
  setTimeout(() => {
7954
- clearInterval(M);
8018
+ clearInterval(E);
7955
8019
  }, 5e3);
7956
8020
  }
7957
8021
  } else
@@ -7962,11 +8026,11 @@ const yt = Me(({
7962
8026
  totalQuestions: a.current.totalQuestions,
7963
8027
  score: a.current.score
7964
8028
  });
7965
- }, [e.nextQuestion, y, T]), _ = P(() => {
7966
- const v = H.current || { modules: [] }, I = v.modules[a.current.currentModuleIndex];
7967
- if (a.current.currentLessonIndex < (I?.lessons?.length || 0) - 1) {
8029
+ }, [e.nextQuestion, y, M]), Q = F(() => {
8030
+ const R = T.current || { modules: [] }, v = R.modules[a.current.currentModuleIndex];
8031
+ if (a.current.currentLessonIndex < (v?.lessons?.length || 0) - 1) {
7968
8032
  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;
7969
- const M = v.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (M?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, j = W || K;
8033
+ const E = R.modules[a.current.currentModuleIndex], W = a.current.currentLessonIndex < (E?.lessons?.length || 0) - 1, K = a.current.currentModuleIndex < (R.modules?.length || 0) - 1, j = W || K;
7970
8034
  c.current.onCustomAction({
7971
8035
  type: "lessonStart",
7972
8036
  moduleIndex: a.current.currentModuleIndex,
@@ -7977,9 +8041,9 @@ const yt = Me(({
7977
8041
  lessonIndex: a.current.currentLessonIndex,
7978
8042
  lesson: y()
7979
8043
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7980
- } else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
8044
+ } else if (a.current.currentModuleIndex < (R.modules?.length || 0) - 1) {
7981
8045
  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;
7982
- const W = v.modules[a.current.currentModuleIndex], K = a.current.currentLessonIndex < (W?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = K || j;
8046
+ const W = R.modules[a.current.currentModuleIndex], K = a.current.currentLessonIndex < (W?.lessons?.length || 0) - 1, j = a.current.currentModuleIndex < (R.modules?.length || 0) - 1, q = K || j;
7983
8047
  c.current.onCustomAction({
7984
8048
  type: "lessonStart",
7985
8049
  moduleIndex: a.current.currentModuleIndex,
@@ -7991,16 +8055,16 @@ const yt = Me(({
7991
8055
  lesson: y()
7992
8056
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7993
8057
  } else
7994
- R.current && R.current();
7995
- }, []), X = P(() => {
7996
- const v = y();
7997
- let I = null;
7998
- if (v?.avatar_script && v?.body) {
7999
- const w = v.avatar_script.trim(), M = v.body.trim(), W = w.match(/[.!?]$/) ? " " : ". ";
8000
- I = `${w}${W}${M}`;
8058
+ I.current && I.current();
8059
+ }, []), Z = F(() => {
8060
+ const R = y();
8061
+ let v = null;
8062
+ if (R?.avatar_script && R?.body) {
8063
+ const w = R.avatar_script.trim(), E = R.body.trim(), W = w.match(/[.!?]$/) ? " " : ". ";
8064
+ v = `${w}${W}${E}`;
8001
8065
  } else
8002
- I = v?.avatar_script || v?.body || null;
8003
- if (h.current && h.current.isReady && I) {
8066
+ v = R?.avatar_script || R?.body || null;
8067
+ if (h.current && h.current.isReady && v) {
8004
8068
  a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, h.current.setMood("happy");
8005
8069
  let w = !1;
8006
8070
  if (e.teaching)
@@ -8010,44 +8074,44 @@ const yt = Me(({
8010
8074
  console.warn("Failed to play teaching animation:", W);
8011
8075
  }
8012
8076
  w || h.current.setBodyMovement("gesturing");
8013
- const M = k.current || { lipsyncLang: "en" };
8077
+ const E = k.current || { lipsyncLang: "en" };
8014
8078
  c.current.onLessonStart({
8015
8079
  moduleIndex: a.current.currentModuleIndex,
8016
8080
  lessonIndex: a.current.currentLessonIndex,
8017
- lesson: v
8081
+ lesson: R
8018
8082
  }), c.current.onCustomAction({
8019
8083
  type: "teachingStart",
8020
8084
  moduleIndex: a.current.currentModuleIndex,
8021
8085
  lessonIndex: a.current.currentLessonIndex,
8022
- lesson: v
8023
- }), h.current.speakText(I, {
8024
- lipsyncLang: M.lipsyncLang,
8086
+ lesson: R
8087
+ }), h.current.speakText(v, {
8088
+ lipsyncLang: E.lipsyncLang,
8025
8089
  onSpeechEnd: () => {
8026
8090
  a.current.isTeaching = !1, c.current.onCustomAction({
8027
8091
  type: "teachingComplete",
8028
8092
  moduleIndex: a.current.currentModuleIndex,
8029
8093
  lessonIndex: a.current.currentLessonIndex,
8030
- lesson: v,
8031
- hasQuestions: v.questions && v.questions.length > 0
8032
- }), v?.code_example && c.current.onCustomAction({
8094
+ lesson: R,
8095
+ hasQuestions: R.questions && R.questions.length > 0
8096
+ }), R?.code_example && c.current.onCustomAction({
8033
8097
  type: "codeExampleReady",
8034
8098
  moduleIndex: a.current.currentModuleIndex,
8035
8099
  lessonIndex: a.current.currentLessonIndex,
8036
- lesson: v,
8037
- codeExample: v.code_example
8100
+ lesson: R,
8101
+ codeExample: R.code_example
8038
8102
  });
8039
8103
  }
8040
8104
  });
8041
8105
  }
8042
- }, [e.teaching, y]), $ = P((v) => {
8043
- const I = T(), w = E(v, I);
8106
+ }, [e.teaching, y]), ee = F((R) => {
8107
+ const v = M(), w = P(R, v);
8044
8108
  if (w && (a.current.score += 1), c.current.onQuestionAnswer({
8045
8109
  moduleIndex: a.current.currentModuleIndex,
8046
8110
  lessonIndex: a.current.currentLessonIndex,
8047
8111
  questionIndex: a.current.currentQuestionIndex,
8048
- answer: v,
8112
+ answer: R,
8049
8113
  isCorrect: w,
8050
- question: I
8114
+ question: v
8051
8115
  }), h.current)
8052
8116
  if (w) {
8053
8117
  if (h.current.setMood("happy"), e.correct)
@@ -8061,7 +8125,7 @@ const yt = Me(({
8061
8125
  a.current.currentQuestionIndex >= W - 1;
8062
8126
  const K = a.current.currentQuestionIndex < W - 1;
8063
8127
  console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", K);
8064
- const j = I.type === "code_test" ? `Great job! Your code passed all the tests! ${I.explanation || ""}` : `Excellent! That's correct! ${I.explanation || ""}`, q = k.current || { lipsyncLang: "en" };
8128
+ const j = v.type === "code_test" ? `Great job! Your code passed all the tests! ${v.explanation || ""}` : `Excellent! That's correct! ${v.explanation || ""}`, q = k.current || { lipsyncLang: "en" };
8065
8129
  h.current.speakText(j, {
8066
8130
  lipsyncLang: q.lipsyncLang,
8067
8131
  onSpeechEnd: () => {
@@ -8087,7 +8151,7 @@ const yt = Me(({
8087
8151
  h.current.setBodyMovement("gesturing");
8088
8152
  const W = y()?.questions?.length || 0, K = a.current.currentQuestionIndex >= W - 1, j = a.current.currentQuestionIndex < W - 1;
8089
8153
  console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", W, "hasNextQuestion:", j);
8090
- const q = I.type === "code_test" ? `Your code didn't pass all the tests. ${I.explanation || "Try again!"}` : `Not quite right, but don't worry! ${I.explanation || ""}${K ? "" : " Let's move on to the next question."}`, Le = k.current || { lipsyncLang: "en" };
8154
+ 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 || ""}${K ? "" : " Let's move on to the next question."}`, Le = k.current || { lipsyncLang: "en" };
8091
8155
  h.current.speakText(q, {
8092
8156
  lipsyncLang: Le.lipsyncLang,
8093
8157
  onSpeechEnd: () => {
@@ -8118,25 +8182,25 @@ const yt = Me(({
8118
8182
  avatarNotReady: !0
8119
8183
  });
8120
8184
  }
8121
- }, [e.correct, e.incorrect, T, y, E]), se = P((v) => {
8122
- const I = T();
8123
- if (!v || typeof v != "object") {
8185
+ }, [e.correct, e.incorrect, M, y, P]), se = F((R) => {
8186
+ const v = M();
8187
+ if (!R || typeof R != "object") {
8124
8188
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
8125
8189
  return;
8126
8190
  }
8127
- if (I?.type !== "code_test") {
8191
+ if (v?.type !== "code_test") {
8128
8192
  console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
8129
8193
  return;
8130
8194
  }
8131
8195
  const w = {
8132
- passed: v.passed === !0,
8133
- results: v.results || [],
8134
- output: v.output || "",
8135
- error: v.error || null,
8136
- executionTime: v.executionTime || null,
8137
- testCount: v.testCount || 0,
8138
- passedCount: v.passedCount || 0,
8139
- failedCount: v.failedCount || 0
8196
+ passed: R.passed === !0,
8197
+ results: R.results || [],
8198
+ output: R.output || "",
8199
+ error: R.error || null,
8200
+ executionTime: R.executionTime || null,
8201
+ testCount: R.testCount || 0,
8202
+ passedCount: R.passedCount || 0,
8203
+ failedCount: R.failedCount || 0
8140
8204
  };
8141
8205
  c.current.onCustomAction({
8142
8206
  type: "codeTestSubmitted",
@@ -8144,45 +8208,45 @@ const yt = Me(({
8144
8208
  lessonIndex: a.current.currentLessonIndex,
8145
8209
  questionIndex: a.current.currentQuestionIndex,
8146
8210
  testResult: w,
8147
- question: I
8148
- }), p.current && p.current(w);
8149
- }, [T, E]), ae = P(() => {
8211
+ question: v
8212
+ }), m.current && m.current(w);
8213
+ }, [M, P]), ae = F(() => {
8150
8214
  if (a.current.currentQuestionIndex > 0) {
8151
8215
  a.current.currentQuestionIndex -= 1;
8152
- const v = T();
8153
- v && c.current.onCustomAction({
8216
+ const R = M();
8217
+ R && c.current.onCustomAction({
8154
8218
  type: "questionStart",
8155
8219
  moduleIndex: a.current.currentModuleIndex,
8156
8220
  lessonIndex: a.current.currentLessonIndex,
8157
8221
  questionIndex: a.current.currentQuestionIndex,
8158
8222
  totalQuestions: a.current.totalQuestions,
8159
- question: v,
8223
+ question: R,
8160
8224
  score: a.current.score
8161
8225
  });
8162
- const I = () => {
8163
- if (!h.current || !v) return;
8226
+ const v = () => {
8227
+ if (!h.current || !R) return;
8164
8228
  h.current.setMood("happy"), h.current.setBodyMovement("idle");
8165
8229
  const w = k.current || { lipsyncLang: "en" };
8166
- v.type === "code_test" ? h.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
8230
+ R.type === "code_test" ? h.current.speakText(`Let's go back to this coding challenge: ${R.question}`, {
8167
8231
  lipsyncLang: w.lipsyncLang
8168
- }) : h.current.speakText(`Going back to: ${v.question}`, {
8232
+ }) : h.current.speakText(`Going back to: ${R.question}`, {
8169
8233
  lipsyncLang: w.lipsyncLang
8170
8234
  });
8171
8235
  };
8172
- if (h.current && h.current.isReady && v)
8173
- I();
8174
- else if (v) {
8236
+ if (h.current && h.current.isReady && R)
8237
+ v();
8238
+ else if (R) {
8175
8239
  const w = setInterval(() => {
8176
- h.current && h.current.isReady && (clearInterval(w), I());
8240
+ h.current && h.current.isReady && (clearInterval(w), v());
8177
8241
  }, 100);
8178
8242
  setTimeout(() => {
8179
8243
  clearInterval(w);
8180
8244
  }, 5e3);
8181
8245
  }
8182
8246
  }
8183
- }, [T]), pe = P(() => {
8184
- const v = H.current || { modules: [] };
8185
- if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
8247
+ }, [M]), pe = F(() => {
8248
+ const R = T.current || { modules: [] };
8249
+ if (R.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
8186
8250
  a.current.currentLessonIndex -= 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
8187
8251
  type: "lessonStart",
8188
8252
  moduleIndex: a.current.currentModuleIndex,
@@ -8193,8 +8257,8 @@ const yt = Me(({
8193
8257
  lesson: y()
8194
8258
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
8195
8259
  else if (a.current.currentModuleIndex > 0) {
8196
- const M = v.modules[a.current.currentModuleIndex - 1];
8197
- a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (M?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
8260
+ const E = R.modules[a.current.currentModuleIndex - 1];
8261
+ a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (E?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, c.current.onCustomAction({
8198
8262
  type: "lessonStart",
8199
8263
  moduleIndex: a.current.currentModuleIndex,
8200
8264
  lessonIndex: a.current.currentLessonIndex
@@ -8204,50 +8268,50 @@ const yt = Me(({
8204
8268
  lesson: y()
8205
8269
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
8206
8270
  }
8207
- }, [y]), ee = P(() => {
8271
+ }, [y]), te = F(() => {
8208
8272
  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;
8209
- }, []), le = P((v) => {
8210
- console.log("Avatar is ready!", v);
8211
- const I = y(), w = I?.avatar_script || I?.body;
8273
+ }, []), le = F((R) => {
8274
+ console.log("Avatar is ready!", R);
8275
+ const v = y(), w = v?.avatar_script || v?.body;
8212
8276
  u && w && setTimeout(() => {
8213
8277
  d.current && d.current();
8214
8278
  }, 10);
8215
8279
  }, [u, y]);
8216
8280
  Xe(() => {
8217
- d.current = X, g.current = _, x.current = O, f.current = G, R.current = te, F.current = S, p.current = $;
8281
+ d.current = Z, g.current = Q, x.current = D, b.current = G, I.current = J, H.current = S, m.current = ee;
8218
8282
  }), Ee(r, () => ({
8219
8283
  // Curriculum control methods
8220
- startTeaching: X,
8284
+ startTeaching: Z,
8221
8285
  startQuestions: S,
8222
- handleAnswerSelect: $,
8286
+ handleAnswerSelect: ee,
8223
8287
  handleCodeTestResult: se,
8224
8288
  nextQuestion: G,
8225
8289
  previousQuestion: ae,
8226
- nextLesson: _,
8290
+ nextLesson: Q,
8227
8291
  previousLesson: pe,
8228
- completeLesson: O,
8229
- completeCurriculum: te,
8230
- resetCurriculum: ee,
8292
+ completeLesson: D,
8293
+ completeCurriculum: J,
8294
+ resetCurriculum: te,
8231
8295
  getState: () => ({ ...a.current }),
8232
- getCurrentQuestion: () => T(),
8296
+ getCurrentQuestion: () => M(),
8233
8297
  getCurrentLesson: () => y(),
8234
8298
  // Direct access to avatar ref (always returns current value)
8235
8299
  getAvatarRef: () => h.current,
8236
8300
  // Convenience methods that delegate to avatar (always check current ref)
8237
- speakText: async (v, I = {}) => {
8301
+ speakText: async (R, v = {}) => {
8238
8302
  await h.current?.resumeAudioContext?.();
8239
8303
  const w = k.current || { lipsyncLang: "en" };
8240
- h.current?.speakText(v, { ...I, lipsyncLang: I.lipsyncLang || w.lipsyncLang });
8304
+ h.current?.speakText(R, { ...v, lipsyncLang: v.lipsyncLang || w.lipsyncLang });
8241
8305
  },
8242
8306
  resumeAudioContext: async () => {
8243
8307
  if (h.current?.resumeAudioContext)
8244
8308
  return await h.current.resumeAudioContext();
8245
- const v = h.current?.talkingHead;
8246
- if (v?.audioCtx) {
8247
- const I = v.audioCtx;
8248
- if (I.state === "suspended" || I.state === "interrupted")
8309
+ const R = h.current?.talkingHead;
8310
+ if (R?.audioCtx) {
8311
+ const v = R.audioCtx;
8312
+ if (v.state === "suspended" || v.state === "interrupted")
8249
8313
  try {
8250
- await I.resume(), console.log("Audio context resumed via talkingHead");
8314
+ await v.resume(), console.log("Audio context resumed via talkingHead");
8251
8315
  } catch (w) {
8252
8316
  console.warn("Failed to resume audio context:", w);
8253
8317
  }
@@ -8258,22 +8322,22 @@ const yt = Me(({
8258
8322
  pauseSpeaking: () => h.current?.pauseSpeaking(),
8259
8323
  resumeSpeaking: async () => await h.current?.resumeSpeaking(),
8260
8324
  isPaused: () => h.current && typeof h.current.isPaused < "u" ? h.current.isPaused : !1,
8261
- setMood: (v) => h.current?.setMood(v),
8262
- playAnimation: (v, I) => h.current?.playAnimation(v, I),
8263
- setBodyMovement: (v) => h.current?.setBodyMovement(v),
8264
- setMovementIntensity: (v) => h.current?.setMovementIntensity(v),
8325
+ setMood: (R) => h.current?.setMood(R),
8326
+ playAnimation: (R, v) => h.current?.playAnimation(R, v),
8327
+ setBodyMovement: (R) => h.current?.setBodyMovement(R),
8328
+ setMovementIntensity: (R) => h.current?.setMovementIntensity(R),
8265
8329
  playRandomDance: () => h.current?.playRandomDance(),
8266
- playReaction: (v) => h.current?.playReaction(v),
8330
+ playReaction: (R) => h.current?.playReaction(R),
8267
8331
  playCelebration: () => h.current?.playCelebration(),
8268
- setShowFullAvatar: (v) => h.current?.setShowFullAvatar(v),
8269
- setTimingAdjustment: (v) => h.current?.setTimingAdjustment(v),
8332
+ setShowFullAvatar: (R) => h.current?.setShowFullAvatar(R),
8333
+ setTimingAdjustment: (R) => h.current?.setTimingAdjustment(R),
8270
8334
  lockAvatarPosition: () => h.current?.lockAvatarPosition(),
8271
8335
  unlockAvatarPosition: () => h.current?.unlockAvatarPosition(),
8272
8336
  // Custom action trigger
8273
- triggerCustomAction: (v, I) => {
8337
+ triggerCustomAction: (R, v) => {
8274
8338
  c.current.onCustomAction({
8275
- type: v,
8276
- ...I,
8339
+ type: R,
8340
+ ...v,
8277
8341
  state: { ...a.current }
8278
8342
  });
8279
8343
  },
@@ -8281,7 +8345,7 @@ const yt = Me(({
8281
8345
  handleResize: () => h.current?.handleResize(),
8282
8346
  // Avatar readiness check (always returns current value)
8283
8347
  isAvatarReady: () => h.current?.isReady || !1
8284
- }), [X, S, $, se, G, _, O, te, ee, T, y]);
8348
+ }), [Z, S, ee, se, G, Q, D, J, te, M, y]);
8285
8349
  const U = k.current || {
8286
8350
  avatarUrl: "/avatars/brunette.glb",
8287
8351
  avatarBody: "F",
@@ -8314,8 +8378,8 @@ const yt = Me(({
8314
8378
  onReady: le,
8315
8379
  onLoading: () => {
8316
8380
  },
8317
- onError: (v) => {
8318
- console.error("Avatar error:", v);
8381
+ onError: (R) => {
8382
+ console.error("Avatar error:", R);
8319
8383
  }
8320
8384
  }
8321
8385
  ) });
@@ -8424,7 +8488,7 @@ const Ge = {
8424
8488
  duration: 5e3,
8425
8489
  description: "Excited, energetic movement"
8426
8490
  }
8427
- }, wt = (Z) => Ge[Z] || null, zt = (Z) => Ge.hasOwnProperty(Z);
8491
+ }, wt = (X) => Ge[X] || null, zt = (X) => Ge.hasOwnProperty(X);
8428
8492
  export {
8429
8493
  yt as CurriculumLearning,
8430
8494
  gt as SimpleTalkingAvatar,