@sage-rsc/talking-head-react 1.0.58 → 1.0.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsxs as Te, jsx as he } from "react/jsx-runtime";
2
- import { forwardRef as ve, useRef as Z, useState as de, useEffect as pe, useCallback as T, useImperativeHandle as Ie, useLayoutEffect as Oe } from "react";
2
+ import { forwardRef as ve, useRef as Z, useState as ce, useEffect as pe, useCallback as T, useImperativeHandle as Ie, useLayoutEffect as Oe } from "react";
3
3
  import * as f from "three";
4
4
  import { OrbitControls as Ne } from "three/addons/controls/OrbitControls.js";
5
5
  import { GLTFLoader as Ue } from "three/addons/loaders/GLTFLoader.js";
@@ -521,10 +521,10 @@ class Qe {
521
521
  for (let l = 0; l < o; l++) {
522
522
  const u = l * s, a = Math.min(u + n, t.length), h = t.slice(u, a), r = this.calculateEnergy(h);
523
523
  i.energy.push(r);
524
- const d = this.calculateSpectralCentroid(h);
525
- i.spectralCentroid.push(d);
526
- const c = this.calculateZeroCrossingRate(h);
527
- i.zeroCrossingRate.push(c);
524
+ const c = this.calculateSpectralCentroid(h);
525
+ i.spectralCentroid.push(c);
526
+ const d = this.calculateZeroCrossingRate(h);
527
+ i.zeroCrossingRate.push(d);
528
528
  const g = this.calculateMFCC(h);
529
529
  i.mfcc.push(g);
530
530
  }
@@ -606,8 +606,8 @@ class Qe {
606
606
  for (let u = 0; u < e; u += n) {
607
607
  let a = 1, h = 0;
608
608
  for (let r = 0; r < n / 2; r++) {
609
- const d = i[(u + r) * 2], c = i[(u + r) * 2 + 1], g = i[(u + r + n / 2) * 2] * a - i[(u + r + n / 2) * 2 + 1] * h, y = i[(u + r + n / 2) * 2] * h + i[(u + r + n / 2) * 2 + 1] * a;
610
- i[(u + r) * 2] = d + g, i[(u + r) * 2 + 1] = c + y, i[(u + r + n / 2) * 2] = d - g, i[(u + r + n / 2) * 2 + 1] = c - y;
609
+ const c = i[(u + r) * 2], d = i[(u + r) * 2 + 1], g = i[(u + r + n / 2) * 2] * a - i[(u + r + n / 2) * 2 + 1] * h, y = i[(u + r + n / 2) * 2] * h + i[(u + r + n / 2) * 2 + 1] * a;
610
+ i[(u + r) * 2] = c + g, i[(u + r) * 2 + 1] = d + y, i[(u + r + n / 2) * 2] = c - g, i[(u + r + n / 2) * 2 + 1] = d - y;
611
611
  const x = a * o - h * l, I = a * l + h * o;
612
612
  a = x, h = I;
613
613
  }
@@ -703,15 +703,15 @@ class Qe {
703
703
  const o = this.textToVisemes(e);
704
704
  let l = 0, u = 0;
705
705
  for (let a = 0; a < s.length && l < o.length; a++) {
706
- const h = s[a], r = o[l], d = t.energy[Math.floor(h / 0.023)] || 0, c = this.calculateVisemeDuration(r, d);
706
+ const h = s[a], r = o[l], c = t.energy[Math.floor(h / 0.023)] || 0, d = this.calculateVisemeDuration(r, c);
707
707
  n.push({
708
708
  viseme: r,
709
709
  startTime: u,
710
- endTime: u + c,
711
- duration: c,
712
- intensity: Math.min(1, d * 2)
710
+ endTime: u + d,
711
+ duration: d,
712
+ intensity: Math.min(1, c * 2)
713
713
  // Map energy to viseme intensity
714
- }), u += c, l++;
714
+ }), u += d, l++;
715
715
  }
716
716
  for (; l < o.length; ) {
717
717
  const a = o[l], h = this.calculateVisemeDuration(a, 0.5);
@@ -1207,10 +1207,10 @@ class qe {
1207
1207
  Object.keys(this.rules).forEach((e) => {
1208
1208
  this.rules[e] = this.rules[e].map((i) => {
1209
1209
  const n = i.indexOf("["), s = i.indexOf("]"), o = i.indexOf("="), l = i.substring(0, n), u = i.substring(n + 1, s), a = i.substring(s + 1, o), h = i.substring(o + 1), r = { regex: "", move: 0, visemes: [] };
1210
- let d = "";
1211
- d += [...l].map((g) => t[g] || g).join("");
1212
- const c = [...u];
1213
- return c[0] = c[0].toLowerCase(), d += c.join(""), r.move = c.length, d += [...a].map((g) => t[g] || g).join(""), r.regex = new RegExp(d), h.length && h.split(" ").forEach((g) => {
1210
+ let c = "";
1211
+ c += [...l].map((g) => t[g] || g).join("");
1212
+ const d = [...u];
1213
+ return d[0] = d[0].toLowerCase(), c += d.join(""), r.move = d.length, c += [...a].map((g) => t[g] || g).join(""), r.regex = new RegExp(c), h.length && h.split(" ").forEach((g) => {
1214
1214
  r.visemes.push(g);
1215
1215
  }), r;
1216
1216
  });
@@ -1380,11 +1380,11 @@ class qe {
1380
1380
  if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(u.regex)) {
1381
1381
  u.visemes.forEach((r) => {
1382
1382
  if (e.visemes.length && e.visemes[e.visemes.length - 1] === r) {
1383
- const d = 0.7 * (this.visemeDurations[r] || 1);
1384
- e.durations[e.durations.length - 1] += d, i += d;
1383
+ const c = 0.7 * (this.visemeDurations[r] || 1);
1384
+ e.durations[e.durations.length - 1] += c, i += c;
1385
1385
  } else {
1386
- const d = this.visemeDurations[r] || 1;
1387
- e.visemes.push(r), e.times.push(i), e.durations.push(d), i += d;
1386
+ const c = this.visemeDurations[r] || 1;
1387
+ e.visemes.push(r), e.times.push(i), e.durations.push(c), i += c;
1388
1388
  }
1389
1389
  }), e.i += u.move;
1390
1390
  break;
@@ -1617,10 +1617,10 @@ class Ke {
1617
1617
  Object.keys(this.rules).forEach((e) => {
1618
1618
  this.rules[e] = this.rules[e].map((i) => {
1619
1619
  const n = i.indexOf("["), s = i.indexOf("]"), o = i.indexOf("="), l = i.substring(0, n), u = i.substring(n + 1, s), a = i.substring(s + 1, o), h = i.substring(o + 1), r = { regex: "", move: 0, visemes: [] };
1620
- let d = "";
1621
- d += [...l].map((g) => t[g] || g).join("");
1622
- const c = [...u];
1623
- return c[0] = c[0].toLowerCase(), d += c.join(""), r.move = c.length, d += [...a].map((g) => t[g] || g).join(""), r.regex = new RegExp(d), h.length && h.split(" ").forEach((g) => {
1620
+ let c = "";
1621
+ c += [...l].map((g) => t[g] || g).join("");
1622
+ const d = [...u];
1623
+ return d[0] = d[0].toLowerCase(), c += d.join(""), r.move = d.length, c += [...a].map((g) => t[g] || g).join(""), r.regex = new RegExp(c), h.length && h.split(" ").forEach((g) => {
1624
1624
  r.visemes.push(g);
1625
1625
  }), r;
1626
1626
  });
@@ -1735,13 +1735,13 @@ class Ke {
1735
1735
  for (let u = 0; u < o.length; u++) {
1736
1736
  const a = o[u];
1737
1737
  if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(a.regex)) {
1738
- a.visemes.forEach((d) => {
1739
- if (e.visemes.length && e.visemes[e.visemes.length - 1] === d) {
1740
- const c = 0.7 * (this.visemeDurations[d] || 1);
1741
- e.durations[e.durations.length - 1] += c, i += c;
1738
+ a.visemes.forEach((c) => {
1739
+ if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
1740
+ const d = 0.7 * (this.visemeDurations[c] || 1);
1741
+ e.durations[e.durations.length - 1] += d, i += d;
1742
1742
  } else {
1743
- const c = this.visemeDurations[d] || 1;
1744
- e.visemes.push(d), e.times.push(i), e.durations.push(c), i += c;
1743
+ const d = this.visemeDurations[c] || 1;
1744
+ e.visemes.push(c), e.times.push(i), e.durations.push(d), i += d;
1745
1745
  }
1746
1746
  }), e.i += a.move, l = !0;
1747
1747
  break;
@@ -2132,10 +2132,10 @@ class $e {
2132
2132
  Object.keys(this.rules).forEach((e) => {
2133
2133
  this.rules[e] = this.rules[e].map((i) => {
2134
2134
  const n = i.indexOf("["), s = i.indexOf("]"), o = i.indexOf("="), l = i.substring(0, n), u = i.substring(n + 1, s), a = i.substring(s + 1, o), h = i.substring(o + 1), r = { regex: "", move: 0, visemes: [] };
2135
- let d = "";
2136
- d += [...l].map((g) => t[g] || g).join("");
2137
- const c = [...u];
2138
- return c[0] = c[0].toLowerCase(), d += c.join(""), r.move = c.length, d += [...a].map((g) => t[g] || g).join(""), r.regex = new RegExp(d, "i"), h.length && h.split(" ").forEach((g) => {
2135
+ let c = "";
2136
+ c += [...l].map((g) => t[g] || g).join("");
2137
+ const d = [...u];
2138
+ return d[0] = d[0].toLowerCase(), c += d.join(""), r.move = d.length, c += [...a].map((g) => t[g] || g).join(""), r.regex = new RegExp(c, "i"), h.length && h.split(" ").forEach((g) => {
2139
2139
  g && r.visemes.push(g);
2140
2140
  }), r;
2141
2141
  });
@@ -2270,13 +2270,13 @@ class $e {
2270
2270
  for (let u = 0; u < o.length; u++) {
2271
2271
  const a = o[u];
2272
2272
  if ((e.words.substring(0, e.i) + s.toLowerCase() + e.words.substring(e.i + 1)).match(a.regex)) {
2273
- a.visemes.forEach((d) => {
2274
- if (e.visemes.length && e.visemes[e.visemes.length - 1] === d) {
2275
- const c = 0.7 * (this.visemeDurations[d] || 1);
2276
- e.durations[e.durations.length - 1] += c, i += c;
2273
+ a.visemes.forEach((c) => {
2274
+ if (e.visemes.length && e.visemes[e.visemes.length - 1] === c) {
2275
+ const d = 0.7 * (this.visemeDurations[c] || 1);
2276
+ e.durations[e.durations.length - 1] += d, i += d;
2277
2277
  } else {
2278
- const c = this.visemeDurations[d] || 1;
2279
- e.visemes.push(d), e.times.push(i), e.durations.push(c), i += c;
2278
+ const d = this.visemeDurations[c] || 1;
2279
+ e.visemes.push(c), e.times.push(i), e.durations.push(d), i += d;
2280
2280
  }
2281
2281
  }), e.i += a.move, l = !0;
2282
2282
  break;
@@ -2629,7 +2629,7 @@ const ot = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2629
2629
  fr: et,
2630
2630
  fi: it,
2631
2631
  lt: ot
2632
- }, W = new f.Quaternion(), M = new f.Euler(), ae = new f.Vector3(), le = new f.Vector3(), Ce = new f.Box3();
2632
+ }, V = new f.Quaternion(), M = new f.Euler(), ae = new f.Vector3(), le = new f.Vector3(), Ce = new f.Box3();
2633
2633
  new f.Matrix4();
2634
2634
  new f.Matrix4();
2635
2635
  new f.Vector3();
@@ -4201,15 +4201,15 @@ class Me {
4201
4201
  let l = null, u = null;
4202
4202
  for (const [a, h] of Object.entries(i))
4203
4203
  if (s.morphTargetDictionary.hasOwnProperty(a)) {
4204
- const r = s.morphTargetDictionary[a], d = o.morphAttributes.position[r], c = o.morphAttributes.normal?.[r];
4205
- l || (l = new f.Float32BufferAttribute(d.count * 3, 3), c && (u = new f.Float32BufferAttribute(d.count * 3, 3)));
4206
- for (let g = 0; g < d.count; g++) {
4207
- const y = l.getX(g) + d.getX(g) * h, x = l.getY(g) + d.getY(g) * h, I = l.getZ(g) + d.getZ(g) * h;
4204
+ const r = s.morphTargetDictionary[a], c = o.morphAttributes.position[r], d = o.morphAttributes.normal?.[r];
4205
+ l || (l = new f.Float32BufferAttribute(c.count * 3, 3), d && (u = new f.Float32BufferAttribute(c.count * 3, 3)));
4206
+ for (let g = 0; g < c.count; g++) {
4207
+ const y = l.getX(g) + c.getX(g) * h, x = l.getY(g) + c.getY(g) * h, I = l.getZ(g) + c.getZ(g) * h;
4208
4208
  l.setXYZ(g, y, x, I);
4209
4209
  }
4210
- if (c)
4211
- for (let g = 0; g < d.count; g++) {
4212
- const y = u.getX(g) + c.getX(g) * h, x = u.getY(g) + c.getY(g) * h, I = u.getZ(g) + c.getZ(g) * h;
4210
+ if (d)
4211
+ for (let g = 0; g < c.count; g++) {
4212
+ const y = u.getX(g) + d.getX(g) * h, x = u.getY(g) + d.getY(g) * h, I = u.getZ(g) + d.getZ(g) * h;
4213
4213
  u.setXYZ(g, y, x, I);
4214
4214
  }
4215
4215
  }
@@ -4275,8 +4275,8 @@ class Me {
4275
4275
  h && ["fixed", "system", "systemd", "realtime", "base", "v", "value", "applied"].forEach((r) => {
4276
4276
  l[a][r] = h[r];
4277
4277
  }), this.morphs.forEach((r) => {
4278
- const d = r.morphTargetDictionary[a];
4279
- d !== void 0 && (l[a].ms.push(r.morphTargetInfluences), l[a].is.push(d), r.morphTargetInfluences[d] = l[a].applied);
4278
+ const c = r.morphTargetDictionary[a];
4279
+ c !== void 0 && (l[a].ms.push(r.morphTargetInfluences), l[a].is.push(c), r.morphTargetInfluences[c] = l[a].applied);
4280
4280
  });
4281
4281
  }), this.mtAvatar = l, this.poseAvatar = { props: {} }, this.posePropNames.forEach((a) => {
4282
4282
  const h = a.split("."), r = this.armature.getObjectByName(h[0]);
@@ -4376,7 +4376,7 @@ class Me {
4376
4376
  if (e.x === 0 && e.y === 0 && e.z === 0) continue;
4377
4377
  M.set(e.x, e.y, e.z);
4378
4378
  const i = this.poseAvatar.props[t];
4379
- i.isQuaternion ? (W.setFromEuler(M), i.multiply(W)) : i.isVector3 && i.add(M);
4379
+ i.isQuaternion ? (V.setFromEuler(M), i.multiply(V)) : i.isVector3 && i.add(M);
4380
4380
  }
4381
4381
  }
4382
4382
  /**
@@ -4975,10 +4975,10 @@ class Me {
4975
4975
  if (l.alt.length > 1) {
4976
4976
  const h = Math.random();
4977
4977
  let r = 0;
4978
- for (let d = 0; d < l.alt.length; d++) {
4979
- let c = this.valueFn(l.alt[d].p);
4980
- if (r += c === void 0 ? (1 - r) / (l.alt.length - 1 - d) : c, h < r) {
4981
- a = l.alt[d];
4978
+ for (let c = 0; c < l.alt.length; c++) {
4979
+ let d = this.valueFn(l.alt[c].p);
4980
+ if (r += d === void 0 ? (1 - r) / (l.alt.length - 1 - c) : d, h < r) {
4981
+ a = l.alt[c];
4982
4982
  break;
4983
4983
  }
4984
4984
  }
@@ -4998,8 +4998,8 @@ class Me {
4998
4998
  }
4999
4999
  s ? o.ts = o.ts.map((a) => u + a * i) : o.ts = o.ts.map((a) => this.animClock + u + a * i);
5000
5000
  for (let [a, h] of Object.entries(l.vs)) {
5001
- const r = this.getBaselineValue(a), d = h.map((c) => (c = this.valueFn(c), c === null ? null : typeof c == "function" ? c : typeof c == "string" || c instanceof String ? c.slice() : Array.isArray(c) ? a === "gesture" ? c.slice() : (r === void 0 ? 0 : r) + n * this.gaussianRandom(...c) : typeof c == "boolean" ? c : c instanceof Object && c.constructor === Object ? Object.assign({}, c) : (r === void 0 ? 0 : r) + n * c));
5002
- a === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...d.map((c) => c > 0 ? c : 0)], o.vs.eyeLookInLeft = [null, ...d.map((c) => c > 0 ? 0 : -c)], o.vs.eyeLookOutRight = [null, ...d.map((c) => c > 0 ? 0 : -c)], o.vs.eyeLookInRight = [null, ...d.map((c) => c > 0 ? c : 0)]) : a === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...d.map((c) => c > 0 ? c : 0)], o.vs.eyesLookUp = [null, ...d.map((c) => c > 0 ? 0 : -c)]) : o.vs[a] = [null, ...d];
5001
+ const r = this.getBaselineValue(a), c = h.map((d) => (d = this.valueFn(d), d === null ? null : typeof d == "function" ? d : typeof d == "string" || d instanceof String ? d.slice() : Array.isArray(d) ? a === "gesture" ? d.slice() : (r === void 0 ? 0 : r) + n * this.gaussianRandom(...d) : typeof d == "boolean" ? d : d instanceof Object && d.constructor === Object ? Object.assign({}, d) : (r === void 0 ? 0 : r) + n * d));
5002
+ a === "eyesRotateY" ? (o.vs.eyeLookOutLeft = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyeLookInLeft = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookOutRight = [null, ...c.map((d) => d > 0 ? 0 : -d)], o.vs.eyeLookInRight = [null, ...c.map((d) => d > 0 ? d : 0)]) : a === "eyesRotateX" ? (o.vs.eyesLookDown = [null, ...c.map((d) => d > 0 ? d : 0)], o.vs.eyesLookUp = [null, ...c.map((d) => d > 0 ? 0 : -d)]) : o.vs[a] = [null, ...c];
5003
5003
  }
5004
5004
  for (let a of Object.keys(o.vs))
5005
5005
  for (; o.vs[a].length <= o.ts.length; ) o.vs[a].push(o.vs[a][o.vs[a].length - 1]);
@@ -5086,20 +5086,20 @@ class Me {
5086
5086
  const r = this.animQueue[i];
5087
5087
  if (!(!r || !r.ts || !r.ts.length || this.animClock < r.ts[0])) {
5088
5088
  for (n = r.ndx || 0, o = r.ts.length; n < o && !(this.animClock < r.ts[n]); n++)
5089
- for (let [d, c] of Object.entries(r.vs))
5090
- if (this.mtAvatar.hasOwnProperty(d)) {
5091
- if (c[n + 1] === null) continue;
5092
- const g = this.mtAvatar[d];
5093
- if (c[n] === null && (c[n] = g.value), n === o - 1)
5094
- g.newvalue = c[n];
5089
+ for (let [c, d] of Object.entries(r.vs))
5090
+ if (this.mtAvatar.hasOwnProperty(c)) {
5091
+ if (d[n + 1] === null) continue;
5092
+ const g = this.mtAvatar[c];
5093
+ if (d[n] === null && (d[n] = g.value), n === o - 1)
5094
+ g.newvalue = d[n];
5095
5095
  else {
5096
- g.newvalue = c[n + 1];
5096
+ g.newvalue = d[n + 1];
5097
5097
  const y = r.ts[n + 1] - r.ts[n];
5098
5098
  let x = 1;
5099
- y > 1e-4 && (x = (this.animClock - r.ts[n]) / y), x < 1 && (g.easing && (x = g.easing(x)), g.newvalue = (1 - x) * c[n] + x * g.newvalue), g.ref && g.ref !== r.vs && g.ref.hasOwnProperty(d) && delete g.ref[d], g.ref = r.vs;
5099
+ y > 1e-4 && (x = (this.animClock - r.ts[n]) / y), x < 1 && (g.easing && (x = g.easing(x)), g.newvalue = (1 - x) * d[n] + x * g.newvalue), g.ref && g.ref !== r.vs && g.ref.hasOwnProperty(c) && delete g.ref[c], g.ref = r.vs;
5100
5100
  }
5101
5101
  if (l)
5102
- switch (d) {
5102
+ switch (c) {
5103
5103
  case "viseme_aa":
5104
5104
  case "viseme_E":
5105
5105
  case "viseme_I":
@@ -5108,11 +5108,11 @@ class Me {
5108
5108
  g.newvalue *= 1 + l / 255 - 0.5;
5109
5109
  }
5110
5110
  g.needsUpdate = !0;
5111
- } else d === "eyeContact" && c[n] !== null && u !== !1 ? u = !!c[n] : d === "headMove" && c[n] !== null && a !== !1 ? c[n] === 0 ? a = !1 : (Math.random() < c[n] && (a = !0), c[n] = null) : c[n] !== null && (h.push({ mt: d, val: c[n] }), c[n] = null);
5111
+ } else c === "eyeContact" && d[n] !== null && u !== !1 ? u = !!d[n] : c === "headMove" && d[n] !== null && a !== !1 ? d[n] === 0 ? a = !1 : (Math.random() < d[n] && (a = !0), d[n] = null) : d[n] !== null && (h.push({ mt: c, val: d[n] }), d[n] = null);
5112
5112
  n === o ? (r.hasOwnProperty("mood") && this.setMood(r.mood), r.loop ? (o = this.isSpeaking && (r.template.name === "head" || r.template.name === "eyes") ? 4 : 1, this.animQueue[i] = this.animFactory(r.template, r.loop > 0 ? r.loop - 1 : r.loop, 1, 1 / o)) : (this.animQueue.splice(i--, 1), s--)) : r.ndx = n - 1;
5113
5113
  }
5114
5114
  }
5115
- for (let r = 0, d = h.length; r < d; r++)
5115
+ for (let r = 0, c = h.length; r < c; r++)
5116
5116
  switch (n = h[r].val, h[r].mt) {
5117
5117
  case "speak":
5118
5118
  this.speakText(n);
@@ -5130,8 +5130,8 @@ class Me {
5130
5130
  n && typeof n == "function" && n();
5131
5131
  break;
5132
5132
  case "moveto":
5133
- Object.entries(n.props).forEach((c) => {
5134
- c[1] ? this.poseTarget.props[c[0]].copy(c[1]) : this.poseTarget.props[c[0]].copy(this.getPoseTemplateProp(c[0])), this.poseTarget.props[c[0]].t = this.animClock, this.poseTarget.props[c[0]].d = c[1] && c[1].d ? c[1].d : c.duration || 2e3;
5133
+ Object.entries(n.props).forEach((d) => {
5134
+ d[1] ? this.poseTarget.props[d[0]].copy(d[1]) : this.poseTarget.props[d[0]].copy(this.getPoseTemplateProp(d[0])), this.poseTarget.props[d[0]].t = this.animClock, this.poseTarget.props[d[0]].d = d[1] && d[1].d ? d[1].d : d.duration || 2e3;
5135
5135
  });
5136
5136
  break;
5137
5137
  case "handLeft":
@@ -5180,13 +5180,13 @@ class Me {
5180
5180
  eyeLookOutRight: [null, 0],
5181
5181
  eyeContact: [0]
5182
5182
  }
5183
- })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (i = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], n = this.mtAvatar[i], n.needsUpdate || Object.assign(n, { base: (this.mood.baseline[i] || 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), i = this.volumeHeadTarget - this.volumeHeadCurrent, n = Math.abs(i), n > 1e-4 && (o = n * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / n) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(i) * Math.min(n, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (W.setFromAxisAngle(at, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(W)), Ce.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ae), ae.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(le), le.sub(this.armature.position), this.objectHips.position.y -= Ce.min.y / 2, this.objectHips.position.x -= (ae.x + le.x) / 4, this.objectHips.position.z -= (ae.z + le.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
5183
+ })))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (i = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], n = this.mtAvatar[i], n.needsUpdate || Object.assign(n, { base: (this.mood.baseline[i] || 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), i = this.volumeHeadTarget - this.volumeHeadCurrent, n = Math.abs(i), n > 1e-4 && (o = n * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / n) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(i) * Math.min(n, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (V.setFromAxisAngle(at, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(V)), Ce.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ae), ae.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(le), le.sub(this.armature.position), this.objectHips.position.y -= Ce.min.y / 2, this.objectHips.position.x -= (ae.x + le.x) / 4, this.objectHips.position.z -= (ae.z + le.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
5184
5184
  this.stats && this.stats.end();
5185
5185
  else {
5186
5186
  if (this.cameraClock !== null && this.cameraClock < 1e3) {
5187
5187
  this.cameraClock += e, this.cameraClock > 1e3 && (this.cameraClock = 1e3);
5188
- let r = new f.Spherical().setFromVector3(this.cameraStart), d = new f.Spherical().setFromVector3(this.cameraEnd);
5189
- r.phi += this.easing(this.cameraClock / 1e3) * (d.phi - r.phi), r.theta += this.easing(this.cameraClock / 1e3) * (d.theta - r.theta), r.radius += this.easing(this.cameraClock / 1e3) * (d.radius - r.radius), r.makeSafe(), this.camera.position.setFromSpherical(r), this.controlsStart.x !== this.controlsEnd.x ? this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd, this.easing(this.cameraClock / 1e3))) : (r.setFromVector3(this.controlsStart), d.setFromVector3(this.controlsEnd), r.phi += this.easing(this.cameraClock / 1e3) * (d.phi - r.phi), r.theta += this.easing(this.cameraClock / 1e3) * (d.theta - r.theta), r.radius += this.easing(this.cameraClock / 1e3) * (d.radius - r.radius), r.makeSafe(), this.controls.target.setFromSpherical(r)), this.controls.update();
5188
+ let r = new f.Spherical().setFromVector3(this.cameraStart), c = new f.Spherical().setFromVector3(this.cameraEnd);
5189
+ r.phi += this.easing(this.cameraClock / 1e3) * (c.phi - r.phi), r.theta += this.easing(this.cameraClock / 1e3) * (c.theta - r.theta), r.radius += this.easing(this.cameraClock / 1e3) * (c.radius - r.radius), r.makeSafe(), this.camera.position.setFromSpherical(r), this.controlsStart.x !== this.controlsEnd.x ? this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd, this.easing(this.cameraClock / 1e3))) : (r.setFromVector3(this.controlsStart), c.setFromVector3(this.controlsEnd), r.phi += this.easing(this.cameraClock / 1e3) * (c.phi - r.phi), r.theta += this.easing(this.cameraClock / 1e3) * (c.theta - r.theta), r.radius += this.easing(this.cameraClock / 1e3) * (c.radius - r.radius), r.makeSafe(), this.controls.target.setFromSpherical(r)), this.controls.update();
5190
5190
  }
5191
5191
  this.controls.autoRotate && this.controls.update(), this.stats && this.stats.end(), this.render();
5192
5192
  }
@@ -5248,17 +5248,17 @@ class Me {
5248
5248
  speakText(t, e = null, i = null, n = null) {
5249
5249
  e = e || {};
5250
5250
  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, a = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
5251
- let h = "", r = "", d = 0, c = [], g = [];
5251
+ let h = "", r = "", c = 0, d = [], g = [];
5252
5252
  const y = Array.from(this.segmenter.segment(t), (x) => x.segment);
5253
5253
  for (let x = 0; x < y.length; x++) {
5254
5254
  const I = x === y.length - 1, P = y[x].match(l);
5255
5255
  let p = y[x].match(s);
5256
5256
  const H = y[x].match(u), z = y[x].match(o);
5257
- if (p && !I && !H && y[x + 1].match(s) && (p = !1), i && (h += y[x]), P && (!n || n.every((v) => x < v[0] || x > v[1])) && (r += y[x]), (z || p || I) && (r.length && (r = this.lipsyncPreProcessText(r, a), r.length && c.push({
5258
- mark: d,
5257
+ if (p && !I && !H && y[x + 1].match(s) && (p = !1), i && (h += y[x]), P && (!n || n.every((v) => x < v[0] || x > v[1])) && (r += y[x]), (z || p || I) && (r.length && (r = this.lipsyncPreProcessText(r, a), r.length && d.push({
5258
+ mark: c,
5259
5259
  word: r
5260
5260
  })), h.length && (g.push({
5261
- mark: d,
5261
+ mark: c,
5262
5262
  template: { name: "subtitles" },
5263
5263
  ts: [0],
5264
5264
  vs: {
@@ -5268,24 +5268,24 @@ class Me {
5268
5268
  const v = this.lipsyncWordsToVisemes(r, a);
5269
5269
  if (v && v.visemes && v.visemes.length) {
5270
5270
  const D = v.times[v.visemes.length - 1] + v.durations[v.visemes.length - 1];
5271
- for (let N = 0; N < v.visemes.length; N++)
5271
+ for (let U = 0; U < v.visemes.length; U++)
5272
5272
  g.push({
5273
- mark: d,
5273
+ mark: c,
5274
5274
  template: { name: "viseme" },
5275
- ts: [(v.times[N] - 0.6) / D, (v.times[N] + 0.5) / D, (v.times[N] + v.durations[N] + 0.5) / D],
5275
+ ts: [(v.times[U] - 0.6) / D, (v.times[U] + 0.5) / D, (v.times[U] + v.durations[U] + 0.5) / D],
5276
5276
  vs: {
5277
- ["viseme_" + v.visemes[N]]: [null, v.visemes[N] === "PP" || v.visemes[N] === "FF" ? 0.9 : 0.6, 0]
5277
+ ["viseme_" + v.visemes[U]]: [null, v.visemes[U] === "PP" || v.visemes[U] === "FF" ? 0.9 : 0.6, 0]
5278
5278
  }
5279
5279
  });
5280
5280
  }
5281
- r = "", d++;
5281
+ r = "", c++;
5282
5282
  }
5283
5283
  if (p || I) {
5284
- if (c.length || I && g.length) {
5284
+ if (d.length || I && g.length) {
5285
5285
  const v = {
5286
5286
  anim: g
5287
5287
  };
5288
- i && (v.onSubtitles = i), c.length && !e.avatarMute && (v.text = c, e.avatarMood && (v.mood = e.avatarMood), e.ttsLang && (v.lang = e.ttsLang), e.ttsVoice && (v.voice = e.ttsVoice), e.ttsRate && (v.rate = e.ttsRate), e.ttsVoice && (v.pitch = e.ttsPitch), e.ttsVolume && (v.volume = e.ttsVolume)), this.speechQueue.push(v), c = [], r = "", d = 0, g = [];
5288
+ i && (v.onSubtitles = i), d.length && !e.avatarMute && (v.text = d, e.avatarMood && (v.mood = e.avatarMood), e.ttsLang && (v.lang = e.ttsLang), e.ttsVoice && (v.voice = e.ttsVoice), e.ttsRate && (v.rate = e.ttsRate), e.ttsVoice && (v.pitch = e.ttsPitch), e.ttsVolume && (v.volume = e.ttsVolume)), this.speechQueue.push(v), d = [], r = "", c = 0, g = [];
5289
5289
  }
5290
5290
  if (H) {
5291
5291
  let v = this.animEmojis[y[x]];
@@ -5379,18 +5379,18 @@ class Me {
5379
5379
  subtitles: [" " + u]
5380
5380
  }
5381
5381
  }), !t.visemes)) {
5382
- const r = this.lipsyncPreProcessText(u, n), d = this.lipsyncWordsToVisemes(r, n);
5383
- if (d && d.visemes && d.visemes.length) {
5384
- const c = d.times[d.visemes.length - 1] + d.durations[d.visemes.length - 1], g = Math.min(h, Math.max(0, h - d.visemes.length * 150));
5382
+ const r = this.lipsyncPreProcessText(u, n), c = this.lipsyncWordsToVisemes(r, n);
5383
+ if (c && c.visemes && c.visemes.length) {
5384
+ 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));
5385
5385
  let y = 0.6 + this.convertRange(g, [0, h], [0, 0.4]);
5386
- if (h = Math.min(h, d.visemes.length * 200), c > 0)
5387
- for (let x = 0; x < d.visemes.length; x++) {
5388
- const I = a + d.times[x] / c * h, P = d.durations[x] / c * h;
5386
+ if (h = Math.min(h, c.visemes.length * 200), d > 0)
5387
+ for (let x = 0; x < c.visemes.length; x++) {
5388
+ const I = a + c.times[x] / d * h, P = c.durations[x] / d * h;
5389
5389
  o.push({
5390
5390
  template: { name: "viseme" },
5391
5391
  ts: [I - Math.min(60, 2 * P / 3), I + Math.min(25, P / 2), I + P + Math.min(60, P / 2)],
5392
5392
  vs: {
5393
- ["viseme_" + d.visemes[x]]: [null, d.visemes[x] === "PP" || d.visemes[x] === "FF" ? 0.9 : y, 0]
5393
+ ["viseme_" + c.visemes[x]]: [null, c.visemes[x] === "PP" || c.visemes[x] === "FF" ? 0.9 : y, 0]
5394
5394
  }
5395
5395
  });
5396
5396
  }
@@ -5473,23 +5473,23 @@ class Me {
5473
5473
  const p = h.find((H) => H.name.includes(r) || H.lang === o);
5474
5474
  p && (s.voice = p);
5475
5475
  }
5476
- const d = n.length * 100 / s.rate, c = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (d / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", y = this.lipsyncPreProcessText(n, g), x = this.lipsyncWordsToVisemes(y, g);
5476
+ const c = n.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", y = this.lipsyncPreProcessText(n, g), x = this.lipsyncWordsToVisemes(y, g);
5477
5477
  console.log("Browser TTS Lip-sync Debug:", {
5478
5478
  text: n,
5479
5479
  lipsyncLang: g,
5480
5480
  processedText: y,
5481
5481
  lipsyncData: x,
5482
5482
  hasVisemes: x && x.visemes && x.visemes.length > 0,
5483
- estimatedDuration: d
5483
+ estimatedDuration: c
5484
5484
  });
5485
5485
  const I = [];
5486
5486
  if (x && x.visemes && x.visemes.length > 0) {
5487
5487
  const p = x.times[x.visemes.length - 1] + x.durations[x.visemes.length - 1];
5488
5488
  for (let H = 0; H < x.visemes.length; H++) {
5489
- const z = x.visemes[H], v = x.times[H] / p, D = x.durations[H] / p, N = v * d, _ = D * d;
5489
+ const z = x.visemes[H], v = x.times[H] / p, D = x.durations[H] / p, U = v * c, _ = D * c;
5490
5490
  I.push({
5491
5491
  template: { name: "viseme" },
5492
- ts: [N - Math.min(60, 2 * _ / 3), N + Math.min(25, _ / 2), N + _ + Math.min(60, _ / 2)],
5492
+ ts: [U - Math.min(60, 2 * _ / 3), U + Math.min(25, _ / 2), U + _ + Math.min(60, _ / 2)],
5493
5493
  vs: {
5494
5494
  ["viseme_" + z]: [null, z === "PP" || z === "FF" ? 0.9 : 0.6, 0]
5495
5495
  }
@@ -5497,7 +5497,7 @@ class Me {
5497
5497
  }
5498
5498
  }
5499
5499
  const P = [...t.anim, ...I];
5500
- this.audioPlaylist.push({ anim: P, audio: c }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5500
+ this.audioPlaylist.push({ anim: P, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
5501
5501
  e();
5502
5502
  }, s.onerror = (p) => {
5503
5503
  console.error("Speech synthesis error:", p.error), i(p.error);
@@ -5509,7 +5509,7 @@ class Me {
5509
5509
  * @param {Object} line Speech line object
5510
5510
  */
5511
5511
  async synthesizeWithElevenLabsTTS(t) {
5512
- const e = t.text.map((d) => d.word).join(" "), i = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice || "21m00Tcm4TlvDq8ikWAM", n = {
5512
+ const e = t.text.map((c) => c.word).join(" "), i = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice || "21m00Tcm4TlvDq8ikWAM", n = {
5513
5513
  text: e,
5514
5514
  model_id: "eleven_monolingual_v1",
5515
5515
  voice_settings: {
@@ -5539,18 +5539,18 @@ class Me {
5539
5539
  lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
5540
5540
  lipsyncLang: u
5541
5541
  });
5542
- const d = this.lipsyncPreProcessText(e, u), c = this.lipsyncWordsToVisemes(d, u);
5542
+ const c = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(c, u);
5543
5543
  if (console.log("Lip-sync data:", {
5544
- processedText: d,
5545
- lipsyncData: c,
5546
- hasVisemes: c && c.visemes && c.visemes.length > 0
5547
- }), c && c.visemes && c.visemes.length > 0)
5544
+ processedText: c,
5545
+ lipsyncData: d,
5546
+ hasVisemes: d && d.visemes && d.visemes.length > 0
5547
+ }), d && d.visemes && d.visemes.length > 0)
5548
5548
  a = {
5549
- visemes: c.visemes.map((g, y) => ({
5549
+ visemes: d.visemes.map((g, y) => ({
5550
5550
  viseme: g,
5551
- startTime: y * l.duration / c.visemes.length,
5552
- endTime: (y + 1) * l.duration / c.visemes.length,
5553
- duration: l.duration / c.visemes.length,
5551
+ startTime: y * l.duration / d.visemes.length,
5552
+ endTime: (y + 1) * l.duration / d.visemes.length,
5553
+ duration: l.duration / d.visemes.length,
5554
5554
  intensity: 0.7
5555
5555
  })),
5556
5556
  words: [],
@@ -5559,10 +5559,10 @@ class Me {
5559
5559
  };
5560
5560
  else
5561
5561
  throw new Error("No visemes generated from text");
5562
- } catch (d) {
5563
- console.error("Text-based lip-sync failed, using fallback:", d);
5564
- const c = e.toLowerCase().split(/\s+/), g = [];
5565
- for (const y of c)
5562
+ } catch (c) {
5563
+ console.error("Text-based lip-sync failed, using fallback:", c);
5564
+ const d = e.toLowerCase().split(/\s+/), g = [];
5565
+ for (const y of d)
5566
5566
  for (const x of y) {
5567
5567
  let I = "aa";
5568
5568
  "aeiou".includes(x) ? I = "aa" : "bp".includes(x) ? I = "PP" : "fv".includes(x) ? I = "FF" : "st".includes(x) ? I = "SS" : "dln".includes(x) ? I = "DD" : "kg".includes(x) ? I = "kk" : "rw".includes(x) && (I = "RR"), g.push(I);
@@ -5595,13 +5595,13 @@ class Me {
5595
5595
  const h = [];
5596
5596
  if (a.visemes && a.visemes.length > 0) {
5597
5597
  console.log("ElevenLabs: Generating lip-sync animation from", a.visemes.length, "visemes");
5598
- for (let d = 0; d < a.visemes.length; d++) {
5599
- const c = a.visemes[d], g = c.startTime * 1e3, y = c.duration * 1e3, x = c.intensity;
5598
+ for (let c = 0; c < a.visemes.length; c++) {
5599
+ const d = a.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3, x = d.intensity;
5600
5600
  h.push({
5601
5601
  template: { name: "viseme" },
5602
5602
  ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
5603
5603
  vs: {
5604
- ["viseme_" + c.viseme]: [null, x, 0]
5604
+ ["viseme_" + d.viseme]: [null, x, 0]
5605
5605
  }
5606
5606
  });
5607
5607
  }
@@ -5616,7 +5616,7 @@ class Me {
5616
5616
  * @param {Object} line Speech line object
5617
5617
  */
5618
5618
  async synthesizeWithDeepgramTTS(t) {
5619
- const e = t.text.map((d) => d.word).join(" "), i = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice || "aura-2-thalia-en", n = `${this.opt.ttsEndpoint}?model=${i}`, s = await fetch(n, {
5619
+ const e = t.text.map((c) => c.word).join(" "), i = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice || "aura-2-thalia-en", n = `${this.opt.ttsEndpoint}?model=${i}`, s = await fetch(n, {
5620
5620
  method: "POST",
5621
5621
  headers: {
5622
5622
  Authorization: `Token ${this.opt.ttsApikey}`,
@@ -5637,18 +5637,18 @@ class Me {
5637
5637
  lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
5638
5638
  lipsyncLang: u
5639
5639
  });
5640
- const d = this.lipsyncPreProcessText(e, u), c = this.lipsyncWordsToVisemes(d, u);
5640
+ const c = this.lipsyncPreProcessText(e, u), d = this.lipsyncWordsToVisemes(c, u);
5641
5641
  if (console.log("Lip-sync data:", {
5642
- processedText: d,
5643
- lipsyncData: c,
5644
- hasVisemes: c && c.visemes && c.visemes.length > 0
5645
- }), c && c.visemes && c.visemes.length > 0)
5642
+ processedText: c,
5643
+ lipsyncData: d,
5644
+ hasVisemes: d && d.visemes && d.visemes.length > 0
5645
+ }), d && d.visemes && d.visemes.length > 0)
5646
5646
  a = {
5647
- visemes: c.visemes.map((g, y) => ({
5647
+ visemes: d.visemes.map((g, y) => ({
5648
5648
  viseme: g,
5649
- startTime: y * l.duration / c.visemes.length,
5650
- endTime: (y + 1) * l.duration / c.visemes.length,
5651
- duration: l.duration / c.visemes.length,
5649
+ startTime: y * l.duration / d.visemes.length,
5650
+ endTime: (y + 1) * l.duration / d.visemes.length,
5651
+ duration: l.duration / d.visemes.length,
5652
5652
  intensity: 0.7
5653
5653
  })),
5654
5654
  words: [],
@@ -5657,10 +5657,10 @@ class Me {
5657
5657
  };
5658
5658
  else
5659
5659
  throw new Error("No visemes generated from text");
5660
- } catch (d) {
5661
- console.error("Text-based lip-sync failed, using fallback:", d);
5662
- const c = e.toLowerCase().split(/\s+/), g = [];
5663
- for (const y of c)
5660
+ } catch (c) {
5661
+ console.error("Text-based lip-sync failed, using fallback:", c);
5662
+ const d = e.toLowerCase().split(/\s+/), g = [];
5663
+ for (const y of d)
5664
5664
  for (const x of y) {
5665
5665
  let I = "aa";
5666
5666
  "aeiou".includes(x) ? I = "aa" : "bp".includes(x) ? I = "PP" : "fv".includes(x) ? I = "FF" : "st".includes(x) ? I = "SS" : "dln".includes(x) ? I = "DD" : "kg".includes(x) ? I = "kk" : "rw".includes(x) && (I = "RR"), g.push(I);
@@ -5693,13 +5693,13 @@ class Me {
5693
5693
  const h = [];
5694
5694
  if (a.visemes && a.visemes.length > 0) {
5695
5695
  console.log("Deepgram: Generating lip-sync animation from", a.visemes.length, "visemes");
5696
- for (let d = 0; d < a.visemes.length; d++) {
5697
- const c = a.visemes[d], g = c.startTime * 1e3, y = c.duration * 1e3, x = c.intensity;
5696
+ for (let c = 0; c < a.visemes.length; c++) {
5697
+ const d = a.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3, x = d.intensity;
5698
5698
  h.push({
5699
5699
  template: { name: "viseme" },
5700
5700
  ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
5701
5701
  vs: {
5702
- ["viseme_" + c.viseme]: [null, x, 0]
5702
+ ["viseme_" + d.viseme]: [null, x, 0]
5703
5703
  }
5704
5704
  });
5705
5705
  }
@@ -5746,12 +5746,12 @@ class Me {
5746
5746
  });
5747
5747
  const a = [];
5748
5748
  for (let r = 0; r < u.visemes.length; r++) {
5749
- const d = u.visemes[r], c = d.startTime * 1e3, g = d.duration * 1e3, y = d.intensity;
5749
+ const c = u.visemes[r], d = c.startTime * 1e3, g = c.duration * 1e3, y = c.intensity;
5750
5750
  a.push({
5751
5751
  template: { name: "viseme" },
5752
- ts: [c - Math.min(60, 2 * g / 3), c + Math.min(25, g / 2), c + g + Math.min(60, g / 2)],
5752
+ ts: [d - Math.min(60, 2 * g / 3), d + Math.min(25, g / 2), d + g + Math.min(60, g / 2)],
5753
5753
  vs: {
5754
- ["viseme_" + d.viseme]: [null, y, 0]
5754
+ ["viseme_" + c.viseme]: [null, y, 0]
5755
5755
  }
5756
5756
  });
5757
5757
  }
@@ -5797,25 +5797,25 @@ class Me {
5797
5797
  this.speakWithHands();
5798
5798
  const u = [0];
5799
5799
  let a = 0;
5800
- t.text.forEach((d, c) => {
5801
- if (c > 0) {
5800
+ t.text.forEach((c, d) => {
5801
+ if (d > 0) {
5802
5802
  let g = u[u.length - 1];
5803
- s.timepoints[a] && (g = s.timepoints[a].timeSeconds * 1e3, s.timepoints[a].markName === "" + d.mark && a++), u.push(g);
5803
+ s.timepoints[a] && (g = s.timepoints[a].timeSeconds * 1e3, s.timepoints[a].markName === "" + c.mark && a++), u.push(g);
5804
5804
  }
5805
5805
  });
5806
5806
  const h = [{ mark: 0, time: 0 }];
5807
- u.forEach((d, c) => {
5808
- if (c > 0) {
5809
- let g = d - u[c - 1];
5810
- h[c - 1].duration = g, h.push({ mark: c, time: d });
5807
+ u.forEach((c, d) => {
5808
+ if (d > 0) {
5809
+ let g = c - u[d - 1];
5810
+ h[d - 1].duration = g, h.push({ mark: d, time: c });
5811
5811
  }
5812
5812
  });
5813
5813
  let r = 1e3 * l.duration;
5814
- r > this.opt.ttsTrimEnd && (r = r - this.opt.ttsTrimEnd), h[h.length - 1].duration = r - h[h.length - 1].time, t.anim.forEach((d) => {
5815
- const c = h[d.mark];
5816
- if (c)
5817
- for (let g = 0; g < d.ts.length; g++)
5818
- d.ts[g] = c.time + d.ts[g] * c.duration + this.opt.ttsTrimStart;
5814
+ r > this.opt.ttsTrimEnd && (r = r - this.opt.ttsTrimEnd), h[h.length - 1].duration = r - h[h.length - 1].time, t.anim.forEach((c) => {
5815
+ const d = h[c.mark];
5816
+ if (d)
5817
+ for (let g = 0; g < c.ts.length; g++)
5818
+ c.ts[g] = d.time + c.ts[g] * d.duration + this.opt.ttsTrimStart;
5819
5819
  }), this.audioPlaylist.push({ anim: t.anim, audio: l }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
5820
5820
  } else
5821
5821
  this.startSpeaking(!0);
@@ -6034,15 +6034,15 @@ class Me {
6034
6034
  const l = this.streamLipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang, u = this.lipsyncPreProcessText(n, l), a = this.lipsyncWordsToVisemes(u, l);
6035
6035
  if (a && a.visemes && a.visemes.length) {
6036
6036
  const h = a.times[a.visemes.length - 1] + a.durations[a.visemes.length - 1], r = Math.min(o, Math.max(0, o - a.visemes.length * 150));
6037
- let d = 0.6 + this.convertRange(r, [0, o], [0, 0.4]);
6037
+ let c = 0.6 + this.convertRange(r, [0, o], [0, 0.4]);
6038
6038
  if (o = Math.min(o, a.visemes.length * 200), h > 0)
6039
- for (let c = 0; c < a.visemes.length; c++) {
6040
- const g = e + s + a.times[c] / h * o, y = a.durations[c] / h * o;
6039
+ for (let d = 0; d < a.visemes.length; d++) {
6040
+ const g = e + s + a.times[d] / h * o, y = a.durations[d] / h * o;
6041
6041
  this.animQueue.push({
6042
6042
  template: { name: "viseme" },
6043
6043
  ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
6044
6044
  vs: {
6045
- ["viseme_" + a.visemes[c]]: [null, a.visemes[c] === "PP" || a.visemes[c] === "FF" ? 0.9 : d, 0]
6045
+ ["viseme_" + a.visemes[d]]: [null, a.visemes[d] === "PP" || a.visemes[d] === "FF" ? 0.9 : c, 0]
6046
6046
  }
6047
6047
  });
6048
6048
  }
@@ -6146,12 +6146,12 @@ class Me {
6146
6146
  this.lookAt(null, null, t);
6147
6147
  return;
6148
6148
  }
6149
- this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ae.setFromMatrixPosition(this.objectLeftEye.matrixWorld), le.setFromMatrixPosition(this.objectRightEye.matrixWorld), ae.add(le).divideScalar(2), W.copy(this.armature.quaternion), W.multiply(this.poseTarget.props["Hips.quaternion"]), W.multiply(this.poseTarget.props["Spine.quaternion"]), W.multiply(this.poseTarget.props["Spine1.quaternion"]), W.multiply(this.poseTarget.props["Spine2.quaternion"]), W.multiply(this.poseTarget.props["Neck.quaternion"]), W.multiply(this.poseTarget.props["Head.quaternion"]);
6149
+ this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ae.setFromMatrixPosition(this.objectLeftEye.matrixWorld), le.setFromMatrixPosition(this.objectRightEye.matrixWorld), ae.add(le).divideScalar(2), V.copy(this.armature.quaternion), V.multiply(this.poseTarget.props["Hips.quaternion"]), V.multiply(this.poseTarget.props["Spine.quaternion"]), V.multiply(this.poseTarget.props["Spine1.quaternion"]), V.multiply(this.poseTarget.props["Spine2.quaternion"]), V.multiply(this.poseTarget.props["Neck.quaternion"]), V.multiply(this.poseTarget.props["Head.quaternion"]);
6150
6150
  const i = new f.Vector3().subVectors(e, ae).normalize(), n = Math.atan2(i.x, i.z), s = Math.asin(-i.y);
6151
6151
  M.set(s, n, 0, "YXZ");
6152
- const l = new f.Quaternion().setFromEuler(M), u = new f.Quaternion().copy(l).multiply(W.clone().invert());
6152
+ const l = new f.Quaternion().setFromEuler(M), u = new f.Quaternion().copy(l).multiply(V.clone().invert());
6153
6153
  M.setFromQuaternion(u, "YXZ");
6154
- let a = M.x / (40 / 24) + 0.2, h = M.y / (9 / 4), r = Math.min(0.6, Math.max(-0.3, a)), d = Math.min(0.8, Math.max(-0.8, h)), c = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6154
+ let a = M.x / (40 / 24) + 0.2, h = M.y / (9 / 4), r = Math.min(0.6, Math.max(-0.3, a)), c = Math.min(0.8, Math.max(-0.8, h)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
6155
6155
  if (t) {
6156
6156
  let y = this.animQueue.findIndex((I) => I.template.name === "lookat");
6157
6157
  y !== -1 && this.animQueue.splice(y, 1);
@@ -6159,9 +6159,9 @@ class Me {
6159
6159
  name: "lookat",
6160
6160
  dt: [750, t],
6161
6161
  vs: {
6162
- bodyRotateX: [r + c],
6163
- bodyRotateY: [d + g],
6164
- eyesRotateX: [-3 * c + 0.1],
6162
+ bodyRotateX: [r + d],
6163
+ bodyRotateY: [c + g],
6164
+ eyesRotateX: [-3 * d + 0.1],
6165
6165
  eyesRotateY: [-5 * g],
6166
6166
  browInnerUp: [[0, 0.7]],
6167
6167
  mouthLeft: [[0, 0.7]],
@@ -6186,8 +6186,8 @@ class Me {
6186
6186
  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);
6187
6187
  l.project(this.camera);
6188
6188
  let u = (l.x + 1) / 2 * n.width + n.left, a = -(l.y - 1) / 2 * n.height + n.top;
6189
- t === null && (t = u), e === null && (e = a), W.copy(this.armature.quaternion), W.multiply(this.poseTarget.props["Hips.quaternion"]), W.multiply(this.poseTarget.props["Spine.quaternion"]), W.multiply(this.poseTarget.props["Spine1.quaternion"]), W.multiply(this.poseTarget.props["Spine2.quaternion"]), W.multiply(this.poseTarget.props["Neck.quaternion"]), W.multiply(this.poseTarget.props["Head.quaternion"]), M.setFromQuaternion(W);
6190
- let h = M.x / (40 / 24), r = M.y / (9 / 4), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - u, u), y = Math.max(window.innerHeight - a, a), x = this.convertRange(e, [a - y, a + y], [-0.3, 0.6]) - h + d, I = this.convertRange(t, [u - g, u + g], [-0.8, 0.8]) - r + c;
6189
+ t === null && (t = u), e === null && (e = a), V.copy(this.armature.quaternion), V.multiply(this.poseTarget.props["Hips.quaternion"]), V.multiply(this.poseTarget.props["Spine.quaternion"]), V.multiply(this.poseTarget.props["Spine1.quaternion"]), V.multiply(this.poseTarget.props["Spine2.quaternion"]), V.multiply(this.poseTarget.props["Neck.quaternion"]), V.multiply(this.poseTarget.props["Head.quaternion"]), M.setFromQuaternion(V);
6190
+ let h = M.x / (40 / 24), r = M.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), y = Math.max(window.innerHeight - a, a), x = this.convertRange(e, [a - y, a + y], [-0.3, 0.6]) - h + c, I = this.convertRange(t, [u - g, u + g], [-0.8, 0.8]) - r + d;
6191
6191
  x = Math.min(0.6, Math.max(-0.3, x)), I = Math.min(0.8, Math.max(-0.8, I));
6192
6192
  let P = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
6193
6193
  if (i) {
@@ -6395,58 +6395,58 @@ class Me {
6395
6395
  }
6396
6396
  let a = !1;
6397
6397
  try {
6398
- const d = await fetch(t, { method: "HEAD" });
6399
- if (a = d.ok, !a) {
6400
- console.error(`FBX file not found at ${t}. Status: ${d.status}`), console.error("Please check:"), console.error("1. File path is correct (note: path is case-sensitive)"), console.error("2. File exists in your public folder"), console.error("3. File is accessible (not blocked by server)");
6398
+ const c = await fetch(t, { method: "HEAD" });
6399
+ if (a = c.ok, !a) {
6400
+ console.error(`FBX file not found at ${t}. Status: ${c.status}`), console.error("Please check:"), console.error("1. File path is correct (note: path is case-sensitive)"), console.error("2. File exists in your public folder"), console.error("3. File is accessible (not blocked by server)");
6401
6401
  return;
6402
6402
  }
6403
- } catch (d) {
6404
- console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, d);
6403
+ } catch (c) {
6404
+ console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, c);
6405
6405
  }
6406
6406
  const h = new ke();
6407
6407
  let r;
6408
6408
  try {
6409
6409
  r = await h.loadAsync(t, e);
6410
- } catch (d) {
6411
- console.error(`Failed to load FBX animation from ${t}:`, d), console.error("Error details:", {
6412
- message: d.message,
6410
+ } catch (c) {
6411
+ console.error(`Failed to load FBX animation from ${t}:`, c), console.error("Error details:", {
6412
+ message: c.message,
6413
6413
  url: t,
6414
6414
  suggestion: "Make sure the file is a valid FBX file and the path is correct"
6415
- }), d.message && d.message.includes("version number") && (console.error("FBX Loader Error: Cannot find version number"), console.error("This error usually means:"), console.error("1. The file is not a valid FBX file (might be GLB, corrupted, or wrong format)"), console.error("2. The file might be corrupted"), console.error("3. The file path might be incorrect"), console.error("4. The server returned an HTML error page instead of the FBX file"), console.error("5. The file might not exist at that path"), console.error(""), console.error("Solution: Please verify:"), console.error(` - File exists at: ${t}`), console.error(" - File is a valid FBX binary file"), console.error(" - File path matches your public folder structure"), console.error(" - File is not corrupted"));
6415
+ }), c.message && c.message.includes("version number") && (console.error("FBX Loader Error: Cannot find version number"), console.error("This error usually means:"), console.error("1. The file is not a valid FBX file (might be GLB, corrupted, or wrong format)"), console.error("2. The file might be corrupted"), console.error("3. The file path might be incorrect"), console.error("4. The server returned an HTML error page instead of the FBX file"), console.error("5. The file might not exist at that path"), console.error(""), console.error("Solution: Please verify:"), console.error(` - File exists at: ${t}`), console.error(" - File is a valid FBX binary file"), console.error(" - File path matches your public folder structure"), console.error(" - File is not corrupted"));
6416
6416
  try {
6417
- const c = await fetch(t), g = c.headers.get("content-type"), y = await c.text();
6417
+ const d = await fetch(t), g = d.headers.get("content-type"), y = await d.text();
6418
6418
  console.error("Response details:", {
6419
- status: c.status,
6419
+ status: d.status,
6420
6420
  contentType: g,
6421
6421
  firstBytes: y.substring(0, 100),
6422
6422
  isHTML: y.trim().startsWith("<!DOCTYPE") || y.trim().startsWith("<html")
6423
6423
  }), (y.trim().startsWith("<!DOCTYPE") || y.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
6424
- } catch (c) {
6425
- console.error("Could not fetch file for debugging:", c);
6424
+ } catch (d) {
6425
+ console.error("Could not fetch file for debugging:", d);
6426
6426
  }
6427
6427
  return;
6428
6428
  }
6429
6429
  if (r && r.animations && r.animations[n]) {
6430
- let d = r.animations[n];
6431
- const c = {};
6432
- d.tracks.forEach((y) => {
6430
+ let c = r.animations[n];
6431
+ const d = {};
6432
+ c.tracks.forEach((y) => {
6433
6433
  y.name = y.name.replaceAll("mixamorig", "");
6434
6434
  const x = y.name.split(".");
6435
6435
  if (x[1] === "position") {
6436
6436
  for (let I = 0; I < y.values.length; I++)
6437
6437
  y.values[I] = y.values[I] * s;
6438
- c[y.name] = new f.Vector3(y.values[0], y.values[1], y.values[2]);
6439
- } else x[1] === "quaternion" ? c[y.name] = new f.Quaternion(y.values[0], y.values[1], y.values[2], y.values[3]) : x[1] === "rotation" && (c[x[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(y.values[0], y.values[1], y.values[2], "XYZ")).normalize());
6438
+ d[y.name] = new f.Vector3(y.values[0], y.values[1], y.values[2]);
6439
+ } else x[1] === "quaternion" ? d[y.name] = new f.Quaternion(y.values[0], y.values[1], y.values[2], y.values[3]) : x[1] === "rotation" && (d[x[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(y.values[0], y.values[1], y.values[2], "XYZ")).normalize());
6440
6440
  });
6441
- const g = { props: c };
6442
- c["Hips.position"] && (c["Hips.position"].y < 0.5 ? g.lying = !0 : g.standing = !0), this.animClips.push({
6441
+ const g = { props: d };
6442
+ d["Hips.position"] && (d["Hips.position"].y < 0.5 ? g.lying = !0 : g.standing = !0), this.animClips.push({
6443
6443
  url: t + "-" + n,
6444
- clip: d,
6444
+ clip: c,
6445
6445
  pose: g
6446
6446
  }), this.playAnimation(t, e, i, n, s);
6447
6447
  } else {
6448
- const d = "Animation " + t + " (ndx=" + n + ") not found";
6449
- console.error(d), r && r.animations ? console.error(`FBX file loaded but has ${r.animations.length} animation(s), requested index ${n}`) : console.error(r ? "FBX file loaded but contains no animations" : "FBX file failed to load or is invalid");
6448
+ const c = "Animation " + t + " (ndx=" + n + ") not found";
6449
+ console.error(c), r && r.animations ? console.error(`FBX file loaded but has ${r.animations.length} animation(s), requested index ${n}`) : console.error(r ? "FBX file loaded but contains no animations" : "FBX file failed to load or is invalid");
6450
6450
  }
6451
6451
  }
6452
6452
  }
@@ -6484,10 +6484,10 @@ class Me {
6484
6484
  if (u && u.animations && u.animations[n]) {
6485
6485
  let a = u.animations[n];
6486
6486
  const h = {};
6487
- a.tracks.forEach((d) => {
6488
- d.name = d.name.replaceAll("mixamorig", "");
6489
- const c = d.name.split(".");
6490
- c[1] === "position" ? h[d.name] = new f.Vector3(d.values[0] * s, d.values[1] * s, d.values[2] * s) : c[1] === "quaternion" ? h[d.name] = new f.Quaternion(d.values[0], d.values[1], d.values[2], d.values[3]) : c[1] === "rotation" && (h[c[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(d.values[0], d.values[1], d.values[2], "XYZ")).normalize());
6487
+ a.tracks.forEach((c) => {
6488
+ c.name = c.name.replaceAll("mixamorig", "");
6489
+ const d = c.name.split(".");
6490
+ 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());
6491
6491
  });
6492
6492
  const r = { props: h };
6493
6493
  h["Hips.position"] && (h["Hips.position"].y < 0.5 ? r.lying = !0 : r.standing = !0), this.animPoses.push({
@@ -6532,13 +6532,13 @@ class Me {
6532
6532
  if (l.gesture = !0, e && Number.isFinite(e)) {
6533
6533
  const u = l.ts[0], h = l.ts[l.ts.length - 1] - u;
6534
6534
  if (e * 1e3 - h > 0) {
6535
- const d = [];
6536
- for (let y = 1; y < l.ts.length; y++) d.push(l.ts[y] - l.ts[y - 1]);
6537
- const c = o.template?.rescale || d.map((y) => y / h), g = e * 1e3 - h;
6538
- l.ts = l.ts.map((y, x, I) => x === 0 ? u : I[x - 1] + d[x - 1] + c[x - 1] * g);
6535
+ const c = [];
6536
+ for (let y = 1; y < l.ts.length; y++) c.push(l.ts[y] - l.ts[y - 1]);
6537
+ const d = o.template?.rescale || c.map((y) => y / h), g = e * 1e3 - h;
6538
+ l.ts = l.ts.map((y, x, I) => x === 0 ? u : I[x - 1] + c[x - 1] + d[x - 1] * g);
6539
6539
  } else {
6540
- const d = e * 1e3 / h;
6541
- l.ts = l.ts.map((c) => u + d * (c - u));
6540
+ const c = e * 1e3 / h;
6541
+ l.ts = l.ts.map((d) => u + c * (d - u));
6542
6542
  }
6543
6543
  }
6544
6544
  this.animQueue.push(l);
@@ -6568,12 +6568,12 @@ class Me {
6568
6568
  * @param {numeric} [d=null] If set, apply in d milliseconds
6569
6569
  */
6570
6570
  ikSolve(t, e = null, i = !1, n = null) {
6571
- const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(), u = new f.Vector3(), a = new f.Quaternion(), h = new f.Vector3(), r = new f.Vector3(), d = new f.Vector3(), c = this.ikMesh.getObjectByName(t.root);
6572
- c.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), c.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && i && e.applyQuaternion(this.armature.quaternion).add(c.position);
6571
+ const s = new f.Vector3(), o = new f.Vector3(), l = new f.Vector3(), u = new f.Vector3(), a = new f.Quaternion(), h = new f.Vector3(), r = new f.Vector3(), c = new f.Vector3(), d = this.ikMesh.getObjectByName(t.root);
6572
+ d.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && i && e.applyQuaternion(this.armature.quaternion).add(d.position);
6573
6573
  const g = this.ikMesh.getObjectByName(t.effector), y = t.links;
6574
6574
  y.forEach((I) => {
6575
6575
  I.bone = this.ikMesh.getObjectByName(I.link), I.bone.quaternion.copy(this.getPoseTemplateProp(I.link + ".quaternion"));
6576
- }), c.updateMatrixWorld(!0);
6576
+ }), d.updateMatrixWorld(!0);
6577
6577
  const x = t.iterations || 10;
6578
6578
  if (e)
6579
6579
  for (let I = 0; I < x; I++) {
@@ -6582,7 +6582,7 @@ class Me {
6582
6582
  const z = y[p].bone;
6583
6583
  z.matrixWorld.decompose(u, a, h), a.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, u), l.applyQuaternion(a), l.normalize(), s.subVectors(e, u), s.applyQuaternion(a), s.normalize();
6584
6584
  let v = s.dot(l);
6585
- v > 1 ? v = 1 : v < -1 && (v = -1), v = Math.acos(v), !(v < 1e-5) && (y[p].minAngle !== void 0 && v < y[p].minAngle && (v = y[p].minAngle), y[p].maxAngle !== void 0 && v > y[p].maxAngle && (v = y[p].maxAngle), r.crossVectors(l, s), r.normalize(), W.setFromAxisAngle(r, v), z.quaternion.multiply(W), z.rotation.setFromVector3(d.setFromEuler(z.rotation).clamp(new f.Vector3(
6585
+ v > 1 ? v = 1 : v < -1 && (v = -1), v = Math.acos(v), !(v < 1e-5) && (y[p].minAngle !== void 0 && v < y[p].minAngle && (v = y[p].minAngle), y[p].maxAngle !== void 0 && v > y[p].maxAngle && (v = y[p].maxAngle), r.crossVectors(l, s), r.normalize(), V.setFromAxisAngle(r, v), z.quaternion.multiply(V), z.rotation.setFromVector3(c.setFromEuler(z.rotation).clamp(new f.Vector3(
6586
6586
  y[p].minx !== void 0 ? y[p].minx : -1 / 0,
6587
6587
  y[p].miny !== void 0 ? y[p].miny : -1 / 0,
6588
6588
  y[p].minz !== void 0 ? y[p].minz : -1 / 0
@@ -6655,16 +6655,16 @@ function Le() {
6655
6655
  };
6656
6656
  }
6657
6657
  function xt() {
6658
- const O = Le(), t = [];
6659
- return Object.entries(O.voices).forEach(([e, i]) => {
6658
+ const N = Le(), t = [];
6659
+ return Object.entries(N.voices).forEach(([e, i]) => {
6660
6660
  t.push({
6661
6661
  value: i,
6662
- label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${O.service})`
6662
+ label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${N.service})`
6663
6663
  });
6664
6664
  }), t;
6665
6665
  }
6666
6666
  const Ee = ve(({
6667
- avatarUrl: O = "/avatars/brunette.glb",
6667
+ avatarUrl: N = "/avatars/brunette.glb",
6668
6668
  avatarBody: t = "F",
6669
6669
  mood: e = "neutral",
6670
6670
  ttsLang: i = "en",
@@ -6677,15 +6677,15 @@ const Ee = ve(({
6677
6677
  cameraView: h = "upper",
6678
6678
  onReady: r = () => {
6679
6679
  },
6680
- onLoading: d = () => {
6680
+ onLoading: c = () => {
6681
6681
  },
6682
- onError: c = () => {
6682
+ onError: d = () => {
6683
6683
  },
6684
6684
  className: g = "",
6685
6685
  style: y = {},
6686
6686
  animations: x = {}
6687
6687
  }, I) => {
6688
- const P = Z(null), p = Z(null), H = Z(a), z = Z(null), [v, D] = de(!0), [N, _] = de(null), [ne, S] = de(!1), [U, V] = de(!1);
6688
+ const P = Z(null), p = Z(null), H = Z(a), z = Z(null), [v, D] = ce(!0), [U, _] = ce(null), [ne, S] = ce(!1), [W, G] = ce(!1);
6689
6689
  pe(() => {
6690
6690
  H.current = a;
6691
6691
  }, [a]);
@@ -6714,7 +6714,7 @@ const Ee = ve(({
6714
6714
  apiKey: o !== null ? o : E.apiKey
6715
6715
  };
6716
6716
  const ue = {
6717
- url: O,
6717
+ url: N,
6718
6718
  body: t,
6719
6719
  avatarMood: e,
6720
6720
  ttsLang: X === "browser" ? "en-US" : i,
@@ -6735,7 +6735,7 @@ const Ee = ve(({
6735
6735
  if (D(!0), _(null), p.current = new Me(P.current, Re), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), x && Object.keys(x).length > 0 && (p.current.customAnimations = x), await p.current.showAvatar(ue, (j) => {
6736
6736
  if (j.lengthComputable) {
6737
6737
  const B = Math.min(100, Math.round(j.loaded / j.total * 100));
6738
- d(B);
6738
+ c(B);
6739
6739
  }
6740
6740
  }), await new Promise((j) => {
6741
6741
  const B = () => {
@@ -6756,9 +6756,9 @@ const Ee = ve(({
6756
6756
  document.removeEventListener("visibilitychange", F);
6757
6757
  };
6758
6758
  } catch (A) {
6759
- console.error("Error initializing TalkingHead:", A), _(A.message || "Failed to initialize avatar"), D(!1), c(A);
6759
+ console.error("Error initializing TalkingHead:", A), _(A.message || "Failed to initialize avatar"), D(!1), d(A);
6760
6760
  }
6761
- }, [O, t, e, i, n, s, o, a, l, u, h]);
6761
+ }, [N, t, e, i, n, s, o, a, l, u, h]);
6762
6762
  pe(() => (ge(), () => {
6763
6763
  p.current && (p.current.stop(), p.current.dispose(), p.current = null);
6764
6764
  }), [ge]), pe(() => {
@@ -6785,18 +6785,18 @@ const Ee = ve(({
6785
6785
  }, []), J = T(async (A, F = {}) => {
6786
6786
  if (p.current && ne)
6787
6787
  try {
6788
- z.current = { text: A, options: F }, V(!1), await re();
6788
+ z.current = { text: A, options: F }, G(!1), await re();
6789
6789
  const j = {
6790
6790
  ...F,
6791
6791
  lipsyncLang: F.lipsyncLang || ue.lipsyncLang || "en"
6792
6792
  };
6793
6793
  if (F.onSpeechEnd && p.current) {
6794
6794
  const B = p.current;
6795
- let ee = null, ce = 0;
6795
+ let ee = null, de = 0;
6796
6796
  const Ae = 1200;
6797
6797
  let ye = !1;
6798
6798
  ee = setInterval(() => {
6799
- if (ce++, ce > Ae) {
6799
+ if (de++, de > Ae) {
6800
6800
  if (ee && (clearInterval(ee), ee = null), !ye) {
6801
6801
  ye = !0;
6802
6802
  try {
@@ -6827,15 +6827,15 @@ const Ee = ve(({
6827
6827
  console.error("Error speaking text:", j), _(j.message || "Failed to speak text");
6828
6828
  }
6829
6829
  }, [ne, re, ue.lipsyncLang]), b = T(() => {
6830
- p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, V(!1));
6830
+ p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, G(!1));
6831
6831
  }, []), R = T(() => {
6832
6832
  if (p.current && p.current.pauseSpeaking) {
6833
6833
  const A = p.current, F = A.isSpeaking || A.audioPlaylist && A.audioPlaylist.length > 0 || A.speechQueue && A.speechQueue.length > 0;
6834
- (F && z.current && z.current.text || F) && (p.current.pauseSpeaking(), V(!0));
6834
+ (F && z.current && z.current.text || F) && (p.current.pauseSpeaking(), G(!0));
6835
6835
  }
6836
6836
  }, []), w = T(async () => {
6837
- if (p.current && U)
6838
- if (V(!1), await re(), z.current && z.current.text) {
6837
+ if (p.current && W)
6838
+ if (G(!1), await re(), z.current && z.current.text) {
6839
6839
  const A = z.current;
6840
6840
  z.current = null;
6841
6841
  const F = {
@@ -6845,9 +6845,9 @@ const Ee = ve(({
6845
6845
  p.current.lipsync && Object.keys(p.current.lipsync).length > 0 && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(A.text, F));
6846
6846
  } else
6847
6847
  z.current = null;
6848
- }, [re, U]), C = T((A) => {
6848
+ }, [re, W]), C = T((A) => {
6849
6849
  p.current && p.current.setMood(A);
6850
- }, []), G = T((A) => {
6850
+ }, []), O = T((A) => {
6851
6851
  p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(A);
6852
6852
  }, []), te = T((A, F = !1) => {
6853
6853
  if (p.current && p.current.playAnimation) {
@@ -6871,9 +6871,9 @@ const Ee = ve(({
6871
6871
  else {
6872
6872
  const B = [".fbx", ".glb", ".gltf"];
6873
6873
  let ee = !1;
6874
- for (const ce of B)
6874
+ for (const de of B)
6875
6875
  try {
6876
- p.current.playAnimation(A + ce, null, 10, 0, 0.01, F), ee = !0;
6876
+ p.current.playAnimation(A + de, null, 10, 0, 0.01, F), ee = !0;
6877
6877
  break;
6878
6878
  } catch {
6879
6879
  }
@@ -6881,8 +6881,8 @@ const Ee = ve(({
6881
6881
  console.warn("Animation not found:", A);
6882
6882
  try {
6883
6883
  p.current.setBodyMovement("idle");
6884
- } catch (ce) {
6885
- console.warn("Fallback animation also failed:", ce);
6884
+ } catch (de) {
6885
+ console.warn("Fallback animation also failed:", de);
6886
6886
  }
6887
6887
  }
6888
6888
  }
@@ -6897,10 +6897,10 @@ const Ee = ve(({
6897
6897
  resumeSpeaking: w,
6898
6898
  resumeAudioContext: re,
6899
6899
  setMood: C,
6900
- setTimingAdjustment: G,
6900
+ setTimingAdjustment: O,
6901
6901
  playAnimation: te,
6902
6902
  isReady: ne,
6903
- isPaused: U,
6903
+ isPaused: W,
6904
6904
  talkingHead: p.current,
6905
6905
  handleResize: ie,
6906
6906
  setBodyMovement: (A) => {
@@ -6992,7 +6992,7 @@ const Ee = ve(({
6992
6992
  fontSize: "18px",
6993
6993
  zIndex: 10
6994
6994
  }, children: "Loading avatar..." }),
6995
- N && /* @__PURE__ */ he("div", { className: "error-overlay", style: {
6995
+ U && /* @__PURE__ */ he("div", { className: "error-overlay", style: {
6996
6996
  position: "absolute",
6997
6997
  top: "50%",
6998
6998
  left: "50%",
@@ -7003,14 +7003,14 @@ const Ee = ve(({
7003
7003
  zIndex: 10,
7004
7004
  padding: "20px",
7005
7005
  borderRadius: "8px"
7006
- }, children: N })
7006
+ }, children: U })
7007
7007
  ]
7008
7008
  }
7009
7009
  );
7010
7010
  });
7011
7011
  Ee.displayName = "TalkingHeadAvatar";
7012
7012
  const rt = ve(({
7013
- text: O = "Hello! I'm a talking avatar. How are you today?",
7013
+ text: N = "Hello! I'm a talking avatar. How are you today?",
7014
7014
  onLoading: t = () => {
7015
7015
  },
7016
7016
  onError: e = () => {
@@ -7021,7 +7021,7 @@ const rt = ve(({
7021
7021
  style: s = {},
7022
7022
  avatarConfig: o = {}
7023
7023
  }, l) => {
7024
- const u = Z(null), a = Z(null), [h, r] = de(!0), [d, c] = de(null), [g, y] = de(!1), x = Le(), I = o.ttsService || x.service, P = I === "browser" ? {
7024
+ const u = Z(null), a = Z(null), [h, r] = ce(!0), [c, d] = ce(null), [g, y] = ce(!1), x = Le(), I = o.ttsService || x.service, P = I === "browser" ? {
7025
7025
  endpoint: "",
7026
7026
  apiKey: null,
7027
7027
  defaultVoice: "Google US English"
@@ -7054,37 +7054,37 @@ const rt = ve(({
7054
7054
  }, z = T(async () => {
7055
7055
  if (!(!u.current || a.current))
7056
7056
  try {
7057
- if (r(!0), c(null), a.current = new Me(u.current, H), await a.current.showAvatar(p, (V) => {
7058
- if (V.lengthComputable) {
7059
- const E = Math.min(100, Math.round(V.loaded / V.total * 100));
7057
+ if (r(!0), d(null), a.current = new Me(u.current, H), await a.current.showAvatar(p, (G) => {
7058
+ if (G.lengthComputable) {
7059
+ const E = Math.min(100, Math.round(G.loaded / G.total * 100));
7060
7060
  t(E);
7061
7061
  }
7062
7062
  }), a.current.morphs && a.current.morphs.length > 0) {
7063
- const V = a.current.morphs[0].morphTargetDictionary;
7064
- console.log("Available morph targets:", Object.keys(V));
7065
- const E = Object.keys(V).filter((X) => X.startsWith("viseme_"));
7063
+ const G = a.current.morphs[0].morphTargetDictionary;
7064
+ console.log("Available morph targets:", Object.keys(G));
7065
+ const E = Object.keys(G).filter((X) => X.startsWith("viseme_"));
7066
7066
  console.log("Viseme morph targets found:", E), E.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"));
7067
7067
  }
7068
- if (await new Promise((V) => {
7068
+ if (await new Promise((G) => {
7069
7069
  const E = () => {
7070
- a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)), V()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(E, 100));
7070
+ a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)), G()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(E, 100));
7071
7071
  };
7072
7072
  E();
7073
7073
  }), a.current && a.current.setShowFullAvatar)
7074
7074
  try {
7075
7075
  a.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
7076
- } catch (V) {
7077
- console.warn("Error setting full body mode on initialization:", V);
7076
+ } catch (G) {
7077
+ console.warn("Error setting full body mode on initialization:", G);
7078
7078
  }
7079
7079
  r(!1), y(!0), i(a.current);
7080
- const U = () => {
7080
+ const W = () => {
7081
7081
  document.visibilityState === "visible" ? a.current?.start() : a.current?.stop();
7082
7082
  };
7083
- return document.addEventListener("visibilitychange", U), () => {
7084
- document.removeEventListener("visibilitychange", U);
7083
+ return document.addEventListener("visibilitychange", W), () => {
7084
+ document.removeEventListener("visibilitychange", W);
7085
7085
  };
7086
7086
  } catch (S) {
7087
- console.error("Error initializing TalkingHead:", S), c(S.message || "Failed to initialize avatar"), r(!1), e(S);
7087
+ console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), r(!1), e(S);
7088
7088
  }
7089
7089
  }, []);
7090
7090
  pe(() => (z(), () => {
@@ -7096,18 +7096,18 @@ const rt = ve(({
7096
7096
  console.log("Speaking text:", S), console.log("Avatar config:", p), console.log("TalkingHead instance:", a.current), a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)), a.current.setSlowdownRate && (a.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), a.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
7097
7097
  a.current && a.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), a.current.setSlowdownRate && (a.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), a.current.speakText(S)) : console.error("Lip-sync still not ready after waiting");
7098
7098
  }, 500));
7099
- } catch (U) {
7100
- console.error("Error speaking text:", U), c(U.message || "Failed to speak text");
7099
+ } catch (W) {
7100
+ console.error("Error speaking text:", W), d(W.message || "Failed to speak text");
7101
7101
  }
7102
7102
  else
7103
7103
  console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!a.current);
7104
7104
  }, [g, p]), D = T(() => {
7105
7105
  a.current && (a.current.stopSpeaking(), a.current.setSlowdownRate && (a.current.setSlowdownRate(1), console.log("Reset timing to normal")));
7106
- }, []), N = T((S) => {
7106
+ }, []), U = T((S) => {
7107
7107
  a.current && a.current.setMood(S);
7108
7108
  }, []), _ = T((S) => {
7109
7109
  a.current && a.current.setSlowdownRate && (a.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
7110
- }, []), ne = T((S, U = !1) => {
7110
+ }, []), ne = T((S, W = !1) => {
7111
7111
  if (a.current && a.current.playAnimation) {
7112
7112
  if (a.current.setShowFullAvatar)
7113
7113
  try {
@@ -7117,7 +7117,7 @@ const rt = ve(({
7117
7117
  }
7118
7118
  if (S.includes("."))
7119
7119
  try {
7120
- a.current.playAnimation(S, null, 10, 0, 0.01, U), console.log("Playing animation:", S);
7120
+ a.current.playAnimation(S, null, 10, 0, 0.01, W), console.log("Playing animation:", S);
7121
7121
  } catch (E) {
7122
7122
  console.log(`Failed to play ${S}:`, E);
7123
7123
  try {
@@ -7131,7 +7131,7 @@ const rt = ve(({
7131
7131
  let X = !1;
7132
7132
  for (const Y of E)
7133
7133
  try {
7134
- a.current.playAnimation(S + Y, null, 10, 0, 0.01, U), console.log("Playing animation:", S + Y), X = !0;
7134
+ a.current.playAnimation(S + Y, null, 10, 0, 0.01, W), console.log("Playing animation:", S + Y), X = !0;
7135
7135
  break;
7136
7136
  } catch {
7137
7137
  console.log(`Failed to play ${S}${Y}, trying next format...`);
@@ -7151,7 +7151,7 @@ const rt = ve(({
7151
7151
  return Ie(l, () => ({
7152
7152
  speakText: v,
7153
7153
  stopSpeaking: D,
7154
- setMood: N,
7154
+ setMood: U,
7155
7155
  setTimingAdjustment: _,
7156
7156
  playAnimation: ne,
7157
7157
  isReady: g,
@@ -7160,8 +7160,8 @@ const rt = ve(({
7160
7160
  if (a.current && a.current.setShowFullAvatar && a.current.setBodyMovement)
7161
7161
  try {
7162
7162
  a.current.setShowFullAvatar(!0), a.current.setBodyMovement(S), console.log("Body movement set with full body mode:", S);
7163
- } catch (U) {
7164
- console.warn("Error setting body movement:", U);
7163
+ } catch (W) {
7164
+ console.warn("Error setting body movement:", W);
7165
7165
  }
7166
7166
  },
7167
7167
  setMovementIntensity: (S) => a.current?.setMovementIntensity(S),
@@ -7177,8 +7177,8 @@ const rt = ve(({
7177
7177
  if (a.current && a.current.setShowFullAvatar && a.current.playReaction)
7178
7178
  try {
7179
7179
  a.current.setShowFullAvatar(!0), a.current.playReaction(S), console.log("Reaction played with full body mode:", S);
7180
- } catch (U) {
7181
- console.warn("Error playing reaction:", U);
7180
+ } catch (W) {
7181
+ console.warn("Error playing reaction:", W);
7182
7182
  }
7183
7183
  },
7184
7184
  playCelebration: () => {
@@ -7193,8 +7193,8 @@ const rt = ve(({
7193
7193
  if (a.current && a.current.setShowFullAvatar)
7194
7194
  try {
7195
7195
  a.current.setShowFullAvatar(S), console.log("Show full avatar set to:", S);
7196
- } catch (U) {
7197
- console.warn("Error setting showFullAvatar:", U);
7196
+ } catch (W) {
7197
+ console.warn("Error setting showFullAvatar:", W);
7198
7198
  }
7199
7199
  },
7200
7200
  lockAvatarPosition: () => {
@@ -7235,7 +7235,7 @@ const rt = ve(({
7235
7235
  fontSize: "18px",
7236
7236
  zIndex: 10
7237
7237
  }, children: "Loading avatar..." }),
7238
- d && /* @__PURE__ */ he("div", { className: "error-overlay", style: {
7238
+ c && /* @__PURE__ */ he("div", { className: "error-overlay", style: {
7239
7239
  position: "absolute",
7240
7240
  top: "50%",
7241
7241
  left: "50%",
@@ -7246,12 +7246,12 @@ const rt = ve(({
7246
7246
  zIndex: 10,
7247
7247
  padding: "20px",
7248
7248
  borderRadius: "8px"
7249
- }, children: d })
7249
+ }, children: c })
7250
7250
  ] });
7251
7251
  });
7252
7252
  rt.displayName = "TalkingHeadComponent";
7253
7253
  const lt = ve(({
7254
- curriculumData: O = null,
7254
+ curriculumData: N = null,
7255
7255
  avatarConfig: t = {},
7256
7256
  animations: e = {},
7257
7257
  onLessonStart: i = () => {
@@ -7276,13 +7276,13 @@ const lt = ve(({
7276
7276
  curriculumCompleted: !1,
7277
7277
  score: 0,
7278
7278
  totalQuestions: 0
7279
- }), d = Z({
7279
+ }), c = Z({
7280
7280
  onLessonStart: i,
7281
7281
  onLessonComplete: n,
7282
7282
  onQuestionAnswer: s,
7283
7283
  onCurriculumComplete: o,
7284
7284
  onCustomAction: l
7285
- }), c = Z(null), g = Z(null), y = Z(null), x = Z(null), I = Z(null), P = Z(null), p = Z(null), H = Z(O?.curriculum || {
7285
+ }), d = Z(null), g = Z(null), y = Z(null), x = Z(null), I = Z(null), P = Z(null), p = Z(null), H = Z(N?.curriculum || {
7286
7286
  title: "Default Curriculum",
7287
7287
  description: "No curriculum data provided",
7288
7288
  language: "en",
@@ -7302,7 +7302,7 @@ const lt = ve(({
7302
7302
  lipsyncLang: "en"
7303
7303
  });
7304
7304
  pe(() => {
7305
- d.current = {
7305
+ c.current = {
7306
7306
  onLessonStart: i,
7307
7307
  onLessonComplete: n,
7308
7308
  onQuestionAnswer: s,
@@ -7310,7 +7310,7 @@ const lt = ve(({
7310
7310
  onCustomAction: l
7311
7311
  };
7312
7312
  }, [i, n, s, o, l]), pe(() => {
7313
- H.current = O?.curriculum || {
7313
+ H.current = N?.curriculum || {
7314
7314
  title: "Default Curriculum",
7315
7315
  description: "No curriculum data provided",
7316
7316
  language: "en",
@@ -7329,18 +7329,23 @@ const lt = ve(({
7329
7329
  animations: e,
7330
7330
  lipsyncLang: "en"
7331
7331
  };
7332
- }, [O, t, e]);
7333
- const v = T(() => (H.current || { modules: [] }).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex], []), D = T(() => v()?.questions[r.current.currentQuestionIndex], [v]), N = T((b, R) => R.type === "multiple_choice" || R.type === "true_false" ? b === R.answer : R.type === "code_test" && typeof b == "object" && b !== null ? b.passed === !0 : !1, []), _ = T(() => {
7332
+ }, [N, t, e]);
7333
+ const v = T(() => (H.current || { modules: [] }).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex], []), D = T(() => v()?.questions[r.current.currentQuestionIndex], [v]), U = T((b, R) => R.type === "multiple_choice" || R.type === "true_false" ? b === R.answer : R.type === "code_test" && typeof b == "object" && b !== null ? b.passed === !0 : !1, []), _ = T(() => {
7334
7334
  r.current.lessonCompleted = !0, r.current.isQuestionMode = !1;
7335
7335
  const b = r.current.totalQuestions > 0 ? Math.round(r.current.score / r.current.totalQuestions * 100) : 100;
7336
7336
  let R = "Congratulations! You've completed this lesson";
7337
- if (r.current.totalQuestions > 0 ? R += ` with a score of ${r.current.score} out of ${r.current.totalQuestions} (${b}%). ` : R += "! ", b >= 80 ? R += "Excellent work! You have a great understanding of this topic." : b >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", d.current.onLessonComplete({
7337
+ if (r.current.totalQuestions > 0) {
7338
+ const w = r.current.score === 1 ? "one" : r.current.score, C = r.current.totalQuestions === 1 ? "one" : r.current.totalQuestions, O = b === 50 ? "fifty" : `${b}`;
7339
+ R += ` You got ${w} correct out of ${C} question${r.current.totalQuestions === 1 ? "" : "s"}, which is ${O} percent. `;
7340
+ } else
7341
+ R += "! ";
7342
+ if (b >= 80 ? R += "Excellent work! You have a great understanding of this topic." : b >= 60 ? R += "Good job! You understand most of the concepts." : R += "Keep practicing! You're making progress.", c.current.onLessonComplete({
7338
7343
  moduleIndex: r.current.currentModuleIndex,
7339
7344
  lessonIndex: r.current.currentLessonIndex,
7340
7345
  score: r.current.score,
7341
7346
  totalQuestions: r.current.totalQuestions,
7342
7347
  percentage: b
7343
- }), d.current.onCustomAction({
7348
+ }), c.current.onCustomAction({
7344
7349
  type: "lessonComplete",
7345
7350
  moduleIndex: r.current.currentModuleIndex,
7346
7351
  lessonIndex: r.current.currentLessonIndex,
@@ -7354,11 +7359,11 @@ const lt = ve(({
7354
7359
  } catch {
7355
7360
  h.current.playCelebration();
7356
7361
  }
7357
- const w = H.current || { modules: [] }, C = w.modules[r.current.currentModuleIndex], G = r.current.currentLessonIndex < (C?.lessons?.length || 0) - 1, te = r.current.currentModuleIndex < (w.modules?.length || 0) - 1, ie = G || te, A = z.current || { lipsyncLang: "en" };
7362
+ const w = H.current || { modules: [] }, C = w.modules[r.current.currentModuleIndex], O = r.current.currentLessonIndex < (C?.lessons?.length || 0) - 1, te = r.current.currentModuleIndex < (w.modules?.length || 0) - 1, ie = O || te, A = z.current || { lipsyncLang: "en" };
7358
7363
  h.current.speakText(R, {
7359
7364
  lipsyncLang: A.lipsyncLang,
7360
7365
  onSpeechEnd: () => {
7361
- d.current.onCustomAction({
7366
+ c.current.onCustomAction({
7362
7367
  type: "lessonCompleteFeedbackDone",
7363
7368
  moduleIndex: r.current.currentModuleIndex,
7364
7369
  lessonIndex: r.current.currentLessonIndex,
@@ -7373,7 +7378,7 @@ const lt = ve(({
7373
7378
  }, [e.lessonComplete]), ne = T(() => {
7374
7379
  r.current.curriculumCompleted = !0;
7375
7380
  const b = H.current || { modules: [] };
7376
- if (d.current.onCurriculumComplete({
7381
+ if (c.current.onCurriculumComplete({
7377
7382
  modules: b.modules.length,
7378
7383
  totalLessons: b.modules.reduce((R, w) => R + w.lessons.length, 0)
7379
7384
  }), h.current) {
@@ -7390,7 +7395,7 @@ const lt = ve(({
7390
7395
  const b = v();
7391
7396
  r.current.isQuestionMode = !0, r.current.currentQuestionIndex = 0, r.current.totalQuestions = b?.questions?.length || 0, r.current.score = 0;
7392
7397
  const R = D();
7393
- R && d.current.onCustomAction({
7398
+ R && c.current.onCustomAction({
7394
7399
  type: "questionStart",
7395
7400
  moduleIndex: r.current.currentModuleIndex,
7396
7401
  lessonIndex: r.current.currentLessonIndex,
@@ -7404,8 +7409,8 @@ const lt = ve(({
7404
7409
  if (h.current.setMood("happy"), e.questionStart)
7405
7410
  try {
7406
7411
  h.current.playAnimation(e.questionStart, !0);
7407
- } catch (G) {
7408
- console.warn("Failed to play questionStart animation:", G);
7412
+ } catch (O) {
7413
+ console.warn("Failed to play questionStart animation:", O);
7409
7414
  }
7410
7415
  const C = z.current || { lipsyncLang: "en" };
7411
7416
  R.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: C.lipsyncLang }) : R.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: C.lipsyncLang }) : R.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: C.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: C.lipsyncLang });
@@ -7423,12 +7428,12 @@ const lt = ve(({
7423
7428
  clearInterval(C);
7424
7429
  }, 5e3);
7425
7430
  }
7426
- }, [e.questionStart, v, D]), U = T(() => {
7431
+ }, [e.questionStart, v, D]), W = T(() => {
7427
7432
  const b = v();
7428
7433
  if (r.current.currentQuestionIndex < (b?.questions?.length || 0) - 1) {
7429
7434
  h.current && h.current.stopSpeaking && h.current.stopSpeaking(), r.current.currentQuestionIndex += 1;
7430
7435
  const R = D();
7431
- R && d.current.onCustomAction({
7436
+ R && c.current.onCustomAction({
7432
7437
  type: "nextQuestion",
7433
7438
  moduleIndex: r.current.currentModuleIndex,
7434
7439
  lessonIndex: r.current.currentLessonIndex,
@@ -7442,8 +7447,8 @@ const lt = ve(({
7442
7447
  if (h.current.setMood("happy"), h.current.setBodyMovement("idle"), e.nextQuestion)
7443
7448
  try {
7444
7449
  h.current.playAnimation(e.nextQuestion, !0);
7445
- } catch (G) {
7446
- console.warn("Failed to play nextQuestion animation:", G);
7450
+ } catch (O) {
7451
+ console.warn("Failed to play nextQuestion animation:", O);
7447
7452
  }
7448
7453
  const C = z.current || { lipsyncLang: "en" };
7449
7454
  R.type === "code_test" ? h.current.speakText(`Great! Now let's move on to your next coding challenge: ${R.question}`, {
@@ -7467,37 +7472,37 @@ const lt = ve(({
7467
7472
  }, 5e3);
7468
7473
  }
7469
7474
  } else
7470
- d.current.onCustomAction({
7475
+ c.current.onCustomAction({
7471
7476
  type: "allQuestionsComplete",
7472
7477
  moduleIndex: r.current.currentModuleIndex,
7473
7478
  lessonIndex: r.current.currentLessonIndex,
7474
7479
  totalQuestions: r.current.totalQuestions,
7475
7480
  score: r.current.score
7476
7481
  });
7477
- }, [e.nextQuestion, v, D]), V = T(() => {
7482
+ }, [e.nextQuestion, v, D]), G = T(() => {
7478
7483
  const b = H.current || { modules: [] }, R = b.modules[r.current.currentModuleIndex];
7479
7484
  if (r.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
7480
7485
  r.current.currentLessonIndex += 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0;
7481
- const C = b.modules[r.current.currentModuleIndex], G = r.current.currentLessonIndex < (C?.lessons?.length || 0) - 1, te = r.current.currentModuleIndex < (b.modules?.length || 0) - 1, ie = G || te;
7482
- d.current.onCustomAction({
7486
+ const C = b.modules[r.current.currentModuleIndex], O = r.current.currentLessonIndex < (C?.lessons?.length || 0) - 1, te = r.current.currentModuleIndex < (b.modules?.length || 0) - 1, ie = O || te;
7487
+ c.current.onCustomAction({
7483
7488
  type: "lessonStart",
7484
7489
  moduleIndex: r.current.currentModuleIndex,
7485
7490
  lessonIndex: r.current.currentLessonIndex,
7486
7491
  hasNextLesson: ie
7487
- }), d.current.onLessonStart({
7492
+ }), c.current.onLessonStart({
7488
7493
  moduleIndex: r.current.currentModuleIndex,
7489
7494
  lessonIndex: r.current.currentLessonIndex,
7490
7495
  lesson: v()
7491
7496
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7492
7497
  } else if (r.current.currentModuleIndex < (b.modules?.length || 0) - 1) {
7493
7498
  r.current.currentModuleIndex += 1, r.current.currentLessonIndex = 0, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0;
7494
- const G = b.modules[r.current.currentModuleIndex], te = r.current.currentLessonIndex < (G?.lessons?.length || 0) - 1, ie = r.current.currentModuleIndex < (b.modules?.length || 0) - 1, A = te || ie;
7495
- d.current.onCustomAction({
7499
+ const O = b.modules[r.current.currentModuleIndex], te = r.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, ie = r.current.currentModuleIndex < (b.modules?.length || 0) - 1, A = te || ie;
7500
+ c.current.onCustomAction({
7496
7501
  type: "lessonStart",
7497
7502
  moduleIndex: r.current.currentModuleIndex,
7498
7503
  lessonIndex: r.current.currentLessonIndex,
7499
7504
  hasNextLesson: A
7500
- }), d.current.onLessonStart({
7505
+ }), c.current.onLessonStart({
7501
7506
  moduleIndex: r.current.currentModuleIndex,
7502
7507
  lessonIndex: r.current.currentLessonIndex,
7503
7508
  lesson: v()
@@ -7508,8 +7513,8 @@ const lt = ve(({
7508
7513
  const b = v();
7509
7514
  let R = null;
7510
7515
  if (b?.avatar_script && b?.body) {
7511
- const w = b.avatar_script.trim(), C = b.body.trim(), G = w.match(/[.!?]$/) ? " " : ". ";
7512
- R = `${w}${G}${C}`;
7516
+ const w = b.avatar_script.trim(), C = b.body.trim(), O = w.match(/[.!?]$/) ? " " : ". ";
7517
+ R = `${w}${O}${C}`;
7513
7518
  } else
7514
7519
  R = b?.avatar_script || b?.body || null;
7515
7520
  if (h.current && h.current.isReady && R) {
@@ -7518,16 +7523,16 @@ const lt = ve(({
7518
7523
  if (e.teaching)
7519
7524
  try {
7520
7525
  h.current.playAnimation(e.teaching, !0), w = !0;
7521
- } catch (G) {
7522
- console.warn("Failed to play teaching animation:", G);
7526
+ } catch (O) {
7527
+ console.warn("Failed to play teaching animation:", O);
7523
7528
  }
7524
7529
  w || h.current.setBodyMovement("gesturing");
7525
7530
  const C = z.current || { lipsyncLang: "en" };
7526
- d.current.onLessonStart({
7531
+ c.current.onLessonStart({
7527
7532
  moduleIndex: r.current.currentModuleIndex,
7528
7533
  lessonIndex: r.current.currentLessonIndex,
7529
7534
  lesson: b
7530
- }), d.current.onCustomAction({
7535
+ }), c.current.onCustomAction({
7531
7536
  type: "teachingStart",
7532
7537
  moduleIndex: r.current.currentModuleIndex,
7533
7538
  lessonIndex: r.current.currentLessonIndex,
@@ -7535,7 +7540,7 @@ const lt = ve(({
7535
7540
  }), h.current.speakText(R, {
7536
7541
  lipsyncLang: C.lipsyncLang,
7537
7542
  onSpeechEnd: () => {
7538
- r.current.isTeaching = !1, d.current.onCustomAction({
7543
+ r.current.isTeaching = !1, c.current.onCustomAction({
7539
7544
  type: "teachingComplete",
7540
7545
  moduleIndex: r.current.currentModuleIndex,
7541
7546
  lessonIndex: r.current.currentLessonIndex,
@@ -7546,8 +7551,8 @@ const lt = ve(({
7546
7551
  });
7547
7552
  }
7548
7553
  }, [e.teaching, v]), X = T((b) => {
7549
- const R = D(), w = N(b, R);
7550
- if (w && (r.current.score += 1), d.current.onQuestionAnswer({
7554
+ const R = D(), w = U(b, R);
7555
+ if (w && (r.current.score += 1), c.current.onQuestionAnswer({
7551
7556
  moduleIndex: r.current.currentModuleIndex,
7552
7557
  lessonIndex: r.current.currentLessonIndex,
7553
7558
  questionIndex: r.current.currentQuestionIndex,
@@ -7563,12 +7568,12 @@ const lt = ve(({
7563
7568
  h.current.setBodyMovement("happy");
7564
7569
  }
7565
7570
  h.current.setBodyMovement("gesturing");
7566
- const C = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, G = z.current || { lipsyncLang: "en" };
7571
+ const C = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, O = z.current || { lipsyncLang: "en" };
7567
7572
  h.current.speakText(C, {
7568
- lipsyncLang: G.lipsyncLang,
7573
+ lipsyncLang: O.lipsyncLang,
7569
7574
  onSpeechEnd: () => {
7570
7575
  const ie = v()?.questions?.length || 0;
7571
- d.current.onCustomAction({
7576
+ c.current.onCustomAction({
7572
7577
  type: "answerFeedbackComplete",
7573
7578
  moduleIndex: r.current.currentModuleIndex,
7574
7579
  lessonIndex: r.current.currentLessonIndex,
@@ -7588,12 +7593,12 @@ const lt = ve(({
7588
7593
  h.current.setBodyMovement("idle");
7589
7594
  }
7590
7595
  h.current.setBodyMovement("gesturing");
7591
- const C = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""} Let's move on to the next question.`, G = z.current || { lipsyncLang: "en" };
7596
+ const C = R.type === "code_test" ? `Your code didn't pass all the tests. ${R.explanation || "Try again!"}` : `Not quite right, but don't worry! ${R.explanation || ""} Let's move on to the next question.`, O = z.current || { lipsyncLang: "en" };
7592
7597
  h.current.speakText(C, {
7593
- lipsyncLang: G.lipsyncLang,
7598
+ lipsyncLang: O.lipsyncLang,
7594
7599
  onSpeechEnd: () => {
7595
7600
  const ie = v()?.questions?.length || 0;
7596
- d.current.onCustomAction({
7601
+ c.current.onCustomAction({
7597
7602
  type: "answerFeedbackComplete",
7598
7603
  moduleIndex: r.current.currentModuleIndex,
7599
7604
  lessonIndex: r.current.currentLessonIndex,
@@ -7607,20 +7612,20 @@ const lt = ve(({
7607
7612
  });
7608
7613
  }
7609
7614
  else {
7610
- const G = v()?.questions?.length || 0;
7611
- d.current.onCustomAction({
7615
+ const O = v()?.questions?.length || 0;
7616
+ c.current.onCustomAction({
7612
7617
  type: "answerFeedbackComplete",
7613
7618
  moduleIndex: r.current.currentModuleIndex,
7614
7619
  lessonIndex: r.current.currentLessonIndex,
7615
7620
  questionIndex: r.current.currentQuestionIndex,
7616
7621
  isCorrect: w,
7617
- hasNextQuestion: r.current.currentQuestionIndex < G - 1,
7622
+ hasNextQuestion: r.current.currentQuestionIndex < O - 1,
7618
7623
  score: r.current.score,
7619
7624
  totalQuestions: r.current.totalQuestions,
7620
7625
  avatarNotReady: !0
7621
7626
  });
7622
7627
  }
7623
- }, [e.correct, e.incorrect, D, v, N]), Y = T((b) => {
7628
+ }, [e.correct, e.incorrect, D, v, U]), Y = T((b) => {
7624
7629
  const R = D();
7625
7630
  if (!b || typeof b != "object") {
7626
7631
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
@@ -7640,7 +7645,7 @@ const lt = ve(({
7640
7645
  passedCount: b.passedCount || 0,
7641
7646
  failedCount: b.failedCount || 0
7642
7647
  };
7643
- d.current.onCustomAction({
7648
+ c.current.onCustomAction({
7644
7649
  type: "codeTestSubmitted",
7645
7650
  moduleIndex: r.current.currentModuleIndex,
7646
7651
  lessonIndex: r.current.currentLessonIndex,
@@ -7648,11 +7653,11 @@ const lt = ve(({
7648
7653
  testResult: w,
7649
7654
  question: R
7650
7655
  }), p.current && p.current(w);
7651
- }, [D, N]), ue = T(() => {
7656
+ }, [D, U]), ue = T(() => {
7652
7657
  if (r.current.currentQuestionIndex > 0) {
7653
7658
  r.current.currentQuestionIndex -= 1;
7654
7659
  const b = D();
7655
- b && d.current.onCustomAction({
7660
+ b && c.current.onCustomAction({
7656
7661
  type: "questionStart",
7657
7662
  moduleIndex: r.current.currentModuleIndex,
7658
7663
  lessonIndex: r.current.currentLessonIndex,
@@ -7685,22 +7690,22 @@ const lt = ve(({
7685
7690
  }, [D]), Re = T(() => {
7686
7691
  const b = H.current || { modules: [] };
7687
7692
  if (b.modules[r.current.currentModuleIndex], r.current.currentLessonIndex > 0)
7688
- r.current.currentLessonIndex -= 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0, d.current.onCustomAction({
7693
+ r.current.currentLessonIndex -= 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0, c.current.onCustomAction({
7689
7694
  type: "lessonStart",
7690
7695
  moduleIndex: r.current.currentModuleIndex,
7691
7696
  lessonIndex: r.current.currentLessonIndex
7692
- }), d.current.onLessonStart({
7697
+ }), c.current.onLessonStart({
7693
7698
  moduleIndex: r.current.currentModuleIndex,
7694
7699
  lessonIndex: r.current.currentLessonIndex,
7695
7700
  lesson: v()
7696
7701
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7697
7702
  else if (r.current.currentModuleIndex > 0) {
7698
7703
  const C = b.modules[r.current.currentModuleIndex - 1];
7699
- r.current.currentModuleIndex -= 1, r.current.currentLessonIndex = (C?.lessons?.length || 1) - 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0, d.current.onCustomAction({
7704
+ r.current.currentModuleIndex -= 1, r.current.currentLessonIndex = (C?.lessons?.length || 1) - 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0, c.current.onCustomAction({
7700
7705
  type: "lessonStart",
7701
7706
  moduleIndex: r.current.currentModuleIndex,
7702
7707
  lessonIndex: r.current.currentLessonIndex
7703
- }), d.current.onLessonStart({
7708
+ }), c.current.onLessonStart({
7704
7709
  moduleIndex: r.current.currentModuleIndex,
7705
7710
  lessonIndex: r.current.currentLessonIndex,
7706
7711
  lesson: v()
@@ -7712,20 +7717,20 @@ const lt = ve(({
7712
7717
  console.log("Avatar is ready!", b);
7713
7718
  const R = v(), w = R?.avatar_script || R?.body;
7714
7719
  u && w && setTimeout(() => {
7715
- c.current && c.current();
7720
+ d.current && d.current();
7716
7721
  }, 10);
7717
7722
  }, [u, v]);
7718
7723
  Oe(() => {
7719
- c.current = E, g.current = V, y.current = _, x.current = U, I.current = ne, P.current = S, p.current = X;
7724
+ d.current = E, g.current = G, y.current = _, x.current = W, I.current = ne, P.current = S, p.current = X;
7720
7725
  }), Ie(a, () => ({
7721
7726
  // Curriculum control methods
7722
7727
  startTeaching: E,
7723
7728
  startQuestions: S,
7724
7729
  handleAnswerSelect: X,
7725
7730
  handleCodeTestResult: Y,
7726
- nextQuestion: U,
7731
+ nextQuestion: W,
7727
7732
  previousQuestion: ue,
7728
- nextLesson: V,
7733
+ nextLesson: G,
7729
7734
  previousLesson: Re,
7730
7735
  completeLesson: _,
7731
7736
  completeCurriculum: ne,
@@ -7773,7 +7778,7 @@ const lt = ve(({
7773
7778
  unlockAvatarPosition: () => h.current?.unlockAvatarPosition(),
7774
7779
  // Custom action trigger
7775
7780
  triggerCustomAction: (b, R) => {
7776
- d.current.onCustomAction({
7781
+ c.current.onCustomAction({
7777
7782
  type: b,
7778
7783
  ...R,
7779
7784
  state: { ...r.current }
@@ -7783,7 +7788,7 @@ const lt = ve(({
7783
7788
  handleResize: () => h.current?.handleResize(),
7784
7789
  // Avatar readiness check (always returns current value)
7785
7790
  isAvatarReady: () => h.current?.isReady || !1
7786
- }), [E, S, X, Y, U, V, _, ne, ge, D, v]);
7791
+ }), [E, S, X, Y, W, G, _, ne, ge, D, v]);
7787
7792
  const J = z.current || {
7788
7793
  avatarUrl: "/avatars/brunette.glb",
7789
7794
  avatarBody: "F",
@@ -7926,7 +7931,7 @@ const Fe = {
7926
7931
  duration: 5e3,
7927
7932
  description: "Excited, energetic movement"
7928
7933
  }
7929
- }, bt = (O) => Fe[O] || null, Rt = (O) => Fe.hasOwnProperty(O);
7934
+ }, bt = (N) => Fe[N] || null, Rt = (N) => Fe.hasOwnProperty(N);
7930
7935
  export {
7931
7936
  lt as CurriculumLearning,
7932
7937
  Ee as TalkingHeadAvatar,