@sage-rsc/talking-head-react 1.1.9 → 1.2.0
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 +338 -332
- package/package.json +1 -1
- package/src/lib/talkinghead.mjs +23 -14
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs as Pe, jsx as pe } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as Me, useRef as
|
|
2
|
+
import { forwardRef as Me, useRef as V, useState as de, useEffect as me, useCallback as N, 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,8 +7,8 @@ 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, le, ue;
|
|
11
|
+
const w = [0, 0, 0, 0], F = new f.Vector3(), ze = new f.Vector3(), ae = new f.Vector3(), Ce = new f.Vector3();
|
|
12
12
|
new f.Plane();
|
|
13
13
|
new f.Ray();
|
|
14
14
|
new f.Euler();
|
|
@@ -321,7 +321,7 @@ class et {
|
|
|
321
321
|
/// Bone's parent object
|
|
322
322
|
vBasis: r.position.clone(),
|
|
323
323
|
// Original local position
|
|
324
|
-
vWorld: r.parent.getWorldPosition(
|
|
324
|
+
vWorld: r.parent.getWorldPosition(F).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(F, re, ae), F.copy(He).applyQuaternion(re).setY(0).normalize(), re.premultiply(Oe.setFromUnitVectors(He, F).invert()).normalize(), u.qWorldInverseYaw = re.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], F.copy(o.vWorld), fe.copy(o.boneParent.matrixWorld), xe.copy(fe).invert(), o.vWorld.setFromMatrixPosition(fe), F.applyMatrix4(xe), F.length() > 0.5 && (console.info("Info: Unrealistic jump of " + F.length().toFixed(2) + " meters."), F.setLength(0.5)), F.applyQuaternion(o.bone.quaternion), w[0] = F.x, w[1] = F.y, w[2] = -F.z, w[3] = F.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, F.set(
|
|
363
363
|
o.vBasis.x + w[0],
|
|
364
364
|
o.vBasis.y + w[1],
|
|
365
365
|
o.vBasis.z + w[2]
|
|
366
|
-
),
|
|
366
|
+
), F.applyMatrix4(fe), F.x += m[0], F.y += m[1], F.z += m[2], F.applyMatrix4(xe), w[0] += F.x - o.vBasis.x, w[1] += F.y - o.vBasis.y, w[2] += F.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(F, re, ae), F.copy(He).applyQuaternion(re).setY(0).normalize(), re.premultiply(Oe.setFromUnitVectors(He, F).invert()).normalize(), o.boneParent.quaternion.multiply(re.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(w[0] / o.l), re.setFromAxisAngle($e, -m), o.boneParent.quaternion.multiply(re)), 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), re.setFromAxisAngle(Ke, -m), o.boneParent.quaternion.multiply(re)), o.isT && (m = 1.5 * Math.tanh(w[3] * 1.5), re.setFromAxisAngle(Je, -m), o.boneParent.quaternion.multiply(re)), 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], ae.set(0, 0, 0), m.deltaLocal && (ae.x += m.deltaLocal[0], ae.y += m.deltaLocal[1], ae.z += m.deltaLocal[2]), ae.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ae.applyMatrix4(xe),
|
|
374
|
+
m = o.excludes[n], ae.set(0, 0, 0), m.deltaLocal && (ae.x += m.deltaLocal[0], ae.y += m.deltaLocal[1], ae.z += m.deltaLocal[2]), ae.applyMatrix4(m.bone.matrixWorld), xe.copy(o.boneParent.matrixWorld).invert(), ae.applyMatrix4(xe), F.copy(o.bone.position), !(F.distanceToSquared(ae) >= m.radiusSq) && (ue = F.length(), le = ae.length(), !(le > m.radius + ue) && (le < Math.abs(m.radius - ue) || (le = (le * le + ue * ue - m.radiusSq) / (2 * le), ae.normalize(), Ce.copy(ae).multiplyScalar(le), le = Math.sqrt(ue * ue - le * le), F.subVectors(F, Ce).projectOnPlane(ae).normalize().multiplyScalar(le), ze.subVectors(o.vBasis, Ce).projectOnPlane(ae).normalize(), ue = ze.dot(F), ue < 0 && (ue = Math.sqrt(le * le - ue * ue), ze.multiplyScalar(ue), F.add(ze)), F.add(Ce).normalize(), ae.copy(o.bone.position).normalize(), re.setFromUnitVectors(ae, F), o.boneParent.quaternion.premultiply(re), 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), F.setFromMatrixPosition(fe), t.setXYZ(e, F.x, F.y, F.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), F.setFromMatrixPosition(fe), t.setXYZ(n, F.x, F.y, F.z), fe.multiplyMatrices(xe, m.bones[e].parent.matrixWorld), F.setFromMatrixPosition(fe), t.setXYZ(n + 1, F.x, F.y, F.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
|
+
}, J = 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();
|
|
@@ -4398,9 +4398,9 @@ class Be {
|
|
|
4398
4398
|
updatePoseDelta() {
|
|
4399
4399
|
for (const [t, e] of Object.entries(this.poseDelta.props)) {
|
|
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 ? (J.setFromEuler(Z), n.multiply(J)) : n.isVector3 && n.add(Z);
|
|
4404
4404
|
}
|
|
4405
4405
|
}
|
|
4406
4406
|
/**
|
|
@@ -5172,7 +5172,7 @@ class Be {
|
|
|
5172
5172
|
}, i.x ? new f.Vector3(i.x, i.y, i.z) : null, !0, i.d);
|
|
5173
5173
|
break;
|
|
5174
5174
|
}
|
|
5175
|
-
if ((h || r) && (
|
|
5175
|
+
if ((h || r) && (Z.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), Z.x = Math.max(-0.9, Math.min(0.9, 2 * Z.x - 0.5)), Z.y = Math.max(-0.9, Math.min(0.9, -2.5 * Z.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: Z.x < 0 ? -Z.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: Z.x < 0 ? 0 : Z.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: Z.y < 0 ? -Z.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: Z.y < 0 ? 0 : Z.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: Z.y < 0 ? 0 : Z.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: Z.y < 0 ? -Z.y : 0, needsUpdate: !0 }), r && (n = -this.mtAvatar.bodyRotateY.value, i = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
|
|
5176
5176
|
name: "headmove",
|
|
5177
5177
|
dt: [[1e3, 2e3], [1e3, 2e3, 1, 2], [1e3, 2e3], [1e3, 2e3, 1, 2]],
|
|
5178
5178
|
vs: {
|
|
@@ -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 && (J.setFromAxisAngle(mt, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(J)), 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, G = b[x].match(l);
|
|
5268
5268
|
let p = b[x].match(s);
|
|
5269
|
-
const P = b[x].match(h),
|
|
5270
|
-
if (p && !S && !P && b[x + 1].match(s) && (p = !1), n && (u += b[x]),
|
|
5269
|
+
const P = b[x].match(h), H = b[x].match(o);
|
|
5270
|
+
if (p && !S && !P && b[x + 1].match(s) && (p = !1), n && (u += b[x]), G && (!i || i.every((y) => x < y[0] || x > y[1])) && (a += b[x]), (H || 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({
|
|
@@ -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, G = 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 * G / 3), S + Math.min(25, G / 2), S + G + Math.min(60, G / 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
|
}
|
|
@@ -5499,18 +5499,18 @@ class Be {
|
|
|
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
5501
|
for (let P = 0; P < x.visemes.length; P++) {
|
|
5502
|
-
const
|
|
5502
|
+
const H = x.visemes[P], y = x.times[P] / p, I = x.durations[P] / 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_" + H]: [null, H === "PP" || H === "FF" ? 0.9 : 0.6, 0]
|
|
5508
5508
|
}
|
|
5509
5509
|
});
|
|
5510
5510
|
}
|
|
5511
5511
|
}
|
|
5512
|
-
const
|
|
5513
|
-
this.audioPlaylist.push({ anim:
|
|
5512
|
+
const G = [...t.anim, ...S];
|
|
5513
|
+
this.audioPlaylist.push({ anim: G, 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,12 +6159,12 @@ 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), J.copy(this.armature.quaternion), J.multiply(this.poseTarget.props["Hips.quaternion"]), J.multiply(this.poseTarget.props["Spine.quaternion"]), J.multiply(this.poseTarget.props["Spine1.quaternion"]), J.multiply(this.poseTarget.props["Spine2.quaternion"]), J.multiply(this.poseTarget.props["Neck.quaternion"]), J.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
|
-
|
|
6165
|
-
const l = new f.Quaternion().setFromEuler(
|
|
6166
|
-
|
|
6167
|
-
let r =
|
|
6164
|
+
Z.set(s, i, 0, "YXZ");
|
|
6165
|
+
const l = new f.Quaternion().setFromEuler(Z), h = new f.Quaternion().copy(l).multiply(J.clone().invert());
|
|
6166
|
+
Z.setFromQuaternion(h, "YXZ");
|
|
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) {
|
|
6169
6169
|
let b = this.animQueue.findIndex((S) => S.template.name === "lookat");
|
|
6170
6170
|
b !== -1 && this.animQueue.splice(b, 1);
|
|
@@ -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),
|
|
6203
|
-
let u =
|
|
6202
|
+
t === null && (t = h), e === null && (e = r), J.copy(this.armature.quaternion), J.multiply(this.poseTarget.props["Hips.quaternion"]), J.multiply(this.poseTarget.props["Spine.quaternion"]), J.multiply(this.poseTarget.props["Spine1.quaternion"]), J.multiply(this.poseTarget.props["Spine2.quaternion"]), J.multiply(this.poseTarget.props["Neck.quaternion"]), J.multiply(this.poseTarget.props["Head.quaternion"]), Z.setFromQuaternion(J);
|
|
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 G = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
|
|
6206
6206
|
if (n) {
|
|
6207
6207
|
let P = this.animQueue.findIndex((y) => y.template.name === "lookat");
|
|
6208
6208
|
P !== -1 && this.animQueue.splice(P, 1);
|
|
6209
|
-
const
|
|
6209
|
+
const H = {
|
|
6210
6210
|
name: "lookat",
|
|
6211
6211
|
dt: [750, n],
|
|
6212
6212
|
vs: {
|
|
6213
|
-
bodyRotateX: [x +
|
|
6213
|
+
bodyRotateX: [x + G],
|
|
6214
6214
|
bodyRotateY: [S + p],
|
|
6215
|
-
eyesRotateX: [-3 *
|
|
6215
|
+
eyesRotateX: [-3 * G + 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(H));
|
|
6225
6225
|
}
|
|
6226
6226
|
}
|
|
6227
6227
|
/**
|
|
@@ -6474,7 +6474,7 @@ class Be {
|
|
|
6474
6474
|
return "LeftShoulder";
|
|
6475
6475
|
if (A.includes("right") && (A.includes("shoulder") || A.includes("clavicle")) && c.has("RightShoulder"))
|
|
6476
6476
|
return "RightShoulder";
|
|
6477
|
-
const
|
|
6477
|
+
const Y = {
|
|
6478
6478
|
// Arm bones - exact matches
|
|
6479
6479
|
LeftArm: "LeftArm",
|
|
6480
6480
|
leftArm: "LeftArm",
|
|
@@ -6514,8 +6514,8 @@ class Be {
|
|
|
6514
6514
|
Root: "Hips",
|
|
6515
6515
|
root: "Hips"
|
|
6516
6516
|
};
|
|
6517
|
-
if (
|
|
6518
|
-
const k =
|
|
6517
|
+
if (Y[z]) {
|
|
6518
|
+
const k = Y[z];
|
|
6519
6519
|
if (c.has(k))
|
|
6520
6520
|
return k;
|
|
6521
6521
|
}
|
|
@@ -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 C = k.toLowerCase();
|
|
6527
|
+
if ((A.includes("left") && C.includes("left") || A.includes("right") && C.includes("right")) && (A.includes("arm") && C.includes("arm") && !C.includes("fore") || A.includes("forearm") && C.includes("forearm") || A.includes("hand") && C.includes("hand") && !C.includes("index") && !C.includes("thumb") || A.includes("shoulder") && C.includes("shoulder")))
|
|
6528
6528
|
return k;
|
|
6529
6529
|
}
|
|
6530
6530
|
return null;
|
|
@@ -6535,34 +6535,40 @@ 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
|
+
), G = 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:",
|
|
6541
|
+
console.log("FBX arm/hand/shoulder bones:", S.sort().join(", ")), console.log("Avatar arm/hand/shoulder bones:", G.sort().join(", "));
|
|
6542
6542
|
const p = [], P = /* @__PURE__ */ new Set();
|
|
6543
6543
|
if (d.tracks.forEach((I) => {
|
|
6544
|
-
const A = I.name.replaceAll("mixamorig", "").split("."),
|
|
6545
|
-
if (
|
|
6546
|
-
const _ = `${
|
|
6544
|
+
const A = I.name.replaceAll("mixamorig", "").split("."), Y = A[0], k = A[1], C = b(Y);
|
|
6545
|
+
if (C && k) {
|
|
6546
|
+
const _ = `${C}.${k}`, B = I.clone();
|
|
6547
6547
|
B.name = _;
|
|
6548
|
-
const
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6548
|
+
const ee = C.includes("Arm") || C.includes("Hand") || C.includes("Shoulder");
|
|
6549
|
+
C.includes("Left"), C.includes("Right");
|
|
6550
|
+
const ie = C.includes("ForeArm") || C.includes("Forearm"), oe = C.includes("Hand") && !C.includes("Index") && !C.includes("Thumb") && !C.includes("Middle") && !C.includes("Ring") && !C.includes("Pinky");
|
|
6551
|
+
if (ee && (k === "quaternion" || k === "rotation") && k === "quaternion" && B.values && B.values.length >= 4) {
|
|
6552
|
+
const he = B.times.length;
|
|
6553
|
+
for (let K = 0; K < he; K++) {
|
|
6554
|
+
const Q = K * 4;
|
|
6555
|
+
if (Q + 3 < B.values.length) {
|
|
6556
|
+
let W = B.values[Q], v = B.values[Q + 1], R = B.values[Q + 2], T = B.values[Q + 3];
|
|
6557
|
+
const M = new f.Quaternion(W, v, R, T);
|
|
6558
|
+
if (oe) {
|
|
6559
|
+
const O = new f.Quaternion().setFromAxisAngle(new f.Vector3(0, 1, 0), Math.PI);
|
|
6560
|
+
M.multiply(O);
|
|
6561
|
+
} else if (ie) {
|
|
6562
|
+
const O = new f.Quaternion().setFromAxisAngle(new f.Vector3(0, 0, 1), Math.PI / 2);
|
|
6563
|
+
M.multiply(O);
|
|
6558
6564
|
}
|
|
6559
|
-
B.values[
|
|
6565
|
+
B.values[Q] = M.x, B.values[Q + 1] = M.y, B.values[Q + 2] = M.z, B.values[Q + 3] = M.w;
|
|
6560
6566
|
}
|
|
6561
6567
|
}
|
|
6562
6568
|
}
|
|
6563
|
-
p.push(B),
|
|
6569
|
+
p.push(B), Y !== C && g.set(Y, C);
|
|
6564
6570
|
} else
|
|
6565
|
-
P.add(
|
|
6571
|
+
P.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`);
|
|
6566
6572
|
}), P.size > 0 && console.warn(`⚠️ ${P.size} bone(s) could not be mapped:`, Array.from(P).sort().join(", ")), p.length > 0) {
|
|
6567
6573
|
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(
|
|
6568
6574
|
`✓ Mapped ${g.size} bone(s):`,
|
|
@@ -6574,18 +6580,18 @@ class Be {
|
|
|
6574
6580
|
I.length > 0 ? console.log(`✓ Arm bones mapped: ${I.join(", ")}`) : console.warn("⚠️ No arm bones were mapped! This may cause arm rigging issues.");
|
|
6575
6581
|
} else
|
|
6576
6582
|
console.error("❌ No tracks could be mapped! Animation may not work correctly.");
|
|
6577
|
-
const
|
|
6583
|
+
const H = {};
|
|
6578
6584
|
d.tracks.forEach((I) => {
|
|
6579
6585
|
I.name = I.name.replaceAll("mixamorig", "");
|
|
6580
6586
|
const z = I.name.split(".");
|
|
6581
6587
|
if (z[1] === "position") {
|
|
6582
6588
|
for (let A = 0; A < I.values.length; A++)
|
|
6583
6589
|
I.values[A] = I.values[A] * s;
|
|
6584
|
-
|
|
6585
|
-
} else z[1] === "quaternion" ?
|
|
6590
|
+
H[I.name] = new f.Vector3(I.values[0], I.values[1], I.values[2]);
|
|
6591
|
+
} else z[1] === "quaternion" ? H[I.name] = new f.Quaternion(I.values[0], I.values[1], I.values[2], I.values[3]) : z[1] === "rotation" && (H[z[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(I.values[0], I.values[1], I.values[2], "XYZ")).normalize());
|
|
6586
6592
|
});
|
|
6587
|
-
const y = { props:
|
|
6588
|
-
|
|
6593
|
+
const y = { props: H };
|
|
6594
|
+
H["Hips.position"] && (H["Hips.position"].y < 0.5 ? y.lying = !0 : y.standing = !0), this.animClips.push({
|
|
6589
6595
|
url: t + "-" + i,
|
|
6590
6596
|
clip: d,
|
|
6591
6597
|
pose: y
|
|
@@ -6723,12 +6729,12 @@ class Be {
|
|
|
6723
6729
|
const x = t.iterations || 10;
|
|
6724
6730
|
if (e)
|
|
6725
6731
|
for (let S = 0; S < x; S++) {
|
|
6726
|
-
let
|
|
6732
|
+
let G = !1;
|
|
6727
6733
|
for (let p = 0, P = b.length; p < P; p++) {
|
|
6728
|
-
const
|
|
6729
|
-
|
|
6734
|
+
const H = b[p].bone;
|
|
6735
|
+
H.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();
|
|
6730
6736
|
let y = s.dot(l);
|
|
6731
|
-
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(),
|
|
6737
|
+
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(), J.setFromAxisAngle(a, y), H.quaternion.multiply(J), H.rotation.setFromVector3(d.setFromEuler(H.rotation).clamp(new f.Vector3(
|
|
6732
6738
|
b[p].minx !== void 0 ? b[p].minx : -1 / 0,
|
|
6733
6739
|
b[p].miny !== void 0 ? b[p].miny : -1 / 0,
|
|
6734
6740
|
b[p].minz !== void 0 ? b[p].minz : -1 / 0
|
|
@@ -6736,9 +6742,9 @@ class Be {
|
|
|
6736
6742
|
b[p].maxx !== void 0 ? b[p].maxx : 1 / 0,
|
|
6737
6743
|
b[p].maxy !== void 0 ? b[p].maxy : 1 / 0,
|
|
6738
6744
|
b[p].maxz !== void 0 ? b[p].maxz : 1 / 0
|
|
6739
|
-
))),
|
|
6745
|
+
))), H.updateMatrixWorld(!0), G = !0);
|
|
6740
6746
|
}
|
|
6741
|
-
if (!
|
|
6747
|
+
if (!G) break;
|
|
6742
6748
|
}
|
|
6743
6749
|
i && b.forEach((S) => {
|
|
6744
6750
|
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;
|
|
@@ -6801,16 +6807,16 @@ function Ee() {
|
|
|
6801
6807
|
};
|
|
6802
6808
|
}
|
|
6803
6809
|
function kt() {
|
|
6804
|
-
const
|
|
6805
|
-
return Object.entries(
|
|
6810
|
+
const X = Ee(), t = [];
|
|
6811
|
+
return Object.entries(X.voices).forEach(([e, n]) => {
|
|
6806
6812
|
t.push({
|
|
6807
6813
|
value: n,
|
|
6808
|
-
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${
|
|
6814
|
+
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${X.service})`
|
|
6809
6815
|
});
|
|
6810
6816
|
}), t;
|
|
6811
6817
|
}
|
|
6812
6818
|
const Ve = Me(({
|
|
6813
|
-
avatarUrl:
|
|
6819
|
+
avatarUrl: X = "/avatars/brunette.glb",
|
|
6814
6820
|
avatarBody: t = "F",
|
|
6815
6821
|
mood: e = "neutral",
|
|
6816
6822
|
ttsLang: n = "en",
|
|
@@ -6831,72 +6837,72 @@ const Ve = Me(({
|
|
|
6831
6837
|
style: b = {},
|
|
6832
6838
|
animations: x = {}
|
|
6833
6839
|
}, S) => {
|
|
6834
|
-
const
|
|
6840
|
+
const G = V(null), p = V(null), P = V(r), H = V(null), y = V(null), I = V(!1), z = V({ remainingText: null, originalText: null, options: null }), A = V([]), Y = V(0), [k, C] = de(!0), [_, B] = de(null), [ee, ie] = de(!1), [oe, he] = de(!1);
|
|
6835
6841
|
me(() => {
|
|
6836
6842
|
I.current = oe;
|
|
6837
6843
|
}, [oe]), me(() => {
|
|
6838
6844
|
P.current = r;
|
|
6839
6845
|
}, [r]);
|
|
6840
|
-
const
|
|
6841
|
-
let
|
|
6842
|
-
|
|
6846
|
+
const K = Ee(), Q = i || K.service;
|
|
6847
|
+
let W;
|
|
6848
|
+
Q === "browser" ? W = {
|
|
6843
6849
|
service: "browser",
|
|
6844
6850
|
endpoint: "",
|
|
6845
6851
|
apiKey: null,
|
|
6846
6852
|
defaultVoice: "Google US English"
|
|
6847
|
-
} :
|
|
6853
|
+
} : Q === "elevenlabs" ? W = {
|
|
6848
6854
|
service: "elevenlabs",
|
|
6849
6855
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6850
|
-
apiKey: o ||
|
|
6851
|
-
defaultVoice: s ||
|
|
6852
|
-
voices:
|
|
6853
|
-
} :
|
|
6856
|
+
apiKey: o || K.apiKey,
|
|
6857
|
+
defaultVoice: s || K.defaultVoice || Ie.defaultVoice,
|
|
6858
|
+
voices: K.voices || Ie.voices
|
|
6859
|
+
} : Q === "deepgram" ? W = {
|
|
6854
6860
|
service: "deepgram",
|
|
6855
6861
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
6856
|
-
apiKey: o ||
|
|
6857
|
-
defaultVoice: s ||
|
|
6858
|
-
voices:
|
|
6859
|
-
} :
|
|
6860
|
-
...
|
|
6862
|
+
apiKey: o || K.apiKey,
|
|
6863
|
+
defaultVoice: s || K.defaultVoice || Te.defaultVoice,
|
|
6864
|
+
voices: K.voices || Te.voices
|
|
6865
|
+
} : W = {
|
|
6866
|
+
...K,
|
|
6861
6867
|
// Override API key if provided via props
|
|
6862
|
-
apiKey: o !== null ? o :
|
|
6868
|
+
apiKey: o !== null ? o : K.apiKey
|
|
6863
6869
|
};
|
|
6864
6870
|
const v = {
|
|
6865
|
-
url:
|
|
6871
|
+
url: X,
|
|
6866
6872
|
body: t,
|
|
6867
6873
|
avatarMood: e,
|
|
6868
|
-
ttsLang:
|
|
6869
|
-
ttsVoice: s ||
|
|
6874
|
+
ttsLang: Q === "browser" ? "en-US" : n,
|
|
6875
|
+
ttsVoice: s || W.defaultVoice,
|
|
6870
6876
|
lipsyncLang: "en",
|
|
6871
6877
|
showFullAvatar: r,
|
|
6872
6878
|
bodyMovement: l,
|
|
6873
6879
|
movementIntensity: h
|
|
6874
6880
|
}, R = {
|
|
6875
|
-
ttsEndpoint:
|
|
6876
|
-
ttsApikey:
|
|
6877
|
-
ttsService:
|
|
6881
|
+
ttsEndpoint: W.endpoint,
|
|
6882
|
+
ttsApikey: W.apiKey,
|
|
6883
|
+
ttsService: Q,
|
|
6878
6884
|
lipsyncModules: ["en"],
|
|
6879
6885
|
cameraView: u
|
|
6880
|
-
},
|
|
6881
|
-
if (!(!
|
|
6886
|
+
}, T = N(async () => {
|
|
6887
|
+
if (!(!G.current || p.current))
|
|
6882
6888
|
try {
|
|
6883
|
-
if (
|
|
6889
|
+
if (C(!0), B(null), p.current = new Be(G.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, (U) => {
|
|
6884
6890
|
if (U.lengthComputable) {
|
|
6885
|
-
const
|
|
6886
|
-
d(
|
|
6891
|
+
const ne = Math.min(100, Math.round(U.loaded / U.total * 100));
|
|
6892
|
+
d(ne);
|
|
6887
6893
|
}
|
|
6888
6894
|
}), await new Promise((U) => {
|
|
6889
|
-
const
|
|
6890
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? U() : setTimeout(
|
|
6895
|
+
const ne = () => {
|
|
6896
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? U() : setTimeout(ne, 100);
|
|
6891
6897
|
};
|
|
6892
|
-
|
|
6898
|
+
ne();
|
|
6893
6899
|
}), p.current && p.current.setShowFullAvatar)
|
|
6894
6900
|
try {
|
|
6895
6901
|
p.current.setShowFullAvatar(r);
|
|
6896
6902
|
} catch (U) {
|
|
6897
6903
|
console.warn("Error setting full body mode on initialization:", U);
|
|
6898
6904
|
}
|
|
6899
|
-
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()),
|
|
6905
|
+
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()), C(!1), ie(!0), a(p.current);
|
|
6900
6906
|
const D = () => {
|
|
6901
6907
|
document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
|
|
6902
6908
|
};
|
|
@@ -6904,25 +6910,25 @@ const Ve = Me(({
|
|
|
6904
6910
|
document.removeEventListener("visibilitychange", D);
|
|
6905
6911
|
};
|
|
6906
6912
|
} catch (L) {
|
|
6907
|
-
console.error("Error initializing TalkingHead:", L), B(L.message || "Failed to initialize avatar"),
|
|
6913
|
+
console.error("Error initializing TalkingHead:", L), B(L.message || "Failed to initialize avatar"), C(!1), c(L);
|
|
6908
6914
|
}
|
|
6909
|
-
}, [
|
|
6910
|
-
me(() => (
|
|
6915
|
+
}, [X, t, e, n, i, s, o, r, l, h, u]);
|
|
6916
|
+
me(() => (T(), () => {
|
|
6911
6917
|
p.current && (p.current.stop(), p.current.dispose(), p.current = null);
|
|
6912
|
-
}), [
|
|
6913
|
-
if (!
|
|
6918
|
+
}), [T]), me(() => {
|
|
6919
|
+
if (!G.current || !p.current) return;
|
|
6914
6920
|
const L = new ResizeObserver((U) => {
|
|
6915
|
-
for (const
|
|
6921
|
+
for (const ne of U)
|
|
6916
6922
|
p.current && p.current.onResize && p.current.onResize();
|
|
6917
6923
|
});
|
|
6918
|
-
L.observe(
|
|
6924
|
+
L.observe(G.current);
|
|
6919
6925
|
const D = () => {
|
|
6920
6926
|
p.current && p.current.onResize && p.current.onResize();
|
|
6921
6927
|
};
|
|
6922
6928
|
return window.addEventListener("resize", D), () => {
|
|
6923
6929
|
L.disconnect(), window.removeEventListener("resize", D);
|
|
6924
6930
|
};
|
|
6925
|
-
}, [
|
|
6931
|
+
}, [ee]);
|
|
6926
6932
|
const M = N(async () => {
|
|
6927
6933
|
if (p.current && p.current.audioCtx)
|
|
6928
6934
|
try {
|
|
@@ -6930,18 +6936,18 @@ const Ve = Me(({
|
|
|
6930
6936
|
} catch (L) {
|
|
6931
6937
|
console.warn("Failed to resume audio context:", L);
|
|
6932
6938
|
}
|
|
6933
|
-
}, []),
|
|
6934
|
-
if (p.current &&
|
|
6939
|
+
}, []), O = N(async (L, D = {}) => {
|
|
6940
|
+
if (p.current && ee)
|
|
6935
6941
|
try {
|
|
6936
|
-
y.current && (clearInterval(y.current), y.current = null),
|
|
6937
|
-
const U = /[!\.\?\n\p{Extended_Pictographic}]/ug,
|
|
6938
|
-
A.current =
|
|
6942
|
+
y.current && (clearInterval(y.current), y.current = null), H.current = { text: L, options: D }, z.current = { remainingText: null, originalText: null, options: null };
|
|
6943
|
+
const U = /[!\.\?\n\p{Extended_Pictographic}]/ug, ne = L.split(U).map((j) => j.trim()).filter((j) => j.length > 0);
|
|
6944
|
+
A.current = ne, Y.current = 0, he(!1), I.current = !1, await M();
|
|
6939
6945
|
const ge = {
|
|
6940
6946
|
...D,
|
|
6941
6947
|
lipsyncLang: D.lipsyncLang || v.lipsyncLang || "en"
|
|
6942
6948
|
};
|
|
6943
6949
|
if (D.onSpeechEnd && p.current) {
|
|
6944
|
-
const
|
|
6950
|
+
const j = p.current;
|
|
6945
6951
|
let ce = null, Se = 0;
|
|
6946
6952
|
const Le = 1200;
|
|
6947
6953
|
let be = !1;
|
|
@@ -6959,9 +6965,9 @@ const Ve = Me(({
|
|
|
6959
6965
|
}
|
|
6960
6966
|
return;
|
|
6961
6967
|
}
|
|
6962
|
-
const ye = !
|
|
6963
|
-
|
|
6964
|
-
if (
|
|
6968
|
+
const ye = !j.speechQueue || j.speechQueue.length === 0, ke = !j.audioPlaylist || j.audioPlaylist.length === 0;
|
|
6969
|
+
j && j.isSpeaking === !1 && ye && ke && j.isAudioPlaying === !1 && !be && !I.current && setTimeout(() => {
|
|
6970
|
+
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) {
|
|
6965
6971
|
be = !0, ce && (clearInterval(ce), ce = null, y.current = null);
|
|
6966
6972
|
try {
|
|
6967
6973
|
D.onSpeechEnd();
|
|
@@ -6978,51 +6984,51 @@ const Ve = Me(({
|
|
|
6978
6984
|
} catch (U) {
|
|
6979
6985
|
console.error("Error speaking text:", U), B(U.message || "Failed to speak text");
|
|
6980
6986
|
}
|
|
6981
|
-
}, [
|
|
6982
|
-
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1),
|
|
6987
|
+
}, [ee, M, v.lipsyncLang]), te = N(() => {
|
|
6988
|
+
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1), H.current = null, he(!1));
|
|
6983
6989
|
}, []), q = N(() => {
|
|
6984
6990
|
if (p.current && p.current.pauseSpeaking) {
|
|
6985
6991
|
const L = p.current;
|
|
6986
6992
|
if (L.isSpeaking || L.audioPlaylist && L.audioPlaylist.length > 0 || L.speechQueue && L.speechQueue.length > 0) {
|
|
6987
6993
|
y.current && (clearInterval(y.current), y.current = null);
|
|
6988
6994
|
let U = "";
|
|
6989
|
-
if (
|
|
6990
|
-
const
|
|
6991
|
-
if (ce > 0 && Se <
|
|
6995
|
+
if (H.current && A.current.length > 0) {
|
|
6996
|
+
const ne = 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, ce = ge + (j ? 1 : 0), Se = ne - ce;
|
|
6997
|
+
if (ce > 0 && Se < ne && (U = A.current.slice(Se).join(". ").trim(), !U && ge > 0 && L.speechQueue)) {
|
|
6992
6998
|
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(" ");
|
|
6993
6999
|
be && be.trim() && (U = be.trim());
|
|
6994
7000
|
}
|
|
6995
7001
|
}
|
|
6996
|
-
|
|
7002
|
+
H.current && (z.current = {
|
|
6997
7003
|
remainingText: U || null,
|
|
6998
|
-
originalText:
|
|
6999
|
-
options:
|
|
7000
|
-
}), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), I.current = !0,
|
|
7004
|
+
originalText: H.current.text,
|
|
7005
|
+
options: H.current.options
|
|
7006
|
+
}), L.speechQueue && (L.speechQueue.length = 0), p.current.pauseSpeaking(), I.current = !0, he(!0);
|
|
7001
7007
|
}
|
|
7002
7008
|
}
|
|
7003
|
-
}, []),
|
|
7009
|
+
}, []), $ = N(async () => {
|
|
7004
7010
|
if (!p.current || !oe)
|
|
7005
7011
|
return;
|
|
7006
7012
|
let L = "", D = {};
|
|
7007
7013
|
if (z.current && z.current.remainingText)
|
|
7008
7014
|
L = z.current.remainingText, D = z.current.options || {}, z.current = { remainingText: null, originalText: null, options: null };
|
|
7009
|
-
else if (
|
|
7010
|
-
L =
|
|
7015
|
+
else if (H.current && H.current.text)
|
|
7016
|
+
L = H.current.text, D = H.current.options || {};
|
|
7011
7017
|
else {
|
|
7012
|
-
console.warn("Resume called but no paused speech found"),
|
|
7018
|
+
console.warn("Resume called but no paused speech found"), he(!1), I.current = !1;
|
|
7013
7019
|
return;
|
|
7014
7020
|
}
|
|
7015
|
-
|
|
7021
|
+
he(!1), I.current = !1, await M();
|
|
7016
7022
|
const U = {
|
|
7017
7023
|
...D,
|
|
7018
7024
|
lipsyncLang: D.lipsyncLang || v.lipsyncLang || "en"
|
|
7019
7025
|
};
|
|
7020
7026
|
try {
|
|
7021
|
-
await
|
|
7022
|
-
} catch (
|
|
7023
|
-
console.error("Error resuming speech:",
|
|
7027
|
+
await O(L, U);
|
|
7028
|
+
} catch (ne) {
|
|
7029
|
+
console.error("Error resuming speech:", ne), he(!1), I.current = !1;
|
|
7024
7030
|
}
|
|
7025
|
-
}, [M, oe,
|
|
7031
|
+
}, [M, oe, O, v]), Ae = N((L) => {
|
|
7026
7032
|
p.current && p.current.setMood(L);
|
|
7027
7033
|
}, []), we = N((L) => {
|
|
7028
7034
|
p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
|
|
@@ -7031,14 +7037,14 @@ const Ve = Me(({
|
|
|
7031
7037
|
if (x && x[L] && (L = x[L]), p.current.setShowFullAvatar)
|
|
7032
7038
|
try {
|
|
7033
7039
|
p.current.setShowFullAvatar(P.current);
|
|
7034
|
-
} catch (
|
|
7035
|
-
console.warn("Error setting full body mode:",
|
|
7040
|
+
} catch (ne) {
|
|
7041
|
+
console.warn("Error setting full body mode:", ne);
|
|
7036
7042
|
}
|
|
7037
7043
|
if (L.includes("."))
|
|
7038
7044
|
try {
|
|
7039
7045
|
p.current.playAnimation(L, null, 10, 0, 0.01, D);
|
|
7040
|
-
} catch (
|
|
7041
|
-
console.warn(`Failed to play ${L}:`,
|
|
7046
|
+
} catch (ne) {
|
|
7047
|
+
console.warn(`Failed to play ${L}:`, ne);
|
|
7042
7048
|
try {
|
|
7043
7049
|
p.current.setBodyMovement("idle");
|
|
7044
7050
|
} catch (ge) {
|
|
@@ -7046,11 +7052,11 @@ const Ve = Me(({
|
|
|
7046
7052
|
}
|
|
7047
7053
|
}
|
|
7048
7054
|
else {
|
|
7049
|
-
const
|
|
7055
|
+
const ne = [".fbx", ".glb", ".gltf"];
|
|
7050
7056
|
let ge = !1;
|
|
7051
|
-
for (const
|
|
7057
|
+
for (const j of ne)
|
|
7052
7058
|
try {
|
|
7053
|
-
p.current.playAnimation(L +
|
|
7059
|
+
p.current.playAnimation(L + j, null, 10, 0, 0.01, D), ge = !0;
|
|
7054
7060
|
break;
|
|
7055
7061
|
} catch {
|
|
7056
7062
|
}
|
|
@@ -7058,8 +7064,8 @@ const Ve = Me(({
|
|
|
7058
7064
|
console.warn("Animation not found:", L);
|
|
7059
7065
|
try {
|
|
7060
7066
|
p.current.setBodyMovement("idle");
|
|
7061
|
-
} catch (
|
|
7062
|
-
console.warn("Fallback animation also failed:",
|
|
7067
|
+
} catch (j) {
|
|
7068
|
+
console.warn("Fallback animation also failed:", j);
|
|
7063
7069
|
}
|
|
7064
7070
|
}
|
|
7065
7071
|
}
|
|
@@ -7068,15 +7074,15 @@ const Ve = Me(({
|
|
|
7068
7074
|
p.current && p.current.onResize && p.current.onResize();
|
|
7069
7075
|
}, []);
|
|
7070
7076
|
return Fe(S, () => ({
|
|
7071
|
-
speakText:
|
|
7072
|
-
stopSpeaking:
|
|
7077
|
+
speakText: O,
|
|
7078
|
+
stopSpeaking: te,
|
|
7073
7079
|
pauseSpeaking: q,
|
|
7074
|
-
resumeSpeaking:
|
|
7080
|
+
resumeSpeaking: $,
|
|
7075
7081
|
resumeAudioContext: M,
|
|
7076
7082
|
setMood: Ae,
|
|
7077
7083
|
setTimingAdjustment: we,
|
|
7078
7084
|
playAnimation: E,
|
|
7079
|
-
isReady:
|
|
7085
|
+
isReady: ee,
|
|
7080
7086
|
isPaused: oe,
|
|
7081
7087
|
talkingHead: p.current,
|
|
7082
7088
|
handleResize: se,
|
|
@@ -7151,7 +7157,7 @@ const Ve = Me(({
|
|
|
7151
7157
|
/* @__PURE__ */ pe(
|
|
7152
7158
|
"div",
|
|
7153
7159
|
{
|
|
7154
|
-
ref:
|
|
7160
|
+
ref: G,
|
|
7155
7161
|
className: "talking-head-viewer",
|
|
7156
7162
|
style: {
|
|
7157
7163
|
width: "100%",
|
|
@@ -7187,7 +7193,7 @@ const Ve = Me(({
|
|
|
7187
7193
|
});
|
|
7188
7194
|
Ve.displayName = "TalkingHeadAvatar";
|
|
7189
7195
|
const pt = Me(({
|
|
7190
|
-
text:
|
|
7196
|
+
text: X = "Hello! I'm a talking avatar. How are you today?",
|
|
7191
7197
|
onLoading: t = () => {
|
|
7192
7198
|
},
|
|
7193
7199
|
onError: e = () => {
|
|
@@ -7198,7 +7204,7 @@ const pt = Me(({
|
|
|
7198
7204
|
style: s = {},
|
|
7199
7205
|
avatarConfig: o = {}
|
|
7200
7206
|
}, l) => {
|
|
7201
|
-
const h =
|
|
7207
|
+
const h = V(null), r = V(null), [u, a] = de(!0), [d, c] = de(null), [g, b] = de(!1), x = Ee(), S = o.ttsService || x.service, G = S === "browser" ? {
|
|
7202
7208
|
endpoint: "",
|
|
7203
7209
|
apiKey: null,
|
|
7204
7210
|
defaultVoice: "Google US English"
|
|
@@ -7214,7 +7220,7 @@ const pt = Me(({
|
|
|
7214
7220
|
body: "F",
|
|
7215
7221
|
avatarMood: "neutral",
|
|
7216
7222
|
ttsLang: S === "browser" ? "en-US" : "en",
|
|
7217
|
-
ttsVoice: o.ttsVoice ||
|
|
7223
|
+
ttsVoice: o.ttsVoice || G.defaultVoice,
|
|
7218
7224
|
lipsyncLang: "en",
|
|
7219
7225
|
// English lip-sync
|
|
7220
7226
|
showFullAvatar: !0,
|
|
@@ -7223,12 +7229,12 @@ const pt = Me(({
|
|
|
7223
7229
|
movementIntensity: 0.5,
|
|
7224
7230
|
...o
|
|
7225
7231
|
}, P = {
|
|
7226
|
-
ttsEndpoint:
|
|
7227
|
-
ttsApikey:
|
|
7232
|
+
ttsEndpoint: G.endpoint,
|
|
7233
|
+
ttsApikey: G.apiKey,
|
|
7228
7234
|
ttsService: S,
|
|
7229
7235
|
lipsyncModules: ["en"],
|
|
7230
7236
|
cameraView: "upper"
|
|
7231
|
-
},
|
|
7237
|
+
}, H = N(async () => {
|
|
7232
7238
|
if (!(!h.current || r.current))
|
|
7233
7239
|
try {
|
|
7234
7240
|
if (a(!0), c(null), r.current = new Be(h.current, P), await r.current.showAvatar(p, (_) => {
|
|
@@ -7239,7 +7245,7 @@ const pt = Me(({
|
|
|
7239
7245
|
}), r.current.morphs && r.current.morphs.length > 0) {
|
|
7240
7246
|
const _ = r.current.morphs[0].morphTargetDictionary;
|
|
7241
7247
|
console.log("Available morph targets:", Object.keys(_));
|
|
7242
|
-
const B = Object.keys(_).filter((
|
|
7248
|
+
const B = Object.keys(_).filter((ee) => ee.startsWith("viseme_"));
|
|
7243
7249
|
console.log("Viseme morph targets found:", B), B.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"));
|
|
7244
7250
|
}
|
|
7245
7251
|
if (await new Promise((_) => {
|
|
@@ -7254,27 +7260,27 @@ const pt = Me(({
|
|
|
7254
7260
|
console.warn("Error setting full body mode on initialization:", _);
|
|
7255
7261
|
}
|
|
7256
7262
|
a(!1), b(!0), n(r.current);
|
|
7257
|
-
const
|
|
7263
|
+
const C = () => {
|
|
7258
7264
|
document.visibilityState === "visible" ? r.current?.start() : r.current?.stop();
|
|
7259
7265
|
};
|
|
7260
|
-
return document.addEventListener("visibilitychange",
|
|
7261
|
-
document.removeEventListener("visibilitychange",
|
|
7266
|
+
return document.addEventListener("visibilitychange", C), () => {
|
|
7267
|
+
document.removeEventListener("visibilitychange", C);
|
|
7262
7268
|
};
|
|
7263
7269
|
} catch (k) {
|
|
7264
7270
|
console.error("Error initializing TalkingHead:", k), c(k.message || "Failed to initialize avatar"), a(!1), e(k);
|
|
7265
7271
|
}
|
|
7266
7272
|
}, []);
|
|
7267
|
-
me(() => (
|
|
7273
|
+
me(() => (H(), () => {
|
|
7268
7274
|
r.current && (r.current.stop(), r.current.dispose(), r.current = null);
|
|
7269
|
-
}), [
|
|
7275
|
+
}), [H]);
|
|
7270
7276
|
const y = N((k) => {
|
|
7271
7277
|
if (r.current && g)
|
|
7272
7278
|
try {
|
|
7273
7279
|
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(() => {
|
|
7274
7280
|
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");
|
|
7275
7281
|
}, 500));
|
|
7276
|
-
} catch (
|
|
7277
|
-
console.error("Error speaking text:",
|
|
7282
|
+
} catch (C) {
|
|
7283
|
+
console.error("Error speaking text:", C), c(C.message || "Failed to speak text");
|
|
7278
7284
|
}
|
|
7279
7285
|
else
|
|
7280
7286
|
console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!r.current);
|
|
@@ -7284,7 +7290,7 @@ const pt = Me(({
|
|
|
7284
7290
|
r.current && r.current.setMood(k);
|
|
7285
7291
|
}, []), A = N((k) => {
|
|
7286
7292
|
r.current && r.current.setSlowdownRate && (r.current.setSlowdownRate(k), console.log("Timing adjustment set to:", k));
|
|
7287
|
-
}, []),
|
|
7293
|
+
}, []), Y = N((k, C = !1) => {
|
|
7288
7294
|
if (r.current && r.current.playAnimation) {
|
|
7289
7295
|
if (r.current.setShowFullAvatar)
|
|
7290
7296
|
try {
|
|
@@ -7294,26 +7300,26 @@ const pt = Me(({
|
|
|
7294
7300
|
}
|
|
7295
7301
|
if (k.includes("."))
|
|
7296
7302
|
try {
|
|
7297
|
-
r.current.playAnimation(k, null, 10, 0, 0.01,
|
|
7303
|
+
r.current.playAnimation(k, null, 10, 0, 0.01, C), console.log("Playing animation:", k);
|
|
7298
7304
|
} catch (B) {
|
|
7299
7305
|
console.log(`Failed to play ${k}:`, B);
|
|
7300
7306
|
try {
|
|
7301
7307
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
7302
|
-
} catch (
|
|
7303
|
-
console.warn("Fallback animation also failed:",
|
|
7308
|
+
} catch (ee) {
|
|
7309
|
+
console.warn("Fallback animation also failed:", ee);
|
|
7304
7310
|
}
|
|
7305
7311
|
}
|
|
7306
7312
|
else {
|
|
7307
7313
|
const B = [".fbx", ".glb", ".gltf"];
|
|
7308
|
-
let
|
|
7314
|
+
let ee = !1;
|
|
7309
7315
|
for (const ie of B)
|
|
7310
7316
|
try {
|
|
7311
|
-
r.current.playAnimation(k + ie, null, 10, 0, 0.01,
|
|
7317
|
+
r.current.playAnimation(k + ie, null, 10, 0, 0.01, C), console.log("Playing animation:", k + ie), ee = !0;
|
|
7312
7318
|
break;
|
|
7313
7319
|
} catch {
|
|
7314
7320
|
console.log(`Failed to play ${k}${ie}, trying next format...`);
|
|
7315
7321
|
}
|
|
7316
|
-
if (
|
|
7322
|
+
if (!ee) {
|
|
7317
7323
|
console.warn("Animation system not available or animation not found:", k);
|
|
7318
7324
|
try {
|
|
7319
7325
|
r.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
@@ -7330,15 +7336,15 @@ const pt = Me(({
|
|
|
7330
7336
|
stopSpeaking: I,
|
|
7331
7337
|
setMood: z,
|
|
7332
7338
|
setTimingAdjustment: A,
|
|
7333
|
-
playAnimation:
|
|
7339
|
+
playAnimation: Y,
|
|
7334
7340
|
isReady: g,
|
|
7335
7341
|
talkingHead: r.current,
|
|
7336
7342
|
setBodyMovement: (k) => {
|
|
7337
7343
|
if (r.current && r.current.setShowFullAvatar && r.current.setBodyMovement)
|
|
7338
7344
|
try {
|
|
7339
7345
|
r.current.setShowFullAvatar(!0), r.current.setBodyMovement(k), console.log("Body movement set with full body mode:", k);
|
|
7340
|
-
} catch (
|
|
7341
|
-
console.warn("Error setting body movement:",
|
|
7346
|
+
} catch (C) {
|
|
7347
|
+
console.warn("Error setting body movement:", C);
|
|
7342
7348
|
}
|
|
7343
7349
|
},
|
|
7344
7350
|
setMovementIntensity: (k) => r.current?.setMovementIntensity(k),
|
|
@@ -7354,8 +7360,8 @@ const pt = Me(({
|
|
|
7354
7360
|
if (r.current && r.current.setShowFullAvatar && r.current.playReaction)
|
|
7355
7361
|
try {
|
|
7356
7362
|
r.current.setShowFullAvatar(!0), r.current.playReaction(k), console.log("Reaction played with full body mode:", k);
|
|
7357
|
-
} catch (
|
|
7358
|
-
console.warn("Error playing reaction:",
|
|
7363
|
+
} catch (C) {
|
|
7364
|
+
console.warn("Error playing reaction:", C);
|
|
7359
7365
|
}
|
|
7360
7366
|
},
|
|
7361
7367
|
playCelebration: () => {
|
|
@@ -7370,8 +7376,8 @@ const pt = Me(({
|
|
|
7370
7376
|
if (r.current && r.current.setShowFullAvatar)
|
|
7371
7377
|
try {
|
|
7372
7378
|
r.current.setShowFullAvatar(k), console.log("Show full avatar set to:", k);
|
|
7373
|
-
} catch (
|
|
7374
|
-
console.warn("Error setting showFullAvatar:",
|
|
7379
|
+
} catch (C) {
|
|
7380
|
+
console.warn("Error setting showFullAvatar:", C);
|
|
7375
7381
|
}
|
|
7376
7382
|
},
|
|
7377
7383
|
lockAvatarPosition: () => {
|
|
@@ -7428,7 +7434,7 @@ const pt = Me(({
|
|
|
7428
7434
|
});
|
|
7429
7435
|
pt.displayName = "TalkingHeadComponent";
|
|
7430
7436
|
const gt = Me(({
|
|
7431
|
-
text:
|
|
7437
|
+
text: X = null,
|
|
7432
7438
|
avatarUrl: t = "/avatars/brunette.glb",
|
|
7433
7439
|
avatarBody: e = "F",
|
|
7434
7440
|
mood: n = "neutral",
|
|
@@ -7450,16 +7456,16 @@ const gt = Me(({
|
|
|
7450
7456
|
},
|
|
7451
7457
|
className: x = "",
|
|
7452
7458
|
style: S = {},
|
|
7453
|
-
animations:
|
|
7459
|
+
animations: G = {},
|
|
7454
7460
|
autoSpeak: p = !1
|
|
7455
7461
|
}, P) => {
|
|
7456
|
-
const
|
|
7462
|
+
const H = V(null), y = V(null), I = V(u), z = V(null), A = V(null), Y = V(!1), k = V({ remainingText: null, originalText: null, options: null }), C = V([]), [_, B] = de(!0), [ee, ie] = de(null), [oe, he] = de(!1), [K, Q] = de(!1);
|
|
7457
7463
|
me(() => {
|
|
7458
|
-
|
|
7459
|
-
}, [
|
|
7464
|
+
Y.current = K;
|
|
7465
|
+
}, [K]), me(() => {
|
|
7460
7466
|
I.current = u;
|
|
7461
7467
|
}, [u]);
|
|
7462
|
-
const
|
|
7468
|
+
const W = Ee(), v = s || W.service;
|
|
7463
7469
|
let R;
|
|
7464
7470
|
v === "browser" ? R = {
|
|
7465
7471
|
service: "browser",
|
|
@@ -7469,20 +7475,20 @@ const gt = Me(({
|
|
|
7469
7475
|
} : v === "elevenlabs" ? R = {
|
|
7470
7476
|
service: "elevenlabs",
|
|
7471
7477
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7472
|
-
apiKey: l ||
|
|
7473
|
-
defaultVoice: o ||
|
|
7474
|
-
voices:
|
|
7478
|
+
apiKey: l || W.apiKey,
|
|
7479
|
+
defaultVoice: o || W.defaultVoice || Ie.defaultVoice,
|
|
7480
|
+
voices: W.voices || Ie.voices
|
|
7475
7481
|
} : v === "deepgram" ? R = {
|
|
7476
7482
|
service: "deepgram",
|
|
7477
7483
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7478
|
-
apiKey: l ||
|
|
7479
|
-
defaultVoice: o ||
|
|
7480
|
-
voices:
|
|
7484
|
+
apiKey: l || W.apiKey,
|
|
7485
|
+
defaultVoice: o || W.defaultVoice || Te.defaultVoice,
|
|
7486
|
+
voices: W.voices || Te.voices
|
|
7481
7487
|
} : R = {
|
|
7482
|
-
...
|
|
7483
|
-
apiKey: l !== null ? l :
|
|
7488
|
+
...W,
|
|
7489
|
+
apiKey: l !== null ? l : W.apiKey
|
|
7484
7490
|
};
|
|
7485
|
-
const
|
|
7491
|
+
const T = {
|
|
7486
7492
|
url: t,
|
|
7487
7493
|
body: e,
|
|
7488
7494
|
avatarMood: n,
|
|
@@ -7498,19 +7504,19 @@ const gt = Me(({
|
|
|
7498
7504
|
ttsService: v,
|
|
7499
7505
|
lipsyncModules: ["en"],
|
|
7500
7506
|
cameraView: a
|
|
7501
|
-
},
|
|
7502
|
-
if (!(!
|
|
7507
|
+
}, O = N(async () => {
|
|
7508
|
+
if (!(!H.current || y.current))
|
|
7503
7509
|
try {
|
|
7504
|
-
B(!0), ie(null), y.current = new Be(
|
|
7505
|
-
url:
|
|
7506
|
-
body:
|
|
7507
|
-
avatarMood:
|
|
7508
|
-
}), await y.current.showAvatar(
|
|
7510
|
+
B(!0), ie(null), y.current = new Be(H.current, M), console.log("Avatar config being passed:", {
|
|
7511
|
+
url: T.url,
|
|
7512
|
+
body: T.body,
|
|
7513
|
+
avatarMood: T.avatarMood
|
|
7514
|
+
}), await y.current.showAvatar(T, (se) => {
|
|
7509
7515
|
if (se.lengthComputable) {
|
|
7510
7516
|
const L = Math.min(100, Math.round(se.loaded / se.total * 100));
|
|
7511
7517
|
c(L);
|
|
7512
7518
|
}
|
|
7513
|
-
}), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), B(!1),
|
|
7519
|
+
}), y.current?.avatar && console.log("Avatar body after initialization:", y.current.avatar.body), B(!1), he(!0), d(y.current);
|
|
7514
7520
|
const E = () => {
|
|
7515
7521
|
document.visibilityState === "visible" ? y.current?.start() : y.current?.stop();
|
|
7516
7522
|
};
|
|
@@ -7521,10 +7527,10 @@ const gt = Me(({
|
|
|
7521
7527
|
console.error("Error initializing TalkingHead:", E), ie(E.message || "Failed to initialize avatar"), B(!1), g(E);
|
|
7522
7528
|
}
|
|
7523
7529
|
}, []);
|
|
7524
|
-
me(() => (
|
|
7530
|
+
me(() => (O(), () => {
|
|
7525
7531
|
y.current && (y.current.stop(), y.current.dispose(), y.current = null);
|
|
7526
|
-
}), [
|
|
7527
|
-
const
|
|
7532
|
+
}), [O]);
|
|
7533
|
+
const te = N(async () => {
|
|
7528
7534
|
if (y.current)
|
|
7529
7535
|
try {
|
|
7530
7536
|
const E = y.current.audioCtx || y.current.audioContext;
|
|
@@ -7541,9 +7547,9 @@ const gt = Me(({
|
|
|
7541
7547
|
console.warn("No text provided to speak");
|
|
7542
7548
|
return;
|
|
7543
7549
|
}
|
|
7544
|
-
await
|
|
7550
|
+
await te(), k.current = { remainingText: null, originalText: null, options: null }, C.current = [], z.current = { text: E, options: se }, A.current && (clearInterval(A.current), A.current = null), Q(!1), Y.current = !1;
|
|
7545
7551
|
const L = E.split(/[.!?]+/).filter((U) => U.trim().length > 0);
|
|
7546
|
-
|
|
7552
|
+
C.current = L;
|
|
7547
7553
|
const D = {
|
|
7548
7554
|
lipsyncLang: se.lipsyncLang || "en",
|
|
7549
7555
|
onSpeechEnd: () => {
|
|
@@ -7555,45 +7561,45 @@ const gt = Me(({
|
|
|
7555
7561
|
} catch (U) {
|
|
7556
7562
|
console.error("Error speaking text:", U), ie(U.message || "Failed to speak text");
|
|
7557
7563
|
}
|
|
7558
|
-
}, [oe, b,
|
|
7564
|
+
}, [oe, b, te]);
|
|
7559
7565
|
me(() => {
|
|
7560
|
-
oe &&
|
|
7561
|
-
}, [oe,
|
|
7562
|
-
const
|
|
7566
|
+
oe && X && p && y.current && q(X);
|
|
7567
|
+
}, [oe, X, p, q]);
|
|
7568
|
+
const $ = N(() => {
|
|
7563
7569
|
if (y.current)
|
|
7564
7570
|
try {
|
|
7565
7571
|
const E = y.current.isSpeaking || !1, se = y.current.audioPlaylist || [], L = y.current.speechQueue || [];
|
|
7566
7572
|
if (E || se.length > 0 || L.length > 0) {
|
|
7567
7573
|
A.current && (clearInterval(A.current), A.current = null);
|
|
7568
7574
|
let D = "";
|
|
7569
|
-
L.length > 0 && (D = L.map((U) => U.text && Array.isArray(U.text) ? U.text.map((
|
|
7575
|
+
L.length > 0 && (D = L.map((U) => U.text && Array.isArray(U.text) ? U.text.map((ne) => ne.word).join(" ") : U.text || "").join(" ")), k.current = {
|
|
7570
7576
|
remainingText: D || null,
|
|
7571
7577
|
originalText: z.current?.text || null,
|
|
7572
7578
|
options: z.current?.options || null
|
|
7573
|
-
}, y.current.speechQueue.length = 0, y.current.pauseSpeaking(),
|
|
7579
|
+
}, y.current.speechQueue.length = 0, y.current.pauseSpeaking(), Q(!0), Y.current = !0;
|
|
7574
7580
|
}
|
|
7575
7581
|
} catch (E) {
|
|
7576
7582
|
console.warn("Error pausing speech:", E);
|
|
7577
7583
|
}
|
|
7578
7584
|
}, []), Ae = N(async () => {
|
|
7579
|
-
if (!(!y.current || !
|
|
7585
|
+
if (!(!y.current || !K))
|
|
7580
7586
|
try {
|
|
7581
|
-
await
|
|
7587
|
+
await te(), Q(!1), Y.current = !1;
|
|
7582
7588
|
const E = k.current?.remainingText, se = k.current?.originalText || z.current?.text, L = k.current?.options || z.current?.options || {}, D = E || se;
|
|
7583
7589
|
D && q(D, L);
|
|
7584
7590
|
} catch (E) {
|
|
7585
|
-
console.warn("Error resuming speech:", E),
|
|
7591
|
+
console.warn("Error resuming speech:", E), Q(!1), Y.current = !1;
|
|
7586
7592
|
}
|
|
7587
|
-
}, [
|
|
7588
|
-
y.current && (y.current.stopSpeaking(), A.current && (clearInterval(A.current), A.current = null),
|
|
7593
|
+
}, [K, q, te]), we = N(() => {
|
|
7594
|
+
y.current && (y.current.stopSpeaking(), A.current && (clearInterval(A.current), A.current = null), Q(!1), Y.current = !1);
|
|
7589
7595
|
}, []);
|
|
7590
7596
|
return Fe(P, () => ({
|
|
7591
7597
|
speakText: q,
|
|
7592
|
-
pauseSpeaking:
|
|
7598
|
+
pauseSpeaking: $,
|
|
7593
7599
|
resumeSpeaking: Ae,
|
|
7594
7600
|
stopSpeaking: we,
|
|
7595
|
-
resumeAudioContext:
|
|
7596
|
-
isPaused: () =>
|
|
7601
|
+
resumeAudioContext: te,
|
|
7602
|
+
isPaused: () => K,
|
|
7597
7603
|
setMood: (E) => y.current?.setMood(E),
|
|
7598
7604
|
setBodyMovement: (E) => {
|
|
7599
7605
|
y.current && y.current.setBodyMovement(E);
|
|
@@ -7612,7 +7618,7 @@ const gt = Me(({
|
|
|
7612
7618
|
/* @__PURE__ */ pe(
|
|
7613
7619
|
"div",
|
|
7614
7620
|
{
|
|
7615
|
-
ref:
|
|
7621
|
+
ref: H,
|
|
7616
7622
|
className: "talking-head-viewer",
|
|
7617
7623
|
style: {
|
|
7618
7624
|
width: "100%",
|
|
@@ -7630,7 +7636,7 @@ const gt = Me(({
|
|
|
7630
7636
|
fontSize: "18px",
|
|
7631
7637
|
zIndex: 10
|
|
7632
7638
|
}, children: "Loading avatar..." }),
|
|
7633
|
-
|
|
7639
|
+
ee && /* @__PURE__ */ pe("div", { className: "error-overlay", style: {
|
|
7634
7640
|
position: "absolute",
|
|
7635
7641
|
top: "50%",
|
|
7636
7642
|
left: "50%",
|
|
@@ -7641,12 +7647,12 @@ const gt = Me(({
|
|
|
7641
7647
|
zIndex: 10,
|
|
7642
7648
|
padding: "20px",
|
|
7643
7649
|
borderRadius: "8px"
|
|
7644
|
-
}, children:
|
|
7650
|
+
}, children: ee })
|
|
7645
7651
|
] });
|
|
7646
7652
|
});
|
|
7647
7653
|
gt.displayName = "SimpleTalkingAvatar";
|
|
7648
7654
|
const yt = Me(({
|
|
7649
|
-
curriculumData:
|
|
7655
|
+
curriculumData: X = null,
|
|
7650
7656
|
avatarConfig: t = {},
|
|
7651
7657
|
animations: e = {},
|
|
7652
7658
|
onLessonStart: n = () => {
|
|
@@ -7661,7 +7667,7 @@ const yt = Me(({
|
|
|
7661
7667
|
},
|
|
7662
7668
|
autoStart: h = !1
|
|
7663
7669
|
}, r) => {
|
|
7664
|
-
const u =
|
|
7670
|
+
const u = V(null), a = V({
|
|
7665
7671
|
currentModuleIndex: 0,
|
|
7666
7672
|
currentLessonIndex: 0,
|
|
7667
7673
|
currentQuestionIndex: 0,
|
|
@@ -7671,18 +7677,18 @@ const yt = Me(({
|
|
|
7671
7677
|
curriculumCompleted: !1,
|
|
7672
7678
|
score: 0,
|
|
7673
7679
|
totalQuestions: 0
|
|
7674
|
-
}), d =
|
|
7680
|
+
}), d = V({
|
|
7675
7681
|
onLessonStart: n,
|
|
7676
7682
|
onLessonComplete: i,
|
|
7677
7683
|
onQuestionAnswer: s,
|
|
7678
7684
|
onCurriculumComplete: o,
|
|
7679
7685
|
onCustomAction: l
|
|
7680
|
-
}), c =
|
|
7686
|
+
}), c = V(null), g = V(null), b = V(null), x = V(null), S = V(null), G = V(null), p = V(null), P = V(X?.curriculum || {
|
|
7681
7687
|
title: "Default Curriculum",
|
|
7682
7688
|
description: "No curriculum data provided",
|
|
7683
7689
|
language: "en",
|
|
7684
7690
|
modules: []
|
|
7685
|
-
}),
|
|
7691
|
+
}), H = V({
|
|
7686
7692
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7687
7693
|
avatarBody: t.avatarBody || "F",
|
|
7688
7694
|
mood: t.mood || "happy",
|
|
@@ -7705,12 +7711,12 @@ const yt = Me(({
|
|
|
7705
7711
|
onCustomAction: l
|
|
7706
7712
|
};
|
|
7707
7713
|
}, [n, i, s, o, l]), me(() => {
|
|
7708
|
-
P.current =
|
|
7714
|
+
P.current = X?.curriculum || {
|
|
7709
7715
|
title: "Default Curriculum",
|
|
7710
7716
|
description: "No curriculum data provided",
|
|
7711
7717
|
language: "en",
|
|
7712
7718
|
modules: []
|
|
7713
|
-
},
|
|
7719
|
+
}, H.current = {
|
|
7714
7720
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7715
7721
|
avatarBody: t.avatarBody || "F",
|
|
7716
7722
|
mood: t.mood || "happy",
|
|
@@ -7724,7 +7730,7 @@ const yt = Me(({
|
|
|
7724
7730
|
animations: e,
|
|
7725
7731
|
lipsyncLang: "en"
|
|
7726
7732
|
};
|
|
7727
|
-
}, [
|
|
7733
|
+
}, [X, t, e]);
|
|
7728
7734
|
const y = N(() => (P.current || { modules: [] }).modules[a.current.currentModuleIndex]?.lessons[a.current.currentLessonIndex], []), I = N(() => y()?.questions[a.current.currentQuestionIndex], [y]), z = N((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 = N(() => {
|
|
7729
7735
|
a.current.lessonCompleted = !0, a.current.isQuestionMode = !1;
|
|
7730
7736
|
const v = a.current.totalQuestions > 0 ? Math.round(a.current.score / a.current.totalQuestions * 100) : 100;
|
|
@@ -7749,9 +7755,9 @@ const yt = Me(({
|
|
|
7749
7755
|
} catch {
|
|
7750
7756
|
u.current.playCelebration();
|
|
7751
7757
|
}
|
|
7752
|
-
const
|
|
7758
|
+
const T = P.current || { modules: [] }, M = T.modules[a.current.currentModuleIndex], O = a.current.currentLessonIndex < (M?.lessons?.length || 0) - 1, te = a.current.currentModuleIndex < (T.modules?.length || 0) - 1, q = O || te, $ = H.current || { lipsyncLang: "en" };
|
|
7753
7759
|
u.current.speakText(R, {
|
|
7754
|
-
lipsyncLang:
|
|
7760
|
+
lipsyncLang: $.lipsyncLang,
|
|
7755
7761
|
onSpeechEnd: () => {
|
|
7756
7762
|
d.current.onCustomAction({
|
|
7757
7763
|
type: "lessonCompleteFeedbackDone",
|
|
@@ -7765,12 +7771,12 @@ const yt = Me(({
|
|
|
7765
7771
|
}
|
|
7766
7772
|
});
|
|
7767
7773
|
}
|
|
7768
|
-
}, [e.lessonComplete]),
|
|
7774
|
+
}, [e.lessonComplete]), Y = N(() => {
|
|
7769
7775
|
a.current.curriculumCompleted = !0;
|
|
7770
7776
|
const v = P.current || { modules: [] };
|
|
7771
7777
|
if (d.current.onCurriculumComplete({
|
|
7772
7778
|
modules: v.modules.length,
|
|
7773
|
-
totalLessons: v.modules.reduce((R,
|
|
7779
|
+
totalLessons: v.modules.reduce((R, T) => R + T.lessons.length, 0)
|
|
7774
7780
|
}), u.current) {
|
|
7775
7781
|
if (u.current.setMood("celebrating"), e.curriculumComplete)
|
|
7776
7782
|
try {
|
|
@@ -7778,7 +7784,7 @@ const yt = Me(({
|
|
|
7778
7784
|
} catch {
|
|
7779
7785
|
u.current.playCelebration();
|
|
7780
7786
|
}
|
|
7781
|
-
const R =
|
|
7787
|
+
const R = H.current || { lipsyncLang: "en" };
|
|
7782
7788
|
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 });
|
|
7783
7789
|
}
|
|
7784
7790
|
}, [e.curriculumComplete]), k = N(() => {
|
|
@@ -7794,31 +7800,31 @@ const yt = Me(({
|
|
|
7794
7800
|
question: R,
|
|
7795
7801
|
score: a.current.score
|
|
7796
7802
|
});
|
|
7797
|
-
const
|
|
7803
|
+
const T = () => {
|
|
7798
7804
|
if (!u.current || !R) return;
|
|
7799
7805
|
if (u.current.setMood("happy"), e.questionStart)
|
|
7800
7806
|
try {
|
|
7801
7807
|
u.current.playAnimation(e.questionStart, !0);
|
|
7802
|
-
} catch (
|
|
7803
|
-
console.warn("Failed to play questionStart animation:",
|
|
7808
|
+
} catch (O) {
|
|
7809
|
+
console.warn("Failed to play questionStart animation:", O);
|
|
7804
7810
|
}
|
|
7805
|
-
const M =
|
|
7811
|
+
const M = H.current || { lipsyncLang: "en" };
|
|
7806
7812
|
R.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${R.question}`, { lipsyncLang: M.lipsyncLang }) : R.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: M.lipsyncLang }) : R.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${R.question}`, { lipsyncLang: M.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${R.question}`, { lipsyncLang: M.lipsyncLang });
|
|
7807
7813
|
};
|
|
7808
7814
|
if (u.current && u.current.isReady && R)
|
|
7809
|
-
|
|
7815
|
+
T();
|
|
7810
7816
|
else if (u.current && u.current.isReady) {
|
|
7811
|
-
const M =
|
|
7817
|
+
const M = H.current || { lipsyncLang: "en" };
|
|
7812
7818
|
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: M.lipsyncLang });
|
|
7813
7819
|
} else {
|
|
7814
7820
|
const M = setInterval(() => {
|
|
7815
|
-
u.current && u.current.isReady && (clearInterval(M), R &&
|
|
7821
|
+
u.current && u.current.isReady && (clearInterval(M), R && T());
|
|
7816
7822
|
}, 100);
|
|
7817
7823
|
setTimeout(() => {
|
|
7818
7824
|
clearInterval(M);
|
|
7819
7825
|
}, 5e3);
|
|
7820
7826
|
}
|
|
7821
|
-
}, [e.questionStart, y, I]),
|
|
7827
|
+
}, [e.questionStart, y, I]), C = N(() => {
|
|
7822
7828
|
const v = y();
|
|
7823
7829
|
if (a.current.currentQuestionIndex < (v?.questions?.length || 0) - 1) {
|
|
7824
7830
|
u.current && u.current.stopSpeaking && u.current.stopSpeaking(), a.current.currentQuestionIndex += 1;
|
|
@@ -7832,42 +7838,42 @@ const yt = Me(({
|
|
|
7832
7838
|
question: R,
|
|
7833
7839
|
score: a.current.score
|
|
7834
7840
|
});
|
|
7835
|
-
const
|
|
7841
|
+
const T = () => {
|
|
7836
7842
|
if (!u.current || !R) return;
|
|
7837
7843
|
if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
|
|
7838
7844
|
try {
|
|
7839
7845
|
u.current.playAnimation(e.nextQuestion, !0);
|
|
7840
|
-
} catch (
|
|
7841
|
-
console.warn("Failed to play nextQuestion animation:",
|
|
7846
|
+
} catch ($) {
|
|
7847
|
+
console.warn("Failed to play nextQuestion animation:", $);
|
|
7842
7848
|
}
|
|
7843
|
-
const M =
|
|
7849
|
+
const M = H.current || { lipsyncLang: "en" }, te = y()?.questions?.length || 0, q = a.current.currentQuestionIndex >= te - 1;
|
|
7844
7850
|
if (R.type === "code_test") {
|
|
7845
|
-
const
|
|
7846
|
-
u.current.speakText(
|
|
7851
|
+
const $ = q ? `Great! Here's your final coding challenge: ${R.question}` : `Great! Now let's move on to your next coding challenge: ${R.question}`;
|
|
7852
|
+
u.current.speakText($, {
|
|
7847
7853
|
lipsyncLang: M.lipsyncLang
|
|
7848
7854
|
});
|
|
7849
7855
|
} else if (R.type === "multiple_choice") {
|
|
7850
|
-
const
|
|
7851
|
-
u.current.speakText(
|
|
7856
|
+
const $ = q ? `Alright! Here's your final question: ${R.question}` : `Alright! Here's your next question: ${R.question}`;
|
|
7857
|
+
u.current.speakText($, {
|
|
7852
7858
|
lipsyncLang: M.lipsyncLang
|
|
7853
7859
|
});
|
|
7854
7860
|
} else if (R.type === "true_false") {
|
|
7855
|
-
const
|
|
7856
|
-
u.current.speakText(
|
|
7861
|
+
const $ = q ? `Now let's try this final one: ${R.question}` : `Now let's try this one: ${R.question}`;
|
|
7862
|
+
u.current.speakText($, {
|
|
7857
7863
|
lipsyncLang: M.lipsyncLang
|
|
7858
7864
|
});
|
|
7859
7865
|
} else {
|
|
7860
|
-
const
|
|
7861
|
-
u.current.speakText(
|
|
7866
|
+
const $ = q ? `Here's your final question: ${R.question}` : `Here's the next question: ${R.question}`;
|
|
7867
|
+
u.current.speakText($, {
|
|
7862
7868
|
lipsyncLang: M.lipsyncLang
|
|
7863
7869
|
});
|
|
7864
7870
|
}
|
|
7865
7871
|
};
|
|
7866
7872
|
if (u.current && u.current.isReady && R)
|
|
7867
|
-
|
|
7873
|
+
T();
|
|
7868
7874
|
else if (R) {
|
|
7869
7875
|
const M = setInterval(() => {
|
|
7870
|
-
u.current && u.current.isReady && (clearInterval(M),
|
|
7876
|
+
u.current && u.current.isReady && (clearInterval(M), T());
|
|
7871
7877
|
}, 100);
|
|
7872
7878
|
setTimeout(() => {
|
|
7873
7879
|
clearInterval(M);
|
|
@@ -7885,7 +7891,7 @@ const yt = Me(({
|
|
|
7885
7891
|
const v = P.current || { modules: [] }, R = v.modules[a.current.currentModuleIndex];
|
|
7886
7892
|
if (a.current.currentLessonIndex < (R?.lessons?.length || 0) - 1) {
|
|
7887
7893
|
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;
|
|
7888
|
-
const M = v.modules[a.current.currentModuleIndex],
|
|
7894
|
+
const M = v.modules[a.current.currentModuleIndex], O = a.current.currentLessonIndex < (M?.lessons?.length || 0) - 1, te = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, q = O || te;
|
|
7889
7895
|
d.current.onCustomAction({
|
|
7890
7896
|
type: "lessonStart",
|
|
7891
7897
|
moduleIndex: a.current.currentModuleIndex,
|
|
@@ -7898,12 +7904,12 @@ const yt = Me(({
|
|
|
7898
7904
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
7899
7905
|
} else if (a.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
|
|
7900
7906
|
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;
|
|
7901
|
-
const
|
|
7907
|
+
const O = v.modules[a.current.currentModuleIndex], te = a.current.currentLessonIndex < (O?.lessons?.length || 0) - 1, q = a.current.currentModuleIndex < (v.modules?.length || 0) - 1, $ = te || q;
|
|
7902
7908
|
d.current.onCustomAction({
|
|
7903
7909
|
type: "lessonStart",
|
|
7904
7910
|
moduleIndex: a.current.currentModuleIndex,
|
|
7905
7911
|
lessonIndex: a.current.currentLessonIndex,
|
|
7906
|
-
hasNextLesson:
|
|
7912
|
+
hasNextLesson: $
|
|
7907
7913
|
}), d.current.onLessonStart({
|
|
7908
7914
|
moduleIndex: a.current.currentModuleIndex,
|
|
7909
7915
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7915,21 +7921,21 @@ const yt = Me(({
|
|
|
7915
7921
|
const v = y();
|
|
7916
7922
|
let R = null;
|
|
7917
7923
|
if (v?.avatar_script && v?.body) {
|
|
7918
|
-
const
|
|
7919
|
-
R = `${
|
|
7924
|
+
const T = v.avatar_script.trim(), M = v.body.trim(), O = T.match(/[.!?]$/) ? " " : ". ";
|
|
7925
|
+
R = `${T}${O}${M}`;
|
|
7920
7926
|
} else
|
|
7921
7927
|
R = v?.avatar_script || v?.body || null;
|
|
7922
7928
|
if (u.current && u.current.isReady && R) {
|
|
7923
7929
|
a.current.isTeaching = !0, a.current.isQuestionMode = !1, a.current.score = 0, a.current.totalQuestions = 0, u.current.setMood("happy");
|
|
7924
|
-
let
|
|
7930
|
+
let T = !1;
|
|
7925
7931
|
if (e.teaching)
|
|
7926
7932
|
try {
|
|
7927
|
-
u.current.playAnimation(e.teaching, !0),
|
|
7928
|
-
} catch (
|
|
7929
|
-
console.warn("Failed to play teaching animation:",
|
|
7933
|
+
u.current.playAnimation(e.teaching, !0), T = !0;
|
|
7934
|
+
} catch (O) {
|
|
7935
|
+
console.warn("Failed to play teaching animation:", O);
|
|
7930
7936
|
}
|
|
7931
|
-
|
|
7932
|
-
const M =
|
|
7937
|
+
T || u.current.setBodyMovement("gesturing");
|
|
7938
|
+
const M = H.current || { lipsyncLang: "en" };
|
|
7933
7939
|
d.current.onLessonStart({
|
|
7934
7940
|
moduleIndex: a.current.currentModuleIndex,
|
|
7935
7941
|
lessonIndex: a.current.currentLessonIndex,
|
|
@@ -7958,17 +7964,17 @@ const yt = Me(({
|
|
|
7958
7964
|
}
|
|
7959
7965
|
});
|
|
7960
7966
|
}
|
|
7961
|
-
}, [e.teaching, y]),
|
|
7962
|
-
const R = I(),
|
|
7963
|
-
if (
|
|
7967
|
+
}, [e.teaching, y]), ee = N((v) => {
|
|
7968
|
+
const R = I(), T = z(v, R);
|
|
7969
|
+
if (T && (a.current.score += 1), d.current.onQuestionAnswer({
|
|
7964
7970
|
moduleIndex: a.current.currentModuleIndex,
|
|
7965
7971
|
lessonIndex: a.current.currentLessonIndex,
|
|
7966
7972
|
questionIndex: a.current.currentQuestionIndex,
|
|
7967
7973
|
answer: v,
|
|
7968
|
-
isCorrect:
|
|
7974
|
+
isCorrect: T,
|
|
7969
7975
|
question: R
|
|
7970
7976
|
}), u.current)
|
|
7971
|
-
if (
|
|
7977
|
+
if (T) {
|
|
7972
7978
|
if (u.current.setMood("happy"), e.correct)
|
|
7973
7979
|
try {
|
|
7974
7980
|
u.current.playReaction("happy");
|
|
@@ -7976,13 +7982,13 @@ const yt = Me(({
|
|
|
7976
7982
|
u.current.setBodyMovement("happy");
|
|
7977
7983
|
}
|
|
7978
7984
|
u.current.setBodyMovement("gesturing");
|
|
7979
|
-
const
|
|
7980
|
-
a.current.currentQuestionIndex >=
|
|
7981
|
-
const
|
|
7982
|
-
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
7983
|
-
const q = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`,
|
|
7985
|
+
const O = y()?.questions?.length || 0;
|
|
7986
|
+
a.current.currentQuestionIndex >= O - 1;
|
|
7987
|
+
const te = a.current.currentQuestionIndex < O - 1;
|
|
7988
|
+
console.log("[CurriculumLearning] Answer feedback - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", O, "hasNextQuestion:", te);
|
|
7989
|
+
const q = R.type === "code_test" ? `Great job! Your code passed all the tests! ${R.explanation || ""}` : `Excellent! That's correct! ${R.explanation || ""}`, $ = H.current || { lipsyncLang: "en" };
|
|
7984
7990
|
u.current.speakText(q, {
|
|
7985
|
-
lipsyncLang:
|
|
7991
|
+
lipsyncLang: $.lipsyncLang,
|
|
7986
7992
|
onSpeechEnd: () => {
|
|
7987
7993
|
d.current.onCustomAction({
|
|
7988
7994
|
type: "answerFeedbackComplete",
|
|
@@ -7990,7 +7996,7 @@ const yt = Me(({
|
|
|
7990
7996
|
lessonIndex: a.current.currentLessonIndex,
|
|
7991
7997
|
questionIndex: a.current.currentQuestionIndex,
|
|
7992
7998
|
isCorrect: !0,
|
|
7993
|
-
hasNextQuestion:
|
|
7999
|
+
hasNextQuestion: te,
|
|
7994
8000
|
score: a.current.score,
|
|
7995
8001
|
totalQuestions: a.current.totalQuestions
|
|
7996
8002
|
});
|
|
@@ -8004,10 +8010,10 @@ const yt = Me(({
|
|
|
8004
8010
|
u.current.setBodyMovement("idle");
|
|
8005
8011
|
}
|
|
8006
8012
|
u.current.setBodyMovement("gesturing");
|
|
8007
|
-
const
|
|
8008
|
-
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:",
|
|
8009
|
-
const
|
|
8010
|
-
u.current.speakText(
|
|
8013
|
+
const O = y()?.questions?.length || 0, te = a.current.currentQuestionIndex >= O - 1, q = a.current.currentQuestionIndex < O - 1;
|
|
8014
|
+
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", a.current.currentQuestionIndex, "totalQuestions:", O, "hasNextQuestion:", q);
|
|
8015
|
+
const $ = 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 || ""}${te ? "" : " Let's move on to the next question."}`, Ae = H.current || { lipsyncLang: "en" };
|
|
8016
|
+
u.current.speakText($, {
|
|
8011
8017
|
lipsyncLang: Ae.lipsyncLang,
|
|
8012
8018
|
onSpeechEnd: () => {
|
|
8013
8019
|
d.current.onCustomAction({
|
|
@@ -8024,14 +8030,14 @@ const yt = Me(({
|
|
|
8024
8030
|
});
|
|
8025
8031
|
}
|
|
8026
8032
|
else {
|
|
8027
|
-
const
|
|
8033
|
+
const O = y()?.questions?.length || 0;
|
|
8028
8034
|
d.current.onCustomAction({
|
|
8029
8035
|
type: "answerFeedbackComplete",
|
|
8030
8036
|
moduleIndex: a.current.currentModuleIndex,
|
|
8031
8037
|
lessonIndex: a.current.currentLessonIndex,
|
|
8032
8038
|
questionIndex: a.current.currentQuestionIndex,
|
|
8033
|
-
isCorrect:
|
|
8034
|
-
hasNextQuestion: a.current.currentQuestionIndex <
|
|
8039
|
+
isCorrect: T,
|
|
8040
|
+
hasNextQuestion: a.current.currentQuestionIndex < O - 1,
|
|
8035
8041
|
score: a.current.score,
|
|
8036
8042
|
totalQuestions: a.current.totalQuestions,
|
|
8037
8043
|
avatarNotReady: !0
|
|
@@ -8047,7 +8053,7 @@ const yt = Me(({
|
|
|
8047
8053
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
8048
8054
|
return;
|
|
8049
8055
|
}
|
|
8050
|
-
const
|
|
8056
|
+
const T = {
|
|
8051
8057
|
passed: v.passed === !0,
|
|
8052
8058
|
results: v.results || [],
|
|
8053
8059
|
output: v.output || "",
|
|
@@ -8062,9 +8068,9 @@ const yt = Me(({
|
|
|
8062
8068
|
moduleIndex: a.current.currentModuleIndex,
|
|
8063
8069
|
lessonIndex: a.current.currentLessonIndex,
|
|
8064
8070
|
questionIndex: a.current.currentQuestionIndex,
|
|
8065
|
-
testResult:
|
|
8071
|
+
testResult: T,
|
|
8066
8072
|
question: R
|
|
8067
|
-
}), p.current && p.current(
|
|
8073
|
+
}), p.current && p.current(T);
|
|
8068
8074
|
}, [I, z]), oe = N(() => {
|
|
8069
8075
|
if (a.current.currentQuestionIndex > 0) {
|
|
8070
8076
|
a.current.currentQuestionIndex -= 1;
|
|
@@ -8081,25 +8087,25 @@ const yt = Me(({
|
|
|
8081
8087
|
const R = () => {
|
|
8082
8088
|
if (!u.current || !v) return;
|
|
8083
8089
|
u.current.setMood("happy"), u.current.setBodyMovement("idle");
|
|
8084
|
-
const
|
|
8090
|
+
const T = H.current || { lipsyncLang: "en" };
|
|
8085
8091
|
v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
|
|
8086
|
-
lipsyncLang:
|
|
8092
|
+
lipsyncLang: T.lipsyncLang
|
|
8087
8093
|
}) : u.current.speakText(`Going back to: ${v.question}`, {
|
|
8088
|
-
lipsyncLang:
|
|
8094
|
+
lipsyncLang: T.lipsyncLang
|
|
8089
8095
|
});
|
|
8090
8096
|
};
|
|
8091
8097
|
if (u.current && u.current.isReady && v)
|
|
8092
8098
|
R();
|
|
8093
8099
|
else if (v) {
|
|
8094
|
-
const
|
|
8095
|
-
u.current && u.current.isReady && (clearInterval(
|
|
8100
|
+
const T = setInterval(() => {
|
|
8101
|
+
u.current && u.current.isReady && (clearInterval(T), R());
|
|
8096
8102
|
}, 100);
|
|
8097
8103
|
setTimeout(() => {
|
|
8098
|
-
clearInterval(
|
|
8104
|
+
clearInterval(T);
|
|
8099
8105
|
}, 5e3);
|
|
8100
8106
|
}
|
|
8101
8107
|
}
|
|
8102
|
-
}, [I]),
|
|
8108
|
+
}, [I]), he = N(() => {
|
|
8103
8109
|
const v = P.current || { modules: [] };
|
|
8104
8110
|
if (v.modules[a.current.currentModuleIndex], a.current.currentLessonIndex > 0)
|
|
8105
8111
|
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({
|
|
@@ -8123,30 +8129,30 @@ const yt = Me(({
|
|
|
8123
8129
|
lesson: y()
|
|
8124
8130
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8125
8131
|
}
|
|
8126
|
-
}, [y]),
|
|
8132
|
+
}, [y]), K = N(() => {
|
|
8127
8133
|
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;
|
|
8128
|
-
}, []),
|
|
8134
|
+
}, []), Q = N((v) => {
|
|
8129
8135
|
console.log("Avatar is ready!", v);
|
|
8130
|
-
const R = y(),
|
|
8131
|
-
h &&
|
|
8136
|
+
const R = y(), T = R?.avatar_script || R?.body;
|
|
8137
|
+
h && T && setTimeout(() => {
|
|
8132
8138
|
c.current && c.current();
|
|
8133
8139
|
}, 10);
|
|
8134
8140
|
}, [h, y]);
|
|
8135
8141
|
Xe(() => {
|
|
8136
|
-
c.current = B, g.current = _, b.current = A, x.current =
|
|
8142
|
+
c.current = B, g.current = _, b.current = A, x.current = C, S.current = Y, G.current = k, p.current = ee;
|
|
8137
8143
|
}), Fe(r, () => ({
|
|
8138
8144
|
// Curriculum control methods
|
|
8139
8145
|
startTeaching: B,
|
|
8140
8146
|
startQuestions: k,
|
|
8141
|
-
handleAnswerSelect:
|
|
8147
|
+
handleAnswerSelect: ee,
|
|
8142
8148
|
handleCodeTestResult: ie,
|
|
8143
|
-
nextQuestion:
|
|
8149
|
+
nextQuestion: C,
|
|
8144
8150
|
previousQuestion: oe,
|
|
8145
8151
|
nextLesson: _,
|
|
8146
|
-
previousLesson:
|
|
8152
|
+
previousLesson: he,
|
|
8147
8153
|
completeLesson: A,
|
|
8148
|
-
completeCurriculum:
|
|
8149
|
-
resetCurriculum:
|
|
8154
|
+
completeCurriculum: Y,
|
|
8155
|
+
resetCurriculum: K,
|
|
8150
8156
|
getState: () => ({ ...a.current }),
|
|
8151
8157
|
getCurrentQuestion: () => I(),
|
|
8152
8158
|
getCurrentLesson: () => y(),
|
|
@@ -8155,8 +8161,8 @@ const yt = Me(({
|
|
|
8155
8161
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8156
8162
|
speakText: async (v, R = {}) => {
|
|
8157
8163
|
await u.current?.resumeAudioContext?.();
|
|
8158
|
-
const
|
|
8159
|
-
u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang ||
|
|
8164
|
+
const T = H.current || { lipsyncLang: "en" };
|
|
8165
|
+
u.current?.speakText(v, { ...R, lipsyncLang: R.lipsyncLang || T.lipsyncLang });
|
|
8160
8166
|
},
|
|
8161
8167
|
resumeAudioContext: async () => {
|
|
8162
8168
|
if (u.current?.resumeAudioContext)
|
|
@@ -8167,8 +8173,8 @@ const yt = Me(({
|
|
|
8167
8173
|
if (R.state === "suspended" || R.state === "interrupted")
|
|
8168
8174
|
try {
|
|
8169
8175
|
await R.resume(), console.log("Audio context resumed via talkingHead");
|
|
8170
|
-
} catch (
|
|
8171
|
-
console.warn("Failed to resume audio context:",
|
|
8176
|
+
} catch (T) {
|
|
8177
|
+
console.warn("Failed to resume audio context:", T);
|
|
8172
8178
|
}
|
|
8173
8179
|
} else
|
|
8174
8180
|
console.warn("Audio context not available yet");
|
|
@@ -8200,8 +8206,8 @@ const yt = Me(({
|
|
|
8200
8206
|
handleResize: () => u.current?.handleResize(),
|
|
8201
8207
|
// Avatar readiness check (always returns current value)
|
|
8202
8208
|
isAvatarReady: () => u.current?.isReady || !1
|
|
8203
|
-
}), [B, k,
|
|
8204
|
-
const
|
|
8209
|
+
}), [B, k, ee, ie, C, _, A, Y, K, I, y]);
|
|
8210
|
+
const W = H.current || {
|
|
8205
8211
|
avatarUrl: "/avatars/brunette.glb",
|
|
8206
8212
|
avatarBody: "F",
|
|
8207
8213
|
mood: "happy",
|
|
@@ -8218,19 +8224,19 @@ const yt = Me(({
|
|
|
8218
8224
|
Ve,
|
|
8219
8225
|
{
|
|
8220
8226
|
ref: u,
|
|
8221
|
-
avatarUrl:
|
|
8222
|
-
avatarBody:
|
|
8223
|
-
mood:
|
|
8224
|
-
ttsLang:
|
|
8225
|
-
ttsService:
|
|
8226
|
-
ttsVoice:
|
|
8227
|
-
ttsApiKey:
|
|
8228
|
-
bodyMovement:
|
|
8229
|
-
movementIntensity:
|
|
8230
|
-
showFullAvatar:
|
|
8227
|
+
avatarUrl: W.avatarUrl,
|
|
8228
|
+
avatarBody: W.avatarBody,
|
|
8229
|
+
mood: W.mood,
|
|
8230
|
+
ttsLang: W.ttsLang,
|
|
8231
|
+
ttsService: W.ttsService,
|
|
8232
|
+
ttsVoice: W.ttsVoice,
|
|
8233
|
+
ttsApiKey: W.ttsApiKey,
|
|
8234
|
+
bodyMovement: W.bodyMovement,
|
|
8235
|
+
movementIntensity: W.movementIntensity,
|
|
8236
|
+
showFullAvatar: W.showFullAvatar,
|
|
8231
8237
|
cameraView: "upper",
|
|
8232
|
-
animations:
|
|
8233
|
-
onReady:
|
|
8238
|
+
animations: W.animations,
|
|
8239
|
+
onReady: Q,
|
|
8234
8240
|
onLoading: () => {
|
|
8235
8241
|
},
|
|
8236
8242
|
onError: (v) => {
|
|
@@ -8343,7 +8349,7 @@ const Ge = {
|
|
|
8343
8349
|
duration: 5e3,
|
|
8344
8350
|
description: "Excited, energetic movement"
|
|
8345
8351
|
}
|
|
8346
|
-
}, wt = (
|
|
8352
|
+
}, wt = (X) => Ge[X] || null, zt = (X) => Ge.hasOwnProperty(X);
|
|
8347
8353
|
export {
|
|
8348
8354
|
yt as CurriculumLearning,
|
|
8349
8355
|
gt as SimpleTalkingAvatar,
|