@sage-rsc/talking-head-react 1.0.72 → 1.0.74
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/README.md +450 -119
- package/dist/index.cjs +2 -2
- package/dist/index.js +88 -84
- package/package.json +1 -1
- package/src/components/SimpleTalkingAvatar.jsx +12 -0
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { FBXLoader as Oe } from "three/addons/loaders/FBXLoader.js";
|
|
|
8
8
|
import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
|
|
9
9
|
import Ke from "three/addons/libs/stats.module.js";
|
|
10
10
|
let m, re, ue;
|
|
11
|
-
const A = [0, 0, 0, 0],
|
|
11
|
+
const A = [0, 0, 0, 0], w = new x.Vector3(), ze = new x.Vector3(), ne = new x.Vector3(), Ce = new x.Vector3();
|
|
12
12
|
new x.Plane();
|
|
13
13
|
new x.Ray();
|
|
14
14
|
new x.Euler();
|
|
@@ -321,7 +321,7 @@ class et {
|
|
|
321
321
|
/// Bone's parent object
|
|
322
322
|
vBasis: r.position.clone(),
|
|
323
323
|
// Original local position
|
|
324
|
-
vWorld: r.parent.getWorldPosition(
|
|
324
|
+
vWorld: r.parent.getWorldPosition(w).clone(),
|
|
325
325
|
// World position, parent
|
|
326
326
|
qBasis: r.parent.quaternion.clone(),
|
|
327
327
|
// Original quaternion, parent
|
|
@@ -338,7 +338,7 @@ class et {
|
|
|
338
338
|
ea: [0, 0, 0, 0]
|
|
339
339
|
// External acceleration [m/s^2]
|
|
340
340
|
};
|
|
341
|
-
u.boneParent.matrixWorld.decompose(
|
|
341
|
+
u.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Ne.setFromUnitVectors(He, w).invert()).normalize(), u.qWorldInverseYaw = ie.clone().normalize(), this.data.push(u), this.dict[h] = u;
|
|
342
342
|
try {
|
|
343
343
|
this.setValue(h, "type", s.type), this.setValue(h, "stiffness", s.stiffness), this.setValue(h, "damping", s.damping), this.setValue(h, "external", s.external), this.setValue(h, "limits", s.limits), this.setValue(h, "excludes", s.excludes), this.setValue(h, "deltaLocal", s.deltaLocal), this.setValue(h, "deltaWorld", s.deltaWorld), this.setValue(h, "pivot", s.pivot), this.setValue(h, "helper", s.helper);
|
|
344
344
|
} catch (a) {
|
|
@@ -356,22 +356,22 @@ class et {
|
|
|
356
356
|
for (this.timerMs += t, t > 1e3 && (this.timerMs = 0), t /= 1e3, e = 0, i = this.objectsUpdate.length; e < i; e++)
|
|
357
357
|
o = this.objectsUpdate[e], o.updateMatrix(), o.parent === null ? o.matrixWorld.copy(o.matrix) : o.matrixWorld.multiplyMatrices(o.parent.matrixWorld, o.matrix), o.matrixWorldNeedsUpdate = !1;
|
|
358
358
|
for (e = 0, i = this.data.length; e < i; e++) {
|
|
359
|
-
if (o = this.data[e],
|
|
359
|
+
if (o = this.data[e], w.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), w.applyMatrix4(xe), w.length() > 0.5 && (console.info("Info: Unrealistic jump of " + w.length().toFixed(2) + " meters."), w.setLength(0.5)), w.applyQuaternion(o.bone.quaternion), A[0] = w.x, A[1] = w.y, A[2] = -w.z, A[3] = w.length() / 3, o.children)
|
|
360
360
|
for (n = 0, s = o.children.length; n < s; n++)
|
|
361
361
|
m = o.children[n], A[0] -= m.v[0] * t / 3, A[1] -= m.v[1] * t / 3, A[2] += m.v[2] * t / 3, A[3] -= m.v[3] * t / 3;
|
|
362
|
-
if (m = this.opt.sensitivityFactor, A[0] *= o.ext * m, A[1] *= o.ext * m, A[2] *= o.ext * m, A[3] *= o.ext * m, o.isX && (m = A[0] / t, o.ea[0] = (m - o.ev[0]) / t, o.ev[0] = m, o.a[0] = -o.k[0] * o.p[0] - o.c[0] * o.v[0] - o.ea[0], o.p[0] += o.v[0] * t + o.a[0] * t * t / 2 + A[0], m = o.v[0] + o.a[0] * t / 2, m = -o.k[0] * o.p[0] - o.c[0] * m - o.ea[0], o.v[0] = o.v[0] + (m + o.a[0]) * t / 2), o.isY && (m = A[1] / t, o.ea[1] = (m - o.ev[1]) / t, o.ev[1] = m, o.a[1] = -o.k[1] * o.p[1] - o.c[1] * o.v[1] - o.ea[1], o.p[1] += o.v[1] * t + o.a[1] * t * t / 2 + A[1], m = o.v[1] + o.a[1] * t / 2, m = -o.k[1] * o.p[1] - o.c[1] * m - o.ea[1], o.v[1] = o.v[1] + (m + o.a[1]) * t / 2), o.isZ && (m = A[2] / t, o.ea[2] = (m - o.ev[2]) / t, o.ev[2] = m, o.a[2] = -o.k[2] * o.p[2] - o.c[2] * o.v[2] - o.ea[2], o.p[2] += o.v[2] * t + o.a[2] * t * t / 2 + A[2], m = o.v[2] + o.a[2] * t / 2, m = -o.k[2] * o.p[2] - o.c[2] * m - o.ea[2], o.v[2] = o.v[2] + (m + o.a[2]) * t / 2), o.isT && (m = A[3] / t, o.ea[3] = (m - o.ev[3]) / t, o.ev[3] = m, o.a[3] = -o.k[3] * o.p[3] - o.c[3] * o.v[3] - o.ea[3], o.p[3] += o.v[3] * t + o.a[3] * t * t / 2 + A[3], m = o.v[3] + o.a[3] * t / 2, m = -o.k[3] * o.p[3] - o.c[3] * m - o.ea[3], o.v[3] = o.v[3] + (m + o.a[3]) * t / 2), this.timerMs < this.opt.warmupMs && (o.v[0] *= 1e-4, o.p[0] *= 1e-4, o.v[1] *= 1e-4, o.p[1] *= 1e-4, o.v[2] *= 1e-4, o.p[2] *= 1e-4, o.v[3] *= 1e-4, o.p[3] *= 1e-4), A[0] = o.p[0], A[1] = o.p[1], A[2] = o.p[2], A[3] = o.p[3], m = this.opt.movementFactor, A[0] *= m, A[1] *= m, A[2] *= m, A[3] *= m, o.dl && (m = o.dl, A[0] += m[0], A[1] += m[1], A[2] += m[2]), o.dw && (m = o.dw,
|
|
362
|
+
if (m = this.opt.sensitivityFactor, A[0] *= o.ext * m, A[1] *= o.ext * m, A[2] *= o.ext * m, A[3] *= o.ext * m, o.isX && (m = A[0] / t, o.ea[0] = (m - o.ev[0]) / t, o.ev[0] = m, o.a[0] = -o.k[0] * o.p[0] - o.c[0] * o.v[0] - o.ea[0], o.p[0] += o.v[0] * t + o.a[0] * t * t / 2 + A[0], m = o.v[0] + o.a[0] * t / 2, m = -o.k[0] * o.p[0] - o.c[0] * m - o.ea[0], o.v[0] = o.v[0] + (m + o.a[0]) * t / 2), o.isY && (m = A[1] / t, o.ea[1] = (m - o.ev[1]) / t, o.ev[1] = m, o.a[1] = -o.k[1] * o.p[1] - o.c[1] * o.v[1] - o.ea[1], o.p[1] += o.v[1] * t + o.a[1] * t * t / 2 + A[1], m = o.v[1] + o.a[1] * t / 2, m = -o.k[1] * o.p[1] - o.c[1] * m - o.ea[1], o.v[1] = o.v[1] + (m + o.a[1]) * t / 2), o.isZ && (m = A[2] / t, o.ea[2] = (m - o.ev[2]) / t, o.ev[2] = m, o.a[2] = -o.k[2] * o.p[2] - o.c[2] * o.v[2] - o.ea[2], o.p[2] += o.v[2] * t + o.a[2] * t * t / 2 + A[2], m = o.v[2] + o.a[2] * t / 2, m = -o.k[2] * o.p[2] - o.c[2] * m - o.ea[2], o.v[2] = o.v[2] + (m + o.a[2]) * t / 2), o.isT && (m = A[3] / t, o.ea[3] = (m - o.ev[3]) / t, o.ev[3] = m, o.a[3] = -o.k[3] * o.p[3] - o.c[3] * o.v[3] - o.ea[3], o.p[3] += o.v[3] * t + o.a[3] * t * t / 2 + A[3], m = o.v[3] + o.a[3] * t / 2, m = -o.k[3] * o.p[3] - o.c[3] * m - o.ea[3], o.v[3] = o.v[3] + (m + o.a[3]) * t / 2), this.timerMs < this.opt.warmupMs && (o.v[0] *= 1e-4, o.p[0] *= 1e-4, o.v[1] *= 1e-4, o.p[1] *= 1e-4, o.v[2] *= 1e-4, o.p[2] *= 1e-4, o.v[3] *= 1e-4, o.p[3] *= 1e-4), A[0] = o.p[0], A[1] = o.p[1], A[2] = o.p[2], A[3] = o.p[3], m = this.opt.movementFactor, A[0] *= m, A[1] *= m, A[2] *= m, A[3] *= m, o.dl && (m = o.dl, A[0] += m[0], A[1] += m[1], A[2] += m[2]), o.dw && (m = o.dw, w.set(
|
|
363
363
|
o.vBasis.x + A[0],
|
|
364
364
|
o.vBasis.y + A[1],
|
|
365
365
|
o.vBasis.z + A[2]
|
|
366
|
-
),
|
|
366
|
+
), w.applyMatrix4(fe), w.x += m[0], w.y += m[1], w.z += m[2], w.applyMatrix4(xe), A[0] += w.x - o.vBasis.x, A[1] += w.y - o.vBasis.y, A[2] += w.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && A[0] < m[0][0] && (A[0] = m[0][0]), m[0][1] !== null && A[0] > m[0][1] && (A[0] = m[0][1])), m[1] && (m[1][0] !== null && A[1] < m[1][0] && (A[1] = m[1][0]), m[1][1] !== null && A[1] > m[1][1] && (A[1] = m[1][1])), m[2] && (m[2][0] !== null && A[2] < m[2][0] && (A[2] = m[2][0]), m[2][1] !== null && A[2] > m[2][1] && (A[2] = m[2][1])), m[3] && (m[3][0] !== null && A[3] < m[3][0] && (A[3] = m[3][0]), m[3][1] !== null && A[3] > m[3][1] && (A[3] = m[3][1]))), o.isPoint)
|
|
367
367
|
o.bone.position.set(
|
|
368
368
|
o.vBasis.x + A[0],
|
|
369
369
|
o.vBasis.y + A[1],
|
|
370
370
|
o.vBasis.z - A[2]
|
|
371
371
|
);
|
|
372
|
-
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(
|
|
372
|
+
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(w, ie, ne), w.copy(He).applyQuaternion(ie).setY(0).normalize(), ie.premultiply(Ne.setFromUnitVectors(He, w).invert()).normalize(), o.boneParent.quaternion.multiply(ie.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), ie.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(ie)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), ie.setFromAxisAngle(_e, -m), o.boneParent.quaternion.multiply(ie)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), ie.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(ie)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
|
|
373
373
|
for (n = 0, s = o.excludes.length; n < s; n++)
|
|
374
|
-
m = o.excludes[n], ne.set(0, 0, 0), m.deltaLocal && (ne.x += m.deltaLocal[0], ne.y += m.deltaLocal[1], ne.z += m.deltaLocal[2]), ne.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ne.applyMatrix4(xe),
|
|
374
|
+
m = o.excludes[n], ne.set(0, 0, 0), m.deltaLocal && (ne.x += m.deltaLocal[0], ne.y += m.deltaLocal[1], ne.z += m.deltaLocal[2]), ne.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ne.applyMatrix4(xe), w.copy(o.bone.position), !(w.distanceToSquared(ne) >= m.radiusSq) && (ue = w.length(), re = ne.length(), !(re > m.radius + ue) && (re < Math.abs(m.radius - ue) || (re = (re * re + ue * ue - m.radiusSq) / (2 * re), ne.normalize(), Ce.copy(ne).multiplyScalar(re), re = Math.sqrt(ue * ue - re * re), w.subVectors(w, Ce).projectOnPlane(ne).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ne).normalize(), ue = ze.dot(w), ue < 0 && (ue = Math.sqrt(re * re - ue * ue), ze.multiplyScalar(ue), w.add(ze)), w.add(Ce).normalize(), ne.copy(o.bone.position).normalize(), ie.setFromUnitVectors(ne, w), o.boneParent.quaternion.premultiply(ie), o.boneParent.updateWorldMatrix(!1, !0))));
|
|
375
375
|
}
|
|
376
376
|
this.helpers.isActive && this.updateHelpers();
|
|
377
377
|
}
|
|
@@ -445,14 +445,14 @@ class et {
|
|
|
445
445
|
xe.copy(this.armature.matrixWorld).invert();
|
|
446
446
|
const t = m.object.geometry.getAttribute("position");
|
|
447
447
|
for (let e = 0, n = m.bones.length; e < n; e++)
|
|
448
|
-
fe.multiplyMatrices(xe, m.bones[e].matrixWorld),
|
|
448
|
+
fe.multiplyMatrices(xe, m.bones[e].matrixWorld), w.setFromMatrixPosition(fe), t.setXYZ(e, w.x, w.y, w.z);
|
|
449
449
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
450
450
|
}
|
|
451
451
|
if (m = this.helpers.lines, m.bones.length) {
|
|
452
452
|
xe.copy(this.armature.matrixWorld).invert();
|
|
453
453
|
const t = m.object.geometry.getAttribute("position");
|
|
454
454
|
for (let e = 0, n = 0, i = m.bones.length; e < i; e++, n += 2)
|
|
455
|
-
fe.multiplyMatrices(xe, m.bones[e].matrixWorld),
|
|
455
|
+
fe.multiplyMatrices(xe, m.bones[e].matrixWorld), w.setFromMatrixPosition(fe), t.setXYZ(n, w.x, w.y, w.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), w.setFromMatrixPosition(fe), t.setXYZ(n + 1, w.x, w.y, w.z);
|
|
456
456
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
457
457
|
}
|
|
458
458
|
}
|
|
@@ -5253,8 +5253,8 @@ class Be {
|
|
|
5253
5253
|
for (let b = 0; b < y.length; b++) {
|
|
5254
5254
|
const I = b === y.length - 1, V = y[b].match(l);
|
|
5255
5255
|
let p = y[b].match(s);
|
|
5256
|
-
const M = y[b].match(h),
|
|
5257
|
-
if (p && !I && !M && y[b + 1].match(s) && (p = !1), n && (u += y[b]), V && (!i || i.every((f) => b < f[0] || b > f[1])) && (a += y[b]), (
|
|
5256
|
+
const M = y[b].match(h), z = y[b].match(o);
|
|
5257
|
+
if (p && !I && !M && y[b + 1].match(s) && (p = !1), n && (u += y[b]), V && (!i || i.every((f) => b < f[0] || b > f[1])) && (a += y[b]), (z || p || I) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && d.push({
|
|
5258
5258
|
mark: c,
|
|
5259
5259
|
word: a
|
|
5260
5260
|
})), u.length && (g.push({
|
|
@@ -5486,12 +5486,12 @@ class Be {
|
|
|
5486
5486
|
if (b && b.visemes && b.visemes.length > 0) {
|
|
5487
5487
|
const p = b.times[b.visemes.length - 1] + b.durations[b.visemes.length - 1];
|
|
5488
5488
|
for (let M = 0; M < b.visemes.length; M++) {
|
|
5489
|
-
const
|
|
5489
|
+
const z = b.visemes[M], f = b.times[M] / p, E = b.durations[M] / p, P = f * c, U = E * c;
|
|
5490
5490
|
I.push({
|
|
5491
5491
|
template: { name: "viseme" },
|
|
5492
5492
|
ts: [P - Math.min(60, 2 * U / 3), P + Math.min(25, U / 2), P + U + Math.min(60, U / 2)],
|
|
5493
5493
|
vs: {
|
|
5494
|
-
["viseme_" +
|
|
5494
|
+
["viseme_" + z]: [null, z === "PP" || z === "FF" ? 0.9 : 0.6, 0]
|
|
5495
5495
|
}
|
|
5496
5496
|
});
|
|
5497
5497
|
}
|
|
@@ -6193,7 +6193,7 @@ class Be {
|
|
|
6193
6193
|
if (n) {
|
|
6194
6194
|
let M = this.animQueue.findIndex((f) => f.template.name === "lookat");
|
|
6195
6195
|
M !== -1 && this.animQueue.splice(M, 1);
|
|
6196
|
-
const
|
|
6196
|
+
const z = {
|
|
6197
6197
|
name: "lookat",
|
|
6198
6198
|
dt: [750, n],
|
|
6199
6199
|
vs: {
|
|
@@ -6208,7 +6208,7 @@ class Be {
|
|
|
6208
6208
|
headMove: [0]
|
|
6209
6209
|
}
|
|
6210
6210
|
};
|
|
6211
|
-
this.animQueue.push(this.animFactory(
|
|
6211
|
+
this.animQueue.push(this.animFactory(z));
|
|
6212
6212
|
}
|
|
6213
6213
|
}
|
|
6214
6214
|
/**
|
|
@@ -6579,10 +6579,10 @@ class Be {
|
|
|
6579
6579
|
for (let I = 0; I < b; I++) {
|
|
6580
6580
|
let V = !1;
|
|
6581
6581
|
for (let p = 0, M = y.length; p < M; p++) {
|
|
6582
|
-
const
|
|
6583
|
-
|
|
6582
|
+
const z = y[p].bone;
|
|
6583
|
+
z.matrixWorld.decompose(h, r, u), r.invert(), o.setFromMatrixPosition(g.matrixWorld), l.subVectors(o, h), l.applyQuaternion(r), l.normalize(), s.subVectors(e, h), s.applyQuaternion(r), s.normalize();
|
|
6584
6584
|
let f = s.dot(l);
|
|
6585
|
-
f > 1 ? f = 1 : f < -1 && (f = -1), f = Math.acos(f), !(f < 1e-5) && (y[p].minAngle !== void 0 && f < y[p].minAngle && (f = y[p].minAngle), y[p].maxAngle !== void 0 && f > y[p].maxAngle && (f = y[p].maxAngle), a.crossVectors(l, s), a.normalize(), Q.setFromAxisAngle(a, f),
|
|
6585
|
+
f > 1 ? f = 1 : f < -1 && (f = -1), f = Math.acos(f), !(f < 1e-5) && (y[p].minAngle !== void 0 && f < y[p].minAngle && (f = y[p].minAngle), y[p].maxAngle !== void 0 && f > y[p].maxAngle && (f = y[p].maxAngle), a.crossVectors(l, s), a.normalize(), Q.setFromAxisAngle(a, f), z.quaternion.multiply(Q), z.rotation.setFromVector3(c.setFromEuler(z.rotation).clamp(new x.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
|
|
@@ -6590,7 +6590,7 @@ class Be {
|
|
|
6590
6590
|
y[p].maxx !== void 0 ? y[p].maxx : 1 / 0,
|
|
6591
6591
|
y[p].maxy !== void 0 ? y[p].maxy : 1 / 0,
|
|
6592
6592
|
y[p].maxz !== void 0 ? y[p].maxz : 1 / 0
|
|
6593
|
-
))),
|
|
6593
|
+
))), z.updateMatrixWorld(!0), V = !0);
|
|
6594
6594
|
}
|
|
6595
6595
|
if (!V) break;
|
|
6596
6596
|
}
|
|
@@ -6685,7 +6685,7 @@ const Ve = Me(({
|
|
|
6685
6685
|
style: y = {},
|
|
6686
6686
|
animations: b = {}
|
|
6687
6687
|
}, I) => {
|
|
6688
|
-
const V = D(null), p = D(null), M = D(r),
|
|
6688
|
+
const V = D(null), p = D(null), M = D(r), z = D(null), f = D(null), E = D(!1), P = D({ remainingText: null, originalText: null, options: null }), U = D([]), oe = D(0), [S, Z] = ce(!0), [K, X] = ce(null), [$, se] = ce(!1), [ae, pe] = ce(!1);
|
|
6689
6689
|
de(() => {
|
|
6690
6690
|
E.current = ae;
|
|
6691
6691
|
}, [ae]), de(() => {
|
|
@@ -6731,7 +6731,7 @@ const Ve = Me(({
|
|
|
6731
6731
|
ttsService: le,
|
|
6732
6732
|
lipsyncModules: ["en"],
|
|
6733
6733
|
cameraView: u
|
|
6734
|
-
},
|
|
6734
|
+
}, k = T(async () => {
|
|
6735
6735
|
if (!(!V.current || p.current))
|
|
6736
6736
|
try {
|
|
6737
6737
|
if (Z(!0), X(null), p.current = new Be(V.current, R), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), b && Object.keys(b).length > 0 && (p.current.customAnimations = b), await p.current.showAvatar(v, (B) => {
|
|
@@ -6761,9 +6761,9 @@ const Ve = Me(({
|
|
|
6761
6761
|
console.error("Error initializing TalkingHead:", L), X(L.message || "Failed to initialize avatar"), Z(!1), d(L);
|
|
6762
6762
|
}
|
|
6763
6763
|
}, [G, t, e, n, i, s, o, r, l, h, u]);
|
|
6764
|
-
de(() => (
|
|
6764
|
+
de(() => (k(), () => {
|
|
6765
6765
|
p.current && (p.current.stop(), p.current.dispose(), p.current = null);
|
|
6766
|
-
}), [
|
|
6766
|
+
}), [k]), de(() => {
|
|
6767
6767
|
if (!V.current || !p.current) return;
|
|
6768
6768
|
const L = new ResizeObserver((B) => {
|
|
6769
6769
|
for (const J of B)
|
|
@@ -6787,7 +6787,7 @@ const Ve = Me(({
|
|
|
6787
6787
|
}, []), N = T(async (L, F = {}) => {
|
|
6788
6788
|
if (p.current && $)
|
|
6789
6789
|
try {
|
|
6790
|
-
f.current && (clearInterval(f.current), f.current = null),
|
|
6790
|
+
f.current && (clearInterval(f.current), f.current = null), z.current = { text: L, options: F }, P.current = { remainingText: null, originalText: null, options: null };
|
|
6791
6791
|
const B = /[!\.\?\n\p{Extended_Pictographic}]/ug, J = L.split(B).map((Y) => Y.trim()).filter((Y) => Y.length > 0);
|
|
6792
6792
|
U.current = J, oe.current = 0, pe(!1), E.current = !1, await H();
|
|
6793
6793
|
const ge = {
|
|
@@ -6833,24 +6833,24 @@ const Ve = Me(({
|
|
|
6833
6833
|
console.error("Error speaking text:", B), X(B.message || "Failed to speak text");
|
|
6834
6834
|
}
|
|
6835
6835
|
}, [$, H, v.lipsyncLang]), _ = T(() => {
|
|
6836
|
-
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1),
|
|
6836
|
+
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), z.current = null, pe(!1));
|
|
6837
6837
|
}, []), j = T(() => {
|
|
6838
6838
|
if (p.current && p.current.pauseSpeaking) {
|
|
6839
6839
|
const L = p.current;
|
|
6840
6840
|
if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
|
|
6841
6841
|
f.current && (clearInterval(f.current), f.current = null);
|
|
6842
6842
|
let B = "";
|
|
6843
|
-
if (
|
|
6843
|
+
if (z.current && U.current.length > 0) {
|
|
6844
6844
|
const J = U.current.length, ge = L.speechQueue ? L.speechQueue.filter((Ae) => Ae && Ae.text && Array.isArray(Ae.text) && Ae.text.length > 0).length : 0, Y = L.audioPlaylist && L.audioPlaylist.length > 0, he = ge + (Y ? 1 : 0), Se = J - he;
|
|
6845
6845
|
if (he > 0 && Se < J && (B = U.current.slice(Se).join(". ").trim(), !B && ge > 0 && L.speechQueue)) {
|
|
6846
6846
|
const be = L.speechQueue.filter((ye) => ye && ye.text && Array.isArray(ye.text) && ye.text.length > 0).map((ye) => ye.text.map((ke) => ke.word || "").filter((ke) => ke.length > 0).join(" ")).filter((ye) => ye.length > 0).join(" ");
|
|
6847
6847
|
be && be.trim() && (B = be.trim());
|
|
6848
6848
|
}
|
|
6849
6849
|
}
|
|
6850
|
-
|
|
6850
|
+
z.current && (P.current = {
|
|
6851
6851
|
remainingText: B || null,
|
|
6852
|
-
originalText:
|
|
6853
|
-
options:
|
|
6852
|
+
originalText: z.current.text,
|
|
6853
|
+
options: z.current.options
|
|
6854
6854
|
}), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), E.current = !0, pe(!0);
|
|
6855
6855
|
}
|
|
6856
6856
|
}
|
|
@@ -6860,8 +6860,8 @@ const Ve = Me(({
|
|
|
6860
6860
|
let L = "", F = {};
|
|
6861
6861
|
if (P.current && P.current.remainingText)
|
|
6862
6862
|
L = P.current.remainingText, F = P.current.options || {}, P.current = { remainingText: null, originalText: null, options: null };
|
|
6863
|
-
else if (
|
|
6864
|
-
L =
|
|
6863
|
+
else if (z.current && z.current.text)
|
|
6864
|
+
L = z.current.text, F = z.current.options || {};
|
|
6865
6865
|
else {
|
|
6866
6866
|
console.warn("Resume called but no paused speech found"), pe(!1), E.current = !1;
|
|
6867
6867
|
return;
|
|
@@ -7082,7 +7082,7 @@ const pt = Me(({
|
|
|
7082
7082
|
ttsService: I,
|
|
7083
7083
|
lipsyncModules: ["en"],
|
|
7084
7084
|
cameraView: "upper"
|
|
7085
|
-
},
|
|
7085
|
+
}, z = T(async () => {
|
|
7086
7086
|
if (!(!h.current || r.current))
|
|
7087
7087
|
try {
|
|
7088
7088
|
if (a(!0), d(null), r.current = new Be(h.current, M), await r.current.showAvatar(p, (K) => {
|
|
@@ -7118,9 +7118,9 @@ const pt = Me(({
|
|
|
7118
7118
|
console.error("Error initializing TalkingHead:", S), d(S.message || "Failed to initialize avatar"), a(!1), e(S);
|
|
7119
7119
|
}
|
|
7120
7120
|
}, []);
|
|
7121
|
-
de(() => (
|
|
7121
|
+
de(() => (z(), () => {
|
|
7122
7122
|
r.current && (r.current.stop(), r.current.dispose(), r.current = null);
|
|
7123
|
-
}), [
|
|
7123
|
+
}), [z]);
|
|
7124
7124
|
const f = T((S) => {
|
|
7125
7125
|
if (r.current && g)
|
|
7126
7126
|
try {
|
|
@@ -7307,7 +7307,7 @@ const gt = Me(({
|
|
|
7307
7307
|
animations: V = {},
|
|
7308
7308
|
autoSpeak: p = !1
|
|
7309
7309
|
}, M) => {
|
|
7310
|
-
const
|
|
7310
|
+
const z = D(null), f = D(null), E = D(u), P = D(null), U = D(null), oe = D(!1), S = D({ remainingText: null, originalText: null, options: null }), Z = D([]), [K, X] = ce(!0), [$, se] = ce(null), [ae, pe] = ce(!1), [ee, le] = ce(!1);
|
|
7311
7311
|
de(() => {
|
|
7312
7312
|
oe.current = ee;
|
|
7313
7313
|
}, [ee]), de(() => {
|
|
@@ -7336,7 +7336,7 @@ const gt = Me(({
|
|
|
7336
7336
|
...O,
|
|
7337
7337
|
apiKey: l !== null ? l : O.apiKey
|
|
7338
7338
|
};
|
|
7339
|
-
const
|
|
7339
|
+
const k = {
|
|
7340
7340
|
url: t,
|
|
7341
7341
|
body: e,
|
|
7342
7342
|
avatarMood: n,
|
|
@@ -7353,14 +7353,18 @@ const gt = Me(({
|
|
|
7353
7353
|
lipsyncModules: ["en"],
|
|
7354
7354
|
cameraView: a
|
|
7355
7355
|
}, N = T(async () => {
|
|
7356
|
-
if (!(!
|
|
7356
|
+
if (!(!z.current || f.current))
|
|
7357
7357
|
try {
|
|
7358
|
-
X(!0), se(null), f.current = new Be(
|
|
7358
|
+
X(!0), se(null), f.current = new Be(z.current, H), console.log("Avatar config being passed:", {
|
|
7359
|
+
url: k.url,
|
|
7360
|
+
body: k.body,
|
|
7361
|
+
avatarMood: k.avatarMood
|
|
7362
|
+
}), await f.current.showAvatar(k, (te) => {
|
|
7359
7363
|
if (te.lengthComputable) {
|
|
7360
7364
|
const L = Math.min(100, Math.round(te.loaded / te.total * 100));
|
|
7361
7365
|
d(L);
|
|
7362
7366
|
}
|
|
7363
|
-
}), X(!1), pe(!0), c(f.current);
|
|
7367
|
+
}), f.current?.avatar && console.log("Avatar body after initialization:", f.current.avatar.body), X(!1), pe(!0), c(f.current);
|
|
7364
7368
|
const C = () => {
|
|
7365
7369
|
document.visibilityState === "visible" ? f.current?.start() : f.current?.stop();
|
|
7366
7370
|
};
|
|
@@ -7462,7 +7466,7 @@ const gt = Me(({
|
|
|
7462
7466
|
/* @__PURE__ */ me(
|
|
7463
7467
|
"div",
|
|
7464
7468
|
{
|
|
7465
|
-
ref:
|
|
7469
|
+
ref: z,
|
|
7466
7470
|
className: "talking-head-viewer",
|
|
7467
7471
|
style: {
|
|
7468
7472
|
width: "100%",
|
|
@@ -7532,7 +7536,7 @@ const yt = Me(({
|
|
|
7532
7536
|
description: "No curriculum data provided",
|
|
7533
7537
|
language: "en",
|
|
7534
7538
|
modules: []
|
|
7535
|
-
}),
|
|
7539
|
+
}), z = D({
|
|
7536
7540
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7537
7541
|
avatarBody: t.avatarBody || "F",
|
|
7538
7542
|
mood: t.mood || "happy",
|
|
@@ -7560,7 +7564,7 @@ const yt = Me(({
|
|
|
7560
7564
|
description: "No curriculum data provided",
|
|
7561
7565
|
language: "en",
|
|
7562
7566
|
modules: []
|
|
7563
|
-
},
|
|
7567
|
+
}, z.current = {
|
|
7564
7568
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7565
7569
|
avatarBody: t.avatarBody || "F",
|
|
7566
7570
|
mood: t.mood || "happy",
|
|
@@ -7599,7 +7603,7 @@ const yt = Me(({
|
|
|
7599
7603
|
} catch {
|
|
7600
7604
|
u.current.playCelebration();
|
|
7601
7605
|
}
|
|
7602
|
-
const
|
|
7606
|
+
const k = M.current || { modules: [] }, H = k.modules[a.current.currentModuleIndex], N = a.current.currentLessonIndex < (H?.lessons?.length || 0) - 1, _ = a.current.currentModuleIndex < (k.modules?.length || 0) - 1, j = N || _, q = z.current || { lipsyncLang: "en" };
|
|
7603
7607
|
u.current.speakText(R, {
|
|
7604
7608
|
lipsyncLang: q.lipsyncLang,
|
|
7605
7609
|
onSpeechEnd: () => {
|
|
@@ -7620,7 +7624,7 @@ const yt = Me(({
|
|
|
7620
7624
|
const v = M.current || { modules: [] };
|
|
7621
7625
|
if (c.current.onCurriculumComplete({
|
|
7622
7626
|
modules: v.modules.length,
|
|
7623
|
-
totalLessons: v.modules.reduce((R,
|
|
7627
|
+
totalLessons: v.modules.reduce((R, k) => R + k.lessons.length, 0)
|
|
7624
7628
|
}), u.current) {
|
|
7625
7629
|
if (u.current.setMood("celebrating"), e.curriculumComplete)
|
|
7626
7630
|
try {
|
|
@@ -7628,7 +7632,7 @@ const yt = Me(({
|
|
|
7628
7632
|
} catch {
|
|
7629
7633
|
u.current.playCelebration();
|
|
7630
7634
|
}
|
|
7631
|
-
const R =
|
|
7635
|
+
const R = z.current || { lipsyncLang: "en" };
|
|
7632
7636
|
u.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 });
|
|
7633
7637
|
}
|
|
7634
7638
|
}, [e.curriculumComplete]), S = T(() => {
|
|
@@ -7644,7 +7648,7 @@ const yt = Me(({
|
|
|
7644
7648
|
question: R,
|
|
7645
7649
|
score: a.current.score
|
|
7646
7650
|
});
|
|
7647
|
-
const
|
|
7651
|
+
const k = () => {
|
|
7648
7652
|
if (!u.current || !R) return;
|
|
7649
7653
|
if (u.current.setMood("happy"), e.questionStart)
|
|
7650
7654
|
try {
|
|
@@ -7652,17 +7656,17 @@ const yt = Me(({
|
|
|
7652
7656
|
} catch (N) {
|
|
7653
7657
|
console.warn("Failed to play questionStart animation:", N);
|
|
7654
7658
|
}
|
|
7655
|
-
const H =
|
|
7659
|
+
const H = z.current || { lipsyncLang: "en" };
|
|
7656
7660
|
R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: H.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: H.lipsyncLang });
|
|
7657
7661
|
};
|
|
7658
7662
|
if (u.current && u.current.isReady && R)
|
|
7659
|
-
|
|
7663
|
+
k();
|
|
7660
7664
|
else if (u.current && u.current.isReady) {
|
|
7661
|
-
const H =
|
|
7665
|
+
const H = z.current || { lipsyncLang: "en" };
|
|
7662
7666
|
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: H.lipsyncLang });
|
|
7663
7667
|
} else {
|
|
7664
7668
|
const H = setInterval(() => {
|
|
7665
|
-
u.current && u.current.isReady && (clearInterval(H), R &&
|
|
7669
|
+
u.current && u.current.isReady && (clearInterval(H), R && k());
|
|
7666
7670
|
}, 100);
|
|
7667
7671
|
setTimeout(() => {
|
|
7668
7672
|
clearInterval(H);
|
|
@@ -7682,7 +7686,7 @@ const yt = Me(({
|
|
|
7682
7686
|
question: R,
|
|
7683
7687
|
score: a.current.score
|
|
7684
7688
|
});
|
|
7685
|
-
const
|
|
7689
|
+
const k = () => {
|
|
7686
7690
|
if (!u.current || !R) return;
|
|
7687
7691
|
if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7688
7692
|
try {
|
|
@@ -7690,7 +7694,7 @@ const yt = Me(({
|
|
|
7690
7694
|
} catch (q) {
|
|
7691
7695
|
console.warn("Failed to play nextQuestion animation:", q);
|
|
7692
7696
|
}
|
|
7693
|
-
const H =
|
|
7697
|
+
const H = z.current || { lipsyncLang: "en" }, _ = f()?.questions?.length || 0, j = a.current.currentQuestionIndex >= _ - 1;
|
|
7694
7698
|
if (R.type === "code_test") {
|
|
7695
7699
|
const q = j ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
|
|
7696
7700
|
u.current.speakText(q, {
|
|
@@ -7714,10 +7718,10 @@ const yt = Me(({
|
|
|
7714
7718
|
}
|
|
7715
7719
|
};
|
|
7716
7720
|
if (u.current && u.current.isReady && R)
|
|
7717
|
-
|
|
7721
|
+
k();
|
|
7718
7722
|
else if (R) {
|
|
7719
7723
|
const H = setInterval(() => {
|
|
7720
|
-
u.current && u.current.isReady && (clearInterval(H),
|
|
7724
|
+
u.current && u.current.isReady && (clearInterval(H), k());
|
|
7721
7725
|
}, 100);
|
|
7722
7726
|
setTimeout(() => {
|
|
7723
7727
|
clearInterval(H);
|
|
@@ -7765,21 +7769,21 @@ const yt = Me(({
|
|
|
7765
7769
|
const v = f();
|
|
7766
7770
|
let R = null;
|
|
7767
7771
|
if (v?.avatar_script && v?.body) {
|
|
7768
|
-
const
|
|
7769
|
-
R = `${
|
|
7772
|
+
const k = v.avatar_script.trim(), H = v.body.trim(), N = k.match(/[.!?]$/) ? " " : ". ";
|
|
7773
|
+
R = `${k}${N}${H}`;
|
|
7770
7774
|
} else
|
|
7771
7775
|
R = v?.avatar_script || v?.body || null;
|
|
7772
7776
|
if (u.current && u.current.isReady && R) {
|
|
7773
7777
|
a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, u.current.setMood("happy");
|
|
7774
|
-
let
|
|
7778
|
+
let k = !1;
|
|
7775
7779
|
if (e.teaching)
|
|
7776
7780
|
try {
|
|
7777
|
-
u.current.playAnimation(e.teaching, !0),
|
|
7781
|
+
u.current.playAnimation(e.teaching, !0), k = !0;
|
|
7778
7782
|
} catch (N) {
|
|
7779
7783
|
console.warn("Failed to play teaching animation:", N);
|
|
7780
7784
|
}
|
|
7781
|
-
|
|
7782
|
-
const H =
|
|
7785
|
+
k || u.current.setBodyMovement("gesturing");
|
|
7786
|
+
const H = z.current || { lipsyncLang: "en" };
|
|
7783
7787
|
c.current.onLessonStart({
|
|
7784
7788
|
moduleIndex: a.current.currentModuleIndex,
|
|
7785
7789
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7809,16 +7813,16 @@ const yt = Me(({
|
|
|
7809
7813
|
});
|
|
7810
7814
|
}
|
|
7811
7815
|
}, [e.teaching, f]), $ = T((v) => {
|
|
7812
|
-
const R = E(),
|
|
7813
|
-
if (
|
|
7816
|
+
const R = E(), k = P(v, R);
|
|
7817
|
+
if (k && (a.current.score += 1), c.current.onQuestionAnswer({
|
|
7814
7818
|
moduleIndex: a.current.currentModuleIndex,
|
|
7815
7819
|
lessonIndex: a.current.currentLessonIndex,
|
|
7816
7820
|
questionIndex: a.current.currentQuestionIndex,
|
|
7817
7821
|
answer: v,
|
|
7818
|
-
isCorrect:
|
|
7822
|
+
isCorrect: k,
|
|
7819
7823
|
question: R
|
|
7820
7824
|
}), u.current)
|
|
7821
|
-
if (
|
|
7825
|
+
if (k) {
|
|
7822
7826
|
if (u.current.setMood("happy"), e.correct)
|
|
7823
7827
|
try {
|
|
7824
7828
|
u.current.playReaction("happy");
|
|
@@ -7830,7 +7834,7 @@ const yt = Me(({
|
|
|
7830
7834
|
a.current.currentQuestionIndex >= N - 1;
|
|
7831
7835
|
const _ = a.current.currentQuestionIndex < N - 1;
|
|
7832
7836
|
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", _);
|
|
7833
|
-
const j = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, q =
|
|
7837
|
+
const j = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, q = z.current || { lipsyncLang: "en" };
|
|
7834
7838
|
u.current.speakText(j, {
|
|
7835
7839
|
lipsyncLang: q.lipsyncLang,
|
|
7836
7840
|
onSpeechEnd: () => {
|
|
@@ -7856,7 +7860,7 @@ const yt = Me(({
|
|
|
7856
7860
|
u.current.setBodyMovement("gesturing");
|
|
7857
7861
|
const N = f()?.questions?.length || 0, _ = a.current.currentQuestionIndex >= N - 1, j = a.current.currentQuestionIndex < N - 1;
|
|
7858
7862
|
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", N, "hasNextQuestion:", j);
|
|
7859
|
-
const q = 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."}`, Le =
|
|
7863
|
+
const q = 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."}`, Le = z.current || { lipsyncLang: "en" };
|
|
7860
7864
|
u.current.speakText(q, {
|
|
7861
7865
|
lipsyncLang: Le.lipsyncLang,
|
|
7862
7866
|
onSpeechEnd: () => {
|
|
@@ -7880,7 +7884,7 @@ const yt = Me(({
|
|
|
7880
7884
|
moduleIndex: a.current.currentModuleIndex,
|
|
7881
7885
|
lessonIndex: a.current.currentLessonIndex,
|
|
7882
7886
|
questionIndex: a.current.currentQuestionIndex,
|
|
7883
|
-
isCorrect:
|
|
7887
|
+
isCorrect: k,
|
|
7884
7888
|
hasNextQuestion: a.current.currentQuestionIndex < N - 1,
|
|
7885
7889
|
score: a.current.score,
|
|
7886
7890
|
totalQuestions: a.current.totalQuestions,
|
|
@@ -7897,7 +7901,7 @@ const yt = Me(({
|
|
|
7897
7901
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
7898
7902
|
return;
|
|
7899
7903
|
}
|
|
7900
|
-
const
|
|
7904
|
+
const k = {
|
|
7901
7905
|
passed: v.passed === !0,
|
|
7902
7906
|
results: v.results || [],
|
|
7903
7907
|
output: v.output || "",
|
|
@@ -7912,9 +7916,9 @@ const yt = Me(({
|
|
|
7912
7916
|
moduleIndex: a.current.currentModuleIndex,
|
|
7913
7917
|
lessonIndex: a.current.currentLessonIndex,
|
|
7914
7918
|
questionIndex: a.current.currentQuestionIndex,
|
|
7915
|
-
testResult:
|
|
7919
|
+
testResult: k,
|
|
7916
7920
|
question: R
|
|
7917
|
-
}), p.current && p.current(
|
|
7921
|
+
}), p.current && p.current(k);
|
|
7918
7922
|
}, [E, P]), ae = T(() => {
|
|
7919
7923
|
if (a.current.currentQuestionIndex > 0) {
|
|
7920
7924
|
a.current.currentQuestionIndex -= 1;
|
|
@@ -7931,21 +7935,21 @@ const yt = Me(({
|
|
|
7931
7935
|
const R = () => {
|
|
7932
7936
|
if (!u.current || !v) return;
|
|
7933
7937
|
u.current.setMood("happy"), u.current.setBodyMovement("idle");
|
|
7934
|
-
const
|
|
7938
|
+
const k = z.current || { lipsyncLang: "en" };
|
|
7935
7939
|
v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
|
|
7936
|
-
lipsyncLang:
|
|
7940
|
+
lipsyncLang: k.lipsyncLang
|
|
7937
7941
|
}) : u.current.speakText(`Going back to: ${v.question}`, {
|
|
7938
|
-
lipsyncLang:
|
|
7942
|
+
lipsyncLang: k.lipsyncLang
|
|
7939
7943
|
});
|
|
7940
7944
|
};
|
|
7941
7945
|
if (u.current && u.current.isReady && v)
|
|
7942
7946
|
R();
|
|
7943
7947
|
else if (v) {
|
|
7944
|
-
const
|
|
7945
|
-
u.current && u.current.isReady && (clearInterval(
|
|
7948
|
+
const k = setInterval(() => {
|
|
7949
|
+
u.current && u.current.isReady && (clearInterval(k), R());
|
|
7946
7950
|
}, 100);
|
|
7947
7951
|
setTimeout(() => {
|
|
7948
|
-
clearInterval(
|
|
7952
|
+
clearInterval(k);
|
|
7949
7953
|
}, 5e3);
|
|
7950
7954
|
}
|
|
7951
7955
|
}
|
|
@@ -7977,8 +7981,8 @@ const yt = Me(({
|
|
|
7977
7981
|
a.current.currentModuleIndex = 0, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.isTeaching = !1, a.current.isQuestionMode = !1, a.current.lessonCompleted = !1, a.current.curriculumCompleted = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
7978
7982
|
}, []), le = T((v) => {
|
|
7979
7983
|
console.log("Avatar is ready!", v);
|
|
7980
|
-
const R = f(),
|
|
7981
|
-
h &&
|
|
7984
|
+
const R = f(), k = R?.avatar_script || R?.body;
|
|
7985
|
+
h && k && setTimeout(() => {
|
|
7982
7986
|
d.current && d.current();
|
|
7983
7987
|
}, 10);
|
|
7984
7988
|
}, [h, f]);
|
|
@@ -8005,8 +8009,8 @@ const yt = Me(({
|
|
|
8005
8009
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8006
8010
|
speakText: async (v, R = {}) => {
|
|
8007
8011
|
await u.current?.resumeAudioContext?.();
|
|
8008
|
-
const
|
|
8009
|
-
u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang ||
|
|
8012
|
+
const k = z.current || { lipsyncLang: "en" };
|
|
8013
|
+
u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || k.lipsyncLang });
|
|
8010
8014
|
},
|
|
8011
8015
|
resumeAudioContext: async () => {
|
|
8012
8016
|
if (u.current?.resumeAudioContext)
|
|
@@ -8017,8 +8021,8 @@ const yt = Me(({
|
|
|
8017
8021
|
if (R.state === "suspended" || R.state === "interrupted")
|
|
8018
8022
|
try {
|
|
8019
8023
|
await R.resume(), console.log("Audio context resumed via talkingHead");
|
|
8020
|
-
} catch (
|
|
8021
|
-
console.warn("Failed to resume audio context:",
|
|
8024
|
+
} catch (k) {
|
|
8025
|
+
console.warn("Failed to resume audio context:", k);
|
|
8022
8026
|
}
|
|
8023
8027
|
} else
|
|
8024
8028
|
console.warn("Audio context not available yet");
|
|
@@ -8051,7 +8055,7 @@ const yt = Me(({
|
|
|
8051
8055
|
// Avatar readiness check (always returns current value)
|
|
8052
8056
|
isAvatarReady: () => u.current?.isReady || !1
|
|
8053
8057
|
}), [X, S, $, se, Z, K, U, oe, ee, E, f]);
|
|
8054
|
-
const O =
|
|
8058
|
+
const O = z.current || {
|
|
8055
8059
|
avatarUrl: "/avatars/brunette.glb",
|
|
8056
8060
|
avatarBody: "F",
|
|
8057
8061
|
mood: "happy",
|
package/package.json
CHANGED
|
@@ -146,6 +146,13 @@ const SimpleTalkingAvatar = forwardRef(({
|
|
|
146
146
|
|
|
147
147
|
talkingHeadRef.current = new TalkingHead(containerRef.current, defaultOptions);
|
|
148
148
|
|
|
149
|
+
// Debug: Log avatar config to verify body type is passed
|
|
150
|
+
console.log('Avatar config being passed:', {
|
|
151
|
+
url: defaultAvatarConfig.url,
|
|
152
|
+
body: defaultAvatarConfig.body,
|
|
153
|
+
avatarMood: defaultAvatarConfig.avatarMood
|
|
154
|
+
});
|
|
155
|
+
|
|
149
156
|
await talkingHeadRef.current.showAvatar(defaultAvatarConfig, (ev) => {
|
|
150
157
|
if (ev.lengthComputable) {
|
|
151
158
|
const progress = Math.min(100, Math.round(ev.loaded / ev.total * 100));
|
|
@@ -153,6 +160,11 @@ const SimpleTalkingAvatar = forwardRef(({
|
|
|
153
160
|
}
|
|
154
161
|
});
|
|
155
162
|
|
|
163
|
+
// Debug: Verify avatar body was set correctly
|
|
164
|
+
if (talkingHeadRef.current?.avatar) {
|
|
165
|
+
console.log('Avatar body after initialization:', talkingHeadRef.current.avatar.body);
|
|
166
|
+
}
|
|
167
|
+
|
|
156
168
|
setIsLoading(false);
|
|
157
169
|
setIsReady(true);
|
|
158
170
|
onReady(talkingHeadRef.current);
|