@sage-rsc/talking-head-react 1.7.6 → 1.7.7
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 +5 -5
- package/dist/index.js +389 -388
- package/package.json +1 -1
- package/src/components/SimpleTalkingAvatar.jsx +12 -14
- package/src/utils/animationLoader.js +24 -2
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { jsxs as we, jsx as
|
|
2
|
-
import { forwardRef as Ye, useRef as
|
|
1
|
+
import { jsxs as we, jsx as J } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as Ye, useRef as V, useState as le, useEffect as Re, useCallback as N, useImperativeHandle as Qe, useLayoutEffect as rt } from "react";
|
|
3
3
|
import * as b from "three";
|
|
4
4
|
import { OrbitControls as at } from "three/addons/controls/OrbitControls.js";
|
|
5
5
|
import { GLTFLoader as lt } from "three/addons/loaders/GLTFLoader.js";
|
|
6
6
|
import { DRACOLoader as ut } from "three/addons/loaders/DRACOLoader.js";
|
|
7
|
-
import { FBXLoader as
|
|
7
|
+
import { FBXLoader as Je } from "three/addons/loaders/FBXLoader.js";
|
|
8
8
|
import { RoomEnvironment as ct } from "three/addons/environments/RoomEnvironment.js";
|
|
9
9
|
import ht from "three/addons/libs/stats.module.js";
|
|
10
10
|
let p, be, Le;
|
|
@@ -12,7 +12,7 @@ const z = [0, 0, 0, 0], O = new b.Vector3(), Ge = new b.Vector3(), pe = new b.Ve
|
|
|
12
12
|
new b.Plane();
|
|
13
13
|
new b.Ray();
|
|
14
14
|
new b.Euler();
|
|
15
|
-
const ge = new b.Quaternion(),
|
|
15
|
+
const ge = new b.Quaternion(), $e = new b.Quaternion(), ze = new b.Matrix4(), He = new b.Matrix4();
|
|
16
16
|
new b.Vector3();
|
|
17
17
|
const Xe = new b.Vector3(0, 0, 1), dt = new b.Vector3(1, 0, 0), mt = new b.Vector3(0, 1, 0), pt = new b.Vector3(0, 0, 1);
|
|
18
18
|
class gt {
|
|
@@ -338,7 +338,7 @@ class gt {
|
|
|
338
338
|
ea: [0, 0, 0, 0]
|
|
339
339
|
// External acceleration [m/s^2]
|
|
340
340
|
};
|
|
341
|
-
u.boneParent.matrixWorld.decompose(O, ge, pe), O.copy(Xe).applyQuaternion(ge).setY(0).normalize(), ge.premultiply(
|
|
341
|
+
u.boneParent.matrixWorld.decompose(O, ge, pe), O.copy(Xe).applyQuaternion(ge).setY(0).normalize(), ge.premultiply($e.setFromUnitVectors(Xe, O).invert()).normalize(), u.qWorldInverseYaw = ge.clone().normalize(), this.data.push(u), this.dict[c] = u;
|
|
342
342
|
try {
|
|
343
343
|
this.setValue(c, "type", s.type), this.setValue(c, "stiffness", s.stiffness), this.setValue(c, "damping", s.damping), this.setValue(c, "external", s.external), this.setValue(c, "limits", s.limits), this.setValue(c, "excludes", s.excludes), this.setValue(c, "deltaLocal", s.deltaLocal), this.setValue(c, "deltaWorld", s.deltaWorld), this.setValue(c, "pivot", s.pivot), this.setValue(c, "helper", s.helper);
|
|
344
344
|
} catch (r) {
|
|
@@ -369,7 +369,7 @@ class gt {
|
|
|
369
369
|
i.vBasis.y + z[1],
|
|
370
370
|
i.vBasis.z - z[2]
|
|
371
371
|
);
|
|
372
|
-
else if (i.boneParent.quaternion.copy(i.qBasis), i.pivot && this.opt.isPivots && (i.boneParent.updateWorldMatrix(!1, !1), i.boneParent.matrixWorld.decompose(O, ge, pe), O.copy(Xe).applyQuaternion(ge).setY(0).normalize(), ge.premultiply(
|
|
372
|
+
else if (i.boneParent.quaternion.copy(i.qBasis), i.pivot && this.opt.isPivots && (i.boneParent.updateWorldMatrix(!1, !1), i.boneParent.matrixWorld.decompose(O, ge, pe), O.copy(Xe).applyQuaternion(ge).setY(0).normalize(), ge.premultiply($e.setFromUnitVectors(Xe, O).invert()).normalize(), i.boneParent.quaternion.multiply(ge.invert()), i.boneParent.quaternion.multiply(i.qWorldInverseYaw)), i.isZ && (p = Math.atan(z[0] / i.l), ge.setFromAxisAngle(pt, -p), i.boneParent.quaternion.multiply(ge)), i.isY && (p = i.l / 3, p = p * Math.tanh(z[1] / p), i.bone.position.setLength(i.l + p)), i.isX && (p = Math.atan(z[2] / i.l), ge.setFromAxisAngle(dt, -p), i.boneParent.quaternion.multiply(ge)), i.isT && (p = 1.5 * Math.tanh(z[3] * 1.5), ge.setFromAxisAngle(mt, -p), i.boneParent.quaternion.multiply(ge)), i.boneParent.updateWorldMatrix(!1, !0), i.excludes && this.opt.isExcludes)
|
|
373
373
|
for (n = 0, s = i.excludes.length; n < s; n++)
|
|
374
374
|
p = i.excludes[n], pe.set(0, 0, 0), p.deltaLocal && (pe.x += p.deltaLocal[0], pe.y += p.deltaLocal[1], pe.z += p.deltaLocal[2]), pe.applyMatrix4(p.bone.matrixWorld), He.copy(i.boneParent.matrixWorld).invert(), pe.applyMatrix4(He), O.copy(i.bone.position), !(O.distanceToSquared(pe) >= p.radiusSq) && (Le = O.length(), be = pe.length(), !(be > p.radius + Le) && (be < Math.abs(p.radius - Le) || (be = (be * be + Le * Le - p.radiusSq) / (2 * be), pe.normalize(), Ze.copy(pe).multiplyScalar(be), be = Math.sqrt(Le * Le - be * be), O.subVectors(O, Ze).projectOnPlane(pe).normalize().multiplyScalar(be), Ge.subVectors(i.vBasis, Ze).projectOnPlane(pe).normalize(), Le = Ge.dot(O), Le < 0 && (Le = Math.sqrt(be * be - Le * Le), Ge.multiplyScalar(Le), O.add(Ge)), O.add(Ze).normalize(), pe.copy(i.bone.position).normalize(), ge.setFromUnitVectors(pe, O), i.boneParent.quaternion.premultiply(ge), i.boneParent.updateWorldMatrix(!1, !0))));
|
|
375
375
|
}
|
|
@@ -608,8 +608,8 @@ class yt {
|
|
|
608
608
|
for (let r = 0; r < o / 2; r++) {
|
|
609
609
|
const d = n[(c + r) * 2], h = n[(c + r) * 2 + 1], g = n[(c + r + o / 2) * 2] * l - n[(c + r + o / 2) * 2 + 1] * u, R = n[(c + r + o / 2) * 2] * u + n[(c + r + o / 2) * 2 + 1] * l;
|
|
610
610
|
n[(c + r) * 2] = d + g, n[(c + r) * 2 + 1] = h + R, n[(c + r + o / 2) * 2] = d - g, n[(c + r + o / 2) * 2 + 1] = h - R;
|
|
611
|
-
const x = l * i - u * a,
|
|
612
|
-
l = x, u =
|
|
611
|
+
const x = l * i - u * a, k = l * a + u * i;
|
|
612
|
+
l = x, u = k;
|
|
613
613
|
}
|
|
614
614
|
}
|
|
615
615
|
}
|
|
@@ -4228,13 +4228,13 @@ class _e {
|
|
|
4228
4228
|
const r = s.morphTargetDictionary[l], d = i.morphAttributes.position[r], h = i.morphAttributes.normal?.[r];
|
|
4229
4229
|
a || (a = new b.Float32BufferAttribute(d.count * 3, 3), h && (c = new b.Float32BufferAttribute(d.count * 3, 3)));
|
|
4230
4230
|
for (let g = 0; g < d.count; g++) {
|
|
4231
|
-
const R = a.getX(g) + d.getX(g) * u, x = a.getY(g) + d.getY(g) * u,
|
|
4232
|
-
a.setXYZ(g, R, x,
|
|
4231
|
+
const R = a.getX(g) + d.getX(g) * u, x = a.getY(g) + d.getY(g) * u, k = a.getZ(g) + d.getZ(g) * u;
|
|
4232
|
+
a.setXYZ(g, R, x, k);
|
|
4233
4233
|
}
|
|
4234
4234
|
if (h)
|
|
4235
4235
|
for (let g = 0; g < d.count; g++) {
|
|
4236
|
-
const R = c.getX(g) + h.getX(g) * u, x = c.getY(g) + h.getY(g) * u,
|
|
4237
|
-
c.setXYZ(g, R, x,
|
|
4236
|
+
const R = c.getX(g) + h.getX(g) * u, x = c.getY(g) + h.getY(g) * u, k = c.getZ(g) + h.getZ(g) * u;
|
|
4237
|
+
c.setXYZ(g, R, x, k);
|
|
4238
4238
|
}
|
|
4239
4239
|
}
|
|
4240
4240
|
if (a) {
|
|
@@ -5271,10 +5271,10 @@ class _e {
|
|
|
5271
5271
|
let u = "", r = "", d = 0, h = [], g = [];
|
|
5272
5272
|
const R = Array.from(this.segmenter.segment(t), (x) => x.segment);
|
|
5273
5273
|
for (let x = 0; x < R.length; x++) {
|
|
5274
|
-
const
|
|
5274
|
+
const k = x === R.length - 1, G = R[x].match(a);
|
|
5275
5275
|
let m = R[x].match(s);
|
|
5276
5276
|
const B = R[x].match(c), M = R[x].match(i);
|
|
5277
|
-
if (m && !
|
|
5277
|
+
if (m && !k && !B && R[x + 1].match(s) && (m = !1), n && (u += R[x]), G && (!o || o.every((y) => x < y[0] || x > y[1])) && (r += R[x]), (M || m || k) && (r.length && (r = this.lipsyncPreProcessText(r, l), r.length && h.push({
|
|
5278
5278
|
mark: d,
|
|
5279
5279
|
word: r
|
|
5280
5280
|
})), u.length && (g.push({
|
|
@@ -5288,20 +5288,20 @@ class _e {
|
|
|
5288
5288
|
const y = this.lipsyncWordsToVisemes(r, l);
|
|
5289
5289
|
if (y && y.visemes && y.visemes.length) {
|
|
5290
5290
|
const F = y.times[y.visemes.length - 1] + y.durations[y.visemes.length - 1];
|
|
5291
|
-
for (let
|
|
5291
|
+
for (let L = 0; L < y.visemes.length; L++)
|
|
5292
5292
|
g.push({
|
|
5293
5293
|
mark: d,
|
|
5294
5294
|
template: { name: "viseme" },
|
|
5295
|
-
ts: [(y.times[
|
|
5295
|
+
ts: [(y.times[L] - 0.6) / F, (y.times[L] + 0.5) / F, (y.times[L] + y.durations[L] + 0.5) / F],
|
|
5296
5296
|
vs: {
|
|
5297
|
-
["viseme_" + y.visemes[
|
|
5297
|
+
["viseme_" + y.visemes[L]]: [null, y.visemes[L] === "PP" || y.visemes[L] === "FF" ? 0.9 : 0.6, 0]
|
|
5298
5298
|
}
|
|
5299
5299
|
});
|
|
5300
5300
|
}
|
|
5301
5301
|
r = "", d++;
|
|
5302
5302
|
}
|
|
5303
|
-
if (m ||
|
|
5304
|
-
if (h.length ||
|
|
5303
|
+
if (m || k) {
|
|
5304
|
+
if (h.length || k && g.length) {
|
|
5305
5305
|
const y = {
|
|
5306
5306
|
anim: g
|
|
5307
5307
|
};
|
|
@@ -5405,10 +5405,10 @@ class _e {
|
|
|
5405
5405
|
let R = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
|
|
5406
5406
|
if (u = Math.min(u, d.visemes.length * 200), h > 0)
|
|
5407
5407
|
for (let x = 0; x < d.visemes.length; x++) {
|
|
5408
|
-
const
|
|
5408
|
+
const k = l + d.times[x] / h * u, G = d.durations[x] / h * u;
|
|
5409
5409
|
i.push({
|
|
5410
5410
|
template: { name: "viseme" },
|
|
5411
|
-
ts: [
|
|
5411
|
+
ts: [k - Math.min(60, 2 * G / 3), k + Math.min(25, G / 2), k + G + Math.min(60, G / 2)],
|
|
5412
5412
|
vs: {
|
|
5413
5413
|
["viseme_" + d.visemes[x]]: [null, d.visemes[x] === "PP" || d.visemes[x] === "FF" ? 0.9 : R, 0]
|
|
5414
5414
|
}
|
|
@@ -5493,21 +5493,21 @@ class _e {
|
|
|
5493
5493
|
const m = u.find((B) => B.name.includes(r) || B.lang === i);
|
|
5494
5494
|
m && (s.voice = m);
|
|
5495
5495
|
}
|
|
5496
|
-
const d = o.length * 100 / s.rate, h = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (d / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", R = this.lipsyncPreProcessText(o, g), x = this.lipsyncWordsToVisemes(R, g),
|
|
5496
|
+
const d = o.length * 100 / s.rate, h = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (d / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", R = this.lipsyncPreProcessText(o, g), x = this.lipsyncWordsToVisemes(R, g), k = [];
|
|
5497
5497
|
if (x && x.visemes && x.visemes.length > 0) {
|
|
5498
5498
|
const m = x.times[x.visemes.length - 1] + x.durations[x.visemes.length - 1];
|
|
5499
5499
|
for (let B = 0; B < x.visemes.length; B++) {
|
|
5500
|
-
const M = x.visemes[B], y = x.times[B] / m, F = x.durations[B] / m,
|
|
5501
|
-
|
|
5500
|
+
const M = x.visemes[B], y = x.times[B] / m, F = x.durations[B] / m, L = y * d, f = F * d;
|
|
5501
|
+
k.push({
|
|
5502
5502
|
template: { name: "viseme" },
|
|
5503
|
-
ts: [
|
|
5503
|
+
ts: [L - Math.min(60, 2 * f / 3), L + Math.min(25, f / 2), L + f + Math.min(60, f / 2)],
|
|
5504
5504
|
vs: {
|
|
5505
5505
|
["viseme_" + M]: [null, M === "PP" || M === "FF" ? 0.9 : 0.6, 0]
|
|
5506
5506
|
}
|
|
5507
5507
|
});
|
|
5508
5508
|
}
|
|
5509
5509
|
}
|
|
5510
|
-
const G = [...t.anim, ...
|
|
5510
|
+
const G = [...t.anim, ...k];
|
|
5511
5511
|
this.audioPlaylist.push({ anim: G, audio: h }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
|
|
5512
5512
|
e();
|
|
5513
5513
|
}, s.onerror = (m) => {
|
|
@@ -5573,8 +5573,8 @@ class _e {
|
|
|
5573
5573
|
const h = e.toLowerCase().split(/\s+/), g = [];
|
|
5574
5574
|
for (const R of h)
|
|
5575
5575
|
for (const x of R) {
|
|
5576
|
-
let
|
|
5577
|
-
"aeiou".includes(x) ?
|
|
5576
|
+
let k = "aa";
|
|
5577
|
+
"aeiou".includes(x) ? k = "aa" : "bp".includes(x) ? k = "PP" : "fv".includes(x) ? k = "FF" : "st".includes(x) ? k = "SS" : "dln".includes(x) ? k = "DD" : "kg".includes(x) ? k = "kk" : "rw".includes(x) && (k = "RR"), g.push(k);
|
|
5578
5578
|
}
|
|
5579
5579
|
l = {
|
|
5580
5580
|
visemes: g.map((R, x) => ({
|
|
@@ -5655,8 +5655,8 @@ class _e {
|
|
|
5655
5655
|
const h = e.toLowerCase().split(/\s+/), g = [];
|
|
5656
5656
|
for (const R of h)
|
|
5657
5657
|
for (const x of R) {
|
|
5658
|
-
let
|
|
5659
|
-
"aeiou".includes(x) ?
|
|
5658
|
+
let k = "aa";
|
|
5659
|
+
"aeiou".includes(x) ? k = "aa" : "bp".includes(x) ? k = "PP" : "fv".includes(x) ? k = "FF" : "st".includes(x) ? k = "SS" : "dln".includes(x) ? k = "DD" : "kg".includes(x) ? k = "kk" : "rw".includes(x) && (k = "RR"), g.push(k);
|
|
5660
5660
|
}
|
|
5661
5661
|
l = {
|
|
5662
5662
|
visemes: g.map((R, x) => ({
|
|
@@ -6119,7 +6119,7 @@ class _e {
|
|
|
6119
6119
|
q.setFromQuaternion(c, "YXZ");
|
|
6120
6120
|
let l = q.x / (40 / 24) + 0.2, u = q.y / (9 / 4), r = Math.min(0.6, Math.max(-0.3, l)), d = Math.min(0.8, Math.max(-0.8, u)), h = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6121
6121
|
if (t) {
|
|
6122
|
-
let R = this.animQueue.findIndex((
|
|
6122
|
+
let R = this.animQueue.findIndex((k) => k.template.name === "lookat");
|
|
6123
6123
|
R !== -1 && this.animQueue.splice(R, 1);
|
|
6124
6124
|
const x = {
|
|
6125
6125
|
name: "lookat",
|
|
@@ -6153,8 +6153,8 @@ class _e {
|
|
|
6153
6153
|
a.project(this.camera);
|
|
6154
6154
|
let c = (a.x + 1) / 2 * o.width + o.left, l = -(a.y - 1) / 2 * o.height + o.top;
|
|
6155
6155
|
t === null && (t = c), e === null && (e = l), ne.copy(this.armature.quaternion), ne.multiply(this.poseTarget.props["Hips.quaternion"]), ne.multiply(this.poseTarget.props["Spine.quaternion"]), ne.multiply(this.poseTarget.props["Spine1.quaternion"]), ne.multiply(this.poseTarget.props["Spine2.quaternion"]), ne.multiply(this.poseTarget.props["Neck.quaternion"]), ne.multiply(this.poseTarget.props["Head.quaternion"]), q.setFromQuaternion(ne);
|
|
6156
|
-
let u = q.x / (40 / 24), r = q.y / (9 / 4), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), h = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - c, c), R = Math.max(window.innerHeight - l, l), x = this.convertRange(e, [l - R, l + R], [-0.3, 0.6]) - u + d,
|
|
6157
|
-
x = Math.min(0.6, Math.max(-0.3, x)),
|
|
6156
|
+
let u = q.x / (40 / 24), r = q.y / (9 / 4), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), h = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - c, c), R = Math.max(window.innerHeight - l, l), x = this.convertRange(e, [l - R, l + R], [-0.3, 0.6]) - u + d, k = this.convertRange(t, [c - g, c + g], [-0.8, 0.8]) - r + h;
|
|
6157
|
+
x = Math.min(0.6, Math.max(-0.3, x)), k = Math.min(0.8, Math.max(-0.8, k));
|
|
6158
6158
|
let G = (Math.random() - 0.5) / 4, m = (Math.random() - 0.5) / 4;
|
|
6159
6159
|
if (n) {
|
|
6160
6160
|
let B = this.animQueue.findIndex((y) => y.template.name === "lookat");
|
|
@@ -6164,7 +6164,7 @@ class _e {
|
|
|
6164
6164
|
dt: [750, n],
|
|
6165
6165
|
vs: {
|
|
6166
6166
|
bodyRotateX: [x + G],
|
|
6167
|
-
bodyRotateY: [
|
|
6167
|
+
bodyRotateY: [k + m],
|
|
6168
6168
|
eyesRotateX: [-3 * G + 0.1],
|
|
6169
6169
|
eyesRotateY: [-5 * m],
|
|
6170
6170
|
browInnerUp: [[0, 0.7]],
|
|
@@ -6386,7 +6386,7 @@ class _e {
|
|
|
6386
6386
|
} catch (h) {
|
|
6387
6387
|
console.warn(`Could not verify file existence for ${t}, attempting to load anyway:`, h);
|
|
6388
6388
|
}
|
|
6389
|
-
const r = new
|
|
6389
|
+
const r = new Je();
|
|
6390
6390
|
let d;
|
|
6391
6391
|
try {
|
|
6392
6392
|
d = await r.loadAsync(t, e);
|
|
@@ -6421,28 +6421,28 @@ class _e {
|
|
|
6421
6421
|
let F = y.replace(/^mixamorig/i, "").replace(/^CC_Base_/i, "").replace(/^RPM_/i, "");
|
|
6422
6422
|
if (g.has(F))
|
|
6423
6423
|
return F;
|
|
6424
|
-
const
|
|
6425
|
-
if (
|
|
6426
|
-
if (
|
|
6424
|
+
const L = F.toLowerCase();
|
|
6425
|
+
if (L.includes("left") && L.includes("arm")) {
|
|
6426
|
+
if (L.includes("fore") || L.includes("lower")) {
|
|
6427
6427
|
if (g.has("LeftForeArm")) return "LeftForeArm";
|
|
6428
6428
|
if (g.has("LeftForearm")) return "LeftForearm";
|
|
6429
|
-
} else if (!
|
|
6429
|
+
} else if (!L.includes("fore") && !L.includes("hand") && g.has("LeftArm"))
|
|
6430
6430
|
return "LeftArm";
|
|
6431
6431
|
}
|
|
6432
|
-
if (
|
|
6433
|
-
if (
|
|
6432
|
+
if (L.includes("right") && L.includes("arm")) {
|
|
6433
|
+
if (L.includes("fore") || L.includes("lower")) {
|
|
6434
6434
|
if (g.has("RightForeArm")) return "RightForeArm";
|
|
6435
6435
|
if (g.has("RightForearm")) return "RightForearm";
|
|
6436
|
-
} else if (!
|
|
6436
|
+
} else if (!L.includes("fore") && !L.includes("hand") && g.has("RightArm"))
|
|
6437
6437
|
return "RightArm";
|
|
6438
6438
|
}
|
|
6439
|
-
if (
|
|
6439
|
+
if (L.includes("left") && L.includes("hand") && !L.includes("index") && !L.includes("thumb") && !L.includes("middle") && !L.includes("ring") && !L.includes("pinky") && g.has("LeftHand"))
|
|
6440
6440
|
return "LeftHand";
|
|
6441
|
-
if (
|
|
6441
|
+
if (L.includes("right") && L.includes("hand") && !L.includes("index") && !L.includes("thumb") && !L.includes("middle") && !L.includes("ring") && !L.includes("pinky") && g.has("RightHand"))
|
|
6442
6442
|
return "RightHand";
|
|
6443
|
-
if (
|
|
6443
|
+
if (L.includes("left") && (L.includes("shoulder") || L.includes("clavicle")) && g.has("LeftShoulder"))
|
|
6444
6444
|
return "LeftShoulder";
|
|
6445
|
-
if (
|
|
6445
|
+
if (L.includes("right") && (L.includes("shoulder") || L.includes("clavicle")) && g.has("RightShoulder"))
|
|
6446
6446
|
return "RightShoulder";
|
|
6447
6447
|
const f = {
|
|
6448
6448
|
// Arm bones - exact matches
|
|
@@ -6485,34 +6485,34 @@ class _e {
|
|
|
6485
6485
|
root: "Hips"
|
|
6486
6486
|
};
|
|
6487
6487
|
if (f[F]) {
|
|
6488
|
-
const
|
|
6489
|
-
if (g.has(
|
|
6490
|
-
return
|
|
6488
|
+
const T = f[F];
|
|
6489
|
+
if (g.has(T))
|
|
6490
|
+
return T;
|
|
6491
6491
|
}
|
|
6492
|
-
for (const
|
|
6493
|
-
if (
|
|
6494
|
-
return
|
|
6495
|
-
for (const
|
|
6496
|
-
const A =
|
|
6497
|
-
if ((
|
|
6498
|
-
return
|
|
6492
|
+
for (const T of g)
|
|
6493
|
+
if (T.toLowerCase() === L)
|
|
6494
|
+
return T;
|
|
6495
|
+
for (const T of g) {
|
|
6496
|
+
const A = T.toLowerCase();
|
|
6497
|
+
if ((L.includes("left") && A.includes("left") || L.includes("right") && A.includes("right")) && (L.includes("arm") && A.includes("arm") && !A.includes("fore") || L.includes("forearm") && A.includes("forearm") || L.includes("hand") && A.includes("hand") && !A.includes("index") && !A.includes("thumb") || L.includes("shoulder") && A.includes("shoulder")))
|
|
6498
|
+
return T;
|
|
6499
6499
|
}
|
|
6500
6500
|
return null;
|
|
6501
|
-
},
|
|
6501
|
+
}, k = /* @__PURE__ */ new Set();
|
|
6502
6502
|
h.tracks.forEach((y) => {
|
|
6503
6503
|
const F = y.name.split(".");
|
|
6504
|
-
|
|
6505
|
-
}), Array.from(
|
|
6504
|
+
k.add(F[0]);
|
|
6505
|
+
}), Array.from(k).filter(
|
|
6506
6506
|
(y) => y.toLowerCase().includes("arm") || y.toLowerCase().includes("hand") || y.toLowerCase().includes("shoulder")
|
|
6507
6507
|
), Array.from(g).filter(
|
|
6508
6508
|
(y) => y.includes("Arm") || y.includes("Hand") || y.includes("Shoulder")
|
|
6509
6509
|
);
|
|
6510
6510
|
const G = [], m = /* @__PURE__ */ new Set();
|
|
6511
6511
|
h.tracks.forEach((y) => {
|
|
6512
|
-
const
|
|
6513
|
-
if (!(A && (A === "LeftShoulder" || A === "RightShoulder") && (
|
|
6514
|
-
if (A &&
|
|
6515
|
-
const D = `${A}.${
|
|
6512
|
+
const L = y.name.replaceAll("mixamorig", "").split("."), f = L[0], T = L[1], A = x(f);
|
|
6513
|
+
if (!(A && (A === "LeftShoulder" || A === "RightShoulder") && (T === "quaternion" || T === "rotation")))
|
|
6514
|
+
if (A && T) {
|
|
6515
|
+
const D = `${A}.${T}`, U = y.clone();
|
|
6516
6516
|
U.name = D, G.push(U), f !== A && R.set(f, A);
|
|
6517
6517
|
} else
|
|
6518
6518
|
m.add(f), (f.toLowerCase().includes("arm") || f.toLowerCase().includes("hand") || f.toLowerCase().includes("shoulder")) && console.warn(`⚠️ Arm bone "${f}" could not be mapped to avatar skeleton`);
|
|
@@ -6522,8 +6522,8 @@ class _e {
|
|
|
6522
6522
|
y.name = y.name.replaceAll("mixamorig", "");
|
|
6523
6523
|
const F = y.name.split(".");
|
|
6524
6524
|
if (F[1] === "position") {
|
|
6525
|
-
for (let
|
|
6526
|
-
y.values[
|
|
6525
|
+
for (let L = 0; L < y.values.length; L++)
|
|
6526
|
+
y.values[L] = y.values[L] * s;
|
|
6527
6527
|
B[y.name] = new b.Vector3(y.values[0], y.values[1], y.values[2]);
|
|
6528
6528
|
} else F[1] === "quaternion" ? B[y.name] = new b.Quaternion(y.values[0], y.values[1], y.values[2], y.values[3]) : F[1] === "rotation" && (B[F[0] + ".quaternion"] = new b.Quaternion().setFromEuler(new b.Euler(y.values[0], y.values[1], y.values[2], "XYZ")).normalize());
|
|
6529
6529
|
});
|
|
@@ -6569,7 +6569,7 @@ class _e {
|
|
|
6569
6569
|
let a = this.animQueue.find((c) => c.template.name === "pose");
|
|
6570
6570
|
a && (a.ts[0] = this.animClock + n * 1e3 + 2e3), this.setPoseFromTemplate(i);
|
|
6571
6571
|
} else {
|
|
6572
|
-
let c = await new
|
|
6572
|
+
let c = await new Je().loadAsync(t, e);
|
|
6573
6573
|
if (c && c.animations && c.animations[o]) {
|
|
6574
6574
|
let l = c.animations[o];
|
|
6575
6575
|
const u = {};
|
|
@@ -6624,7 +6624,7 @@ class _e {
|
|
|
6624
6624
|
const d = [];
|
|
6625
6625
|
for (let R = 1; R < a.ts.length; R++) d.push(a.ts[R] - a.ts[R - 1]);
|
|
6626
6626
|
const h = i.template?.rescale || d.map((R) => R / u), g = e * 1e3 - u;
|
|
6627
|
-
a.ts = a.ts.map((R, x,
|
|
6627
|
+
a.ts = a.ts.map((R, x, k) => x === 0 ? c : k[x - 1] + d[x - 1] + h[x - 1] * g);
|
|
6628
6628
|
} else {
|
|
6629
6629
|
const d = e * 1e3 / u;
|
|
6630
6630
|
a.ts = a.ts.map((h) => c + d * (h - c));
|
|
@@ -6660,12 +6660,12 @@ class _e {
|
|
|
6660
6660
|
const s = new b.Vector3(), i = new b.Vector3(), a = new b.Vector3(), c = new b.Vector3(), l = new b.Quaternion(), u = new b.Vector3(), r = new b.Vector3(), d = new b.Vector3(), h = this.ikMesh.getObjectByName(t.root);
|
|
6661
6661
|
h.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), h.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && n && e.applyQuaternion(this.armature.quaternion).add(h.position);
|
|
6662
6662
|
const g = this.ikMesh.getObjectByName(t.effector), R = t.links;
|
|
6663
|
-
R.forEach((
|
|
6664
|
-
|
|
6663
|
+
R.forEach((k) => {
|
|
6664
|
+
k.bone = this.ikMesh.getObjectByName(k.link), k.bone.quaternion.copy(this.getPoseTemplateProp(k.link + ".quaternion"));
|
|
6665
6665
|
}), h.updateMatrixWorld(!0);
|
|
6666
6666
|
const x = t.iterations || 10;
|
|
6667
6667
|
if (e)
|
|
6668
|
-
for (let
|
|
6668
|
+
for (let k = 0; k < x; k++) {
|
|
6669
6669
|
let G = !1;
|
|
6670
6670
|
for (let m = 0, B = R.length; m < B; m++) {
|
|
6671
6671
|
const M = R[m].bone;
|
|
@@ -6683,8 +6683,8 @@ class _e {
|
|
|
6683
6683
|
}
|
|
6684
6684
|
if (!G) break;
|
|
6685
6685
|
}
|
|
6686
|
-
o && R.forEach((
|
|
6687
|
-
this.poseTarget.props[
|
|
6686
|
+
o && R.forEach((k) => {
|
|
6687
|
+
this.poseTarget.props[k.link + ".quaternion"].copy(k.bone.quaternion), this.poseTarget.props[k.link + ".quaternion"].t = this.animClock, this.poseTarget.props[k.link + ".quaternion"].d = o;
|
|
6688
6688
|
});
|
|
6689
6689
|
}
|
|
6690
6690
|
/**
|
|
@@ -6744,16 +6744,16 @@ function qe() {
|
|
|
6744
6744
|
};
|
|
6745
6745
|
}
|
|
6746
6746
|
function Wt() {
|
|
6747
|
-
const
|
|
6748
|
-
return Object.entries(
|
|
6747
|
+
const W = qe(), t = [];
|
|
6748
|
+
return Object.entries(W.voices).forEach(([e, n]) => {
|
|
6749
6749
|
t.push({
|
|
6750
6750
|
value: n,
|
|
6751
|
-
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${
|
|
6751
|
+
label: `${e.charAt(0).toUpperCase() + e.slice(1)} (${W.service})`
|
|
6752
6752
|
});
|
|
6753
6753
|
}), t;
|
|
6754
6754
|
}
|
|
6755
6755
|
const it = Ye(({
|
|
6756
|
-
avatarUrl:
|
|
6756
|
+
avatarUrl: W = "/avatars/brunette.glb",
|
|
6757
6757
|
avatarBody: t = "F",
|
|
6758
6758
|
mood: e = "neutral",
|
|
6759
6759
|
ttsLang: n = "en",
|
|
@@ -6773,8 +6773,8 @@ const it = Ye(({
|
|
|
6773
6773
|
className: g = "",
|
|
6774
6774
|
style: R = {},
|
|
6775
6775
|
animations: x = {}
|
|
6776
|
-
},
|
|
6777
|
-
const G =
|
|
6776
|
+
}, k) => {
|
|
6777
|
+
const G = V(null), m = V(null), B = V(l), M = V(null), y = V(null), F = V(!1), L = V({ remainingText: null, originalText: null, options: null }), f = V([]), T = V(0), [A, D] = le(!0), [U, X] = le(null), [j, xe] = le(!1), [re, Se] = le(!1);
|
|
6778
6778
|
Re(() => {
|
|
6779
6779
|
F.current = re;
|
|
6780
6780
|
}, [re]), Re(() => {
|
|
@@ -6805,7 +6805,7 @@ const it = Ye(({
|
|
|
6805
6805
|
apiKey: i !== null ? i : ce.apiKey
|
|
6806
6806
|
};
|
|
6807
6807
|
const v = {
|
|
6808
|
-
url:
|
|
6808
|
+
url: W,
|
|
6809
6809
|
body: t,
|
|
6810
6810
|
avatarMood: e,
|
|
6811
6811
|
ttsLang: ye === "browser" ? "en-US" : n,
|
|
@@ -6820,7 +6820,7 @@ const it = Ye(({
|
|
|
6820
6820
|
ttsService: ye,
|
|
6821
6821
|
lipsyncModules: ["en"],
|
|
6822
6822
|
cameraView: u
|
|
6823
|
-
},
|
|
6823
|
+
}, H = N(async () => {
|
|
6824
6824
|
if (!(!G.current || m.current))
|
|
6825
6825
|
try {
|
|
6826
6826
|
if (D(!0), X(null), m.current = new _e(G.current, I), m.current.controls && (m.current.controls.enableRotate = !1, m.current.controls.enableZoom = !1, m.current.controls.enablePan = !1, m.current.controls.enableDamping = !1), x && Object.keys(x).length > 0 && (m.current.customAnimations = x), await m.current.showAvatar(v, (ee) => {
|
|
@@ -6846,39 +6846,39 @@ const it = Ye(({
|
|
|
6846
6846
|
return document.addEventListener("visibilitychange", Y), () => {
|
|
6847
6847
|
document.removeEventListener("visibilitychange", Y);
|
|
6848
6848
|
};
|
|
6849
|
-
} catch (
|
|
6850
|
-
console.error("Error initializing TalkingHead:",
|
|
6849
|
+
} catch (w) {
|
|
6850
|
+
console.error("Error initializing TalkingHead:", w), X(w.message || "Failed to initialize avatar"), D(!1), h(w);
|
|
6851
6851
|
}
|
|
6852
|
-
}, [
|
|
6853
|
-
Re(() => (
|
|
6852
|
+
}, [W, t, e, n, o, s, i, l, a, c, u]);
|
|
6853
|
+
Re(() => (H(), () => {
|
|
6854
6854
|
m.current && (m.current.stop(), m.current.dispose(), m.current = null);
|
|
6855
|
-
}), [
|
|
6855
|
+
}), [H]), Re(() => {
|
|
6856
6856
|
if (!G.current || !m.current) return;
|
|
6857
|
-
const
|
|
6857
|
+
const w = new ResizeObserver((ee) => {
|
|
6858
6858
|
for (const se of ee)
|
|
6859
6859
|
m.current && m.current.onResize && m.current.onResize();
|
|
6860
6860
|
});
|
|
6861
|
-
|
|
6861
|
+
w.observe(G.current);
|
|
6862
6862
|
const Y = () => {
|
|
6863
6863
|
m.current && m.current.onResize && m.current.onResize();
|
|
6864
6864
|
};
|
|
6865
6865
|
return window.addEventListener("resize", Y), () => {
|
|
6866
|
-
|
|
6866
|
+
w.disconnect(), window.removeEventListener("resize", Y);
|
|
6867
6867
|
};
|
|
6868
6868
|
}, [j]);
|
|
6869
6869
|
const E = N(async () => {
|
|
6870
6870
|
if (m.current && m.current.audioCtx)
|
|
6871
6871
|
try {
|
|
6872
6872
|
(m.current.audioCtx.state === "suspended" || m.current.audioCtx.state === "interrupted") && (await m.current.audioCtx.resume(), console.log("Audio context resumed"));
|
|
6873
|
-
} catch (
|
|
6874
|
-
console.warn("Failed to resume audio context:",
|
|
6873
|
+
} catch (w) {
|
|
6874
|
+
console.warn("Failed to resume audio context:", w);
|
|
6875
6875
|
}
|
|
6876
|
-
}, []), Z = N(async (
|
|
6876
|
+
}, []), Z = N(async (w, Y = {}) => {
|
|
6877
6877
|
if (m.current && j)
|
|
6878
6878
|
try {
|
|
6879
|
-
y.current && (clearInterval(y.current), y.current = null), M.current = { text:
|
|
6880
|
-
const ee = /[!\.\?\n\p{Extended_Pictographic}]/ug, se =
|
|
6881
|
-
f.current = se,
|
|
6879
|
+
y.current && (clearInterval(y.current), y.current = null), M.current = { text: w, options: Y }, L.current = { remainingText: null, originalText: null, options: null };
|
|
6880
|
+
const ee = /[!\.\?\n\p{Extended_Pictographic}]/ug, se = w.split(ee).map((_) => _.trim()).filter((_) => _.length > 0);
|
|
6881
|
+
f.current = se, T.current = 0, Se(!1), F.current = !1, await E();
|
|
6882
6882
|
const he = {
|
|
6883
6883
|
...Y,
|
|
6884
6884
|
lipsyncLang: Y.lipsyncLang || v.lipsyncLang || "en"
|
|
@@ -6908,49 +6908,49 @@ const it = Ye(({
|
|
|
6908
6908
|
ue = !0, fe && (clearInterval(fe), fe = null, y.current = null);
|
|
6909
6909
|
try {
|
|
6910
6910
|
Y.onSpeechEnd();
|
|
6911
|
-
} catch (
|
|
6912
|
-
console.error("Error in onSpeechEnd callback:",
|
|
6911
|
+
} catch (S) {
|
|
6912
|
+
console.error("Error in onSpeechEnd callback:", S);
|
|
6913
6913
|
}
|
|
6914
6914
|
}
|
|
6915
6915
|
}, 100);
|
|
6916
6916
|
}, 100), y.current = fe;
|
|
6917
6917
|
}
|
|
6918
|
-
m.current.lipsync && Object.keys(m.current.lipsync).length > 0 ? (m.current.setSlowdownRate && m.current.setSlowdownRate(1.05), m.current.speakText(
|
|
6919
|
-
await E(), m.current && m.current.lipsync && (m.current.setSlowdownRate && m.current.setSlowdownRate(1.05), m.current.speakText(
|
|
6918
|
+
m.current.lipsync && Object.keys(m.current.lipsync).length > 0 ? (m.current.setSlowdownRate && m.current.setSlowdownRate(1.05), m.current.speakText(w, he)) : setTimeout(async () => {
|
|
6919
|
+
await E(), m.current && m.current.lipsync && (m.current.setSlowdownRate && m.current.setSlowdownRate(1.05), m.current.speakText(w, he));
|
|
6920
6920
|
}, 100);
|
|
6921
6921
|
} catch (ee) {
|
|
6922
6922
|
console.error("Error speaking text:", ee), X(ee.message || "Failed to speak text");
|
|
6923
6923
|
}
|
|
6924
6924
|
}, [j, E, v.lipsyncLang]), oe = N(() => {
|
|
6925
6925
|
m.current && (m.current.stopSpeaking(), m.current.setSlowdownRate && m.current.setSlowdownRate(1), M.current = null, Se(!1));
|
|
6926
|
-
}, []),
|
|
6926
|
+
}, []), $ = N(() => {
|
|
6927
6927
|
if (m.current && m.current.pauseSpeaking) {
|
|
6928
|
-
const
|
|
6929
|
-
if (
|
|
6928
|
+
const w = m.current;
|
|
6929
|
+
if (w.isSpeaking || w.audioPlaylist && w.audioPlaylist.length > 0 || w.speechQueue && w.speechQueue.length > 0) {
|
|
6930
6930
|
y.current && (clearInterval(y.current), y.current = null);
|
|
6931
6931
|
let ee = "";
|
|
6932
6932
|
if (M.current && f.current.length > 0) {
|
|
6933
|
-
const se = f.current.length, he =
|
|
6934
|
-
if (fe > 0 && Me < se && (ee = f.current.slice(Me).join(". ").trim(), !ee && he > 0 &&
|
|
6935
|
-
const ue =
|
|
6933
|
+
const se = f.current.length, he = w.speechQueue ? w.speechQueue.filter((Ce) => Ce && Ce.text && Array.isArray(Ce.text) && Ce.text.length > 0).length : 0, _ = w.audioPlaylist && w.audioPlaylist.length > 0, fe = he + (_ ? 1 : 0), Me = se - fe;
|
|
6934
|
+
if (fe > 0 && Me < se && (ee = f.current.slice(Me).join(". ").trim(), !ee && he > 0 && w.speechQueue)) {
|
|
6935
|
+
const ue = w.speechQueue.filter((de) => de && de.text && Array.isArray(de.text) && de.text.length > 0).map((de) => de.text.map((De) => De.word || "").filter((De) => De.length > 0).join(" ")).filter((de) => de.length > 0).join(" ");
|
|
6936
6936
|
ue && ue.trim() && (ee = ue.trim());
|
|
6937
6937
|
}
|
|
6938
6938
|
}
|
|
6939
|
-
M.current && (
|
|
6939
|
+
M.current && (L.current = {
|
|
6940
6940
|
remainingText: ee || null,
|
|
6941
6941
|
originalText: M.current.text,
|
|
6942
6942
|
options: M.current.options
|
|
6943
|
-
}),
|
|
6943
|
+
}), w.speechQueue && (w.speechQueue.length = 0), m.current.pauseSpeaking(), F.current = !0, Se(!0);
|
|
6944
6944
|
}
|
|
6945
6945
|
}
|
|
6946
6946
|
}, []), K = N(async () => {
|
|
6947
6947
|
if (!m.current || !re)
|
|
6948
6948
|
return;
|
|
6949
|
-
let
|
|
6950
|
-
if (
|
|
6951
|
-
|
|
6949
|
+
let w = "", Y = {};
|
|
6950
|
+
if (L.current && L.current.remainingText)
|
|
6951
|
+
w = L.current.remainingText, Y = L.current.options || {}, L.current = { remainingText: null, originalText: null, options: null };
|
|
6952
6952
|
else if (M.current && M.current.text)
|
|
6953
|
-
|
|
6953
|
+
w = M.current.text, Y = M.current.options || {};
|
|
6954
6954
|
else {
|
|
6955
6955
|
console.warn("Resume called but no paused speech found"), Se(!1), F.current = !1;
|
|
6956
6956
|
return;
|
|
@@ -6961,27 +6961,27 @@ const it = Ye(({
|
|
|
6961
6961
|
lipsyncLang: Y.lipsyncLang || v.lipsyncLang || "en"
|
|
6962
6962
|
};
|
|
6963
6963
|
try {
|
|
6964
|
-
await Z(
|
|
6964
|
+
await Z(w, ee);
|
|
6965
6965
|
} catch (se) {
|
|
6966
6966
|
console.error("Error resuming speech:", se), Se(!1), F.current = !1;
|
|
6967
6967
|
}
|
|
6968
|
-
}, [E, re, Z, v]), ve = N((
|
|
6969
|
-
m.current && m.current.setMood(
|
|
6970
|
-
}, []), Oe = N((
|
|
6971
|
-
m.current && m.current.setSlowdownRate && m.current.setSlowdownRate(
|
|
6972
|
-
}, []), ke = N((
|
|
6968
|
+
}, [E, re, Z, v]), ve = N((w) => {
|
|
6969
|
+
m.current && m.current.setMood(w);
|
|
6970
|
+
}, []), Oe = N((w) => {
|
|
6971
|
+
m.current && m.current.setSlowdownRate && m.current.setSlowdownRate(w);
|
|
6972
|
+
}, []), ke = N((w, Y = !1) => {
|
|
6973
6973
|
if (m.current && m.current.playAnimation) {
|
|
6974
|
-
if (x && x[
|
|
6974
|
+
if (x && x[w] && (w = x[w]), m.current.setShowFullAvatar)
|
|
6975
6975
|
try {
|
|
6976
6976
|
m.current.setShowFullAvatar(B.current);
|
|
6977
6977
|
} catch (se) {
|
|
6978
6978
|
console.warn("Error setting full body mode:", se);
|
|
6979
6979
|
}
|
|
6980
|
-
if (
|
|
6980
|
+
if (w.includes("."))
|
|
6981
6981
|
try {
|
|
6982
|
-
m.current.playAnimation(
|
|
6982
|
+
m.current.playAnimation(w, null, 10, 0, 0.01, Y);
|
|
6983
6983
|
} catch (se) {
|
|
6984
|
-
console.warn(`Failed to play ${
|
|
6984
|
+
console.warn(`Failed to play ${w}:`, se);
|
|
6985
6985
|
try {
|
|
6986
6986
|
m.current.setBodyMovement("idle");
|
|
6987
6987
|
} catch (he) {
|
|
@@ -6993,12 +6993,12 @@ const it = Ye(({
|
|
|
6993
6993
|
let he = !1;
|
|
6994
6994
|
for (const _ of se)
|
|
6995
6995
|
try {
|
|
6996
|
-
m.current.playAnimation(
|
|
6996
|
+
m.current.playAnimation(w + _, null, 10, 0, 0.01, Y), he = !0;
|
|
6997
6997
|
break;
|
|
6998
6998
|
} catch {
|
|
6999
6999
|
}
|
|
7000
7000
|
if (!he) {
|
|
7001
|
-
console.warn("Animation not found:",
|
|
7001
|
+
console.warn("Animation not found:", w);
|
|
7002
7002
|
try {
|
|
7003
7003
|
m.current.setBodyMovement("idle");
|
|
7004
7004
|
} catch (_) {
|
|
@@ -7010,10 +7010,10 @@ const it = Ye(({
|
|
|
7010
7010
|
}, [x]), Be = N(() => {
|
|
7011
7011
|
m.current && m.current.onResize && m.current.onResize();
|
|
7012
7012
|
}, []);
|
|
7013
|
-
return Qe(
|
|
7013
|
+
return Qe(k, () => ({
|
|
7014
7014
|
speakText: Z,
|
|
7015
7015
|
stopSpeaking: oe,
|
|
7016
|
-
pauseSpeaking:
|
|
7016
|
+
pauseSpeaking: $,
|
|
7017
7017
|
resumeSpeaking: K,
|
|
7018
7018
|
resumeAudioContext: E,
|
|
7019
7019
|
setMood: ve,
|
|
@@ -7023,27 +7023,27 @@ const it = Ye(({
|
|
|
7023
7023
|
isPaused: re,
|
|
7024
7024
|
talkingHead: m.current,
|
|
7025
7025
|
handleResize: Be,
|
|
7026
|
-
setBodyMovement: (
|
|
7026
|
+
setBodyMovement: (w) => {
|
|
7027
7027
|
if (m.current && m.current.setShowFullAvatar && m.current.setBodyMovement)
|
|
7028
7028
|
try {
|
|
7029
|
-
m.current.setShowFullAvatar(B.current), m.current.setBodyMovement(
|
|
7029
|
+
m.current.setShowFullAvatar(B.current), m.current.setBodyMovement(w);
|
|
7030
7030
|
} catch (Y) {
|
|
7031
7031
|
console.warn("Error setting body movement:", Y);
|
|
7032
7032
|
}
|
|
7033
7033
|
},
|
|
7034
|
-
setMovementIntensity: (
|
|
7034
|
+
setMovementIntensity: (w) => m.current?.setMovementIntensity(w),
|
|
7035
7035
|
playRandomDance: () => {
|
|
7036
7036
|
if (m.current && m.current.setShowFullAvatar && m.current.playRandomDance)
|
|
7037
7037
|
try {
|
|
7038
7038
|
m.current.setShowFullAvatar(B.current), m.current.playRandomDance();
|
|
7039
|
-
} catch (
|
|
7040
|
-
console.warn("Error playing random dance:",
|
|
7039
|
+
} catch (w) {
|
|
7040
|
+
console.warn("Error playing random dance:", w);
|
|
7041
7041
|
}
|
|
7042
7042
|
},
|
|
7043
|
-
playReaction: (
|
|
7043
|
+
playReaction: (w) => {
|
|
7044
7044
|
if (m.current && m.current.setShowFullAvatar && m.current.playReaction)
|
|
7045
7045
|
try {
|
|
7046
|
-
m.current.setShowFullAvatar(B.current), m.current.playReaction(
|
|
7046
|
+
m.current.setShowFullAvatar(B.current), m.current.playReaction(w);
|
|
7047
7047
|
} catch (Y) {
|
|
7048
7048
|
console.warn("Error playing reaction:", Y);
|
|
7049
7049
|
}
|
|
@@ -7052,14 +7052,14 @@ const it = Ye(({
|
|
|
7052
7052
|
if (m.current && m.current.setShowFullAvatar && m.current.playCelebration)
|
|
7053
7053
|
try {
|
|
7054
7054
|
m.current.setShowFullAvatar(B.current), m.current.playCelebration();
|
|
7055
|
-
} catch (
|
|
7056
|
-
console.warn("Error playing celebration:",
|
|
7055
|
+
} catch (w) {
|
|
7056
|
+
console.warn("Error playing celebration:", w);
|
|
7057
7057
|
}
|
|
7058
7058
|
},
|
|
7059
|
-
setShowFullAvatar: (
|
|
7059
|
+
setShowFullAvatar: (w) => {
|
|
7060
7060
|
if (m.current && m.current.setShowFullAvatar)
|
|
7061
7061
|
try {
|
|
7062
|
-
B.current =
|
|
7062
|
+
B.current = w, m.current.setShowFullAvatar(w);
|
|
7063
7063
|
} catch (Y) {
|
|
7064
7064
|
console.warn("Error setting showFullAvatar:", Y);
|
|
7065
7065
|
}
|
|
@@ -7068,16 +7068,16 @@ const it = Ye(({
|
|
|
7068
7068
|
if (m.current && m.current.lockAvatarPosition)
|
|
7069
7069
|
try {
|
|
7070
7070
|
m.current.lockAvatarPosition();
|
|
7071
|
-
} catch (
|
|
7072
|
-
console.warn("Error locking avatar position:",
|
|
7071
|
+
} catch (w) {
|
|
7072
|
+
console.warn("Error locking avatar position:", w);
|
|
7073
7073
|
}
|
|
7074
7074
|
},
|
|
7075
7075
|
unlockAvatarPosition: () => {
|
|
7076
7076
|
if (m.current && m.current.unlockAvatarPosition)
|
|
7077
7077
|
try {
|
|
7078
7078
|
m.current.unlockAvatarPosition();
|
|
7079
|
-
} catch (
|
|
7080
|
-
console.warn("Error unlocking avatar position:",
|
|
7079
|
+
} catch (w) {
|
|
7080
|
+
console.warn("Error unlocking avatar position:", w);
|
|
7081
7081
|
}
|
|
7082
7082
|
}
|
|
7083
7083
|
})), /* @__PURE__ */ we(
|
|
@@ -7091,7 +7091,7 @@ const it = Ye(({
|
|
|
7091
7091
|
...R
|
|
7092
7092
|
},
|
|
7093
7093
|
children: [
|
|
7094
|
-
/* @__PURE__ */
|
|
7094
|
+
/* @__PURE__ */ J(
|
|
7095
7095
|
"div",
|
|
7096
7096
|
{
|
|
7097
7097
|
ref: G,
|
|
@@ -7103,7 +7103,7 @@ const it = Ye(({
|
|
|
7103
7103
|
}
|
|
7104
7104
|
}
|
|
7105
7105
|
),
|
|
7106
|
-
A && /* @__PURE__ */
|
|
7106
|
+
A && /* @__PURE__ */ J("div", { className: "loading-overlay", style: {
|
|
7107
7107
|
position: "absolute",
|
|
7108
7108
|
top: "50%",
|
|
7109
7109
|
left: "50%",
|
|
@@ -7112,7 +7112,7 @@ const it = Ye(({
|
|
|
7112
7112
|
fontSize: "18px",
|
|
7113
7113
|
zIndex: 10
|
|
7114
7114
|
}, children: "Loading avatar..." }),
|
|
7115
|
-
U && /* @__PURE__ */
|
|
7115
|
+
U && /* @__PURE__ */ J("div", { className: "error-overlay", style: {
|
|
7116
7116
|
position: "absolute",
|
|
7117
7117
|
top: "50%",
|
|
7118
7118
|
left: "50%",
|
|
@@ -7130,7 +7130,7 @@ const it = Ye(({
|
|
|
7130
7130
|
});
|
|
7131
7131
|
it.displayName = "TalkingHeadAvatar";
|
|
7132
7132
|
const zt = Ye(({
|
|
7133
|
-
text:
|
|
7133
|
+
text: W = "Hello! I'm a talking avatar. How are you today?",
|
|
7134
7134
|
onLoading: t = () => {
|
|
7135
7135
|
},
|
|
7136
7136
|
onError: e = () => {
|
|
@@ -7141,7 +7141,7 @@ const zt = Ye(({
|
|
|
7141
7141
|
style: s = {},
|
|
7142
7142
|
avatarConfig: i = {}
|
|
7143
7143
|
}, a) => {
|
|
7144
|
-
const c =
|
|
7144
|
+
const c = V(null), l = V(null), [u, r] = le(!0), [d, h] = le(null), [g, R] = le(!1), x = qe(), k = i.ttsService || x.service, G = k === "browser" ? {
|
|
7145
7145
|
endpoint: "",
|
|
7146
7146
|
apiKey: null,
|
|
7147
7147
|
defaultVoice: "Google US English"
|
|
@@ -7150,13 +7150,13 @@ const zt = Ye(({
|
|
|
7150
7150
|
// Override API key if provided via avatarConfig
|
|
7151
7151
|
apiKey: i.ttsApiKey !== void 0 && i.ttsApiKey !== null ? i.ttsApiKey : x.apiKey,
|
|
7152
7152
|
// Override endpoint for ElevenLabs if service is explicitly set
|
|
7153
|
-
endpoint:
|
|
7153
|
+
endpoint: k === "elevenlabs" && i.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : x.endpoint
|
|
7154
7154
|
}, m = {
|
|
7155
7155
|
url: "/avatars/brunette.glb",
|
|
7156
7156
|
// Use brunette avatar (working glTF file)
|
|
7157
7157
|
body: "F",
|
|
7158
7158
|
avatarMood: "neutral",
|
|
7159
|
-
ttsLang:
|
|
7159
|
+
ttsLang: k === "browser" ? "en-US" : "en",
|
|
7160
7160
|
ttsVoice: i.ttsVoice || G.defaultVoice,
|
|
7161
7161
|
lipsyncLang: "en",
|
|
7162
7162
|
// English lip-sync
|
|
@@ -7168,7 +7168,7 @@ const zt = Ye(({
|
|
|
7168
7168
|
}, B = {
|
|
7169
7169
|
ttsEndpoint: G.endpoint,
|
|
7170
7170
|
ttsApikey: G.apiKey,
|
|
7171
|
-
ttsService:
|
|
7171
|
+
ttsService: k,
|
|
7172
7172
|
lipsyncModules: ["en"],
|
|
7173
7173
|
cameraView: "upper"
|
|
7174
7174
|
}, M = N(async () => {
|
|
@@ -7223,11 +7223,11 @@ const zt = Ye(({
|
|
|
7223
7223
|
console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!l.current);
|
|
7224
7224
|
}, [g, m]), F = N(() => {
|
|
7225
7225
|
l.current && (l.current.stopSpeaking(), l.current.setSlowdownRate && (l.current.setSlowdownRate(1), console.log("Reset timing to normal")));
|
|
7226
|
-
}, []),
|
|
7226
|
+
}, []), L = N((A) => {
|
|
7227
7227
|
l.current && l.current.setMood(A);
|
|
7228
7228
|
}, []), f = N((A) => {
|
|
7229
7229
|
l.current && l.current.setSlowdownRate && (l.current.setSlowdownRate(A), console.log("Timing adjustment set to:", A));
|
|
7230
|
-
}, []),
|
|
7230
|
+
}, []), T = N((A, D = !1) => {
|
|
7231
7231
|
if (l.current && l.current.playAnimation) {
|
|
7232
7232
|
if (l.current.setShowFullAvatar)
|
|
7233
7233
|
try {
|
|
@@ -7271,9 +7271,9 @@ const zt = Ye(({
|
|
|
7271
7271
|
return Qe(a, () => ({
|
|
7272
7272
|
speakText: y,
|
|
7273
7273
|
stopSpeaking: F,
|
|
7274
|
-
setMood:
|
|
7274
|
+
setMood: L,
|
|
7275
7275
|
setTimingAdjustment: f,
|
|
7276
|
-
playAnimation:
|
|
7276
|
+
playAnimation: T,
|
|
7277
7277
|
isReady: g,
|
|
7278
7278
|
talkingHead: l.current,
|
|
7279
7279
|
setBodyMovement: (A) => {
|
|
@@ -7334,7 +7334,7 @@ const zt = Ye(({
|
|
|
7334
7334
|
}
|
|
7335
7335
|
}
|
|
7336
7336
|
})), /* @__PURE__ */ we("div", { className: `talking-head-container ${o}`, style: s, children: [
|
|
7337
|
-
/* @__PURE__ */
|
|
7337
|
+
/* @__PURE__ */ J(
|
|
7338
7338
|
"div",
|
|
7339
7339
|
{
|
|
7340
7340
|
ref: c,
|
|
@@ -7346,7 +7346,7 @@ const zt = Ye(({
|
|
|
7346
7346
|
}
|
|
7347
7347
|
}
|
|
7348
7348
|
),
|
|
7349
|
-
u && /* @__PURE__ */
|
|
7349
|
+
u && /* @__PURE__ */ J("div", { className: "loading-overlay", style: {
|
|
7350
7350
|
position: "absolute",
|
|
7351
7351
|
top: "50%",
|
|
7352
7352
|
left: "50%",
|
|
@@ -7355,7 +7355,7 @@ const zt = Ye(({
|
|
|
7355
7355
|
fontSize: "18px",
|
|
7356
7356
|
zIndex: 10
|
|
7357
7357
|
}, children: "Loading avatar..." }),
|
|
7358
|
-
d && /* @__PURE__ */
|
|
7358
|
+
d && /* @__PURE__ */ J("div", { className: "error-overlay", style: {
|
|
7359
7359
|
position: "absolute",
|
|
7360
7360
|
top: "50%",
|
|
7361
7361
|
left: "50%",
|
|
@@ -7370,18 +7370,25 @@ const zt = Ye(({
|
|
|
7370
7370
|
] });
|
|
7371
7371
|
});
|
|
7372
7372
|
zt.displayName = "TalkingHeadComponent";
|
|
7373
|
-
async function Ue(
|
|
7373
|
+
async function Ue(W) {
|
|
7374
7374
|
try {
|
|
7375
|
-
const t = await fetch(
|
|
7376
|
-
if (!t.ok)
|
|
7375
|
+
const t = await fetch(W);
|
|
7376
|
+
if (!t.ok) {
|
|
7377
|
+
if (t.status === 404)
|
|
7378
|
+
return {};
|
|
7377
7379
|
throw new Error(`Failed to fetch manifest: ${t.status} ${t.statusText}`);
|
|
7378
|
-
|
|
7380
|
+
}
|
|
7381
|
+
const e = t.headers.get("content-type");
|
|
7382
|
+
if (e && !e.includes("application/json"))
|
|
7383
|
+
return {};
|
|
7384
|
+
const n = await t.text();
|
|
7385
|
+
return n.trim().startsWith("<!") ? {} : JSON.parse(n).animations || {};
|
|
7379
7386
|
} catch (t) {
|
|
7380
|
-
return console.
|
|
7387
|
+
return t instanceof SyntaxError || console.warn("⚠️ Could not load animation manifest (this is optional):", W), {};
|
|
7381
7388
|
}
|
|
7382
7389
|
}
|
|
7383
|
-
async function Ht(
|
|
7384
|
-
const e = [], n =
|
|
7390
|
+
async function Ht(W, t = "F") {
|
|
7391
|
+
const e = [], n = W.replace(/\/$/, "");
|
|
7385
7392
|
try {
|
|
7386
7393
|
const i = [
|
|
7387
7394
|
`${n}/.list.json`,
|
|
@@ -7424,9 +7431,9 @@ async function Ht(V, t = "F") {
|
|
|
7424
7431
|
}
|
|
7425
7432
|
return e.length > 0, e;
|
|
7426
7433
|
}
|
|
7427
|
-
async function nt(
|
|
7434
|
+
async function nt(W, t = "F") {
|
|
7428
7435
|
const e = {};
|
|
7429
|
-
for (const [n, o] of Object.entries(
|
|
7436
|
+
for (const [n, o] of Object.entries(W))
|
|
7430
7437
|
try {
|
|
7431
7438
|
const s = await Ht(o, t);
|
|
7432
7439
|
s.length > 0 && (e[n] = s);
|
|
@@ -7436,7 +7443,7 @@ async function nt(V, t = "F") {
|
|
|
7436
7443
|
return e;
|
|
7437
7444
|
}
|
|
7438
7445
|
const Tt = Ye(({
|
|
7439
|
-
text:
|
|
7446
|
+
text: W = null,
|
|
7440
7447
|
avatarUrl: t = "/avatars/brunette.glb",
|
|
7441
7448
|
avatarBody: e = "F",
|
|
7442
7449
|
mood: n = "neutral",
|
|
@@ -7458,7 +7465,7 @@ const Tt = Ye(({
|
|
|
7458
7465
|
},
|
|
7459
7466
|
onSpeechEnd: x = () => {
|
|
7460
7467
|
},
|
|
7461
|
-
className:
|
|
7468
|
+
className: k = "",
|
|
7462
7469
|
style: G = {},
|
|
7463
7470
|
animations: m = {},
|
|
7464
7471
|
autoAnimationGroup: B = null,
|
|
@@ -7467,40 +7474,36 @@ const Tt = Ye(({
|
|
|
7467
7474
|
// e.g., "idle" - will randomly select from this group when idle
|
|
7468
7475
|
autoSpeak: y = !1
|
|
7469
7476
|
}, F) => {
|
|
7470
|
-
const
|
|
7477
|
+
const L = V(null), f = V(null), T = V(u), A = V(null), D = V(null), U = V(!1), X = V({ remainingText: null, originalText: null, options: null }), j = V([]), [xe, re] = le(!0), [Se, ce] = le(null), [ye, ie] = le(!1), [v, I] = le(!1), [H, E] = le(m), Z = V(null), oe = V(!1), $ = V(null), K = V([]), ve = V([]);
|
|
7471
7478
|
Re(() => {
|
|
7472
7479
|
U.current = v;
|
|
7473
7480
|
}, [v]);
|
|
7474
|
-
const Oe = N((
|
|
7475
|
-
let
|
|
7476
|
-
if (
|
|
7477
|
-
const P =
|
|
7478
|
-
P === "M" || P === "MALE" ?
|
|
7481
|
+
const Oe = N((S) => {
|
|
7482
|
+
let C = "F";
|
|
7483
|
+
if (S) {
|
|
7484
|
+
const P = S.toString().toUpperCase().trim();
|
|
7485
|
+
P === "M" || P === "MALE" ? C = "M" : (P === "F" || P === "FEMALE") && (C = "F");
|
|
7479
7486
|
}
|
|
7480
|
-
return
|
|
7487
|
+
return C === "M" ? "male" : "female";
|
|
7481
7488
|
}, []);
|
|
7482
7489
|
Re(() => {
|
|
7483
7490
|
(async () => {
|
|
7484
7491
|
if (m.manifest && m.auto)
|
|
7485
7492
|
try {
|
|
7486
|
-
const
|
|
7487
|
-
E(
|
|
7493
|
+
const C = await Ue(m.manifest);
|
|
7494
|
+
E(C);
|
|
7488
7495
|
return;
|
|
7489
7496
|
} catch {
|
|
7490
7497
|
}
|
|
7491
|
-
if (m.manifest && !m.auto)
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
} catch (k) {
|
|
7496
|
-
console.error("Failed to load animation manifest:", k), E(m);
|
|
7497
|
-
}
|
|
7498
|
-
else if (m.auto)
|
|
7498
|
+
if (m.manifest && !m.auto) {
|
|
7499
|
+
const C = await Ue(m.manifest), P = Object.keys(C).length > 0;
|
|
7500
|
+
E(P ? C : m);
|
|
7501
|
+
} else if (m.auto)
|
|
7499
7502
|
try {
|
|
7500
|
-
let
|
|
7503
|
+
let C = null;
|
|
7501
7504
|
if (m.manifest)
|
|
7502
7505
|
try {
|
|
7503
|
-
|
|
7506
|
+
C = await Ue(m.manifest);
|
|
7504
7507
|
} catch {
|
|
7505
7508
|
}
|
|
7506
7509
|
if (typeof m.auto == "string") {
|
|
@@ -7508,10 +7511,10 @@ const Tt = Ye(({
|
|
|
7508
7511
|
talking: `${P}/talking`,
|
|
7509
7512
|
idle: `${P}/idle`
|
|
7510
7513
|
}, te = Oe(e);
|
|
7511
|
-
Q[`${te}_talking`] = `${P}/${te}/talking`, Q[`${te}_idle`] = `${P}/${te}/idle`, Q.shared_talking = `${P}/shared/talking`, Q.shared_idle = `${P}/shared/idle
|
|
7514
|
+
Q[`${te}_talking`] = `${P}/${te}/talking`, Q[`${te}_idle`] = `${P}/${te}/idle`, Q.shared_talking = `${P}/shared/talking`, Q.shared_idle = `${P}/shared/idle`;
|
|
7512
7515
|
const Ie = await nt(Q, e);
|
|
7513
|
-
if (!Object.values(Ie).some((me) => Array.isArray(me) && me.length > 0) &&
|
|
7514
|
-
E(
|
|
7516
|
+
if (!Object.values(Ie).some((me) => Array.isArray(me) && me.length > 0) && C) {
|
|
7517
|
+
E(C);
|
|
7515
7518
|
return;
|
|
7516
7519
|
}
|
|
7517
7520
|
const ae = {
|
|
@@ -7526,19 +7529,19 @@ const Tt = Ye(({
|
|
|
7526
7529
|
Ve === "shared" ? (ae._genderSpecific.shared[Ne] || (ae._genderSpecific.shared[Ne] = []), ae._genderSpecific.shared[Ne].push(...Fe)) : Ve === te && (ae._genderSpecific[te][Ne] || (ae._genderSpecific[te][Ne] = []), ae._genderSpecific[te][Ne].push(...Fe));
|
|
7527
7530
|
} else
|
|
7528
7531
|
ae[me] = Fe;
|
|
7529
|
-
}),
|
|
7530
|
-
ae._genderSpecific[me] || (ae._genderSpecific[me] = {}), Object.entries(
|
|
7532
|
+
}), C && (C._genderSpecific && Object.keys(C._genderSpecific).forEach((me) => {
|
|
7533
|
+
ae._genderSpecific[me] || (ae._genderSpecific[me] = {}), Object.entries(C._genderSpecific[me]).forEach(([Fe, Ve]) => {
|
|
7531
7534
|
ae._genderSpecific[me][Fe] || (ae._genderSpecific[me][Fe] = Ve);
|
|
7532
7535
|
});
|
|
7533
|
-
}), Object.entries(
|
|
7536
|
+
}), Object.entries(C).forEach(([me, Fe]) => {
|
|
7534
7537
|
me !== "_genderSpecific" && !ae[me] && (ae[me] = Fe);
|
|
7535
7538
|
})), E(ae);
|
|
7536
7539
|
} else if (typeof m.auto == "object") {
|
|
7537
7540
|
const P = await nt(m.auto, e), Q = Object.values(P).some((te) => Array.isArray(te) && te.length > 0);
|
|
7538
|
-
E(!Q &&
|
|
7541
|
+
E(!Q && C ? C : P);
|
|
7539
7542
|
}
|
|
7540
|
-
} catch (
|
|
7541
|
-
if (console.error("Failed to auto-discover animations:",
|
|
7543
|
+
} catch (C) {
|
|
7544
|
+
if (console.error("Failed to auto-discover animations:", C), m.manifest)
|
|
7542
7545
|
try {
|
|
7543
7546
|
const P = await Ue(m.manifest);
|
|
7544
7547
|
E(P);
|
|
@@ -7552,28 +7555,28 @@ const Tt = Ye(({
|
|
|
7552
7555
|
E(m);
|
|
7553
7556
|
})();
|
|
7554
7557
|
}, [m, e, Oe]), Re(() => {
|
|
7555
|
-
|
|
7558
|
+
T.current = u;
|
|
7556
7559
|
}, [u]);
|
|
7557
7560
|
const ke = qe(), Be = s || ke.service;
|
|
7558
|
-
let
|
|
7559
|
-
Be === "browser" ?
|
|
7561
|
+
let w;
|
|
7562
|
+
Be === "browser" ? w = {
|
|
7560
7563
|
service: "browser",
|
|
7561
7564
|
endpoint: "",
|
|
7562
7565
|
apiKey: null,
|
|
7563
7566
|
defaultVoice: "Google US English"
|
|
7564
|
-
} : Be === "elevenlabs" ?
|
|
7567
|
+
} : Be === "elevenlabs" ? w = {
|
|
7565
7568
|
service: "elevenlabs",
|
|
7566
7569
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
7567
7570
|
apiKey: a || ke.apiKey,
|
|
7568
7571
|
defaultVoice: i || ke.defaultVoice || Pe.defaultVoice,
|
|
7569
7572
|
voices: ke.voices || Pe.voices
|
|
7570
|
-
} : Be === "deepgram" ?
|
|
7573
|
+
} : Be === "deepgram" ? w = {
|
|
7571
7574
|
service: "deepgram",
|
|
7572
7575
|
endpoint: "https://api.deepgram.com/v1/speak",
|
|
7573
7576
|
apiKey: a || ke.apiKey,
|
|
7574
7577
|
defaultVoice: i || ke.defaultVoice || je.defaultVoice,
|
|
7575
7578
|
voices: ke.voices || je.voices
|
|
7576
|
-
} :
|
|
7579
|
+
} : w = {
|
|
7577
7580
|
...ke,
|
|
7578
7581
|
apiKey: a !== null ? a : ke.apiKey
|
|
7579
7582
|
};
|
|
@@ -7582,34 +7585,34 @@ const Tt = Ye(({
|
|
|
7582
7585
|
body: e,
|
|
7583
7586
|
avatarMood: n,
|
|
7584
7587
|
ttsLang: Be === "browser" ? "en-US" : o,
|
|
7585
|
-
ttsVoice: i ||
|
|
7588
|
+
ttsVoice: i || w.defaultVoice,
|
|
7586
7589
|
lipsyncLang: "en",
|
|
7587
7590
|
showFullAvatar: u,
|
|
7588
7591
|
bodyMovement: c,
|
|
7589
7592
|
movementIntensity: l
|
|
7590
7593
|
}, ee = {
|
|
7591
|
-
ttsEndpoint:
|
|
7592
|
-
ttsApikey:
|
|
7594
|
+
ttsEndpoint: w.endpoint,
|
|
7595
|
+
ttsApikey: w.apiKey,
|
|
7593
7596
|
ttsService: Be,
|
|
7594
7597
|
lipsyncModules: ["en"],
|
|
7595
7598
|
cameraView: r
|
|
7596
7599
|
}, se = N(async () => {
|
|
7597
|
-
if (!(!
|
|
7600
|
+
if (!(!L.current || f.current))
|
|
7598
7601
|
try {
|
|
7599
|
-
re(!0), ce(null), f.current = new _e(
|
|
7600
|
-
if (
|
|
7601
|
-
const P = Math.min(100, Math.round(
|
|
7602
|
+
re(!0), ce(null), f.current = new _e(L.current, ee), await f.current.showAvatar(Y, (C) => {
|
|
7603
|
+
if (C.lengthComputable) {
|
|
7604
|
+
const P = Math.min(100, Math.round(C.loaded / C.total * 100));
|
|
7602
7605
|
h(P);
|
|
7603
7606
|
}
|
|
7604
7607
|
}), re(!1), ie(!0), d(f.current);
|
|
7605
|
-
const
|
|
7608
|
+
const S = () => {
|
|
7606
7609
|
document.visibilityState === "visible" ? f.current?.start() : f.current?.stop();
|
|
7607
7610
|
};
|
|
7608
|
-
return document.addEventListener("visibilitychange",
|
|
7609
|
-
document.removeEventListener("visibilitychange",
|
|
7611
|
+
return document.addEventListener("visibilitychange", S), () => {
|
|
7612
|
+
document.removeEventListener("visibilitychange", S);
|
|
7610
7613
|
};
|
|
7611
|
-
} catch (
|
|
7612
|
-
console.error("Error initializing TalkingHead:",
|
|
7614
|
+
} catch (S) {
|
|
7615
|
+
console.error("Error initializing TalkingHead:", S), ce(S.message || "Failed to initialize avatar"), re(!1), g(S);
|
|
7613
7616
|
}
|
|
7614
7617
|
}, []);
|
|
7615
7618
|
Re(() => (se(), () => {
|
|
@@ -7618,82 +7621,80 @@ const Tt = Ye(({
|
|
|
7618
7621
|
const he = N(async () => {
|
|
7619
7622
|
if (f.current)
|
|
7620
7623
|
try {
|
|
7621
|
-
const
|
|
7622
|
-
|
|
7623
|
-
} catch (
|
|
7624
|
-
console.warn("Failed to resume audio context:",
|
|
7624
|
+
const S = f.current.audioCtx || f.current.audioContext;
|
|
7625
|
+
S && (S.state === "suspended" || S.state === "interrupted") && await S.resume();
|
|
7626
|
+
} catch (S) {
|
|
7627
|
+
console.warn("Failed to resume audio context:", S);
|
|
7625
7628
|
}
|
|
7626
|
-
}, []), _ = N((
|
|
7627
|
-
if (!
|
|
7629
|
+
}, []), _ = N((S) => {
|
|
7630
|
+
if (!H)
|
|
7628
7631
|
return [];
|
|
7629
|
-
let
|
|
7630
|
-
if (
|
|
7631
|
-
const P = Oe(e);
|
|
7632
|
-
|
|
7633
|
-
const Q = T._genderSpecific[P];
|
|
7634
|
-
Q && Q[L] ? (k = Q[L], console.log(`✅ Found ${P} animations for "${L}": ${Array.isArray(k) ? k.length : 1} animation(s)`)) : T._genderSpecific.shared && T._genderSpecific.shared[L] ? (k = T._genderSpecific.shared[L], console.log(`✅ Found shared animations for "${L}": ${Array.isArray(k) ? k.length : 1} animation(s)`)) : console.log(`⚠️ No ${P} or shared animations found for "${L}"`);
|
|
7632
|
+
let C = null;
|
|
7633
|
+
if (H._genderSpecific) {
|
|
7634
|
+
const P = Oe(e), Q = H._genderSpecific[P];
|
|
7635
|
+
Q && Q[S] ? C = Q[S] : H._genderSpecific.shared && H._genderSpecific.shared[S] && (C = H._genderSpecific.shared[S]);
|
|
7635
7636
|
}
|
|
7636
|
-
return !
|
|
7637
|
-
}, [
|
|
7638
|
-
const
|
|
7639
|
-
for (let P =
|
|
7637
|
+
return !C && H[S] && (C = H[S]), C ? Array.isArray(C) ? [...C] : typeof C == "string" ? [C] : [] : ((Object.keys(H).length > 0 || H._genderSpecific && Object.keys(H._genderSpecific).length > 0) && console.warn(`⚠️ No animations found for group "${S}". Make sure animations are configured correctly.`), []);
|
|
7638
|
+
}, [H, e, Oe]), fe = N((S) => {
|
|
7639
|
+
const C = [...S];
|
|
7640
|
+
for (let P = C.length - 1; P > 0; P--) {
|
|
7640
7641
|
const Q = Math.floor(Math.random() * (P + 1));
|
|
7641
|
-
[
|
|
7642
|
+
[C[P], C[Q]] = [C[Q], C[P]];
|
|
7642
7643
|
}
|
|
7643
|
-
return
|
|
7644
|
-
}, []), Me = N((
|
|
7644
|
+
return C;
|
|
7645
|
+
}, []), Me = N((S) => {
|
|
7645
7646
|
if (ve.current.length === 0) {
|
|
7646
|
-
const P = _(
|
|
7647
|
+
const P = _(S);
|
|
7647
7648
|
if (P.length === 0)
|
|
7648
7649
|
return null;
|
|
7649
7650
|
ve.current = fe(P), K.current = [];
|
|
7650
7651
|
}
|
|
7651
|
-
const
|
|
7652
|
-
return
|
|
7653
|
-
}, [_, fe]), Ce = N((
|
|
7652
|
+
const C = ve.current.shift();
|
|
7653
|
+
return C && K.current.push(C), C;
|
|
7654
|
+
}, [_, fe]), Ce = N((S) => S ? S.split("/").pop().replace(".fbx", "").replace(/[-_]/g, " ") : "Unknown", []), ue = N((S, C = !1, P = null) => {
|
|
7654
7655
|
if (!f.current)
|
|
7655
7656
|
return null;
|
|
7656
|
-
const Q = Me(
|
|
7657
|
+
const Q = Me(S);
|
|
7657
7658
|
if (Q)
|
|
7658
7659
|
try {
|
|
7659
7660
|
const te = Ce(Q);
|
|
7660
7661
|
console.log(`🎬 Playing animation: "${te}"`);
|
|
7661
7662
|
const Ie = () => {
|
|
7662
|
-
oe.current &&
|
|
7663
|
-
ue(
|
|
7664
|
-
}, 100) : (oe.current = !1,
|
|
7663
|
+
oe.current && $.current === S && f.current && (f.current.isSpeaking || f.current.audioPlaylist && f.current.audioPlaylist.length > 0 || f.current.speechQueue && f.current.speechQueue.length > 0) ? setTimeout(() => {
|
|
7664
|
+
ue(S, C, P);
|
|
7665
|
+
}, 100) : (oe.current = !1, $.current = null, P && P());
|
|
7665
7666
|
};
|
|
7666
|
-
return f.current.playAnimation(Q, null, 0, 0, 0.01,
|
|
7667
|
+
return f.current.playAnimation(Q, null, 0, 0, 0.01, C, Ie), Q;
|
|
7667
7668
|
} catch (te) {
|
|
7668
7669
|
return console.error("Failed to play animation:", te), null;
|
|
7669
7670
|
}
|
|
7670
7671
|
else
|
|
7671
|
-
oe.current &&
|
|
7672
|
-
ue(
|
|
7672
|
+
oe.current && $.current === S && f.current && (f.current.isSpeaking || f.current.audioPlaylist && f.current.audioPlaylist.length > 0 || f.current.speechQueue && f.current.speechQueue.length > 0) && (ve.current = [], K.current = [], setTimeout(() => {
|
|
7673
|
+
ue(S, C, P);
|
|
7673
7674
|
}, 100));
|
|
7674
7675
|
return null;
|
|
7675
|
-
}, [Me, Ce]), de = N(async (
|
|
7676
|
-
if (!f.current || !ye || !
|
|
7676
|
+
}, [Me, Ce]), de = N(async (S, C = {}) => {
|
|
7677
|
+
if (!f.current || !ye || !S || S.trim() === "")
|
|
7677
7678
|
return;
|
|
7678
7679
|
await he();
|
|
7679
|
-
const P =
|
|
7680
|
-
P && !
|
|
7680
|
+
const P = C.animationGroup || B;
|
|
7681
|
+
P && !C.skipAnimation && (oe.current = !0, $.current = P, ve.current = [], K.current = [], ue(P));
|
|
7681
7682
|
try {
|
|
7682
|
-
R(
|
|
7683
|
+
R(S), C.onSpeechStart && C.onSpeechStart(S);
|
|
7683
7684
|
} catch (Ie) {
|
|
7684
7685
|
console.warn("Error in onSpeechStart callback:", Ie);
|
|
7685
7686
|
}
|
|
7686
|
-
X.current = { remainingText: null, originalText: null, options: null }, j.current = [], A.current = { text:
|
|
7687
|
-
const Q =
|
|
7687
|
+
X.current = { remainingText: null, originalText: null, options: null }, j.current = [], A.current = { text: S, options: C }, D.current && (clearInterval(D.current), D.current = null), I(!1), U.current = !1;
|
|
7688
|
+
const Q = S.split(/[.!?]+/).filter((Ie) => Ie.trim().length > 0);
|
|
7688
7689
|
j.current = Q;
|
|
7689
7690
|
const te = {
|
|
7690
|
-
lipsyncLang:
|
|
7691
|
+
lipsyncLang: C.lipsyncLang || "en",
|
|
7691
7692
|
onSpeechEnd: () => {
|
|
7692
|
-
D.current && (clearInterval(D.current), D.current = null), oe.current = !1,
|
|
7693
|
+
D.current && (clearInterval(D.current), D.current = null), oe.current = !1, $.current = null, ve.current = [], K.current = [], C.onSpeechEnd && C.onSpeechEnd(), x();
|
|
7693
7694
|
}
|
|
7694
7695
|
};
|
|
7695
7696
|
try {
|
|
7696
|
-
f.current.speakText(
|
|
7697
|
+
f.current.speakText(S, te);
|
|
7697
7698
|
} catch (Ie) {
|
|
7698
7699
|
console.error("Error speaking text:", Ie), ce(Ie.message || "Failed to speak text");
|
|
7699
7700
|
}
|
|
@@ -7702,27 +7703,27 @@ const Tt = Ye(({
|
|
|
7702
7703
|
if (!ye || !M || !f.current)
|
|
7703
7704
|
return;
|
|
7704
7705
|
Z.current && clearInterval(Z.current);
|
|
7705
|
-
const
|
|
7706
|
+
const S = () => {
|
|
7706
7707
|
f.current && !U.current && ue(M);
|
|
7707
7708
|
};
|
|
7708
|
-
return
|
|
7709
|
-
|
|
7709
|
+
return S(), Z.current = setInterval(() => {
|
|
7710
|
+
S();
|
|
7710
7711
|
}, 12e3 + Math.random() * 3e3), () => {
|
|
7711
7712
|
Z.current && (clearInterval(Z.current), Z.current = null);
|
|
7712
7713
|
};
|
|
7713
7714
|
}, [ye, M, ue]), Re(() => {
|
|
7714
|
-
ye &&
|
|
7715
|
-
}, [ye,
|
|
7715
|
+
ye && W && y && f.current && de(W);
|
|
7716
|
+
}, [ye, W, y, de]);
|
|
7716
7717
|
const De = N(() => {
|
|
7717
7718
|
if (f.current)
|
|
7718
7719
|
try {
|
|
7719
|
-
const
|
|
7720
|
-
if (
|
|
7720
|
+
const S = f.current.isSpeaking || !1, C = f.current.audioPlaylist || [], P = f.current.speechQueue || [];
|
|
7721
|
+
if (S || C.length > 0 || P.length > 0) {
|
|
7721
7722
|
D.current && (clearInterval(D.current), D.current = null);
|
|
7722
7723
|
let Q = "";
|
|
7723
7724
|
P.length > 0 && (Q = P.map((Ae) => Ae.text && Array.isArray(Ae.text) ? Ae.text.map((ae) => ae.word).join(" ") : Ae.text || "").join(" "));
|
|
7724
7725
|
let te = "";
|
|
7725
|
-
|
|
7726
|
+
C.length > 0 && (te = C.map((Ae) => Ae.text ? Array.isArray(Ae.text) ? Ae.text.map((ae) => ae.word).join(" ") : Ae.text : "").filter((Ae) => Ae.trim().length > 0).join(" "));
|
|
7726
7727
|
const Ie = te ? te + (Q ? " " + Q : "") : Q;
|
|
7727
7728
|
X.current = {
|
|
7728
7729
|
remainingText: Ie || null,
|
|
@@ -7730,25 +7731,25 @@ const Tt = Ye(({
|
|
|
7730
7731
|
options: A.current?.options || null
|
|
7731
7732
|
}, f.current.speechQueue.length = 0, f.current.pauseSpeaking(), I(!0), U.current = !0;
|
|
7732
7733
|
}
|
|
7733
|
-
} catch (
|
|
7734
|
-
console.warn("Error pausing speech:",
|
|
7734
|
+
} catch (S) {
|
|
7735
|
+
console.warn("Error pausing speech:", S);
|
|
7735
7736
|
}
|
|
7736
7737
|
}, []), Ke = N(async () => {
|
|
7737
7738
|
if (!(!f.current || !v))
|
|
7738
7739
|
try {
|
|
7739
7740
|
await he(), I(!1), U.current = !1;
|
|
7740
|
-
const
|
|
7741
|
+
const S = X.current?.remainingText, C = X.current?.originalText || A.current?.text, P = X.current?.options || A.current?.options || {}, Q = S || C;
|
|
7741
7742
|
Q && de(Q, P);
|
|
7742
|
-
} catch (
|
|
7743
|
-
console.warn("Error resuming speech:",
|
|
7743
|
+
} catch (S) {
|
|
7744
|
+
console.warn("Error resuming speech:", S), I(!1), U.current = !1;
|
|
7744
7745
|
}
|
|
7745
7746
|
}, [v, de, he]), We = N(() => {
|
|
7746
7747
|
if (f.current) {
|
|
7747
|
-
f.current.stopSpeaking(), D.current && (clearInterval(D.current), D.current = null), oe.current = !1,
|
|
7748
|
+
f.current.stopSpeaking(), D.current && (clearInterval(D.current), D.current = null), oe.current = !1, $.current = null, ve.current = [], K.current = [], I(!1), U.current = !1;
|
|
7748
7749
|
try {
|
|
7749
7750
|
x();
|
|
7750
|
-
} catch (
|
|
7751
|
-
console.warn("Error in onSpeechEnd callback (stopSpeaking):",
|
|
7751
|
+
} catch (S) {
|
|
7752
|
+
console.warn("Error in onSpeechEnd callback (stopSpeaking):", S);
|
|
7752
7753
|
}
|
|
7753
7754
|
}
|
|
7754
7755
|
}, [x]);
|
|
@@ -7759,27 +7760,27 @@ const Tt = Ye(({
|
|
|
7759
7760
|
stopSpeaking: We,
|
|
7760
7761
|
resumeAudioContext: he,
|
|
7761
7762
|
isPaused: () => v,
|
|
7762
|
-
setMood: (
|
|
7763
|
-
setBodyMovement: (
|
|
7764
|
-
f.current && f.current.setBodyMovement(
|
|
7763
|
+
setMood: (S) => f.current?.setMood(S),
|
|
7764
|
+
setBodyMovement: (S) => {
|
|
7765
|
+
f.current && f.current.setBodyMovement(S);
|
|
7765
7766
|
},
|
|
7766
|
-
playAnimation: (
|
|
7767
|
-
f.current && f.current.playAnimation && f.current.playAnimation(
|
|
7767
|
+
playAnimation: (S, C = !1) => {
|
|
7768
|
+
f.current && f.current.playAnimation && f.current.playAnimation(S, null, 10, 0, 0.01, C);
|
|
7768
7769
|
},
|
|
7769
|
-
playRandomAnimation: (
|
|
7770
|
-
getRandomAnimation: (
|
|
7771
|
-
playReaction: (
|
|
7770
|
+
playRandomAnimation: (S, C = !1) => ue(S, C),
|
|
7771
|
+
getRandomAnimation: (S) => getRandomAnimation(S),
|
|
7772
|
+
playReaction: (S) => f.current?.playReaction(S),
|
|
7772
7773
|
playCelebration: () => f.current?.playCelebration(),
|
|
7773
|
-
setShowFullAvatar: (
|
|
7774
|
-
f.current && (
|
|
7774
|
+
setShowFullAvatar: (S) => {
|
|
7775
|
+
f.current && (T.current = S, f.current.setShowFullAvatar(S));
|
|
7775
7776
|
},
|
|
7776
7777
|
isReady: ye,
|
|
7777
7778
|
talkingHead: f.current
|
|
7778
|
-
})), /* @__PURE__ */ we("div", { className: `simple-talking-avatar-container ${
|
|
7779
|
-
/* @__PURE__ */
|
|
7779
|
+
})), /* @__PURE__ */ we("div", { className: `simple-talking-avatar-container ${k}`, style: G, children: [
|
|
7780
|
+
/* @__PURE__ */ J(
|
|
7780
7781
|
"div",
|
|
7781
7782
|
{
|
|
7782
|
-
ref:
|
|
7783
|
+
ref: L,
|
|
7783
7784
|
className: "talking-head-viewer",
|
|
7784
7785
|
style: {
|
|
7785
7786
|
width: "100%",
|
|
@@ -7788,7 +7789,7 @@ const Tt = Ye(({
|
|
|
7788
7789
|
}
|
|
7789
7790
|
}
|
|
7790
7791
|
),
|
|
7791
|
-
xe && /* @__PURE__ */
|
|
7792
|
+
xe && /* @__PURE__ */ J("div", { className: "loading-overlay", style: {
|
|
7792
7793
|
position: "absolute",
|
|
7793
7794
|
top: "50%",
|
|
7794
7795
|
left: "50%",
|
|
@@ -7797,7 +7798,7 @@ const Tt = Ye(({
|
|
|
7797
7798
|
fontSize: "18px",
|
|
7798
7799
|
zIndex: 10
|
|
7799
7800
|
}, children: "Loading avatar..." }),
|
|
7800
|
-
Se && /* @__PURE__ */
|
|
7801
|
+
Se && /* @__PURE__ */ J("div", { className: "error-overlay", style: {
|
|
7801
7802
|
position: "absolute",
|
|
7802
7803
|
top: "50%",
|
|
7803
7804
|
left: "50%",
|
|
@@ -7813,7 +7814,7 @@ const Tt = Ye(({
|
|
|
7813
7814
|
});
|
|
7814
7815
|
Tt.displayName = "SimpleTalkingAvatar";
|
|
7815
7816
|
const Mt = Ye(({
|
|
7816
|
-
curriculumData:
|
|
7817
|
+
curriculumData: W = null,
|
|
7817
7818
|
avatarConfig: t = {},
|
|
7818
7819
|
animations: e = {},
|
|
7819
7820
|
onLessonStart: n = () => {
|
|
@@ -7828,7 +7829,7 @@ const Mt = Ye(({
|
|
|
7828
7829
|
},
|
|
7829
7830
|
autoStart: c = !1
|
|
7830
7831
|
}, l) => {
|
|
7831
|
-
const u =
|
|
7832
|
+
const u = V(null), r = V({
|
|
7832
7833
|
currentModuleIndex: 0,
|
|
7833
7834
|
currentLessonIndex: 0,
|
|
7834
7835
|
currentQuestionIndex: 0,
|
|
@@ -7838,18 +7839,18 @@ const Mt = Ye(({
|
|
|
7838
7839
|
curriculumCompleted: !1,
|
|
7839
7840
|
score: 0,
|
|
7840
7841
|
totalQuestions: 0
|
|
7841
|
-
}), d =
|
|
7842
|
+
}), d = V({
|
|
7842
7843
|
onLessonStart: n,
|
|
7843
7844
|
onLessonComplete: o,
|
|
7844
7845
|
onQuestionAnswer: s,
|
|
7845
7846
|
onCurriculumComplete: i,
|
|
7846
7847
|
onCustomAction: a
|
|
7847
|
-
}), h =
|
|
7848
|
+
}), h = V(null), g = V(null), R = V(null), x = V(null), k = V(null), G = V(null), m = V(null), B = V(W?.curriculum || {
|
|
7848
7849
|
title: "Default Curriculum",
|
|
7849
7850
|
description: "No curriculum data provided",
|
|
7850
7851
|
language: "en",
|
|
7851
7852
|
modules: []
|
|
7852
|
-
}), M =
|
|
7853
|
+
}), M = V({
|
|
7853
7854
|
avatarUrl: t.avatarUrl || "/avatars/brunette.glb",
|
|
7854
7855
|
avatarBody: t.avatarBody || "F",
|
|
7855
7856
|
mood: t.mood || "happy",
|
|
@@ -7872,7 +7873,7 @@ const Mt = Ye(({
|
|
|
7872
7873
|
onCustomAction: a
|
|
7873
7874
|
};
|
|
7874
7875
|
}, [n, o, s, i, a]), Re(() => {
|
|
7875
|
-
B.current =
|
|
7876
|
+
B.current = W?.curriculum || {
|
|
7876
7877
|
title: "Default Curriculum",
|
|
7877
7878
|
description: "No curriculum data provided",
|
|
7878
7879
|
language: "en",
|
|
@@ -7891,8 +7892,8 @@ const Mt = Ye(({
|
|
|
7891
7892
|
animations: e,
|
|
7892
7893
|
lipsyncLang: "en"
|
|
7893
7894
|
};
|
|
7894
|
-
}, [
|
|
7895
|
-
const y = N(() => (B.current || { modules: [] }).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex], []), F = N(() => y()?.questions[r.current.currentQuestionIndex], [y]),
|
|
7895
|
+
}, [W, t, e]);
|
|
7896
|
+
const y = N(() => (B.current || { modules: [] }).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex], []), F = N(() => y()?.questions[r.current.currentQuestionIndex], [y]), L = N((v, I) => I.type === "multiple_choice" || I.type === "true_false" ? v === I.answer : I.type === "code_test" && typeof v == "object" && v !== null ? v.passed === !0 : !1, []), f = N(() => {
|
|
7896
7897
|
r.current.lessonCompleted = !0, r.current.isQuestionMode = !1;
|
|
7897
7898
|
const v = r.current.totalQuestions > 0 ? Math.round(r.current.score / r.current.totalQuestions * 100) : 100;
|
|
7898
7899
|
let I = "Congratulations! You've completed this lesson";
|
|
@@ -7916,7 +7917,7 @@ const Mt = Ye(({
|
|
|
7916
7917
|
} catch {
|
|
7917
7918
|
u.current.playCelebration();
|
|
7918
7919
|
}
|
|
7919
|
-
const
|
|
7920
|
+
const H = B.current || { modules: [] }, E = H.modules[r.current.currentModuleIndex], Z = r.current.currentLessonIndex < (E?.lessons?.length || 0) - 1, oe = r.current.currentModuleIndex < (H.modules?.length || 0) - 1, $ = Z || oe, K = M.current || { lipsyncLang: "en" };
|
|
7920
7921
|
u.current.speakText(I, {
|
|
7921
7922
|
lipsyncLang: K.lipsyncLang,
|
|
7922
7923
|
onSpeechEnd: () => {
|
|
@@ -7927,17 +7928,17 @@ const Mt = Ye(({
|
|
|
7927
7928
|
score: r.current.score,
|
|
7928
7929
|
totalQuestions: r.current.totalQuestions,
|
|
7929
7930
|
percentage: v,
|
|
7930
|
-
hasNextLesson:
|
|
7931
|
+
hasNextLesson: $
|
|
7931
7932
|
});
|
|
7932
7933
|
}
|
|
7933
7934
|
});
|
|
7934
7935
|
}
|
|
7935
|
-
}, [e.lessonComplete]),
|
|
7936
|
+
}, [e.lessonComplete]), T = N(() => {
|
|
7936
7937
|
r.current.curriculumCompleted = !0;
|
|
7937
7938
|
const v = B.current || { modules: [] };
|
|
7938
7939
|
if (d.current.onCurriculumComplete({
|
|
7939
7940
|
modules: v.modules.length,
|
|
7940
|
-
totalLessons: v.modules.reduce((I,
|
|
7941
|
+
totalLessons: v.modules.reduce((I, H) => I + H.lessons.length, 0)
|
|
7941
7942
|
}), u.current) {
|
|
7942
7943
|
if (u.current.setMood("celebrating"), e.curriculumComplete)
|
|
7943
7944
|
try {
|
|
@@ -7961,7 +7962,7 @@ const Mt = Ye(({
|
|
|
7961
7962
|
question: I,
|
|
7962
7963
|
score: r.current.score
|
|
7963
7964
|
});
|
|
7964
|
-
const
|
|
7965
|
+
const H = () => {
|
|
7965
7966
|
if (!u.current || !I) return;
|
|
7966
7967
|
if (u.current.setMood("happy"), e.questionStart)
|
|
7967
7968
|
try {
|
|
@@ -7973,13 +7974,13 @@ const Mt = Ye(({
|
|
|
7973
7974
|
I.type === "code_test" ? u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${I.question}`, { lipsyncLang: E.lipsyncLang }) : I.type === "multiple_choice" ? u.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`, { lipsyncLang: E.lipsyncLang }) : I.type === "true_false" ? u.current.speakText(`Let's start with some true or false questions. First question: ${I.question}`, { lipsyncLang: E.lipsyncLang }) : u.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`, { lipsyncLang: E.lipsyncLang });
|
|
7974
7975
|
};
|
|
7975
7976
|
if (u.current && u.current.isReady && I)
|
|
7976
|
-
|
|
7977
|
+
H();
|
|
7977
7978
|
else if (u.current && u.current.isReady) {
|
|
7978
7979
|
const E = M.current || { lipsyncLang: "en" };
|
|
7979
7980
|
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: E.lipsyncLang });
|
|
7980
7981
|
} else {
|
|
7981
7982
|
const E = setInterval(() => {
|
|
7982
|
-
u.current && u.current.isReady && (clearInterval(E), I &&
|
|
7983
|
+
u.current && u.current.isReady && (clearInterval(E), I && H());
|
|
7983
7984
|
}, 100);
|
|
7984
7985
|
setTimeout(() => {
|
|
7985
7986
|
clearInterval(E);
|
|
@@ -7999,7 +8000,7 @@ const Mt = Ye(({
|
|
|
7999
8000
|
question: I,
|
|
8000
8001
|
score: r.current.score
|
|
8001
8002
|
});
|
|
8002
|
-
const
|
|
8003
|
+
const H = () => {
|
|
8003
8004
|
if (!u.current || !I) return;
|
|
8004
8005
|
if (u.current.setMood("happy"), u.current.setBodyMovement("idle"), e.nextQuestion)
|
|
8005
8006
|
try {
|
|
@@ -8007,34 +8008,34 @@ const Mt = Ye(({
|
|
|
8007
8008
|
} catch (K) {
|
|
8008
8009
|
console.warn("Failed to play nextQuestion animation:", K);
|
|
8009
8010
|
}
|
|
8010
|
-
const E = M.current || { lipsyncLang: "en" }, oe = y()?.questions?.length || 0,
|
|
8011
|
+
const E = M.current || { lipsyncLang: "en" }, oe = y()?.questions?.length || 0, $ = r.current.currentQuestionIndex >= oe - 1;
|
|
8011
8012
|
if (I.type === "code_test") {
|
|
8012
|
-
const K =
|
|
8013
|
+
const K = $ ? `Great! Here's your final coding challenge: ${I.question}` : `Great! Now let's move on to your next coding challenge: ${I.question}`;
|
|
8013
8014
|
u.current.speakText(K, {
|
|
8014
8015
|
lipsyncLang: E.lipsyncLang
|
|
8015
8016
|
});
|
|
8016
8017
|
} else if (I.type === "multiple_choice") {
|
|
8017
|
-
const K =
|
|
8018
|
+
const K = $ ? `Alright! Here's your final question: ${I.question}` : `Alright! Here's your next question: ${I.question}`;
|
|
8018
8019
|
u.current.speakText(K, {
|
|
8019
8020
|
lipsyncLang: E.lipsyncLang
|
|
8020
8021
|
});
|
|
8021
8022
|
} else if (I.type === "true_false") {
|
|
8022
|
-
const K =
|
|
8023
|
+
const K = $ ? `Now let's try this final one: ${I.question}` : `Now let's try this one: ${I.question}`;
|
|
8023
8024
|
u.current.speakText(K, {
|
|
8024
8025
|
lipsyncLang: E.lipsyncLang
|
|
8025
8026
|
});
|
|
8026
8027
|
} else {
|
|
8027
|
-
const K =
|
|
8028
|
+
const K = $ ? `Here's your final question: ${I.question}` : `Here's the next question: ${I.question}`;
|
|
8028
8029
|
u.current.speakText(K, {
|
|
8029
8030
|
lipsyncLang: E.lipsyncLang
|
|
8030
8031
|
});
|
|
8031
8032
|
}
|
|
8032
8033
|
};
|
|
8033
8034
|
if (u.current && u.current.isReady && I)
|
|
8034
|
-
|
|
8035
|
+
H();
|
|
8035
8036
|
else if (I) {
|
|
8036
8037
|
const E = setInterval(() => {
|
|
8037
|
-
u.current && u.current.isReady && (clearInterval(E),
|
|
8038
|
+
u.current && u.current.isReady && (clearInterval(E), H());
|
|
8038
8039
|
}, 100);
|
|
8039
8040
|
setTimeout(() => {
|
|
8040
8041
|
clearInterval(E);
|
|
@@ -8052,12 +8053,12 @@ const Mt = Ye(({
|
|
|
8052
8053
|
const v = B.current || { modules: [] }, I = v.modules[r.current.currentModuleIndex];
|
|
8053
8054
|
if (r.current.currentLessonIndex < (I?.lessons?.length || 0) - 1) {
|
|
8054
8055
|
r.current.currentLessonIndex += 1, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0;
|
|
8055
|
-
const E = v.modules[r.current.currentModuleIndex], Z = r.current.currentLessonIndex < (E?.lessons?.length || 0) - 1, oe = r.current.currentModuleIndex < (v.modules?.length || 0) - 1,
|
|
8056
|
+
const E = v.modules[r.current.currentModuleIndex], Z = r.current.currentLessonIndex < (E?.lessons?.length || 0) - 1, oe = r.current.currentModuleIndex < (v.modules?.length || 0) - 1, $ = Z || oe;
|
|
8056
8057
|
d.current.onCustomAction({
|
|
8057
8058
|
type: "lessonStart",
|
|
8058
8059
|
moduleIndex: r.current.currentModuleIndex,
|
|
8059
8060
|
lessonIndex: r.current.currentLessonIndex,
|
|
8060
|
-
hasNextLesson:
|
|
8061
|
+
hasNextLesson: $
|
|
8061
8062
|
}), d.current.onLessonStart({
|
|
8062
8063
|
moduleIndex: r.current.currentModuleIndex,
|
|
8063
8064
|
lessonIndex: r.current.currentLessonIndex,
|
|
@@ -8065,7 +8066,7 @@ const Mt = Ye(({
|
|
|
8065
8066
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8066
8067
|
} else if (r.current.currentModuleIndex < (v.modules?.length || 0) - 1) {
|
|
8067
8068
|
r.current.currentModuleIndex += 1, r.current.currentLessonIndex = 0, r.current.currentQuestionIndex = 0, r.current.lessonCompleted = !1, r.current.isQuestionMode = !1, r.current.isTeaching = !1, r.current.score = 0, r.current.totalQuestions = 0;
|
|
8068
|
-
const Z = v.modules[r.current.currentModuleIndex], oe = r.current.currentLessonIndex < (Z?.lessons?.length || 0) - 1,
|
|
8069
|
+
const Z = v.modules[r.current.currentModuleIndex], oe = r.current.currentLessonIndex < (Z?.lessons?.length || 0) - 1, $ = r.current.currentModuleIndex < (v.modules?.length || 0) - 1, K = oe || $;
|
|
8069
8070
|
d.current.onCustomAction({
|
|
8070
8071
|
type: "lessonStart",
|
|
8071
8072
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -8077,25 +8078,25 @@ const Mt = Ye(({
|
|
|
8077
8078
|
lesson: y()
|
|
8078
8079
|
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"));
|
|
8079
8080
|
} else
|
|
8080
|
-
|
|
8081
|
+
k.current && k.current();
|
|
8081
8082
|
}, []), X = N(() => {
|
|
8082
8083
|
const v = y();
|
|
8083
8084
|
let I = null;
|
|
8084
8085
|
if (v?.avatar_script && v?.body) {
|
|
8085
|
-
const
|
|
8086
|
-
I = `${
|
|
8086
|
+
const H = v.avatar_script.trim(), E = v.body.trim(), Z = H.match(/[.!?]$/) ? " " : ". ";
|
|
8087
|
+
I = `${H}${Z}${E}`;
|
|
8087
8088
|
} else
|
|
8088
8089
|
I = v?.avatar_script || v?.body || null;
|
|
8089
8090
|
if (u.current && u.current.isReady && I) {
|
|
8090
8091
|
r.current.isTeaching = !0, r.current.isQuestionMode = !1, r.current.score = 0, r.current.totalQuestions = 0, u.current.setMood("happy");
|
|
8091
|
-
let
|
|
8092
|
+
let H = !1;
|
|
8092
8093
|
if (e.teaching)
|
|
8093
8094
|
try {
|
|
8094
|
-
u.current.playAnimation(e.teaching, !0),
|
|
8095
|
+
u.current.playAnimation(e.teaching, !0), H = !0;
|
|
8095
8096
|
} catch (Z) {
|
|
8096
8097
|
console.warn("Failed to play teaching animation:", Z);
|
|
8097
8098
|
}
|
|
8098
|
-
|
|
8099
|
+
H || u.current.setBodyMovement("gesturing");
|
|
8099
8100
|
const E = M.current || { lipsyncLang: "en" };
|
|
8100
8101
|
d.current.onLessonStart({
|
|
8101
8102
|
moduleIndex: r.current.currentModuleIndex,
|
|
@@ -8126,16 +8127,16 @@ const Mt = Ye(({
|
|
|
8126
8127
|
});
|
|
8127
8128
|
}
|
|
8128
8129
|
}, [e.teaching, y]), j = N((v) => {
|
|
8129
|
-
const I = F(),
|
|
8130
|
-
if (
|
|
8130
|
+
const I = F(), H = L(v, I);
|
|
8131
|
+
if (H && (r.current.score += 1), d.current.onQuestionAnswer({
|
|
8131
8132
|
moduleIndex: r.current.currentModuleIndex,
|
|
8132
8133
|
lessonIndex: r.current.currentLessonIndex,
|
|
8133
8134
|
questionIndex: r.current.currentQuestionIndex,
|
|
8134
8135
|
answer: v,
|
|
8135
|
-
isCorrect:
|
|
8136
|
+
isCorrect: H,
|
|
8136
8137
|
question: I
|
|
8137
8138
|
}), u.current)
|
|
8138
|
-
if (
|
|
8139
|
+
if (H) {
|
|
8139
8140
|
if (u.current.setMood("happy"), e.correct)
|
|
8140
8141
|
try {
|
|
8141
8142
|
u.current.playReaction("happy");
|
|
@@ -8147,8 +8148,8 @@ const Mt = Ye(({
|
|
|
8147
8148
|
r.current.currentQuestionIndex >= Z - 1;
|
|
8148
8149
|
const oe = r.current.currentQuestionIndex < Z - 1;
|
|
8149
8150
|
console.log("[CurriculumLearning] Answer feedback - questionIndex:", r.current.currentQuestionIndex, "totalQuestions:", Z, "hasNextQuestion:", oe);
|
|
8150
|
-
const
|
|
8151
|
-
u.current.speakText(
|
|
8151
|
+
const $ = I.type === "code_test" ? `Great job! Your code passed all the tests! ${I.explanation || ""}` : `Excellent! That's correct! ${I.explanation || ""}`, K = M.current || { lipsyncLang: "en" };
|
|
8152
|
+
u.current.speakText($, {
|
|
8152
8153
|
lipsyncLang: K.lipsyncLang,
|
|
8153
8154
|
onSpeechEnd: () => {
|
|
8154
8155
|
d.current.onCustomAction({
|
|
@@ -8171,8 +8172,8 @@ const Mt = Ye(({
|
|
|
8171
8172
|
u.current.setBodyMovement("idle");
|
|
8172
8173
|
}
|
|
8173
8174
|
u.current.setBodyMovement("gesturing");
|
|
8174
|
-
const Z = y()?.questions?.length || 0, oe = r.current.currentQuestionIndex >= Z - 1,
|
|
8175
|
-
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", r.current.currentQuestionIndex, "totalQuestions:", Z, "hasNextQuestion:",
|
|
8175
|
+
const Z = y()?.questions?.length || 0, oe = r.current.currentQuestionIndex >= Z - 1, $ = r.current.currentQuestionIndex < Z - 1;
|
|
8176
|
+
console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:", r.current.currentQuestionIndex, "totalQuestions:", Z, "hasNextQuestion:", $);
|
|
8176
8177
|
const K = I.type === "code_test" ? `Your code didn't pass all the tests. ${I.explanation || "Try again!"}` : `Not quite right, but don't worry! ${I.explanation || ""}${oe ? "" : " Let's move on to the next question."}`, ve = M.current || { lipsyncLang: "en" };
|
|
8177
8178
|
u.current.speakText(K, {
|
|
8178
8179
|
lipsyncLang: ve.lipsyncLang,
|
|
@@ -8183,7 +8184,7 @@ const Mt = Ye(({
|
|
|
8183
8184
|
lessonIndex: r.current.currentLessonIndex,
|
|
8184
8185
|
questionIndex: r.current.currentQuestionIndex,
|
|
8185
8186
|
isCorrect: !1,
|
|
8186
|
-
hasNextQuestion:
|
|
8187
|
+
hasNextQuestion: $,
|
|
8187
8188
|
score: r.current.score,
|
|
8188
8189
|
totalQuestions: r.current.totalQuestions
|
|
8189
8190
|
});
|
|
@@ -8197,14 +8198,14 @@ const Mt = Ye(({
|
|
|
8197
8198
|
moduleIndex: r.current.currentModuleIndex,
|
|
8198
8199
|
lessonIndex: r.current.currentLessonIndex,
|
|
8199
8200
|
questionIndex: r.current.currentQuestionIndex,
|
|
8200
|
-
isCorrect:
|
|
8201
|
+
isCorrect: H,
|
|
8201
8202
|
hasNextQuestion: r.current.currentQuestionIndex < Z - 1,
|
|
8202
8203
|
score: r.current.score,
|
|
8203
8204
|
totalQuestions: r.current.totalQuestions,
|
|
8204
8205
|
avatarNotReady: !0
|
|
8205
8206
|
});
|
|
8206
8207
|
}
|
|
8207
|
-
}, [e.correct, e.incorrect, F, y,
|
|
8208
|
+
}, [e.correct, e.incorrect, F, y, L]), xe = N((v) => {
|
|
8208
8209
|
const I = F();
|
|
8209
8210
|
if (!v || typeof v != "object") {
|
|
8210
8211
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
@@ -8214,7 +8215,7 @@ const Mt = Ye(({
|
|
|
8214
8215
|
console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");
|
|
8215
8216
|
return;
|
|
8216
8217
|
}
|
|
8217
|
-
const
|
|
8218
|
+
const H = {
|
|
8218
8219
|
passed: v.passed === !0,
|
|
8219
8220
|
results: v.results || [],
|
|
8220
8221
|
output: v.output || "",
|
|
@@ -8229,10 +8230,10 @@ const Mt = Ye(({
|
|
|
8229
8230
|
moduleIndex: r.current.currentModuleIndex,
|
|
8230
8231
|
lessonIndex: r.current.currentLessonIndex,
|
|
8231
8232
|
questionIndex: r.current.currentQuestionIndex,
|
|
8232
|
-
testResult:
|
|
8233
|
+
testResult: H,
|
|
8233
8234
|
question: I
|
|
8234
|
-
}), m.current && m.current(
|
|
8235
|
-
}, [F,
|
|
8235
|
+
}), m.current && m.current(H);
|
|
8236
|
+
}, [F, L]), re = N(() => {
|
|
8236
8237
|
if (r.current.currentQuestionIndex > 0) {
|
|
8237
8238
|
r.current.currentQuestionIndex -= 1;
|
|
8238
8239
|
const v = F();
|
|
@@ -8248,21 +8249,21 @@ const Mt = Ye(({
|
|
|
8248
8249
|
const I = () => {
|
|
8249
8250
|
if (!u.current || !v) return;
|
|
8250
8251
|
u.current.setMood("happy"), u.current.setBodyMovement("idle");
|
|
8251
|
-
const
|
|
8252
|
+
const H = M.current || { lipsyncLang: "en" };
|
|
8252
8253
|
v.type === "code_test" ? u.current.speakText(`Let's go back to this coding challenge: ${v.question}`, {
|
|
8253
|
-
lipsyncLang:
|
|
8254
|
+
lipsyncLang: H.lipsyncLang
|
|
8254
8255
|
}) : u.current.speakText(`Going back to: ${v.question}`, {
|
|
8255
|
-
lipsyncLang:
|
|
8256
|
+
lipsyncLang: H.lipsyncLang
|
|
8256
8257
|
});
|
|
8257
8258
|
};
|
|
8258
8259
|
if (u.current && u.current.isReady && v)
|
|
8259
8260
|
I();
|
|
8260
8261
|
else if (v) {
|
|
8261
|
-
const
|
|
8262
|
-
u.current && u.current.isReady && (clearInterval(
|
|
8262
|
+
const H = setInterval(() => {
|
|
8263
|
+
u.current && u.current.isReady && (clearInterval(H), I());
|
|
8263
8264
|
}, 100);
|
|
8264
8265
|
setTimeout(() => {
|
|
8265
|
-
clearInterval(
|
|
8266
|
+
clearInterval(H);
|
|
8266
8267
|
}, 5e3);
|
|
8267
8268
|
}
|
|
8268
8269
|
}
|
|
@@ -8294,13 +8295,13 @@ const Mt = Ye(({
|
|
|
8294
8295
|
r.current.currentModuleIndex = 0, r.current.currentLessonIndex = 0, r.current.currentQuestionIndex = 0, r.current.isTeaching = !1, r.current.isQuestionMode = !1, r.current.lessonCompleted = !1, r.current.curriculumCompleted = !1, r.current.score = 0, r.current.totalQuestions = 0;
|
|
8295
8296
|
}, []), ye = N((v) => {
|
|
8296
8297
|
console.log("Avatar is ready!", v);
|
|
8297
|
-
const I = y(),
|
|
8298
|
-
c &&
|
|
8298
|
+
const I = y(), H = I?.avatar_script || I?.body;
|
|
8299
|
+
c && H && setTimeout(() => {
|
|
8299
8300
|
h.current && h.current();
|
|
8300
8301
|
}, 10);
|
|
8301
8302
|
}, [c, y]);
|
|
8302
8303
|
rt(() => {
|
|
8303
|
-
h.current = X, g.current = U, R.current = f, x.current = D,
|
|
8304
|
+
h.current = X, g.current = U, R.current = f, x.current = D, k.current = T, G.current = A, m.current = j;
|
|
8304
8305
|
}), Qe(l, () => ({
|
|
8305
8306
|
// Curriculum control methods
|
|
8306
8307
|
startTeaching: X,
|
|
@@ -8312,7 +8313,7 @@ const Mt = Ye(({
|
|
|
8312
8313
|
nextLesson: U,
|
|
8313
8314
|
previousLesson: Se,
|
|
8314
8315
|
completeLesson: f,
|
|
8315
|
-
completeCurriculum:
|
|
8316
|
+
completeCurriculum: T,
|
|
8316
8317
|
resetCurriculum: ce,
|
|
8317
8318
|
getState: () => ({ ...r.current }),
|
|
8318
8319
|
getCurrentQuestion: () => F(),
|
|
@@ -8322,8 +8323,8 @@ const Mt = Ye(({
|
|
|
8322
8323
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
8323
8324
|
speakText: async (v, I = {}) => {
|
|
8324
8325
|
await u.current?.resumeAudioContext?.();
|
|
8325
|
-
const
|
|
8326
|
-
u.current?.speakText(v, { ...I, lipsyncLang: I.lipsyncLang ||
|
|
8326
|
+
const H = M.current || { lipsyncLang: "en" };
|
|
8327
|
+
u.current?.speakText(v, { ...I, lipsyncLang: I.lipsyncLang || H.lipsyncLang });
|
|
8327
8328
|
},
|
|
8328
8329
|
resumeAudioContext: async () => {
|
|
8329
8330
|
if (u.current?.resumeAudioContext)
|
|
@@ -8334,8 +8335,8 @@ const Mt = Ye(({
|
|
|
8334
8335
|
if (I.state === "suspended" || I.state === "interrupted")
|
|
8335
8336
|
try {
|
|
8336
8337
|
await I.resume(), console.log("Audio context resumed via talkingHead");
|
|
8337
|
-
} catch (
|
|
8338
|
-
console.warn("Failed to resume audio context:",
|
|
8338
|
+
} catch (H) {
|
|
8339
|
+
console.warn("Failed to resume audio context:", H);
|
|
8339
8340
|
}
|
|
8340
8341
|
} else
|
|
8341
8342
|
console.warn("Audio context not available yet");
|
|
@@ -8367,7 +8368,7 @@ const Mt = Ye(({
|
|
|
8367
8368
|
handleResize: () => u.current?.handleResize(),
|
|
8368
8369
|
// Avatar readiness check (always returns current value)
|
|
8369
8370
|
isAvatarReady: () => u.current?.isReady || !1
|
|
8370
|
-
}), [X, A, j, xe, D, U, f,
|
|
8371
|
+
}), [X, A, j, xe, D, U, f, T, ce, F, y]);
|
|
8371
8372
|
const ie = M.current || {
|
|
8372
8373
|
avatarUrl: "/avatars/brunette.glb",
|
|
8373
8374
|
avatarBody: "F",
|
|
@@ -8381,7 +8382,7 @@ const Mt = Ye(({
|
|
|
8381
8382
|
showFullAvatar: !1,
|
|
8382
8383
|
animations: e
|
|
8383
8384
|
};
|
|
8384
|
-
return /* @__PURE__ */
|
|
8385
|
+
return /* @__PURE__ */ J("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ J(
|
|
8385
8386
|
it,
|
|
8386
8387
|
{
|
|
8387
8388
|
ref: u,
|
|
@@ -8408,22 +8409,22 @@ const Mt = Ye(({
|
|
|
8408
8409
|
});
|
|
8409
8410
|
Mt.displayName = "CurriculumLearning";
|
|
8410
8411
|
function Vt({
|
|
8411
|
-
manifestPath:
|
|
8412
|
+
manifestPath: W = "/animations/manifest.json",
|
|
8412
8413
|
avatarBody: t = "F",
|
|
8413
8414
|
onAnimationPlay: e = null,
|
|
8414
8415
|
onAnimationsSelected: n = null,
|
|
8415
8416
|
onDeleteAnimations: o = null,
|
|
8416
8417
|
style: s = {}
|
|
8417
8418
|
}) {
|
|
8418
|
-
const [i, a] = le([]), [c, l] = le(/* @__PURE__ */ new Set()), [u, r] = le(!0), [d, h] = le(null), [g, R] = le("all"), [x,
|
|
8419
|
+
const [i, a] = le([]), [c, l] = le(/* @__PURE__ */ new Set()), [u, r] = le(!0), [d, h] = le(null), [g, R] = le("all"), [x, k] = le("");
|
|
8419
8420
|
Re(() => {
|
|
8420
8421
|
(async () => {
|
|
8421
8422
|
r(!0), h(null);
|
|
8422
8423
|
try {
|
|
8423
|
-
const
|
|
8424
|
-
if (
|
|
8424
|
+
const T = await Ue(W), A = [];
|
|
8425
|
+
if (T._genderSpecific) {
|
|
8425
8426
|
const U = (t?.toUpperCase() || "F") === "M" ? "male" : "female";
|
|
8426
|
-
|
|
8427
|
+
T._genderSpecific[U] && Object.entries(T._genderSpecific[U]).forEach(([X, j]) => {
|
|
8427
8428
|
(Array.isArray(j) ? j : [j]).forEach((re) => {
|
|
8428
8429
|
A.push({
|
|
8429
8430
|
path: re,
|
|
@@ -8432,7 +8433,7 @@ function Vt({
|
|
|
8432
8433
|
name: re.split("/").pop().replace(".fbx", "")
|
|
8433
8434
|
});
|
|
8434
8435
|
});
|
|
8435
|
-
}),
|
|
8436
|
+
}), T._genderSpecific.shared && Object.entries(T._genderSpecific.shared).forEach(([X, j]) => {
|
|
8436
8437
|
(Array.isArray(j) ? j : [j]).forEach((re) => {
|
|
8437
8438
|
A.push({
|
|
8438
8439
|
path: re,
|
|
@@ -8443,7 +8444,7 @@ function Vt({
|
|
|
8443
8444
|
});
|
|
8444
8445
|
});
|
|
8445
8446
|
}
|
|
8446
|
-
Object.entries(
|
|
8447
|
+
Object.entries(T).forEach(([D, U]) => {
|
|
8447
8448
|
D !== "_genderSpecific" && (Array.isArray(U) ? U : [U]).forEach((j) => {
|
|
8448
8449
|
typeof j == "string" && A.push({
|
|
8449
8450
|
path: j,
|
|
@@ -8453,43 +8454,43 @@ function Vt({
|
|
|
8453
8454
|
});
|
|
8454
8455
|
});
|
|
8455
8456
|
}), a(A), r(!1);
|
|
8456
|
-
} catch (
|
|
8457
|
-
console.error("Failed to load animations:",
|
|
8457
|
+
} catch (T) {
|
|
8458
|
+
console.error("Failed to load animations:", T), h(T.message), r(!1);
|
|
8458
8459
|
}
|
|
8459
8460
|
})();
|
|
8460
|
-
}, [
|
|
8461
|
+
}, [W, t]);
|
|
8461
8462
|
const G = ["all", ...new Set(i.map((f) => f.group))], m = i.filter((f) => {
|
|
8462
|
-
const
|
|
8463
|
-
return
|
|
8463
|
+
const T = g === "all" || f.group === g, A = x === "" || f.name.toLowerCase().includes(x.toLowerCase()) || f.path.toLowerCase().includes(x.toLowerCase());
|
|
8464
|
+
return T && A;
|
|
8464
8465
|
}), B = (f) => {
|
|
8465
|
-
const
|
|
8466
|
-
|
|
8466
|
+
const T = new Set(c);
|
|
8467
|
+
T.has(f) ? T.delete(f) : T.add(f), l(T), n && n(Array.from(T));
|
|
8467
8468
|
}, M = () => {
|
|
8468
8469
|
const f = new Set(c);
|
|
8469
|
-
m.forEach((
|
|
8470
|
-
f.add(
|
|
8470
|
+
m.forEach((T) => {
|
|
8471
|
+
f.add(T.path);
|
|
8471
8472
|
}), l(f), n && n(Array.from(f));
|
|
8472
8473
|
}, y = () => {
|
|
8473
8474
|
const f = new Set(c);
|
|
8474
|
-
m.forEach((
|
|
8475
|
-
f.delete(
|
|
8475
|
+
m.forEach((T) => {
|
|
8476
|
+
f.delete(T.path);
|
|
8476
8477
|
}), l(f), n && n(Array.from(f));
|
|
8477
8478
|
}, F = () => {
|
|
8478
|
-
const
|
|
8479
|
-
if (
|
|
8479
|
+
const T = i.filter((A) => !c.has(A.path)).map((A) => A.path);
|
|
8480
|
+
if (T.length === 0) {
|
|
8480
8481
|
alert("No animations to delete. Select animations to keep, then delete will remove the unselected ones.");
|
|
8481
8482
|
return;
|
|
8482
8483
|
}
|
|
8483
|
-
window.confirm(`Are you sure you want to delete ${
|
|
8484
|
+
window.confirm(`Are you sure you want to delete ${T.length} animation(s)?
|
|
8484
8485
|
|
|
8485
8486
|
This will delete:
|
|
8486
|
-
${
|
|
8487
|
-
`)}${
|
|
8488
|
-
...` : ""}`) && (o && o(
|
|
8489
|
-
},
|
|
8487
|
+
${T.slice(0, 5).join(`
|
|
8488
|
+
`)}${T.length > 5 ? `
|
|
8489
|
+
...` : ""}`) && (o && o(T), a(i.filter((A) => c.has(A.path))), l(/* @__PURE__ */ new Set()));
|
|
8490
|
+
}, L = (f) => {
|
|
8490
8491
|
e && e(f);
|
|
8491
8492
|
};
|
|
8492
|
-
return u ? /* @__PURE__ */
|
|
8493
|
+
return u ? /* @__PURE__ */ J("div", { style: { padding: "20px", textAlign: "center", ...s }, children: /* @__PURE__ */ J("p", { children: "Loading animations..." }) }) : d ? /* @__PURE__ */ J("div", { style: { padding: "20px", color: "red", ...s }, children: /* @__PURE__ */ we("p", { children: [
|
|
8493
8494
|
"Error loading animations: ",
|
|
8494
8495
|
d
|
|
8495
8496
|
] }) }) : /* @__PURE__ */ we("div", { style: {
|
|
@@ -8499,8 +8500,8 @@ ${H.slice(0, 5).join(`
|
|
|
8499
8500
|
color: "#fff",
|
|
8500
8501
|
...s
|
|
8501
8502
|
}, children: [
|
|
8502
|
-
/* @__PURE__ */
|
|
8503
|
-
/* @__PURE__ */
|
|
8503
|
+
/* @__PURE__ */ J("h2", { style: { marginTop: 0 }, children: "Animation Selector" }),
|
|
8504
|
+
/* @__PURE__ */ J("p", { style: { color: "#aaa", fontSize: "14px" }, children: "Click buttons to play animations. Select animations to keep, then delete will remove the rest." }),
|
|
8504
8505
|
/* @__PURE__ */ we("div", { style: {
|
|
8505
8506
|
display: "flex",
|
|
8506
8507
|
gap: "10px",
|
|
@@ -8508,13 +8509,13 @@ ${H.slice(0, 5).join(`
|
|
|
8508
8509
|
flexWrap: "wrap",
|
|
8509
8510
|
alignItems: "center"
|
|
8510
8511
|
}, children: [
|
|
8511
|
-
/* @__PURE__ */
|
|
8512
|
+
/* @__PURE__ */ J(
|
|
8512
8513
|
"input",
|
|
8513
8514
|
{
|
|
8514
8515
|
type: "text",
|
|
8515
8516
|
placeholder: "Search animations...",
|
|
8516
8517
|
value: x,
|
|
8517
|
-
onChange: (f) =>
|
|
8518
|
+
onChange: (f) => k(f.target.value),
|
|
8518
8519
|
style: {
|
|
8519
8520
|
padding: "8px 12px",
|
|
8520
8521
|
borderRadius: "6px",
|
|
@@ -8527,7 +8528,7 @@ ${H.slice(0, 5).join(`
|
|
|
8527
8528
|
}
|
|
8528
8529
|
}
|
|
8529
8530
|
),
|
|
8530
|
-
/* @__PURE__ */
|
|
8531
|
+
/* @__PURE__ */ J(
|
|
8531
8532
|
"select",
|
|
8532
8533
|
{
|
|
8533
8534
|
value: g,
|
|
@@ -8540,10 +8541,10 @@ ${H.slice(0, 5).join(`
|
|
|
8540
8541
|
color: "#fff",
|
|
8541
8542
|
fontSize: "14px"
|
|
8542
8543
|
},
|
|
8543
|
-
children: G.map((f) => /* @__PURE__ */
|
|
8544
|
+
children: G.map((f) => /* @__PURE__ */ J("option", { value: f, children: f === "all" ? "All Groups" : f }, f))
|
|
8544
8545
|
}
|
|
8545
8546
|
),
|
|
8546
|
-
/* @__PURE__ */
|
|
8547
|
+
/* @__PURE__ */ J(
|
|
8547
8548
|
"button",
|
|
8548
8549
|
{
|
|
8549
8550
|
onClick: M,
|
|
@@ -8559,7 +8560,7 @@ ${H.slice(0, 5).join(`
|
|
|
8559
8560
|
children: "Select All Visible"
|
|
8560
8561
|
}
|
|
8561
8562
|
),
|
|
8562
|
-
/* @__PURE__ */
|
|
8563
|
+
/* @__PURE__ */ J(
|
|
8563
8564
|
"button",
|
|
8564
8565
|
{
|
|
8565
8566
|
onClick: y,
|
|
@@ -8609,7 +8610,7 @@ ${H.slice(0, 5).join(`
|
|
|
8609
8610
|
" | Showing: ",
|
|
8610
8611
|
m.length
|
|
8611
8612
|
] }),
|
|
8612
|
-
/* @__PURE__ */
|
|
8613
|
+
/* @__PURE__ */ J("div", { style: {
|
|
8613
8614
|
display: "grid",
|
|
8614
8615
|
gridTemplateColumns: "repeat(auto-fill, minmax(200px, 1fr))",
|
|
8615
8616
|
gap: "10px",
|
|
@@ -8618,7 +8619,7 @@ ${H.slice(0, 5).join(`
|
|
|
8618
8619
|
padding: "10px",
|
|
8619
8620
|
backgroundColor: "#1a1a1a",
|
|
8620
8621
|
borderRadius: "6px"
|
|
8621
|
-
}, children: m.map((f,
|
|
8622
|
+
}, children: m.map((f, T) => {
|
|
8622
8623
|
const A = c.has(f.path);
|
|
8623
8624
|
return /* @__PURE__ */ we(
|
|
8624
8625
|
"div",
|
|
@@ -8634,7 +8635,7 @@ ${H.slice(0, 5).join(`
|
|
|
8634
8635
|
onClick: () => B(f.path),
|
|
8635
8636
|
children: [
|
|
8636
8637
|
/* @__PURE__ */ we("div", { style: { marginBottom: "8px" }, children: [
|
|
8637
|
-
/* @__PURE__ */
|
|
8638
|
+
/* @__PURE__ */ J(
|
|
8638
8639
|
"input",
|
|
8639
8640
|
{
|
|
8640
8641
|
type: "checkbox",
|
|
@@ -8653,17 +8654,17 @@ ${H.slice(0, 5).join(`
|
|
|
8653
8654
|
f.gender !== "root" && `(${f.gender})`
|
|
8654
8655
|
] })
|
|
8655
8656
|
] }),
|
|
8656
|
-
/* @__PURE__ */
|
|
8657
|
+
/* @__PURE__ */ J("div", { style: {
|
|
8657
8658
|
fontSize: "13px",
|
|
8658
8659
|
fontWeight: "bold",
|
|
8659
8660
|
marginBottom: "8px",
|
|
8660
8661
|
wordBreak: "break-word"
|
|
8661
8662
|
}, children: f.name }),
|
|
8662
|
-
/* @__PURE__ */
|
|
8663
|
+
/* @__PURE__ */ J(
|
|
8663
8664
|
"button",
|
|
8664
8665
|
{
|
|
8665
8666
|
onClick: (D) => {
|
|
8666
|
-
D.stopPropagation(),
|
|
8667
|
+
D.stopPropagation(), L(f.path);
|
|
8667
8668
|
},
|
|
8668
8669
|
style: {
|
|
8669
8670
|
width: "100%",
|
|
@@ -8680,10 +8681,10 @@ ${H.slice(0, 5).join(`
|
|
|
8680
8681
|
)
|
|
8681
8682
|
]
|
|
8682
8683
|
},
|
|
8683
|
-
`${f.path}-${
|
|
8684
|
+
`${f.path}-${T}`
|
|
8684
8685
|
);
|
|
8685
8686
|
}) }),
|
|
8686
|
-
m.length === 0 && /* @__PURE__ */
|
|
8687
|
+
m.length === 0 && /* @__PURE__ */ J("div", { style: {
|
|
8687
8688
|
padding: "40px",
|
|
8688
8689
|
textAlign: "center",
|
|
8689
8690
|
color: "#aaa"
|
|
@@ -8793,7 +8794,7 @@ const ot = {
|
|
|
8793
8794
|
duration: 5e3,
|
|
8794
8795
|
description: "Excited, energetic movement"
|
|
8795
8796
|
}
|
|
8796
|
-
}, Gt = (
|
|
8797
|
+
}, Gt = (W) => ot[W] || null, Zt = (W) => ot.hasOwnProperty(W);
|
|
8797
8798
|
export {
|
|
8798
8799
|
Vt as AnimationSelector,
|
|
8799
8800
|
Mt as CurriculumLearning,
|