@sage-rsc/talking-head-react 1.8.6 → 1.8.8
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 +3 -3
- package/dist/index.js +519 -517
- package/package.json +1 -1
- package/src/components/SimpleTalkingAvatar.jsx +43 -31
package/dist/index.cjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Q=require("react/jsx-runtime"),b=require("react"),mt=require("three"),pt=require("three/addons/controls/OrbitControls.js"),gt=require("three/addons/loaders/GLTFLoader.js"),ft=require("three/addons/loaders/DRACOLoader.js"),tt=require("three/addons/loaders/FBXLoader.js"),yt=require("three/addons/environments/RoomEnvironment.js"),xt=require("three/addons/libs/stats.module.js");var _e=typeof document<"u"?document.currentScript:null;function bt(W){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(W){for(const e in W)if(e!=="default"){const t=Object.getOwnPropertyDescriptor(W,e);Object.defineProperty(n,e,t.get?t:{enumerable:!0,get:()=>W[e]})}}return n.default=W,Object.freeze(n)}const A=bt(mt);let p,Le,Ce;const H=[0,0,0,0],U=new A.Vector3,Ze=new A.Vector3,ye=new A.Vector3,je=new A.Vector3;new A.Plane;new A.Ray;new A.Euler;const xe=new A.Quaternion,nt=new A.Quaternion,Ee=new A.Matrix4,Pe=new A.Matrix4;new A.Vector3;const Qe=new A.Vector3(0,0,1),Rt=new A.Vector3(1,0,0),At=new A.Vector3(0,1,0),vt=new A.Vector3(0,0,1);class It{constructor(n=null){this.opt=Object.assign({warmupMs:2e3,sensitivityFactor:1,movementFactor:1,isExcludes:!0,isPivots:!0,isLimits:!0,helperBoneColor1:16711680,helperBoneColor2:16238028,helperLinkColor1:16711680,helperLinkColor2:255,helperExcludesColor:11184895},n||{}),this.scene=null,this.armature=null,this.config=[],this.data=[],this.dict={},this.objectsUpdate=[],this.helpers={isActive:!1,isShowAll:!1,points:{bones:[],pivots:[],object:null},lines:{bones:[],object:null},excludes:{bones:[],deltaLocals:[],radii:[],objects:[]}},this.running=!1,this.timerMs=0}getOptionValue(n){return this.opt[n]}setOptionValue(n,e){this.opt[n]=e,this.helpers.isActive&&this.showHelpers()}getBoneNames(){return this.data.map(n=>n.name)}getValue(n,e){if(this.scene===null)throw new Error("Dynamic bones has not been setup yet.");if(!this.dict.hasOwnProperty(n))throw new Error("Dynamic bone '"+n+"' not found.");const t=this.dict[n];let o;if(e==="type")o=t.type;else if(e==="stiffness")o=t.k.every(s=>s===t.k[0])?t.k[0]:[...t.k];else if(e==="damping")o=t.c.every(s=>s===t.c[0])?t.c[0]:[...t.c];else if(e==="external")o=t.ext<1?t.ext:null;else if(e==="limits")o=t.limits?.map(s=>s===null?null:[...s]);else if(e==="deltaLocal")o=t.dl?[...t.dl]:null;else if(e==="excludes")o=t.excludes?[...t.excludes.map(s=>{const i={bone:s.bone.name.slice(),radius:s.radius};return s.deltaLocal&&(i.deltaLocal=[...s.deltaLocal]),i})]:null;else if(e==="deltaWorld")o=t.dw?[...t.dw]:null;else if(e==="pivot")o=t.pivot;else if(e==="helper")o=t.helper;else throw new Error("Unsupported property '"+e+"'.");return o}setValue(n,e,t){if(this.scene===null)throw new Error("Dynamic bones has not been setup yet.");if(!this.dict.hasOwnProperty(n))throw new Error("Dynamic bone '"+n+"' not found.");const o=this.dict[n];if(e==="type"){if(!t)throw new Error("Parameter 'type' not set.");if(typeof t!="string")throw new Error("Type must be a string.");switch(t){case"point":o.isPoint=!0,o.isX=!0,o.isY=!0,o.isZ=!0,o.isT=!1;break;case"link":o.isPoint=!1,o.isX=!0,o.isY=!1,o.isZ=!0,o.isT=!1;break;case"mix1":o.isPoint=!1,o.isX=!0,o.isY=!0,o.isZ=!0,o.isT=!1;break;case"mix2":o.isPoint=!1,o.isX=!0,o.isY=!1,o.isZ=!0,o.isT=!0;break;case"full":o.isPoint=!1,o.isX=!0,o.isY=!0,o.isZ=!0,o.isT=!0;break;default:throw new Error("Unknown type'"+t+"'.")}o.type=t.slice()}else if(e==="stiffness"){if(!t)throw new Error("Parameter 'stiffness' not set.");if(!Number.isNaN(t)&&t>=0)o.k=Array(4).fill(t);else if(Array.isArray(t)&&t.length===4&&t.every(s=>s>=0))o.k=[...t];else throw new Error("Stiffness must be a non-negative number or an array of four non-negative numbers.")}else if(e==="damping"){if(!t)throw new Error("Parameter 'damping' not set.");if(!Number.isNaN(t)&&t>=0)o.c=Array(4).fill(t);else if(Array.isArray(t)&&t.length===4&&t.every(s=>s>=0))o.c=[...t];else throw new Error("Damping must be a non-negative number or an array of four non-negative numbers.")}else if(e==="external")if(t==null)o.ext=1;else if(!Number.isNaN(t)&&t>=0&&t<=1)o.ext=t;else throw new Error("External (if set) must be a number between [0,1].");else if(e==="limits")if(t==null)o.limits=null;else{if(!Array.isArray(t)||t.length!==4)throw new Error("Limits (if set) must null, or an array of four arrays.");if(!t.every(s=>s===null||Array.isArray(s)&&s.length===2&&(s[0]===null||!Number.isNaN(s[0]))&&(s[1]===null||!Number.isNaN(s))))throw new Error("Limit values must be null or numbers.");o.limits=[t[0]?[...t[0]]:null,t[1]?[...t[1]]:null,t[2]?[...t[2]]:null,t[3]?[...t[3]]:null]}else if(e==="excludes"){if(t==null)o.excludes=null;else{if(!Array.isArray(t))throw new Error("Excludes (if set) must null, or an array.");o.excludes=[],t.forEach((s,i)=>{if(!s.bone)throw new Error("Bone not specified in #"+i+" exclude.");if(typeof s.bone!="string"||s.bone.length===0)throw new Error("Bone name must be a non-empty string in #"+i+" exclude.");const a=this.armature.getObjectByName(s.bone);if(!a)throw new Error("Bone '"+s.bone+"' not found in #"+i+" exclude.");if(Number.isNaN(s.radius)&&s.radius>=0)throw new Error("Radius must be a non-negative number in #"+i+" exclude.");const c={bone:a,radius:s.radius,radiusSq:s.radius*s.radius,deltaLocal:null};if(s.deltaLocal){if(!Array.isArray(s.deltaLocal)||s.deltaLocal.length!==3||s.deltaLocal.some(l=>Number.isNaN(l)))throw new Error("deltaLocal must be an array of three numbers in #"+i+" exclude.");c.deltaLocal=[...s.deltaLocal]}o.excludes.push(c)})}this.showHelpers()}else if(e==="helper"){if(t==null)o.helper=null;else{if(t!==!1&&t!==!0)throw new Error("Helper, if set, must be false or true.");o.helper=t}this.showHelpers()}else if(e==="pivot")if(t==null)o.pivot=null;else{if(t!==!1&&t!==!0)throw new Error("Pivot, if set, must be false or true.");if(t===!0&&o.type===0)throw new Error("Point type bone can't be a pivot.");o.pivot=t}else if(e==="deltaLocal")if(t==null)o.dl=null;else{if(!Array.isArray(t)||t.length!==3)throw new Error("deltaLocal, is set, must be an array of three numbers.");if(!t.every(s=>!Number.isNaN(s)))throw new Error("deltaLocal values must be numbers.");o.dl=[...t]}else if(e==="deltaWorld")if(t==null)o.dw=null;else{if(!Array.isArray(t)||t.length!==3)throw new Error("deltaWorld, is set, must be an array of three values.");if(!t.every(s=>!Number.isNaN(s)))throw new Error("deltaWorld values must be numbers.");o.dw=[...t]}else throw new Error("Unsupported property "+e)}getConfig(){return this.data.map(n=>{const e={bone:n.name.slice()};return["type","stiffness","damping","external","deltaLocal","deltaWorld","limits","excludes","pivot","helper"].forEach(t=>{p=this.getValue(n.name,t),p&&(e[t]=p)}),e})}sortBones(){if(this.scene===null)throw new Error("Dynamic bones has not been setup yet.");let n=0;const e=new WeakMap;this.armature.traverse(i=>{e.has(i)||(e.set(i,n),n++)}),this.data.sort((i,a)=>e.get(i.bone)-e.get(a.bone)),this.data.forEach(i=>{p=this.dict[i.boneParent.name],p&&(p.children||(p.children=[]),p.children.push(i))}),this.objectsUpdate=[];const t=new WeakSet,o=i=>i.parent?.isBone?[i,...o(i.parent)]:[i],s=i=>{o(i).forEach(c=>{t.has(c)||(this.objectsUpdate.push(c),t.add(c))})};this.data.forEach(i=>{s(i.bone),i.excludes&&i.excludes.forEach(a=>{s(a.bone)})}),this.objectsUpdate.sort((i,a)=>e.get(i)-e.get(a))}setup(n,e,t){this.dispose();const o=(s,i)=>{if(!s)throw this.dispose(),new Error(i)};o(n?.isScene,"First parameter must be Scene."),this.scene=n,o(e?.isObject3D,"Second parameter must be the armature Object3D."),this.armature=e,o(Array.isArray(t),"Third parameter must be an array of bone configs."),this.config=t,this.config.forEach((s,i)=>{const a="Config item #"+i+": ";o(s.bone,a+"Bone not specified.");const c=s.bone;o(typeof c=="string"&&c.length>0,a+"Bone name must be a non-empty string.");const l=this.armature.getObjectByName(c);o(l,a+"Bone '"+c+"' not found."),o(l.parent?.isBone,a+"Bone must have a parent bone."),o(this.data.every(r=>r.bone!==l),a+"Bone '"+c+"' already exists."),l.updateMatrixWorld(!0);const u={name:c,bone:l,boneParent:l.parent,vBasis:l.position.clone(),vWorld:l.parent.getWorldPosition(U).clone(),qBasis:l.parent.quaternion.clone(),l:l.position.length(),p:[0,0,0,0],v:[0,0,0,0],a:[0,0,0,0],ev:[0,0,0,0],ea:[0,0,0,0]};u.boneParent.matrixWorld.decompose(U,xe,ye),U.copy(Qe).applyQuaternion(xe).setY(0).normalize(),xe.premultiply(nt.setFromUnitVectors(Qe,U).invert()).normalize(),u.qWorldInverseYaw=xe.clone().normalize(),this.data.push(u),this.dict[c]=u;try{this.setValue(c,"type",s.type),this.setValue(c,"stiffness",s.stiffness),this.setValue(c,"damping",s.damping),this.setValue(c,"external",s.external),this.setValue(c,"limits",s.limits),this.setValue(c,"excludes",s.excludes),this.setValue(c,"deltaLocal",s.deltaLocal),this.setValue(c,"deltaWorld",s.deltaWorld),this.setValue(c,"pivot",s.pivot),this.setValue(c,"helper",s.helper)}catch(r){o(!1,a+r)}}),this.sortBones(),this.start()}update(n){if(!this.running)return;let e,t,o,s,i;for(this.timerMs+=n,n>1e3&&(this.timerMs=0),n/=1e3,e=0,o=this.objectsUpdate.length;e<o;e++)i=this.objectsUpdate[e],i.updateMatrix(),i.parent===null?i.matrixWorld.copy(i.matrix):i.matrixWorld.multiplyMatrices(i.parent.matrixWorld,i.matrix),i.matrixWorldNeedsUpdate=!1;for(e=0,o=this.data.length;e<o;e++){if(i=this.data[e],U.copy(i.vWorld),Ee.copy(i.boneParent.matrixWorld),Pe.copy(Ee).invert(),i.vWorld.setFromMatrixPosition(Ee),U.applyMatrix4(Pe),U.length()>.5&&(console.info("Info: Unrealistic jump of "+U.length().toFixed(2)+" meters."),U.setLength(.5)),U.applyQuaternion(i.bone.quaternion),H[0]=U.x,H[1]=U.y,H[2]=-U.z,H[3]=U.length()/3,i.children)for(t=0,s=i.children.length;t<s;t++)p=i.children[t],H[0]-=p.v[0]*n/3,H[1]-=p.v[1]*n/3,H[2]+=p.v[2]*n/3,H[3]-=p.v[3]*n/3;if(p=this.opt.sensitivityFactor,H[0]*=i.ext*p,H[1]*=i.ext*p,H[2]*=i.ext*p,H[3]*=i.ext*p,i.isX&&(p=H[0]/n,i.ea[0]=(p-i.ev[0])/n,i.ev[0]=p,i.a[0]=-i.k[0]*i.p[0]-i.c[0]*i.v[0]-i.ea[0],i.p[0]+=i.v[0]*n+i.a[0]*n*n/2+H[0],p=i.v[0]+i.a[0]*n/2,p=-i.k[0]*i.p[0]-i.c[0]*p-i.ea[0],i.v[0]=i.v[0]+(p+i.a[0])*n/2),i.isY&&(p=H[1]/n,i.ea[1]=(p-i.ev[1])/n,i.ev[1]=p,i.a[1]=-i.k[1]*i.p[1]-i.c[1]*i.v[1]-i.ea[1],i.p[1]+=i.v[1]*n+i.a[1]*n*n/2+H[1],p=i.v[1]+i.a[1]*n/2,p=-i.k[1]*i.p[1]-i.c[1]*p-i.ea[1],i.v[1]=i.v[1]+(p+i.a[1])*n/2),i.isZ&&(p=H[2]/n,i.ea[2]=(p-i.ev[2])/n,i.ev[2]=p,i.a[2]=-i.k[2]*i.p[2]-i.c[2]*i.v[2]-i.ea[2],i.p[2]+=i.v[2]*n+i.a[2]*n*n/2+H[2],p=i.v[2]+i.a[2]*n/2,p=-i.k[2]*i.p[2]-i.c[2]*p-i.ea[2],i.v[2]=i.v[2]+(p+i.a[2])*n/2),i.isT&&(p=H[3]/n,i.ea[3]=(p-i.ev[3])/n,i.ev[3]=p,i.a[3]=-i.k[3]*i.p[3]-i.c[3]*i.v[3]-i.ea[3],i.p[3]+=i.v[3]*n+i.a[3]*n*n/2+H[3],p=i.v[3]+i.a[3]*n/2,p=-i.k[3]*i.p[3]-i.c[3]*p-i.ea[3],i.v[3]=i.v[3]+(p+i.a[3])*n/2),this.timerMs<this.opt.warmupMs&&(i.v[0]*=1e-4,i.p[0]*=1e-4,i.v[1]*=1e-4,i.p[1]*=1e-4,i.v[2]*=1e-4,i.p[2]*=1e-4,i.v[3]*=1e-4,i.p[3]*=1e-4),H[0]=i.p[0],H[1]=i.p[1],H[2]=i.p[2],H[3]=i.p[3],p=this.opt.movementFactor,H[0]*=p,H[1]*=p,H[2]*=p,H[3]*=p,i.dl&&(p=i.dl,H[0]+=p[0],H[1]+=p[1],H[2]+=p[2]),i.dw&&(p=i.dw,U.set(i.vBasis.x+H[0],i.vBasis.y+H[1],i.vBasis.z+H[2]),U.applyMatrix4(Ee),U.x+=p[0],U.y+=p[1],U.z+=p[2],U.applyMatrix4(Pe),H[0]+=U.x-i.vBasis.x,H[1]+=U.y-i.vBasis.y,H[2]+=U.z-i.vBasis.z),i.limits&&this.opt.isLimits&&(p=i.limits,p[0]&&(p[0][0]!==null&&H[0]<p[0][0]&&(H[0]=p[0][0]),p[0][1]!==null&&H[0]>p[0][1]&&(H[0]=p[0][1])),p[1]&&(p[1][0]!==null&&H[1]<p[1][0]&&(H[1]=p[1][0]),p[1][1]!==null&&H[1]>p[1][1]&&(H[1]=p[1][1])),p[2]&&(p[2][0]!==null&&H[2]<p[2][0]&&(H[2]=p[2][0]),p[2][1]!==null&&H[2]>p[2][1]&&(H[2]=p[2][1])),p[3]&&(p[3][0]!==null&&H[3]<p[3][0]&&(H[3]=p[3][0]),p[3][1]!==null&&H[3]>p[3][1]&&(H[3]=p[3][1]))),i.isPoint)i.bone.position.set(i.vBasis.x+H[0],i.vBasis.y+H[1],i.vBasis.z-H[2]);else if(i.boneParent.quaternion.copy(i.qBasis),i.pivot&&this.opt.isPivots&&(i.boneParent.updateWorldMatrix(!1,!1),i.boneParent.matrixWorld.decompose(U,xe,ye),U.copy(Qe).applyQuaternion(xe).setY(0).normalize(),xe.premultiply(nt.setFromUnitVectors(Qe,U).invert()).normalize(),i.boneParent.quaternion.multiply(xe.invert()),i.boneParent.quaternion.multiply(i.qWorldInverseYaw)),i.isZ&&(p=Math.atan(H[0]/i.l),xe.setFromAxisAngle(vt,-p),i.boneParent.quaternion.multiply(xe)),i.isY&&(p=i.l/3,p=p*Math.tanh(H[1]/p),i.bone.position.setLength(i.l+p)),i.isX&&(p=Math.atan(H[2]/i.l),xe.setFromAxisAngle(Rt,-p),i.boneParent.quaternion.multiply(xe)),i.isT&&(p=1.5*Math.tanh(H[3]*1.5),xe.setFromAxisAngle(At,-p),i.boneParent.quaternion.multiply(xe)),i.boneParent.updateWorldMatrix(!1,!0),i.excludes&&this.opt.isExcludes)for(t=0,s=i.excludes.length;t<s;t++)p=i.excludes[t],ye.set(0,0,0),p.deltaLocal&&(ye.x+=p.deltaLocal[0],ye.y+=p.deltaLocal[1],ye.z+=p.deltaLocal[2]),ye.applyMatrix4(p.bone.matrixWorld),Pe.copy(i.boneParent.matrixWorld).invert(),ye.applyMatrix4(Pe),U.copy(i.bone.position),!(U.distanceToSquared(ye)>=p.radiusSq)&&(Ce=U.length(),Le=ye.length(),!(Le>p.radius+Ce)&&(Le<Math.abs(p.radius-Ce)||(Le=(Le*Le+Ce*Ce-p.radiusSq)/(2*Le),ye.normalize(),je.copy(ye).multiplyScalar(Le),Le=Math.sqrt(Ce*Ce-Le*Le),U.subVectors(U,je).projectOnPlane(ye).normalize().multiplyScalar(Le),Ze.subVectors(i.vBasis,je).projectOnPlane(ye).normalize(),Ce=Ze.dot(U),Ce<0&&(Ce=Math.sqrt(Le*Le-Ce*Ce),Ze.multiplyScalar(Ce),U.add(Ze)),U.add(je).normalize(),ye.copy(i.bone.position).normalize(),xe.setFromUnitVectors(ye,U),i.boneParent.quaternion.premultiply(xe),i.boneParent.updateWorldMatrix(!1,!0))))}this.helpers.isActive&&this.updateHelpers()}showHelpers(n){if(this.hideHelpers(),this.helpers.isShowAll=n===void 0?this.helpers.isShowAll:n===!0,p=this.helpers,this.data.forEach(e=>{(this.helpers.isShowAll||e.helper===!0)&&(p.points.bones.push(e.bone),p.points.pivots.push(e.pivot),e.type!==0&&p.lines.bones.push(e.bone),e.excludes&&e.excludes.forEach(t=>{let o=!1;for(let s=0;s<p.excludes.bones.length;s++)if(p.excludes.bones[s]===t.bone&&p.excludes.radii[s]===t.radius&&!(p.excludes.deltaLocals[s]===null&&t.deltaLocal!==null)&&!(p.excludes.deltaLocals[s]!==null&&t.deltaLocal===null)&&!(p.excludes.deltaLocals[s]!==null&&p.excludes.deltaLocals[s].some((i,a)=>i!==t.deltaLocal[a]))){o=!0;break}o||(p.excludes.bones.push(t.bone),p.excludes.radii.push(t.radius),p.excludes.deltaLocals.push(t.deltaLocal?[...t.deltaLocal]:null),p.excludes.objects.push(null))}))}),p=this.helpers.excludes,this.opt.isExcludes&&p.bones.length&&p.bones.forEach((e,t)=>{const o=new A.SphereGeometry(p.radii[t],6,6),s=new A.MeshBasicMaterial({depthTest:!1,depthWrite:!1,toneMapped:!1,transparent:!0,wireframe:!0,color:this.opt.helperExcludesColor});p.objects[t]=new A.Mesh(o,s),p.objects[t].renderOrder=997,e.add(p.objects[t]),p.deltaLocals[t]&&p.objects[t].position.set(p.deltaLocals[t][0],p.deltaLocals[t][1],p.deltaLocals[t][2])}),p=this.helpers.points,p.bones.length){this.helpers.isActive=!0;const e=new A.BufferGeometry,t=p.bones.map(c=>[0,0,0]).flat();e.setAttribute("position",new A.Float32BufferAttribute(t,3));const o=new A.Color(this.opt.helperBoneColor1),s=new A.Color(this.opt.helperBoneColor2),i=p.pivots.map(c=>c&&this.opt.isPivots?[s.r,s.g,s.b]:[o.r,o.g,o.b]).flat();e.setAttribute("color",new A.Float32BufferAttribute(i,3));const a=new A.PointsMaterial({depthTest:!1,depthWrite:!1,toneMapped:!1,transparent:!0,size:.2,vertexColors:!0});p.object=new A.Points(e,a),p.object.renderOrder=998,p.object.matrix=this.armature.matrixWorld,p.object.matrixAutoUpdate=!1,this.scene.add(p.object)}if(p=this.helpers.lines,p.bones.length){const e=new A.BufferGeometry,t=p.bones.map(c=>[0,0,0,0,0,0]).flat();e.setAttribute("position",new A.Float32BufferAttribute(t,3));const o=new A.Color(this.opt.helperLinkColor1),s=new A.Color(this.opt.helperLinkColor2),i=p.bones.map(c=>[o.r,o.g,o.b,s.r,s.g,s.b]).flat();e.setAttribute("color",new A.Float32BufferAttribute(i,3));const a=new A.LineBasicMaterial({vertexColors:!0,depthTest:!1,depthWrite:!1,toneMapped:!1,transparent:!0});p.object=new A.LineSegments(e,a),p.object.renderOrder=999,p.object.matrix=this.armature.matrixWorld,p.object.matrixAutoUpdate=!1,this.scene.add(p.object)}}updateHelpers(){if(p=this.helpers.points,p.bones.length){Pe.copy(this.armature.matrixWorld).invert();const n=p.object.geometry.getAttribute("position");for(let e=0,t=p.bones.length;e<t;e++)Ee.multiplyMatrices(Pe,p.bones[e].matrixWorld),U.setFromMatrixPosition(Ee),n.setXYZ(e,U.x,U.y,U.z);n.needsUpdate=!0,p.object.updateMatrixWorld()}if(p=this.helpers.lines,p.bones.length){Pe.copy(this.armature.matrixWorld).invert();const n=p.object.geometry.getAttribute("position");for(let e=0,t=0,o=p.bones.length;e<o;e++,t+=2)Ee.multiplyMatrices(Pe,p.bones[e].matrixWorld),U.setFromMatrixPosition(Ee),n.setXYZ(t,U.x,U.y,U.z),Ee.multiplyMatrices(Pe,p.bones[e].parent.matrixWorld),U.setFromMatrixPosition(Ee),n.setXYZ(t+1,U.x,U.y,U.z);n.needsUpdate=!0,p.object.updateMatrixWorld()}}hideHelpers(){[this.helpers.points,this.helpers.lines].forEach(n=>{n.bones=[],n.object&&(this.scene.remove(n.object),n.object.geometry.dispose(),n.object.material.dispose(),n.object=null)}),p=this.helpers.excludes,p.objects.forEach((n,e)=>{n&&(p.bones[e].remove(n),n.geometry.dispose(),n.material.dispose())}),p.bones=[],p.deltaLocals=[],p.radii=[],p.objects=[],this.helpers.isActive=!1}start(){this.data.length&&(this.running=!0,this.timerMs=0,this.showHelpers())}stop(){this.running=!1,this.hideHelpers();for(let n=0,e=this.data.length;n<e;n++){const t=this.data[n];t.bone.position.copy(t.vBasis),t.boneParent.quaternion.copy(t.qBasis)}}dispose(){this.stop(),this.scene=null,this.armature=null,this.config=[],this.data=[],this.dict={},this.objectsUpdate=[],this.timerMs=0}}class Lt{constructor(n){this.audioContext=n,this.analyzer=null,this.dataArray=null,this.bufferLength=0}async analyzeAudio(n,e){const t=n.sampleRate,o=n.duration,s=n.getChannelData(0),i=this.extractAudioFeatures(s,t);return this.generateTimingData(i,e,o)}extractAudioFeatures(n,e){const t={energy:[],spectralCentroid:[],zeroCrossingRate:[],mfcc:[],onsets:[],phonemeBoundaries:[]},o=1024,s=512,i=Math.floor((n.length-o)/s)+1;for(let a=0;a<i;a++){const c=a*s,l=Math.min(c+o,n.length),u=n.slice(c,l),r=this.calculateEnergy(u);t.energy.push(r);const h=this.calculateSpectralCentroid(u);t.spectralCentroid.push(h);const d=this.calculateZeroCrossingRate(u);t.zeroCrossingRate.push(d);const g=this.calculateMFCC(u);t.mfcc.push(g)}return t.onsets=this.detectOnsets(t.energy),t.phonemeBoundaries=this.detectPhonemeBoundaries(t),t}calculateEnergy(n){let e=0;for(let t=0;t<n.length;t++)e+=n[t]*n[t];return e/n.length}calculateSpectralCentroid(n){const e=this.fft(n);let t=0,o=0;for(let s=0;s<e.length/2;s++){const i=Math.sqrt(e[s*2]*e[s*2]+e[s*2+1]*e[s*2+1]);t+=s*i,o+=i}return o>0?t/o:0}calculateZeroCrossingRate(n){let e=0;for(let t=1;t<n.length;t++)n[t]>=0!=n[t-1]>=0&&e++;return e/(n.length-1)}calculateMFCC(n){const e=this.fft(n),t=[];for(let o=0;o<13;o++){let s=0;for(let i=0;i<e.length/2;i++){const a=Math.sqrt(e[i*2]*e[i*2]+e[i*2+1]*e[i*2+1]);s+=a*Math.cos(Math.PI*o*(i+.5)/(e.length/2))}t.push(s)}return t}fft(n){const e=n.length,t=new Float32Array(e*2);for(let o=0;o<e;o++)t[o*2]=n[o],t[o*2+1]=0;for(let o=1,s=0;o<e;o++){let i=e>>1;for(;s&i;)s^=i,i>>=1;if(s^=i,o<s){const a=t[o*2],c=t[o*2+1];t[o*2]=t[s*2],t[o*2+1]=t[s*2+1],t[s*2]=a,t[s*2+1]=c}}for(let o=2;o<=e;o<<=1){const s=-2*Math.PI/o,i=Math.cos(s),a=Math.sin(s);for(let c=0;c<e;c+=o){let l=1,u=0;for(let r=0;r<o/2;r++){const h=t[(c+r)*2],d=t[(c+r)*2+1],g=t[(c+r+o/2)*2]*l-t[(c+r+o/2)*2+1]*u,R=t[(c+r+o/2)*2]*u+t[(c+r+o/2)*2+1]*l;t[(c+r)*2]=h+g,t[(c+r)*2+1]=d+R,t[(c+r+o/2)*2]=h-g,t[(c+r+o/2)*2+1]=d-R;const x=l*i-u*a,w=l*a+u*i;l=x,u=w}}}return t}detectOnsets(n){const e=[];let s=-.1;for(let i=1;i<n.length;i++){const a=n[i]-n[i-1],c=i*.023;a>.1&&c-s>.1&&(e.push(c),s=c)}return e}detectPhonemeBoundaries(n){const e=[],{energy:t,spectralCentroid:o,zeroCrossingRate:s}=n;for(let i=1;i<t.length;i++){const a=i*.023,c=Math.abs(t[i]-t[i-1]),l=Math.abs(o[i]-o[i-1]),u=Math.abs(s[i]-s[i-1]);c+l*.1+u*.5>.2&&e.push(a)}return e}generateTimingData(n,e,t){const o=e.toLowerCase().split(/\s+/);n.phonemeBoundaries,n.onsets;const s=[];let i=0;for(let c=0;c<o.length;c++){const l=o[c],u=this.estimateWordDuration(l,t/o.length);s.push({word:l,startTime:i,endTime:i+u,duration:u}),i+=u}const a=this.generateVisemeTimings(n,e,t);return{words:s,visemes:a,duration:t,features:n}}estimateWordDuration(n,e){const t=Math.max(.5,Math.min(2,n.length/5)),o=this.getWordComplexity(n);return e*t*o}getWordComplexity(n){const e=(n.match(/[bcdfghjklmnpqrstvwxyz]{2,}/g)||[]).length,t=(n.match(/[aeiou]{2,}/g)||[]).length;return 1+e*.2+t*.1}generateVisemeTimings(n,e,t){const o=[],s=n.phonemeBoundaries;n.onsets;const i=this.textToVisemes(e);let a=0,c=0;for(let l=0;l<s.length&&a<i.length;l++){const u=s[l],r=i[a],h=n.energy[Math.floor(u/.023)]||0,d=this.calculateVisemeDuration(r,h);o.push({viseme:r,startTime:c,endTime:c+d,duration:d,intensity:Math.min(1,h*2)}),c+=d,a++}for(;a<i.length;){const l=i[a],u=this.calculateVisemeDuration(l,.5);o.push({viseme:l,startTime:c,endTime:c+u,duration:u,intensity:.6}),c+=u,a++}return o}textToVisemes(n){const e={a:"aa",e:"E",i:"I",o:"O",u:"U",ae:"aa",ai:"aa",au:"O",ea:"E",ee:"E",ei:"E",ie:"I",oa:"O",oo:"U",ou:"U",b:"PP",p:"PP",m:"PP",f:"FF",v:"FF",th:"SS",s:"SS",z:"SS",sh:"SS",ch:"SS",d:"DD",t:"DD",n:"nn",l:"nn",k:"kk",g:"kk",ng:"kk",r:"RR",w:"RR",y:"I",h:"kk"},t=[],o=n.toLowerCase().replace(/[^a-z\s]/g,"").split(/\s+/);for(const s of o){let i=0;for(;i<s.length;){let a=!1;for(let c=3;c>=2;c--){const l=s.substr(i,c);if(e[l]){t.push(e[l]),i+=c,a=!0;break}}if(!a){const c=s[i];e[c]&&t.push(e[c]),i++}}}return t}calculateVisemeDuration(n,e){const o={aa:.15,E:.12,I:.1,O:.14,U:.13,PP:.08,FF:.1,SS:.12,DD:.11,kk:.09,nn:.1,RR:.11}[n]||.1,s=.5+e*.5;return o*s}}class St{constructor(){this.rules={A:["[A] =aa"," [ARE] =aa RR"," [AR]O=aa RR","[AR]#=E RR"," ^[AS]#=E SS","[A]WA=aa","[AW]=aa"," :[ANY]=E nn I","[A]^+#=E","#:[ALLY]=aa nn I"," [AL]#=aa nn","[AGAIN]=aa kk E nn","#:[AG]E=I kk","[A]^+:#=aa",":[A]^+ =E","[A]^%=E"," [ARR]=aa RR","[ARR]=aa RR"," :[AR] =aa RR","[AR] =E","[AR]=aa RR","[AIR]=E RR","[AI]=E","[AY]=E","[AU]=aa","#:[AL] =aa nn","#:[ALS] =aa nn SS","[ALK]=aa kk","[AL]^=aa nn"," :[ABLE]=E PP aa nn","[ABLE]=aa PP aa nn","[ANG]+=E nn kk","[A]=aa"],B:[" [BE]^#=PP I","[BEING]=PP I I nn"," [BOTH] =PP O TH"," [BUS]#=PP I SS","[BUIL]=PP I nn","[B]=PP"],C:[" [CH]^=kk","^E[CH]=kk","[CH]=CH"," S[CI]#=SS aa","[CI]A=SS","[CI]O=SS","[CI]EN=SS","[C]+=SS","[CK]=kk","[COM]%=kk aa PP","[C]=kk"],D:["#:[DED] =DD I DD",".E[D] =DD","#^:E[D] =DD"," [DE]^#=DD I"," [DO] =DD U"," [DOES]=DD aa SS"," [DOING]=DD U I nn"," [DOW]=DD aa","[DU]A=kk U","[D]=DD"],E:["#:[E] =","'^:[E] ="," :[E] =I","#[ED] =DD","#:[E]D =","[EV]ER=E FF","[E]^%=I","[ERI]#=I RR I","[ERI]=E RR I","#:[ER]#=E","[ER]#=E RR","[ER]=E"," [EVEN]=I FF E nn","#:[E]W=","@[EW]=U","[EW]=I U","[E]O=I","#:&[ES] =I SS","#:[E]S =","#:[ELY] =nn I","#:[EMENT]=PP E nn DD","[EFUL]=FF U nn","[EE]=I","[EARN]=E nn"," [EAR]^=E","[EAD]=E DD","#:[EA] =I aa","[EA]SU=E","[EA]=I","[EIGH]=E","[EI]=I"," [EYE]=aa","[EY]=I","[EU]=I U","[E]=E"],F:["[FUL]=FF U nn","[F]=FF"],G:["[GIV]=kk I FF"," [G]I^=kk","[GE]T=kk E","SU[GGES]=kk kk E SS","[GG]=kk"," B#[G]=kk","[G]+=kk","[GREAT]=kk RR E DD","#[GH]=","[G]=kk"],H:[" [HAV]=I aa FF"," [HERE]=I I RR"," [HOUR]=aa EE","[HOW]=I aa","[H]#=I","[H]="],I:[" [IN]=I nn"," [I] =aa","[IN]D=aa nn","[IER]=I E","#:R[IED] =I DD","[IED] =aa DD","[IEN]=I E nn","[IE]T=aa E"," :[I]%=aa","[I]%=I","[IE]=I","[I]^+:#=I","[IR]#=aa RR","[IZ]%=aa SS","[IS]%=aa SS","[I]D%=aa","+^[I]^+=I","[I]T%=aa","#^:[I]^+=I","[I]^+=aa","[IR]=E","[IGH]=aa","[ILD]=aa nn DD","[IGN] =aa nn","[IGN]^=aa nn","[IGN]%=aa nn","[IQUE]=I kk","[I]=I"],J:["[J]=kk"],K:[" [K]N=","[K]=kk"],L:["[LO]C#=nn O","L[L]=","#^:[L]%=aa nn","[LEAD]=nn I DD","[L]=nn"],M:["[MOV]=PP U FF","[M]=PP"],N:["E[NG]+=nn kk","[NG]R=nn kk","[NG]#=nn kk","[NGL]%=nn kk aa nn","[NG]=nn","[NK]=nn kk"," [NOW] =nn aa","[N]=nn"],O:["[OF] =aa FF","[OROUGH]=E O","#:[OR] =E","#:[ORS] =E SS","[OR]=aa RR"," [ONE]=FF aa nn","[OW]=O"," [OVER]=O FF E","[OV]=aa FF","[O]^%=O","[O]^EN=O","[O]^I#=O","[OL]D=O nn","[OUGHT]=aa DD","[OUGH]=aa FF"," [OU]=aa","H[OU]S#=aa","[OUS]=aa SS","[OUR]=aa RR","[OULD]=U DD","^[OU]^L=aa","[OUP]=U OO","[OU]=aa","[OY]=O","[OING]=O I nn","[OI]=O","[OOR]=aa RR","[OOK]=U kk","[OOD]=U DD","[OO]=U","[O]E=O","[O] =O","[OA]=O"," [ONLY]=O nn nn I"," [ONCE]=FF aa nn SS","[ON'T]=O nn DD","C[O]N=aa","[O]NG=aa"," ^:[O]N=aa","I[ON]=aa nn","#:[ON] =aa nn","#^[ON]=aa nn","[O]ST =O","[OF]^=aa FF","[OTHER]=aa TH E","[OSS] =aa SS","#^:[OM]=aa PP","[O]=aa"],P:["[PH]=FF","[PEOP]=PP I PP","[POW]=PP aa","[PUT] =PP U DD","[P]=PP"],Q:["[QUAR]=kk FF aa RR","[QU]=kk FF","[Q]=kk"],R:[" [RE]^#=RR I","[R]=RR"],S:["[SH]=SS","#[SION]=SS aa nn","[SOME]=SS aa PP","#[SUR]#=SS E","[SUR]#=SS E","#[SU]#=SS U","#[SSU]#=SS U","#[SED] =SS DD","#[S]#=SS","[SAID]=SS E DD","^[SION]=SS aa nn","[S]S=",".[S] =SS","#:.E[S] =SS","#^:##[S] =SS","#^:#[S] =SS","U[S] =SS"," :#[S] =SS"," [SCH]=SS kk","[S]C+=","#[SM]=SS PP","#[SN]'=SS aa nn","[S]=SS"],T:[" [THE] =TH aa","[TO] =DD U","[THAT] =TH aa DD"," [THIS] =TH I SS"," [THEY]=TH E"," [THERE]=TH E RR","[THER]=TH E","[THEIR]=TH E RR"," [THAN] =TH aa nn"," [THEM] =TH E PP","[THESE] =TH I SS"," [THEN]=TH E nn","[THROUGH]=TH RR U","[THOSE]=TH O SS","[THOUGH] =TH O"," [THUS]=TH aa SS","[TH]=TH","#:[TED] =DD I DD","S[TI]#N=CH","[TI]O=SS","[TI]A=SS","[TIEN]=SS aa nn","[TUR]#=CH E","[TU]A=CH U"," [TWO]=DD U","[T]=DD"],U:[" [UN]I=I U nn"," [UN]=aa nn"," [UPON]=aa PP aa nn","@[UR]#=U RR","[UR]#=I U RR","[UR]=E","[U]^ =aa","[U]^^=aa","[UY]=aa"," G[U]#=","G[U]%=","G[U]#=FF","#N[U]=I U","@[U]=I","[U]=I U"],V:["[VIEW]=FF I U","[V]=FF"],W:[" [WERE]=FF E","[WA]S=FF aa","[WA]T=FF aa","[WHERE]=FF E RR","[WHAT]=FF aa DD","[WHOL]=I O nn","[WHO]=I U","[WH]=FF","[WAR]=FF aa RR","[WOR]^=FF E","[WR]=RR","[W]=FF"],X:[" [X]=SS","[X]=kk SS"],Y:["[YOUNG]=I aa nn"," [YOU]=I U"," [YES]=I E SS"," [Y]=I","#^:[Y] =I","#^:[Y]I=I"," :[Y] =aa"," :[Y]#=aa"," :[Y]^+:#=I"," :[Y]^#=I","[Y]=I"],Z:["[Z]=SS"]};const n={"#":"[AEIOUY]+",".":"[BDVGJLMNRWZ]","%":"(?:ER|E|ES|ED|ING|ELY)","&":"(?:[SCGZXJ]|CH|SH)","@":"(?:[TSRDLZNJ]|TH|CH|SH)","^":"[BCDFGHJKLMNPQRSTVWXZ]","+":"[EIY]",":":"[BCDFGHJKLMNPQRSTVWXZ]*"," ":"\\b"};Object.keys(this.rules).forEach(e=>{this.rules[e]=this.rules[e].map(t=>{const o=t.indexOf("["),s=t.indexOf("]"),i=t.indexOf("="),a=t.substring(0,o),c=t.substring(o+1,s),l=t.substring(s+1,i),u=t.substring(i+1),r={regex:"",move:0,visemes:[]};let h="";h+=[...a].map(g=>n[g]||g).join("");const d=[...c];return d[0]=d[0].toLowerCase(),h+=d.join(""),r.move=d.length,h+=[...l].map(g=>n[g]||g).join(""),r.regex=new RegExp(h),u.length&&u.split(" ").forEach(g=>{r.visemes.push(g)}),r})}),this.visemeDurations={aa:.95,E:.9,I:.92,O:.96,U:.95,PP:1.08,SS:1.23,TH:1,DD:1.05,FF:1,kk:1.21,nn:.88,RR:.88,DD:1.05,sil:1},this.specialDurations={" ":1,",":3,"-":.5,"'":.5},this.digits=["oh","one","two","three","four","five","six","seven","eight","nine"],this.ones=["","one","two","three","four","five","six","seven","eight","nine"],this.tens=["","","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"],this.teens=["ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"],this.decades={20:"twenties",30:"thirties",40:"forties",50:"fifties",60:"sixties",70:"seventies",80:"eighties",90:"nineties"},this.ordinals={1:"first",2:"second",3:"third",4:"fourth",5:"fifth",6:"sixth",7:"seventh",8:"eighth",9:"ninth",10:"tenth",11:"eleventh",12:"twelfth",13:"thirteenth",14:"fourteenth",15:"fifteenth",16:"sixteenth",17:"seventeeth",18:"eighteenth",19:"nineteenth",20:"twentieth",30:"thirtieth",40:"fortieth",50:"fiftieth",60:"sixtieth",70:"seventieth",80:"eightieth",90:"ninetieth"},this.symbols={"%":"percent","€":"euros","&":"and","+":"plus",$:"dollars"},this.symbolsReg=/[%€&\+\$]/g}convert_digit_by_digit(n){n=String(n).split("");let e="";for(let t=0;t<n.length;t++)e+=this.digits[n[t]]+" ";return e=e.substring(0,e.length-1),e}convert_sets_of_two(n){let e=String(n).substring(0,2),t=String(n).substring(2,4),o=this.convert_tens(e);return o+=" "+this.convert_tens(t),o}convert_millions(n){return n>=1e6?this.convert_millions(Math.floor(n/1e6))+" million "+this.convert_thousands(n%1e6):this.convert_thousands(n)}convert_thousands(n){return n>=1e3?this.convert_hundreds(Math.floor(n/1e3))+" thousand "+this.convert_hundreds(n%1e3):this.convert_hundreds(n)}convert_hundreds(n){return n>99?this.ones[Math.floor(n/100)]+" hundred "+this.convert_tens(n%100):this.convert_tens(n)}convert_tens(n){return n<10?(Number(n)!=0&&n.toString().startsWith("0")?"oh ":"")+this.ones[Number(n)]:n>=10&&n<20?this.teens[n-10]:(this.tens[Math.floor(n/10)]+" "+this.ones[n%10]).trim()}convertNumberToWords(n,e=!1){const t=parseFloat(n);if(n=="0")return"zero";if(n<0)return" minus "+this.convertNumberToWords(Math.abs(n).toString(),e).trim();if(t&&!Number.isInteger(t)){const o=t.toString().split(".");return this.convertNumberToWords(o[0],e).trim()+" point "+this.convert_digit_by_digit(o[1]).trim()}else return n.toString().startsWith("0")?this.convert_digit_by_digit(n).trim():!e&&(n<1e3&&n>99&&n%100!==0||n>1e4&&n<1e6)?this.convert_digit_by_digit(n).trim():!e&&(n>1e3&&n<2e3||n>2009&&n<3e3)?n%100!=0?this.convert_sets_of_two(n).trim():this.convert_tens(n.toString().substring(0,2)).trim()+" hundred":this.convert_millions(n).trim()}convertDecade(n){const e=parseInt(n),t=!isNaN(e)&&n.length===2,o=!isNaN(e)&&n.length>2&&e>0&&e<=3e3,s=o&&e%1e3===0?Math.floor(e/1e3):null,i=o&&!s?Math.floor(e/100):null,a=t||o?Math.floor(e%100/10)*10:null;let c=[];return s?c.push(this.convertNumberToWords(s).trim(),"thousands"):(i&&c.push(this.convertNumberToWords(i).trim()),a?c.push(this.decades[a]||this.convertNumberToWords(a).trim()+"s"):i?c.push("hundreds"):c.push(n)),c.join(" ")}convertOrdinal(n){if(this.ordinals.hasOwnProperty(n))return this.ordinals[n];const e=Math.floor(n/100),t=Math.floor(n%100/10)*10,o=n%10;let s=[];return e&&(s.push(this.convertNumberToWords(e).trim()),t||o?s.push("hundred"):s.push("hundredth")),t&&(o?s.push(this.convertNumberToWords(t).trim()):s.push(this.ordinals[t])),o&&s.push(this.ordinals[o]),s.join(" ")}preProcessText(n){let e=n.replace('/[#_*":;]/g',"");return e=e.replace(this.symbolsReg,t=>" "+this.symbols[t]+" "),/\d/.test(e)&&(e=e.replace(/\b(\d{2,4})[''']?\s?[sS](?=\s|[.,!?;:]|$)/g,(t,o)=>{const s=this.convertDecade(o);return s===o?t:s}),e=e.replace(/\b(\d+)\s*(st|nd|rd|th)(?=\s|[.,!?;:]|$)/gi,(t,o)=>this.convertOrdinal(Number(o))),e=e.replace(/\b(\w*?)(\d+)([A-Za-z]+)\b/g,(t,o,s,i)=>{const a=this.convertNumberToWords(s);return`${o}${a} ${i}`}).replace(/\b([A-Za-z]+)(\d+)(\w*?)\b/g,(t,o,s,i)=>{const a=this.convertNumberToWords(s);return`${o} ${a}${i}`}),e=e.replace(/-?(?:\d{1,3}(?:,\d{3})+|\d+)(\.\d+)?/g,(t,o)=>{let s=t,i=!1;return/,/.test(s)&&(s=s.replace(/,/g,""),i=!0),o&&(i=!0),this.convertNumberToWords(s,i)})),e=e.replace(/(\D)\1\1+/g,"$1$1").replaceAll(" "," ").normalize("NFD").replace(/[\u0300-\u036f]/g,"").normalize("NFC").trim(),e}wordsToVisemes(n){let e={words:n.toUpperCase(),visemes:[],times:[],durations:[],i:0},t=0;const o=[...e.words];for(;e.i<o.length;){const s=o[e.i],i=this.rules[s];if(i)for(let a=0;a<i.length;a++){const c=i[a];if((e.words.substring(0,e.i)+s.toLowerCase()+e.words.substring(e.i+1)).match(c.regex)){c.visemes.forEach(r=>{if(e.visemes.length&&e.visemes[e.visemes.length-1]===r){const h=.7*(this.visemeDurations[r]||1);e.durations[e.durations.length-1]+=h,t+=h}else{const h=this.visemeDurations[r]||1;e.visemes.push(r),e.times.push(t),e.durations.push(h),t+=h}}),e.i+=c.move;break}}else e.i++,t+=this.specialDurations[s]||0}return e}}const kt=Object.freeze(Object.defineProperty({__proto__:null,LipsyncEn:St},Symbol.toStringTag,{value:"Module"}));class wt{constructor(){this.rules={A:["[AH]=aa","[AU]=aa U","[AI]=aa I","[AE]=E","[A]H=aa","[A]U=aa U","[A]I=aa I"," [AN] =aa nn"," [AM] =aa PP","[ARR]=aa RR","[AR]=aa RR"," [ALS]=aa nn SS","[AL]=aa nn","[AUCH]=aa U kk","[ABER]=aa PP E RR","[A]=aa"],Ä:["[Ä]H=E","[ÄU]=O","[Ä]=E"],B:["[B]=PP"],C:["[CH]S=kk SS","[CH]=kk"," [CH]=kk","#[CH]=kk","[CK]=kk","[C]H=kk","[C]=kk"],D:[" [DAS] =DD aa SS"," [DEN] =DD E nn"," [DER] =DD E RR"," [DIE] =DD I"," [DU] =DD U"," [DURCH]=DD U RR kk","[D]=DD"],E:["[EI]=aa I","[EU]=O","[EH]=E"," [ER] =E RR"," [ES] =E SS"," [EIN] =aa I nn"," [EINE]=aa I nn aa","[ER]#=E","[ER]=E RR","[EN]#=aa nn","[E]=E"],F:["[F]=FF"],G:["[G]=kk"],H:[" [HAT] =I aa DD"," [HABEN]=I aa PP aa nn"," [HIER]=I I RR"," [HEUTE]=I O DD aa","[H]="],I:[" [ICH] =I kk"," [IHR] =I RR"," [IN] =I nn"," [IST] =I SS DD"," [IM] =I PP","[IE]=I","[IH]=I","[I]=I"],J:["[J]=I"],K:["[K]=kk"],L:["[L]=nn"],M:[" [MIT] =PP I DD"," [MAN] =PP aa nn"," [MEHR]=PP E RR"," [MICH]=PP I kk","[M]=PP"],N:[" [NICHT]=nn I kk DD"," [NUR] =nn U RR"," [NACH]=nn aa kk"," [NOCH]=nn aa kk","[NG]=nn kk","[N]=nn"],O:["[OO]=U","[OH]=O","[OU]=aa U"," [ODER]=O DD E RR"," [OHNE]=O nn aa","[Ö]=E","[O]=aa"],Ö:["[ÖH]=E","[Ö]=E"],P:["[PF]=FF FF","[PH]=FF","[P]=PP"],Q:["[QU]=kk FF","[Q]=kk"],R:["[R]=RR"],S:["[SCH]=SS","[SP]=SS PP","[ST]=SS DD","[SS]=SS","[S]=SS"],ß:["[ß]=SS"],T:["[TZ]=DD SS","[TH]=DD","[T]=DD"],U:[" [UND] =U nn DD"," [UM] =U PP"," [UNTER]=U nn DD E RR"," [UNS] =U nn SS","[UH]=U","[ÜH]=I U","[Ü]=I U","[U]=U"],Ü:["[ÜH]=I U","[Ü]=I U"],V:[" [VON] =FF aa nn"," [VOR] =FF aa RR"," [VIEL]=FF I nn","[V]=FF"],W:[" [WAS] =FF aa SS"," [WIR] =FF I RR"," [WIE] =FF I"," [WENN]=FF E nn"," [WILL]=FF I nn"," [WO] =FF aa"," [WIEDER]=FF I DD E RR","[W]=FF"],X:["[X]=kk SS"],Y:["[Y]=I"],Z:[" [ZU] =DD SS U"," [ZUM] =DD SS U PP"," [ZUR] =DD SS U RR"," [ZEIT]=DD SS aa I DD","[Z]=DD SS"]};const n={"#":"[AEIOUÄÖÜ]+",".":"[BDVGJLMNRWZ]","%":"(?:ER|E|ES|ED|ING|ELY|EN|TE|ST)","&":"(?:[SCGZXJ]|CH|SCH|TZ)","@":"(?:[TSRDLZNJ]|TH|CH|SCH)","^":"[BCDFGHJKLMNPQRSTVWXYZß]","+":"[EIY]",":":"[BCDFGHJKLMNPQRSTVWXYZß]*"," ":"\\b"};Object.keys(this.rules).forEach(e=>{this.rules[e]=this.rules[e].map(t=>{const o=t.indexOf("["),s=t.indexOf("]"),i=t.indexOf("="),a=t.substring(0,o),c=t.substring(o+1,s),l=t.substring(s+1,i),u=t.substring(i+1),r={regex:"",move:0,visemes:[]};let h="";h+=[...a].map(g=>n[g]||g).join("");const d=[...c];return d[0]=d[0].toLowerCase(),h+=d.join(""),r.move=d.length,h+=[...l].map(g=>n[g]||g).join(""),r.regex=new RegExp(h),u.length&&u.split(" ").forEach(g=>{r.visemes.push(g)}),r})}),this.visemeDurations={aa:1,E:.85,I:.9,O:1.05,U:1,PP:1.15,SS:1.2,TH:1,DD:1.1,FF:1.05,kk:1.25,nn:.85,RR:.9,sil:1},this.specialDurations={" ":1,",":3,"-":.5,"'":.5,".":4,"!":3,"?":3},this.digits=["null","eins","zwei","drei","vier","fünf","sechs","sieben","acht","neun"],this.ones=["","ein","zwei","drei","vier","fünf","sechs","sieben","acht","neun"],this.tens=["","","zwanzig","dreißig","vierzig","fünfzig","sechzig","siebzig","achtzig","neunzig"],this.teens=["zehn","elf","zwölf","dreizehn","vierzehn","fünfzehn","sechzehn","siebzehn","achtzehn","neunzehn"],this.symbols={"%":"prozent","€":"euro","&":"und","+":"plus",$:"dollar","=":"gleich","@":"at","#":"hashtag"},this.symbolsReg=/[%€&\+\$=@#]/g}convert_digit_by_digit(n){n=String(n).split("");let e="";for(let t=0;t<n.length;t++)e+=this.digits[n[t]]+" ";return e=e.substring(0,e.length-1),e}convert_millions(n){if(n>=1e6){const e=Math.floor(n/1e6),t=n%1e6;let o=this.convert_thousands(e);return o+=e===1?" million ":" millionen ",t>0&&(o+=this.convert_thousands(t)),o}else return this.convert_thousands(n)}convert_thousands(n){if(n>=1e3){const e=Math.floor(n/1e3),t=n%1e3;let o="";return e===1?o="eintausend":o=this.convert_hundreds(e)+"tausend",t>0&&(o+=this.convert_hundreds(t)),o}else return this.convert_hundreds(n)}convert_hundreds(n){if(n>99){const e=Math.floor(n/100),t=n%100;let o="";return e===1?o="einhundert":o=this.ones[e]+"hundert",t>0&&(o+=this.convert_tens(t)),o}else return this.convert_tens(n)}convert_tens(n){if(n<10)return this.ones[Number(n)]||"";if(n>=10&&n<20)return this.teens[n-10];{const e=Math.floor(n/10),t=n%10;return t===0?this.tens[e]:this.ones[t]+"und"+this.tens[e]}}convertNumberToWords(n){const e=String(n);return n=="0"?"null":e.startsWith("0")?this.convert_digit_by_digit(n):e.length===4&&(n<1e3||n>2100)?this.convert_digit_by_digit(n):this.convert_millions(Number(n))}preProcessText(n){return n.replace(/[#_*\":;]/g,"").replace(this.symbolsReg,e=>" "+this.symbols[e]+" ").replace(/(\d)\.(\d)/g,"$1 komma $2").replace(/(\d),(\d)/g,"$1 komma $2").replace(/\d+/g,this.convertNumberToWords.bind(this)).replace(/(\D)\1\1+/g,"$1$1").replace(/\s+/g," ").toLowerCase().trim()}wordsToVisemes(n){let e={words:n.toUpperCase(),visemes:[],times:[],durations:[],i:0},t=0;const o=[...e.words];for(;e.i<o.length;){const s=o[e.i],i=this.rules[s];if(i){let a=!1;for(let c=0;c<i.length;c++){const l=i[c];if((e.words.substring(0,e.i)+s.toLowerCase()+e.words.substring(e.i+1)).match(l.regex)){l.visemes.forEach(h=>{if(e.visemes.length&&e.visemes[e.visemes.length-1]===h){const d=.7*(this.visemeDurations[h]||1);e.durations[e.durations.length-1]+=d,t+=d}else{const d=this.visemeDurations[h]||1;e.visemes.push(h),e.times.push(t),e.durations.push(d),t+=d}}),e.i+=l.move,a=!0;break}}a||(e.i++,t+=this.specialDurations[s]||0)}else e.i++,t+=this.specialDurations[s]||0}return e}}const Ct=Object.freeze(Object.defineProperty({__proto__:null,LipsyncDe:wt},Symbol.toStringTag,{value:"Module"}));class zt{constructor(){this.rules={A:["[AN]C=aa nn","[AN]G=aa nn","[AN]T=aa nn","[AN]D=aa nn","[AN] =aa nn","[AN]$=aa nn","[AM]P=aa nn","[AM]B=aa nn","[AM] =aa nn","[AM]$=aa nn","[AI]N=E nn","[AIM]=E nn","[AIN]=E nn","[AU]=O","[AUX]=O","[AUT]=O","[AI]=E","[AY]=E","[A]=aa"],À:["[À]=aa"],Â:["[Â]=aa"],B:[" [B] =PP","[BB]=PP","[B]=PP"],C:["[C]E=SS","[C]I=SS","[C]Y=SS","[C]È=SS","[C]É=SS","[C]Ê=SS","[CH]=SS","[C]A=kk","[C]O=kk","[C]U=kk","[C]L=kk","[C]R=kk","[CK]=kk","[C]=kk"],Ç:["[Ç]=SS"],D:["[D]=DD"],E:["[EN]C=aa nn","[EN]T=aa nn","[EN]D=aa nn","[EN] =aa nn","[EN]$=aa nn","[EM]P=aa nn","[EM]B=aa nn","[EM] =aa nn","[EM]$=aa nn","[EAU]=O","[EAU]X=O","[EU]=U","[EUX]=U","[EUR]=U RR","[EI]=E","[EIN]=E nn","[ER] =E","[ER]$=E","[EZ] =E","[EZ]$=E","[ED] =E","[ED]$=E"," [E] =","[E] =","[E]$=","[E]S =","[E]S$=","[E]NT =","[E]NT$=","[È]=E","[É]=E","[Ê]=E","[Ë]=E","[E]=E"],È:["[È]=E"],É:["[É]=E"],Ê:["[Ê]=E"],Ë:["[Ë]=E"],F:["[FF]=FF","[F]=FF","[PH]=FF"],G:["[G]E=SS","[G]I=SS","[G]Y=SS","[G]È=SS","[G]É=SS","[G]Ê=SS","[GN]=nn I","[GN]E=nn","[GN]A=nn aa","[GN]O=nn O","[GU]E=kk","[GU]I=kk","[GU]A=kk FF aa","[GU]O=kk FF O","[G]A=kk","[G]O=kk","[G]U=kk","[G]L=kk","[G]R=kk","[GG]=kk","[G]=kk"],H:["[H]="],I:["[IN]C=E nn","[IN]T=E nn","[IN]D=E nn","[IN] =E nn","[IN]$=E nn","[IM]P=E nn","[IM]B=E nn","[IM] =E nn","[IM]$=E nn","[IEN]=I E nn","[IER]=I E","[IEU]=I U","[IEZ]=I E","[ILL]E=I","[ILLE]=I","[ILL]=I","[Î]=I","[Ï]=I","[I]=I"],Î:["[Î]=I"],Ï:["[Ï]=I"],J:["[J]=SS"],K:["[K]=kk"],L:["[LL]E=","[LLE]=","[LL]A=I aa","[LL]O=I O","[LL]U=I U","[LL]I=I","[LL]=I","[L]=nn"],M:["[MM]=PP","[M]=PP"],N:["[NN]=nn","[N]=nn"],O:["[ON]C=O nn","[ON]T=O nn","[ON]D=O nn","[ON] =O nn","[ON]$=O nn","[OM]P=O nn","[OM]B=O nn","[OM] =O nn","[OM]$=O nn","[OI]N=FF E nn","[OI]G=FF aa","[OI]S=FF aa","[OI]T=FF aa","[OI]X=FF aa","[OI]=FF aa","[OU]=U","[OÙ]=U","[OÛ]=U","[OEU]=U","[OEUR]=U RR","[OUGH]=U FF","[OUGH]T=U","[Ô]=O","[O]=O"],Ô:["[Ô]=O"],Ù:["[Ù]=U"],Û:["[Û]=U"],P:["[PH]=FF","[PP]=PP","[P]=PP"],Q:["[QU]=kk","[Q]=kk"],R:["[RR]=RR","[R]=RR"],S:["#[S]#=SS"," [S]=SS","[SS]=SS","[S] =","[S]$=","[SC]E=SS","[SC]I=SS","[SC]Y=SS","[S]=SS"],T:["[TI]A=SS I aa","[TI]E=SS I E","[TI]O=SS I O","[TI]ON=SS I O nn","[TH]=DD","[TT]=DD","[T] =","[T]$=","[T]=DD"],U:["[UN]C=U nn","[UN]T=U nn","[UN]D=U nn","[UN] =U nn","[UN]$=U nn","[UM]=U nn","[UE]=I","[UEI]=I E","[UEIL]=I I","[UILL]=I","[Ù]=U","[Û]=U","[Ü]=I U","[U]=I U"],Ü:["[Ü]=I U"],V:["[V]=FF"],W:["[W]=FF"],X:["[X] =","[X]$=","#[X]#=kk SS"," [X]=kk SS","[X]=kk SS"],Y:["[Y]=I"," [Y]=I","[YE]=I E","[YA]=I aa","[YO]=I O","[YU]=I U"],Z:["[Z]=SS"]};const n={"#":"[AEIOUYÀÂÈÉÊËÎÏÔÙÛÜ]+",".":"[BDVGJLMNRWZ]","%":"(?:ER|E|ES|ÉS|ÈS|ÊS|ENT|MENT|TION|SION)","&":"(?:[SCGZXJ]|CH|SH|GN)","@":"(?:[TSRDLZNJ]|TH|CH|SH|GN)","^":"[BCDFGHJKLMNPQRSTVWXZÇ]+","+":"[EIYÈÉÊËÎÏ]",":":"[BCDFGHJKLMNPQRSTVWXZÇ]*"," ":"\\b",$:"$"};Object.keys(this.rules).forEach(e=>{this.rules[e]=this.rules[e].map(t=>{const o=t.indexOf("["),s=t.indexOf("]"),i=t.indexOf("="),a=t.substring(0,o),c=t.substring(o+1,s),l=t.substring(s+1,i),u=t.substring(i+1),r={regex:"",move:0,visemes:[]};let h="";h+=[...a].map(g=>n[g]||g).join("");const d=[...c];return d[0]=d[0].toLowerCase(),h+=d.join(""),r.move=d.length,h+=[...l].map(g=>n[g]||g).join(""),r.regex=new RegExp(h,"i"),u.length&&u.split(" ").forEach(g=>{g&&r.visemes.push(g)}),r})}),this.visemeDurations={aa:1,E:.95,I:.9,O:1.05,U:.95,PP:1.1,SS:1.25,TH:1,DD:1.05,FF:1,kk:1.2,nn:.88,RR:1.15,sil:1},this.specialDurations={" ":1,",":2.5,".":3.5,";":2.8,":":2.2,"!":3.2,"?":3.2,"-":.8,"'":.3,'"':.3,"(":1.5,")":1.5},this.digits=["zéro","un","deux","trois","quatre","cinq","six","sept","huit","neuf"],this.ones=["","un","deux","trois","quatre","cinq","six","sept","huit","neuf"],this.teens=["dix","onze","douze","treize","quatorze","quinze","seize","dix-sept","dix-huit","dix-neuf"],this.tens=["","dix","vingt","trente","quarante","cinquante","soixante","soixante-dix","quatre-vingts","quatre-vingt-dix"],this.symbols={"%":"pourcent","€":"euros","&":"et","+":"plus",$:"dollars","=":"égale","@":"arobase","#":"dièse","°":"degrés"},this.symbolsReg=/[%€&\+\$=@#°]/g}convert_digit_by_digit(n){n=String(n).split("");let e="";for(let t=0;t<n.length;t++)e+=this.digits[n[t]]+" ";return e=e.substring(0,e.length-1),e}convert_tens(n){if(n<10)return this.ones[n]||"";if(n>=10&&n<20)return this.teens[n-10];if(n>=70&&n<80){const e=n-60;return e===11?"soixante et onze":"soixante-"+this.teens[e-10]}else if(n>=90){const e=n-80;return e===11?"quatre-vingt-onze":"quatre-vingt-"+this.teens[e-10]}else{const e=Math.floor(n/10),t=n%10;return e===8&&t===0?"quatre-vingts":e===8?"quatre-vingt-"+this.ones[t]:(e===2||e===3||e===4||e===5||e===6)&&t===1?this.tens[e]+" et un":t===0?this.tens[e]:this.tens[e]+"-"+this.ones[t]}}convert_hundreds(n){if(n>=100){const e=Math.floor(n/100),t=n%100;let o="";return e===1?o="cent":(o=this.ones[e]+" cent",t===0&&(o+="s")),t>0&&(o+=" "+this.convert_tens(t)),o}else return this.convert_tens(n)}convert_thousands(n){if(n>=1e3){const e=Math.floor(n/1e3),t=n%1e3;let o="";return e===1?o="mille":o=this.convert_hundreds(e)+" mille",t>0&&(o+=" "+this.convert_hundreds(t)),o}else return this.convert_hundreds(n)}convert_millions(n){if(n>=1e6){const e=Math.floor(n/1e6),t=n%1e6;let o="";return e===1?o="un million":o=this.convert_hundreds(e)+" millions",t>0&&(o+=" "+this.convert_thousands(t)),o}else return this.convert_thousands(n)}convertNumberToWords(n){const e=String(n);return n==="0"||n===0?"zéro":e.startsWith("0")?this.convert_digit_by_digit(n):this.convert_millions(Number(n))}preProcessText(n){return n.replace(/[#_*\":;]/g,"").replace(this.symbolsReg,e=>" "+this.symbols[e]+" ").replace(/(\d)[,.](\d)/g,"$1 virgule $2").replace(/\d+/g,this.convertNumberToWords.bind(this)).replace(/(\D)\1\1+/g,"$1$1").replace(/\s+/g," ").replace(/'/g,"'").trim()}wordsToVisemes(n){let e={words:n.toUpperCase(),visemes:[],times:[],durations:[],i:0},t=0;const o=[...e.words];for(;e.i<o.length;){const s=o[e.i],i=this.rules[s];if(i){let a=!1;for(let c=0;c<i.length;c++){const l=i[c];if((e.words.substring(0,e.i)+s.toLowerCase()+e.words.substring(e.i+1)).match(l.regex)){l.visemes.forEach(h=>{if(e.visemes.length&&e.visemes[e.visemes.length-1]===h){const d=.7*(this.visemeDurations[h]||1);e.durations[e.durations.length-1]+=d,t+=d}else{const d=this.visemeDurations[h]||1;e.visemes.push(h),e.times.push(t),e.durations.push(d),t+=d}}),e.i+=l.move,a=!0;break}}a||(e.i++,t+=this.specialDurations[s]||0)}else e.i++,t+=this.specialDurations[s]||0}return e}}const Ht=Object.freeze(Object.defineProperty({__proto__:null,LipsyncFr:zt},Symbol.toStringTag,{value:"Module"}));class Tt{constructor(){this.visemes={a:"aa",e:"E",i:"I",o:"O",u:"U",y:"U",ä:"aa",ö:"O",å:"O",b:"PP",c:"SS",d:"DD",f:"FF",g:"kk",h:"kk",j:"I",k:"kk",l:"nn",m:"PP",n:"nn",p:"PP",q:"kk",r:"RR",s:"SS",t:"DD",v:"FF",w:"FF",x:"SS",z:"SS"},this.visemeDurations={aa:.95,E:.9,I:.92,O:.96,U:.95,PP:1.08,SS:1.23,DD:1.05,FF:1,kk:1.21,nn:.88,RR:.88,DD:1.05,sil:1},this.specialDurations={" ":1,",":3,"-":.5},this.numbers=["nolla","yksi","kaksi","kolme","neljä","viisi","kuusi","seitsemän","kahdeksan","yhdeksän","kymmenen","yksitoista","kaksitoista","kolmetoista","neljätoista","viisitoista","kuusitoista","seitsemäntoista","kahdeksantoista","yhdeksäntoista"],this.symbols={"%":"prosenttia","€":"euroa","&":"ja","+":"plus",$:"dollaria"},this.symbolsReg=/[%€&\+\$]/g}numberToFinnishWords(n){const e=[];let t=parseFloat(n);if(t===void 0)return n;let o=(s,i,a,c,l)=>{if(s<i)return s;const u=Math.floor(s/i);return e.push(a+(u===1?c:this.numberToFinnishWords(u.toString())+l)),s-u*i};if(t<0&&(e.push("miinus "),t=Math.abs(t)),t=o(t,1e9," ","miljardi"," miljardia"),t=o(t,1e6," ","miljoona"," miljoonaa"),t=o(t,1e3,"","tuhat","tuhatta"),t=o(t,100," ","sata","sataa"),t>20&&(t=o(t,10,"","","kymmentä")),t>=1){let s=Math.floor(t);e.push(this.numbers[s]),t-=s}if(t>=0&&Math.abs(parseFloat(n))<1&&e.push("nolla"),t>0){let s=n.split(".");if(s.length>1){e.push(" pilkku");let i=[...s[s.length-1]];for(let a=0;a<i.length;a++)e.push(" "+this.numbers[i[a]])}}return e.join("").trim()}preProcessText(n){return n.replace(/[#_*\'\":;]/g,"").replace(this.symbolsReg,e=>" "+this.symbols[e]+" ").replace(/(\d)\,(\d)/g,"$1 pilkku $2").replace(/\d+/g,this.numberToFinnishWords.bind(this)).replaceAll(" "," ").normalize("NFD").replace(/[\u0300-\u0307\u0309\u030b-\u036f]/g,"").normalize("NFC").trim()}wordsToVisemes(n){let e={words:n,visemes:[],times:[],durations:[]},t=0;const o=[...n];for(let s=0;s<o.length;s++){const i=this.visemes[o[s].toLowerCase()];if(i)if(e.visemes.length&&e.visemes[e.visemes.length-1]===i){const a=.7*(this.visemeDurations[i]||1);e.durations[e.durations.length-1]+=a,t+=a}else{const a=this.visemeDurations[i]||1;e.visemes.push(i),e.times.push(t),e.durations.push(a),t+=a}else t+=this.specialDurations[o[s]]||0}return e}}const Ft=Object.freeze(Object.defineProperty({__proto__:null,LipsyncFi:Tt},Symbol.toStringTag,{value:"Module"}));class Mt{constructor(){this.visemes={a:"aa",ą:"O",e:"E",ę:"E",ė:"E",i:"I",į:"I",o:"O",u:"U",ū:"U",ų:"U",y:"I",b:"PP",c:"SS",č:"SS",d:"DD",f:"FF",g:"kk",h:"kk",j:"I",k:"kk",l:"nn",m:"PP",n:"nn",p:"PP",q:"kk",r:"RR",s:"SS",š:"CH",t:"DD",v:"FF",w:"FF",x:"SS",z:"SS",ž:"SS"},this.durations={a:.95,ą:1.5,e:.9,ę:1.5,ė:1.5,i:.92,į:1.5,o:.96,u:.95,ū:1.5,ų:1.5,y:1.5,b:1.08,c:1.23,d:1.05,f:1,g:1.21,h:1.21,j:.92,k:1.21,l:.88,m:1.08,n:.88,p:1.08,q:1.21,r:.88,s:1.23,š:1.23,t:1.05,v:1,w:1,x:1.23,z:1.23,ž:1.23},this.pauses={" ":1,",":3,"-":.5},this.numbers=["nulis","vienas","du","trys","keturi","penki","šeši","septyni","aštuoni","devyni","dešimt","vienuolika","dvylika","trylika","keturiolika","penkiolika","šešiolika","septyniolika","aštuoniolika","devyniolika"],this.tens=[this.numbers[0],this.numbers[10],"dvidešimt","trisdešimt","keturiasdešimt","penkiasdešimt","šešiasdešimt","septyniasdešimt","aštuoniasdešimt","devyniasdešimt"]}numberToLithuanianWords(n){const e=[];let t=parseFloat(n);if(t===void 0)return n;let o=(s,i,a,c,l)=>{if(s<i)return s;const u=Math.floor(s/i);return u===1?e.push(this.numbers[1]):e.push(this.numberToLithuanianWords(u.toString())),u%10===1?e.push(a):u%10===0||u%100>10&&u%100<20?e.push(l):e.push(c),s-u*i};t<0&&(e.push("minus"),t=Math.abs(t)),t=o(t,1e9,"milijardas","milijardai","milijardų"),t=o(t,1e6,"milijonas","milijonai","milijonų"),t=o(t,1e3,"tūkstantis","tūkstančiai","tūkstančių"),t=o(t,100,"šimtas","šimtai","šimtų");for(let s=this.tens.length-1;s>=1;s--)if(t>=10*s){e.push(this.tens[s]),t=t-10*s;break}if(t>=1){let s=Math.floor(t);e.push(this.numbers[s]),t-=s}if(t>=0&&Math.abs(parseFloat(n))<1&&e.push(this.numbers[0]),t>0){let s=n.split(".");if(s.length>1){e.push("kablelis");let i=[...s[s.length-1]];for(let a=0;a<i.length;a++)e.push(this.numbers[i[a]])}}return e.join(" ").trim()}preProcessText(n){return n.replace(`/[#_*'":;]/g`,"").replaceAll("0 %","0 procentų ").replaceAll("1 %","1 procentas ").replaceAll("%"," procentai ").replaceAll("0 €","0 eurų ").replaceAll("1 €","1 euras ").replaceAll("€"," eurai ").replaceAll("0 $","0 dolerių ").replaceAll("1 $","1 doleris ").replaceAll("$"," doleriai ").replaceAll("&"," ir ").replaceAll("+"," pliusas ").replace(/(\d)\,(\d)/g,"$1 kablelis $2").replace(/\d+/g,this.numberToLithuanianWords.bind(this)).replace(/(\D)\1\1+/g,"$1$1").replaceAll(" "," ").normalize("NFD").replace(/[\u0300-\u0303\u0305\u0306\u0308-\u0327\u0329-\u036f]/g,"").normalize("NFC").trim()}wordsToVisemes(n){let e={words:n,visemes:[],times:[],durations:[]},t=0;const o=[...n];for(let s=0;s<o.length;s++){const i=o[s].toLowerCase(),a=this.visemes[i];if(a)if(e.visemes.length&&e.visemes[e.visemes.length-1]===a){const c=.7*(this.durations[i]||1);e.durations[e.durations.length-1]+=c,t+=c}else{const c=this.durations[i]||1;e.visemes.push(a),e.times.push(t),e.durations.push(c),t+=c}else t+=this.pauses[o[s]]||0}return e}}const Et=Object.freeze(Object.defineProperty({__proto__:null,LipsyncLt:Mt},Symbol.toStringTag,{value:"Module"})),Pt=new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=",typeof document>"u"?require("url").pathToFileURL(__filename).href:_e&&_e.tagName.toUpperCase()==="SCRIPT"&&_e.src||new URL("index.cjs",document.baseURI).href),it={en:kt,de:Ct,fr:Ht,fi:Ft,lt:Et},ue=new A.Quaternion,oe=new A.Euler,Be=new A.Vector3,Ne=new A.Vector3,ot=new A.Box3;new A.Matrix4;new A.Matrix4;new A.Vector3;new A.Vector3(0,0,1);const Bt=new A.Vector3(1,0,0);new A.Vector3(0,1,0);new A.Vector3(0,0,1);class Ke{constructor(n,e=null){this.nodeAvatar=n,this.opt={jwtGet:null,ttsEndpoint:"",ttsApikey:null,ttsTrimStart:0,ttsTrimEnd:400,ttsLang:"fi-FI",ttsVoice:"fi-FI-Standard-A",ttsRate:1,ttsPitch:0,ttsVolume:.3,mixerGainSpeech:1.2,mixerGainBackground:null,lipsyncLang:"fi",lipsyncModules:["fi","en","lt"],pcmSampleRate:22050,modelRoot:"Armature",modelPixelRatio:1,modelFPS:30,modelMovementFactor:1,cameraView:"full",dracoEnabled:!1,dracoDecoderPath:"https://www.gstatic.com/draco/v1/decoders/",cameraDistance:0,cameraX:0,cameraY:0,cameraRotateX:0,cameraRotateY:0,cameraRotateEnable:!0,cameraPanEnable:!1,cameraZoomEnable:!1,lightAmbientColor:16777215,lightAmbientIntensity:1.25,lightDirectColor:8947882,lightDirectIntensity:12,lightDirectPhi:1,lightDirectTheta:2,lightSpotIntensity:0,lightSpotColor:3377407,lightSpotPhi:.1,lightSpotTheta:4,lightSpotDispersion:1,avatarMood:"neutral",avatarMute:!1,avatarIdleEyeContact:.6,avatarIdleHeadMove:.5,avatarSpeakingEyeContact:.8,avatarSpeakingHeadMove:.5,avatarIgnoreCamera:!1,listeningSilenceThresholdLevel:40,listeningSilenceThresholdMs:2e3,listeningSilenceDurationMax:1e4,listeningActiveThresholdLevel:75,listeningActiveThresholdMs:300,listeningActiveDurationMax:24e4,update:null,avatarOnly:!1,avatarOnlyScene:null,avatarOnlyCamera:null,statsNode:null,statsStyle:null},Object.assign(this.opt,e||{}),this.opt.statsNode&&(this.stats=new xt,this.opt.statsStyle&&(this.stats.dom.style.cssText=this.opt.statsStyle),this.opt.statsNode.appendChild(this.stats.dom)),this.poseTemplates={side:{standing:!0,props:{"Hips.position":{x:0,y:1,z:0},"Hips.rotation":{x:-.003,y:-.017,z:.1},"Spine.rotation":{x:-.103,y:-.002,z:-.063},"Spine1.rotation":{x:.042,y:-.02,z:-.069},"Spine2.rotation":{x:.131,y:-.012,z:-.065},"Neck.rotation":{x:.027,y:.006,z:0},"Head.rotation":{x:.077,y:-.065,z:0},"LeftShoulder.rotation":{x:1.599,y:.084,z:-1.77},"LeftArm.rotation":{x:1.364,y:.052,z:-.044},"LeftForeArm.rotation":{x:.002,y:-.007,z:.331},"LeftHand.rotation":{x:.104,y:-.067,z:-.174},"LeftHandThumb1.rotation":{x:.231,y:.258,z:.355},"LeftHandThumb2.rotation":{x:-.106,y:-.339,z:-.454},"LeftHandThumb3.rotation":{x:-.02,y:-.142,z:-.004},"LeftHandIndex1.rotation":{x:.148,y:.032,z:-.069},"LeftHandIndex2.rotation":{x:.326,y:-.049,z:-.029},"LeftHandIndex3.rotation":{x:.247,y:-.053,z:-.073},"LeftHandMiddle1.rotation":{x:.238,y:-.057,z:-.089},"LeftHandMiddle2.rotation":{x:.469,y:-.036,z:-.081},"LeftHandMiddle3.rotation":{x:.206,y:-.015,z:-.017},"LeftHandRing1.rotation":{x:.187,y:-.118,z:-.157},"LeftHandRing2.rotation":{x:.579,y:.02,z:-.097},"LeftHandRing3.rotation":{x:.272,y:.021,z:-.063},"LeftHandPinky1.rotation":{x:.405,y:-.182,z:-.138},"LeftHandPinky2.rotation":{x:.613,y:.128,z:-.144},"LeftHandPinky3.rotation":{x:.268,y:.094,z:-.081},"RightShoulder.rotation":{x:1.541,y:.192,z:1.775},"RightArm.rotation":{x:1.273,y:-.352,z:-.067},"RightForeArm.rotation":{x:-.011,y:-.031,z:-.357},"RightHand.rotation":{x:-.008,y:.312,z:-.028},"RightHandThumb1.rotation":{x:.23,y:-.258,z:-.355},"RightHandThumb2.rotation":{x:-.107,y:.339,z:.454},"RightHandThumb3.rotation":{x:-.02,y:.142,z:.004},"RightHandIndex1.rotation":{x:.148,y:-.031,z:.069},"RightHandIndex2.rotation":{x:.326,y:.049,z:.029},"RightHandIndex3.rotation":{x:.247,y:.053,z:.073},"RightHandMiddle1.rotation":{x:.237,y:.057,z:.089},"RightHandMiddle2.rotation":{x:.469,y:.036,z:.081},"RightHandMiddle3.rotation":{x:.206,y:.015,z:.017},"RightHandRing1.rotation":{x:.204,y:.086,z:.135},"RightHandRing2.rotation":{x:.579,y:-.02,z:.098},"RightHandRing3.rotation":{x:.272,y:-.021,z:.063},"RightHandPinky1.rotation":{x:.404,y:.182,z:.137},"RightHandPinky2.rotation":{x:.613,y:-.128,z:.144},"RightHandPinky3.rotation":{x:.268,y:-.094,z:.081},"LeftUpLeg.rotation":{x:.096,y:.209,z:2.983},"LeftLeg.rotation":{x:-.053,y:.042,z:-.017},"LeftFoot.rotation":{x:1.091,y:.15,z:.026},"LeftToeBase.rotation":{x:.469,y:-.07,z:-.015},"RightUpLeg.rotation":{x:-.307,y:-.219,z:2.912},"RightLeg.rotation":{x:-.359,y:.164,z:.015},"RightFoot.rotation":{x:1.035,y:.11,z:.005},"RightToeBase.rotation":{x:.467,y:.07,z:.015}}},hip:{standing:!0,props:{"Hips.position":{x:0,y:1,z:0},"Hips.rotation":{x:-.036,y:.09,z:.135},"Spine.rotation":{x:.076,y:-.035,z:.01},"Spine1.rotation":{x:-.096,y:.013,z:-.094},"Spine2.rotation":{x:-.014,y:.002,z:-.097},"Neck.rotation":{x:.034,y:-.051,z:-.075},"Head.rotation":{x:.298,y:-.1,z:.154},"LeftShoulder.rotation":{x:1.694,y:.011,z:-1.68},"LeftArm.rotation":{x:1.343,y:.177,z:-.153},"LeftForeArm.rotation":{x:-.049,y:.134,z:.351},"LeftHand.rotation":{x:.057,y:-.189,z:-.026},"LeftHandThumb1.rotation":{x:.368,y:-.066,z:.438},"LeftHandThumb2.rotation":{x:-.156,y:.029,z:-.369},"LeftHandThumb3.rotation":{x:.034,y:-.009,z:.016},"LeftHandIndex1.rotation":{x:.157,y:-.002,z:-.171},"LeftHandIndex2.rotation":{x:.099,y:0,z:0},"LeftHandIndex3.rotation":{x:.1,y:0,z:0},"LeftHandMiddle1.rotation":{x:.222,y:-.019,z:-.16},"LeftHandMiddle2.rotation":{x:.142,y:0,z:0},"LeftHandMiddle3.rotation":{x:.141,y:0,z:0},"LeftHandRing1.rotation":{x:.333,y:-.039,z:-.174},"LeftHandRing2.rotation":{x:.214,y:0,z:0},"LeftHandRing3.rotation":{x:.213,y:0,z:0},"LeftHandPinky1.rotation":{x:.483,y:-.069,z:-.189},"LeftHandPinky2.rotation":{x:.312,y:0,z:0},"LeftHandPinky3.rotation":{x:.309,y:0,z:0},"RightShoulder.rotation":{x:1.597,y:.012,z:1.816},"RightArm.rotation":{x:.618,y:-1.274,z:-.266},"RightForeArm.rotation":{x:-.395,y:-.097,z:-1.342},"RightHand.rotation":{x:-.816,y:-.057,z:-.976},"RightHandThumb1.rotation":{x:.42,y:.23,z:-1.172},"RightHandThumb2.rotation":{x:-.027,y:.361,z:.122},"RightHandThumb3.rotation":{x:.076,y:.125,z:-.371},"RightHandIndex1.rotation":{x:-.158,y:-.045,z:.033},"RightHandIndex2.rotation":{x:.391,y:.051,z:.025},"RightHandIndex3.rotation":{x:.317,y:.058,z:.07},"RightHandMiddle1.rotation":{x:.486,y:.066,z:.014},"RightHandMiddle2.rotation":{x:.718,y:.055,z:.07},"RightHandMiddle3.rotation":{x:.453,y:.019,z:.013},"RightHandRing1.rotation":{x:.591,y:.241,z:.11},"RightHandRing2.rotation":{x:1.014,y:.023,z:.097},"RightHandRing3.rotation":{x:.708,y:.008,z:.066},"RightHandPinky1.rotation":{x:1.02,y:.305,z:.051},"RightHandPinky2.rotation":{x:1.187,y:-.028,z:.191},"RightHandPinky3.rotation":{x:.872,y:-.031,z:.121},"LeftUpLeg.rotation":{x:-.095,y:-.058,z:-3.338},"LeftLeg.rotation":{x:-.366,y:.287,z:-.021},"LeftFoot.rotation":{x:1.131,y:.21,z:.176},"LeftToeBase.rotation":{x:.739,y:-.068,z:-.001},"RightUpLeg.rotation":{x:-.502,y:.362,z:3.153},"RightLeg.rotation":{x:-1.002,y:.109,z:.008},"RightFoot.rotation":{x:.626,y:-.097,z:-.194},"RightToeBase.rotation":{x:1.33,y:.288,z:-.078}}},turn:{standing:!0,props:{"Hips.position":{x:0,y:1,z:0},"Hips.rotation":{x:-.07,y:-.604,z:-.004},"Spine.rotation":{x:-.007,y:.003,z:.071},"Spine1.rotation":{x:-.053,y:.024,z:-.06},"Spine2.rotation":{x:.074,y:.013,z:-.068},"Neck.rotation":{x:.03,y:.186,z:-.077},"Head.rotation":{x:.045,y:.243,z:-.086},"LeftShoulder.rotation":{x:1.717,y:-.085,z:-1.761},"LeftArm.rotation":{x:1.314,y:.07,z:-.057},"LeftForeArm.rotation":{x:-.151,y:.714,z:.302},"LeftHand.rotation":{x:-.069,y:.003,z:-.118},"LeftHandThumb1.rotation":{x:.23,y:.258,z:.354},"LeftHandThumb2.rotation":{x:-.107,y:-.338,z:-.455},"LeftHandThumb3.rotation":{x:-.015,y:-.142,z:.002},"LeftHandIndex1.rotation":{x:.145,y:.032,z:-.069},"LeftHandIndex2.rotation":{x:.323,y:-.049,z:-.028},"LeftHandIndex3.rotation":{x:.249,y:-.053,z:-.074},"LeftHandMiddle1.rotation":{x:.235,y:-.057,z:-.088},"LeftHandMiddle2.rotation":{x:.468,y:-.036,z:-.081},"LeftHandMiddle3.rotation":{x:.203,y:-.015,z:-.017},"LeftHandRing1.rotation":{x:.185,y:-.118,z:-.157},"LeftHandRing2.rotation":{x:.578,y:.02,z:-.097},"LeftHandRing3.rotation":{x:.27,y:.021,z:-.063},"LeftHandPinky1.rotation":{x:.404,y:-.182,z:-.138},"LeftHandPinky2.rotation":{x:.612,y:.128,z:-.144},"LeftHandPinky3.rotation":{x:.267,y:.094,z:-.081},"RightShoulder.rotation":{x:1.605,y:.17,z:1.625},"RightArm.rotation":{x:1.574,y:-.655,z:.388},"RightForeArm.rotation":{x:-.36,y:-.849,z:-.465},"RightHand.rotation":{x:.114,y:.416,z:-.069},"RightHandThumb1.rotation":{x:.486,y:.009,z:-.492},"RightHandThumb2.rotation":{x:-.073,y:-.01,z:.284},"RightHandThumb3.rotation":{x:-.054,y:-.006,z:.209},"RightHandIndex1.rotation":{x:.245,y:-.014,z:.052},"RightHandIndex2.rotation":{x:.155,y:0,z:0},"RightHandIndex3.rotation":{x:.153,y:0,z:0},"RightHandMiddle1.rotation":{x:.238,y:.004,z:.028},"RightHandMiddle2.rotation":{x:.15,y:0,z:0},"RightHandMiddle3.rotation":{x:.149,y:0,z:0},"RightHandRing1.rotation":{x:.267,y:.012,z:.007},"RightHandRing2.rotation":{x:.169,y:0,z:0},"RightHandRing3.rotation":{x:.167,y:0,z:0},"RightHandPinky1.rotation":{x:.304,y:.018,z:-.021},"RightHandPinky2.rotation":{x:.192,y:0,z:0},"RightHandPinky3.rotation":{x:.19,y:0,z:0},"LeftUpLeg.rotation":{x:-.001,y:-.058,z:-3.238},"LeftLeg.rotation":{x:-.29,y:.058,z:-.021},"LeftFoot.rotation":{x:1.288,y:.168,z:.183},"LeftToeBase.rotation":{x:.363,y:-.09,z:-.01},"RightUpLeg.rotation":{x:-.1,y:.36,z:3.062},"RightLeg.rotation":{x:-.67,y:-.304,z:.043},"RightFoot.rotation":{x:1.195,y:-.159,z:-.294},"RightToeBase.rotation":{x:.737,y:.164,z:-.002}}},bend:{bend:!0,standing:!0,props:{"Hips.position":{x:-.007,y:.943,z:-.001},"Hips.rotation":{x:1.488,y:-.633,z:1.435},"Spine.rotation":{x:-.126,y:.007,z:-.057},"Spine1.rotation":{x:-.134,y:.009,z:.01},"Spine2.rotation":{x:-.019,y:0,z:-.002},"Neck.rotation":{x:-.159,y:.572,z:-.108},"Head.rotation":{x:-.064,y:.716,z:-.257},"RightShoulder.rotation":{x:1.625,y:-.043,z:1.382},"RightArm.rotation":{x:.746,y:-.96,z:-1.009},"RightForeArm.rotation":{x:-.199,y:-.528,z:-.38},"RightHand.rotation":{x:-.261,y:-.043,z:-.027},"RightHandThumb1.rotation":{x:.172,y:-.138,z:-.445},"RightHandThumb2.rotation":{x:-.158,y:.327,z:.545},"RightHandThumb3.rotation":{x:-.062,y:.138,z:.152},"RightHandIndex1.rotation":{x:.328,y:-.005,z:.132},"RightHandIndex2.rotation":{x:.303,y:.049,z:.028},"RightHandIndex3.rotation":{x:.241,y:.046,z:.077},"RightHandMiddle1.rotation":{x:.309,y:.074,z:.089},"RightHandMiddle2.rotation":{x:.392,y:.036,z:.081},"RightHandMiddle3.rotation":{x:.199,y:.014,z:.019},"RightHandRing1.rotation":{x:.239,y:.143,z:.091},"RightHandRing2.rotation":{x:.275,y:-.02,z:.097},"RightHandRing3.rotation":{x:.248,y:-.023,z:.061},"RightHandPinky1.rotation":{x:.211,y:.154,z:.029},"RightHandPinky2.rotation":{x:.348,y:-.128,z:.144},"RightHandPinky3.rotation":{x:.21,y:-.091,z:.065},"LeftShoulder.rotation":{x:1.626,y:-.027,z:-1.367},"LeftArm.rotation":{x:1.048,y:.737,z:.712},"LeftForeArm.rotation":{x:-.508,y:.879,z:.625},"LeftHand.rotation":{x:.06,y:-.243,z:-.079},"LeftHandThumb1.rotation":{x:.187,y:-.072,z:.346},"LeftHandThumb2.rotation":{x:-.066,y:.008,z:-.256},"LeftHandThumb3.rotation":{x:-.085,y:.014,z:-.334},"LeftHandIndex1.rotation":{x:-.1,y:.016,z:-.058},"LeftHandIndex2.rotation":{x:.334,y:0,z:0},"LeftHandIndex3.rotation":{x:.281,y:0,z:0},"LeftHandMiddle1.rotation":{x:-.056,y:0,z:0},"LeftHandMiddle2.rotation":{x:.258,y:0,z:0},"LeftHandMiddle3.rotation":{x:.26,y:0,z:0},"LeftHandRing1.rotation":{x:-.067,y:-.002,z:.008},"LeftHandRing2.rotation":{x:.259,y:0,z:0},"LeftHandRing3.rotation":{x:.276,y:0,z:0},"LeftHandPinky1.rotation":{x:-.128,y:-.007,z:.042},"LeftHandPinky2.rotation":{x:.227,y:0,z:0},"LeftHandPinky3.rotation":{x:.145,y:0,z:0},"RightUpLeg.rotation":{x:-1.507,y:.2,z:-3.043},"RightLeg.rotation":{x:-.689,y:-.124,z:.017},"RightFoot.rotation":{x:.909,y:.008,z:-.093},"RightToeBase.rotation":{x:.842,y:.075,z:-.008},"LeftUpLeg.rotation":{x:-1.449,y:-.2,z:3.018},"LeftLeg.rotation":{x:-.74,y:-.115,z:-.008},"LeftFoot.rotation":{x:1.048,y:-.058,z:.117},"LeftToeBase.rotation":{x:.807,y:-.067,z:.003}}},back:{standing:!0,props:{"Hips.position":{x:0,y:1,z:0},"Hips.rotation":{x:-.732,y:-1.463,z:-.637},"Spine.rotation":{x:-.171,y:.106,z:.157},"Spine1.rotation":{x:-.044,y:.138,z:-.059},"Spine2.rotation":{x:.082,y:.133,z:-.074},"Neck.rotation":{x:.39,y:.591,z:-.248},"Head.rotation":{x:-.001,y:.596,z:-.057},"LeftShoulder.rotation":{x:1.676,y:.007,z:-1.892},"LeftArm.rotation":{x:-5.566,y:1.188,z:-.173},"LeftForeArm.rotation":{x:-.673,y:-.105,z:1.702},"LeftHand.rotation":{x:-.469,y:-.739,z:.003},"LeftHandThumb1.rotation":{x:.876,y:.274,z:.793},"LeftHandThumb2.rotation":{x:.161,y:-.23,z:-.172},"LeftHandThumb3.rotation":{x:.078,y:.027,z:.156},"LeftHandIndex1.rotation":{x:-.085,y:-.002,z:.009},"LeftHandIndex2.rotation":{x:.176,y:0,z:-.002},"LeftHandIndex3.rotation":{x:-.036,y:.001,z:-.035},"LeftHandMiddle1.rotation":{x:.015,y:.144,z:-.076},"LeftHandMiddle2.rotation":{x:.378,y:-.007,z:-.077},"LeftHandMiddle3.rotation":{x:-.141,y:-.001,z:.031},"LeftHandRing1.rotation":{x:.039,y:.02,z:-.2},"LeftHandRing2.rotation":{x:.25,y:-.002,z:-.073},"LeftHandRing3.rotation":{x:.236,y:.006,z:-.075},"LeftHandPinky1.rotation":{x:.172,y:-.033,z:-.275},"LeftHandPinky2.rotation":{x:.216,y:.043,z:-.054},"LeftHandPinky3.rotation":{x:.325,y:.078,z:-.13},"RightShoulder.rotation":{x:2.015,y:-.168,z:1.706},"RightArm.rotation":{x:.203,y:-1.258,z:-.782},"RightForeArm.rotation":{x:-.658,y:-.133,z:-1.401},"RightHand.rotation":{x:-1.504,y:.375,z:-.005},"RightHandThumb1.rotation":{x:.413,y:-.158,z:-1.121},"RightHandThumb2.rotation":{x:-.142,y:-.008,z:.209},"RightHandThumb3.rotation":{x:-.091,y:.021,z:.142},"RightHandIndex1.rotation":{x:-.167,y:.014,z:-.072},"RightHandIndex2.rotation":{x:.474,y:.009,z:.051},"RightHandIndex3.rotation":{x:.115,y:.006,z:.047},"RightHandMiddle1.rotation":{x:.385,y:.019,z:.144},"RightHandMiddle2.rotation":{x:.559,y:.035,z:.101},"RightHandMiddle3.rotation":{x:.229,y:0,z:.027},"RightHandRing1.rotation":{x:.48,y:.026,z:.23},"RightHandRing2.rotation":{x:.772,y:.038,z:.109},"RightHandRing3.rotation":{x:.622,y:.039,z:.106},"RightHandPinky1.rotation":{x:.767,y:.288,z:.353},"RightHandPinky2.rotation":{x:.886,y:.049,z:.122},"RightHandPinky3.rotation":{x:.662,y:.044,z:.113},"LeftUpLeg.rotation":{x:-.206,y:-.268,z:-3.343},"LeftLeg.rotation":{x:-.333,y:.757,z:-.043},"LeftFoot.rotation":{x:1.049,y:.167,z:.287},"LeftToeBase.rotation":{x:.672,y:-.069,z:-.004},"RightUpLeg.rotation":{x:.055,y:-.226,z:3.037},"RightLeg.rotation":{x:-.559,y:.39,z:-.001},"RightFoot.rotation":{x:1.2,y:.133,z:.085},"RightToeBase.rotation":{x:.92,y:.093,z:-.013}}},straight:{standing:!0,props:{"Hips.position":{x:0,y:.989,z:.001},"Hips.rotation":{x:.047,y:.007,z:-.007},"Spine.rotation":{x:-.143,y:-.007,z:.005},"Spine1.rotation":{x:-.043,y:-.014,z:.012},"Spine2.rotation":{x:.072,y:-.013,z:.013},"Neck.rotation":{x:.048,y:-.003,z:.012},"Head.rotation":{x:.05,y:-.02,z:-.017},"LeftShoulder.rotation":{x:1.62,y:-.166,z:-1.605},"LeftArm.rotation":{x:1.275,y:.544,z:-.092},"LeftForeArm.rotation":{x:0,y:0,z:.302},"LeftHand.rotation":{x:-.225,y:-.154,z:.11},"LeftHandThumb1.rotation":{x:.435,y:-.044,z:.457},"LeftHandThumb2.rotation":{x:-.028,y:.002,z:-.246},"LeftHandThumb3.rotation":{x:-.236,y:-.025,z:.113},"LeftHandIndex1.rotation":{x:.218,y:.008,z:-.081},"LeftHandIndex2.rotation":{x:.165,y:-.001,z:-.017},"LeftHandIndex3.rotation":{x:.165,y:-.001,z:-.017},"LeftHandMiddle1.rotation":{x:.235,y:-.011,z:-.065},"LeftHandMiddle2.rotation":{x:.182,y:-.002,z:-.019},"LeftHandMiddle3.rotation":{x:.182,y:-.002,z:-.019},"LeftHandRing1.rotation":{x:.316,y:-.017,z:.008},"LeftHandRing2.rotation":{x:.253,y:-.003,z:-.026},"LeftHandRing3.rotation":{x:.255,y:-.003,z:-.026},"LeftHandPinky1.rotation":{x:.336,y:-.062,z:.088},"LeftHandPinky2.rotation":{x:.276,y:-.004,z:-.028},"LeftHandPinky3.rotation":{x:.276,y:-.004,z:-.028},"RightShoulder.rotation":{x:1.615,y:.064,z:1.53},"RightArm.rotation":{x:1.313,y:-.424,z:.131},"RightForeArm.rotation":{x:0,y:0,z:-.317},"RightHand.rotation":{x:-.158,y:-.639,z:-.196},"RightHandThumb1.rotation":{x:.44,y:.048,z:-.549},"RightHandThumb2.rotation":{x:-.056,y:-.008,z:.274},"RightHandThumb3.rotation":{x:-.258,y:.031,z:-.095},"RightHandIndex1.rotation":{x:.169,y:-.011,z:.105},"RightHandIndex2.rotation":{x:.134,y:.001,z:.011},"RightHandIndex3.rotation":{x:.134,y:.001,z:.011},"RightHandMiddle1.rotation":{x:.288,y:.014,z:.092},"RightHandMiddle2.rotation":{x:.248,y:.003,z:.02},"RightHandMiddle3.rotation":{x:.249,y:.003,z:.02},"RightHandRing1.rotation":{x:.369,y:.019,z:.006},"RightHandRing2.rotation":{x:.321,y:.004,z:.026},"RightHandRing3.rotation":{x:.323,y:.004,z:.026},"RightHandPinky1.rotation":{x:.468,y:.085,z:-.03},"RightHandPinky2.rotation":{x:.427,y:.007,z:.034},"RightHandPinky3.rotation":{x:.142,y:.001,z:.012},"LeftUpLeg.rotation":{x:-.077,y:-.058,z:3.126},"LeftLeg.rotation":{x:-.252,y:.001,z:-.018},"LeftFoot.rotation":{x:1.315,y:-.064,z:.315},"LeftToeBase.rotation":{x:.577,y:-.07,z:-.009},"RightUpLeg.rotation":{x:-.083,y:-.032,z:3.124},"RightLeg.rotation":{x:-.272,y:-.003,z:.021},"RightFoot.rotation":{x:1.342,y:.076,z:-.222},"RightToeBase.rotation":{x:.44,y:.069,z:.016}}},wide:{standing:!0,props:{"Hips.position":{x:0,y:1.017,z:.016},"Hips.rotation":{x:.064,y:-.048,z:.059},"Spine.rotation":{x:-.123,y:0,z:-.018},"Spine1.rotation":{x:.014,y:.003,z:-.006},"Spine2.rotation":{x:.04,y:.003,z:-.007},"Neck.rotation":{x:.101,y:.007,z:-.035},"Head.rotation":{x:-.091,y:-.049,z:.105},"RightShoulder.rotation":{x:1.831,y:.017,z:1.731},"RightArm.rotation":{x:-1.673,y:-1.102,z:-3.132},"RightForeArm.rotation":{x:.265,y:.23,z:-.824},"RightHand.rotation":{x:-.52,y:.345,z:-.061},"RightHandThumb1.rotation":{x:.291,y:.056,z:-.428},"RightHandThumb2.rotation":{x:.025,y:.005,z:.166},"RightHandThumb3.rotation":{x:-.089,y:.009,z:.068},"RightHandIndex1.rotation":{x:.392,y:-.015,z:.11},"RightHandIndex2.rotation":{x:.391,y:.001,z:.004},"RightHandIndex3.rotation":{x:.326,y:0,z:.003},"RightHandMiddle1.rotation":{x:.285,y:.068,z:.081},"RightHandMiddle2.rotation":{x:.519,y:.004,z:.011},"RightHandMiddle3.rotation":{x:.252,y:0,z:.001},"RightHandRing1.rotation":{x:.207,y:.133,z:.146},"RightHandRing2.rotation":{x:.597,y:.004,z:.004},"RightHandRing3.rotation":{x:.292,y:.002,z:.012},"RightHandPinky1.rotation":{x:.338,y:.182,z:.136},"RightHandPinky2.rotation":{x:.533,y:.002,z:.004},"RightHandPinky3.rotation":{x:.194,y:0,z:.002},"LeftShoulder.rotation":{x:1.83,y:-.063,z:-1.808},"LeftArm.rotation":{x:-1.907,y:1.228,z:-2.959},"LeftForeArm.rotation":{x:-.159,y:.268,z:.572},"LeftHand.rotation":{x:.069,y:-.498,z:-.025},"LeftHandThumb1.rotation":{x:.738,y:.123,z:.178},"LeftHandThumb2.rotation":{x:-.26,y:.028,z:-.477},"LeftHandThumb3.rotation":{x:-.448,y:.093,z:-.661},"LeftHandIndex1.rotation":{x:1.064,y:.005,z:-.13},"LeftHandIndex2.rotation":{x:1.55,y:-.143,z:-.136},"LeftHandIndex3.rotation":{x:.722,y:-.076,z:-.127},"LeftHandMiddle1.rotation":{x:1.095,y:-.091,z:.006},"LeftHandMiddle2.rotation":{x:1.493,y:-.174,z:-.151},"LeftHandMiddle3.rotation":{x:.651,y:-.031,z:-.087},"LeftHandRing1.rotation":{x:1.083,y:-.224,z:.072},"LeftHandRing2.rotation":{x:1.145,y:-.107,z:-.195},"LeftHandRing3.rotation":{x:1.208,y:-.134,z:-.158},"LeftHandPinky1.rotation":{x:.964,y:-.383,z:.128},"LeftHandPinky2.rotation":{x:1.457,y:-.146,z:-.159},"LeftHandPinky3.rotation":{x:1.019,y:-.102,z:-.141},"RightUpLeg.rotation":{x:-.221,y:-.233,z:2.87},"RightLeg.rotation":{x:-.339,y:-.043,z:-.041},"RightFoot.rotation":{x:1.081,y:.177,z:.114},"RightToeBase.rotation":{x:.775,y:0,z:0},"LeftUpLeg.rotation":{x:-.185,y:.184,z:3.131},"LeftLeg.rotation":{x:-.408,y:.129,z:.02},"LeftFoot.rotation":{x:1.167,y:-.002,z:-.007},"LeftToeBase.rotation":{x:.723,y:0,z:0}}},oneknee:{kneeling:!0,props:{"Hips.position":{x:-.005,y:.415,z:-.017},"Hips.rotation":{x:-.25,y:.04,z:-.238},"Spine.rotation":{x:.037,y:.043,z:.047},"Spine1.rotation":{x:.317,y:.103,z:.066},"Spine2.rotation":{x:.433,y:.109,z:.054},"Neck.rotation":{x:-.156,y:-.092,z:.059},"Head.rotation":{x:-.398,y:-.032,z:.018},"RightShoulder.rotation":{x:1.546,y:.119,z:1.528},"RightArm.rotation":{x:.896,y:-.247,z:-.512},"RightForeArm.rotation":{x:.007,y:0,z:-1.622},"RightHand.rotation":{x:1.139,y:-.853,z:.874},"RightHandThumb1.rotation":{x:.176,y:.107,z:-.311},"RightHandThumb2.rotation":{x:-.047,y:-.003,z:.12},"RightHandThumb3.rotation":{x:0,y:0,z:0},"RightHandIndex1.rotation":{x:.186,y:.005,z:.125},"RightHandIndex2.rotation":{x:.454,y:.005,z:.015},"RightHandIndex3.rotation":{x:0,y:0,z:0},"RightHandMiddle1.rotation":{x:.444,y:.035,z:.127},"RightHandMiddle2.rotation":{x:.403,y:-.006,z:-.04},"RightHandMiddle3.rotation":{x:0,y:0,z:0},"RightHandRing1.rotation":{x:.543,y:.074,z:.121},"RightHandRing2.rotation":{x:.48,y:-.018,z:-.063},"RightHandRing3.rotation":{x:0,y:0,z:0},"RightHandPinky1.rotation":{x:.464,y:.086,z:.113},"RightHandPinky2.rotation":{x:.667,y:-.06,z:-.128},"RightHandPinky3.rotation":{x:0,y:0,z:0},"LeftShoulder.rotation":{x:1.545,y:-.116,z:-1.529},"LeftArm.rotation":{x:.799,y:.631,z:.556},"LeftForeArm.rotation":{x:-.002,y:.007,z:.926},"LeftHand.rotation":{x:-.508,y:.439,z:.502},"LeftHandThumb1.rotation":{x:.651,y:-.035,z:.308},"LeftHandThumb2.rotation":{x:-.053,y:.008,z:-.11},"LeftHandThumb3.rotation":{x:0,y:0,z:0},"LeftHandIndex1.rotation":{x:.662,y:-.053,z:-.116},"LeftHandIndex2.rotation":{x:.309,y:-.004,z:-.02},"LeftHandIndex3.rotation":{x:0,y:0,z:0},"LeftHandMiddle1.rotation":{x:.501,y:-.062,z:-.12},"LeftHandMiddle2.rotation":{x:.144,y:-.002,z:.016},"LeftHandMiddle3.rotation":{x:0,y:0,z:0},"LeftHandRing1.rotation":{x:.397,y:-.029,z:-.143},"LeftHandRing2.rotation":{x:.328,y:.01,z:.059},"LeftHandRing3.rotation":{x:0,y:0,z:0},"LeftHandPinky1.rotation":{x:.194,y:.008,z:-.164},"LeftHandPinky2.rotation":{x:.38,y:.031,z:.128},"LeftHandPinky3.rotation":{x:0,y:0,z:0},"RightUpLeg.rotation":{x:-1.594,y:-.251,z:2.792},"RightLeg.rotation":{x:-2.301,y:-.073,z:.055},"RightFoot.rotation":{x:1.553,y:-.207,z:-.094},"RightToeBase.rotation":{x:.459,y:.069,z:.016},"LeftUpLeg.rotation":{x:-.788,y:-.236,z:-2.881},"LeftLeg.rotation":{x:-2.703,y:.012,z:-.047},"LeftFoot.rotation":{x:2.191,y:-.102,z:.019},"LeftToeBase.rotation":{x:1.215,y:-.027,z:.01}}},kneel:{kneeling:!0,lying:!0,props:{"Hips.position":{x:0,y:.532,z:-.002},"Hips.rotation":{x:.018,y:-.008,z:-.017},"Spine.rotation":{x:-.139,y:-.01,z:.002},"Spine1.rotation":{x:.002,y:-.002,z:.001},"Spine2.rotation":{x:.028,y:-.002,z:.001},"Neck.rotation":{x:-.007,y:0,z:-.002},"Head.rotation":{x:-.02,y:-.008,z:-.004},"LeftShoulder.rotation":{x:1.77,y:-.428,z:-1.588},"LeftArm.rotation":{x:.911,y:.343,z:.083},"LeftForeArm.rotation":{x:0,y:0,z:.347},"LeftHand.rotation":{x:.033,y:-.052,z:-.105},"LeftHandThumb1.rotation":{x:.508,y:-.22,z:.708},"LeftHandThumb2.rotation":{x:-.323,y:-.139,z:-.56},"LeftHandThumb3.rotation":{x:-.328,y:.16,z:-.301},"LeftHandIndex1.rotation":{x:.178,y:.248,z:.045},"LeftHandIndex2.rotation":{x:.236,y:-.002,z:-.019},"LeftHandIndex3.rotation":{x:-.062,y:0,z:.005},"LeftHandMiddle1.rotation":{x:.123,y:-.005,z:-.019},"LeftHandMiddle2.rotation":{x:.589,y:-.014,z:-.045},"LeftHandMiddle3.rotation":{x:.231,y:-.002,z:-.019},"LeftHandRing1.rotation":{x:.196,y:-.008,z:-.091},"LeftHandRing2.rotation":{x:.483,y:-.009,z:-.038},"LeftHandRing3.rotation":{x:.367,y:-.005,z:-.029},"LeftHandPinky1.rotation":{x:.191,y:-.269,z:-.246},"LeftHandPinky2.rotation":{x:.37,y:-.006,z:-.029},"LeftHandPinky3.rotation":{x:.368,y:-.005,z:-.029},"RightShoulder.rotation":{x:1.73,y:.434,z:1.715},"RightArm.rotation":{x:.841,y:-.508,z:-.155},"RightForeArm.rotation":{x:0,y:0,z:-.355},"RightHand.rotation":{x:.091,y:.137,z:.197},"RightHandThumb1.rotation":{x:.33,y:.051,z:-.753},"RightHandThumb2.rotation":{x:-.113,y:.075,z:.612},"RightHandThumb3.rotation":{x:-.271,y:-.166,z:.164},"RightHandIndex1.rotation":{x:.073,y:.001,z:-.093},"RightHandIndex2.rotation":{x:.338,y:.006,z:.034},"RightHandIndex3.rotation":{x:.131,y:.001,z:.013},"RightHandMiddle1.rotation":{x:.13,y:.005,z:-.017},"RightHandMiddle2.rotation":{x:.602,y:.018,z:.058},"RightHandMiddle3.rotation":{x:-.031,y:0,z:-.003},"RightHandRing1.rotation":{x:.351,y:.019,z:.045},"RightHandRing2.rotation":{x:.19,y:.002,z:.019},"RightHandRing3.rotation":{x:.21,y:.002,z:.021},"RightHandPinky1.rotation":{x:.256,y:.17,z:.118},"RightHandPinky2.rotation":{x:.451,y:.01,z:.045},"RightHandPinky3.rotation":{x:.346,y:.006,z:.035},"LeftUpLeg.rotation":{x:-.06,y:.1,z:-2.918},"LeftLeg.rotation":{x:-1.933,y:-.01,z:.011},"LeftFoot.rotation":{x:.774,y:-.162,z:-.144},"LeftToeBase.rotation":{x:1.188,y:0,z:0},"RightUpLeg.rotation":{x:-.099,y:-.057,z:2.922},"RightLeg.rotation":{x:-1.93,y:.172,z:-.02},"RightFoot.rotation":{x:.644,y:.251,z:.212},"RightToeBase.rotation":{x:.638,y:-.034,z:-.001}}},sitting:{sitting:!0,lying:!0,props:{"Hips.position":{x:0,y:.117,z:.005},"Hips.rotation":{x:-.411,y:-.049,z:.056},"Spine.rotation":{x:.45,y:-.039,z:-.116},"Spine1.rotation":{x:.092,y:-.076,z:.08},"Spine2.rotation":{x:.073,y:.035,z:.066},"Neck.rotation":{x:.051,y:.053,z:-.079},"Head.rotation":{x:-.169,y:.009,z:.034},"LeftShoulder.rotation":{x:1.756,y:-.037,z:-1.301},"LeftArm.rotation":{x:-.098,y:.016,z:1.006},"LeftForeArm.rotation":{x:-.089,y:.08,z:.837},"LeftHand.rotation":{x:.262,y:-.399,z:.3},"LeftHandThumb1.rotation":{x:.149,y:-.043,z:.452},"LeftHandThumb2.rotation":{x:.032,y:.006,z:-.162},"LeftHandThumb3.rotation":{x:-.086,y:-.005,z:-.069},"LeftHandIndex1.rotation":{x:.145,y:.032,z:-.069},"LeftHandIndex2.rotation":{x:.325,y:-.001,z:-.004},"LeftHandIndex3.rotation":{x:.253,y:0,z:-.003},"LeftHandMiddle1.rotation":{x:.186,y:-.051,z:-.091},"LeftHandMiddle2.rotation":{x:.42,y:-.003,z:-.011},"LeftHandMiddle3.rotation":{x:.153,y:.001,z:-.001},"LeftHandRing1.rotation":{x:.087,y:-.19,z:-.078},"LeftHandRing2.rotation":{x:.488,y:-.004,z:-.005},"LeftHandRing3.rotation":{x:.183,y:-.001,z:-.012},"LeftHandPinky1.rotation":{x:.205,y:-.262,z:.051},"LeftHandPinky2.rotation":{x:.407,y:-.002,z:-.004},"LeftHandPinky3.rotation":{x:.068,y:0,z:-.002},"RightShoulder.rotation":{x:1.619,y:-.139,z:1.179},"RightArm.rotation":{x:.17,y:-.037,z:-1.07},"RightForeArm.rotation":{x:-.044,y:-.056,z:-.665},"RightHand.rotation":{x:.278,y:.454,z:-.253},"RightHandThumb1.rotation":{x:.173,y:.089,z:-.584},"RightHandThumb2.rotation":{x:-.003,y:-.004,z:.299},"RightHandThumb3.rotation":{x:-.133,y:-.002,z:.235},"RightHandIndex1.rotation":{x:.393,y:-.023,z:.108},"RightHandIndex2.rotation":{x:.391,y:.001,z:.004},"RightHandIndex3.rotation":{x:.326,y:0,z:.003},"RightHandMiddle1.rotation":{x:.285,y:.062,z:.086},"RightHandMiddle2.rotation":{x:.519,y:.003,z:.011},"RightHandMiddle3.rotation":{x:.252,y:-.001,z:.001},"RightHandRing1.rotation":{x:.207,y:.122,z:.155},"RightHandRing2.rotation":{x:.597,y:.004,z:.005},"RightHandRing3.rotation":{x:.292,y:.001,z:.012},"RightHandPinky1.rotation":{x:.338,y:.171,z:.149},"RightHandPinky2.rotation":{x:.533,y:.002,z:.004},"RightHandPinky3.rotation":{x:.194,y:0,z:.002},"LeftUpLeg.rotation":{x:-1.957,y:.083,z:-2.886},"LeftLeg.rotation":{x:-1.46,y:.123,z:.005},"LeftFoot.rotation":{x:-.013,y:.016,z:.09},"LeftToeBase.rotation":{x:.744,y:0,z:0},"RightUpLeg.rotation":{x:-1.994,y:.125,z:2.905},"RightLeg.rotation":{x:-1.5,y:-.202,z:-.006},"RightFoot.rotation":{x:-.012,y:-.065,z:.081},"RightToeBase.rotation":{x:.758,y:0,z:0}}}},this.gestureTemplates={handup:{"LeftShoulder.rotation":{x:[1.5,2,1,2],y:[.2,.4,1,2],z:[-1.5,-1.3,1,2]},"LeftArm.rotation":{x:[1.5,1.7,1,2],y:[-.6,-.4,1,2],z:[1,1.2,1,2]},"LeftForeArm.rotation":{x:-.815,y:[-.4,0,1,2],z:1.575},"LeftHand.rotation":{x:-.529,y:-.2,z:.022},"LeftHandThumb1.rotation":{x:.745,y:-.526,z:.604},"LeftHandThumb2.rotation":{x:-.107,y:-.01,z:-.142},"LeftHandThumb3.rotation":{x:0,y:.001,z:0},"LeftHandIndex1.rotation":{x:-.126,y:-.035,z:-.087},"LeftHandIndex2.rotation":{x:.255,y:.007,z:-.085},"LeftHandIndex3.rotation":{x:0,y:0,z:0},"LeftHandMiddle1.rotation":{x:-.019,y:-.128,z:-.082},"LeftHandMiddle2.rotation":{x:.233,y:.019,z:-.074},"LeftHandMiddle3.rotation":{x:0,y:0,z:0},"LeftHandRing1.rotation":{x:.005,y:-.241,z:-.122},"LeftHandRing2.rotation":{x:.261,y:.021,z:-.076},"LeftHandRing3.rotation":{x:0,y:0,z:0},"LeftHandPinky1.rotation":{x:.059,y:-.336,z:-.2},"LeftHandPinky2.rotation":{x:.153,y:.019,z:.001},"LeftHandPinky3.rotation":{x:0,y:0,z:0}},index:{"LeftShoulder.rotation":{x:[1.5,2,1,2],y:[.2,.4,1,2],z:[-1.5,-1.3,1,2]},"LeftArm.rotation":{x:[1.5,1.7,1,2],y:[-.6,-.4,1,2],z:[1,1.2,1,2]},"LeftForeArm.rotation":{x:-.815,y:[-.4,0,1,2],z:1.575},"LeftHand.rotation":{x:-.276,y:-.506,z:-.208},"LeftHandThumb1.rotation":{x:.579,y:.228,z:.363},"LeftHandThumb2.rotation":{x:-.027,y:-.04,z:-.662},"LeftHandThumb3.rotation":{x:0,y:.001,z:0},"LeftHandIndex1.rotation":{x:0,y:-.105,z:.225},"LeftHandIndex2.rotation":{x:.256,y:-.103,z:-.213},"LeftHandIndex3.rotation":{x:0,y:0,z:0},"LeftHandMiddle1.rotation":{x:1.453,y:.07,z:.021},"LeftHandMiddle2.rotation":{x:1.599,y:.062,z:.07},"LeftHandMiddle3.rotation":{x:0,y:0,z:0},"LeftHandRing1.rotation":{x:1.528,y:-.073,z:.052},"LeftHandRing2.rotation":{x:1.386,y:.044,z:.053},"LeftHandRing3.rotation":{x:0,y:0,z:0},"LeftHandPinky1.rotation":{x:1.65,y:-.204,z:.031},"LeftHandPinky2.rotation":{x:1.302,y:.071,z:.085},"LeftHandPinky3.rotation":{x:0,y:0,z:0}},ok:{"LeftShoulder.rotation":{x:[1.5,2,1,2],y:[.2,.4,1,2],z:[-1.5,-1.3,1,2]},"LeftArm.rotation":{x:[1.5,1.7,1,1],y:[-.6,-.4,1,2],z:[1,1.2,1,2]},"LeftForeArm.rotation":{x:-.415,y:[-.4,0,1,2],z:1.575},"LeftHand.rotation":{x:-.476,y:-.506,z:-.208},"LeftHandThumb1.rotation":{x:.703,y:.445,z:.899},"LeftHandThumb2.rotation":{x:-.312,y:-.04,z:-.938},"LeftHandThumb3.rotation":{x:-.37,y:.024,z:-.393},"LeftHandIndex1.rotation":{x:.8,y:-.086,z:-.091},"LeftHandIndex2.rotation":{x:1.123,y:-.046,z:-.074},"LeftHandIndex3.rotation":{x:.562,y:-.013,z:-.043},"LeftHandMiddle1.rotation":{x:-.019,y:-.128,z:-.082},"LeftHandMiddle2.rotation":{x:.233,y:.019,z:-.074},"LeftHandMiddle3.rotation":{x:0,y:0,z:0},"LeftHandRing1.rotation":{x:.005,y:-.241,z:-.122},"LeftHandRing2.rotation":{x:.261,y:.021,z:-.076},"LeftHandRing3.rotation":{x:0,y:0,z:0},"LeftHandPinky1.rotation":{x:.059,y:-.336,z:-.2},"LeftHandPinky2.rotation":{x:.153,y:.019,z:.001},"LeftHandPinky3.rotation":{x:0,y:0,z:0}},thumbup:{"LeftShoulder.rotation":{x:[1.5,2,1,2],y:[.2,.4,1,2],z:[-1.5,-1.3,1,2]},"LeftArm.rotation":{x:[1.5,1.7,1,2],y:[-.6,-.4,1,2],z:[1,1.2,1,2]},"LeftForeArm.rotation":{x:-.415,y:.206,z:1.575},"LeftHand.rotation":{x:-.276,y:-.506,z:-.208},"LeftHandThumb1.rotation":{x:.208,y:-.189,z:.685},"LeftHandThumb2.rotation":{x:.129,y:-.285,z:-.163},"LeftHandThumb3.rotation":{x:-.047,y:.068,z:.401},"LeftHandIndex1.rotation":{x:1.412,y:-.102,z:-.152},"LeftHandIndex2.rotation":{x:1.903,y:-.16,z:-.114},"LeftHandIndex3.rotation":{x:.535,y:-.017,z:-.062},"LeftHandMiddle1.rotation":{x:1.424,y:-.103,z:-.12},"LeftHandMiddle2.rotation":{x:1.919,y:-.162,z:-.114},"LeftHandMiddle3.rotation":{x:.44,y:-.012,z:-.051},"LeftHandRing1.rotation":{x:1.619,y:-.127,z:-.053},"LeftHandRing2.rotation":{x:1.898,y:-.16,z:-.115},"LeftHandRing3.rotation":{x:.262,y:-.004,z:-.031},"LeftHandPinky1.rotation":{x:1.661,y:-.131,z:-.016},"LeftHandPinky2.rotation":{x:1.715,y:-.067,z:-.13},"LeftHandPinky3.rotation":{x:.627,y:-.023,z:-.071}},thumbdown:{"LeftShoulder.rotation":{x:[1.5,2,1,2],y:[.2,.4,1,2],z:[-1.5,-1.3,1,2]},"LeftArm.rotation":{x:[1.5,1.7,1,2],y:[-.6,-.4,1,2],z:[1,1.2,1,2]},"LeftForeArm.rotation":{x:-2.015,y:.406,z:1.575},"LeftHand.rotation":{x:-.176,y:-.206,z:-.208},"LeftHandThumb1.rotation":{x:.208,y:-.189,z:.685},"LeftHandThumb2.rotation":{x:.129,y:-.285,z:-.163},"LeftHandThumb3.rotation":{x:-.047,y:.068,z:.401},"LeftHandIndex1.rotation":{x:1.412,y:-.102,z:-.152},"LeftHandIndex2.rotation":{x:1.903,y:-.16,z:-.114},"LeftHandIndex3.rotation":{x:.535,y:-.017,z:-.062},"LeftHandMiddle1.rotation":{x:1.424,y:-.103,z:-.12},"LeftHandMiddle2.rotation":{x:1.919,y:-.162,z:-.114},"LeftHandMiddle3.rotation":{x:.44,y:-.012,z:-.051},"LeftHandRing1.rotation":{x:1.619,y:-.127,z:-.053},"LeftHandRing2.rotation":{x:1.898,y:-.16,z:-.115},"LeftHandRing3.rotation":{x:.262,y:-.004,z:-.031},"LeftHandPinky1.rotation":{x:1.661,y:-.131,z:-.016},"LeftHandPinky2.rotation":{x:1.715,y:-.067,z:-.13},"LeftHandPinky3.rotation":{x:.627,y:-.023,z:-.071}},side:{"LeftShoulder.rotation":{x:1.755,y:-.035,z:-1.63},"LeftArm.rotation":{x:1.263,y:-.955,z:1.024},"LeftForeArm.rotation":{x:0,y:0,z:.8},"LeftHand.rotation":{x:-.36,y:-1.353,z:-.184},"LeftHandThumb1.rotation":{x:.137,y:-.049,z:.863},"LeftHandThumb2.rotation":{x:-.293,y:.153,z:-.193},"LeftHandThumb3.rotation":{x:-.271,y:-.17,z:.18},"LeftHandIndex1.rotation":{x:-.018,y:.007,z:.28},"LeftHandIndex2.rotation":{x:.247,y:-.003,z:-.025},"LeftHandIndex3.rotation":{x:.13,y:-.001,z:-.013},"LeftHandMiddle1.rotation":{x:.333,y:-.015,z:.182},"LeftHandMiddle2.rotation":{x:.313,y:-.005,z:-.032},"LeftHandMiddle3.rotation":{x:.294,y:-.004,z:-.03},"LeftHandRing1.rotation":{x:.456,y:-.028,z:-.092},"LeftHandRing2.rotation":{x:.53,y:-.014,z:-.052},"LeftHandRing3.rotation":{x:.478,y:-.012,z:-.047},"LeftHandPinky1.rotation":{x:.647,y:-.049,z:-.184},"LeftHandPinky2.rotation":{x:.29,y:-.004,z:-.029},"LeftHandPinky3.rotation":{x:.501,y:-.013,z:-.049}},shrug:{"Neck.rotation":{x:[-.3,.3,1,2],y:[-.3,.3,1,2],z:[-.1,.1]},"Head.rotation":{x:[-.3,.3],y:[-.3,.3],z:[-.1,.1]},"RightShoulder.rotation":{x:1.732,y:-.058,z:1.407},"RightArm.rotation":{x:1.305,y:.46,z:.118},"RightForeArm.rotation":{x:[0,2],y:[-1,.2],z:-1.637},"RightHand.rotation":{x:-.048,y:.165,z:-.39},"RightHandThumb1.rotation":{x:1.467,y:.599,z:-1.315},"RightHandThumb2.rotation":{x:-.255,y:-.123,z:.119},"RightHandThumb3.rotation":{x:0,y:-.002,z:0},"RightHandIndex1.rotation":{x:-.293,y:-.066,z:-.112},"RightHandIndex2.rotation":{x:.181,y:.007,z:.069},"RightHandIndex3.rotation":{x:0,y:0,z:0},"RightHandMiddle1.rotation":{x:-.063,y:-.041,z:.032},"RightHandMiddle2.rotation":{x:.149,y:.005,z:.05},"RightHandMiddle3.rotation":{x:0,y:0,z:0},"RightHandRing1.rotation":{x:.152,y:-.03,z:.132},"RightHandRing2.rotation":{x:.194,y:.007,z:.058},"RightHandRing3.rotation":{x:0,y:0,z:0},"RightHandPinky1.rotation":{x:.306,y:-.015,z:.257},"RightHandPinky2.rotation":{x:.15,y:-.003,z:-.003},"RightHandPinky3.rotation":{x:0,y:0,z:0},"LeftShoulder.rotation":{x:1.713,y:.141,z:-1.433},"LeftArm.rotation":{x:1.136,y:-.422,z:-.416},"LeftForeArm.rotation":{x:1.42,y:.123,z:1.506},"LeftHand.rotation":{x:.073,y:-.138,z:.064},"LeftHandThumb1.rotation":{x:1.467,y:-.599,z:1.314},"LeftHandThumb2.rotation":{x:-.255,y:.123,z:-.119},"LeftHandThumb3.rotation":{x:0,y:.001,z:0},"LeftHandIndex1.rotation":{x:-.293,y:.066,z:.112},"LeftHandIndex2.rotation":{x:.181,y:-.007,z:-.069},"LeftHandIndex3.rotation":{x:0,y:0,z:0},"LeftHandMiddle1.rotation":{x:-.062,y:.041,z:-.032},"LeftHandMiddle2.rotation":{x:.149,y:-.005,z:-.05},"LeftHandMiddle3.rotation":{x:0,y:0,z:0},"LeftHandRing1.rotation":{x:.152,y:.03,z:-.132},"LeftHandRing2.rotation":{x:.194,y:-.007,z:-.058},"LeftHandRing3.rotation":{x:0,y:0,z:0},"LeftHandPinky1.rotation":{x:.306,y:.015,z:-.257},"LeftHandPinky2.rotation":{x:.15,y:.003,z:.003},"LeftHandPinky3.rotation":{x:0,y:0,z:0}},namaste:{"RightShoulder.rotation":{x:1.758,y:.099,z:1.604},"RightArm.rotation":{x:.862,y:-.292,z:-.932},"RightForeArm.rotation":{x:.083,y:.066,z:-1.791},"RightHand.rotation":{x:-.52,y:-.001,z:-.176},"RightHandThumb1.rotation":{x:.227,y:.418,z:-.776},"RightHandThumb2.rotation":{x:-.011,y:-.003,z:.171},"RightHandThumb3.rotation":{x:-.041,y:-.001,z:-.013},"RightHandIndex1.rotation":{x:-.236,y:.003,z:-.028},"RightHandIndex2.rotation":{x:.004,y:0,z:.001},"RightHandIndex3.rotation":{x:.002,y:0,z:0},"RightHandMiddle1.rotation":{x:-.236,y:.003,z:-.028},"RightHandMiddle2.rotation":{x:.004,y:0,z:.001},"RightHandMiddle3.rotation":{x:.002,y:0,z:0},"RightHandRing1.rotation":{x:-.236,y:.003,z:-.028},"RightHandRing2.rotation":{x:.004,y:0,z:.001},"RightHandRing3.rotation":{x:.002,y:0,z:0},"RightHandPinky1.rotation":{x:-.236,y:.003,z:-.028},"RightHandPinky2.rotation":{x:.004,y:0,z:.001},"RightHandPinky3.rotation":{x:.002,y:0,z:0},"LeftShoulder.rotation":{x:1.711,y:-.002,z:-1.625},"LeftArm.rotation":{x:.683,y:.334,z:.977},"LeftForeArm.rotation":{x:.086,y:-.066,z:1.843},"LeftHand.rotation":{x:-.595,y:-.229,z:.096},"LeftHandThumb1.rotation":{x:.404,y:-.05,z:.537},"LeftHandThumb2.rotation":{x:-.02,y:.004,z:-.154},"LeftHandThumb3.rotation":{x:-.049,y:.002,z:-.019},"LeftHandIndex1.rotation":{x:-.113,y:-.001,z:.014},"LeftHandIndex2.rotation":{x:.003,y:0,z:0},"LeftHandIndex3.rotation":{x:.002,y:0,z:0},"LeftHandMiddle1.rotation":{x:-.113,y:-.001,z:.014},"LeftHandMiddle2.rotation":{x:.004,y:0,z:0},"LeftHandMiddle3.rotation":{x:.002,y:0,z:0},"LeftHandRing1.rotation":{x:-.113,y:-.001,z:.014},"LeftHandRing2.rotation":{x:.003,y:0,z:0},"LeftHandRing3.rotation":{x:.002,y:0,z:0},"LeftHandPinky1.rotation":{x:-.122,y:-.001,z:-.057},"LeftHandPinky2.rotation":{x:.012,y:.001,z:.07},"LeftHandPinky3.rotation":{x:.002,y:0,z:0}}},this.poseDelta={props:{"Hips.quaternion":{x:0,y:0,z:0},"Spine.quaternion":{x:0,y:0,z:0},"Spine1.quaternion":{x:0,y:0,z:0},"Neck.quaternion":{x:0,y:0,z:0},"Head.quaternion":{x:0,y:0,z:0},"Spine1.scale":{x:0,y:0,z:0},"Neck.scale":{x:0,y:0,z:0},"LeftArm.scale":{x:0,y:0,z:0},"RightArm.scale":{x:0,y:0,z:0}}},["Left","Right"].forEach(a=>{["Leg","UpLeg","Arm","ForeArm","Hand"].forEach(c=>{this.poseDelta.props[a+c+".quaternion"]={x:0,y:0,z:0}}),["HandThumb","HandIndex","HandMiddle","HandRing","HandPinky"].forEach(c=>{this.poseDelta.props[a+c+"1.quaternion"]={x:0,y:0,z:0},this.poseDelta.props[a+c+"2.quaternion"]={x:0,y:0,z:0},this.poseDelta.props[a+c+"3.quaternion"]={x:0,y:0,z:0}})});const t=new Set;Object.values(this.poseTemplates).forEach(a=>{Object.keys(this.propsToThreeObjects(a.props)).forEach(c=>t.add(c))}),Object.keys(this.poseDelta.props).forEach(a=>{t.add(a)}),this.posePropNames=[...t],this.poseName="side",this.poseWeightOnLeft=!0,this.gesture=null,this.poseCurrentTemplate=this.poseTemplates[this.poseName],this.poseStraight=this.propsToThreeObjects(this.poseTemplates.straight.props),this.poseBase=this.poseFactory(this.poseCurrentTemplate),this.poseTarget=this.poseFactory(this.poseCurrentTemplate),this.poseAvatar=null,this.avatarHeight=1.7,this.animTemplateEyes={name:"eyes",idle:{alt:[{p:()=>this.avatar?.hasOwnProperty("avatarIdleEyeContact")?this.avatar.avatarIdleEyeContact:this.opt.avatarIdleEyeContact,delay:[200,5e3],dt:[200,[2e3,5e3],[3e3,1e4,1,2]],vs:{headMove:[this.avatar?.hasOwnProperty("avatarIdleHeadMove")?this.avatar.avatarIdleHeadMove:this.opt.avatarIdleHeadMove],eyesRotateY:[[-.6,.6]],eyesRotateX:[[-.2,.6]],eyeContact:[null,1]}},{delay:[200,5e3],dt:[200,[2e3,5e3,1,2]],vs:{headMove:[this.avatar?.hasOwnProperty("avatarIdleHeadMove")?this.avatar.avatarIdleHeadMove:this.opt.avatarIdleHeadMove],eyesRotateY:[[-.6,.6]],eyesRotateX:[[-.2,.6]]}}]},speaking:{alt:[{p:()=>this.avatar?.hasOwnProperty("avatarSpeakingEyeContact")?this.avatar.avatarSpeakingEyeContact:this.opt.avatarSpeakingEyeContact,delay:[200,5e3],dt:[0,[3e3,1e4,1,2],[2e3,5e3]],vs:{eyeContact:[1,null],headMove:[null,this.avatar?.hasOwnProperty("avatarSpeakingHeadMove")?this.avatar.avatarSpeakingHeadMove:this.opt.avatarSpeakingHeadMove,null],eyesRotateY:[null,[-.6,.6]],eyesRotateX:[null,[-.2,.6]]}},{delay:[200,5e3],dt:[200,[2e3,5e3,1,2]],vs:{headMove:[this.avatar?.hasOwnProperty("avatarSpeakingHeadMove")?this.avatar.avatarSpeakingHeadMove:this.opt.avatarSpeakingHeadMove,null],eyesRotateY:[[-.6,.6]],eyesRotateX:[[-.2,.6]]}}]}},this.animTemplateBlink={name:"blink",alt:[{p:.85,delay:[1e3,8e3,1,2],dt:[50,[100,300],100],vs:{eyeBlinkLeft:[1,1,0],eyeBlinkRight:[1,1,0]}},{delay:[1e3,4e3,1,2],dt:[50,[100,200],100,[10,400,0],50,[100,200],100],vs:{eyeBlinkLeft:[1,1,0,0,1,1,0],eyeBlinkRight:[1,1,0,0,1,1,0]}}]},this.animMoods={neutral:{baseline:{eyesLookDown:0},speech:{deltaRate:0,deltaPitch:0,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1200,500,1e3],vs:{chestInhale:[.5,.5,0]}},{name:"pose",alt:[{p:.5,delay:[5e3,3e4],vs:{pose:["side"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}},{p:.3,delay:[5e3,3e4],vs:{pose:["hip"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}},{delay:[5e3,3e4],vs:{pose:["straight"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}}]},{name:"head",idle:{delay:[0,1e3],dt:[[200,5e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.3,.3]],bodyRotateZ:[[-.08,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.15,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.1,.1]]}}},this.animTemplateEyes,this.animTemplateBlink,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.3]]}},{name:"misc",delay:[100,5e3],dt:[[100,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[0,.3,2]],browOuterUpLeft:[[0,.3,2]],browOuterUpRight:[[0,.3,2]]}}]},happy:{baseline:{mouthSmile:.2,eyesLookDown:0},speech:{deltaRate:0,deltaPitch:.1,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1200,500,1e3],vs:{chestInhale:[.5,.5,0]}},{name:"pose",idle:{alt:[{p:.6,delay:[5e3,3e4],vs:{pose:["side"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}},{p:.2,delay:[5e3,3e4],vs:{pose:["hip"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}},{p:.1,delay:[5e3,3e4],vs:{pose:["straight"]}},{delay:[5e3,1e4],vs:{pose:["wide"]}},{delay:[1e3,3e3],vs:{pose:["turn"]}}]},speaking:{alt:[{p:.4,delay:[5e3,3e4],vs:{pose:["side"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}},{p:.4,delay:[5e3,3e4],vs:{pose:["straight"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}},{delay:[5e3,2e4],vs:{pose:["hip"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}}]}},{name:"head",idle:{dt:[[1e3,5e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.3,.3]],bodyRotateZ:[[-.08,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.15,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.1,.1]]}}},this.animTemplateEyes,this.animTemplateBlink,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthLeft:[[0,.3,2]],mouthSmile:[[0,.2,3]],mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.3]]}},{name:"misc",delay:[100,5e3],dt:[[100,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[0,.3,2]],browOuterUpLeft:[[0,.3,2]],browOuterUpRight:[[0,.3,2]]}}]},angry:{baseline:{eyesLookDown:.1,browDownLeft:.6,browDownRight:.6,jawForward:.3,mouthFrownLeft:.7,mouthFrownRight:.7,mouthRollLower:.2,mouthShrugLower:.3,handFistLeft:1,handFistRight:1},speech:{deltaRate:-.2,deltaPitch:.2,deltaVolume:0},anims:[{name:"breathing",delay:500,dt:[1e3,500,1e3],vs:{chestInhale:[.7,.7,0]}},{name:"pose",alt:[{p:.4,delay:[5e3,3e4],vs:{pose:["side"]}},{p:.4,delay:[5e3,3e4],vs:{pose:["straight"]}},{p:.2,delay:[5e3,3e4],vs:{pose:["hip"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}}]},{name:"head",idle:{delay:[100,500],dt:[[200,5e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.2,.2]],bodyRotateZ:[[-.08,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.15,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.1,.1]]}}},this.animTemplateEyes,this.animTemplateBlink,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.3]]}},{name:"misc",delay:[100,5e3],dt:[[100,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[0,.3,2]],browOuterUpLeft:[[0,.3,2]],browOuterUpRight:[[0,.3,2]]}}]},sad:{baseline:{eyesLookDown:.2,browDownRight:.1,browInnerUp:.6,browOuterUpRight:.2,eyeSquintLeft:.7,eyeSquintRight:.7,mouthFrownLeft:.8,mouthFrownRight:.8,mouthLeft:.2,mouthPucker:.5,mouthRollLower:.2,mouthRollUpper:.2,mouthShrugLower:.2,mouthShrugUpper:.2,mouthStretchLeft:.4},speech:{deltaRate:-.2,deltaPitch:-.2,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1e3,500,1e3],vs:{chestInhale:[.3,.3,0]}},{name:"pose",alt:[{p:.4,delay:[5e3,3e4],vs:{pose:["side"]}},{p:.4,delay:[5e3,3e4],vs:{pose:["straight"]}},{delay:[5e3,2e4],vs:{pose:["side"]},full:{delay:[5e3,2e4],vs:{pose:["oneknee"]}}}]},{name:"head",idle:{delay:[100,500],dt:[[200,5e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.2,.2]],bodyRotateZ:[[-.08,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.15,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.1,.1]]}}},this.animTemplateEyes,this.animTemplateBlink,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.3]]}},{name:"misc",delay:[100,5e3],dt:[[100,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[0,.3,2]],browOuterUpLeft:[[0,.3,2]],browOuterUpRight:[[0,.3,2]]}}]},fear:{baseline:{browInnerUp:.7,eyeSquintLeft:.5,eyeSquintRight:.5,eyeWideLeft:.6,eyeWideRight:.6,mouthClose:.1,mouthFunnel:.3,mouthShrugLower:.5,mouthShrugUpper:.5},speech:{deltaRate:-.2,deltaPitch:0,deltaVolume:0},anims:[{name:"breathing",delay:500,dt:[1e3,500,1e3],vs:{chestInhale:[.7,.7,0]}},{name:"pose",alt:[{p:.8,delay:[5e3,3e4],vs:{pose:["side"]}},{delay:[5e3,3e4],vs:{pose:["straight"]}},{delay:[5e3,2e4],vs:{pose:["wide"]}},{delay:[5e3,2e4],vs:{pose:["side"]},full:{delay:[5e3,2e4],vs:{pose:["oneknee"]}}}]},{name:"head",idle:{delay:[100,500],dt:[[200,3e3]],vs:{bodyRotateX:[[-.06,.12]],bodyRotateY:[[-.7,.7]],bodyRotateZ:[[-.1,.1]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.15,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.1,.1]]}}},this.animTemplateEyes,this.animTemplateBlink,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.3]]}},{name:"misc",delay:[100,5e3],dt:[[100,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[0,.3,2]],browOuterUpLeft:[[0,.3,2]],browOuterUpRight:[[0,.3,2]]}}]},disgust:{baseline:{browDownLeft:.7,browDownRight:.1,browInnerUp:.3,eyeSquintLeft:1,eyeSquintRight:1,eyeWideLeft:.5,eyeWideRight:.5,eyesRotateX:.05,mouthLeft:.4,mouthPressLeft:.3,mouthRollLower:.3,mouthShrugLower:.3,mouthShrugUpper:.8,mouthUpperUpLeft:.3,noseSneerLeft:1,noseSneerRight:.7},speech:{deltaRate:-.2,deltaPitch:0,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1e3,500,1e3],vs:{chestInhale:[.5,.5,0]}},{name:"pose",alt:[{delay:[5e3,2e4],vs:{pose:["side"]}}]},{name:"head",idle:{delay:[100,500],dt:[[200,5e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.2,.2]],bodyRotateZ:[[-.08,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.15,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.1,.1]]}}},this.animTemplateEyes,this.animTemplateBlink,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.3]]}},{name:"misc",delay:[100,5e3],dt:[[100,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[0,.3,2]],browOuterUpLeft:[[0,.3,2]],browOuterUpRight:[[0,.3,2]]}}]},love:{baseline:{browInnerUp:.4,browOuterUpLeft:.2,browOuterUpRight:.2,mouthSmile:.2,eyeBlinkLeft:.6,eyeBlinkRight:.6,eyeWideLeft:.7,eyeWideRight:.7,bodyRotateX:.1,mouthDimpleLeft:.1,mouthDimpleRight:.1,mouthPressLeft:.2,mouthShrugUpper:.2,mouthUpperUpLeft:.1,mouthUpperUpRight:.1},speech:{deltaRate:-.1,deltaPitch:-.7,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1500,500,1500],vs:{chestInhale:[.8,.8,0]}},{name:"pose",alt:[{p:.4,delay:[5e3,3e4],vs:{pose:["side"]}},{p:.2,delay:[5e3,3e4],vs:{pose:["straight"]}},{p:.2,delay:[5e3,3e4],vs:{pose:["hip"]},M:{delay:[5e3,3e4],vs:{pose:["side"]}}},{delay:[5e3,1e4],vs:{pose:["side"]},full:{delay:[5e3,1e4],vs:{pose:["kneel"]}}},{delay:[1e3,3e3],vs:{pose:["turn"]},M:{delay:[1e3,3e3],vs:{pose:["wide"]}}},{delay:[1e3,3e3],vs:{pose:["back"]},M:{delay:[1e3,3e3],vs:{pose:["wide"]}}},{delay:[5e3,2e4],vs:{pose:["side"]},M:{delay:[5e3,2e4],vs:{pose:["side"]}},full:{delay:[5e3,2e4],vs:{pose:["bend"]}}},{delay:[1e3,3e3],vs:{pose:["side"]},full:{delay:[5e3,1e4],vs:{pose:["oneknee"]}}}]},{name:"head",idle:{dt:[[1e3,5e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.3,.3]],bodyRotateZ:[[-.08,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.15,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.1,.1]]}}},this.animTemplateEyes,this.deepCopy(this.animTemplateBlink,a=>{a.alt[0].delay[0]=a.alt[1].delay[0]=2e3}),{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthLeft:[[0,.3,2]],mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.3]]}},{name:"misc",delay:[100,5e3],dt:[[500,1e3],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[.3,.6,2]],browOuterUpLeft:[[.1,.3,2]],browOuterUpRight:[[.1,.3,2]]}}]},sleep:{baseline:{eyeBlinkLeft:1,eyeBlinkRight:1,eyesClosed:.6},speech:{deltaRate:0,deltaPitch:-.2,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1e3,500,1e3],vs:{chestInhale:[.6,.6,0]}},{name:"pose",alt:[{delay:[5e3,2e4],vs:{pose:["side"]}}]},{name:"head",delay:[1e3,5e3],dt:[[2e3,1e4]],vs:{bodyRotateX:[[0,.4]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.04,.04]]}},{name:"eyes",delay:10010,dt:[],vs:{}},{name:"blink",delay:10020,dt:[],vs:{}},{name:"mouth",delay:10030,dt:[],vs:{}},{name:"misc",delay:10040,dt:[],vs:{}}]}},this.moodName=this.opt.avatarMood||"neutral",this.mood=this.animMoods[this.moodName],this.mood||(this.moodName="neutral",this.mood=this.animMoods.neutral),this.animEmojis={"😐":{dt:[300,2e3],rescale:[0,1],vs:{pose:["straight"],browInnerUp:[.4],eyeWideLeft:[.7],eyeWideRight:[.7],mouthPressLeft:[.6],mouthPressRight:[.6],mouthRollLower:[.3],mouthStretchLeft:[1],mouthStretchRight:[1]}},"😶":{link:"😐"},"😏":{dt:[300,2e3],rescale:[0,1],vs:{eyeContact:[0],browDownRight:[.1],browInnerUp:[.7],browOuterUpRight:[.2],eyeLookInRight:[.7],eyeLookOutLeft:[.7],eyeSquintLeft:[1],eyeSquintRight:[.8],eyesRotateY:[.7],mouthLeft:[.4],mouthPucker:[.4],mouthShrugLower:[.3],mouthShrugUpper:[.2],mouthSmile:[.2],mouthSmileLeft:[.4],mouthSmileRight:[.2],mouthStretchLeft:[.5],mouthUpperUpLeft:[.6],noseSneerLeft:[.7]}},"🙂":{dt:[300,2e3],rescale:[0,1],vs:{mouthSmile:[.5]}},"🙃":{link:"🙂"},"😊":{dt:[300,2e3],rescale:[0,1],vs:{browInnerUp:[.6],eyeSquintLeft:[1],eyeSquintRight:[1],mouthSmile:[.7],noseSneerLeft:[.7],noseSneerRight:[.7]}},"😇":{link:"😊"},"😀":{dt:[300,2e3],rescale:[0,1],vs:{browInnerUp:[.6],jawOpen:[.1],mouthDimpleLeft:[.2],mouthDimpleRight:[.2],mouthOpen:[.3],mouthPressLeft:[.3],mouthPressRight:[.3],mouthRollLower:[.4],mouthShrugUpper:[.4],mouthSmile:[.7],mouthUpperUpLeft:[.3],mouthUpperUpRight:[.3],noseSneerLeft:[.4],noseSneerRight:[.4]}},"😃":{dt:[300,2e3],rescale:[0,1],vs:{browInnerUp:[.6],eyeWideLeft:[.7],eyeWideRight:[.7],jawOpen:[.1],mouthDimpleLeft:[.2],mouthDimpleRight:[.2],mouthOpen:[.3],mouthPressLeft:[.3],mouthPressRight:[.3],mouthRollLower:[.4],mouthShrugUpper:[.4],mouthSmile:[.7],mouthUpperUpLeft:[.3],mouthUpperUpRight:[.3],noseSneerLeft:[.4],noseSneerRight:[.4]}},"😄":{dt:[300,2e3],rescale:[0,1],vs:{browInnerUp:[.3],eyeSquintLeft:[1],eyeSquintRight:[1],jawOpen:[.2],mouthDimpleLeft:[.2],mouthDimpleRight:[.2],mouthOpen:[.3],mouthPressLeft:[.3],mouthPressRight:[.3],mouthRollLower:[.4],mouthShrugUpper:[.4],mouthSmile:[.7],mouthUpperUpLeft:[.3],mouthUpperUpRight:[.3],noseSneerLeft:[.4],noseSneerRight:[.4]}},"😁":{dt:[300,2e3],rescale:[0,1],vs:{browInnerUp:[.3],eyeSquintLeft:[1],eyeSquintRight:[1],jawOpen:[.3],mouthDimpleLeft:[.2],mouthDimpleRight:[.2],mouthPressLeft:[.5],mouthPressRight:[.5],mouthShrugUpper:[.4],mouthSmile:[.7],mouthUpperUpLeft:[.3],mouthUpperUpRight:[.3],noseSneerLeft:[.4],noseSneerRight:[.4]}},"😆":{dt:[300,2e3],rescale:[0,1],vs:{browInnerUp:[.3],eyeSquintLeft:[1],eyeSquintRight:[1],eyesClosed:[.6],jawOpen:[.3],mouthDimpleLeft:[.2],mouthDimpleRight:[.2],mouthPressLeft:[.5],mouthPressRight:[.5],mouthShrugUpper:[.4],mouthSmile:[.7],mouthUpperUpLeft:[.3],mouthUpperUpRight:[.3],noseSneerLeft:[.4],noseSneerRight:[.4]}},"😝":{dt:[300,100,1500,500,500],rescale:[0,0,1,0,0],vs:{browInnerUp:[.8],eyesClosed:[1],jawOpen:[.7],mouthFunnel:[.5],mouthSmile:[1],tongueOut:[0,1,1,0]}},"😋":{link:"😝"},"😛":{link:"😝"},"😛":{link:"😝"},"😜":{link:"😝"},"🤪":{link:"😝"},"😂":{dt:[300,2e3],rescale:[0,1],vs:{browInnerUp:[.3],eyeSquintLeft:[1],eyeSquintRight:[1],eyesClosed:[.6],jawOpen:[.3],mouthDimpleLeft:[.2],mouthDimpleRight:[.2],mouthPressLeft:[.5],mouthPressRight:[.5],mouthShrugUpper:[.4],mouthSmile:[.7],mouthUpperUpLeft:[.3],mouthUpperUpRight:[.3],noseSneerLeft:[.4],noseSneerRight:[.4]}},"🤣":{link:"😂"},"😅":{link:"😂"},"😉":{dt:[500,200,500,500],rescale:[0,0,0,1],vs:{mouthSmile:[.5],mouthOpen:[.2],mouthSmileLeft:[0,.5,0],eyeBlinkLeft:[0,.7,0],eyeBlinkRight:[0,0,0],bodyRotateX:[.05,.05,.05,0],bodyRotateZ:[-.05,-.05,-.05,0],browDownLeft:[0,.7,0],cheekSquintLeft:[0,.7,0],eyeSquintLeft:[0,1,0],eyesClosed:[0]}},"😭":{dt:[1e3,1e3],rescale:[0,1],vs:{browInnerUp:[1],eyeSquintLeft:[1],eyeSquintRight:[1],eyesClosed:[.1],jawOpen:[0],mouthFrownLeft:[1],mouthFrownRight:[1],mouthOpen:[.5],mouthPucker:[.5],mouthUpperUpLeft:[.6],mouthUpperUpRight:[.6]}},"🥺":{dt:[1e3,1e3],rescale:[0,1],vs:{browDownLeft:[.2],browDownRight:[.2],browInnerUp:[1],eyeWideLeft:[.9],eyeWideRight:[.9],eyesClosed:[.1],mouthClose:[.2],mouthFrownLeft:[1],mouthFrownRight:[1],mouthPressLeft:[.4],mouthPressRight:[.4],mouthPucker:[1],mouthRollLower:[.6],mouthRollUpper:[.2],mouthUpperUpLeft:[.8],mouthUpperUpRight:[.8]}},"😞":{dt:[1e3,1e3],rescale:[0,1],vs:{browInnerUp:[.7],eyeSquintLeft:[1],eyeSquintRight:[1],eyesClosed:[.5],bodyRotateX:[.3],mouthClose:[.2],mouthFrownLeft:[1],mouthFrownRight:[1],mouthPucker:[1],mouthRollLower:[1],mouthShrugLower:[.2],mouthUpperUpLeft:[.8],mouthUpperUpRight:[.8]}},"😔":{dt:[1e3,1e3],rescale:[0,1],vs:{browInnerUp:[1],eyeSquintLeft:[1],eyeSquintRight:[1],eyesClosed:[.5],bodyRotateX:[.3],mouthClose:[.2],mouthFrownLeft:[1],mouthFrownRight:[1],mouthPressLeft:[.4],mouthPressRight:[.4],mouthPucker:[1],mouthRollLower:[.6],mouthRollUpper:[.2],mouthUpperUpLeft:[.8],mouthUpperUpRight:[.8]}},"😳":{dt:[1e3,1e3],rescale:[0,1],vs:{browInnerUp:[1],eyeWideLeft:[.5],eyeWideRight:[.5],eyesRotateY:[.05],eyesRotateX:[.05],mouthClose:[.2],mouthFunnel:[.5],mouthPucker:[.4],mouthRollLower:[.4],mouthRollUpper:[.4]}},"☹️":{dt:[500,1500],rescale:[0,1],vs:{mouthFrownLeft:[1],mouthFrownRight:[1],mouthPucker:[.1],mouthRollLower:[.8]}},"😚":{dt:[500,1e3,1e3],rescale:[0,1,0],vs:{browInnerUp:[.6],eyeBlinkLeft:[1],eyeBlinkRight:[1],eyeSquintLeft:[1],eyeSquintRight:[1],mouthPucker:[0,.5],noseSneerLeft:[0,.7],noseSneerRight:[0,.7],viseme_U:[0,1]}},"😘":{dt:[500,500,200,500],rescale:[0,0,0,1],vs:{browInnerUp:[.6],eyeBlinkLeft:[0,0,1,0],eyeBlinkRight:[0],eyesRotateY:[0],bodyRotateY:[0],bodyRotateX:[0,.05,.05,0],bodyRotateZ:[0,-.05,-.05,0],eyeSquintLeft:[1],eyeSquintRight:[1],mouthPucker:[0,.5,0],noseSneerLeft:[0,.7],noseSneerRight:[.7],viseme_U:[0,1]}},"🥰":{dt:[1e3,1e3],rescale:[0,1],vs:{browInnerUp:[.6],eyeSquintLeft:[1],eyeSquintRight:[1],mouthSmile:[.7],noseSneerLeft:[.7],noseSneerRight:[.7]}},"😍":{dt:[1e3,1e3],rescale:[0,1],vs:{browInnerUp:[.6],jawOpen:[.1],mouthDimpleLeft:[.2],mouthDimpleRight:[.2],mouthOpen:[.3],mouthPressLeft:[.3],mouthPressRight:[.3],mouthRollLower:[.4],mouthShrugUpper:[.4],mouthSmile:[.7],mouthUpperUpLeft:[.3],mouthUpperUpRight:[.3],noseSneerLeft:[.4],noseSneerRight:[.4]}},"🤩":{link:"😍"},"😡":{dt:[1e3,1500],rescale:[0,1],vs:{browDownLeft:[1],browDownRight:[1],eyesLookUp:[.2],jawForward:[.3],mouthFrownLeft:[1],mouthFrownRight:[1],bodyRotateX:[.15]}},"😠":{dt:[1e3,1500],rescale:[0,1],vs:{browDownLeft:[1],browDownRight:[1],eyesLookUp:[.2],jawForward:[.3],mouthFrownLeft:[1],mouthFrownRight:[1],bodyRotateX:[.15]}},"🤬":{link:"😠"},"😒":{dt:[1e3,1e3],rescale:[0,1],vs:{eyeContact:[0],browDownRight:[.1],browInnerUp:[.7],browOuterUpRight:[.2],eyeLookInRight:[.7],eyeLookOutLeft:[.7],eyeSquintLeft:[1],eyeSquintRight:[.8],eyesRotateY:[.7],mouthFrownLeft:[1],mouthFrownRight:[1],mouthLeft:[.2],mouthPucker:[.5],mouthRollLower:[.2],mouthRollUpper:[.2],mouthShrugLower:[.2],mouthShrugUpper:[.2],mouthStretchLeft:[.5]}},"😱":{dt:[500,1500],rescale:[0,1],vs:{browInnerUp:[.8],eyeWideLeft:[.5],eyeWideRight:[.5],jawOpen:[.7],mouthFunnel:[.5]}},"😬":{dt:[500,1500],rescale:[0,1],vs:{browDownLeft:[1],browDownRight:[1],browInnerUp:[1],mouthDimpleLeft:[.5],mouthDimpleRight:[.5],mouthLowerDownLeft:[1],mouthLowerDownRight:[1],mouthPressLeft:[.4],mouthPressRight:[.4],mouthPucker:[.5],mouthSmile:[.1],mouthSmileLeft:[.2],mouthSmileRight:[.2],mouthStretchLeft:[1],mouthStretchRight:[1],mouthUpperUpLeft:[1],mouthUpperUpRight:[1]}},"🙄":{dt:[500,1500],rescale:[0,1],vs:{browInnerUp:[.8],eyeWideLeft:[1],eyeWideRight:[1],eyesRotateX:[-.8],bodyRotateX:[.15],mouthPucker:[.5],mouthRollLower:[.6],mouthRollUpper:[.5],mouthShrugLower:[0],mouthSmile:[0]}},"🤔":{dt:[500,1500],rescale:[0,1],vs:{browDownLeft:[1],browOuterUpRight:[1],eyeSquintLeft:[.6],mouthFrownLeft:[.7],mouthFrownRight:[.7],mouthLowerDownLeft:[.3],mouthPressRight:[.4],mouthPucker:[.1],mouthRight:[.5],mouthRollLower:[.5],mouthRollUpper:[.2],handRight:[{x:.1,y:.1,z:.1,d:1e3},{d:1e3}],handFistRight:[.1]}},"👀":{dt:[500,1500],rescale:[0,1],vs:{eyesRotateY:[-.8]}},"😴":{dt:[5e3,5e3],rescale:[0,1],vs:{eyeBlinkLeft:[1],eyeBlinkRight:[1],bodyRotateX:[.2],bodyRotateZ:[.1]}},"✋":{dt:[300,2e3],rescale:[0,1],vs:{mouthSmile:[.5],gesture:[["handup",2,!0],null]}},"🤚":{dt:[300,2e3],rescale:[0,1],vs:{mouthSmile:[.5],gesture:[["handup",2],null]}},"👋":{link:"✋"},"👍":{dt:[300,2e3],rescale:[0,1],vs:{mouthSmile:[.5],gesture:[["thumbup",2],null]}},"👎":{dt:[300,2e3],rescale:[0,1],vs:{browDownLeft:[1],browDownRight:[1],eyesLookUp:[.2],jawForward:[.3],mouthFrownLeft:[1],mouthFrownRight:[1],bodyRotateX:[.15],gesture:[["thumbdown",2],null]}},"👌":{dt:[300,2e3],rescale:[0,1],vs:{mouthSmile:[.5],gesture:[["ok",2],null]}},"🤷♂️":{dt:[1e3,1500],rescale:[0,1],vs:{gesture:[["shrug",2],null]}},"🤷♀️":{link:"🤷♂️"},"🤷":{link:"🤷♂️"},"🙏":{dt:[1500,300,1e3],rescale:[0,1,0],vs:{eyeBlinkLeft:[0,1],eyeBlinkRight:[0,1],bodyRotateX:[0],bodyRotateZ:[.1],gesture:[["namaste",2],null]}},yes:{dt:[[200,500],[200,500],[200,500],[200,500]],vs:{headMove:[0],headRotateX:[[.1,.2],.1,[.1,.2],0],headRotateZ:[[-.2,.2]]}},no:{dt:[[200,500],[200,500],[200,500],[200,500],[200,500]],vs:{headMove:[0],headRotateY:[[-.1,-.05],[.05,.1],[-.1,-.05],[.05,.1],0],headRotateZ:[[-.2,.2]]}}},this.mtAvatar={},this.mtCustoms=["handFistLeft","handFistRight","bodyRotateX","bodyRotateY","bodyRotateZ","headRotateX","headRotateY","headRotateZ","chestInhale"],this.mtEasingDefault=this.sigmoidFactory(5),this.mtAccDefault=.01,this.mtAccExceptions={eyeBlinkLeft:.1,eyeBlinkRight:.1,eyeLookOutLeft:.1,eyeLookInLeft:.1,eyeLookOutRight:.1,eyeLookInRight:.1},this.mtMaxVDefault=5,this.mtMaxVExceptions={bodyRotateX:1,bodyRotateY:1,bodyRotateZ:1},this.mtBaselineDefault=0,this.mtBaselineExceptions={bodyRotateX:null,bodyRotateY:null,bodyRotateZ:null,eyeLookOutLeft:null,eyeLookInLeft:null,eyeLookOutRight:null,eyeLookInRight:null,eyesLookDown:null,eyesLookUp:null},this.mtMinDefault=0,this.mtMinExceptions={bodyRotateX:-1,bodyRotateY:-1,bodyRotateZ:-1,headRotateX:-1,headRotateY:-1,headRotateZ:-1},this.mtMaxDefault=1,this.mtMaxExceptions={},this.mtLimits={eyeBlinkLeft:a=>Math.max(a,(this.mtAvatar.eyesLookDown.value+this.mtAvatar.browDownLeft.value)/2),eyeBlinkRight:a=>Math.max(a,(this.mtAvatar.eyesLookDown.value+this.mtAvatar.browDownRight.value)/2)},this.mtOnchange={eyesLookDown:()=>{this.mtAvatar.eyeBlinkLeft.needsUpdate=!0,this.mtAvatar.eyeBlinkRight.needsUpdate=!0},browDownLeft:()=>{this.mtAvatar.eyeBlinkLeft.needsUpdate=!0},browDownRight:()=>{this.mtAvatar.eyeBlinkRight.needsUpdate=!0}},this.mtRandomized=["mouthDimpleLeft","mouthDimpleRight","mouthLeft","mouthPressLeft","mouthPressRight","mouthStretchLeft","mouthStretchRight","mouthShrugLower","mouthShrugUpper","noseSneerLeft","noseSneerRight","mouthRollLower","mouthRollUpper","browDownLeft","browDownRight","browOuterUpLeft","browOuterUpRight","cheekPuff","cheekSquintLeft","cheekSquintRight"],this.mtExtras=[{key:"mouthOpen",mix:{jawOpen:.5}},{key:"mouthSmile",mix:{mouthSmileLeft:.8,mouthSmileRight:.8}},{key:"eyesClosed",mix:{eyeBlinkLeft:1,eyeBlinkRight:1}},{key:"eyesLookUp",mix:{eyeLookUpLeft:1,eyeLookUpRight:1}},{key:"eyesLookDown",mix:{eyeLookDownLeft:1,eyeLookDownRight:1}}],this.animQueue=[],this.animClips=[],this.animPoses=[],this.animFrameDur=1e3/this.opt.modelFPS,this.animClock=0,this.animSlowdownRate=1,this.animTimeLast=0,this.easing=this.sigmoidFactory(5),this.lipsync={},this.opt.lipsyncModules.forEach(a=>{this.lipsyncGetProcessor(a)}),this.visemeNames=["aa","E","I","O","U","PP","SS","TH","DD","FF","kk","nn","RR","CH","sil"],this.segmenter=new Intl.Segmenter("en",{granularity:"grapheme"}),this.initAudioGraph(),this.audioPlaylist=[],this.volumeFrequencyData=new Uint8Array(16),this.volumeMax=0,this.volumeHeadBase=0,this.volumeHeadTarget=0,this.volumeHeadCurrent=0,this.volumeHeadVelocity=.15,this.volumeHeadEasing=this.sigmoidFactory(3),this.isListening=!1,this.listeningAnalyzer=null,this.listeningActive=!1,this.listeningVolume=0,this.listeningSilenceThresholdLevel=this.opt.listeningSilenceThresholdLevel,this.listeningSilenceThresholdMs=this.opt.listeningSilenceThresholdMs,this.listeningSilenceDurationMax=this.opt.listeningSilenceDurationMax,this.listeningActiveThresholdLevel=this.opt.listeningActiveThresholdLevel,this.listeningActiveThresholdMs=this.opt.listeningActiveThresholdMs,this.listeningActiveDurationMax=this.opt.listeningActiveDurationMax,this.listeningTimer=0,this.listeningTimerTotal=0,this.dracoEnabled=this.opt.dracoEnabled,this.dracoDecoderPath=this.opt.dracoDecoderPath;const o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";this.b64Lookup=typeof Uint8Array>"u"?[]:new Uint8Array(256);for(let a=0;a<o.length;a++)this.b64Lookup[o.charCodeAt(a)]=a;if(this.stateName="idle",this.speechQueue=[],this.isSpeaking=!1,this.isListening=!1,this.audioStartTime=null,this.currentAudioItem=null,this.pausedAudioData=null,this.opt.ttsEndpoint){let a=new Audio;if(a.canPlayType("audio/ogg"))this.ttsAudioEncoding="OGG-OPUS";else if(a.canPlayType("audio/mp3"))this.ttsAudioEncoding="MP3";else throw new Error("There was no support for either OGG or MP3 audio.")}if(this.isAvatarOnly=this.opt.avatarOnly,this.isAvatarOnly)this.scene=this.opt.avatarOnlyScene,this.camera=this.opt.avatarOnlyCamera;else{this.renderer=new A.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=A.SRGBColorSpace,this.renderer.toneMapping=A.ACESFilmicToneMapping,this.renderer.shadowMap.enabled=!1,this.nodeAvatar.appendChild(this.renderer.domElement),this.camera=new A.PerspectiveCamera(10,this.nodeAvatar.clientWidth/this.nodeAvatar.clientHeight,.1,2e3),this.scene=new A.Scene,this.lightAmbient=new A.AmbientLight(new A.Color(this.opt.lightAmbientColor),this.opt.lightAmbientIntensity),this.lightDirect=new A.DirectionalLight(new A.Color(this.opt.lightDirectColor),this.opt.lightDirectIntensity),this.lightSpot=new A.SpotLight(new A.Color(this.opt.lightSpotColor),this.opt.lightSpotIntensity,0,this.opt.lightSpotDispersion),this.setLighting(this.opt);const a=new A.PMREMGenerator(this.renderer);a.compileEquirectangularShader(),this.scene.environment=a.fromScene(new yt.RoomEnvironment).texture,this.resizeobserver=new ResizeObserver(this.onResize.bind(this)),this.resizeobserver.observe(this.nodeAvatar),this.controls=new pt.OrbitControls(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}this.ikMesh=new A.SkinnedMesh;const s={LeftShoulder:null,LeftArm:"LeftShoulder",LeftForeArm:"LeftArm",LeftHand:"LeftForeArm",LeftHandMiddle1:"LeftHand",RightShoulder:null,RightArm:"RightShoulder",RightForeArm:"RightArm",RightHand:"RightForeArm",RightHandMiddle1:"RightHand"},i=[];Object.entries(s).forEach((a,c)=>{const l=new A.Bone;l.name=a[0],a[1]?this.ikMesh.getObjectByName(a[1]).add(l):this.ikMesh.add(l),i.push(l)}),this.ikMesh.bind(new A.Skeleton(i)),this.dynamicbones=new It,this.isStreaming=!1,this.streamWorkletNode=null,this.streamAudioStartTime=null,this.streamWaitForAudioChunks=!0,this.streamLipsyncLang=null,this.streamLipsyncType="visemes",this.streamLipsyncQueue=[]}initAudioGraph(n=null){if(this.audioCtx&&this.audioCtx.state!=="closed"&&this.audioCtx.close(),n?this.audioCtx=new AudioContext({sampleRate:n}):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=.1,this.audioAnalyzerNode.minDecibels=-70,this.audioAnalyzerNode.maxDecibels=-10,this.audioAnalyzer=new Lt(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(this.opt.mixerGainSpeech,this.opt.mixerGainBackground),this.workletLoaded=!1,this.streamWorkletNode){try{this.streamWorkletNode.port.postMessage({type:"stop"}),this.streamWorkletNode.disconnect(),this.isStreaming=!1}catch(e){console.error("Error disconnecting streamWorkletNode:",e)}this.streamWorkletNode=null}}valueFn(n){return typeof n=="function"?n():n}deepCopy(n,e=null){const t=JSON.parse(JSON.stringify(n));return e&&typeof e=="function"&&e(t),t}b64ToArrayBuffer(n){let e=3*n.length/4;n[n.length-1]==="="&&(e--,n[n.length-2]==="="&&e--);const t=new ArrayBuffer(e),o=new Uint8Array(t);let s,i=0,a,c,l,u;for(s=0;s<n.length;s+=4)a=this.b64Lookup[n.charCodeAt(s)],c=this.b64Lookup[n.charCodeAt(s+1)],l=this.b64Lookup[n.charCodeAt(s+2)],u=this.b64Lookup[n.charCodeAt(s+3)],o[i++]=a<<2|c>>4,o[i++]=(c&15)<<4|l>>2,o[i++]=(l&3)<<6|u&63;return t}concatArrayBuffers(n){if(n.length===1)return n[0];let e=0;for(let i=0;i<n.length;i++)e+=n[i].byteLength;let t=new ArrayBuffer(e),o=new Uint8Array(t),s=0;for(let i=0;i<n.length;i++)o.set(new Uint8Array(n[i]),s),s+=n[i].byteLength;return t}pcmToAudioBuffer(n){const e=new Int16Array(n),t=new Float32Array(e.length);for(let s=0;s<e.length;s++)t[s]=e[s]>=32768?-(65536-e[s])/32768:e[s]/32767;const o=this.audioCtx.createBuffer(1,t.length,this.opt.pcmSampleRate);return o.copyToChannel(t,0,0),o}propsToThreeObjects(n){const e={};for(let[t,o]of Object.entries(n)){const s=t.split(".");let i=Array.isArray(o.x)?this.gaussianRandom(...o.x):o.x,a=Array.isArray(o.y)?this.gaussianRandom(...o.y):o.y,c=Array.isArray(o.z)?this.gaussianRandom(...o.z):o.z;s[1]==="position"||s[1]==="scale"?e[t]=new A.Vector3(i,a,c):s[1]==="rotation"?(t=s[0]+".quaternion",e[t]=new A.Quaternion().setFromEuler(new A.Euler(i,a,c,"XYZ")).normalize()):s[1]==="quaternion"&&(e[t]=new A.Quaternion(i,a,c,o.w).normalize())}return e}clearThree(n){for(;n.children.length;)this.clearThree(n.children[0]),n.remove(n.children[0]);n.geometry&&n.geometry.dispose(),n.material&&(Object.keys(n.material).forEach(e=>{n.material[e]&&n.material[e]!==null&&typeof n.material[e].dispose=="function"&&n.material[e].dispose()}),n.material.dispose())}addMixedMorphTarget(n,e,t,o=!1){n.forEach(s=>{if(!o&&s.morphTargetDictionary.hasOwnProperty(e))return;const i=s.geometry;let a=null,c=null;for(const[l,u]of Object.entries(t))if(s.morphTargetDictionary.hasOwnProperty(l)){const r=s.morphTargetDictionary[l],h=i.morphAttributes.position[r],d=i.morphAttributes.normal?.[r];a||(a=new A.Float32BufferAttribute(h.count*3,3),d&&(c=new A.Float32BufferAttribute(h.count*3,3)));for(let g=0;g<h.count;g++){const R=a.getX(g)+h.getX(g)*u,x=a.getY(g)+h.getY(g)*u,w=a.getZ(g)+h.getZ(g)*u;a.setXYZ(g,R,x,w)}if(d)for(let g=0;g<h.count;g++){const R=c.getX(g)+d.getX(g)*u,x=c.getY(g)+d.getY(g)*u,w=c.getZ(g)+d.getZ(g)*u;c.setXYZ(g,R,x,w)}}if(a){i.morphAttributes.position.push(a),c&&i.morphAttributes.normal.push(c);const l=i.morphAttributes.position.length-1;s.morphTargetInfluences[l]=0,s.morphTargetDictionary[e]=l}})}async showAvatar(n,e=null){if(!n||!n.hasOwnProperty("url"))throw new Error("Invalid parameter. The avatar must have at least 'url' specified.");const t=new gt.GLTFLoader;if(this.dracoEnabled){const l=new ft.DRACOLoader;l.setDecoderPath(this.dracoDecoderPath),t.setDRACOLoader(l)}let o=await t.loadAsync(n.url,e);const s=[this.opt.modelRoot];if(this.posePropNames.forEach(l=>s.push(l.split(".")[0])),s.forEach(l=>{if(!o.scene.getObjectByName(l))throw new Error("Avatar object "+l+" not found")}),this.stop(),this.avatar=n,this.bodyMovement=n.bodyMovement||"idle",this.movementIntensity=n.movementIntensity||.5,this.showFullAvatar=n.showFullAvatar||!1,this.fbxAnimationLoader=null,this.dynamicbones.dispose(),this.mixer=null,this.isAvatarOnly?this.armature&&this.clearThree(this.armature):this.armature&&this.clearThree(this.scene),this.armature=o.scene.getObjectByName(this.opt.modelRoot),this.armature.scale.setScalar(1),this.animations=o.animations,this.userData=o.userData,this.morphs=[],this.armature.traverse(l=>{l.morphTargetInfluences&&l.morphTargetInfluences.length&&l.morphTargetDictionary&&this.morphs.push(l),l.frustumCulled=!1}),this.morphs.length===0)throw new Error("Blend shapes not found");const i=new Set(this.mtCustoms);this.morphs.forEach(l=>{Object.keys(l.morphTargetDictionary).forEach(u=>i.add(u))}),this.mtExtras.forEach(l=>{i.has(l.key)||(this.addMixedMorphTarget(this.morphs,l.key,l.mix),i.add(l.key))});const a={};if(i.forEach(l=>{a[l]={fixed:null,realtime:null,system:null,systemd:null,newvalue:null,ref:null,min:this.mtMinExceptions.hasOwnProperty(l)?this.mtMinExceptions[l]:this.mtMinDefault,max:this.mtMaxExceptions.hasOwnProperty(l)?this.mtMaxExceptions[l]:this.mtMaxDefault,easing:this.mtEasingDefault,base:null,v:0,needsUpdate:!0,acc:(this.mtAccExceptions.hasOwnProperty(l)?this.mtAccExceptions[l]:this.mtAccDefault)/1e3,maxv:(this.mtMaxVExceptions.hasOwnProperty(l)?this.mtMaxVExceptions[l]:this.mtMaxVDefault)/1e3,limit:this.mtLimits.hasOwnProperty(l)?this.mtLimits[l]:null,onchange:this.mtOnchange.hasOwnProperty(l)?this.mtOnchange[l]:null,baseline:this.avatar.baseline?.hasOwnProperty(l)?this.avatar.baseline[l]:this.mtBaselineExceptions.hasOwnProperty(l)?this.mtBaselineExceptions[l]:this.mtBaselineDefault,ms:[],is:[]},a[l].value=a[l].baseline,a[l].applied=a[l].baseline;const u=this.mtAvatar[l];u&&["fixed","system","systemd","realtime","base","v","value","applied"].forEach(r=>{a[l][r]=u[r]}),this.morphs.forEach(r=>{const h=r.morphTargetDictionary[l];h!==void 0&&(a[l].ms.push(r.morphTargetInfluences),a[l].is.push(h),r.morphTargetInfluences[h]=a[l].applied)})}),this.mtAvatar=a,this.poseAvatar={props:{}},this.posePropNames.forEach(l=>{const u=l.split("."),r=this.armature.getObjectByName(u[0]);this.poseAvatar.props[l]=r[u[1]],this.poseBase.props.hasOwnProperty(l)?this.poseAvatar.props[l].copy(this.poseBase.props[l]):this.poseBase.props[l]=this.poseAvatar.props[l].clone(),this.poseDelta.props.hasOwnProperty(l)&&!this.poseTarget.props.hasOwnProperty(l)&&(this.poseTarget.props[l]=this.poseAvatar.props[l].clone()),this.poseTarget.props[l].t=this.animClock,this.poseTarget.props[l].d=2e3}),this.ikMesh.traverse(l=>{l.isBone&&l.position.copy(this.armature.getObjectByName(l.name).position)}),this.isAvatarOnly?this.scene&&this.scene.add(this.armature):(this.scene.add(o.scene),this.scene.add(this.lightAmbient),this.scene.add(this.lightDirect),this.scene.add(this.lightSpot),this.lightSpot.target=this.armature.getObjectByName("Head")),n.hasOwnProperty("modelDynamicBones"))try{this.dynamicbones.setup(this.scene,this.armature,n.modelDynamicBones)}catch(l){console.error("Dynamic bones setup failed: "+l)}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");const c=new A.Vector3;this.objectLeftEye.getWorldPosition(c),this.avatarHeight=c.y+.2,this.viewName||this.setView(this.opt.cameraView),this.setMood(this.avatar.avatarMood||this.moodName||this.opt.avatarMood),this.avatar.body==="M"&&this.poseTemplates.wide&&(this.poseName="wide",this.setPoseFromTemplate(this.poseTemplates.wide,0)),this.initializeFBXAnimationLoader(),this.bodyMovement&&this.bodyMovement!=="idle"&&this.applyBodyMovementAnimation(),this.start()}getViewNames(){return["full","mid","upper","head"]}getView(){return this.viewName}setView(n,e=null){if(n=n||this.viewName,n!=="full"&&n!=="upper"&&n!=="head"&&n!=="mid")return;if(!this.armature){this.opt.cameraView=n;return}if(this.viewName=n||this.viewName,e=e||{},this.isAvatarOnly)return;const t=e.hasOwnProperty("cameraX")?e.cameraX:this.opt.cameraX,o=e.hasOwnProperty("cameraY")?e.cameraY:this.opt.cameraY,s=e.hasOwnProperty("cameraDistance")?e.cameraDistance:this.opt.cameraDistance,i=e.hasOwnProperty("cameraRotateX")?e.cameraRotateX:this.opt.cameraRotateX,a=e.hasOwnProperty("cameraRotateY")?e.cameraRotateY:this.opt.cameraRotateY,c=this.camera.fov*(Math.PI/180);let l=-t*Math.tan(c/2),u=(1-o)*Math.tan(c/2),r=s;switch(this.viewName){case"head":r+=2,u=u*r+4*this.avatarHeight/5;break;case"upper":r+=4.5,u=u*r+2*this.avatarHeight/3;break;case"mid":r+=8,u=u*r+this.avatarHeight/3;break;default:r+=12,u=u*r}l=l*r,this.controlsEnd=new A.Vector3(l,u,0),this.cameraEnd=new A.Vector3(l,u,r).applyEuler(new A.Euler(i,a,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}setLighting(n){this.isAvatarOnly||(n=n||{},n.hasOwnProperty("lightAmbientColor")&&this.lightAmbient.color.set(new A.Color(n.lightAmbientColor)),n.hasOwnProperty("lightAmbientIntensity")&&(this.lightAmbient.intensity=n.lightAmbientIntensity,this.lightAmbient.visible=n.lightAmbientIntensity!==0),n.hasOwnProperty("lightDirectColor")&&this.lightDirect.color.set(new A.Color(n.lightDirectColor)),n.hasOwnProperty("lightDirectIntensity")&&(this.lightDirect.intensity=n.lightDirectIntensity,this.lightDirect.visible=n.lightDirectIntensity!==0),n.hasOwnProperty("lightDirectPhi")&&n.hasOwnProperty("lightDirectTheta")&&this.lightDirect.position.setFromSphericalCoords(2,n.lightDirectPhi,n.lightDirectTheta),n.hasOwnProperty("lightSpotColor")&&this.lightSpot.color.set(new A.Color(n.lightSpotColor)),n.hasOwnProperty("lightSpotIntensity")&&(this.lightSpot.intensity=n.lightSpotIntensity,this.lightSpot.visible=n.lightSpotIntensity!==0),n.hasOwnProperty("lightSpotPhi")&&n.hasOwnProperty("lightSpotTheta")&&(this.lightSpot.position.setFromSphericalCoords(2,n.lightSpotPhi,n.lightSpotTheta),this.lightSpot.position.add(new A.Vector3(0,1.5,0))),n.hasOwnProperty("lightSpotDispersion")&&(this.lightSpot.angle=n.lightSpotDispersion))}render(){this.isRunning&&!this.isAvatarOnly&&this.renderer&&this.renderer.render(this.scene,this.camera)}onResize(){!this.isAvatarOnly&&this.renderer&&(this.camera.aspect=this.nodeAvatar.clientWidth/this.nodeAvatar.clientHeight,this.camera.updateProjectionMatrix(),this.renderer.setSize(this.nodeAvatar.clientWidth,this.nodeAvatar.clientHeight),this.controls.update(),this.render())}updatePoseBase(n){for(const[e,t]of Object.entries(this.poseTarget.props)){const o=this.poseAvatar.props[e];if(o){let s=(n-t.t)/t.d;s>1||!this.poseBase.props.hasOwnProperty(e)?o.copy(t):o.isQuaternion?o.copy(this.poseBase.props[e].slerp(t,this.easing(s))):o.isVector3&&o.copy(this.poseBase.props[e].lerp(t,this.easing(s)))}}}applyShoulderAdjustment(){}applyShoulderAdjustmentToBones(){}updatePoseDelta(){for(const[n,e]of Object.entries(this.poseDelta.props)){if(e.x===0&&e.y===0&&e.z===0)continue;oe.set(e.x,e.y,e.z);const t=this.poseAvatar.props[n];t.isQuaternion?(ue.setFromEuler(oe),t.multiply(ue)):t.isVector3&&t.add(oe)}}updateMorphTargets(n){for(let[e,t]of Object.entries(this.mtAvatar)){if(!t.needsUpdate)continue;let o=null,s=null;if(t.fixed!==null){if(o=t.fixed,t.system=null,t.systemd=null,t.newvalue=null,t.ref&&t.ref.hasOwnProperty(e)&&delete t.ref[e],t.ref=null,t.base=null,t.value===o){t.needsUpdate=!1;continue}}else t.realtime!==null?(t.ref=null,t.base=null,s=t.realtime):t.system!==null?(o=t.system,t.newvalue=null,t.ref&&t.ref.hasOwnProperty(e)&&delete t.ref[e],t.ref=null,t.base=null,t.systemd!==null?t.systemd===0?(o=null,t.system=null,t.systemd=null):(t.systemd-=n,t.systemd<0&&(t.systemd=0),t.value===o&&(o=null)):t.value===o&&(o=null,t.system=null)):t.newvalue!==null?(t.ref=null,t.base=null,s=t.newvalue,t.newvalue=null):t.base!==null?(o=t.base,t.ref=null,t.value===o&&(o=null,t.base=null,t.needsUpdate=!1)):(t.ref=null,t.baseline!==null&&t.value!==t.baseline?(o=t.baseline,t.base=t.baseline):t.needsUpdate=!1);if(o!==null){let i=o-t.value;i>=0?i<.005?(s=o,t.v=0):(t.v<t.maxv&&(t.v+=t.acc*n),t.v>=0?s=t.value+i*(1-Math.exp(-t.v*n)):s=t.value+t.v*n*(1-Math.exp(t.v*n))):i>-.005?(s=o,t.v=0):(t.v>-t.maxv&&(t.v-=t.acc*n),t.v>=0?s=t.value+t.v*n*(1-Math.exp(-t.v*n)):s=t.value+i*(1-Math.exp(t.v*n)))}if(t.limit!==null){if(s!==null&&s!==t.value&&(t.value=s,t.onchange!==null&&t.onchange(s)),s=t.limit(t.value),s===t.applied)continue}else{if(s===null||s===t.value)continue;t.value=s,t.onchange!==null&&t.onchange(s)}switch(t.applied=s,t.applied<t.min&&(t.applied=t.min),t.applied>t.max&&(t.applied=t.max),e){case"headRotateX":this.poseDelta.props["Head.quaternion"].x=t.applied+this.mtAvatar.bodyRotateX.applied;break;case"headRotateY":this.poseDelta.props["Head.quaternion"].y=t.applied+this.mtAvatar.bodyRotateY.applied;break;case"headRotateZ":this.poseDelta.props["Head.quaternion"].z=t.applied+this.mtAvatar.bodyRotateZ.applied;break;case"bodyRotateX":this.poseDelta.props["Head.quaternion"].x=t.applied+this.mtAvatar.headRotateX.applied,this.poseDelta.props["Spine1.quaternion"].x=t.applied/2,this.poseDelta.props["Spine.quaternion"].x=t.applied/8,this.poseDelta.props["Hips.quaternion"].x=t.applied/24;break;case"bodyRotateY":this.poseDelta.props["Head.quaternion"].y=t.applied+this.mtAvatar.headRotateY.applied,this.poseDelta.props["Spine1.quaternion"].y=t.applied/2,this.poseDelta.props["Spine.quaternion"].y=t.applied/2,this.poseDelta.props["Hips.quaternion"].y=t.applied/4,this.poseDelta.props["LeftUpLeg.quaternion"].y=t.applied/2,this.poseDelta.props["RightUpLeg.quaternion"].y=t.applied/2,this.poseDelta.props["LeftLeg.quaternion"].y=t.applied/4,this.poseDelta.props["RightLeg.quaternion"].y=t.applied/4;break;case"bodyRotateZ":this.poseDelta.props["Head.quaternion"].z=t.applied+this.mtAvatar.headRotateZ.applied,this.poseDelta.props["Spine1.quaternion"].z=t.applied/12,this.poseDelta.props["Spine.quaternion"].z=t.applied/12,this.poseDelta.props["Hips.quaternion"].z=t.applied/24;break;case"handFistLeft":case"handFistRight":const i=e.substring(8);["HandThumb","HandIndex","HandMiddle","HandRing","HandPinky"].forEach((u,r)=>{r===0?(this.poseDelta.props[i+u+"1.quaternion"].x=0,this.poseDelta.props[i+u+"2.quaternion"].z=(i==="Left"?-1:1)*t.applied,this.poseDelta.props[i+u+"3.quaternion"].z=(i==="Left"?-1:1)*t.applied):(this.poseDelta.props[i+u+"1.quaternion"].x=t.applied,this.poseDelta.props[i+u+"2.quaternion"].x=1.5*t.applied,this.poseDelta.props[i+u+"3.quaternion"].x=1.5*t.applied)});break;case"chestInhale":const a=t.applied/20,c={x:a,y:a/2,z:3*a},l={x:1/(1+a)-1,y:1/(1+a/2)-1,z:1/(1+3*a)-1};this.poseDelta.props["Spine1.scale"]=c,this.poseDelta.props["Neck.scale"]=l,this.poseDelta.props["LeftArm.scale"]=l,this.poseDelta.props["RightArm.scale"]=l;break;default:for(let u=0,r=t.ms.length;u<r;u++)t.ms[u][t.is[u]]=t.applied}}}getPoseString(n,e=1e3){let t="{";return Object.entries(n).forEach((o,s)=>{const i=o[0].split(".");if(i[1]==="position"||i[1]==="rotation"||i[1]==="quaternion"){const a=i[1]==="quaternion"?i[0]+".rotation":o[0],c=o[1].isQuaternion?new A.Euler().setFromQuaternion(o[1]):o[1];t+=(s?", ":"")+"'"+a+"':{",t+="x:"+Math.round(c.x*e)/e,t+=", y:"+Math.round(c.y*e)/e,t+=", z:"+Math.round(c.z*e)/e,t+="}"}}),t+="}",t}getPoseTemplateProp(n){const e=n.split(".");let t=e[0]+"."+(e[1]==="rotation"?"quaternion":e[1]);if(this.gesture&&this.gesture.hasOwnProperty(t))return this.gesture[t].clone();{let o=e[0]+"."+(e[1]==="quaternion"?"rotation":e[1]);this.poseWeightOnLeft||(o.startsWith("Left")?(o="Right"+o.substring(4),t="Right"+t.substring(4)):o.startsWith("Right")&&(o="Left"+o.substring(5),t="Left"+t.substring(5)));let s;if(this.poseTarget.template.props.hasOwnProperty(t)){const i={};i[t]=this.poseTarget.template.props[t],s=this.propsToThreeObjects(i)[t]}else if(this.poseTarget.template.props.hasOwnProperty(o)){const i={};i[o]=this.poseTarget.template.props[o],s=this.propsToThreeObjects(i)[t]}return s&&!this.poseWeightOnLeft&&s.isQuaternion&&(s.x*=-1,s.w*=-1),s}}mirrorPose(n){const e={};for(let[t,o]of Object.entries(n))o.isQuaternion&&(t.startsWith("Left")?t="Right"+t.substring(4):t.startsWith("Right")&&(t="Left"+t.substring(5)),o.x*=-1,o.w*=-1),e[t]=o.clone(),e[t].t=o.t,e[t].d=o.d;return e}poseFactory(n,e=2e3){const t={template:n,props:this.propsToThreeObjects(n.props)};for(const[o,s]of Object.entries(t.props)){if(this.opt.modelMovementFactor<1&&n.standing&&(o==="Hips.quaternion"||o==="Spine.quaternion"||o==="Spine1.quaternion"||o==="Spine2.quaternion"||o==="Neck.quaternion"||o==="LeftUpLeg.quaternion"||o==="LeftLeg.quaternion"||o==="RightUpLeg.quaternion"||o==="RightLeg.quaternion")){const i=this.poseStraight[o],a=s.angleTo(i);s.rotateTowards(i,(1-this.opt.modelMovementFactor)*a)}s.t=this.animClock,s.d=e}return t}setPoseFromTemplate(n,e=2e3){const t=n&&this.poseTarget&&this.poseTarget.template&&(this.poseTarget.template.standing&&n.lying||this.poseTarget.template.lying&&n.standing),o=n&&n===this.poseCurrentTemplate,s=this.poseWeightOnLeft;let i=t?1e3:e;if(t?(this.poseCurrentTemplate=this.poseTemplates.oneknee,setTimeout(()=>{this.setPoseFromTemplate(n,e)},i)):this.poseCurrentTemplate=n||this.poseCurrentTemplate,this.poseTarget=this.poseFactory(this.poseCurrentTemplate,i),this.poseWeightOnLeft=!0,(!o&&!s||o&&s)&&(this.poseTarget.props=this.mirrorPose(this.poseTarget.props),this.poseWeightOnLeft=!this.poseWeightOnLeft),this.gesture)for(let[a,c]of Object.entries(this.gesture))this.poseTarget.props.hasOwnProperty(a)&&(this.poseTarget.props[a].copy(c),this.poseTarget.props[a].t=c.t,this.poseTarget.props[a].d=c.d);Object.keys(this.poseDelta.props).forEach(a=>{this.poseTarget.props.hasOwnProperty(a)||(this.poseTarget.props[a]=this.poseBase.props[a].clone(),this.poseTarget.props[a].t=this.animClock,this.poseTarget.props[a].d=i)})}getValue(n){return this.mtAvatar[n]?.value}setValue(n,e,t=null){this.mtAvatar.hasOwnProperty(n)&&Object.assign(this.mtAvatar[n],{system:e,systemd:t,needsUpdate:!0})}getMoodNames(){return Object.keys(this.animMoods)}getMood(){return this.opt.avatarMood}setMood(n){if(n=(n||"").trim().toLowerCase(),!this.animMoods.hasOwnProperty(n))throw new Error("Unknown mood.");this.moodName=n,this.mood=this.animMoods[this.moodName];for(let e of Object.keys(this.mtAvatar)){let t=this.mtBaselineExceptions.hasOwnProperty(e)?this.mtBaselineExceptions[e]:this.mtBaselineDefault;this.mood.baseline.hasOwnProperty(e)?t=this.mood.baseline[e]:this.avatar.baseline?.hasOwnProperty(e)&&(t=this.avatar.baseline[e]),this.setBaselineValue(e,t)}this.mood.anims.forEach(e=>{let t=this.animQueue.findIndex(o=>o.template.name===e.name);t!==-1&&this.animQueue.splice(t,1),this.animQueue.push(this.animFactory(e,-1))})}async initializeFBXAnimationLoader(){try{const{FBXAnimationLoader:n}=await Promise.resolve().then(()=>require("./fbxAnimationLoader-CNrfhJRz.cjs"));this.fbxAnimationLoader=new n(this.armature)}catch(n){console.warn("FBX Animation Loader not available:",n),this.fbxAnimationLoader=null}}setBodyMovement(n){this.bodyMovement=n,this.avatar&&(this.avatar.bodyMovement=n),n==="idle"&&this.unlockAvatarPosition(),this.applyBodyMovementAnimation()}async applyBodyMovementAnimation(){if(!this.armature||!this.animQueue)return;if(this.animQueue=this.animQueue.filter(e=>!e.template.name.startsWith("bodyMovement")),this.bodyMovement==="idle"){this.fbxAnimationLoader&&this.fbxAnimationLoader.stopCurrentAnimation();return}if(this.fbxAnimationLoader)try{await this.fbxAnimationLoader.playGestureAnimation(this.bodyMovement,this.movementIntensity);return}catch{}const n=this.createBodyMovementAnimation(this.bodyMovement);if(n)try{const e=this.animFactory(n,!0);e&&e.ts&&e.ts.length>0?this.animQueue.push(e):(console.error("Invalid animation object created for:",this.bodyMovement),console.error("Animation object:",e))}catch(e){console.error("Error creating body movement animation:",e)}}lockAvatarPosition(){if(!this.armature){console.warn("Cannot lock position: armature not available");return}this.originalPosition||(this.originalPosition={x:this.armature.position.x,y:this.armature.position.y,z:this.armature.position.z}),this.lockedPosition={x:this.armature.position.x,y:this.armature.position.y,z:this.armature.position.z}}unlockAvatarPosition(){this.armature&&this.originalPosition?this.armature.position.set(this.originalPosition.x,this.originalPosition.y,this.originalPosition.z):this.armature&&this.armature.position.set(0,0,0),this.lockedPosition=null,this.originalPosition=null}maintainLockedPosition(){this.lockedPosition&&this.armature&&this.armature.position.set(this.lockedPosition.x,this.lockedPosition.y,this.lockedPosition.z)}createBodyMovementAnimation(n){const e=this.movementIntensity||.5,t={walking:{name:"bodyMovement_walking",delay:[500,2e3],dt:[800,1200],vs:{bodyRotateY:[-.1*e,.1*e,0],bodyRotateZ:[-.05*e,.05*e,0],bodyRotateX:[-.02*e,.02*e,0]}},prancing:{name:"bodyMovement_prancing",delay:[300,1e3],dt:[400,800],vs:{bodyRotateY:[-.15*e,.15*e,0],bodyRotateZ:[-.08*e,.08*e,0],bodyRotateX:[-.05*e,.05*e,0]}},gesturing:{name:"bodyMovement_gesturing",delay:[400,1500],dt:[600,1e3],vs:{bodyRotateY:[-.08*e,.08*e,0],bodyRotateZ:[-.03*e,.03*e,0]}},dancing:{name:"bodyMovement_dancing",delay:[200,600],dt:[400,800],vs:{bodyRotateY:[-.25*e,.25*e,0],bodyRotateZ:[-.15*e,.15*e,0],bodyRotateX:[-.1*e,.1*e,0]}},dancing2:{name:"bodyMovement_dancing2",delay:[150,500],dt:[300,700],vs:{bodyRotateY:[-.3*e,.3*e,0],bodyRotateZ:[-.2*e,.2*e,0],bodyRotateX:[-.12*e,.12*e,0]}},dancing3:{name:"bodyMovement_dancing3",delay:[100,400],dt:[200,600],vs:{bodyRotateY:[-.35*e,.35*e,0],bodyRotateZ:[-.25*e,.25*e,0],bodyRotateX:[-.15*e,.15*e,0]}},excited:{name:"bodyMovement_excited",delay:[200,600],dt:[300,700],vs:{bodyRotateY:[-.12*e,.12*e,0],bodyRotateZ:[-.06*e,.06*e,0],bodyRotateX:[-.04*e,.04*e,0]}},happy:{name:"bodyMovement_happy",delay:[300,800],dt:[500,1e3],vs:{bodyRotateY:[-.08*e,.08*e,0],bodyRotateZ:[-.04*e,.04*e,0],bodyRotateX:[-.02*e,.02*e,0]}},surprised:{name:"bodyMovement_surprised",delay:[100,300],dt:[200,500],vs:{bodyRotateY:[-.05*e,.05*e,0],bodyRotateZ:[-.03*e,.03*e,0],bodyRotateX:[-.01*e,.01*e,0]}},thinking:{name:"bodyMovement_thinking",delay:[800,2e3],dt:[1e3,1500],vs:{bodyRotateY:[-.06*e,.06*e,0],bodyRotateZ:[-.03*e,.03*e,0],bodyRotateX:[-.02*e,.02*e,0]}},nodding:{name:"bodyMovement_nodding",delay:[400,800],dt:[300,600],vs:{bodyRotateX:[-.1*e,.1*e,0],bodyRotateY:[-.02*e,.02*e,0]}},shaking:{name:"bodyMovement_shaking",delay:[200,400],dt:[150,300],vs:{bodyRotateY:[-.15*e,.15*e,0],bodyRotateZ:[-.05*e,.05*e,0]}},celebration:{name:"bodyMovement_celebration",delay:[100,300],dt:[200,500],vs:{bodyRotateY:[-.2*e,.2*e,0],bodyRotateZ:[-.1*e,.1*e,0],bodyRotateX:[-.08*e,.08*e,0]}},energetic:{name:"bodyMovement_energetic",delay:[150,400],dt:[250,500],vs:{bodyRotateY:[-.18*e,.18*e,0],bodyRotateZ:[-.12*e,.12*e,0],bodyRotateX:[-.08*e,.08*e,0]}},swaying:{name:"bodyMovement_swaying",delay:[600,1200],dt:[800,1e3],vs:{bodyRotateY:[-.1*e,.1*e,0],bodyRotateZ:[-.05*e,.05*e,0]}},bouncing:{name:"bodyMovement_bouncing",delay:[300,600],dt:[400,700],vs:{bodyRotateY:[-.05*e,.05*e,0]}}};if(n==="dancing"){const o=["dancing","dancing2","dancing3"],s=o[Math.floor(Math.random()*o.length)];return t[s]||t.dancing}return t[n]||null}playRandomDance(){const n=["dancing","dancing2","dancing3"],e=n[Math.floor(Math.random()*n.length)];this.setBodyMovement(e)}playReaction(n){["happy","surprised","thinking","nodding","shaking","celebration","energetic","swaying","bouncing"].includes(n)?(this.setBodyMovement(n),["surprised","nodding","shaking","celebration"].includes(n)&&setTimeout(()=>{this.setBodyMovement("idle")},3e3)):console.warn("Invalid reaction type:",n)}playCelebration(){this.playReaction("celebration"),setTimeout(()=>{this.playRandomDance()},2e3)}setMovementIntensity(n){this.movementIntensity=Math.max(0,Math.min(1,n)),this.avatar&&(this.avatar.movementIntensity=this.movementIntensity),this.fbxAnimationLoader&&this.fbxAnimationLoader.setIntensity(this.movementIntensity),this.applyBodyMovementAnimation()}setShowFullAvatar(n){this.showFullAvatar=n,this.avatar&&(this.avatar.showFullAvatar=n),n&&this.viewName!=="full"?this.setView("full"):!n&&this.viewName!=="upper"&&this.setView("upper")}getMorphTargetNames(){return["eyesRotateX","eyesRotateY",...Object.keys(this.mtAvatar)].sort()}getBaselineValue(n){if(n==="eyesRotateY"){const e=this.getBaselineValue("eyeLookOutLeft");if(e===void 0)return;const t=this.getBaselineValue("eyeLookInLeft");return t===void 0||this.getBaselineValue("eyeLookOutRight")===void 0||this.getBaselineValue("eyeLookInRight")===void 0?void 0:e-t}else if(n==="eyesRotateX"){const e=this.getBaselineValue("eyesLookDown");if(e===void 0)return;const t=this.getBaselineValue("eyesLookUp");return t===void 0?void 0:e-t}else return this.mtAvatar[n]?.baseline}setBaselineValue(n,e){n==="eyesRotateY"?(this.setBaselineValue("eyeLookOutLeft",e===null?null:e>0?e:0),this.setBaselineValue("eyeLookInLeft",e===null?null:e>0?0:-e),this.setBaselineValue("eyeLookOutRight",e===null?null:e>0?0:-e),this.setBaselineValue("eyeLookInRight",e===null?null:e>0?e:0)):n==="eyesRotateX"?(this.setBaselineValue("eyesLookDown",e===null?null:e>0?e:0),this.setBaselineValue("eyesLookUp",e===null?null:e>0?0:-e)):this.mtAvatar.hasOwnProperty(n)&&Object.assign(this.mtAvatar[n],{base:null,baseline:e,needsUpdate:!0})}getFixedValue(n){if(n==="eyesRotateY"){const e=this.getFixedValue("eyeLookOutLeft");if(e===null)return null;const t=this.getFixedValue("eyeLookInLeft");return t===null||this.getFixedValue("eyeLookOutRight")===null||this.getFixedValue("eyeLookInRight")===null?null:e-t}else if(n==="eyesRotateX"){const e=this.getFixedValue("eyesLookDown");if(e===null)return null;const t=this.getFixedValue("eyesLookUp");return t===null?null:e-t}else return this.mtAvatar[n]?.fixed}setFixedValue(n,e,t=null){n==="eyesRotateY"?(this.setFixedValue("eyeLookOutLeft",e===null?null:e>0?e:0,t),this.setFixedValue("eyeLookInLeft",e===null?null:e>0?0:-e,t),this.setFixedValue("eyeLookOutRight",e===null?null:e>0?0:-e,t),this.setFixedValue("eyeLookInRight",e===null?null:e>0?e:0,t)):n==="eyesRotateX"?(this.setFixedValue("eyesLookDown",e===null?null:e>0?e:0,t),this.setFixedValue("eyesLookUp",e===null?null:e>0?0:-e,t)):this.mtAvatar.hasOwnProperty(n)&&Object.assign(this.mtAvatar[n],{fixed:e,needsUpdate:!0})}animFactory(n,e=!1,t=1,o=1,s=!1){const i={template:n,ts:[0],vs:{}};let a=n;for(;;)if(a.hasOwnProperty(this.stateName))this.stateName==="speaking"||this.stateName,a=a[this.stateName];else if(a.hasOwnProperty(this.moodName))a=a[this.moodName];else if(a.hasOwnProperty(this.poseName))a=a[this.poseName];else if(a.hasOwnProperty(this.viewName))a=a[this.viewName];else if(this.avatar&&this.avatar.body&&a.hasOwnProperty(this.avatar.body))a=a[this.avatar.body];else if(a.hasOwnProperty("alt")){let l=a.alt[0];if(a.alt.length>1){const u=Math.random();let r=0;for(let h=0;h<a.alt.length;h++){let d=this.valueFn(a.alt[h].p);if(r+=d===void 0?(1-r)/(a.alt.length-1-h):d,u<r){l=a.alt[h];break}}}a=l,this.avatar&&this.avatar.body&&a.hasOwnProperty(this.avatar.body);continue}else break;let c=this.valueFn(a.delay)||0;if(Array.isArray(c)&&(c=this.gaussianRandom(...c)),a.hasOwnProperty("dt"))a.dt.forEach((l,u)=>{let r=this.valueFn(l);Array.isArray(r)&&(r=this.gaussianRandom(...r)),i.ts[u+1]=i.ts[u]+r});else{let l=Object.values(a.vs).reduce((u,r)=>r.length>u?r.length:u,0);i.ts=Array(l+1).fill(0)}s?i.ts=i.ts.map(l=>c+l*t):i.ts=i.ts.map(l=>this.animClock+c+l*t),a.vs&&a.vs.pose;for(let[l,u]of Object.entries(a.vs)){const r=this.getBaselineValue(l),h=u.map(d=>(d=this.valueFn(d),d===null?null:typeof d=="function"?d:typeof d=="string"||d instanceof String?l==="pose"&&this.avatar&&this.avatar.body==="M"&&(d==="hip"||d==="side")?"wide":d.slice():Array.isArray(d)?l==="gesture"?d.slice():(r===void 0?0:r)+o*this.gaussianRandom(...d):typeof d=="boolean"?d:d instanceof Object&&d.constructor===Object?Object.assign({},d):(r===void 0?0:r)+o*d));l==="eyesRotateY"?(i.vs.eyeLookOutLeft=[null,...h.map(d=>d>0?d:0)],i.vs.eyeLookInLeft=[null,...h.map(d=>d>0?0:-d)],i.vs.eyeLookOutRight=[null,...h.map(d=>d>0?0:-d)],i.vs.eyeLookInRight=[null,...h.map(d=>d>0?d:0)]):l==="eyesRotateX"?(i.vs.eyesLookDown=[null,...h.map(d=>d>0?d:0)],i.vs.eyesLookUp=[null,...h.map(d=>d>0?0:-d)]):i.vs[l]=[null,...h]}for(let l of Object.keys(i.vs))for(;i.vs[l].length<=i.ts.length;)i.vs[l].push(i.vs[l][i.vs[l].length-1]);return n.hasOwnProperty("mood")&&(i.mood=this.valueFn(n.mood).slice()),e&&(i.loop=e),i}valueAnimationSeq(n,e,t,o,s,i=null){n=this.valueFn(n),e=this.valueFn(e),s<t&&(s=t),s>o&&(s=o);let a=(e-n)/(o-t);return i&&(a*=i((s-t)/(o-t))),a*s+(n-a*t)}gaussianRandom(n,e,t=1,o=5){let s=0;for(let i=0;i<o;i++)s+=Math.random();return n+Math.pow(s/o,t)*(e-n)}sigmoidFactory(n){function e(o){return 1/(1+Math.exp(-n*o))-.5}var t=.5/e(1);return function(o){return t*e(2*Math.max(Math.min(o,1),0)-1)+.5}}convertRange(n,e,t){return(n-e[0])*(t[1]-t[0])/(e[1]-e[0])+t[0]}animate(n){if(!this.isRunning)return;let e;if(this.isAvatarOnly)e=n;else{if(requestAnimationFrame(this.animate.bind(this)),e=n-this.animTimeLast,e<this.animFrameDur)return;this.animTimeLast=n}e=e/this.animSlowdownRate,this.animClock+=e,this.maintainLockedPosition();let t,o,s,i,a=0;if(this.stats&&this.stats.begin(),this.isListening){for(this.listeningAnalyzer.getByteFrequencyData(this.volumeFrequencyData),t=2,s=10;t<s;t++)this.volumeFrequencyData[t]>a&&(a=this.volumeFrequencyData[t]);this.listeningVolume=(this.listeningVolume+a)/2,this.listeningActive?(this.listeningTimerTotal+=e,this.listeningVolume<this.listeningSilenceThresholdLevel?(this.listeningTimer+=e,this.listeningTimer>this.listeningSilenceThresholdMs&&(this.listeningOnchange&&this.listeningOnchange("stop",this.listeningTimer),this.listeningActive=!1,this.listeningTimer=0,this.listeningTimerTotal=0)):this.listeningTimer*=.5,this.listeningTimerTotal>this.listeningActiveDurationMax&&(this.listeningOnchange&&this.listeningOnchange("maxactive"),this.listeningTimerTotal=0)):(this.listeningTimerTotal+=e,this.listeningVolume>this.listeningActiveThresholdLevel?(this.listeningTimer+=e,this.listeningTimer>this.listeningActiveThresholdMs&&(this.listeningOnchange&&this.listeningOnchange("start"),this.listeningActive=!0,this.listeningTimer=0,this.listeningTimerTotal=0)):this.listeningTimer*=.5,this.listeningTimerTotal>this.listeningSilenceDurationMax&&(this.listeningOnchange&&this.listeningOnchange("maxsilence"),this.listeningTimerTotal=0))}if(this.isSpeaking)for(a=0,this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData),t=2,s=10;t<s;t++)this.volumeFrequencyData[t]>a&&(a=this.volumeFrequencyData[t]);let c=null,l=null;const u=[];for(t=0,s=this.animQueue.length;t<s;t++){const r=this.animQueue[t];if(!(!r||!r.ts||!r.ts.length||this.animClock<r.ts[0])){for(o=r.ndx||0,i=r.ts.length;o<i&&!(this.animClock<r.ts[o]);o++)for(let[h,d]of Object.entries(r.vs))if(this.mtAvatar.hasOwnProperty(h)){if(d[o+1]===null)continue;const g=this.mtAvatar[h];if(d[o]===null&&(d[o]=g.value),o===i-1)g.newvalue=d[o];else{g.newvalue=d[o+1];const R=r.ts[o+1]-r.ts[o];let x=1;R>1e-4&&(x=(this.animClock-r.ts[o])/R),x<1&&(g.easing&&(x=g.easing(x)),g.newvalue=(1-x)*d[o]+x*g.newvalue),g.ref&&g.ref!==r.vs&&g.ref.hasOwnProperty(h)&&delete g.ref[h],g.ref=r.vs}if(a)switch(h){case"viseme_aa":case"viseme_E":case"viseme_I":case"viseme_O":case"viseme_U":g.newvalue*=1+a/255-.5}g.needsUpdate=!0}else h==="eyeContact"&&d[o]!==null&&c!==!1?c=!!d[o]:h==="headMove"&&d[o]!==null&&l!==!1?d[o]===0?l=!1:(Math.random()<d[o]&&(l=!0),d[o]=null):d[o]!==null&&(u.push({mt:h,val:d[o]}),d[o]=null);o===i?(r.hasOwnProperty("mood")&&this.setMood(r.mood),r.loop?(i=this.isSpeaking&&(r.template.name==="head"||r.template.name==="eyes")?4:1,this.animQueue[t]=this.animFactory(r.template,r.loop>0?r.loop-1:r.loop,1,1/i)):(this.animQueue.splice(t--,1),s--)):r.ndx=o-1}}for(let r=0,h=u.length;r<h;r++)switch(o=u[r].val,u[r].mt){case"speak":this.speakText(o);break;case"subtitles":this.onSubtitles&&typeof this.onSubtitles=="function"&&this.onSubtitles(o);break;case"pose":this.avatar&&this.avatar.body==="M"&&(o==="hip"||o==="side")&&this.poseTemplates.wide&&(o="wide"),this.poseName=o,this.setPoseFromTemplate(this.poseTemplates[this.poseName]);break;case"gesture":this.playGesture(...o);break;case"function":o&&typeof o=="function"&&o();break;case"moveto":Object.entries(o.props).forEach(d=>{d[1]?this.poseTarget.props[d[0]].copy(d[1]):this.poseTarget.props[d[0]].copy(this.getPoseTemplateProp(d[0])),this.poseTarget.props[d[0]].t=this.animClock,this.poseTarget.props[d[0]].d=d[1]&&d[1].d?d[1].d:d.duration||2e3});break;case"handLeft":this.ikSolve({iterations:20,root:"LeftShoulder",effector:"LeftHandMiddle1",links:[{link:"LeftHand",minx:-.5,maxx:.5,miny:-1,maxy:1,minz:-.5,maxz:.5},{link:"LeftForeArm",minx:-.5,maxx:1.5,miny:-1.5,maxy:1.5,minz:-.5,maxz:3},{link:"LeftArm",minx:-1.5,maxx:1.5,miny:0,maxy:0,minz:-1,maxz:3}]},o.x?new A.Vector3(o.x,o.y,o.z):null,!0,o.d);break;case"handRight":this.ikSolve({iterations:20,root:"RightShoulder",effector:"RightHandMiddle1",links:[{link:"RightHand",minx:-.5,maxx:.5,miny:-1,maxy:1,minz:-.5,maxz:.5,maxAngle:.1},{link:"RightForeArm",minx:-.5,maxx:1.5,miny:-1.5,maxy:1.5,minz:-3,maxz:.5,maxAngle:.2},{link:"RightArm",minx:-1.5,maxx:1.5,miny:0,maxy:0,minz:-1,maxz:3}]},o.x?new A.Vector3(o.x,o.y,o.z):null,!0,o.d);break}if((c||l)&&(oe.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]),oe.x=Math.max(-.9,Math.min(.9,2*oe.x-.5)),oe.y=Math.max(-.9,Math.min(.9,-2.5*oe.y)),c?(Object.assign(this.mtAvatar.eyesLookDown,{system:oe.x<0?-oe.x:0,needsUpdate:!0}),Object.assign(this.mtAvatar.eyesLookUp,{system:oe.x<0?0:oe.x,needsUpdate:!0}),Object.assign(this.mtAvatar.eyeLookInLeft,{system:oe.y<0?-oe.y:0,needsUpdate:!0}),Object.assign(this.mtAvatar.eyeLookOutLeft,{system:oe.y<0?0:oe.y,needsUpdate:!0}),Object.assign(this.mtAvatar.eyeLookInRight,{system:oe.y<0?0:oe.y,needsUpdate:!0}),Object.assign(this.mtAvatar.eyeLookOutRight,{system:oe.y<0?-oe.y:0,needsUpdate:!0}),l&&(t=-this.mtAvatar.bodyRotateY.value,o=this.gaussianRandom(-.2,.2),this.animQueue.push(this.animFactory({name:"headmove",dt:[[1e3,2e3],[1e3,2e3,1,2],[1e3,2e3],[1e3,2e3,1,2]],vs:{headRotateY:[t,t,0],headRotateX:[o,o,0],headRotateZ:[-t/4,-t/4,0]}})))):(t=this.mtAvatar.eyeLookInLeft.value-this.mtAvatar.eyeLookOutLeft.value,o=this.gaussianRandom(-.2,.2),this.animQueue.push(this.animFactory({name:"headmove",dt:[[1e3,2e3],[1e3,2e3,1,2],[1e3,2e3],[1e3,2e3,1,2]],vs:{headRotateY:[null,t,t,0],headRotateX:[null,o,o,0],headRotateZ:[null,-t/4,-t/4,0],eyeLookInLeft:[null,0],eyeLookOutLeft:[null,0],eyeLookInRight:[null,0],eyeLookOutRight:[null,0],eyeContact:[0]}})))),e>2*this.animFrameDur&&(e=2*this.animFrameDur),(this.viewName!=="full"||this.isAvatarOnly)&&(t=this.mtRandomized[Math.floor(Math.random()*this.mtRandomized.length)],o=this.mtAvatar[t],o.needsUpdate||Object.assign(o,{base:(this.mood.baseline[t]||0)+(1+a/255)*Math.random()/5,needsUpdate:!0})),this.updatePoseBase(this.animClock),this.mixer&&(this.mixer.update(e/1e3*this.mixer.timeScale),this.currentFBXActionForCallback&&this.currentFBXActionClipDuration)){const r=this.currentFBXActionForCallback,h=r.time,d=this.currentFBXActionClipDuration;if(!r.isRunning()||h>=d-.1||r.getEffectiveTimeScale()===0&&h>0)if(console.log(`🎬 Manual check: Animation finished (time: ${h.toFixed(3)}/${d.toFixed(3)}, running: ${r.isRunning()})`),this.animationFinishedCallback){const R=this.animationFinishedCallback;this.animationFinishedCallback=null,this.currentFBXActionCallback=null,this.currentFBXActionForCallback=null,this.currentFBXActionStartTime=null,this.currentFBXActionClipDuration=null,R()}else this.currentFBXActionCallback&&(this.currentFBXActionCallback=null,this.currentFBXActionForCallback=null,this.currentFBXActionStartTime=null,this.currentFBXActionClipDuration=null)}if(this.updatePoseDelta(),(this.isSpeaking||this.isListening)&&c?a>this.volumeMax?(this.volumeHeadBase=.05,Math.random()>.6&&(this.volumeHeadTarget=-.05-Math.random()/15),this.volumeMax=a):(this.volumeMax*=.92,this.volumeHeadTarget=this.volumeHeadBase-.9*(this.volumeHeadBase-this.volumeHeadTarget)):(this.volumeHeadTarget=0,this.volumeMax=0),t=this.volumeHeadTarget-this.volumeHeadCurrent,o=Math.abs(t),o>1e-4&&(i=o*(this.volumeHeadEasing(Math.min(1,this.volumeHeadVelocity*e/1e3/o)/2+.5)-.5),this.volumeHeadCurrent+=Math.sign(t)*Math.min(o,i)),Math.abs(this.volumeHeadCurrent)>1e-4&&(ue.setFromAxisAngle(Bt,this.volumeHeadCurrent),this.objectNeck.quaternion.multiply(ue)),ot.setFromObject(this.armature),this.objectLeftToeBase.getWorldPosition(Be),Be.sub(this.armature.position),this.objectRightToeBase.getWorldPosition(Ne),Ne.sub(this.armature.position),this.objectHips.position.y-=ot.min.y/2,this.objectHips.position.x-=(Be.x+Ne.x)/4,this.objectHips.position.z-=(Be.z+Ne.z)/2,this.dynamicbones.update(e),this.fbxAnimationLoader&&this.fbxAnimationLoader.update(),this.opt.update&&this.opt.update(e),this.updateMorphTargets(e),this.isAvatarOnly)this.stats&&this.stats.end();else{if(this.cameraClock!==null&&this.cameraClock<1e3){this.cameraClock+=e,this.cameraClock>1e3&&(this.cameraClock=1e3);let r=new A.Spherical().setFromVector3(this.cameraStart),h=new A.Spherical().setFromVector3(this.cameraEnd);r.phi+=this.easing(this.cameraClock/1e3)*(h.phi-r.phi),r.theta+=this.easing(this.cameraClock/1e3)*(h.theta-r.theta),r.radius+=this.easing(this.cameraClock/1e3)*(h.radius-r.radius),r.makeSafe(),this.camera.position.setFromSpherical(r),this.controlsStart.x!==this.controlsEnd.x?this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd,this.easing(this.cameraClock/1e3))):(r.setFromVector3(this.controlsStart),h.setFromVector3(this.controlsEnd),r.phi+=this.easing(this.cameraClock/1e3)*(h.phi-r.phi),r.theta+=this.easing(this.cameraClock/1e3)*(h.theta-r.theta),r.radius+=this.easing(this.cameraClock/1e3)*(h.radius-r.radius),r.makeSafe(),this.controls.target.setFromSpherical(r)),this.controls.update()}this.controls.autoRotate&&this.controls.update(),this.stats&&this.stats.end(),this.render()}}resetLips(){this.visemeNames.forEach(n=>{this.morphs.forEach(e=>{const t=e.morphTargetDictionary["viseme_"+n];t!==void 0&&(e.morphTargetInfluences[t]=0)})})}lipsyncGetProcessor(n,e="./"){if(!this.lipsync.hasOwnProperty(n)){const t=n.toLowerCase(),o="Lipsync"+n.charAt(0).toUpperCase()+n.slice(1);try{const s=it[t];s&&s[o]?this.lipsync[n]=new s[o]:console.warn(`Lip-sync module for ${n} not found. Available modules:`,Object.keys(it))}catch(s){console.warn(`Failed to load lip-sync module for ${n}:`,s)}}}lipsyncPreProcessText(n,e){return(this.lipsync[e]||Object.values(this.lipsync)[0]).preProcessText(n)}lipsyncWordsToVisemes(n,e){return(this.lipsync[e]||Object.values(this.lipsync)[0]).wordsToVisemes(n)}speakText(n,e=null,t=null,o=null){e=e||{};const s=/[!\.\?\n\p{Extended_Pictographic}]/ug,i=/[ ]/ug,a=/[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug,c=/[\p{Extended_Pictographic}]/ug,l=e.lipsyncLang||this.avatar.lipsyncLang||this.opt.lipsyncLang;let u="",r="",h=0,d=[],g=[];const R=Array.from(this.segmenter.segment(n),x=>x.segment);for(let x=0;x<R.length;x++){const w=x===R.length-1,G=R[x].match(a);let m=R[x].match(s);const N=R[x].match(c),F=R[x].match(i);if(m&&!w&&!N&&R[x+1].match(s)&&(m=!1),t&&(u+=R[x]),G&&(!o||o.every(y=>x<y[0]||x>y[1]))&&(r+=R[x]),(F||m||w)&&(r.length&&(r=this.lipsyncPreProcessText(r,l),r.length&&d.push({mark:h,word:r})),u.length&&(g.push({mark:h,template:{name:"subtitles"},ts:[0],vs:{subtitles:[u]}}),u=""),r.length)){const y=this.lipsyncWordsToVisemes(r,l);if(y&&y.visemes&&y.visemes.length){const O=y.times[y.visemes.length-1]+y.durations[y.visemes.length-1];for(let S=0;S<y.visemes.length;S++)g.push({mark:h,template:{name:"viseme"},ts:[(y.times[S]-.6)/O,(y.times[S]+.5)/O,(y.times[S]+y.durations[S]+.5)/O],vs:{["viseme_"+y.visemes[S]]:[null,y.visemes[S]==="PP"||y.visemes[S]==="FF"?.9:.6,0]}})}r="",h++}if(m||w){if(d.length||w&&g.length){const y={anim:g};t&&(y.onSubtitles=t),d.length&&!e.avatarMute&&(y.text=d,e.avatarMood&&(y.mood=e.avatarMood),e.ttsLang&&(y.lang=e.ttsLang),e.ttsVoice&&(y.voice=e.ttsVoice),e.ttsRate&&(y.rate=e.ttsRate),e.ttsVoice&&(y.pitch=e.ttsPitch),e.ttsVolume&&(y.volume=e.ttsVolume)),this.speechQueue.push(y),d=[],r="",h=0,g=[]}if(N){let y=this.animEmojis[R[x]];y&&y.link&&(y=this.animEmojis[y.link]),y&&this.speechQueue.push({emoji:y})}this.speechQueue.push({break:100})}}this.speechQueue.push({break:1e3}),this.startSpeaking()}async speakEmoji(n){let e=this.animEmojis[n];e&&e.link&&(e=this.animEmojis[e.link]),e&&this.speechQueue.push({emoji:e}),this.startSpeaking()}async speakBreak(n){this.speechQueue.push({break:n}),this.startSpeaking()}async speakMarker(n){this.speechQueue.push({marker:n}),this.startSpeaking()}async playBackgroundAudio(n){let t=await(await fetch(n)).arrayBuffer();this.stopBackgroundAudio(),this.audioBackgroundSource=this.audioCtx.createBufferSource(),this.audioBackgroundSource.loop=!0,this.audioBackgroundSource.buffer=await this.audioCtx.decodeAudioData(t),this.audioBackgroundSource.playbackRate.value=1/this.animSlowdownRate,this.audioBackgroundSource.connect(this.audioBackgroundGainNode),this.audioBackgroundSource.start(0)}stopBackgroundAudio(){try{this.audioBackgroundSource.stop()}catch{}this.audioBackgroundSource.disconnect()}async setReverb(n=null){if(n){let t=await(await fetch(n)).arrayBuffer();this.audioReverbNode.buffer=await this.audioCtx.decodeAudioData(t)}else{const e=this.audioCtx.sampleRate,t=this.audioCtx.createBuffer(2,e,e);t.getChannelData(0)[0]=1,t.getChannelData(1)[0]=1,this.audioReverbNode.buffer=t}}setMixerGain(n,e=null,t=0){n!==null&&(this.audioSpeechGainNode.gain.cancelScheduledValues(this.audioCtx.currentTime),t?(this.audioSpeechGainNode.gain.setValueAtTime(Math.max(this.audioSpeechGainNode.gain.value,1e-4),this.audioCtx.currentTime),this.audioSpeechGainNode.gain.exponentialRampToValueAtTime(Math.max(n,1e-4),this.audioCtx.currentTime+t)):this.audioSpeechGainNode.gain.setValueAtTime(n,this.audioCtx.currentTime)),e!==null&&(this.audioBackgroundGainNode.gain.cancelScheduledValues(this.audioCtx.currentTime),t?(this.audioBackgroundGainNode.gain.setValueAtTime(Math.max(this.audioBackgroundGainNode.gain.value,1e-4),this.audioCtx.currentTime),this.audioBackgroundGainNode.gain.exponentialRampToValueAtTime(Math.max(e,1e-4),this.audioCtx.currentTime+t)):this.audioBackgroundGainNode.gain.setValueAtTime(e,this.audioCtx.currentTime))}speakAudio(n,e=null,t=null){e=e||{};const o=e.lipsyncLang||this.avatar.lipsyncLang||this.opt.lipsyncLang,s={};if(n.words){let i=[];for(let a=0;a<n.words.length;a++){const c=n.words[a],l=n.wtimes[a];let u=n.wdurations[a];if(c.length&&(t&&i.push({template:{name:"subtitles"},ts:[l],vs:{subtitles:[" "+c]}}),!n.visemes)){const r=this.lipsyncPreProcessText(c,o),h=this.lipsyncWordsToVisemes(r,o);if(h&&h.visemes&&h.visemes.length){const d=h.times[h.visemes.length-1]+h.durations[h.visemes.length-1],g=Math.min(u,Math.max(0,u-h.visemes.length*150));let R=.6+this.convertRange(g,[0,u],[0,.4]);if(u=Math.min(u,h.visemes.length*200),d>0)for(let x=0;x<h.visemes.length;x++){const w=l+h.times[x]/d*u,G=h.durations[x]/d*u;i.push({template:{name:"viseme"},ts:[w-Math.min(60,2*G/3),w+Math.min(25,G/2),w+G+Math.min(60,G/2)],vs:{["viseme_"+h.visemes[x]]:[null,h.visemes[x]==="PP"||h.visemes[x]==="FF"?.9:R,0]}})}}}}if(n.visemes)for(let a=0;a<n.visemes.length;a++){const c=n.visemes[a],l=n.vtimes[a],u=n.vdurations[a];i.push({template:{name:"viseme"},ts:[l-2*u/3,l+u/2,l+u+u/2],vs:{["viseme_"+c]:[null,c==="PP"||c==="FF"?.9:.6,0]}})}if(n.markers)for(let a=0;a<n.markers.length;a++){const c=n.markers[a],l=n.mtimes[a];i.push({template:{name:"markers"},ts:[l],vs:{function:[c]}})}i.length&&(s.anim=i)}if(n.audio&&(s.audio=n.audio),n.anim?.name){let i=this.animFactory(n.anim,!1,1,1,!0);s.anim?s.anim.push(i):s.anim=[i]}t&&(s.onSubtitles=t),e.isRaw&&(s.isRaw=!0),Object.keys(s).length&&(this.speechQueue.push(s),s.isRaw||this.speechQueue.push({break:300}),this.startSpeaking())}async playAudio(n=!1,e=null){if(!(!this.armature||this.isAudioPlaying&&!n)){if(this.isAudioPlaying=!0,e&&e.audio){const t={audio:e.audio,anim:e.anim,text:e.text,delay:e.delay||0};if(this.audioCtx.state==="suspended"||this.audioCtx.state==="interrupted"){const s=this.audioCtx.resume(),i=new Promise((a,c)=>setTimeout(()=>c("p2"),1e3));try{await Promise.race([s,i])}catch{console.log("Can't play audio. Web Audio API suspended."),this.playAudio(!0);return}}this.currentAudioItem={audio:t.audio,anim:t.anim?JSON.parse(JSON.stringify(t.anim)):null,text:t.text,delay:t.delay},this.audioSpeechSource=this.audioCtx.createBufferSource(),this.audioSpeechSource.buffer=t.audio,this.audioSpeechSource.playbackRate.value=1/this.animSlowdownRate,this.audioSpeechSource.connect(this.audioAnalyzerNode);const o=t.delay/1e3;if(this.audioStartTime=this.audioCtx.currentTime+o,this.audioSpeechSource.addEventListener("ended",()=>{this.audioSpeechSource.disconnect(),this.audioStartTime=null,this.currentAudioItem=null,this.isSpeaking||(this.isSpeaking=!0),this.playAudio(!0)},{once:!0}),t.anim&&t.anim.length>0){const s=this.animClock;t.anim.forEach(i=>{if(i&&i.ts&&i.ts.length>0){const a={template:i.template,ts:i.ts.map(c=>s+c),vs:i.vs};this.animQueue.push(a)}})}this.audioSpeechSource.start(o);return}if(this.audioPlaylist.length){const t=this.audioPlaylist.shift();if(this.audioCtx.state==="suspended"||this.audioCtx.state==="interrupted"){const a=this.audioCtx.resume(),c=new Promise((l,u)=>setTimeout(()=>u("p2"),1e3));try{await Promise.race([a,c])}catch{console.log("Can't play audio. Web Audio API suspended. This is often due to calling some speak method before the first user action, which is typically prevented by the browser."),this.playAudio(!0);return}}let o;if(Array.isArray(t.audio)){let a=this.concatArrayBuffers(t.audio);o=this.pcmToAudioBuffer(a)}else o=t.audio;this.currentAudioItem={audio:o,anim:t.anim?JSON.parse(JSON.stringify(t.anim)):null,text:t.text,delay:0};let s=0;t.anim&&(t.isRaw||(s=Math.abs(Math.min(0,...t.anim.map(a=>Math.min(...a.ts))))),this.currentAudioItem.delay=s),this.audioSpeechSource=this.audioCtx.createBufferSource(),this.audioSpeechSource.buffer=o,this.audioSpeechSource.playbackRate.value=1/this.animSlowdownRate,this.audioSpeechSource.connect(this.audioAnalyzerNode);const i=s/1e3;this.audioStartTime=this.audioCtx.currentTime+i,this.audioSpeechSource.addEventListener("ended",()=>{this.audioSpeechSource.disconnect(),this.audioStartTime=null,this.currentAudioItem=null,this.isSpeaking=!0,this.playAudio(!0)},{once:!0}),t.anim&&t.anim.forEach(a=>{for(let c=0;c<a.ts.length;c++)a.ts[c]=this.animClock+a.ts[c]+s;this.animQueue.push(a)}),this.audioSpeechSource.start(i)}else this.isAudioPlaying=!1,this.startSpeaking(!0)}}async synthesizeWithBrowserTTS(n){return new Promise((e,t)=>{const o=Array.isArray(n.text)?n.text.map(m=>m.word).join(" "):typeof n.text=="string"?n.text:"",s=new SpeechSynthesisUtterance(o),i=n.lang||this.avatar.ttsLang||this.opt.ttsLang||"en-US",a=(n.rate||this.avatar.ttsRate||this.opt.ttsRate||1)+this.mood.speech.deltaRate,c=(n.pitch||this.avatar.ttsPitch||this.opt.ttsPitch||1)+this.mood.speech.deltaPitch,l=(n.volume||this.avatar.ttsVolume||this.opt.ttsVolume||1)+this.mood.speech.deltaVolume;s.lang=i,s.rate=Math.max(.1,Math.min(10,a)),s.pitch=Math.max(0,Math.min(2,c)),s.volume=Math.max(0,Math.min(1,l));const u=speechSynthesis.getVoices(),r=n.voice||this.avatar.ttsVoice||this.opt.ttsVoice;if(r&&u.length>0){const m=u.find(N=>N.name.includes(r)||N.lang===i);m&&(s.voice=m)}const h=o.length*100/s.rate,d=this.audioCtx.createBuffer(1,this.audioCtx.sampleRate*(h/1e3),this.audioCtx.sampleRate),g=this.avatar.lipsyncLang||this.opt.lipsyncLang||"en",R=this.lipsyncPreProcessText(o,g),x=this.lipsyncWordsToVisemes(R,g),w=[];if(x&&x.visemes&&x.visemes.length>0){const m=x.times[x.visemes.length-1]+x.durations[x.visemes.length-1];for(let N=0;N<x.visemes.length;N++){const F=x.visemes[N],y=x.times[N]/m,O=x.durations[N]/m,S=y*h,f=O*h;w.push({template:{name:"viseme"},ts:[S-Math.min(60,2*f/3),S+Math.min(25,f/2),S+f+Math.min(60,f/2)],vs:{["viseme_"+F]:[null,F==="PP"||F==="FF"?.9:.6,0]}})}}const G=[...n.anim,...w];this.audioPlaylist.push({anim:G,audio:d}),this.onSubtitles=n.onSubtitles||null,this.resetLips(),n.mood&&this.setMood(n.mood),this.playAudio(),s.onend=()=>{e()},s.onerror=m=>{console.error("Speech synthesis error:",m.error),t(m.error)},speechSynthesis.speak(s)})}async synthesizeWithElevenLabsTTS(n){const e=Array.isArray(n.text)?n.text.map(h=>h.word).join(" "):typeof n.text=="string"?n.text:"",t=n.voice||this.avatar.ttsVoice||this.opt.ttsVoice||"21m00Tcm4TlvDq8ikWAM",o={text:e,model_id:"eleven_monolingual_v1",voice_settings:{stability:.5,similarity_boost:.5,style:0,use_speaker_boost:!0}},s=await fetch(`${this.opt.ttsEndpoint}/${t}`,{method:"POST",headers:{Accept:"audio/mpeg","Content-Type":"application/json","xi-api-key":this.opt.ttsApikey},body:JSON.stringify(o)});if(!s.ok)throw new Error(`ElevenLabs TTS error: ${s.status} ${s.statusText}`);const i=await s.arrayBuffer(),a=await this.audioCtx.decodeAudioData(i),c=this.avatar.lipsyncLang||this.opt.lipsyncLang||"en";let l;try{console.log("Lip-sync modules available:",{hasLipsync:!!this.lipsync,lipsyncKeys:this.lipsync?Object.keys(this.lipsync):[],lipsyncLang:c});const h=this.lipsyncPreProcessText(e,c),d=this.lipsyncWordsToVisemes(h,c);if(console.log("Lip-sync data:",{processedText:h,lipsyncData:d,hasVisemes:d&&d.visemes&&d.visemes.length>0}),d&&d.visemes&&d.visemes.length>0)l={visemes:d.visemes.map((g,R)=>({viseme:g,startTime:R*a.duration/d.visemes.length,endTime:(R+1)*a.duration/d.visemes.length,duration:a.duration/d.visemes.length,intensity:.7})),words:[],duration:a.duration,features:{onsets:[],boundaries:[]}};else throw new Error("No visemes generated from text")}catch(h){console.error("Text-based lip-sync failed, using fallback:",h);const d=e.toLowerCase().split(/\s+/),g=[];for(const R of d)for(const x of R){let w="aa";"aeiou".includes(x)?w="aa":"bp".includes(x)?w="PP":"fv".includes(x)?w="FF":"st".includes(x)?w="SS":"dln".includes(x)?w="DD":"kg".includes(x)?w="kk":"rw".includes(x)&&(w="RR"),g.push(w)}l={visemes:g.map((R,x)=>({viseme:R,startTime:x*a.duration/g.length,endTime:(x+1)*a.duration/g.length,duration:a.duration/g.length,intensity:.6})),words:[],duration:a.duration,features:{onsets:[],boundaries:[]}}}const u=[];if(l.visemes&&l.visemes.length>0)for(let h=0;h<l.visemes.length;h++){const d=l.visemes[h],g=d.startTime*1e3,R=d.duration*1e3,x=d.intensity;u.push({template:{name:"viseme"},ts:[g-Math.min(60,2*R/3),g+Math.min(25,R/2),g+R+Math.min(60,R/2)],vs:{["viseme_"+d.viseme]:[null,x,0]}})}else console.warn("ElevenLabs: No visemes available for lip-sync animation");const r=[...n.anim,...u];this.audioPlaylist.push({anim:r,audio:a}),this.onSubtitles=n.onSubtitles||null,this.resetLips(),n.mood&&this.setMood(n.mood),this.playAudio()}async synthesizeWithDeepgramTTS(n){const e=Array.isArray(n.text)?n.text.map(h=>h.word).join(" "):typeof n.text=="string"?n.text:"",t=n.voice||this.avatar.ttsVoice||this.opt.ttsVoice||"aura-2-thalia-en",o=`${this.opt.ttsEndpoint}?model=${t}`,s=await fetch(o,{method:"POST",headers:{Authorization:`Token ${this.opt.ttsApikey}`,"Content-Type":"text/plain",Accept:"audio/mpeg"},body:e});if(!s.ok)throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);const i=await s.arrayBuffer(),a=await this.audioCtx.decodeAudioData(i),c=this.avatar.lipsyncLang||this.opt.lipsyncLang||"en";let l;try{console.log("Lip-sync modules available:",{hasLipsync:!!this.lipsync,lipsyncKeys:this.lipsync?Object.keys(this.lipsync):[],lipsyncLang:c});const h=this.lipsyncPreProcessText(e,c),d=this.lipsyncWordsToVisemes(h,c);if(console.log("Lip-sync data:",{processedText:h,lipsyncData:d,hasVisemes:d&&d.visemes&&d.visemes.length>0}),d&&d.visemes&&d.visemes.length>0)l={visemes:d.visemes.map((g,R)=>({viseme:g,startTime:R*a.duration/d.visemes.length,endTime:(R+1)*a.duration/d.visemes.length,duration:a.duration/d.visemes.length,intensity:.7})),words:[],duration:a.duration,features:{onsets:[],boundaries:[]}};else throw new Error("No visemes generated from text")}catch(h){console.error("Text-based lip-sync failed, using fallback:",h);const d=e.toLowerCase().split(/\s+/),g=[];for(const R of d)for(const x of R){let w="aa";"aeiou".includes(x)?w="aa":"bp".includes(x)?w="PP":"fv".includes(x)?w="FF":"st".includes(x)?w="SS":"dln".includes(x)?w="DD":"kg".includes(x)?w="kk":"rw".includes(x)&&(w="RR"),g.push(w)}l={visemes:g.map((R,x)=>({viseme:R,startTime:x*a.duration/g.length,endTime:(x+1)*a.duration/g.length,duration:a.duration/g.length,intensity:.6})),words:[],duration:a.duration,features:{onsets:[],boundaries:[]}}}const u=[];if(l.visemes&&l.visemes.length>0)for(let h=0;h<l.visemes.length;h++){const d=l.visemes[h],g=d.startTime*1e3,R=d.duration*1e3,x=d.intensity;u.push({template:{name:"viseme"},ts:[g-Math.min(60,2*R/3),g+Math.min(25,R/2),g+R+Math.min(60,R/2)],vs:{["viseme_"+d.viseme]:[null,x,0]}})}else console.warn("Deepgram: No visemes available for lip-sync animation");const r=[...n.anim,...u];this.audioPlaylist.push({anim:r,audio:a}),this.onSubtitles=n.onSubtitles||null,this.resetLips(),n.mood&&this.setMood(n.mood),this.playAudio()}async synthesizeWithAzureTTS(n){const e=Array.isArray(n.text)?n.text.map(r=>r.word).join(" "):typeof n.text=="string"?n.text:"",o=`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const j=require("react/jsx-runtime"),b=require("react"),pt=require("three"),gt=require("three/addons/controls/OrbitControls.js"),ft=require("three/addons/loaders/GLTFLoader.js"),yt=require("three/addons/loaders/DRACOLoader.js"),nt=require("three/addons/loaders/FBXLoader.js"),xt=require("three/addons/environments/RoomEnvironment.js"),bt=require("three/addons/libs/stats.module.js");var Ke=typeof document<"u"?document.currentScript:null;function Rt(W){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(W){for(const e in W)if(e!=="default"){const t=Object.getOwnPropertyDescriptor(W,e);Object.defineProperty(n,e,t.get?t:{enumerable:!0,get:()=>W[e]})}}return n.default=W,Object.freeze(n)}const A=Rt(pt);let p,Se,He;const H=[0,0,0,0],U=new A.Vector3,Ge=new A.Vector3,xe=new A.Vector3,Ze=new A.Vector3;new A.Plane;new A.Ray;new A.Euler;const be=new A.Quaternion,it=new A.Quaternion,Me=new A.Matrix4,Ee=new A.Matrix4;new A.Vector3;const je=new A.Vector3(0,0,1),At=new A.Vector3(1,0,0),vt=new A.Vector3(0,1,0),It=new A.Vector3(0,0,1);class Lt{constructor(n=null){this.opt=Object.assign({warmupMs:2e3,sensitivityFactor:1,movementFactor:1,isExcludes:!0,isPivots:!0,isLimits:!0,helperBoneColor1:16711680,helperBoneColor2:16238028,helperLinkColor1:16711680,helperLinkColor2:255,helperExcludesColor:11184895},n||{}),this.scene=null,this.armature=null,this.config=[],this.data=[],this.dict={},this.objectsUpdate=[],this.helpers={isActive:!1,isShowAll:!1,points:{bones:[],pivots:[],object:null},lines:{bones:[],object:null},excludes:{bones:[],deltaLocals:[],radii:[],objects:[]}},this.running=!1,this.timerMs=0}getOptionValue(n){return this.opt[n]}setOptionValue(n,e){this.opt[n]=e,this.helpers.isActive&&this.showHelpers()}getBoneNames(){return this.data.map(n=>n.name)}getValue(n,e){if(this.scene===null)throw new Error("Dynamic bones has not been setup yet.");if(!this.dict.hasOwnProperty(n))throw new Error("Dynamic bone '"+n+"' not found.");const t=this.dict[n];let o;if(e==="type")o=t.type;else if(e==="stiffness")o=t.k.every(s=>s===t.k[0])?t.k[0]:[...t.k];else if(e==="damping")o=t.c.every(s=>s===t.c[0])?t.c[0]:[...t.c];else if(e==="external")o=t.ext<1?t.ext:null;else if(e==="limits")o=t.limits?.map(s=>s===null?null:[...s]);else if(e==="deltaLocal")o=t.dl?[...t.dl]:null;else if(e==="excludes")o=t.excludes?[...t.excludes.map(s=>{const i={bone:s.bone.name.slice(),radius:s.radius};return s.deltaLocal&&(i.deltaLocal=[...s.deltaLocal]),i})]:null;else if(e==="deltaWorld")o=t.dw?[...t.dw]:null;else if(e==="pivot")o=t.pivot;else if(e==="helper")o=t.helper;else throw new Error("Unsupported property '"+e+"'.");return o}setValue(n,e,t){if(this.scene===null)throw new Error("Dynamic bones has not been setup yet.");if(!this.dict.hasOwnProperty(n))throw new Error("Dynamic bone '"+n+"' not found.");const o=this.dict[n];if(e==="type"){if(!t)throw new Error("Parameter 'type' not set.");if(typeof t!="string")throw new Error("Type must be a string.");switch(t){case"point":o.isPoint=!0,o.isX=!0,o.isY=!0,o.isZ=!0,o.isT=!1;break;case"link":o.isPoint=!1,o.isX=!0,o.isY=!1,o.isZ=!0,o.isT=!1;break;case"mix1":o.isPoint=!1,o.isX=!0,o.isY=!0,o.isZ=!0,o.isT=!1;break;case"mix2":o.isPoint=!1,o.isX=!0,o.isY=!1,o.isZ=!0,o.isT=!0;break;case"full":o.isPoint=!1,o.isX=!0,o.isY=!0,o.isZ=!0,o.isT=!0;break;default:throw new Error("Unknown type'"+t+"'.")}o.type=t.slice()}else if(e==="stiffness"){if(!t)throw new Error("Parameter 'stiffness' not set.");if(!Number.isNaN(t)&&t>=0)o.k=Array(4).fill(t);else if(Array.isArray(t)&&t.length===4&&t.every(s=>s>=0))o.k=[...t];else throw new Error("Stiffness must be a non-negative number or an array of four non-negative numbers.")}else if(e==="damping"){if(!t)throw new Error("Parameter 'damping' not set.");if(!Number.isNaN(t)&&t>=0)o.c=Array(4).fill(t);else if(Array.isArray(t)&&t.length===4&&t.every(s=>s>=0))o.c=[...t];else throw new Error("Damping must be a non-negative number or an array of four non-negative numbers.")}else if(e==="external")if(t==null)o.ext=1;else if(!Number.isNaN(t)&&t>=0&&t<=1)o.ext=t;else throw new Error("External (if set) must be a number between [0,1].");else if(e==="limits")if(t==null)o.limits=null;else{if(!Array.isArray(t)||t.length!==4)throw new Error("Limits (if set) must null, or an array of four arrays.");if(!t.every(s=>s===null||Array.isArray(s)&&s.length===2&&(s[0]===null||!Number.isNaN(s[0]))&&(s[1]===null||!Number.isNaN(s))))throw new Error("Limit values must be null or numbers.");o.limits=[t[0]?[...t[0]]:null,t[1]?[...t[1]]:null,t[2]?[...t[2]]:null,t[3]?[...t[3]]:null]}else if(e==="excludes"){if(t==null)o.excludes=null;else{if(!Array.isArray(t))throw new Error("Excludes (if set) must null, or an array.");o.excludes=[],t.forEach((s,i)=>{if(!s.bone)throw new Error("Bone not specified in #"+i+" exclude.");if(typeof s.bone!="string"||s.bone.length===0)throw new Error("Bone name must be a non-empty string in #"+i+" exclude.");const a=this.armature.getObjectByName(s.bone);if(!a)throw new Error("Bone '"+s.bone+"' not found in #"+i+" exclude.");if(Number.isNaN(s.radius)&&s.radius>=0)throw new Error("Radius must be a non-negative number in #"+i+" exclude.");const c={bone:a,radius:s.radius,radiusSq:s.radius*s.radius,deltaLocal:null};if(s.deltaLocal){if(!Array.isArray(s.deltaLocal)||s.deltaLocal.length!==3||s.deltaLocal.some(l=>Number.isNaN(l)))throw new Error("deltaLocal must be an array of three numbers in #"+i+" exclude.");c.deltaLocal=[...s.deltaLocal]}o.excludes.push(c)})}this.showHelpers()}else if(e==="helper"){if(t==null)o.helper=null;else{if(t!==!1&&t!==!0)throw new Error("Helper, if set, must be false or true.");o.helper=t}this.showHelpers()}else if(e==="pivot")if(t==null)o.pivot=null;else{if(t!==!1&&t!==!0)throw new Error("Pivot, if set, must be false or true.");if(t===!0&&o.type===0)throw new Error("Point type bone can't be a pivot.");o.pivot=t}else if(e==="deltaLocal")if(t==null)o.dl=null;else{if(!Array.isArray(t)||t.length!==3)throw new Error("deltaLocal, is set, must be an array of three numbers.");if(!t.every(s=>!Number.isNaN(s)))throw new Error("deltaLocal values must be numbers.");o.dl=[...t]}else if(e==="deltaWorld")if(t==null)o.dw=null;else{if(!Array.isArray(t)||t.length!==3)throw new Error("deltaWorld, is set, must be an array of three values.");if(!t.every(s=>!Number.isNaN(s)))throw new Error("deltaWorld values must be numbers.");o.dw=[...t]}else throw new Error("Unsupported property "+e)}getConfig(){return this.data.map(n=>{const e={bone:n.name.slice()};return["type","stiffness","damping","external","deltaLocal","deltaWorld","limits","excludes","pivot","helper"].forEach(t=>{p=this.getValue(n.name,t),p&&(e[t]=p)}),e})}sortBones(){if(this.scene===null)throw new Error("Dynamic bones has not been setup yet.");let n=0;const e=new WeakMap;this.armature.traverse(i=>{e.has(i)||(e.set(i,n),n++)}),this.data.sort((i,a)=>e.get(i.bone)-e.get(a.bone)),this.data.forEach(i=>{p=this.dict[i.boneParent.name],p&&(p.children||(p.children=[]),p.children.push(i))}),this.objectsUpdate=[];const t=new WeakSet,o=i=>i.parent?.isBone?[i,...o(i.parent)]:[i],s=i=>{o(i).forEach(c=>{t.has(c)||(this.objectsUpdate.push(c),t.add(c))})};this.data.forEach(i=>{s(i.bone),i.excludes&&i.excludes.forEach(a=>{s(a.bone)})}),this.objectsUpdate.sort((i,a)=>e.get(i)-e.get(a))}setup(n,e,t){this.dispose();const o=(s,i)=>{if(!s)throw this.dispose(),new Error(i)};o(n?.isScene,"First parameter must be Scene."),this.scene=n,o(e?.isObject3D,"Second parameter must be the armature Object3D."),this.armature=e,o(Array.isArray(t),"Third parameter must be an array of bone configs."),this.config=t,this.config.forEach((s,i)=>{const a="Config item #"+i+": ";o(s.bone,a+"Bone not specified.");const c=s.bone;o(typeof c=="string"&&c.length>0,a+"Bone name must be a non-empty string.");const l=this.armature.getObjectByName(c);o(l,a+"Bone '"+c+"' not found."),o(l.parent?.isBone,a+"Bone must have a parent bone."),o(this.data.every(r=>r.bone!==l),a+"Bone '"+c+"' already exists."),l.updateMatrixWorld(!0);const u={name:c,bone:l,boneParent:l.parent,vBasis:l.position.clone(),vWorld:l.parent.getWorldPosition(U).clone(),qBasis:l.parent.quaternion.clone(),l:l.position.length(),p:[0,0,0,0],v:[0,0,0,0],a:[0,0,0,0],ev:[0,0,0,0],ea:[0,0,0,0]};u.boneParent.matrixWorld.decompose(U,be,xe),U.copy(je).applyQuaternion(be).setY(0).normalize(),be.premultiply(it.setFromUnitVectors(je,U).invert()).normalize(),u.qWorldInverseYaw=be.clone().normalize(),this.data.push(u),this.dict[c]=u;try{this.setValue(c,"type",s.type),this.setValue(c,"stiffness",s.stiffness),this.setValue(c,"damping",s.damping),this.setValue(c,"external",s.external),this.setValue(c,"limits",s.limits),this.setValue(c,"excludes",s.excludes),this.setValue(c,"deltaLocal",s.deltaLocal),this.setValue(c,"deltaWorld",s.deltaWorld),this.setValue(c,"pivot",s.pivot),this.setValue(c,"helper",s.helper)}catch(r){o(!1,a+r)}}),this.sortBones(),this.start()}update(n){if(!this.running)return;let e,t,o,s,i;for(this.timerMs+=n,n>1e3&&(this.timerMs=0),n/=1e3,e=0,o=this.objectsUpdate.length;e<o;e++)i=this.objectsUpdate[e],i.updateMatrix(),i.parent===null?i.matrixWorld.copy(i.matrix):i.matrixWorld.multiplyMatrices(i.parent.matrixWorld,i.matrix),i.matrixWorldNeedsUpdate=!1;for(e=0,o=this.data.length;e<o;e++){if(i=this.data[e],U.copy(i.vWorld),Me.copy(i.boneParent.matrixWorld),Ee.copy(Me).invert(),i.vWorld.setFromMatrixPosition(Me),U.applyMatrix4(Ee),U.length()>.5&&(console.info("Info: Unrealistic jump of "+U.length().toFixed(2)+" meters."),U.setLength(.5)),U.applyQuaternion(i.bone.quaternion),H[0]=U.x,H[1]=U.y,H[2]=-U.z,H[3]=U.length()/3,i.children)for(t=0,s=i.children.length;t<s;t++)p=i.children[t],H[0]-=p.v[0]*n/3,H[1]-=p.v[1]*n/3,H[2]+=p.v[2]*n/3,H[3]-=p.v[3]*n/3;if(p=this.opt.sensitivityFactor,H[0]*=i.ext*p,H[1]*=i.ext*p,H[2]*=i.ext*p,H[3]*=i.ext*p,i.isX&&(p=H[0]/n,i.ea[0]=(p-i.ev[0])/n,i.ev[0]=p,i.a[0]=-i.k[0]*i.p[0]-i.c[0]*i.v[0]-i.ea[0],i.p[0]+=i.v[0]*n+i.a[0]*n*n/2+H[0],p=i.v[0]+i.a[0]*n/2,p=-i.k[0]*i.p[0]-i.c[0]*p-i.ea[0],i.v[0]=i.v[0]+(p+i.a[0])*n/2),i.isY&&(p=H[1]/n,i.ea[1]=(p-i.ev[1])/n,i.ev[1]=p,i.a[1]=-i.k[1]*i.p[1]-i.c[1]*i.v[1]-i.ea[1],i.p[1]+=i.v[1]*n+i.a[1]*n*n/2+H[1],p=i.v[1]+i.a[1]*n/2,p=-i.k[1]*i.p[1]-i.c[1]*p-i.ea[1],i.v[1]=i.v[1]+(p+i.a[1])*n/2),i.isZ&&(p=H[2]/n,i.ea[2]=(p-i.ev[2])/n,i.ev[2]=p,i.a[2]=-i.k[2]*i.p[2]-i.c[2]*i.v[2]-i.ea[2],i.p[2]+=i.v[2]*n+i.a[2]*n*n/2+H[2],p=i.v[2]+i.a[2]*n/2,p=-i.k[2]*i.p[2]-i.c[2]*p-i.ea[2],i.v[2]=i.v[2]+(p+i.a[2])*n/2),i.isT&&(p=H[3]/n,i.ea[3]=(p-i.ev[3])/n,i.ev[3]=p,i.a[3]=-i.k[3]*i.p[3]-i.c[3]*i.v[3]-i.ea[3],i.p[3]+=i.v[3]*n+i.a[3]*n*n/2+H[3],p=i.v[3]+i.a[3]*n/2,p=-i.k[3]*i.p[3]-i.c[3]*p-i.ea[3],i.v[3]=i.v[3]+(p+i.a[3])*n/2),this.timerMs<this.opt.warmupMs&&(i.v[0]*=1e-4,i.p[0]*=1e-4,i.v[1]*=1e-4,i.p[1]*=1e-4,i.v[2]*=1e-4,i.p[2]*=1e-4,i.v[3]*=1e-4,i.p[3]*=1e-4),H[0]=i.p[0],H[1]=i.p[1],H[2]=i.p[2],H[3]=i.p[3],p=this.opt.movementFactor,H[0]*=p,H[1]*=p,H[2]*=p,H[3]*=p,i.dl&&(p=i.dl,H[0]+=p[0],H[1]+=p[1],H[2]+=p[2]),i.dw&&(p=i.dw,U.set(i.vBasis.x+H[0],i.vBasis.y+H[1],i.vBasis.z+H[2]),U.applyMatrix4(Me),U.x+=p[0],U.y+=p[1],U.z+=p[2],U.applyMatrix4(Ee),H[0]+=U.x-i.vBasis.x,H[1]+=U.y-i.vBasis.y,H[2]+=U.z-i.vBasis.z),i.limits&&this.opt.isLimits&&(p=i.limits,p[0]&&(p[0][0]!==null&&H[0]<p[0][0]&&(H[0]=p[0][0]),p[0][1]!==null&&H[0]>p[0][1]&&(H[0]=p[0][1])),p[1]&&(p[1][0]!==null&&H[1]<p[1][0]&&(H[1]=p[1][0]),p[1][1]!==null&&H[1]>p[1][1]&&(H[1]=p[1][1])),p[2]&&(p[2][0]!==null&&H[2]<p[2][0]&&(H[2]=p[2][0]),p[2][1]!==null&&H[2]>p[2][1]&&(H[2]=p[2][1])),p[3]&&(p[3][0]!==null&&H[3]<p[3][0]&&(H[3]=p[3][0]),p[3][1]!==null&&H[3]>p[3][1]&&(H[3]=p[3][1]))),i.isPoint)i.bone.position.set(i.vBasis.x+H[0],i.vBasis.y+H[1],i.vBasis.z-H[2]);else if(i.boneParent.quaternion.copy(i.qBasis),i.pivot&&this.opt.isPivots&&(i.boneParent.updateWorldMatrix(!1,!1),i.boneParent.matrixWorld.decompose(U,be,xe),U.copy(je).applyQuaternion(be).setY(0).normalize(),be.premultiply(it.setFromUnitVectors(je,U).invert()).normalize(),i.boneParent.quaternion.multiply(be.invert()),i.boneParent.quaternion.multiply(i.qWorldInverseYaw)),i.isZ&&(p=Math.atan(H[0]/i.l),be.setFromAxisAngle(It,-p),i.boneParent.quaternion.multiply(be)),i.isY&&(p=i.l/3,p=p*Math.tanh(H[1]/p),i.bone.position.setLength(i.l+p)),i.isX&&(p=Math.atan(H[2]/i.l),be.setFromAxisAngle(At,-p),i.boneParent.quaternion.multiply(be)),i.isT&&(p=1.5*Math.tanh(H[3]*1.5),be.setFromAxisAngle(vt,-p),i.boneParent.quaternion.multiply(be)),i.boneParent.updateWorldMatrix(!1,!0),i.excludes&&this.opt.isExcludes)for(t=0,s=i.excludes.length;t<s;t++)p=i.excludes[t],xe.set(0,0,0),p.deltaLocal&&(xe.x+=p.deltaLocal[0],xe.y+=p.deltaLocal[1],xe.z+=p.deltaLocal[2]),xe.applyMatrix4(p.bone.matrixWorld),Ee.copy(i.boneParent.matrixWorld).invert(),xe.applyMatrix4(Ee),U.copy(i.bone.position),!(U.distanceToSquared(xe)>=p.radiusSq)&&(He=U.length(),Se=xe.length(),!(Se>p.radius+He)&&(Se<Math.abs(p.radius-He)||(Se=(Se*Se+He*He-p.radiusSq)/(2*Se),xe.normalize(),Ze.copy(xe).multiplyScalar(Se),Se=Math.sqrt(He*He-Se*Se),U.subVectors(U,Ze).projectOnPlane(xe).normalize().multiplyScalar(Se),Ge.subVectors(i.vBasis,Ze).projectOnPlane(xe).normalize(),He=Ge.dot(U),He<0&&(He=Math.sqrt(Se*Se-He*He),Ge.multiplyScalar(He),U.add(Ge)),U.add(Ze).normalize(),xe.copy(i.bone.position).normalize(),be.setFromUnitVectors(xe,U),i.boneParent.quaternion.premultiply(be),i.boneParent.updateWorldMatrix(!1,!0))))}this.helpers.isActive&&this.updateHelpers()}showHelpers(n){if(this.hideHelpers(),this.helpers.isShowAll=n===void 0?this.helpers.isShowAll:n===!0,p=this.helpers,this.data.forEach(e=>{(this.helpers.isShowAll||e.helper===!0)&&(p.points.bones.push(e.bone),p.points.pivots.push(e.pivot),e.type!==0&&p.lines.bones.push(e.bone),e.excludes&&e.excludes.forEach(t=>{let o=!1;for(let s=0;s<p.excludes.bones.length;s++)if(p.excludes.bones[s]===t.bone&&p.excludes.radii[s]===t.radius&&!(p.excludes.deltaLocals[s]===null&&t.deltaLocal!==null)&&!(p.excludes.deltaLocals[s]!==null&&t.deltaLocal===null)&&!(p.excludes.deltaLocals[s]!==null&&p.excludes.deltaLocals[s].some((i,a)=>i!==t.deltaLocal[a]))){o=!0;break}o||(p.excludes.bones.push(t.bone),p.excludes.radii.push(t.radius),p.excludes.deltaLocals.push(t.deltaLocal?[...t.deltaLocal]:null),p.excludes.objects.push(null))}))}),p=this.helpers.excludes,this.opt.isExcludes&&p.bones.length&&p.bones.forEach((e,t)=>{const o=new A.SphereGeometry(p.radii[t],6,6),s=new A.MeshBasicMaterial({depthTest:!1,depthWrite:!1,toneMapped:!1,transparent:!0,wireframe:!0,color:this.opt.helperExcludesColor});p.objects[t]=new A.Mesh(o,s),p.objects[t].renderOrder=997,e.add(p.objects[t]),p.deltaLocals[t]&&p.objects[t].position.set(p.deltaLocals[t][0],p.deltaLocals[t][1],p.deltaLocals[t][2])}),p=this.helpers.points,p.bones.length){this.helpers.isActive=!0;const e=new A.BufferGeometry,t=p.bones.map(c=>[0,0,0]).flat();e.setAttribute("position",new A.Float32BufferAttribute(t,3));const o=new A.Color(this.opt.helperBoneColor1),s=new A.Color(this.opt.helperBoneColor2),i=p.pivots.map(c=>c&&this.opt.isPivots?[s.r,s.g,s.b]:[o.r,o.g,o.b]).flat();e.setAttribute("color",new A.Float32BufferAttribute(i,3));const a=new A.PointsMaterial({depthTest:!1,depthWrite:!1,toneMapped:!1,transparent:!0,size:.2,vertexColors:!0});p.object=new A.Points(e,a),p.object.renderOrder=998,p.object.matrix=this.armature.matrixWorld,p.object.matrixAutoUpdate=!1,this.scene.add(p.object)}if(p=this.helpers.lines,p.bones.length){const e=new A.BufferGeometry,t=p.bones.map(c=>[0,0,0,0,0,0]).flat();e.setAttribute("position",new A.Float32BufferAttribute(t,3));const o=new A.Color(this.opt.helperLinkColor1),s=new A.Color(this.opt.helperLinkColor2),i=p.bones.map(c=>[o.r,o.g,o.b,s.r,s.g,s.b]).flat();e.setAttribute("color",new A.Float32BufferAttribute(i,3));const a=new A.LineBasicMaterial({vertexColors:!0,depthTest:!1,depthWrite:!1,toneMapped:!1,transparent:!0});p.object=new A.LineSegments(e,a),p.object.renderOrder=999,p.object.matrix=this.armature.matrixWorld,p.object.matrixAutoUpdate=!1,this.scene.add(p.object)}}updateHelpers(){if(p=this.helpers.points,p.bones.length){Ee.copy(this.armature.matrixWorld).invert();const n=p.object.geometry.getAttribute("position");for(let e=0,t=p.bones.length;e<t;e++)Me.multiplyMatrices(Ee,p.bones[e].matrixWorld),U.setFromMatrixPosition(Me),n.setXYZ(e,U.x,U.y,U.z);n.needsUpdate=!0,p.object.updateMatrixWorld()}if(p=this.helpers.lines,p.bones.length){Ee.copy(this.armature.matrixWorld).invert();const n=p.object.geometry.getAttribute("position");for(let e=0,t=0,o=p.bones.length;e<o;e++,t+=2)Me.multiplyMatrices(Ee,p.bones[e].matrixWorld),U.setFromMatrixPosition(Me),n.setXYZ(t,U.x,U.y,U.z),Me.multiplyMatrices(Ee,p.bones[e].parent.matrixWorld),U.setFromMatrixPosition(Me),n.setXYZ(t+1,U.x,U.y,U.z);n.needsUpdate=!0,p.object.updateMatrixWorld()}}hideHelpers(){[this.helpers.points,this.helpers.lines].forEach(n=>{n.bones=[],n.object&&(this.scene.remove(n.object),n.object.geometry.dispose(),n.object.material.dispose(),n.object=null)}),p=this.helpers.excludes,p.objects.forEach((n,e)=>{n&&(p.bones[e].remove(n),n.geometry.dispose(),n.material.dispose())}),p.bones=[],p.deltaLocals=[],p.radii=[],p.objects=[],this.helpers.isActive=!1}start(){this.data.length&&(this.running=!0,this.timerMs=0,this.showHelpers())}stop(){this.running=!1,this.hideHelpers();for(let n=0,e=this.data.length;n<e;n++){const t=this.data[n];t.bone.position.copy(t.vBasis),t.boneParent.quaternion.copy(t.qBasis)}}dispose(){this.stop(),this.scene=null,this.armature=null,this.config=[],this.data=[],this.dict={},this.objectsUpdate=[],this.timerMs=0}}class St{constructor(n){this.audioContext=n,this.analyzer=null,this.dataArray=null,this.bufferLength=0}async analyzeAudio(n,e){const t=n.sampleRate,o=n.duration,s=n.getChannelData(0),i=this.extractAudioFeatures(s,t);return this.generateTimingData(i,e,o)}extractAudioFeatures(n,e){const t={energy:[],spectralCentroid:[],zeroCrossingRate:[],mfcc:[],onsets:[],phonemeBoundaries:[]},o=1024,s=512,i=Math.floor((n.length-o)/s)+1;for(let a=0;a<i;a++){const c=a*s,l=Math.min(c+o,n.length),u=n.slice(c,l),r=this.calculateEnergy(u);t.energy.push(r);const h=this.calculateSpectralCentroid(u);t.spectralCentroid.push(h);const d=this.calculateZeroCrossingRate(u);t.zeroCrossingRate.push(d);const g=this.calculateMFCC(u);t.mfcc.push(g)}return t.onsets=this.detectOnsets(t.energy),t.phonemeBoundaries=this.detectPhonemeBoundaries(t),t}calculateEnergy(n){let e=0;for(let t=0;t<n.length;t++)e+=n[t]*n[t];return e/n.length}calculateSpectralCentroid(n){const e=this.fft(n);let t=0,o=0;for(let s=0;s<e.length/2;s++){const i=Math.sqrt(e[s*2]*e[s*2]+e[s*2+1]*e[s*2+1]);t+=s*i,o+=i}return o>0?t/o:0}calculateZeroCrossingRate(n){let e=0;for(let t=1;t<n.length;t++)n[t]>=0!=n[t-1]>=0&&e++;return e/(n.length-1)}calculateMFCC(n){const e=this.fft(n),t=[];for(let o=0;o<13;o++){let s=0;for(let i=0;i<e.length/2;i++){const a=Math.sqrt(e[i*2]*e[i*2]+e[i*2+1]*e[i*2+1]);s+=a*Math.cos(Math.PI*o*(i+.5)/(e.length/2))}t.push(s)}return t}fft(n){const e=n.length,t=new Float32Array(e*2);for(let o=0;o<e;o++)t[o*2]=n[o],t[o*2+1]=0;for(let o=1,s=0;o<e;o++){let i=e>>1;for(;s&i;)s^=i,i>>=1;if(s^=i,o<s){const a=t[o*2],c=t[o*2+1];t[o*2]=t[s*2],t[o*2+1]=t[s*2+1],t[s*2]=a,t[s*2+1]=c}}for(let o=2;o<=e;o<<=1){const s=-2*Math.PI/o,i=Math.cos(s),a=Math.sin(s);for(let c=0;c<e;c+=o){let l=1,u=0;for(let r=0;r<o/2;r++){const h=t[(c+r)*2],d=t[(c+r)*2+1],g=t[(c+r+o/2)*2]*l-t[(c+r+o/2)*2+1]*u,R=t[(c+r+o/2)*2]*u+t[(c+r+o/2)*2+1]*l;t[(c+r)*2]=h+g,t[(c+r)*2+1]=d+R,t[(c+r+o/2)*2]=h-g,t[(c+r+o/2)*2+1]=d-R;const x=l*i-u*a,w=l*a+u*i;l=x,u=w}}}return t}detectOnsets(n){const e=[];let s=-.1;for(let i=1;i<n.length;i++){const a=n[i]-n[i-1],c=i*.023;a>.1&&c-s>.1&&(e.push(c),s=c)}return e}detectPhonemeBoundaries(n){const e=[],{energy:t,spectralCentroid:o,zeroCrossingRate:s}=n;for(let i=1;i<t.length;i++){const a=i*.023,c=Math.abs(t[i]-t[i-1]),l=Math.abs(o[i]-o[i-1]),u=Math.abs(s[i]-s[i-1]);c+l*.1+u*.5>.2&&e.push(a)}return e}generateTimingData(n,e,t){const o=e.toLowerCase().split(/\s+/);n.phonemeBoundaries,n.onsets;const s=[];let i=0;for(let c=0;c<o.length;c++){const l=o[c],u=this.estimateWordDuration(l,t/o.length);s.push({word:l,startTime:i,endTime:i+u,duration:u}),i+=u}const a=this.generateVisemeTimings(n,e,t);return{words:s,visemes:a,duration:t,features:n}}estimateWordDuration(n,e){const t=Math.max(.5,Math.min(2,n.length/5)),o=this.getWordComplexity(n);return e*t*o}getWordComplexity(n){const e=(n.match(/[bcdfghjklmnpqrstvwxyz]{2,}/g)||[]).length,t=(n.match(/[aeiou]{2,}/g)||[]).length;return 1+e*.2+t*.1}generateVisemeTimings(n,e,t){const o=[],s=n.phonemeBoundaries;n.onsets;const i=this.textToVisemes(e);let a=0,c=0;for(let l=0;l<s.length&&a<i.length;l++){const u=s[l],r=i[a],h=n.energy[Math.floor(u/.023)]||0,d=this.calculateVisemeDuration(r,h);o.push({viseme:r,startTime:c,endTime:c+d,duration:d,intensity:Math.min(1,h*2)}),c+=d,a++}for(;a<i.length;){const l=i[a],u=this.calculateVisemeDuration(l,.5);o.push({viseme:l,startTime:c,endTime:c+u,duration:u,intensity:.6}),c+=u,a++}return o}textToVisemes(n){const e={a:"aa",e:"E",i:"I",o:"O",u:"U",ae:"aa",ai:"aa",au:"O",ea:"E",ee:"E",ei:"E",ie:"I",oa:"O",oo:"U",ou:"U",b:"PP",p:"PP",m:"PP",f:"FF",v:"FF",th:"SS",s:"SS",z:"SS",sh:"SS",ch:"SS",d:"DD",t:"DD",n:"nn",l:"nn",k:"kk",g:"kk",ng:"kk",r:"RR",w:"RR",y:"I",h:"kk"},t=[],o=n.toLowerCase().replace(/[^a-z\s]/g,"").split(/\s+/);for(const s of o){let i=0;for(;i<s.length;){let a=!1;for(let c=3;c>=2;c--){const l=s.substr(i,c);if(e[l]){t.push(e[l]),i+=c,a=!0;break}}if(!a){const c=s[i];e[c]&&t.push(e[c]),i++}}}return t}calculateVisemeDuration(n,e){const o={aa:.15,E:.12,I:.1,O:.14,U:.13,PP:.08,FF:.1,SS:.12,DD:.11,kk:.09,nn:.1,RR:.11}[n]||.1,s=.5+e*.5;return o*s}}class kt{constructor(){this.rules={A:["[A] =aa"," [ARE] =aa RR"," [AR]O=aa RR","[AR]#=E RR"," ^[AS]#=E SS","[A]WA=aa","[AW]=aa"," :[ANY]=E nn I","[A]^+#=E","#:[ALLY]=aa nn I"," [AL]#=aa nn","[AGAIN]=aa kk E nn","#:[AG]E=I kk","[A]^+:#=aa",":[A]^+ =E","[A]^%=E"," [ARR]=aa RR","[ARR]=aa RR"," :[AR] =aa RR","[AR] =E","[AR]=aa RR","[AIR]=E RR","[AI]=E","[AY]=E","[AU]=aa","#:[AL] =aa nn","#:[ALS] =aa nn SS","[ALK]=aa kk","[AL]^=aa nn"," :[ABLE]=E PP aa nn","[ABLE]=aa PP aa nn","[ANG]+=E nn kk","[A]=aa"],B:[" [BE]^#=PP I","[BEING]=PP I I nn"," [BOTH] =PP O TH"," [BUS]#=PP I SS","[BUIL]=PP I nn","[B]=PP"],C:[" [CH]^=kk","^E[CH]=kk","[CH]=CH"," S[CI]#=SS aa","[CI]A=SS","[CI]O=SS","[CI]EN=SS","[C]+=SS","[CK]=kk","[COM]%=kk aa PP","[C]=kk"],D:["#:[DED] =DD I DD",".E[D] =DD","#^:E[D] =DD"," [DE]^#=DD I"," [DO] =DD U"," [DOES]=DD aa SS"," [DOING]=DD U I nn"," [DOW]=DD aa","[DU]A=kk U","[D]=DD"],E:["#:[E] =","'^:[E] ="," :[E] =I","#[ED] =DD","#:[E]D =","[EV]ER=E FF","[E]^%=I","[ERI]#=I RR I","[ERI]=E RR I","#:[ER]#=E","[ER]#=E RR","[ER]=E"," [EVEN]=I FF E nn","#:[E]W=","@[EW]=U","[EW]=I U","[E]O=I","#:&[ES] =I SS","#:[E]S =","#:[ELY] =nn I","#:[EMENT]=PP E nn DD","[EFUL]=FF U nn","[EE]=I","[EARN]=E nn"," [EAR]^=E","[EAD]=E DD","#:[EA] =I aa","[EA]SU=E","[EA]=I","[EIGH]=E","[EI]=I"," [EYE]=aa","[EY]=I","[EU]=I U","[E]=E"],F:["[FUL]=FF U nn","[F]=FF"],G:["[GIV]=kk I FF"," [G]I^=kk","[GE]T=kk E","SU[GGES]=kk kk E SS","[GG]=kk"," B#[G]=kk","[G]+=kk","[GREAT]=kk RR E DD","#[GH]=","[G]=kk"],H:[" [HAV]=I aa FF"," [HERE]=I I RR"," [HOUR]=aa EE","[HOW]=I aa","[H]#=I","[H]="],I:[" [IN]=I nn"," [I] =aa","[IN]D=aa nn","[IER]=I E","#:R[IED] =I DD","[IED] =aa DD","[IEN]=I E nn","[IE]T=aa E"," :[I]%=aa","[I]%=I","[IE]=I","[I]^+:#=I","[IR]#=aa RR","[IZ]%=aa SS","[IS]%=aa SS","[I]D%=aa","+^[I]^+=I","[I]T%=aa","#^:[I]^+=I","[I]^+=aa","[IR]=E","[IGH]=aa","[ILD]=aa nn DD","[IGN] =aa nn","[IGN]^=aa nn","[IGN]%=aa nn","[IQUE]=I kk","[I]=I"],J:["[J]=kk"],K:[" [K]N=","[K]=kk"],L:["[LO]C#=nn O","L[L]=","#^:[L]%=aa nn","[LEAD]=nn I DD","[L]=nn"],M:["[MOV]=PP U FF","[M]=PP"],N:["E[NG]+=nn kk","[NG]R=nn kk","[NG]#=nn kk","[NGL]%=nn kk aa nn","[NG]=nn","[NK]=nn kk"," [NOW] =nn aa","[N]=nn"],O:["[OF] =aa FF","[OROUGH]=E O","#:[OR] =E","#:[ORS] =E SS","[OR]=aa RR"," [ONE]=FF aa nn","[OW]=O"," [OVER]=O FF E","[OV]=aa FF","[O]^%=O","[O]^EN=O","[O]^I#=O","[OL]D=O nn","[OUGHT]=aa DD","[OUGH]=aa FF"," [OU]=aa","H[OU]S#=aa","[OUS]=aa SS","[OUR]=aa RR","[OULD]=U DD","^[OU]^L=aa","[OUP]=U OO","[OU]=aa","[OY]=O","[OING]=O I nn","[OI]=O","[OOR]=aa RR","[OOK]=U kk","[OOD]=U DD","[OO]=U","[O]E=O","[O] =O","[OA]=O"," [ONLY]=O nn nn I"," [ONCE]=FF aa nn SS","[ON'T]=O nn DD","C[O]N=aa","[O]NG=aa"," ^:[O]N=aa","I[ON]=aa nn","#:[ON] =aa nn","#^[ON]=aa nn","[O]ST =O","[OF]^=aa FF","[OTHER]=aa TH E","[OSS] =aa SS","#^:[OM]=aa PP","[O]=aa"],P:["[PH]=FF","[PEOP]=PP I PP","[POW]=PP aa","[PUT] =PP U DD","[P]=PP"],Q:["[QUAR]=kk FF aa RR","[QU]=kk FF","[Q]=kk"],R:[" [RE]^#=RR I","[R]=RR"],S:["[SH]=SS","#[SION]=SS aa nn","[SOME]=SS aa PP","#[SUR]#=SS E","[SUR]#=SS E","#[SU]#=SS U","#[SSU]#=SS U","#[SED] =SS DD","#[S]#=SS","[SAID]=SS E DD","^[SION]=SS aa nn","[S]S=",".[S] =SS","#:.E[S] =SS","#^:##[S] =SS","#^:#[S] =SS","U[S] =SS"," :#[S] =SS"," [SCH]=SS kk","[S]C+=","#[SM]=SS PP","#[SN]'=SS aa nn","[S]=SS"],T:[" [THE] =TH aa","[TO] =DD U","[THAT] =TH aa DD"," [THIS] =TH I SS"," [THEY]=TH E"," [THERE]=TH E RR","[THER]=TH E","[THEIR]=TH E RR"," [THAN] =TH aa nn"," [THEM] =TH E PP","[THESE] =TH I SS"," [THEN]=TH E nn","[THROUGH]=TH RR U","[THOSE]=TH O SS","[THOUGH] =TH O"," [THUS]=TH aa SS","[TH]=TH","#:[TED] =DD I DD","S[TI]#N=CH","[TI]O=SS","[TI]A=SS","[TIEN]=SS aa nn","[TUR]#=CH E","[TU]A=CH U"," [TWO]=DD U","[T]=DD"],U:[" [UN]I=I U nn"," [UN]=aa nn"," [UPON]=aa PP aa nn","@[UR]#=U RR","[UR]#=I U RR","[UR]=E","[U]^ =aa","[U]^^=aa","[UY]=aa"," G[U]#=","G[U]%=","G[U]#=FF","#N[U]=I U","@[U]=I","[U]=I U"],V:["[VIEW]=FF I U","[V]=FF"],W:[" [WERE]=FF E","[WA]S=FF aa","[WA]T=FF aa","[WHERE]=FF E RR","[WHAT]=FF aa DD","[WHOL]=I O nn","[WHO]=I U","[WH]=FF","[WAR]=FF aa RR","[WOR]^=FF E","[WR]=RR","[W]=FF"],X:[" [X]=SS","[X]=kk SS"],Y:["[YOUNG]=I aa nn"," [YOU]=I U"," [YES]=I E SS"," [Y]=I","#^:[Y] =I","#^:[Y]I=I"," :[Y] =aa"," :[Y]#=aa"," :[Y]^+:#=I"," :[Y]^#=I","[Y]=I"],Z:["[Z]=SS"]};const n={"#":"[AEIOUY]+",".":"[BDVGJLMNRWZ]","%":"(?:ER|E|ES|ED|ING|ELY)","&":"(?:[SCGZXJ]|CH|SH)","@":"(?:[TSRDLZNJ]|TH|CH|SH)","^":"[BCDFGHJKLMNPQRSTVWXZ]","+":"[EIY]",":":"[BCDFGHJKLMNPQRSTVWXZ]*"," ":"\\b"};Object.keys(this.rules).forEach(e=>{this.rules[e]=this.rules[e].map(t=>{const o=t.indexOf("["),s=t.indexOf("]"),i=t.indexOf("="),a=t.substring(0,o),c=t.substring(o+1,s),l=t.substring(s+1,i),u=t.substring(i+1),r={regex:"",move:0,visemes:[]};let h="";h+=[...a].map(g=>n[g]||g).join("");const d=[...c];return d[0]=d[0].toLowerCase(),h+=d.join(""),r.move=d.length,h+=[...l].map(g=>n[g]||g).join(""),r.regex=new RegExp(h),u.length&&u.split(" ").forEach(g=>{r.visemes.push(g)}),r})}),this.visemeDurations={aa:.95,E:.9,I:.92,O:.96,U:.95,PP:1.08,SS:1.23,TH:1,DD:1.05,FF:1,kk:1.21,nn:.88,RR:.88,DD:1.05,sil:1},this.specialDurations={" ":1,",":3,"-":.5,"'":.5},this.digits=["oh","one","two","three","four","five","six","seven","eight","nine"],this.ones=["","one","two","three","four","five","six","seven","eight","nine"],this.tens=["","","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"],this.teens=["ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"],this.decades={20:"twenties",30:"thirties",40:"forties",50:"fifties",60:"sixties",70:"seventies",80:"eighties",90:"nineties"},this.ordinals={1:"first",2:"second",3:"third",4:"fourth",5:"fifth",6:"sixth",7:"seventh",8:"eighth",9:"ninth",10:"tenth",11:"eleventh",12:"twelfth",13:"thirteenth",14:"fourteenth",15:"fifteenth",16:"sixteenth",17:"seventeeth",18:"eighteenth",19:"nineteenth",20:"twentieth",30:"thirtieth",40:"fortieth",50:"fiftieth",60:"sixtieth",70:"seventieth",80:"eightieth",90:"ninetieth"},this.symbols={"%":"percent","€":"euros","&":"and","+":"plus",$:"dollars"},this.symbolsReg=/[%€&\+\$]/g}convert_digit_by_digit(n){n=String(n).split("");let e="";for(let t=0;t<n.length;t++)e+=this.digits[n[t]]+" ";return e=e.substring(0,e.length-1),e}convert_sets_of_two(n){let e=String(n).substring(0,2),t=String(n).substring(2,4),o=this.convert_tens(e);return o+=" "+this.convert_tens(t),o}convert_millions(n){return n>=1e6?this.convert_millions(Math.floor(n/1e6))+" million "+this.convert_thousands(n%1e6):this.convert_thousands(n)}convert_thousands(n){return n>=1e3?this.convert_hundreds(Math.floor(n/1e3))+" thousand "+this.convert_hundreds(n%1e3):this.convert_hundreds(n)}convert_hundreds(n){return n>99?this.ones[Math.floor(n/100)]+" hundred "+this.convert_tens(n%100):this.convert_tens(n)}convert_tens(n){return n<10?(Number(n)!=0&&n.toString().startsWith("0")?"oh ":"")+this.ones[Number(n)]:n>=10&&n<20?this.teens[n-10]:(this.tens[Math.floor(n/10)]+" "+this.ones[n%10]).trim()}convertNumberToWords(n,e=!1){const t=parseFloat(n);if(n=="0")return"zero";if(n<0)return" minus "+this.convertNumberToWords(Math.abs(n).toString(),e).trim();if(t&&!Number.isInteger(t)){const o=t.toString().split(".");return this.convertNumberToWords(o[0],e).trim()+" point "+this.convert_digit_by_digit(o[1]).trim()}else return n.toString().startsWith("0")?this.convert_digit_by_digit(n).trim():!e&&(n<1e3&&n>99&&n%100!==0||n>1e4&&n<1e6)?this.convert_digit_by_digit(n).trim():!e&&(n>1e3&&n<2e3||n>2009&&n<3e3)?n%100!=0?this.convert_sets_of_two(n).trim():this.convert_tens(n.toString().substring(0,2)).trim()+" hundred":this.convert_millions(n).trim()}convertDecade(n){const e=parseInt(n),t=!isNaN(e)&&n.length===2,o=!isNaN(e)&&n.length>2&&e>0&&e<=3e3,s=o&&e%1e3===0?Math.floor(e/1e3):null,i=o&&!s?Math.floor(e/100):null,a=t||o?Math.floor(e%100/10)*10:null;let c=[];return s?c.push(this.convertNumberToWords(s).trim(),"thousands"):(i&&c.push(this.convertNumberToWords(i).trim()),a?c.push(this.decades[a]||this.convertNumberToWords(a).trim()+"s"):i?c.push("hundreds"):c.push(n)),c.join(" ")}convertOrdinal(n){if(this.ordinals.hasOwnProperty(n))return this.ordinals[n];const e=Math.floor(n/100),t=Math.floor(n%100/10)*10,o=n%10;let s=[];return e&&(s.push(this.convertNumberToWords(e).trim()),t||o?s.push("hundred"):s.push("hundredth")),t&&(o?s.push(this.convertNumberToWords(t).trim()):s.push(this.ordinals[t])),o&&s.push(this.ordinals[o]),s.join(" ")}preProcessText(n){let e=n.replace('/[#_*":;]/g',"");return e=e.replace(this.symbolsReg,t=>" "+this.symbols[t]+" "),/\d/.test(e)&&(e=e.replace(/\b(\d{2,4})[''']?\s?[sS](?=\s|[.,!?;:]|$)/g,(t,o)=>{const s=this.convertDecade(o);return s===o?t:s}),e=e.replace(/\b(\d+)\s*(st|nd|rd|th)(?=\s|[.,!?;:]|$)/gi,(t,o)=>this.convertOrdinal(Number(o))),e=e.replace(/\b(\w*?)(\d+)([A-Za-z]+)\b/g,(t,o,s,i)=>{const a=this.convertNumberToWords(s);return`${o}${a} ${i}`}).replace(/\b([A-Za-z]+)(\d+)(\w*?)\b/g,(t,o,s,i)=>{const a=this.convertNumberToWords(s);return`${o} ${a}${i}`}),e=e.replace(/-?(?:\d{1,3}(?:,\d{3})+|\d+)(\.\d+)?/g,(t,o)=>{let s=t,i=!1;return/,/.test(s)&&(s=s.replace(/,/g,""),i=!0),o&&(i=!0),this.convertNumberToWords(s,i)})),e=e.replace(/(\D)\1\1+/g,"$1$1").replaceAll(" "," ").normalize("NFD").replace(/[\u0300-\u036f]/g,"").normalize("NFC").trim(),e}wordsToVisemes(n){let e={words:n.toUpperCase(),visemes:[],times:[],durations:[],i:0},t=0;const o=[...e.words];for(;e.i<o.length;){const s=o[e.i],i=this.rules[s];if(i)for(let a=0;a<i.length;a++){const c=i[a];if((e.words.substring(0,e.i)+s.toLowerCase()+e.words.substring(e.i+1)).match(c.regex)){c.visemes.forEach(r=>{if(e.visemes.length&&e.visemes[e.visemes.length-1]===r){const h=.7*(this.visemeDurations[r]||1);e.durations[e.durations.length-1]+=h,t+=h}else{const h=this.visemeDurations[r]||1;e.visemes.push(r),e.times.push(t),e.durations.push(h),t+=h}}),e.i+=c.move;break}}else e.i++,t+=this.specialDurations[s]||0}return e}}const wt=Object.freeze(Object.defineProperty({__proto__:null,LipsyncEn:kt},Symbol.toStringTag,{value:"Module"}));class Ct{constructor(){this.rules={A:["[AH]=aa","[AU]=aa U","[AI]=aa I","[AE]=E","[A]H=aa","[A]U=aa U","[A]I=aa I"," [AN] =aa nn"," [AM] =aa PP","[ARR]=aa RR","[AR]=aa RR"," [ALS]=aa nn SS","[AL]=aa nn","[AUCH]=aa U kk","[ABER]=aa PP E RR","[A]=aa"],Ä:["[Ä]H=E","[ÄU]=O","[Ä]=E"],B:["[B]=PP"],C:["[CH]S=kk SS","[CH]=kk"," [CH]=kk","#[CH]=kk","[CK]=kk","[C]H=kk","[C]=kk"],D:[" [DAS] =DD aa SS"," [DEN] =DD E nn"," [DER] =DD E RR"," [DIE] =DD I"," [DU] =DD U"," [DURCH]=DD U RR kk","[D]=DD"],E:["[EI]=aa I","[EU]=O","[EH]=E"," [ER] =E RR"," [ES] =E SS"," [EIN] =aa I nn"," [EINE]=aa I nn aa","[ER]#=E","[ER]=E RR","[EN]#=aa nn","[E]=E"],F:["[F]=FF"],G:["[G]=kk"],H:[" [HAT] =I aa DD"," [HABEN]=I aa PP aa nn"," [HIER]=I I RR"," [HEUTE]=I O DD aa","[H]="],I:[" [ICH] =I kk"," [IHR] =I RR"," [IN] =I nn"," [IST] =I SS DD"," [IM] =I PP","[IE]=I","[IH]=I","[I]=I"],J:["[J]=I"],K:["[K]=kk"],L:["[L]=nn"],M:[" [MIT] =PP I DD"," [MAN] =PP aa nn"," [MEHR]=PP E RR"," [MICH]=PP I kk","[M]=PP"],N:[" [NICHT]=nn I kk DD"," [NUR] =nn U RR"," [NACH]=nn aa kk"," [NOCH]=nn aa kk","[NG]=nn kk","[N]=nn"],O:["[OO]=U","[OH]=O","[OU]=aa U"," [ODER]=O DD E RR"," [OHNE]=O nn aa","[Ö]=E","[O]=aa"],Ö:["[ÖH]=E","[Ö]=E"],P:["[PF]=FF FF","[PH]=FF","[P]=PP"],Q:["[QU]=kk FF","[Q]=kk"],R:["[R]=RR"],S:["[SCH]=SS","[SP]=SS PP","[ST]=SS DD","[SS]=SS","[S]=SS"],ß:["[ß]=SS"],T:["[TZ]=DD SS","[TH]=DD","[T]=DD"],U:[" [UND] =U nn DD"," [UM] =U PP"," [UNTER]=U nn DD E RR"," [UNS] =U nn SS","[UH]=U","[ÜH]=I U","[Ü]=I U","[U]=U"],Ü:["[ÜH]=I U","[Ü]=I U"],V:[" [VON] =FF aa nn"," [VOR] =FF aa RR"," [VIEL]=FF I nn","[V]=FF"],W:[" [WAS] =FF aa SS"," [WIR] =FF I RR"," [WIE] =FF I"," [WENN]=FF E nn"," [WILL]=FF I nn"," [WO] =FF aa"," [WIEDER]=FF I DD E RR","[W]=FF"],X:["[X]=kk SS"],Y:["[Y]=I"],Z:[" [ZU] =DD SS U"," [ZUM] =DD SS U PP"," [ZUR] =DD SS U RR"," [ZEIT]=DD SS aa I DD","[Z]=DD SS"]};const n={"#":"[AEIOUÄÖÜ]+",".":"[BDVGJLMNRWZ]","%":"(?:ER|E|ES|ED|ING|ELY|EN|TE|ST)","&":"(?:[SCGZXJ]|CH|SCH|TZ)","@":"(?:[TSRDLZNJ]|TH|CH|SCH)","^":"[BCDFGHJKLMNPQRSTVWXYZß]","+":"[EIY]",":":"[BCDFGHJKLMNPQRSTVWXYZß]*"," ":"\\b"};Object.keys(this.rules).forEach(e=>{this.rules[e]=this.rules[e].map(t=>{const o=t.indexOf("["),s=t.indexOf("]"),i=t.indexOf("="),a=t.substring(0,o),c=t.substring(o+1,s),l=t.substring(s+1,i),u=t.substring(i+1),r={regex:"",move:0,visemes:[]};let h="";h+=[...a].map(g=>n[g]||g).join("");const d=[...c];return d[0]=d[0].toLowerCase(),h+=d.join(""),r.move=d.length,h+=[...l].map(g=>n[g]||g).join(""),r.regex=new RegExp(h),u.length&&u.split(" ").forEach(g=>{r.visemes.push(g)}),r})}),this.visemeDurations={aa:1,E:.85,I:.9,O:1.05,U:1,PP:1.15,SS:1.2,TH:1,DD:1.1,FF:1.05,kk:1.25,nn:.85,RR:.9,sil:1},this.specialDurations={" ":1,",":3,"-":.5,"'":.5,".":4,"!":3,"?":3},this.digits=["null","eins","zwei","drei","vier","fünf","sechs","sieben","acht","neun"],this.ones=["","ein","zwei","drei","vier","fünf","sechs","sieben","acht","neun"],this.tens=["","","zwanzig","dreißig","vierzig","fünfzig","sechzig","siebzig","achtzig","neunzig"],this.teens=["zehn","elf","zwölf","dreizehn","vierzehn","fünfzehn","sechzehn","siebzehn","achtzehn","neunzehn"],this.symbols={"%":"prozent","€":"euro","&":"und","+":"plus",$:"dollar","=":"gleich","@":"at","#":"hashtag"},this.symbolsReg=/[%€&\+\$=@#]/g}convert_digit_by_digit(n){n=String(n).split("");let e="";for(let t=0;t<n.length;t++)e+=this.digits[n[t]]+" ";return e=e.substring(0,e.length-1),e}convert_millions(n){if(n>=1e6){const e=Math.floor(n/1e6),t=n%1e6;let o=this.convert_thousands(e);return o+=e===1?" million ":" millionen ",t>0&&(o+=this.convert_thousands(t)),o}else return this.convert_thousands(n)}convert_thousands(n){if(n>=1e3){const e=Math.floor(n/1e3),t=n%1e3;let o="";return e===1?o="eintausend":o=this.convert_hundreds(e)+"tausend",t>0&&(o+=this.convert_hundreds(t)),o}else return this.convert_hundreds(n)}convert_hundreds(n){if(n>99){const e=Math.floor(n/100),t=n%100;let o="";return e===1?o="einhundert":o=this.ones[e]+"hundert",t>0&&(o+=this.convert_tens(t)),o}else return this.convert_tens(n)}convert_tens(n){if(n<10)return this.ones[Number(n)]||"";if(n>=10&&n<20)return this.teens[n-10];{const e=Math.floor(n/10),t=n%10;return t===0?this.tens[e]:this.ones[t]+"und"+this.tens[e]}}convertNumberToWords(n){const e=String(n);return n=="0"?"null":e.startsWith("0")?this.convert_digit_by_digit(n):e.length===4&&(n<1e3||n>2100)?this.convert_digit_by_digit(n):this.convert_millions(Number(n))}preProcessText(n){return n.replace(/[#_*\":;]/g,"").replace(this.symbolsReg,e=>" "+this.symbols[e]+" ").replace(/(\d)\.(\d)/g,"$1 komma $2").replace(/(\d),(\d)/g,"$1 komma $2").replace(/\d+/g,this.convertNumberToWords.bind(this)).replace(/(\D)\1\1+/g,"$1$1").replace(/\s+/g," ").toLowerCase().trim()}wordsToVisemes(n){let e={words:n.toUpperCase(),visemes:[],times:[],durations:[],i:0},t=0;const o=[...e.words];for(;e.i<o.length;){const s=o[e.i],i=this.rules[s];if(i){let a=!1;for(let c=0;c<i.length;c++){const l=i[c];if((e.words.substring(0,e.i)+s.toLowerCase()+e.words.substring(e.i+1)).match(l.regex)){l.visemes.forEach(h=>{if(e.visemes.length&&e.visemes[e.visemes.length-1]===h){const d=.7*(this.visemeDurations[h]||1);e.durations[e.durations.length-1]+=d,t+=d}else{const d=this.visemeDurations[h]||1;e.visemes.push(h),e.times.push(t),e.durations.push(d),t+=d}}),e.i+=l.move,a=!0;break}}a||(e.i++,t+=this.specialDurations[s]||0)}else e.i++,t+=this.specialDurations[s]||0}return e}}const zt=Object.freeze(Object.defineProperty({__proto__:null,LipsyncDe:Ct},Symbol.toStringTag,{value:"Module"}));class Ht{constructor(){this.rules={A:["[AN]C=aa nn","[AN]G=aa nn","[AN]T=aa nn","[AN]D=aa nn","[AN] =aa nn","[AN]$=aa nn","[AM]P=aa nn","[AM]B=aa nn","[AM] =aa nn","[AM]$=aa nn","[AI]N=E nn","[AIM]=E nn","[AIN]=E nn","[AU]=O","[AUX]=O","[AUT]=O","[AI]=E","[AY]=E","[A]=aa"],À:["[À]=aa"],Â:["[Â]=aa"],B:[" [B] =PP","[BB]=PP","[B]=PP"],C:["[C]E=SS","[C]I=SS","[C]Y=SS","[C]È=SS","[C]É=SS","[C]Ê=SS","[CH]=SS","[C]A=kk","[C]O=kk","[C]U=kk","[C]L=kk","[C]R=kk","[CK]=kk","[C]=kk"],Ç:["[Ç]=SS"],D:["[D]=DD"],E:["[EN]C=aa nn","[EN]T=aa nn","[EN]D=aa nn","[EN] =aa nn","[EN]$=aa nn","[EM]P=aa nn","[EM]B=aa nn","[EM] =aa nn","[EM]$=aa nn","[EAU]=O","[EAU]X=O","[EU]=U","[EUX]=U","[EUR]=U RR","[EI]=E","[EIN]=E nn","[ER] =E","[ER]$=E","[EZ] =E","[EZ]$=E","[ED] =E","[ED]$=E"," [E] =","[E] =","[E]$=","[E]S =","[E]S$=","[E]NT =","[E]NT$=","[È]=E","[É]=E","[Ê]=E","[Ë]=E","[E]=E"],È:["[È]=E"],É:["[É]=E"],Ê:["[Ê]=E"],Ë:["[Ë]=E"],F:["[FF]=FF","[F]=FF","[PH]=FF"],G:["[G]E=SS","[G]I=SS","[G]Y=SS","[G]È=SS","[G]É=SS","[G]Ê=SS","[GN]=nn I","[GN]E=nn","[GN]A=nn aa","[GN]O=nn O","[GU]E=kk","[GU]I=kk","[GU]A=kk FF aa","[GU]O=kk FF O","[G]A=kk","[G]O=kk","[G]U=kk","[G]L=kk","[G]R=kk","[GG]=kk","[G]=kk"],H:["[H]="],I:["[IN]C=E nn","[IN]T=E nn","[IN]D=E nn","[IN] =E nn","[IN]$=E nn","[IM]P=E nn","[IM]B=E nn","[IM] =E nn","[IM]$=E nn","[IEN]=I E nn","[IER]=I E","[IEU]=I U","[IEZ]=I E","[ILL]E=I","[ILLE]=I","[ILL]=I","[Î]=I","[Ï]=I","[I]=I"],Î:["[Î]=I"],Ï:["[Ï]=I"],J:["[J]=SS"],K:["[K]=kk"],L:["[LL]E=","[LLE]=","[LL]A=I aa","[LL]O=I O","[LL]U=I U","[LL]I=I","[LL]=I","[L]=nn"],M:["[MM]=PP","[M]=PP"],N:["[NN]=nn","[N]=nn"],O:["[ON]C=O nn","[ON]T=O nn","[ON]D=O nn","[ON] =O nn","[ON]$=O nn","[OM]P=O nn","[OM]B=O nn","[OM] =O nn","[OM]$=O nn","[OI]N=FF E nn","[OI]G=FF aa","[OI]S=FF aa","[OI]T=FF aa","[OI]X=FF aa","[OI]=FF aa","[OU]=U","[OÙ]=U","[OÛ]=U","[OEU]=U","[OEUR]=U RR","[OUGH]=U FF","[OUGH]T=U","[Ô]=O","[O]=O"],Ô:["[Ô]=O"],Ù:["[Ù]=U"],Û:["[Û]=U"],P:["[PH]=FF","[PP]=PP","[P]=PP"],Q:["[QU]=kk","[Q]=kk"],R:["[RR]=RR","[R]=RR"],S:["#[S]#=SS"," [S]=SS","[SS]=SS","[S] =","[S]$=","[SC]E=SS","[SC]I=SS","[SC]Y=SS","[S]=SS"],T:["[TI]A=SS I aa","[TI]E=SS I E","[TI]O=SS I O","[TI]ON=SS I O nn","[TH]=DD","[TT]=DD","[T] =","[T]$=","[T]=DD"],U:["[UN]C=U nn","[UN]T=U nn","[UN]D=U nn","[UN] =U nn","[UN]$=U nn","[UM]=U nn","[UE]=I","[UEI]=I E","[UEIL]=I I","[UILL]=I","[Ù]=U","[Û]=U","[Ü]=I U","[U]=I U"],Ü:["[Ü]=I U"],V:["[V]=FF"],W:["[W]=FF"],X:["[X] =","[X]$=","#[X]#=kk SS"," [X]=kk SS","[X]=kk SS"],Y:["[Y]=I"," [Y]=I","[YE]=I E","[YA]=I aa","[YO]=I O","[YU]=I U"],Z:["[Z]=SS"]};const n={"#":"[AEIOUYÀÂÈÉÊËÎÏÔÙÛÜ]+",".":"[BDVGJLMNRWZ]","%":"(?:ER|E|ES|ÉS|ÈS|ÊS|ENT|MENT|TION|SION)","&":"(?:[SCGZXJ]|CH|SH|GN)","@":"(?:[TSRDLZNJ]|TH|CH|SH|GN)","^":"[BCDFGHJKLMNPQRSTVWXZÇ]+","+":"[EIYÈÉÊËÎÏ]",":":"[BCDFGHJKLMNPQRSTVWXZÇ]*"," ":"\\b",$:"$"};Object.keys(this.rules).forEach(e=>{this.rules[e]=this.rules[e].map(t=>{const o=t.indexOf("["),s=t.indexOf("]"),i=t.indexOf("="),a=t.substring(0,o),c=t.substring(o+1,s),l=t.substring(s+1,i),u=t.substring(i+1),r={regex:"",move:0,visemes:[]};let h="";h+=[...a].map(g=>n[g]||g).join("");const d=[...c];return d[0]=d[0].toLowerCase(),h+=d.join(""),r.move=d.length,h+=[...l].map(g=>n[g]||g).join(""),r.regex=new RegExp(h,"i"),u.length&&u.split(" ").forEach(g=>{g&&r.visemes.push(g)}),r})}),this.visemeDurations={aa:1,E:.95,I:.9,O:1.05,U:.95,PP:1.1,SS:1.25,TH:1,DD:1.05,FF:1,kk:1.2,nn:.88,RR:1.15,sil:1},this.specialDurations={" ":1,",":2.5,".":3.5,";":2.8,":":2.2,"!":3.2,"?":3.2,"-":.8,"'":.3,'"':.3,"(":1.5,")":1.5},this.digits=["zéro","un","deux","trois","quatre","cinq","six","sept","huit","neuf"],this.ones=["","un","deux","trois","quatre","cinq","six","sept","huit","neuf"],this.teens=["dix","onze","douze","treize","quatorze","quinze","seize","dix-sept","dix-huit","dix-neuf"],this.tens=["","dix","vingt","trente","quarante","cinquante","soixante","soixante-dix","quatre-vingts","quatre-vingt-dix"],this.symbols={"%":"pourcent","€":"euros","&":"et","+":"plus",$:"dollars","=":"égale","@":"arobase","#":"dièse","°":"degrés"},this.symbolsReg=/[%€&\+\$=@#°]/g}convert_digit_by_digit(n){n=String(n).split("");let e="";for(let t=0;t<n.length;t++)e+=this.digits[n[t]]+" ";return e=e.substring(0,e.length-1),e}convert_tens(n){if(n<10)return this.ones[n]||"";if(n>=10&&n<20)return this.teens[n-10];if(n>=70&&n<80){const e=n-60;return e===11?"soixante et onze":"soixante-"+this.teens[e-10]}else if(n>=90){const e=n-80;return e===11?"quatre-vingt-onze":"quatre-vingt-"+this.teens[e-10]}else{const e=Math.floor(n/10),t=n%10;return e===8&&t===0?"quatre-vingts":e===8?"quatre-vingt-"+this.ones[t]:(e===2||e===3||e===4||e===5||e===6)&&t===1?this.tens[e]+" et un":t===0?this.tens[e]:this.tens[e]+"-"+this.ones[t]}}convert_hundreds(n){if(n>=100){const e=Math.floor(n/100),t=n%100;let o="";return e===1?o="cent":(o=this.ones[e]+" cent",t===0&&(o+="s")),t>0&&(o+=" "+this.convert_tens(t)),o}else return this.convert_tens(n)}convert_thousands(n){if(n>=1e3){const e=Math.floor(n/1e3),t=n%1e3;let o="";return e===1?o="mille":o=this.convert_hundreds(e)+" mille",t>0&&(o+=" "+this.convert_hundreds(t)),o}else return this.convert_hundreds(n)}convert_millions(n){if(n>=1e6){const e=Math.floor(n/1e6),t=n%1e6;let o="";return e===1?o="un million":o=this.convert_hundreds(e)+" millions",t>0&&(o+=" "+this.convert_thousands(t)),o}else return this.convert_thousands(n)}convertNumberToWords(n){const e=String(n);return n==="0"||n===0?"zéro":e.startsWith("0")?this.convert_digit_by_digit(n):this.convert_millions(Number(n))}preProcessText(n){return n.replace(/[#_*\":;]/g,"").replace(this.symbolsReg,e=>" "+this.symbols[e]+" ").replace(/(\d)[,.](\d)/g,"$1 virgule $2").replace(/\d+/g,this.convertNumberToWords.bind(this)).replace(/(\D)\1\1+/g,"$1$1").replace(/\s+/g," ").replace(/'/g,"'").trim()}wordsToVisemes(n){let e={words:n.toUpperCase(),visemes:[],times:[],durations:[],i:0},t=0;const o=[...e.words];for(;e.i<o.length;){const s=o[e.i],i=this.rules[s];if(i){let a=!1;for(let c=0;c<i.length;c++){const l=i[c];if((e.words.substring(0,e.i)+s.toLowerCase()+e.words.substring(e.i+1)).match(l.regex)){l.visemes.forEach(h=>{if(e.visemes.length&&e.visemes[e.visemes.length-1]===h){const d=.7*(this.visemeDurations[h]||1);e.durations[e.durations.length-1]+=d,t+=d}else{const d=this.visemeDurations[h]||1;e.visemes.push(h),e.times.push(t),e.durations.push(d),t+=d}}),e.i+=l.move,a=!0;break}}a||(e.i++,t+=this.specialDurations[s]||0)}else e.i++,t+=this.specialDurations[s]||0}return e}}const Tt=Object.freeze(Object.defineProperty({__proto__:null,LipsyncFr:Ht},Symbol.toStringTag,{value:"Module"}));class Ft{constructor(){this.visemes={a:"aa",e:"E",i:"I",o:"O",u:"U",y:"U",ä:"aa",ö:"O",å:"O",b:"PP",c:"SS",d:"DD",f:"FF",g:"kk",h:"kk",j:"I",k:"kk",l:"nn",m:"PP",n:"nn",p:"PP",q:"kk",r:"RR",s:"SS",t:"DD",v:"FF",w:"FF",x:"SS",z:"SS"},this.visemeDurations={aa:.95,E:.9,I:.92,O:.96,U:.95,PP:1.08,SS:1.23,DD:1.05,FF:1,kk:1.21,nn:.88,RR:.88,DD:1.05,sil:1},this.specialDurations={" ":1,",":3,"-":.5},this.numbers=["nolla","yksi","kaksi","kolme","neljä","viisi","kuusi","seitsemän","kahdeksan","yhdeksän","kymmenen","yksitoista","kaksitoista","kolmetoista","neljätoista","viisitoista","kuusitoista","seitsemäntoista","kahdeksantoista","yhdeksäntoista"],this.symbols={"%":"prosenttia","€":"euroa","&":"ja","+":"plus",$:"dollaria"},this.symbolsReg=/[%€&\+\$]/g}numberToFinnishWords(n){const e=[];let t=parseFloat(n);if(t===void 0)return n;let o=(s,i,a,c,l)=>{if(s<i)return s;const u=Math.floor(s/i);return e.push(a+(u===1?c:this.numberToFinnishWords(u.toString())+l)),s-u*i};if(t<0&&(e.push("miinus "),t=Math.abs(t)),t=o(t,1e9," ","miljardi"," miljardia"),t=o(t,1e6," ","miljoona"," miljoonaa"),t=o(t,1e3,"","tuhat","tuhatta"),t=o(t,100," ","sata","sataa"),t>20&&(t=o(t,10,"","","kymmentä")),t>=1){let s=Math.floor(t);e.push(this.numbers[s]),t-=s}if(t>=0&&Math.abs(parseFloat(n))<1&&e.push("nolla"),t>0){let s=n.split(".");if(s.length>1){e.push(" pilkku");let i=[...s[s.length-1]];for(let a=0;a<i.length;a++)e.push(" "+this.numbers[i[a]])}}return e.join("").trim()}preProcessText(n){return n.replace(/[#_*\'\":;]/g,"").replace(this.symbolsReg,e=>" "+this.symbols[e]+" ").replace(/(\d)\,(\d)/g,"$1 pilkku $2").replace(/\d+/g,this.numberToFinnishWords.bind(this)).replaceAll(" "," ").normalize("NFD").replace(/[\u0300-\u0307\u0309\u030b-\u036f]/g,"").normalize("NFC").trim()}wordsToVisemes(n){let e={words:n,visemes:[],times:[],durations:[]},t=0;const o=[...n];for(let s=0;s<o.length;s++){const i=this.visemes[o[s].toLowerCase()];if(i)if(e.visemes.length&&e.visemes[e.visemes.length-1]===i){const a=.7*(this.visemeDurations[i]||1);e.durations[e.durations.length-1]+=a,t+=a}else{const a=this.visemeDurations[i]||1;e.visemes.push(i),e.times.push(t),e.durations.push(a),t+=a}else t+=this.specialDurations[o[s]]||0}return e}}const Mt=Object.freeze(Object.defineProperty({__proto__:null,LipsyncFi:Ft},Symbol.toStringTag,{value:"Module"}));class Et{constructor(){this.visemes={a:"aa",ą:"O",e:"E",ę:"E",ė:"E",i:"I",į:"I",o:"O",u:"U",ū:"U",ų:"U",y:"I",b:"PP",c:"SS",č:"SS",d:"DD",f:"FF",g:"kk",h:"kk",j:"I",k:"kk",l:"nn",m:"PP",n:"nn",p:"PP",q:"kk",r:"RR",s:"SS",š:"CH",t:"DD",v:"FF",w:"FF",x:"SS",z:"SS",ž:"SS"},this.durations={a:.95,ą:1.5,e:.9,ę:1.5,ė:1.5,i:.92,į:1.5,o:.96,u:.95,ū:1.5,ų:1.5,y:1.5,b:1.08,c:1.23,d:1.05,f:1,g:1.21,h:1.21,j:.92,k:1.21,l:.88,m:1.08,n:.88,p:1.08,q:1.21,r:.88,s:1.23,š:1.23,t:1.05,v:1,w:1,x:1.23,z:1.23,ž:1.23},this.pauses={" ":1,",":3,"-":.5},this.numbers=["nulis","vienas","du","trys","keturi","penki","šeši","septyni","aštuoni","devyni","dešimt","vienuolika","dvylika","trylika","keturiolika","penkiolika","šešiolika","septyniolika","aštuoniolika","devyniolika"],this.tens=[this.numbers[0],this.numbers[10],"dvidešimt","trisdešimt","keturiasdešimt","penkiasdešimt","šešiasdešimt","septyniasdešimt","aštuoniasdešimt","devyniasdešimt"]}numberToLithuanianWords(n){const e=[];let t=parseFloat(n);if(t===void 0)return n;let o=(s,i,a,c,l)=>{if(s<i)return s;const u=Math.floor(s/i);return u===1?e.push(this.numbers[1]):e.push(this.numberToLithuanianWords(u.toString())),u%10===1?e.push(a):u%10===0||u%100>10&&u%100<20?e.push(l):e.push(c),s-u*i};t<0&&(e.push("minus"),t=Math.abs(t)),t=o(t,1e9,"milijardas","milijardai","milijardų"),t=o(t,1e6,"milijonas","milijonai","milijonų"),t=o(t,1e3,"tūkstantis","tūkstančiai","tūkstančių"),t=o(t,100,"šimtas","šimtai","šimtų");for(let s=this.tens.length-1;s>=1;s--)if(t>=10*s){e.push(this.tens[s]),t=t-10*s;break}if(t>=1){let s=Math.floor(t);e.push(this.numbers[s]),t-=s}if(t>=0&&Math.abs(parseFloat(n))<1&&e.push(this.numbers[0]),t>0){let s=n.split(".");if(s.length>1){e.push("kablelis");let i=[...s[s.length-1]];for(let a=0;a<i.length;a++)e.push(this.numbers[i[a]])}}return e.join(" ").trim()}preProcessText(n){return n.replace(`/[#_*'":;]/g`,"").replaceAll("0 %","0 procentų ").replaceAll("1 %","1 procentas ").replaceAll("%"," procentai ").replaceAll("0 €","0 eurų ").replaceAll("1 €","1 euras ").replaceAll("€"," eurai ").replaceAll("0 $","0 dolerių ").replaceAll("1 $","1 doleris ").replaceAll("$"," doleriai ").replaceAll("&"," ir ").replaceAll("+"," pliusas ").replace(/(\d)\,(\d)/g,"$1 kablelis $2").replace(/\d+/g,this.numberToLithuanianWords.bind(this)).replace(/(\D)\1\1+/g,"$1$1").replaceAll(" "," ").normalize("NFD").replace(/[\u0300-\u0303\u0305\u0306\u0308-\u0327\u0329-\u036f]/g,"").normalize("NFC").trim()}wordsToVisemes(n){let e={words:n,visemes:[],times:[],durations:[]},t=0;const o=[...n];for(let s=0;s<o.length;s++){const i=o[s].toLowerCase(),a=this.visemes[i];if(a)if(e.visemes.length&&e.visemes[e.visemes.length-1]===a){const c=.7*(this.durations[i]||1);e.durations[e.durations.length-1]+=c,t+=c}else{const c=this.durations[i]||1;e.visemes.push(a),e.times.push(t),e.durations.push(c),t+=c}else t+=this.pauses[o[s]]||0}return e}}const Pt=Object.freeze(Object.defineProperty({__proto__:null,LipsyncLt:Et},Symbol.toStringTag,{value:"Module"})),Bt=new URL("data:text/javascript;base64,Y2xhc3MgUGxheWJhY2tXb3JrbGV0IGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHsKICBzdGF0aWMgRlNNID0gewogICAgSURMRTogMCwKICAgIFBMQVlJTkc6IDEsCiAgfTsKCiAgY29uc3RydWN0b3Iob3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMucG9ydC5vbm1lc3NhZ2UgPSB0aGlzLmhhbmRsZU1lc3NhZ2UuYmluZCh0aGlzKTsKCiAgICB0aGlzLl9zYW1wbGVSYXRlID0gb3B0aW9ucz8ucHJvY2Vzc29yT3B0aW9ucz8uc2FtcGxlUmF0ZSB8fCBzYW1wbGVSYXRlOwogICAgdGhpcy5fc2NhbGUgPSAxIC8gMzI3Njg7IC8vIFBDTTE2IC0+IGZsb2F0CgogICAgLy8gU2lsZW5jZSBkZXRlY3Rpb24gdGhyZXNob2xkICgxIHNlY29uZCkgYXMgYSBmYWxsYmFjayBzYWZldHkgbmV0CiAgICBjb25zdCBzaWxlbmNlRHVyYXRpb25TZWNvbmRzID0gMS4wOwogICAgdGhpcy5fc2lsZW5jZVRocmVzaG9sZEJsb2NrcyA9IE1hdGguY2VpbCgodGhpcy5fc2FtcGxlUmF0ZSAqIHNpbGVuY2VEdXJhdGlvblNlY29uZHMpIC8gMTI4KTsKCiAgICAvLyBNZXRyaWNzIGNvbmZpZ3VyYXRpb24gdmlhIG9wdGlvbnMKICAgIGNvbnN0IG1ldHJpY3NDZmcgPSBvcHRpb25zPy5wcm9jZXNzb3JPcHRpb25zPy5tZXRyaWNzIHx8IHt9OwogICAgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSBtZXRyaWNzQ2ZnLmVuYWJsZWQgIT09IGZhbHNlOwogICAgY29uc3QgaW50ZXJ2YWxIeiA9ICh0eXBlb2YgbWV0cmljc0NmZy5pbnRlcnZhbEh6ID09PSAibnVtYmVyIiAmJiBtZXRyaWNzQ2ZnLmludGVydmFsSHogPiAwKQogICAgICA/IG1ldHJpY3NDZmcuaW50ZXJ2YWxIeiA6IDI7CiAgICAvLyBNZXRyaWNzIHN0YXRlIChsb3ctb3ZlcmhlYWQpCiAgICB0aGlzLl9mcmFtZXNQcm9jZXNzZWQgPSAwOwogICAgdGhpcy5fdW5kZXJydW5CbG9ja3MgPSAwOwogICAgdGhpcy5fbWF4UXVldWVTYW1wbGVzID0gMDsKICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSAwOwogICAgLy8gQ29udmVydCB0byBmcmFtZXMgYmV0d2VlbiByZXBvcnRzCiAgICB0aGlzLl9tZXRyaWNzSW50ZXJ2YWxGcmFtZXMgPSBNYXRoLm1heCgxMjgsIE1hdGgucm91bmQodGhpcy5fc2FtcGxlUmF0ZSAvIGludGVydmFsSHopKTsKCiAgICB0aGlzLnJlc2V0KCk7CiAgfQoKICAvKioKICAgKiBSZXNldHMgdGhlIHdvcmtsZXQgdG8gaXRzIGluaXRpYWwgSURMRSBzdGF0ZS4KICAgKi8KICByZXNldCgpIHsKICAgIHRoaXMuX2J1ZmZlclF1ZXVlID0gW107CiAgICB0aGlzLl9jdXJyZW50Q2h1bmsgPSBudWxsOwogICAgdGhpcy5fY3VycmVudENodW5rT2Zmc2V0ID0gMDsKICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFOwoKICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IGZhbHNlOwogICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsKICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IGZhbHNlOwogICAgLy8gUmVzZXQgbWF4IHF1ZXVlIHRyYWNrZXIgb25seSB3aGVuIGdvaW5nIGlkbGUKICAgIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IDA7CiAgfQoKICBoYW5kbGVNZXNzYWdlKGV2ZW50KSB7CiAgICBjb25zdCB7IHR5cGUsIGRhdGEgfSA9IGV2ZW50LmRhdGE7CgogICAgLy8gSU5URVJSVVBUOiBUaGUgbWFpbiB0aHJlYWQgd2FudHMgdG8gc3RvcCBpbW1lZGlhdGVseS4KICAgIGlmICh0eXBlID09PSAic3RvcCIpIHsKICAgICAgdGhpcy5yZXNldCgpOwogICAgICAvLyBTZW5kIGZpbmFsIG1ldHJpY3Mgc2hvd2luZyBjbGVhcmVkIHN0YXRlCiAgICAgIGlmICh0aGlzLl9tZXRyaWNzRW5hYmxlZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAibWV0cmljcyIsCiAgICAgICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgICBzdGF0ZTogUGxheWJhY2tXb3JrbGV0LkZTTS5JRExFLAogICAgICAgICAgICAgIHF1ZXVlZFNhbXBsZXM6IDAsCiAgICAgICAgICAgICAgcXVldWVkTXM6IDAsCiAgICAgICAgICAgICAgbWF4UXVldWVkTXM6IE1hdGgucm91bmQoKHRoaXMuX21heFF1ZXVlU2FtcGxlcyAvIHRoaXMuX3NhbXBsZVJhdGUpICogMTAwMCksCiAgICAgICAgICAgICAgdW5kZXJydW5CbG9ja3M6IHRoaXMuX3VuZGVycnVuQmxvY2tzLAogICAgICAgICAgICAgIGZyYW1lc1Byb2Nlc3NlZDogdGhpcy5fZnJhbWVzUHJvY2Vzc2VkCiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgIH0gY2F0Y2ggKF8pIHsgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBNYWluIHRocmVhZCBoYXMgc2lnbmFsZWQgdGhhdCBubyBtb3JlIGF1ZGlvIGNodW5rcyB3aWxsIGJlIHNlbnQgZm9yIHRoaXMgdXR0ZXJhbmNlLgogICAgaWYgKHR5cGUgPT09ICJuby1tb3JlLWRhdGEiKSB7CiAgICAgIHRoaXMuX25vTW9yZURhdGFSZWNlaXZlZCA9IHRydWU7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBVcGRhdGUgbWV0cmljcyBjb25maWd1cmF0aW9uIGF0IHJ1bnRpbWUKICAgIGlmICh0eXBlID09PSAiY29uZmlnLW1ldHJpY3MiICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICJvYmplY3QiKSB7CiAgICAgIGlmICgiZW5hYmxlZCIgaW4gZGF0YSkgdGhpcy5fbWV0cmljc0VuYWJsZWQgPSAhIWRhdGEuZW5hYmxlZDsKICAgICAgaWYgKHR5cGVvZiBkYXRhLmludGVydmFsSHogPT09ICJudW1iZXIiICYmIGRhdGEuaW50ZXJ2YWxIeiA+IDApIHsKICAgICAgICBjb25zdCBpbnRlcnZhbEh6ID0gZGF0YS5pbnRlcnZhbEh6OwogICAgICAgIHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcyA9IE1hdGgubWF4KDEyOCwgTWF0aC5yb3VuZCh0aGlzLl9zYW1wbGVSYXRlIC8gaW50ZXJ2YWxIeikpOwogICAgICB9CiAgICAgIC8vIFJlc2V0IHBhY2luZyBzbyB0aGUgbmV4dCByZXBvcnQgYWxpZ25zIHdpdGggbmV3IGludGVydmFsCiAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBOZXcgYXVkaW8gZGF0YSBoYXMgYXJyaXZlZC4KICAgIGlmICh0eXBlID09PSAiYXVkaW9EYXRhIiAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5fbm9Nb3JlRGF0YVJlY2VpdmVkID0gZmFsc2U7CiAgICAgIC8vIElmIHdlIHdlcmUgaWRsZSwgdGhpcyBuZXcgZGF0YSBraWNrcyBvZmYgdGhlIHBsYXliYWNrLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uSURMRSkgewogICAgICAgIHRoaXMuX3N0YXRlID0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HOwogICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7IHR5cGU6ICJwbGF5YmFjay1zdGFydGVkIiB9KTsKICAgICAgfQoKICAgICAgLy8gV2Ugb25seSBxdWV1ZSBkYXRhIGlmIHdlIGFyZSBpbiB0aGUgUExBWUlORyBzdGF0ZS4gVGhpcyBwcmV2ZW50cwogICAgICAvLyBkYXRhIGZyb20gYSBwcmV2aW91cywgaW50ZXJydXB0ZWQgc3RyZWFtIGZyb20gbGluZ2VyaW5nLgogICAgICBpZiAodGhpcy5fc3RhdGUgPT09IFBsYXliYWNrV29ya2xldC5GU00uUExBWUlORykgewogICAgICAgIC8vIFN0b3JlIGFzIEludDE2QXJyYXkgdmlldyB0byBhdm9pZCBjb25zdHJ1Y3RpbmcgaXQgaW4gcHJvY2VzcygpCiAgICAgICAgdGhpcy5fYnVmZmVyUXVldWUucHVzaChuZXcgSW50MTZBcnJheShkYXRhKSk7CiAgICAgICAgdGhpcy5fc2lsZW5jZUZyYW1lc0NvdW50ID0gMDsgLy8gUmVzZXQgc2lsZW5jZSBjb3VudGVyIG9uIG5ldyBkYXRhCiAgICAgIH0KICAgIH0KICB9CgogIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICBjb25zdCBvdXRwdXRDaGFubmVsID0gb3V0cHV0c1swXT8uWzBdOwogICAgaWYgKCFvdXRwdXRDaGFubmVsKSB7CiAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIGFsaXZlIGV2ZW4gaWYgb3V0cHV0IGlzIHRlbXBvcmFyaWx5IGRpc2Nvbm5lY3RlZAogICAgfQoKICAgIC8vIElmIHdlIGFyZSBub3QgcGxheWluZywganVzdCBvdXRwdXQgc2lsZW5jZSBhbmQgd2FpdC4KICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gUGxheWJhY2tXb3JrbGV0LkZTTS5QTEFZSU5HKSB7CiAgICAgIG91dHB1dENoYW5uZWwuZmlsbCgwKTsKICAgICAgcmV0dXJuIHRydWU7IC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSB0byBrZWVwIHRoZSBwcm9jZXNzb3IgYWxpdmUKICAgIH0KCiAgICAvLyBDb3JlIFBMQVlJTkcgTG9naWMKICAgIGNvbnN0IGJsb2NrU2l6ZSA9IG91dHB1dENoYW5uZWwubGVuZ3RoOwogICAgbGV0IHNhbXBsZXNDb3BpZWQgPSAwOwoKICAgIHdoaWxlIChzYW1wbGVzQ29waWVkIDwgYmxvY2tTaXplKSB7CiAgICAgIGlmICghdGhpcy5fY3VycmVudENodW5rIHx8IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCA+PSB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoKSB7CiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aCA+IDApIHsKICAgICAgICAgIHRoaXMuX2N1cnJlbnRDaHVuayA9IHRoaXMuX2J1ZmZlclF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBCdWZmZXIgaXMgZW1wdHkuIENoZWNrIGZvciBlbmQgY29uZGl0aW9ucy4KICAgICAgICAgIGNvbnN0IGlzVGltZWRPdXQgPSB0aGlzLl9zaWxlbmNlRnJhbWVzQ291bnQgPiB0aGlzLl9zaWxlbmNlVGhyZXNob2xkQmxvY2tzOwoKICAgICAgICAgIGlmICh0aGlzLl9ub01vcmVEYXRhUmVjZWl2ZWQgfHwgaXNUaW1lZE91dCkgewogICAgICAgICAgICAvLyBFTkQgT0YgUExBWUJBQ0s6IEVpdGhlciBleHBsaWNpdGx5IHNpZ25hbGVkIG9yIHRpbWVkIG91dC4KICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNTZW50RW5kZWQpIHsKICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAicGxheWJhY2stZW5kZWQiIH0pOwogICAgICAgICAgICAgIHRoaXMuX2hhc1NlbnRFbmRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2VuZCBmaW5hbCBtZXRyaWNzIHNob3dpbmcgY2xlYXJlZCBzdGF0ZQogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHsKICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHsKICAgICAgICAgICAgICAgICAgdHlwZTogIm1ldHJpY3MiLAogICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU6IFBsYXliYWNrV29ya2xldC5GU00uSURMRSwKICAgICAgICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzOiAwLAogICAgICAgICAgICAgICAgICAgIHF1ZXVlZE1zOiAwLAogICAgICAgICAgICAgICAgICAgIG1heFF1ZXVlZE1zOiBNYXRoLnJvdW5kKCh0aGlzLl9tYXhRdWV1ZVNhbXBsZXMgLyB0aGlzLl9zYW1wbGVSYXRlKSAqIDEwMDApLAogICAgICAgICAgICAgICAgICAgIHVuZGVycnVuQmxvY2tzOiB0aGlzLl91bmRlcnJ1bkJsb2NrcywKICAgICAgICAgICAgICAgICAgICBmcmFtZXNQcm9jZXNzZWQ6IHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZAogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9IGNhdGNoIChfKSB7IH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnJlc2V0KCk7IC8vIFJlc2V0IHRvIElETEUgc3RhdGUgZm9yIHJldXNlCiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEJVRkZFUiBVTkRFUlJVTiAoTEFHKTogUGxheSBzaWxlbmNlIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEuCiAgICAgICAgICAgIHRoaXMuX3NpbGVuY2VGcmFtZXNDb3VudCsrOwogICAgICAgICAgICBpZiAodGhpcy5fbWV0cmljc0VuYWJsZWQpIHRoaXMuX3VuZGVycnVuQmxvY2tzKys7CiAgICAgICAgICAgIGJyZWFrOyAvLyBFeGl0IHdoaWxlIGxvb3AKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIElmIHdlIGhhdmUgYSBjaHVuayAoY291bGQgYmUgYSBuZXcgb25lIGZyb20gdGhlIGxvZ2ljIGFib3ZlKSwgcHJvY2VzcyBpdC4KICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDaHVuaykgewogICAgICAgIGNvbnN0IHNhbXBsZXNUb0NvcHkgPSBNYXRoLm1pbigKICAgICAgICAgIGJsb2NrU2l6ZSAtIHNhbXBsZXNDb3BpZWQsCiAgICAgICAgICB0aGlzLl9jdXJyZW50Q2h1bmsubGVuZ3RoIC0gdGhpcy5fY3VycmVudENodW5rT2Zmc2V0CiAgICAgICAgKTsKICAgICAgICAvLyBEaXJlY3RseSB3cml0ZSB0byBvdXRwdXRDaGFubmVsIHRvIGF2b2lkIGV4dHJhIGNvcHkKICAgICAgICBjb25zdCBzcmMgPSB0aGlzLl9jdXJyZW50Q2h1bms7CiAgICAgICAgY29uc3QgYmFzZVNyYyA9IHRoaXMuX2N1cnJlbnRDaHVua09mZnNldDsKICAgICAgICBjb25zdCBiYXNlRHN0ID0gc2FtcGxlc0NvcGllZDsKICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWxlOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2FtcGxlc1RvQ29weTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXRDaGFubmVsW2Jhc2VEc3QgKyBpXSA9IHNyY1tiYXNlU3JjICsgaV0gKiBzY2FsZTsKICAgICAgICB9CgogICAgICAgIHRoaXMuX2N1cnJlbnRDaHVua09mZnNldCArPSBzYW1wbGVzVG9Db3B5OwogICAgICAgIHNhbXBsZXNDb3BpZWQgKz0gc2FtcGxlc1RvQ29weTsKICAgICAgfQogICAgfQoKICAgIC8vIFplcm8tZmlsbCB0aGUgcmVtYWluZGVyLCBpZiBhbnksIG9uY2UgcGVyIGJsb2NrCiAgICBpZiAoc2FtcGxlc0NvcGllZCA8IGJsb2NrU2l6ZSkgewogICAgICBvdXRwdXRDaGFubmVsLmZpbGwoMCwgc2FtcGxlc0NvcGllZCk7CiAgICB9CgogICAgLy8gVXBkYXRlIG1ldHJpY3MgKG9wdGlvbmFsKQogICAgaWYgKHRoaXMuX21ldHJpY3NFbmFibGVkKSB7CiAgICAgIHRoaXMuX2ZyYW1lc1Byb2Nlc3NlZCArPSBibG9ja1NpemU7CgogICAgICAvLyBUcmFjayBxdWV1ZSBkZXB0aCBpbiBzYW1wbGVzIChhcHByb3hpbWF0ZSkKICAgICAgbGV0IHF1ZXVlZFNhbXBsZXMgPSAwOwogICAgICBpZiAodGhpcy5fY3VycmVudENodW5rKSBxdWV1ZWRTYW1wbGVzICs9IE1hdGgubWF4KDAsIHRoaXMuX2N1cnJlbnRDaHVuay5sZW5ndGggLSB0aGlzLl9jdXJyZW50Q2h1bmtPZmZzZXQpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2J1ZmZlclF1ZXVlLmxlbmd0aDsgaSsrKSBxdWV1ZWRTYW1wbGVzICs9IHRoaXMuX2J1ZmZlclF1ZXVlW2ldLmxlbmd0aDsKICAgICAgaWYgKHF1ZXVlZFNhbXBsZXMgPiB0aGlzLl9tYXhRdWV1ZVNhbXBsZXMpIHRoaXMuX21heFF1ZXVlU2FtcGxlcyA9IHF1ZXVlZFNhbXBsZXM7CgogICAgICAvLyBQZXJpb2RpY2FsbHkgc2VuZCBtZXRyaWNzIHRvIG1haW4gdGhyZWFkCiAgICAgIGlmICh0aGlzLl9mcmFtZXNQcm9jZXNzZWQgLSB0aGlzLl9sYXN0TWV0cmljc1NlbnRBdEZyYW1lID49IHRoaXMuX21ldHJpY3NJbnRlcnZhbEZyYW1lcykgewogICAgICAgIHRoaXMuX2xhc3RNZXRyaWNzU2VudEF0RnJhbWUgPSB0aGlzLl9mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7CiAgICAgICAgICAgIHR5cGU6ICJtZXRyaWNzIiwKICAgICAgICAgICAgZGF0YTogewogICAgICAgICAgICAgIHN0YXRlOiB0aGlzLl9zdGF0ZSwKICAgICAgICAgICAgICBxdWV1ZWRTYW1wbGVzLAogICAgICAgICAgICAgIHF1ZXVlZE1zOiBNYXRoLnJvdW5kKChxdWV1ZWRTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICBtYXhRdWV1ZWRNczogTWF0aC5yb3VuZCgodGhpcy5fbWF4UXVldWVTYW1wbGVzIC8gdGhpcy5fc2FtcGxlUmF0ZSkgKiAxMDAwKSwKICAgICAgICAgICAgICB1bmRlcnJ1bkJsb2NrczogdGhpcy5fdW5kZXJydW5CbG9ja3MsCiAgICAgICAgICAgICAgZnJhbWVzUHJvY2Vzc2VkOiB0aGlzLl9mcmFtZXNQcm9jZXNzZWQKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSBjYXRjaCAoXykgeyB9CiAgICAgICAgLy8gRG9uJ3QgcmVzZXQgbWF4IHRyYWNrZXIgLSBrZWVwIHNlc3Npb24gcGVhayB1bnRpbCBpZGxlCiAgICAgIH0KICAgIH0KCiAgICAvLyBBTFdBWVMgcmV0dXJuIHRydWUgdG8ga2VlcCB0aGUgcHJvY2Vzc29yIGFsaXZlIGZvciByZXVzZS4KICAgIHJldHVybiB0cnVlOwogIH0KfQoKcmVnaXN0ZXJQcm9jZXNzb3IoInBsYXliYWNrLXdvcmtsZXQiLCBQbGF5YmFja1dvcmtsZXQpOwo=",typeof document>"u"?require("url").pathToFileURL(__filename).href:Ke&&Ke.tagName.toUpperCase()==="SCRIPT"&&Ke.src||new URL("index.cjs",document.baseURI).href),ot={en:wt,de:zt,fr:Tt,fi:Mt,lt:Pt},ue=new A.Quaternion,oe=new A.Euler,Pe=new A.Vector3,Ne=new A.Vector3,st=new A.Box3;new A.Matrix4;new A.Matrix4;new A.Vector3;new A.Vector3(0,0,1);const Ot=new A.Vector3(1,0,0);new A.Vector3(0,1,0);new A.Vector3(0,0,1);class $e{constructor(n,e=null){this.nodeAvatar=n,this.opt={jwtGet:null,ttsEndpoint:"",ttsApikey:null,ttsTrimStart:0,ttsTrimEnd:400,ttsLang:"fi-FI",ttsVoice:"fi-FI-Standard-A",ttsRate:1,ttsPitch:0,ttsVolume:.3,mixerGainSpeech:1.2,mixerGainBackground:null,lipsyncLang:"fi",lipsyncModules:["fi","en","lt"],pcmSampleRate:22050,modelRoot:"Armature",modelPixelRatio:1,modelFPS:30,modelMovementFactor:1,cameraView:"full",dracoEnabled:!1,dracoDecoderPath:"https://www.gstatic.com/draco/v1/decoders/",cameraDistance:0,cameraX:0,cameraY:0,cameraRotateX:0,cameraRotateY:0,cameraRotateEnable:!0,cameraPanEnable:!1,cameraZoomEnable:!1,lightAmbientColor:16777215,lightAmbientIntensity:1.25,lightDirectColor:8947882,lightDirectIntensity:12,lightDirectPhi:1,lightDirectTheta:2,lightSpotIntensity:0,lightSpotColor:3377407,lightSpotPhi:.1,lightSpotTheta:4,lightSpotDispersion:1,avatarMood:"neutral",avatarMute:!1,avatarIdleEyeContact:.6,avatarIdleHeadMove:.5,avatarSpeakingEyeContact:.8,avatarSpeakingHeadMove:.5,avatarIgnoreCamera:!1,listeningSilenceThresholdLevel:40,listeningSilenceThresholdMs:2e3,listeningSilenceDurationMax:1e4,listeningActiveThresholdLevel:75,listeningActiveThresholdMs:300,listeningActiveDurationMax:24e4,update:null,avatarOnly:!1,avatarOnlyScene:null,avatarOnlyCamera:null,statsNode:null,statsStyle:null},Object.assign(this.opt,e||{}),this.opt.statsNode&&(this.stats=new bt,this.opt.statsStyle&&(this.stats.dom.style.cssText=this.opt.statsStyle),this.opt.statsNode.appendChild(this.stats.dom)),this.poseTemplates={side:{standing:!0,props:{"Hips.position":{x:0,y:1,z:0},"Hips.rotation":{x:-.003,y:-.017,z:.1},"Spine.rotation":{x:-.103,y:-.002,z:-.063},"Spine1.rotation":{x:.042,y:-.02,z:-.069},"Spine2.rotation":{x:.131,y:-.012,z:-.065},"Neck.rotation":{x:.027,y:.006,z:0},"Head.rotation":{x:.077,y:-.065,z:0},"LeftShoulder.rotation":{x:1.599,y:.084,z:-1.77},"LeftArm.rotation":{x:1.364,y:.052,z:-.044},"LeftForeArm.rotation":{x:.002,y:-.007,z:.331},"LeftHand.rotation":{x:.104,y:-.067,z:-.174},"LeftHandThumb1.rotation":{x:.231,y:.258,z:.355},"LeftHandThumb2.rotation":{x:-.106,y:-.339,z:-.454},"LeftHandThumb3.rotation":{x:-.02,y:-.142,z:-.004},"LeftHandIndex1.rotation":{x:.148,y:.032,z:-.069},"LeftHandIndex2.rotation":{x:.326,y:-.049,z:-.029},"LeftHandIndex3.rotation":{x:.247,y:-.053,z:-.073},"LeftHandMiddle1.rotation":{x:.238,y:-.057,z:-.089},"LeftHandMiddle2.rotation":{x:.469,y:-.036,z:-.081},"LeftHandMiddle3.rotation":{x:.206,y:-.015,z:-.017},"LeftHandRing1.rotation":{x:.187,y:-.118,z:-.157},"LeftHandRing2.rotation":{x:.579,y:.02,z:-.097},"LeftHandRing3.rotation":{x:.272,y:.021,z:-.063},"LeftHandPinky1.rotation":{x:.405,y:-.182,z:-.138},"LeftHandPinky2.rotation":{x:.613,y:.128,z:-.144},"LeftHandPinky3.rotation":{x:.268,y:.094,z:-.081},"RightShoulder.rotation":{x:1.541,y:.192,z:1.775},"RightArm.rotation":{x:1.273,y:-.352,z:-.067},"RightForeArm.rotation":{x:-.011,y:-.031,z:-.357},"RightHand.rotation":{x:-.008,y:.312,z:-.028},"RightHandThumb1.rotation":{x:.23,y:-.258,z:-.355},"RightHandThumb2.rotation":{x:-.107,y:.339,z:.454},"RightHandThumb3.rotation":{x:-.02,y:.142,z:.004},"RightHandIndex1.rotation":{x:.148,y:-.031,z:.069},"RightHandIndex2.rotation":{x:.326,y:.049,z:.029},"RightHandIndex3.rotation":{x:.247,y:.053,z:.073},"RightHandMiddle1.rotation":{x:.237,y:.057,z:.089},"RightHandMiddle2.rotation":{x:.469,y:.036,z:.081},"RightHandMiddle3.rotation":{x:.206,y:.015,z:.017},"RightHandRing1.rotation":{x:.204,y:.086,z:.135},"RightHandRing2.rotation":{x:.579,y:-.02,z:.098},"RightHandRing3.rotation":{x:.272,y:-.021,z:.063},"RightHandPinky1.rotation":{x:.404,y:.182,z:.137},"RightHandPinky2.rotation":{x:.613,y:-.128,z:.144},"RightHandPinky3.rotation":{x:.268,y:-.094,z:.081},"LeftUpLeg.rotation":{x:.096,y:.209,z:2.983},"LeftLeg.rotation":{x:-.053,y:.042,z:-.017},"LeftFoot.rotation":{x:1.091,y:.15,z:.026},"LeftToeBase.rotation":{x:.469,y:-.07,z:-.015},"RightUpLeg.rotation":{x:-.307,y:-.219,z:2.912},"RightLeg.rotation":{x:-.359,y:.164,z:.015},"RightFoot.rotation":{x:1.035,y:.11,z:.005},"RightToeBase.rotation":{x:.467,y:.07,z:.015}}},hip:{standing:!0,props:{"Hips.position":{x:0,y:1,z:0},"Hips.rotation":{x:-.036,y:.09,z:.135},"Spine.rotation":{x:.076,y:-.035,z:.01},"Spine1.rotation":{x:-.096,y:.013,z:-.094},"Spine2.rotation":{x:-.014,y:.002,z:-.097},"Neck.rotation":{x:.034,y:-.051,z:-.075},"Head.rotation":{x:.298,y:-.1,z:.154},"LeftShoulder.rotation":{x:1.694,y:.011,z:-1.68},"LeftArm.rotation":{x:1.343,y:.177,z:-.153},"LeftForeArm.rotation":{x:-.049,y:.134,z:.351},"LeftHand.rotation":{x:.057,y:-.189,z:-.026},"LeftHandThumb1.rotation":{x:.368,y:-.066,z:.438},"LeftHandThumb2.rotation":{x:-.156,y:.029,z:-.369},"LeftHandThumb3.rotation":{x:.034,y:-.009,z:.016},"LeftHandIndex1.rotation":{x:.157,y:-.002,z:-.171},"LeftHandIndex2.rotation":{x:.099,y:0,z:0},"LeftHandIndex3.rotation":{x:.1,y:0,z:0},"LeftHandMiddle1.rotation":{x:.222,y:-.019,z:-.16},"LeftHandMiddle2.rotation":{x:.142,y:0,z:0},"LeftHandMiddle3.rotation":{x:.141,y:0,z:0},"LeftHandRing1.rotation":{x:.333,y:-.039,z:-.174},"LeftHandRing2.rotation":{x:.214,y:0,z:0},"LeftHandRing3.rotation":{x:.213,y:0,z:0},"LeftHandPinky1.rotation":{x:.483,y:-.069,z:-.189},"LeftHandPinky2.rotation":{x:.312,y:0,z:0},"LeftHandPinky3.rotation":{x:.309,y:0,z:0},"RightShoulder.rotation":{x:1.597,y:.012,z:1.816},"RightArm.rotation":{x:.618,y:-1.274,z:-.266},"RightForeArm.rotation":{x:-.395,y:-.097,z:-1.342},"RightHand.rotation":{x:-.816,y:-.057,z:-.976},"RightHandThumb1.rotation":{x:.42,y:.23,z:-1.172},"RightHandThumb2.rotation":{x:-.027,y:.361,z:.122},"RightHandThumb3.rotation":{x:.076,y:.125,z:-.371},"RightHandIndex1.rotation":{x:-.158,y:-.045,z:.033},"RightHandIndex2.rotation":{x:.391,y:.051,z:.025},"RightHandIndex3.rotation":{x:.317,y:.058,z:.07},"RightHandMiddle1.rotation":{x:.486,y:.066,z:.014},"RightHandMiddle2.rotation":{x:.718,y:.055,z:.07},"RightHandMiddle3.rotation":{x:.453,y:.019,z:.013},"RightHandRing1.rotation":{x:.591,y:.241,z:.11},"RightHandRing2.rotation":{x:1.014,y:.023,z:.097},"RightHandRing3.rotation":{x:.708,y:.008,z:.066},"RightHandPinky1.rotation":{x:1.02,y:.305,z:.051},"RightHandPinky2.rotation":{x:1.187,y:-.028,z:.191},"RightHandPinky3.rotation":{x:.872,y:-.031,z:.121},"LeftUpLeg.rotation":{x:-.095,y:-.058,z:-3.338},"LeftLeg.rotation":{x:-.366,y:.287,z:-.021},"LeftFoot.rotation":{x:1.131,y:.21,z:.176},"LeftToeBase.rotation":{x:.739,y:-.068,z:-.001},"RightUpLeg.rotation":{x:-.502,y:.362,z:3.153},"RightLeg.rotation":{x:-1.002,y:.109,z:.008},"RightFoot.rotation":{x:.626,y:-.097,z:-.194},"RightToeBase.rotation":{x:1.33,y:.288,z:-.078}}},turn:{standing:!0,props:{"Hips.position":{x:0,y:1,z:0},"Hips.rotation":{x:-.07,y:-.604,z:-.004},"Spine.rotation":{x:-.007,y:.003,z:.071},"Spine1.rotation":{x:-.053,y:.024,z:-.06},"Spine2.rotation":{x:.074,y:.013,z:-.068},"Neck.rotation":{x:.03,y:.186,z:-.077},"Head.rotation":{x:.045,y:.243,z:-.086},"LeftShoulder.rotation":{x:1.717,y:-.085,z:-1.761},"LeftArm.rotation":{x:1.314,y:.07,z:-.057},"LeftForeArm.rotation":{x:-.151,y:.714,z:.302},"LeftHand.rotation":{x:-.069,y:.003,z:-.118},"LeftHandThumb1.rotation":{x:.23,y:.258,z:.354},"LeftHandThumb2.rotation":{x:-.107,y:-.338,z:-.455},"LeftHandThumb3.rotation":{x:-.015,y:-.142,z:.002},"LeftHandIndex1.rotation":{x:.145,y:.032,z:-.069},"LeftHandIndex2.rotation":{x:.323,y:-.049,z:-.028},"LeftHandIndex3.rotation":{x:.249,y:-.053,z:-.074},"LeftHandMiddle1.rotation":{x:.235,y:-.057,z:-.088},"LeftHandMiddle2.rotation":{x:.468,y:-.036,z:-.081},"LeftHandMiddle3.rotation":{x:.203,y:-.015,z:-.017},"LeftHandRing1.rotation":{x:.185,y:-.118,z:-.157},"LeftHandRing2.rotation":{x:.578,y:.02,z:-.097},"LeftHandRing3.rotation":{x:.27,y:.021,z:-.063},"LeftHandPinky1.rotation":{x:.404,y:-.182,z:-.138},"LeftHandPinky2.rotation":{x:.612,y:.128,z:-.144},"LeftHandPinky3.rotation":{x:.267,y:.094,z:-.081},"RightShoulder.rotation":{x:1.605,y:.17,z:1.625},"RightArm.rotation":{x:1.574,y:-.655,z:.388},"RightForeArm.rotation":{x:-.36,y:-.849,z:-.465},"RightHand.rotation":{x:.114,y:.416,z:-.069},"RightHandThumb1.rotation":{x:.486,y:.009,z:-.492},"RightHandThumb2.rotation":{x:-.073,y:-.01,z:.284},"RightHandThumb3.rotation":{x:-.054,y:-.006,z:.209},"RightHandIndex1.rotation":{x:.245,y:-.014,z:.052},"RightHandIndex2.rotation":{x:.155,y:0,z:0},"RightHandIndex3.rotation":{x:.153,y:0,z:0},"RightHandMiddle1.rotation":{x:.238,y:.004,z:.028},"RightHandMiddle2.rotation":{x:.15,y:0,z:0},"RightHandMiddle3.rotation":{x:.149,y:0,z:0},"RightHandRing1.rotation":{x:.267,y:.012,z:.007},"RightHandRing2.rotation":{x:.169,y:0,z:0},"RightHandRing3.rotation":{x:.167,y:0,z:0},"RightHandPinky1.rotation":{x:.304,y:.018,z:-.021},"RightHandPinky2.rotation":{x:.192,y:0,z:0},"RightHandPinky3.rotation":{x:.19,y:0,z:0},"LeftUpLeg.rotation":{x:-.001,y:-.058,z:-3.238},"LeftLeg.rotation":{x:-.29,y:.058,z:-.021},"LeftFoot.rotation":{x:1.288,y:.168,z:.183},"LeftToeBase.rotation":{x:.363,y:-.09,z:-.01},"RightUpLeg.rotation":{x:-.1,y:.36,z:3.062},"RightLeg.rotation":{x:-.67,y:-.304,z:.043},"RightFoot.rotation":{x:1.195,y:-.159,z:-.294},"RightToeBase.rotation":{x:.737,y:.164,z:-.002}}},bend:{bend:!0,standing:!0,props:{"Hips.position":{x:-.007,y:.943,z:-.001},"Hips.rotation":{x:1.488,y:-.633,z:1.435},"Spine.rotation":{x:-.126,y:.007,z:-.057},"Spine1.rotation":{x:-.134,y:.009,z:.01},"Spine2.rotation":{x:-.019,y:0,z:-.002},"Neck.rotation":{x:-.159,y:.572,z:-.108},"Head.rotation":{x:-.064,y:.716,z:-.257},"RightShoulder.rotation":{x:1.625,y:-.043,z:1.382},"RightArm.rotation":{x:.746,y:-.96,z:-1.009},"RightForeArm.rotation":{x:-.199,y:-.528,z:-.38},"RightHand.rotation":{x:-.261,y:-.043,z:-.027},"RightHandThumb1.rotation":{x:.172,y:-.138,z:-.445},"RightHandThumb2.rotation":{x:-.158,y:.327,z:.545},"RightHandThumb3.rotation":{x:-.062,y:.138,z:.152},"RightHandIndex1.rotation":{x:.328,y:-.005,z:.132},"RightHandIndex2.rotation":{x:.303,y:.049,z:.028},"RightHandIndex3.rotation":{x:.241,y:.046,z:.077},"RightHandMiddle1.rotation":{x:.309,y:.074,z:.089},"RightHandMiddle2.rotation":{x:.392,y:.036,z:.081},"RightHandMiddle3.rotation":{x:.199,y:.014,z:.019},"RightHandRing1.rotation":{x:.239,y:.143,z:.091},"RightHandRing2.rotation":{x:.275,y:-.02,z:.097},"RightHandRing3.rotation":{x:.248,y:-.023,z:.061},"RightHandPinky1.rotation":{x:.211,y:.154,z:.029},"RightHandPinky2.rotation":{x:.348,y:-.128,z:.144},"RightHandPinky3.rotation":{x:.21,y:-.091,z:.065},"LeftShoulder.rotation":{x:1.626,y:-.027,z:-1.367},"LeftArm.rotation":{x:1.048,y:.737,z:.712},"LeftForeArm.rotation":{x:-.508,y:.879,z:.625},"LeftHand.rotation":{x:.06,y:-.243,z:-.079},"LeftHandThumb1.rotation":{x:.187,y:-.072,z:.346},"LeftHandThumb2.rotation":{x:-.066,y:.008,z:-.256},"LeftHandThumb3.rotation":{x:-.085,y:.014,z:-.334},"LeftHandIndex1.rotation":{x:-.1,y:.016,z:-.058},"LeftHandIndex2.rotation":{x:.334,y:0,z:0},"LeftHandIndex3.rotation":{x:.281,y:0,z:0},"LeftHandMiddle1.rotation":{x:-.056,y:0,z:0},"LeftHandMiddle2.rotation":{x:.258,y:0,z:0},"LeftHandMiddle3.rotation":{x:.26,y:0,z:0},"LeftHandRing1.rotation":{x:-.067,y:-.002,z:.008},"LeftHandRing2.rotation":{x:.259,y:0,z:0},"LeftHandRing3.rotation":{x:.276,y:0,z:0},"LeftHandPinky1.rotation":{x:-.128,y:-.007,z:.042},"LeftHandPinky2.rotation":{x:.227,y:0,z:0},"LeftHandPinky3.rotation":{x:.145,y:0,z:0},"RightUpLeg.rotation":{x:-1.507,y:.2,z:-3.043},"RightLeg.rotation":{x:-.689,y:-.124,z:.017},"RightFoot.rotation":{x:.909,y:.008,z:-.093},"RightToeBase.rotation":{x:.842,y:.075,z:-.008},"LeftUpLeg.rotation":{x:-1.449,y:-.2,z:3.018},"LeftLeg.rotation":{x:-.74,y:-.115,z:-.008},"LeftFoot.rotation":{x:1.048,y:-.058,z:.117},"LeftToeBase.rotation":{x:.807,y:-.067,z:.003}}},back:{standing:!0,props:{"Hips.position":{x:0,y:1,z:0},"Hips.rotation":{x:-.732,y:-1.463,z:-.637},"Spine.rotation":{x:-.171,y:.106,z:.157},"Spine1.rotation":{x:-.044,y:.138,z:-.059},"Spine2.rotation":{x:.082,y:.133,z:-.074},"Neck.rotation":{x:.39,y:.591,z:-.248},"Head.rotation":{x:-.001,y:.596,z:-.057},"LeftShoulder.rotation":{x:1.676,y:.007,z:-1.892},"LeftArm.rotation":{x:-5.566,y:1.188,z:-.173},"LeftForeArm.rotation":{x:-.673,y:-.105,z:1.702},"LeftHand.rotation":{x:-.469,y:-.739,z:.003},"LeftHandThumb1.rotation":{x:.876,y:.274,z:.793},"LeftHandThumb2.rotation":{x:.161,y:-.23,z:-.172},"LeftHandThumb3.rotation":{x:.078,y:.027,z:.156},"LeftHandIndex1.rotation":{x:-.085,y:-.002,z:.009},"LeftHandIndex2.rotation":{x:.176,y:0,z:-.002},"LeftHandIndex3.rotation":{x:-.036,y:.001,z:-.035},"LeftHandMiddle1.rotation":{x:.015,y:.144,z:-.076},"LeftHandMiddle2.rotation":{x:.378,y:-.007,z:-.077},"LeftHandMiddle3.rotation":{x:-.141,y:-.001,z:.031},"LeftHandRing1.rotation":{x:.039,y:.02,z:-.2},"LeftHandRing2.rotation":{x:.25,y:-.002,z:-.073},"LeftHandRing3.rotation":{x:.236,y:.006,z:-.075},"LeftHandPinky1.rotation":{x:.172,y:-.033,z:-.275},"LeftHandPinky2.rotation":{x:.216,y:.043,z:-.054},"LeftHandPinky3.rotation":{x:.325,y:.078,z:-.13},"RightShoulder.rotation":{x:2.015,y:-.168,z:1.706},"RightArm.rotation":{x:.203,y:-1.258,z:-.782},"RightForeArm.rotation":{x:-.658,y:-.133,z:-1.401},"RightHand.rotation":{x:-1.504,y:.375,z:-.005},"RightHandThumb1.rotation":{x:.413,y:-.158,z:-1.121},"RightHandThumb2.rotation":{x:-.142,y:-.008,z:.209},"RightHandThumb3.rotation":{x:-.091,y:.021,z:.142},"RightHandIndex1.rotation":{x:-.167,y:.014,z:-.072},"RightHandIndex2.rotation":{x:.474,y:.009,z:.051},"RightHandIndex3.rotation":{x:.115,y:.006,z:.047},"RightHandMiddle1.rotation":{x:.385,y:.019,z:.144},"RightHandMiddle2.rotation":{x:.559,y:.035,z:.101},"RightHandMiddle3.rotation":{x:.229,y:0,z:.027},"RightHandRing1.rotation":{x:.48,y:.026,z:.23},"RightHandRing2.rotation":{x:.772,y:.038,z:.109},"RightHandRing3.rotation":{x:.622,y:.039,z:.106},"RightHandPinky1.rotation":{x:.767,y:.288,z:.353},"RightHandPinky2.rotation":{x:.886,y:.049,z:.122},"RightHandPinky3.rotation":{x:.662,y:.044,z:.113},"LeftUpLeg.rotation":{x:-.206,y:-.268,z:-3.343},"LeftLeg.rotation":{x:-.333,y:.757,z:-.043},"LeftFoot.rotation":{x:1.049,y:.167,z:.287},"LeftToeBase.rotation":{x:.672,y:-.069,z:-.004},"RightUpLeg.rotation":{x:.055,y:-.226,z:3.037},"RightLeg.rotation":{x:-.559,y:.39,z:-.001},"RightFoot.rotation":{x:1.2,y:.133,z:.085},"RightToeBase.rotation":{x:.92,y:.093,z:-.013}}},straight:{standing:!0,props:{"Hips.position":{x:0,y:.989,z:.001},"Hips.rotation":{x:.047,y:.007,z:-.007},"Spine.rotation":{x:-.143,y:-.007,z:.005},"Spine1.rotation":{x:-.043,y:-.014,z:.012},"Spine2.rotation":{x:.072,y:-.013,z:.013},"Neck.rotation":{x:.048,y:-.003,z:.012},"Head.rotation":{x:.05,y:-.02,z:-.017},"LeftShoulder.rotation":{x:1.62,y:-.166,z:-1.605},"LeftArm.rotation":{x:1.275,y:.544,z:-.092},"LeftForeArm.rotation":{x:0,y:0,z:.302},"LeftHand.rotation":{x:-.225,y:-.154,z:.11},"LeftHandThumb1.rotation":{x:.435,y:-.044,z:.457},"LeftHandThumb2.rotation":{x:-.028,y:.002,z:-.246},"LeftHandThumb3.rotation":{x:-.236,y:-.025,z:.113},"LeftHandIndex1.rotation":{x:.218,y:.008,z:-.081},"LeftHandIndex2.rotation":{x:.165,y:-.001,z:-.017},"LeftHandIndex3.rotation":{x:.165,y:-.001,z:-.017},"LeftHandMiddle1.rotation":{x:.235,y:-.011,z:-.065},"LeftHandMiddle2.rotation":{x:.182,y:-.002,z:-.019},"LeftHandMiddle3.rotation":{x:.182,y:-.002,z:-.019},"LeftHandRing1.rotation":{x:.316,y:-.017,z:.008},"LeftHandRing2.rotation":{x:.253,y:-.003,z:-.026},"LeftHandRing3.rotation":{x:.255,y:-.003,z:-.026},"LeftHandPinky1.rotation":{x:.336,y:-.062,z:.088},"LeftHandPinky2.rotation":{x:.276,y:-.004,z:-.028},"LeftHandPinky3.rotation":{x:.276,y:-.004,z:-.028},"RightShoulder.rotation":{x:1.615,y:.064,z:1.53},"RightArm.rotation":{x:1.313,y:-.424,z:.131},"RightForeArm.rotation":{x:0,y:0,z:-.317},"RightHand.rotation":{x:-.158,y:-.639,z:-.196},"RightHandThumb1.rotation":{x:.44,y:.048,z:-.549},"RightHandThumb2.rotation":{x:-.056,y:-.008,z:.274},"RightHandThumb3.rotation":{x:-.258,y:.031,z:-.095},"RightHandIndex1.rotation":{x:.169,y:-.011,z:.105},"RightHandIndex2.rotation":{x:.134,y:.001,z:.011},"RightHandIndex3.rotation":{x:.134,y:.001,z:.011},"RightHandMiddle1.rotation":{x:.288,y:.014,z:.092},"RightHandMiddle2.rotation":{x:.248,y:.003,z:.02},"RightHandMiddle3.rotation":{x:.249,y:.003,z:.02},"RightHandRing1.rotation":{x:.369,y:.019,z:.006},"RightHandRing2.rotation":{x:.321,y:.004,z:.026},"RightHandRing3.rotation":{x:.323,y:.004,z:.026},"RightHandPinky1.rotation":{x:.468,y:.085,z:-.03},"RightHandPinky2.rotation":{x:.427,y:.007,z:.034},"RightHandPinky3.rotation":{x:.142,y:.001,z:.012},"LeftUpLeg.rotation":{x:-.077,y:-.058,z:3.126},"LeftLeg.rotation":{x:-.252,y:.001,z:-.018},"LeftFoot.rotation":{x:1.315,y:-.064,z:.315},"LeftToeBase.rotation":{x:.577,y:-.07,z:-.009},"RightUpLeg.rotation":{x:-.083,y:-.032,z:3.124},"RightLeg.rotation":{x:-.272,y:-.003,z:.021},"RightFoot.rotation":{x:1.342,y:.076,z:-.222},"RightToeBase.rotation":{x:.44,y:.069,z:.016}}},wide:{standing:!0,props:{"Hips.position":{x:0,y:1.017,z:.016},"Hips.rotation":{x:.064,y:-.048,z:.059},"Spine.rotation":{x:-.123,y:0,z:-.018},"Spine1.rotation":{x:.014,y:.003,z:-.006},"Spine2.rotation":{x:.04,y:.003,z:-.007},"Neck.rotation":{x:.101,y:.007,z:-.035},"Head.rotation":{x:-.091,y:-.049,z:.105},"RightShoulder.rotation":{x:1.831,y:.017,z:1.731},"RightArm.rotation":{x:-1.673,y:-1.102,z:-3.132},"RightForeArm.rotation":{x:.265,y:.23,z:-.824},"RightHand.rotation":{x:-.52,y:.345,z:-.061},"RightHandThumb1.rotation":{x:.291,y:.056,z:-.428},"RightHandThumb2.rotation":{x:.025,y:.005,z:.166},"RightHandThumb3.rotation":{x:-.089,y:.009,z:.068},"RightHandIndex1.rotation":{x:.392,y:-.015,z:.11},"RightHandIndex2.rotation":{x:.391,y:.001,z:.004},"RightHandIndex3.rotation":{x:.326,y:0,z:.003},"RightHandMiddle1.rotation":{x:.285,y:.068,z:.081},"RightHandMiddle2.rotation":{x:.519,y:.004,z:.011},"RightHandMiddle3.rotation":{x:.252,y:0,z:.001},"RightHandRing1.rotation":{x:.207,y:.133,z:.146},"RightHandRing2.rotation":{x:.597,y:.004,z:.004},"RightHandRing3.rotation":{x:.292,y:.002,z:.012},"RightHandPinky1.rotation":{x:.338,y:.182,z:.136},"RightHandPinky2.rotation":{x:.533,y:.002,z:.004},"RightHandPinky3.rotation":{x:.194,y:0,z:.002},"LeftShoulder.rotation":{x:1.83,y:-.063,z:-1.808},"LeftArm.rotation":{x:-1.907,y:1.228,z:-2.959},"LeftForeArm.rotation":{x:-.159,y:.268,z:.572},"LeftHand.rotation":{x:.069,y:-.498,z:-.025},"LeftHandThumb1.rotation":{x:.738,y:.123,z:.178},"LeftHandThumb2.rotation":{x:-.26,y:.028,z:-.477},"LeftHandThumb3.rotation":{x:-.448,y:.093,z:-.661},"LeftHandIndex1.rotation":{x:1.064,y:.005,z:-.13},"LeftHandIndex2.rotation":{x:1.55,y:-.143,z:-.136},"LeftHandIndex3.rotation":{x:.722,y:-.076,z:-.127},"LeftHandMiddle1.rotation":{x:1.095,y:-.091,z:.006},"LeftHandMiddle2.rotation":{x:1.493,y:-.174,z:-.151},"LeftHandMiddle3.rotation":{x:.651,y:-.031,z:-.087},"LeftHandRing1.rotation":{x:1.083,y:-.224,z:.072},"LeftHandRing2.rotation":{x:1.145,y:-.107,z:-.195},"LeftHandRing3.rotation":{x:1.208,y:-.134,z:-.158},"LeftHandPinky1.rotation":{x:.964,y:-.383,z:.128},"LeftHandPinky2.rotation":{x:1.457,y:-.146,z:-.159},"LeftHandPinky3.rotation":{x:1.019,y:-.102,z:-.141},"RightUpLeg.rotation":{x:-.221,y:-.233,z:2.87},"RightLeg.rotation":{x:-.339,y:-.043,z:-.041},"RightFoot.rotation":{x:1.081,y:.177,z:.114},"RightToeBase.rotation":{x:.775,y:0,z:0},"LeftUpLeg.rotation":{x:-.185,y:.184,z:3.131},"LeftLeg.rotation":{x:-.408,y:.129,z:.02},"LeftFoot.rotation":{x:1.167,y:-.002,z:-.007},"LeftToeBase.rotation":{x:.723,y:0,z:0}}},oneknee:{kneeling:!0,props:{"Hips.position":{x:-.005,y:.415,z:-.017},"Hips.rotation":{x:-.25,y:.04,z:-.238},"Spine.rotation":{x:.037,y:.043,z:.047},"Spine1.rotation":{x:.317,y:.103,z:.066},"Spine2.rotation":{x:.433,y:.109,z:.054},"Neck.rotation":{x:-.156,y:-.092,z:.059},"Head.rotation":{x:-.398,y:-.032,z:.018},"RightShoulder.rotation":{x:1.546,y:.119,z:1.528},"RightArm.rotation":{x:.896,y:-.247,z:-.512},"RightForeArm.rotation":{x:.007,y:0,z:-1.622},"RightHand.rotation":{x:1.139,y:-.853,z:.874},"RightHandThumb1.rotation":{x:.176,y:.107,z:-.311},"RightHandThumb2.rotation":{x:-.047,y:-.003,z:.12},"RightHandThumb3.rotation":{x:0,y:0,z:0},"RightHandIndex1.rotation":{x:.186,y:.005,z:.125},"RightHandIndex2.rotation":{x:.454,y:.005,z:.015},"RightHandIndex3.rotation":{x:0,y:0,z:0},"RightHandMiddle1.rotation":{x:.444,y:.035,z:.127},"RightHandMiddle2.rotation":{x:.403,y:-.006,z:-.04},"RightHandMiddle3.rotation":{x:0,y:0,z:0},"RightHandRing1.rotation":{x:.543,y:.074,z:.121},"RightHandRing2.rotation":{x:.48,y:-.018,z:-.063},"RightHandRing3.rotation":{x:0,y:0,z:0},"RightHandPinky1.rotation":{x:.464,y:.086,z:.113},"RightHandPinky2.rotation":{x:.667,y:-.06,z:-.128},"RightHandPinky3.rotation":{x:0,y:0,z:0},"LeftShoulder.rotation":{x:1.545,y:-.116,z:-1.529},"LeftArm.rotation":{x:.799,y:.631,z:.556},"LeftForeArm.rotation":{x:-.002,y:.007,z:.926},"LeftHand.rotation":{x:-.508,y:.439,z:.502},"LeftHandThumb1.rotation":{x:.651,y:-.035,z:.308},"LeftHandThumb2.rotation":{x:-.053,y:.008,z:-.11},"LeftHandThumb3.rotation":{x:0,y:0,z:0},"LeftHandIndex1.rotation":{x:.662,y:-.053,z:-.116},"LeftHandIndex2.rotation":{x:.309,y:-.004,z:-.02},"LeftHandIndex3.rotation":{x:0,y:0,z:0},"LeftHandMiddle1.rotation":{x:.501,y:-.062,z:-.12},"LeftHandMiddle2.rotation":{x:.144,y:-.002,z:.016},"LeftHandMiddle3.rotation":{x:0,y:0,z:0},"LeftHandRing1.rotation":{x:.397,y:-.029,z:-.143},"LeftHandRing2.rotation":{x:.328,y:.01,z:.059},"LeftHandRing3.rotation":{x:0,y:0,z:0},"LeftHandPinky1.rotation":{x:.194,y:.008,z:-.164},"LeftHandPinky2.rotation":{x:.38,y:.031,z:.128},"LeftHandPinky3.rotation":{x:0,y:0,z:0},"RightUpLeg.rotation":{x:-1.594,y:-.251,z:2.792},"RightLeg.rotation":{x:-2.301,y:-.073,z:.055},"RightFoot.rotation":{x:1.553,y:-.207,z:-.094},"RightToeBase.rotation":{x:.459,y:.069,z:.016},"LeftUpLeg.rotation":{x:-.788,y:-.236,z:-2.881},"LeftLeg.rotation":{x:-2.703,y:.012,z:-.047},"LeftFoot.rotation":{x:2.191,y:-.102,z:.019},"LeftToeBase.rotation":{x:1.215,y:-.027,z:.01}}},kneel:{kneeling:!0,lying:!0,props:{"Hips.position":{x:0,y:.532,z:-.002},"Hips.rotation":{x:.018,y:-.008,z:-.017},"Spine.rotation":{x:-.139,y:-.01,z:.002},"Spine1.rotation":{x:.002,y:-.002,z:.001},"Spine2.rotation":{x:.028,y:-.002,z:.001},"Neck.rotation":{x:-.007,y:0,z:-.002},"Head.rotation":{x:-.02,y:-.008,z:-.004},"LeftShoulder.rotation":{x:1.77,y:-.428,z:-1.588},"LeftArm.rotation":{x:.911,y:.343,z:.083},"LeftForeArm.rotation":{x:0,y:0,z:.347},"LeftHand.rotation":{x:.033,y:-.052,z:-.105},"LeftHandThumb1.rotation":{x:.508,y:-.22,z:.708},"LeftHandThumb2.rotation":{x:-.323,y:-.139,z:-.56},"LeftHandThumb3.rotation":{x:-.328,y:.16,z:-.301},"LeftHandIndex1.rotation":{x:.178,y:.248,z:.045},"LeftHandIndex2.rotation":{x:.236,y:-.002,z:-.019},"LeftHandIndex3.rotation":{x:-.062,y:0,z:.005},"LeftHandMiddle1.rotation":{x:.123,y:-.005,z:-.019},"LeftHandMiddle2.rotation":{x:.589,y:-.014,z:-.045},"LeftHandMiddle3.rotation":{x:.231,y:-.002,z:-.019},"LeftHandRing1.rotation":{x:.196,y:-.008,z:-.091},"LeftHandRing2.rotation":{x:.483,y:-.009,z:-.038},"LeftHandRing3.rotation":{x:.367,y:-.005,z:-.029},"LeftHandPinky1.rotation":{x:.191,y:-.269,z:-.246},"LeftHandPinky2.rotation":{x:.37,y:-.006,z:-.029},"LeftHandPinky3.rotation":{x:.368,y:-.005,z:-.029},"RightShoulder.rotation":{x:1.73,y:.434,z:1.715},"RightArm.rotation":{x:.841,y:-.508,z:-.155},"RightForeArm.rotation":{x:0,y:0,z:-.355},"RightHand.rotation":{x:.091,y:.137,z:.197},"RightHandThumb1.rotation":{x:.33,y:.051,z:-.753},"RightHandThumb2.rotation":{x:-.113,y:.075,z:.612},"RightHandThumb3.rotation":{x:-.271,y:-.166,z:.164},"RightHandIndex1.rotation":{x:.073,y:.001,z:-.093},"RightHandIndex2.rotation":{x:.338,y:.006,z:.034},"RightHandIndex3.rotation":{x:.131,y:.001,z:.013},"RightHandMiddle1.rotation":{x:.13,y:.005,z:-.017},"RightHandMiddle2.rotation":{x:.602,y:.018,z:.058},"RightHandMiddle3.rotation":{x:-.031,y:0,z:-.003},"RightHandRing1.rotation":{x:.351,y:.019,z:.045},"RightHandRing2.rotation":{x:.19,y:.002,z:.019},"RightHandRing3.rotation":{x:.21,y:.002,z:.021},"RightHandPinky1.rotation":{x:.256,y:.17,z:.118},"RightHandPinky2.rotation":{x:.451,y:.01,z:.045},"RightHandPinky3.rotation":{x:.346,y:.006,z:.035},"LeftUpLeg.rotation":{x:-.06,y:.1,z:-2.918},"LeftLeg.rotation":{x:-1.933,y:-.01,z:.011},"LeftFoot.rotation":{x:.774,y:-.162,z:-.144},"LeftToeBase.rotation":{x:1.188,y:0,z:0},"RightUpLeg.rotation":{x:-.099,y:-.057,z:2.922},"RightLeg.rotation":{x:-1.93,y:.172,z:-.02},"RightFoot.rotation":{x:.644,y:.251,z:.212},"RightToeBase.rotation":{x:.638,y:-.034,z:-.001}}},sitting:{sitting:!0,lying:!0,props:{"Hips.position":{x:0,y:.117,z:.005},"Hips.rotation":{x:-.411,y:-.049,z:.056},"Spine.rotation":{x:.45,y:-.039,z:-.116},"Spine1.rotation":{x:.092,y:-.076,z:.08},"Spine2.rotation":{x:.073,y:.035,z:.066},"Neck.rotation":{x:.051,y:.053,z:-.079},"Head.rotation":{x:-.169,y:.009,z:.034},"LeftShoulder.rotation":{x:1.756,y:-.037,z:-1.301},"LeftArm.rotation":{x:-.098,y:.016,z:1.006},"LeftForeArm.rotation":{x:-.089,y:.08,z:.837},"LeftHand.rotation":{x:.262,y:-.399,z:.3},"LeftHandThumb1.rotation":{x:.149,y:-.043,z:.452},"LeftHandThumb2.rotation":{x:.032,y:.006,z:-.162},"LeftHandThumb3.rotation":{x:-.086,y:-.005,z:-.069},"LeftHandIndex1.rotation":{x:.145,y:.032,z:-.069},"LeftHandIndex2.rotation":{x:.325,y:-.001,z:-.004},"LeftHandIndex3.rotation":{x:.253,y:0,z:-.003},"LeftHandMiddle1.rotation":{x:.186,y:-.051,z:-.091},"LeftHandMiddle2.rotation":{x:.42,y:-.003,z:-.011},"LeftHandMiddle3.rotation":{x:.153,y:.001,z:-.001},"LeftHandRing1.rotation":{x:.087,y:-.19,z:-.078},"LeftHandRing2.rotation":{x:.488,y:-.004,z:-.005},"LeftHandRing3.rotation":{x:.183,y:-.001,z:-.012},"LeftHandPinky1.rotation":{x:.205,y:-.262,z:.051},"LeftHandPinky2.rotation":{x:.407,y:-.002,z:-.004},"LeftHandPinky3.rotation":{x:.068,y:0,z:-.002},"RightShoulder.rotation":{x:1.619,y:-.139,z:1.179},"RightArm.rotation":{x:.17,y:-.037,z:-1.07},"RightForeArm.rotation":{x:-.044,y:-.056,z:-.665},"RightHand.rotation":{x:.278,y:.454,z:-.253},"RightHandThumb1.rotation":{x:.173,y:.089,z:-.584},"RightHandThumb2.rotation":{x:-.003,y:-.004,z:.299},"RightHandThumb3.rotation":{x:-.133,y:-.002,z:.235},"RightHandIndex1.rotation":{x:.393,y:-.023,z:.108},"RightHandIndex2.rotation":{x:.391,y:.001,z:.004},"RightHandIndex3.rotation":{x:.326,y:0,z:.003},"RightHandMiddle1.rotation":{x:.285,y:.062,z:.086},"RightHandMiddle2.rotation":{x:.519,y:.003,z:.011},"RightHandMiddle3.rotation":{x:.252,y:-.001,z:.001},"RightHandRing1.rotation":{x:.207,y:.122,z:.155},"RightHandRing2.rotation":{x:.597,y:.004,z:.005},"RightHandRing3.rotation":{x:.292,y:.001,z:.012},"RightHandPinky1.rotation":{x:.338,y:.171,z:.149},"RightHandPinky2.rotation":{x:.533,y:.002,z:.004},"RightHandPinky3.rotation":{x:.194,y:0,z:.002},"LeftUpLeg.rotation":{x:-1.957,y:.083,z:-2.886},"LeftLeg.rotation":{x:-1.46,y:.123,z:.005},"LeftFoot.rotation":{x:-.013,y:.016,z:.09},"LeftToeBase.rotation":{x:.744,y:0,z:0},"RightUpLeg.rotation":{x:-1.994,y:.125,z:2.905},"RightLeg.rotation":{x:-1.5,y:-.202,z:-.006},"RightFoot.rotation":{x:-.012,y:-.065,z:.081},"RightToeBase.rotation":{x:.758,y:0,z:0}}}},this.gestureTemplates={handup:{"LeftShoulder.rotation":{x:[1.5,2,1,2],y:[.2,.4,1,2],z:[-1.5,-1.3,1,2]},"LeftArm.rotation":{x:[1.5,1.7,1,2],y:[-.6,-.4,1,2],z:[1,1.2,1,2]},"LeftForeArm.rotation":{x:-.815,y:[-.4,0,1,2],z:1.575},"LeftHand.rotation":{x:-.529,y:-.2,z:.022},"LeftHandThumb1.rotation":{x:.745,y:-.526,z:.604},"LeftHandThumb2.rotation":{x:-.107,y:-.01,z:-.142},"LeftHandThumb3.rotation":{x:0,y:.001,z:0},"LeftHandIndex1.rotation":{x:-.126,y:-.035,z:-.087},"LeftHandIndex2.rotation":{x:.255,y:.007,z:-.085},"LeftHandIndex3.rotation":{x:0,y:0,z:0},"LeftHandMiddle1.rotation":{x:-.019,y:-.128,z:-.082},"LeftHandMiddle2.rotation":{x:.233,y:.019,z:-.074},"LeftHandMiddle3.rotation":{x:0,y:0,z:0},"LeftHandRing1.rotation":{x:.005,y:-.241,z:-.122},"LeftHandRing2.rotation":{x:.261,y:.021,z:-.076},"LeftHandRing3.rotation":{x:0,y:0,z:0},"LeftHandPinky1.rotation":{x:.059,y:-.336,z:-.2},"LeftHandPinky2.rotation":{x:.153,y:.019,z:.001},"LeftHandPinky3.rotation":{x:0,y:0,z:0}},index:{"LeftShoulder.rotation":{x:[1.5,2,1,2],y:[.2,.4,1,2],z:[-1.5,-1.3,1,2]},"LeftArm.rotation":{x:[1.5,1.7,1,2],y:[-.6,-.4,1,2],z:[1,1.2,1,2]},"LeftForeArm.rotation":{x:-.815,y:[-.4,0,1,2],z:1.575},"LeftHand.rotation":{x:-.276,y:-.506,z:-.208},"LeftHandThumb1.rotation":{x:.579,y:.228,z:.363},"LeftHandThumb2.rotation":{x:-.027,y:-.04,z:-.662},"LeftHandThumb3.rotation":{x:0,y:.001,z:0},"LeftHandIndex1.rotation":{x:0,y:-.105,z:.225},"LeftHandIndex2.rotation":{x:.256,y:-.103,z:-.213},"LeftHandIndex3.rotation":{x:0,y:0,z:0},"LeftHandMiddle1.rotation":{x:1.453,y:.07,z:.021},"LeftHandMiddle2.rotation":{x:1.599,y:.062,z:.07},"LeftHandMiddle3.rotation":{x:0,y:0,z:0},"LeftHandRing1.rotation":{x:1.528,y:-.073,z:.052},"LeftHandRing2.rotation":{x:1.386,y:.044,z:.053},"LeftHandRing3.rotation":{x:0,y:0,z:0},"LeftHandPinky1.rotation":{x:1.65,y:-.204,z:.031},"LeftHandPinky2.rotation":{x:1.302,y:.071,z:.085},"LeftHandPinky3.rotation":{x:0,y:0,z:0}},ok:{"LeftShoulder.rotation":{x:[1.5,2,1,2],y:[.2,.4,1,2],z:[-1.5,-1.3,1,2]},"LeftArm.rotation":{x:[1.5,1.7,1,1],y:[-.6,-.4,1,2],z:[1,1.2,1,2]},"LeftForeArm.rotation":{x:-.415,y:[-.4,0,1,2],z:1.575},"LeftHand.rotation":{x:-.476,y:-.506,z:-.208},"LeftHandThumb1.rotation":{x:.703,y:.445,z:.899},"LeftHandThumb2.rotation":{x:-.312,y:-.04,z:-.938},"LeftHandThumb3.rotation":{x:-.37,y:.024,z:-.393},"LeftHandIndex1.rotation":{x:.8,y:-.086,z:-.091},"LeftHandIndex2.rotation":{x:1.123,y:-.046,z:-.074},"LeftHandIndex3.rotation":{x:.562,y:-.013,z:-.043},"LeftHandMiddle1.rotation":{x:-.019,y:-.128,z:-.082},"LeftHandMiddle2.rotation":{x:.233,y:.019,z:-.074},"LeftHandMiddle3.rotation":{x:0,y:0,z:0},"LeftHandRing1.rotation":{x:.005,y:-.241,z:-.122},"LeftHandRing2.rotation":{x:.261,y:.021,z:-.076},"LeftHandRing3.rotation":{x:0,y:0,z:0},"LeftHandPinky1.rotation":{x:.059,y:-.336,z:-.2},"LeftHandPinky2.rotation":{x:.153,y:.019,z:.001},"LeftHandPinky3.rotation":{x:0,y:0,z:0}},thumbup:{"LeftShoulder.rotation":{x:[1.5,2,1,2],y:[.2,.4,1,2],z:[-1.5,-1.3,1,2]},"LeftArm.rotation":{x:[1.5,1.7,1,2],y:[-.6,-.4,1,2],z:[1,1.2,1,2]},"LeftForeArm.rotation":{x:-.415,y:.206,z:1.575},"LeftHand.rotation":{x:-.276,y:-.506,z:-.208},"LeftHandThumb1.rotation":{x:.208,y:-.189,z:.685},"LeftHandThumb2.rotation":{x:.129,y:-.285,z:-.163},"LeftHandThumb3.rotation":{x:-.047,y:.068,z:.401},"LeftHandIndex1.rotation":{x:1.412,y:-.102,z:-.152},"LeftHandIndex2.rotation":{x:1.903,y:-.16,z:-.114},"LeftHandIndex3.rotation":{x:.535,y:-.017,z:-.062},"LeftHandMiddle1.rotation":{x:1.424,y:-.103,z:-.12},"LeftHandMiddle2.rotation":{x:1.919,y:-.162,z:-.114},"LeftHandMiddle3.rotation":{x:.44,y:-.012,z:-.051},"LeftHandRing1.rotation":{x:1.619,y:-.127,z:-.053},"LeftHandRing2.rotation":{x:1.898,y:-.16,z:-.115},"LeftHandRing3.rotation":{x:.262,y:-.004,z:-.031},"LeftHandPinky1.rotation":{x:1.661,y:-.131,z:-.016},"LeftHandPinky2.rotation":{x:1.715,y:-.067,z:-.13},"LeftHandPinky3.rotation":{x:.627,y:-.023,z:-.071}},thumbdown:{"LeftShoulder.rotation":{x:[1.5,2,1,2],y:[.2,.4,1,2],z:[-1.5,-1.3,1,2]},"LeftArm.rotation":{x:[1.5,1.7,1,2],y:[-.6,-.4,1,2],z:[1,1.2,1,2]},"LeftForeArm.rotation":{x:-2.015,y:.406,z:1.575},"LeftHand.rotation":{x:-.176,y:-.206,z:-.208},"LeftHandThumb1.rotation":{x:.208,y:-.189,z:.685},"LeftHandThumb2.rotation":{x:.129,y:-.285,z:-.163},"LeftHandThumb3.rotation":{x:-.047,y:.068,z:.401},"LeftHandIndex1.rotation":{x:1.412,y:-.102,z:-.152},"LeftHandIndex2.rotation":{x:1.903,y:-.16,z:-.114},"LeftHandIndex3.rotation":{x:.535,y:-.017,z:-.062},"LeftHandMiddle1.rotation":{x:1.424,y:-.103,z:-.12},"LeftHandMiddle2.rotation":{x:1.919,y:-.162,z:-.114},"LeftHandMiddle3.rotation":{x:.44,y:-.012,z:-.051},"LeftHandRing1.rotation":{x:1.619,y:-.127,z:-.053},"LeftHandRing2.rotation":{x:1.898,y:-.16,z:-.115},"LeftHandRing3.rotation":{x:.262,y:-.004,z:-.031},"LeftHandPinky1.rotation":{x:1.661,y:-.131,z:-.016},"LeftHandPinky2.rotation":{x:1.715,y:-.067,z:-.13},"LeftHandPinky3.rotation":{x:.627,y:-.023,z:-.071}},side:{"LeftShoulder.rotation":{x:1.755,y:-.035,z:-1.63},"LeftArm.rotation":{x:1.263,y:-.955,z:1.024},"LeftForeArm.rotation":{x:0,y:0,z:.8},"LeftHand.rotation":{x:-.36,y:-1.353,z:-.184},"LeftHandThumb1.rotation":{x:.137,y:-.049,z:.863},"LeftHandThumb2.rotation":{x:-.293,y:.153,z:-.193},"LeftHandThumb3.rotation":{x:-.271,y:-.17,z:.18},"LeftHandIndex1.rotation":{x:-.018,y:.007,z:.28},"LeftHandIndex2.rotation":{x:.247,y:-.003,z:-.025},"LeftHandIndex3.rotation":{x:.13,y:-.001,z:-.013},"LeftHandMiddle1.rotation":{x:.333,y:-.015,z:.182},"LeftHandMiddle2.rotation":{x:.313,y:-.005,z:-.032},"LeftHandMiddle3.rotation":{x:.294,y:-.004,z:-.03},"LeftHandRing1.rotation":{x:.456,y:-.028,z:-.092},"LeftHandRing2.rotation":{x:.53,y:-.014,z:-.052},"LeftHandRing3.rotation":{x:.478,y:-.012,z:-.047},"LeftHandPinky1.rotation":{x:.647,y:-.049,z:-.184},"LeftHandPinky2.rotation":{x:.29,y:-.004,z:-.029},"LeftHandPinky3.rotation":{x:.501,y:-.013,z:-.049}},shrug:{"Neck.rotation":{x:[-.3,.3,1,2],y:[-.3,.3,1,2],z:[-.1,.1]},"Head.rotation":{x:[-.3,.3],y:[-.3,.3],z:[-.1,.1]},"RightShoulder.rotation":{x:1.732,y:-.058,z:1.407},"RightArm.rotation":{x:1.305,y:.46,z:.118},"RightForeArm.rotation":{x:[0,2],y:[-1,.2],z:-1.637},"RightHand.rotation":{x:-.048,y:.165,z:-.39},"RightHandThumb1.rotation":{x:1.467,y:.599,z:-1.315},"RightHandThumb2.rotation":{x:-.255,y:-.123,z:.119},"RightHandThumb3.rotation":{x:0,y:-.002,z:0},"RightHandIndex1.rotation":{x:-.293,y:-.066,z:-.112},"RightHandIndex2.rotation":{x:.181,y:.007,z:.069},"RightHandIndex3.rotation":{x:0,y:0,z:0},"RightHandMiddle1.rotation":{x:-.063,y:-.041,z:.032},"RightHandMiddle2.rotation":{x:.149,y:.005,z:.05},"RightHandMiddle3.rotation":{x:0,y:0,z:0},"RightHandRing1.rotation":{x:.152,y:-.03,z:.132},"RightHandRing2.rotation":{x:.194,y:.007,z:.058},"RightHandRing3.rotation":{x:0,y:0,z:0},"RightHandPinky1.rotation":{x:.306,y:-.015,z:.257},"RightHandPinky2.rotation":{x:.15,y:-.003,z:-.003},"RightHandPinky3.rotation":{x:0,y:0,z:0},"LeftShoulder.rotation":{x:1.713,y:.141,z:-1.433},"LeftArm.rotation":{x:1.136,y:-.422,z:-.416},"LeftForeArm.rotation":{x:1.42,y:.123,z:1.506},"LeftHand.rotation":{x:.073,y:-.138,z:.064},"LeftHandThumb1.rotation":{x:1.467,y:-.599,z:1.314},"LeftHandThumb2.rotation":{x:-.255,y:.123,z:-.119},"LeftHandThumb3.rotation":{x:0,y:.001,z:0},"LeftHandIndex1.rotation":{x:-.293,y:.066,z:.112},"LeftHandIndex2.rotation":{x:.181,y:-.007,z:-.069},"LeftHandIndex3.rotation":{x:0,y:0,z:0},"LeftHandMiddle1.rotation":{x:-.062,y:.041,z:-.032},"LeftHandMiddle2.rotation":{x:.149,y:-.005,z:-.05},"LeftHandMiddle3.rotation":{x:0,y:0,z:0},"LeftHandRing1.rotation":{x:.152,y:.03,z:-.132},"LeftHandRing2.rotation":{x:.194,y:-.007,z:-.058},"LeftHandRing3.rotation":{x:0,y:0,z:0},"LeftHandPinky1.rotation":{x:.306,y:.015,z:-.257},"LeftHandPinky2.rotation":{x:.15,y:.003,z:.003},"LeftHandPinky3.rotation":{x:0,y:0,z:0}},namaste:{"RightShoulder.rotation":{x:1.758,y:.099,z:1.604},"RightArm.rotation":{x:.862,y:-.292,z:-.932},"RightForeArm.rotation":{x:.083,y:.066,z:-1.791},"RightHand.rotation":{x:-.52,y:-.001,z:-.176},"RightHandThumb1.rotation":{x:.227,y:.418,z:-.776},"RightHandThumb2.rotation":{x:-.011,y:-.003,z:.171},"RightHandThumb3.rotation":{x:-.041,y:-.001,z:-.013},"RightHandIndex1.rotation":{x:-.236,y:.003,z:-.028},"RightHandIndex2.rotation":{x:.004,y:0,z:.001},"RightHandIndex3.rotation":{x:.002,y:0,z:0},"RightHandMiddle1.rotation":{x:-.236,y:.003,z:-.028},"RightHandMiddle2.rotation":{x:.004,y:0,z:.001},"RightHandMiddle3.rotation":{x:.002,y:0,z:0},"RightHandRing1.rotation":{x:-.236,y:.003,z:-.028},"RightHandRing2.rotation":{x:.004,y:0,z:.001},"RightHandRing3.rotation":{x:.002,y:0,z:0},"RightHandPinky1.rotation":{x:-.236,y:.003,z:-.028},"RightHandPinky2.rotation":{x:.004,y:0,z:.001},"RightHandPinky3.rotation":{x:.002,y:0,z:0},"LeftShoulder.rotation":{x:1.711,y:-.002,z:-1.625},"LeftArm.rotation":{x:.683,y:.334,z:.977},"LeftForeArm.rotation":{x:.086,y:-.066,z:1.843},"LeftHand.rotation":{x:-.595,y:-.229,z:.096},"LeftHandThumb1.rotation":{x:.404,y:-.05,z:.537},"LeftHandThumb2.rotation":{x:-.02,y:.004,z:-.154},"LeftHandThumb3.rotation":{x:-.049,y:.002,z:-.019},"LeftHandIndex1.rotation":{x:-.113,y:-.001,z:.014},"LeftHandIndex2.rotation":{x:.003,y:0,z:0},"LeftHandIndex3.rotation":{x:.002,y:0,z:0},"LeftHandMiddle1.rotation":{x:-.113,y:-.001,z:.014},"LeftHandMiddle2.rotation":{x:.004,y:0,z:0},"LeftHandMiddle3.rotation":{x:.002,y:0,z:0},"LeftHandRing1.rotation":{x:-.113,y:-.001,z:.014},"LeftHandRing2.rotation":{x:.003,y:0,z:0},"LeftHandRing3.rotation":{x:.002,y:0,z:0},"LeftHandPinky1.rotation":{x:-.122,y:-.001,z:-.057},"LeftHandPinky2.rotation":{x:.012,y:.001,z:.07},"LeftHandPinky3.rotation":{x:.002,y:0,z:0}}},this.poseDelta={props:{"Hips.quaternion":{x:0,y:0,z:0},"Spine.quaternion":{x:0,y:0,z:0},"Spine1.quaternion":{x:0,y:0,z:0},"Neck.quaternion":{x:0,y:0,z:0},"Head.quaternion":{x:0,y:0,z:0},"Spine1.scale":{x:0,y:0,z:0},"Neck.scale":{x:0,y:0,z:0},"LeftArm.scale":{x:0,y:0,z:0},"RightArm.scale":{x:0,y:0,z:0}}},["Left","Right"].forEach(a=>{["Leg","UpLeg","Arm","ForeArm","Hand"].forEach(c=>{this.poseDelta.props[a+c+".quaternion"]={x:0,y:0,z:0}}),["HandThumb","HandIndex","HandMiddle","HandRing","HandPinky"].forEach(c=>{this.poseDelta.props[a+c+"1.quaternion"]={x:0,y:0,z:0},this.poseDelta.props[a+c+"2.quaternion"]={x:0,y:0,z:0},this.poseDelta.props[a+c+"3.quaternion"]={x:0,y:0,z:0}})});const t=new Set;Object.values(this.poseTemplates).forEach(a=>{Object.keys(this.propsToThreeObjects(a.props)).forEach(c=>t.add(c))}),Object.keys(this.poseDelta.props).forEach(a=>{t.add(a)}),this.posePropNames=[...t],this.poseName="side",this.poseWeightOnLeft=!0,this.gesture=null,this.poseCurrentTemplate=this.poseTemplates[this.poseName],this.poseStraight=this.propsToThreeObjects(this.poseTemplates.straight.props),this.poseBase=this.poseFactory(this.poseCurrentTemplate),this.poseTarget=this.poseFactory(this.poseCurrentTemplate),this.poseAvatar=null,this.avatarHeight=1.7,this.animTemplateEyes={name:"eyes",idle:{alt:[{p:()=>this.avatar?.hasOwnProperty("avatarIdleEyeContact")?this.avatar.avatarIdleEyeContact:this.opt.avatarIdleEyeContact,delay:[200,5e3],dt:[200,[2e3,5e3],[3e3,1e4,1,2]],vs:{headMove:[this.avatar?.hasOwnProperty("avatarIdleHeadMove")?this.avatar.avatarIdleHeadMove:this.opt.avatarIdleHeadMove],eyesRotateY:[[-.6,.6]],eyesRotateX:[[-.2,.6]],eyeContact:[null,1]}},{delay:[200,5e3],dt:[200,[2e3,5e3,1,2]],vs:{headMove:[this.avatar?.hasOwnProperty("avatarIdleHeadMove")?this.avatar.avatarIdleHeadMove:this.opt.avatarIdleHeadMove],eyesRotateY:[[-.6,.6]],eyesRotateX:[[-.2,.6]]}}]},speaking:{alt:[{p:()=>this.avatar?.hasOwnProperty("avatarSpeakingEyeContact")?this.avatar.avatarSpeakingEyeContact:this.opt.avatarSpeakingEyeContact,delay:[200,5e3],dt:[0,[3e3,1e4,1,2],[2e3,5e3]],vs:{eyeContact:[1,null],headMove:[null,this.avatar?.hasOwnProperty("avatarSpeakingHeadMove")?this.avatar.avatarSpeakingHeadMove:this.opt.avatarSpeakingHeadMove,null],eyesRotateY:[null,[-.6,.6]],eyesRotateX:[null,[-.2,.6]]}},{delay:[200,5e3],dt:[200,[2e3,5e3,1,2]],vs:{headMove:[this.avatar?.hasOwnProperty("avatarSpeakingHeadMove")?this.avatar.avatarSpeakingHeadMove:this.opt.avatarSpeakingHeadMove,null],eyesRotateY:[[-.6,.6]],eyesRotateX:[[-.2,.6]]}}]}},this.animTemplateBlink={name:"blink",alt:[{p:.85,delay:[1e3,8e3,1,2],dt:[50,[100,300],100],vs:{eyeBlinkLeft:[1,1,0],eyeBlinkRight:[1,1,0]}},{delay:[1e3,4e3,1,2],dt:[50,[100,200],100,[10,400,0],50,[100,200],100],vs:{eyeBlinkLeft:[1,1,0,0,1,1,0],eyeBlinkRight:[1,1,0,0,1,1,0]}}]},this.animMoods={neutral:{baseline:{eyesLookDown:0},speech:{deltaRate:0,deltaPitch:0,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1200,500,1e3],vs:{chestInhale:[.5,.5,0]}},{name:"pose",alt:[{p:.5,delay:[5e3,3e4],vs:{pose:["side"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}},{p:.3,delay:[5e3,3e4],vs:{pose:["hip"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}},{delay:[5e3,3e4],vs:{pose:["straight"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}}]},{name:"head",idle:{delay:[0,1e3],dt:[[200,5e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.3,.3]],bodyRotateZ:[[-.08,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.15,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.1,.1]]}}},this.animTemplateEyes,this.animTemplateBlink,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.3]]}},{name:"misc",delay:[100,5e3],dt:[[100,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[0,.3,2]],browOuterUpLeft:[[0,.3,2]],browOuterUpRight:[[0,.3,2]]}}]},happy:{baseline:{mouthSmile:.2,eyesLookDown:0},speech:{deltaRate:0,deltaPitch:.1,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1200,500,1e3],vs:{chestInhale:[.5,.5,0]}},{name:"pose",idle:{alt:[{p:.6,delay:[5e3,3e4],vs:{pose:["side"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}},{p:.2,delay:[5e3,3e4],vs:{pose:["hip"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}},{p:.1,delay:[5e3,3e4],vs:{pose:["straight"]}},{delay:[5e3,1e4],vs:{pose:["wide"]}},{delay:[1e3,3e3],vs:{pose:["turn"]}}]},speaking:{alt:[{p:.4,delay:[5e3,3e4],vs:{pose:["side"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}},{p:.4,delay:[5e3,3e4],vs:{pose:["straight"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}},{delay:[5e3,2e4],vs:{pose:["hip"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}}]}},{name:"head",idle:{dt:[[1e3,5e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.3,.3]],bodyRotateZ:[[-.08,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.15,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.1,.1]]}}},this.animTemplateEyes,this.animTemplateBlink,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthLeft:[[0,.3,2]],mouthSmile:[[0,.2,3]],mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.3]]}},{name:"misc",delay:[100,5e3],dt:[[100,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[0,.3,2]],browOuterUpLeft:[[0,.3,2]],browOuterUpRight:[[0,.3,2]]}}]},angry:{baseline:{eyesLookDown:.1,browDownLeft:.6,browDownRight:.6,jawForward:.3,mouthFrownLeft:.7,mouthFrownRight:.7,mouthRollLower:.2,mouthShrugLower:.3,handFistLeft:1,handFistRight:1},speech:{deltaRate:-.2,deltaPitch:.2,deltaVolume:0},anims:[{name:"breathing",delay:500,dt:[1e3,500,1e3],vs:{chestInhale:[.7,.7,0]}},{name:"pose",alt:[{p:.4,delay:[5e3,3e4],vs:{pose:["side"]}},{p:.4,delay:[5e3,3e4],vs:{pose:["straight"]}},{p:.2,delay:[5e3,3e4],vs:{pose:["hip"]},M:{delay:[5e3,3e4],vs:{pose:["wide"]}}}]},{name:"head",idle:{delay:[100,500],dt:[[200,5e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.2,.2]],bodyRotateZ:[[-.08,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.15,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.1,.1]]}}},this.animTemplateEyes,this.animTemplateBlink,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.3]]}},{name:"misc",delay:[100,5e3],dt:[[100,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[0,.3,2]],browOuterUpLeft:[[0,.3,2]],browOuterUpRight:[[0,.3,2]]}}]},sad:{baseline:{eyesLookDown:.2,browDownRight:.1,browInnerUp:.6,browOuterUpRight:.2,eyeSquintLeft:.7,eyeSquintRight:.7,mouthFrownLeft:.8,mouthFrownRight:.8,mouthLeft:.2,mouthPucker:.5,mouthRollLower:.2,mouthRollUpper:.2,mouthShrugLower:.2,mouthShrugUpper:.2,mouthStretchLeft:.4},speech:{deltaRate:-.2,deltaPitch:-.2,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1e3,500,1e3],vs:{chestInhale:[.3,.3,0]}},{name:"pose",alt:[{p:.4,delay:[5e3,3e4],vs:{pose:["side"]}},{p:.4,delay:[5e3,3e4],vs:{pose:["straight"]}},{delay:[5e3,2e4],vs:{pose:["side"]},full:{delay:[5e3,2e4],vs:{pose:["oneknee"]}}}]},{name:"head",idle:{delay:[100,500],dt:[[200,5e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.2,.2]],bodyRotateZ:[[-.08,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.15,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.1,.1]]}}},this.animTemplateEyes,this.animTemplateBlink,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.3]]}},{name:"misc",delay:[100,5e3],dt:[[100,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[0,.3,2]],browOuterUpLeft:[[0,.3,2]],browOuterUpRight:[[0,.3,2]]}}]},fear:{baseline:{browInnerUp:.7,eyeSquintLeft:.5,eyeSquintRight:.5,eyeWideLeft:.6,eyeWideRight:.6,mouthClose:.1,mouthFunnel:.3,mouthShrugLower:.5,mouthShrugUpper:.5},speech:{deltaRate:-.2,deltaPitch:0,deltaVolume:0},anims:[{name:"breathing",delay:500,dt:[1e3,500,1e3],vs:{chestInhale:[.7,.7,0]}},{name:"pose",alt:[{p:.8,delay:[5e3,3e4],vs:{pose:["side"]}},{delay:[5e3,3e4],vs:{pose:["straight"]}},{delay:[5e3,2e4],vs:{pose:["wide"]}},{delay:[5e3,2e4],vs:{pose:["side"]},full:{delay:[5e3,2e4],vs:{pose:["oneknee"]}}}]},{name:"head",idle:{delay:[100,500],dt:[[200,3e3]],vs:{bodyRotateX:[[-.06,.12]],bodyRotateY:[[-.7,.7]],bodyRotateZ:[[-.1,.1]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.15,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.1,.1]]}}},this.animTemplateEyes,this.animTemplateBlink,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.3]]}},{name:"misc",delay:[100,5e3],dt:[[100,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[0,.3,2]],browOuterUpLeft:[[0,.3,2]],browOuterUpRight:[[0,.3,2]]}}]},disgust:{baseline:{browDownLeft:.7,browDownRight:.1,browInnerUp:.3,eyeSquintLeft:1,eyeSquintRight:1,eyeWideLeft:.5,eyeWideRight:.5,eyesRotateX:.05,mouthLeft:.4,mouthPressLeft:.3,mouthRollLower:.3,mouthShrugLower:.3,mouthShrugUpper:.8,mouthUpperUpLeft:.3,noseSneerLeft:1,noseSneerRight:.7},speech:{deltaRate:-.2,deltaPitch:0,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1e3,500,1e3],vs:{chestInhale:[.5,.5,0]}},{name:"pose",alt:[{delay:[5e3,2e4],vs:{pose:["side"]}}]},{name:"head",idle:{delay:[100,500],dt:[[200,5e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.2,.2]],bodyRotateZ:[[-.08,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.15,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.1,.1]]}}},this.animTemplateEyes,this.animTemplateBlink,{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.3]]}},{name:"misc",delay:[100,5e3],dt:[[100,500],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[0,.3,2]],browOuterUpLeft:[[0,.3,2]],browOuterUpRight:[[0,.3,2]]}}]},love:{baseline:{browInnerUp:.4,browOuterUpLeft:.2,browOuterUpRight:.2,mouthSmile:.2,eyeBlinkLeft:.6,eyeBlinkRight:.6,eyeWideLeft:.7,eyeWideRight:.7,bodyRotateX:.1,mouthDimpleLeft:.1,mouthDimpleRight:.1,mouthPressLeft:.2,mouthShrugUpper:.2,mouthUpperUpLeft:.1,mouthUpperUpRight:.1},speech:{deltaRate:-.1,deltaPitch:-.7,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1500,500,1500],vs:{chestInhale:[.8,.8,0]}},{name:"pose",alt:[{p:.4,delay:[5e3,3e4],vs:{pose:["side"]}},{p:.2,delay:[5e3,3e4],vs:{pose:["straight"]}},{p:.2,delay:[5e3,3e4],vs:{pose:["hip"]},M:{delay:[5e3,3e4],vs:{pose:["side"]}}},{delay:[5e3,1e4],vs:{pose:["side"]},full:{delay:[5e3,1e4],vs:{pose:["kneel"]}}},{delay:[1e3,3e3],vs:{pose:["turn"]},M:{delay:[1e3,3e3],vs:{pose:["wide"]}}},{delay:[1e3,3e3],vs:{pose:["back"]},M:{delay:[1e3,3e3],vs:{pose:["wide"]}}},{delay:[5e3,2e4],vs:{pose:["side"]},M:{delay:[5e3,2e4],vs:{pose:["side"]}},full:{delay:[5e3,2e4],vs:{pose:["bend"]}}},{delay:[1e3,3e3],vs:{pose:["side"]},full:{delay:[5e3,1e4],vs:{pose:["oneknee"]}}}]},{name:"head",idle:{dt:[[1e3,5e3]],vs:{bodyRotateX:[[-.04,.1]],bodyRotateY:[[-.3,.3]],bodyRotateZ:[[-.08,.08]]}},speaking:{dt:[[0,1e3,0]],vs:{bodyRotateX:[[-.05,.15,1,2]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.1,.1]]}}},this.animTemplateEyes,this.deepCopy(this.animTemplateBlink,a=>{a.alt[0].delay[0]=a.alt[1].delay[0]=2e3}),{name:"mouth",delay:[1e3,5e3],dt:[[100,500],[100,5e3,2]],vs:{mouthLeft:[[0,.3,2]],mouthRollLower:[[0,.3,2]],mouthRollUpper:[[0,.3,2]],mouthStretchLeft:[[0,.3]],mouthStretchRight:[[0,.3]],mouthPucker:[[0,.3]]}},{name:"misc",delay:[100,5e3],dt:[[500,1e3],[1e3,5e3,2]],vs:{eyeSquintLeft:[[0,.3,2]],eyeSquintRight:[[0,.3,2]],browInnerUp:[[.3,.6,2]],browOuterUpLeft:[[.1,.3,2]],browOuterUpRight:[[.1,.3,2]]}}]},sleep:{baseline:{eyeBlinkLeft:1,eyeBlinkRight:1,eyesClosed:.6},speech:{deltaRate:0,deltaPitch:-.2,deltaVolume:0},anims:[{name:"breathing",delay:1500,dt:[1e3,500,1e3],vs:{chestInhale:[.6,.6,0]}},{name:"pose",alt:[{delay:[5e3,2e4],vs:{pose:["side"]}}]},{name:"head",delay:[1e3,5e3],dt:[[2e3,1e4]],vs:{bodyRotateX:[[0,.4]],bodyRotateY:[[-.1,.1]],bodyRotateZ:[[-.04,.04]]}},{name:"eyes",delay:10010,dt:[],vs:{}},{name:"blink",delay:10020,dt:[],vs:{}},{name:"mouth",delay:10030,dt:[],vs:{}},{name:"misc",delay:10040,dt:[],vs:{}}]}},this.moodName=this.opt.avatarMood||"neutral",this.mood=this.animMoods[this.moodName],this.mood||(this.moodName="neutral",this.mood=this.animMoods.neutral),this.animEmojis={"😐":{dt:[300,2e3],rescale:[0,1],vs:{pose:["straight"],browInnerUp:[.4],eyeWideLeft:[.7],eyeWideRight:[.7],mouthPressLeft:[.6],mouthPressRight:[.6],mouthRollLower:[.3],mouthStretchLeft:[1],mouthStretchRight:[1]}},"😶":{link:"😐"},"😏":{dt:[300,2e3],rescale:[0,1],vs:{eyeContact:[0],browDownRight:[.1],browInnerUp:[.7],browOuterUpRight:[.2],eyeLookInRight:[.7],eyeLookOutLeft:[.7],eyeSquintLeft:[1],eyeSquintRight:[.8],eyesRotateY:[.7],mouthLeft:[.4],mouthPucker:[.4],mouthShrugLower:[.3],mouthShrugUpper:[.2],mouthSmile:[.2],mouthSmileLeft:[.4],mouthSmileRight:[.2],mouthStretchLeft:[.5],mouthUpperUpLeft:[.6],noseSneerLeft:[.7]}},"🙂":{dt:[300,2e3],rescale:[0,1],vs:{mouthSmile:[.5]}},"🙃":{link:"🙂"},"😊":{dt:[300,2e3],rescale:[0,1],vs:{browInnerUp:[.6],eyeSquintLeft:[1],eyeSquintRight:[1],mouthSmile:[.7],noseSneerLeft:[.7],noseSneerRight:[.7]}},"😇":{link:"😊"},"😀":{dt:[300,2e3],rescale:[0,1],vs:{browInnerUp:[.6],jawOpen:[.1],mouthDimpleLeft:[.2],mouthDimpleRight:[.2],mouthOpen:[.3],mouthPressLeft:[.3],mouthPressRight:[.3],mouthRollLower:[.4],mouthShrugUpper:[.4],mouthSmile:[.7],mouthUpperUpLeft:[.3],mouthUpperUpRight:[.3],noseSneerLeft:[.4],noseSneerRight:[.4]}},"😃":{dt:[300,2e3],rescale:[0,1],vs:{browInnerUp:[.6],eyeWideLeft:[.7],eyeWideRight:[.7],jawOpen:[.1],mouthDimpleLeft:[.2],mouthDimpleRight:[.2],mouthOpen:[.3],mouthPressLeft:[.3],mouthPressRight:[.3],mouthRollLower:[.4],mouthShrugUpper:[.4],mouthSmile:[.7],mouthUpperUpLeft:[.3],mouthUpperUpRight:[.3],noseSneerLeft:[.4],noseSneerRight:[.4]}},"😄":{dt:[300,2e3],rescale:[0,1],vs:{browInnerUp:[.3],eyeSquintLeft:[1],eyeSquintRight:[1],jawOpen:[.2],mouthDimpleLeft:[.2],mouthDimpleRight:[.2],mouthOpen:[.3],mouthPressLeft:[.3],mouthPressRight:[.3],mouthRollLower:[.4],mouthShrugUpper:[.4],mouthSmile:[.7],mouthUpperUpLeft:[.3],mouthUpperUpRight:[.3],noseSneerLeft:[.4],noseSneerRight:[.4]}},"😁":{dt:[300,2e3],rescale:[0,1],vs:{browInnerUp:[.3],eyeSquintLeft:[1],eyeSquintRight:[1],jawOpen:[.3],mouthDimpleLeft:[.2],mouthDimpleRight:[.2],mouthPressLeft:[.5],mouthPressRight:[.5],mouthShrugUpper:[.4],mouthSmile:[.7],mouthUpperUpLeft:[.3],mouthUpperUpRight:[.3],noseSneerLeft:[.4],noseSneerRight:[.4]}},"😆":{dt:[300,2e3],rescale:[0,1],vs:{browInnerUp:[.3],eyeSquintLeft:[1],eyeSquintRight:[1],eyesClosed:[.6],jawOpen:[.3],mouthDimpleLeft:[.2],mouthDimpleRight:[.2],mouthPressLeft:[.5],mouthPressRight:[.5],mouthShrugUpper:[.4],mouthSmile:[.7],mouthUpperUpLeft:[.3],mouthUpperUpRight:[.3],noseSneerLeft:[.4],noseSneerRight:[.4]}},"😝":{dt:[300,100,1500,500,500],rescale:[0,0,1,0,0],vs:{browInnerUp:[.8],eyesClosed:[1],jawOpen:[.7],mouthFunnel:[.5],mouthSmile:[1],tongueOut:[0,1,1,0]}},"😋":{link:"😝"},"😛":{link:"😝"},"😛":{link:"😝"},"😜":{link:"😝"},"🤪":{link:"😝"},"😂":{dt:[300,2e3],rescale:[0,1],vs:{browInnerUp:[.3],eyeSquintLeft:[1],eyeSquintRight:[1],eyesClosed:[.6],jawOpen:[.3],mouthDimpleLeft:[.2],mouthDimpleRight:[.2],mouthPressLeft:[.5],mouthPressRight:[.5],mouthShrugUpper:[.4],mouthSmile:[.7],mouthUpperUpLeft:[.3],mouthUpperUpRight:[.3],noseSneerLeft:[.4],noseSneerRight:[.4]}},"🤣":{link:"😂"},"😅":{link:"😂"},"😉":{dt:[500,200,500,500],rescale:[0,0,0,1],vs:{mouthSmile:[.5],mouthOpen:[.2],mouthSmileLeft:[0,.5,0],eyeBlinkLeft:[0,.7,0],eyeBlinkRight:[0,0,0],bodyRotateX:[.05,.05,.05,0],bodyRotateZ:[-.05,-.05,-.05,0],browDownLeft:[0,.7,0],cheekSquintLeft:[0,.7,0],eyeSquintLeft:[0,1,0],eyesClosed:[0]}},"😭":{dt:[1e3,1e3],rescale:[0,1],vs:{browInnerUp:[1],eyeSquintLeft:[1],eyeSquintRight:[1],eyesClosed:[.1],jawOpen:[0],mouthFrownLeft:[1],mouthFrownRight:[1],mouthOpen:[.5],mouthPucker:[.5],mouthUpperUpLeft:[.6],mouthUpperUpRight:[.6]}},"🥺":{dt:[1e3,1e3],rescale:[0,1],vs:{browDownLeft:[.2],browDownRight:[.2],browInnerUp:[1],eyeWideLeft:[.9],eyeWideRight:[.9],eyesClosed:[.1],mouthClose:[.2],mouthFrownLeft:[1],mouthFrownRight:[1],mouthPressLeft:[.4],mouthPressRight:[.4],mouthPucker:[1],mouthRollLower:[.6],mouthRollUpper:[.2],mouthUpperUpLeft:[.8],mouthUpperUpRight:[.8]}},"😞":{dt:[1e3,1e3],rescale:[0,1],vs:{browInnerUp:[.7],eyeSquintLeft:[1],eyeSquintRight:[1],eyesClosed:[.5],bodyRotateX:[.3],mouthClose:[.2],mouthFrownLeft:[1],mouthFrownRight:[1],mouthPucker:[1],mouthRollLower:[1],mouthShrugLower:[.2],mouthUpperUpLeft:[.8],mouthUpperUpRight:[.8]}},"😔":{dt:[1e3,1e3],rescale:[0,1],vs:{browInnerUp:[1],eyeSquintLeft:[1],eyeSquintRight:[1],eyesClosed:[.5],bodyRotateX:[.3],mouthClose:[.2],mouthFrownLeft:[1],mouthFrownRight:[1],mouthPressLeft:[.4],mouthPressRight:[.4],mouthPucker:[1],mouthRollLower:[.6],mouthRollUpper:[.2],mouthUpperUpLeft:[.8],mouthUpperUpRight:[.8]}},"😳":{dt:[1e3,1e3],rescale:[0,1],vs:{browInnerUp:[1],eyeWideLeft:[.5],eyeWideRight:[.5],eyesRotateY:[.05],eyesRotateX:[.05],mouthClose:[.2],mouthFunnel:[.5],mouthPucker:[.4],mouthRollLower:[.4],mouthRollUpper:[.4]}},"☹️":{dt:[500,1500],rescale:[0,1],vs:{mouthFrownLeft:[1],mouthFrownRight:[1],mouthPucker:[.1],mouthRollLower:[.8]}},"😚":{dt:[500,1e3,1e3],rescale:[0,1,0],vs:{browInnerUp:[.6],eyeBlinkLeft:[1],eyeBlinkRight:[1],eyeSquintLeft:[1],eyeSquintRight:[1],mouthPucker:[0,.5],noseSneerLeft:[0,.7],noseSneerRight:[0,.7],viseme_U:[0,1]}},"😘":{dt:[500,500,200,500],rescale:[0,0,0,1],vs:{browInnerUp:[.6],eyeBlinkLeft:[0,0,1,0],eyeBlinkRight:[0],eyesRotateY:[0],bodyRotateY:[0],bodyRotateX:[0,.05,.05,0],bodyRotateZ:[0,-.05,-.05,0],eyeSquintLeft:[1],eyeSquintRight:[1],mouthPucker:[0,.5,0],noseSneerLeft:[0,.7],noseSneerRight:[.7],viseme_U:[0,1]}},"🥰":{dt:[1e3,1e3],rescale:[0,1],vs:{browInnerUp:[.6],eyeSquintLeft:[1],eyeSquintRight:[1],mouthSmile:[.7],noseSneerLeft:[.7],noseSneerRight:[.7]}},"😍":{dt:[1e3,1e3],rescale:[0,1],vs:{browInnerUp:[.6],jawOpen:[.1],mouthDimpleLeft:[.2],mouthDimpleRight:[.2],mouthOpen:[.3],mouthPressLeft:[.3],mouthPressRight:[.3],mouthRollLower:[.4],mouthShrugUpper:[.4],mouthSmile:[.7],mouthUpperUpLeft:[.3],mouthUpperUpRight:[.3],noseSneerLeft:[.4],noseSneerRight:[.4]}},"🤩":{link:"😍"},"😡":{dt:[1e3,1500],rescale:[0,1],vs:{browDownLeft:[1],browDownRight:[1],eyesLookUp:[.2],jawForward:[.3],mouthFrownLeft:[1],mouthFrownRight:[1],bodyRotateX:[.15]}},"😠":{dt:[1e3,1500],rescale:[0,1],vs:{browDownLeft:[1],browDownRight:[1],eyesLookUp:[.2],jawForward:[.3],mouthFrownLeft:[1],mouthFrownRight:[1],bodyRotateX:[.15]}},"🤬":{link:"😠"},"😒":{dt:[1e3,1e3],rescale:[0,1],vs:{eyeContact:[0],browDownRight:[.1],browInnerUp:[.7],browOuterUpRight:[.2],eyeLookInRight:[.7],eyeLookOutLeft:[.7],eyeSquintLeft:[1],eyeSquintRight:[.8],eyesRotateY:[.7],mouthFrownLeft:[1],mouthFrownRight:[1],mouthLeft:[.2],mouthPucker:[.5],mouthRollLower:[.2],mouthRollUpper:[.2],mouthShrugLower:[.2],mouthShrugUpper:[.2],mouthStretchLeft:[.5]}},"😱":{dt:[500,1500],rescale:[0,1],vs:{browInnerUp:[.8],eyeWideLeft:[.5],eyeWideRight:[.5],jawOpen:[.7],mouthFunnel:[.5]}},"😬":{dt:[500,1500],rescale:[0,1],vs:{browDownLeft:[1],browDownRight:[1],browInnerUp:[1],mouthDimpleLeft:[.5],mouthDimpleRight:[.5],mouthLowerDownLeft:[1],mouthLowerDownRight:[1],mouthPressLeft:[.4],mouthPressRight:[.4],mouthPucker:[.5],mouthSmile:[.1],mouthSmileLeft:[.2],mouthSmileRight:[.2],mouthStretchLeft:[1],mouthStretchRight:[1],mouthUpperUpLeft:[1],mouthUpperUpRight:[1]}},"🙄":{dt:[500,1500],rescale:[0,1],vs:{browInnerUp:[.8],eyeWideLeft:[1],eyeWideRight:[1],eyesRotateX:[-.8],bodyRotateX:[.15],mouthPucker:[.5],mouthRollLower:[.6],mouthRollUpper:[.5],mouthShrugLower:[0],mouthSmile:[0]}},"🤔":{dt:[500,1500],rescale:[0,1],vs:{browDownLeft:[1],browOuterUpRight:[1],eyeSquintLeft:[.6],mouthFrownLeft:[.7],mouthFrownRight:[.7],mouthLowerDownLeft:[.3],mouthPressRight:[.4],mouthPucker:[.1],mouthRight:[.5],mouthRollLower:[.5],mouthRollUpper:[.2],handRight:[{x:.1,y:.1,z:.1,d:1e3},{d:1e3}],handFistRight:[.1]}},"👀":{dt:[500,1500],rescale:[0,1],vs:{eyesRotateY:[-.8]}},"😴":{dt:[5e3,5e3],rescale:[0,1],vs:{eyeBlinkLeft:[1],eyeBlinkRight:[1],bodyRotateX:[.2],bodyRotateZ:[.1]}},"✋":{dt:[300,2e3],rescale:[0,1],vs:{mouthSmile:[.5],gesture:[["handup",2,!0],null]}},"🤚":{dt:[300,2e3],rescale:[0,1],vs:{mouthSmile:[.5],gesture:[["handup",2],null]}},"👋":{link:"✋"},"👍":{dt:[300,2e3],rescale:[0,1],vs:{mouthSmile:[.5],gesture:[["thumbup",2],null]}},"👎":{dt:[300,2e3],rescale:[0,1],vs:{browDownLeft:[1],browDownRight:[1],eyesLookUp:[.2],jawForward:[.3],mouthFrownLeft:[1],mouthFrownRight:[1],bodyRotateX:[.15],gesture:[["thumbdown",2],null]}},"👌":{dt:[300,2e3],rescale:[0,1],vs:{mouthSmile:[.5],gesture:[["ok",2],null]}},"🤷♂️":{dt:[1e3,1500],rescale:[0,1],vs:{gesture:[["shrug",2],null]}},"🤷♀️":{link:"🤷♂️"},"🤷":{link:"🤷♂️"},"🙏":{dt:[1500,300,1e3],rescale:[0,1,0],vs:{eyeBlinkLeft:[0,1],eyeBlinkRight:[0,1],bodyRotateX:[0],bodyRotateZ:[.1],gesture:[["namaste",2],null]}},yes:{dt:[[200,500],[200,500],[200,500],[200,500]],vs:{headMove:[0],headRotateX:[[.1,.2],.1,[.1,.2],0],headRotateZ:[[-.2,.2]]}},no:{dt:[[200,500],[200,500],[200,500],[200,500],[200,500]],vs:{headMove:[0],headRotateY:[[-.1,-.05],[.05,.1],[-.1,-.05],[.05,.1],0],headRotateZ:[[-.2,.2]]}}},this.mtAvatar={},this.mtCustoms=["handFistLeft","handFistRight","bodyRotateX","bodyRotateY","bodyRotateZ","headRotateX","headRotateY","headRotateZ","chestInhale"],this.mtEasingDefault=this.sigmoidFactory(5),this.mtAccDefault=.01,this.mtAccExceptions={eyeBlinkLeft:.1,eyeBlinkRight:.1,eyeLookOutLeft:.1,eyeLookInLeft:.1,eyeLookOutRight:.1,eyeLookInRight:.1},this.mtMaxVDefault=5,this.mtMaxVExceptions={bodyRotateX:1,bodyRotateY:1,bodyRotateZ:1},this.mtBaselineDefault=0,this.mtBaselineExceptions={bodyRotateX:null,bodyRotateY:null,bodyRotateZ:null,eyeLookOutLeft:null,eyeLookInLeft:null,eyeLookOutRight:null,eyeLookInRight:null,eyesLookDown:null,eyesLookUp:null},this.mtMinDefault=0,this.mtMinExceptions={bodyRotateX:-1,bodyRotateY:-1,bodyRotateZ:-1,headRotateX:-1,headRotateY:-1,headRotateZ:-1},this.mtMaxDefault=1,this.mtMaxExceptions={},this.mtLimits={eyeBlinkLeft:a=>Math.max(a,(this.mtAvatar.eyesLookDown.value+this.mtAvatar.browDownLeft.value)/2),eyeBlinkRight:a=>Math.max(a,(this.mtAvatar.eyesLookDown.value+this.mtAvatar.browDownRight.value)/2)},this.mtOnchange={eyesLookDown:()=>{this.mtAvatar.eyeBlinkLeft.needsUpdate=!0,this.mtAvatar.eyeBlinkRight.needsUpdate=!0},browDownLeft:()=>{this.mtAvatar.eyeBlinkLeft.needsUpdate=!0},browDownRight:()=>{this.mtAvatar.eyeBlinkRight.needsUpdate=!0}},this.mtRandomized=["mouthDimpleLeft","mouthDimpleRight","mouthLeft","mouthPressLeft","mouthPressRight","mouthStretchLeft","mouthStretchRight","mouthShrugLower","mouthShrugUpper","noseSneerLeft","noseSneerRight","mouthRollLower","mouthRollUpper","browDownLeft","browDownRight","browOuterUpLeft","browOuterUpRight","cheekPuff","cheekSquintLeft","cheekSquintRight"],this.mtExtras=[{key:"mouthOpen",mix:{jawOpen:.5}},{key:"mouthSmile",mix:{mouthSmileLeft:.8,mouthSmileRight:.8}},{key:"eyesClosed",mix:{eyeBlinkLeft:1,eyeBlinkRight:1}},{key:"eyesLookUp",mix:{eyeLookUpLeft:1,eyeLookUpRight:1}},{key:"eyesLookDown",mix:{eyeLookDownLeft:1,eyeLookDownRight:1}}],this.animQueue=[],this.animClips=[],this.animPoses=[],this.animFrameDur=1e3/this.opt.modelFPS,this.animClock=0,this.animSlowdownRate=1,this.animTimeLast=0,this.easing=this.sigmoidFactory(5),this.lipsync={},this.opt.lipsyncModules.forEach(a=>{this.lipsyncGetProcessor(a)}),this.visemeNames=["aa","E","I","O","U","PP","SS","TH","DD","FF","kk","nn","RR","CH","sil"],this.segmenter=new Intl.Segmenter("en",{granularity:"grapheme"}),this.initAudioGraph(),this.audioPlaylist=[],this.volumeFrequencyData=new Uint8Array(16),this.volumeMax=0,this.volumeHeadBase=0,this.volumeHeadTarget=0,this.volumeHeadCurrent=0,this.volumeHeadVelocity=.15,this.volumeHeadEasing=this.sigmoidFactory(3),this.isListening=!1,this.listeningAnalyzer=null,this.listeningActive=!1,this.listeningVolume=0,this.listeningSilenceThresholdLevel=this.opt.listeningSilenceThresholdLevel,this.listeningSilenceThresholdMs=this.opt.listeningSilenceThresholdMs,this.listeningSilenceDurationMax=this.opt.listeningSilenceDurationMax,this.listeningActiveThresholdLevel=this.opt.listeningActiveThresholdLevel,this.listeningActiveThresholdMs=this.opt.listeningActiveThresholdMs,this.listeningActiveDurationMax=this.opt.listeningActiveDurationMax,this.listeningTimer=0,this.listeningTimerTotal=0,this.dracoEnabled=this.opt.dracoEnabled,this.dracoDecoderPath=this.opt.dracoDecoderPath;const o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";this.b64Lookup=typeof Uint8Array>"u"?[]:new Uint8Array(256);for(let a=0;a<o.length;a++)this.b64Lookup[o.charCodeAt(a)]=a;if(this.stateName="idle",this.speechQueue=[],this.isSpeaking=!1,this.isListening=!1,this.audioStartTime=null,this.currentAudioItem=null,this.pausedAudioData=null,this.opt.ttsEndpoint){let a=new Audio;if(a.canPlayType("audio/ogg"))this.ttsAudioEncoding="OGG-OPUS";else if(a.canPlayType("audio/mp3"))this.ttsAudioEncoding="MP3";else throw new Error("There was no support for either OGG or MP3 audio.")}if(this.isAvatarOnly=this.opt.avatarOnly,this.isAvatarOnly)this.scene=this.opt.avatarOnlyScene,this.camera=this.opt.avatarOnlyCamera;else{this.renderer=new A.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=A.SRGBColorSpace,this.renderer.toneMapping=A.ACESFilmicToneMapping,this.renderer.shadowMap.enabled=!1,this.nodeAvatar.appendChild(this.renderer.domElement),this.camera=new A.PerspectiveCamera(10,this.nodeAvatar.clientWidth/this.nodeAvatar.clientHeight,.1,2e3),this.scene=new A.Scene,this.lightAmbient=new A.AmbientLight(new A.Color(this.opt.lightAmbientColor),this.opt.lightAmbientIntensity),this.lightDirect=new A.DirectionalLight(new A.Color(this.opt.lightDirectColor),this.opt.lightDirectIntensity),this.lightSpot=new A.SpotLight(new A.Color(this.opt.lightSpotColor),this.opt.lightSpotIntensity,0,this.opt.lightSpotDispersion),this.setLighting(this.opt);const a=new A.PMREMGenerator(this.renderer);a.compileEquirectangularShader(),this.scene.environment=a.fromScene(new xt.RoomEnvironment).texture,this.resizeobserver=new ResizeObserver(this.onResize.bind(this)),this.resizeobserver.observe(this.nodeAvatar),this.controls=new gt.OrbitControls(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}this.ikMesh=new A.SkinnedMesh;const s={LeftShoulder:null,LeftArm:"LeftShoulder",LeftForeArm:"LeftArm",LeftHand:"LeftForeArm",LeftHandMiddle1:"LeftHand",RightShoulder:null,RightArm:"RightShoulder",RightForeArm:"RightArm",RightHand:"RightForeArm",RightHandMiddle1:"RightHand"},i=[];Object.entries(s).forEach((a,c)=>{const l=new A.Bone;l.name=a[0],a[1]?this.ikMesh.getObjectByName(a[1]).add(l):this.ikMesh.add(l),i.push(l)}),this.ikMesh.bind(new A.Skeleton(i)),this.dynamicbones=new Lt,this.isStreaming=!1,this.streamWorkletNode=null,this.streamAudioStartTime=null,this.streamWaitForAudioChunks=!0,this.streamLipsyncLang=null,this.streamLipsyncType="visemes",this.streamLipsyncQueue=[]}initAudioGraph(n=null){if(this.audioCtx&&this.audioCtx.state!=="closed"&&this.audioCtx.close(),n?this.audioCtx=new AudioContext({sampleRate:n}):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=.1,this.audioAnalyzerNode.minDecibels=-70,this.audioAnalyzerNode.maxDecibels=-10,this.audioAnalyzer=new St(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(this.opt.mixerGainSpeech,this.opt.mixerGainBackground),this.workletLoaded=!1,this.streamWorkletNode){try{this.streamWorkletNode.port.postMessage({type:"stop"}),this.streamWorkletNode.disconnect(),this.isStreaming=!1}catch(e){console.error("Error disconnecting streamWorkletNode:",e)}this.streamWorkletNode=null}}valueFn(n){return typeof n=="function"?n():n}deepCopy(n,e=null){const t=JSON.parse(JSON.stringify(n));return e&&typeof e=="function"&&e(t),t}b64ToArrayBuffer(n){let e=3*n.length/4;n[n.length-1]==="="&&(e--,n[n.length-2]==="="&&e--);const t=new ArrayBuffer(e),o=new Uint8Array(t);let s,i=0,a,c,l,u;for(s=0;s<n.length;s+=4)a=this.b64Lookup[n.charCodeAt(s)],c=this.b64Lookup[n.charCodeAt(s+1)],l=this.b64Lookup[n.charCodeAt(s+2)],u=this.b64Lookup[n.charCodeAt(s+3)],o[i++]=a<<2|c>>4,o[i++]=(c&15)<<4|l>>2,o[i++]=(l&3)<<6|u&63;return t}concatArrayBuffers(n){if(n.length===1)return n[0];let e=0;for(let i=0;i<n.length;i++)e+=n[i].byteLength;let t=new ArrayBuffer(e),o=new Uint8Array(t),s=0;for(let i=0;i<n.length;i++)o.set(new Uint8Array(n[i]),s),s+=n[i].byteLength;return t}pcmToAudioBuffer(n){const e=new Int16Array(n),t=new Float32Array(e.length);for(let s=0;s<e.length;s++)t[s]=e[s]>=32768?-(65536-e[s])/32768:e[s]/32767;const o=this.audioCtx.createBuffer(1,t.length,this.opt.pcmSampleRate);return o.copyToChannel(t,0,0),o}propsToThreeObjects(n){const e={};for(let[t,o]of Object.entries(n)){const s=t.split(".");let i=Array.isArray(o.x)?this.gaussianRandom(...o.x):o.x,a=Array.isArray(o.y)?this.gaussianRandom(...o.y):o.y,c=Array.isArray(o.z)?this.gaussianRandom(...o.z):o.z;s[1]==="position"||s[1]==="scale"?e[t]=new A.Vector3(i,a,c):s[1]==="rotation"?(t=s[0]+".quaternion",e[t]=new A.Quaternion().setFromEuler(new A.Euler(i,a,c,"XYZ")).normalize()):s[1]==="quaternion"&&(e[t]=new A.Quaternion(i,a,c,o.w).normalize())}return e}clearThree(n){for(;n.children.length;)this.clearThree(n.children[0]),n.remove(n.children[0]);n.geometry&&n.geometry.dispose(),n.material&&(Object.keys(n.material).forEach(e=>{n.material[e]&&n.material[e]!==null&&typeof n.material[e].dispose=="function"&&n.material[e].dispose()}),n.material.dispose())}addMixedMorphTarget(n,e,t,o=!1){n.forEach(s=>{if(!o&&s.morphTargetDictionary.hasOwnProperty(e))return;const i=s.geometry;let a=null,c=null;for(const[l,u]of Object.entries(t))if(s.morphTargetDictionary.hasOwnProperty(l)){const r=s.morphTargetDictionary[l],h=i.morphAttributes.position[r],d=i.morphAttributes.normal?.[r];a||(a=new A.Float32BufferAttribute(h.count*3,3),d&&(c=new A.Float32BufferAttribute(h.count*3,3)));for(let g=0;g<h.count;g++){const R=a.getX(g)+h.getX(g)*u,x=a.getY(g)+h.getY(g)*u,w=a.getZ(g)+h.getZ(g)*u;a.setXYZ(g,R,x,w)}if(d)for(let g=0;g<h.count;g++){const R=c.getX(g)+d.getX(g)*u,x=c.getY(g)+d.getY(g)*u,w=c.getZ(g)+d.getZ(g)*u;c.setXYZ(g,R,x,w)}}if(a){i.morphAttributes.position.push(a),c&&i.morphAttributes.normal.push(c);const l=i.morphAttributes.position.length-1;s.morphTargetInfluences[l]=0,s.morphTargetDictionary[e]=l}})}async showAvatar(n,e=null){if(!n||!n.hasOwnProperty("url"))throw new Error("Invalid parameter. The avatar must have at least 'url' specified.");const t=new ft.GLTFLoader;if(this.dracoEnabled){const l=new yt.DRACOLoader;l.setDecoderPath(this.dracoDecoderPath),t.setDRACOLoader(l)}let o=await t.loadAsync(n.url,e);const s=[this.opt.modelRoot];if(this.posePropNames.forEach(l=>s.push(l.split(".")[0])),s.forEach(l=>{if(!o.scene.getObjectByName(l))throw new Error("Avatar object "+l+" not found")}),this.stop(),this.avatar=n,this.bodyMovement=n.bodyMovement||"idle",this.movementIntensity=n.movementIntensity||.5,this.showFullAvatar=n.showFullAvatar||!1,this.fbxAnimationLoader=null,this.dynamicbones.dispose(),this.mixer=null,this.isAvatarOnly?this.armature&&this.clearThree(this.armature):this.armature&&this.clearThree(this.scene),this.armature=o.scene.getObjectByName(this.opt.modelRoot),this.armature.scale.setScalar(1),this.animations=o.animations,this.userData=o.userData,this.morphs=[],this.armature.traverse(l=>{l.morphTargetInfluences&&l.morphTargetInfluences.length&&l.morphTargetDictionary&&this.morphs.push(l),l.frustumCulled=!1}),this.morphs.length===0)throw new Error("Blend shapes not found");const i=new Set(this.mtCustoms);this.morphs.forEach(l=>{Object.keys(l.morphTargetDictionary).forEach(u=>i.add(u))}),this.mtExtras.forEach(l=>{i.has(l.key)||(this.addMixedMorphTarget(this.morphs,l.key,l.mix),i.add(l.key))});const a={};if(i.forEach(l=>{a[l]={fixed:null,realtime:null,system:null,systemd:null,newvalue:null,ref:null,min:this.mtMinExceptions.hasOwnProperty(l)?this.mtMinExceptions[l]:this.mtMinDefault,max:this.mtMaxExceptions.hasOwnProperty(l)?this.mtMaxExceptions[l]:this.mtMaxDefault,easing:this.mtEasingDefault,base:null,v:0,needsUpdate:!0,acc:(this.mtAccExceptions.hasOwnProperty(l)?this.mtAccExceptions[l]:this.mtAccDefault)/1e3,maxv:(this.mtMaxVExceptions.hasOwnProperty(l)?this.mtMaxVExceptions[l]:this.mtMaxVDefault)/1e3,limit:this.mtLimits.hasOwnProperty(l)?this.mtLimits[l]:null,onchange:this.mtOnchange.hasOwnProperty(l)?this.mtOnchange[l]:null,baseline:this.avatar.baseline?.hasOwnProperty(l)?this.avatar.baseline[l]:this.mtBaselineExceptions.hasOwnProperty(l)?this.mtBaselineExceptions[l]:this.mtBaselineDefault,ms:[],is:[]},a[l].value=a[l].baseline,a[l].applied=a[l].baseline;const u=this.mtAvatar[l];u&&["fixed","system","systemd","realtime","base","v","value","applied"].forEach(r=>{a[l][r]=u[r]}),this.morphs.forEach(r=>{const h=r.morphTargetDictionary[l];h!==void 0&&(a[l].ms.push(r.morphTargetInfluences),a[l].is.push(h),r.morphTargetInfluences[h]=a[l].applied)})}),this.mtAvatar=a,this.poseAvatar={props:{}},this.posePropNames.forEach(l=>{const u=l.split("."),r=this.armature.getObjectByName(u[0]);this.poseAvatar.props[l]=r[u[1]],this.poseBase.props.hasOwnProperty(l)?this.poseAvatar.props[l].copy(this.poseBase.props[l]):this.poseBase.props[l]=this.poseAvatar.props[l].clone(),this.poseDelta.props.hasOwnProperty(l)&&!this.poseTarget.props.hasOwnProperty(l)&&(this.poseTarget.props[l]=this.poseAvatar.props[l].clone()),this.poseTarget.props[l].t=this.animClock,this.poseTarget.props[l].d=2e3}),this.ikMesh.traverse(l=>{l.isBone&&l.position.copy(this.armature.getObjectByName(l.name).position)}),this.isAvatarOnly?this.scene&&this.scene.add(this.armature):(this.scene.add(o.scene),this.scene.add(this.lightAmbient),this.scene.add(this.lightDirect),this.scene.add(this.lightSpot),this.lightSpot.target=this.armature.getObjectByName("Head")),n.hasOwnProperty("modelDynamicBones"))try{this.dynamicbones.setup(this.scene,this.armature,n.modelDynamicBones)}catch(l){console.error("Dynamic bones setup failed: "+l)}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");const c=new A.Vector3;this.objectLeftEye.getWorldPosition(c),this.avatarHeight=c.y+.2,this.viewName||this.setView(this.opt.cameraView),this.setMood(this.avatar.avatarMood||this.moodName||this.opt.avatarMood),this.avatar.body==="M"&&this.poseTemplates.wide&&(this.poseName="wide",this.setPoseFromTemplate(this.poseTemplates.wide,0)),this.initializeFBXAnimationLoader(),this.bodyMovement&&this.bodyMovement!=="idle"&&this.applyBodyMovementAnimation(),this.start()}getViewNames(){return["full","mid","upper","head"]}getView(){return this.viewName}setView(n,e=null){if(n=n||this.viewName,n!=="full"&&n!=="upper"&&n!=="head"&&n!=="mid")return;if(!this.armature){this.opt.cameraView=n;return}if(this.viewName=n||this.viewName,e=e||{},this.isAvatarOnly)return;const t=e.hasOwnProperty("cameraX")?e.cameraX:this.opt.cameraX,o=e.hasOwnProperty("cameraY")?e.cameraY:this.opt.cameraY,s=e.hasOwnProperty("cameraDistance")?e.cameraDistance:this.opt.cameraDistance,i=e.hasOwnProperty("cameraRotateX")?e.cameraRotateX:this.opt.cameraRotateX,a=e.hasOwnProperty("cameraRotateY")?e.cameraRotateY:this.opt.cameraRotateY,c=this.camera.fov*(Math.PI/180);let l=-t*Math.tan(c/2),u=(1-o)*Math.tan(c/2),r=s;switch(this.viewName){case"head":r+=2,u=u*r+4*this.avatarHeight/5;break;case"upper":r+=4.5,u=u*r+2*this.avatarHeight/3;break;case"mid":r+=8,u=u*r+this.avatarHeight/3;break;default:r+=12,u=u*r}l=l*r,this.controlsEnd=new A.Vector3(l,u,0),this.cameraEnd=new A.Vector3(l,u,r).applyEuler(new A.Euler(i,a,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}setLighting(n){this.isAvatarOnly||(n=n||{},n.hasOwnProperty("lightAmbientColor")&&this.lightAmbient.color.set(new A.Color(n.lightAmbientColor)),n.hasOwnProperty("lightAmbientIntensity")&&(this.lightAmbient.intensity=n.lightAmbientIntensity,this.lightAmbient.visible=n.lightAmbientIntensity!==0),n.hasOwnProperty("lightDirectColor")&&this.lightDirect.color.set(new A.Color(n.lightDirectColor)),n.hasOwnProperty("lightDirectIntensity")&&(this.lightDirect.intensity=n.lightDirectIntensity,this.lightDirect.visible=n.lightDirectIntensity!==0),n.hasOwnProperty("lightDirectPhi")&&n.hasOwnProperty("lightDirectTheta")&&this.lightDirect.position.setFromSphericalCoords(2,n.lightDirectPhi,n.lightDirectTheta),n.hasOwnProperty("lightSpotColor")&&this.lightSpot.color.set(new A.Color(n.lightSpotColor)),n.hasOwnProperty("lightSpotIntensity")&&(this.lightSpot.intensity=n.lightSpotIntensity,this.lightSpot.visible=n.lightSpotIntensity!==0),n.hasOwnProperty("lightSpotPhi")&&n.hasOwnProperty("lightSpotTheta")&&(this.lightSpot.position.setFromSphericalCoords(2,n.lightSpotPhi,n.lightSpotTheta),this.lightSpot.position.add(new A.Vector3(0,1.5,0))),n.hasOwnProperty("lightSpotDispersion")&&(this.lightSpot.angle=n.lightSpotDispersion))}render(){this.isRunning&&!this.isAvatarOnly&&this.renderer&&this.renderer.render(this.scene,this.camera)}onResize(){!this.isAvatarOnly&&this.renderer&&(this.camera.aspect=this.nodeAvatar.clientWidth/this.nodeAvatar.clientHeight,this.camera.updateProjectionMatrix(),this.renderer.setSize(this.nodeAvatar.clientWidth,this.nodeAvatar.clientHeight),this.controls.update(),this.render())}updatePoseBase(n){for(const[e,t]of Object.entries(this.poseTarget.props)){const o=this.poseAvatar.props[e];if(o){let s=(n-t.t)/t.d;s>1||!this.poseBase.props.hasOwnProperty(e)?o.copy(t):o.isQuaternion?o.copy(this.poseBase.props[e].slerp(t,this.easing(s))):o.isVector3&&o.copy(this.poseBase.props[e].lerp(t,this.easing(s)))}}}applyShoulderAdjustment(){}applyShoulderAdjustmentToBones(){}updatePoseDelta(){for(const[n,e]of Object.entries(this.poseDelta.props)){if(e.x===0&&e.y===0&&e.z===0)continue;oe.set(e.x,e.y,e.z);const t=this.poseAvatar.props[n];t.isQuaternion?(ue.setFromEuler(oe),t.multiply(ue)):t.isVector3&&t.add(oe)}}updateMorphTargets(n){for(let[e,t]of Object.entries(this.mtAvatar)){if(!t.needsUpdate)continue;let o=null,s=null;if(t.fixed!==null){if(o=t.fixed,t.system=null,t.systemd=null,t.newvalue=null,t.ref&&t.ref.hasOwnProperty(e)&&delete t.ref[e],t.ref=null,t.base=null,t.value===o){t.needsUpdate=!1;continue}}else t.realtime!==null?(t.ref=null,t.base=null,s=t.realtime):t.system!==null?(o=t.system,t.newvalue=null,t.ref&&t.ref.hasOwnProperty(e)&&delete t.ref[e],t.ref=null,t.base=null,t.systemd!==null?t.systemd===0?(o=null,t.system=null,t.systemd=null):(t.systemd-=n,t.systemd<0&&(t.systemd=0),t.value===o&&(o=null)):t.value===o&&(o=null,t.system=null)):t.newvalue!==null?(t.ref=null,t.base=null,s=t.newvalue,t.newvalue=null):t.base!==null?(o=t.base,t.ref=null,t.value===o&&(o=null,t.base=null,t.needsUpdate=!1)):(t.ref=null,t.baseline!==null&&t.value!==t.baseline?(o=t.baseline,t.base=t.baseline):t.needsUpdate=!1);if(o!==null){let i=o-t.value;i>=0?i<.005?(s=o,t.v=0):(t.v<t.maxv&&(t.v+=t.acc*n),t.v>=0?s=t.value+i*(1-Math.exp(-t.v*n)):s=t.value+t.v*n*(1-Math.exp(t.v*n))):i>-.005?(s=o,t.v=0):(t.v>-t.maxv&&(t.v-=t.acc*n),t.v>=0?s=t.value+t.v*n*(1-Math.exp(-t.v*n)):s=t.value+i*(1-Math.exp(t.v*n)))}if(t.limit!==null){if(s!==null&&s!==t.value&&(t.value=s,t.onchange!==null&&t.onchange(s)),s=t.limit(t.value),s===t.applied)continue}else{if(s===null||s===t.value)continue;t.value=s,t.onchange!==null&&t.onchange(s)}switch(t.applied=s,t.applied<t.min&&(t.applied=t.min),t.applied>t.max&&(t.applied=t.max),e){case"headRotateX":this.poseDelta.props["Head.quaternion"].x=t.applied+this.mtAvatar.bodyRotateX.applied;break;case"headRotateY":this.poseDelta.props["Head.quaternion"].y=t.applied+this.mtAvatar.bodyRotateY.applied;break;case"headRotateZ":this.poseDelta.props["Head.quaternion"].z=t.applied+this.mtAvatar.bodyRotateZ.applied;break;case"bodyRotateX":this.poseDelta.props["Head.quaternion"].x=t.applied+this.mtAvatar.headRotateX.applied,this.poseDelta.props["Spine1.quaternion"].x=t.applied/2,this.poseDelta.props["Spine.quaternion"].x=t.applied/8,this.poseDelta.props["Hips.quaternion"].x=t.applied/24;break;case"bodyRotateY":this.poseDelta.props["Head.quaternion"].y=t.applied+this.mtAvatar.headRotateY.applied,this.poseDelta.props["Spine1.quaternion"].y=t.applied/2,this.poseDelta.props["Spine.quaternion"].y=t.applied/2,this.poseDelta.props["Hips.quaternion"].y=t.applied/4,this.poseDelta.props["LeftUpLeg.quaternion"].y=t.applied/2,this.poseDelta.props["RightUpLeg.quaternion"].y=t.applied/2,this.poseDelta.props["LeftLeg.quaternion"].y=t.applied/4,this.poseDelta.props["RightLeg.quaternion"].y=t.applied/4;break;case"bodyRotateZ":this.poseDelta.props["Head.quaternion"].z=t.applied+this.mtAvatar.headRotateZ.applied,this.poseDelta.props["Spine1.quaternion"].z=t.applied/12,this.poseDelta.props["Spine.quaternion"].z=t.applied/12,this.poseDelta.props["Hips.quaternion"].z=t.applied/24;break;case"handFistLeft":case"handFistRight":const i=e.substring(8);["HandThumb","HandIndex","HandMiddle","HandRing","HandPinky"].forEach((u,r)=>{r===0?(this.poseDelta.props[i+u+"1.quaternion"].x=0,this.poseDelta.props[i+u+"2.quaternion"].z=(i==="Left"?-1:1)*t.applied,this.poseDelta.props[i+u+"3.quaternion"].z=(i==="Left"?-1:1)*t.applied):(this.poseDelta.props[i+u+"1.quaternion"].x=t.applied,this.poseDelta.props[i+u+"2.quaternion"].x=1.5*t.applied,this.poseDelta.props[i+u+"3.quaternion"].x=1.5*t.applied)});break;case"chestInhale":const a=t.applied/20,c={x:a,y:a/2,z:3*a},l={x:1/(1+a)-1,y:1/(1+a/2)-1,z:1/(1+3*a)-1};this.poseDelta.props["Spine1.scale"]=c,this.poseDelta.props["Neck.scale"]=l,this.poseDelta.props["LeftArm.scale"]=l,this.poseDelta.props["RightArm.scale"]=l;break;default:for(let u=0,r=t.ms.length;u<r;u++)t.ms[u][t.is[u]]=t.applied}}}getPoseString(n,e=1e3){let t="{";return Object.entries(n).forEach((o,s)=>{const i=o[0].split(".");if(i[1]==="position"||i[1]==="rotation"||i[1]==="quaternion"){const a=i[1]==="quaternion"?i[0]+".rotation":o[0],c=o[1].isQuaternion?new A.Euler().setFromQuaternion(o[1]):o[1];t+=(s?", ":"")+"'"+a+"':{",t+="x:"+Math.round(c.x*e)/e,t+=", y:"+Math.round(c.y*e)/e,t+=", z:"+Math.round(c.z*e)/e,t+="}"}}),t+="}",t}getPoseTemplateProp(n){const e=n.split(".");let t=e[0]+"."+(e[1]==="rotation"?"quaternion":e[1]);if(this.gesture&&this.gesture.hasOwnProperty(t))return this.gesture[t].clone();{let o=e[0]+"."+(e[1]==="quaternion"?"rotation":e[1]);this.poseWeightOnLeft||(o.startsWith("Left")?(o="Right"+o.substring(4),t="Right"+t.substring(4)):o.startsWith("Right")&&(o="Left"+o.substring(5),t="Left"+t.substring(5)));let s;if(this.poseTarget.template.props.hasOwnProperty(t)){const i={};i[t]=this.poseTarget.template.props[t],s=this.propsToThreeObjects(i)[t]}else if(this.poseTarget.template.props.hasOwnProperty(o)){const i={};i[o]=this.poseTarget.template.props[o],s=this.propsToThreeObjects(i)[t]}return s&&!this.poseWeightOnLeft&&s.isQuaternion&&(s.x*=-1,s.w*=-1),s}}mirrorPose(n){const e={};for(let[t,o]of Object.entries(n))o.isQuaternion&&(t.startsWith("Left")?t="Right"+t.substring(4):t.startsWith("Right")&&(t="Left"+t.substring(5)),o.x*=-1,o.w*=-1),e[t]=o.clone(),e[t].t=o.t,e[t].d=o.d;return e}poseFactory(n,e=2e3){const t={template:n,props:this.propsToThreeObjects(n.props)};for(const[o,s]of Object.entries(t.props)){if(this.opt.modelMovementFactor<1&&n.standing&&(o==="Hips.quaternion"||o==="Spine.quaternion"||o==="Spine1.quaternion"||o==="Spine2.quaternion"||o==="Neck.quaternion"||o==="LeftUpLeg.quaternion"||o==="LeftLeg.quaternion"||o==="RightUpLeg.quaternion"||o==="RightLeg.quaternion")){const i=this.poseStraight[o],a=s.angleTo(i);s.rotateTowards(i,(1-this.opt.modelMovementFactor)*a)}s.t=this.animClock,s.d=e}return t}setPoseFromTemplate(n,e=2e3){const t=n&&this.poseTarget&&this.poseTarget.template&&(this.poseTarget.template.standing&&n.lying||this.poseTarget.template.lying&&n.standing),o=n&&n===this.poseCurrentTemplate,s=this.poseWeightOnLeft;let i=t?1e3:e;if(t?(this.poseCurrentTemplate=this.poseTemplates.oneknee,setTimeout(()=>{this.setPoseFromTemplate(n,e)},i)):this.poseCurrentTemplate=n||this.poseCurrentTemplate,this.poseTarget=this.poseFactory(this.poseCurrentTemplate,i),this.poseWeightOnLeft=!0,(!o&&!s||o&&s)&&(this.poseTarget.props=this.mirrorPose(this.poseTarget.props),this.poseWeightOnLeft=!this.poseWeightOnLeft),this.gesture)for(let[a,c]of Object.entries(this.gesture))this.poseTarget.props.hasOwnProperty(a)&&(this.poseTarget.props[a].copy(c),this.poseTarget.props[a].t=c.t,this.poseTarget.props[a].d=c.d);Object.keys(this.poseDelta.props).forEach(a=>{this.poseTarget.props.hasOwnProperty(a)||(this.poseTarget.props[a]=this.poseBase.props[a].clone(),this.poseTarget.props[a].t=this.animClock,this.poseTarget.props[a].d=i)})}getValue(n){return this.mtAvatar[n]?.value}setValue(n,e,t=null){this.mtAvatar.hasOwnProperty(n)&&Object.assign(this.mtAvatar[n],{system:e,systemd:t,needsUpdate:!0})}getMoodNames(){return Object.keys(this.animMoods)}getMood(){return this.opt.avatarMood}setMood(n){if(n=(n||"").trim().toLowerCase(),!this.animMoods.hasOwnProperty(n))throw new Error("Unknown mood.");this.moodName=n,this.mood=this.animMoods[this.moodName];for(let e of Object.keys(this.mtAvatar)){let t=this.mtBaselineExceptions.hasOwnProperty(e)?this.mtBaselineExceptions[e]:this.mtBaselineDefault;this.mood.baseline.hasOwnProperty(e)?t=this.mood.baseline[e]:this.avatar.baseline?.hasOwnProperty(e)&&(t=this.avatar.baseline[e]),this.setBaselineValue(e,t)}this.mood.anims.forEach(e=>{let t=this.animQueue.findIndex(o=>o.template.name===e.name);t!==-1&&this.animQueue.splice(t,1),this.animQueue.push(this.animFactory(e,-1))})}async initializeFBXAnimationLoader(){try{const{FBXAnimationLoader:n}=await Promise.resolve().then(()=>require("./fbxAnimationLoader-CNrfhJRz.cjs"));this.fbxAnimationLoader=new n(this.armature)}catch(n){console.warn("FBX Animation Loader not available:",n),this.fbxAnimationLoader=null}}setBodyMovement(n){this.bodyMovement=n,this.avatar&&(this.avatar.bodyMovement=n),n==="idle"&&this.unlockAvatarPosition(),this.applyBodyMovementAnimation()}async applyBodyMovementAnimation(){if(!this.armature||!this.animQueue)return;if(this.animQueue=this.animQueue.filter(e=>!e.template.name.startsWith("bodyMovement")),this.bodyMovement==="idle"){this.fbxAnimationLoader&&this.fbxAnimationLoader.stopCurrentAnimation();return}if(this.fbxAnimationLoader)try{await this.fbxAnimationLoader.playGestureAnimation(this.bodyMovement,this.movementIntensity);return}catch{}const n=this.createBodyMovementAnimation(this.bodyMovement);if(n)try{const e=this.animFactory(n,!0);e&&e.ts&&e.ts.length>0?this.animQueue.push(e):(console.error("Invalid animation object created for:",this.bodyMovement),console.error("Animation object:",e))}catch(e){console.error("Error creating body movement animation:",e)}}lockAvatarPosition(){if(!this.armature){console.warn("Cannot lock position: armature not available");return}this.originalPosition||(this.originalPosition={x:this.armature.position.x,y:this.armature.position.y,z:this.armature.position.z}),this.lockedPosition={x:this.armature.position.x,y:this.armature.position.y,z:this.armature.position.z}}unlockAvatarPosition(){this.armature&&this.originalPosition?this.armature.position.set(this.originalPosition.x,this.originalPosition.y,this.originalPosition.z):this.armature&&this.armature.position.set(0,0,0),this.lockedPosition=null,this.originalPosition=null}maintainLockedPosition(){this.lockedPosition&&this.armature&&this.armature.position.set(this.lockedPosition.x,this.lockedPosition.y,this.lockedPosition.z)}createBodyMovementAnimation(n){const e=this.movementIntensity||.5,t={walking:{name:"bodyMovement_walking",delay:[500,2e3],dt:[800,1200],vs:{bodyRotateY:[-.1*e,.1*e,0],bodyRotateZ:[-.05*e,.05*e,0],bodyRotateX:[-.02*e,.02*e,0]}},prancing:{name:"bodyMovement_prancing",delay:[300,1e3],dt:[400,800],vs:{bodyRotateY:[-.15*e,.15*e,0],bodyRotateZ:[-.08*e,.08*e,0],bodyRotateX:[-.05*e,.05*e,0]}},gesturing:{name:"bodyMovement_gesturing",delay:[400,1500],dt:[600,1e3],vs:{bodyRotateY:[-.08*e,.08*e,0],bodyRotateZ:[-.03*e,.03*e,0]}},dancing:{name:"bodyMovement_dancing",delay:[200,600],dt:[400,800],vs:{bodyRotateY:[-.25*e,.25*e,0],bodyRotateZ:[-.15*e,.15*e,0],bodyRotateX:[-.1*e,.1*e,0]}},dancing2:{name:"bodyMovement_dancing2",delay:[150,500],dt:[300,700],vs:{bodyRotateY:[-.3*e,.3*e,0],bodyRotateZ:[-.2*e,.2*e,0],bodyRotateX:[-.12*e,.12*e,0]}},dancing3:{name:"bodyMovement_dancing3",delay:[100,400],dt:[200,600],vs:{bodyRotateY:[-.35*e,.35*e,0],bodyRotateZ:[-.25*e,.25*e,0],bodyRotateX:[-.15*e,.15*e,0]}},excited:{name:"bodyMovement_excited",delay:[200,600],dt:[300,700],vs:{bodyRotateY:[-.12*e,.12*e,0],bodyRotateZ:[-.06*e,.06*e,0],bodyRotateX:[-.04*e,.04*e,0]}},happy:{name:"bodyMovement_happy",delay:[300,800],dt:[500,1e3],vs:{bodyRotateY:[-.08*e,.08*e,0],bodyRotateZ:[-.04*e,.04*e,0],bodyRotateX:[-.02*e,.02*e,0]}},surprised:{name:"bodyMovement_surprised",delay:[100,300],dt:[200,500],vs:{bodyRotateY:[-.05*e,.05*e,0],bodyRotateZ:[-.03*e,.03*e,0],bodyRotateX:[-.01*e,.01*e,0]}},thinking:{name:"bodyMovement_thinking",delay:[800,2e3],dt:[1e3,1500],vs:{bodyRotateY:[-.06*e,.06*e,0],bodyRotateZ:[-.03*e,.03*e,0],bodyRotateX:[-.02*e,.02*e,0]}},nodding:{name:"bodyMovement_nodding",delay:[400,800],dt:[300,600],vs:{bodyRotateX:[-.1*e,.1*e,0],bodyRotateY:[-.02*e,.02*e,0]}},shaking:{name:"bodyMovement_shaking",delay:[200,400],dt:[150,300],vs:{bodyRotateY:[-.15*e,.15*e,0],bodyRotateZ:[-.05*e,.05*e,0]}},celebration:{name:"bodyMovement_celebration",delay:[100,300],dt:[200,500],vs:{bodyRotateY:[-.2*e,.2*e,0],bodyRotateZ:[-.1*e,.1*e,0],bodyRotateX:[-.08*e,.08*e,0]}},energetic:{name:"bodyMovement_energetic",delay:[150,400],dt:[250,500],vs:{bodyRotateY:[-.18*e,.18*e,0],bodyRotateZ:[-.12*e,.12*e,0],bodyRotateX:[-.08*e,.08*e,0]}},swaying:{name:"bodyMovement_swaying",delay:[600,1200],dt:[800,1e3],vs:{bodyRotateY:[-.1*e,.1*e,0],bodyRotateZ:[-.05*e,.05*e,0]}},bouncing:{name:"bodyMovement_bouncing",delay:[300,600],dt:[400,700],vs:{bodyRotateY:[-.05*e,.05*e,0]}}};if(n==="dancing"){const o=["dancing","dancing2","dancing3"],s=o[Math.floor(Math.random()*o.length)];return t[s]||t.dancing}return t[n]||null}playRandomDance(){const n=["dancing","dancing2","dancing3"],e=n[Math.floor(Math.random()*n.length)];this.setBodyMovement(e)}playReaction(n){["happy","surprised","thinking","nodding","shaking","celebration","energetic","swaying","bouncing"].includes(n)?(this.setBodyMovement(n),["surprised","nodding","shaking","celebration"].includes(n)&&setTimeout(()=>{this.setBodyMovement("idle")},3e3)):console.warn("Invalid reaction type:",n)}playCelebration(){this.playReaction("celebration"),setTimeout(()=>{this.playRandomDance()},2e3)}setMovementIntensity(n){this.movementIntensity=Math.max(0,Math.min(1,n)),this.avatar&&(this.avatar.movementIntensity=this.movementIntensity),this.fbxAnimationLoader&&this.fbxAnimationLoader.setIntensity(this.movementIntensity),this.applyBodyMovementAnimation()}setShowFullAvatar(n){this.showFullAvatar=n,this.avatar&&(this.avatar.showFullAvatar=n),n&&this.viewName!=="full"?this.setView("full"):!n&&this.viewName!=="upper"&&this.setView("upper")}getMorphTargetNames(){return["eyesRotateX","eyesRotateY",...Object.keys(this.mtAvatar)].sort()}getBaselineValue(n){if(n==="eyesRotateY"){const e=this.getBaselineValue("eyeLookOutLeft");if(e===void 0)return;const t=this.getBaselineValue("eyeLookInLeft");return t===void 0||this.getBaselineValue("eyeLookOutRight")===void 0||this.getBaselineValue("eyeLookInRight")===void 0?void 0:e-t}else if(n==="eyesRotateX"){const e=this.getBaselineValue("eyesLookDown");if(e===void 0)return;const t=this.getBaselineValue("eyesLookUp");return t===void 0?void 0:e-t}else return this.mtAvatar[n]?.baseline}setBaselineValue(n,e){n==="eyesRotateY"?(this.setBaselineValue("eyeLookOutLeft",e===null?null:e>0?e:0),this.setBaselineValue("eyeLookInLeft",e===null?null:e>0?0:-e),this.setBaselineValue("eyeLookOutRight",e===null?null:e>0?0:-e),this.setBaselineValue("eyeLookInRight",e===null?null:e>0?e:0)):n==="eyesRotateX"?(this.setBaselineValue("eyesLookDown",e===null?null:e>0?e:0),this.setBaselineValue("eyesLookUp",e===null?null:e>0?0:-e)):this.mtAvatar.hasOwnProperty(n)&&Object.assign(this.mtAvatar[n],{base:null,baseline:e,needsUpdate:!0})}getFixedValue(n){if(n==="eyesRotateY"){const e=this.getFixedValue("eyeLookOutLeft");if(e===null)return null;const t=this.getFixedValue("eyeLookInLeft");return t===null||this.getFixedValue("eyeLookOutRight")===null||this.getFixedValue("eyeLookInRight")===null?null:e-t}else if(n==="eyesRotateX"){const e=this.getFixedValue("eyesLookDown");if(e===null)return null;const t=this.getFixedValue("eyesLookUp");return t===null?null:e-t}else return this.mtAvatar[n]?.fixed}setFixedValue(n,e,t=null){n==="eyesRotateY"?(this.setFixedValue("eyeLookOutLeft",e===null?null:e>0?e:0,t),this.setFixedValue("eyeLookInLeft",e===null?null:e>0?0:-e,t),this.setFixedValue("eyeLookOutRight",e===null?null:e>0?0:-e,t),this.setFixedValue("eyeLookInRight",e===null?null:e>0?e:0,t)):n==="eyesRotateX"?(this.setFixedValue("eyesLookDown",e===null?null:e>0?e:0,t),this.setFixedValue("eyesLookUp",e===null?null:e>0?0:-e,t)):this.mtAvatar.hasOwnProperty(n)&&Object.assign(this.mtAvatar[n],{fixed:e,needsUpdate:!0})}animFactory(n,e=!1,t=1,o=1,s=!1){const i={template:n,ts:[0],vs:{}};let a=n;for(;;)if(a.hasOwnProperty(this.stateName))this.stateName==="speaking"||this.stateName,a=a[this.stateName];else if(a.hasOwnProperty(this.moodName))a=a[this.moodName];else if(a.hasOwnProperty(this.poseName))a=a[this.poseName];else if(a.hasOwnProperty(this.viewName))a=a[this.viewName];else if(this.avatar&&this.avatar.body&&a.hasOwnProperty(this.avatar.body))a=a[this.avatar.body];else if(a.hasOwnProperty("alt")){let l=a.alt[0];if(a.alt.length>1){const u=Math.random();let r=0;for(let h=0;h<a.alt.length;h++){let d=this.valueFn(a.alt[h].p);if(r+=d===void 0?(1-r)/(a.alt.length-1-h):d,u<r){l=a.alt[h];break}}}a=l,this.avatar&&this.avatar.body&&a.hasOwnProperty(this.avatar.body);continue}else break;let c=this.valueFn(a.delay)||0;if(Array.isArray(c)&&(c=this.gaussianRandom(...c)),a.hasOwnProperty("dt"))a.dt.forEach((l,u)=>{let r=this.valueFn(l);Array.isArray(r)&&(r=this.gaussianRandom(...r)),i.ts[u+1]=i.ts[u]+r});else{let l=Object.values(a.vs).reduce((u,r)=>r.length>u?r.length:u,0);i.ts=Array(l+1).fill(0)}s?i.ts=i.ts.map(l=>c+l*t):i.ts=i.ts.map(l=>this.animClock+c+l*t),a.vs&&a.vs.pose;for(let[l,u]of Object.entries(a.vs)){const r=this.getBaselineValue(l),h=u.map(d=>(d=this.valueFn(d),d===null?null:typeof d=="function"?d:typeof d=="string"||d instanceof String?l==="pose"&&this.avatar&&this.avatar.body==="M"&&(d==="hip"||d==="side")?"wide":d.slice():Array.isArray(d)?l==="gesture"?d.slice():(r===void 0?0:r)+o*this.gaussianRandom(...d):typeof d=="boolean"?d:d instanceof Object&&d.constructor===Object?Object.assign({},d):(r===void 0?0:r)+o*d));l==="eyesRotateY"?(i.vs.eyeLookOutLeft=[null,...h.map(d=>d>0?d:0)],i.vs.eyeLookInLeft=[null,...h.map(d=>d>0?0:-d)],i.vs.eyeLookOutRight=[null,...h.map(d=>d>0?0:-d)],i.vs.eyeLookInRight=[null,...h.map(d=>d>0?d:0)]):l==="eyesRotateX"?(i.vs.eyesLookDown=[null,...h.map(d=>d>0?d:0)],i.vs.eyesLookUp=[null,...h.map(d=>d>0?0:-d)]):i.vs[l]=[null,...h]}for(let l of Object.keys(i.vs))for(;i.vs[l].length<=i.ts.length;)i.vs[l].push(i.vs[l][i.vs[l].length-1]);return n.hasOwnProperty("mood")&&(i.mood=this.valueFn(n.mood).slice()),e&&(i.loop=e),i}valueAnimationSeq(n,e,t,o,s,i=null){n=this.valueFn(n),e=this.valueFn(e),s<t&&(s=t),s>o&&(s=o);let a=(e-n)/(o-t);return i&&(a*=i((s-t)/(o-t))),a*s+(n-a*t)}gaussianRandom(n,e,t=1,o=5){let s=0;for(let i=0;i<o;i++)s+=Math.random();return n+Math.pow(s/o,t)*(e-n)}sigmoidFactory(n){function e(o){return 1/(1+Math.exp(-n*o))-.5}var t=.5/e(1);return function(o){return t*e(2*Math.max(Math.min(o,1),0)-1)+.5}}convertRange(n,e,t){return(n-e[0])*(t[1]-t[0])/(e[1]-e[0])+t[0]}animate(n){if(!this.isRunning)return;let e;if(this.isAvatarOnly)e=n;else{if(requestAnimationFrame(this.animate.bind(this)),e=n-this.animTimeLast,e<this.animFrameDur)return;this.animTimeLast=n}e=e/this.animSlowdownRate,this.animClock+=e,this.maintainLockedPosition();let t,o,s,i,a=0;if(this.stats&&this.stats.begin(),this.isListening){for(this.listeningAnalyzer.getByteFrequencyData(this.volumeFrequencyData),t=2,s=10;t<s;t++)this.volumeFrequencyData[t]>a&&(a=this.volumeFrequencyData[t]);this.listeningVolume=(this.listeningVolume+a)/2,this.listeningActive?(this.listeningTimerTotal+=e,this.listeningVolume<this.listeningSilenceThresholdLevel?(this.listeningTimer+=e,this.listeningTimer>this.listeningSilenceThresholdMs&&(this.listeningOnchange&&this.listeningOnchange("stop",this.listeningTimer),this.listeningActive=!1,this.listeningTimer=0,this.listeningTimerTotal=0)):this.listeningTimer*=.5,this.listeningTimerTotal>this.listeningActiveDurationMax&&(this.listeningOnchange&&this.listeningOnchange("maxactive"),this.listeningTimerTotal=0)):(this.listeningTimerTotal+=e,this.listeningVolume>this.listeningActiveThresholdLevel?(this.listeningTimer+=e,this.listeningTimer>this.listeningActiveThresholdMs&&(this.listeningOnchange&&this.listeningOnchange("start"),this.listeningActive=!0,this.listeningTimer=0,this.listeningTimerTotal=0)):this.listeningTimer*=.5,this.listeningTimerTotal>this.listeningSilenceDurationMax&&(this.listeningOnchange&&this.listeningOnchange("maxsilence"),this.listeningTimerTotal=0))}if(this.isSpeaking)for(a=0,this.audioAnalyzerNode.getByteFrequencyData(this.volumeFrequencyData),t=2,s=10;t<s;t++)this.volumeFrequencyData[t]>a&&(a=this.volumeFrequencyData[t]);let c=null,l=null;const u=[];for(t=0,s=this.animQueue.length;t<s;t++){const r=this.animQueue[t];if(!(!r||!r.ts||!r.ts.length||this.animClock<r.ts[0])){for(o=r.ndx||0,i=r.ts.length;o<i&&!(this.animClock<r.ts[o]);o++)for(let[h,d]of Object.entries(r.vs))if(this.mtAvatar.hasOwnProperty(h)){if(d[o+1]===null)continue;const g=this.mtAvatar[h];if(d[o]===null&&(d[o]=g.value),o===i-1)g.newvalue=d[o];else{g.newvalue=d[o+1];const R=r.ts[o+1]-r.ts[o];let x=1;R>1e-4&&(x=(this.animClock-r.ts[o])/R),x<1&&(g.easing&&(x=g.easing(x)),g.newvalue=(1-x)*d[o]+x*g.newvalue),g.ref&&g.ref!==r.vs&&g.ref.hasOwnProperty(h)&&delete g.ref[h],g.ref=r.vs}if(a)switch(h){case"viseme_aa":case"viseme_E":case"viseme_I":case"viseme_O":case"viseme_U":g.newvalue*=1+a/255-.5}g.needsUpdate=!0}else h==="eyeContact"&&d[o]!==null&&c!==!1?c=!!d[o]:h==="headMove"&&d[o]!==null&&l!==!1?d[o]===0?l=!1:(Math.random()<d[o]&&(l=!0),d[o]=null):d[o]!==null&&(u.push({mt:h,val:d[o]}),d[o]=null);o===i?(r.hasOwnProperty("mood")&&this.setMood(r.mood),r.loop?(i=this.isSpeaking&&(r.template.name==="head"||r.template.name==="eyes")?4:1,this.animQueue[t]=this.animFactory(r.template,r.loop>0?r.loop-1:r.loop,1,1/i)):(this.animQueue.splice(t--,1),s--)):r.ndx=o-1}}for(let r=0,h=u.length;r<h;r++)switch(o=u[r].val,u[r].mt){case"speak":this.speakText(o);break;case"subtitles":this.onSubtitles&&typeof this.onSubtitles=="function"&&this.onSubtitles(o);break;case"pose":this.avatar&&this.avatar.body==="M"&&(o==="hip"||o==="side")&&this.poseTemplates.wide&&(o="wide"),this.poseName=o,this.setPoseFromTemplate(this.poseTemplates[this.poseName]);break;case"gesture":this.playGesture(...o);break;case"function":o&&typeof o=="function"&&o();break;case"moveto":Object.entries(o.props).forEach(d=>{d[1]?this.poseTarget.props[d[0]].copy(d[1]):this.poseTarget.props[d[0]].copy(this.getPoseTemplateProp(d[0])),this.poseTarget.props[d[0]].t=this.animClock,this.poseTarget.props[d[0]].d=d[1]&&d[1].d?d[1].d:d.duration||2e3});break;case"handLeft":this.ikSolve({iterations:20,root:"LeftShoulder",effector:"LeftHandMiddle1",links:[{link:"LeftHand",minx:-.5,maxx:.5,miny:-1,maxy:1,minz:-.5,maxz:.5},{link:"LeftForeArm",minx:-.5,maxx:1.5,miny:-1.5,maxy:1.5,minz:-.5,maxz:3},{link:"LeftArm",minx:-1.5,maxx:1.5,miny:0,maxy:0,minz:-1,maxz:3}]},o.x?new A.Vector3(o.x,o.y,o.z):null,!0,o.d);break;case"handRight":this.ikSolve({iterations:20,root:"RightShoulder",effector:"RightHandMiddle1",links:[{link:"RightHand",minx:-.5,maxx:.5,miny:-1,maxy:1,minz:-.5,maxz:.5,maxAngle:.1},{link:"RightForeArm",minx:-.5,maxx:1.5,miny:-1.5,maxy:1.5,minz:-3,maxz:.5,maxAngle:.2},{link:"RightArm",minx:-1.5,maxx:1.5,miny:0,maxy:0,minz:-1,maxz:3}]},o.x?new A.Vector3(o.x,o.y,o.z):null,!0,o.d);break}if((c||l)&&(oe.setFromQuaternion(this.poseAvatar.props["Head.quaternion"]),oe.x=Math.max(-.9,Math.min(.9,2*oe.x-.5)),oe.y=Math.max(-.9,Math.min(.9,-2.5*oe.y)),c?(Object.assign(this.mtAvatar.eyesLookDown,{system:oe.x<0?-oe.x:0,needsUpdate:!0}),Object.assign(this.mtAvatar.eyesLookUp,{system:oe.x<0?0:oe.x,needsUpdate:!0}),Object.assign(this.mtAvatar.eyeLookInLeft,{system:oe.y<0?-oe.y:0,needsUpdate:!0}),Object.assign(this.mtAvatar.eyeLookOutLeft,{system:oe.y<0?0:oe.y,needsUpdate:!0}),Object.assign(this.mtAvatar.eyeLookInRight,{system:oe.y<0?0:oe.y,needsUpdate:!0}),Object.assign(this.mtAvatar.eyeLookOutRight,{system:oe.y<0?-oe.y:0,needsUpdate:!0}),l&&(t=-this.mtAvatar.bodyRotateY.value,o=this.gaussianRandom(-.2,.2),this.animQueue.push(this.animFactory({name:"headmove",dt:[[1e3,2e3],[1e3,2e3,1,2],[1e3,2e3],[1e3,2e3,1,2]],vs:{headRotateY:[t,t,0],headRotateX:[o,o,0],headRotateZ:[-t/4,-t/4,0]}})))):(t=this.mtAvatar.eyeLookInLeft.value-this.mtAvatar.eyeLookOutLeft.value,o=this.gaussianRandom(-.2,.2),this.animQueue.push(this.animFactory({name:"headmove",dt:[[1e3,2e3],[1e3,2e3,1,2],[1e3,2e3],[1e3,2e3,1,2]],vs:{headRotateY:[null,t,t,0],headRotateX:[null,o,o,0],headRotateZ:[null,-t/4,-t/4,0],eyeLookInLeft:[null,0],eyeLookOutLeft:[null,0],eyeLookInRight:[null,0],eyeLookOutRight:[null,0],eyeContact:[0]}})))),e>2*this.animFrameDur&&(e=2*this.animFrameDur),(this.viewName!=="full"||this.isAvatarOnly)&&(t=this.mtRandomized[Math.floor(Math.random()*this.mtRandomized.length)],o=this.mtAvatar[t],o.needsUpdate||Object.assign(o,{base:(this.mood.baseline[t]||0)+(1+a/255)*Math.random()/5,needsUpdate:!0})),this.updatePoseBase(this.animClock),this.mixer&&(this.mixer.update(e/1e3*this.mixer.timeScale),this.currentFBXActionForCallback&&this.currentFBXActionClipDuration)){const r=this.currentFBXActionForCallback,h=r.time,d=this.currentFBXActionClipDuration;if(!r.isRunning()||h>=d-.1||r.getEffectiveTimeScale()===0&&h>0)if(console.log(`🎬 Manual check: Animation finished (time: ${h.toFixed(3)}/${d.toFixed(3)}, running: ${r.isRunning()})`),this.animationFinishedCallback){const R=this.animationFinishedCallback;this.animationFinishedCallback=null,this.currentFBXActionCallback=null,this.currentFBXActionForCallback=null,this.currentFBXActionStartTime=null,this.currentFBXActionClipDuration=null,R()}else this.currentFBXActionCallback&&(this.currentFBXActionCallback=null,this.currentFBXActionForCallback=null,this.currentFBXActionStartTime=null,this.currentFBXActionClipDuration=null)}if(this.updatePoseDelta(),(this.isSpeaking||this.isListening)&&c?a>this.volumeMax?(this.volumeHeadBase=.05,Math.random()>.6&&(this.volumeHeadTarget=-.05-Math.random()/15),this.volumeMax=a):(this.volumeMax*=.92,this.volumeHeadTarget=this.volumeHeadBase-.9*(this.volumeHeadBase-this.volumeHeadTarget)):(this.volumeHeadTarget=0,this.volumeMax=0),t=this.volumeHeadTarget-this.volumeHeadCurrent,o=Math.abs(t),o>1e-4&&(i=o*(this.volumeHeadEasing(Math.min(1,this.volumeHeadVelocity*e/1e3/o)/2+.5)-.5),this.volumeHeadCurrent+=Math.sign(t)*Math.min(o,i)),Math.abs(this.volumeHeadCurrent)>1e-4&&(ue.setFromAxisAngle(Ot,this.volumeHeadCurrent),this.objectNeck.quaternion.multiply(ue)),st.setFromObject(this.armature),this.objectLeftToeBase.getWorldPosition(Pe),Pe.sub(this.armature.position),this.objectRightToeBase.getWorldPosition(Ne),Ne.sub(this.armature.position),this.objectHips.position.y-=st.min.y/2,this.objectHips.position.x-=(Pe.x+Ne.x)/4,this.objectHips.position.z-=(Pe.z+Ne.z)/2,this.dynamicbones.update(e),this.fbxAnimationLoader&&this.fbxAnimationLoader.update(),this.opt.update&&this.opt.update(e),this.updateMorphTargets(e),this.isAvatarOnly)this.stats&&this.stats.end();else{if(this.cameraClock!==null&&this.cameraClock<1e3){this.cameraClock+=e,this.cameraClock>1e3&&(this.cameraClock=1e3);let r=new A.Spherical().setFromVector3(this.cameraStart),h=new A.Spherical().setFromVector3(this.cameraEnd);r.phi+=this.easing(this.cameraClock/1e3)*(h.phi-r.phi),r.theta+=this.easing(this.cameraClock/1e3)*(h.theta-r.theta),r.radius+=this.easing(this.cameraClock/1e3)*(h.radius-r.radius),r.makeSafe(),this.camera.position.setFromSpherical(r),this.controlsStart.x!==this.controlsEnd.x?this.controls.target.copy(this.controlsStart.lerp(this.controlsEnd,this.easing(this.cameraClock/1e3))):(r.setFromVector3(this.controlsStart),h.setFromVector3(this.controlsEnd),r.phi+=this.easing(this.cameraClock/1e3)*(h.phi-r.phi),r.theta+=this.easing(this.cameraClock/1e3)*(h.theta-r.theta),r.radius+=this.easing(this.cameraClock/1e3)*(h.radius-r.radius),r.makeSafe(),this.controls.target.setFromSpherical(r)),this.controls.update()}this.controls.autoRotate&&this.controls.update(),this.stats&&this.stats.end(),this.render()}}resetLips(){this.visemeNames.forEach(n=>{this.morphs.forEach(e=>{const t=e.morphTargetDictionary["viseme_"+n];t!==void 0&&(e.morphTargetInfluences[t]=0)})})}lipsyncGetProcessor(n,e="./"){if(!this.lipsync.hasOwnProperty(n)){const t=n.toLowerCase(),o="Lipsync"+n.charAt(0).toUpperCase()+n.slice(1);try{const s=ot[t];s&&s[o]?this.lipsync[n]=new s[o]:console.warn(`Lip-sync module for ${n} not found. Available modules:`,Object.keys(ot))}catch(s){console.warn(`Failed to load lip-sync module for ${n}:`,s)}}}lipsyncPreProcessText(n,e){return(this.lipsync[e]||Object.values(this.lipsync)[0]).preProcessText(n)}lipsyncWordsToVisemes(n,e){return(this.lipsync[e]||Object.values(this.lipsync)[0]).wordsToVisemes(n)}speakText(n,e=null,t=null,o=null){e=e||{};const s=/[!\.\?\n\p{Extended_Pictographic}]/ug,i=/[ ]/ug,a=/[\p{L}\p{N},\.\p{Quotation_Mark}!€\$\+\p{Dash_Punctuation}%&\?]/ug,c=/[\p{Extended_Pictographic}]/ug,l=e.lipsyncLang||this.avatar.lipsyncLang||this.opt.lipsyncLang;let u="",r="",h=0,d=[],g=[];const R=Array.from(this.segmenter.segment(n),x=>x.segment);for(let x=0;x<R.length;x++){const w=x===R.length-1,G=R[x].match(a);let m=R[x].match(s);const N=R[x].match(c),F=R[x].match(i);if(m&&!w&&!N&&R[x+1].match(s)&&(m=!1),t&&(u+=R[x]),G&&(!o||o.every(y=>x<y[0]||x>y[1]))&&(r+=R[x]),(F||m||w)&&(r.length&&(r=this.lipsyncPreProcessText(r,l),r.length&&d.push({mark:h,word:r})),u.length&&(g.push({mark:h,template:{name:"subtitles"},ts:[0],vs:{subtitles:[u]}}),u=""),r.length)){const y=this.lipsyncWordsToVisemes(r,l);if(y&&y.visemes&&y.visemes.length){const O=y.times[y.visemes.length-1]+y.durations[y.visemes.length-1];for(let S=0;S<y.visemes.length;S++)g.push({mark:h,template:{name:"viseme"},ts:[(y.times[S]-.6)/O,(y.times[S]+.5)/O,(y.times[S]+y.durations[S]+.5)/O],vs:{["viseme_"+y.visemes[S]]:[null,y.visemes[S]==="PP"||y.visemes[S]==="FF"?.9:.6,0]}})}r="",h++}if(m||w){if(d.length||w&&g.length){const y={anim:g};t&&(y.onSubtitles=t),d.length&&!e.avatarMute&&(y.text=d,e.avatarMood&&(y.mood=e.avatarMood),e.ttsLang&&(y.lang=e.ttsLang),e.ttsVoice&&(y.voice=e.ttsVoice),e.ttsRate&&(y.rate=e.ttsRate),e.ttsVoice&&(y.pitch=e.ttsPitch),e.ttsVolume&&(y.volume=e.ttsVolume)),this.speechQueue.push(y),d=[],r="",h=0,g=[]}if(N){let y=this.animEmojis[R[x]];y&&y.link&&(y=this.animEmojis[y.link]),y&&this.speechQueue.push({emoji:y})}this.speechQueue.push({break:100})}}this.speechQueue.push({break:1e3}),this.startSpeaking()}async speakEmoji(n){let e=this.animEmojis[n];e&&e.link&&(e=this.animEmojis[e.link]),e&&this.speechQueue.push({emoji:e}),this.startSpeaking()}async speakBreak(n){this.speechQueue.push({break:n}),this.startSpeaking()}async speakMarker(n){this.speechQueue.push({marker:n}),this.startSpeaking()}async playBackgroundAudio(n){let t=await(await fetch(n)).arrayBuffer();this.stopBackgroundAudio(),this.audioBackgroundSource=this.audioCtx.createBufferSource(),this.audioBackgroundSource.loop=!0,this.audioBackgroundSource.buffer=await this.audioCtx.decodeAudioData(t),this.audioBackgroundSource.playbackRate.value=1/this.animSlowdownRate,this.audioBackgroundSource.connect(this.audioBackgroundGainNode),this.audioBackgroundSource.start(0)}stopBackgroundAudio(){try{this.audioBackgroundSource.stop()}catch{}this.audioBackgroundSource.disconnect()}async setReverb(n=null){if(n){let t=await(await fetch(n)).arrayBuffer();this.audioReverbNode.buffer=await this.audioCtx.decodeAudioData(t)}else{const e=this.audioCtx.sampleRate,t=this.audioCtx.createBuffer(2,e,e);t.getChannelData(0)[0]=1,t.getChannelData(1)[0]=1,this.audioReverbNode.buffer=t}}setMixerGain(n,e=null,t=0){n!==null&&(this.audioSpeechGainNode.gain.cancelScheduledValues(this.audioCtx.currentTime),t?(this.audioSpeechGainNode.gain.setValueAtTime(Math.max(this.audioSpeechGainNode.gain.value,1e-4),this.audioCtx.currentTime),this.audioSpeechGainNode.gain.exponentialRampToValueAtTime(Math.max(n,1e-4),this.audioCtx.currentTime+t)):this.audioSpeechGainNode.gain.setValueAtTime(n,this.audioCtx.currentTime)),e!==null&&(this.audioBackgroundGainNode.gain.cancelScheduledValues(this.audioCtx.currentTime),t?(this.audioBackgroundGainNode.gain.setValueAtTime(Math.max(this.audioBackgroundGainNode.gain.value,1e-4),this.audioCtx.currentTime),this.audioBackgroundGainNode.gain.exponentialRampToValueAtTime(Math.max(e,1e-4),this.audioCtx.currentTime+t)):this.audioBackgroundGainNode.gain.setValueAtTime(e,this.audioCtx.currentTime))}speakAudio(n,e=null,t=null){e=e||{};const o=e.lipsyncLang||this.avatar.lipsyncLang||this.opt.lipsyncLang,s={};if(n.words){let i=[];for(let a=0;a<n.words.length;a++){const c=n.words[a],l=n.wtimes[a];let u=n.wdurations[a];if(c.length&&(t&&i.push({template:{name:"subtitles"},ts:[l],vs:{subtitles:[" "+c]}}),!n.visemes)){const r=this.lipsyncPreProcessText(c,o),h=this.lipsyncWordsToVisemes(r,o);if(h&&h.visemes&&h.visemes.length){const d=h.times[h.visemes.length-1]+h.durations[h.visemes.length-1],g=Math.min(u,Math.max(0,u-h.visemes.length*150));let R=.6+this.convertRange(g,[0,u],[0,.4]);if(u=Math.min(u,h.visemes.length*200),d>0)for(let x=0;x<h.visemes.length;x++){const w=l+h.times[x]/d*u,G=h.durations[x]/d*u;i.push({template:{name:"viseme"},ts:[w-Math.min(60,2*G/3),w+Math.min(25,G/2),w+G+Math.min(60,G/2)],vs:{["viseme_"+h.visemes[x]]:[null,h.visemes[x]==="PP"||h.visemes[x]==="FF"?.9:R,0]}})}}}}if(n.visemes)for(let a=0;a<n.visemes.length;a++){const c=n.visemes[a],l=n.vtimes[a],u=n.vdurations[a];i.push({template:{name:"viseme"},ts:[l-2*u/3,l+u/2,l+u+u/2],vs:{["viseme_"+c]:[null,c==="PP"||c==="FF"?.9:.6,0]}})}if(n.markers)for(let a=0;a<n.markers.length;a++){const c=n.markers[a],l=n.mtimes[a];i.push({template:{name:"markers"},ts:[l],vs:{function:[c]}})}i.length&&(s.anim=i)}if(n.audio&&(s.audio=n.audio),n.anim?.name){let i=this.animFactory(n.anim,!1,1,1,!0);s.anim?s.anim.push(i):s.anim=[i]}t&&(s.onSubtitles=t),e.isRaw&&(s.isRaw=!0),Object.keys(s).length&&(this.speechQueue.push(s),s.isRaw||this.speechQueue.push({break:300}),this.startSpeaking())}async playAudio(n=!1,e=null){if(!(!this.armature||this.isAudioPlaying&&!n)){if(this.isAudioPlaying=!0,e&&e.audio){const t={audio:e.audio,anim:e.anim,text:e.text,delay:e.delay||0};if(this.audioCtx.state==="suspended"||this.audioCtx.state==="interrupted"){const s=this.audioCtx.resume(),i=new Promise((a,c)=>setTimeout(()=>c("p2"),1e3));try{await Promise.race([s,i])}catch{console.log("Can't play audio. Web Audio API suspended."),this.playAudio(!0);return}}this.currentAudioItem={audio:t.audio,anim:t.anim?JSON.parse(JSON.stringify(t.anim)):null,text:t.text,delay:t.delay},this.audioSpeechSource=this.audioCtx.createBufferSource(),this.audioSpeechSource.buffer=t.audio,this.audioSpeechSource.playbackRate.value=1/this.animSlowdownRate,this.audioSpeechSource.connect(this.audioAnalyzerNode);const o=t.delay/1e3;if(this.audioStartTime=this.audioCtx.currentTime+o,this.audioSpeechSource.addEventListener("ended",()=>{this.audioSpeechSource.disconnect(),this.audioStartTime=null,this.currentAudioItem=null,this.isSpeaking||(this.isSpeaking=!0),this.playAudio(!0)},{once:!0}),t.anim&&t.anim.length>0){const s=this.animClock;t.anim.forEach(i=>{if(i&&i.ts&&i.ts.length>0){const a={template:i.template,ts:i.ts.map(c=>s+c),vs:i.vs};this.animQueue.push(a)}})}this.audioSpeechSource.start(o);return}if(this.audioPlaylist.length){const t=this.audioPlaylist.shift();if(this.audioCtx.state==="suspended"||this.audioCtx.state==="interrupted"){const a=this.audioCtx.resume(),c=new Promise((l,u)=>setTimeout(()=>u("p2"),1e3));try{await Promise.race([a,c])}catch{console.log("Can't play audio. Web Audio API suspended. This is often due to calling some speak method before the first user action, which is typically prevented by the browser."),this.playAudio(!0);return}}let o;if(Array.isArray(t.audio)){let a=this.concatArrayBuffers(t.audio);o=this.pcmToAudioBuffer(a)}else o=t.audio;this.currentAudioItem={audio:o,anim:t.anim?JSON.parse(JSON.stringify(t.anim)):null,text:t.text,delay:0};let s=0;t.anim&&(t.isRaw||(s=Math.abs(Math.min(0,...t.anim.map(a=>Math.min(...a.ts))))),this.currentAudioItem.delay=s),this.audioSpeechSource=this.audioCtx.createBufferSource(),this.audioSpeechSource.buffer=o,this.audioSpeechSource.playbackRate.value=1/this.animSlowdownRate,this.audioSpeechSource.connect(this.audioAnalyzerNode);const i=s/1e3;this.audioStartTime=this.audioCtx.currentTime+i,this.audioSpeechSource.addEventListener("ended",()=>{this.audioSpeechSource.disconnect(),this.audioStartTime=null,this.currentAudioItem=null,this.isSpeaking=!0,this.playAudio(!0)},{once:!0}),t.anim&&t.anim.forEach(a=>{for(let c=0;c<a.ts.length;c++)a.ts[c]=this.animClock+a.ts[c]+s;this.animQueue.push(a)}),this.audioSpeechSource.start(i)}else this.isAudioPlaying=!1,this.startSpeaking(!0)}}async synthesizeWithBrowserTTS(n){return new Promise((e,t)=>{const o=Array.isArray(n.text)?n.text.map(m=>m.word).join(" "):typeof n.text=="string"?n.text:"",s=new SpeechSynthesisUtterance(o),i=n.lang||this.avatar.ttsLang||this.opt.ttsLang||"en-US",a=(n.rate||this.avatar.ttsRate||this.opt.ttsRate||1)+this.mood.speech.deltaRate,c=(n.pitch||this.avatar.ttsPitch||this.opt.ttsPitch||1)+this.mood.speech.deltaPitch,l=(n.volume||this.avatar.ttsVolume||this.opt.ttsVolume||1)+this.mood.speech.deltaVolume;s.lang=i,s.rate=Math.max(.1,Math.min(10,a)),s.pitch=Math.max(0,Math.min(2,c)),s.volume=Math.max(0,Math.min(1,l));const u=speechSynthesis.getVoices(),r=n.voice||this.avatar.ttsVoice||this.opt.ttsVoice;if(r&&u.length>0){const m=u.find(N=>N.name.includes(r)||N.lang===i);m&&(s.voice=m)}const h=o.length*100/s.rate,d=this.audioCtx.createBuffer(1,this.audioCtx.sampleRate*(h/1e3),this.audioCtx.sampleRate),g=this.avatar.lipsyncLang||this.opt.lipsyncLang||"en",R=this.lipsyncPreProcessText(o,g),x=this.lipsyncWordsToVisemes(R,g),w=[];if(x&&x.visemes&&x.visemes.length>0){const m=x.times[x.visemes.length-1]+x.durations[x.visemes.length-1];for(let N=0;N<x.visemes.length;N++){const F=x.visemes[N],y=x.times[N]/m,O=x.durations[N]/m,S=y*h,f=O*h;w.push({template:{name:"viseme"},ts:[S-Math.min(60,2*f/3),S+Math.min(25,f/2),S+f+Math.min(60,f/2)],vs:{["viseme_"+F]:[null,F==="PP"||F==="FF"?.9:.6,0]}})}}const G=[...n.anim,...w];this.audioPlaylist.push({anim:G,audio:d}),this.onSubtitles=n.onSubtitles||null,this.resetLips(),n.mood&&this.setMood(n.mood),this.playAudio(),s.onend=()=>{e()},s.onerror=m=>{console.error("Speech synthesis error:",m.error),t(m.error)},speechSynthesis.speak(s)})}async synthesizeWithElevenLabsTTS(n){const e=Array.isArray(n.text)?n.text.map(h=>h.word).join(" "):typeof n.text=="string"?n.text:"",t=n.voice||this.avatar.ttsVoice||this.opt.ttsVoice||"21m00Tcm4TlvDq8ikWAM",o={text:e,model_id:"eleven_monolingual_v1",voice_settings:{stability:.5,similarity_boost:.5,style:0,use_speaker_boost:!0}},s=await fetch(`${this.opt.ttsEndpoint}/${t}`,{method:"POST",headers:{Accept:"audio/mpeg","Content-Type":"application/json","xi-api-key":this.opt.ttsApikey},body:JSON.stringify(o)});if(!s.ok)throw new Error(`ElevenLabs TTS error: ${s.status} ${s.statusText}`);const i=await s.arrayBuffer(),a=await this.audioCtx.decodeAudioData(i),c=this.avatar.lipsyncLang||this.opt.lipsyncLang||"en";let l;try{console.log("Lip-sync modules available:",{hasLipsync:!!this.lipsync,lipsyncKeys:this.lipsync?Object.keys(this.lipsync):[],lipsyncLang:c});const h=this.lipsyncPreProcessText(e,c),d=this.lipsyncWordsToVisemes(h,c);if(console.log("Lip-sync data:",{processedText:h,lipsyncData:d,hasVisemes:d&&d.visemes&&d.visemes.length>0}),d&&d.visemes&&d.visemes.length>0)l={visemes:d.visemes.map((g,R)=>({viseme:g,startTime:R*a.duration/d.visemes.length,endTime:(R+1)*a.duration/d.visemes.length,duration:a.duration/d.visemes.length,intensity:.7})),words:[],duration:a.duration,features:{onsets:[],boundaries:[]}};else throw new Error("No visemes generated from text")}catch(h){console.error("Text-based lip-sync failed, using fallback:",h);const d=e.toLowerCase().split(/\s+/),g=[];for(const R of d)for(const x of R){let w="aa";"aeiou".includes(x)?w="aa":"bp".includes(x)?w="PP":"fv".includes(x)?w="FF":"st".includes(x)?w="SS":"dln".includes(x)?w="DD":"kg".includes(x)?w="kk":"rw".includes(x)&&(w="RR"),g.push(w)}l={visemes:g.map((R,x)=>({viseme:R,startTime:x*a.duration/g.length,endTime:(x+1)*a.duration/g.length,duration:a.duration/g.length,intensity:.6})),words:[],duration:a.duration,features:{onsets:[],boundaries:[]}}}const u=[];if(l.visemes&&l.visemes.length>0)for(let h=0;h<l.visemes.length;h++){const d=l.visemes[h],g=d.startTime*1e3,R=d.duration*1e3,x=d.intensity;u.push({template:{name:"viseme"},ts:[g-Math.min(60,2*R/3),g+Math.min(25,R/2),g+R+Math.min(60,R/2)],vs:{["viseme_"+d.viseme]:[null,x,0]}})}else console.warn("ElevenLabs: No visemes available for lip-sync animation");const r=[...n.anim,...u];this.audioPlaylist.push({anim:r,audio:a}),this.onSubtitles=n.onSubtitles||null,this.resetLips(),n.mood&&this.setMood(n.mood),this.playAudio()}async synthesizeWithDeepgramTTS(n){const e=Array.isArray(n.text)?n.text.map(h=>h.word).join(" "):typeof n.text=="string"?n.text:"",t=n.voice||this.avatar.ttsVoice||this.opt.ttsVoice||"aura-2-thalia-en",o=`${this.opt.ttsEndpoint}?model=${t}`,s=await fetch(o,{method:"POST",headers:{Authorization:`Token ${this.opt.ttsApikey}`,"Content-Type":"text/plain",Accept:"audio/mpeg"},body:e});if(!s.ok)throw new Error(`Deepgram TTS error: ${s.status} ${s.statusText}`);const i=await s.arrayBuffer(),a=await this.audioCtx.decodeAudioData(i),c=this.avatar.lipsyncLang||this.opt.lipsyncLang||"en";let l;try{console.log("Lip-sync modules available:",{hasLipsync:!!this.lipsync,lipsyncKeys:this.lipsync?Object.keys(this.lipsync):[],lipsyncLang:c});const h=this.lipsyncPreProcessText(e,c),d=this.lipsyncWordsToVisemes(h,c);if(console.log("Lip-sync data:",{processedText:h,lipsyncData:d,hasVisemes:d&&d.visemes&&d.visemes.length>0}),d&&d.visemes&&d.visemes.length>0)l={visemes:d.visemes.map((g,R)=>({viseme:g,startTime:R*a.duration/d.visemes.length,endTime:(R+1)*a.duration/d.visemes.length,duration:a.duration/d.visemes.length,intensity:.7})),words:[],duration:a.duration,features:{onsets:[],boundaries:[]}};else throw new Error("No visemes generated from text")}catch(h){console.error("Text-based lip-sync failed, using fallback:",h);const d=e.toLowerCase().split(/\s+/),g=[];for(const R of d)for(const x of R){let w="aa";"aeiou".includes(x)?w="aa":"bp".includes(x)?w="PP":"fv".includes(x)?w="FF":"st".includes(x)?w="SS":"dln".includes(x)?w="DD":"kg".includes(x)?w="kk":"rw".includes(x)&&(w="RR"),g.push(w)}l={visemes:g.map((R,x)=>({viseme:R,startTime:x*a.duration/g.length,endTime:(x+1)*a.duration/g.length,duration:a.duration/g.length,intensity:.6})),words:[],duration:a.duration,features:{onsets:[],boundaries:[]}}}const u=[];if(l.visemes&&l.visemes.length>0)for(let h=0;h<l.visemes.length;h++){const d=l.visemes[h],g=d.startTime*1e3,R=d.duration*1e3,x=d.intensity;u.push({template:{name:"viseme"},ts:[g-Math.min(60,2*R/3),g+Math.min(25,R/2),g+R+Math.min(60,R/2)],vs:{["viseme_"+d.viseme]:[null,x,0]}})}else console.warn("Deepgram: No visemes available for lip-sync animation");const r=[...n.anim,...u];this.audioPlaylist.push({anim:r,audio:a}),this.onSubtitles=n.onSubtitles||null,this.resetLips(),n.mood&&this.setMood(n.mood),this.playAudio()}async synthesizeWithAzureTTS(n){const e=Array.isArray(n.text)?n.text.map(r=>r.word).join(" "):typeof n.text=="string"?n.text:"",o=`
|
|
2
2
|
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
|
|
3
3
|
<voice name="${n.voice||this.avatar.ttsVoice||this.opt.ttsVoice||"en-US-AriaNeural"}">
|
|
4
4
|
${e}
|
|
5
5
|
</voice>
|
|
6
6
|
</speak>
|
|
7
|
-
`,s=await fetch(this.opt.ttsEndpoint,{method:"POST",headers:{"Ocp-Apim-Subscription-Key":this.opt.ttsApikey,"Content-Type":"application/ssml+xml","X-Microsoft-OutputFormat":"audio-16khz-128kbitrate-mono-mp3"},body:o});if(!s.ok)throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);const i=await s.arrayBuffer(),a=await this.audioCtx.decodeAudioData(i),c=await this.audioAnalyzer.analyzeAudio(a,e),l=[];for(let r=0;r<c.visemes.length;r++){const h=c.visemes[r],d=h.startTime*1e3,g=h.duration*1e3,R=h.intensity;l.push({template:{name:"viseme"},ts:[d-Math.min(60,2*g/3),d+Math.min(25,g/2),d+g+Math.min(60,g/2)],vs:{["viseme_"+h.viseme]:[null,R,0]}})}const u=[...n.anim,...l];this.audioPlaylist.push({anim:u,audio:a}),this.onSubtitles=n.onSubtitles||null,this.resetLips(),n.mood&&this.setMood(n.mood),this.playAudio()}async synthesizeWithExternalTTS(n){let e="<speak>";n.text.forEach((i,a)=>{a>0&&(e+=" <mark name='"+i.mark+"'/>"),e+=i.word.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'").replace(new RegExp("^\\p{Dash_Punctuation}$","ug"),'<break time="750ms"/>')}),e+="</speak>";const t={method:"POST",headers:{"Content-Type":"application/json; charset=utf-8"},body:JSON.stringify({input:{ssml:e},voice:{languageCode:n.lang||this.avatar.ttsLang||this.opt.ttsLang,name:n.voice||this.avatar.ttsVoice||this.opt.ttsVoice},audioConfig:{audioEncoding:this.ttsAudioEncoding,speakingRate:(n.rate||this.avatar.ttsRate||this.opt.ttsRate)+this.mood.speech.deltaRate,pitch:(n.pitch||this.avatar.ttsPitch||this.opt.ttsPitch)+this.mood.speech.deltaPitch,volumeGainDb:(n.volume||this.avatar.ttsVolume||this.opt.ttsVolume)+this.mood.speech.deltaVolume},enableTimePointing:[1]})};this.opt.jwtGet&&typeof this.opt.jwtGet=="function"&&(t.headers.Authorization="Bearer "+await this.opt.jwtGet());const o=await fetch(this.opt.ttsEndpoint+(this.opt.ttsApikey?"?key="+this.opt.ttsApikey:""),t),s=await o.json();if(o.status===200&&s&&s.audioContent){const i=this.b64ToArrayBuffer(s.audioContent),a=await this.audioCtx.decodeAudioData(i);this.speakWithHands();const c=[0];let l=0;n.text.forEach((h,d)=>{if(d>0){let g=c[c.length-1];s.timepoints[l]&&(g=s.timepoints[l].timeSeconds*1e3,s.timepoints[l].markName===""+h.mark&&l++),c.push(g)}});const u=[{mark:0,time:0}];c.forEach((h,d)=>{if(d>0){let g=h-c[d-1];u[d-1].duration=g,u.push({mark:d,time:h})}});let r=1e3*a.duration;r>this.opt.ttsTrimEnd&&(r=r-this.opt.ttsTrimEnd),u[u.length-1].duration=r-u[u.length-1].time,n.anim.forEach(h=>{const d=u[h.mark];if(d)for(let g=0;g<h.ts.length;g++)h.ts[g]=d.time+h.ts[g]*d.duration+this.opt.ttsTrimStart}),this.audioPlaylist.push({anim:n.anim,audio:a}),this.onSubtitles=n.onSubtitles||null,this.resetLips(),n.mood&&this.setMood(n.mood),this.playAudio()}else this.startSpeaking(!0)}async startSpeaking(n=!1){if(!(!this.armature||this.isSpeaking&&!n))if(this.stateName="speaking",this.isSpeaking=!0,this.speechQueue.length){let e=this.speechQueue.shift();if(e.emoji){this.lookAtCamera(500);let t=e.emoji.dt.reduce((o,s)=>o+s,0);this.animQueue.push(this.animFactory(e.emoji)),setTimeout(this.startSpeaking.bind(this),t,!0)}else if(e.break)setTimeout(this.startSpeaking.bind(this),e.break,!0);else if(e.audio)e.isRaw||(this.lookAtCamera(500),this.speakWithHands(),this.resetLips()),this.audioPlaylist.push({anim:e.anim,audio:e.audio,isRaw:e.isRaw}),this.onSubtitles=e.onSubtitles||null,e.mood&&this.setMood(e.mood),this.playAudio();else if(e.text){this.lookAtCamera(500);try{!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)}catch(t){console.error("Error:",t),this.startSpeaking(!0)}}else e.anim?(this.onSubtitles=e.onSubtitles||null,this.resetLips(),e.mood&&this.setMood(e.mood),e.anim.forEach((t,o)=>{for(let s=0;s<t.ts.length;s++)t.ts[s]=this.animClock+10*o;this.animQueue.push(t)}),setTimeout(this.startSpeaking.bind(this),10*e.anim.length,!0)):e.marker?(typeof e.marker=="function"&&e.marker(),this.startSpeaking(!0)):this.startSpeaking(!0)}else this.stateName="idle",this.isSpeaking=!1}pauseSpeaking(){let n=null;if(this.audioSpeechSource&&this.currentAudioItem&&this.audioStartTime!==null)try{const e=this.audioCtx.currentTime,t=Math.max(0,e-this.audioStartTime),o=this.audioSpeechSource.playbackRate.value,s=t*o,i=this.currentAudioItem.audio,a=i.sampleRate,c=Math.floor(s*a);if(c<i.length){const l=i.length-c,u=this.audioCtx.createBuffer(i.numberOfChannels,l,a);for(let h=0;h<i.numberOfChannels;h++){const d=i.getChannelData(h),g=u.getChannelData(h);for(let R=0;R<l;R++)g[R]=d[c+R]}let r=null;if(this.currentAudioItem.anim){const h=this.animClock+this.currentAudioItem.delay,d=t*1e3,g=h+d;r=this.currentAudioItem.anim.map(R=>{const x={template:R.template,ts:[],vs:[]};for(let w=0;w<R.ts.length;w++){const G=R.ts[w];if(G>g){const m=G-g;x.ts.push(m),x.vs.push(R.vs[w])}}return x.ts.length>0?x:null}).filter(R=>R!==null)}n={audio:u,anim:r,text:this.currentAudioItem.text,delay:0,elapsedTime:t}}this.audioSpeechSource.stop()}catch(e){console.warn("Error trimming audio buffer on pause:",e)}else try{this.audioSpeechSource?.stop()}catch{}return this.audioPlaylist.length=0,this.stateName="idle",this.isSpeaking=!1,this.isAudioPlaying=!1,this.audioStartTime=null,this.currentAudioItem=null,this.speechQueue.length=0,this.animQueue=this.animQueue.filter(e=>e.template.name!=="viseme"&&e.template.name!=="subtitles"&&e.template.name!=="blendshapes"),this.armature&&(this.resetLips(),this.render()),n}stopSpeaking(){if(this.audioSpeechSource){try{this.audioSpeechSource.stop()}catch{}this.audioSpeechSource=null}this.audioPlaylist.length=0,this.speechQueue.length=0,this.animQueue=this.animQueue.filter(n=>n.template.name!=="viseme"&&n.template.name!=="subtitles"&&n.template.name!=="blendshapes"),this.stateName="idle",this.isSpeaking=!1,this.isAudioPlaying=!1,this.currentAudioItem=null,this.audioStartTime=null,this.armature&&(this.resetLips(),this.render())}async streamStart(n={},e=null,t=null,o=null,s=null){if(this.stopSpeaking(),this.isStreaming=!0,n.waitForAudioChunks!==void 0&&(this.streamWaitForAudioChunks=n.waitForAudioChunks),this.streamWaitForAudioChunks||(this.streamAudioStartTime=this.animClock),this.streamLipsyncQueue=[],this.streamLipsyncType=n.lipsyncType||this.streamLipsyncType||"visemes",this.streamLipsyncLang=n.lipsyncLang||this.streamLipsyncLang||this.avatar.lipsyncLang||this.opt.lipsyncLang,this.onAudioStart=e,this.onAudioEnd=t,this.onMetrics=s,n.sampleRate!==void 0){const a=n.sampleRate;typeof a=="number"&&a>=8e3&&a<=96e3?a!==this.audioCtx.sampleRate&&this.initAudioGraph(a):console.warn("Invalid sampleRate provided. It must be a number between 8000 and 96000 Hz.")}if(n.gain!==void 0&&(this.audioStreamGainNode.gain.value=n.gain),!this.streamWorkletNode||!this.streamWorkletNode.port||this.streamWorkletNode.numberOfOutputs===0||this.streamWorkletNode.context!==this.audioCtx){if(this.streamWorkletNode)try{this.streamWorkletNode.disconnect(),this.streamWorkletNode=null}catch{}if(!this.workletLoaded)try{const a=this.audioCtx.audioWorklet.addModule(Pt.href),c=new Promise((l,u)=>setTimeout(()=>u(new Error("Worklet loading timed out")),5e3));await Promise.race([a,c]),this.workletLoaded=!0}catch(a){throw console.error("Failed to load audio worklet:",a),new Error("Failed to initialize streaming speech")}this.streamWorkletNode=new AudioWorkletNode(this.audioCtx,"playback-worklet",{processorOptions:{sampleRate:this.audioCtx.sampleRate,metrics:n.metrics||{enabled:!1}}}),this.streamWorkletNode.connect(this.audioStreamGainNode),this.streamWorkletNode.connect(this.audioAnalyzerNode),this.streamWorkletNode.port.onmessage=a=>{if(a.data.type==="playback-started"&&(this.isSpeaking=!0,this.stateName="speaking",this.streamWaitForAudioChunks&&(this.streamAudioStartTime=this.animClock),this._processStreamLipsyncQueue(),this.speakWithHands(),this.onAudioStart))try{this.onAudioStart?.()}catch(c){console.error(c)}if(a.data.type==="playback-ended"&&(this._streamPause(),this.onAudioEnd))try{this.onAudioEnd()}catch{}if(this.onMetrics&&a.data.type==="metrics")try{this.onMetrics(a.data)}catch{}}}if(n.metrics)try{this.streamWorkletNode.port.postMessage({type:"config-metrics",data:n.metrics})}catch{}if(this.resetLips(),this.lookAtCamera(500),n.mood&&this.setMood(n.mood),this.onSubtitles=o||null,this.audioCtx.state==="suspended"||this.audioCtx.state==="interrupted"){const a=this.audioCtx.resume(),c=new Promise((l,u)=>setTimeout(()=>u("p2"),1e3));try{await Promise.race([a,c])}catch{console.warn("Can't play audio. Web Audio API suspended. This is often due to calling some speak method before the first user action, which is typically prevented by the browser.");return}}}streamNotifyEnd(){!this.isStreaming||!this.streamWorkletNode||this.streamWorkletNode.port.postMessage({type:"no-more-data"})}streamInterrupt(){if(!this.isStreaming)return;const n=this.isSpeaking;if(this.streamWorkletNode)try{this.streamWorkletNode.port.postMessage({type:"stop"})}catch{}if(this._streamPause(!0),n&&this.onAudioEnd)try{this.onAudioEnd()}catch{}}streamStop(){if(this.isStreaming){if(this.streamInterrupt(),this.streamWorkletNode){try{this.streamWorkletNode.disconnect()}catch{}this.streamWorkletNode=null}this.isStreaming=!1}}_streamPause(n=!1){this.isSpeaking=!1,this.stateName="idle",n&&(this.streamWaitForAudioChunks&&(this.streamAudioStartTime=null),this.streamLipsyncQueue=[],this.animQueue=this.animQueue.filter(e=>e.template.name!=="viseme"&&e.template.name!=="subtitles"&&e.template.name!=="blendshapes"),this.armature&&(this.resetLips(),this.render()))}_processStreamLipsyncQueue(){if(this.isStreaming)for(;this.streamLipsyncQueue.length>0;){const n=this.streamLipsyncQueue.shift();this._processLipsyncData(n,this.streamAudioStartTime)}}_processLipsyncData(n,e){if(this.isStreaming){if(n.visemes&&this.streamLipsyncType=="visemes")for(let t=0;t<n.visemes.length;t++){const o=n.visemes[t],s=e+n.vtimes[t],i=n.vdurations[t],a={template:{name:"viseme"},ts:[s-2*i/3,s+i/2,s+i+i/2],vs:{["viseme_"+o]:[null,o==="PP"||o==="FF"?.9:.6,0]}};this.animQueue.push(a)}if(n.words&&(this.onSubtitles||this.streamLipsyncType=="words"))for(let t=0;t<n.words.length;t++){const o=n.words[t],s=n.wtimes[t];let i=n.wdurations[t];if(o.length&&(this.onSubtitles&&this.animQueue.push({template:{name:"subtitles"},ts:[e+s],vs:{subtitles:[" "+o]}}),this.streamLipsyncType=="words")){const a=this.streamLipsyncLang||this.avatar.lipsyncLang||this.opt.lipsyncLang,c=this.lipsyncPreProcessText(o,a),l=this.lipsyncWordsToVisemes(c,a);if(l&&l.visemes&&l.visemes.length){const u=l.times[l.visemes.length-1]+l.durations[l.visemes.length-1],r=Math.min(i,Math.max(0,i-l.visemes.length*150));let h=.6+this.convertRange(r,[0,i],[0,.4]);if(i=Math.min(i,l.visemes.length*200),u>0)for(let d=0;d<l.visemes.length;d++){const g=e+s+l.times[d]/u*i,R=l.durations[d]/u*i;this.animQueue.push({template:{name:"viseme"},ts:[g-Math.min(60,2*R/3),g+Math.min(25,R/2),g+R+Math.min(60,R/2)],vs:{["viseme_"+l.visemes[d]]:[null,l.visemes[d]==="PP"||l.visemes[d]==="FF"?.9:h,0]}})}}}}if(n.anims&&this.streamLipsyncType=="blendshapes")for(let t=0;t<n.anims.length;t++){let o=n.anims[t];o.delay+=e;let s=this.animFactory(o,!1,1,1,!0);this.animQueue.push(s)}}}streamAudio(n){if(!(!this.isStreaming||!this.streamWorkletNode)){if(this.isSpeaking||(this.streamLipsyncQueue=[],this.streamAudioStartTime=null),this.isSpeaking=!0,this.stateName="speaking",n.audio!==void 0){const e={type:"audioData",data:null};if(n.audio instanceof ArrayBuffer)e.data=n.audio,this.streamWorkletNode.port.postMessage(e,[e.data]);else if(n.audio instanceof Int16Array||n.audio instanceof Uint8Array){const t=n.audio.buffer.slice(n.audio.byteOffset,n.audio.byteOffset+n.audio.byteLength);e.data=t,this.streamWorkletNode.port.postMessage(e,[e.data])}else if(n.audio instanceof Float32Array){const t=new Int16Array(n.audio.length);for(let o=0;o<n.audio.length;o++){let s=Math.max(-1,Math.min(1,n.audio[o]));t[o]=s<0?s*32768:s*32767}e.data=t.buffer,this.streamWorkletNode.port.postMessage(e,[e.data])}else console.error("r.audio is not a supported type. Must be ArrayBuffer, Int16Array, Uint8Array, or Float32Array:",n.audio)}if(n.visemes||n.anims||n.words){if(this.streamWaitForAudioChunks&&!this.streamAudioStartTime){this.streamLipsyncQueue.length>=200&&this.streamLipsyncQueue.shift(),this.streamLipsyncQueue.push(n);return}else!this.streamWaitForAudioChunks&&!this.streamAudioStartTime&&(this.streamAudioStartTime=this.animClock);this._processLipsyncData(n,this.streamAudioStartTime)}}}makeEyeContact(n){this.animQueue.push(this.animFactory({name:"eyecontact",dt:[0,n],vs:{eyeContact:[1]}}))}lookAhead(n){if(n){let e=(Math.random()-.5)/4,t=(Math.random()-.5)/4,o=this.animQueue.findIndex(i=>i.template.name==="lookat");o!==-1&&this.animQueue.splice(o,1);const s={name:"lookat",dt:[750,n],vs:{bodyRotateX:[e],bodyRotateY:[t],eyesRotateX:[-3*e+.1],eyesRotateY:[-5*t],browInnerUp:[[0,.7]],mouthLeft:[[0,.7]],mouthRight:[[0,.7]],eyeContact:[0],headMove:[0]}};this.animQueue.push(this.animFactory(s))}}lookAtCamera(n){let e;if(this.speakTo&&(e=new A.Vector3,this.speakTo.objectLeftEye?.isObject3D?(this.speakTo.armature.objectHead,this.speakTo.objectLeftEye.updateMatrixWorld(!0),this.speakTo.objectRightEye.updateMatrixWorld(!0),Be.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld),Ne.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld),e.addVectors(Be,Ne).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){if(this.avatar.hasOwnProperty("avatarIgnoreCamera")){if(this.avatar.avatarIgnoreCamera){this.lookAhead(n);return}}else if(this.opt.avatarIgnoreCamera){this.lookAhead(n);return}this.lookAt(null,null,n);return}this.objectLeftEye.updateMatrixWorld(!0),this.objectRightEye.updateMatrixWorld(!0),Be.setFromMatrixPosition(this.objectLeftEye.matrixWorld),Ne.setFromMatrixPosition(this.objectRightEye.matrixWorld),Be.add(Ne).divideScalar(2),ue.copy(this.armature.quaternion),ue.multiply(this.poseTarget.props["Hips.quaternion"]),ue.multiply(this.poseTarget.props["Spine.quaternion"]),ue.multiply(this.poseTarget.props["Spine1.quaternion"]),ue.multiply(this.poseTarget.props["Spine2.quaternion"]),ue.multiply(this.poseTarget.props["Neck.quaternion"]),ue.multiply(this.poseTarget.props["Head.quaternion"]);const t=new A.Vector3().subVectors(e,Be).normalize(),o=Math.atan2(t.x,t.z),s=Math.asin(-t.y);oe.set(s,o,0,"YXZ");const a=new A.Quaternion().setFromEuler(oe),c=new A.Quaternion().copy(a).multiply(ue.clone().invert());oe.setFromQuaternion(c,"YXZ");let l=oe.x/(40/24)+.2,u=oe.y/(9/4),r=Math.min(.6,Math.max(-.3,l)),h=Math.min(.8,Math.max(-.8,u)),d=(Math.random()-.5)/4,g=(Math.random()-.5)/4;if(n){let R=this.animQueue.findIndex(w=>w.template.name==="lookat");R!==-1&&this.animQueue.splice(R,1);const x={name:"lookat",dt:[750,n],vs:{bodyRotateX:[r+d],bodyRotateY:[h+g],eyesRotateX:[-3*d+.1],eyesRotateY:[-5*g],browInnerUp:[[0,.7]],mouthLeft:[[0,.7]],mouthRight:[[0,.7]],eyeContact:[0],headMove:[0]}};this.animQueue.push(this.animFactory(x))}}lookAt(n,e,t){if(!this.camera)return;const o=this.nodeAvatar.getBoundingClientRect();this.objectLeftEye.updateMatrixWorld(!0),this.objectRightEye.updateMatrixWorld(!0);const s=new A.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld),i=new A.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld),a=new A.Vector3().addVectors(s,i).divideScalar(2);a.project(this.camera);let c=(a.x+1)/2*o.width+o.left,l=-(a.y-1)/2*o.height+o.top;n===null&&(n=c),e===null&&(e=l),ue.copy(this.armature.quaternion),ue.multiply(this.poseTarget.props["Hips.quaternion"]),ue.multiply(this.poseTarget.props["Spine.quaternion"]),ue.multiply(this.poseTarget.props["Spine1.quaternion"]),ue.multiply(this.poseTarget.props["Spine2.quaternion"]),ue.multiply(this.poseTarget.props["Neck.quaternion"]),ue.multiply(this.poseTarget.props["Head.quaternion"]),oe.setFromQuaternion(ue);let u=oe.x/(40/24),r=oe.y/(9/4),h=Math.min(.4,Math.max(-.4,this.camera.rotation.x)),d=Math.min(.4,Math.max(-.4,this.camera.rotation.y)),g=Math.max(window.innerWidth-c,c),R=Math.max(window.innerHeight-l,l),x=this.convertRange(e,[l-R,l+R],[-.3,.6])-u+h,w=this.convertRange(n,[c-g,c+g],[-.8,.8])-r+d;x=Math.min(.6,Math.max(-.3,x)),w=Math.min(.8,Math.max(-.8,w));let G=(Math.random()-.5)/4,m=(Math.random()-.5)/4;if(t){let N=this.animQueue.findIndex(y=>y.template.name==="lookat");N!==-1&&this.animQueue.splice(N,1);const F={name:"lookat",dt:[750,t],vs:{bodyRotateX:[x+G],bodyRotateY:[w+m],eyesRotateX:[-3*G+.1],eyesRotateY:[-5*m],browInnerUp:[[0,.7]],mouthLeft:[[0,.7]],mouthRight:[[0,.7]],eyeContact:[0],headMove:[0]}};this.animQueue.push(this.animFactory(F))}}touchAt(n,e){if(!this.camera)return;const t=this.nodeAvatar.getBoundingClientRect(),o=new A.Vector2((n-t.left)/t.width*2-1,-((e-t.top)/t.height)*2+1),s=new A.Raycaster;s.setFromCamera(o,this.camera);const i=s.intersectObject(this.armature);if(i.length>0){const a=i[0].point,c=new A.Vector3,l=new A.Vector3;this.objectLeftArm.getWorldPosition(c),this.objectRightArm.getWorldPosition(l);const u=c.distanceToSquared(a),r=l.distanceToSquared(a);u<r?(this.ikSolve({iterations:20,root:"LeftShoulder",effector:"LeftHandMiddle1",links:[{link:"LeftHand",minx:-.5,maxx:.5,miny:-1,maxy:1,minz:-.5,maxz:.5,maxAngle:.1},{link:"LeftForeArm",minx:-.5,maxx:1.5,miny:-1.5,maxy:1.5,minz:-.5,maxz:3,maxAngle:.2},{link:"LeftArm",minx:-1.5,maxx:1.5,miny:0,maxy:0,minz:-1,maxz:3}]},a,!1,1e3),this.setValue("handFistLeft",0)):(this.ikSolve({iterations:20,root:"RightShoulder",effector:"RightHandMiddle1",links:[{link:"RightHand",minx:-.5,maxx:.5,miny:-1,maxy:1,minz:-.5,maxz:.5,maxAngle:.1},{link:"RightForeArm",minx:-.5,maxx:1.5,miny:-1.5,maxy:1.5,minz:-3,maxz:.5,maxAngle:.2},{link:"RightArm",minx:-1.5,maxx:1.5,miny:0,maxy:0,minz:-1,maxz:3}]},a,!1,1e3),this.setValue("handFistRight",0))}else["LeftArm","LeftForeArm","LeftHand","RightArm","RightForeArm","RightHand"].forEach(a=>{let c=a+".quaternion";this.poseTarget.props[c].copy(this.getPoseTemplateProp(c)),this.poseTarget.props[c].t=this.animClock,this.poseTarget.props[c].d=1e3});return i.length>0}speakWithHands(n=0,e=.5){if(this.mixer||this.gesture||!this.poseTarget.template.standing||this.poseTarget.template.bend||Math.random()>e)return;this.ikSolve({root:"LeftShoulder",effector:"LeftHandMiddle1",links:[{link:"LeftHand",minx:-.5,maxx:.5,miny:-1,maxy:1,minz:-.5,maxz:.5},{link:"LeftForeArm",minx:-.5,maxx:1.5,miny:-1.5,maxy:1.5,minz:-.5,maxz:3},{link:"LeftArm",minx:-1.5,maxx:1.5,miny:-1.5,maxy:1.5,minz:-1,maxz:3}]},new A.Vector3(this.gaussianRandom(0,.5),this.gaussianRandom(-.8,-.2),this.gaussianRandom(0,.5)),!0),this.ikSolve({root:"RightShoulder",effector:"RightHandMiddle1",links:[{link:"RightHand",minx:-.5,maxx:.5,miny:-1,maxy:1,minz:-.5,maxz:.5},{link:"RightForeArm",minx:-.5,maxx:1.5,miny:-1.5,maxy:1.5,minz:-3,maxz:.5},{link:"RightArm"}]},new A.Vector3(this.gaussianRandom(-.5,0),this.gaussianRandom(-.8,-.2),this.gaussianRandom(0,.5)),!0);const t=[],o=[];t.push(100+Math.round(Math.random()*500)),o.push({duration:1e3,props:{"LeftHand.quaternion":new A.Quaternion().setFromEuler(new A.Euler(0,-1-Math.random(),0)),"RightHand.quaternion":new A.Quaternion().setFromEuler(new A.Euler(0,1+Math.random(),0))}}),["LeftArm","LeftForeArm","RightArm","RightForeArm"].forEach(i=>{o[0].props[i+".quaternion"]=this.ikMesh.getObjectByName(i).quaternion.clone()}),t.push(1e3+Math.round(Math.random()*500)),o.push({duration:2e3,props:{}}),["LeftArm","LeftForeArm","RightArm","RightForeArm","LeftHand","RightHand"].forEach(i=>{o[1].props[i+".quaternion"]=null});const s=this.animFactory({name:"talkinghands",delay:n,dt:t,vs:{moveto:o}});this.animQueue.push(s)}getSlowdownRate(n){return this.animSlowdownRate}setSlowdownRate(n){this.animSlowdownRate=n,this.audioSpeechSource.playbackRate.value=1/this.animSlowdownRate,this.audioBackgroundSource.playbackRate.value=1/this.animSlowdownRate}getAutoRotateSpeed(n){return this.controls.autoRotateSpeed}setAutoRotateSpeed(n){this.controls.autoRotateSpeed=n,this.controls.autoRotate=n>0}start(){this.armature&&this.isRunning===!1&&(this.audioCtx.resume(),this.animTimeLast=performance.now(),this.isRunning=!0,this.isAvatarOnly||requestAnimationFrame(this.animate.bind(this)))}stop(){this.isRunning=!1,this.audioCtx.suspend()}startListening(n,e={},t=null){this.listeningAnalyzer=n,this.listeningAnalyzer.fftSize=256,this.listeningAnalyzer.smoothingTimeConstant=.1,this.listeningAnalyzer.minDecibels=-70,this.listeningAnalyzer.maxDecibels=-10,this.listeningOnchange=t&&typeof t=="function"?t:null,this.listeningSilenceThresholdLevel=e?.hasOwnProperty("listeningSilenceThresholdLevel")?e.listeningSilenceThresholdLevel:this.opt.listeningSilenceThresholdLevel,this.listeningSilenceThresholdMs=e?.hasOwnProperty("listeningSilenceThresholdMs")?e.listeningSilenceThresholdMs:this.opt.listeningSilenceThresholdMs,this.listeningSilenceDurationMax=e?.hasOwnProperty("listeningSilenceDurationMax")?e.listeningSilenceDurationMax:this.opt.listeningSilenceDurationMax,this.listeningActiveThresholdLevel=e?.hasOwnProperty("listeningActiveThresholdLevel")?e.listeningActiveThresholdLevel:this.opt.listeningActiveThresholdLevel,this.listeningActiveThresholdMs=e?.hasOwnProperty("listeningActiveThresholdMs")?e.listeningActiveThresholdMs:this.opt.listeningActiveThresholdMs,this.listeningActiveDurationMax=e?.hasOwnProperty("listeningActiveDurationMax")?e.listeningActiveDurationMax:this.opt.listeningActiveDurationMax,this.listeningActive=!1,this.listeningVolume=0,this.listeningTimer=0,this.listeningTimerTotal=0,this.isListening=!0}stopListening(){this.isListening=!1}async playAnimation(n,e=null,t=10,o=0,s=.01,i=!1,a=null){if(!this.armature)return;this.positionWasLocked=!i,i||this.lockAvatarPosition();let c=this.animClips.find(l=>l.url===n+"-"+o);if(c){let l=this.animQueue.find(h=>h.template.name==="pose");l&&(l.ts[0]=1/0),Object.entries(c.pose.props).forEach(h=>{this.poseBase.props[h[0]]=h[1].clone(),this.poseTarget.props[h[0]]=h[1].clone(),this.poseTarget.props[h[0]].t=0,this.poseTarget.props[h[0]].d=1e3}),this.mixer||(this.mixer=new A.AnimationMixer(this.armature)),this.animationFinishedCallback=a,console.log("🎬 Stored animation callback:",a?"callback exists":"callback is null");const u=()=>{console.log(`🎬 Mixer 'finished' event fired for animation: ${n}, callback exists: ${!!this.animationFinishedCallback}`);const h=this.animationFinishedCallback;if(h){console.log("🎬 Calling animation callback..."),this.animationFinishedCallback=null,this.currentFBXActionCallback=null,this.currentFBXActionForCallback=null,this.currentFBXActionStartTime=null,this.currentFBXActionClipDuration=null;try{h(),console.log("🎬 Animation callback executed successfully")}catch(d){console.error("🎬 Error in animation callback:",d)}}else console.log("🎬 No callback to call (already cleared or never set)")},r=this.mixer.clipAction(c.clip);if(t<=0)r.setLoop(A.LoopOnce,1),console.log(`🎬 Setting animation to LoopOnce, duration: ${c.clip.duration.toFixed(3)}s`);else{const h=Math.ceil(t/c.clip.duration);r.setLoop(A.LoopRepeat,h)}if(r.clampWhenFinished=!0,r.time=0,this.mixer.addEventListener("finished",u,{once:!0}),this.currentFBXActionForCallback=r,this.currentFBXActionCallback=u,this.currentFBXActionClipDuration=c.clip.duration,this.currentFBXActionStartTime=null,this.currentFBXAction&&this.currentFBXAction.isRunning()){this.currentFBXAction.fadeOut(.3),setTimeout(()=>{this.currentFBXAction=r,this.currentFBXActionForCallback=r,this.currentFBXActionCallback=u,this.currentFBXActionClipDuration=c.clip.duration,this.currentFBXActionStartTime=this.mixer.time;try{r.fadeIn(.5).play(),console.log("FBX animation started successfully (with fade transition):",n)}catch(h){console.warn("FBX animation failed to start:",h),this.stopAnimation()}},300);return}this.currentFBXAction=r,this.currentFBXActionStartTime=this.mixer.time;try{r.fadeIn(.5).play(),console.log("FBX animation started successfully:",n)}catch(h){console.warn("FBX animation failed to start:",h),this.stopAnimation();return}if(r.getClip().tracks.length===0){console.warn("FBX animation has no valid tracks, stopping"),this.stopAnimation();return}}else{if(n.split(".").pop().toLowerCase()!=="fbx"){console.error(`Invalid file type for FBX animation: ${n}. Expected .fbx file.`);return}let u=!1;try{const d=await fetch(n,{method:"HEAD"});if(u=d.ok,!u){console.error(`FBX file not found at ${n}. Status: ${d.status}`),console.error("Please check:"),console.error("1. File path is correct (note: path is case-sensitive)"),console.error("2. File exists in your public folder"),console.error("3. File is accessible (not blocked by server)");return}}catch(d){console.warn(`Could not verify file existence for ${n}, attempting to load anyway:`,d)}const r=new tt.FBXLoader;let h;try{h=await r.loadAsync(n,e)}catch(d){console.error(`Failed to load FBX animation from ${n}:`,d),console.error("Error details:",{message:d.message,url:n,suggestion:"Make sure the file is a valid FBX file and the path is correct"}),d.message&&d.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: ${n}`),console.error(" - File is a valid FBX binary file"),console.error(" - File path matches your public folder structure"),console.error(" - File is not corrupted"));try{const g=await fetch(n),R=g.headers.get("content-type"),x=await g.text();console.error("Response details:",{status:g.status,contentType:R,firstBytes:x.substring(0,100),isHTML:x.trim().startsWith("<!DOCTYPE")||x.trim().startsWith("<html")}),(x.trim().startsWith("<!DOCTYPE")||x.trim().startsWith("<html"))&&console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.")}catch(g){console.error("Could not fetch file for debugging:",g)}return}if(h&&h.animations&&h.animations[o]){let d=h.animations[o];const g=new Set;this.armature&&this.armature.traverse(y=>{(y.isBone||y.type==="Bone")&&g.add(y.name)});const R=new Map,x=y=>{if(g.has(y))return y;let O=y.replace(/^mixamorig/i,"").replace(/^CC_Base_/i,"").replace(/^RPM_/i,"");if(g.has(O))return O;const S=O.toLowerCase();if(S.includes("left")&&S.includes("arm")){if(S.includes("fore")||S.includes("lower")){if(g.has("LeftForeArm"))return"LeftForeArm";if(g.has("LeftForearm"))return"LeftForearm"}else if(!S.includes("fore")&&!S.includes("hand")&&g.has("LeftArm"))return"LeftArm"}if(S.includes("right")&&S.includes("arm")){if(S.includes("fore")||S.includes("lower")){if(g.has("RightForeArm"))return"RightForeArm";if(g.has("RightForearm"))return"RightForearm"}else if(!S.includes("fore")&&!S.includes("hand")&&g.has("RightArm"))return"RightArm"}if(S.includes("left")&&S.includes("hand")&&!S.includes("index")&&!S.includes("thumb")&&!S.includes("middle")&&!S.includes("ring")&&!S.includes("pinky")&&g.has("LeftHand"))return"LeftHand";if(S.includes("right")&&S.includes("hand")&&!S.includes("index")&&!S.includes("thumb")&&!S.includes("middle")&&!S.includes("ring")&&!S.includes("pinky")&&g.has("RightHand"))return"RightHand";if(S.includes("left")&&(S.includes("shoulder")||S.includes("clavicle"))&&g.has("LeftShoulder"))return"LeftShoulder";if(S.includes("right")&&(S.includes("shoulder")||S.includes("clavicle"))&&g.has("RightShoulder"))return"RightShoulder";const f={LeftArm:"LeftArm",leftArm:"LeftArm",LEFTARM:"LeftArm",RightArm:"RightArm",rightArm:"RightArm",RIGHTARM:"RightArm",LeftForeArm:"LeftForeArm",leftForeArm:"LeftForeArm",leftForearm:"LeftForeArm",LeftForearm:"LeftForeArm",RightForeArm:"RightForeArm",rightForeArm:"RightForeArm",rightForearm:"RightForeArm",RightForearm:"RightForeArm",LeftHand:"LeftHand",leftHand:"LeftHand",RightHand:"RightHand",rightHand:"RightHand",LeftShoulder:"LeftShoulder",leftShoulder:"LeftShoulder",RightShoulder:"RightShoulder",rightShoulder:"RightShoulder",Spine:"Spine1",spine:"Spine1",Spine1:"Spine1",Spine2:"Spine2",Head:"Head",head:"Head",Neck:"Neck",neck:"Neck",Hips:"Hips",hips:"Hips",Root:"Hips",root:"Hips"};if(f[O]){const E=f[O];if(g.has(E))return E}for(const E of g)if(E.toLowerCase()===S)return E;for(const E of g){const L=E.toLowerCase();if((S.includes("left")&&L.includes("left")||S.includes("right")&&L.includes("right"))&&(S.includes("arm")&&L.includes("arm")&&!L.includes("fore")||S.includes("forearm")&&L.includes("forearm")||S.includes("hand")&&L.includes("hand")&&!L.includes("index")&&!L.includes("thumb")||S.includes("shoulder")&&L.includes("shoulder")))return E}return null},w=new Set;d.tracks.forEach(y=>{const O=y.name.split(".");w.add(O[0])}),Array.from(w).filter(y=>y.toLowerCase().includes("arm")||y.toLowerCase().includes("hand")||y.toLowerCase().includes("shoulder")),Array.from(g).filter(y=>y.includes("Arm")||y.includes("Hand")||y.includes("Shoulder"));const G=[],m=new Set;d.tracks.forEach(y=>{const S=y.name.replaceAll("mixamorig","").split("."),f=S[0],E=S[1],L=x(f);if(!(L&&(L==="LeftShoulder"||L==="RightShoulder")&&(E==="quaternion"||E==="rotation")))if(L&&E){const P=`${L}.${E}`,B=y.clone();B.name=P,G.push(B),f!==L&&R.set(f,L)}else m.add(f),(f.toLowerCase().includes("arm")||f.toLowerCase().includes("hand")||f.toLowerCase().includes("shoulder"))&&console.warn(`⚠️ Arm bone "${f}" could not be mapped to avatar skeleton`)}),G.length>0?d=new A.AnimationClip(d.name,d.duration,G):console.error("No tracks could be mapped! Animation may not work correctly.");const N={};d.tracks.forEach(y=>{y.name=y.name.replaceAll("mixamorig","");const O=y.name.split(".");if(O[1]==="position"){for(let S=0;S<y.values.length;S++)y.values[S]=y.values[S]*s;N[y.name]=new A.Vector3(y.values[0],y.values[1],y.values[2])}else O[1]==="quaternion"?N[y.name]=new A.Quaternion(y.values[0],y.values[1],y.values[2],y.values[3]):O[1]==="rotation"&&(N[O[0]+".quaternion"]=new A.Quaternion().setFromEuler(new A.Euler(y.values[0],y.values[1],y.values[2],"XYZ")).normalize())});const F={props:N};N["Hips.position"]&&(N["Hips.position"].y<.5?F.lying=!0:F.standing=!0),this.animClips.push({url:n+"-"+o,clip:d,pose:F}),this.playAnimation(n,e,t,o,s)}else{const d="Animation "+n+" (ndx="+o+") not found";console.error(d),h&&h.animations?console.error(`FBX file loaded but has ${h.animations.length} animation(s), requested index ${o}`):console.error(h?"FBX file loaded but contains no animations":"FBX file failed to load or is invalid")}}}stopAnimation(){if(this.currentFBXAction&&(this.currentFBXAction.stop(),this.currentFBXAction=null),this.currentFBXActionForCallback=null,this.currentFBXActionCallback=null,this.currentFBXActionStartTime=null,this.currentFBXActionClipDuration=null,this.mixer&&this.mixer._actions.length===0&&(this.mixer=null),this.positionWasLocked&&this.unlockAvatarPosition(),this.gesture)for(let[e,t]of Object.entries(this.gesture))t.t=this.animClock,t.d=1e3,this.poseTarget.props.hasOwnProperty(e)&&(this.poseTarget.props[e].copy(t),this.poseTarget.props[e].t=this.animClock,this.poseTarget.props[e].d=1e3);let n=this.animQueue.find(e=>e.template.name==="pose");n&&(n.ts[0]=this.animClock),this.setPoseFromTemplate(null)}async playPose(n,e=null,t=5,o=0,s=.01){if(!this.armature)return;let i=this.poseTemplates[n];if(!i){const a=this.animPoses.find(c=>c.url===n+"-"+o);a&&(i=a.pose)}if(i){this.poseName=n,this.mixer=null;let a=this.animQueue.find(c=>c.template.name==="pose");a&&(a.ts[0]=this.animClock+t*1e3+2e3),this.setPoseFromTemplate(i)}else{let c=await new tt.FBXLoader().loadAsync(n,e);if(c&&c.animations&&c.animations[o]){let l=c.animations[o];const u={};l.tracks.forEach(h=>{h.name=h.name.replaceAll("mixamorig","");const d=h.name.split(".");d[1]==="position"?u[h.name]=new A.Vector3(h.values[0]*s,h.values[1]*s,h.values[2]*s):d[1]==="quaternion"?u[h.name]=new A.Quaternion(h.values[0],h.values[1],h.values[2],h.values[3]):d[1]==="rotation"&&(u[d[0]+".quaternion"]=new A.Quaternion().setFromEuler(new A.Euler(h.values[0],h.values[1],h.values[2],"XYZ")).normalize())});const r={props:u};u["Hips.position"]&&(u["Hips.position"].y<.5?r.lying=!0:r.standing=!0),this.animPoses.push({url:n+"-"+o,pose:r}),this.playPose(n,e,t,o,s)}else{const l="Pose "+n+" (ndx="+o+") not found";console.error(l)}}}stopPose(){this.stopAnimation()}playGesture(n,e=3,t=!1,o=1e3){if(!this.armature)return;let s=this.gestureTemplates[n];if(s){this.gestureTimeout&&(clearTimeout(this.gestureTimeout),this.gestureTimeout=null);let a=this.animQueue.findIndex(c=>c.template.name==="talkinghands");a!==-1&&(this.animQueue[a].ts=this.animQueue[a].ts.map(c=>0)),this.gesture=this.propsToThreeObjects(s),t&&(this.gesture=this.mirrorPose(this.gesture)),n==="namaste"&&this.avatar.body==="M"&&(this.gesture["RightArm.quaternion"].rotateTowards(new A.Quaternion(0,1,0,0),-.25),this.gesture["LeftArm.quaternion"].rotateTowards(new A.Quaternion(0,1,0,0),-.25));for(let[c,l]of Object.entries(this.gesture))l.t=this.animClock,l.d=o,this.poseTarget.props.hasOwnProperty(c)&&(this.poseTarget.props[c].copy(l),this.poseTarget.props[c].t=this.animClock,this.poseTarget.props[c].d=o);e&&Number.isFinite(e)&&(this.gestureTimeout=setTimeout(this.stopGesture.bind(this,o),1e3*e))}let i=this.animEmojis[n];if(i&&(i&&i.link&&(i=this.animEmojis[i.link]),i)){this.lookAtCamera(500);const a=this.animFactory(i);if(a.gesture=!0,e&&Number.isFinite(e)){const c=a.ts[0],u=a.ts[a.ts.length-1]-c;if(e*1e3-u>0){const h=[];for(let R=1;R<a.ts.length;R++)h.push(a.ts[R]-a.ts[R-1]);const d=i.template?.rescale||h.map(R=>R/u),g=e*1e3-u;a.ts=a.ts.map((R,x,w)=>x===0?c:w[x-1]+h[x-1]+d[x-1]*g)}else{const h=e*1e3/u;a.ts=a.ts.map(d=>c+h*(d-c))}}this.animQueue.push(a)}}stopGesture(n=1e3){if(this.gestureTimeout&&(clearTimeout(this.gestureTimeout),this.gestureTimeout=null),this.gesture){const t=Object.entries(this.gesture);this.gesture=null;for(const[o,s]of t)this.poseTarget.props.hasOwnProperty(o)&&(this.poseTarget.props[o].copy(this.getPoseTemplateProp(o)),this.poseTarget.props[o].t=this.animClock,this.poseTarget.props[o].d=n)}let e=this.animQueue.findIndex(t=>t.gesture);e!==-1&&this.animQueue.splice(e,1)}ikSolve(n,e=null,t=!1,o=null){const s=new A.Vector3,i=new A.Vector3,a=new A.Vector3,c=new A.Vector3,l=new A.Quaternion,u=new A.Vector3,r=new A.Vector3,h=new A.Vector3,d=this.ikMesh.getObjectByName(n.root);d.position.setFromMatrixPosition(this.armature.getObjectByName(n.root).matrixWorld),d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(n.root).matrixWorld),e&&t&&e.applyQuaternion(this.armature.quaternion).add(d.position);const g=this.ikMesh.getObjectByName(n.effector),R=n.links;R.forEach(w=>{w.bone=this.ikMesh.getObjectByName(w.link),w.bone.quaternion.copy(this.getPoseTemplateProp(w.link+".quaternion"))}),d.updateMatrixWorld(!0);const x=n.iterations||10;if(e)for(let w=0;w<x;w++){let G=!1;for(let m=0,N=R.length;m<N;m++){const F=R[m].bone;F.matrixWorld.decompose(c,l,u),l.invert(),i.setFromMatrixPosition(g.matrixWorld),a.subVectors(i,c),a.applyQuaternion(l),a.normalize(),s.subVectors(e,c),s.applyQuaternion(l),s.normalize();let y=s.dot(a);y>1?y=1:y<-1&&(y=-1),y=Math.acos(y),!(y<1e-5)&&(R[m].minAngle!==void 0&&y<R[m].minAngle&&(y=R[m].minAngle),R[m].maxAngle!==void 0&&y>R[m].maxAngle&&(y=R[m].maxAngle),r.crossVectors(a,s),r.normalize(),ue.setFromAxisAngle(r,y),F.quaternion.multiply(ue),F.rotation.setFromVector3(h.setFromEuler(F.rotation).clamp(new A.Vector3(R[m].minx!==void 0?R[m].minx:-1/0,R[m].miny!==void 0?R[m].miny:-1/0,R[m].minz!==void 0?R[m].minz:-1/0),new A.Vector3(R[m].maxx!==void 0?R[m].maxx:1/0,R[m].maxy!==void 0?R[m].maxy:1/0,R[m].maxz!==void 0?R[m].maxz:1/0))),F.updateMatrixWorld(!0),G=!0)}if(!G)break}o&&R.forEach(w=>{this.poseTarget.props[w.link+".quaternion"].copy(w.bone.quaternion),this.poseTarget.props[w.link+".quaternion"].t=this.animClock,this.poseTarget.props[w.link+".quaternion"].d=o})}dispose(){this.isRunning=!1,this.stop(),this.stopSpeaking(),this.streamStop(),this.isAvatarOnly?this.armature&&(this.armature.parent&&this.armature.parent.remove(this.armature),this.clearThree(this.armature)):(this.clearThree(this.scene),this.resizeobserver.disconnect(),this.renderer&&(this.renderer.dispose(),this.renderer.domElement&&this.renderer.domElement.parentNode&&this.renderer.domElement.parentNode.removeChild(this.renderer.domElement),this.renderer=null)),this.clearThree(this.ikMesh),this.dynamicbones.dispose()}}const Ue={apiKey:"sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",endpoint:"https://api.elevenlabs.io/v1/text-to-speech",defaultVoice:"21m00Tcm4TlvDq8ikWAM",voices:{rachel:"21m00Tcm4TlvDq8ikWAM",drew:"29vD33N1CtxCmqQRPOHJ",bella:"EXAVITQu4vr4xnSDxMaL",antoni:"ErXwobaYiN019PkySvjV",elli:"MF3mGyEYCl7XYWbV9V6O",josh:"VR6AewLTigWG4xSOukaG"}},Ye={defaultVoice:"aura-2-thalia-en",voices:{thalia:"aura-2-thalia-en",asteria:"aura-2-asteria-en",orion:"aura-2-orion-en",stella:"aura-2-stella-en",athena:"aura-2-athena-en",hera:"aura-2-hera-en",zeus:"aura-2-zeus-en"}};function Ge(){return{service:"elevenlabs",endpoint:Ue.endpoint,apiKey:Ue.apiKey,defaultVoice:Ue.defaultVoice,voices:Ue.voices}}function Ot(){const W=Ge(),n=[];return Object.entries(W.voices).forEach(([e,t])=>{n.push({value:t,label:`${e.charAt(0).toUpperCase()+e.slice(1)} (${W.service})`})}),n}const $e=b.forwardRef(({avatarUrl:W="/avatars/brunette.glb",avatarBody:n="F",mood:e="neutral",ttsLang:t="en",ttsService:o=null,ttsVoice:s=null,ttsApiKey:i=null,bodyMovement:a="idle",movementIntensity:c=.5,showFullAvatar:l=!0,cameraView:u="upper",onReady:r=()=>{},onLoading:h=()=>{},onError:d=()=>{},className:g="",style:R={},animations:x={}},w)=>{const G=b.useRef(null),m=b.useRef(null),N=b.useRef(l),F=b.useRef(null),y=b.useRef(null),O=b.useRef(!1),S=b.useRef({remainingText:null,originalText:null,options:null}),f=b.useRef([]),E=b.useRef(0),[L,P]=b.useState(!0),[B,q]=b.useState(null),[K,ve]=b.useState(!1),[me,Te]=b.useState(!1);b.useEffect(()=>{O.current=me},[me]),b.useEffect(()=>{N.current=l},[l]);const fe=Ge(),be=o||fe.service;let ce;be==="browser"?ce={service:"browser",endpoint:"",apiKey:null,defaultVoice:"Google US English"}:be==="elevenlabs"?ce={service:"elevenlabs",endpoint:"https://api.elevenlabs.io/v1/text-to-speech",apiKey:i||fe.apiKey,defaultVoice:s||fe.defaultVoice||Ue.defaultVoice,voices:fe.voices||Ue.voices}:be==="deepgram"?ce={service:"deepgram",endpoint:"https://api.deepgram.com/v1/speak",apiKey:i||fe.apiKey,defaultVoice:s||fe.defaultVoice||Ye.defaultVoice,voices:fe.voices||Ye.voices}:ce={...fe,apiKey:i!==null?i:fe.apiKey};const v={url:W,body:n,avatarMood:e,ttsLang:be==="browser"?"en-US":t,ttsVoice:s||ce.defaultVoice,lipsyncLang:"en",showFullAvatar:l,bodyMovement:a,movementIntensity:c},I={ttsEndpoint:ce.endpoint,ttsApikey:ce.apiKey,ttsService:be,lipsyncModules:["en"],cameraView:u},M=b.useCallback(async()=>{if(!(!G.current||m.current))try{if(P(!0),q(null),m.current=new Ke(G.current,I),m.current.controls&&(m.current.controls.enableRotate=!1,m.current.controls.enableZoom=!1,m.current.controls.enablePan=!1,m.current.controls.enableDamping=!1),x&&Object.keys(x).length>0&&(m.current.customAnimations=x),await m.current.showAvatar(v,ne=>{if(ne.lengthComputable){const se=Math.min(100,Math.round(ne.loaded/ne.total*100));h(se)}}),await new Promise(ne=>{const se=()=>{m.current.lipsync&&Object.keys(m.current.lipsync).length>0?ne():setTimeout(se,100)};se()}),m.current&&m.current.setShowFullAvatar)try{m.current.setShowFullAvatar(l)}catch(ne){console.warn("Error setting full body mode on initialization:",ne)}m.current&&m.current.controls&&(m.current.controls.enableRotate=!1,m.current.controls.enableZoom=!1,m.current.controls.enablePan=!1,m.current.controls.enableDamping=!1,m.current.controls.update()),P(!1),ve(!0),r(m.current);const j=()=>{document.visibilityState==="visible"?m.current?.start():m.current?.stop()};return document.addEventListener("visibilitychange",j),()=>{document.removeEventListener("visibilitychange",j)}}catch(z){console.error("Error initializing TalkingHead:",z),q(z.message||"Failed to initialize avatar"),P(!1),d(z)}},[W,n,e,t,o,s,i,l,a,c,u]);b.useEffect(()=>(M(),()=>{m.current&&(m.current.stop(),m.current.dispose(),m.current=null)}),[M]),b.useEffect(()=>{if(!G.current||!m.current)return;const z=new ResizeObserver(ne=>{for(const se of ne)m.current&&m.current.onResize&&m.current.onResize()});z.observe(G.current);const j=()=>{m.current&&m.current.onResize&&m.current.onResize()};return window.addEventListener("resize",j),()=>{z.disconnect(),window.removeEventListener("resize",j)}},[K]);const D=b.useCallback(async()=>{if(m.current&&m.current.audioCtx)try{(m.current.audioCtx.state==="suspended"||m.current.audioCtx.state==="interrupted")&&(await m.current.audioCtx.resume(),console.log("Audio context resumed"))}catch(z){console.warn("Failed to resume audio context:",z)}},[]),V=b.useCallback(async(z,j={})=>{if(m.current&&K)try{y.current&&(clearInterval(y.current),y.current=null),F.current={text:z,options:j},S.current={remainingText:null,originalText:null,options:null};const ne=/[!\.\?\n\p{Extended_Pictographic}]/ug,se=z.split(ne).map(re=>re.trim()).filter(re=>re.length>0);f.current=se,E.current=0,Te(!1),O.current=!1,await D();const ze={...j,lipsyncLang:j.lipsyncLang||v.lipsyncLang||"en"};if(j.onSpeechEnd&&m.current){const re=m.current;let Re=null,Fe=0;const Me=1200;let He=!1;Re=setInterval(()=>{if(Fe++,O.current)return;if(Fe>Me){if(Re&&(clearInterval(Re),Re=null,y.current=null),!He&&!O.current){He=!0;try{j.onSpeechEnd()}catch(Ae){console.error("Error in onSpeechEnd callback (timeout):",Ae)}}return}const Se=!re.speechQueue||re.speechQueue.length===0,Oe=!re.audioPlaylist||re.audioPlaylist.length===0;re&&re.isSpeaking===!1&&Se&&Oe&&re.isAudioPlaying===!1&&!He&&!O.current&&setTimeout(()=>{if(re&&!O.current&&re.isSpeaking===!1&&(!re.speechQueue||re.speechQueue.length===0)&&(!re.audioPlaylist||re.audioPlaylist.length===0)&&re.isAudioPlaying===!1&&!He&&!O.current){He=!0,Re&&(clearInterval(Re),Re=null,y.current=null);try{j.onSpeechEnd()}catch(We){console.error("Error in onSpeechEnd callback:",We)}}},100)},100),y.current=Re}m.current.lipsync&&Object.keys(m.current.lipsync).length>0?(m.current.setSlowdownRate&&m.current.setSlowdownRate(1.05),m.current.speakText(z,ze)):setTimeout(async()=>{await D(),m.current&&m.current.lipsync&&(m.current.setSlowdownRate&&m.current.setSlowdownRate(1.05),m.current.speakText(z,ze))},100)}catch(ne){console.error("Error speaking text:",ne),q(ne.message||"Failed to speak text")}},[K,D,v.lipsyncLang]),Z=b.useCallback(()=>{m.current&&(m.current.stopSpeaking(),m.current.setSlowdownRate&&m.current.setSlowdownRate(1),F.current=null,Te(!1))},[]),_=b.useCallback(()=>{if(m.current&&m.current.pauseSpeaking){const z=m.current;if(z.isSpeaking||z.audioPlaylist&&z.audioPlaylist.length>0||z.speechQueue&&z.speechQueue.length>0){y.current&&(clearInterval(y.current),y.current=null);let ne="";if(F.current&&f.current.length>0){const se=f.current.length,ze=z.speechQueue?z.speechQueue.filter(Me=>Me&&Me.text&&Array.isArray(Me.text)&&Me.text.length>0).length:0,re=z.audioPlaylist&&z.audioPlaylist.length>0,Re=ze+(re?1:0),Fe=se-Re;if(Re>0&&Fe<se&&(ne=f.current.slice(Fe).join(". ").trim(),!ne&&ze>0&&z.speechQueue)){const He=z.speechQueue.filter(Se=>Se&&Se.text&&Array.isArray(Se.text)&&Se.text.length>0).map(Se=>Se.text.map(Oe=>Oe.word||"").filter(Oe=>Oe.length>0).join(" ")).filter(Se=>Se.length>0).join(" ");He&&He.trim()&&(ne=He.trim())}}F.current&&(S.current={remainingText:ne||null,originalText:F.current.text,options:F.current.options}),z.speechQueue&&(z.speechQueue.length=0),m.current.pauseSpeaking(),O.current=!0,Te(!0)}}},[]),te=b.useCallback(async()=>{if(!m.current||!me)return;let z="",j={};if(S.current&&S.current.remainingText)z=S.current.remainingText,j=S.current.options||{},S.current={remainingText:null,originalText:null,options:null};else if(F.current&&F.current.text)z=F.current.text,j=F.current.options||{};else{console.warn("Resume called but no paused speech found"),Te(!1),O.current=!1;return}Te(!1),O.current=!1,await D();const ne={...j,lipsyncLang:j.lipsyncLang||v.lipsyncLang||"en"};try{await V(z,ne)}catch(se){console.error("Error resuming speech:",se),Te(!1),O.current=!1}},[D,me,V,v]),de=b.useCallback(z=>{m.current&&m.current.setMood(z)},[]),pe=b.useCallback(z=>{m.current&&m.current.setSlowdownRate&&m.current.setSlowdownRate(z)},[]),qe=b.useCallback((z,j=!1)=>{if(m.current&&m.current.playAnimation){if(x&&x[z]&&(z=x[z]),m.current.setShowFullAvatar)try{m.current.setShowFullAvatar(N.current)}catch(se){console.warn("Error setting full body mode:",se)}if(z.includes("."))try{m.current.playAnimation(z,null,10,0,.01,j)}catch(se){console.warn(`Failed to play ${z}:`,se);try{m.current.setBodyMovement("idle")}catch(ze){console.warn("Fallback animation also failed:",ze)}}else{const se=[".fbx",".glb",".gltf"];let ze=!1;for(const re of se)try{m.current.playAnimation(z+re,null,10,0,.01,j),ze=!0;break}catch{}if(!ze){console.warn("Animation not found:",z);try{m.current.setBodyMovement("idle")}catch(re){console.warn("Fallback animation also failed:",re)}}}}},[x]),Ie=b.useCallback(()=>{m.current&&m.current.onResize&&m.current.onResize()},[]);return b.useImperativeHandle(w,()=>({speakText:V,stopSpeaking:Z,pauseSpeaking:_,resumeSpeaking:te,resumeAudioContext:D,setMood:de,setTimingAdjustment:pe,playAnimation:qe,isReady:K,isPaused:me,talkingHead:m.current,handleResize:Ie,setBodyMovement:z=>{if(m.current&&m.current.setShowFullAvatar&&m.current.setBodyMovement)try{m.current.setShowFullAvatar(N.current),m.current.setBodyMovement(z)}catch(j){console.warn("Error setting body movement:",j)}},setMovementIntensity:z=>m.current?.setMovementIntensity(z),playRandomDance:()=>{if(m.current&&m.current.setShowFullAvatar&&m.current.playRandomDance)try{m.current.setShowFullAvatar(N.current),m.current.playRandomDance()}catch(z){console.warn("Error playing random dance:",z)}},playReaction:z=>{if(m.current&&m.current.setShowFullAvatar&&m.current.playReaction)try{m.current.setShowFullAvatar(N.current),m.current.playReaction(z)}catch(j){console.warn("Error playing reaction:",j)}},playCelebration:()=>{if(m.current&&m.current.setShowFullAvatar&&m.current.playCelebration)try{m.current.setShowFullAvatar(N.current),m.current.playCelebration()}catch(z){console.warn("Error playing celebration:",z)}},setShowFullAvatar:z=>{if(m.current&&m.current.setShowFullAvatar)try{N.current=z,m.current.setShowFullAvatar(z)}catch(j){console.warn("Error setting showFullAvatar:",j)}},lockAvatarPosition:()=>{if(m.current&&m.current.lockAvatarPosition)try{m.current.lockAvatarPosition()}catch(z){console.warn("Error locking avatar position:",z)}},unlockAvatarPosition:()=>{if(m.current&&m.current.unlockAvatarPosition)try{m.current.unlockAvatarPosition()}catch(z){console.warn("Error unlocking avatar position:",z)}}})),Q.jsxs("div",{className:`talking-head-avatar ${g}`,style:{width:"100%",height:"100%",position:"relative",...R},children:[Q.jsx("div",{ref:G,className:"talking-head-viewer",style:{width:"100%",height:"100%",minHeight:"400px"}}),L&&Q.jsx("div",{className:"loading-overlay",style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",color:"white",fontSize:"18px",zIndex:10},children:"Loading avatar..."}),B&&Q.jsx("div",{className:"error-overlay",style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",color:"#ff6b6b",fontSize:"16px",textAlign:"center",zIndex:10,padding:"20px",borderRadius:"8px"},children:B})]})});$e.displayName="TalkingHeadAvatar";const rt=b.forwardRef(({text:W="Hello! I'm a talking avatar. How are you today?",onLoading:n=()=>{},onError:e=()=>{},onReady:t=()=>{},className:o="",style:s={},avatarConfig:i={}},a)=>{const c=b.useRef(null),l=b.useRef(null),[u,r]=b.useState(!0),[h,d]=b.useState(null),[g,R]=b.useState(!1),x=Ge(),w=i.ttsService||x.service,G=w==="browser"?{endpoint:"",apiKey:null,defaultVoice:"Google US English"}:{...x,apiKey:i.ttsApiKey!==void 0&&i.ttsApiKey!==null?i.ttsApiKey:x.apiKey,endpoint:w==="elevenlabs"&&i.ttsApiKey?"https://api.elevenlabs.io/v1/text-to-speech":x.endpoint},m={url:"/avatars/brunette.glb",body:"F",avatarMood:"neutral",ttsLang:w==="browser"?"en-US":"en",ttsVoice:i.ttsVoice||G.defaultVoice,lipsyncLang:"en",showFullAvatar:!0,bodyMovement:"idle",movementIntensity:.5,...i},N={ttsEndpoint:G.endpoint,ttsApikey:G.apiKey,ttsService:w,lipsyncModules:["en"],cameraView:"upper"},F=b.useCallback(async()=>{if(!(!c.current||l.current))try{if(r(!0),d(null),l.current=new Ke(c.current,N),await l.current.showAvatar(m,B=>{if(B.lengthComputable){const q=Math.min(100,Math.round(B.loaded/B.total*100));n(q)}}),l.current.morphs&&l.current.morphs.length>0){const B=l.current.morphs[0].morphTargetDictionary;console.log("Available morph targets:",Object.keys(B));const q=Object.keys(B).filter(K=>K.startsWith("viseme_"));console.log("Viseme morph targets found:",q),q.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"))}if(await new Promise(B=>{const q=()=>{l.current.lipsync&&Object.keys(l.current.lipsync).length>0?(console.log("Lip-sync modules loaded:",Object.keys(l.current.lipsync)),B()):(console.log("Waiting for lip-sync modules to load..."),setTimeout(q,100))};q()}),l.current&&l.current.setShowFullAvatar)try{l.current.setShowFullAvatar(!0),console.log("Avatar initialized in full body mode")}catch(B){console.warn("Error setting full body mode on initialization:",B)}r(!1),R(!0),t(l.current);const P=()=>{document.visibilityState==="visible"?l.current?.start():l.current?.stop()};return document.addEventListener("visibilitychange",P),()=>{document.removeEventListener("visibilitychange",P)}}catch(L){console.error("Error initializing TalkingHead:",L),d(L.message||"Failed to initialize avatar"),r(!1),e(L)}},[]);b.useEffect(()=>(F(),()=>{l.current&&(l.current.stop(),l.current.dispose(),l.current=null)}),[F]);const y=b.useCallback(L=>{if(l.current&&g)try{console.log("Speaking text:",L),console.log("Avatar config:",m),console.log("TalkingHead instance:",l.current),l.current.lipsync&&Object.keys(l.current.lipsync).length>0?(console.log("Lip-sync modules loaded:",Object.keys(l.current.lipsync)),l.current.setSlowdownRate&&(l.current.setSlowdownRate(1.05),console.log("Applied timing adjustment for better lip-sync")),l.current.speakText(L)):(console.warn("Lip-sync modules not ready, waiting..."),setTimeout(()=>{l.current&&l.current.lipsync?(console.log("Lip-sync now ready, speaking..."),l.current.setSlowdownRate&&(l.current.setSlowdownRate(1.05),console.log("Applied timing adjustment for better lip-sync")),l.current.speakText(L)):console.error("Lip-sync still not ready after waiting")},500))}catch(P){console.error("Error speaking text:",P),d(P.message||"Failed to speak text")}else console.warn("Avatar not ready for speaking. isReady:",g,"talkingHeadRef:",!!l.current)},[g,m]),O=b.useCallback(()=>{l.current&&(l.current.stopSpeaking(),l.current.setSlowdownRate&&(l.current.setSlowdownRate(1),console.log("Reset timing to normal")))},[]),S=b.useCallback(L=>{l.current&&l.current.setMood(L)},[]),f=b.useCallback(L=>{l.current&&l.current.setSlowdownRate&&(l.current.setSlowdownRate(L),console.log("Timing adjustment set to:",L))},[]),E=b.useCallback((L,P=!1)=>{if(l.current&&l.current.playAnimation){if(l.current.setShowFullAvatar)try{l.current.setShowFullAvatar(!0)}catch(q){console.warn("Error setting full body mode:",q)}if(L.includes("."))try{l.current.playAnimation(L,null,10,0,.01,P),console.log("Playing animation:",L)}catch(q){console.log(`Failed to play ${L}:`,q);try{l.current.setBodyMovement("idle"),console.log("Fallback to idle animation")}catch(K){console.warn("Fallback animation also failed:",K)}}else{const q=[".fbx",".glb",".gltf"];let K=!1;for(const ve of q)try{l.current.playAnimation(L+ve,null,10,0,.01,P),console.log("Playing animation:",L+ve),K=!0;break}catch{console.log(`Failed to play ${L}${ve}, trying next format...`)}if(!K){console.warn("Animation system not available or animation not found:",L);try{l.current.setBodyMovement("idle"),console.log("Fallback to idle animation")}catch(ve){console.warn("Fallback animation also failed:",ve)}}}}else console.warn("Animation system not available or animation not found:",L)},[]);return b.useImperativeHandle(a,()=>({speakText:y,stopSpeaking:O,setMood:S,setTimingAdjustment:f,playAnimation:E,isReady:g,talkingHead:l.current,setBodyMovement:L=>{if(l.current&&l.current.setShowFullAvatar&&l.current.setBodyMovement)try{l.current.setShowFullAvatar(!0),l.current.setBodyMovement(L),console.log("Body movement set with full body mode:",L)}catch(P){console.warn("Error setting body movement:",P)}},setMovementIntensity:L=>l.current?.setMovementIntensity(L),playRandomDance:()=>{if(l.current&&l.current.setShowFullAvatar&&l.current.playRandomDance)try{l.current.setShowFullAvatar(!0),l.current.playRandomDance(),console.log("Random dance played with full body mode")}catch(L){console.warn("Error playing random dance:",L)}},playReaction:L=>{if(l.current&&l.current.setShowFullAvatar&&l.current.playReaction)try{l.current.setShowFullAvatar(!0),l.current.playReaction(L),console.log("Reaction played with full body mode:",L)}catch(P){console.warn("Error playing reaction:",P)}},playCelebration:()=>{if(l.current&&l.current.setShowFullAvatar&&l.current.playCelebration)try{l.current.setShowFullAvatar(!0),l.current.playCelebration(),console.log("Celebration played with full body mode")}catch(L){console.warn("Error playing celebration:",L)}},setShowFullAvatar:L=>{if(l.current&&l.current.setShowFullAvatar)try{l.current.setShowFullAvatar(L),console.log("Show full avatar set to:",L)}catch(P){console.warn("Error setting showFullAvatar:",P)}},lockAvatarPosition:()=>{if(l.current&&l.current.lockAvatarPosition)try{l.current.lockAvatarPosition()}catch(L){console.warn("Error locking avatar position:",L)}},unlockAvatarPosition:()=>{if(l.current&&l.current.unlockAvatarPosition)try{l.current.unlockAvatarPosition()}catch(L){console.warn("Error unlocking avatar position:",L)}}})),Q.jsxs("div",{className:`talking-head-container ${o}`,style:s,children:[Q.jsx("div",{ref:c,className:"talking-head-viewer",style:{width:"100%",height:"100%",minHeight:"400px"}}),u&&Q.jsx("div",{className:"loading-overlay",style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",color:"white",fontSize:"18px",zIndex:10},children:"Loading avatar..."}),h&&Q.jsx("div",{className:"error-overlay",style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",color:"#ff6b6b",fontSize:"16px",textAlign:"center",zIndex:10,padding:"20px",borderRadius:"8px"},children:h})]})});rt.displayName="TalkingHeadComponent";async function Xe(W){try{const n=await fetch(W);if(!n.ok){if(n.status===404)return{};throw new Error(`Failed to fetch manifest: ${n.status} ${n.statusText}`)}const e=n.headers.get("content-type");if(e&&!e.includes("application/json"))return{};const t=await n.text();return t.trim().startsWith("<!")?{}:JSON.parse(t).animations||{}}catch(n){return n instanceof SyntaxError||console.warn("⚠️ Could not load animation manifest (this is optional):",W),{}}}async function Dt(W,n="F"){const e=[],t=W.replace(/\/$/,"");try{const i=[`${t}/.list.json`,`/api/directory?path=${encodeURIComponent(t)}`,`${t}/index.json`];for(const a of i)try{const c=await fetch(a);if(c.ok){const l=await c.json(),r=(Array.isArray(l)?l:l.files||[]).filter(h=>typeof h=="string"&&h.toLowerCase().endsWith(".fbx")).map(h=>h.startsWith("/")?h:`${t}/${h}`);if(r.length>0)return r}}catch{continue}}catch(i){console.warn(`⚠️ Could not use directory listing API for ${t}:`,i)}let o="F";if(n){const i=n.toString().toUpperCase().trim();i==="M"||i==="MALE"?o="M":(i==="F"||i==="FEMALE")&&(o="F")}const s=[];o==="M"?s.push(`${t}/male`,`${t}/m`):s.push(`${t}/female`,`${t}/f`),s.push(`${t}/shared`);for(const i of s)try{const a=`${i}/.list.json`,c=await fetch(a);if(c.ok){const l=await c.json(),u=(Array.isArray(l)?l:l.files||[]).filter(r=>typeof r=="string"&&r.toLowerCase().endsWith(".fbx")).map(r=>r.startsWith("/")?r:`${i}/${r}`);u.length>0&&e.push(...u)}}catch{continue}return e.length>0,e}async function st(W,n="F"){const e={};for(const[t,o]of Object.entries(W))try{const s=await Dt(o,n);s.length>0&&(e[t]=s)}catch(s){console.error(`❌ Failed to auto-load animations from ${o}:`,s)}return e}const at=b.forwardRef(({text:W=null,avatarUrl:n="/avatars/brunette.glb",avatarBody:e="F",mood:t="neutral",ttsLang:o="en",ttsService:s=null,ttsVoice:i=null,ttsApiKey:a=null,bodyMovement:c="idle",movementIntensity:l=.5,showFullAvatar:u=!1,cameraView:r="upper",onReady:h=()=>{},onLoading:d=()=>{},onError:g=()=>{},onSpeechStart:R=()=>{},onSpeechEnd:x=()=>{},className:w="",style:G={},animations:m={},autoAnimationGroup:N=null,autoIdleGroup:F=null,autoSpeak:y=!1},O)=>{const S=b.useRef(null),f=b.useRef(null),E=b.useRef(u),L=b.useRef(null),P=b.useRef(null),B=b.useRef(!1),q=b.useRef({remainingText:null,originalText:null,options:null}),K=b.useRef([]),[ve,me]=b.useState(!0),[Te,fe]=b.useState(null),[be,ce]=b.useState(!1),[v,I]=b.useState(!1),[M,D]=b.useState(m),V=b.useRef(null),Z=b.useRef(!1),_=b.useRef(null),te=b.useRef(!1),de=b.useRef([]),pe=b.useRef([]),qe=b.useRef(0),Ie=b.useRef(null);b.useEffect(()=>{B.current=v},[v]);const z=b.useCallback(k=>{let C="F";if(k){const T=k.toString().toUpperCase().trim();T==="M"||T==="MALE"?C="M":(T==="F"||T==="FEMALE")&&(C="F")}return C==="M"?"male":"female"},[]);b.useEffect(()=>{(async()=>{if(m.manifest&&m.auto)try{const C=await Xe(m.manifest);D(C);return}catch{}if(m.manifest&&!m.auto){const C=await Xe(m.manifest),T=Object.keys(C).length>0;D(T?C:m)}else if(m.auto)try{let C=null;if(m.manifest)try{C=await Xe(m.manifest)}catch{}if(typeof m.auto=="string"){const T=m.auto,$={talking:`${T}/talking`,idle:`${T}/idle`},X=z(e);$[`${X}_talking`]=`${T}/${X}/talking`,$[`${X}_idle`]=`${T}/${X}/idle`,$.shared_talking=`${T}/shared/talking`,$.shared_idle=`${T}/shared/idle`;const ie=await st($,e);if(!Object.values(ie).some(Y=>Array.isArray(Y)&&Y.length>0)&&C){D(C);return}const le={_genderSpecific:{[X]:{},shared:{}}};Object.entries(ie).forEach(([Y,J])=>{if(Y.includes("_")){const[ee,...ge]=Y.split("_"),he=ge.join("_");ee==="shared"?(le._genderSpecific.shared[he]||(le._genderSpecific.shared[he]=[]),le._genderSpecific.shared[he].push(...J)):ee===X&&(le._genderSpecific[X][he]||(le._genderSpecific[X][he]=[]),le._genderSpecific[X][he].push(...J))}else le[Y]=J}),C&&(C._genderSpecific&&Object.keys(C._genderSpecific).forEach(Y=>{le._genderSpecific[Y]||(le._genderSpecific[Y]={}),Object.entries(C._genderSpecific[Y]).forEach(([J,ee])=>{le._genderSpecific[Y][J]||(le._genderSpecific[Y][J]=ee)})}),Object.entries(C).forEach(([Y,J])=>{Y!=="_genderSpecific"&&!le[Y]&&(le[Y]=J)})),D(le)}else if(typeof m.auto=="object"){const T=await st(m.auto,e),$=Object.values(T).some(X=>Array.isArray(X)&&X.length>0);D(!$&&C?C:T)}}catch(C){if(console.error("Failed to auto-discover animations:",C),m.manifest)try{const T=await Xe(m.manifest);D(T)}catch{D(m)}else D(m)}else D(m)})()},[m,e,z]),b.useEffect(()=>{E.current=u},[u]);const j=Ge(),ne=s||j.service;let se;ne==="browser"?se={service:"browser",endpoint:"",apiKey:null,defaultVoice:"Google US English"}:ne==="elevenlabs"?se={service:"elevenlabs",endpoint:"https://api.elevenlabs.io/v1/text-to-speech",apiKey:a||j.apiKey,defaultVoice:i||j.defaultVoice||Ue.defaultVoice,voices:j.voices||Ue.voices}:ne==="deepgram"?se={service:"deepgram",endpoint:"https://api.deepgram.com/v1/speak",apiKey:a||j.apiKey,defaultVoice:i||j.defaultVoice||Ye.defaultVoice,voices:j.voices||Ye.voices}:se={...j,apiKey:a!==null?a:j.apiKey};const ze={url:n,body:e,avatarMood:t,ttsLang:ne==="browser"?"en-US":o,ttsVoice:i||se.defaultVoice,lipsyncLang:"en",showFullAvatar:u,bodyMovement:c,movementIntensity:l},re={ttsEndpoint:se.endpoint,ttsApikey:se.apiKey,ttsService:ne,lipsyncModules:["en"],cameraView:r},Re=b.useCallback(async()=>{if(!(!S.current||f.current))try{me(!0),fe(null),f.current=new Ke(S.current,re),await f.current.showAvatar(ze,C=>{if(C.lengthComputable){const T=Math.min(100,Math.round(C.loaded/C.total*100));d(T)}}),me(!1),ce(!0),h(f.current);const k=()=>{document.visibilityState==="visible"?f.current?.start():f.current?.stop()};return document.addEventListener("visibilitychange",k),()=>{document.removeEventListener("visibilitychange",k)}}catch(k){console.error("Error initializing TalkingHead:",k),fe(k.message||"Failed to initialize avatar"),me(!1),g(k)}},[]);b.useEffect(()=>(Re(),()=>{f.current&&(f.current.stop(),f.current.dispose(),f.current=null)}),[Re]);const Fe=b.useCallback(async()=>{if(f.current)try{const k=f.current.audioCtx||f.current.audioContext;k&&(k.state==="suspended"||k.state==="interrupted")&&await k.resume()}catch(k){console.warn("Failed to resume audio context:",k)}},[]),Me=b.useCallback(k=>{if(!M)return[];let C=null;if(M._genderSpecific){const T=z(e),$=M._genderSpecific[T];if($&&$[k]&&Array.isArray($[k])&&$[k].length>0&&(C=$[k]),!C&&M._genderSpecific.shared&&M._genderSpecific.shared[k]){const X=M._genderSpecific.shared[k];Array.isArray(X)&&X.length>0&&(C=X)}}if(!C&&M[k]){const T=M[k];Array.isArray(T)&&T.length>0?C=T:typeof T=="string"&&(C=[T])}return!C||Array.isArray(C)&&C.length===0?((Object.keys(M).length>0||M._genderSpecific&&Object.keys(M._genderSpecific).length>0)&&console.warn(`⚠️ No animations found for group "${k}" (gender: ${z(e)}). Make sure animations are configured correctly.`),[]):Array.isArray(C)?[...C]:typeof C=="string"?[C]:[]},[M,e,z]),He=b.useCallback(k=>{const C=[...k];for(let T=C.length-1;T>0;T--){const $=Math.floor(Math.random()*(T+1));[C[T],C[$]]=[C[$],C[T]]}return C},[]),Se=b.useCallback(k=>{if(pe.current.length===0){const T=Me(k);if(T.length===0)return null;pe.current=He(T),de.current=[]}const C=pe.current.shift();return C&&de.current.push(C),C},[Me,He]),Oe=b.useCallback(k=>k?k.split("/").pop().replace(".fbx","").replace(/[-_]/g," "):"Unknown",[]),Ve=b.useCallback(()=>{F&&f.current&&!Z.current&&(V.current&&(clearInterval(V.current),V.current=null),pe.current=[],de.current=[],Ae(F,!1,null),V.current=setInterval(()=>{!Z.current&&!B.current&&F&&(pe.current=[],de.current=[],Ae(F,!1,null))},12e3+Math.random()*3e3))},[F,Ae]),Ae=b.useCallback((k,C=!1,T=null)=>{if(!f.current||!Z.current||_.current!==k)return null;const $=Se(k);if($)try{const X=Oe($);console.log(`🎬 Playing animation: "${X}"`);const ie=()=>{console.log("🎬 Animation finished, checking if should continue...");const ae=()=>{if(!f.current)return console.log("🎬 No talkingHeadRef, stopping animations"),!1;if(!Z.current)return console.log("🎬 isSpeakingRef is false, stopping animations"),!1;if(_.current!==k)return console.log(`🎬 Animation group mismatch (${_.current} !== ${k}), stopping animations`),!1;const Y=f.current,J=Y.isAudioPlaying===!0,ee=Y.audioPlaylist&&Y.audioPlaylist.length>0,ge=Y.speechQueue&&Y.speechQueue.length>0,he=Y.isSpeaking===!0,De=he||J||ee||ge;return console.log("🎬 Still speaking check:",{isSpeakingRef:Z.current,isTalkingHeadSpeaking:he,hasAudioPlaying:J,hasAudioInPlaylist:ee,hasItemsInQueue:ge,shouldContinue:De}),De};ae()?(console.log("🎬 Still speaking, continuing to next animation..."),requestAnimationFrame(()=>{ae()?(console.log("🎬 Playing next animation..."),Ae(k,C,T)):(console.log("🎬 Speech ended, stopping animations"),Z.current=!1,_.current=null,f.current&&f.current.stopAnimation(),T&&T())})):(console.log("🎬 Speech has ended, stopping animations"),Z.current=!1,_.current=null,f.current&&f.current.stopAnimation(),T&&T())};return f.current.playAnimation($,null,0,0,.01,C,ie),$}catch(X){return console.error("Failed to play animation:",X),null}else{const X=()=>{if(!f.current||!Z.current||_.current!==k)return!1;const ae=f.current,le=ae.isAudioPlaying===!0,Y=ae.audioPlaylist&&ae.audioPlaylist.length>0,J=ae.speechQueue&&ae.speechQueue.length>0;return ae.isSpeaking===!0||le||Y||J};X()&&(pe.current=[],de.current=[],X()?Ae(k,C,T):(Z.current=!1,_.current=null,f.current&&f.current.stopAnimation()))}return null},[Se,Oe]),We=b.useCallback(async(k,C={})=>{if(!f.current||!be||!k||k.trim()==="")return;await Fe(),V.current&&(clearInterval(V.current),V.current=null);const T=C.animationGroup||N;T&&!C.skipAnimation&&(Z.current=!0,_.current=T,pe.current=[],de.current=[],Ae(T));try{R(k),C.onSpeechStart&&C.onSpeechStart(k)}catch(ie){console.warn("Error in onSpeechStart callback:",ie)}q.current={remainingText:null,originalText:null,options:null},K.current=[],L.current={text:k,options:C},P.current&&(clearInterval(P.current),P.current=null),I(!1),B.current=!1,te.current=!1;const $=k.split(/[.!?]+/).filter(ie=>ie.trim().length>0);K.current=$,qe.current=0;const X={lipsyncLang:C.lipsyncLang||"en"};if(f.current){const ie=f.current;let ae=0;const le=1200;P.current&&(clearInterval(P.current),P.current=null);const Y={current:!1},J=setInterval(()=>{if(ae++,B.current)return;if(ae>le){if(J&&(clearInterval(J),P.current=null),!Y.current&&!B.current){Y.current=!0,Z.current=!1,_.current=null,pe.current=[],de.current=[],f.current&&(f.current.stopAnimation(),f.current.isSpeaking=!1);try{C.onSpeechEnd&&C.onSpeechEnd(),x()}catch(ke){console.error("Error in onSpeechEnd callback (timeout):",ke)}}return}const ee=!ie.speechQueue||ie.speechQueue.length===0,ge=!ie.audioPlaylist||ie.audioPlaylist.length===0,he=ie.isAudioPlaying===!1;ie&&!B.current&&ee&&ge&&he&&ie.isSpeaking===!1&&!Y.current&&!B.current&&setTimeout(()=>{const ke=f.current;if(!ke)return;!B.current&&(!ke.speechQueue||ke.speechQueue.length===0)&&(!ke.audioPlaylist||ke.audioPlaylist.length===0)&&ke.isAudioPlaying===!1&&ke.isSpeaking===!1&&!Y.current&&!B.current&&(Y.current=!0,J&&(clearInterval(J),P.current=null),Z.current=!1,_.current=null,pe.current=[],de.current=[],ke&&(ke.stopAnimation(),ke.isSpeaking=!1),te.current=!0,setTimeout(()=>{Ve()},500),setTimeout(()=>{try{C.onSpeechEnd&&C.onSpeechEnd(),x(),setTimeout(()=>{te.current=!1},500)}catch(et){console.error("Error in onSpeechEnd callback:",et),te.current=!1}},100))},200)},50);P.current=J}try{f.current.speakText(k,X)}catch(ie){console.error("Error speaking text:",ie),fe(ie.message||"Failed to speak text")}},[be,x,Fe,N,Ae,Ve]);b.useEffect(()=>{if(!be||!F||!f.current)return;V.current&&(clearInterval(V.current),V.current=null);const k=()=>{f.current&&!B.current&&!Z.current&&(pe.current=[],de.current=[],Ae(F,!1,null))};return Z.current||k(),V.current=setInterval(()=>{Z.current||k()},12e3+Math.random()*3e3),()=>{V.current&&(clearInterval(V.current),V.current=null)}},[be,F,Ae,Z]),b.useEffect(()=>{be&&W&&y&&f.current&&!Z.current&&!B.current&&!te.current&&We(W)},[be,W,y,We]);const ut=b.useCallback(()=>{if(f.current)try{const k=f.current.isSpeaking||!1,C=[...f.current.audioPlaylist||[]],T=[...f.current.speechQueue||[]];if(k||C.length>0||T.length>0){P.current&&(clearInterval(P.current),P.current=null);const $=K.current;let X=[];const ie=f.current.isAudioPlaying||!1;if($.length>0){const ee=C.length+T.length,ge=ie?1:0,he=$.length-ee-ge,De=ie?he:he+ge;De<$.length&&(X=$.slice(De))}else C.length>0&&C.forEach(ee=>{if(ee.text)if(Array.isArray(ee.text)){const ge=ee.text.map(he=>he.word).join(" ");ge.trim()&&X.push(ge)}else ee.text.trim()&&X.push(ee.text)}),T.length>0&&T.forEach(ee=>{if(ee.text)if(Array.isArray(ee.text)){const ge=ee.text.map(he=>he.word).join(" ");ge.trim()&&X.push(ge)}else ee.text.trim()&&X.push(ee.text)});const ae=X.join(" ");q.current={remainingText:ae||null,originalText:L.current?.text||null,options:L.current?.options||null,isMidSentence:C.length>0};const Y=f.current.isAudioPlaying||!1?[...f.current.speechQueue||[]]:null;f.current.speechQueue.length=0;const J=f.current.pauseSpeaking();f.current.isSpeaking=!1,Z.current=!1,_.current=null,J&&J.audio&&Y?(Ie.current=J,Ie.current.savedSpeechQueue=Y):Ie.current=J,I(!0),B.current=!0}}catch(k){console.warn("Error pausing speech:",k)}},[]),ct=b.useCallback(async()=>{if(!(!f.current||!v))try{if(await Fe(),I(!1),B.current=!1,Ie.current&&Ie.current.audio){Z.current=!0;const X=q.current?.options||L.current?.options||{},ie=X.animationGroup||N;if(ie&&(_.current=ie),Ie.current.savedSpeechQueue&&(f.current.speechQueue.length=0,f.current.speechQueue.push(...Ie.current.savedSpeechQueue)),f.current.isSpeaking=!0,f.current){const ae=f.current;let le=0;const Y=1200,J={current:!1};P.current&&(clearInterval(P.current),P.current=null);const ee=setInterval(()=>{if(le++,B.current)return;if(le>Y){if(ee&&(clearInterval(ee),P.current=null),!J.current&&!B.current){J.current=!0,Z.current=!1,_.current=null,pe.current=[],de.current=[],f.current&&(f.current.stopAnimation(),f.current.isSpeaking=!1);try{X.onSpeechEnd&&X.onSpeechEnd(),x()}catch(we){console.error("Error in onSpeechEnd callback (timeout):",we)}}return}const ge=!ae.speechQueue||ae.speechQueue.length===0,he=!ae.audioPlaylist||ae.audioPlaylist.length===0,De=ae.isAudioPlaying===!1;ae&&!B.current&&ge&&he&&De&&ae.isSpeaking===!1&&!J.current&&!B.current&&setTimeout(()=>{const we=f.current;if(!we)return;!B.current&&(!we.speechQueue||we.speechQueue.length===0)&&(!we.audioPlaylist||we.audioPlaylist.length===0)&&we.isAudioPlaying===!1&&we.isSpeaking===!1&&!J.current&&!B.current&&(J.current=!0,ee&&(clearInterval(ee),P.current=null),Z.current=!1,_.current=null,pe.current=[],de.current=[],we&&(we.stopAnimation(),we.isSpeaking=!1),te.current=!0,setTimeout(()=>{Ve()},500),setTimeout(()=>{try{X.onSpeechEnd&&X.onSpeechEnd(),x(),setTimeout(()=>{te.current=!1},500)}catch(dt){console.error("Error in onSpeechEnd callback:",dt),te.current=!1}},100))},200)},50);P.current=ee}await f.current.playAudio(!1,Ie.current),ie&&!X.skipAnimation&&(pe.current=[],de.current=[],Ae(ie)),Ie.current=null;return}const k=q.current?.remainingText,C=q.current?.originalText||L.current?.text,T=q.current?.options||L.current?.options||{},$=k||C;$&&We($,T),Ie.current=null}catch(k){console.warn("Error resuming speech:",k),I(!1),B.current=!1,Ie.current=null}},[v,We,Fe,N,Ae]),ht=b.useCallback(()=>{if(f.current){f.current.stopAnimation(),f.current.stopSpeaking(),P.current&&(clearInterval(P.current),P.current=null),Z.current=!1,_.current=null,pe.current=[],de.current=[],I(!1),B.current=!1,Ie.current=null,te.current=!1,setTimeout(()=>{Ve()},500);try{x()}catch(k){console.warn("Error in onSpeechEnd callback (stopSpeaking):",k)}}},[x]);return b.useImperativeHandle(O,()=>({speakText:We,pauseSpeaking:ut,resumeSpeaking:ct,stopSpeaking:ht,resumeAudioContext:Fe,isPaused:()=>v,setMood:k=>f.current?.setMood(k),setBodyMovement:k=>{f.current&&f.current.setBodyMovement(k)},playAnimation:(k,C=!1)=>{f.current&&f.current.playAnimation&&f.current.playAnimation(k,null,10,0,.01,C)},playRandomAnimation:(k,C=!1)=>Ae(k,C),getRandomAnimation:k=>getRandomAnimation(k),playReaction:k=>f.current?.playReaction(k),playCelebration:()=>f.current?.playCelebration(),setShowFullAvatar:k=>{f.current&&(E.current=k,f.current.setShowFullAvatar(k))},isReady:be,talkingHead:f.current})),Q.jsxs("div",{className:`simple-talking-avatar-container ${w}`,style:G,children:[Q.jsx("div",{ref:S,className:"talking-head-viewer",style:{width:"100%",height:"100%",minHeight:"400px"}}),ve&&Q.jsx("div",{className:"loading-overlay",style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",color:"white",fontSize:"18px",zIndex:10},children:"Loading avatar..."}),Te&&Q.jsx("div",{className:"error-overlay",style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",color:"#ff6b6b",fontSize:"16px",textAlign:"center",zIndex:10,padding:"20px",borderRadius:"8px"},children:Te})]})});at.displayName="SimpleTalkingAvatar";const lt=b.forwardRef(({curriculumData:W=null,avatarConfig:n={},animations:e={},onLessonStart:t=()=>{},onLessonComplete:o=()=>{},onQuestionAnswer:s=()=>{},onCurriculumComplete:i=()=>{},onCustomAction:a=()=>{},autoStart:c=!1},l)=>{const u=b.useRef(null),r=b.useRef({currentModuleIndex:0,currentLessonIndex:0,currentQuestionIndex:0,isTeaching:!1,isQuestionMode:!1,lessonCompleted:!1,curriculumCompleted:!1,score:0,totalQuestions:0}),h=b.useRef({onLessonStart:t,onLessonComplete:o,onQuestionAnswer:s,onCurriculumComplete:i,onCustomAction:a}),d=b.useRef(null),g=b.useRef(null),R=b.useRef(null),x=b.useRef(null),w=b.useRef(null),G=b.useRef(null),m=b.useRef(null),N=b.useRef(W?.curriculum||{title:"Default Curriculum",description:"No curriculum data provided",language:"en",modules:[]}),F=b.useRef({avatarUrl:n.avatarUrl||"/avatars/brunette.glb",avatarBody:n.avatarBody||"F",mood:n.mood||"happy",ttsLang:n.ttsLang||"en",ttsService:n.ttsService||null,ttsVoice:n.ttsVoice||null,ttsApiKey:n.ttsApiKey||null,bodyMovement:n.bodyMovement||"gesturing",movementIntensity:n.movementIntensity||.7,showFullAvatar:n.showFullAvatar!==void 0?n.showFullAvatar:!1,animations:e,lipsyncLang:"en"});b.useEffect(()=>{h.current={onLessonStart:t,onLessonComplete:o,onQuestionAnswer:s,onCurriculumComplete:i,onCustomAction:a}},[t,o,s,i,a]),b.useEffect(()=>{N.current=W?.curriculum||{title:"Default Curriculum",description:"No curriculum data provided",language:"en",modules:[]},F.current={avatarUrl:n.avatarUrl||"/avatars/brunette.glb",avatarBody:n.avatarBody||"F",mood:n.mood||"happy",ttsLang:n.ttsLang||"en",ttsService:n.ttsService||null,ttsVoice:n.ttsVoice||null,ttsApiKey:n.ttsApiKey||null,bodyMovement:n.bodyMovement||"gesturing",movementIntensity:n.movementIntensity||.7,showFullAvatar:n.showFullAvatar!==void 0?n.showFullAvatar:!1,animations:e,lipsyncLang:"en"}},[W,n,e]);const y=b.useCallback(()=>(N.current||{modules:[]}).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex],[]),O=b.useCallback(()=>y()?.questions[r.current.currentQuestionIndex],[y]),S=b.useCallback((v,I)=>I.type==="multiple_choice"||I.type==="true_false"?v===I.answer:I.type==="code_test"&&typeof v=="object"&&v!==null?v.passed===!0:!1,[]),f=b.useCallback(()=>{r.current.lessonCompleted=!0,r.current.isQuestionMode=!1;const v=r.current.totalQuestions>0?Math.round(r.current.score/r.current.totalQuestions*100):100;let I="Congratulations! You've completed this lesson";if(r.current.totalQuestions>0?I+=` You got ${r.current.score} correct out of ${r.current.totalQuestions} question${r.current.totalQuestions===1?"":"s"}, achieving a score of ${v} percent. `:I+="! ",v>=80?I+="Excellent work! You have a great understanding of this topic.":v>=60?I+="Good job! You understand most of the concepts.":I+="Keep practicing! You're making progress.",h.current.onLessonComplete({moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,score:r.current.score,totalQuestions:r.current.totalQuestions,percentage:v}),h.current.onCustomAction({type:"lessonComplete",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,score:r.current.score,totalQuestions:r.current.totalQuestions,percentage:v}),u.current){if(u.current.setMood("happy"),e.lessonComplete)try{u.current.playAnimation(e.lessonComplete,!0)}catch{u.current.playCelebration()}const M=N.current||{modules:[]},D=M.modules[r.current.currentModuleIndex],V=r.current.currentLessonIndex<(D?.lessons?.length||0)-1,Z=r.current.currentModuleIndex<(M.modules?.length||0)-1,_=V||Z,te=F.current||{lipsyncLang:"en"};u.current.speakText(I,{lipsyncLang:te.lipsyncLang,onSpeechEnd:()=>{h.current.onCustomAction({type:"lessonCompleteFeedbackDone",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,score:r.current.score,totalQuestions:r.current.totalQuestions,percentage:v,hasNextLesson:_})}})}},[e.lessonComplete]),E=b.useCallback(()=>{r.current.curriculumCompleted=!0;const v=N.current||{modules:[]};if(h.current.onCurriculumComplete({modules:v.modules.length,totalLessons:v.modules.reduce((I,M)=>I+M.lessons.length,0)}),u.current){if(u.current.setMood("celebrating"),e.curriculumComplete)try{u.current.playAnimation(e.curriculumComplete,!0)}catch{u.current.playCelebration()}const I=F.current||{lipsyncLang:"en"};u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!",{lipsyncLang:I.lipsyncLang})}},[e.curriculumComplete]),L=b.useCallback(()=>{const v=y();r.current.isQuestionMode=!0,r.current.currentQuestionIndex=0,r.current.totalQuestions=v?.questions?.length||0,r.current.score=0;const I=O();I&&h.current.onCustomAction({type:"questionStart",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,totalQuestions:r.current.totalQuestions,question:I,score:r.current.score});const M=()=>{if(!u.current||!I)return;if(u.current.setMood("happy"),e.questionStart)try{u.current.playAnimation(e.questionStart,!0)}catch(V){console.warn("Failed to play questionStart animation:",V)}const D=F.current||{lipsyncLang:"en"};I.type==="code_test"?u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${I.question}`,{lipsyncLang:D.lipsyncLang}):I.type==="multiple_choice"?u.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`,{lipsyncLang:D.lipsyncLang}):I.type==="true_false"?u.current.speakText(`Let's start with some true or false questions. First question: ${I.question}`,{lipsyncLang:D.lipsyncLang}):u.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`,{lipsyncLang:D.lipsyncLang})};if(u.current&&u.current.isReady&&I)M();else if(u.current&&u.current.isReady){const D=F.current||{lipsyncLang:"en"};u.current.speakText("Now let me ask you some questions to test your understanding.",{lipsyncLang:D.lipsyncLang})}else{const D=setInterval(()=>{u.current&&u.current.isReady&&(clearInterval(D),I&&M())},100);setTimeout(()=>{clearInterval(D)},5e3)}},[e.questionStart,y,O]),P=b.useCallback(()=>{const v=y();if(r.current.currentQuestionIndex<(v?.questions?.length||0)-1){u.current&&u.current.stopSpeaking&&u.current.stopSpeaking(),r.current.currentQuestionIndex+=1;const I=O();I&&h.current.onCustomAction({type:"nextQuestion",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,totalQuestions:r.current.totalQuestions,question:I,score:r.current.score});const M=()=>{if(!u.current||!I)return;if(u.current.setMood("happy"),u.current.setBodyMovement("idle"),e.nextQuestion)try{u.current.playAnimation(e.nextQuestion,!0)}catch(te){console.warn("Failed to play nextQuestion animation:",te)}const D=F.current||{lipsyncLang:"en"},Z=y()?.questions?.length||0,_=r.current.currentQuestionIndex>=Z-1;if(I.type==="code_test"){const te=_?`Great! Here's your final coding challenge: ${I.question}`:`Great! Now let's move on to your next coding challenge: ${I.question}`;u.current.speakText(te,{lipsyncLang:D.lipsyncLang})}else if(I.type==="multiple_choice"){const te=_?`Alright! Here's your final question: ${I.question}`:`Alright! Here's your next question: ${I.question}`;u.current.speakText(te,{lipsyncLang:D.lipsyncLang})}else if(I.type==="true_false"){const te=_?`Now let's try this final one: ${I.question}`:`Now let's try this one: ${I.question}`;u.current.speakText(te,{lipsyncLang:D.lipsyncLang})}else{const te=_?`Here's your final question: ${I.question}`:`Here's the next question: ${I.question}`;u.current.speakText(te,{lipsyncLang:D.lipsyncLang})}};if(u.current&&u.current.isReady&&I)M();else if(I){const D=setInterval(()=>{u.current&&u.current.isReady&&(clearInterval(D),M())},100);setTimeout(()=>{clearInterval(D)},5e3)}}else h.current.onCustomAction({type:"allQuestionsComplete",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,totalQuestions:r.current.totalQuestions,score:r.current.score})},[e.nextQuestion,y,O]),B=b.useCallback(()=>{const v=N.current||{modules:[]},I=v.modules[r.current.currentModuleIndex];if(r.current.currentLessonIndex<(I?.lessons?.length||0)-1){r.current.currentLessonIndex+=1,r.current.currentQuestionIndex=0,r.current.lessonCompleted=!1,r.current.isQuestionMode=!1,r.current.isTeaching=!1,r.current.score=0,r.current.totalQuestions=0;const D=v.modules[r.current.currentModuleIndex],V=r.current.currentLessonIndex<(D?.lessons?.length||0)-1,Z=r.current.currentModuleIndex<(v.modules?.length||0)-1,_=V||Z;h.current.onCustomAction({type:"lessonStart",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,hasNextLesson:_}),h.current.onLessonStart({moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:y()}),u.current&&(u.current.setMood("happy"),u.current.setBodyMovement("idle"))}else if(r.current.currentModuleIndex<(v.modules?.length||0)-1){r.current.currentModuleIndex+=1,r.current.currentLessonIndex=0,r.current.currentQuestionIndex=0,r.current.lessonCompleted=!1,r.current.isQuestionMode=!1,r.current.isTeaching=!1,r.current.score=0,r.current.totalQuestions=0;const V=v.modules[r.current.currentModuleIndex],Z=r.current.currentLessonIndex<(V?.lessons?.length||0)-1,_=r.current.currentModuleIndex<(v.modules?.length||0)-1,te=Z||_;h.current.onCustomAction({type:"lessonStart",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,hasNextLesson:te}),h.current.onLessonStart({moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:y()}),u.current&&(u.current.setMood("happy"),u.current.setBodyMovement("idle"))}else w.current&&w.current()},[]),q=b.useCallback(()=>{const v=y();let I=null;if(v?.avatar_script&&v?.body){const M=v.avatar_script.trim(),D=v.body.trim(),V=M.match(/[.!?]$/)?" ":". ";I=`${M}${V}${D}`}else I=v?.avatar_script||v?.body||null;if(u.current&&u.current.isReady&&I){r.current.isTeaching=!0,r.current.isQuestionMode=!1,r.current.score=0,r.current.totalQuestions=0,u.current.setMood("happy");let M=!1;if(e.teaching)try{u.current.playAnimation(e.teaching,!0),M=!0}catch(V){console.warn("Failed to play teaching animation:",V)}M||u.current.setBodyMovement("gesturing");const D=F.current||{lipsyncLang:"en"};h.current.onLessonStart({moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:v}),h.current.onCustomAction({type:"teachingStart",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:v}),u.current.speakText(I,{lipsyncLang:D.lipsyncLang,onSpeechEnd:()=>{r.current.isTeaching=!1,h.current.onCustomAction({type:"teachingComplete",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:v,hasQuestions:v.questions&&v.questions.length>0}),v?.code_example&&h.current.onCustomAction({type:"codeExampleReady",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:v,codeExample:v.code_example})}})}},[e.teaching,y]),K=b.useCallback(v=>{const I=O(),M=S(v,I);if(M&&(r.current.score+=1),h.current.onQuestionAnswer({moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,answer:v,isCorrect:M,question:I}),u.current)if(M){if(u.current.setMood("happy"),e.correct)try{u.current.playReaction("happy")}catch{u.current.setBodyMovement("happy")}u.current.setBodyMovement("gesturing");const V=y()?.questions?.length||0;r.current.currentQuestionIndex>=V-1;const Z=r.current.currentQuestionIndex<V-1;console.log("[CurriculumLearning] Answer feedback - questionIndex:",r.current.currentQuestionIndex,"totalQuestions:",V,"hasNextQuestion:",Z);const _=I.type==="code_test"?`Great job! Your code passed all the tests! ${I.explanation||""}`:`Excellent! That's correct! ${I.explanation||""}`,te=F.current||{lipsyncLang:"en"};u.current.speakText(_,{lipsyncLang:te.lipsyncLang,onSpeechEnd:()=>{h.current.onCustomAction({type:"answerFeedbackComplete",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,isCorrect:!0,hasNextQuestion:Z,score:r.current.score,totalQuestions:r.current.totalQuestions})}})}else{if(u.current.setMood("sad"),e.incorrect)try{u.current.playAnimation(e.incorrect,!0)}catch{u.current.setBodyMovement("idle")}u.current.setBodyMovement("gesturing");const V=y()?.questions?.length||0,Z=r.current.currentQuestionIndex>=V-1,_=r.current.currentQuestionIndex<V-1;console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:",r.current.currentQuestionIndex,"totalQuestions:",V,"hasNextQuestion:",_);const te=I.type==="code_test"?`Your code didn't pass all the tests. ${I.explanation||"Try again!"}`:`Not quite right, but don't worry! ${I.explanation||""}${Z?"":" Let's move on to the next question."}`,de=F.current||{lipsyncLang:"en"};u.current.speakText(te,{lipsyncLang:de.lipsyncLang,onSpeechEnd:()=>{h.current.onCustomAction({type:"answerFeedbackComplete",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,isCorrect:!1,hasNextQuestion:_,score:r.current.score,totalQuestions:r.current.totalQuestions})}})}else{const V=y()?.questions?.length||0;h.current.onCustomAction({type:"answerFeedbackComplete",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,isCorrect:M,hasNextQuestion:r.current.currentQuestionIndex<V-1,score:r.current.score,totalQuestions:r.current.totalQuestions,avatarNotReady:!0})}},[e.correct,e.incorrect,O,y,S]),ve=b.useCallback(v=>{const I=O();if(!v||typeof v!="object"){console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");return}if(I?.type!=="code_test"){console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");return}const M={passed:v.passed===!0,results:v.results||[],output:v.output||"",error:v.error||null,executionTime:v.executionTime||null,testCount:v.testCount||0,passedCount:v.passedCount||0,failedCount:v.failedCount||0};h.current.onCustomAction({type:"codeTestSubmitted",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,testResult:M,question:I}),m.current&&m.current(M)},[O,S]),me=b.useCallback(()=>{if(r.current.currentQuestionIndex>0){r.current.currentQuestionIndex-=1;const v=O();v&&h.current.onCustomAction({type:"questionStart",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,totalQuestions:r.current.totalQuestions,question:v,score:r.current.score});const I=()=>{if(!u.current||!v)return;u.current.setMood("happy"),u.current.setBodyMovement("idle");const M=F.current||{lipsyncLang:"en"};v.type==="code_test"?u.current.speakText(`Let's go back to this coding challenge: ${v.question}`,{lipsyncLang:M.lipsyncLang}):u.current.speakText(`Going back to: ${v.question}`,{lipsyncLang:M.lipsyncLang})};if(u.current&&u.current.isReady&&v)I();else if(v){const M=setInterval(()=>{u.current&&u.current.isReady&&(clearInterval(M),I())},100);setTimeout(()=>{clearInterval(M)},5e3)}}},[O]),Te=b.useCallback(()=>{const v=N.current||{modules:[]};if(v.modules[r.current.currentModuleIndex],r.current.currentLessonIndex>0)r.current.currentLessonIndex-=1,r.current.currentQuestionIndex=0,r.current.lessonCompleted=!1,r.current.isQuestionMode=!1,r.current.isTeaching=!1,r.current.score=0,r.current.totalQuestions=0,h.current.onCustomAction({type:"lessonStart",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex}),h.current.onLessonStart({moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:y()}),u.current&&(u.current.setMood("happy"),u.current.setBodyMovement("idle"));else if(r.current.currentModuleIndex>0){const D=v.modules[r.current.currentModuleIndex-1];r.current.currentModuleIndex-=1,r.current.currentLessonIndex=(D?.lessons?.length||1)-1,r.current.currentQuestionIndex=0,r.current.lessonCompleted=!1,r.current.isQuestionMode=!1,r.current.isTeaching=!1,r.current.score=0,r.current.totalQuestions=0,h.current.onCustomAction({type:"lessonStart",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex}),h.current.onLessonStart({moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:y()}),u.current&&(u.current.setMood("happy"),u.current.setBodyMovement("idle"))}},[y]),fe=b.useCallback(()=>{r.current.currentModuleIndex=0,r.current.currentLessonIndex=0,r.current.currentQuestionIndex=0,r.current.isTeaching=!1,r.current.isQuestionMode=!1,r.current.lessonCompleted=!1,r.current.curriculumCompleted=!1,r.current.score=0,r.current.totalQuestions=0},[]),be=b.useCallback(v=>{console.log("Avatar is ready!",v);const I=y(),M=I?.avatar_script||I?.body;c&&M&&setTimeout(()=>{d.current&&d.current()},10)},[c,y]);b.useLayoutEffect(()=>{d.current=q,g.current=B,R.current=f,x.current=P,w.current=E,G.current=L,m.current=K}),b.useImperativeHandle(l,()=>({startTeaching:q,startQuestions:L,handleAnswerSelect:K,handleCodeTestResult:ve,nextQuestion:P,previousQuestion:me,nextLesson:B,previousLesson:Te,completeLesson:f,completeCurriculum:E,resetCurriculum:fe,getState:()=>({...r.current}),getCurrentQuestion:()=>O(),getCurrentLesson:()=>y(),getAvatarRef:()=>u.current,speakText:async(v,I={})=>{await u.current?.resumeAudioContext?.();const M=F.current||{lipsyncLang:"en"};u.current?.speakText(v,{...I,lipsyncLang:I.lipsyncLang||M.lipsyncLang})},resumeAudioContext:async()=>{if(u.current?.resumeAudioContext)return await u.current.resumeAudioContext();const v=u.current?.talkingHead;if(v?.audioCtx){const I=v.audioCtx;if(I.state==="suspended"||I.state==="interrupted")try{await I.resume(),console.log("Audio context resumed via talkingHead")}catch(M){console.warn("Failed to resume audio context:",M)}}else console.warn("Audio context not available yet")},stopSpeaking:()=>u.current?.stopSpeaking(),pauseSpeaking:()=>u.current?.pauseSpeaking(),resumeSpeaking:async()=>await u.current?.resumeSpeaking(),isPaused:()=>u.current&&typeof u.current.isPaused<"u"?u.current.isPaused:!1,setMood:v=>u.current?.setMood(v),playAnimation:(v,I)=>u.current?.playAnimation(v,I),setBodyMovement:v=>u.current?.setBodyMovement(v),setMovementIntensity:v=>u.current?.setMovementIntensity(v),playRandomDance:()=>u.current?.playRandomDance(),playReaction:v=>u.current?.playReaction(v),playCelebration:()=>u.current?.playCelebration(),setShowFullAvatar:v=>u.current?.setShowFullAvatar(v),setTimingAdjustment:v=>u.current?.setTimingAdjustment(v),lockAvatarPosition:()=>u.current?.lockAvatarPosition(),unlockAvatarPosition:()=>u.current?.unlockAvatarPosition(),triggerCustomAction:(v,I)=>{h.current.onCustomAction({type:v,...I,state:{...r.current}})},handleResize:()=>u.current?.handleResize(),isAvatarReady:()=>u.current?.isReady||!1}),[q,L,K,ve,P,B,f,E,fe,O,y]);const ce=F.current||{avatarUrl:"/avatars/brunette.glb",avatarBody:"F",mood:"happy",ttsLang:"en",ttsService:null,ttsVoice:null,ttsApiKey:null,bodyMovement:"gesturing",movementIntensity:.7,showFullAvatar:!1,animations:e};return Q.jsx("div",{style:{width:"100%",height:"100%"},children:Q.jsx($e,{ref:u,avatarUrl:ce.avatarUrl,avatarBody:ce.avatarBody,mood:ce.mood,ttsLang:ce.ttsLang,ttsService:ce.ttsService,ttsVoice:ce.ttsVoice,ttsApiKey:ce.ttsApiKey,bodyMovement:ce.bodyMovement,movementIntensity:ce.movementIntensity,showFullAvatar:ce.showFullAvatar,cameraView:"upper",animations:ce.animations,onReady:be,onLoading:()=>{},onError:v=>{console.error("Avatar error:",v)}})})});lt.displayName="CurriculumLearning";function Nt({manifestPath:W="/animations/manifest.json",avatarBody:n="F",onAnimationPlay:e=null,onAnimationsSelected:t=null,onDeleteAnimations:o=null,style:s={}}){const[i,a]=b.useState([]),[c,l]=b.useState(new Set),[u,r]=b.useState(!0),[h,d]=b.useState(null),[g,R]=b.useState("all"),[x,w]=b.useState("");b.useEffect(()=>{(async()=>{r(!0),d(null);try{const E=await Xe(W),L=[];if(E._genderSpecific){const B=(n?.toUpperCase()||"F")==="M"?"male":"female";E._genderSpecific[B]&&Object.entries(E._genderSpecific[B]).forEach(([q,K])=>{(Array.isArray(K)?K:[K]).forEach(me=>{L.push({path:me,group:q,gender:B,name:me.split("/").pop().replace(".fbx","")})})}),E._genderSpecific.shared&&Object.entries(E._genderSpecific.shared).forEach(([q,K])=>{(Array.isArray(K)?K:[K]).forEach(me=>{L.push({path:me,group:q,gender:"shared",name:me.split("/").pop().replace(".fbx","")})})})}Object.entries(E).forEach(([P,B])=>{P!=="_genderSpecific"&&(Array.isArray(B)?B:[B]).forEach(K=>{typeof K=="string"&&L.push({path:K,group:P,gender:"root",name:K.split("/").pop().replace(".fbx","")})})}),a(L),r(!1)}catch(E){console.error("Failed to load animations:",E),d(E.message),r(!1)}})()},[W,n]);const G=["all",...new Set(i.map(f=>f.group))],m=i.filter(f=>{const E=g==="all"||f.group===g,L=x===""||f.name.toLowerCase().includes(x.toLowerCase())||f.path.toLowerCase().includes(x.toLowerCase());return E&&L}),N=f=>{const E=new Set(c);E.has(f)?E.delete(f):E.add(f),l(E),t&&t(Array.from(E))},F=()=>{const f=new Set(c);m.forEach(E=>{f.add(E.path)}),l(f),t&&t(Array.from(f))},y=()=>{const f=new Set(c);m.forEach(E=>{f.delete(E.path)}),l(f),t&&t(Array.from(f))},O=()=>{const E=i.filter(L=>!c.has(L.path)).map(L=>L.path);if(E.length===0){alert("No animations to delete. Select animations to keep, then delete will remove the unselected ones.");return}window.confirm(`Are you sure you want to delete ${E.length} animation(s)?
|
|
7
|
+
`,s=await fetch(this.opt.ttsEndpoint,{method:"POST",headers:{"Ocp-Apim-Subscription-Key":this.opt.ttsApikey,"Content-Type":"application/ssml+xml","X-Microsoft-OutputFormat":"audio-16khz-128kbitrate-mono-mp3"},body:o});if(!s.ok)throw new Error(`Azure TTS error: ${s.status} ${s.statusText}`);const i=await s.arrayBuffer(),a=await this.audioCtx.decodeAudioData(i),c=await this.audioAnalyzer.analyzeAudio(a,e),l=[];for(let r=0;r<c.visemes.length;r++){const h=c.visemes[r],d=h.startTime*1e3,g=h.duration*1e3,R=h.intensity;l.push({template:{name:"viseme"},ts:[d-Math.min(60,2*g/3),d+Math.min(25,g/2),d+g+Math.min(60,g/2)],vs:{["viseme_"+h.viseme]:[null,R,0]}})}const u=[...n.anim,...l];this.audioPlaylist.push({anim:u,audio:a}),this.onSubtitles=n.onSubtitles||null,this.resetLips(),n.mood&&this.setMood(n.mood),this.playAudio()}async synthesizeWithExternalTTS(n){let e="<speak>";n.text.forEach((i,a)=>{a>0&&(e+=" <mark name='"+i.mark+"'/>"),e+=i.word.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'").replace(new RegExp("^\\p{Dash_Punctuation}$","ug"),'<break time="750ms"/>')}),e+="</speak>";const t={method:"POST",headers:{"Content-Type":"application/json; charset=utf-8"},body:JSON.stringify({input:{ssml:e},voice:{languageCode:n.lang||this.avatar.ttsLang||this.opt.ttsLang,name:n.voice||this.avatar.ttsVoice||this.opt.ttsVoice},audioConfig:{audioEncoding:this.ttsAudioEncoding,speakingRate:(n.rate||this.avatar.ttsRate||this.opt.ttsRate)+this.mood.speech.deltaRate,pitch:(n.pitch||this.avatar.ttsPitch||this.opt.ttsPitch)+this.mood.speech.deltaPitch,volumeGainDb:(n.volume||this.avatar.ttsVolume||this.opt.ttsVolume)+this.mood.speech.deltaVolume},enableTimePointing:[1]})};this.opt.jwtGet&&typeof this.opt.jwtGet=="function"&&(t.headers.Authorization="Bearer "+await this.opt.jwtGet());const o=await fetch(this.opt.ttsEndpoint+(this.opt.ttsApikey?"?key="+this.opt.ttsApikey:""),t),s=await o.json();if(o.status===200&&s&&s.audioContent){const i=this.b64ToArrayBuffer(s.audioContent),a=await this.audioCtx.decodeAudioData(i);this.speakWithHands();const c=[0];let l=0;n.text.forEach((h,d)=>{if(d>0){let g=c[c.length-1];s.timepoints[l]&&(g=s.timepoints[l].timeSeconds*1e3,s.timepoints[l].markName===""+h.mark&&l++),c.push(g)}});const u=[{mark:0,time:0}];c.forEach((h,d)=>{if(d>0){let g=h-c[d-1];u[d-1].duration=g,u.push({mark:d,time:h})}});let r=1e3*a.duration;r>this.opt.ttsTrimEnd&&(r=r-this.opt.ttsTrimEnd),u[u.length-1].duration=r-u[u.length-1].time,n.anim.forEach(h=>{const d=u[h.mark];if(d)for(let g=0;g<h.ts.length;g++)h.ts[g]=d.time+h.ts[g]*d.duration+this.opt.ttsTrimStart}),this.audioPlaylist.push({anim:n.anim,audio:a}),this.onSubtitles=n.onSubtitles||null,this.resetLips(),n.mood&&this.setMood(n.mood),this.playAudio()}else this.startSpeaking(!0)}async startSpeaking(n=!1){if(!(!this.armature||this.isSpeaking&&!n))if(this.stateName="speaking",this.isSpeaking=!0,this.speechQueue.length){let e=this.speechQueue.shift();if(e.emoji){this.lookAtCamera(500);let t=e.emoji.dt.reduce((o,s)=>o+s,0);this.animQueue.push(this.animFactory(e.emoji)),setTimeout(this.startSpeaking.bind(this),t,!0)}else if(e.break)setTimeout(this.startSpeaking.bind(this),e.break,!0);else if(e.audio)e.isRaw||(this.lookAtCamera(500),this.speakWithHands(),this.resetLips()),this.audioPlaylist.push({anim:e.anim,audio:e.audio,isRaw:e.isRaw}),this.onSubtitles=e.onSubtitles||null,e.mood&&this.setMood(e.mood),this.playAudio();else if(e.text){this.lookAtCamera(500);try{!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)}catch(t){console.error("Error:",t),this.startSpeaking(!0)}}else e.anim?(this.onSubtitles=e.onSubtitles||null,this.resetLips(),e.mood&&this.setMood(e.mood),e.anim.forEach((t,o)=>{for(let s=0;s<t.ts.length;s++)t.ts[s]=this.animClock+10*o;this.animQueue.push(t)}),setTimeout(this.startSpeaking.bind(this),10*e.anim.length,!0)):e.marker?(typeof e.marker=="function"&&e.marker(),this.startSpeaking(!0)):this.startSpeaking(!0)}else this.stateName="idle",this.isSpeaking=!1}pauseSpeaking(){let n=null;if(this.audioSpeechSource&&this.currentAudioItem&&this.audioStartTime!==null)try{const e=this.audioCtx.currentTime,t=Math.max(0,e-this.audioStartTime),o=this.audioSpeechSource.playbackRate.value,s=t*o,i=this.currentAudioItem.audio,a=i.sampleRate,c=Math.floor(s*a);if(c<i.length){const l=i.length-c,u=this.audioCtx.createBuffer(i.numberOfChannels,l,a);for(let h=0;h<i.numberOfChannels;h++){const d=i.getChannelData(h),g=u.getChannelData(h);for(let R=0;R<l;R++)g[R]=d[c+R]}let r=null;if(this.currentAudioItem.anim){const h=this.animClock+this.currentAudioItem.delay,d=t*1e3,g=h+d;r=this.currentAudioItem.anim.map(R=>{const x={template:R.template,ts:[],vs:[]};for(let w=0;w<R.ts.length;w++){const G=R.ts[w];if(G>g){const m=G-g;x.ts.push(m),x.vs.push(R.vs[w])}}return x.ts.length>0?x:null}).filter(R=>R!==null)}n={audio:u,anim:r,text:this.currentAudioItem.text,delay:0,elapsedTime:t}}this.audioSpeechSource.stop()}catch(e){console.warn("Error trimming audio buffer on pause:",e)}else try{this.audioSpeechSource?.stop()}catch{}return this.audioPlaylist.length=0,this.stateName="idle",this.isSpeaking=!1,this.isAudioPlaying=!1,this.audioStartTime=null,this.currentAudioItem=null,this.speechQueue.length=0,this.animQueue=this.animQueue.filter(e=>e.template.name!=="viseme"&&e.template.name!=="subtitles"&&e.template.name!=="blendshapes"),this.armature&&(this.resetLips(),this.render()),n}stopSpeaking(){if(this.audioSpeechSource){try{this.audioSpeechSource.stop()}catch{}this.audioSpeechSource=null}this.audioPlaylist.length=0,this.speechQueue.length=0,this.animQueue=this.animQueue.filter(n=>n.template.name!=="viseme"&&n.template.name!=="subtitles"&&n.template.name!=="blendshapes"),this.stateName="idle",this.isSpeaking=!1,this.isAudioPlaying=!1,this.currentAudioItem=null,this.audioStartTime=null,this.armature&&(this.resetLips(),this.render())}async streamStart(n={},e=null,t=null,o=null,s=null){if(this.stopSpeaking(),this.isStreaming=!0,n.waitForAudioChunks!==void 0&&(this.streamWaitForAudioChunks=n.waitForAudioChunks),this.streamWaitForAudioChunks||(this.streamAudioStartTime=this.animClock),this.streamLipsyncQueue=[],this.streamLipsyncType=n.lipsyncType||this.streamLipsyncType||"visemes",this.streamLipsyncLang=n.lipsyncLang||this.streamLipsyncLang||this.avatar.lipsyncLang||this.opt.lipsyncLang,this.onAudioStart=e,this.onAudioEnd=t,this.onMetrics=s,n.sampleRate!==void 0){const a=n.sampleRate;typeof a=="number"&&a>=8e3&&a<=96e3?a!==this.audioCtx.sampleRate&&this.initAudioGraph(a):console.warn("Invalid sampleRate provided. It must be a number between 8000 and 96000 Hz.")}if(n.gain!==void 0&&(this.audioStreamGainNode.gain.value=n.gain),!this.streamWorkletNode||!this.streamWorkletNode.port||this.streamWorkletNode.numberOfOutputs===0||this.streamWorkletNode.context!==this.audioCtx){if(this.streamWorkletNode)try{this.streamWorkletNode.disconnect(),this.streamWorkletNode=null}catch{}if(!this.workletLoaded)try{const a=this.audioCtx.audioWorklet.addModule(Bt.href),c=new Promise((l,u)=>setTimeout(()=>u(new Error("Worklet loading timed out")),5e3));await Promise.race([a,c]),this.workletLoaded=!0}catch(a){throw console.error("Failed to load audio worklet:",a),new Error("Failed to initialize streaming speech")}this.streamWorkletNode=new AudioWorkletNode(this.audioCtx,"playback-worklet",{processorOptions:{sampleRate:this.audioCtx.sampleRate,metrics:n.metrics||{enabled:!1}}}),this.streamWorkletNode.connect(this.audioStreamGainNode),this.streamWorkletNode.connect(this.audioAnalyzerNode),this.streamWorkletNode.port.onmessage=a=>{if(a.data.type==="playback-started"&&(this.isSpeaking=!0,this.stateName="speaking",this.streamWaitForAudioChunks&&(this.streamAudioStartTime=this.animClock),this._processStreamLipsyncQueue(),this.speakWithHands(),this.onAudioStart))try{this.onAudioStart?.()}catch(c){console.error(c)}if(a.data.type==="playback-ended"&&(this._streamPause(),this.onAudioEnd))try{this.onAudioEnd()}catch{}if(this.onMetrics&&a.data.type==="metrics")try{this.onMetrics(a.data)}catch{}}}if(n.metrics)try{this.streamWorkletNode.port.postMessage({type:"config-metrics",data:n.metrics})}catch{}if(this.resetLips(),this.lookAtCamera(500),n.mood&&this.setMood(n.mood),this.onSubtitles=o||null,this.audioCtx.state==="suspended"||this.audioCtx.state==="interrupted"){const a=this.audioCtx.resume(),c=new Promise((l,u)=>setTimeout(()=>u("p2"),1e3));try{await Promise.race([a,c])}catch{console.warn("Can't play audio. Web Audio API suspended. This is often due to calling some speak method before the first user action, which is typically prevented by the browser.");return}}}streamNotifyEnd(){!this.isStreaming||!this.streamWorkletNode||this.streamWorkletNode.port.postMessage({type:"no-more-data"})}streamInterrupt(){if(!this.isStreaming)return;const n=this.isSpeaking;if(this.streamWorkletNode)try{this.streamWorkletNode.port.postMessage({type:"stop"})}catch{}if(this._streamPause(!0),n&&this.onAudioEnd)try{this.onAudioEnd()}catch{}}streamStop(){if(this.isStreaming){if(this.streamInterrupt(),this.streamWorkletNode){try{this.streamWorkletNode.disconnect()}catch{}this.streamWorkletNode=null}this.isStreaming=!1}}_streamPause(n=!1){this.isSpeaking=!1,this.stateName="idle",n&&(this.streamWaitForAudioChunks&&(this.streamAudioStartTime=null),this.streamLipsyncQueue=[],this.animQueue=this.animQueue.filter(e=>e.template.name!=="viseme"&&e.template.name!=="subtitles"&&e.template.name!=="blendshapes"),this.armature&&(this.resetLips(),this.render()))}_processStreamLipsyncQueue(){if(this.isStreaming)for(;this.streamLipsyncQueue.length>0;){const n=this.streamLipsyncQueue.shift();this._processLipsyncData(n,this.streamAudioStartTime)}}_processLipsyncData(n,e){if(this.isStreaming){if(n.visemes&&this.streamLipsyncType=="visemes")for(let t=0;t<n.visemes.length;t++){const o=n.visemes[t],s=e+n.vtimes[t],i=n.vdurations[t],a={template:{name:"viseme"},ts:[s-2*i/3,s+i/2,s+i+i/2],vs:{["viseme_"+o]:[null,o==="PP"||o==="FF"?.9:.6,0]}};this.animQueue.push(a)}if(n.words&&(this.onSubtitles||this.streamLipsyncType=="words"))for(let t=0;t<n.words.length;t++){const o=n.words[t],s=n.wtimes[t];let i=n.wdurations[t];if(o.length&&(this.onSubtitles&&this.animQueue.push({template:{name:"subtitles"},ts:[e+s],vs:{subtitles:[" "+o]}}),this.streamLipsyncType=="words")){const a=this.streamLipsyncLang||this.avatar.lipsyncLang||this.opt.lipsyncLang,c=this.lipsyncPreProcessText(o,a),l=this.lipsyncWordsToVisemes(c,a);if(l&&l.visemes&&l.visemes.length){const u=l.times[l.visemes.length-1]+l.durations[l.visemes.length-1],r=Math.min(i,Math.max(0,i-l.visemes.length*150));let h=.6+this.convertRange(r,[0,i],[0,.4]);if(i=Math.min(i,l.visemes.length*200),u>0)for(let d=0;d<l.visemes.length;d++){const g=e+s+l.times[d]/u*i,R=l.durations[d]/u*i;this.animQueue.push({template:{name:"viseme"},ts:[g-Math.min(60,2*R/3),g+Math.min(25,R/2),g+R+Math.min(60,R/2)],vs:{["viseme_"+l.visemes[d]]:[null,l.visemes[d]==="PP"||l.visemes[d]==="FF"?.9:h,0]}})}}}}if(n.anims&&this.streamLipsyncType=="blendshapes")for(let t=0;t<n.anims.length;t++){let o=n.anims[t];o.delay+=e;let s=this.animFactory(o,!1,1,1,!0);this.animQueue.push(s)}}}streamAudio(n){if(!(!this.isStreaming||!this.streamWorkletNode)){if(this.isSpeaking||(this.streamLipsyncQueue=[],this.streamAudioStartTime=null),this.isSpeaking=!0,this.stateName="speaking",n.audio!==void 0){const e={type:"audioData",data:null};if(n.audio instanceof ArrayBuffer)e.data=n.audio,this.streamWorkletNode.port.postMessage(e,[e.data]);else if(n.audio instanceof Int16Array||n.audio instanceof Uint8Array){const t=n.audio.buffer.slice(n.audio.byteOffset,n.audio.byteOffset+n.audio.byteLength);e.data=t,this.streamWorkletNode.port.postMessage(e,[e.data])}else if(n.audio instanceof Float32Array){const t=new Int16Array(n.audio.length);for(let o=0;o<n.audio.length;o++){let s=Math.max(-1,Math.min(1,n.audio[o]));t[o]=s<0?s*32768:s*32767}e.data=t.buffer,this.streamWorkletNode.port.postMessage(e,[e.data])}else console.error("r.audio is not a supported type. Must be ArrayBuffer, Int16Array, Uint8Array, or Float32Array:",n.audio)}if(n.visemes||n.anims||n.words){if(this.streamWaitForAudioChunks&&!this.streamAudioStartTime){this.streamLipsyncQueue.length>=200&&this.streamLipsyncQueue.shift(),this.streamLipsyncQueue.push(n);return}else!this.streamWaitForAudioChunks&&!this.streamAudioStartTime&&(this.streamAudioStartTime=this.animClock);this._processLipsyncData(n,this.streamAudioStartTime)}}}makeEyeContact(n){this.animQueue.push(this.animFactory({name:"eyecontact",dt:[0,n],vs:{eyeContact:[1]}}))}lookAhead(n){if(n){let e=(Math.random()-.5)/4,t=(Math.random()-.5)/4,o=this.animQueue.findIndex(i=>i.template.name==="lookat");o!==-1&&this.animQueue.splice(o,1);const s={name:"lookat",dt:[750,n],vs:{bodyRotateX:[e],bodyRotateY:[t],eyesRotateX:[-3*e+.1],eyesRotateY:[-5*t],browInnerUp:[[0,.7]],mouthLeft:[[0,.7]],mouthRight:[[0,.7]],eyeContact:[0],headMove:[0]}};this.animQueue.push(this.animFactory(s))}}lookAtCamera(n){let e;if(this.speakTo&&(e=new A.Vector3,this.speakTo.objectLeftEye?.isObject3D?(this.speakTo.armature.objectHead,this.speakTo.objectLeftEye.updateMatrixWorld(!0),this.speakTo.objectRightEye.updateMatrixWorld(!0),Pe.setFromMatrixPosition(this.speakTo.objectLeftEye.matrixWorld),Ne.setFromMatrixPosition(this.speakTo.objectRightEye.matrixWorld),e.addVectors(Pe,Ne).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){if(this.avatar.hasOwnProperty("avatarIgnoreCamera")){if(this.avatar.avatarIgnoreCamera){this.lookAhead(n);return}}else if(this.opt.avatarIgnoreCamera){this.lookAhead(n);return}this.lookAt(null,null,n);return}this.objectLeftEye.updateMatrixWorld(!0),this.objectRightEye.updateMatrixWorld(!0),Pe.setFromMatrixPosition(this.objectLeftEye.matrixWorld),Ne.setFromMatrixPosition(this.objectRightEye.matrixWorld),Pe.add(Ne).divideScalar(2),ue.copy(this.armature.quaternion),ue.multiply(this.poseTarget.props["Hips.quaternion"]),ue.multiply(this.poseTarget.props["Spine.quaternion"]),ue.multiply(this.poseTarget.props["Spine1.quaternion"]),ue.multiply(this.poseTarget.props["Spine2.quaternion"]),ue.multiply(this.poseTarget.props["Neck.quaternion"]),ue.multiply(this.poseTarget.props["Head.quaternion"]);const t=new A.Vector3().subVectors(e,Pe).normalize(),o=Math.atan2(t.x,t.z),s=Math.asin(-t.y);oe.set(s,o,0,"YXZ");const a=new A.Quaternion().setFromEuler(oe),c=new A.Quaternion().copy(a).multiply(ue.clone().invert());oe.setFromQuaternion(c,"YXZ");let l=oe.x/(40/24)+.2,u=oe.y/(9/4),r=Math.min(.6,Math.max(-.3,l)),h=Math.min(.8,Math.max(-.8,u)),d=(Math.random()-.5)/4,g=(Math.random()-.5)/4;if(n){let R=this.animQueue.findIndex(w=>w.template.name==="lookat");R!==-1&&this.animQueue.splice(R,1);const x={name:"lookat",dt:[750,n],vs:{bodyRotateX:[r+d],bodyRotateY:[h+g],eyesRotateX:[-3*d+.1],eyesRotateY:[-5*g],browInnerUp:[[0,.7]],mouthLeft:[[0,.7]],mouthRight:[[0,.7]],eyeContact:[0],headMove:[0]}};this.animQueue.push(this.animFactory(x))}}lookAt(n,e,t){if(!this.camera)return;const o=this.nodeAvatar.getBoundingClientRect();this.objectLeftEye.updateMatrixWorld(!0),this.objectRightEye.updateMatrixWorld(!0);const s=new A.Vector3().setFromMatrixPosition(this.objectLeftEye.matrixWorld),i=new A.Vector3().setFromMatrixPosition(this.objectRightEye.matrixWorld),a=new A.Vector3().addVectors(s,i).divideScalar(2);a.project(this.camera);let c=(a.x+1)/2*o.width+o.left,l=-(a.y-1)/2*o.height+o.top;n===null&&(n=c),e===null&&(e=l),ue.copy(this.armature.quaternion),ue.multiply(this.poseTarget.props["Hips.quaternion"]),ue.multiply(this.poseTarget.props["Spine.quaternion"]),ue.multiply(this.poseTarget.props["Spine1.quaternion"]),ue.multiply(this.poseTarget.props["Spine2.quaternion"]),ue.multiply(this.poseTarget.props["Neck.quaternion"]),ue.multiply(this.poseTarget.props["Head.quaternion"]),oe.setFromQuaternion(ue);let u=oe.x/(40/24),r=oe.y/(9/4),h=Math.min(.4,Math.max(-.4,this.camera.rotation.x)),d=Math.min(.4,Math.max(-.4,this.camera.rotation.y)),g=Math.max(window.innerWidth-c,c),R=Math.max(window.innerHeight-l,l),x=this.convertRange(e,[l-R,l+R],[-.3,.6])-u+h,w=this.convertRange(n,[c-g,c+g],[-.8,.8])-r+d;x=Math.min(.6,Math.max(-.3,x)),w=Math.min(.8,Math.max(-.8,w));let G=(Math.random()-.5)/4,m=(Math.random()-.5)/4;if(t){let N=this.animQueue.findIndex(y=>y.template.name==="lookat");N!==-1&&this.animQueue.splice(N,1);const F={name:"lookat",dt:[750,t],vs:{bodyRotateX:[x+G],bodyRotateY:[w+m],eyesRotateX:[-3*G+.1],eyesRotateY:[-5*m],browInnerUp:[[0,.7]],mouthLeft:[[0,.7]],mouthRight:[[0,.7]],eyeContact:[0],headMove:[0]}};this.animQueue.push(this.animFactory(F))}}touchAt(n,e){if(!this.camera)return;const t=this.nodeAvatar.getBoundingClientRect(),o=new A.Vector2((n-t.left)/t.width*2-1,-((e-t.top)/t.height)*2+1),s=new A.Raycaster;s.setFromCamera(o,this.camera);const i=s.intersectObject(this.armature);if(i.length>0){const a=i[0].point,c=new A.Vector3,l=new A.Vector3;this.objectLeftArm.getWorldPosition(c),this.objectRightArm.getWorldPosition(l);const u=c.distanceToSquared(a),r=l.distanceToSquared(a);u<r?(this.ikSolve({iterations:20,root:"LeftShoulder",effector:"LeftHandMiddle1",links:[{link:"LeftHand",minx:-.5,maxx:.5,miny:-1,maxy:1,minz:-.5,maxz:.5,maxAngle:.1},{link:"LeftForeArm",minx:-.5,maxx:1.5,miny:-1.5,maxy:1.5,minz:-.5,maxz:3,maxAngle:.2},{link:"LeftArm",minx:-1.5,maxx:1.5,miny:0,maxy:0,minz:-1,maxz:3}]},a,!1,1e3),this.setValue("handFistLeft",0)):(this.ikSolve({iterations:20,root:"RightShoulder",effector:"RightHandMiddle1",links:[{link:"RightHand",minx:-.5,maxx:.5,miny:-1,maxy:1,minz:-.5,maxz:.5,maxAngle:.1},{link:"RightForeArm",minx:-.5,maxx:1.5,miny:-1.5,maxy:1.5,minz:-3,maxz:.5,maxAngle:.2},{link:"RightArm",minx:-1.5,maxx:1.5,miny:0,maxy:0,minz:-1,maxz:3}]},a,!1,1e3),this.setValue("handFistRight",0))}else["LeftArm","LeftForeArm","LeftHand","RightArm","RightForeArm","RightHand"].forEach(a=>{let c=a+".quaternion";this.poseTarget.props[c].copy(this.getPoseTemplateProp(c)),this.poseTarget.props[c].t=this.animClock,this.poseTarget.props[c].d=1e3});return i.length>0}speakWithHands(n=0,e=.5){if(this.mixer||this.gesture||!this.poseTarget.template.standing||this.poseTarget.template.bend||Math.random()>e)return;this.ikSolve({root:"LeftShoulder",effector:"LeftHandMiddle1",links:[{link:"LeftHand",minx:-.5,maxx:.5,miny:-1,maxy:1,minz:-.5,maxz:.5},{link:"LeftForeArm",minx:-.5,maxx:1.5,miny:-1.5,maxy:1.5,minz:-.5,maxz:3},{link:"LeftArm",minx:-1.5,maxx:1.5,miny:-1.5,maxy:1.5,minz:-1,maxz:3}]},new A.Vector3(this.gaussianRandom(0,.5),this.gaussianRandom(-.8,-.2),this.gaussianRandom(0,.5)),!0),this.ikSolve({root:"RightShoulder",effector:"RightHandMiddle1",links:[{link:"RightHand",minx:-.5,maxx:.5,miny:-1,maxy:1,minz:-.5,maxz:.5},{link:"RightForeArm",minx:-.5,maxx:1.5,miny:-1.5,maxy:1.5,minz:-3,maxz:.5},{link:"RightArm"}]},new A.Vector3(this.gaussianRandom(-.5,0),this.gaussianRandom(-.8,-.2),this.gaussianRandom(0,.5)),!0);const t=[],o=[];t.push(100+Math.round(Math.random()*500)),o.push({duration:1e3,props:{"LeftHand.quaternion":new A.Quaternion().setFromEuler(new A.Euler(0,-1-Math.random(),0)),"RightHand.quaternion":new A.Quaternion().setFromEuler(new A.Euler(0,1+Math.random(),0))}}),["LeftArm","LeftForeArm","RightArm","RightForeArm"].forEach(i=>{o[0].props[i+".quaternion"]=this.ikMesh.getObjectByName(i).quaternion.clone()}),t.push(1e3+Math.round(Math.random()*500)),o.push({duration:2e3,props:{}}),["LeftArm","LeftForeArm","RightArm","RightForeArm","LeftHand","RightHand"].forEach(i=>{o[1].props[i+".quaternion"]=null});const s=this.animFactory({name:"talkinghands",delay:n,dt:t,vs:{moveto:o}});this.animQueue.push(s)}getSlowdownRate(n){return this.animSlowdownRate}setSlowdownRate(n){this.animSlowdownRate=n,this.audioSpeechSource.playbackRate.value=1/this.animSlowdownRate,this.audioBackgroundSource.playbackRate.value=1/this.animSlowdownRate}getAutoRotateSpeed(n){return this.controls.autoRotateSpeed}setAutoRotateSpeed(n){this.controls.autoRotateSpeed=n,this.controls.autoRotate=n>0}start(){this.armature&&this.isRunning===!1&&(this.audioCtx.resume(),this.animTimeLast=performance.now(),this.isRunning=!0,this.isAvatarOnly||requestAnimationFrame(this.animate.bind(this)))}stop(){this.isRunning=!1,this.audioCtx.suspend()}startListening(n,e={},t=null){this.listeningAnalyzer=n,this.listeningAnalyzer.fftSize=256,this.listeningAnalyzer.smoothingTimeConstant=.1,this.listeningAnalyzer.minDecibels=-70,this.listeningAnalyzer.maxDecibels=-10,this.listeningOnchange=t&&typeof t=="function"?t:null,this.listeningSilenceThresholdLevel=e?.hasOwnProperty("listeningSilenceThresholdLevel")?e.listeningSilenceThresholdLevel:this.opt.listeningSilenceThresholdLevel,this.listeningSilenceThresholdMs=e?.hasOwnProperty("listeningSilenceThresholdMs")?e.listeningSilenceThresholdMs:this.opt.listeningSilenceThresholdMs,this.listeningSilenceDurationMax=e?.hasOwnProperty("listeningSilenceDurationMax")?e.listeningSilenceDurationMax:this.opt.listeningSilenceDurationMax,this.listeningActiveThresholdLevel=e?.hasOwnProperty("listeningActiveThresholdLevel")?e.listeningActiveThresholdLevel:this.opt.listeningActiveThresholdLevel,this.listeningActiveThresholdMs=e?.hasOwnProperty("listeningActiveThresholdMs")?e.listeningActiveThresholdMs:this.opt.listeningActiveThresholdMs,this.listeningActiveDurationMax=e?.hasOwnProperty("listeningActiveDurationMax")?e.listeningActiveDurationMax:this.opt.listeningActiveDurationMax,this.listeningActive=!1,this.listeningVolume=0,this.listeningTimer=0,this.listeningTimerTotal=0,this.isListening=!0}stopListening(){this.isListening=!1}async playAnimation(n,e=null,t=10,o=0,s=.01,i=!1,a=null){if(!this.armature)return;this.positionWasLocked=!i,i||this.lockAvatarPosition();let c=this.animClips.find(l=>l.url===n+"-"+o);if(c){let l=this.animQueue.find(h=>h.template.name==="pose");l&&(l.ts[0]=1/0),Object.entries(c.pose.props).forEach(h=>{this.poseBase.props[h[0]]=h[1].clone(),this.poseTarget.props[h[0]]=h[1].clone(),this.poseTarget.props[h[0]].t=0,this.poseTarget.props[h[0]].d=1e3}),this.mixer||(this.mixer=new A.AnimationMixer(this.armature)),this.animationFinishedCallback=a,console.log("🎬 Stored animation callback:",a?"callback exists":"callback is null");const u=()=>{console.log(`🎬 Mixer 'finished' event fired for animation: ${n}, callback exists: ${!!this.animationFinishedCallback}`);const h=this.animationFinishedCallback;if(h){console.log("🎬 Calling animation callback..."),this.animationFinishedCallback=null,this.currentFBXActionCallback=null,this.currentFBXActionForCallback=null,this.currentFBXActionStartTime=null,this.currentFBXActionClipDuration=null;try{h(),console.log("🎬 Animation callback executed successfully")}catch(d){console.error("🎬 Error in animation callback:",d)}}else console.log("🎬 No callback to call (already cleared or never set)")},r=this.mixer.clipAction(c.clip);if(t<=0)r.setLoop(A.LoopOnce,1),console.log(`🎬 Setting animation to LoopOnce, duration: ${c.clip.duration.toFixed(3)}s`);else{const h=Math.ceil(t/c.clip.duration);r.setLoop(A.LoopRepeat,h)}if(r.clampWhenFinished=!0,r.time=0,this.mixer.addEventListener("finished",u,{once:!0}),this.currentFBXActionForCallback=r,this.currentFBXActionCallback=u,this.currentFBXActionClipDuration=c.clip.duration,this.currentFBXActionStartTime=null,this.currentFBXAction&&this.currentFBXAction.isRunning()){this.currentFBXAction.fadeOut(.3),setTimeout(()=>{this.currentFBXAction=r,this.currentFBXActionForCallback=r,this.currentFBXActionCallback=u,this.currentFBXActionClipDuration=c.clip.duration,this.currentFBXActionStartTime=this.mixer.time;try{r.fadeIn(.5).play(),console.log("FBX animation started successfully (with fade transition):",n)}catch(h){console.warn("FBX animation failed to start:",h),this.stopAnimation()}},300);return}this.currentFBXAction=r,this.currentFBXActionStartTime=this.mixer.time;try{r.fadeIn(.5).play(),console.log("FBX animation started successfully:",n)}catch(h){console.warn("FBX animation failed to start:",h),this.stopAnimation();return}if(r.getClip().tracks.length===0){console.warn("FBX animation has no valid tracks, stopping"),this.stopAnimation();return}}else{if(n.split(".").pop().toLowerCase()!=="fbx"){console.error(`Invalid file type for FBX animation: ${n}. Expected .fbx file.`);return}let u=!1;try{const d=await fetch(n,{method:"HEAD"});if(u=d.ok,!u){console.error(`FBX file not found at ${n}. Status: ${d.status}`),console.error("Please check:"),console.error("1. File path is correct (note: path is case-sensitive)"),console.error("2. File exists in your public folder"),console.error("3. File is accessible (not blocked by server)");return}}catch(d){console.warn(`Could not verify file existence for ${n}, attempting to load anyway:`,d)}const r=new nt.FBXLoader;let h;try{h=await r.loadAsync(n,e)}catch(d){console.error(`Failed to load FBX animation from ${n}:`,d),console.error("Error details:",{message:d.message,url:n,suggestion:"Make sure the file is a valid FBX file and the path is correct"}),d.message&&d.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: ${n}`),console.error(" - File is a valid FBX binary file"),console.error(" - File path matches your public folder structure"),console.error(" - File is not corrupted"));try{const g=await fetch(n),R=g.headers.get("content-type"),x=await g.text();console.error("Response details:",{status:g.status,contentType:R,firstBytes:x.substring(0,100),isHTML:x.trim().startsWith("<!DOCTYPE")||x.trim().startsWith("<html")}),(x.trim().startsWith("<!DOCTYPE")||x.trim().startsWith("<html"))&&console.error("The server returned an HTML page instead of an FBX file. The file path is likely incorrect.")}catch(g){console.error("Could not fetch file for debugging:",g)}return}if(h&&h.animations&&h.animations[o]){let d=h.animations[o];const g=new Set;this.armature&&this.armature.traverse(y=>{(y.isBone||y.type==="Bone")&&g.add(y.name)});const R=new Map,x=y=>{if(g.has(y))return y;let O=y.replace(/^mixamorig/i,"").replace(/^CC_Base_/i,"").replace(/^RPM_/i,"");if(g.has(O))return O;const S=O.toLowerCase();if(S.includes("left")&&S.includes("arm")){if(S.includes("fore")||S.includes("lower")){if(g.has("LeftForeArm"))return"LeftForeArm";if(g.has("LeftForearm"))return"LeftForearm"}else if(!S.includes("fore")&&!S.includes("hand")&&g.has("LeftArm"))return"LeftArm"}if(S.includes("right")&&S.includes("arm")){if(S.includes("fore")||S.includes("lower")){if(g.has("RightForeArm"))return"RightForeArm";if(g.has("RightForearm"))return"RightForearm"}else if(!S.includes("fore")&&!S.includes("hand")&&g.has("RightArm"))return"RightArm"}if(S.includes("left")&&S.includes("hand")&&!S.includes("index")&&!S.includes("thumb")&&!S.includes("middle")&&!S.includes("ring")&&!S.includes("pinky")&&g.has("LeftHand"))return"LeftHand";if(S.includes("right")&&S.includes("hand")&&!S.includes("index")&&!S.includes("thumb")&&!S.includes("middle")&&!S.includes("ring")&&!S.includes("pinky")&&g.has("RightHand"))return"RightHand";if(S.includes("left")&&(S.includes("shoulder")||S.includes("clavicle"))&&g.has("LeftShoulder"))return"LeftShoulder";if(S.includes("right")&&(S.includes("shoulder")||S.includes("clavicle"))&&g.has("RightShoulder"))return"RightShoulder";const f={LeftArm:"LeftArm",leftArm:"LeftArm",LEFTARM:"LeftArm",RightArm:"RightArm",rightArm:"RightArm",RIGHTARM:"RightArm",LeftForeArm:"LeftForeArm",leftForeArm:"LeftForeArm",leftForearm:"LeftForeArm",LeftForearm:"LeftForeArm",RightForeArm:"RightForeArm",rightForeArm:"RightForeArm",rightForearm:"RightForeArm",RightForearm:"RightForeArm",LeftHand:"LeftHand",leftHand:"LeftHand",RightHand:"RightHand",rightHand:"RightHand",LeftShoulder:"LeftShoulder",leftShoulder:"LeftShoulder",RightShoulder:"RightShoulder",rightShoulder:"RightShoulder",Spine:"Spine1",spine:"Spine1",Spine1:"Spine1",Spine2:"Spine2",Head:"Head",head:"Head",Neck:"Neck",neck:"Neck",Hips:"Hips",hips:"Hips",Root:"Hips",root:"Hips"};if(f[O]){const E=f[O];if(g.has(E))return E}for(const E of g)if(E.toLowerCase()===S)return E;for(const E of g){const L=E.toLowerCase();if((S.includes("left")&&L.includes("left")||S.includes("right")&&L.includes("right"))&&(S.includes("arm")&&L.includes("arm")&&!L.includes("fore")||S.includes("forearm")&&L.includes("forearm")||S.includes("hand")&&L.includes("hand")&&!L.includes("index")&&!L.includes("thumb")||S.includes("shoulder")&&L.includes("shoulder")))return E}return null},w=new Set;d.tracks.forEach(y=>{const O=y.name.split(".");w.add(O[0])}),Array.from(w).filter(y=>y.toLowerCase().includes("arm")||y.toLowerCase().includes("hand")||y.toLowerCase().includes("shoulder")),Array.from(g).filter(y=>y.includes("Arm")||y.includes("Hand")||y.includes("Shoulder"));const G=[],m=new Set;d.tracks.forEach(y=>{const S=y.name.replaceAll("mixamorig","").split("."),f=S[0],E=S[1],L=x(f);if(!(L&&(L==="LeftShoulder"||L==="RightShoulder")&&(E==="quaternion"||E==="rotation")))if(L&&E){const P=`${L}.${E}`,B=y.clone();B.name=P,G.push(B),f!==L&&R.set(f,L)}else m.add(f),(f.toLowerCase().includes("arm")||f.toLowerCase().includes("hand")||f.toLowerCase().includes("shoulder"))&&console.warn(`⚠️ Arm bone "${f}" could not be mapped to avatar skeleton`)}),G.length>0?d=new A.AnimationClip(d.name,d.duration,G):console.error("No tracks could be mapped! Animation may not work correctly.");const N={};d.tracks.forEach(y=>{y.name=y.name.replaceAll("mixamorig","");const O=y.name.split(".");if(O[1]==="position"){for(let S=0;S<y.values.length;S++)y.values[S]=y.values[S]*s;N[y.name]=new A.Vector3(y.values[0],y.values[1],y.values[2])}else O[1]==="quaternion"?N[y.name]=new A.Quaternion(y.values[0],y.values[1],y.values[2],y.values[3]):O[1]==="rotation"&&(N[O[0]+".quaternion"]=new A.Quaternion().setFromEuler(new A.Euler(y.values[0],y.values[1],y.values[2],"XYZ")).normalize())});const F={props:N};N["Hips.position"]&&(N["Hips.position"].y<.5?F.lying=!0:F.standing=!0),this.animClips.push({url:n+"-"+o,clip:d,pose:F}),this.playAnimation(n,e,t,o,s)}else{const d="Animation "+n+" (ndx="+o+") not found";console.error(d),h&&h.animations?console.error(`FBX file loaded but has ${h.animations.length} animation(s), requested index ${o}`):console.error(h?"FBX file loaded but contains no animations":"FBX file failed to load or is invalid")}}}stopAnimation(){if(this.currentFBXAction&&(this.currentFBXAction.stop(),this.currentFBXAction=null),this.currentFBXActionForCallback=null,this.currentFBXActionCallback=null,this.currentFBXActionStartTime=null,this.currentFBXActionClipDuration=null,this.mixer&&this.mixer._actions.length===0&&(this.mixer=null),this.positionWasLocked&&this.unlockAvatarPosition(),this.gesture)for(let[e,t]of Object.entries(this.gesture))t.t=this.animClock,t.d=1e3,this.poseTarget.props.hasOwnProperty(e)&&(this.poseTarget.props[e].copy(t),this.poseTarget.props[e].t=this.animClock,this.poseTarget.props[e].d=1e3);let n=this.animQueue.find(e=>e.template.name==="pose");n&&(n.ts[0]=this.animClock),this.setPoseFromTemplate(null)}async playPose(n,e=null,t=5,o=0,s=.01){if(!this.armature)return;let i=this.poseTemplates[n];if(!i){const a=this.animPoses.find(c=>c.url===n+"-"+o);a&&(i=a.pose)}if(i){this.poseName=n,this.mixer=null;let a=this.animQueue.find(c=>c.template.name==="pose");a&&(a.ts[0]=this.animClock+t*1e3+2e3),this.setPoseFromTemplate(i)}else{let c=await new nt.FBXLoader().loadAsync(n,e);if(c&&c.animations&&c.animations[o]){let l=c.animations[o];const u={};l.tracks.forEach(h=>{h.name=h.name.replaceAll("mixamorig","");const d=h.name.split(".");d[1]==="position"?u[h.name]=new A.Vector3(h.values[0]*s,h.values[1]*s,h.values[2]*s):d[1]==="quaternion"?u[h.name]=new A.Quaternion(h.values[0],h.values[1],h.values[2],h.values[3]):d[1]==="rotation"&&(u[d[0]+".quaternion"]=new A.Quaternion().setFromEuler(new A.Euler(h.values[0],h.values[1],h.values[2],"XYZ")).normalize())});const r={props:u};u["Hips.position"]&&(u["Hips.position"].y<.5?r.lying=!0:r.standing=!0),this.animPoses.push({url:n+"-"+o,pose:r}),this.playPose(n,e,t,o,s)}else{const l="Pose "+n+" (ndx="+o+") not found";console.error(l)}}}stopPose(){this.stopAnimation()}playGesture(n,e=3,t=!1,o=1e3){if(!this.armature)return;let s=this.gestureTemplates[n];if(s){this.gestureTimeout&&(clearTimeout(this.gestureTimeout),this.gestureTimeout=null);let a=this.animQueue.findIndex(c=>c.template.name==="talkinghands");a!==-1&&(this.animQueue[a].ts=this.animQueue[a].ts.map(c=>0)),this.gesture=this.propsToThreeObjects(s),t&&(this.gesture=this.mirrorPose(this.gesture)),n==="namaste"&&this.avatar.body==="M"&&(this.gesture["RightArm.quaternion"].rotateTowards(new A.Quaternion(0,1,0,0),-.25),this.gesture["LeftArm.quaternion"].rotateTowards(new A.Quaternion(0,1,0,0),-.25));for(let[c,l]of Object.entries(this.gesture))l.t=this.animClock,l.d=o,this.poseTarget.props.hasOwnProperty(c)&&(this.poseTarget.props[c].copy(l),this.poseTarget.props[c].t=this.animClock,this.poseTarget.props[c].d=o);e&&Number.isFinite(e)&&(this.gestureTimeout=setTimeout(this.stopGesture.bind(this,o),1e3*e))}let i=this.animEmojis[n];if(i&&(i&&i.link&&(i=this.animEmojis[i.link]),i)){this.lookAtCamera(500);const a=this.animFactory(i);if(a.gesture=!0,e&&Number.isFinite(e)){const c=a.ts[0],u=a.ts[a.ts.length-1]-c;if(e*1e3-u>0){const h=[];for(let R=1;R<a.ts.length;R++)h.push(a.ts[R]-a.ts[R-1]);const d=i.template?.rescale||h.map(R=>R/u),g=e*1e3-u;a.ts=a.ts.map((R,x,w)=>x===0?c:w[x-1]+h[x-1]+d[x-1]*g)}else{const h=e*1e3/u;a.ts=a.ts.map(d=>c+h*(d-c))}}this.animQueue.push(a)}}stopGesture(n=1e3){if(this.gestureTimeout&&(clearTimeout(this.gestureTimeout),this.gestureTimeout=null),this.gesture){const t=Object.entries(this.gesture);this.gesture=null;for(const[o,s]of t)this.poseTarget.props.hasOwnProperty(o)&&(this.poseTarget.props[o].copy(this.getPoseTemplateProp(o)),this.poseTarget.props[o].t=this.animClock,this.poseTarget.props[o].d=n)}let e=this.animQueue.findIndex(t=>t.gesture);e!==-1&&this.animQueue.splice(e,1)}ikSolve(n,e=null,t=!1,o=null){const s=new A.Vector3,i=new A.Vector3,a=new A.Vector3,c=new A.Vector3,l=new A.Quaternion,u=new A.Vector3,r=new A.Vector3,h=new A.Vector3,d=this.ikMesh.getObjectByName(n.root);d.position.setFromMatrixPosition(this.armature.getObjectByName(n.root).matrixWorld),d.quaternion.setFromRotationMatrix(this.armature.getObjectByName(n.root).matrixWorld),e&&t&&e.applyQuaternion(this.armature.quaternion).add(d.position);const g=this.ikMesh.getObjectByName(n.effector),R=n.links;R.forEach(w=>{w.bone=this.ikMesh.getObjectByName(w.link),w.bone.quaternion.copy(this.getPoseTemplateProp(w.link+".quaternion"))}),d.updateMatrixWorld(!0);const x=n.iterations||10;if(e)for(let w=0;w<x;w++){let G=!1;for(let m=0,N=R.length;m<N;m++){const F=R[m].bone;F.matrixWorld.decompose(c,l,u),l.invert(),i.setFromMatrixPosition(g.matrixWorld),a.subVectors(i,c),a.applyQuaternion(l),a.normalize(),s.subVectors(e,c),s.applyQuaternion(l),s.normalize();let y=s.dot(a);y>1?y=1:y<-1&&(y=-1),y=Math.acos(y),!(y<1e-5)&&(R[m].minAngle!==void 0&&y<R[m].minAngle&&(y=R[m].minAngle),R[m].maxAngle!==void 0&&y>R[m].maxAngle&&(y=R[m].maxAngle),r.crossVectors(a,s),r.normalize(),ue.setFromAxisAngle(r,y),F.quaternion.multiply(ue),F.rotation.setFromVector3(h.setFromEuler(F.rotation).clamp(new A.Vector3(R[m].minx!==void 0?R[m].minx:-1/0,R[m].miny!==void 0?R[m].miny:-1/0,R[m].minz!==void 0?R[m].minz:-1/0),new A.Vector3(R[m].maxx!==void 0?R[m].maxx:1/0,R[m].maxy!==void 0?R[m].maxy:1/0,R[m].maxz!==void 0?R[m].maxz:1/0))),F.updateMatrixWorld(!0),G=!0)}if(!G)break}o&&R.forEach(w=>{this.poseTarget.props[w.link+".quaternion"].copy(w.bone.quaternion),this.poseTarget.props[w.link+".quaternion"].t=this.animClock,this.poseTarget.props[w.link+".quaternion"].d=o})}dispose(){this.isRunning=!1,this.stop(),this.stopSpeaking(),this.streamStop(),this.isAvatarOnly?this.armature&&(this.armature.parent&&this.armature.parent.remove(this.armature),this.clearThree(this.armature)):(this.clearThree(this.scene),this.resizeobserver.disconnect(),this.renderer&&(this.renderer.dispose(),this.renderer.domElement&&this.renderer.domElement.parentNode&&this.renderer.domElement.parentNode.removeChild(this.renderer.domElement),this.renderer=null)),this.clearThree(this.ikMesh),this.dynamicbones.dispose()}}const Ue={apiKey:"sk_ace57ef3ef65a92b9d3bee2a00183b78ca790bc3e10964f2",endpoint:"https://api.elevenlabs.io/v1/text-to-speech",defaultVoice:"21m00Tcm4TlvDq8ikWAM",voices:{rachel:"21m00Tcm4TlvDq8ikWAM",drew:"29vD33N1CtxCmqQRPOHJ",bella:"EXAVITQu4vr4xnSDxMaL",antoni:"ErXwobaYiN019PkySvjV",elli:"MF3mGyEYCl7XYWbV9V6O",josh:"VR6AewLTigWG4xSOukaG"}},Qe={defaultVoice:"aura-2-thalia-en",voices:{thalia:"aura-2-thalia-en",asteria:"aura-2-asteria-en",orion:"aura-2-orion-en",stella:"aura-2-stella-en",athena:"aura-2-athena-en",hera:"aura-2-hera-en",zeus:"aura-2-zeus-en"}};function Xe(){return{service:"elevenlabs",endpoint:Ue.endpoint,apiKey:Ue.apiKey,defaultVoice:Ue.defaultVoice,voices:Ue.voices}}function Dt(){const W=Xe(),n=[];return Object.entries(W.voices).forEach(([e,t])=>{n.push({value:t,label:`${e.charAt(0).toUpperCase()+e.slice(1)} (${W.service})`})}),n}const Je=b.forwardRef(({avatarUrl:W="/avatars/brunette.glb",avatarBody:n="F",mood:e="neutral",ttsLang:t="en",ttsService:o=null,ttsVoice:s=null,ttsApiKey:i=null,bodyMovement:a="idle",movementIntensity:c=.5,showFullAvatar:l=!0,cameraView:u="upper",onReady:r=()=>{},onLoading:h=()=>{},onError:d=()=>{},className:g="",style:R={},animations:x={}},w)=>{const G=b.useRef(null),m=b.useRef(null),N=b.useRef(l),F=b.useRef(null),y=b.useRef(null),O=b.useRef(!1),S=b.useRef({remainingText:null,originalText:null,options:null}),f=b.useRef([]),E=b.useRef(0),[L,P]=b.useState(!0),[B,Y]=b.useState(null),[$,ve]=b.useState(!1),[me,Fe]=b.useState(!1);b.useEffect(()=>{O.current=me},[me]),b.useEffect(()=>{N.current=l},[l]);const ye=Xe(),Re=o||ye.service;let ce;Re==="browser"?ce={service:"browser",endpoint:"",apiKey:null,defaultVoice:"Google US English"}:Re==="elevenlabs"?ce={service:"elevenlabs",endpoint:"https://api.elevenlabs.io/v1/text-to-speech",apiKey:i||ye.apiKey,defaultVoice:s||ye.defaultVoice||Ue.defaultVoice,voices:ye.voices||Ue.voices}:Re==="deepgram"?ce={service:"deepgram",endpoint:"https://api.deepgram.com/v1/speak",apiKey:i||ye.apiKey,defaultVoice:s||ye.defaultVoice||Qe.defaultVoice,voices:ye.voices||Qe.voices}:ce={...ye,apiKey:i!==null?i:ye.apiKey};const v={url:W,body:n,avatarMood:e,ttsLang:Re==="browser"?"en-US":t,ttsVoice:s||ce.defaultVoice,lipsyncLang:"en",showFullAvatar:l,bodyMovement:a,movementIntensity:c},I={ttsEndpoint:ce.endpoint,ttsApikey:ce.apiKey,ttsService:Re,lipsyncModules:["en"],cameraView:u},M=b.useCallback(async()=>{if(!(!G.current||m.current))try{if(P(!0),Y(null),m.current=new $e(G.current,I),m.current.controls&&(m.current.controls.enableRotate=!1,m.current.controls.enableZoom=!1,m.current.controls.enablePan=!1,m.current.controls.enableDamping=!1),x&&Object.keys(x).length>0&&(m.current.customAnimations=x),await m.current.showAvatar(v,K=>{if(K.lengthComputable){const re=Math.min(100,Math.round(K.loaded/K.total*100));h(re)}}),await new Promise(K=>{const re=()=>{m.current.lipsync&&Object.keys(m.current.lipsync).length>0?K():setTimeout(re,100)};re()}),m.current&&m.current.setShowFullAvatar)try{m.current.setShowFullAvatar(l)}catch(K){console.warn("Error setting full body mode on initialization:",K)}m.current&&m.current.controls&&(m.current.controls.enableRotate=!1,m.current.controls.enableZoom=!1,m.current.controls.enablePan=!1,m.current.controls.enableDamping=!1,m.current.controls.update()),P(!1),ve(!0),r(m.current);const _=()=>{document.visibilityState==="visible"?m.current?.start():m.current?.stop()};return document.addEventListener("visibilitychange",_),()=>{document.removeEventListener("visibilitychange",_)}}catch(z){console.error("Error initializing TalkingHead:",z),Y(z.message||"Failed to initialize avatar"),P(!1),d(z)}},[W,n,e,t,o,s,i,l,a,c,u]);b.useEffect(()=>(M(),()=>{m.current&&(m.current.stop(),m.current.dispose(),m.current=null)}),[M]),b.useEffect(()=>{if(!G.current||!m.current)return;const z=new ResizeObserver(K=>{for(const re of K)m.current&&m.current.onResize&&m.current.onResize()});z.observe(G.current);const _=()=>{m.current&&m.current.onResize&&m.current.onResize()};return window.addEventListener("resize",_),()=>{z.disconnect(),window.removeEventListener("resize",_)}},[$]);const D=b.useCallback(async()=>{if(m.current&&m.current.audioCtx)try{(m.current.audioCtx.state==="suspended"||m.current.audioCtx.state==="interrupted")&&(await m.current.audioCtx.resume(),console.log("Audio context resumed"))}catch(z){console.warn("Failed to resume audio context:",z)}},[]),V=b.useCallback(async(z,_={})=>{if(m.current&&$)try{y.current&&(clearInterval(y.current),y.current=null),F.current={text:z,options:_},S.current={remainingText:null,originalText:null,options:null};const K=/[!\.\?\n\p{Extended_Pictographic}]/ug,re=z.split(K).map(se=>se.trim()).filter(se=>se.length>0);f.current=re,E.current=0,Fe(!1),O.current=!1,await D();const pe={..._,lipsyncLang:_.lipsyncLang||v.lipsyncLang||"en"};if(_.onSpeechEnd&&m.current){const se=m.current;let Le=null,Be=0;const ke=1200;let Te=!1;Le=setInterval(()=>{if(Be++,O.current)return;if(Be>ke){if(Le&&(clearInterval(Le),Le=null,y.current=null),!Te&&!O.current){Te=!0;try{_.onSpeechEnd()}catch(Ae){console.error("Error in onSpeechEnd callback (timeout):",Ae)}}return}const we=!se.speechQueue||se.speechQueue.length===0,Oe=!se.audioPlaylist||se.audioPlaylist.length===0;se&&se.isSpeaking===!1&&we&&Oe&&se.isAudioPlaying===!1&&!Te&&!O.current&&setTimeout(()=>{if(se&&!O.current&&se.isSpeaking===!1&&(!se.speechQueue||se.speechQueue.length===0)&&(!se.audioPlaylist||se.audioPlaylist.length===0)&&se.isAudioPlaying===!1&&!Te&&!O.current){Te=!0,Le&&(clearInterval(Le),Le=null,y.current=null);try{_.onSpeechEnd()}catch(_e){console.error("Error in onSpeechEnd callback:",_e)}}},100)},100),y.current=Le}m.current.lipsync&&Object.keys(m.current.lipsync).length>0?(m.current.setSlowdownRate&&m.current.setSlowdownRate(1.05),m.current.speakText(z,pe)):setTimeout(async()=>{await D(),m.current&&m.current.lipsync&&(m.current.setSlowdownRate&&m.current.setSlowdownRate(1.05),m.current.speakText(z,pe))},100)}catch(K){console.error("Error speaking text:",K),Y(K.message||"Failed to speak text")}},[$,D,v.lipsyncLang]),Z=b.useCallback(()=>{m.current&&(m.current.stopSpeaking(),m.current.setSlowdownRate&&m.current.setSlowdownRate(1),F.current=null,Fe(!1))},[]),q=b.useCallback(()=>{if(m.current&&m.current.pauseSpeaking){const z=m.current;if(z.isSpeaking||z.audioPlaylist&&z.audioPlaylist.length>0||z.speechQueue&&z.speechQueue.length>0){y.current&&(clearInterval(y.current),y.current=null);let K="";if(F.current&&f.current.length>0){const re=f.current.length,pe=z.speechQueue?z.speechQueue.filter(ke=>ke&&ke.text&&Array.isArray(ke.text)&&ke.text.length>0).length:0,se=z.audioPlaylist&&z.audioPlaylist.length>0,Le=pe+(se?1:0),Be=re-Le;if(Le>0&&Be<re&&(K=f.current.slice(Be).join(". ").trim(),!K&&pe>0&&z.speechQueue)){const Te=z.speechQueue.filter(we=>we&&we.text&&Array.isArray(we.text)&&we.text.length>0).map(we=>we.text.map(Oe=>Oe.word||"").filter(Oe=>Oe.length>0).join(" ")).filter(we=>we.length>0).join(" ");Te&&Te.trim()&&(K=Te.trim())}}F.current&&(S.current={remainingText:K||null,originalText:F.current.text,options:F.current.options}),z.speechQueue&&(z.speechQueue.length=0),m.current.pauseSpeaking(),O.current=!0,Fe(!0)}}},[]),ne=b.useCallback(async()=>{if(!m.current||!me)return;let z="",_={};if(S.current&&S.current.remainingText)z=S.current.remainingText,_=S.current.options||{},S.current={remainingText:null,originalText:null,options:null};else if(F.current&&F.current.text)z=F.current.text,_=F.current.options||{};else{console.warn("Resume called but no paused speech found"),Fe(!1),O.current=!1;return}Fe(!1),O.current=!1,await D();const K={..._,lipsyncLang:_.lipsyncLang||v.lipsyncLang||"en"};try{await V(z,K)}catch(re){console.error("Error resuming speech:",re),Fe(!1),O.current=!1}},[D,me,V,v]),de=b.useCallback(z=>{m.current&&m.current.setMood(z)},[]),ge=b.useCallback(z=>{m.current&&m.current.setSlowdownRate&&m.current.setSlowdownRate(z)},[]),Ye=b.useCallback((z,_=!1)=>{if(m.current&&m.current.playAnimation){if(x&&x[z]&&(z=x[z]),m.current.setShowFullAvatar)try{m.current.setShowFullAvatar(N.current)}catch(re){console.warn("Error setting full body mode:",re)}if(z.includes("."))try{m.current.playAnimation(z,null,10,0,.01,_)}catch(re){console.warn(`Failed to play ${z}:`,re);try{m.current.setBodyMovement("idle")}catch(pe){console.warn("Fallback animation also failed:",pe)}}else{const re=[".fbx",".glb",".gltf"];let pe=!1;for(const se of re)try{m.current.playAnimation(z+se,null,10,0,.01,_),pe=!0;break}catch{}if(!pe){console.warn("Animation not found:",z);try{m.current.setBodyMovement("idle")}catch(se){console.warn("Fallback animation also failed:",se)}}}}},[x]),Ie=b.useCallback(()=>{m.current&&m.current.onResize&&m.current.onResize()},[]);return b.useImperativeHandle(w,()=>({speakText:V,stopSpeaking:Z,pauseSpeaking:q,resumeSpeaking:ne,resumeAudioContext:D,setMood:de,setTimingAdjustment:ge,playAnimation:Ye,isReady:$,isPaused:me,talkingHead:m.current,handleResize:Ie,setBodyMovement:z=>{if(m.current&&m.current.setShowFullAvatar&&m.current.setBodyMovement)try{m.current.setShowFullAvatar(N.current),m.current.setBodyMovement(z)}catch(_){console.warn("Error setting body movement:",_)}},setMovementIntensity:z=>m.current?.setMovementIntensity(z),playRandomDance:()=>{if(m.current&&m.current.setShowFullAvatar&&m.current.playRandomDance)try{m.current.setShowFullAvatar(N.current),m.current.playRandomDance()}catch(z){console.warn("Error playing random dance:",z)}},playReaction:z=>{if(m.current&&m.current.setShowFullAvatar&&m.current.playReaction)try{m.current.setShowFullAvatar(N.current),m.current.playReaction(z)}catch(_){console.warn("Error playing reaction:",_)}},playCelebration:()=>{if(m.current&&m.current.setShowFullAvatar&&m.current.playCelebration)try{m.current.setShowFullAvatar(N.current),m.current.playCelebration()}catch(z){console.warn("Error playing celebration:",z)}},setShowFullAvatar:z=>{if(m.current&&m.current.setShowFullAvatar)try{N.current=z,m.current.setShowFullAvatar(z)}catch(_){console.warn("Error setting showFullAvatar:",_)}},lockAvatarPosition:()=>{if(m.current&&m.current.lockAvatarPosition)try{m.current.lockAvatarPosition()}catch(z){console.warn("Error locking avatar position:",z)}},unlockAvatarPosition:()=>{if(m.current&&m.current.unlockAvatarPosition)try{m.current.unlockAvatarPosition()}catch(z){console.warn("Error unlocking avatar position:",z)}}})),j.jsxs("div",{className:`talking-head-avatar ${g}`,style:{width:"100%",height:"100%",position:"relative",...R},children:[j.jsx("div",{ref:G,className:"talking-head-viewer",style:{width:"100%",height:"100%",minHeight:"400px"}}),L&&j.jsx("div",{className:"loading-overlay",style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",color:"white",fontSize:"18px",zIndex:10},children:"Loading avatar..."}),B&&j.jsx("div",{className:"error-overlay",style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",color:"#ff6b6b",fontSize:"16px",textAlign:"center",zIndex:10,padding:"20px",borderRadius:"8px"},children:B})]})});Je.displayName="TalkingHeadAvatar";const at=b.forwardRef(({text:W="Hello! I'm a talking avatar. How are you today?",onLoading:n=()=>{},onError:e=()=>{},onReady:t=()=>{},className:o="",style:s={},avatarConfig:i={}},a)=>{const c=b.useRef(null),l=b.useRef(null),[u,r]=b.useState(!0),[h,d]=b.useState(null),[g,R]=b.useState(!1),x=Xe(),w=i.ttsService||x.service,G=w==="browser"?{endpoint:"",apiKey:null,defaultVoice:"Google US English"}:{...x,apiKey:i.ttsApiKey!==void 0&&i.ttsApiKey!==null?i.ttsApiKey:x.apiKey,endpoint:w==="elevenlabs"&&i.ttsApiKey?"https://api.elevenlabs.io/v1/text-to-speech":x.endpoint},m={url:"/avatars/brunette.glb",body:"F",avatarMood:"neutral",ttsLang:w==="browser"?"en-US":"en",ttsVoice:i.ttsVoice||G.defaultVoice,lipsyncLang:"en",showFullAvatar:!0,bodyMovement:"idle",movementIntensity:.5,...i},N={ttsEndpoint:G.endpoint,ttsApikey:G.apiKey,ttsService:w,lipsyncModules:["en"],cameraView:"upper"},F=b.useCallback(async()=>{if(!(!c.current||l.current))try{if(r(!0),d(null),l.current=new $e(c.current,N),await l.current.showAvatar(m,B=>{if(B.lengthComputable){const Y=Math.min(100,Math.round(B.loaded/B.total*100));n(Y)}}),l.current.morphs&&l.current.morphs.length>0){const B=l.current.morphs[0].morphTargetDictionary;console.log("Available morph targets:",Object.keys(B));const Y=Object.keys(B).filter($=>$.startsWith("viseme_"));console.log("Viseme morph targets found:",Y),Y.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"))}if(await new Promise(B=>{const Y=()=>{l.current.lipsync&&Object.keys(l.current.lipsync).length>0?(console.log("Lip-sync modules loaded:",Object.keys(l.current.lipsync)),B()):(console.log("Waiting for lip-sync modules to load..."),setTimeout(Y,100))};Y()}),l.current&&l.current.setShowFullAvatar)try{l.current.setShowFullAvatar(!0),console.log("Avatar initialized in full body mode")}catch(B){console.warn("Error setting full body mode on initialization:",B)}r(!1),R(!0),t(l.current);const P=()=>{document.visibilityState==="visible"?l.current?.start():l.current?.stop()};return document.addEventListener("visibilitychange",P),()=>{document.removeEventListener("visibilitychange",P)}}catch(L){console.error("Error initializing TalkingHead:",L),d(L.message||"Failed to initialize avatar"),r(!1),e(L)}},[]);b.useEffect(()=>(F(),()=>{l.current&&(l.current.stop(),l.current.dispose(),l.current=null)}),[F]);const y=b.useCallback(L=>{if(l.current&&g)try{console.log("Speaking text:",L),console.log("Avatar config:",m),console.log("TalkingHead instance:",l.current),l.current.lipsync&&Object.keys(l.current.lipsync).length>0?(console.log("Lip-sync modules loaded:",Object.keys(l.current.lipsync)),l.current.setSlowdownRate&&(l.current.setSlowdownRate(1.05),console.log("Applied timing adjustment for better lip-sync")),l.current.speakText(L)):(console.warn("Lip-sync modules not ready, waiting..."),setTimeout(()=>{l.current&&l.current.lipsync?(console.log("Lip-sync now ready, speaking..."),l.current.setSlowdownRate&&(l.current.setSlowdownRate(1.05),console.log("Applied timing adjustment for better lip-sync")),l.current.speakText(L)):console.error("Lip-sync still not ready after waiting")},500))}catch(P){console.error("Error speaking text:",P),d(P.message||"Failed to speak text")}else console.warn("Avatar not ready for speaking. isReady:",g,"talkingHeadRef:",!!l.current)},[g,m]),O=b.useCallback(()=>{l.current&&(l.current.stopSpeaking(),l.current.setSlowdownRate&&(l.current.setSlowdownRate(1),console.log("Reset timing to normal")))},[]),S=b.useCallback(L=>{l.current&&l.current.setMood(L)},[]),f=b.useCallback(L=>{l.current&&l.current.setSlowdownRate&&(l.current.setSlowdownRate(L),console.log("Timing adjustment set to:",L))},[]),E=b.useCallback((L,P=!1)=>{if(l.current&&l.current.playAnimation){if(l.current.setShowFullAvatar)try{l.current.setShowFullAvatar(!0)}catch(Y){console.warn("Error setting full body mode:",Y)}if(L.includes("."))try{l.current.playAnimation(L,null,10,0,.01,P),console.log("Playing animation:",L)}catch(Y){console.log(`Failed to play ${L}:`,Y);try{l.current.setBodyMovement("idle"),console.log("Fallback to idle animation")}catch($){console.warn("Fallback animation also failed:",$)}}else{const Y=[".fbx",".glb",".gltf"];let $=!1;for(const ve of Y)try{l.current.playAnimation(L+ve,null,10,0,.01,P),console.log("Playing animation:",L+ve),$=!0;break}catch{console.log(`Failed to play ${L}${ve}, trying next format...`)}if(!$){console.warn("Animation system not available or animation not found:",L);try{l.current.setBodyMovement("idle"),console.log("Fallback to idle animation")}catch(ve){console.warn("Fallback animation also failed:",ve)}}}}else console.warn("Animation system not available or animation not found:",L)},[]);return b.useImperativeHandle(a,()=>({speakText:y,stopSpeaking:O,setMood:S,setTimingAdjustment:f,playAnimation:E,isReady:g,talkingHead:l.current,setBodyMovement:L=>{if(l.current&&l.current.setShowFullAvatar&&l.current.setBodyMovement)try{l.current.setShowFullAvatar(!0),l.current.setBodyMovement(L),console.log("Body movement set with full body mode:",L)}catch(P){console.warn("Error setting body movement:",P)}},setMovementIntensity:L=>l.current?.setMovementIntensity(L),playRandomDance:()=>{if(l.current&&l.current.setShowFullAvatar&&l.current.playRandomDance)try{l.current.setShowFullAvatar(!0),l.current.playRandomDance(),console.log("Random dance played with full body mode")}catch(L){console.warn("Error playing random dance:",L)}},playReaction:L=>{if(l.current&&l.current.setShowFullAvatar&&l.current.playReaction)try{l.current.setShowFullAvatar(!0),l.current.playReaction(L),console.log("Reaction played with full body mode:",L)}catch(P){console.warn("Error playing reaction:",P)}},playCelebration:()=>{if(l.current&&l.current.setShowFullAvatar&&l.current.playCelebration)try{l.current.setShowFullAvatar(!0),l.current.playCelebration(),console.log("Celebration played with full body mode")}catch(L){console.warn("Error playing celebration:",L)}},setShowFullAvatar:L=>{if(l.current&&l.current.setShowFullAvatar)try{l.current.setShowFullAvatar(L),console.log("Show full avatar set to:",L)}catch(P){console.warn("Error setting showFullAvatar:",P)}},lockAvatarPosition:()=>{if(l.current&&l.current.lockAvatarPosition)try{l.current.lockAvatarPosition()}catch(L){console.warn("Error locking avatar position:",L)}},unlockAvatarPosition:()=>{if(l.current&&l.current.unlockAvatarPosition)try{l.current.unlockAvatarPosition()}catch(L){console.warn("Error unlocking avatar position:",L)}}})),j.jsxs("div",{className:`talking-head-container ${o}`,style:s,children:[j.jsx("div",{ref:c,className:"talking-head-viewer",style:{width:"100%",height:"100%",minHeight:"400px"}}),u&&j.jsx("div",{className:"loading-overlay",style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",color:"white",fontSize:"18px",zIndex:10},children:"Loading avatar..."}),h&&j.jsx("div",{className:"error-overlay",style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",color:"#ff6b6b",fontSize:"16px",textAlign:"center",zIndex:10,padding:"20px",borderRadius:"8px"},children:h})]})});at.displayName="TalkingHeadComponent";async function Ve(W){try{const n=await fetch(W);if(!n.ok){if(n.status===404)return{};throw new Error(`Failed to fetch manifest: ${n.status} ${n.statusText}`)}const e=n.headers.get("content-type");if(e&&!e.includes("application/json"))return{};const t=await n.text();return t.trim().startsWith("<!")?{}:JSON.parse(t).animations||{}}catch(n){return n instanceof SyntaxError||console.warn("⚠️ Could not load animation manifest (this is optional):",W),{}}}async function Nt(W,n="F"){const e=[],t=W.replace(/\/$/,"");try{const i=[`${t}/.list.json`,`/api/directory?path=${encodeURIComponent(t)}`,`${t}/index.json`];for(const a of i)try{const c=await fetch(a);if(c.ok){const l=await c.json(),r=(Array.isArray(l)?l:l.files||[]).filter(h=>typeof h=="string"&&h.toLowerCase().endsWith(".fbx")).map(h=>h.startsWith("/")?h:`${t}/${h}`);if(r.length>0)return r}}catch{continue}}catch(i){console.warn(`⚠️ Could not use directory listing API for ${t}:`,i)}let o="F";if(n){const i=n.toString().toUpperCase().trim();i==="M"||i==="MALE"?o="M":(i==="F"||i==="FEMALE")&&(o="F")}const s=[];o==="M"?s.push(`${t}/male`,`${t}/m`):s.push(`${t}/female`,`${t}/f`),s.push(`${t}/shared`);for(const i of s)try{const a=`${i}/.list.json`,c=await fetch(a);if(c.ok){const l=await c.json(),u=(Array.isArray(l)?l:l.files||[]).filter(r=>typeof r=="string"&&r.toLowerCase().endsWith(".fbx")).map(r=>r.startsWith("/")?r:`${i}/${r}`);u.length>0&&e.push(...u)}}catch{continue}return e.length>0,e}async function rt(W,n="F"){const e={};for(const[t,o]of Object.entries(W))try{const s=await Nt(o,n);s.length>0&&(e[t]=s)}catch(s){console.error(`❌ Failed to auto-load animations from ${o}:`,s)}return e}const lt=b.forwardRef(({text:W=null,avatarUrl:n="/avatars/brunette.glb",avatarBody:e="F",mood:t="neutral",ttsLang:o="en",ttsService:s=null,ttsVoice:i=null,ttsApiKey:a=null,bodyMovement:c="idle",movementIntensity:l=.5,showFullAvatar:u=!1,cameraView:r="upper",onReady:h=()=>{},onLoading:d=()=>{},onError:g=()=>{},onSpeechStart:R=()=>{},onSpeechEnd:x=()=>{},className:w="",style:G={},animations:m={},autoAnimationGroup:N=null,autoIdleGroup:F=null,autoSpeak:y=!1},O)=>{const S=b.useRef(null),f=b.useRef(null),E=b.useRef(u),L=b.useRef(null),P=b.useRef(null),B=b.useRef(!1),Y=b.useRef({remainingText:null,originalText:null,options:null}),$=b.useRef([]),[ve,me]=b.useState(!0),[Fe,ye]=b.useState(null),[Re,ce]=b.useState(!1),[v,I]=b.useState(!1),[M,D]=b.useState(m),V=b.useRef(null),Z=b.useRef(!1),q=b.useRef(null),ne=b.useRef(!1),de=b.useRef([]),ge=b.useRef([]),Ye=b.useRef(0),Ie=b.useRef(null),z=b.useRef(null);b.useEffect(()=>{B.current=v},[v]);const _=b.useCallback(k=>{let C="F";if(k){const T=k.toString().toUpperCase().trim();T==="M"||T==="MALE"?C="M":(T==="F"||T==="FEMALE")&&(C="F")}return C==="M"?"male":"female"},[]);b.useEffect(()=>{(async()=>{if(m.manifest&&m.auto)try{const C=await Ve(m.manifest);D(C);return}catch{}if(m.manifest&&!m.auto){const C=await Ve(m.manifest),T=Object.keys(C).length>0;D(T?C:m)}else if(m.auto)try{let C=null;if(m.manifest)try{C=await Ve(m.manifest)}catch{}if(typeof m.auto=="string"){const T=m.auto,J={talking:`${T}/talking`,idle:`${T}/idle`},X=_(e);J[`${X}_talking`]=`${T}/${X}/talking`,J[`${X}_idle`]=`${T}/${X}/idle`,J.shared_talking=`${T}/shared/talking`,J.shared_idle=`${T}/shared/idle`;const ie=await rt(J,e);if(!Object.values(ie).some(Q=>Array.isArray(Q)&&Q.length>0)&&C){D(C);return}const le={_genderSpecific:{[X]:{},shared:{}}};Object.entries(ie).forEach(([Q,ee])=>{if(Q.includes("_")){const[te,...fe]=Q.split("_"),he=fe.join("_");te==="shared"?(le._genderSpecific.shared[he]||(le._genderSpecific.shared[he]=[]),le._genderSpecific.shared[he].push(...ee)):te===X&&(le._genderSpecific[X][he]||(le._genderSpecific[X][he]=[]),le._genderSpecific[X][he].push(...ee))}else le[Q]=ee}),C&&(C._genderSpecific&&Object.keys(C._genderSpecific).forEach(Q=>{le._genderSpecific[Q]||(le._genderSpecific[Q]={}),Object.entries(C._genderSpecific[Q]).forEach(([ee,te])=>{le._genderSpecific[Q][ee]||(le._genderSpecific[Q][ee]=te)})}),Object.entries(C).forEach(([Q,ee])=>{Q!=="_genderSpecific"&&!le[Q]&&(le[Q]=ee)})),D(le)}else if(typeof m.auto=="object"){const T=await rt(m.auto,e),J=Object.values(T).some(X=>Array.isArray(X)&&X.length>0);D(!J&&C?C:T)}}catch(C){if(console.error("Failed to auto-discover animations:",C),m.manifest)try{const T=await Ve(m.manifest);D(T)}catch{D(m)}else D(m)}else D(m)})()},[m,e,_]),b.useEffect(()=>{E.current=u},[u]);const K=Xe(),re=s||K.service;let pe;re==="browser"?pe={service:"browser",endpoint:"",apiKey:null,defaultVoice:"Google US English"}:re==="elevenlabs"?pe={service:"elevenlabs",endpoint:"https://api.elevenlabs.io/v1/text-to-speech",apiKey:a||K.apiKey,defaultVoice:i||K.defaultVoice||Ue.defaultVoice,voices:K.voices||Ue.voices}:re==="deepgram"?pe={service:"deepgram",endpoint:"https://api.deepgram.com/v1/speak",apiKey:a||K.apiKey,defaultVoice:i||K.defaultVoice||Qe.defaultVoice,voices:K.voices||Qe.voices}:pe={...K,apiKey:a!==null?a:K.apiKey};const se={url:n,body:e,avatarMood:t,ttsLang:re==="browser"?"en-US":o,ttsVoice:i||pe.defaultVoice,lipsyncLang:"en",showFullAvatar:u,bodyMovement:c,movementIntensity:l},Le={ttsEndpoint:pe.endpoint,ttsApikey:pe.apiKey,ttsService:re,lipsyncModules:["en"],cameraView:r},Be=b.useCallback(async()=>{if(!(!S.current||f.current))try{me(!0),ye(null),f.current=new $e(S.current,Le),await f.current.showAvatar(se,C=>{if(C.lengthComputable){const T=Math.min(100,Math.round(C.loaded/C.total*100));d(T)}}),me(!1),ce(!0),h(f.current);const k=()=>{document.visibilityState==="visible"?f.current?.start():f.current?.stop()};return document.addEventListener("visibilitychange",k),()=>{document.removeEventListener("visibilitychange",k)}}catch(k){console.error("Error initializing TalkingHead:",k),ye(k.message||"Failed to initialize avatar"),me(!1),g(k)}},[]);b.useEffect(()=>(Be(),()=>{f.current&&(f.current.stop(),f.current.dispose(),f.current=null)}),[Be]);const ke=b.useCallback(async()=>{if(f.current)try{const k=f.current.audioCtx||f.current.audioContext;k&&(k.state==="suspended"||k.state==="interrupted")&&await k.resume()}catch(k){console.warn("Failed to resume audio context:",k)}},[]),Te=b.useCallback(k=>{if(!M)return[];let C=null;if(M._genderSpecific){const T=_(e),J=M._genderSpecific[T];if(J&&J[k]&&Array.isArray(J[k])&&J[k].length>0&&(C=J[k]),!C&&M._genderSpecific.shared&&M._genderSpecific.shared[k]){const X=M._genderSpecific.shared[k];Array.isArray(X)&&X.length>0&&(C=X)}}if(!C&&M[k]){const T=M[k];Array.isArray(T)&&T.length>0?C=T:typeof T=="string"&&(C=[T])}return!C||Array.isArray(C)&&C.length===0?((Object.keys(M).length>0||M._genderSpecific&&Object.keys(M._genderSpecific).length>0)&&console.warn(`⚠️ No animations found for group "${k}" (gender: ${_(e)}). Make sure animations are configured correctly.`),[]):Array.isArray(C)?[...C]:typeof C=="string"?[C]:[]},[M,e,_]),we=b.useCallback(k=>{const C=[...k];for(let T=C.length-1;T>0;T--){const J=Math.floor(Math.random()*(T+1));[C[T],C[J]]=[C[J],C[T]]}return C},[]),Oe=b.useCallback(k=>{if(ge.current.length===0){const T=Te(k);if(T.length===0)return null;ge.current=we(T),de.current=[]}const C=ge.current.shift();return C&&de.current.push(C),C},[Te,we]),qe=b.useCallback(k=>k?k.split("/").pop().replace(".fbx","").replace(/[-_]/g," "):"Unknown",[]),Ae=b.useCallback((k,C=!1,T=null)=>{if(!f.current||!Z.current||q.current!==k)return null;const J=Oe(k);if(J)try{const X=qe(J);console.log(`🎬 Playing animation: "${X}"`);const ie=()=>{console.log("🎬 Animation finished, checking if should continue...");const ae=()=>{if(!f.current)return console.log("🎬 No talkingHeadRef, stopping animations"),!1;if(!Z.current)return console.log("🎬 isSpeakingRef is false, stopping animations"),!1;if(q.current!==k)return console.log(`🎬 Animation group mismatch (${q.current} !== ${k}), stopping animations`),!1;const Q=f.current,ee=Q.isAudioPlaying===!0,te=Q.audioPlaylist&&Q.audioPlaylist.length>0,fe=Q.speechQueue&&Q.speechQueue.length>0,he=Q.isSpeaking===!0,De=he||ee||te||fe;return console.log("🎬 Still speaking check:",{isSpeakingRef:Z.current,isTalkingHeadSpeaking:he,hasAudioPlaying:ee,hasAudioInPlaylist:te,hasItemsInQueue:fe,shouldContinue:De}),De};ae()?(console.log("🎬 Still speaking, continuing to next animation..."),requestAnimationFrame(()=>{ae()?(console.log("🎬 Playing next animation..."),Ae(k,C,T)):(console.log("🎬 Speech ended, stopping animations"),Z.current=!1,q.current=null,f.current&&f.current.stopAnimation(),T&&T())})):(console.log("🎬 Speech has ended, stopping animations"),Z.current=!1,q.current=null,f.current&&f.current.stopAnimation(),T&&T())};return f.current.playAnimation(J,null,0,0,.01,C,ie),J}catch(X){return console.error("Failed to play animation:",X),null}else{const X=()=>{if(!f.current||!Z.current||q.current!==k)return!1;const ae=f.current,le=ae.isAudioPlaying===!0,Q=ae.audioPlaylist&&ae.audioPlaylist.length>0,ee=ae.speechQueue&&ae.speechQueue.length>0;return ae.isSpeaking===!0||le||Q||ee};X()&&(ge.current=[],de.current=[],X()?Ae(k,C,T):(Z.current=!1,q.current=null,f.current&&f.current.stopAnimation()))}return null},[Oe,qe]),_e=b.useCallback(()=>{F&&f.current&&!Z.current&&(V.current&&(clearInterval(V.current),V.current=null),ge.current=[],de.current=[],Ae(F,!1,null),V.current=setInterval(()=>{!Z.current&&!B.current&&F&&(ge.current=[],de.current=[],Ae(F,!1,null))},12e3+Math.random()*3e3))},[F,Ae]);z.current=_e;const We=b.useCallback(async(k,C={})=>{if(!f.current||!Re||!k||k.trim()==="")return;await ke(),V.current&&(clearInterval(V.current),V.current=null);const T=C.animationGroup||N;T&&!C.skipAnimation&&(Z.current=!0,q.current=T,ge.current=[],de.current=[],Ae(T));try{R(k),C.onSpeechStart&&C.onSpeechStart(k)}catch(ie){console.warn("Error in onSpeechStart callback:",ie)}Y.current={remainingText:null,originalText:null,options:null},$.current=[],L.current={text:k,options:C},P.current&&(clearInterval(P.current),P.current=null),I(!1),B.current=!1,ne.current=!1;const J=k.split(/[.!?]+/).filter(ie=>ie.trim().length>0);$.current=J,Ye.current=0;const X={lipsyncLang:C.lipsyncLang||"en"};if(f.current){const ie=f.current;let ae=0;const le=1200;P.current&&(clearInterval(P.current),P.current=null);const Q={current:!1},ee=setInterval(()=>{if(ae++,B.current)return;if(ae>le){if(ee&&(clearInterval(ee),P.current=null),!Q.current&&!B.current){Q.current=!0,Z.current=!1,q.current=null,ge.current=[],de.current=[],f.current&&(f.current.stopAnimation(),f.current.isSpeaking=!1);try{C.onSpeechEnd&&C.onSpeechEnd(),x()}catch(Ce){console.error("Error in onSpeechEnd callback (timeout):",Ce)}}return}const te=!ie.speechQueue||ie.speechQueue.length===0,fe=!ie.audioPlaylist||ie.audioPlaylist.length===0,he=ie.isAudioPlaying===!1;ie&&!B.current&&te&&fe&&he&&ie.isSpeaking===!1&&!Q.current&&!B.current&&setTimeout(()=>{const Ce=f.current;if(!Ce)return;!B.current&&(!Ce.speechQueue||Ce.speechQueue.length===0)&&(!Ce.audioPlaylist||Ce.audioPlaylist.length===0)&&Ce.isAudioPlaying===!1&&Ce.isSpeaking===!1&&!Q.current&&!B.current&&(Q.current=!0,ee&&(clearInterval(ee),P.current=null),Z.current=!1,q.current=null,ge.current=[],de.current=[],Ce&&(Ce.stopAnimation(),Ce.isSpeaking=!1),ne.current=!0,setTimeout(()=>{z.current&&z.current()},500),setTimeout(()=>{try{C.onSpeechEnd&&C.onSpeechEnd(),x(),setTimeout(()=>{ne.current=!1},500)}catch(tt){console.error("Error in onSpeechEnd callback:",tt),ne.current=!1}},100))},200)},50);P.current=ee}try{f.current.speakText(k,X)}catch(ie){console.error("Error speaking text:",ie),ye(ie.message||"Failed to speak text")}},[Re,x,ke,N,Ae]);b.useEffect(()=>{if(!Re||!F||!f.current)return;V.current&&(clearInterval(V.current),V.current=null);const k=()=>{f.current&&!B.current&&!Z.current&&(ge.current=[],de.current=[],Ae(F,!1,null))};return Z.current||k(),V.current=setInterval(()=>{Z.current||k()},12e3+Math.random()*3e3),()=>{V.current&&(clearInterval(V.current),V.current=null)}},[Re,F,Ae,Z]),b.useEffect(()=>{Re&&W&&y&&f.current&&!Z.current&&!B.current&&!ne.current&&We(W)},[Re,W,y,We]);const ct=b.useCallback(()=>{if(f.current)try{const k=f.current.isSpeaking||!1,C=[...f.current.audioPlaylist||[]],T=[...f.current.speechQueue||[]];if(k||C.length>0||T.length>0){P.current&&(clearInterval(P.current),P.current=null);const J=$.current;let X=[];const ie=f.current.isAudioPlaying||!1;if(J.length>0){const te=C.length+T.length,fe=ie?1:0,he=J.length-te-fe,De=ie?he:he+fe;De<J.length&&(X=J.slice(De))}else C.length>0&&C.forEach(te=>{if(te.text)if(Array.isArray(te.text)){const fe=te.text.map(he=>he.word).join(" ");fe.trim()&&X.push(fe)}else te.text.trim()&&X.push(te.text)}),T.length>0&&T.forEach(te=>{if(te.text)if(Array.isArray(te.text)){const fe=te.text.map(he=>he.word).join(" ");fe.trim()&&X.push(fe)}else te.text.trim()&&X.push(te.text)});const ae=X.join(" ");Y.current={remainingText:ae||null,originalText:L.current?.text||null,options:L.current?.options||null,isMidSentence:C.length>0};const Q=f.current.isAudioPlaying||!1?[...f.current.speechQueue||[]]:null;f.current.speechQueue.length=0;const ee=f.current.pauseSpeaking();f.current.isSpeaking=!1,Z.current=!1,q.current=null,ee&&ee.audio&&Q?(Ie.current=ee,Ie.current.savedSpeechQueue=Q):Ie.current=ee,I(!0),B.current=!0}}catch(k){console.warn("Error pausing speech:",k)}},[]),ht=b.useCallback(async()=>{if(!(!f.current||!v))try{if(await ke(),I(!1),B.current=!1,Ie.current&&Ie.current.audio){Z.current=!0;const X=Y.current?.options||L.current?.options||{},ie=X.animationGroup||N;if(ie&&(q.current=ie),Ie.current.savedSpeechQueue&&(f.current.speechQueue.length=0,f.current.speechQueue.push(...Ie.current.savedSpeechQueue)),f.current.isSpeaking=!0,f.current){const ae=f.current;let le=0;const Q=1200,ee={current:!1};P.current&&(clearInterval(P.current),P.current=null);const te=setInterval(()=>{if(le++,B.current)return;if(le>Q){if(te&&(clearInterval(te),P.current=null),!ee.current&&!B.current){ee.current=!0,Z.current=!1,q.current=null,ge.current=[],de.current=[],f.current&&(f.current.stopAnimation(),f.current.isSpeaking=!1);try{X.onSpeechEnd&&X.onSpeechEnd(),x()}catch(ze){console.error("Error in onSpeechEnd callback (timeout):",ze)}}return}const fe=!ae.speechQueue||ae.speechQueue.length===0,he=!ae.audioPlaylist||ae.audioPlaylist.length===0,De=ae.isAudioPlaying===!1;ae&&!B.current&&fe&&he&&De&&ae.isSpeaking===!1&&!ee.current&&!B.current&&setTimeout(()=>{const ze=f.current;if(!ze)return;!B.current&&(!ze.speechQueue||ze.speechQueue.length===0)&&(!ze.audioPlaylist||ze.audioPlaylist.length===0)&&ze.isAudioPlaying===!1&&ze.isSpeaking===!1&&!ee.current&&!B.current&&(ee.current=!0,te&&(clearInterval(te),P.current=null),Z.current=!1,q.current=null,ge.current=[],de.current=[],ze&&(ze.stopAnimation(),ze.isSpeaking=!1),ne.current=!0,setTimeout(()=>{z.current&&z.current()},500),setTimeout(()=>{try{X.onSpeechEnd&&X.onSpeechEnd(),x(),setTimeout(()=>{ne.current=!1},500)}catch(mt){console.error("Error in onSpeechEnd callback:",mt),ne.current=!1}},100))},200)},50);P.current=te}await f.current.playAudio(!1,Ie.current),ie&&!X.skipAnimation&&(ge.current=[],de.current=[],Ae(ie)),Ie.current=null;return}const k=Y.current?.remainingText,C=Y.current?.originalText||L.current?.text,T=Y.current?.options||L.current?.options||{},J=k||C;J&&We(J,T),Ie.current=null}catch(k){console.warn("Error resuming speech:",k),I(!1),B.current=!1,Ie.current=null}},[v,We,ke,N,Ae]),dt=b.useCallback(()=>{if(f.current){f.current.stopAnimation(),f.current.stopSpeaking(),P.current&&(clearInterval(P.current),P.current=null),Z.current=!1,q.current=null,ge.current=[],de.current=[],I(!1),B.current=!1,Ie.current=null,ne.current=!1,setTimeout(()=>{z.current&&z.current()},500);try{x()}catch(k){console.warn("Error in onSpeechEnd callback (stopSpeaking):",k)}}},[x]);return b.useImperativeHandle(O,()=>({speakText:We,pauseSpeaking:ct,resumeSpeaking:ht,stopSpeaking:dt,resumeAudioContext:ke,isPaused:()=>v,setMood:k=>f.current?.setMood(k),setBodyMovement:k=>{f.current&&f.current.setBodyMovement(k)},playAnimation:(k,C=!1)=>{f.current&&f.current.playAnimation&&f.current.playAnimation(k,null,10,0,.01,C)},playRandomAnimation:(k,C=!1)=>Ae(k,C),getRandomAnimation:k=>getRandomAnimation(k),playReaction:k=>f.current?.playReaction(k),playCelebration:()=>f.current?.playCelebration(),setShowFullAvatar:k=>{f.current&&(E.current=k,f.current.setShowFullAvatar(k))},isReady:Re,talkingHead:f.current})),j.jsxs("div",{className:`simple-talking-avatar-container ${w}`,style:G,children:[j.jsx("div",{ref:S,className:"talking-head-viewer",style:{width:"100%",height:"100%",minHeight:"400px"}}),ve&&j.jsx("div",{className:"loading-overlay",style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",color:"white",fontSize:"18px",zIndex:10},children:"Loading avatar..."}),Fe&&j.jsx("div",{className:"error-overlay",style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",color:"#ff6b6b",fontSize:"16px",textAlign:"center",zIndex:10,padding:"20px",borderRadius:"8px"},children:Fe})]})});lt.displayName="SimpleTalkingAvatar";const ut=b.forwardRef(({curriculumData:W=null,avatarConfig:n={},animations:e={},onLessonStart:t=()=>{},onLessonComplete:o=()=>{},onQuestionAnswer:s=()=>{},onCurriculumComplete:i=()=>{},onCustomAction:a=()=>{},autoStart:c=!1},l)=>{const u=b.useRef(null),r=b.useRef({currentModuleIndex:0,currentLessonIndex:0,currentQuestionIndex:0,isTeaching:!1,isQuestionMode:!1,lessonCompleted:!1,curriculumCompleted:!1,score:0,totalQuestions:0}),h=b.useRef({onLessonStart:t,onLessonComplete:o,onQuestionAnswer:s,onCurriculumComplete:i,onCustomAction:a}),d=b.useRef(null),g=b.useRef(null),R=b.useRef(null),x=b.useRef(null),w=b.useRef(null),G=b.useRef(null),m=b.useRef(null),N=b.useRef(W?.curriculum||{title:"Default Curriculum",description:"No curriculum data provided",language:"en",modules:[]}),F=b.useRef({avatarUrl:n.avatarUrl||"/avatars/brunette.glb",avatarBody:n.avatarBody||"F",mood:n.mood||"happy",ttsLang:n.ttsLang||"en",ttsService:n.ttsService||null,ttsVoice:n.ttsVoice||null,ttsApiKey:n.ttsApiKey||null,bodyMovement:n.bodyMovement||"gesturing",movementIntensity:n.movementIntensity||.7,showFullAvatar:n.showFullAvatar!==void 0?n.showFullAvatar:!1,animations:e,lipsyncLang:"en"});b.useEffect(()=>{h.current={onLessonStart:t,onLessonComplete:o,onQuestionAnswer:s,onCurriculumComplete:i,onCustomAction:a}},[t,o,s,i,a]),b.useEffect(()=>{N.current=W?.curriculum||{title:"Default Curriculum",description:"No curriculum data provided",language:"en",modules:[]},F.current={avatarUrl:n.avatarUrl||"/avatars/brunette.glb",avatarBody:n.avatarBody||"F",mood:n.mood||"happy",ttsLang:n.ttsLang||"en",ttsService:n.ttsService||null,ttsVoice:n.ttsVoice||null,ttsApiKey:n.ttsApiKey||null,bodyMovement:n.bodyMovement||"gesturing",movementIntensity:n.movementIntensity||.7,showFullAvatar:n.showFullAvatar!==void 0?n.showFullAvatar:!1,animations:e,lipsyncLang:"en"}},[W,n,e]);const y=b.useCallback(()=>(N.current||{modules:[]}).modules[r.current.currentModuleIndex]?.lessons[r.current.currentLessonIndex],[]),O=b.useCallback(()=>y()?.questions[r.current.currentQuestionIndex],[y]),S=b.useCallback((v,I)=>I.type==="multiple_choice"||I.type==="true_false"?v===I.answer:I.type==="code_test"&&typeof v=="object"&&v!==null?v.passed===!0:!1,[]),f=b.useCallback(()=>{r.current.lessonCompleted=!0,r.current.isQuestionMode=!1;const v=r.current.totalQuestions>0?Math.round(r.current.score/r.current.totalQuestions*100):100;let I="Congratulations! You've completed this lesson";if(r.current.totalQuestions>0?I+=` You got ${r.current.score} correct out of ${r.current.totalQuestions} question${r.current.totalQuestions===1?"":"s"}, achieving a score of ${v} percent. `:I+="! ",v>=80?I+="Excellent work! You have a great understanding of this topic.":v>=60?I+="Good job! You understand most of the concepts.":I+="Keep practicing! You're making progress.",h.current.onLessonComplete({moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,score:r.current.score,totalQuestions:r.current.totalQuestions,percentage:v}),h.current.onCustomAction({type:"lessonComplete",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,score:r.current.score,totalQuestions:r.current.totalQuestions,percentage:v}),u.current){if(u.current.setMood("happy"),e.lessonComplete)try{u.current.playAnimation(e.lessonComplete,!0)}catch{u.current.playCelebration()}const M=N.current||{modules:[]},D=M.modules[r.current.currentModuleIndex],V=r.current.currentLessonIndex<(D?.lessons?.length||0)-1,Z=r.current.currentModuleIndex<(M.modules?.length||0)-1,q=V||Z,ne=F.current||{lipsyncLang:"en"};u.current.speakText(I,{lipsyncLang:ne.lipsyncLang,onSpeechEnd:()=>{h.current.onCustomAction({type:"lessonCompleteFeedbackDone",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,score:r.current.score,totalQuestions:r.current.totalQuestions,percentage:v,hasNextLesson:q})}})}},[e.lessonComplete]),E=b.useCallback(()=>{r.current.curriculumCompleted=!0;const v=N.current||{modules:[]};if(h.current.onCurriculumComplete({modules:v.modules.length,totalLessons:v.modules.reduce((I,M)=>I+M.lessons.length,0)}),u.current){if(u.current.setMood("celebrating"),e.curriculumComplete)try{u.current.playAnimation(e.curriculumComplete,!0)}catch{u.current.playCelebration()}const I=F.current||{lipsyncLang:"en"};u.current.speakText("Amazing! You've completed the entire curriculum! You're now ready to move on to more advanced topics. Well done!",{lipsyncLang:I.lipsyncLang})}},[e.curriculumComplete]),L=b.useCallback(()=>{const v=y();r.current.isQuestionMode=!0,r.current.currentQuestionIndex=0,r.current.totalQuestions=v?.questions?.length||0,r.current.score=0;const I=O();I&&h.current.onCustomAction({type:"questionStart",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,totalQuestions:r.current.totalQuestions,question:I,score:r.current.score});const M=()=>{if(!u.current||!I)return;if(u.current.setMood("happy"),e.questionStart)try{u.current.playAnimation(e.questionStart,!0)}catch(V){console.warn("Failed to play questionStart animation:",V)}const D=F.current||{lipsyncLang:"en"};I.type==="code_test"?u.current.speakText(`Let's test your coding skills! Here's your first challenge: ${I.question}`,{lipsyncLang:D.lipsyncLang}):I.type==="multiple_choice"?u.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`,{lipsyncLang:D.lipsyncLang}):I.type==="true_false"?u.current.speakText(`Let's start with some true or false questions. First question: ${I.question}`,{lipsyncLang:D.lipsyncLang}):u.current.speakText(`Now let me ask you some questions. Here's the first one: ${I.question}`,{lipsyncLang:D.lipsyncLang})};if(u.current&&u.current.isReady&&I)M();else if(u.current&&u.current.isReady){const D=F.current||{lipsyncLang:"en"};u.current.speakText("Now let me ask you some questions to test your understanding.",{lipsyncLang:D.lipsyncLang})}else{const D=setInterval(()=>{u.current&&u.current.isReady&&(clearInterval(D),I&&M())},100);setTimeout(()=>{clearInterval(D)},5e3)}},[e.questionStart,y,O]),P=b.useCallback(()=>{const v=y();if(r.current.currentQuestionIndex<(v?.questions?.length||0)-1){u.current&&u.current.stopSpeaking&&u.current.stopSpeaking(),r.current.currentQuestionIndex+=1;const I=O();I&&h.current.onCustomAction({type:"nextQuestion",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,totalQuestions:r.current.totalQuestions,question:I,score:r.current.score});const M=()=>{if(!u.current||!I)return;if(u.current.setMood("happy"),u.current.setBodyMovement("idle"),e.nextQuestion)try{u.current.playAnimation(e.nextQuestion,!0)}catch(ne){console.warn("Failed to play nextQuestion animation:",ne)}const D=F.current||{lipsyncLang:"en"},Z=y()?.questions?.length||0,q=r.current.currentQuestionIndex>=Z-1;if(I.type==="code_test"){const ne=q?`Great! Here's your final coding challenge: ${I.question}`:`Great! Now let's move on to your next coding challenge: ${I.question}`;u.current.speakText(ne,{lipsyncLang:D.lipsyncLang})}else if(I.type==="multiple_choice"){const ne=q?`Alright! Here's your final question: ${I.question}`:`Alright! Here's your next question: ${I.question}`;u.current.speakText(ne,{lipsyncLang:D.lipsyncLang})}else if(I.type==="true_false"){const ne=q?`Now let's try this final one: ${I.question}`:`Now let's try this one: ${I.question}`;u.current.speakText(ne,{lipsyncLang:D.lipsyncLang})}else{const ne=q?`Here's your final question: ${I.question}`:`Here's the next question: ${I.question}`;u.current.speakText(ne,{lipsyncLang:D.lipsyncLang})}};if(u.current&&u.current.isReady&&I)M();else if(I){const D=setInterval(()=>{u.current&&u.current.isReady&&(clearInterval(D),M())},100);setTimeout(()=>{clearInterval(D)},5e3)}}else h.current.onCustomAction({type:"allQuestionsComplete",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,totalQuestions:r.current.totalQuestions,score:r.current.score})},[e.nextQuestion,y,O]),B=b.useCallback(()=>{const v=N.current||{modules:[]},I=v.modules[r.current.currentModuleIndex];if(r.current.currentLessonIndex<(I?.lessons?.length||0)-1){r.current.currentLessonIndex+=1,r.current.currentQuestionIndex=0,r.current.lessonCompleted=!1,r.current.isQuestionMode=!1,r.current.isTeaching=!1,r.current.score=0,r.current.totalQuestions=0;const D=v.modules[r.current.currentModuleIndex],V=r.current.currentLessonIndex<(D?.lessons?.length||0)-1,Z=r.current.currentModuleIndex<(v.modules?.length||0)-1,q=V||Z;h.current.onCustomAction({type:"lessonStart",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,hasNextLesson:q}),h.current.onLessonStart({moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:y()}),u.current&&(u.current.setMood("happy"),u.current.setBodyMovement("idle"))}else if(r.current.currentModuleIndex<(v.modules?.length||0)-1){r.current.currentModuleIndex+=1,r.current.currentLessonIndex=0,r.current.currentQuestionIndex=0,r.current.lessonCompleted=!1,r.current.isQuestionMode=!1,r.current.isTeaching=!1,r.current.score=0,r.current.totalQuestions=0;const V=v.modules[r.current.currentModuleIndex],Z=r.current.currentLessonIndex<(V?.lessons?.length||0)-1,q=r.current.currentModuleIndex<(v.modules?.length||0)-1,ne=Z||q;h.current.onCustomAction({type:"lessonStart",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,hasNextLesson:ne}),h.current.onLessonStart({moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:y()}),u.current&&(u.current.setMood("happy"),u.current.setBodyMovement("idle"))}else w.current&&w.current()},[]),Y=b.useCallback(()=>{const v=y();let I=null;if(v?.avatar_script&&v?.body){const M=v.avatar_script.trim(),D=v.body.trim(),V=M.match(/[.!?]$/)?" ":". ";I=`${M}${V}${D}`}else I=v?.avatar_script||v?.body||null;if(u.current&&u.current.isReady&&I){r.current.isTeaching=!0,r.current.isQuestionMode=!1,r.current.score=0,r.current.totalQuestions=0,u.current.setMood("happy");let M=!1;if(e.teaching)try{u.current.playAnimation(e.teaching,!0),M=!0}catch(V){console.warn("Failed to play teaching animation:",V)}M||u.current.setBodyMovement("gesturing");const D=F.current||{lipsyncLang:"en"};h.current.onLessonStart({moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:v}),h.current.onCustomAction({type:"teachingStart",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:v}),u.current.speakText(I,{lipsyncLang:D.lipsyncLang,onSpeechEnd:()=>{r.current.isTeaching=!1,h.current.onCustomAction({type:"teachingComplete",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:v,hasQuestions:v.questions&&v.questions.length>0}),v?.code_example&&h.current.onCustomAction({type:"codeExampleReady",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:v,codeExample:v.code_example})}})}},[e.teaching,y]),$=b.useCallback(v=>{const I=O(),M=S(v,I);if(M&&(r.current.score+=1),h.current.onQuestionAnswer({moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,answer:v,isCorrect:M,question:I}),u.current)if(M){if(u.current.setMood("happy"),e.correct)try{u.current.playReaction("happy")}catch{u.current.setBodyMovement("happy")}u.current.setBodyMovement("gesturing");const V=y()?.questions?.length||0;r.current.currentQuestionIndex>=V-1;const Z=r.current.currentQuestionIndex<V-1;console.log("[CurriculumLearning] Answer feedback - questionIndex:",r.current.currentQuestionIndex,"totalQuestions:",V,"hasNextQuestion:",Z);const q=I.type==="code_test"?`Great job! Your code passed all the tests! ${I.explanation||""}`:`Excellent! That's correct! ${I.explanation||""}`,ne=F.current||{lipsyncLang:"en"};u.current.speakText(q,{lipsyncLang:ne.lipsyncLang,onSpeechEnd:()=>{h.current.onCustomAction({type:"answerFeedbackComplete",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,isCorrect:!0,hasNextQuestion:Z,score:r.current.score,totalQuestions:r.current.totalQuestions})}})}else{if(u.current.setMood("sad"),e.incorrect)try{u.current.playAnimation(e.incorrect,!0)}catch{u.current.setBodyMovement("idle")}u.current.setBodyMovement("gesturing");const V=y()?.questions?.length||0,Z=r.current.currentQuestionIndex>=V-1,q=r.current.currentQuestionIndex<V-1;console.log("[CurriculumLearning] Answer feedback (incorrect) - questionIndex:",r.current.currentQuestionIndex,"totalQuestions:",V,"hasNextQuestion:",q);const ne=I.type==="code_test"?`Your code didn't pass all the tests. ${I.explanation||"Try again!"}`:`Not quite right, but don't worry! ${I.explanation||""}${Z?"":" Let's move on to the next question."}`,de=F.current||{lipsyncLang:"en"};u.current.speakText(ne,{lipsyncLang:de.lipsyncLang,onSpeechEnd:()=>{h.current.onCustomAction({type:"answerFeedbackComplete",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,isCorrect:!1,hasNextQuestion:q,score:r.current.score,totalQuestions:r.current.totalQuestions})}})}else{const V=y()?.questions?.length||0;h.current.onCustomAction({type:"answerFeedbackComplete",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,isCorrect:M,hasNextQuestion:r.current.currentQuestionIndex<V-1,score:r.current.score,totalQuestions:r.current.totalQuestions,avatarNotReady:!0})}},[e.correct,e.incorrect,O,y,S]),ve=b.useCallback(v=>{const I=O();if(!v||typeof v!="object"){console.error("Invalid code test result format. Expected object with {passed: boolean, ...}");return}if(I?.type!=="code_test"){console.warn("Current question is not a code test. Use handleAnswerSelect for other question types.");return}const M={passed:v.passed===!0,results:v.results||[],output:v.output||"",error:v.error||null,executionTime:v.executionTime||null,testCount:v.testCount||0,passedCount:v.passedCount||0,failedCount:v.failedCount||0};h.current.onCustomAction({type:"codeTestSubmitted",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,testResult:M,question:I}),m.current&&m.current(M)},[O,S]),me=b.useCallback(()=>{if(r.current.currentQuestionIndex>0){r.current.currentQuestionIndex-=1;const v=O();v&&h.current.onCustomAction({type:"questionStart",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,questionIndex:r.current.currentQuestionIndex,totalQuestions:r.current.totalQuestions,question:v,score:r.current.score});const I=()=>{if(!u.current||!v)return;u.current.setMood("happy"),u.current.setBodyMovement("idle");const M=F.current||{lipsyncLang:"en"};v.type==="code_test"?u.current.speakText(`Let's go back to this coding challenge: ${v.question}`,{lipsyncLang:M.lipsyncLang}):u.current.speakText(`Going back to: ${v.question}`,{lipsyncLang:M.lipsyncLang})};if(u.current&&u.current.isReady&&v)I();else if(v){const M=setInterval(()=>{u.current&&u.current.isReady&&(clearInterval(M),I())},100);setTimeout(()=>{clearInterval(M)},5e3)}}},[O]),Fe=b.useCallback(()=>{const v=N.current||{modules:[]};if(v.modules[r.current.currentModuleIndex],r.current.currentLessonIndex>0)r.current.currentLessonIndex-=1,r.current.currentQuestionIndex=0,r.current.lessonCompleted=!1,r.current.isQuestionMode=!1,r.current.isTeaching=!1,r.current.score=0,r.current.totalQuestions=0,h.current.onCustomAction({type:"lessonStart",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex}),h.current.onLessonStart({moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:y()}),u.current&&(u.current.setMood("happy"),u.current.setBodyMovement("idle"));else if(r.current.currentModuleIndex>0){const D=v.modules[r.current.currentModuleIndex-1];r.current.currentModuleIndex-=1,r.current.currentLessonIndex=(D?.lessons?.length||1)-1,r.current.currentQuestionIndex=0,r.current.lessonCompleted=!1,r.current.isQuestionMode=!1,r.current.isTeaching=!1,r.current.score=0,r.current.totalQuestions=0,h.current.onCustomAction({type:"lessonStart",moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex}),h.current.onLessonStart({moduleIndex:r.current.currentModuleIndex,lessonIndex:r.current.currentLessonIndex,lesson:y()}),u.current&&(u.current.setMood("happy"),u.current.setBodyMovement("idle"))}},[y]),ye=b.useCallback(()=>{r.current.currentModuleIndex=0,r.current.currentLessonIndex=0,r.current.currentQuestionIndex=0,r.current.isTeaching=!1,r.current.isQuestionMode=!1,r.current.lessonCompleted=!1,r.current.curriculumCompleted=!1,r.current.score=0,r.current.totalQuestions=0},[]),Re=b.useCallback(v=>{console.log("Avatar is ready!",v);const I=y(),M=I?.avatar_script||I?.body;c&&M&&setTimeout(()=>{d.current&&d.current()},10)},[c,y]);b.useLayoutEffect(()=>{d.current=Y,g.current=B,R.current=f,x.current=P,w.current=E,G.current=L,m.current=$}),b.useImperativeHandle(l,()=>({startTeaching:Y,startQuestions:L,handleAnswerSelect:$,handleCodeTestResult:ve,nextQuestion:P,previousQuestion:me,nextLesson:B,previousLesson:Fe,completeLesson:f,completeCurriculum:E,resetCurriculum:ye,getState:()=>({...r.current}),getCurrentQuestion:()=>O(),getCurrentLesson:()=>y(),getAvatarRef:()=>u.current,speakText:async(v,I={})=>{await u.current?.resumeAudioContext?.();const M=F.current||{lipsyncLang:"en"};u.current?.speakText(v,{...I,lipsyncLang:I.lipsyncLang||M.lipsyncLang})},resumeAudioContext:async()=>{if(u.current?.resumeAudioContext)return await u.current.resumeAudioContext();const v=u.current?.talkingHead;if(v?.audioCtx){const I=v.audioCtx;if(I.state==="suspended"||I.state==="interrupted")try{await I.resume(),console.log("Audio context resumed via talkingHead")}catch(M){console.warn("Failed to resume audio context:",M)}}else console.warn("Audio context not available yet")},stopSpeaking:()=>u.current?.stopSpeaking(),pauseSpeaking:()=>u.current?.pauseSpeaking(),resumeSpeaking:async()=>await u.current?.resumeSpeaking(),isPaused:()=>u.current&&typeof u.current.isPaused<"u"?u.current.isPaused:!1,setMood:v=>u.current?.setMood(v),playAnimation:(v,I)=>u.current?.playAnimation(v,I),setBodyMovement:v=>u.current?.setBodyMovement(v),setMovementIntensity:v=>u.current?.setMovementIntensity(v),playRandomDance:()=>u.current?.playRandomDance(),playReaction:v=>u.current?.playReaction(v),playCelebration:()=>u.current?.playCelebration(),setShowFullAvatar:v=>u.current?.setShowFullAvatar(v),setTimingAdjustment:v=>u.current?.setTimingAdjustment(v),lockAvatarPosition:()=>u.current?.lockAvatarPosition(),unlockAvatarPosition:()=>u.current?.unlockAvatarPosition(),triggerCustomAction:(v,I)=>{h.current.onCustomAction({type:v,...I,state:{...r.current}})},handleResize:()=>u.current?.handleResize(),isAvatarReady:()=>u.current?.isReady||!1}),[Y,L,$,ve,P,B,f,E,ye,O,y]);const ce=F.current||{avatarUrl:"/avatars/brunette.glb",avatarBody:"F",mood:"happy",ttsLang:"en",ttsService:null,ttsVoice:null,ttsApiKey:null,bodyMovement:"gesturing",movementIntensity:.7,showFullAvatar:!1,animations:e};return j.jsx("div",{style:{width:"100%",height:"100%"},children:j.jsx(Je,{ref:u,avatarUrl:ce.avatarUrl,avatarBody:ce.avatarBody,mood:ce.mood,ttsLang:ce.ttsLang,ttsService:ce.ttsService,ttsVoice:ce.ttsVoice,ttsApiKey:ce.ttsApiKey,bodyMovement:ce.bodyMovement,movementIntensity:ce.movementIntensity,showFullAvatar:ce.showFullAvatar,cameraView:"upper",animations:ce.animations,onReady:Re,onLoading:()=>{},onError:v=>{console.error("Avatar error:",v)}})})});ut.displayName="CurriculumLearning";function Ut({manifestPath:W="/animations/manifest.json",avatarBody:n="F",onAnimationPlay:e=null,onAnimationsSelected:t=null,onDeleteAnimations:o=null,style:s={}}){const[i,a]=b.useState([]),[c,l]=b.useState(new Set),[u,r]=b.useState(!0),[h,d]=b.useState(null),[g,R]=b.useState("all"),[x,w]=b.useState("");b.useEffect(()=>{(async()=>{r(!0),d(null);try{const E=await Ve(W),L=[];if(E._genderSpecific){const B=(n?.toUpperCase()||"F")==="M"?"male":"female";E._genderSpecific[B]&&Object.entries(E._genderSpecific[B]).forEach(([Y,$])=>{(Array.isArray($)?$:[$]).forEach(me=>{L.push({path:me,group:Y,gender:B,name:me.split("/").pop().replace(".fbx","")})})}),E._genderSpecific.shared&&Object.entries(E._genderSpecific.shared).forEach(([Y,$])=>{(Array.isArray($)?$:[$]).forEach(me=>{L.push({path:me,group:Y,gender:"shared",name:me.split("/").pop().replace(".fbx","")})})})}Object.entries(E).forEach(([P,B])=>{P!=="_genderSpecific"&&(Array.isArray(B)?B:[B]).forEach($=>{typeof $=="string"&&L.push({path:$,group:P,gender:"root",name:$.split("/").pop().replace(".fbx","")})})}),a(L),r(!1)}catch(E){console.error("Failed to load animations:",E),d(E.message),r(!1)}})()},[W,n]);const G=["all",...new Set(i.map(f=>f.group))],m=i.filter(f=>{const E=g==="all"||f.group===g,L=x===""||f.name.toLowerCase().includes(x.toLowerCase())||f.path.toLowerCase().includes(x.toLowerCase());return E&&L}),N=f=>{const E=new Set(c);E.has(f)?E.delete(f):E.add(f),l(E),t&&t(Array.from(E))},F=()=>{const f=new Set(c);m.forEach(E=>{f.add(E.path)}),l(f),t&&t(Array.from(f))},y=()=>{const f=new Set(c);m.forEach(E=>{f.delete(E.path)}),l(f),t&&t(Array.from(f))},O=()=>{const E=i.filter(L=>!c.has(L.path)).map(L=>L.path);if(E.length===0){alert("No animations to delete. Select animations to keep, then delete will remove the unselected ones.");return}window.confirm(`Are you sure you want to delete ${E.length} animation(s)?
|
|
8
8
|
|
|
9
9
|
This will delete:
|
|
10
10
|
${E.slice(0,5).join(`
|
|
11
11
|
`)}${E.length>5?`
|
|
12
|
-
...`:""}`)&&(o&&o(E),a(i.filter(L=>c.has(L.path))),l(new Set))},S=f=>{e&&e(f)};return u?
|
|
12
|
+
...`:""}`)&&(o&&o(E),a(i.filter(L=>c.has(L.path))),l(new Set))},S=f=>{e&&e(f)};return u?j.jsx("div",{style:{padding:"20px",textAlign:"center",...s},children:j.jsx("p",{children:"Loading animations..."})}):h?j.jsx("div",{style:{padding:"20px",color:"red",...s},children:j.jsxs("p",{children:["Error loading animations: ",h]})}):j.jsxs("div",{style:{padding:"20px",backgroundColor:"#2a2a2a",borderRadius:"8px",color:"#fff",...s},children:[j.jsx("h2",{style:{marginTop:0},children:"Animation Selector"}),j.jsx("p",{style:{color:"#aaa",fontSize:"14px"},children:"Click buttons to play animations. Select animations to keep, then delete will remove the rest."}),j.jsxs("div",{style:{display:"flex",gap:"10px",marginBottom:"20px",flexWrap:"wrap",alignItems:"center"},children:[j.jsx("input",{type:"text",placeholder:"Search animations...",value:x,onChange:f=>w(f.target.value),style:{padding:"8px 12px",borderRadius:"6px",border:"1px solid #555",backgroundColor:"#333",color:"#fff",fontSize:"14px",flex:"1",minWidth:"200px"}}),j.jsx("select",{value:g,onChange:f=>R(f.target.value),style:{padding:"8px 12px",borderRadius:"6px",border:"1px solid #555",backgroundColor:"#333",color:"#fff",fontSize:"14px"},children:G.map(f=>j.jsx("option",{value:f,children:f==="all"?"All Groups":f},f))}),j.jsx("button",{onClick:F,style:{padding:"8px 16px",backgroundColor:"#4CAF50",color:"white",border:"none",borderRadius:"6px",cursor:"pointer",fontSize:"14px"},children:"Select All Visible"}),j.jsx("button",{onClick:y,style:{padding:"8px 16px",backgroundColor:"#666",color:"white",border:"none",borderRadius:"6px",cursor:"pointer",fontSize:"14px"},children:"Deselect All Visible"}),j.jsxs("button",{onClick:O,style:{padding:"8px 16px",backgroundColor:"#f44336",color:"white",border:"none",borderRadius:"6px",cursor:"pointer",fontSize:"14px",fontWeight:"bold"},children:["Delete Unselected (",i.length-c.size,")"]})]}),j.jsxs("div",{style:{marginBottom:"15px",fontSize:"14px",color:"#aaa"},children:["Total: ",i.length," | Selected: ",c.size," | Showing: ",m.length]}),j.jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(200px, 1fr))",gap:"10px",maxHeight:"500px",overflowY:"auto",padding:"10px",backgroundColor:"#1a1a1a",borderRadius:"6px"},children:m.map((f,E)=>{const L=c.has(f.path);return j.jsxs("div",{style:{border:`2px solid ${L?"#4CAF50":"#555"}`,borderRadius:"6px",padding:"10px",backgroundColor:L?"#2a4a2a":"#222",cursor:"pointer",transition:"all 0.2s"},onClick:()=>N(f.path),children:[j.jsxs("div",{style:{marginBottom:"8px"},children:[j.jsx("input",{type:"checkbox",checked:L,onChange:()=>N(f.path),onClick:P=>P.stopPropagation(),style:{marginRight:"8px",cursor:"pointer"}}),j.jsxs("span",{style:{fontSize:"12px",color:"#aaa"},children:[f.group," ",f.gender!=="root"&&`(${f.gender})`]})]}),j.jsx("div",{style:{fontSize:"13px",fontWeight:"bold",marginBottom:"8px",wordBreak:"break-word"},children:f.name}),j.jsx("button",{onClick:P=>{P.stopPropagation(),S(f.path)},style:{width:"100%",padding:"6px",backgroundColor:"#2196F3",color:"white",border:"none",borderRadius:"4px",cursor:"pointer",fontSize:"12px"},children:"▶ Play"})]},`${f.path}-${E}`)})}),m.length===0&&j.jsx("div",{style:{padding:"40px",textAlign:"center",color:"#aaa"},children:"No animations found matching your filters."})]})}const et={dance:{name:"dance",type:"code-based",variations:["dancing","dancing2","dancing3"],loop:!0,duration:1e4,description:"Celebration dance animation with multiple variations"},happy:{name:"happy",type:"code-based",loop:!0,duration:5e3,description:"Happy, upbeat body movement"},surprised:{name:"surprised",type:"code-based",loop:!1,duration:3e3,description:"Surprised reaction with quick movements"},thinking:{name:"thinking",type:"code-based",loop:!0,duration:8e3,description:"Thoughtful, contemplative movement"},nodding:{name:"nodding",type:"code-based",loop:!1,duration:2e3,description:"Nodding agreement gesture"},shaking:{name:"shaking",type:"code-based",loop:!1,duration:2e3,description:"Shaking head disagreement gesture"},celebration:{name:"celebration",type:"code-based",loop:!1,duration:3e3,description:"Celebration animation for achievements"},energetic:{name:"energetic",type:"code-based",loop:!0,duration:6e3,description:"High-energy, enthusiastic movement"},swaying:{name:"swaying",type:"code-based",loop:!0,duration:8e3,description:"Gentle swaying motion"},bouncing:{name:"bouncing",type:"code-based",loop:!0,duration:4e3,description:"Bouncy, playful movement"},gesturing:{name:"gesturing",type:"code-based",loop:!0,duration:5e3,description:"Teaching gesture animation"},walking:{name:"walking",type:"code-based",loop:!0,duration:6e3,description:"Walking motion"},prancing:{name:"prancing",type:"code-based",loop:!0,duration:4e3,description:"Playful prancing movement"},excited:{name:"excited",type:"code-based",loop:!0,duration:5e3,description:"Excited, energetic movement"}},Wt=W=>et[W]||null,Vt=W=>et.hasOwnProperty(W);exports.AnimationSelector=Ut;exports.CurriculumLearning=ut;exports.SimpleTalkingAvatar=lt;exports.TalkingHeadAvatar=Je;exports.TalkingHeadComponent=at;exports.animations=et;exports.getActiveTTSConfig=Xe;exports.getAnimation=Wt;exports.getVoiceOptions=Dt;exports.hasAnimation=Vt;
|