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

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 Re, 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;
@@ -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]);
@@ -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":
@@ -5185,8 +5185,8 @@ class Me {
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,48 +5248,48 @@ 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((R) => x < R[0] || x > R[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: {
5265
5265
  subtitles: [h]
5266
5266
  }
5267
5267
  }), h = ""), r.length)) {
5268
- const v = this.lipsyncWordsToVisemes(r, a);
5269
- if (v && v.visemes && v.visemes.length) {
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++)
5268
+ const R = this.lipsyncWordsToVisemes(r, a);
5269
+ if (R && R.visemes && R.visemes.length) {
5270
+ const D = R.times[R.visemes.length - 1] + R.durations[R.visemes.length - 1];
5271
+ for (let N = 0; N < R.visemes.length; N++)
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: [(R.times[N] - 0.6) / D, (R.times[N] + 0.5) / D, (R.times[N] + R.durations[N] + 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_" + R.visemes[N]]: [null, R.visemes[N] === "PP" || R.visemes[N] === "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) {
5285
- const v = {
5284
+ if (d.length || I && g.length) {
5285
+ const R = {
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 && (R.onSubtitles = i), d.length && !e.avatarMute && (R.text = d, e.avatarMood && (R.mood = e.avatarMood), e.ttsLang && (R.lang = e.ttsLang), e.ttsVoice && (R.voice = e.ttsVoice), e.ttsRate && (R.rate = e.ttsRate), e.ttsVoice && (R.pitch = e.ttsPitch), e.ttsVolume && (R.volume = e.ttsVolume)), this.speechQueue.push(R), d = [], r = "", c = 0, g = [];
5289
5289
  }
5290
5290
  if (H) {
5291
- let v = this.animEmojis[y[x]];
5292
- v && v.link && (v = this.animEmojis[v.link]), v && this.speechQueue.push({ emoji: v });
5291
+ let R = this.animEmojis[y[x]];
5292
+ R && R.link && (R = this.animEmojis[R.link]), R && this.speechQueue.push({ emoji: R });
5293
5293
  }
5294
5294
  this.speechQueue.push({ break: 100 });
5295
5295
  }
@@ -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,20 +5473,20 @@ 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], R = x.times[H] / p, D = x.durations[H] / p, N = R * c, _ = D * c;
5490
5490
  I.push({
5491
5491
  template: { name: "viseme" },
5492
5492
  ts: [N - Math.min(60, 2 * _ / 3), N + Math.min(25, _ / 2), N + _ + Math.min(60, _ / 2)],
@@ -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
  }
@@ -6151,7 +6151,7 @@ class Me {
6151
6151
  M.set(s, n, 0, "YXZ");
6152
6152
  const l = new f.Quaternion().setFromEuler(M), u = new f.Quaternion().copy(l).multiply(W.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]],
@@ -6187,11 +6187,11 @@ class Me {
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
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;
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) {
6194
- let H = this.animQueue.findIndex((v) => v.template.name === "lookat");
6194
+ let H = this.animQueue.findIndex((R) => R.template.name === "lookat");
6195
6195
  H !== -1 && this.animQueue.splice(H, 1);
6196
6196
  const z = {
6197
6197
  name: "lookat",
@@ -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++) {
@@ -6581,8 +6581,8 @@ class Me {
6581
6581
  for (let p = 0, H = y.length; p < H; p++) {
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
- 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(
6584
+ let R = s.dot(l);
6585
+ R > 1 ? R = 1 : R < -1 && (R = -1), R = Math.acos(R), !(R < 1e-5) && (y[p].minAngle !== void 0 && R < y[p].minAngle && (R = y[p].minAngle), y[p].maxAngle !== void 0 && R > y[p].maxAngle && (R = y[p].maxAngle), r.crossVectors(l, s), r.normalize(), W.setFromAxisAngle(r, R), z.quaternion.multiply(W), 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
@@ -6663,7 +6663,7 @@ function xt() {
6663
6663
  });
6664
6664
  }), t;
6665
6665
  }
6666
- const Ee = ve(({
6666
+ const Ee = Re(({
6667
6667
  avatarUrl: O = "/avatars/brunette.glb",
6668
6668
  avatarBody: t = "F",
6669
6669
  mood: e = "neutral",
@@ -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), [R, D] = ce(!0), [N, _] = ce(null), [ne, S] = ce(!1), [U, V] = ce(!1);
6689
6689
  pe(() => {
6690
6690
  H.current = a;
6691
6691
  }, [a]);
@@ -6723,7 +6723,7 @@ const Ee = ve(({
6723
6723
  showFullAvatar: a,
6724
6724
  bodyMovement: l,
6725
6725
  movementIntensity: u
6726
- }, Re = {
6726
+ }, ve = {
6727
6727
  ttsEndpoint: Y.endpoint,
6728
6728
  ttsApikey: Y.apiKey,
6729
6729
  ttsService: X,
@@ -6732,10 +6732,10 @@ const Ee = ve(({
6732
6732
  }, ge = T(async () => {
6733
6733
  if (!(!P.current || p.current))
6734
6734
  try {
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) => {
6735
+ if (D(!0), _(null), p.current = new Me(P.current, ve), 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,7 +6756,7 @@ 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
6761
  }, [O, t, e, i, n, s, o, a, l, u, h]);
6762
6762
  pe(() => (ge(), () => {
@@ -6792,11 +6792,11 @@ const Ee = ve(({
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 {
@@ -6828,7 +6828,7 @@ const Ee = ve(({
6828
6828
  }
6829
6829
  }, [ne, re, ue.lipsyncLang]), b = T(() => {
6830
6830
  p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, V(!1));
6831
- }, []), R = T(() => {
6831
+ }, []), v = 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
6834
  (F && z.current && z.current.text || F) && (p.current.pauseSpeaking(), V(!0));
@@ -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
  }
@@ -6893,7 +6893,7 @@ const Ee = ve(({
6893
6893
  return Ie(I, () => ({
6894
6894
  speakText: J,
6895
6895
  stopSpeaking: b,
6896
- pauseSpeaking: R,
6896
+ pauseSpeaking: v,
6897
6897
  resumeSpeaking: w,
6898
6898
  resumeAudioContext: re,
6899
6899
  setMood: C,
@@ -6983,7 +6983,7 @@ const Ee = ve(({
6983
6983
  }
6984
6984
  }
6985
6985
  ),
6986
- v && /* @__PURE__ */ he("div", { className: "loading-overlay", style: {
6986
+ R && /* @__PURE__ */ he("div", { className: "loading-overlay", style: {
6987
6987
  position: "absolute",
6988
6988
  top: "50%",
6989
6989
  left: "50%",
@@ -7009,7 +7009,7 @@ const Ee = ve(({
7009
7009
  );
7010
7010
  });
7011
7011
  Ee.displayName = "TalkingHeadAvatar";
7012
- const rt = ve(({
7012
+ const rt = Re(({
7013
7013
  text: O = "Hello! I'm a talking avatar. How are you today?",
7014
7014
  onLoading: t = () => {
7015
7015
  },
@@ -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,7 +7054,7 @@ 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) => {
7057
+ if (r(!0), d(null), a.current = new Me(u.current, H), await a.current.showAvatar(p, (V) => {
7058
7058
  if (V.lengthComputable) {
7059
7059
  const E = Math.min(100, Math.round(V.loaded / V.total * 100));
7060
7060
  t(E);
@@ -7084,20 +7084,20 @@ const rt = ve(({
7084
7084
  document.removeEventListener("visibilitychange", U);
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(), () => {
7091
7091
  a.current && (a.current.stop(), a.current.dispose(), a.current = null);
7092
7092
  }), [z]);
7093
- const v = T((S) => {
7093
+ const R = T((S) => {
7094
7094
  if (a.current && g)
7095
7095
  try {
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
7099
  } catch (U) {
7100
- console.error("Error speaking text:", U), c(U.message || "Failed to speak text");
7100
+ console.error("Error speaking text:", U), d(U.message || "Failed to speak text");
7101
7101
  }
7102
7102
  else
7103
7103
  console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!a.current);
@@ -7149,7 +7149,7 @@ const rt = ve(({
7149
7149
  console.warn("Animation system not available or animation not found:", S);
7150
7150
  }, []);
7151
7151
  return Ie(l, () => ({
7152
- speakText: v,
7152
+ speakText: R,
7153
7153
  stopSpeaking: D,
7154
7154
  setMood: N,
7155
7155
  setTimingAdjustment: _,
@@ -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,11 +7246,11 @@ 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
- const lt = ve(({
7253
+ const lt = Re(({
7254
7254
  curriculumData: O = null,
7255
7255
  avatarConfig: t = {},
7256
7256
  animations: e = {},
@@ -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(O?.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,
@@ -7330,17 +7330,17 @@ const lt = ve(({
7330
7330
  lipsyncLang: "en"
7331
7331
  };
7332
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(() => {
7333
+ const R = T(() => (H.current || { modules: [] }).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex], []), D = T(() => R()?.questions[r.current.currentQuestionIndex], [R]), N = T((b, v) => v.type === "multiple_choice" || v.type === "true_false" ? b === v.answer : v.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
- 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({
7336
+ let v = "Congratulations! You've completed this lesson";
7337
+ if (r.current.totalQuestions > 0 ? v += ` You got ${r.current.score} correct out of ${r.current.totalQuestions} question${r.current.totalQuestions === 1 ? "" : "s"}, achieving a score of ${b} percent. ` : v += "! ", b >= 80 ? v += "Excellent work! You have a great understanding of this topic." : b >= 60 ? v += "Good job! You understand most of the concepts." : v += "Keep practicing! You're making progress.", c.current.onLessonComplete({
7338
7338
  moduleIndex: r.current.currentModuleIndex,
7339
7339
  lessonIndex: r.current.currentLessonIndex,
7340
7340
  score: r.current.score,
7341
7341
  totalQuestions: r.current.totalQuestions,
7342
7342
  percentage: b
7343
- }), d.current.onCustomAction({
7343
+ }), c.current.onCustomAction({
7344
7344
  type: "lessonComplete",
7345
7345
  moduleIndex: r.current.currentModuleIndex,
7346
7346
  lessonIndex: r.current.currentLessonIndex,
@@ -7355,10 +7355,10 @@ const lt = ve(({
7355
7355
  h.current.playCelebration();
7356
7356
  }
7357
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" };
7358
- h.current.speakText(R, {
7358
+ h.current.speakText(v, {
7359
7359
  lipsyncLang: A.lipsyncLang,
7360
7360
  onSpeechEnd: () => {
7361
- d.current.onCustomAction({
7361
+ c.current.onCustomAction({
7362
7362
  type: "lessonCompleteFeedbackDone",
7363
7363
  moduleIndex: r.current.currentModuleIndex,
7364
7364
  lessonIndex: r.current.currentLessonIndex,
@@ -7373,9 +7373,9 @@ const lt = ve(({
7373
7373
  }, [e.lessonComplete]), ne = T(() => {
7374
7374
  r.current.curriculumCompleted = !0;
7375
7375
  const b = H.current || { modules: [] };
7376
- if (d.current.onCurriculumComplete({
7376
+ if (c.current.onCurriculumComplete({
7377
7377
  modules: b.modules.length,
7378
- totalLessons: b.modules.reduce((R, w) => R + w.lessons.length, 0)
7378
+ totalLessons: b.modules.reduce((v, w) => v + w.lessons.length, 0)
7379
7379
  }), h.current) {
7380
7380
  if (h.current.setMood("celebrating"), e.curriculumComplete)
7381
7381
  try {
@@ -7383,24 +7383,24 @@ const lt = ve(({
7383
7383
  } catch {
7384
7384
  h.current.playCelebration();
7385
7385
  }
7386
- const R = z.current || { lipsyncLang: "en" };
7387
- h.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: R.lipsyncLang });
7386
+ const v = z.current || { lipsyncLang: "en" };
7387
+ h.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: v.lipsyncLang });
7388
7388
  }
7389
7389
  }, [e.curriculumComplete]), S = T(() => {
7390
- const b = v();
7390
+ const b = R();
7391
7391
  r.current.isQuestionMode = !0, r.current.currentQuestionIndex = 0, r.current.totalQuestions = b?.questions?.length || 0, r.current.score = 0;
7392
- const R = D();
7393
- R && d.current.onCustomAction({
7392
+ const v = D();
7393
+ v && c.current.onCustomAction({
7394
7394
  type: "questionStart",
7395
7395
  moduleIndex: r.current.currentModuleIndex,
7396
7396
  lessonIndex: r.current.currentLessonIndex,
7397
7397
  questionIndex: r.current.currentQuestionIndex,
7398
7398
  totalQuestions: r.current.totalQuestions,
7399
- question: R,
7399
+ question: v,
7400
7400
  score: r.current.score
7401
7401
  });
7402
7402
  const w = () => {
7403
- if (!h.current || !R) return;
7403
+ if (!h.current || !v) return;
7404
7404
  if (h.current.setMood("happy"), e.questionStart)
7405
7405
  try {
7406
7406
  h.current.playAnimation(e.questionStart, !0);
@@ -7408,37 +7408,37 @@ const lt = ve(({
7408
7408
  console.warn("Failed to play questionStart animation:", G);
7409
7409
  }
7410
7410
  const C = z.current || { lipsyncLang: "en" };
7411
- 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 });
7411
+ v.type === "code_test" ? h.current.speakText(`Let's test your coding skills! Here's your first challenge: ${v.question}`, { lipsyncLang: C.lipsyncLang }) : v.type === "multiple_choice" ? h.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: C.lipsyncLang }) : v.type === "true_false" ? h.current.speakText(`Let's start with some true or false questions. First question: ${v.question}`, { lipsyncLang: C.lipsyncLang }) : h.current.speakText(`Now let me ask you some questions. Here's the first one: ${v.question}`, { lipsyncLang: C.lipsyncLang });
7412
7412
  };
7413
- if (h.current && h.current.isReady && R)
7413
+ if (h.current && h.current.isReady && v)
7414
7414
  w();
7415
7415
  else if (h.current && h.current.isReady) {
7416
7416
  const C = z.current || { lipsyncLang: "en" };
7417
7417
  h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: C.lipsyncLang });
7418
7418
  } else {
7419
7419
  const C = setInterval(() => {
7420
- h.current && h.current.isReady && (clearInterval(C), R && w());
7420
+ h.current && h.current.isReady && (clearInterval(C), v && w());
7421
7421
  }, 100);
7422
7422
  setTimeout(() => {
7423
7423
  clearInterval(C);
7424
7424
  }, 5e3);
7425
7425
  }
7426
- }, [e.questionStart, v, D]), U = T(() => {
7427
- const b = v();
7426
+ }, [e.questionStart, R, D]), U = T(() => {
7427
+ const b = R();
7428
7428
  if (r.current.currentQuestionIndex < (b?.questions?.length || 0) - 1) {
7429
7429
  h.current && h.current.stopSpeaking && h.current.stopSpeaking(), r.current.currentQuestionIndex += 1;
7430
- const R = D();
7431
- R && d.current.onCustomAction({
7430
+ const v = D();
7431
+ v && c.current.onCustomAction({
7432
7432
  type: "nextQuestion",
7433
7433
  moduleIndex: r.current.currentModuleIndex,
7434
7434
  lessonIndex: r.current.currentLessonIndex,
7435
7435
  questionIndex: r.current.currentQuestionIndex,
7436
7436
  totalQuestions: r.current.totalQuestions,
7437
- question: R,
7437
+ question: v,
7438
7438
  score: r.current.score
7439
7439
  });
7440
7440
  const w = () => {
7441
- if (!h.current || !R) return;
7441
+ if (!h.current || !v) return;
7442
7442
  if (h.current.setMood("happy"), h.current.setBodyMovement("idle"), e.nextQuestion)
7443
7443
  try {
7444
7444
  h.current.playAnimation(e.nextQuestion, !0);
@@ -7446,19 +7446,19 @@ const lt = ve(({
7446
7446
  console.warn("Failed to play nextQuestion animation:", G);
7447
7447
  }
7448
7448
  const C = z.current || { lipsyncLang: "en" };
7449
- R.type === "code_test" ? h.current.speakText(`Great! Now let's move on to your next coding challenge: ${R.question}`, {
7449
+ v.type === "code_test" ? h.current.speakText(`Great! Now let's move on to your next coding challenge: ${v.question}`, {
7450
7450
  lipsyncLang: C.lipsyncLang
7451
- }) : R.type === "multiple_choice" ? h.current.speakText(`Alright! Here's your next question: ${R.question}`, {
7451
+ }) : v.type === "multiple_choice" ? h.current.speakText(`Alright! Here's your next question: ${v.question}`, {
7452
7452
  lipsyncLang: C.lipsyncLang
7453
- }) : R.type === "true_false" ? h.current.speakText(`Now let's try this one: ${R.question}`, {
7453
+ }) : v.type === "true_false" ? h.current.speakText(`Now let's try this one: ${v.question}`, {
7454
7454
  lipsyncLang: C.lipsyncLang
7455
- }) : h.current.speakText(`Here's the next question: ${R.question}`, {
7455
+ }) : h.current.speakText(`Here's the next question: ${v.question}`, {
7456
7456
  lipsyncLang: C.lipsyncLang
7457
7457
  });
7458
7458
  };
7459
- if (h.current && h.current.isReady && R)
7459
+ if (h.current && h.current.isReady && v)
7460
7460
  w();
7461
- else if (R) {
7461
+ else if (v) {
7462
7462
  const C = setInterval(() => {
7463
7463
  h.current && h.current.isReady && (clearInterval(C), w());
7464
7464
  }, 100);
@@ -7467,52 +7467,52 @@ const lt = ve(({
7467
7467
  }, 5e3);
7468
7468
  }
7469
7469
  } else
7470
- d.current.onCustomAction({
7470
+ c.current.onCustomAction({
7471
7471
  type: "allQuestionsComplete",
7472
7472
  moduleIndex: r.current.currentModuleIndex,
7473
7473
  lessonIndex: r.current.currentLessonIndex,
7474
7474
  totalQuestions: r.current.totalQuestions,
7475
7475
  score: r.current.score
7476
7476
  });
7477
- }, [e.nextQuestion, v, D]), V = T(() => {
7478
- const b = H.current || { modules: [] }, R = b.modules[r.current.currentModuleIndex];
7479
- if (r.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
7477
+ }, [e.nextQuestion, R, D]), V = T(() => {
7478
+ const b = H.current || { modules: [] }, v = b.modules[r.current.currentModuleIndex];
7479
+ if (r.current.currentLessonIndex < (v?.lessons?.length || 0) - 1) {
7480
7480
  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
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({
7482
+ c.current.onCustomAction({
7483
7483
  type: "lessonStart",
7484
7484
  moduleIndex: r.current.currentModuleIndex,
7485
7485
  lessonIndex: r.current.currentLessonIndex,
7486
7486
  hasNextLesson: ie
7487
- }), d.current.onLessonStart({
7487
+ }), c.current.onLessonStart({
7488
7488
  moduleIndex: r.current.currentModuleIndex,
7489
7489
  lessonIndex: r.current.currentLessonIndex,
7490
- lesson: v()
7490
+ lesson: R()
7491
7491
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7492
7492
  } else if (r.current.currentModuleIndex < (b.modules?.length || 0) - 1) {
7493
7493
  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
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({
7495
+ c.current.onCustomAction({
7496
7496
  type: "lessonStart",
7497
7497
  moduleIndex: r.current.currentModuleIndex,
7498
7498
  lessonIndex: r.current.currentLessonIndex,
7499
7499
  hasNextLesson: A
7500
- }), d.current.onLessonStart({
7500
+ }), c.current.onLessonStart({
7501
7501
  moduleIndex: r.current.currentModuleIndex,
7502
7502
  lessonIndex: r.current.currentLessonIndex,
7503
- lesson: v()
7503
+ lesson: R()
7504
7504
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7505
7505
  } else
7506
7506
  I.current && I.current();
7507
7507
  }, []), E = T(() => {
7508
- const b = v();
7509
- let R = null;
7508
+ const b = R();
7509
+ let v = null;
7510
7510
  if (b?.avatar_script && b?.body) {
7511
7511
  const w = b.avatar_script.trim(), C = b.body.trim(), G = w.match(/[.!?]$/) ? " " : ". ";
7512
- R = `${w}${G}${C}`;
7512
+ v = `${w}${G}${C}`;
7513
7513
  } else
7514
- R = b?.avatar_script || b?.body || null;
7515
- if (h.current && h.current.isReady && R) {
7514
+ v = b?.avatar_script || b?.body || null;
7515
+ if (h.current && h.current.isReady && v) {
7516
7516
  r.current.isTeaching = !0, r.current.isQuestionMode = !1, r.current.score = 0, r.current.totalQuestions = 0, h.current.setMood("happy");
7517
7517
  let w = !1;
7518
7518
  if (e.teaching)
@@ -7523,19 +7523,19 @@ const lt = ve(({
7523
7523
  }
7524
7524
  w || h.current.setBodyMovement("gesturing");
7525
7525
  const C = z.current || { lipsyncLang: "en" };
7526
- d.current.onLessonStart({
7526
+ c.current.onLessonStart({
7527
7527
  moduleIndex: r.current.currentModuleIndex,
7528
7528
  lessonIndex: r.current.currentLessonIndex,
7529
7529
  lesson: b
7530
- }), d.current.onCustomAction({
7530
+ }), c.current.onCustomAction({
7531
7531
  type: "teachingStart",
7532
7532
  moduleIndex: r.current.currentModuleIndex,
7533
7533
  lessonIndex: r.current.currentLessonIndex,
7534
7534
  lesson: b
7535
- }), h.current.speakText(R, {
7535
+ }), h.current.speakText(v, {
7536
7536
  lipsyncLang: C.lipsyncLang,
7537
7537
  onSpeechEnd: () => {
7538
- r.current.isTeaching = !1, d.current.onCustomAction({
7538
+ r.current.isTeaching = !1, c.current.onCustomAction({
7539
7539
  type: "teachingComplete",
7540
7540
  moduleIndex: r.current.currentModuleIndex,
7541
7541
  lessonIndex: r.current.currentLessonIndex,
@@ -7545,15 +7545,15 @@ const lt = ve(({
7545
7545
  }
7546
7546
  });
7547
7547
  }
7548
- }, [e.teaching, v]), X = T((b) => {
7549
- const R = D(), w = N(b, R);
7550
- if (w && (r.current.score += 1), d.current.onQuestionAnswer({
7548
+ }, [e.teaching, R]), X = T((b) => {
7549
+ const v = D(), w = N(b, v);
7550
+ if (w && (r.current.score += 1), c.current.onQuestionAnswer({
7551
7551
  moduleIndex: r.current.currentModuleIndex,
7552
7552
  lessonIndex: r.current.currentLessonIndex,
7553
7553
  questionIndex: r.current.currentQuestionIndex,
7554
7554
  answer: b,
7555
7555
  isCorrect: w,
7556
- question: R
7556
+ question: v
7557
7557
  }), h.current)
7558
7558
  if (w) {
7559
7559
  if (h.current.setMood("happy"), e.correct)
@@ -7563,12 +7563,12 @@ const lt = ve(({
7563
7563
  h.current.setBodyMovement("happy");
7564
7564
  }
7565
7565
  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" };
7566
+ const C = v.type === "code_test" ? `Great job! Your code passed all the tests! ${v.explanation || ""}` : `Excellent! That's correct! ${v.explanation || ""}`, G = z.current || { lipsyncLang: "en" };
7567
7567
  h.current.speakText(C, {
7568
7568
  lipsyncLang: G.lipsyncLang,
7569
7569
  onSpeechEnd: () => {
7570
- const ie = v()?.questions?.length || 0;
7571
- d.current.onCustomAction({
7570
+ const ie = R()?.questions?.length || 0;
7571
+ c.current.onCustomAction({
7572
7572
  type: "answerFeedbackComplete",
7573
7573
  moduleIndex: r.current.currentModuleIndex,
7574
7574
  lessonIndex: r.current.currentLessonIndex,
@@ -7588,12 +7588,12 @@ const lt = ve(({
7588
7588
  h.current.setBodyMovement("idle");
7589
7589
  }
7590
7590
  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" };
7591
+ const C = v.type === "code_test" ? `Your code didn't pass all the tests. ${v.explanation || "Try again!"}` : `Not quite right, but don't worry! ${v.explanation || ""} Let's move on to the next question.`, G = z.current || { lipsyncLang: "en" };
7592
7592
  h.current.speakText(C, {
7593
7593
  lipsyncLang: G.lipsyncLang,
7594
7594
  onSpeechEnd: () => {
7595
- const ie = v()?.questions?.length || 0;
7596
- d.current.onCustomAction({
7595
+ const ie = R()?.questions?.length || 0;
7596
+ c.current.onCustomAction({
7597
7597
  type: "answerFeedbackComplete",
7598
7598
  moduleIndex: r.current.currentModuleIndex,
7599
7599
  lessonIndex: r.current.currentLessonIndex,
@@ -7607,8 +7607,8 @@ const lt = ve(({
7607
7607
  });
7608
7608
  }
7609
7609
  else {
7610
- const G = v()?.questions?.length || 0;
7611
- d.current.onCustomAction({
7610
+ const G = R()?.questions?.length || 0;
7611
+ c.current.onCustomAction({
7612
7612
  type: "answerFeedbackComplete",
7613
7613
  moduleIndex: r.current.currentModuleIndex,
7614
7614
  lessonIndex: r.current.currentLessonIndex,
@@ -7620,13 +7620,13 @@ const lt = ve(({
7620
7620
  avatarNotReady: !0
7621
7621
  });
7622
7622
  }
7623
- }, [e.correct, e.incorrect, D, v, N]), Y = T((b) => {
7624
- const R = D();
7623
+ }, [e.correct, e.incorrect, D, R, N]), Y = T((b) => {
7624
+ const v = D();
7625
7625
  if (!b || typeof b != "object") {
7626
7626
  console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
7627
7627
  return;
7628
7628
  }
7629
- if (R?.type !== "code_test") {
7629
+ if (v?.type !== "code_test") {
7630
7630
  console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
7631
7631
  return;
7632
7632
  }
@@ -7640,19 +7640,19 @@ const lt = ve(({
7640
7640
  passedCount: b.passedCount || 0,
7641
7641
  failedCount: b.failedCount || 0
7642
7642
  };
7643
- d.current.onCustomAction({
7643
+ c.current.onCustomAction({
7644
7644
  type: "codeTestSubmitted",
7645
7645
  moduleIndex: r.current.currentModuleIndex,
7646
7646
  lessonIndex: r.current.currentLessonIndex,
7647
7647
  questionIndex: r.current.currentQuestionIndex,
7648
7648
  testResult: w,
7649
- question: R
7649
+ question: v
7650
7650
  }), p.current && p.current(w);
7651
7651
  }, [D, N]), ue = T(() => {
7652
7652
  if (r.current.currentQuestionIndex > 0) {
7653
7653
  r.current.currentQuestionIndex -= 1;
7654
7654
  const b = D();
7655
- b && d.current.onCustomAction({
7655
+ b && c.current.onCustomAction({
7656
7656
  type: "questionStart",
7657
7657
  moduleIndex: r.current.currentModuleIndex,
7658
7658
  lessonIndex: r.current.currentLessonIndex,
@@ -7661,7 +7661,7 @@ const lt = ve(({
7661
7661
  question: b,
7662
7662
  score: r.current.score
7663
7663
  });
7664
- const R = () => {
7664
+ const v = () => {
7665
7665
  if (!h.current || !b) return;
7666
7666
  h.current.setMood("happy"), h.current.setBodyMovement("idle");
7667
7667
  const w = z.current || { lipsyncLang: "en" };
@@ -7672,51 +7672,51 @@ const lt = ve(({
7672
7672
  });
7673
7673
  };
7674
7674
  if (h.current && h.current.isReady && b)
7675
- R();
7675
+ v();
7676
7676
  else if (b) {
7677
7677
  const w = setInterval(() => {
7678
- h.current && h.current.isReady && (clearInterval(w), R());
7678
+ h.current && h.current.isReady && (clearInterval(w), v());
7679
7679
  }, 100);
7680
7680
  setTimeout(() => {
7681
7681
  clearInterval(w);
7682
7682
  }, 5e3);
7683
7683
  }
7684
7684
  }
7685
- }, [D]), Re = T(() => {
7685
+ }, [D]), ve = T(() => {
7686
7686
  const b = H.current || { modules: [] };
7687
7687
  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({
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, c.current.onCustomAction({
7689
7689
  type: "lessonStart",
7690
7690
  moduleIndex: r.current.currentModuleIndex,
7691
7691
  lessonIndex: r.current.currentLessonIndex
7692
- }), d.current.onLessonStart({
7692
+ }), c.current.onLessonStart({
7693
7693
  moduleIndex: r.current.currentModuleIndex,
7694
7694
  lessonIndex: r.current.currentLessonIndex,
7695
- lesson: v()
7695
+ lesson: R()
7696
7696
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7697
7697
  else if (r.current.currentModuleIndex > 0) {
7698
7698
  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({
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, c.current.onCustomAction({
7700
7700
  type: "lessonStart",
7701
7701
  moduleIndex: r.current.currentModuleIndex,
7702
7702
  lessonIndex: r.current.currentLessonIndex
7703
- }), d.current.onLessonStart({
7703
+ }), c.current.onLessonStart({
7704
7704
  moduleIndex: r.current.currentModuleIndex,
7705
7705
  lessonIndex: r.current.currentLessonIndex,
7706
- lesson: v()
7706
+ lesson: R()
7707
7707
  }), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
7708
7708
  }
7709
- }, [v]), ge = T(() => {
7709
+ }, [R]), ge = T(() => {
7710
7710
  r.current.currentModuleIndex = 0, r.current.currentLessonIndex = 0, r.current.currentQuestionIndex = 0, r.current.isTeaching = !1, r.current.isQuestionMode = !1, r.current.lessonCompleted = !1, r.current.curriculumCompleted = !1, r.current.score = 0, r.current.totalQuestions = 0;
7711
7711
  }, []), re = T((b) => {
7712
7712
  console.log("Avatar is ready!", b);
7713
- const R = v(), w = R?.avatar_script || R?.body;
7713
+ const v = R(), w = v?.avatar_script || v?.body;
7714
7714
  u && w && setTimeout(() => {
7715
- c.current && c.current();
7715
+ d.current && d.current();
7716
7716
  }, 10);
7717
- }, [u, v]);
7717
+ }, [u, R]);
7718
7718
  Oe(() => {
7719
- c.current = E, g.current = V, y.current = _, x.current = U, I.current = ne, P.current = S, p.current = X;
7719
+ d.current = E, g.current = V, y.current = _, x.current = U, I.current = ne, P.current = S, p.current = X;
7720
7720
  }), Ie(a, () => ({
7721
7721
  // Curriculum control methods
7722
7722
  startTeaching: E,
@@ -7726,30 +7726,30 @@ const lt = ve(({
7726
7726
  nextQuestion: U,
7727
7727
  previousQuestion: ue,
7728
7728
  nextLesson: V,
7729
- previousLesson: Re,
7729
+ previousLesson: ve,
7730
7730
  completeLesson: _,
7731
7731
  completeCurriculum: ne,
7732
7732
  resetCurriculum: ge,
7733
7733
  getState: () => ({ ...r.current }),
7734
7734
  getCurrentQuestion: () => D(),
7735
- getCurrentLesson: () => v(),
7735
+ getCurrentLesson: () => R(),
7736
7736
  // Direct access to avatar ref (always returns current value)
7737
7737
  getAvatarRef: () => h.current,
7738
7738
  // Convenience methods that delegate to avatar (always check current ref)
7739
- speakText: async (b, R = {}) => {
7739
+ speakText: async (b, v = {}) => {
7740
7740
  await h.current?.resumeAudioContext?.();
7741
7741
  const w = z.current || { lipsyncLang: "en" };
7742
- h.current?.speakText(b, { ...R, lipsyncLang: R.lipsyncLang || w.lipsyncLang });
7742
+ h.current?.speakText(b, { ...v, lipsyncLang: v.lipsyncLang || w.lipsyncLang });
7743
7743
  },
7744
7744
  resumeAudioContext: async () => {
7745
7745
  if (h.current?.resumeAudioContext)
7746
7746
  return await h.current.resumeAudioContext();
7747
7747
  const b = h.current?.talkingHead;
7748
7748
  if (b?.audioCtx) {
7749
- const R = b.audioCtx;
7750
- if (R.state === "suspended" || R.state === "interrupted")
7749
+ const v = b.audioCtx;
7750
+ if (v.state === "suspended" || v.state === "interrupted")
7751
7751
  try {
7752
- await R.resume(), console.log("Audio context resumed via talkingHead");
7752
+ await v.resume(), console.log("Audio context resumed via talkingHead");
7753
7753
  } catch (w) {
7754
7754
  console.warn("Failed to resume audio context:", w);
7755
7755
  }
@@ -7761,7 +7761,7 @@ const lt = ve(({
7761
7761
  resumeSpeaking: async () => await h.current?.resumeSpeaking(),
7762
7762
  isPaused: () => h.current && typeof h.current.isPaused < "u" ? h.current.isPaused : !1,
7763
7763
  setMood: (b) => h.current?.setMood(b),
7764
- playAnimation: (b, R) => h.current?.playAnimation(b, R),
7764
+ playAnimation: (b, v) => h.current?.playAnimation(b, v),
7765
7765
  setBodyMovement: (b) => h.current?.setBodyMovement(b),
7766
7766
  setMovementIntensity: (b) => h.current?.setMovementIntensity(b),
7767
7767
  playRandomDance: () => h.current?.playRandomDance(),
@@ -7772,10 +7772,10 @@ const lt = ve(({
7772
7772
  lockAvatarPosition: () => h.current?.lockAvatarPosition(),
7773
7773
  unlockAvatarPosition: () => h.current?.unlockAvatarPosition(),
7774
7774
  // Custom action trigger
7775
- triggerCustomAction: (b, R) => {
7776
- d.current.onCustomAction({
7775
+ triggerCustomAction: (b, v) => {
7776
+ c.current.onCustomAction({
7777
7777
  type: b,
7778
- ...R,
7778
+ ...v,
7779
7779
  state: { ...r.current }
7780
7780
  });
7781
7781
  },
@@ -7783,7 +7783,7 @@ const lt = ve(({
7783
7783
  handleResize: () => h.current?.handleResize(),
7784
7784
  // Avatar readiness check (always returns current value)
7785
7785
  isAvatarReady: () => h.current?.isReady || !1
7786
- }), [E, S, X, Y, U, V, _, ne, ge, D, v]);
7786
+ }), [E, S, X, Y, U, V, _, ne, ge, D, R]);
7787
7787
  const J = z.current || {
7788
7788
  avatarUrl: "/avatars/brunette.glb",
7789
7789
  avatarBody: "F",
@@ -7926,7 +7926,7 @@ const Fe = {
7926
7926
  duration: 5e3,
7927
7927
  description: "Excited, energetic movement"
7928
7928
  }
7929
- }, bt = (O) => Fe[O] || null, Rt = (O) => Fe.hasOwnProperty(O);
7929
+ }, bt = (O) => Fe[O] || null, vt = (O) => Fe.hasOwnProperty(O);
7930
7930
  export {
7931
7931
  lt as CurriculumLearning,
7932
7932
  Ee as TalkingHeadAvatar,
@@ -7935,5 +7935,5 @@ export {
7935
7935
  Le as getActiveTTSConfig,
7936
7936
  bt as getAnimation,
7937
7937
  xt as getVoiceOptions,
7938
- Rt as hasAnimation
7938
+ vt as hasAnimation
7939
7939
  };