@sage-rsc/talking-head-react 1.0.59 → 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.cjs +2 -2
- package/dist/index.js +171 -176
- package/package.json +1 -1
- package/src/components/CurriculumLearning.jsx +3 -5
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
|
|
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";
|
|
@@ -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
|
-
},
|
|
2632
|
+
}, W = 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();
|
|
@@ -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 ? (
|
|
4379
|
+
i.isQuaternion ? (W.setFromEuler(M), i.multiply(W)) : i.isVector3 && i.add(M);
|
|
4380
4380
|
}
|
|
4381
4381
|
}
|
|
4382
4382
|
/**
|
|
@@ -5180,7 +5180,7 @@ 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 && (
|
|
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)
|
|
5184
5184
|
this.stats && this.stats.end();
|
|
5185
5185
|
else {
|
|
5186
5186
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
@@ -5254,7 +5254,7 @@ class Me {
|
|
|
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((
|
|
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
5258
|
mark: c,
|
|
5259
5259
|
word: r
|
|
5260
5260
|
})), h.length && (g.push({
|
|
@@ -5265,16 +5265,16 @@ class Me {
|
|
|
5265
5265
|
subtitles: [h]
|
|
5266
5266
|
}
|
|
5267
5267
|
}), h = ""), r.length)) {
|
|
5268
|
-
const
|
|
5269
|
-
if (
|
|
5270
|
-
const D =
|
|
5271
|
-
for (let
|
|
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
5273
|
mark: c,
|
|
5274
5274
|
template: { name: "viseme" },
|
|
5275
|
-
ts: [(
|
|
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_" +
|
|
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
|
}
|
|
@@ -5282,14 +5282,14 @@ class Me {
|
|
|
5282
5282
|
}
|
|
5283
5283
|
if (p || I) {
|
|
5284
5284
|
if (d.length || I && g.length) {
|
|
5285
|
-
const
|
|
5285
|
+
const R = {
|
|
5286
5286
|
anim: g
|
|
5287
5287
|
};
|
|
5288
|
-
i && (
|
|
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
|
|
5292
|
-
|
|
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
|
}
|
|
@@ -5486,10 +5486,10 @@ class Me {
|
|
|
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],
|
|
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
|
-
ts: [
|
|
5492
|
+
ts: [N - Math.min(60, 2 * _ / 3), N + Math.min(25, _ / 2), N + _ + Math.min(60, _ / 2)],
|
|
5493
5493
|
vs: {
|
|
5494
5494
|
["viseme_" + z]: [null, z === "PP" || z === "FF" ? 0.9 : 0.6, 0]
|
|
5495
5495
|
}
|
|
@@ -6146,10 +6146,10 @@ 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),
|
|
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"]);
|
|
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(
|
|
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
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) {
|
|
@@ -6186,12 +6186,12 @@ 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),
|
|
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
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((
|
|
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",
|
|
@@ -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
|
|
6585
|
-
|
|
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
|
|
@@ -6655,16 +6655,16 @@ function Le() {
|
|
|
6655
6655
|
};
|
|
6656
6656
|
}
|
|
6657
6657
|
function xt() {
|
|
6658
|
-
const
|
|
6659
|
-
return Object.entries(
|
|
6658
|
+
const O = Le(), t = [];
|
|
6659
|
+
return Object.entries(O.voices).forEach(([e, i]) => {
|
|
6660
6660
|
t.push({
|
|
6661
6661
|
value: i,
|
|
6662
|
-
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${
|
|
6662
|
+
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${O.service})`
|
|
6663
6663
|
});
|
|
6664
6664
|
}), t;
|
|
6665
6665
|
}
|
|
6666
|
-
const Ee =
|
|
6667
|
-
avatarUrl:
|
|
6666
|
+
const Ee = Re(({
|
|
6667
|
+
avatarUrl: O = "/avatars/brunette.glb",
|
|
6668
6668
|
avatarBody: t = "F",
|
|
6669
6669
|
mood: e = "neutral",
|
|
6670
6670
|
ttsLang: i = "en",
|
|
@@ -6685,7 +6685,7 @@ const Ee = ve(({
|
|
|
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), [
|
|
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]);
|
|
@@ -6714,7 +6714,7 @@ const Ee = ve(({
|
|
|
6714
6714
|
apiKey: o !== null ? o : E.apiKey
|
|
6715
6715
|
};
|
|
6716
6716
|
const ue = {
|
|
6717
|
-
url:
|
|
6717
|
+
url: O,
|
|
6718
6718
|
body: t,
|
|
6719
6719
|
avatarMood: e,
|
|
6720
6720
|
ttsLang: X === "browser" ? "en-US" : i,
|
|
@@ -6723,7 +6723,7 @@ const Ee = ve(({
|
|
|
6723
6723
|
showFullAvatar: a,
|
|
6724
6724
|
bodyMovement: l,
|
|
6725
6725
|
movementIntensity: u
|
|
6726
|
-
},
|
|
6726
|
+
}, ve = {
|
|
6727
6727
|
ttsEndpoint: Y.endpoint,
|
|
6728
6728
|
ttsApikey: Y.apiKey,
|
|
6729
6729
|
ttsService: X,
|
|
@@ -6732,7 +6732,7 @@ 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,
|
|
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
6738
|
c(B);
|
|
@@ -6758,7 +6758,7 @@ const Ee = ve(({
|
|
|
6758
6758
|
} catch (A) {
|
|
6759
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(), () => {
|
|
6763
6763
|
p.current && (p.current.stop(), p.current.dispose(), p.current = null);
|
|
6764
6764
|
}), [ge]), pe(() => {
|
|
@@ -6785,7 +6785,7 @@ 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 },
|
|
6788
|
+
z.current = { text: A, options: F }, V(!1), await re();
|
|
6789
6789
|
const j = {
|
|
6790
6790
|
...F,
|
|
6791
6791
|
lipsyncLang: F.lipsyncLang || ue.lipsyncLang || "en"
|
|
@@ -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,
|
|
6831
|
-
}, []),
|
|
6830
|
+
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, V(!1));
|
|
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
|
-
(F && z.current && z.current.text || F) && (p.current.pauseSpeaking(),
|
|
6834
|
+
(F && z.current && z.current.text || F) && (p.current.pauseSpeaking(), V(!0));
|
|
6835
6835
|
}
|
|
6836
6836
|
}, []), w = T(async () => {
|
|
6837
|
-
if (p.current &&
|
|
6838
|
-
if (
|
|
6837
|
+
if (p.current && U)
|
|
6838
|
+
if (V(!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,
|
|
6848
|
+
}, [re, U]), C = T((A) => {
|
|
6849
6849
|
p.current && p.current.setMood(A);
|
|
6850
|
-
}, []),
|
|
6850
|
+
}, []), G = 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) {
|
|
@@ -6893,14 +6893,14 @@ const Ee = ve(({
|
|
|
6893
6893
|
return Ie(I, () => ({
|
|
6894
6894
|
speakText: J,
|
|
6895
6895
|
stopSpeaking: b,
|
|
6896
|
-
pauseSpeaking:
|
|
6896
|
+
pauseSpeaking: v,
|
|
6897
6897
|
resumeSpeaking: w,
|
|
6898
6898
|
resumeAudioContext: re,
|
|
6899
6899
|
setMood: C,
|
|
6900
|
-
setTimingAdjustment:
|
|
6900
|
+
setTimingAdjustment: G,
|
|
6901
6901
|
playAnimation: te,
|
|
6902
6902
|
isReady: ne,
|
|
6903
|
-
isPaused:
|
|
6903
|
+
isPaused: U,
|
|
6904
6904
|
talkingHead: p.current,
|
|
6905
6905
|
handleResize: ie,
|
|
6906
6906
|
setBodyMovement: (A) => {
|
|
@@ -6983,7 +6983,7 @@ const Ee = ve(({
|
|
|
6983
6983
|
}
|
|
6984
6984
|
}
|
|
6985
6985
|
),
|
|
6986
|
-
|
|
6986
|
+
R && /* @__PURE__ */ he("div", { className: "loading-overlay", style: {
|
|
6987
6987
|
position: "absolute",
|
|
6988
6988
|
top: "50%",
|
|
6989
6989
|
left: "50%",
|
|
@@ -6992,7 +6992,7 @@ const Ee = ve(({
|
|
|
6992
6992
|
fontSize: "18px",
|
|
6993
6993
|
zIndex: 10
|
|
6994
6994
|
}, children: "Loading avatar..." }),
|
|
6995
|
-
|
|
6995
|
+
N && /* @__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:
|
|
7006
|
+
}, children: N })
|
|
7007
7007
|
]
|
|
7008
7008
|
}
|
|
7009
7009
|
);
|
|
7010
7010
|
});
|
|
7011
7011
|
Ee.displayName = "TalkingHeadAvatar";
|
|
7012
|
-
const rt =
|
|
7013
|
-
text:
|
|
7012
|
+
const rt = Re(({
|
|
7013
|
+
text: O = "Hello! I'm a talking avatar. How are you today?",
|
|
7014
7014
|
onLoading: t = () => {
|
|
7015
7015
|
},
|
|
7016
7016
|
onError: e = () => {
|
|
@@ -7054,34 +7054,34 @@ const rt = ve(({
|
|
|
7054
7054
|
}, z = T(async () => {
|
|
7055
7055
|
if (!(!u.current || a.current))
|
|
7056
7056
|
try {
|
|
7057
|
-
if (r(!0), d(null), a.current = new Me(u.current, H), await a.current.showAvatar(p, (
|
|
7058
|
-
if (
|
|
7059
|
-
const E = Math.min(100, Math.round(
|
|
7057
|
+
if (r(!0), d(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));
|
|
7060
7060
|
t(E);
|
|
7061
7061
|
}
|
|
7062
7062
|
}), a.current.morphs && a.current.morphs.length > 0) {
|
|
7063
|
-
const
|
|
7064
|
-
console.log("Available morph targets:", Object.keys(
|
|
7065
|
-
const E = Object.keys(
|
|
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_"));
|
|
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((
|
|
7068
|
+
if (await new Promise((V) => {
|
|
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)),
|
|
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));
|
|
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 (
|
|
7077
|
-
console.warn("Error setting full body mode on initialization:",
|
|
7076
|
+
} catch (V) {
|
|
7077
|
+
console.warn("Error setting full body mode on initialization:", V);
|
|
7078
7078
|
}
|
|
7079
7079
|
r(!1), y(!0), i(a.current);
|
|
7080
|
-
const
|
|
7080
|
+
const U = () => {
|
|
7081
7081
|
document.visibilityState === "visible" ? a.current?.start() : a.current?.stop();
|
|
7082
7082
|
};
|
|
7083
|
-
return document.addEventListener("visibilitychange",
|
|
7084
|
-
document.removeEventListener("visibilitychange",
|
|
7083
|
+
return document.addEventListener("visibilitychange", U), () => {
|
|
7084
|
+
document.removeEventListener("visibilitychange", U);
|
|
7085
7085
|
};
|
|
7086
7086
|
} catch (S) {
|
|
7087
7087
|
console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), r(!1), e(S);
|
|
@@ -7090,24 +7090,24 @@ const rt = ve(({
|
|
|
7090
7090
|
pe(() => (z(), () => {
|
|
7091
7091
|
a.current && (a.current.stop(), a.current.dispose(), a.current = null);
|
|
7092
7092
|
}), [z]);
|
|
7093
|
-
const
|
|
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
|
-
} catch (
|
|
7100
|
-
console.error("Error speaking text:",
|
|
7099
|
+
} catch (U) {
|
|
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);
|
|
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
|
-
}, []),
|
|
7106
|
+
}, []), N = 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,
|
|
7110
|
+
}, []), ne = T((S, U = !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,
|
|
7120
|
+
a.current.playAnimation(S, null, 10, 0, 0.01, U), 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,
|
|
7134
|
+
a.current.playAnimation(S + Y, null, 10, 0, 0.01, U), 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...`);
|
|
@@ -7149,9 +7149,9 @@ 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:
|
|
7152
|
+
speakText: R,
|
|
7153
7153
|
stopSpeaking: D,
|
|
7154
|
-
setMood:
|
|
7154
|
+
setMood: N,
|
|
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 (
|
|
7164
|
-
console.warn("Error setting body movement:",
|
|
7163
|
+
} catch (U) {
|
|
7164
|
+
console.warn("Error setting body movement:", U);
|
|
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 (
|
|
7181
|
-
console.warn("Error playing reaction:",
|
|
7180
|
+
} catch (U) {
|
|
7181
|
+
console.warn("Error playing reaction:", U);
|
|
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 (
|
|
7197
|
-
console.warn("Error setting showFullAvatar:",
|
|
7196
|
+
} catch (U) {
|
|
7197
|
+
console.warn("Error setting showFullAvatar:", U);
|
|
7198
7198
|
}
|
|
7199
7199
|
},
|
|
7200
7200
|
lockAvatarPosition: () => {
|
|
@@ -7250,8 +7250,8 @@ const rt = ve(({
|
|
|
7250
7250
|
] });
|
|
7251
7251
|
});
|
|
7252
7252
|
rt.displayName = "TalkingHeadComponent";
|
|
7253
|
-
const lt =
|
|
7254
|
-
curriculumData:
|
|
7253
|
+
const lt = Re(({
|
|
7254
|
+
curriculumData: O = null,
|
|
7255
7255
|
avatarConfig: t = {},
|
|
7256
7256
|
animations: e = {},
|
|
7257
7257
|
onLessonStart: i = () => {
|
|
@@ -7282,7 +7282,7 @@ const lt = ve(({
|
|
|
7282
7282
|
onQuestionAnswer: s,
|
|
7283
7283
|
onCurriculumComplete: o,
|
|
7284
7284
|
onCustomAction: l
|
|
7285
|
-
}), d = Z(null), g = Z(null), y = Z(null), x = Z(null), I = Z(null), P = Z(null), p = Z(null), H = Z(
|
|
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",
|
|
@@ -7310,7 +7310,7 @@ const lt = ve(({
|
|
|
7310
7310
|
onCustomAction: l
|
|
7311
7311
|
};
|
|
7312
7312
|
}, [i, n, s, o, l]), pe(() => {
|
|
7313
|
-
H.current =
|
|
7313
|
+
H.current = O?.curriculum || {
|
|
7314
7314
|
title: "Default Curriculum",
|
|
7315
7315
|
description: "No curriculum data provided",
|
|
7316
7316
|
language: "en",
|
|
@@ -7329,17 +7329,12 @@ const lt = ve(({
|
|
|
7329
7329
|
animations: e,
|
|
7330
7330
|
lipsyncLang: "en"
|
|
7331
7331
|
};
|
|
7332
|
-
}, [
|
|
7333
|
-
const
|
|
7332
|
+
}, [O, t, e]);
|
|
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
|
|
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({
|
|
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({
|
|
7343
7338
|
moduleIndex: r.current.currentModuleIndex,
|
|
7344
7339
|
lessonIndex: r.current.currentLessonIndex,
|
|
7345
7340
|
score: r.current.score,
|
|
@@ -7359,8 +7354,8 @@ const lt = ve(({
|
|
|
7359
7354
|
} catch {
|
|
7360
7355
|
h.current.playCelebration();
|
|
7361
7356
|
}
|
|
7362
|
-
const w = H.current || { modules: [] }, C = w.modules[r.current.currentModuleIndex],
|
|
7363
|
-
h.current.speakText(
|
|
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(v, {
|
|
7364
7359
|
lipsyncLang: A.lipsyncLang,
|
|
7365
7360
|
onSpeechEnd: () => {
|
|
7366
7361
|
c.current.onCustomAction({
|
|
@@ -7380,7 +7375,7 @@ const lt = ve(({
|
|
|
7380
7375
|
const b = H.current || { modules: [] };
|
|
7381
7376
|
if (c.current.onCurriculumComplete({
|
|
7382
7377
|
modules: b.modules.length,
|
|
7383
|
-
totalLessons: b.modules.reduce((
|
|
7378
|
+
totalLessons: b.modules.reduce((v, w) => v + w.lessons.length, 0)
|
|
7384
7379
|
}), h.current) {
|
|
7385
7380
|
if (h.current.setMood("celebrating"), e.curriculumComplete)
|
|
7386
7381
|
try {
|
|
@@ -7388,82 +7383,82 @@ const lt = ve(({
|
|
|
7388
7383
|
} catch {
|
|
7389
7384
|
h.current.playCelebration();
|
|
7390
7385
|
}
|
|
7391
|
-
const
|
|
7392
|
-
h.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { 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 });
|
|
7393
7388
|
}
|
|
7394
7389
|
}, [e.curriculumComplete]), S = T(() => {
|
|
7395
|
-
const b =
|
|
7390
|
+
const b = R();
|
|
7396
7391
|
r.current.isQuestionMode = !0, r.current.currentQuestionIndex = 0, r.current.totalQuestions = b?.questions?.length || 0, r.current.score = 0;
|
|
7397
|
-
const
|
|
7398
|
-
|
|
7392
|
+
const v = D();
|
|
7393
|
+
v && c.current.onCustomAction({
|
|
7399
7394
|
type: "questionStart",
|
|
7400
7395
|
moduleIndex: r.current.currentModuleIndex,
|
|
7401
7396
|
lessonIndex: r.current.currentLessonIndex,
|
|
7402
7397
|
questionIndex: r.current.currentQuestionIndex,
|
|
7403
7398
|
totalQuestions: r.current.totalQuestions,
|
|
7404
|
-
question:
|
|
7399
|
+
question: v,
|
|
7405
7400
|
score: r.current.score
|
|
7406
7401
|
});
|
|
7407
7402
|
const w = () => {
|
|
7408
|
-
if (!h.current || !
|
|
7403
|
+
if (!h.current || !v) return;
|
|
7409
7404
|
if (h.current.setMood("happy"), e.questionStart)
|
|
7410
7405
|
try {
|
|
7411
7406
|
h.current.playAnimation(e.questionStart, !0);
|
|
7412
|
-
} catch (
|
|
7413
|
-
console.warn("Failed to play questionStart animation:",
|
|
7407
|
+
} catch (G) {
|
|
7408
|
+
console.warn("Failed to play questionStart animation:", G);
|
|
7414
7409
|
}
|
|
7415
7410
|
const C = z.current || { lipsyncLang: "en" };
|
|
7416
|
-
|
|
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 });
|
|
7417
7412
|
};
|
|
7418
|
-
if (h.current && h.current.isReady &&
|
|
7413
|
+
if (h.current && h.current.isReady && v)
|
|
7419
7414
|
w();
|
|
7420
7415
|
else if (h.current && h.current.isReady) {
|
|
7421
7416
|
const C = z.current || { lipsyncLang: "en" };
|
|
7422
7417
|
h.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: C.lipsyncLang });
|
|
7423
7418
|
} else {
|
|
7424
7419
|
const C = setInterval(() => {
|
|
7425
|
-
h.current && h.current.isReady && (clearInterval(C),
|
|
7420
|
+
h.current && h.current.isReady && (clearInterval(C), v && w());
|
|
7426
7421
|
}, 100);
|
|
7427
7422
|
setTimeout(() => {
|
|
7428
7423
|
clearInterval(C);
|
|
7429
7424
|
}, 5e3);
|
|
7430
7425
|
}
|
|
7431
|
-
}, [e.questionStart,
|
|
7432
|
-
const b =
|
|
7426
|
+
}, [e.questionStart, R, D]), U = T(() => {
|
|
7427
|
+
const b = R();
|
|
7433
7428
|
if (r.current.currentQuestionIndex < (b?.questions?.length || 0) - 1) {
|
|
7434
7429
|
h.current && h.current.stopSpeaking && h.current.stopSpeaking(), r.current.currentQuestionIndex += 1;
|
|
7435
|
-
const
|
|
7436
|
-
|
|
7430
|
+
const v = D();
|
|
7431
|
+
v && c.current.onCustomAction({
|
|
7437
7432
|
type: "nextQuestion",
|
|
7438
7433
|
moduleIndex: r.current.currentModuleIndex,
|
|
7439
7434
|
lessonIndex: r.current.currentLessonIndex,
|
|
7440
7435
|
questionIndex: r.current.currentQuestionIndex,
|
|
7441
7436
|
totalQuestions: r.current.totalQuestions,
|
|
7442
|
-
question:
|
|
7437
|
+
question: v,
|
|
7443
7438
|
score: r.current.score
|
|
7444
7439
|
});
|
|
7445
7440
|
const w = () => {
|
|
7446
|
-
if (!h.current || !
|
|
7441
|
+
if (!h.current || !v) return;
|
|
7447
7442
|
if (h.current.setMood("happy"), h.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7448
7443
|
try {
|
|
7449
7444
|
h.current.playAnimation(e.nextQuestion, !0);
|
|
7450
|
-
} catch (
|
|
7451
|
-
console.warn("Failed to play nextQuestion animation:",
|
|
7445
|
+
} catch (G) {
|
|
7446
|
+
console.warn("Failed to play nextQuestion animation:", G);
|
|
7452
7447
|
}
|
|
7453
7448
|
const C = z.current || { lipsyncLang: "en" };
|
|
7454
|
-
|
|
7449
|
+
v.type === "code_test" ? h.current.speakText(`Great! Now let's move on to your next coding challenge: ${v.question}`, {
|
|
7455
7450
|
lipsyncLang: C.lipsyncLang
|
|
7456
|
-
}) :
|
|
7451
|
+
}) : v.type === "multiple_choice" ? h.current.speakText(`Alright! Here's your next question: ${v.question}`, {
|
|
7457
7452
|
lipsyncLang: C.lipsyncLang
|
|
7458
|
-
}) :
|
|
7453
|
+
}) : v.type === "true_false" ? h.current.speakText(`Now let's try this one: ${v.question}`, {
|
|
7459
7454
|
lipsyncLang: C.lipsyncLang
|
|
7460
|
-
}) : h.current.speakText(`Here's the next question: ${
|
|
7455
|
+
}) : h.current.speakText(`Here's the next question: ${v.question}`, {
|
|
7461
7456
|
lipsyncLang: C.lipsyncLang
|
|
7462
7457
|
});
|
|
7463
7458
|
};
|
|
7464
|
-
if (h.current && h.current.isReady &&
|
|
7459
|
+
if (h.current && h.current.isReady && v)
|
|
7465
7460
|
w();
|
|
7466
|
-
else if (
|
|
7461
|
+
else if (v) {
|
|
7467
7462
|
const C = setInterval(() => {
|
|
7468
7463
|
h.current && h.current.isReady && (clearInterval(C), w());
|
|
7469
7464
|
}, 100);
|
|
@@ -7479,11 +7474,11 @@ const lt = ve(({
|
|
|
7479
7474
|
totalQuestions: r.current.totalQuestions,
|
|
7480
7475
|
score: r.current.score
|
|
7481
7476
|
});
|
|
7482
|
-
}, [e.nextQuestion,
|
|
7483
|
-
const b = H.current || { modules: [] },
|
|
7484
|
-
if (r.current.currentLessonIndex < (
|
|
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) {
|
|
7485
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;
|
|
7486
|
-
const C = b.modules[r.current.currentModuleIndex],
|
|
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;
|
|
7487
7482
|
c.current.onCustomAction({
|
|
7488
7483
|
type: "lessonStart",
|
|
7489
7484
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -7492,11 +7487,11 @@ const lt = ve(({
|
|
|
7492
7487
|
}), c.current.onLessonStart({
|
|
7493
7488
|
moduleIndex: r.current.currentModuleIndex,
|
|
7494
7489
|
lessonIndex: r.current.currentLessonIndex,
|
|
7495
|
-
lesson:
|
|
7490
|
+
lesson: R()
|
|
7496
7491
|
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
7497
7492
|
} else if (r.current.currentModuleIndex < (b.modules?.length || 0) - 1) {
|
|
7498
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;
|
|
7499
|
-
const
|
|
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;
|
|
7500
7495
|
c.current.onCustomAction({
|
|
7501
7496
|
type: "lessonStart",
|
|
7502
7497
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -7505,26 +7500,26 @@ const lt = ve(({
|
|
|
7505
7500
|
}), c.current.onLessonStart({
|
|
7506
7501
|
moduleIndex: r.current.currentModuleIndex,
|
|
7507
7502
|
lessonIndex: r.current.currentLessonIndex,
|
|
7508
|
-
lesson:
|
|
7503
|
+
lesson: R()
|
|
7509
7504
|
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
7510
7505
|
} else
|
|
7511
7506
|
I.current && I.current();
|
|
7512
7507
|
}, []), E = T(() => {
|
|
7513
|
-
const b =
|
|
7514
|
-
let
|
|
7508
|
+
const b = R();
|
|
7509
|
+
let v = null;
|
|
7515
7510
|
if (b?.avatar_script && b?.body) {
|
|
7516
|
-
const w = b.avatar_script.trim(), C = b.body.trim(),
|
|
7517
|
-
|
|
7511
|
+
const w = b.avatar_script.trim(), C = b.body.trim(), G = w.match(/[.!?]$/) ? " " : ". ";
|
|
7512
|
+
v = `${w}${G}${C}`;
|
|
7518
7513
|
} else
|
|
7519
|
-
|
|
7520
|
-
if (h.current && h.current.isReady &&
|
|
7514
|
+
v = b?.avatar_script || b?.body || null;
|
|
7515
|
+
if (h.current && h.current.isReady && v) {
|
|
7521
7516
|
r.current.isTeaching = !0, r.current.isQuestionMode = !1, r.current.score = 0, r.current.totalQuestions = 0, h.current.setMood("happy");
|
|
7522
7517
|
let w = !1;
|
|
7523
7518
|
if (e.teaching)
|
|
7524
7519
|
try {
|
|
7525
7520
|
h.current.playAnimation(e.teaching, !0), w = !0;
|
|
7526
|
-
} catch (
|
|
7527
|
-
console.warn("Failed to play teaching animation:",
|
|
7521
|
+
} catch (G) {
|
|
7522
|
+
console.warn("Failed to play teaching animation:", G);
|
|
7528
7523
|
}
|
|
7529
7524
|
w || h.current.setBodyMovement("gesturing");
|
|
7530
7525
|
const C = z.current || { lipsyncLang: "en" };
|
|
@@ -7537,7 +7532,7 @@ const lt = ve(({
|
|
|
7537
7532
|
moduleIndex: r.current.currentModuleIndex,
|
|
7538
7533
|
lessonIndex: r.current.currentLessonIndex,
|
|
7539
7534
|
lesson: b
|
|
7540
|
-
}), h.current.speakText(
|
|
7535
|
+
}), h.current.speakText(v, {
|
|
7541
7536
|
lipsyncLang: C.lipsyncLang,
|
|
7542
7537
|
onSpeechEnd: () => {
|
|
7543
7538
|
r.current.isTeaching = !1, c.current.onCustomAction({
|
|
@@ -7550,15 +7545,15 @@ const lt = ve(({
|
|
|
7550
7545
|
}
|
|
7551
7546
|
});
|
|
7552
7547
|
}
|
|
7553
|
-
}, [e.teaching,
|
|
7554
|
-
const
|
|
7548
|
+
}, [e.teaching, R]), X = T((b) => {
|
|
7549
|
+
const v = D(), w = N(b, v);
|
|
7555
7550
|
if (w && (r.current.score += 1), c.current.onQuestionAnswer({
|
|
7556
7551
|
moduleIndex: r.current.currentModuleIndex,
|
|
7557
7552
|
lessonIndex: r.current.currentLessonIndex,
|
|
7558
7553
|
questionIndex: r.current.currentQuestionIndex,
|
|
7559
7554
|
answer: b,
|
|
7560
7555
|
isCorrect: w,
|
|
7561
|
-
question:
|
|
7556
|
+
question: v
|
|
7562
7557
|
}), h.current)
|
|
7563
7558
|
if (w) {
|
|
7564
7559
|
if (h.current.setMood("happy"), e.correct)
|
|
@@ -7568,11 +7563,11 @@ const lt = ve(({
|
|
|
7568
7563
|
h.current.setBodyMovement("happy");
|
|
7569
7564
|
}
|
|
7570
7565
|
h.current.setBodyMovement("gesturing");
|
|
7571
|
-
const C =
|
|
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" };
|
|
7572
7567
|
h.current.speakText(C, {
|
|
7573
|
-
lipsyncLang:
|
|
7568
|
+
lipsyncLang: G.lipsyncLang,
|
|
7574
7569
|
onSpeechEnd: () => {
|
|
7575
|
-
const ie =
|
|
7570
|
+
const ie = R()?.questions?.length || 0;
|
|
7576
7571
|
c.current.onCustomAction({
|
|
7577
7572
|
type: "answerFeedbackComplete",
|
|
7578
7573
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -7593,11 +7588,11 @@ const lt = ve(({
|
|
|
7593
7588
|
h.current.setBodyMovement("idle");
|
|
7594
7589
|
}
|
|
7595
7590
|
h.current.setBodyMovement("gesturing");
|
|
7596
|
-
const C =
|
|
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" };
|
|
7597
7592
|
h.current.speakText(C, {
|
|
7598
|
-
lipsyncLang:
|
|
7593
|
+
lipsyncLang: G.lipsyncLang,
|
|
7599
7594
|
onSpeechEnd: () => {
|
|
7600
|
-
const ie =
|
|
7595
|
+
const ie = R()?.questions?.length || 0;
|
|
7601
7596
|
c.current.onCustomAction({
|
|
7602
7597
|
type: "answerFeedbackComplete",
|
|
7603
7598
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -7612,26 +7607,26 @@ const lt = ve(({
|
|
|
7612
7607
|
});
|
|
7613
7608
|
}
|
|
7614
7609
|
else {
|
|
7615
|
-
const
|
|
7610
|
+
const G = R()?.questions?.length || 0;
|
|
7616
7611
|
c.current.onCustomAction({
|
|
7617
7612
|
type: "answerFeedbackComplete",
|
|
7618
7613
|
moduleIndex: r.current.currentModuleIndex,
|
|
7619
7614
|
lessonIndex: r.current.currentLessonIndex,
|
|
7620
7615
|
questionIndex: r.current.currentQuestionIndex,
|
|
7621
7616
|
isCorrect: w,
|
|
7622
|
-
hasNextQuestion: r.current.currentQuestionIndex <
|
|
7617
|
+
hasNextQuestion: r.current.currentQuestionIndex < G - 1,
|
|
7623
7618
|
score: r.current.score,
|
|
7624
7619
|
totalQuestions: r.current.totalQuestions,
|
|
7625
7620
|
avatarNotReady: !0
|
|
7626
7621
|
});
|
|
7627
7622
|
}
|
|
7628
|
-
}, [e.correct, e.incorrect, D,
|
|
7629
|
-
const
|
|
7623
|
+
}, [e.correct, e.incorrect, D, R, N]), Y = T((b) => {
|
|
7624
|
+
const v = D();
|
|
7630
7625
|
if (!b || typeof b != "object") {
|
|
7631
7626
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
7632
7627
|
return;
|
|
7633
7628
|
}
|
|
7634
|
-
if (
|
|
7629
|
+
if (v?.type !== "code_test") {
|
|
7635
7630
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
7636
7631
|
return;
|
|
7637
7632
|
}
|
|
@@ -7651,9 +7646,9 @@ const lt = ve(({
|
|
|
7651
7646
|
lessonIndex: r.current.currentLessonIndex,
|
|
7652
7647
|
questionIndex: r.current.currentQuestionIndex,
|
|
7653
7648
|
testResult: w,
|
|
7654
|
-
question:
|
|
7649
|
+
question: v
|
|
7655
7650
|
}), p.current && p.current(w);
|
|
7656
|
-
}, [D,
|
|
7651
|
+
}, [D, N]), ue = T(() => {
|
|
7657
7652
|
if (r.current.currentQuestionIndex > 0) {
|
|
7658
7653
|
r.current.currentQuestionIndex -= 1;
|
|
7659
7654
|
const b = D();
|
|
@@ -7666,7 +7661,7 @@ const lt = ve(({
|
|
|
7666
7661
|
question: b,
|
|
7667
7662
|
score: r.current.score
|
|
7668
7663
|
});
|
|
7669
|
-
const
|
|
7664
|
+
const v = () => {
|
|
7670
7665
|
if (!h.current || !b) return;
|
|
7671
7666
|
h.current.setMood("happy"), h.current.setBodyMovement("idle");
|
|
7672
7667
|
const w = z.current || { lipsyncLang: "en" };
|
|
@@ -7677,17 +7672,17 @@ const lt = ve(({
|
|
|
7677
7672
|
});
|
|
7678
7673
|
};
|
|
7679
7674
|
if (h.current && h.current.isReady && b)
|
|
7680
|
-
|
|
7675
|
+
v();
|
|
7681
7676
|
else if (b) {
|
|
7682
7677
|
const w = setInterval(() => {
|
|
7683
|
-
h.current && h.current.isReady && (clearInterval(w),
|
|
7678
|
+
h.current && h.current.isReady && (clearInterval(w), v());
|
|
7684
7679
|
}, 100);
|
|
7685
7680
|
setTimeout(() => {
|
|
7686
7681
|
clearInterval(w);
|
|
7687
7682
|
}, 5e3);
|
|
7688
7683
|
}
|
|
7689
7684
|
}
|
|
7690
|
-
}, [D]),
|
|
7685
|
+
}, [D]), ve = T(() => {
|
|
7691
7686
|
const b = H.current || { modules: [] };
|
|
7692
7687
|
if (b.modules[r.current.currentModuleIndex], r.current.currentLessonIndex > 0)
|
|
7693
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({
|
|
@@ -7697,7 +7692,7 @@ const lt = ve(({
|
|
|
7697
7692
|
}), c.current.onLessonStart({
|
|
7698
7693
|
moduleIndex: r.current.currentModuleIndex,
|
|
7699
7694
|
lessonIndex: r.current.currentLessonIndex,
|
|
7700
|
-
lesson:
|
|
7695
|
+
lesson: R()
|
|
7701
7696
|
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
7702
7697
|
else if (r.current.currentModuleIndex > 0) {
|
|
7703
7698
|
const C = b.modules[r.current.currentModuleIndex - 1];
|
|
@@ -7708,53 +7703,53 @@ const lt = ve(({
|
|
|
7708
7703
|
}), c.current.onLessonStart({
|
|
7709
7704
|
moduleIndex: r.current.currentModuleIndex,
|
|
7710
7705
|
lessonIndex: r.current.currentLessonIndex,
|
|
7711
|
-
lesson:
|
|
7706
|
+
lesson: R()
|
|
7712
7707
|
}), h.current && (h.current.setMood("happy"), h.current.setBodyMovement("idle"));
|
|
7713
7708
|
}
|
|
7714
|
-
}, [
|
|
7709
|
+
}, [R]), ge = T(() => {
|
|
7715
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;
|
|
7716
7711
|
}, []), re = T((b) => {
|
|
7717
7712
|
console.log("Avatar is ready!", b);
|
|
7718
|
-
const
|
|
7713
|
+
const v = R(), w = v?.avatar_script || v?.body;
|
|
7719
7714
|
u && w && setTimeout(() => {
|
|
7720
7715
|
d.current && d.current();
|
|
7721
7716
|
}, 10);
|
|
7722
|
-
}, [u,
|
|
7717
|
+
}, [u, R]);
|
|
7723
7718
|
Oe(() => {
|
|
7724
|
-
d.current = E, g.current =
|
|
7719
|
+
d.current = E, g.current = V, y.current = _, x.current = U, I.current = ne, P.current = S, p.current = X;
|
|
7725
7720
|
}), Ie(a, () => ({
|
|
7726
7721
|
// Curriculum control methods
|
|
7727
7722
|
startTeaching: E,
|
|
7728
7723
|
startQuestions: S,
|
|
7729
7724
|
handleAnswerSelect: X,
|
|
7730
7725
|
handleCodeTestResult: Y,
|
|
7731
|
-
nextQuestion:
|
|
7726
|
+
nextQuestion: U,
|
|
7732
7727
|
previousQuestion: ue,
|
|
7733
|
-
nextLesson:
|
|
7734
|
-
previousLesson:
|
|
7728
|
+
nextLesson: V,
|
|
7729
|
+
previousLesson: ve,
|
|
7735
7730
|
completeLesson: _,
|
|
7736
7731
|
completeCurriculum: ne,
|
|
7737
7732
|
resetCurriculum: ge,
|
|
7738
7733
|
getState: () => ({ ...r.current }),
|
|
7739
7734
|
getCurrentQuestion: () => D(),
|
|
7740
|
-
getCurrentLesson: () =>
|
|
7735
|
+
getCurrentLesson: () => R(),
|
|
7741
7736
|
// Direct access to avatar ref (always returns current value)
|
|
7742
7737
|
getAvatarRef: () => h.current,
|
|
7743
7738
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
7744
|
-
speakText: async (b,
|
|
7739
|
+
speakText: async (b, v = {}) => {
|
|
7745
7740
|
await h.current?.resumeAudioContext?.();
|
|
7746
7741
|
const w = z.current || { lipsyncLang: "en" };
|
|
7747
|
-
h.current?.speakText(b, { ...
|
|
7742
|
+
h.current?.speakText(b, { ...v, lipsyncLang: v.lipsyncLang || w.lipsyncLang });
|
|
7748
7743
|
},
|
|
7749
7744
|
resumeAudioContext: async () => {
|
|
7750
7745
|
if (h.current?.resumeAudioContext)
|
|
7751
7746
|
return await h.current.resumeAudioContext();
|
|
7752
7747
|
const b = h.current?.talkingHead;
|
|
7753
7748
|
if (b?.audioCtx) {
|
|
7754
|
-
const
|
|
7755
|
-
if (
|
|
7749
|
+
const v = b.audioCtx;
|
|
7750
|
+
if (v.state === "suspended" || v.state === "interrupted")
|
|
7756
7751
|
try {
|
|
7757
|
-
await
|
|
7752
|
+
await v.resume(), console.log("Audio context resumed via talkingHead");
|
|
7758
7753
|
} catch (w) {
|
|
7759
7754
|
console.warn("Failed to resume audio context:", w);
|
|
7760
7755
|
}
|
|
@@ -7766,7 +7761,7 @@ const lt = ve(({
|
|
|
7766
7761
|
resumeSpeaking: async () => await h.current?.resumeSpeaking(),
|
|
7767
7762
|
isPaused: () => h.current && typeof h.current.isPaused < "u" ? h.current.isPaused : !1,
|
|
7768
7763
|
setMood: (b) => h.current?.setMood(b),
|
|
7769
|
-
playAnimation: (b,
|
|
7764
|
+
playAnimation: (b, v) => h.current?.playAnimation(b, v),
|
|
7770
7765
|
setBodyMovement: (b) => h.current?.setBodyMovement(b),
|
|
7771
7766
|
setMovementIntensity: (b) => h.current?.setMovementIntensity(b),
|
|
7772
7767
|
playRandomDance: () => h.current?.playRandomDance(),
|
|
@@ -7777,10 +7772,10 @@ const lt = ve(({
|
|
|
7777
7772
|
lockAvatarPosition: () => h.current?.lockAvatarPosition(),
|
|
7778
7773
|
unlockAvatarPosition: () => h.current?.unlockAvatarPosition(),
|
|
7779
7774
|
// Custom action trigger
|
|
7780
|
-
triggerCustomAction: (b,
|
|
7775
|
+
triggerCustomAction: (b, v) => {
|
|
7781
7776
|
c.current.onCustomAction({
|
|
7782
7777
|
type: b,
|
|
7783
|
-
...
|
|
7778
|
+
...v,
|
|
7784
7779
|
state: { ...r.current }
|
|
7785
7780
|
});
|
|
7786
7781
|
},
|
|
@@ -7788,7 +7783,7 @@ const lt = ve(({
|
|
|
7788
7783
|
handleResize: () => h.current?.handleResize(),
|
|
7789
7784
|
// Avatar readiness check (always returns current value)
|
|
7790
7785
|
isAvatarReady: () => h.current?.isReady || !1
|
|
7791
|
-
}), [E, S, X, Y,
|
|
7786
|
+
}), [E, S, X, Y, U, V, _, ne, ge, D, R]);
|
|
7792
7787
|
const J = z.current || {
|
|
7793
7788
|
avatarUrl: "/avatars/brunette.glb",
|
|
7794
7789
|
avatarBody: "F",
|
|
@@ -7931,7 +7926,7 @@ const Fe = {
|
|
|
7931
7926
|
duration: 5e3,
|
|
7932
7927
|
description: "Excited, energetic movement"
|
|
7933
7928
|
}
|
|
7934
|
-
}, bt = (
|
|
7929
|
+
}, bt = (O) => Fe[O] || null, vt = (O) => Fe.hasOwnProperty(O);
|
|
7935
7930
|
export {
|
|
7936
7931
|
lt as CurriculumLearning,
|
|
7937
7932
|
Ee as TalkingHeadAvatar,
|
|
@@ -7940,5 +7935,5 @@ export {
|
|
|
7940
7935
|
Le as getActiveTTSConfig,
|
|
7941
7936
|
bt as getAnimation,
|
|
7942
7937
|
xt as getVoiceOptions,
|
|
7943
|
-
|
|
7938
|
+
vt as hasAnimation
|
|
7944
7939
|
};
|