@sage-rsc/talking-head-react 1.0.39 → 1.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -2
- package/dist/index.js +453 -330
- package/package.json +1 -1
- package/src/components/TalkingHeadAvatar.jsx +12 -2
- package/src/config/ttsConfig.js +41 -10
- package/src/lib/talkinghead.mjs +158 -2
package/dist/index.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { forwardRef as ye, useRef as X, useState as re, useCallback as M, useEffect as he, useImperativeHandle as fe, useLayoutEffect as
|
|
3
|
-
import * as
|
|
4
|
-
import { OrbitControls as
|
|
5
|
-
import { GLTFLoader as
|
|
6
|
-
import { DRACOLoader as
|
|
1
|
+
import { jsxs as Le, jsx as se } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as ye, useRef as X, useState as re, useCallback as M, useEffect as he, useImperativeHandle as fe, useLayoutEffect as He } from "react";
|
|
3
|
+
import * as f from "three";
|
|
4
|
+
import { OrbitControls as Te } from "three/addons/controls/OrbitControls.js";
|
|
5
|
+
import { GLTFLoader as Me } from "three/addons/loaders/GLTFLoader.js";
|
|
6
|
+
import { DRACOLoader as Ee } from "three/addons/loaders/DRACOLoader.js";
|
|
7
7
|
import { FBXLoader as be } from "three/addons/loaders/FBXLoader.js";
|
|
8
|
-
import { RoomEnvironment as
|
|
9
|
-
import
|
|
10
|
-
let m,
|
|
11
|
-
const A = [0, 0, 0, 0], k = new
|
|
12
|
-
new
|
|
13
|
-
new
|
|
14
|
-
new
|
|
15
|
-
const Z = new
|
|
16
|
-
new
|
|
17
|
-
const ce = new
|
|
18
|
-
class
|
|
8
|
+
import { RoomEnvironment as Fe } from "three/addons/environments/RoomEnvironment.js";
|
|
9
|
+
import Pe from "three/addons/libs/stats.module.js";
|
|
10
|
+
let m, j, K;
|
|
11
|
+
const A = [0, 0, 0, 0], k = new f.Vector3(), ue = new f.Vector3(), G = new f.Vector3(), de = new f.Vector3();
|
|
12
|
+
new f.Plane();
|
|
13
|
+
new f.Ray();
|
|
14
|
+
new f.Euler();
|
|
15
|
+
const Z = new f.Quaternion(), Re = new f.Quaternion(), ee = new f.Matrix4(), te = new f.Matrix4();
|
|
16
|
+
new f.Vector3();
|
|
17
|
+
const ce = new f.Vector3(0, 0, 1), Be = new f.Vector3(1, 0, 0), De = new f.Vector3(0, 1, 0), Oe = new f.Vector3(0, 0, 1);
|
|
18
|
+
class Ne {
|
|
19
19
|
constructor(t = null) {
|
|
20
20
|
this.opt = Object.assign({
|
|
21
21
|
warmupMs: 2e3,
|
|
@@ -369,9 +369,9 @@ class De {
|
|
|
369
369
|
o.vBasis.y + A[1],
|
|
370
370
|
o.vBasis.z - A[2]
|
|
371
371
|
);
|
|
372
|
-
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(k, Z, G), k.copy(ce).applyQuaternion(Z).setY(0).normalize(), Z.premultiply(Re.setFromUnitVectors(ce, k).invert()).normalize(), o.boneParent.quaternion.multiply(Z.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), Z.setFromAxisAngle(Oe, -m), o.boneParent.quaternion.multiply(Z)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), Z.setFromAxisAngle(
|
|
372
|
+
else if (o.boneParent.quaternion.copy(o.qBasis), o.pivot && this.opt.isPivots && (o.boneParent.updateWorldMatrix(!1, !1), o.boneParent.matrixWorld.decompose(k, Z, G), k.copy(ce).applyQuaternion(Z).setY(0).normalize(), Z.premultiply(Re.setFromUnitVectors(ce, k).invert()).normalize(), o.boneParent.quaternion.multiply(Z.invert()), o.boneParent.quaternion.multiply(o.qWorldInverseYaw)), o.isZ && (m = Math.atan(A[0] / o.l), Z.setFromAxisAngle(Oe, -m), o.boneParent.quaternion.multiply(Z)), o.isY && (m = o.l / 3, m = m * Math.tanh(A[1] / m), o.bone.position.setLength(o.l + m)), o.isX && (m = Math.atan(A[2] / o.l), Z.setFromAxisAngle(Be, -m), o.boneParent.quaternion.multiply(Z)), o.isT && (m = 1.5 * Math.tanh(A[3] * 1.5), Z.setFromAxisAngle(De, -m), o.boneParent.quaternion.multiply(Z)), o.boneParent.updateWorldMatrix(!1, !0), o.excludes && this.opt.isExcludes)
|
|
373
373
|
for (i = 0, s = o.excludes.length; i < s; i++)
|
|
374
|
-
m = o.excludes[i], G.set(0, 0, 0), m.deltaLocal && (G.x += m.deltaLocal[0], G.y += m.deltaLocal[1], G.z += m.deltaLocal[2]), G.applyMatrix4(m.bone.matrixWorld), te.copy(o.boneParent.matrixWorld).invert(), G.applyMatrix4(te), k.copy(o.bone.position), !(k.distanceToSquared(G) >= m.radiusSq) && (
|
|
374
|
+
m = o.excludes[i], G.set(0, 0, 0), m.deltaLocal && (G.x += m.deltaLocal[0], G.y += m.deltaLocal[1], G.z += m.deltaLocal[2]), G.applyMatrix4(m.bone.matrixWorld), te.copy(o.boneParent.matrixWorld).invert(), G.applyMatrix4(te), k.copy(o.bone.position), !(k.distanceToSquared(G) >= m.radiusSq) && (K = k.length(), j = G.length(), !(j > m.radius + K) && (j < Math.abs(m.radius - K) || (j = (j * j + K * K - m.radiusSq) / (2 * j), G.normalize(), de.copy(G).multiplyScalar(j), j = Math.sqrt(K * K - j * j), k.subVectors(k, de).projectOnPlane(G).normalize().multiplyScalar(j), ue.subVectors(o.vBasis, de).projectOnPlane(G).normalize(), K = ue.dot(k), K < 0 && (K = Math.sqrt(j * j - K * K), ue.multiplyScalar(K), k.add(ue)), k.add(de).normalize(), G.copy(o.bone.position).normalize(), Z.setFromUnitVectors(G, k), o.boneParent.quaternion.premultiply(Z), o.boneParent.updateWorldMatrix(!1, !0))));
|
|
375
375
|
}
|
|
376
376
|
this.helpers.isActive && this.updateHelpers();
|
|
377
377
|
}
|
|
@@ -393,7 +393,7 @@ class De {
|
|
|
393
393
|
n || (m.excludes.bones.push(i.bone), m.excludes.radii.push(i.radius), m.excludes.deltaLocals.push(i.deltaLocal ? [...i.deltaLocal] : null), m.excludes.objects.push(null));
|
|
394
394
|
}));
|
|
395
395
|
}), m = this.helpers.excludes, this.opt.isExcludes && m.bones.length && m.bones.forEach((e, i) => {
|
|
396
|
-
const n = new
|
|
396
|
+
const n = new f.SphereGeometry(m.radii[i], 6, 6), s = new f.MeshBasicMaterial({
|
|
397
397
|
depthTest: !1,
|
|
398
398
|
depthWrite: !1,
|
|
399
399
|
toneMapped: !1,
|
|
@@ -401,18 +401,18 @@ class De {
|
|
|
401
401
|
wireframe: !0,
|
|
402
402
|
color: this.opt.helperExcludesColor
|
|
403
403
|
});
|
|
404
|
-
m.objects[i] = new
|
|
404
|
+
m.objects[i] = new f.Mesh(n, s), m.objects[i].renderOrder = 997, e.add(m.objects[i]), m.deltaLocals[i] && m.objects[i].position.set(
|
|
405
405
|
m.deltaLocals[i][0],
|
|
406
406
|
m.deltaLocals[i][1],
|
|
407
407
|
m.deltaLocals[i][2]
|
|
408
408
|
);
|
|
409
409
|
}), m = this.helpers.points, m.bones.length) {
|
|
410
410
|
this.helpers.isActive = !0;
|
|
411
|
-
const e = new
|
|
412
|
-
e.setAttribute("position", new
|
|
413
|
-
const n = new
|
|
414
|
-
e.setAttribute("color", new
|
|
415
|
-
const r = new
|
|
411
|
+
const e = new f.BufferGeometry(), i = m.bones.map((h) => [0, 0, 0]).flat();
|
|
412
|
+
e.setAttribute("position", new f.Float32BufferAttribute(i, 3));
|
|
413
|
+
const n = new f.Color(this.opt.helperBoneColor1), s = new f.Color(this.opt.helperBoneColor2), o = m.pivots.map((h) => h && this.opt.isPivots ? [s.r, s.g, s.b] : [n.r, n.g, n.b]).flat();
|
|
414
|
+
e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
|
|
415
|
+
const r = new f.PointsMaterial({
|
|
416
416
|
depthTest: !1,
|
|
417
417
|
depthWrite: !1,
|
|
418
418
|
toneMapped: !1,
|
|
@@ -420,21 +420,21 @@ class De {
|
|
|
420
420
|
size: 0.2,
|
|
421
421
|
vertexColors: !0
|
|
422
422
|
});
|
|
423
|
-
m.object = new
|
|
423
|
+
m.object = new f.Points(e, r), m.object.renderOrder = 998, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
|
|
424
424
|
}
|
|
425
425
|
if (m = this.helpers.lines, m.bones.length) {
|
|
426
|
-
const e = new
|
|
427
|
-
e.setAttribute("position", new
|
|
428
|
-
const n = new
|
|
429
|
-
e.setAttribute("color", new
|
|
430
|
-
const r = new
|
|
426
|
+
const e = new f.BufferGeometry(), i = m.bones.map((h) => [0, 0, 0, 0, 0, 0]).flat();
|
|
427
|
+
e.setAttribute("position", new f.Float32BufferAttribute(i, 3));
|
|
428
|
+
const n = new f.Color(this.opt.helperLinkColor1), s = new f.Color(this.opt.helperLinkColor2), o = m.bones.map((h) => [n.r, n.g, n.b, s.r, s.g, s.b]).flat();
|
|
429
|
+
e.setAttribute("color", new f.Float32BufferAttribute(o, 3));
|
|
430
|
+
const r = new f.LineBasicMaterial({
|
|
431
431
|
vertexColors: !0,
|
|
432
432
|
depthTest: !1,
|
|
433
433
|
depthWrite: !1,
|
|
434
434
|
toneMapped: !1,
|
|
435
435
|
transparent: !0
|
|
436
436
|
});
|
|
437
|
-
m.object = new
|
|
437
|
+
m.object = new f.LineSegments(e, r), m.object.renderOrder = 999, m.object.matrix = this.armature.matrixWorld, m.object.matrixAutoUpdate = !1, this.scene.add(m.object);
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
/**
|
|
@@ -489,7 +489,7 @@ class De {
|
|
|
489
489
|
this.stop(), this.scene = null, this.armature = null, this.config = [], this.data = [], this.dict = {}, this.objectsUpdate = [], this.timerMs = 0;
|
|
490
490
|
}
|
|
491
491
|
}
|
|
492
|
-
class
|
|
492
|
+
class Ue {
|
|
493
493
|
constructor(t) {
|
|
494
494
|
this.audioContext = t, this.analyzer = null, this.dataArray = null, this.bufferLength = 0;
|
|
495
495
|
}
|
|
@@ -606,10 +606,10 @@ class Ne {
|
|
|
606
606
|
for (let h = 0; h < e; h += n) {
|
|
607
607
|
let a = 1, u = 0;
|
|
608
608
|
for (let l = 0; l < n / 2; l++) {
|
|
609
|
-
const c = i[(h + l) * 2], d = i[(h + l) * 2 + 1], g = i[(h + l + n / 2) * 2] * a - i[(h + l + n / 2) * 2 + 1] * u,
|
|
610
|
-
i[(h + l) * 2] = c + g, i[(h + l) * 2 + 1] = d +
|
|
611
|
-
const x = a * o - u * r,
|
|
612
|
-
a = x, u =
|
|
609
|
+
const c = i[(h + l) * 2], d = i[(h + l) * 2 + 1], g = i[(h + l + n / 2) * 2] * a - i[(h + l + n / 2) * 2 + 1] * u, y = i[(h + l + n / 2) * 2] * u + i[(h + l + n / 2) * 2 + 1] * a;
|
|
610
|
+
i[(h + l) * 2] = c + g, i[(h + l) * 2 + 1] = d + y, i[(h + l + n / 2) * 2] = c - g, i[(h + l + n / 2) * 2 + 1] = d - y;
|
|
611
|
+
const x = a * o - u * r, v = a * r + u * o;
|
|
612
|
+
a = x, u = v;
|
|
613
613
|
}
|
|
614
614
|
}
|
|
615
615
|
}
|
|
@@ -814,7 +814,7 @@ class Ne {
|
|
|
814
814
|
return n * s;
|
|
815
815
|
}
|
|
816
816
|
}
|
|
817
|
-
class
|
|
817
|
+
class We {
|
|
818
818
|
/**
|
|
819
819
|
* @constructor
|
|
820
820
|
*/
|
|
@@ -1396,11 +1396,11 @@ class Ue {
|
|
|
1396
1396
|
return e;
|
|
1397
1397
|
}
|
|
1398
1398
|
}
|
|
1399
|
-
const
|
|
1399
|
+
const Ve = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1400
1400
|
__proto__: null,
|
|
1401
|
-
LipsyncEn:
|
|
1401
|
+
LipsyncEn: We
|
|
1402
1402
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1403
|
-
class
|
|
1403
|
+
class Ge {
|
|
1404
1404
|
/**
|
|
1405
1405
|
* @constructor
|
|
1406
1406
|
*/
|
|
@@ -1754,11 +1754,11 @@ class Ve {
|
|
|
1754
1754
|
return e;
|
|
1755
1755
|
}
|
|
1756
1756
|
}
|
|
1757
|
-
const
|
|
1757
|
+
const Ze = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1758
1758
|
__proto__: null,
|
|
1759
|
-
LipsyncDe:
|
|
1759
|
+
LipsyncDe: Ge
|
|
1760
1760
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1761
|
-
class
|
|
1761
|
+
class Xe {
|
|
1762
1762
|
/**
|
|
1763
1763
|
* @constructor
|
|
1764
1764
|
*/
|
|
@@ -2289,11 +2289,11 @@ class Ze {
|
|
|
2289
2289
|
return e;
|
|
2290
2290
|
}
|
|
2291
2291
|
}
|
|
2292
|
-
const
|
|
2292
|
+
const Ye = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2293
2293
|
__proto__: null,
|
|
2294
|
-
LipsyncFr:
|
|
2294
|
+
LipsyncFr: Xe
|
|
2295
2295
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2296
|
-
class
|
|
2296
|
+
class je {
|
|
2297
2297
|
/**
|
|
2298
2298
|
* @constructor
|
|
2299
2299
|
*/
|
|
@@ -2436,11 +2436,11 @@ class Ye {
|
|
|
2436
2436
|
return e;
|
|
2437
2437
|
}
|
|
2438
2438
|
}
|
|
2439
|
-
const
|
|
2439
|
+
const Qe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2440
2440
|
__proto__: null,
|
|
2441
|
-
LipsyncFi:
|
|
2441
|
+
LipsyncFi: je
|
|
2442
2442
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2443
|
-
class
|
|
2443
|
+
class qe {
|
|
2444
2444
|
/**
|
|
2445
2445
|
* @constructor
|
|
2446
2446
|
*/
|
|
@@ -2620,24 +2620,24 @@ class Qe {
|
|
|
2620
2620
|
return e;
|
|
2621
2621
|
}
|
|
2622
2622
|
}
|
|
2623
|
-
const
|
|
2623
|
+
const _e = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2624
2624
|
__proto__: null,
|
|
2625
|
-
LipsyncLt:
|
|
2626
|
-
}, Symbol.toStringTag, { value: "Module" })), _e = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), ve = {
|
|
2627
|
-
en:
|
|
2628
|
-
de:
|
|
2629
|
-
fr:
|
|
2630
|
-
fi:
|
|
2631
|
-
lt:
|
|
2632
|
-
}, N = new
|
|
2633
|
-
new
|
|
2634
|
-
new
|
|
2635
|
-
new
|
|
2636
|
-
new
|
|
2637
|
-
const
|
|
2638
|
-
new
|
|
2639
|
-
new
|
|
2640
|
-
class
|
|
2625
|
+
LipsyncLt: qe
|
|
2626
|
+
}, Symbol.toStringTag, { value: "Module" })), Ke = new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=", import.meta.url), ve = {
|
|
2627
|
+
en: Ve,
|
|
2628
|
+
de: Ze,
|
|
2629
|
+
fr: Ye,
|
|
2630
|
+
fi: Qe,
|
|
2631
|
+
lt: _e
|
|
2632
|
+
}, N = new f.Quaternion(), T = new f.Euler(), ie = new f.Vector3(), oe = new f.Vector3(), Ie = new f.Box3();
|
|
2633
|
+
new f.Matrix4();
|
|
2634
|
+
new f.Matrix4();
|
|
2635
|
+
new f.Vector3();
|
|
2636
|
+
new f.Vector3(0, 0, 1);
|
|
2637
|
+
const Je = new f.Vector3(1, 0, 0);
|
|
2638
|
+
new f.Vector3(0, 1, 0);
|
|
2639
|
+
new f.Vector3(0, 0, 1);
|
|
2640
|
+
class Se {
|
|
2641
2641
|
/**
|
|
2642
2642
|
* Avatar.
|
|
2643
2643
|
* @typedef {Object} Avatar
|
|
@@ -2734,9 +2734,9 @@ class Le {
|
|
|
2734
2734
|
cameraPanEnable: !1,
|
|
2735
2735
|
cameraZoomEnable: !1,
|
|
2736
2736
|
lightAmbientColor: 16777215,
|
|
2737
|
-
lightAmbientIntensity:
|
|
2737
|
+
lightAmbientIntensity: 2,
|
|
2738
2738
|
lightDirectColor: 8947882,
|
|
2739
|
-
lightDirectIntensity:
|
|
2739
|
+
lightDirectIntensity: 30,
|
|
2740
2740
|
lightDirectPhi: 1,
|
|
2741
2741
|
lightDirectTheta: 2,
|
|
2742
2742
|
lightSpotIntensity: 0,
|
|
@@ -2763,7 +2763,7 @@ class Le {
|
|
|
2763
2763
|
avatarOnlyCamera: null,
|
|
2764
2764
|
statsNode: null,
|
|
2765
2765
|
statsStyle: null
|
|
2766
|
-
}, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new
|
|
2766
|
+
}, Object.assign(this.opt, e || {}), this.opt.statsNode && (this.stats = new Pe(), this.opt.statsStyle && (this.stats.dom.style.cssText = this.opt.statsStyle), this.opt.statsNode.appendChild(this.stats.dom)), this.poseTemplates = {
|
|
2767
2767
|
side: {
|
|
2768
2768
|
standing: !0,
|
|
2769
2769
|
props: {
|
|
@@ -4049,22 +4049,22 @@ class Le {
|
|
|
4049
4049
|
if (this.isAvatarOnly = this.opt.avatarOnly, this.isAvatarOnly)
|
|
4050
4050
|
this.scene = this.opt.avatarOnlyScene, this.camera = this.opt.avatarOnlyCamera;
|
|
4051
4051
|
else {
|
|
4052
|
-
this.renderer = new
|
|
4053
|
-
new
|
|
4052
|
+
this.renderer = new f.WebGLRenderer({ antialias: !0, alpha: !0 }), this.renderer.setPixelRatio(this.opt.modelPixelRatio * window.devicePixelRatio), this.renderer.setSize(this.nodeAvatar.clientWidth, this.nodeAvatar.clientHeight), this.renderer.outputColorSpace = f.SRGBColorSpace, this.renderer.toneMapping = f.ACESFilmicToneMapping, this.renderer.shadowMap.enabled = !1, this.nodeAvatar.appendChild(this.renderer.domElement), this.camera = new f.PerspectiveCamera(10, this.nodeAvatar.clientWidth / this.nodeAvatar.clientHeight, 0.1, 2e3), this.scene = new f.Scene(), this.lightAmbient = new f.AmbientLight(
|
|
4053
|
+
new f.Color(this.opt.lightAmbientColor),
|
|
4054
4054
|
this.opt.lightAmbientIntensity
|
|
4055
|
-
), this.lightDirect = new
|
|
4056
|
-
new
|
|
4055
|
+
), this.lightDirect = new f.DirectionalLight(
|
|
4056
|
+
new f.Color(this.opt.lightDirectColor),
|
|
4057
4057
|
this.opt.lightDirectIntensity
|
|
4058
|
-
), this.lightSpot = new
|
|
4059
|
-
new
|
|
4058
|
+
), this.lightSpot = new f.SpotLight(
|
|
4059
|
+
new f.Color(this.opt.lightSpotColor),
|
|
4060
4060
|
this.opt.lightSpotIntensity,
|
|
4061
4061
|
0,
|
|
4062
4062
|
this.opt.lightSpotDispersion
|
|
4063
4063
|
), this.setLighting(this.opt);
|
|
4064
|
-
const r = new
|
|
4065
|
-
r.compileEquirectangularShader(), this.scene.environment = r.fromScene(new
|
|
4064
|
+
const r = new f.PMREMGenerator(this.renderer);
|
|
4065
|
+
r.compileEquirectangularShader(), this.scene.environment = r.fromScene(new Fe()).texture, this.resizeobserver = new ResizeObserver(this.onResize.bind(this)), this.resizeobserver.observe(this.nodeAvatar), this.controls = new Te(this.camera, this.renderer.domElement), this.controls.enableZoom = this.opt.cameraZoomEnable, this.controls.enableRotate = this.opt.cameraRotateEnable, this.controls.enablePan = this.opt.cameraPanEnable, this.controls.minDistance = 2, this.controls.maxDistance = 2e3, this.controls.autoRotateSpeed = 0, this.controls.autoRotate = !1, this.controls.update(), this.cameraClock = null;
|
|
4066
4066
|
}
|
|
4067
|
-
this.ikMesh = new
|
|
4067
|
+
this.ikMesh = new f.SkinnedMesh();
|
|
4068
4068
|
const s = {
|
|
4069
4069
|
LeftShoulder: null,
|
|
4070
4070
|
LeftArm: "LeftShoulder",
|
|
@@ -4078,16 +4078,16 @@ class Le {
|
|
|
4078
4078
|
RightHandMiddle1: "RightHand"
|
|
4079
4079
|
}, o = [];
|
|
4080
4080
|
Object.entries(s).forEach((r, h) => {
|
|
4081
|
-
const a = new
|
|
4081
|
+
const a = new f.Bone();
|
|
4082
4082
|
a.name = r[0], r[1] ? this.ikMesh.getObjectByName(r[1]).add(a) : this.ikMesh.add(a), o.push(a);
|
|
4083
|
-
}), this.ikMesh.bind(new
|
|
4083
|
+
}), this.ikMesh.bind(new f.Skeleton(o)), this.dynamicbones = new Ne(), this.isStreaming = !1, this.streamWorkletNode = null, this.streamAudioStartTime = null, this.streamWaitForAudioChunks = !0, this.streamLipsyncLang = null, this.streamLipsyncType = "visemes", this.streamLipsyncQueue = [];
|
|
4084
4084
|
}
|
|
4085
4085
|
/**
|
|
4086
4086
|
* Helper that re/creates the audio context and the other nodes.
|
|
4087
4087
|
* @param {number} sampleRate
|
|
4088
4088
|
*/
|
|
4089
4089
|
initAudioGraph(t = null) {
|
|
4090
|
-
if (this.audioCtx && this.audioCtx.state !== "closed" && this.audioCtx.close(), t ? this.audioCtx = new AudioContext({ sampleRate: t }) : this.audioCtx = new AudioContext(), this.audioSpeechSource = this.audioCtx.createBufferSource(), this.audioBackgroundSource = this.audioCtx.createBufferSource(), this.audioBackgroundGainNode = this.audioCtx.createGain(), this.audioSpeechGainNode = this.audioCtx.createGain(), this.audioStreamGainNode = this.audioCtx.createGain(), this.audioAnalyzerNode = this.audioCtx.createAnalyser(), this.audioAnalyzerNode.fftSize = 256, this.audioAnalyzerNode.smoothingTimeConstant = 0.1, this.audioAnalyzerNode.minDecibels = -70, this.audioAnalyzerNode.maxDecibels = -10, this.audioAnalyzer = new
|
|
4090
|
+
if (this.audioCtx && this.audioCtx.state !== "closed" && this.audioCtx.close(), t ? this.audioCtx = new AudioContext({ sampleRate: t }) : this.audioCtx = new AudioContext(), this.audioSpeechSource = this.audioCtx.createBufferSource(), this.audioBackgroundSource = this.audioCtx.createBufferSource(), this.audioBackgroundGainNode = this.audioCtx.createGain(), this.audioSpeechGainNode = this.audioCtx.createGain(), this.audioStreamGainNode = this.audioCtx.createGain(), this.audioAnalyzerNode = this.audioCtx.createAnalyser(), this.audioAnalyzerNode.fftSize = 256, this.audioAnalyzerNode.smoothingTimeConstant = 0.1, this.audioAnalyzerNode.minDecibels = -70, this.audioAnalyzerNode.maxDecibels = -10, this.audioAnalyzer = new Ue(this.audioCtx), this.audioReverbNode = this.audioCtx.createConvolver(), this.audioBackgroundGainNode.connect(this.audioReverbNode), this.audioAnalyzerNode.connect(this.audioSpeechGainNode), this.audioSpeechGainNode.connect(this.audioReverbNode), this.audioStreamGainNode.connect(this.audioReverbNode), this.audioReverbNode.connect(this.audioCtx.destination), this.setReverb(this.currentReverb || null), this.setMixerGain(
|
|
4091
4091
|
this.opt.mixerGainSpeech,
|
|
4092
4092
|
this.opt.mixerGainBackground
|
|
4093
4093
|
), this.workletLoaded = !1, this.streamWorkletNode) {
|
|
@@ -4170,7 +4170,7 @@ class Le {
|
|
|
4170
4170
|
for (let [i, n] of Object.entries(t)) {
|
|
4171
4171
|
const s = i.split(".");
|
|
4172
4172
|
let o = Array.isArray(n.x) ? this.gaussianRandom(...n.x) : n.x, r = Array.isArray(n.y) ? this.gaussianRandom(...n.y) : n.y, h = Array.isArray(n.z) ? this.gaussianRandom(...n.z) : n.z;
|
|
4173
|
-
s[1] === "position" || s[1] === "scale" ? e[i] = new
|
|
4173
|
+
s[1] === "position" || s[1] === "scale" ? e[i] = new f.Vector3(o, r, h) : s[1] === "rotation" ? (i = s[0] + ".quaternion", e[i] = new f.Quaternion().setFromEuler(new f.Euler(o, r, h, "XYZ")).normalize()) : s[1] === "quaternion" && (e[i] = new f.Quaternion(o, r, h, n.w).normalize());
|
|
4174
4174
|
}
|
|
4175
4175
|
return e;
|
|
4176
4176
|
}
|
|
@@ -4202,15 +4202,15 @@ class Le {
|
|
|
4202
4202
|
for (const [a, u] of Object.entries(i))
|
|
4203
4203
|
if (s.morphTargetDictionary.hasOwnProperty(a)) {
|
|
4204
4204
|
const l = s.morphTargetDictionary[a], c = o.morphAttributes.position[l], d = o.morphAttributes.normal?.[l];
|
|
4205
|
-
r || (r = new
|
|
4205
|
+
r || (r = new f.Float32BufferAttribute(c.count * 3, 3), d && (h = new f.Float32BufferAttribute(c.count * 3, 3)));
|
|
4206
4206
|
for (let g = 0; g < c.count; g++) {
|
|
4207
|
-
const
|
|
4208
|
-
r.setXYZ(g,
|
|
4207
|
+
const y = r.getX(g) + c.getX(g) * u, x = r.getY(g) + c.getY(g) * u, v = r.getZ(g) + c.getZ(g) * u;
|
|
4208
|
+
r.setXYZ(g, y, x, v);
|
|
4209
4209
|
}
|
|
4210
4210
|
if (d)
|
|
4211
4211
|
for (let g = 0; g < c.count; g++) {
|
|
4212
|
-
const
|
|
4213
|
-
h.setXYZ(g,
|
|
4212
|
+
const y = h.getX(g) + d.getX(g) * u, x = h.getY(g) + d.getY(g) * u, v = h.getZ(g) + d.getZ(g) * u;
|
|
4213
|
+
h.setXYZ(g, y, x, v);
|
|
4214
4214
|
}
|
|
4215
4215
|
}
|
|
4216
4216
|
if (r) {
|
|
@@ -4228,9 +4228,9 @@ class Le {
|
|
|
4228
4228
|
async showAvatar(t, e = null) {
|
|
4229
4229
|
if (!t || !t.hasOwnProperty("url"))
|
|
4230
4230
|
throw new Error("Invalid parameter. The avatar must have at least 'url' specified.");
|
|
4231
|
-
const i = new
|
|
4231
|
+
const i = new Me();
|
|
4232
4232
|
if (this.dracoEnabled) {
|
|
4233
|
-
const a = new
|
|
4233
|
+
const a = new Ee();
|
|
4234
4234
|
a.setDecoderPath(this.dracoDecoderPath), i.setDRACOLoader(a);
|
|
4235
4235
|
}
|
|
4236
4236
|
let n = await i.loadAsync(t.url, e);
|
|
@@ -4290,7 +4290,7 @@ class Le {
|
|
|
4290
4290
|
console.error("Dynamic bones setup failed: " + a);
|
|
4291
4291
|
}
|
|
4292
4292
|
this.objectLeftToeBase = this.armature.getObjectByName("LeftToeBase"), this.objectRightToeBase = this.armature.getObjectByName("RightToeBase"), this.objectLeftEye = this.armature.getObjectByName("LeftEye"), this.objectRightEye = this.armature.getObjectByName("RightEye"), this.objectLeftArm = this.armature.getObjectByName("LeftArm"), this.objectRightArm = this.armature.getObjectByName("RightArm"), this.objectHips = this.armature.getObjectByName("Hips"), this.objectHead = this.armature.getObjectByName("Head"), this.objectNeck = this.armature.getObjectByName("Neck");
|
|
4293
|
-
const h = new
|
|
4293
|
+
const h = new f.Vector3();
|
|
4294
4294
|
this.objectLeftEye.getWorldPosition(h), this.avatarHeight = h.y + 0.2, this.viewName || this.setView(this.opt.cameraView), this.setMood(this.avatar.avatarMood || this.moodName || this.opt.avatarMood), this.initializeFBXAnimationLoader(), this.bodyMovement && this.bodyMovement !== "idle" && this.applyBodyMovementAnimation(), this.start();
|
|
4295
4295
|
}
|
|
4296
4296
|
/**
|
|
@@ -4334,14 +4334,14 @@ class Le {
|
|
|
4334
4334
|
default:
|
|
4335
4335
|
l += 12, u = u * l;
|
|
4336
4336
|
}
|
|
4337
|
-
a = a * l, this.controlsEnd = new
|
|
4337
|
+
a = a * l, this.controlsEnd = new f.Vector3(a, u, 0), this.cameraEnd = new f.Vector3(a, u, l).applyEuler(new f.Euler(o, r, 0)), this.cameraClock === null && (this.controls.target.copy(this.controlsEnd), this.camera.position.copy(this.cameraEnd)), this.controlsStart = this.controls.target.clone(), this.cameraStart = this.camera.position.clone(), this.cameraClock = 0;
|
|
4338
4338
|
}
|
|
4339
4339
|
/**
|
|
4340
4340
|
* Change light colors and intensities.
|
|
4341
4341
|
* @param {Object} opt Options
|
|
4342
4342
|
*/
|
|
4343
4343
|
setLighting(t) {
|
|
4344
|
-
this.isAvatarOnly || (t = t || {}, t.hasOwnProperty("lightAmbientColor") && this.lightAmbient.color.set(new
|
|
4344
|
+
this.isAvatarOnly || (t = t || {}, t.hasOwnProperty("lightAmbientColor") && this.lightAmbient.color.set(new f.Color(t.lightAmbientColor)), t.hasOwnProperty("lightAmbientIntensity") && (this.lightAmbient.intensity = t.lightAmbientIntensity, this.lightAmbient.visible = t.lightAmbientIntensity !== 0), t.hasOwnProperty("lightDirectColor") && this.lightDirect.color.set(new f.Color(t.lightDirectColor)), t.hasOwnProperty("lightDirectIntensity") && (this.lightDirect.intensity = t.lightDirectIntensity, this.lightDirect.visible = t.lightDirectIntensity !== 0), t.hasOwnProperty("lightDirectPhi") && t.hasOwnProperty("lightDirectTheta") && this.lightDirect.position.setFromSphericalCoords(2, t.lightDirectPhi, t.lightDirectTheta), t.hasOwnProperty("lightSpotColor") && this.lightSpot.color.set(new f.Color(t.lightSpotColor)), t.hasOwnProperty("lightSpotIntensity") && (this.lightSpot.intensity = t.lightSpotIntensity, this.lightSpot.visible = t.lightSpotIntensity !== 0), t.hasOwnProperty("lightSpotPhi") && t.hasOwnProperty("lightSpotTheta") && (this.lightSpot.position.setFromSphericalCoords(2, t.lightSpotPhi, t.lightSpotTheta), this.lightSpot.position.add(new f.Vector3(0, 1.5, 0))), t.hasOwnProperty("lightSpotDispersion") && (this.lightSpot.angle = t.lightSpotDispersion));
|
|
4345
4345
|
}
|
|
4346
4346
|
/**
|
|
4347
4347
|
* Render scene.
|
|
@@ -4456,7 +4456,7 @@ class Le {
|
|
|
4456
4456
|
return Object.entries(t).forEach((n, s) => {
|
|
4457
4457
|
const o = n[0].split(".");
|
|
4458
4458
|
if (o[1] === "position" || o[1] === "rotation" || o[1] === "quaternion") {
|
|
4459
|
-
const r = o[1] === "quaternion" ? o[0] + ".rotation" : n[0], h = n[1].isQuaternion ? new
|
|
4459
|
+
const r = o[1] === "quaternion" ? o[0] + ".rotation" : n[0], h = n[1].isQuaternion ? new f.Euler().setFromQuaternion(n[1]) : n[1];
|
|
4460
4460
|
i += (s ? ", " : "") + "'" + r + "':{", i += "x:" + Math.round(h.x * e) / e, i += ", y:" + Math.round(h.y * e) / e, i += ", z:" + Math.round(h.z * e) / e, i += "}";
|
|
4461
4461
|
}
|
|
4462
4462
|
}), i += "}", i;
|
|
@@ -5094,9 +5094,9 @@ class Le {
|
|
|
5094
5094
|
g.newvalue = d[n];
|
|
5095
5095
|
else {
|
|
5096
5096
|
g.newvalue = d[n + 1];
|
|
5097
|
-
const
|
|
5097
|
+
const y = l.ts[n + 1] - l.ts[n];
|
|
5098
5098
|
let x = 1;
|
|
5099
|
-
|
|
5099
|
+
y > 1e-4 && (x = (this.animClock - l.ts[n]) / y), x < 1 && (g.easing && (x = g.easing(x)), g.newvalue = (1 - x) * d[n] + x * g.newvalue), g.ref && g.ref !== l.vs && g.ref.hasOwnProperty(c) && delete g.ref[c], g.ref = l.vs;
|
|
5100
5100
|
}
|
|
5101
5101
|
if (r)
|
|
5102
5102
|
switch (c) {
|
|
@@ -5144,7 +5144,7 @@ class Le {
|
|
|
5144
5144
|
{ link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
|
|
5145
5145
|
{ link: "LeftArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
|
|
5146
5146
|
]
|
|
5147
|
-
}, n.x ? new
|
|
5147
|
+
}, n.x ? new f.Vector3(n.x, n.y, n.z) : null, !0, n.d);
|
|
5148
5148
|
break;
|
|
5149
5149
|
case "handRight":
|
|
5150
5150
|
this.ikSolve({
|
|
@@ -5156,7 +5156,7 @@ class Le {
|
|
|
5156
5156
|
{ link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5, maxAngle: 0.2 },
|
|
5157
5157
|
{ link: "RightArm", minx: -1.5, maxx: 1.5, miny: 0, maxy: 0, minz: -1, maxz: 3 }
|
|
5158
5158
|
]
|
|
5159
|
-
}, n.x ? new
|
|
5159
|
+
}, n.x ? new f.Vector3(n.x, n.y, n.z) : null, !0, n.d);
|
|
5160
5160
|
break;
|
|
5161
5161
|
}
|
|
5162
5162
|
if ((h || a) && (T.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]), T.x = Math.max(-0.9, Math.min(0.9, 2 * T.x - 0.5)), T.y = Math.max(-0.9, Math.min(0.9, -2.5 * T.y)), h ? (Object.assign(this.mtAvatar.eyesLookDown, { system: T.x < 0 ? -T.x : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyesLookUp, { system: T.x < 0 ? 0 : T.x, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInLeft, { system: T.y < 0 ? -T.y : 0, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutLeft, { system: T.y < 0 ? 0 : T.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookInRight, { system: T.y < 0 ? 0 : T.y, needsUpdate: !0 }), Object.assign(this.mtAvatar.eyeLookOutRight, { system: T.y < 0 ? -T.y : 0, needsUpdate: !0 }), a && (i = -this.mtAvatar.bodyRotateY.value, n = this.gaussianRandom(-0.2, 0.2), this.animQueue.push(this.animFactory({
|
|
@@ -5180,12 +5180,12 @@ class Le {
|
|
|
5180
5180
|
eyeLookOutRight: [null, 0],
|
|
5181
5181
|
eyeContact: [0]
|
|
5182
5182
|
}
|
|
5183
|
-
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (i = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], n = this.mtAvatar[i], n.needsUpdate || Object.assign(n, { base: (this.mood.baseline[i] || 0) + (1 + r / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? r > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = r) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), i = this.volumeHeadTarget - this.volumeHeadCurrent, n = Math.abs(i), n > 1e-4 && (o = n * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / n) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(i) * Math.min(n, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (N.setFromAxisAngle(
|
|
5183
|
+
})))), e > 2 * this.animFrameDur && (e = 2 * this.animFrameDur), (this.viewName !== "full" || this.isAvatarOnly) && (i = this.mtRandomized[Math.floor(Math.random() * this.mtRandomized.length)], n = this.mtAvatar[i], n.needsUpdate || Object.assign(n, { base: (this.mood.baseline[i] || 0) + (1 + r / 255) * Math.random() / 5, needsUpdate: !0 })), this.updatePoseBase(this.animClock), this.mixer && this.mixer.update(e / 1e3 * this.mixer.timeScale), this.updatePoseDelta(), (this.isSpeaking || this.isListening) && h ? r > this.volumeMax ? (this.volumeHeadBase = 0.05, Math.random() > 0.6 && (this.volumeHeadTarget = -0.05 - Math.random() / 15), this.volumeMax = r) : (this.volumeMax *= 0.92, this.volumeHeadTarget = this.volumeHeadBase - 0.9 * (this.volumeHeadBase - this.volumeHeadTarget)) : (this.volumeHeadTarget = 0, this.volumeMax = 0), i = this.volumeHeadTarget - this.volumeHeadCurrent, n = Math.abs(i), n > 1e-4 && (o = n * (this.volumeHeadEasing(Math.min(1, this.volumeHeadVelocity * e / 1e3 / n) / 2 + 0.5) - 0.5), this.volumeHeadCurrent += Math.sign(i) * Math.min(n, o)), Math.abs(this.volumeHeadCurrent) > 1e-4 && (N.setFromAxisAngle(Je, this.volumeHeadCurrent), this.objectNeck.quaternion.multiply(N)), Ie.setFromObject(this.armature), this.objectLeftToeBase.getWorldPosition(ie), ie.sub(this.armature.position), this.objectRightToeBase.getWorldPosition(oe), oe.sub(this.armature.position), this.objectHips.position.y -= Ie.min.y / 2, this.objectHips.position.x -= (ie.x + oe.x) / 4, this.objectHips.position.z -= (ie.z + oe.z) / 2, this.dynamicbones.update(e), this.fbxAnimationLoader && this.fbxAnimationLoader.update(), this.opt.update && this.opt.update(e), this.updateMorphTargets(e), this.isAvatarOnly)
|
|
5184
5184
|
this.stats && this.stats.end();
|
|
5185
5185
|
else {
|
|
5186
5186
|
if (this.cameraClock !== null && this.cameraClock < 1e3) {
|
|
5187
5187
|
this.cameraClock += e, this.cameraClock > 1e3 && (this.cameraClock = 1e3);
|
|
5188
|
-
let l = new
|
|
5188
|
+
let l = new f.Spherical().setFromVector3(this.cameraStart), c = new f.Spherical().setFromVector3(this.cameraEnd);
|
|
5189
5189
|
l.phi += this.easing(this.cameraClock / 1e3) * (c.phi - l.phi), l.theta += this.easing(this.cameraClock / 1e3) * (c.theta - l.theta), l.radius += this.easing(this.cameraClock / 1e3) * (c.radius - l.radius), l.makeSafe(), this.camera.position.setFromSpherical(l), this.controlsStart.x !== this.controlsEnd.x ? this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd, this.easing(this.cameraClock / 1e3))) : (l.setFromVector3(this.controlsStart), c.setFromVector3(this.controlsEnd), l.phi += this.easing(this.cameraClock / 1e3) * (c.phi - l.phi), l.theta += this.easing(this.cameraClock / 1e3) * (c.theta - l.theta), l.radius += this.easing(this.cameraClock / 1e3) * (c.radius - l.radius), l.makeSafe(), this.controls.target.setFromSpherical(l)), this.controls.update();
|
|
5190
5190
|
}
|
|
5191
5191
|
this.controls.autoRotate && this.controls.update(), this.stats && this.stats.end(), this.render();
|
|
@@ -5249,12 +5249,12 @@ class Le {
|
|
|
5249
5249
|
e = e || {};
|
|
5250
5250
|
const s = /[!\.\?\n\p{Extended_Pictographic}]/ug, o = /[ ]/ug, r = /[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug, h = /[\p{Extended_Pictographic}]/ug, a = e.lipsyncLang || this.avatar.lipsyncLang || this.opt.lipsyncLang;
|
|
5251
5251
|
let u = "", l = "", c = 0, d = [], g = [];
|
|
5252
|
-
const
|
|
5253
|
-
for (let x = 0; x <
|
|
5254
|
-
const
|
|
5255
|
-
let p =
|
|
5256
|
-
const E =
|
|
5257
|
-
if (p && !
|
|
5252
|
+
const y = Array.from(this.segmenter.segment(t), (x) => x.segment);
|
|
5253
|
+
for (let x = 0; x < y.length; x++) {
|
|
5254
|
+
const v = x === y.length - 1, H = y[x].match(r);
|
|
5255
|
+
let p = y[x].match(s);
|
|
5256
|
+
const E = y[x].match(h), z = y[x].match(o);
|
|
5257
|
+
if (p && !v && !E && y[x + 1].match(s) && (p = !1), i && (u += y[x]), H && (!n || n.every((I) => x < I[0] || x > I[1])) && (l += y[x]), (z || p || v) && (l.length && (l = this.lipsyncPreProcessText(l, a), l.length && d.push({
|
|
5258
5258
|
mark: c,
|
|
5259
5259
|
word: l
|
|
5260
5260
|
})), u.length && (g.push({
|
|
@@ -5265,31 +5265,31 @@ class Le {
|
|
|
5265
5265
|
subtitles: [u]
|
|
5266
5266
|
}
|
|
5267
5267
|
}), u = ""), l.length)) {
|
|
5268
|
-
const
|
|
5269
|
-
if (
|
|
5270
|
-
const
|
|
5271
|
-
for (let P = 0; P <
|
|
5268
|
+
const I = this.lipsyncWordsToVisemes(l, a);
|
|
5269
|
+
if (I && I.visemes && I.visemes.length) {
|
|
5270
|
+
const D = I.times[I.visemes.length - 1] + I.durations[I.visemes.length - 1];
|
|
5271
|
+
for (let P = 0; P < I.visemes.length; P++)
|
|
5272
5272
|
g.push({
|
|
5273
5273
|
mark: c,
|
|
5274
5274
|
template: { name: "viseme" },
|
|
5275
|
-
ts: [(
|
|
5275
|
+
ts: [(I.times[P] - 0.6) / D, (I.times[P] + 0.5) / D, (I.times[P] + I.durations[P] + 0.5) / D],
|
|
5276
5276
|
vs: {
|
|
5277
|
-
["viseme_" +
|
|
5277
|
+
["viseme_" + I.visemes[P]]: [null, I.visemes[P] === "PP" || I.visemes[P] === "FF" ? 0.9 : 0.6, 0]
|
|
5278
5278
|
}
|
|
5279
5279
|
});
|
|
5280
5280
|
}
|
|
5281
5281
|
l = "", c++;
|
|
5282
5282
|
}
|
|
5283
|
-
if (p ||
|
|
5284
|
-
if (d.length ||
|
|
5285
|
-
const
|
|
5283
|
+
if (p || v) {
|
|
5284
|
+
if (d.length || v && g.length) {
|
|
5285
|
+
const I = {
|
|
5286
5286
|
anim: g
|
|
5287
5287
|
};
|
|
5288
|
-
i && (
|
|
5288
|
+
i && (I.onSubtitles = i), d.length && !e.avatarMute && (I.text = d, e.avatarMood && (I.mood = e.avatarMood), e.ttsLang && (I.lang = e.ttsLang), e.ttsVoice && (I.voice = e.ttsVoice), e.ttsRate && (I.rate = e.ttsRate), e.ttsVoice && (I.pitch = e.ttsPitch), e.ttsVolume && (I.volume = e.ttsVolume)), this.speechQueue.push(I), d = [], l = "", c = 0, g = [];
|
|
5289
5289
|
}
|
|
5290
5290
|
if (E) {
|
|
5291
|
-
let
|
|
5292
|
-
|
|
5291
|
+
let I = this.animEmojis[y[x]];
|
|
5292
|
+
I && I.link && (I = this.animEmojis[I.link]), I && this.speechQueue.push({ emoji: I });
|
|
5293
5293
|
}
|
|
5294
5294
|
this.speechQueue.push({ break: 100 });
|
|
5295
5295
|
}
|
|
@@ -5382,15 +5382,15 @@ class Le {
|
|
|
5382
5382
|
const l = this.lipsyncPreProcessText(h, n), c = this.lipsyncWordsToVisemes(l, n);
|
|
5383
5383
|
if (c && c.visemes && c.visemes.length) {
|
|
5384
5384
|
const d = c.times[c.visemes.length - 1] + c.durations[c.visemes.length - 1], g = Math.min(u, Math.max(0, u - c.visemes.length * 150));
|
|
5385
|
-
let
|
|
5385
|
+
let y = 0.6 + this.convertRange(g, [0, u], [0, 0.4]);
|
|
5386
5386
|
if (u = Math.min(u, c.visemes.length * 200), d > 0)
|
|
5387
5387
|
for (let x = 0; x < c.visemes.length; x++) {
|
|
5388
|
-
const
|
|
5388
|
+
const v = a + c.times[x] / d * u, H = c.durations[x] / d * u;
|
|
5389
5389
|
o.push({
|
|
5390
5390
|
template: { name: "viseme" },
|
|
5391
|
-
ts: [
|
|
5391
|
+
ts: [v - Math.min(60, 2 * H / 3), v + Math.min(25, H / 2), v + H + Math.min(60, H / 2)],
|
|
5392
5392
|
vs: {
|
|
5393
|
-
["viseme_" + c.visemes[x]]: [null, c.visemes[x] === "PP" || c.visemes[x] === "FF" ? 0.9 :
|
|
5393
|
+
["viseme_" + c.visemes[x]]: [null, c.visemes[x] === "PP" || c.visemes[x] === "FF" ? 0.9 : y, 0]
|
|
5394
5394
|
}
|
|
5395
5395
|
});
|
|
5396
5396
|
}
|
|
@@ -5473,30 +5473,30 @@ class Le {
|
|
|
5473
5473
|
const p = u.find((E) => E.name.includes(l) || E.lang === o);
|
|
5474
5474
|
p && (s.voice = p);
|
|
5475
5475
|
}
|
|
5476
|
-
const c = n.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en",
|
|
5476
|
+
const c = n.length * 100 / s.rate, d = this.audioCtx.createBuffer(1, this.audioCtx.sampleRate * (c / 1e3), this.audioCtx.sampleRate), g = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en", y = this.lipsyncPreProcessText(n, g), x = this.lipsyncWordsToVisemes(y, g);
|
|
5477
5477
|
console.log("Browser TTS Lip-sync Debug:", {
|
|
5478
5478
|
text: n,
|
|
5479
5479
|
lipsyncLang: g,
|
|
5480
|
-
processedText:
|
|
5480
|
+
processedText: y,
|
|
5481
5481
|
lipsyncData: x,
|
|
5482
5482
|
hasVisemes: x && x.visemes && x.visemes.length > 0,
|
|
5483
5483
|
estimatedDuration: c
|
|
5484
5484
|
});
|
|
5485
|
-
const
|
|
5485
|
+
const v = [];
|
|
5486
5486
|
if (x && x.visemes && x.visemes.length > 0) {
|
|
5487
5487
|
const p = x.times[x.visemes.length - 1] + x.durations[x.visemes.length - 1];
|
|
5488
5488
|
for (let E = 0; E < x.visemes.length; E++) {
|
|
5489
|
-
const z = x.visemes[E],
|
|
5490
|
-
|
|
5489
|
+
const z = x.visemes[E], I = x.times[E] / p, D = x.durations[E] / p, P = I * c, J = D * c;
|
|
5490
|
+
v.push({
|
|
5491
5491
|
template: { name: "viseme" },
|
|
5492
|
-
ts: [P - Math.min(60, 2 *
|
|
5492
|
+
ts: [P - Math.min(60, 2 * J / 3), P + Math.min(25, J / 2), P + J + Math.min(60, J / 2)],
|
|
5493
5493
|
vs: {
|
|
5494
5494
|
["viseme_" + z]: [null, z === "PP" || z === "FF" ? 0.9 : 0.6, 0]
|
|
5495
5495
|
}
|
|
5496
5496
|
});
|
|
5497
5497
|
}
|
|
5498
5498
|
}
|
|
5499
|
-
const H = [...t.anim, ...
|
|
5499
|
+
const H = [...t.anim, ...v];
|
|
5500
5500
|
this.audioPlaylist.push({ anim: H, audio: d }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio(), s.onend = () => {
|
|
5501
5501
|
e();
|
|
5502
5502
|
}, s.onerror = (p) => {
|
|
@@ -5546,10 +5546,10 @@ class Le {
|
|
|
5546
5546
|
hasVisemes: d && d.visemes && d.visemes.length > 0
|
|
5547
5547
|
}), d && d.visemes && d.visemes.length > 0)
|
|
5548
5548
|
a = {
|
|
5549
|
-
visemes: d.visemes.map((g,
|
|
5549
|
+
visemes: d.visemes.map((g, y) => ({
|
|
5550
5550
|
viseme: g,
|
|
5551
|
-
startTime:
|
|
5552
|
-
endTime: (
|
|
5551
|
+
startTime: y * r.duration / d.visemes.length,
|
|
5552
|
+
endTime: (y + 1) * r.duration / d.visemes.length,
|
|
5553
5553
|
duration: r.duration / d.visemes.length,
|
|
5554
5554
|
intensity: 0.7
|
|
5555
5555
|
})),
|
|
@@ -5562,14 +5562,14 @@ class Le {
|
|
|
5562
5562
|
} catch (c) {
|
|
5563
5563
|
console.error("Text-based lip-sync failed, using fallback:", c);
|
|
5564
5564
|
const d = e.toLowerCase().split(/\s+/), g = [];
|
|
5565
|
-
for (const
|
|
5566
|
-
for (const x of
|
|
5567
|
-
let
|
|
5568
|
-
"aeiou".includes(x) ?
|
|
5565
|
+
for (const y of d)
|
|
5566
|
+
for (const x of y) {
|
|
5567
|
+
let v = "aa";
|
|
5568
|
+
"aeiou".includes(x) ? v = "aa" : "bp".includes(x) ? v = "PP" : "fv".includes(x) ? v = "FF" : "st".includes(x) ? v = "SS" : "dln".includes(x) ? v = "DD" : "kg".includes(x) ? v = "kk" : "rw".includes(x) && (v = "RR"), g.push(v);
|
|
5569
5569
|
}
|
|
5570
5570
|
a = {
|
|
5571
|
-
visemes: g.map((
|
|
5572
|
-
viseme:
|
|
5571
|
+
visemes: g.map((y, x) => ({
|
|
5572
|
+
viseme: y,
|
|
5573
5573
|
startTime: x * r.duration / g.length,
|
|
5574
5574
|
endTime: (x + 1) * r.duration / g.length,
|
|
5575
5575
|
duration: r.duration / g.length,
|
|
@@ -5596,10 +5596,10 @@ class Le {
|
|
|
5596
5596
|
if (a.visemes && a.visemes.length > 0) {
|
|
5597
5597
|
console.log("ElevenLabs: Generating lip-sync animation from", a.visemes.length, "visemes");
|
|
5598
5598
|
for (let c = 0; c < a.visemes.length; c++) {
|
|
5599
|
-
const d = a.visemes[c], g = d.startTime * 1e3,
|
|
5599
|
+
const d = a.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3, x = d.intensity;
|
|
5600
5600
|
u.push({
|
|
5601
5601
|
template: { name: "viseme" },
|
|
5602
|
-
ts: [g - Math.min(60, 2 *
|
|
5602
|
+
ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
|
|
5603
5603
|
vs: {
|
|
5604
5604
|
["viseme_" + d.viseme]: [null, x, 0]
|
|
5605
5605
|
}
|
|
@@ -5611,6 +5611,104 @@ class Le {
|
|
|
5611
5611
|
const l = [...t.anim, ...u];
|
|
5612
5612
|
console.log("ElevenLabs: Combined animation frames:", l.length, "(original:", t.anim.length, "+ lipsync:", u.length, ")"), this.audioPlaylist.push({ anim: l, audio: r }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5613
5613
|
}
|
|
5614
|
+
/**
|
|
5615
|
+
* Synthesize speech using Deepgram Aura-2 TTS
|
|
5616
|
+
* @param {Object} line Speech line object
|
|
5617
|
+
*/
|
|
5618
|
+
async synthesizeWithDeepgramTTS(t) {
|
|
5619
|
+
const e = t.text.map((c) => c.word).join(" "), i = t.voice || this.avatar.ttsVoice || this.opt.ttsVoice || "aura-2-thalia-en", n = `${this.opt.ttsEndpoint}?model=${i}`, s = await fetch(n, {
|
|
5620
|
+
method: "POST",
|
|
5621
|
+
headers: {
|
|
5622
|
+
Authorization: `Token ${this.opt.ttsApikey}`,
|
|
5623
|
+
"Content-Type": "text/plain",
|
|
5624
|
+
Accept: "audio/mpeg"
|
|
5625
|
+
},
|
|
5626
|
+
body: e
|
|
5627
|
+
});
|
|
5628
|
+
if (!s.ok)
|
|
5629
|
+
throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);
|
|
5630
|
+
const o = await s.arrayBuffer(), r = await this.audioCtx.decodeAudioData(o);
|
|
5631
|
+
console.log("Using text-based lip-sync for Deepgram...");
|
|
5632
|
+
const h = this.avatar.lipsyncLang || this.opt.lipsyncLang || "en";
|
|
5633
|
+
let a;
|
|
5634
|
+
try {
|
|
5635
|
+
console.log("Lip-sync modules available:", {
|
|
5636
|
+
hasLipsync: !!this.lipsync,
|
|
5637
|
+
lipsyncKeys: this.lipsync ? Object.keys(this.lipsync) : [],
|
|
5638
|
+
lipsyncLang: h
|
|
5639
|
+
});
|
|
5640
|
+
const c = this.lipsyncPreProcessText(e, h), d = this.lipsyncWordsToVisemes(c, h);
|
|
5641
|
+
if (console.log("Lip-sync data:", {
|
|
5642
|
+
processedText: c,
|
|
5643
|
+
lipsyncData: d,
|
|
5644
|
+
hasVisemes: d && d.visemes && d.visemes.length > 0
|
|
5645
|
+
}), d && d.visemes && d.visemes.length > 0)
|
|
5646
|
+
a = {
|
|
5647
|
+
visemes: d.visemes.map((g, y) => ({
|
|
5648
|
+
viseme: g,
|
|
5649
|
+
startTime: y * r.duration / d.visemes.length,
|
|
5650
|
+
endTime: (y + 1) * r.duration / d.visemes.length,
|
|
5651
|
+
duration: r.duration / d.visemes.length,
|
|
5652
|
+
intensity: 0.7
|
|
5653
|
+
})),
|
|
5654
|
+
words: [],
|
|
5655
|
+
duration: r.duration,
|
|
5656
|
+
features: { onsets: [], boundaries: [] }
|
|
5657
|
+
};
|
|
5658
|
+
else
|
|
5659
|
+
throw new Error("No visemes generated from text");
|
|
5660
|
+
} catch (c) {
|
|
5661
|
+
console.error("Text-based lip-sync failed, using fallback:", c);
|
|
5662
|
+
const d = e.toLowerCase().split(/\s+/), g = [];
|
|
5663
|
+
for (const y of d)
|
|
5664
|
+
for (const x of y) {
|
|
5665
|
+
let v = "aa";
|
|
5666
|
+
"aeiou".includes(x) ? v = "aa" : "bp".includes(x) ? v = "PP" : "fv".includes(x) ? v = "FF" : "st".includes(x) ? v = "SS" : "dln".includes(x) ? v = "DD" : "kg".includes(x) ? v = "kk" : "rw".includes(x) && (v = "RR"), g.push(v);
|
|
5667
|
+
}
|
|
5668
|
+
a = {
|
|
5669
|
+
visemes: g.map((y, x) => ({
|
|
5670
|
+
viseme: y,
|
|
5671
|
+
startTime: x * r.duration / g.length,
|
|
5672
|
+
endTime: (x + 1) * r.duration / g.length,
|
|
5673
|
+
duration: r.duration / g.length,
|
|
5674
|
+
intensity: 0.6
|
|
5675
|
+
})),
|
|
5676
|
+
words: [],
|
|
5677
|
+
duration: r.duration,
|
|
5678
|
+
features: { onsets: [], boundaries: [] }
|
|
5679
|
+
};
|
|
5680
|
+
}
|
|
5681
|
+
console.log("Deepgram TTS Audio Analysis:", {
|
|
5682
|
+
text: e,
|
|
5683
|
+
audioDuration: r.duration,
|
|
5684
|
+
visemeCount: a.visemes ? a.visemes.length : 0,
|
|
5685
|
+
wordCount: a.words ? a.words.length : 0,
|
|
5686
|
+
features: {
|
|
5687
|
+
onsets: a.features && a.features.onsets ? a.features.onsets.length : 0,
|
|
5688
|
+
boundaries: a.features && a.features.phonemeBoundaries ? a.features.phonemeBoundaries.length : 0
|
|
5689
|
+
},
|
|
5690
|
+
visemes: a.visemes ? a.visemes.slice(0, 3) : []
|
|
5691
|
+
// Show first 3 visemes for debugging
|
|
5692
|
+
});
|
|
5693
|
+
const u = [];
|
|
5694
|
+
if (a.visemes && a.visemes.length > 0) {
|
|
5695
|
+
console.log("Deepgram: Generating lip-sync animation from", a.visemes.length, "visemes");
|
|
5696
|
+
for (let c = 0; c < a.visemes.length; c++) {
|
|
5697
|
+
const d = a.visemes[c], g = d.startTime * 1e3, y = d.duration * 1e3, x = d.intensity;
|
|
5698
|
+
u.push({
|
|
5699
|
+
template: { name: "viseme" },
|
|
5700
|
+
ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
|
|
5701
|
+
vs: {
|
|
5702
|
+
["viseme_" + d.viseme]: [null, x, 0]
|
|
5703
|
+
}
|
|
5704
|
+
});
|
|
5705
|
+
}
|
|
5706
|
+
console.log("Deepgram: Generated", u.length, "lip-sync animation frames");
|
|
5707
|
+
} else
|
|
5708
|
+
console.warn("Deepgram: No visemes available for lip-sync animation");
|
|
5709
|
+
const l = [...t.anim, ...u];
|
|
5710
|
+
console.log("Deepgram: Combined animation frames:", l.length, "(original:", t.anim.length, "+ lipsync:", u.length, ")"), this.audioPlaylist.push({ anim: l, audio: r }), this.onSubtitles = t.onSubtitles || null, this.resetLips(), t.mood && this.setMood(t.mood), this.playAudio();
|
|
5711
|
+
}
|
|
5614
5712
|
/**
|
|
5615
5713
|
* Synthesize speech using Azure TTS
|
|
5616
5714
|
* @param {Object} line Speech line object
|
|
@@ -5648,12 +5746,12 @@ class Le {
|
|
|
5648
5746
|
});
|
|
5649
5747
|
const a = [];
|
|
5650
5748
|
for (let l = 0; l < h.visemes.length; l++) {
|
|
5651
|
-
const c = h.visemes[l], d = c.startTime * 1e3, g = c.duration * 1e3,
|
|
5749
|
+
const c = h.visemes[l], d = c.startTime * 1e3, g = c.duration * 1e3, y = c.intensity;
|
|
5652
5750
|
a.push({
|
|
5653
5751
|
template: { name: "viseme" },
|
|
5654
5752
|
ts: [d - Math.min(60, 2 * g / 3), d + Math.min(25, g / 2), d + g + Math.min(60, g / 2)],
|
|
5655
5753
|
vs: {
|
|
5656
|
-
["viseme_" + c.viseme]: [null,
|
|
5754
|
+
["viseme_" + c.viseme]: [null, y, 0]
|
|
5657
5755
|
}
|
|
5658
5756
|
});
|
|
5659
5757
|
}
|
|
@@ -5742,7 +5840,7 @@ class Le {
|
|
|
5742
5840
|
else if (e.text) {
|
|
5743
5841
|
this.lookAtCamera(500);
|
|
5744
5842
|
try {
|
|
5745
|
-
!this.opt.ttsEndpoint || this.opt.ttsEndpoint === "" ? await this.synthesizeWithBrowserTTS(e) : this.opt.ttsService === "elevenlabs" ? await this.synthesizeWithElevenLabsTTS(e) : this.opt.ttsService === "azure" ? await this.synthesizeWithAzureTTS(e) : await this.synthesizeWithExternalTTS(e);
|
|
5843
|
+
!this.opt.ttsEndpoint || this.opt.ttsEndpoint === "" ? await this.synthesizeWithBrowserTTS(e) : this.opt.ttsService === "elevenlabs" ? await this.synthesizeWithElevenLabsTTS(e) : this.opt.ttsService === "deepgram" ? await this.synthesizeWithDeepgramTTS(e) : this.opt.ttsService === "azure" ? await this.synthesizeWithAzureTTS(e) : await this.synthesizeWithExternalTTS(e);
|
|
5746
5844
|
} catch (i) {
|
|
5747
5845
|
console.error("Error:", i), this.startSpeaking(!0);
|
|
5748
5846
|
}
|
|
@@ -5797,7 +5895,7 @@ class Le {
|
|
|
5797
5895
|
}
|
|
5798
5896
|
if (!this.workletLoaded)
|
|
5799
5897
|
try {
|
|
5800
|
-
const r = this.audioCtx.audioWorklet.addModule(
|
|
5898
|
+
const r = this.audioCtx.audioWorklet.addModule(Ke.href), h = new Promise(
|
|
5801
5899
|
(a, u) => setTimeout(() => u(new Error("Worklet loading timed out")), 5e3)
|
|
5802
5900
|
);
|
|
5803
5901
|
await Promise.race([r, h]), this.workletLoaded = !0;
|
|
@@ -5939,10 +6037,10 @@ class Le {
|
|
|
5939
6037
|
let c = 0.6 + this.convertRange(l, [0, o], [0, 0.4]);
|
|
5940
6038
|
if (o = Math.min(o, a.visemes.length * 200), u > 0)
|
|
5941
6039
|
for (let d = 0; d < a.visemes.length; d++) {
|
|
5942
|
-
const g = e + s + a.times[d] / u * o,
|
|
6040
|
+
const g = e + s + a.times[d] / u * o, y = a.durations[d] / u * o;
|
|
5943
6041
|
this.animQueue.push({
|
|
5944
6042
|
template: { name: "viseme" },
|
|
5945
|
-
ts: [g - Math.min(60, 2 *
|
|
6043
|
+
ts: [g - Math.min(60, 2 * y / 3), g + Math.min(25, y / 2), g + y + Math.min(60, y / 2)],
|
|
5946
6044
|
vs: {
|
|
5947
6045
|
["viseme_" + a.visemes[d]]: [null, a.visemes[d] === "PP" || a.visemes[d] === "FF" ? 0.9 : c, 0]
|
|
5948
6046
|
}
|
|
@@ -6035,7 +6133,7 @@ class Le {
|
|
|
6035
6133
|
*/
|
|
6036
6134
|
lookAtCamera(t) {
|
|
6037
6135
|
let e;
|
|
6038
|
-
if (this.speakTo && (e = new
|
|
6136
|
+
if (this.speakTo && (e = new f.Vector3(), this.speakTo.objectLeftEye?.isObject3D ? (this.speakTo.armature.objectHead, this.speakTo.objectLeftEye.updateMatrixWorld(!0), this.speakTo.objectRightEye.updateMatrixWorld(!0), ie.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld), oe.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld), e.addVectors(ie, oe).divideScalar(2)) : this.speakTo.isObject3D ? this.speakTo.getWorldPosition(e) : this.speakTo.isVector3 ? e.set(this.speakTo) : this.speakTo.x && this.speakTo.y && this.speakTo.z && e.set(this.speakTo.x, this.speakTo.y, this.speakTo.z)), !e) {
|
|
6039
6137
|
if (this.avatar.hasOwnProperty("avatarIgnoreCamera")) {
|
|
6040
6138
|
if (this.avatar.avatarIgnoreCamera) {
|
|
6041
6139
|
this.lookAhead(t);
|
|
@@ -6049,14 +6147,14 @@ class Le {
|
|
|
6049
6147
|
return;
|
|
6050
6148
|
}
|
|
6051
6149
|
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0), ie.setFromMatrixPosition(this.objectLeftEye.matrixWorld), oe.setFromMatrixPosition(this.objectRightEye.matrixWorld), ie.add(oe).divideScalar(2), N.copy(this.armature.quaternion), N.multiply(this.poseTarget.props["Hips.quaternion"]), N.multiply(this.poseTarget.props["Spine.quaternion"]), N.multiply(this.poseTarget.props["Spine1.quaternion"]), N.multiply(this.poseTarget.props["Spine2.quaternion"]), N.multiply(this.poseTarget.props["Neck.quaternion"]), N.multiply(this.poseTarget.props["Head.quaternion"]);
|
|
6052
|
-
const i = new
|
|
6150
|
+
const i = new f.Vector3().subVectors(e, ie).normalize(), n = Math.atan2(i.x, i.z), s = Math.asin(-i.y);
|
|
6053
6151
|
T.set(s, n, 0, "YXZ");
|
|
6054
|
-
const r = new
|
|
6152
|
+
const r = new f.Quaternion().setFromEuler(T), h = new f.Quaternion().copy(r).multiply(N.clone().invert());
|
|
6055
6153
|
T.setFromQuaternion(h, "YXZ");
|
|
6056
6154
|
let a = T.x / (40 / 24) + 0.2, u = T.y / (9 / 4), l = Math.min(0.6, Math.max(-0.3, a)), c = Math.min(0.8, Math.max(-0.8, u)), d = (Math.random() - 0.5) / 4, g = (Math.random() - 0.5) / 4;
|
|
6057
6155
|
if (t) {
|
|
6058
|
-
let
|
|
6059
|
-
|
|
6156
|
+
let y = this.animQueue.findIndex((v) => v.template.name === "lookat");
|
|
6157
|
+
y !== -1 && this.animQueue.splice(y, 1);
|
|
6060
6158
|
const x = {
|
|
6061
6159
|
name: "lookat",
|
|
6062
6160
|
dt: [750, t],
|
|
@@ -6085,22 +6183,22 @@ class Le {
|
|
|
6085
6183
|
if (!this.camera) return;
|
|
6086
6184
|
const n = this.nodeAvatar.getBoundingClientRect();
|
|
6087
6185
|
this.objectLeftEye.updateMatrixWorld(!0), this.objectRightEye.updateMatrixWorld(!0);
|
|
6088
|
-
const s = new
|
|
6186
|
+
const s = new f.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld), o = new f.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld), r = new f.Vector3().addVectors(s, o).divideScalar(2);
|
|
6089
6187
|
r.project(this.camera);
|
|
6090
6188
|
let h = (r.x + 1) / 2 * n.width + n.left, a = -(r.y - 1) / 2 * n.height + n.top;
|
|
6091
6189
|
t === null && (t = h), e === null && (e = a), N.copy(this.armature.quaternion), N.multiply(this.poseTarget.props["Hips.quaternion"]), N.multiply(this.poseTarget.props["Spine.quaternion"]), N.multiply(this.poseTarget.props["Spine1.quaternion"]), N.multiply(this.poseTarget.props["Spine2.quaternion"]), N.multiply(this.poseTarget.props["Neck.quaternion"]), N.multiply(this.poseTarget.props["Head.quaternion"]), T.setFromQuaternion(N);
|
|
6092
|
-
let u = T.x / (40 / 24), l = T.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - h, h),
|
|
6093
|
-
x = Math.min(0.6, Math.max(-0.3, x)),
|
|
6190
|
+
let u = T.x / (40 / 24), l = T.y / (9 / 4), c = Math.min(0.4, Math.max(-0.4, this.camera.rotation.x)), d = Math.min(0.4, Math.max(-0.4, this.camera.rotation.y)), g = Math.max(window.innerWidth - h, h), y = Math.max(window.innerHeight - a, a), x = this.convertRange(e, [a - y, a + y], [-0.3, 0.6]) - u + c, v = this.convertRange(t, [h - g, h + g], [-0.8, 0.8]) - l + d;
|
|
6191
|
+
x = Math.min(0.6, Math.max(-0.3, x)), v = Math.min(0.8, Math.max(-0.8, v));
|
|
6094
6192
|
let H = (Math.random() - 0.5) / 4, p = (Math.random() - 0.5) / 4;
|
|
6095
6193
|
if (i) {
|
|
6096
|
-
let E = this.animQueue.findIndex((
|
|
6194
|
+
let E = this.animQueue.findIndex((I) => I.template.name === "lookat");
|
|
6097
6195
|
E !== -1 && this.animQueue.splice(E, 1);
|
|
6098
6196
|
const z = {
|
|
6099
6197
|
name: "lookat",
|
|
6100
6198
|
dt: [750, i],
|
|
6101
6199
|
vs: {
|
|
6102
6200
|
bodyRotateX: [x + H],
|
|
6103
|
-
bodyRotateY: [
|
|
6201
|
+
bodyRotateY: [v + p],
|
|
6104
6202
|
eyesRotateX: [-3 * H + 0.1],
|
|
6105
6203
|
eyesRotateY: [-5 * p],
|
|
6106
6204
|
browInnerUp: [[0, 0.7]],
|
|
@@ -6121,14 +6219,14 @@ class Le {
|
|
|
6121
6219
|
*/
|
|
6122
6220
|
touchAt(t, e) {
|
|
6123
6221
|
if (!this.camera) return;
|
|
6124
|
-
const i = this.nodeAvatar.getBoundingClientRect(), n = new
|
|
6222
|
+
const i = this.nodeAvatar.getBoundingClientRect(), n = new f.Vector2(
|
|
6125
6223
|
(t - i.left) / i.width * 2 - 1,
|
|
6126
6224
|
-((e - i.top) / i.height) * 2 + 1
|
|
6127
|
-
), s = new
|
|
6225
|
+
), s = new f.Raycaster();
|
|
6128
6226
|
s.setFromCamera(n, this.camera);
|
|
6129
6227
|
const o = s.intersectObject(this.armature);
|
|
6130
6228
|
if (o.length > 0) {
|
|
6131
|
-
const r = o[0].point, h = new
|
|
6229
|
+
const r = o[0].point, h = new f.Vector3(), a = new f.Vector3();
|
|
6132
6230
|
this.objectLeftArm.getWorldPosition(h), this.objectRightArm.getWorldPosition(a);
|
|
6133
6231
|
const u = h.distanceToSquared(r), l = a.distanceToSquared(r);
|
|
6134
6232
|
u < l ? (this.ikSolve({
|
|
@@ -6172,7 +6270,7 @@ class Le {
|
|
|
6172
6270
|
{ link: "LeftForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -0.5, maxz: 3 },
|
|
6173
6271
|
{ link: "LeftArm", minx: -1.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -1, maxz: 3 }
|
|
6174
6272
|
]
|
|
6175
|
-
}, new
|
|
6273
|
+
}, new f.Vector3(
|
|
6176
6274
|
this.gaussianRandom(0, 0.5),
|
|
6177
6275
|
this.gaussianRandom(-0.8, -0.2),
|
|
6178
6276
|
this.gaussianRandom(0, 0.5)
|
|
@@ -6184,15 +6282,15 @@ class Le {
|
|
|
6184
6282
|
{ link: "RightForeArm", minx: -0.5, maxx: 1.5, miny: -1.5, maxy: 1.5, minz: -3, maxz: 0.5 },
|
|
6185
6283
|
{ link: "RightArm" }
|
|
6186
6284
|
]
|
|
6187
|
-
}, new
|
|
6285
|
+
}, new f.Vector3(
|
|
6188
6286
|
this.gaussianRandom(-0.5, 0),
|
|
6189
6287
|
this.gaussianRandom(-0.8, -0.2),
|
|
6190
6288
|
this.gaussianRandom(0, 0.5)
|
|
6191
6289
|
), !0);
|
|
6192
6290
|
const i = [], n = [];
|
|
6193
6291
|
i.push(100 + Math.round(Math.random() * 500)), n.push({ duration: 1e3, props: {
|
|
6194
|
-
"LeftHand.quaternion": new
|
|
6195
|
-
"RightHand.quaternion": new
|
|
6292
|
+
"LeftHand.quaternion": new f.Quaternion().setFromEuler(new f.Euler(0, -1 - Math.random(), 0)),
|
|
6293
|
+
"RightHand.quaternion": new f.Quaternion().setFromEuler(new f.Euler(0, 1 + Math.random(), 0))
|
|
6196
6294
|
} }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm"].forEach((o) => {
|
|
6197
6295
|
n[0].props[o + ".quaternion"] = this.ikMesh.getObjectByName(o).quaternion.clone();
|
|
6198
6296
|
}), i.push(1e3 + Math.round(Math.random() * 500)), n.push({ duration: 2e3, props: {} }), ["LeftArm", "LeftForeArm", "RightArm", "RightForeArm", "LeftHand", "RightHand"].forEach((o) => {
|
|
@@ -6277,9 +6375,9 @@ class Le {
|
|
|
6277
6375
|
let h = this.animQueue.find((l) => l.template.name === "pose");
|
|
6278
6376
|
h && (h.ts[0] = 1 / 0), Object.entries(r.pose.props).forEach((l) => {
|
|
6279
6377
|
this.poseBase.props[l[0]] = l[1].clone(), this.poseTarget.props[l[0]] = l[1].clone(), this.poseTarget.props[l[0]].t = 0, this.poseTarget.props[l[0]].d = 1e3;
|
|
6280
|
-
}), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new
|
|
6378
|
+
}), this.mixer ? console.log("Using existing mixer for FBX animation, preserving morph targets") : (this.mixer = new f.AnimationMixer(this.armature), console.log("Created new mixer for FBX animation")), this.mixer.addEventListener("finished", this.stopAnimation.bind(this), { once: !0 });
|
|
6281
6379
|
const a = Math.ceil(i / r.clip.duration), u = this.mixer.clipAction(r.clip);
|
|
6282
|
-
u.setLoop(
|
|
6380
|
+
u.setLoop(f.LoopRepeat, a), u.clampWhenFinished = !0, this.currentFBXAction = u;
|
|
6283
6381
|
try {
|
|
6284
6382
|
u.fadeIn(0.5).play(), console.log("FBX animation started successfully:", t);
|
|
6285
6383
|
} catch (l) {
|
|
@@ -6316,13 +6414,13 @@ class Le {
|
|
|
6316
6414
|
suggestion: "Make sure the file is a valid FBX file and the path is correct"
|
|
6317
6415
|
}), c.message && c.message.includes("version number") && (console.error("FBX Loader Error: Cannot find version number"), console.error("This error usually means:"), console.error("1. The file is not a valid FBX file (might be GLB, corrupted, or wrong format)"), console.error("2. The file might be corrupted"), console.error("3. The file path might be incorrect"), console.error("4. The server returned an HTML error page instead of the FBX file"), console.error("5. The file might not exist at that path"), console.error(""), console.error("Solution: Please verify:"), console.error(` - File exists at: ${t}`), console.error(" - File is a valid FBX binary file"), console.error(" - File path matches your public folder structure"), console.error(" - File is not corrupted"));
|
|
6318
6416
|
try {
|
|
6319
|
-
const d = await fetch(t), g = d.headers.get("content-type"),
|
|
6417
|
+
const d = await fetch(t), g = d.headers.get("content-type"), y = await d.text();
|
|
6320
6418
|
console.error("Response details:", {
|
|
6321
6419
|
status: d.status,
|
|
6322
6420
|
contentType: g,
|
|
6323
|
-
firstBytes:
|
|
6324
|
-
isHTML:
|
|
6325
|
-
}), (
|
|
6421
|
+
firstBytes: y.substring(0, 100),
|
|
6422
|
+
isHTML: y.trim().startsWith("<!DOCTYPE") || y.trim().startsWith("<html")
|
|
6423
|
+
}), (y.trim().startsWith("<!DOCTYPE") || y.trim().startsWith("<html")) && console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.");
|
|
6326
6424
|
} catch (d) {
|
|
6327
6425
|
console.error("Could not fetch file for debugging:", d);
|
|
6328
6426
|
}
|
|
@@ -6331,14 +6429,14 @@ class Le {
|
|
|
6331
6429
|
if (l && l.animations && l.animations[n]) {
|
|
6332
6430
|
let c = l.animations[n];
|
|
6333
6431
|
const d = {};
|
|
6334
|
-
c.tracks.forEach((
|
|
6335
|
-
|
|
6336
|
-
const x =
|
|
6432
|
+
c.tracks.forEach((y) => {
|
|
6433
|
+
y.name = y.name.replaceAll("mixamorig", "");
|
|
6434
|
+
const x = y.name.split(".");
|
|
6337
6435
|
if (x[1] === "position") {
|
|
6338
|
-
for (let
|
|
6339
|
-
|
|
6340
|
-
d[
|
|
6341
|
-
} else x[1] === "quaternion" ? d[
|
|
6436
|
+
for (let v = 0; v < y.values.length; v++)
|
|
6437
|
+
y.values[v] = y.values[v] * s;
|
|
6438
|
+
d[y.name] = new f.Vector3(y.values[0], y.values[1], y.values[2]);
|
|
6439
|
+
} else x[1] === "quaternion" ? d[y.name] = new f.Quaternion(y.values[0], y.values[1], y.values[2], y.values[3]) : x[1] === "rotation" && (d[x[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(y.values[0], y.values[1], y.values[2], "XYZ")).normalize());
|
|
6342
6440
|
});
|
|
6343
6441
|
const g = { props: d };
|
|
6344
6442
|
d["Hips.position"] && (d["Hips.position"].y < 0.5 ? g.lying = !0 : g.standing = !0), this.animClips.push({
|
|
@@ -6389,7 +6487,7 @@ class Le {
|
|
|
6389
6487
|
a.tracks.forEach((c) => {
|
|
6390
6488
|
c.name = c.name.replaceAll("mixamorig", "");
|
|
6391
6489
|
const d = c.name.split(".");
|
|
6392
|
-
d[1] === "position" ? u[c.name] = new
|
|
6490
|
+
d[1] === "position" ? u[c.name] = new f.Vector3(c.values[0] * s, c.values[1] * s, c.values[2] * s) : d[1] === "quaternion" ? u[c.name] = new f.Quaternion(c.values[0], c.values[1], c.values[2], c.values[3]) : d[1] === "rotation" && (u[d[0] + ".quaternion"] = new f.Quaternion().setFromEuler(new f.Euler(c.values[0], c.values[1], c.values[2], "XYZ")).normalize());
|
|
6393
6491
|
});
|
|
6394
6492
|
const l = { props: u };
|
|
6395
6493
|
u["Hips.position"] && (u["Hips.position"].y < 0.5 ? l.lying = !0 : l.standing = !0), this.animPoses.push({
|
|
@@ -6422,7 +6520,7 @@ class Le {
|
|
|
6422
6520
|
if (s) {
|
|
6423
6521
|
this.gestureTimeout && (clearTimeout(this.gestureTimeout), this.gestureTimeout = null);
|
|
6424
6522
|
let r = this.animQueue.findIndex((h) => h.template.name === "talkinghands");
|
|
6425
|
-
r !== -1 && (this.animQueue[r].ts = this.animQueue[r].ts.map((h) => 0)), this.gesture = this.propsToThreeObjects(s), i && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new
|
|
6523
|
+
r !== -1 && (this.animQueue[r].ts = this.animQueue[r].ts.map((h) => 0)), this.gesture = this.propsToThreeObjects(s), i && (this.gesture = this.mirrorPose(this.gesture)), t === "namaste" && this.avatar.body === "M" && (this.gesture["RightArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25), this.gesture["LeftArm.quaternion"].rotateTowards(new f.Quaternion(0, 1, 0, 0), -0.25));
|
|
6426
6524
|
for (let [h, a] of Object.entries(this.gesture))
|
|
6427
6525
|
a.t = this.animClock, a.d = n, this.poseTarget.props.hasOwnProperty(h) && (this.poseTarget.props[h].copy(a), this.poseTarget.props[h].t = this.animClock, this.poseTarget.props[h].d = n);
|
|
6428
6526
|
e && Number.isFinite(e) && (this.gestureTimeout = setTimeout(this.stopGesture.bind(this, n), 1e3 * e));
|
|
@@ -6435,9 +6533,9 @@ class Le {
|
|
|
6435
6533
|
const h = r.ts[0], u = r.ts[r.ts.length - 1] - h;
|
|
6436
6534
|
if (e * 1e3 - u > 0) {
|
|
6437
6535
|
const c = [];
|
|
6438
|
-
for (let
|
|
6439
|
-
const d = o.template?.rescale || c.map((
|
|
6440
|
-
r.ts = r.ts.map((
|
|
6536
|
+
for (let y = 1; y < r.ts.length; y++) c.push(r.ts[y] - r.ts[y - 1]);
|
|
6537
|
+
const d = o.template?.rescale || c.map((y) => y / u), g = e * 1e3 - u;
|
|
6538
|
+
r.ts = r.ts.map((y, x, v) => x === 0 ? h : v[x - 1] + c[x - 1] + d[x - 1] * g);
|
|
6441
6539
|
} else {
|
|
6442
6540
|
const c = e * 1e3 / u;
|
|
6443
6541
|
r.ts = r.ts.map((d) => h + c * (d - h));
|
|
@@ -6470,34 +6568,34 @@ class Le {
|
|
|
6470
6568
|
* @param {numeric} [d=null] If set, apply in d milliseconds
|
|
6471
6569
|
*/
|
|
6472
6570
|
ikSolve(t, e = null, i = !1, n = null) {
|
|
6473
|
-
const s = new
|
|
6571
|
+
const s = new f.Vector3(), o = new f.Vector3(), r = new f.Vector3(), h = new f.Vector3(), a = new f.Quaternion(), u = new f.Vector3(), l = new f.Vector3(), c = new f.Vector3(), d = this.ikMesh.getObjectByName(t.root);
|
|
6474
6572
|
d.position.setFromMatrixPosition(this.armature.getObjectByName(t.root).matrixWorld), d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(t.root).matrixWorld), e && i && e.applyQuaternion(this.armature.quaternion).add(d.position);
|
|
6475
|
-
const g = this.ikMesh.getObjectByName(t.effector),
|
|
6476
|
-
|
|
6477
|
-
|
|
6573
|
+
const g = this.ikMesh.getObjectByName(t.effector), y = t.links;
|
|
6574
|
+
y.forEach((v) => {
|
|
6575
|
+
v.bone = this.ikMesh.getObjectByName(v.link), v.bone.quaternion.copy(this.getPoseTemplateProp(v.link + ".quaternion"));
|
|
6478
6576
|
}), d.updateMatrixWorld(!0);
|
|
6479
6577
|
const x = t.iterations || 10;
|
|
6480
6578
|
if (e)
|
|
6481
|
-
for (let
|
|
6579
|
+
for (let v = 0; v < x; v++) {
|
|
6482
6580
|
let H = !1;
|
|
6483
|
-
for (let p = 0, E =
|
|
6484
|
-
const z =
|
|
6581
|
+
for (let p = 0, E = y.length; p < E; p++) {
|
|
6582
|
+
const z = y[p].bone;
|
|
6485
6583
|
z.matrixWorld.decompose(h, a, u), a.invert(), o.setFromMatrixPosition(g.matrixWorld), r.subVectors(o, h), r.applyQuaternion(a), r.normalize(), s.subVectors(e, h), s.applyQuaternion(a), s.normalize();
|
|
6486
|
-
let
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
), new
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6584
|
+
let I = s.dot(r);
|
|
6585
|
+
I > 1 ? I = 1 : I < -1 && (I = -1), I = Math.acos(I), !(I < 1e-5) && (y[p].minAngle !== void 0 && I < y[p].minAngle && (I = y[p].minAngle), y[p].maxAngle !== void 0 && I > y[p].maxAngle && (I = y[p].maxAngle), l.crossVectors(r, s), l.normalize(), N.setFromAxisAngle(l, I), z.quaternion.multiply(N), z.rotation.setFromVector3(c.setFromEuler(z.rotation).clamp(new f.Vector3(
|
|
6586
|
+
y[p].minx !== void 0 ? y[p].minx : -1 / 0,
|
|
6587
|
+
y[p].miny !== void 0 ? y[p].miny : -1 / 0,
|
|
6588
|
+
y[p].minz !== void 0 ? y[p].minz : -1 / 0
|
|
6589
|
+
), new f.Vector3(
|
|
6590
|
+
y[p].maxx !== void 0 ? y[p].maxx : 1 / 0,
|
|
6591
|
+
y[p].maxy !== void 0 ? y[p].maxy : 1 / 0,
|
|
6592
|
+
y[p].maxz !== void 0 ? y[p].maxz : 1 / 0
|
|
6495
6593
|
))), z.updateMatrixWorld(!0), H = !0);
|
|
6496
6594
|
}
|
|
6497
6595
|
if (!H) break;
|
|
6498
6596
|
}
|
|
6499
|
-
n &&
|
|
6500
|
-
this.poseTarget.props[
|
|
6597
|
+
n && y.forEach((v) => {
|
|
6598
|
+
this.poseTarget.props[v.link + ".quaternion"].copy(v.bone.quaternion), this.poseTarget.props[v.link + ".quaternion"].t = this.animClock, this.poseTarget.props[v.link + ".quaternion"].d = n;
|
|
6501
6599
|
});
|
|
6502
6600
|
}
|
|
6503
6601
|
/**
|
|
@@ -6527,6 +6625,25 @@ const ae = {
|
|
|
6527
6625
|
josh: "VR6AewLTigWG4xSOukaG"
|
|
6528
6626
|
// Male, American
|
|
6529
6627
|
}
|
|
6628
|
+
}, Ae = {
|
|
6629
|
+
defaultVoice: "aura-2-thalia-en",
|
|
6630
|
+
// Thalia (Female, English)
|
|
6631
|
+
voices: {
|
|
6632
|
+
thalia: "aura-2-thalia-en",
|
|
6633
|
+
// Female, English - Natural and clear
|
|
6634
|
+
asteria: "aura-2-asteria-en",
|
|
6635
|
+
// Female, English - Warm and friendly
|
|
6636
|
+
orion: "aura-2-orion-en",
|
|
6637
|
+
// Male, English - Professional
|
|
6638
|
+
stella: "aura-2-stella-en",
|
|
6639
|
+
// Female, English - Energetic
|
|
6640
|
+
athena: "aura-2-athena-en",
|
|
6641
|
+
// Female, English - Authoritative
|
|
6642
|
+
hera: "aura-2-hera-en",
|
|
6643
|
+
// Female, English - Calm
|
|
6644
|
+
zeus: "aura-2-zeus-en"
|
|
6645
|
+
// Male, English - Powerful
|
|
6646
|
+
}
|
|
6530
6647
|
};
|
|
6531
6648
|
function xe() {
|
|
6532
6649
|
return {
|
|
@@ -6537,7 +6654,7 @@ function xe() {
|
|
|
6537
6654
|
voices: ae.voices
|
|
6538
6655
|
};
|
|
6539
6656
|
}
|
|
6540
|
-
function
|
|
6657
|
+
function ht() {
|
|
6541
6658
|
const B = xe(), t = [];
|
|
6542
6659
|
return Object.entries(B.voices).forEach(([e, i]) => {
|
|
6543
6660
|
t.push({
|
|
@@ -6546,7 +6663,7 @@ function lt() {
|
|
|
6546
6663
|
});
|
|
6547
6664
|
}), t;
|
|
6548
6665
|
}
|
|
6549
|
-
const
|
|
6666
|
+
const ke = ye(({
|
|
6550
6667
|
avatarUrl: B = "/avatars/brunette.glb",
|
|
6551
6668
|
avatarBody: t = "F",
|
|
6552
6669
|
mood: e = "neutral",
|
|
@@ -6565,10 +6682,10 @@ const Se = ye(({
|
|
|
6565
6682
|
onError: d = () => {
|
|
6566
6683
|
},
|
|
6567
6684
|
className: g = "",
|
|
6568
|
-
style:
|
|
6685
|
+
style: y = {},
|
|
6569
6686
|
animations: x = {}
|
|
6570
|
-
},
|
|
6571
|
-
const H = X(null), p = X(null), [E, z] = re(!0), [
|
|
6687
|
+
}, v) => {
|
|
6688
|
+
const H = X(null), p = X(null), [E, z] = re(!0), [I, D] = re(null), [P, J] = re(!1), Y = xe(), S = n || Y.service;
|
|
6572
6689
|
let F;
|
|
6573
6690
|
S === "browser" ? F = {
|
|
6574
6691
|
service: "browser",
|
|
@@ -6578,13 +6695,19 @@ const Se = ye(({
|
|
|
6578
6695
|
} : S === "elevenlabs" ? F = {
|
|
6579
6696
|
service: "elevenlabs",
|
|
6580
6697
|
endpoint: "https://api.elevenlabs.io/v1/text-to-speech",
|
|
6581
|
-
apiKey: o ||
|
|
6582
|
-
defaultVoice: s ||
|
|
6583
|
-
voices:
|
|
6698
|
+
apiKey: o || Y.apiKey,
|
|
6699
|
+
defaultVoice: s || Y.defaultVoice || ae.defaultVoice,
|
|
6700
|
+
voices: Y.voices || ae.voices
|
|
6701
|
+
} : S === "deepgram" ? F = {
|
|
6702
|
+
service: "deepgram",
|
|
6703
|
+
endpoint: "https://api.deepgram.com/v1/speak",
|
|
6704
|
+
apiKey: o || Y.apiKey,
|
|
6705
|
+
defaultVoice: s || Y.defaultVoice || Ae.defaultVoice,
|
|
6706
|
+
voices: Y.voices || Ae.voices
|
|
6584
6707
|
} : F = {
|
|
6585
|
-
...
|
|
6708
|
+
...Y,
|
|
6586
6709
|
// Override API key if provided via props
|
|
6587
|
-
apiKey: o !== null ? o :
|
|
6710
|
+
apiKey: o !== null ? o : Y.apiKey
|
|
6588
6711
|
};
|
|
6589
6712
|
const W = {
|
|
6590
6713
|
url: B,
|
|
@@ -6602,26 +6725,26 @@ const Se = ye(({
|
|
|
6602
6725
|
ttsService: S,
|
|
6603
6726
|
lipsyncModules: ["en"],
|
|
6604
6727
|
cameraView: u
|
|
6605
|
-
},
|
|
6728
|
+
}, Q = M(async () => {
|
|
6606
6729
|
if (!(!H.current || p.current))
|
|
6607
6730
|
try {
|
|
6608
|
-
if (z(!0),
|
|
6731
|
+
if (z(!0), D(null), p.current = new Se(H.current, V), p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1), x && Object.keys(x).length > 0 && (p.current.customAnimations = x), await p.current.showAvatar(W, (U) => {
|
|
6609
6732
|
if (U.lengthComputable) {
|
|
6610
|
-
const
|
|
6611
|
-
c(
|
|
6733
|
+
const O = Math.min(100, Math.round(U.loaded / U.total * 100));
|
|
6734
|
+
c(O);
|
|
6612
6735
|
}
|
|
6613
6736
|
}), await new Promise((U) => {
|
|
6614
|
-
const
|
|
6615
|
-
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? U() : setTimeout(
|
|
6737
|
+
const O = () => {
|
|
6738
|
+
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? U() : setTimeout(O, 100);
|
|
6616
6739
|
};
|
|
6617
|
-
|
|
6740
|
+
O();
|
|
6618
6741
|
}), p.current && p.current.setShowFullAvatar)
|
|
6619
6742
|
try {
|
|
6620
6743
|
p.current.setShowFullAvatar(a);
|
|
6621
6744
|
} catch (U) {
|
|
6622
6745
|
console.warn("Error setting full body mode on initialization:", U);
|
|
6623
6746
|
}
|
|
6624
|
-
p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), z(!1),
|
|
6747
|
+
p.current && p.current.controls && (p.current.controls.enableRotate = !1, p.current.controls.enableZoom = !1, p.current.controls.enablePan = !1, p.current.controls.enableDamping = !1, p.current.controls.update()), z(!1), J(!0), l(p.current);
|
|
6625
6748
|
const C = () => {
|
|
6626
6749
|
document.visibilityState === "visible" ? p.current?.start() : p.current?.stop();
|
|
6627
6750
|
};
|
|
@@ -6629,15 +6752,15 @@ const Se = ye(({
|
|
|
6629
6752
|
document.removeEventListener("visibilitychange", C);
|
|
6630
6753
|
};
|
|
6631
6754
|
} catch (L) {
|
|
6632
|
-
console.error("Error initializing TalkingHead:", L),
|
|
6755
|
+
console.error("Error initializing TalkingHead:", L), D(L.message || "Failed to initialize avatar"), z(!1), d(L);
|
|
6633
6756
|
}
|
|
6634
6757
|
}, [B, t, e, i, n, s, o, a, r, h, u]);
|
|
6635
|
-
he(() => (
|
|
6758
|
+
he(() => (Q(), () => {
|
|
6636
6759
|
p.current && (p.current.stop(), p.current.dispose(), p.current = null);
|
|
6637
|
-
}), [
|
|
6760
|
+
}), [Q]), he(() => {
|
|
6638
6761
|
if (!H.current || !p.current) return;
|
|
6639
6762
|
const L = new ResizeObserver((U) => {
|
|
6640
|
-
for (const
|
|
6763
|
+
for (const O of U)
|
|
6641
6764
|
p.current && p.current.onResize && p.current.onResize();
|
|
6642
6765
|
});
|
|
6643
6766
|
L.observe(H.current);
|
|
@@ -6648,7 +6771,7 @@ const Se = ye(({
|
|
|
6648
6771
|
L.disconnect(), window.removeEventListener("resize", C);
|
|
6649
6772
|
};
|
|
6650
6773
|
}, [P]);
|
|
6651
|
-
const
|
|
6774
|
+
const q = M(async () => {
|
|
6652
6775
|
if (p.current && p.current.audioCtx)
|
|
6653
6776
|
try {
|
|
6654
6777
|
(p.current.audioCtx.state === "suspended" || p.current.audioCtx.state === "interrupted") && (await p.current.audioCtx.resume(), console.log("Audio context resumed"));
|
|
@@ -6658,16 +6781,16 @@ const Se = ye(({
|
|
|
6658
6781
|
}, []), le = M(async (L, C = {}) => {
|
|
6659
6782
|
if (p.current && P)
|
|
6660
6783
|
try {
|
|
6661
|
-
await
|
|
6784
|
+
await q();
|
|
6662
6785
|
const U = {
|
|
6663
6786
|
...C,
|
|
6664
6787
|
lipsyncLang: C.lipsyncLang || W.lipsyncLang || "en"
|
|
6665
6788
|
};
|
|
6666
6789
|
if (C.onSpeechEnd && p.current) {
|
|
6667
|
-
const
|
|
6790
|
+
const O = p.current, ne = O.onAudioEnd;
|
|
6668
6791
|
let $ = null, pe = 0;
|
|
6669
|
-
const
|
|
6670
|
-
if (pe++, pe >
|
|
6792
|
+
const ze = 600, Ce = () => {
|
|
6793
|
+
if (pe++, pe > ze) {
|
|
6671
6794
|
$ && (clearInterval($), $ = null);
|
|
6672
6795
|
try {
|
|
6673
6796
|
C.onSpeechEnd();
|
|
@@ -6676,7 +6799,7 @@ const Se = ye(({
|
|
|
6676
6799
|
}
|
|
6677
6800
|
return;
|
|
6678
6801
|
}
|
|
6679
|
-
|
|
6802
|
+
O && (!O.isSpeaking || O.isSpeaking === !1) && (!O.audioPlaylist || O.audioPlaylist.length === 0) && (!O.isAudioPlaying || O.isAudioPlaying === !1) && ($ && (clearInterval($), $ = null), setTimeout(() => {
|
|
6680
6803
|
try {
|
|
6681
6804
|
C.onSpeechEnd();
|
|
6682
6805
|
} catch (ge) {
|
|
@@ -6685,18 +6808,18 @@ const Se = ye(({
|
|
|
6685
6808
|
}, 100));
|
|
6686
6809
|
};
|
|
6687
6810
|
setTimeout(() => {
|
|
6688
|
-
$ = setInterval(
|
|
6811
|
+
$ = setInterval(Ce, 100);
|
|
6689
6812
|
}, 500);
|
|
6690
6813
|
}
|
|
6691
6814
|
p.current.lipsync && Object.keys(p.current.lipsync).length > 0 ? (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, U)) : setTimeout(async () => {
|
|
6692
|
-
await
|
|
6815
|
+
await q(), p.current && p.current.lipsync && (p.current.setSlowdownRate && p.current.setSlowdownRate(1.05), p.current.speakText(L, U));
|
|
6693
6816
|
}, 500);
|
|
6694
6817
|
} catch (U) {
|
|
6695
|
-
console.error("Error speaking text:", U),
|
|
6818
|
+
console.error("Error speaking text:", U), D(U.message || "Failed to speak text");
|
|
6696
6819
|
}
|
|
6697
|
-
}, [P,
|
|
6820
|
+
}, [P, q, W.lipsyncLang]), me = M(() => {
|
|
6698
6821
|
p.current && (p.current.stopSpeaking(), p.current.setSlowdownRate && p.current.setSlowdownRate(1));
|
|
6699
|
-
}, []),
|
|
6822
|
+
}, []), _ = M((L) => {
|
|
6700
6823
|
p.current && p.current.setMood(L);
|
|
6701
6824
|
}, []), b = M((L) => {
|
|
6702
6825
|
p.current && p.current.setSlowdownRate && p.current.setSlowdownRate(L);
|
|
@@ -6705,14 +6828,14 @@ const Se = ye(({
|
|
|
6705
6828
|
if (x && x[L] && (L = x[L]), p.current.setShowFullAvatar)
|
|
6706
6829
|
try {
|
|
6707
6830
|
p.current.setShowFullAvatar(!0);
|
|
6708
|
-
} catch (
|
|
6709
|
-
console.warn("Error setting full body mode:",
|
|
6831
|
+
} catch (O) {
|
|
6832
|
+
console.warn("Error setting full body mode:", O);
|
|
6710
6833
|
}
|
|
6711
6834
|
if (L.includes("."))
|
|
6712
6835
|
try {
|
|
6713
6836
|
p.current.playAnimation(L, null, 10, 0, 0.01, C);
|
|
6714
|
-
} catch (
|
|
6715
|
-
console.warn(`Failed to play ${L}:`,
|
|
6837
|
+
} catch (O) {
|
|
6838
|
+
console.warn(`Failed to play ${L}:`, O);
|
|
6716
6839
|
try {
|
|
6717
6840
|
p.current.setBodyMovement("idle");
|
|
6718
6841
|
} catch (ne) {
|
|
@@ -6720,9 +6843,9 @@ const Se = ye(({
|
|
|
6720
6843
|
}
|
|
6721
6844
|
}
|
|
6722
6845
|
else {
|
|
6723
|
-
const
|
|
6846
|
+
const O = [".fbx", ".glb", ".gltf"];
|
|
6724
6847
|
let ne = !1;
|
|
6725
|
-
for (const $ of
|
|
6848
|
+
for (const $ of O)
|
|
6726
6849
|
try {
|
|
6727
6850
|
p.current.playAnimation(L + $, null, 10, 0, 0.01, C), ne = !0;
|
|
6728
6851
|
break;
|
|
@@ -6741,11 +6864,11 @@ const Se = ye(({
|
|
|
6741
6864
|
}, [x]), w = M(() => {
|
|
6742
6865
|
p.current && p.current.onResize && p.current.onResize();
|
|
6743
6866
|
}, []);
|
|
6744
|
-
return fe(
|
|
6867
|
+
return fe(v, () => ({
|
|
6745
6868
|
speakText: le,
|
|
6746
6869
|
stopSpeaking: me,
|
|
6747
|
-
resumeAudioContext:
|
|
6748
|
-
setMood:
|
|
6870
|
+
resumeAudioContext: q,
|
|
6871
|
+
setMood: _,
|
|
6749
6872
|
setTimingAdjustment: b,
|
|
6750
6873
|
playAnimation: R,
|
|
6751
6874
|
isReady: P,
|
|
@@ -6808,7 +6931,7 @@ const Se = ye(({
|
|
|
6808
6931
|
console.warn("Error unlocking avatar position:", L);
|
|
6809
6932
|
}
|
|
6810
6933
|
}
|
|
6811
|
-
})), /* @__PURE__ */
|
|
6934
|
+
})), /* @__PURE__ */ Le(
|
|
6812
6935
|
"div",
|
|
6813
6936
|
{
|
|
6814
6937
|
className: `talking-head-avatar ${g}`,
|
|
@@ -6816,7 +6939,7 @@ const Se = ye(({
|
|
|
6816
6939
|
width: "100%",
|
|
6817
6940
|
height: "100%",
|
|
6818
6941
|
position: "relative",
|
|
6819
|
-
...
|
|
6942
|
+
...y
|
|
6820
6943
|
},
|
|
6821
6944
|
children: [
|
|
6822
6945
|
/* @__PURE__ */ se(
|
|
@@ -6840,7 +6963,7 @@ const Se = ye(({
|
|
|
6840
6963
|
fontSize: "18px",
|
|
6841
6964
|
zIndex: 10
|
|
6842
6965
|
}, children: "Loading avatar..." }),
|
|
6843
|
-
|
|
6966
|
+
I && /* @__PURE__ */ se("div", { className: "error-overlay", style: {
|
|
6844
6967
|
position: "absolute",
|
|
6845
6968
|
top: "50%",
|
|
6846
6969
|
left: "50%",
|
|
@@ -6851,13 +6974,13 @@ const Se = ye(({
|
|
|
6851
6974
|
zIndex: 10,
|
|
6852
6975
|
padding: "20px",
|
|
6853
6976
|
borderRadius: "8px"
|
|
6854
|
-
}, children:
|
|
6977
|
+
}, children: I })
|
|
6855
6978
|
]
|
|
6856
6979
|
}
|
|
6857
6980
|
);
|
|
6858
6981
|
});
|
|
6859
|
-
|
|
6860
|
-
const
|
|
6982
|
+
ke.displayName = "TalkingHeadAvatar";
|
|
6983
|
+
const $e = ye(({
|
|
6861
6984
|
text: B = "Hello! I'm a talking avatar. How are you today?",
|
|
6862
6985
|
onLoading: t = () => {
|
|
6863
6986
|
},
|
|
@@ -6869,7 +6992,7 @@ const Je = ye(({
|
|
|
6869
6992
|
style: s = {},
|
|
6870
6993
|
avatarConfig: o = {}
|
|
6871
6994
|
}, r) => {
|
|
6872
|
-
const h = X(null), a = X(null), [u, l] = re(!0), [c, d] = re(null), [g,
|
|
6995
|
+
const h = X(null), a = X(null), [u, l] = re(!0), [c, d] = re(null), [g, y] = re(!1), x = xe(), v = o.ttsService || x.service, H = v === "browser" ? {
|
|
6873
6996
|
endpoint: "",
|
|
6874
6997
|
apiKey: null,
|
|
6875
6998
|
defaultVoice: "Google US English"
|
|
@@ -6878,13 +7001,13 @@ const Je = ye(({
|
|
|
6878
7001
|
// Override API key if provided via avatarConfig
|
|
6879
7002
|
apiKey: o.ttsApiKey !== void 0 && o.ttsApiKey !== null ? o.ttsApiKey : x.apiKey,
|
|
6880
7003
|
// Override endpoint for ElevenLabs if service is explicitly set
|
|
6881
|
-
endpoint:
|
|
7004
|
+
endpoint: v === "elevenlabs" && o.ttsApiKey ? "https://api.elevenlabs.io/v1/text-to-speech" : x.endpoint
|
|
6882
7005
|
}, p = {
|
|
6883
7006
|
url: "/avatars/brunette.glb",
|
|
6884
7007
|
// Use brunette avatar (working glTF file)
|
|
6885
7008
|
body: "F",
|
|
6886
7009
|
avatarMood: "neutral",
|
|
6887
|
-
ttsLang:
|
|
7010
|
+
ttsLang: v === "browser" ? "en-US" : "en",
|
|
6888
7011
|
ttsVoice: o.ttsVoice || H.defaultVoice,
|
|
6889
7012
|
lipsyncLang: "en",
|
|
6890
7013
|
// English lip-sync
|
|
@@ -6896,13 +7019,13 @@ const Je = ye(({
|
|
|
6896
7019
|
}, E = {
|
|
6897
7020
|
ttsEndpoint: H.endpoint,
|
|
6898
7021
|
ttsApikey: H.apiKey,
|
|
6899
|
-
ttsService:
|
|
7022
|
+
ttsService: v,
|
|
6900
7023
|
lipsyncModules: ["en"],
|
|
6901
7024
|
cameraView: "upper"
|
|
6902
7025
|
}, z = M(async () => {
|
|
6903
7026
|
if (!(!h.current || a.current))
|
|
6904
7027
|
try {
|
|
6905
|
-
if (l(!0), d(null), a.current = new
|
|
7028
|
+
if (l(!0), d(null), a.current = new Se(h.current, E), await a.current.showAvatar(p, (W) => {
|
|
6906
7029
|
if (W.lengthComputable) {
|
|
6907
7030
|
const V = Math.min(100, Math.round(W.loaded / W.total * 100));
|
|
6908
7031
|
t(V);
|
|
@@ -6910,7 +7033,7 @@ const Je = ye(({
|
|
|
6910
7033
|
}), a.current.morphs && a.current.morphs.length > 0) {
|
|
6911
7034
|
const W = a.current.morphs[0].morphTargetDictionary;
|
|
6912
7035
|
console.log("Available morph targets:", Object.keys(W));
|
|
6913
|
-
const V = Object.keys(W).filter((
|
|
7036
|
+
const V = Object.keys(W).filter((Q) => Q.startsWith("viseme_"));
|
|
6914
7037
|
console.log("Viseme morph targets found:", V), V.length === 0 && (console.warn("No viseme morph targets found! Lip-sync will not work properly."), console.log("Expected viseme targets: viseme_aa, viseme_E, viseme_I, viseme_O, viseme_U, viseme_PP, viseme_SS, viseme_TH, viseme_DD, viseme_FF, viseme_kk, viseme_nn, viseme_RR, viseme_CH, viseme_sil"));
|
|
6915
7038
|
}
|
|
6916
7039
|
if (await new Promise((W) => {
|
|
@@ -6924,7 +7047,7 @@ const Je = ye(({
|
|
|
6924
7047
|
} catch (W) {
|
|
6925
7048
|
console.warn("Error setting full body mode on initialization:", W);
|
|
6926
7049
|
}
|
|
6927
|
-
l(!1),
|
|
7050
|
+
l(!1), y(!0), i(a.current);
|
|
6928
7051
|
const F = () => {
|
|
6929
7052
|
document.visibilityState === "visible" ? a.current?.start() : a.current?.stop();
|
|
6930
7053
|
};
|
|
@@ -6938,7 +7061,7 @@ const Je = ye(({
|
|
|
6938
7061
|
he(() => (z(), () => {
|
|
6939
7062
|
a.current && (a.current.stop(), a.current.dispose(), a.current = null);
|
|
6940
7063
|
}), [z]);
|
|
6941
|
-
const
|
|
7064
|
+
const I = M((S) => {
|
|
6942
7065
|
if (a.current && g)
|
|
6943
7066
|
try {
|
|
6944
7067
|
console.log("Speaking text:", S), console.log("Avatar config:", p), console.log("TalkingHead instance:", a.current), a.current.lipsync && Object.keys(a.current.lipsync).length > 0 ? (console.log("Lip-sync modules loaded:", Object.keys(a.current.lipsync)), a.current.setSlowdownRate && (a.current.setSlowdownRate(1.05), console.log("Applied timing adjustment for better lip-sync")), a.current.speakText(S)) : (console.warn("Lip-sync modules not ready, waiting..."), setTimeout(() => {
|
|
@@ -6949,13 +7072,13 @@ const Je = ye(({
|
|
|
6949
7072
|
}
|
|
6950
7073
|
else
|
|
6951
7074
|
console.warn("Avatar not ready for speaking. isReady:", g, "talkingHeadRef:", !!a.current);
|
|
6952
|
-
}, [g, p]),
|
|
7075
|
+
}, [g, p]), D = M(() => {
|
|
6953
7076
|
a.current && (a.current.stopSpeaking(), a.current.setSlowdownRate && (a.current.setSlowdownRate(1), console.log("Reset timing to normal")));
|
|
6954
7077
|
}, []), P = M((S) => {
|
|
6955
7078
|
a.current && a.current.setMood(S);
|
|
6956
|
-
}, []),
|
|
7079
|
+
}, []), J = M((S) => {
|
|
6957
7080
|
a.current && a.current.setSlowdownRate && (a.current.setSlowdownRate(S), console.log("Timing adjustment set to:", S));
|
|
6958
|
-
}, []),
|
|
7081
|
+
}, []), Y = M((S, F = !1) => {
|
|
6959
7082
|
if (a.current && a.current.playAnimation) {
|
|
6960
7083
|
if (a.current.setShowFullAvatar)
|
|
6961
7084
|
try {
|
|
@@ -6970,26 +7093,26 @@ const Je = ye(({
|
|
|
6970
7093
|
console.log(`Failed to play ${S}:`, V);
|
|
6971
7094
|
try {
|
|
6972
7095
|
a.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
6973
|
-
} catch (
|
|
6974
|
-
console.warn("Fallback animation also failed:",
|
|
7096
|
+
} catch (Q) {
|
|
7097
|
+
console.warn("Fallback animation also failed:", Q);
|
|
6975
7098
|
}
|
|
6976
7099
|
}
|
|
6977
7100
|
else {
|
|
6978
7101
|
const V = [".fbx", ".glb", ".gltf"];
|
|
6979
|
-
let
|
|
6980
|
-
for (const
|
|
7102
|
+
let Q = !1;
|
|
7103
|
+
for (const q of V)
|
|
6981
7104
|
try {
|
|
6982
|
-
a.current.playAnimation(S +
|
|
7105
|
+
a.current.playAnimation(S + q, null, 10, 0, 0.01, F), console.log("Playing animation:", S + q), Q = !0;
|
|
6983
7106
|
break;
|
|
6984
7107
|
} catch {
|
|
6985
|
-
console.log(`Failed to play ${S}${
|
|
7108
|
+
console.log(`Failed to play ${S}${q}, trying next format...`);
|
|
6986
7109
|
}
|
|
6987
|
-
if (!
|
|
7110
|
+
if (!Q) {
|
|
6988
7111
|
console.warn("Animation system not available or animation not found:", S);
|
|
6989
7112
|
try {
|
|
6990
7113
|
a.current.setBodyMovement("idle"), console.log("Fallback to idle animation");
|
|
6991
|
-
} catch (
|
|
6992
|
-
console.warn("Fallback animation also failed:",
|
|
7114
|
+
} catch (q) {
|
|
7115
|
+
console.warn("Fallback animation also failed:", q);
|
|
6993
7116
|
}
|
|
6994
7117
|
}
|
|
6995
7118
|
}
|
|
@@ -6997,11 +7120,11 @@ const Je = ye(({
|
|
|
6997
7120
|
console.warn("Animation system not available or animation not found:", S);
|
|
6998
7121
|
}, []);
|
|
6999
7122
|
return fe(r, () => ({
|
|
7000
|
-
speakText:
|
|
7001
|
-
stopSpeaking:
|
|
7123
|
+
speakText: I,
|
|
7124
|
+
stopSpeaking: D,
|
|
7002
7125
|
setMood: P,
|
|
7003
|
-
setTimingAdjustment:
|
|
7004
|
-
playAnimation:
|
|
7126
|
+
setTimingAdjustment: J,
|
|
7127
|
+
playAnimation: Y,
|
|
7005
7128
|
isReady: g,
|
|
7006
7129
|
talkingHead: a.current,
|
|
7007
7130
|
setBodyMovement: (S) => {
|
|
@@ -7061,7 +7184,7 @@ const Je = ye(({
|
|
|
7061
7184
|
console.warn("Error unlocking avatar position:", S);
|
|
7062
7185
|
}
|
|
7063
7186
|
}
|
|
7064
|
-
})), /* @__PURE__ */
|
|
7187
|
+
})), /* @__PURE__ */ Le("div", { className: `talking-head-container ${n}`, style: s, children: [
|
|
7065
7188
|
/* @__PURE__ */ se(
|
|
7066
7189
|
"div",
|
|
7067
7190
|
{
|
|
@@ -7097,8 +7220,8 @@ const Je = ye(({
|
|
|
7097
7220
|
}, children: c })
|
|
7098
7221
|
] });
|
|
7099
7222
|
});
|
|
7100
|
-
|
|
7101
|
-
const
|
|
7223
|
+
$e.displayName = "TalkingHeadComponent";
|
|
7224
|
+
const et = ye(({
|
|
7102
7225
|
curriculumData: B = null,
|
|
7103
7226
|
avatarConfig: t = {},
|
|
7104
7227
|
animations: e = {},
|
|
@@ -7130,7 +7253,7 @@ const $e = ye(({
|
|
|
7130
7253
|
onQuestionAnswer: s,
|
|
7131
7254
|
onCurriculumComplete: o,
|
|
7132
7255
|
onCustomAction: r
|
|
7133
|
-
}), d = X(null), g = X(null),
|
|
7256
|
+
}), d = X(null), g = X(null), y = X(null), x = X(null), v = X(null), H = X(null), p = X(null), E = X(B?.curriculum || {
|
|
7134
7257
|
title: "Default Curriculum",
|
|
7135
7258
|
description: "No curriculum data provided",
|
|
7136
7259
|
language: "en",
|
|
@@ -7178,7 +7301,7 @@ const $e = ye(({
|
|
|
7178
7301
|
lipsyncLang: "en"
|
|
7179
7302
|
};
|
|
7180
7303
|
}, [B, t, e]);
|
|
7181
|
-
const
|
|
7304
|
+
const I = M(() => (E.current || { modules: [] }).modules[l.current.currentModuleIndex]?.lessons[l.current.currentLessonIndex], []), D = M(() => I()?.questions[l.current.currentQuestionIndex], [I]), P = M((b, R) => R.type === "multiple_choice" || R.type === "true_false" ? b === R.answer : R.type === "code_test" && typeof b == "object" && b !== null ? b.passed === !0 : !1, []), J = M(() => {
|
|
7182
7305
|
l.current.lessonCompleted = !0, l.current.isQuestionMode = !1;
|
|
7183
7306
|
const b = l.current.totalQuestions > 0 ? Math.round(l.current.score / l.current.totalQuestions * 100) : 100;
|
|
7184
7307
|
let R = "Congratulations! You've completed this lesson";
|
|
@@ -7202,8 +7325,8 @@ const $e = ye(({
|
|
|
7202
7325
|
} catch {
|
|
7203
7326
|
u.current.playCelebration();
|
|
7204
7327
|
}
|
|
7205
|
-
const w = E.current || { modules: [] }, L = w.modules[l.current.currentModuleIndex], C = l.current.currentLessonIndex < (L?.lessons?.length || 0) - 1, U = l.current.currentModuleIndex < (w.modules?.length || 0) - 1,
|
|
7206
|
-
|
|
7328
|
+
const w = E.current || { modules: [] }, L = w.modules[l.current.currentModuleIndex], C = l.current.currentLessonIndex < (L?.lessons?.length || 0) - 1, U = l.current.currentModuleIndex < (w.modules?.length || 0) - 1, O = C || U, ne = z.current || { lipsyncLang: "en" };
|
|
7329
|
+
O ? u.current.speakText(R, {
|
|
7207
7330
|
lipsyncLang: ne.lipsyncLang,
|
|
7208
7331
|
onSpeechEnd: () => {
|
|
7209
7332
|
g.current && g.current();
|
|
@@ -7211,11 +7334,11 @@ const $e = ye(({
|
|
|
7211
7334
|
}) : u.current.speakText(R, {
|
|
7212
7335
|
lipsyncLang: ne.lipsyncLang,
|
|
7213
7336
|
onSpeechEnd: () => {
|
|
7214
|
-
|
|
7337
|
+
v.current && v.current();
|
|
7215
7338
|
}
|
|
7216
7339
|
});
|
|
7217
7340
|
}
|
|
7218
|
-
}, [e.lessonComplete]),
|
|
7341
|
+
}, [e.lessonComplete]), Y = M(() => {
|
|
7219
7342
|
l.current.curriculumCompleted = !0;
|
|
7220
7343
|
const b = E.current || { modules: [] };
|
|
7221
7344
|
if (c.current.onCurriculumComplete({
|
|
@@ -7232,9 +7355,9 @@ const $e = ye(({
|
|
|
7232
7355
|
u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!", { lipsyncLang: R.lipsyncLang });
|
|
7233
7356
|
}
|
|
7234
7357
|
}, [e.curriculumComplete]), S = M(() => {
|
|
7235
|
-
const b =
|
|
7358
|
+
const b = I();
|
|
7236
7359
|
l.current.isQuestionMode = !0, l.current.currentQuestionIndex = 0, l.current.totalQuestions = b?.questions?.length || 0;
|
|
7237
|
-
const R =
|
|
7360
|
+
const R = D();
|
|
7238
7361
|
if (R && c.current.onCustomAction({
|
|
7239
7362
|
type: "questionStart",
|
|
7240
7363
|
moduleIndex: l.current.currentModuleIndex,
|
|
@@ -7255,11 +7378,11 @@ const $e = ye(({
|
|
|
7255
7378
|
const w = z.current || { lipsyncLang: "en" };
|
|
7256
7379
|
u.current.speakText("Now let me ask you some questions to test your understanding.", { lipsyncLang: w.lipsyncLang });
|
|
7257
7380
|
}
|
|
7258
|
-
}, [e.questionStart,
|
|
7259
|
-
const b =
|
|
7381
|
+
}, [e.questionStart, I, D]), F = M(() => {
|
|
7382
|
+
const b = I();
|
|
7260
7383
|
if (l.current.currentQuestionIndex < (b?.questions?.length || 0) - 1) {
|
|
7261
7384
|
l.current.currentQuestionIndex += 1;
|
|
7262
|
-
const R =
|
|
7385
|
+
const R = D();
|
|
7263
7386
|
if (R && c.current.onCustomAction({
|
|
7264
7387
|
type: "nextQuestion",
|
|
7265
7388
|
moduleIndex: l.current.currentModuleIndex,
|
|
@@ -7286,8 +7409,8 @@ const $e = ye(({
|
|
|
7286
7409
|
});
|
|
7287
7410
|
}
|
|
7288
7411
|
} else
|
|
7289
|
-
|
|
7290
|
-
}, [e.nextQuestion,
|
|
7412
|
+
y.current && y.current();
|
|
7413
|
+
}, [e.nextQuestion, I, D]), W = M(() => {
|
|
7291
7414
|
const b = E.current || { modules: [] }, R = b.modules[l.current.currentModuleIndex];
|
|
7292
7415
|
l.current.currentLessonIndex < (R?.lessons?.length || 0) - 1 ? (l.current.currentLessonIndex += 1, l.current.currentQuestionIndex = 0, l.current.lessonCompleted = !1, l.current.isQuestionMode = !1, l.current.isTeaching = !1, l.current.score = 0, l.current.totalQuestions = 0, c.current.onCustomAction({
|
|
7293
7416
|
type: "lessonStart",
|
|
@@ -7297,9 +7420,9 @@ const $e = ye(({
|
|
|
7297
7420
|
type: "lessonStart",
|
|
7298
7421
|
moduleIndex: l.current.currentModuleIndex,
|
|
7299
7422
|
lessonIndex: l.current.currentLessonIndex
|
|
7300
|
-
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"), d.current && d.current())) :
|
|
7423
|
+
}), u.current && (u.current.setMood("happy"), u.current.setBodyMovement("idle"), d.current && d.current())) : v.current && v.current();
|
|
7301
7424
|
}, []), V = M(() => {
|
|
7302
|
-
const b =
|
|
7425
|
+
const b = I();
|
|
7303
7426
|
let R = null;
|
|
7304
7427
|
if (b?.avatar_script && b?.body) {
|
|
7305
7428
|
const w = b.avatar_script.trim(), L = b.body.trim(), C = w.match(/[.!?]$/) ? " " : ". ";
|
|
@@ -7329,12 +7452,12 @@ const $e = ye(({
|
|
|
7329
7452
|
}), u.current.speakText(R, {
|
|
7330
7453
|
lipsyncLang: L.lipsyncLang,
|
|
7331
7454
|
onSpeechEnd: () => {
|
|
7332
|
-
l.current.isTeaching = !1, b.questions && b.questions.length > 0 ? H.current && H.current() :
|
|
7455
|
+
l.current.isTeaching = !1, b.questions && b.questions.length > 0 ? H.current && H.current() : y.current && y.current();
|
|
7333
7456
|
}
|
|
7334
7457
|
});
|
|
7335
7458
|
}
|
|
7336
|
-
}, [e.teaching,
|
|
7337
|
-
const R =
|
|
7459
|
+
}, [e.teaching, I]), Q = M((b) => {
|
|
7460
|
+
const R = D(), w = P(b, R);
|
|
7338
7461
|
if (w && (l.current.score += 1), c.current.onQuestionAnswer({
|
|
7339
7462
|
moduleIndex: l.current.currentModuleIndex,
|
|
7340
7463
|
lessonIndex: l.current.currentLessonIndex,
|
|
@@ -7376,8 +7499,8 @@ const $e = ye(({
|
|
|
7376
7499
|
}
|
|
7377
7500
|
else
|
|
7378
7501
|
x.current && x.current();
|
|
7379
|
-
}, [e.correct, e.incorrect,
|
|
7380
|
-
const R =
|
|
7502
|
+
}, [e.correct, e.incorrect, D, P]), q = M((b) => {
|
|
7503
|
+
const R = D();
|
|
7381
7504
|
if (!b || typeof b != "object") {
|
|
7382
7505
|
console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");
|
|
7383
7506
|
return;
|
|
@@ -7404,31 +7527,31 @@ const $e = ye(({
|
|
|
7404
7527
|
testResult: w,
|
|
7405
7528
|
question: R
|
|
7406
7529
|
}), p.current && p.current(w);
|
|
7407
|
-
}, [
|
|
7530
|
+
}, [D, P]), le = M(() => {
|
|
7408
7531
|
l.current.currentModuleIndex = 0, l.current.currentLessonIndex = 0, l.current.currentQuestionIndex = 0, l.current.isTeaching = !1, l.current.isQuestionMode = !1, l.current.lessonCompleted = !1, l.current.curriculumCompleted = !1, l.current.score = 0, l.current.totalQuestions = 0;
|
|
7409
7532
|
}, []), me = M((b) => {
|
|
7410
7533
|
console.log("Avatar is ready!", b);
|
|
7411
|
-
const R =
|
|
7534
|
+
const R = I(), w = R?.avatar_script || R?.body;
|
|
7412
7535
|
h && w && setTimeout(() => {
|
|
7413
7536
|
d.current && d.current();
|
|
7414
7537
|
}, 50);
|
|
7415
|
-
}, [h,
|
|
7416
|
-
|
|
7417
|
-
d.current = V, g.current = W,
|
|
7538
|
+
}, [h, I]);
|
|
7539
|
+
He(() => {
|
|
7540
|
+
d.current = V, g.current = W, y.current = J, x.current = F, v.current = Y, H.current = S, p.current = Q;
|
|
7418
7541
|
}), fe(a, () => ({
|
|
7419
7542
|
// Curriculum control methods
|
|
7420
7543
|
startTeaching: V,
|
|
7421
7544
|
startQuestions: S,
|
|
7422
|
-
handleAnswerSelect:
|
|
7423
|
-
handleCodeTestResult:
|
|
7545
|
+
handleAnswerSelect: Q,
|
|
7546
|
+
handleCodeTestResult: q,
|
|
7424
7547
|
nextQuestion: F,
|
|
7425
7548
|
nextLesson: W,
|
|
7426
|
-
completeLesson:
|
|
7427
|
-
completeCurriculum:
|
|
7549
|
+
completeLesson: J,
|
|
7550
|
+
completeCurriculum: Y,
|
|
7428
7551
|
resetCurriculum: le,
|
|
7429
7552
|
getState: () => ({ ...l.current }),
|
|
7430
|
-
getCurrentQuestion: () =>
|
|
7431
|
-
getCurrentLesson: () =>
|
|
7553
|
+
getCurrentQuestion: () => D(),
|
|
7554
|
+
getCurrentLesson: () => I(),
|
|
7432
7555
|
// Direct access to avatar ref (always returns current value)
|
|
7433
7556
|
getAvatarRef: () => u.current,
|
|
7434
7557
|
// Convenience methods that delegate to avatar (always check current ref)
|
|
@@ -7476,8 +7599,8 @@ const $e = ye(({
|
|
|
7476
7599
|
handleResize: () => u.current?.handleResize(),
|
|
7477
7600
|
// Avatar readiness check (always returns current value)
|
|
7478
7601
|
isAvatarReady: () => u.current?.isReady || !1
|
|
7479
|
-
}), [V, S,
|
|
7480
|
-
const
|
|
7602
|
+
}), [V, S, Q, q, F, W, J, Y, le, D, I]);
|
|
7603
|
+
const _ = z.current || {
|
|
7481
7604
|
avatarUrl: "/avatars/brunette.glb",
|
|
7482
7605
|
avatarBody: "F",
|
|
7483
7606
|
mood: "happy",
|
|
@@ -7491,21 +7614,21 @@ const $e = ye(({
|
|
|
7491
7614
|
animations: e
|
|
7492
7615
|
};
|
|
7493
7616
|
return /* @__PURE__ */ se("div", { style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ se(
|
|
7494
|
-
|
|
7617
|
+
ke,
|
|
7495
7618
|
{
|
|
7496
7619
|
ref: u,
|
|
7497
|
-
avatarUrl:
|
|
7498
|
-
avatarBody:
|
|
7499
|
-
mood:
|
|
7500
|
-
ttsLang:
|
|
7501
|
-
ttsService:
|
|
7502
|
-
ttsVoice:
|
|
7503
|
-
ttsApiKey:
|
|
7504
|
-
bodyMovement:
|
|
7505
|
-
movementIntensity:
|
|
7506
|
-
showFullAvatar:
|
|
7620
|
+
avatarUrl: _.avatarUrl,
|
|
7621
|
+
avatarBody: _.avatarBody,
|
|
7622
|
+
mood: _.mood,
|
|
7623
|
+
ttsLang: _.ttsLang,
|
|
7624
|
+
ttsService: _.ttsService,
|
|
7625
|
+
ttsVoice: _.ttsVoice,
|
|
7626
|
+
ttsApiKey: _.ttsApiKey,
|
|
7627
|
+
bodyMovement: _.bodyMovement,
|
|
7628
|
+
movementIntensity: _.movementIntensity,
|
|
7629
|
+
showFullAvatar: _.showFullAvatar,
|
|
7507
7630
|
cameraView: "upper",
|
|
7508
|
-
animations:
|
|
7631
|
+
animations: _.animations,
|
|
7509
7632
|
onReady: me,
|
|
7510
7633
|
onLoading: () => {
|
|
7511
7634
|
},
|
|
@@ -7515,8 +7638,8 @@ const $e = ye(({
|
|
|
7515
7638
|
}
|
|
7516
7639
|
) });
|
|
7517
7640
|
});
|
|
7518
|
-
|
|
7519
|
-
const
|
|
7641
|
+
et.displayName = "CurriculumLearning";
|
|
7642
|
+
const we = {
|
|
7520
7643
|
// Code-based dance animations (no FBX required)
|
|
7521
7644
|
dance: {
|
|
7522
7645
|
name: "dance",
|
|
@@ -7619,14 +7742,14 @@ const ke = {
|
|
|
7619
7742
|
duration: 5e3,
|
|
7620
7743
|
description: "Excited, energetic movement"
|
|
7621
7744
|
}
|
|
7622
|
-
},
|
|
7745
|
+
}, ut = (B) => we[B] || null, dt = (B) => we.hasOwnProperty(B);
|
|
7623
7746
|
export {
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7747
|
+
et as CurriculumLearning,
|
|
7748
|
+
ke as TalkingHeadAvatar,
|
|
7749
|
+
$e as TalkingHeadComponent,
|
|
7750
|
+
we as animations,
|
|
7628
7751
|
xe as getActiveTTSConfig,
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7752
|
+
ut as getAnimation,
|
|
7753
|
+
ht as getVoiceOptions,
|
|
7754
|
+
dt as hasAnimation
|
|
7632
7755
|
};
|