@sage-rsc/talking-head-react 1.2.1 → 1.2.2
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 +476 -490
- package/package.json +1 -1
- package/src/lib/talkinghead.mjs +3 -52
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { jsxs as Pe, jsx as
|
|
2
|
-
import { forwardRef as Me, useRef as
|
|
1
|
+
import { jsxs as Pe, jsx as me } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as Me, useRef as O, useState as ce, useEffect as de, useCallback as B, useImperativeHandle as Fe, useLayoutEffect as Xe } from "react";
|
|
3
3
|
import * as f from "three";
|
|
4
4
|
import { OrbitControls as Ye } from "three/addons/controls/OrbitControls.js";
|
|
5
5
|
import { GLTFLoader as je } from "three/addons/loaders/GLTFLoader.js";
|
|
@@ -7,12 +7,12 @@ import { DRACOLoader as Qe } from "three/addons/loaders/DRACOLoader.js";
|
|
|
7
7
|
import { FBXLoader as De } from "three/addons/loaders/FBXLoader.js";
|
|
8
8
|
import { RoomEnvironment as qe } from "three/addons/environments/RoomEnvironment.js";
|
|
9
9
|
import _e from "three/addons/libs/stats.module.js";
|
|
10
|
-
let m,
|
|
11
|
-
const w = [0, 0, 0, 0],
|
|
10
|
+
let m, re, ue;
|
|
11
|
+
const w = [0, 0, 0, 0], T = new f.Vector3(), ze = new f.Vector3(), ie = new f.Vector3(), Ce = new f.Vector3();
|
|
12
12
|
new f.Plane();
|
|
13
13
|
new f.Ray();
|
|
14
14
|
new f.Euler();
|
|
15
|
-
const
|
|
15
|
+
const oe = new f.Quaternion(), Oe = new f.Quaternion(), fe = new f.Matrix4(), xe = new f.Matrix4();
|
|
16
16
|
new f.Vector3();
|
|
17
17
|
const He = new f.Vector3(0, 0, 1), Ke = new f.Vector3(1, 0, 0), Je = new f.Vector3(0, 1, 0), $e = new f.Vector3(0, 0, 1);
|
|
18
18
|
class et {
|
|
@@ -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(T).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(T, oe, ie), T.copy(He).applyQuaternion(oe).setY(0).normalize(), oe.premultiply(Oe.setFromUnitVectors(He, T).invert()).normalize(), u.qWorldInverseYaw = oe.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], T.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), T.applyMatrix4(xe), T.length() > 0.5 && (console.info("Info: Unrealistic jump of " + T.length().toFixed(2) + " meters."), T.setLength(0.5)), T.applyQuaternion(o.bone.quaternion), w[0] = T.x, w[1] = T.y, w[2] = -T.z, w[3] = T.length() / 3, o.children)
|
|
360
360
|
for (n = 0, s = o.children.length; n < s; n++)
|
|
361
361
|
m = o.children[n], w[0] -= m.v[0] * t / 3, w[1] -= m.v[1] * t / 3, w[2] += m.v[2] * t / 3, w[3] -= m.v[3] * t / 3;
|
|
362
|
-
if (m = this.opt.sensitivityFactor, w[0] *= o.ext * m, w[1] *= o.ext * m, w[2] *= o.ext * m, w[3] *= o.ext * m, o.isX && (m = w[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 + w[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 = w[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 + w[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 = w[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 + w[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 = w[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 + w[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), w[0] = o.p[0], w[1] = o.p[1], w[2] = o.p[2], w[3] = o.p[3], m = this.opt.movementFactor, w[0] *= m, w[1] *= m, w[2] *= m, w[3] *= m, o.dl && (m = o.dl, w[0] += m[0], w[1] += m[1], w[2] += m[2]), o.dw && (m = o.dw,
|
|
362
|
+
if (m = this.opt.sensitivityFactor, w[0] *= o.ext * m, w[1] *= o.ext * m, w[2] *= o.ext * m, w[3] *= o.ext * m, o.isX && (m = w[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 + w[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 = w[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 + w[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 = w[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 + w[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 = w[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 + w[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), w[0] = o.p[0], w[1] = o.p[1], w[2] = o.p[2], w[3] = o.p[3], m = this.opt.movementFactor, w[0] *= m, w[1] *= m, w[2] *= m, w[3] *= m, o.dl && (m = o.dl, w[0] += m[0], w[1] += m[1], w[2] += m[2]), o.dw && (m = o.dw, T.set(
|
|
363
363
|
o.vBasis.x + w[0],
|
|
364
364
|
o.vBasis.y + w[1],
|
|
365
365
|
o.vBasis.z + w[2]
|
|
366
|
-
),
|
|
366
|
+
), T.applyMatrix4(fe), T.x += m[0], T.y += m[1], T.z += m[2], T.applyMatrix4(xe), w[0] += T.x - o.vBasis.x, w[1] += T.y - o.vBasis.y, w[2] += T.z - o.vBasis.z), o.limits && this.opt.isLimits && (m = o.limits, m[0] && (m[0][0] !== null && w[0] < m[0][0] && (w[0] = m[0][0]), m[0][1] !== null && w[0] > m[0][1] && (w[0] = m[0][1])), m[1] && (m[1][0] !== null && w[1] < m[1][0] && (w[1] = m[1][0]), m[1][1] !== null && w[1] > m[1][1] && (w[1] = m[1][1])), m[2] && (m[2][0] !== null && w[2] < m[2][0] && (w[2] = m[2][0]), m[2][1] !== null && w[2] > m[2][1] && (w[2] = m[2][1])), m[3] && (m[3][0] !== null && w[3] < m[3][0] && (w[3] = m[3][0]), m[3][1] !== null && w[3] > m[3][1] && (w[3] = m[3][1]))), o.isPoint)
|
|
367
367
|
o.bone.position.set(
|
|
368
368
|
o.vBasis.x + w[0],
|
|
369
369
|
o.vBasis.y + w[1],
|
|
370
370
|
o.vBasis.z - w[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(T, oe, ie), T.copy(He).applyQuaternion(oe).setY(0).normalize(), oe.premultiply(Oe.setFromUnitVectors(He, T).invert()).normalize(), o.boneParent.quaternion.multiply(oe.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(w[0] / o.l), oe.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(oe)), o.isY && (m = o.l / 3, m = m * Math.tanh(w[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(w[2] / o.l), oe.setFromAxisAngle(Ke, -m), o.boneParent.quaternion.multiply(oe)), o.isT && (m = 1.5 * Math.tanh(w[3] * 1.5), oe.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(oe)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
|
|
373
373
|
for (n = 0, s = o.excludes.length; n < s; n++)
|
|
374
|
-
m = o.excludes[n],
|
|
374
|
+
m = o.excludes[n], ie.set(0, 0, 0), m.deltaLocal && (ie.x += m.deltaLocal[0], ie.y += m.deltaLocal[1], ie.z += m.deltaLocal[2]), ie.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ie.applyMatrix4(xe), T.copy(o.bone.position), !(T.distanceToSquared(ie) >= m.radiusSq) && (ue = T.length(), re = ie.length(), !(re > m.radius + ue) && (re < Math.abs(m.radius - ue) || (re = (re * re + ue * ue - m.radiusSq) / (2 * re), ie.normalize(), Ce.copy(ie).multiplyScalar(re), re = Math.sqrt(ue * ue - re * re), T.subVectors(T, Ce).projectOnPlane(ie).normalize().multiplyScalar(re), ze.subVectors(o.vBasis, Ce).projectOnPlane(ie).normalize(), ue = ze.dot(T), ue < 0 && (ue = Math.sqrt(re * re - ue * ue), ze.multiplyScalar(ue), T.add(ze)), T.add(Ce).normalize(), ie.copy(o.bone.position).normalize(), oe.setFromUnitVectors(ie, T), o.boneParent.quaternion.premultiply(oe), 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), T.setFromMatrixPosition(fe), t.setXYZ(e, T.x, T.y, T.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), T.setFromMatrixPosition(fe), t.setXYZ(n, T.x, T.y, T.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), T.setFromMatrixPosition(fe), t.setXYZ(n + 1, T.x, T.y, T.z);
|
|
456
456
|
t.needsUpdate = !0, m.object.updateMatrixWorld();
|
|
457
457
|
}
|
|
458
458
|
}
|
|
@@ -2629,7 +2629,7 @@ const ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
|
2629
2629
|
fr: rt,
|
|
2630
2630
|
fi: ut,
|
|
2631
2631
|
lt: ct
|
|
2632
|
-
},
|
|
2632
|
+
}, _ = new f.Quaternion(), Z = new f.Euler(), ve = new f.Vector3(), Re = new f.Vector3(), We = new f.Box3();
|
|
2633
2633
|
new f.Matrix4();
|
|
2634
2634
|
new f.Matrix4();
|
|
2635
2635
|
new f.Vector3();
|
|
@@ -4400,7 +4400,7 @@ class Be {
|
|
|
4400
4400
|
if (e.x === 0 && e.y === 0 && e.z === 0) continue;
|
|
4401
4401
|
Z.set(e.x, e.y, e.z);
|
|
4402
4402
|
const n = this.poseAvatar.props[t];
|
|
4403
|
-
n.isQuaternion ? (
|
|
4403
|
+
n.isQuaternion ? (_.setFromEuler(Z), n.multiply(_)) : n.isVector3 && n.add(Z);
|
|
4404
4404
|
}
|
|
4405
4405
|
}
|
|
4406
4406
|
/**
|
|
@@ -5193,7 +5193,7 @@ class Be {
|
|
|
5193
5193
|
eyeLookOutRight: [null, 0],
|
|
5194
5194
|
eyeContact: [0]
|
|
5195
5195
|
}
|
|
5196
|
-
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (
|
|
5196
|
+
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (n = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], i = this.mtAvatar[n], i.needsUpdate || Object.assign(i, { base: (this.mood.baseline[n] || 0) + (1 + l / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? l > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = l) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), n = this.volumeHeadTarget - this.volumeHeadCurrent, i = Math.abs(n), i > 1e-4 && (o = i * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / i) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(n) * Math.min(i, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (_.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(_)), We.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ve), ve.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(Re), Re.sub(this.armature.position), this.objectHips.position.y -= We.min.y / 2, this.objectHips.position.x -= (ve.x + Re.x) / 4, this.objectHips.position.z -= (ve.z + Re.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
|
|
5197
5197
|
this.stats && this.stats.end();
|
|
5198
5198
|
else {
|
|
5199
5199
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
@@ -5264,10 +5264,10 @@ class Be {
|
|
|
5264
5264
|
let u = "", a = "", d = 0, c = [], g = [];
|
|
5265
5265
|
const b = Array.from(this.segmenter.segment(t), (x) => x.segment);
|
|
5266
5266
|
for (let x = 0; x < b.length; x++) {
|
|
5267
|
-
const S = x === b.length - 1,
|
|
5267
|
+
const S = x === b.length - 1, U = b[x].match(l);
|
|
5268
5268
|
let p = b[x].match(s);
|
|
5269
|
-
const
|
|
5270
|
-
if (p && !S && !
|
|
5269
|
+
const F = b[x].match(h), C = b[x].match(o);
|
|
5270
|
+
if (p && !S && !F && b[x + 1].match(s) && (p = !1), n && (u += b[x]), U && (!i || i.every((y) => x < y[0] || x > y[1])) && (a += b[x]), (C || p || S) && (a.length && (a = this.lipsyncPreProcessText(a, r), a.length && c.push({
|
|
5271
5271
|
mark: d,
|
|
5272
5272
|
word: a
|
|
5273
5273
|
})), u.length && (g.push({
|
|
@@ -5300,7 +5300,7 @@ class Be {
|
|
|
5300
5300
|
};
|
|
5301
5301
|
n && (y.onSubtitles = n), c.length && !e.avatarMute && (y.text = c, e.avatarMood && (y.mood = e.avatarMood), e.ttsLang && (y.lang = e.ttsLang), e.ttsVoice && (y.voice = e.ttsVoice), e.ttsRate && (y.rate = e.ttsRate), e.ttsVoice && (y.pitch = e.ttsPitch), e.ttsVolume && (y.volume = e.ttsVolume)), this.speechQueue.push(y), c = [], a = "", d = 0, g = [];
|
|
5302
5302
|
}
|
|
5303
|
-
if (
|
|
5303
|
+
if (F) {
|
|
5304
5304
|
let y = this.animEmojis[b[x]];
|
|
5305
5305
|
y && y.link && (y = this.animEmojis[y.link]), y && this.speechQueue.push({ emoji: y });
|
|
5306
5306
|
}
|
|
@@ -5398,10 +5398,10 @@ class Be {
|
|
|
5398
5398
|
let b = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
|
|
5399
5399
|
if (u = Math.min(u, d.visemes.length * 200), c > 0)
|
|
5400
5400
|
for (let x = 0; x < d.visemes.length; x++) {
|
|
5401
|
-
const S = r + d.times[x] / c * u,
|
|
5401
|
+
const S = r + d.times[x] / c * u, U = d.durations[x] / c * u;
|
|
5402
5402
|
o.push({
|
|
5403
5403
|
template: { name: "viseme" },
|
|
5404
|
-
ts: [S - Math.min(60, 2 *
|
|
5404
|
+
ts: [S - Math.min(60, 2 * U / 3), S + Math.min(25, U / 2), S + U + Math.min(60, U / 2)],
|
|
5405
5405
|
vs: {
|
|
5406
5406
|
["viseme_" + d.visemes[x]]: [null, d.visemes[x] === "PP" || d.visemes[x] === "FF" ? 0.9 : b, 0]
|
|
5407
5407
|
}
|
|
@@ -5483,7 +5483,7 @@ class Be {
|
|
|
5483
5483
|
s.lang = o, s.rate = Math.max(0.1, Math.min(10, l)), s.pitch = Math.max(0, Math.min(2, h)), s.volume = Math.max(0, Math.min(1, r));
|
|
5484
5484
|
const u = speechSynthesis.getVoices(), a = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice;
|
|
5485
5485
|
if (a && u.length > 0) {
|
|
5486
|
-
const p = u.find((
|
|
5486
|
+
const p = u.find((F) => F.name.includes(a) || F.lang === o);
|
|
5487
5487
|
p && (s.voice = p);
|
|
5488
5488
|
}
|
|
5489
5489
|
const d = i.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", b = this.lipsyncPreProcessText(i, g), x = this.lipsyncWordsToVisemes(b, g);
|
|
@@ -5498,19 +5498,19 @@ class Be {
|
|
|
5498
5498
|
const S = [];
|
|
5499
5499
|
if (x && x.visemes && x.visemes.length > 0) {
|
|
5500
5500
|
const p = x.times[x.visemes.length - 1] + x.durations[x.visemes.length - 1];
|
|
5501
|
-
for (let
|
|
5502
|
-
const
|
|
5501
|
+
for (let F = 0; F < x.visemes.length; F++) {
|
|
5502
|
+
const C = x.visemes[F], y = x.times[F] / p, I = x.durations[F] / p, z = y * d, A = I * d;
|
|
5503
5503
|
S.push({
|
|
5504
5504
|
template: { name: "viseme" },
|
|
5505
5505
|
ts: [z - Math.min(60, 2 * A / 3), z + Math.min(25, A / 2), z + A + Math.min(60, A / 2)],
|
|
5506
5506
|
vs: {
|
|
5507
|
-
["viseme_" +
|
|
5507
|
+
["viseme_" + C]: [null, C === "PP" || C === "FF" ? 0.9 : 0.6, 0]
|
|
5508
5508
|
}
|
|
5509
5509
|
});
|
|
5510
5510
|
}
|
|
5511
5511
|
}
|
|
5512
|
-
const
|
|
5513
|
-
this.audioPlaylist.push({ anim:
|
|
5512
|
+
const U = [...t.anim, ...S];
|
|
5513
|
+
this.audioPlaylist.push({ anim: U, audio: c }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
|
|
5514
5514
|
e();
|
|
5515
5515
|
}, s.onerror = (p) => {
|
|
5516
5516
|
console.error("Speech synthesis error:", p.error), n(p.error);
|
|
@@ -6159,10 +6159,10 @@ class Be {
|
|
|
6159
6159
|
this.lookAt(null, null, t);
|
|
6160
6160
|
return;
|
|
6161
6161
|
}
|
|
6162
|
-
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2),
|
|
6162
|
+
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ve.setFromMatrixPosition(this.objectLeftEye.matrixWorld), Re.setFromMatrixPosition(this.objectRightEye.matrixWorld), ve.add(Re).divideScalar(2), _.copy(this.armature.quaternion), _.multiply(this.poseTarget.props["Hips.quaternion"]), _.multiply(this.poseTarget.props["Spine.quaternion"]), _.multiply(this.poseTarget.props["Spine1.quaternion"]), _.multiply(this.poseTarget.props["Spine2.quaternion"]), _.multiply(this.poseTarget.props["Neck.quaternion"]), _.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6163
6163
|
const n = new f.Vector3().subVectors(e, ve).normalize(), i = Math.atan2(n.x, n.z), s = Math.asin(-n.y);
|
|
6164
6164
|
Z.set(s, i, 0, "YXZ");
|
|
6165
|
-
const l = new f.Quaternion().setFromEuler(Z), h = new f.Quaternion().copy(l).multiply(
|
|
6165
|
+
const l = new f.Quaternion().setFromEuler(Z), h = new f.Quaternion().copy(l).multiply(_.clone().invert());
|
|
6166
6166
|
Z.setFromQuaternion(h, "YXZ");
|
|
6167
6167
|
let r = Z.x / (40 / 24) + 0.2, u = Z.y / (9 / 4), a = Math.min(0.6, Math.max(-0.3, r)), d = Math.min(0.8, Math.max(-0.8, u)), c = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6168
6168
|
if (t) {
|
|
@@ -6199,20 +6199,20 @@ class Be {
|
|
|
6199
6199
|
const s = new f.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new f.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), l = new f.Vector3().addVectors(s, o).divideScalar(2);
|
|
6200
6200
|
l.project(this.camera);
|
|
6201
6201
|
let h = (l.x + 1) / 2 * i.width + i.left, r = -(l.y - 1) / 2 * i.height + i.top;
|
|
6202
|
-
t === null && (t = h), e === null && (e = r),
|
|
6202
|
+
t === null && (t = h), e === null && (e = r), _.copy(this.armature.quaternion), _.multiply(this.poseTarget.props["Hips.quaternion"]), _.multiply(this.poseTarget.props["Spine.quaternion"]), _.multiply(this.poseTarget.props["Spine1.quaternion"]), _.multiply(this.poseTarget.props["Spine2.quaternion"]), _.multiply(this.poseTarget.props["Neck.quaternion"]), _.multiply(this.poseTarget.props["Head.quaternion"]), Z.setFromQuaternion(_);
|
|
6203
6203
|
let u = Z.x / (40 / 24), a = Z.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 - h, h), b = Math.max(window.innerHeight - r, r), x = this.convertRange(e, [r - b, r + b], [-0.3, 0.6]) - u + d, S = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - a + c;
|
|
6204
6204
|
x = Math.min(0.6, Math.max(-0.3, x)), S = Math.min(0.8, Math.max(-0.8, S));
|
|
6205
|
-
let
|
|
6205
|
+
let U = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
|
|
6206
6206
|
if (n) {
|
|
6207
|
-
let
|
|
6208
|
-
|
|
6209
|
-
const
|
|
6207
|
+
let F = this.animQueue.findIndex((y) => y.template.name === "lookat");
|
|
6208
|
+
F !== -1 && this.animQueue.splice(F, 1);
|
|
6209
|
+
const C = {
|
|
6210
6210
|
name: "lookat",
|
|
6211
6211
|
dt: [750, n],
|
|
6212
6212
|
vs: {
|
|
6213
|
-
bodyRotateX: [x +
|
|
6213
|
+
bodyRotateX: [x + U],
|
|
6214
6214
|
bodyRotateY: [S + p],
|
|
6215
|
-
eyesRotateX: [-3 *
|
|
6215
|
+
eyesRotateX: [-3 * U + 0.1],
|
|
6216
6216
|
eyesRotateY: [-5 * p],
|
|
6217
6217
|
browInnerUp: [[0, 0.7]],
|
|
6218
6218
|
mouthLeft: [[0, 0.7]],
|
|
@@ -6221,7 +6221,7 @@ class Be {
|
|
|
6221
6221
|
headMove: [0]
|
|
6222
6222
|
}
|
|
6223
6223
|
};
|
|
6224
|
-
this.animQueue.push(this.animFactory(
|
|
6224
|
+
this.animQueue.push(this.animFactory(C));
|
|
6225
6225
|
}
|
|
6226
6226
|
}
|
|
6227
6227
|
/**
|
|
@@ -6523,8 +6523,8 @@ class Be {
|
|
|
6523
6523
|
if (k.toLowerCase() === A)
|
|
6524
6524
|
return k;
|
|
6525
6525
|
for (const k of c) {
|
|
6526
|
-
const
|
|
6527
|
-
if ((A.includes("left") &&
|
|
6526
|
+
const E = k.toLowerCase();
|
|
6527
|
+
if ((A.includes("left") && E.includes("left") || A.includes("right") && E.includes("right")) && (A.includes("arm") && E.includes("arm") && !E.includes("fore") || A.includes("forearm") && E.includes("forearm") || A.includes("hand") && E.includes("hand") && !E.includes("index") && !E.includes("thumb") || A.includes("shoulder") && E.includes("shoulder")))
|
|
6528
6528
|
return k;
|
|
6529
6529
|
}
|
|
6530
6530
|
return null;
|
|
@@ -6535,33 +6535,19 @@ class Be {
|
|
|
6535
6535
|
}), console.log("=== Ready Player Me Animation Bone Analysis ==="), console.log("FBX bone names:", Array.from(x).sort().join(", ")), console.log("Avatar skeleton bone names:", Array.from(c).sort().join(", "));
|
|
6536
6536
|
const S = Array.from(x).filter(
|
|
6537
6537
|
(I) => I.toLowerCase().includes("arm") || I.toLowerCase().includes("hand") || I.toLowerCase().includes("shoulder")
|
|
6538
|
-
),
|
|
6538
|
+
), U = Array.from(c).filter(
|
|
6539
6539
|
(I) => I.includes("Arm") || I.includes("Hand") || I.includes("Shoulder")
|
|
6540
6540
|
);
|
|
6541
|
-
console.log("FBX arm/hand/shoulder bones:", S.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:",
|
|
6542
|
-
const p = [],
|
|
6541
|
+
console.log("FBX arm/hand/shoulder bones:", S.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:", U.sort().join(", "));
|
|
6542
|
+
const p = [], F = /* @__PURE__ */ new Set();
|
|
6543
6543
|
if (d.tracks.forEach((I) => {
|
|
6544
|
-
const A = I.name.replaceAll("mixamorig", "").split("."), Y = A[0], k = A[1],
|
|
6545
|
-
if (
|
|
6546
|
-
const q = `${
|
|
6547
|
-
|
|
6548
|
-
const $ = C.includes("Arm") || C.includes("Hand") || C.includes("Shoulder"), ie = C.includes("Left");
|
|
6549
|
-
C.includes("Right");
|
|
6550
|
-
const oe = C.includes("ForeArm") || C.includes("Forearm"), he = C.includes("Hand") && !C.includes("Index") && !C.includes("Thumb") && !C.includes("Middle") && !C.includes("Ring") && !C.includes("Pinky");
|
|
6551
|
-
if ($ && (k === "quaternion" || k === "rotation") && k === "quaternion" && N.values && N.values.length >= 4) {
|
|
6552
|
-
const ee = N.times.length;
|
|
6553
|
-
for (let ne = 0; ne < ee; ne++) {
|
|
6554
|
-
const D = ne * 4;
|
|
6555
|
-
if (D + 3 < N.values.length) {
|
|
6556
|
-
let v = N.values[D], R = N.values[D + 1], T = N.values[D + 2], F = N.values[D + 3], P = new f.Quaternion(v, R, T, F);
|
|
6557
|
-
ie && (he ? (P.conjugate(), P = new f.Quaternion().setFromAxisAngle(new f.Vector3(0, 1, 0), Math.PI).multiply(P)) : oe && (P = new f.Quaternion().setFromAxisAngle(new f.Vector3(0, 1, 0), Math.PI).multiply(P), P = new f.Quaternion().setFromAxisAngle(new f.Vector3(1, 0, 0), Math.PI / 2).multiply(P))), N.values[D] = P.x, N.values[D + 1] = P.y, N.values[D + 2] = P.z, N.values[D + 3] = P.w;
|
|
6558
|
-
}
|
|
6559
|
-
}
|
|
6560
|
-
}
|
|
6561
|
-
p.push(N), Y !== C && g.set(Y, C);
|
|
6544
|
+
const A = I.name.replaceAll("mixamorig", "").split("."), Y = A[0], k = A[1], E = b(Y);
|
|
6545
|
+
if (E && k) {
|
|
6546
|
+
const q = `${E}.${k}`, G = I.clone();
|
|
6547
|
+
G.name = q, p.push(G), Y !== E && g.set(Y, E);
|
|
6562
6548
|
} else
|
|
6563
|
-
|
|
6564
|
-
}),
|
|
6549
|
+
F.add(Y), (Y.toLowerCase().includes("arm") || Y.toLowerCase().includes("hand") || Y.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${Y}" could not be mapped to avatar skeleton`);
|
|
6550
|
+
}), F.size > 0 && console.warn(`⚠️ ${F.size} bone(s) could not be mapped:`, Array.from(F).sort().join(", ")), p.length > 0) {
|
|
6565
6551
|
d = new f.AnimationClip(d.name, d.duration, p), console.log(`✓ Created animation with ${p.length} mapped tracks (from ${d.tracks.length} original tracks)`), g.size > 0 && console.log(
|
|
6566
6552
|
`✓ Mapped ${g.size} bone(s):`,
|
|
6567
6553
|
Array.from(g.entries()).map(([z, A]) => `${z}→${A}`).join(", ")
|
|
@@ -6572,18 +6558,18 @@ class Be {
|
|
|
6572
6558
|
I.length > 0 ? console.log(`✓ Arm bones mapped: ${I.join(", ")}`) : console.warn("⚠️ No arm bones were mapped! This may cause arm rigging issues.");
|
|
6573
6559
|
} else
|
|
6574
6560
|
console.error("❌ No tracks could be mapped! Animation may not work correctly.");
|
|
6575
|
-
const
|
|
6561
|
+
const C = {};
|
|
6576
6562
|
d.tracks.forEach((I) => {
|
|
6577
6563
|
I.name = I.name.replaceAll("mixamorig", "");
|
|
6578
6564
|
const z = I.name.split(".");
|
|
6579
6565
|
if (z[1] === "position") {
|
|
6580
6566
|
for (let A = 0; A < I.values.length; A++)
|
|
6581
6567
|
I.values[A] = I.values[A] * s;
|
|
6582
|
-
|
|
6583
|
-
} else z[1] === "quaternion" ?
|
|
6568
|
+
C[I.name] = new f.Vector3(I.values[0], I.values[1], I.values[2]);
|
|
6569
|
+
} else z[1] === "quaternion" ? C[I.name] = new f.Quaternion(I.values[0], I.values[1], I.values[2], I.values[3]) : z[1] === "rotation" && (C[z[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(I.values[0], I.values[1], I.values[2], "XYZ")).normalize());
|
|
6584
6570
|
});
|
|
6585
|
-
const y = { props:
|
|
6586
|
-
|
|
6571
|
+
const y = { props: C };
|
|
6572
|
+
C["Hips.position"] && (C["Hips.position"].y < 0.5 ? y.lying = !0 : y.standing = !0), this.animClips.push({
|
|
6587
6573
|
url: t + "-" + i,
|
|
6588
6574
|
clip: d,
|
|
6589
6575
|
pose: y
|
|
@@ -6721,12 +6707,12 @@ class Be {
|
|
|
6721
6707
|
const x = t.iterations || 10;
|
|
6722
6708
|
if (e)
|
|
6723
6709
|
for (let S = 0; S < x; S++) {
|
|
6724
|
-
let
|
|
6725
|
-
for (let p = 0,
|
|
6726
|
-
const
|
|
6727
|
-
|
|
6710
|
+
let U = !1;
|
|
6711
|
+
for (let p = 0, F = b.length; p < F; p++) {
|
|
6712
|
+
const C = b[p].bone;
|
|
6713
|
+
C.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();
|
|
6728
6714
|
let y = s.dot(l);
|
|
6729
|
-
y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (b[p].minAngle !== void 0 && y < b[p].minAngle && (y = b[p].minAngle), b[p].maxAngle !== void 0 && y > b[p].maxAngle && (y = b[p].maxAngle), a.crossVectors(l, s), a.normalize(),
|
|
6715
|
+
y > 1 ? y = 1 : y < -1 && (y = -1), y = Math.acos(y), !(y < 1e-5) && (b[p].minAngle !== void 0 && y < b[p].minAngle && (y = b[p].minAngle), b[p].maxAngle !== void 0 && y > b[p].maxAngle && (y = b[p].maxAngle), a.crossVectors(l, s), a.normalize(), _.setFromAxisAngle(a, y), C.quaternion.multiply(_), C.rotation.setFromVector3(d.setFromEuler(C.rotation).clamp(new f.Vector3(
|
|
6730
6716
|
b[p].minx !== void 0 ? b[p].minx : -1 / 0,
|
|
6731
6717
|
b[p].miny !== void 0 ? b[p].miny : -1 / 0,
|
|
6732
6718
|
b[p].minz !== void 0 ? b[p].minz : -1 / 0
|
|
@@ -6734,9 +6720,9 @@ class Be {
|
|
|
6734
6720
|
b[p].maxx !== void 0 ? b[p].maxx : 1 / 0,
|
|
6735
6721
|
b[p].maxy !== void 0 ? b[p].maxy : 1 / 0,
|
|
6736
6722
|
b[p].maxz !== void 0 ? b[p].maxz : 1 / 0
|
|
6737
|
-
))),
|
|
6723
|
+
))), C.updateMatrixWorld(!0), U = !0);
|
|
6738
6724
|
}
|
|
6739
|
-
if (!
|
|
6725
|
+
if (!U) break;
|
|
6740
6726
|
}
|
|
6741
6727
|
i && b.forEach((S) => {
|
|
6742
6728
|
this.poseTarget.props[S.link + ".quaternion"].copy(S.bone.quaternion), this.poseTarget.props[S.link + ".quaternion"].t = this.animClock, this.poseTarget.props[S.link + ".quaternion"].d = i;
|
|
@@ -6829,214 +6815,214 @@ const Ve = Me(({
|
|
|
6829
6815
|
style: b = {},
|
|
6830
6816
|
animations: x = {}
|
|
6831
6817
|
}, S) => {
|
|
6832
|
-
const
|
|
6833
|
-
|
|
6834
|
-
I.current =
|
|
6835
|
-
}, [
|
|
6836
|
-
|
|
6818
|
+
const U = O(null), p = O(null), F = O(r), C = O(null), y = O(null), I = O(!1), z = O({ remainingText: null, originalText: null, options: null }), A = O([]), Y = O(0), [k, E] = ce(!0), [q, G] = ce(null), [ee, se] = ce(!1), [ae, pe] = ce(!1);
|
|
6819
|
+
de(() => {
|
|
6820
|
+
I.current = ae;
|
|
6821
|
+
}, [ae]), de(() => {
|
|
6822
|
+
F.current = r;
|
|
6837
6823
|
}, [r]);
|
|
6838
|
-
const
|
|
6839
|
-
let
|
|
6840
|
-
|
|
6824
|
+
const te = Ee(), le = i || te.service;
|
|
6825
|
+
let W;
|
|
6826
|
+
le === "browser" ? W = {
|
|
6841
6827
|
service: "browser",
|
|
6842
6828
|
endpoint: "",
|
|
6843
6829
|
apiKey: null,
|
|
6844
6830
|
defaultVoice: "Google US English"
|
|
6845
|
-
} :
|
|
6831
|
+
} : le === "elevenlabs" ? W = {
|
|
6846
6832
|
service: "elevenlabs",
|
|
6847
6833
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6848
|
-
apiKey: o ||
|
|
6849
|
-
defaultVoice: s ||
|
|
6850
|
-
voices:
|
|
6851
|
-
} :
|
|
6834
|
+
apiKey: o || te.apiKey,
|
|
6835
|
+
defaultVoice: s || te.defaultVoice || Ie.defaultVoice,
|
|
6836
|
+
voices: te.voices || Ie.voices
|
|
6837
|
+
} : le === "deepgram" ? W = {
|
|
6852
6838
|
service: "deepgram",
|
|
6853
6839
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
6854
|
-
apiKey: o ||
|
|
6855
|
-
defaultVoice: s ||
|
|
6856
|
-
voices:
|
|
6857
|
-
} :
|
|
6858
|
-
...
|
|
6840
|
+
apiKey: o || te.apiKey,
|
|
6841
|
+
defaultVoice: s || te.defaultVoice || Te.defaultVoice,
|
|
6842
|
+
voices: te.voices || Te.voices
|
|
6843
|
+
} : W = {
|
|
6844
|
+
...te,
|
|
6859
6845
|
// Override API key if provided via props
|
|
6860
|
-
apiKey: o !== null ? o :
|
|
6846
|
+
apiKey: o !== null ? o : te.apiKey
|
|
6861
6847
|
};
|
|
6862
6848
|
const v = {
|
|
6863
6849
|
url: X,
|
|
6864
6850
|
body: t,
|
|
6865
6851
|
avatarMood: e,
|
|
6866
|
-
ttsLang:
|
|
6867
|
-
ttsVoice: s ||
|
|
6852
|
+
ttsLang: le === "browser" ? "en-US" : n,
|
|
6853
|
+
ttsVoice: s || W.defaultVoice,
|
|
6868
6854
|
lipsyncLang: "en",
|
|
6869
6855
|
showFullAvatar: r,
|
|
6870
6856
|
bodyMovement: l,
|
|
6871
6857
|
movementIntensity: h
|
|
6872
6858
|
}, R = {
|
|
6873
|
-
ttsEndpoint:
|
|
6874
|
-
ttsApikey:
|
|
6875
|
-
ttsService:
|
|
6859
|
+
ttsEndpoint: W.endpoint,
|
|
6860
|
+
ttsApikey: W.apiKey,
|
|
6861
|
+
ttsService: le,
|
|
6876
6862
|
lipsyncModules: ["en"],
|
|
6877
6863
|
cameraView: u
|
|
6878
|
-
},
|
|
6879
|
-
if (!(!
|
|
6864
|
+
}, H = B(async () => {
|
|
6865
|
+
if (!(!U.current || p.current))
|
|
6880
6866
|
try {
|
|
6881
|
-
if (
|
|
6882
|
-
if (
|
|
6883
|
-
const
|
|
6884
|
-
d(
|
|
6867
|
+
if (E(!0), G(null), p.current = new Be(U.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), x && Object.keys(x).length > 0 && (p.current.customAnimations = x), await p.current.showAvatar(v, (D) => {
|
|
6868
|
+
if (D.lengthComputable) {
|
|
6869
|
+
const $ = Math.min(100, Math.round(D.loaded / D.total * 100));
|
|
6870
|
+
d($);
|
|
6885
6871
|
}
|
|
6886
|
-
}), await new Promise((
|
|
6887
|
-
const
|
|
6888
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ?
|
|
6872
|
+
}), await new Promise((D) => {
|
|
6873
|
+
const $ = () => {
|
|
6874
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? D() : setTimeout($, 100);
|
|
6889
6875
|
};
|
|
6890
|
-
|
|
6876
|
+
$();
|
|
6891
6877
|
}), p.current && p.current.setShowFullAvatar)
|
|
6892
6878
|
try {
|
|
6893
6879
|
p.current.setShowFullAvatar(r);
|
|
6894
|
-
} catch (
|
|
6895
|
-
console.warn("Error setting full body mode on initialization:",
|
|
6880
|
+
} catch (D) {
|
|
6881
|
+
console.warn("Error setting full body mode on initialization:", D);
|
|
6896
6882
|
}
|
|
6897
|
-
p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()),
|
|
6898
|
-
const
|
|
6883
|
+
p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), E(!1), se(!0), a(p.current);
|
|
6884
|
+
const N = () => {
|
|
6899
6885
|
document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
|
|
6900
6886
|
};
|
|
6901
|
-
return document.addEventListener("visibilitychange",
|
|
6902
|
-
document.removeEventListener("visibilitychange",
|
|
6887
|
+
return document.addEventListener("visibilitychange", N), () => {
|
|
6888
|
+
document.removeEventListener("visibilitychange", N);
|
|
6903
6889
|
};
|
|
6904
6890
|
} catch (L) {
|
|
6905
|
-
console.error("Error initializing TalkingHead:", L),
|
|
6891
|
+
console.error("Error initializing TalkingHead:", L), G(L.message || "Failed to initialize avatar"), E(!1), c(L);
|
|
6906
6892
|
}
|
|
6907
6893
|
}, [X, t, e, n, i, s, o, r, l, h, u]);
|
|
6908
|
-
|
|
6894
|
+
de(() => (H(), () => {
|
|
6909
6895
|
p.current && (p.current.stop(), p.current.dispose(), p.current = null);
|
|
6910
|
-
}), [
|
|
6911
|
-
if (!
|
|
6912
|
-
const L = new ResizeObserver((
|
|
6913
|
-
for (const
|
|
6896
|
+
}), [H]), de(() => {
|
|
6897
|
+
if (!U.current || !p.current) return;
|
|
6898
|
+
const L = new ResizeObserver((D) => {
|
|
6899
|
+
for (const $ of D)
|
|
6914
6900
|
p.current && p.current.onResize && p.current.onResize();
|
|
6915
6901
|
});
|
|
6916
|
-
L.observe(
|
|
6917
|
-
const
|
|
6902
|
+
L.observe(U.current);
|
|
6903
|
+
const N = () => {
|
|
6918
6904
|
p.current && p.current.onResize && p.current.onResize();
|
|
6919
6905
|
};
|
|
6920
|
-
return window.addEventListener("resize",
|
|
6921
|
-
L.disconnect(), window.removeEventListener("resize",
|
|
6906
|
+
return window.addEventListener("resize", N), () => {
|
|
6907
|
+
L.disconnect(), window.removeEventListener("resize", N);
|
|
6922
6908
|
};
|
|
6923
|
-
}, [
|
|
6924
|
-
const
|
|
6909
|
+
}, [ee]);
|
|
6910
|
+
const P = B(async () => {
|
|
6925
6911
|
if (p.current && p.current.audioCtx)
|
|
6926
6912
|
try {
|
|
6927
6913
|
(p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
|
|
6928
6914
|
} catch (L) {
|
|
6929
6915
|
console.warn("Failed to resume audio context:", L);
|
|
6930
6916
|
}
|
|
6931
|
-
}, []),
|
|
6932
|
-
if (p.current &&
|
|
6917
|
+
}, []), V = B(async (L, N = {}) => {
|
|
6918
|
+
if (p.current && ee)
|
|
6933
6919
|
try {
|
|
6934
|
-
y.current && (clearInterval(y.current), y.current = null),
|
|
6935
|
-
const
|
|
6936
|
-
A.current =
|
|
6920
|
+
y.current && (clearInterval(y.current), y.current = null), C.current = { text: L, options: N }, z.current = { remainingText: null, originalText: null, options: null };
|
|
6921
|
+
const D = /[!\.\?\n\p{Extended_Pictographic}]/ug, $ = L.split(D).map((j) => j.trim()).filter((j) => j.length > 0);
|
|
6922
|
+
A.current = $, Y.current = 0, pe(!1), I.current = !1, await P();
|
|
6937
6923
|
const ge = {
|
|
6938
|
-
...
|
|
6939
|
-
lipsyncLang:
|
|
6924
|
+
...N,
|
|
6925
|
+
lipsyncLang: N.lipsyncLang || v.lipsyncLang || "en"
|
|
6940
6926
|
};
|
|
6941
|
-
if (
|
|
6942
|
-
const
|
|
6943
|
-
let
|
|
6927
|
+
if (N.onSpeechEnd && p.current) {
|
|
6928
|
+
const j = p.current;
|
|
6929
|
+
let he = null, Se = 0;
|
|
6944
6930
|
const Le = 1200;
|
|
6945
6931
|
let be = !1;
|
|
6946
|
-
|
|
6932
|
+
he = setInterval(() => {
|
|
6947
6933
|
if (Se++, I.current)
|
|
6948
6934
|
return;
|
|
6949
6935
|
if (Se > Le) {
|
|
6950
|
-
if (
|
|
6936
|
+
if (he && (clearInterval(he), he = null, y.current = null), !be && !I.current) {
|
|
6951
6937
|
be = !0;
|
|
6952
6938
|
try {
|
|
6953
|
-
|
|
6939
|
+
N.onSpeechEnd();
|
|
6954
6940
|
} catch (Ne) {
|
|
6955
6941
|
console.error("Error in onSpeechEnd callback (timeout):", Ne);
|
|
6956
6942
|
}
|
|
6957
6943
|
}
|
|
6958
6944
|
return;
|
|
6959
6945
|
}
|
|
6960
|
-
const ye = !
|
|
6961
|
-
|
|
6962
|
-
if (
|
|
6963
|
-
be = !0,
|
|
6946
|
+
const ye = !j.speechQueue || j.speechQueue.length === 0, ke = !j.audioPlaylist || j.audioPlaylist.length === 0;
|
|
6947
|
+
j && j.isSpeaking === !1 && ye && ke && j.isAudioPlaying === !1 && !be && !I.current && setTimeout(() => {
|
|
6948
|
+
if (j && !I.current && j.isSpeaking === !1 && (!j.speechQueue || j.speechQueue.length === 0) && (!j.audioPlaylist || j.audioPlaylist.length === 0) && j.isAudioPlaying === !1 && !be && !I.current) {
|
|
6949
|
+
be = !0, he && (clearInterval(he), he = null, y.current = null);
|
|
6964
6950
|
try {
|
|
6965
|
-
|
|
6951
|
+
N.onSpeechEnd();
|
|
6966
6952
|
} catch (Ze) {
|
|
6967
6953
|
console.error("Error in onSpeechEnd callback:", Ze);
|
|
6968
6954
|
}
|
|
6969
6955
|
}
|
|
6970
6956
|
}, 100);
|
|
6971
|
-
}, 100), y.current =
|
|
6957
|
+
}, 100), y.current = he;
|
|
6972
6958
|
}
|
|
6973
6959
|
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge)) : setTimeout(async () => {
|
|
6974
|
-
await
|
|
6960
|
+
await P(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, ge));
|
|
6975
6961
|
}, 100);
|
|
6976
|
-
} catch (
|
|
6977
|
-
console.error("Error speaking text:",
|
|
6962
|
+
} catch (D) {
|
|
6963
|
+
console.error("Error speaking text:", D), G(D.message || "Failed to speak text");
|
|
6978
6964
|
}
|
|
6979
|
-
}, [
|
|
6980
|
-
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1),
|
|
6981
|
-
}, []),
|
|
6965
|
+
}, [ee, P, v.lipsyncLang]), J = B(() => {
|
|
6966
|
+
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), C.current = null, pe(!1));
|
|
6967
|
+
}, []), Q = B(() => {
|
|
6982
6968
|
if (p.current && p.current.pauseSpeaking) {
|
|
6983
6969
|
const L = p.current;
|
|
6984
6970
|
if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
|
|
6985
6971
|
y.current && (clearInterval(y.current), y.current = null);
|
|
6986
|
-
let
|
|
6987
|
-
if (
|
|
6988
|
-
const
|
|
6989
|
-
if (
|
|
6972
|
+
let D = "";
|
|
6973
|
+
if (C.current && A.current.length > 0) {
|
|
6974
|
+
const $ = A.current.length, ge = L.speechQueue ? L.speechQueue.filter((Le) => Le && Le.text && Array.isArray(Le.text) && Le.text.length > 0).length : 0, j = L.audioPlaylist && L.audioPlaylist.length > 0, he = ge + (j ? 1 : 0), Se = $ - he;
|
|
6975
|
+
if (he > 0 && Se < $ && (D = A.current.slice(Se).join(". ").trim(), !D && ge > 0 && L.speechQueue)) {
|
|
6990
6976
|
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(" ");
|
|
6991
|
-
be && be.trim() && (
|
|
6977
|
+
be && be.trim() && (D = be.trim());
|
|
6992
6978
|
}
|
|
6993
6979
|
}
|
|
6994
|
-
|
|
6995
|
-
remainingText:
|
|
6996
|
-
originalText:
|
|
6997
|
-
options:
|
|
6998
|
-
}), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), I.current = !0,
|
|
6980
|
+
C.current && (z.current = {
|
|
6981
|
+
remainingText: D || null,
|
|
6982
|
+
originalText: C.current.text,
|
|
6983
|
+
options: C.current.options
|
|
6984
|
+
}), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), I.current = !0, pe(!0);
|
|
6999
6985
|
}
|
|
7000
6986
|
}
|
|
7001
|
-
}, []),
|
|
7002
|
-
if (!p.current || !
|
|
6987
|
+
}, []), K = B(async () => {
|
|
6988
|
+
if (!p.current || !ae)
|
|
7003
6989
|
return;
|
|
7004
|
-
let L = "",
|
|
6990
|
+
let L = "", N = {};
|
|
7005
6991
|
if (z.current && z.current.remainingText)
|
|
7006
|
-
L = z.current.remainingText,
|
|
7007
|
-
else if (
|
|
7008
|
-
L =
|
|
6992
|
+
L = z.current.remainingText, N = z.current.options || {}, z.current = { remainingText: null, originalText: null, options: null };
|
|
6993
|
+
else if (C.current && C.current.text)
|
|
6994
|
+
L = C.current.text, N = C.current.options || {};
|
|
7009
6995
|
else {
|
|
7010
|
-
console.warn("Resume called but no paused speech found"),
|
|
6996
|
+
console.warn("Resume called but no paused speech found"), pe(!1), I.current = !1;
|
|
7011
6997
|
return;
|
|
7012
6998
|
}
|
|
7013
|
-
|
|
7014
|
-
const
|
|
7015
|
-
...
|
|
7016
|
-
lipsyncLang:
|
|
6999
|
+
pe(!1), I.current = !1, await P();
|
|
7000
|
+
const D = {
|
|
7001
|
+
...N,
|
|
7002
|
+
lipsyncLang: N.lipsyncLang || v.lipsyncLang || "en"
|
|
7017
7003
|
};
|
|
7018
7004
|
try {
|
|
7019
|
-
await
|
|
7020
|
-
} catch (
|
|
7021
|
-
console.error("Error resuming speech:",
|
|
7005
|
+
await V(L, D);
|
|
7006
|
+
} catch ($) {
|
|
7007
|
+
console.error("Error resuming speech:", $), pe(!1), I.current = !1;
|
|
7022
7008
|
}
|
|
7023
|
-
}, [
|
|
7009
|
+
}, [P, ae, V, v]), Ae = B((L) => {
|
|
7024
7010
|
p.current && p.current.setMood(L);
|
|
7025
|
-
}, []), we =
|
|
7011
|
+
}, []), we = B((L) => {
|
|
7026
7012
|
p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
|
|
7027
|
-
}, []),
|
|
7013
|
+
}, []), M = B((L, N = !1) => {
|
|
7028
7014
|
if (p.current && p.current.playAnimation) {
|
|
7029
7015
|
if (x && x[L] && (L = x[L]), p.current.setShowFullAvatar)
|
|
7030
7016
|
try {
|
|
7031
|
-
p.current.setShowFullAvatar(
|
|
7032
|
-
} catch (
|
|
7033
|
-
console.warn("Error setting full body mode:",
|
|
7017
|
+
p.current.setShowFullAvatar(F.current);
|
|
7018
|
+
} catch ($) {
|
|
7019
|
+
console.warn("Error setting full body mode:", $);
|
|
7034
7020
|
}
|
|
7035
7021
|
if (L.includes("."))
|
|
7036
7022
|
try {
|
|
7037
|
-
p.current.playAnimation(L, null, 10, 0, 0.01,
|
|
7038
|
-
} catch (
|
|
7039
|
-
console.warn(`Failed to play ${L}:`,
|
|
7023
|
+
p.current.playAnimation(L, null, 10, 0, 0.01, N);
|
|
7024
|
+
} catch ($) {
|
|
7025
|
+
console.warn(`Failed to play ${L}:`, $);
|
|
7040
7026
|
try {
|
|
7041
7027
|
p.current.setBodyMovement("idle");
|
|
7042
7028
|
} catch (ge) {
|
|
@@ -7044,11 +7030,11 @@ const Ve = Me(({
|
|
|
7044
7030
|
}
|
|
7045
7031
|
}
|
|
7046
7032
|
else {
|
|
7047
|
-
const
|
|
7033
|
+
const $ = [".fbx", ".glb", ".gltf"];
|
|
7048
7034
|
let ge = !1;
|
|
7049
|
-
for (const
|
|
7035
|
+
for (const j of $)
|
|
7050
7036
|
try {
|
|
7051
|
-
p.current.playAnimation(L +
|
|
7037
|
+
p.current.playAnimation(L + j, null, 10, 0, 0.01, N), ge = !0;
|
|
7052
7038
|
break;
|
|
7053
7039
|
} catch {
|
|
7054
7040
|
}
|
|
@@ -7056,41 +7042,41 @@ const Ve = Me(({
|
|
|
7056
7042
|
console.warn("Animation not found:", L);
|
|
7057
7043
|
try {
|
|
7058
7044
|
p.current.setBodyMovement("idle");
|
|
7059
|
-
} catch (
|
|
7060
|
-
console.warn("Fallback animation also failed:",
|
|
7045
|
+
} catch (j) {
|
|
7046
|
+
console.warn("Fallback animation also failed:", j);
|
|
7061
7047
|
}
|
|
7062
7048
|
}
|
|
7063
7049
|
}
|
|
7064
7050
|
}
|
|
7065
|
-
}, [x]),
|
|
7051
|
+
}, [x]), ne = B(() => {
|
|
7066
7052
|
p.current && p.current.onResize && p.current.onResize();
|
|
7067
7053
|
}, []);
|
|
7068
7054
|
return Fe(S, () => ({
|
|
7069
|
-
speakText:
|
|
7070
|
-
stopSpeaking:
|
|
7071
|
-
pauseSpeaking:
|
|
7072
|
-
resumeSpeaking:
|
|
7073
|
-
resumeAudioContext:
|
|
7055
|
+
speakText: V,
|
|
7056
|
+
stopSpeaking: J,
|
|
7057
|
+
pauseSpeaking: Q,
|
|
7058
|
+
resumeSpeaking: K,
|
|
7059
|
+
resumeAudioContext: P,
|
|
7074
7060
|
setMood: Ae,
|
|
7075
7061
|
setTimingAdjustment: we,
|
|
7076
|
-
playAnimation:
|
|
7077
|
-
isReady:
|
|
7078
|
-
isPaused:
|
|
7062
|
+
playAnimation: M,
|
|
7063
|
+
isReady: ee,
|
|
7064
|
+
isPaused: ae,
|
|
7079
7065
|
talkingHead: p.current,
|
|
7080
|
-
handleResize:
|
|
7066
|
+
handleResize: ne,
|
|
7081
7067
|
setBodyMovement: (L) => {
|
|
7082
7068
|
if (p.current && p.current.setShowFullAvatar && p.current.setBodyMovement)
|
|
7083
7069
|
try {
|
|
7084
|
-
p.current.setShowFullAvatar(
|
|
7085
|
-
} catch (
|
|
7086
|
-
console.warn("Error setting body movement:",
|
|
7070
|
+
p.current.setShowFullAvatar(F.current), p.current.setBodyMovement(L);
|
|
7071
|
+
} catch (N) {
|
|
7072
|
+
console.warn("Error setting body movement:", N);
|
|
7087
7073
|
}
|
|
7088
7074
|
},
|
|
7089
7075
|
setMovementIntensity: (L) => p.current?.setMovementIntensity(L),
|
|
7090
7076
|
playRandomDance: () => {
|
|
7091
7077
|
if (p.current && p.current.setShowFullAvatar && p.current.playRandomDance)
|
|
7092
7078
|
try {
|
|
7093
|
-
p.current.setShowFullAvatar(
|
|
7079
|
+
p.current.setShowFullAvatar(F.current), p.current.playRandomDance();
|
|
7094
7080
|
} catch (L) {
|
|
7095
7081
|
console.warn("Error playing random dance:", L);
|
|
7096
7082
|
}
|
|
@@ -7098,15 +7084,15 @@ const Ve = Me(({
|
|
|
7098
7084
|
playReaction: (L) => {
|
|
7099
7085
|
if (p.current && p.current.setShowFullAvatar && p.current.playReaction)
|
|
7100
7086
|
try {
|
|
7101
|
-
p.current.setShowFullAvatar(
|
|
7102
|
-
} catch (
|
|
7103
|
-
console.warn("Error playing reaction:",
|
|
7087
|
+
p.current.setShowFullAvatar(F.current), p.current.playReaction(L);
|
|
7088
|
+
} catch (N) {
|
|
7089
|
+
console.warn("Error playing reaction:", N);
|
|
7104
7090
|
}
|
|
7105
7091
|
},
|
|
7106
7092
|
playCelebration: () => {
|
|
7107
7093
|
if (p.current && p.current.setShowFullAvatar && p.current.playCelebration)
|
|
7108
7094
|
try {
|
|
7109
|
-
p.current.setShowFullAvatar(
|
|
7095
|
+
p.current.setShowFullAvatar(F.current), p.current.playCelebration();
|
|
7110
7096
|
} catch (L) {
|
|
7111
7097
|
console.warn("Error playing celebration:", L);
|
|
7112
7098
|
}
|
|
@@ -7114,9 +7100,9 @@ const Ve = Me(({
|
|
|
7114
7100
|
setShowFullAvatar: (L) => {
|
|
7115
7101
|
if (p.current && p.current.setShowFullAvatar)
|
|
7116
7102
|
try {
|
|
7117
|
-
|
|
7118
|
-
} catch (
|
|
7119
|
-
console.warn("Error setting showFullAvatar:",
|
|
7103
|
+
F.current = L, p.current.setShowFullAvatar(L);
|
|
7104
|
+
} catch (N) {
|
|
7105
|
+
console.warn("Error setting showFullAvatar:", N);
|
|
7120
7106
|
}
|
|
7121
7107
|
},
|
|
7122
7108
|
lockAvatarPosition: () => {
|
|
@@ -7146,10 +7132,10 @@ const Ve = Me(({
|
|
|
7146
7132
|
...b
|
|
7147
7133
|
},
|
|
7148
7134
|
children: [
|
|
7149
|
-
/* @__PURE__ */
|
|
7135
|
+
/* @__PURE__ */ me(
|
|
7150
7136
|
"div",
|
|
7151
7137
|
{
|
|
7152
|
-
ref:
|
|
7138
|
+
ref: U,
|
|
7153
7139
|
className: "talking-head-viewer",
|
|
7154
7140
|
style: {
|
|
7155
7141
|
width: "100%",
|
|
@@ -7158,7 +7144,7 @@ const Ve = Me(({
|
|
|
7158
7144
|
}
|
|
7159
7145
|
}
|
|
7160
7146
|
),
|
|
7161
|
-
k && /* @__PURE__ */
|
|
7147
|
+
k && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7162
7148
|
position: "absolute",
|
|
7163
7149
|
top: "50%",
|
|
7164
7150
|
left: "50%",
|
|
@@ -7167,7 +7153,7 @@ const Ve = Me(({
|
|
|
7167
7153
|
fontSize: "18px",
|
|
7168
7154
|
zIndex: 10
|
|
7169
7155
|
}, children: "Loading avatar..." }),
|
|
7170
|
-
q && /* @__PURE__ */
|
|
7156
|
+
q && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7171
7157
|
position: "absolute",
|
|
7172
7158
|
top: "50%",
|
|
7173
7159
|
left: "50%",
|
|
@@ -7196,7 +7182,7 @@ const pt = Me(({
|
|
|
7196
7182
|
style: s = {},
|
|
7197
7183
|
avatarConfig: o = {}
|
|
7198
7184
|
}, l) => {
|
|
7199
|
-
const h =
|
|
7185
|
+
const h = O(null), r = O(null), [u, a] = ce(!0), [d, c] = ce(null), [g, b] = ce(!1), x = Ee(), S = o.ttsService || x.service, U = S === "browser" ? {
|
|
7200
7186
|
endpoint: "",
|
|
7201
7187
|
apiKey: null,
|
|
7202
7188
|
defaultVoice: "Google US English"
|
|
@@ -7212,7 +7198,7 @@ const pt = Me(({
|
|
|
7212
7198
|
body: "F",
|
|
7213
7199
|
avatarMood: "neutral",
|
|
7214
7200
|
ttsLang: S === "browser" ? "en-US" : "en",
|
|
7215
|
-
ttsVoice: o.ttsVoice ||
|
|
7201
|
+
ttsVoice: o.ttsVoice || U.defaultVoice,
|
|
7216
7202
|
lipsyncLang: "en",
|
|
7217
7203
|
// English lip-sync
|
|
7218
7204
|
showFullAvatar: !0,
|
|
@@ -7220,31 +7206,31 @@ const pt = Me(({
|
|
|
7220
7206
|
bodyMovement: "idle",
|
|
7221
7207
|
movementIntensity: 0.5,
|
|
7222
7208
|
...o
|
|
7223
|
-
},
|
|
7224
|
-
ttsEndpoint:
|
|
7225
|
-
ttsApikey:
|
|
7209
|
+
}, F = {
|
|
7210
|
+
ttsEndpoint: U.endpoint,
|
|
7211
|
+
ttsApikey: U.apiKey,
|
|
7226
7212
|
ttsService: S,
|
|
7227
7213
|
lipsyncModules: ["en"],
|
|
7228
7214
|
cameraView: "upper"
|
|
7229
|
-
},
|
|
7215
|
+
}, C = B(async () => {
|
|
7230
7216
|
if (!(!h.current || r.current))
|
|
7231
7217
|
try {
|
|
7232
|
-
if (a(!0), c(null), r.current = new Be(h.current,
|
|
7218
|
+
if (a(!0), c(null), r.current = new Be(h.current, F), await r.current.showAvatar(p, (q) => {
|
|
7233
7219
|
if (q.lengthComputable) {
|
|
7234
|
-
const
|
|
7235
|
-
t(
|
|
7220
|
+
const G = Math.min(100, Math.round(q.loaded / q.total * 100));
|
|
7221
|
+
t(G);
|
|
7236
7222
|
}
|
|
7237
7223
|
}), r.current.morphs && r.current.morphs.length > 0) {
|
|
7238
7224
|
const q = r.current.morphs[0].morphTargetDictionary;
|
|
7239
7225
|
console.log("Available morph targets:", Object.keys(q));
|
|
7240
|
-
const
|
|
7241
|
-
console.log("Viseme morph targets found:",
|
|
7226
|
+
const G = Object.keys(q).filter((ee) => ee.startsWith("viseme_"));
|
|
7227
|
+
console.log("Viseme morph targets found:", G), G.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"));
|
|
7242
7228
|
}
|
|
7243
7229
|
if (await new Promise((q) => {
|
|
7244
|
-
const
|
|
7245
|
-
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), q()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(
|
|
7230
|
+
const G = () => {
|
|
7231
|
+
r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), q()) : (console.log("Waiting for lip-sync modules to load..."), setTimeout(G, 100));
|
|
7246
7232
|
};
|
|
7247
|
-
|
|
7233
|
+
G();
|
|
7248
7234
|
}), r.current && r.current.setShowFullAvatar)
|
|
7249
7235
|
try {
|
|
7250
7236
|
r.current.setShowFullAvatar(!0), console.log("Avatar initialized in full body mode");
|
|
@@ -7252,71 +7238,71 @@ const pt = Me(({
|
|
|
7252
7238
|
console.warn("Error setting full body mode on initialization:", q);
|
|
7253
7239
|
}
|
|
7254
7240
|
a(!1), b(!0), n(r.current);
|
|
7255
|
-
const
|
|
7241
|
+
const E = () => {
|
|
7256
7242
|
document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
|
|
7257
7243
|
};
|
|
7258
|
-
return document.addEventListener("visibilitychange",
|
|
7259
|
-
document.removeEventListener("visibilitychange",
|
|
7244
|
+
return document.addEventListener("visibilitychange", E), () => {
|
|
7245
|
+
document.removeEventListener("visibilitychange", E);
|
|
7260
7246
|
};
|
|
7261
7247
|
} catch (k) {
|
|
7262
7248
|
console.error("Error initializing TalkingHead:", k), c(k.message || "Failed to initialize avatar"), a(!1), e(k);
|
|
7263
7249
|
}
|
|
7264
7250
|
}, []);
|
|
7265
|
-
|
|
7251
|
+
de(() => (C(), () => {
|
|
7266
7252
|
r.current && (r.current.stop(), r.current.dispose(), r.current = null);
|
|
7267
|
-
}), [
|
|
7268
|
-
const y =
|
|
7253
|
+
}), [C]);
|
|
7254
|
+
const y = B((k) => {
|
|
7269
7255
|
if (r.current && g)
|
|
7270
7256
|
try {
|
|
7271
7257
|
console.log("Speaking text:", k), console.log("Avatar config:", p), console.log("TalkingHead instance:", r.current), r.current.lipsync && Object.keys(r.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(r.current.lipsync)), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(k)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
|
|
7272
7258
|
r.current && r.current.lipsync ? (console.log("Lip-sync now ready, speaking..."), r.current.setSlowdownRate && (r.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), r.current.speakText(k)) : console.error("Lip-sync still not ready after waiting");
|
|
7273
7259
|
}, 500));
|
|
7274
|
-
} catch (
|
|
7275
|
-
console.error("Error speaking text:",
|
|
7260
|
+
} catch (E) {
|
|
7261
|
+
console.error("Error speaking text:", E), c(E.message || "Failed to speak text");
|
|
7276
7262
|
}
|
|
7277
7263
|
else
|
|
7278
7264
|
console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
|
|
7279
|
-
}, [g, p]), I =
|
|
7265
|
+
}, [g, p]), I = B(() => {
|
|
7280
7266
|
r.current && (r.current.stopSpeaking(), r.current.setSlowdownRate && (r.current.setSlowdownRate(1), console.log("Reset timing to normal")));
|
|
7281
|
-
}, []), z =
|
|
7267
|
+
}, []), z = B((k) => {
|
|
7282
7268
|
r.current && r.current.setMood(k);
|
|
7283
|
-
}, []), A =
|
|
7269
|
+
}, []), A = B((k) => {
|
|
7284
7270
|
r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(k), console.log("Timing adjustment set to:", k));
|
|
7285
|
-
}, []), Y =
|
|
7271
|
+
}, []), Y = B((k, E = !1) => {
|
|
7286
7272
|
if (r.current && r.current.playAnimation) {
|
|
7287
7273
|
if (r.current.setShowFullAvatar)
|
|
7288
7274
|
try {
|
|
7289
7275
|
r.current.setShowFullAvatar(!0);
|
|
7290
|
-
} catch (
|
|
7291
|
-
console.warn("Error setting full body mode:",
|
|
7276
|
+
} catch (G) {
|
|
7277
|
+
console.warn("Error setting full body mode:", G);
|
|
7292
7278
|
}
|
|
7293
7279
|
if (k.includes("."))
|
|
7294
7280
|
try {
|
|
7295
|
-
r.current.playAnimation(k, null, 10, 0, 0.01,
|
|
7296
|
-
} catch (
|
|
7297
|
-
console.log(`Failed to play ${k}:`,
|
|
7281
|
+
r.current.playAnimation(k, null, 10, 0, 0.01, E), console.log("Playing animation:", k);
|
|
7282
|
+
} catch (G) {
|
|
7283
|
+
console.log(`Failed to play ${k}:`, G);
|
|
7298
7284
|
try {
|
|
7299
7285
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7300
|
-
} catch (
|
|
7301
|
-
console.warn("Fallback animation also failed:",
|
|
7286
|
+
} catch (ee) {
|
|
7287
|
+
console.warn("Fallback animation also failed:", ee);
|
|
7302
7288
|
}
|
|
7303
7289
|
}
|
|
7304
7290
|
else {
|
|
7305
|
-
const
|
|
7306
|
-
let
|
|
7307
|
-
for (const
|
|
7291
|
+
const G = [".fbx", ".glb", ".gltf"];
|
|
7292
|
+
let ee = !1;
|
|
7293
|
+
for (const se of G)
|
|
7308
7294
|
try {
|
|
7309
|
-
r.current.playAnimation(k +
|
|
7295
|
+
r.current.playAnimation(k + se, null, 10, 0, 0.01, E), console.log("Playing animation:", k + se), ee = !0;
|
|
7310
7296
|
break;
|
|
7311
7297
|
} catch {
|
|
7312
|
-
console.log(`Failed to play ${k}${
|
|
7298
|
+
console.log(`Failed to play ${k}${se}, trying next format...`);
|
|
7313
7299
|
}
|
|
7314
|
-
if (
|
|
7300
|
+
if (!ee) {
|
|
7315
7301
|
console.warn("Animation system not available or animation not found:", k);
|
|
7316
7302
|
try {
|
|
7317
7303
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7318
|
-
} catch (
|
|
7319
|
-
console.warn("Fallback animation also failed:",
|
|
7304
|
+
} catch (se) {
|
|
7305
|
+
console.warn("Fallback animation also failed:", se);
|
|
7320
7306
|
}
|
|
7321
7307
|
}
|
|
7322
7308
|
}
|
|
@@ -7335,8 +7321,8 @@ const pt = Me(({
|
|
|
7335
7321
|
if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
|
|
7336
7322
|
try {
|
|
7337
7323
|
r.current.setShowFullAvatar(!0), r.current.setBodyMovement(k), console.log("Body movement set with full body mode:", k);
|
|
7338
|
-
} catch (
|
|
7339
|
-
console.warn("Error setting body movement:",
|
|
7324
|
+
} catch (E) {
|
|
7325
|
+
console.warn("Error setting body movement:", E);
|
|
7340
7326
|
}
|
|
7341
7327
|
},
|
|
7342
7328
|
setMovementIntensity: (k) => r.current?.setMovementIntensity(k),
|
|
@@ -7352,8 +7338,8 @@ const pt = Me(({
|
|
|
7352
7338
|
if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
|
|
7353
7339
|
try {
|
|
7354
7340
|
r.current.setShowFullAvatar(!0), r.current.playReaction(k), console.log("Reaction played with full body mode:", k);
|
|
7355
|
-
} catch (
|
|
7356
|
-
console.warn("Error playing reaction:",
|
|
7341
|
+
} catch (E) {
|
|
7342
|
+
console.warn("Error playing reaction:", E);
|
|
7357
7343
|
}
|
|
7358
7344
|
},
|
|
7359
7345
|
playCelebration: () => {
|
|
@@ -7368,8 +7354,8 @@ const pt = Me(({
|
|
|
7368
7354
|
if (r.current && r.current.setShowFullAvatar)
|
|
7369
7355
|
try {
|
|
7370
7356
|
r.current.setShowFullAvatar(k), console.log("Show full avatar set to:", k);
|
|
7371
|
-
} catch (
|
|
7372
|
-
console.warn("Error setting showFullAvatar:",
|
|
7357
|
+
} catch (E) {
|
|
7358
|
+
console.warn("Error setting showFullAvatar:", E);
|
|
7373
7359
|
}
|
|
7374
7360
|
},
|
|
7375
7361
|
lockAvatarPosition: () => {
|
|
@@ -7389,7 +7375,7 @@ const pt = Me(({
|
|
|
7389
7375
|
}
|
|
7390
7376
|
}
|
|
7391
7377
|
})), /* @__PURE__ */ Pe("div", { className: `talking-head-container ${i}`, style: s, children: [
|
|
7392
|
-
/* @__PURE__ */
|
|
7378
|
+
/* @__PURE__ */ me(
|
|
7393
7379
|
"div",
|
|
7394
7380
|
{
|
|
7395
7381
|
ref: h,
|
|
@@ -7401,7 +7387,7 @@ const pt = Me(({
|
|
|
7401
7387
|
}
|
|
7402
7388
|
}
|
|
7403
7389
|
),
|
|
7404
|
-
u && /* @__PURE__ */
|
|
7390
|
+
u && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7405
7391
|
position: "absolute",
|
|
7406
7392
|
top: "50%",
|
|
7407
7393
|
left: "50%",
|
|
@@ -7410,7 +7396,7 @@ const pt = Me(({
|
|
|
7410
7396
|
fontSize: "18px",
|
|
7411
7397
|
zIndex: 10
|
|
7412
7398
|
}, children: "Loading avatar..." }),
|
|
7413
|
-
d && /* @__PURE__ */
|
|
7399
|
+
d && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7414
7400
|
position: "absolute",
|
|
7415
7401
|
top: "50%",
|
|
7416
7402
|
left: "50%",
|
|
@@ -7448,16 +7434,16 @@ const gt = Me(({
|
|
|
7448
7434
|
},
|
|
7449
7435
|
className: x = "",
|
|
7450
7436
|
style: S = {},
|
|
7451
|
-
animations:
|
|
7437
|
+
animations: U = {},
|
|
7452
7438
|
autoSpeak: p = !1
|
|
7453
|
-
},
|
|
7454
|
-
const
|
|
7455
|
-
|
|
7456
|
-
Y.current =
|
|
7457
|
-
}, [
|
|
7439
|
+
}, F) => {
|
|
7440
|
+
const C = O(null), y = O(null), I = O(u), z = O(null), A = O(null), Y = O(!1), k = O({ remainingText: null, originalText: null, options: null }), E = O([]), [q, G] = ce(!0), [ee, se] = ce(null), [ae, pe] = ce(!1), [te, le] = ce(!1);
|
|
7441
|
+
de(() => {
|
|
7442
|
+
Y.current = te;
|
|
7443
|
+
}, [te]), de(() => {
|
|
7458
7444
|
I.current = u;
|
|
7459
7445
|
}, [u]);
|
|
7460
|
-
const
|
|
7446
|
+
const W = Ee(), v = s || W.service;
|
|
7461
7447
|
let R;
|
|
7462
7448
|
v === "browser" ? R = {
|
|
7463
7449
|
service: "browser",
|
|
@@ -7467,20 +7453,20 @@ const gt = Me(({
|
|
|
7467
7453
|
} : v === "elevenlabs" ? R = {
|
|
7468
7454
|
service: "elevenlabs",
|
|
7469
7455
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7470
|
-
apiKey: l ||
|
|
7471
|
-
defaultVoice: o ||
|
|
7472
|
-
voices:
|
|
7456
|
+
apiKey: l || W.apiKey,
|
|
7457
|
+
defaultVoice: o || W.defaultVoice || Ie.defaultVoice,
|
|
7458
|
+
voices: W.voices || Ie.voices
|
|
7473
7459
|
} : v === "deepgram" ? R = {
|
|
7474
7460
|
service: "deepgram",
|
|
7475
7461
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7476
|
-
apiKey: l ||
|
|
7477
|
-
defaultVoice: o ||
|
|
7478
|
-
voices:
|
|
7462
|
+
apiKey: l || W.apiKey,
|
|
7463
|
+
defaultVoice: o || W.defaultVoice || Te.defaultVoice,
|
|
7464
|
+
voices: W.voices || Te.voices
|
|
7479
7465
|
} : R = {
|
|
7480
|
-
...
|
|
7481
|
-
apiKey: l !== null ? l :
|
|
7466
|
+
...W,
|
|
7467
|
+
apiKey: l !== null ? l : W.apiKey
|
|
7482
7468
|
};
|
|
7483
|
-
const
|
|
7469
|
+
const H = {
|
|
7484
7470
|
url: t,
|
|
7485
7471
|
body: e,
|
|
7486
7472
|
avatarMood: n,
|
|
@@ -7490,127 +7476,127 @@ const gt = Me(({
|
|
|
7490
7476
|
showFullAvatar: u,
|
|
7491
7477
|
bodyMovement: h,
|
|
7492
7478
|
movementIntensity: r
|
|
7493
|
-
},
|
|
7479
|
+
}, P = {
|
|
7494
7480
|
ttsEndpoint: R.endpoint,
|
|
7495
7481
|
ttsApikey: R.apiKey,
|
|
7496
7482
|
ttsService: v,
|
|
7497
7483
|
lipsyncModules: ["en"],
|
|
7498
7484
|
cameraView: a
|
|
7499
|
-
},
|
|
7500
|
-
if (!(!
|
|
7485
|
+
}, V = B(async () => {
|
|
7486
|
+
if (!(!C.current || y.current))
|
|
7501
7487
|
try {
|
|
7502
|
-
|
|
7503
|
-
url:
|
|
7504
|
-
body:
|
|
7505
|
-
avatarMood:
|
|
7506
|
-
}), await y.current.showAvatar(
|
|
7507
|
-
if (
|
|
7508
|
-
const L = Math.min(100, Math.round(
|
|
7488
|
+
G(!0), se(null), y.current = new Be(C.current, P), console.log("Avatar config being passed:", {
|
|
7489
|
+
url: H.url,
|
|
7490
|
+
body: H.body,
|
|
7491
|
+
avatarMood: H.avatarMood
|
|
7492
|
+
}), await y.current.showAvatar(H, (ne) => {
|
|
7493
|
+
if (ne.lengthComputable) {
|
|
7494
|
+
const L = Math.min(100, Math.round(ne.loaded / ne.total * 100));
|
|
7509
7495
|
c(L);
|
|
7510
7496
|
}
|
|
7511
|
-
}), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body),
|
|
7512
|
-
const
|
|
7497
|
+
}), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), G(!1), pe(!0), d(y.current);
|
|
7498
|
+
const M = () => {
|
|
7513
7499
|
document.visibilityState === "visible" ? y.current?.start() : y.current?.stop();
|
|
7514
7500
|
};
|
|
7515
|
-
return document.addEventListener("visibilitychange",
|
|
7516
|
-
document.removeEventListener("visibilitychange",
|
|
7501
|
+
return document.addEventListener("visibilitychange", M), () => {
|
|
7502
|
+
document.removeEventListener("visibilitychange", M);
|
|
7517
7503
|
};
|
|
7518
|
-
} catch (
|
|
7519
|
-
console.error("Error initializing TalkingHead:",
|
|
7504
|
+
} catch (M) {
|
|
7505
|
+
console.error("Error initializing TalkingHead:", M), se(M.message || "Failed to initialize avatar"), G(!1), g(M);
|
|
7520
7506
|
}
|
|
7521
7507
|
}, []);
|
|
7522
|
-
|
|
7508
|
+
de(() => (V(), () => {
|
|
7523
7509
|
y.current && (y.current.stop(), y.current.dispose(), y.current = null);
|
|
7524
|
-
}), [
|
|
7525
|
-
const
|
|
7510
|
+
}), [V]);
|
|
7511
|
+
const J = B(async () => {
|
|
7526
7512
|
if (y.current)
|
|
7527
7513
|
try {
|
|
7528
|
-
const
|
|
7529
|
-
|
|
7530
|
-
} catch (
|
|
7531
|
-
console.warn("Failed to resume audio context:",
|
|
7514
|
+
const M = y.current.audioCtx || y.current.audioContext;
|
|
7515
|
+
M && (M.state === "suspended" || M.state === "interrupted") && (await M.resume(), console.log("Audio context resumed"));
|
|
7516
|
+
} catch (M) {
|
|
7517
|
+
console.warn("Failed to resume audio context:", M);
|
|
7532
7518
|
}
|
|
7533
|
-
}, []),
|
|
7534
|
-
if (!y.current || !
|
|
7519
|
+
}, []), Q = B(async (M, ne = {}) => {
|
|
7520
|
+
if (!y.current || !ae) {
|
|
7535
7521
|
console.warn("Avatar not ready for speaking");
|
|
7536
7522
|
return;
|
|
7537
7523
|
}
|
|
7538
|
-
if (!
|
|
7524
|
+
if (!M || M.trim() === "") {
|
|
7539
7525
|
console.warn("No text provided to speak");
|
|
7540
7526
|
return;
|
|
7541
7527
|
}
|
|
7542
|
-
await
|
|
7543
|
-
const L =
|
|
7544
|
-
|
|
7545
|
-
const
|
|
7546
|
-
lipsyncLang:
|
|
7528
|
+
await J(), k.current = { remainingText: null, originalText: null, options: null }, E.current = [], z.current = { text: M, options: ne }, A.current && (clearInterval(A.current), A.current = null), le(!1), Y.current = !1;
|
|
7529
|
+
const L = M.split(/[.!?]+/).filter((D) => D.trim().length > 0);
|
|
7530
|
+
E.current = L;
|
|
7531
|
+
const N = {
|
|
7532
|
+
lipsyncLang: ne.lipsyncLang || "en",
|
|
7547
7533
|
onSpeechEnd: () => {
|
|
7548
|
-
A.current && (clearInterval(A.current), A.current = null),
|
|
7534
|
+
A.current && (clearInterval(A.current), A.current = null), ne.onSpeechEnd && ne.onSpeechEnd(), b();
|
|
7549
7535
|
}
|
|
7550
7536
|
};
|
|
7551
7537
|
try {
|
|
7552
|
-
y.current.speakText(
|
|
7553
|
-
} catch (
|
|
7554
|
-
console.error("Error speaking text:",
|
|
7538
|
+
y.current.speakText(M, N);
|
|
7539
|
+
} catch (D) {
|
|
7540
|
+
console.error("Error speaking text:", D), se(D.message || "Failed to speak text");
|
|
7555
7541
|
}
|
|
7556
|
-
}, [
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
}, [
|
|
7560
|
-
const
|
|
7542
|
+
}, [ae, b, J]);
|
|
7543
|
+
de(() => {
|
|
7544
|
+
ae && X && p && y.current && Q(X);
|
|
7545
|
+
}, [ae, X, p, Q]);
|
|
7546
|
+
const K = B(() => {
|
|
7561
7547
|
if (y.current)
|
|
7562
7548
|
try {
|
|
7563
|
-
const
|
|
7564
|
-
if (
|
|
7549
|
+
const M = y.current.isSpeaking || !1, ne = y.current.audioPlaylist || [], L = y.current.speechQueue || [];
|
|
7550
|
+
if (M || ne.length > 0 || L.length > 0) {
|
|
7565
7551
|
A.current && (clearInterval(A.current), A.current = null);
|
|
7566
|
-
let
|
|
7567
|
-
L.length > 0 && (
|
|
7568
|
-
remainingText:
|
|
7552
|
+
let N = "";
|
|
7553
|
+
L.length > 0 && (N = L.map((D) => D.text && Array.isArray(D.text) ? D.text.map(($) => $.word).join(" ") : D.text || "").join(" ")), k.current = {
|
|
7554
|
+
remainingText: N || null,
|
|
7569
7555
|
originalText: z.current?.text || null,
|
|
7570
7556
|
options: z.current?.options || null
|
|
7571
|
-
}, y.current.speechQueue.length = 0, y.current.pauseSpeaking(),
|
|
7557
|
+
}, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), le(!0), Y.current = !0;
|
|
7572
7558
|
}
|
|
7573
|
-
} catch (
|
|
7574
|
-
console.warn("Error pausing speech:",
|
|
7559
|
+
} catch (M) {
|
|
7560
|
+
console.warn("Error pausing speech:", M);
|
|
7575
7561
|
}
|
|
7576
|
-
}, []), Ae =
|
|
7577
|
-
if (!(!y.current || !
|
|
7562
|
+
}, []), Ae = B(async () => {
|
|
7563
|
+
if (!(!y.current || !te))
|
|
7578
7564
|
try {
|
|
7579
|
-
await
|
|
7580
|
-
const
|
|
7581
|
-
|
|
7582
|
-
} catch (
|
|
7583
|
-
console.warn("Error resuming speech:",
|
|
7565
|
+
await J(), le(!1), Y.current = !1;
|
|
7566
|
+
const M = k.current?.remainingText, ne = k.current?.originalText || z.current?.text, L = k.current?.options || z.current?.options || {}, N = M || ne;
|
|
7567
|
+
N && Q(N, L);
|
|
7568
|
+
} catch (M) {
|
|
7569
|
+
console.warn("Error resuming speech:", M), le(!1), Y.current = !1;
|
|
7584
7570
|
}
|
|
7585
|
-
}, [
|
|
7586
|
-
y.current && (y.current.stopSpeaking(), A.current && (clearInterval(A.current), A.current = null),
|
|
7571
|
+
}, [te, Q, J]), we = B(() => {
|
|
7572
|
+
y.current && (y.current.stopSpeaking(), A.current && (clearInterval(A.current), A.current = null), le(!1), Y.current = !1);
|
|
7587
7573
|
}, []);
|
|
7588
|
-
return Fe(
|
|
7589
|
-
speakText:
|
|
7590
|
-
pauseSpeaking:
|
|
7574
|
+
return Fe(F, () => ({
|
|
7575
|
+
speakText: Q,
|
|
7576
|
+
pauseSpeaking: K,
|
|
7591
7577
|
resumeSpeaking: Ae,
|
|
7592
7578
|
stopSpeaking: we,
|
|
7593
|
-
resumeAudioContext:
|
|
7594
|
-
isPaused: () =>
|
|
7595
|
-
setMood: (
|
|
7596
|
-
setBodyMovement: (
|
|
7597
|
-
y.current && y.current.setBodyMovement(
|
|
7579
|
+
resumeAudioContext: J,
|
|
7580
|
+
isPaused: () => te,
|
|
7581
|
+
setMood: (M) => y.current?.setMood(M),
|
|
7582
|
+
setBodyMovement: (M) => {
|
|
7583
|
+
y.current && y.current.setBodyMovement(M);
|
|
7598
7584
|
},
|
|
7599
|
-
playAnimation: (
|
|
7600
|
-
y.current && y.current.playAnimation && y.current.playAnimation(
|
|
7585
|
+
playAnimation: (M, ne = !1) => {
|
|
7586
|
+
y.current && y.current.playAnimation && y.current.playAnimation(M, null, 10, 0, 0.01, ne);
|
|
7601
7587
|
},
|
|
7602
|
-
playReaction: (
|
|
7588
|
+
playReaction: (M) => y.current?.playReaction(M),
|
|
7603
7589
|
playCelebration: () => y.current?.playCelebration(),
|
|
7604
|
-
setShowFullAvatar: (
|
|
7605
|
-
y.current && (I.current =
|
|
7590
|
+
setShowFullAvatar: (M) => {
|
|
7591
|
+
y.current && (I.current = M, y.current.setShowFullAvatar(M));
|
|
7606
7592
|
},
|
|
7607
|
-
isReady:
|
|
7593
|
+
isReady: ae,
|
|
7608
7594
|
talkingHead: y.current
|
|
7609
7595
|
})), /* @__PURE__ */ Pe("div", { className: `simple-talking-avatar-container ${x}`, style: S, children: [
|
|
7610
|
-
/* @__PURE__ */
|
|
7596
|
+
/* @__PURE__ */ me(
|
|
7611
7597
|
"div",
|
|
7612
7598
|
{
|
|
7613
|
-
ref:
|
|
7599
|
+
ref: C,
|
|
7614
7600
|
className: "talking-head-viewer",
|
|
7615
7601
|
style: {
|
|
7616
7602
|
width: "100%",
|
|
@@ -7619,7 +7605,7 @@ const gt = Me(({
|
|
|
7619
7605
|
}
|
|
7620
7606
|
}
|
|
7621
7607
|
),
|
|
7622
|
-
q && /* @__PURE__ */
|
|
7608
|
+
q && /* @__PURE__ */ me("div", { className: "loading-overlay", style: {
|
|
7623
7609
|
position: "absolute",
|
|
7624
7610
|
top: "50%",
|
|
7625
7611
|
left: "50%",
|
|
@@ -7628,7 +7614,7 @@ const gt = Me(({
|
|
|
7628
7614
|
fontSize: "18px",
|
|
7629
7615
|
zIndex: 10
|
|
7630
7616
|
}, children: "Loading avatar..." }),
|
|
7631
|
-
|
|
7617
|
+
ee && /* @__PURE__ */ me("div", { className: "error-overlay", style: {
|
|
7632
7618
|
position: "absolute",
|
|
7633
7619
|
top: "50%",
|
|
7634
7620
|
left: "50%",
|
|
@@ -7639,7 +7625,7 @@ const gt = Me(({
|
|
|
7639
7625
|
zIndex: 10,
|
|
7640
7626
|
padding: "20px",
|
|
7641
7627
|
borderRadius: "8px"
|
|
7642
|
-
}, children:
|
|
7628
|
+
}, children: ee })
|
|
7643
7629
|
] });
|
|
7644
7630
|
});
|
|
7645
7631
|
gt.displayName = "SimpleTalkingAvatar";
|
|
@@ -7659,7 +7645,7 @@ const yt = Me(({
|
|
|
7659
7645
|
},
|
|
7660
7646
|
autoStart: h = !1
|
|
7661
7647
|
}, r) => {
|
|
7662
|
-
const u =
|
|
7648
|
+
const u = O(null), a = O({
|
|
7663
7649
|
currentModuleIndex: 0,
|
|
7664
7650
|
currentLessonIndex: 0,
|
|
7665
7651
|
currentQuestionIndex: 0,
|
|
@@ -7669,18 +7655,18 @@ const yt = Me(({
|
|
|
7669
7655
|
curriculumCompleted: !1,
|
|
7670
7656
|
score: 0,
|
|
7671
7657
|
totalQuestions: 0
|
|
7672
|
-
}), d =
|
|
7658
|
+
}), d = O({
|
|
7673
7659
|
onLessonStart: n,
|
|
7674
7660
|
onLessonComplete: i,
|
|
7675
7661
|
onQuestionAnswer: s,
|
|
7676
7662
|
onCurriculumComplete: o,
|
|
7677
7663
|
onCustomAction: l
|
|
7678
|
-
}), c =
|
|
7664
|
+
}), c = O(null), g = O(null), b = O(null), x = O(null), S = O(null), U = O(null), p = O(null), F = O(X?.curriculum || {
|
|
7679
7665
|
title: "Default Curriculum",
|
|
7680
7666
|
description: "No curriculum data provided",
|
|
7681
7667
|
language: "en",
|
|
7682
7668
|
modules: []
|
|
7683
|
-
}),
|
|
7669
|
+
}), C = O({
|
|
7684
7670
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7685
7671
|
avatarBody: t.avatarBody || "F",
|
|
7686
7672
|
mood: t.mood || "happy",
|
|
@@ -7694,7 +7680,7 @@ const yt = Me(({
|
|
|
7694
7680
|
animations: e,
|
|
7695
7681
|
lipsyncLang: "en"
|
|
7696
7682
|
});
|
|
7697
|
-
|
|
7683
|
+
de(() => {
|
|
7698
7684
|
d.current = {
|
|
7699
7685
|
onLessonStart: n,
|
|
7700
7686
|
onLessonComplete: i,
|
|
@@ -7702,13 +7688,13 @@ const yt = Me(({
|
|
|
7702
7688
|
onCurriculumComplete: o,
|
|
7703
7689
|
onCustomAction: l
|
|
7704
7690
|
};
|
|
7705
|
-
}, [n, i, s, o, l]),
|
|
7706
|
-
|
|
7691
|
+
}, [n, i, s, o, l]), de(() => {
|
|
7692
|
+
F.current = X?.curriculum || {
|
|
7707
7693
|
title: "Default Curriculum",
|
|
7708
7694
|
description: "No curriculum data provided",
|
|
7709
7695
|
language: "en",
|
|
7710
7696
|
modules: []
|
|
7711
|
-
},
|
|
7697
|
+
}, C.current = {
|
|
7712
7698
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7713
7699
|
avatarBody: t.avatarBody || "F",
|
|
7714
7700
|
mood: t.mood || "happy",
|
|
@@ -7723,7 +7709,7 @@ const yt = Me(({
|
|
|
7723
7709
|
lipsyncLang: "en"
|
|
7724
7710
|
};
|
|
7725
7711
|
}, [X, t, e]);
|
|
7726
|
-
const y =
|
|
7712
|
+
const y = B(() => (F.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), I = B(() => y()?.questions[a.current.currentQuestionIndex], [y]), z = B((v, R) => R.type === "multiple_choice" || R.type === "true_false" ? v === R.answer : R.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), A = B(() => {
|
|
7727
7713
|
a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
|
|
7728
7714
|
const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
|
|
7729
7715
|
let R = "Congratulations! You've completed this lesson";
|
|
@@ -7747,9 +7733,9 @@ const yt = Me(({
|
|
|
7747
7733
|
} catch {
|
|
7748
7734
|
u.current.playCelebration();
|
|
7749
7735
|
}
|
|
7750
|
-
const
|
|
7736
|
+
const H = F.current || { modules: [] }, P = H.modules[a.current.currentModuleIndex], V = a.current.currentLessonIndex < (P?.lessons?.length || 0) - 1, J = a.current.currentModuleIndex < (H.modules?.length || 0) - 1, Q = V || J, K = C.current || { lipsyncLang: "en" };
|
|
7751
7737
|
u.current.speakText(R, {
|
|
7752
|
-
lipsyncLang:
|
|
7738
|
+
lipsyncLang: K.lipsyncLang,
|
|
7753
7739
|
onSpeechEnd: () => {
|
|
7754
7740
|
d.current.onCustomAction({
|
|
7755
7741
|
type: "lessonCompleteFeedbackDone",
|
|
@@ -7758,17 +7744,17 @@ const yt = Me(({
|
|
|
7758
7744
|
score: a.current.score,
|
|
7759
7745
|
totalQuestions: a.current.totalQuestions,
|
|
7760
7746
|
percentage: v,
|
|
7761
|
-
hasNextLesson:
|
|
7747
|
+
hasNextLesson: Q
|
|
7762
7748
|
});
|
|
7763
7749
|
}
|
|
7764
7750
|
});
|
|
7765
7751
|
}
|
|
7766
|
-
}, [e.lessonComplete]), Y =
|
|
7752
|
+
}, [e.lessonComplete]), Y = B(() => {
|
|
7767
7753
|
a.current.curriculumCompleted = !0;
|
|
7768
|
-
const v =
|
|
7754
|
+
const v = F.current || { modules: [] };
|
|
7769
7755
|
if (d.current.onCurriculumComplete({
|
|
7770
7756
|
modules: v.modules.length,
|
|
7771
|
-
totalLessons: v.modules.reduce((R,
|
|
7757
|
+
totalLessons: v.modules.reduce((R, H) => R + H.lessons.length, 0)
|
|
7772
7758
|
}), u.current) {
|
|
7773
7759
|
if (u.current.setMood("celebrating"), e.curriculumComplete)
|
|
7774
7760
|
try {
|
|
@@ -7776,10 +7762,10 @@ const yt = Me(({
|
|
|
7776
7762
|
} catch {
|
|
7777
7763
|
u.current.playCelebration();
|
|
7778
7764
|
}
|
|
7779
|
-
const R =
|
|
7765
|
+
const R = C.current || { lipsyncLang: "en" };
|
|
7780
7766
|
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 });
|
|
7781
7767
|
}
|
|
7782
|
-
}, [e.curriculumComplete]), k =
|
|
7768
|
+
}, [e.curriculumComplete]), k = B(() => {
|
|
7783
7769
|
const v = y();
|
|
7784
7770
|
a.current.isQuestionMode = !0, a.current.currentQuestionIndex = 0, a.current.totalQuestions = v?.questions?.length || 0, a.current.score = 0;
|
|
7785
7771
|
const R = I();
|
|
@@ -7792,31 +7778,31 @@ const yt = Me(({
|
|
|
7792
7778
|
question: R,
|
|
7793
7779
|
score: a.current.score
|
|
7794
7780
|
});
|
|
7795
|
-
const
|
|
7781
|
+
const H = () => {
|
|
7796
7782
|
if (!u.current || !R) return;
|
|
7797
7783
|
if (u.current.setMood("happy"), e.questionStart)
|
|
7798
7784
|
try {
|
|
7799
7785
|
u.current.playAnimation(e.questionStart, !0);
|
|
7800
|
-
} catch (
|
|
7801
|
-
console.warn("Failed to play questionStart animation:",
|
|
7786
|
+
} catch (V) {
|
|
7787
|
+
console.warn("Failed to play questionStart animation:", V);
|
|
7802
7788
|
}
|
|
7803
|
-
const
|
|
7804
|
-
R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang:
|
|
7789
|
+
const P = C.current || { lipsyncLang: "en" };
|
|
7790
|
+
R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: P.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: P.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: P.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: P.lipsyncLang });
|
|
7805
7791
|
};
|
|
7806
7792
|
if (u.current && u.current.isReady && R)
|
|
7807
|
-
|
|
7793
|
+
H();
|
|
7808
7794
|
else if (u.current && u.current.isReady) {
|
|
7809
|
-
const
|
|
7810
|
-
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang:
|
|
7795
|
+
const P = C.current || { lipsyncLang: "en" };
|
|
7796
|
+
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: P.lipsyncLang });
|
|
7811
7797
|
} else {
|
|
7812
|
-
const
|
|
7813
|
-
u.current && u.current.isReady && (clearInterval(
|
|
7798
|
+
const P = setInterval(() => {
|
|
7799
|
+
u.current && u.current.isReady && (clearInterval(P), R && H());
|
|
7814
7800
|
}, 100);
|
|
7815
7801
|
setTimeout(() => {
|
|
7816
|
-
clearInterval(
|
|
7802
|
+
clearInterval(P);
|
|
7817
7803
|
}, 5e3);
|
|
7818
7804
|
}
|
|
7819
|
-
}, [e.questionStart, y, I]),
|
|
7805
|
+
}, [e.questionStart, y, I]), E = B(() => {
|
|
7820
7806
|
const v = y();
|
|
7821
7807
|
if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
|
|
7822
7808
|
u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
|
|
@@ -7830,45 +7816,45 @@ const yt = Me(({
|
|
|
7830
7816
|
question: R,
|
|
7831
7817
|
score: a.current.score
|
|
7832
7818
|
});
|
|
7833
|
-
const
|
|
7819
|
+
const H = () => {
|
|
7834
7820
|
if (!u.current || !R) return;
|
|
7835
7821
|
if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7836
7822
|
try {
|
|
7837
7823
|
u.current.playAnimation(e.nextQuestion, !0);
|
|
7838
|
-
} catch (
|
|
7839
|
-
console.warn("Failed to play nextQuestion animation:",
|
|
7824
|
+
} catch (K) {
|
|
7825
|
+
console.warn("Failed to play nextQuestion animation:", K);
|
|
7840
7826
|
}
|
|
7841
|
-
const
|
|
7827
|
+
const P = C.current || { lipsyncLang: "en" }, J = y()?.questions?.length || 0, Q = a.current.currentQuestionIndex >= J - 1;
|
|
7842
7828
|
if (R.type === "code_test") {
|
|
7843
|
-
const
|
|
7844
|
-
u.current.speakText(
|
|
7845
|
-
lipsyncLang:
|
|
7829
|
+
const K = Q ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
|
|
7830
|
+
u.current.speakText(K, {
|
|
7831
|
+
lipsyncLang: P.lipsyncLang
|
|
7846
7832
|
});
|
|
7847
7833
|
} else if (R.type === "multiple_choice") {
|
|
7848
|
-
const
|
|
7849
|
-
u.current.speakText(
|
|
7850
|
-
lipsyncLang:
|
|
7834
|
+
const K = Q ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
|
|
7835
|
+
u.current.speakText(K, {
|
|
7836
|
+
lipsyncLang: P.lipsyncLang
|
|
7851
7837
|
});
|
|
7852
7838
|
} else if (R.type === "true_false") {
|
|
7853
|
-
const
|
|
7854
|
-
u.current.speakText(
|
|
7855
|
-
lipsyncLang:
|
|
7839
|
+
const K = Q ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
|
|
7840
|
+
u.current.speakText(K, {
|
|
7841
|
+
lipsyncLang: P.lipsyncLang
|
|
7856
7842
|
});
|
|
7857
7843
|
} else {
|
|
7858
|
-
const
|
|
7859
|
-
u.current.speakText(
|
|
7860
|
-
lipsyncLang:
|
|
7844
|
+
const K = Q ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
|
|
7845
|
+
u.current.speakText(K, {
|
|
7846
|
+
lipsyncLang: P.lipsyncLang
|
|
7861
7847
|
});
|
|
7862
7848
|
}
|
|
7863
7849
|
};
|
|
7864
7850
|
if (u.current && u.current.isReady && R)
|
|
7865
|
-
|
|
7851
|
+
H();
|
|
7866
7852
|
else if (R) {
|
|
7867
|
-
const
|
|
7868
|
-
u.current && u.current.isReady && (clearInterval(
|
|
7853
|
+
const P = setInterval(() => {
|
|
7854
|
+
u.current && u.current.isReady && (clearInterval(P), H());
|
|
7869
7855
|
}, 100);
|
|
7870
7856
|
setTimeout(() => {
|
|
7871
|
-
clearInterval(
|
|
7857
|
+
clearInterval(P);
|
|
7872
7858
|
}, 5e3);
|
|
7873
7859
|
}
|
|
7874
7860
|
} else
|
|
@@ -7879,16 +7865,16 @@ const yt = Me(({
|
|
|
7879
7865
|
totalQuestions: a.current.totalQuestions,
|
|
7880
7866
|
score: a.current.score
|
|
7881
7867
|
});
|
|
7882
|
-
}, [e.nextQuestion, y, I]), q =
|
|
7883
|
-
const v =
|
|
7868
|
+
}, [e.nextQuestion, y, I]), q = B(() => {
|
|
7869
|
+
const v = F.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
|
|
7884
7870
|
if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
|
|
7885
7871
|
a.current.currentLessonIndex += 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
7886
|
-
const
|
|
7872
|
+
const P = v.modules[a.current.currentModuleIndex], V = a.current.currentLessonIndex < (P?.lessons?.length || 0) - 1, J = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, Q = V || J;
|
|
7887
7873
|
d.current.onCustomAction({
|
|
7888
7874
|
type: "lessonStart",
|
|
7889
7875
|
moduleIndex: a.current.currentModuleIndex,
|
|
7890
7876
|
lessonIndex: a.current.currentLessonIndex,
|
|
7891
|
-
hasNextLesson:
|
|
7877
|
+
hasNextLesson: Q
|
|
7892
7878
|
}), d.current.onLessonStart({
|
|
7893
7879
|
moduleIndex: a.current.currentModuleIndex,
|
|
7894
7880
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7896,12 +7882,12 @@ const yt = Me(({
|
|
|
7896
7882
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7897
7883
|
} else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
|
|
7898
7884
|
a.current.currentModuleIndex += 1, a.current.currentLessonIndex = 0, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0;
|
|
7899
|
-
const
|
|
7885
|
+
const V = v.modules[a.current.currentModuleIndex], J = a.current.currentLessonIndex < (V?.lessons?.length || 0) - 1, Q = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, K = J || Q;
|
|
7900
7886
|
d.current.onCustomAction({
|
|
7901
7887
|
type: "lessonStart",
|
|
7902
7888
|
moduleIndex: a.current.currentModuleIndex,
|
|
7903
7889
|
lessonIndex: a.current.currentLessonIndex,
|
|
7904
|
-
hasNextLesson:
|
|
7890
|
+
hasNextLesson: K
|
|
7905
7891
|
}), d.current.onLessonStart({
|
|
7906
7892
|
moduleIndex: a.current.currentModuleIndex,
|
|
7907
7893
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7909,25 +7895,25 @@ const yt = Me(({
|
|
|
7909
7895
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7910
7896
|
} else
|
|
7911
7897
|
S.current && S.current();
|
|
7912
|
-
}, []),
|
|
7898
|
+
}, []), G = B(() => {
|
|
7913
7899
|
const v = y();
|
|
7914
7900
|
let R = null;
|
|
7915
7901
|
if (v?.avatar_script && v?.body) {
|
|
7916
|
-
const
|
|
7917
|
-
R = `${
|
|
7902
|
+
const H = v.avatar_script.trim(), P = v.body.trim(), V = H.match(/[.!?]$/) ? " " : ". ";
|
|
7903
|
+
R = `${H}${V}${P}`;
|
|
7918
7904
|
} else
|
|
7919
7905
|
R = v?.avatar_script || v?.body || null;
|
|
7920
7906
|
if (u.current && u.current.isReady && R) {
|
|
7921
7907
|
a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, u.current.setMood("happy");
|
|
7922
|
-
let
|
|
7908
|
+
let H = !1;
|
|
7923
7909
|
if (e.teaching)
|
|
7924
7910
|
try {
|
|
7925
|
-
u.current.playAnimation(e.teaching, !0),
|
|
7926
|
-
} catch (
|
|
7927
|
-
console.warn("Failed to play teaching animation:",
|
|
7911
|
+
u.current.playAnimation(e.teaching, !0), H = !0;
|
|
7912
|
+
} catch (V) {
|
|
7913
|
+
console.warn("Failed to play teaching animation:", V);
|
|
7928
7914
|
}
|
|
7929
|
-
|
|
7930
|
-
const
|
|
7915
|
+
H || u.current.setBodyMovement("gesturing");
|
|
7916
|
+
const P = C.current || { lipsyncLang: "en" };
|
|
7931
7917
|
d.current.onLessonStart({
|
|
7932
7918
|
moduleIndex: a.current.currentModuleIndex,
|
|
7933
7919
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7938,7 +7924,7 @@ const yt = Me(({
|
|
|
7938
7924
|
lessonIndex: a.current.currentLessonIndex,
|
|
7939
7925
|
lesson: v
|
|
7940
7926
|
}), u.current.speakText(R, {
|
|
7941
|
-
lipsyncLang:
|
|
7927
|
+
lipsyncLang: P.lipsyncLang,
|
|
7942
7928
|
onSpeechEnd: () => {
|
|
7943
7929
|
a.current.isTeaching = !1, d.current.onCustomAction({
|
|
7944
7930
|
type: "teachingComplete",
|
|
@@ -7956,17 +7942,17 @@ const yt = Me(({
|
|
|
7956
7942
|
}
|
|
7957
7943
|
});
|
|
7958
7944
|
}
|
|
7959
|
-
}, [e.teaching, y]),
|
|
7960
|
-
const R = I(),
|
|
7961
|
-
if (
|
|
7945
|
+
}, [e.teaching, y]), ee = B((v) => {
|
|
7946
|
+
const R = I(), H = z(v, R);
|
|
7947
|
+
if (H && (a.current.score += 1), d.current.onQuestionAnswer({
|
|
7962
7948
|
moduleIndex: a.current.currentModuleIndex,
|
|
7963
7949
|
lessonIndex: a.current.currentLessonIndex,
|
|
7964
7950
|
questionIndex: a.current.currentQuestionIndex,
|
|
7965
7951
|
answer: v,
|
|
7966
|
-
isCorrect:
|
|
7952
|
+
isCorrect: H,
|
|
7967
7953
|
question: R
|
|
7968
7954
|
}), u.current)
|
|
7969
|
-
if (
|
|
7955
|
+
if (H) {
|
|
7970
7956
|
if (u.current.setMood("happy"), e.correct)
|
|
7971
7957
|
try {
|
|
7972
7958
|
u.current.playReaction("happy");
|
|
@@ -7974,13 +7960,13 @@ const yt = Me(({
|
|
|
7974
7960
|
u.current.setBodyMovement("happy");
|
|
7975
7961
|
}
|
|
7976
7962
|
u.current.setBodyMovement("gesturing");
|
|
7977
|
-
const
|
|
7978
|
-
a.current.currentQuestionIndex >=
|
|
7979
|
-
const
|
|
7980
|
-
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
7981
|
-
const
|
|
7982
|
-
u.current.speakText(
|
|
7983
|
-
lipsyncLang:
|
|
7963
|
+
const V = y()?.questions?.length || 0;
|
|
7964
|
+
a.current.currentQuestionIndex >= V - 1;
|
|
7965
|
+
const J = a.current.currentQuestionIndex < V - 1;
|
|
7966
|
+
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", V, "hasNextQuestion:", J);
|
|
7967
|
+
const Q = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, K = C.current || { lipsyncLang: "en" };
|
|
7968
|
+
u.current.speakText(Q, {
|
|
7969
|
+
lipsyncLang: K.lipsyncLang,
|
|
7984
7970
|
onSpeechEnd: () => {
|
|
7985
7971
|
d.current.onCustomAction({
|
|
7986
7972
|
type: "answerFeedbackComplete",
|
|
@@ -7988,7 +7974,7 @@ const yt = Me(({
|
|
|
7988
7974
|
lessonIndex: a.current.currentLessonIndex,
|
|
7989
7975
|
questionIndex: a.current.currentQuestionIndex,
|
|
7990
7976
|
isCorrect: !0,
|
|
7991
|
-
hasNextQuestion:
|
|
7977
|
+
hasNextQuestion: J,
|
|
7992
7978
|
score: a.current.score,
|
|
7993
7979
|
totalQuestions: a.current.totalQuestions
|
|
7994
7980
|
});
|
|
@@ -8002,10 +7988,10 @@ const yt = Me(({
|
|
|
8002
7988
|
u.current.setBodyMovement("idle");
|
|
8003
7989
|
}
|
|
8004
7990
|
u.current.setBodyMovement("gesturing");
|
|
8005
|
-
const
|
|
8006
|
-
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
8007
|
-
const
|
|
8008
|
-
u.current.speakText(
|
|
7991
|
+
const V = y()?.questions?.length || 0, J = a.current.currentQuestionIndex >= V - 1, Q = a.current.currentQuestionIndex < V - 1;
|
|
7992
|
+
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", V, "hasNextQuestion:", Q);
|
|
7993
|
+
const K = 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 || ""}${J ? "" : " Let's move on to the next question."}`, Ae = C.current || { lipsyncLang: "en" };
|
|
7994
|
+
u.current.speakText(K, {
|
|
8009
7995
|
lipsyncLang: Ae.lipsyncLang,
|
|
8010
7996
|
onSpeechEnd: () => {
|
|
8011
7997
|
d.current.onCustomAction({
|
|
@@ -8014,7 +8000,7 @@ const yt = Me(({
|
|
|
8014
8000
|
lessonIndex: a.current.currentLessonIndex,
|
|
8015
8001
|
questionIndex: a.current.currentQuestionIndex,
|
|
8016
8002
|
isCorrect: !1,
|
|
8017
|
-
hasNextQuestion:
|
|
8003
|
+
hasNextQuestion: Q,
|
|
8018
8004
|
score: a.current.score,
|
|
8019
8005
|
totalQuestions: a.current.totalQuestions
|
|
8020
8006
|
});
|
|
@@ -8022,20 +8008,20 @@ const yt = Me(({
|
|
|
8022
8008
|
});
|
|
8023
8009
|
}
|
|
8024
8010
|
else {
|
|
8025
|
-
const
|
|
8011
|
+
const V = y()?.questions?.length || 0;
|
|
8026
8012
|
d.current.onCustomAction({
|
|
8027
8013
|
type: "answerFeedbackComplete",
|
|
8028
8014
|
moduleIndex: a.current.currentModuleIndex,
|
|
8029
8015
|
lessonIndex: a.current.currentLessonIndex,
|
|
8030
8016
|
questionIndex: a.current.currentQuestionIndex,
|
|
8031
|
-
isCorrect:
|
|
8032
|
-
hasNextQuestion: a.current.currentQuestionIndex <
|
|
8017
|
+
isCorrect: H,
|
|
8018
|
+
hasNextQuestion: a.current.currentQuestionIndex < V - 1,
|
|
8033
8019
|
score: a.current.score,
|
|
8034
8020
|
totalQuestions: a.current.totalQuestions,
|
|
8035
8021
|
avatarNotReady: !0
|
|
8036
8022
|
});
|
|
8037
8023
|
}
|
|
8038
|
-
}, [e.correct, e.incorrect, I, y, z]),
|
|
8024
|
+
}, [e.correct, e.incorrect, I, y, z]), se = B((v) => {
|
|
8039
8025
|
const R = I();
|
|
8040
8026
|
if (!v || typeof v != "object") {
|
|
8041
8027
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
@@ -8045,7 +8031,7 @@ const yt = Me(({
|
|
|
8045
8031
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
8046
8032
|
return;
|
|
8047
8033
|
}
|
|
8048
|
-
const
|
|
8034
|
+
const H = {
|
|
8049
8035
|
passed: v.passed === !0,
|
|
8050
8036
|
results: v.results || [],
|
|
8051
8037
|
output: v.output || "",
|
|
@@ -8060,10 +8046,10 @@ const yt = Me(({
|
|
|
8060
8046
|
moduleIndex: a.current.currentModuleIndex,
|
|
8061
8047
|
lessonIndex: a.current.currentLessonIndex,
|
|
8062
8048
|
questionIndex: a.current.currentQuestionIndex,
|
|
8063
|
-
testResult:
|
|
8049
|
+
testResult: H,
|
|
8064
8050
|
question: R
|
|
8065
|
-
}), p.current && p.current(
|
|
8066
|
-
}, [I, z]),
|
|
8051
|
+
}), p.current && p.current(H);
|
|
8052
|
+
}, [I, z]), ae = B(() => {
|
|
8067
8053
|
if (a.current.currentQuestionIndex > 0) {
|
|
8068
8054
|
a.current.currentQuestionIndex -= 1;
|
|
8069
8055
|
const v = I();
|
|
@@ -8079,26 +8065,26 @@ const yt = Me(({
|
|
|
8079
8065
|
const R = () => {
|
|
8080
8066
|
if (!u.current || !v) return;
|
|
8081
8067
|
u.current.setMood("happy"), u.current.setBodyMovement("idle");
|
|
8082
|
-
const
|
|
8068
|
+
const H = C.current || { lipsyncLang: "en" };
|
|
8083
8069
|
v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
|
|
8084
|
-
lipsyncLang:
|
|
8070
|
+
lipsyncLang: H.lipsyncLang
|
|
8085
8071
|
}) : u.current.speakText(`Going back to: ${v.question}`, {
|
|
8086
|
-
lipsyncLang:
|
|
8072
|
+
lipsyncLang: H.lipsyncLang
|
|
8087
8073
|
});
|
|
8088
8074
|
};
|
|
8089
8075
|
if (u.current && u.current.isReady && v)
|
|
8090
8076
|
R();
|
|
8091
8077
|
else if (v) {
|
|
8092
|
-
const
|
|
8093
|
-
u.current && u.current.isReady && (clearInterval(
|
|
8078
|
+
const H = setInterval(() => {
|
|
8079
|
+
u.current && u.current.isReady && (clearInterval(H), R());
|
|
8094
8080
|
}, 100);
|
|
8095
8081
|
setTimeout(() => {
|
|
8096
|
-
clearInterval(
|
|
8082
|
+
clearInterval(H);
|
|
8097
8083
|
}, 5e3);
|
|
8098
8084
|
}
|
|
8099
8085
|
}
|
|
8100
|
-
}, [I]),
|
|
8101
|
-
const v =
|
|
8086
|
+
}, [I]), pe = B(() => {
|
|
8087
|
+
const v = F.current || { modules: [] };
|
|
8102
8088
|
if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
|
|
8103
8089
|
a.current.currentLessonIndex -= 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, d.current.onCustomAction({
|
|
8104
8090
|
type: "lessonStart",
|
|
@@ -8110,8 +8096,8 @@ const yt = Me(({
|
|
|
8110
8096
|
lesson: y()
|
|
8111
8097
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8112
8098
|
else if (a.current.currentModuleIndex > 0) {
|
|
8113
|
-
const
|
|
8114
|
-
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (
|
|
8099
|
+
const P = v.modules[a.current.currentModuleIndex - 1];
|
|
8100
|
+
a.current.currentModuleIndex -= 1, a.current.currentLessonIndex = (P?.lessons?.length || 1) - 1, a.current.currentQuestionIndex = 0, a.current.lessonCompleted = !1, a.current.isQuestionMode = !1, a.current.isTeaching = !1, a.current.score = 0, a.current.totalQuestions = 0, d.current.onCustomAction({
|
|
8115
8101
|
type: "lessonStart",
|
|
8116
8102
|
moduleIndex: a.current.currentModuleIndex,
|
|
8117
8103
|
lessonIndex: a.current.currentLessonIndex
|
|
@@ -8121,30 +8107,30 @@ const yt = Me(({
|
|
|
8121
8107
|
lesson: y()
|
|
8122
8108
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8123
8109
|
}
|
|
8124
|
-
}, [y]),
|
|
8110
|
+
}, [y]), te = B(() => {
|
|
8125
8111
|
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;
|
|
8126
|
-
}, []),
|
|
8112
|
+
}, []), le = B((v) => {
|
|
8127
8113
|
console.log("Avatar is ready!", v);
|
|
8128
|
-
const R = y(),
|
|
8129
|
-
h &&
|
|
8114
|
+
const R = y(), H = R?.avatar_script || R?.body;
|
|
8115
|
+
h && H && setTimeout(() => {
|
|
8130
8116
|
c.current && c.current();
|
|
8131
8117
|
}, 10);
|
|
8132
8118
|
}, [h, y]);
|
|
8133
8119
|
Xe(() => {
|
|
8134
|
-
c.current =
|
|
8120
|
+
c.current = G, g.current = q, b.current = A, x.current = E, S.current = Y, U.current = k, p.current = ee;
|
|
8135
8121
|
}), Fe(r, () => ({
|
|
8136
8122
|
// Curriculum control methods
|
|
8137
|
-
startTeaching:
|
|
8123
|
+
startTeaching: G,
|
|
8138
8124
|
startQuestions: k,
|
|
8139
|
-
handleAnswerSelect:
|
|
8140
|
-
handleCodeTestResult:
|
|
8141
|
-
nextQuestion:
|
|
8142
|
-
previousQuestion:
|
|
8125
|
+
handleAnswerSelect: ee,
|
|
8126
|
+
handleCodeTestResult: se,
|
|
8127
|
+
nextQuestion: E,
|
|
8128
|
+
previousQuestion: ae,
|
|
8143
8129
|
nextLesson: q,
|
|
8144
|
-
previousLesson:
|
|
8130
|
+
previousLesson: pe,
|
|
8145
8131
|
completeLesson: A,
|
|
8146
8132
|
completeCurriculum: Y,
|
|
8147
|
-
resetCurriculum:
|
|
8133
|
+
resetCurriculum: te,
|
|
8148
8134
|
getState: () => ({ ...a.current }),
|
|
8149
8135
|
getCurrentQuestion: () => I(),
|
|
8150
8136
|
getCurrentLesson: () => y(),
|
|
@@ -8153,8 +8139,8 @@ const yt = Me(({
|
|
|
8153
8139
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8154
8140
|
speakText: async (v, R = {}) => {
|
|
8155
8141
|
await u.current?.resumeAudioContext?.();
|
|
8156
|
-
const
|
|
8157
|
-
u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang ||
|
|
8142
|
+
const H = C.current || { lipsyncLang: "en" };
|
|
8143
|
+
u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || H.lipsyncLang });
|
|
8158
8144
|
},
|
|
8159
8145
|
resumeAudioContext: async () => {
|
|
8160
8146
|
if (u.current?.resumeAudioContext)
|
|
@@ -8165,8 +8151,8 @@ const yt = Me(({
|
|
|
8165
8151
|
if (R.state === "suspended" || R.state === "interrupted")
|
|
8166
8152
|
try {
|
|
8167
8153
|
await R.resume(), console.log("Audio context resumed via talkingHead");
|
|
8168
|
-
} catch (
|
|
8169
|
-
console.warn("Failed to resume audio context:",
|
|
8154
|
+
} catch (H) {
|
|
8155
|
+
console.warn("Failed to resume audio context:", H);
|
|
8170
8156
|
}
|
|
8171
8157
|
} else
|
|
8172
8158
|
console.warn("Audio context not available yet");
|
|
@@ -8198,8 +8184,8 @@ const yt = Me(({
|
|
|
8198
8184
|
handleResize: () => u.current?.handleResize(),
|
|
8199
8185
|
// Avatar readiness check (always returns current value)
|
|
8200
8186
|
isAvatarReady: () => u.current?.isReady || !1
|
|
8201
|
-
}), [
|
|
8202
|
-
const
|
|
8187
|
+
}), [G, k, ee, se, E, q, A, Y, te, I, y]);
|
|
8188
|
+
const W = C.current || {
|
|
8203
8189
|
avatarUrl: "/avatars/brunette.glb",
|
|
8204
8190
|
avatarBody: "F",
|
|
8205
8191
|
mood: "happy",
|
|
@@ -8212,23 +8198,23 @@ const yt = Me(({
|
|
|
8212
8198
|
showFullAvatar: !1,
|
|
8213
8199
|
animations: e
|
|
8214
8200
|
};
|
|
8215
|
-
return /* @__PURE__ */
|
|
8201
|
+
return /* @__PURE__ */ me("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ me(
|
|
8216
8202
|
Ve,
|
|
8217
8203
|
{
|
|
8218
8204
|
ref: u,
|
|
8219
|
-
avatarUrl:
|
|
8220
|
-
avatarBody:
|
|
8221
|
-
mood:
|
|
8222
|
-
ttsLang:
|
|
8223
|
-
ttsService:
|
|
8224
|
-
ttsVoice:
|
|
8225
|
-
ttsApiKey:
|
|
8226
|
-
bodyMovement:
|
|
8227
|
-
movementIntensity:
|
|
8228
|
-
showFullAvatar:
|
|
8205
|
+
avatarUrl: W.avatarUrl,
|
|
8206
|
+
avatarBody: W.avatarBody,
|
|
8207
|
+
mood: W.mood,
|
|
8208
|
+
ttsLang: W.ttsLang,
|
|
8209
|
+
ttsService: W.ttsService,
|
|
8210
|
+
ttsVoice: W.ttsVoice,
|
|
8211
|
+
ttsApiKey: W.ttsApiKey,
|
|
8212
|
+
bodyMovement: W.bodyMovement,
|
|
8213
|
+
movementIntensity: W.movementIntensity,
|
|
8214
|
+
showFullAvatar: W.showFullAvatar,
|
|
8229
8215
|
cameraView: "upper",
|
|
8230
|
-
animations:
|
|
8231
|
-
onReady:
|
|
8216
|
+
animations: W.animations,
|
|
8217
|
+
onReady: le,
|
|
8232
8218
|
onLoading: () => {
|
|
8233
8219
|
},
|
|
8234
8220
|
onError: (v) => {
|